feat(learner): web shell, library, lesson views (LessonView), decks, code files, exercises, notes, account and admin pages
Tasks 10-12 of the WP-A plan in one commit (the route modules import each other): - header extras portalled into the Phase 0 header: course switcher, search, Reading/Work, account - course frame with outline sidebar (mobile overlay, Escape closes), progress, gating locks - library: featured course, continue row, New and collection rows, course list, filters, search - LessonView: text (track switcher, folds, ordered hint tiers), video (resume, done near the end, timestamp notes, transcript), companion decks rendered with pdf.js (thumbs, arrows, fullscreen, per-slide notes), code files (tree, tabs, copy, zip, command), exercises (Web Worker runner or local command with optional pasted evidence), floating action bar - notes list, account (email/password, providers, SSO by email) and owner admin pages - pdf.js worker served from /api/learner/pdf.worker.mjs - browser entry @stc/feature-learner/web (the package index also carries the server half) Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
99c0e4929f
commit
89c51f013d
@@ -0,0 +1,20 @@
|
||||
import type { Feature } from "@stc/contracts";
|
||||
|
||||
/** The pdf.js worker from the installed pdfjs-dist, for client-side deck rendering. */
|
||||
export function pdfWorkerPath(): string {
|
||||
return Bun.resolveSync("pdfjs-dist/build/pdf.worker.min.mjs", import.meta.dir);
|
||||
}
|
||||
|
||||
export function assetRoutes(): Feature["routes"] {
|
||||
let path: string | null = null;
|
||||
return {
|
||||
"/api/learner/pdf.worker.mjs": {
|
||||
GET: async () => {
|
||||
path ??= pdfWorkerPath();
|
||||
return new Response(Bun.file(path), {
|
||||
headers: { "Content-Type": "text/javascript; charset=utf-8", "Cache-Control": "public, max-age=86400" },
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import { lessonRoutes } from "./lesson";
|
||||
import { userDataRoutes } from "./userdata";
|
||||
import { codeRoutes } from "./code";
|
||||
import { transpileRoutes } from "./transpile";
|
||||
import { assetRoutes } from "./assets";
|
||||
|
||||
/**
|
||||
* The learner feature: auth, library, reader, notes, progress and exercises.
|
||||
@@ -32,6 +33,7 @@ export function learnerFeature(ctx: ServerContext): Feature & { auth: AuthServic
|
||||
...userDataRoutes(ctx),
|
||||
...codeRoutes(ctx),
|
||||
...transpileRoutes(),
|
||||
...assetRoutes(),
|
||||
};
|
||||
// Every handler waits for the learner migrations (a no-op once Phase 2 runs them in migrate()).
|
||||
for (const methods of Object.values(routes)) {
|
||||
|
||||
Reference in New Issue
Block a user