feat(app): the module registry drives the render (S6b DoD)

Replace App's page-render ternary and the three side-rail page conditionals with
a data-driven lookup: components/moduleRegistry maps each page to a prop-free
content component (+ optional side rail + shell fadeTop), and App renders
PAGE_CONTENT[page]/PAGE_RAIL[page] gated by moduleDef(page).gate (an unreachable
gated page falls back to the feed, as the old ternary did). Content modules and
the two rails are now prop-free: they read `me` via the new useMe() hook and
their module-local state from the scoped providers; FeedPage/MessagesPage are the
only wrappers (they wire the global feed scope / meId). App.tsx 796->431 lines,
zero `page===X` chrome conditionals — closes the Platform epic DoD. (Platform S6b.3)
This commit is contained in:
2026-07-19 01:25:32 +02:00
parent fd1742e783
commit a42e0a9e3e
11 changed files with 193 additions and 106 deletions
+4 -2
View File
@@ -27,7 +27,8 @@ const VideoEditor = lazy(() => import("./VideoEditor"));
const ShareDialog = lazy(() => import("./ShareDialog"));
import { useConfirm } from "./ConfirmProvider";
import { useLiveQuery } from "../lib/useLiveQuery";
import { api, type DownloadJob, type Me } from "../lib/api";
import { useMe } from "../lib/useMe";
import { api, type DownloadJob } from "../lib/api";
import { invalidateDownloads } from "../lib/downloads";
import { notify } from "../lib/notifications";
import { formatBytes, formatDuration, formatEta, formatSpeed } from "../lib/format";
@@ -539,7 +540,8 @@ function AdminSystem() {
// --- Main -----------------------------------------------------------------------------------
export default function DownloadCenter({ me }: { me: Me }) {
export default function DownloadCenter() {
const me = useMe();
const { t } = useTranslation();
const qc = useQueryClient();
const confirm = useConfirm();