From 1138f273647d6d0a55cb0977340b0ebb36ec0fdb Mon Sep 17 00:00:00 2001 From: Jared Pereira Date: Mon, 24 Nov 2025 13:46:38 -0500 Subject: [PATCH] simplify page handling and support root canvas page --- .../[did]/[publication]/[rkey]/CanvasPage.tsx | 45 ++--- .../[rkey]/DocumentPageRenderer.tsx | 14 +- .../[rkey]/LinearDocumentPage.tsx | 45 ++--- .../[did]/[publication]/[rkey]/PostPages.tsx | 170 ++++++++++-------- .../[publication]/[rkey]/extractCodeBlocks.ts | 5 +- 5 files changed, 139 insertions(+), 140 deletions(-) diff --git a/app/lish/[did]/[publication]/[rkey]/CanvasPage.tsx b/app/lish/[did]/[publication]/[rkey]/CanvasPage.tsx index c4e05e3a..32bccd2c 100644 --- a/app/lish/[did]/[publication]/[rkey]/CanvasPage.tsx +++ b/app/lish/[did]/[publication]/[rkey]/CanvasPage.tsx @@ -21,40 +21,31 @@ import { InfoSmall } from "components/Icons/InfoSmall"; import { PostHeader } from "./PostHeader/PostHeader"; import { useDrawerOpen } from "./Interactions/InteractionDrawer"; import { PollData } from "./fetchPollData"; +import { SharedPageProps } from "./PostPages"; export function CanvasPage({ - document, blocks, - did, - profile, - preferences, - pubRecord, - theme, - prerenderedCodeBlocks, - bskyPostData, - pollData, - document_uri, - pageId, - pageOptions, - fullPageScroll, pages, -}: { - document_uri: string; - document: PostPageData; + ...props +}: Omit & { blocks: PubLeafletPagesCanvas.Block[]; - profile: ProfileViewDetailed; - pubRecord?: PubLeafletPublication.Record; - theme?: PubLeafletPublication.Theme | null; - did: string; - prerenderedCodeBlocks?: Map; - bskyPostData: AppBskyFeedDefs.PostView[]; - pollData: PollData[]; - preferences: { showComments?: boolean }; - pageId?: string; - pageOptions?: React.ReactNode; - fullPageScroll: boolean; pages: (PubLeafletPagesLinearDocument.Main | PubLeafletPagesCanvas.Main)[]; }) { + const { + document, + did, + profile, + preferences, + pubRecord, + theme, + prerenderedCodeBlocks, + bskyPostData, + pollData, + document_uri, + pageId, + pageOptions, + fullPageScroll, + } = props; if (!document) return null; let hasPageBackground = !!theme?.showPageBackground; diff --git a/app/lish/[did]/[publication]/[rkey]/DocumentPageRenderer.tsx b/app/lish/[did]/[publication]/[rkey]/DocumentPageRenderer.tsx index 5213fad8..b53b6383 100644 --- a/app/lish/[did]/[publication]/[rkey]/DocumentPageRenderer.tsx +++ b/app/lish/[did]/[publication]/[rkey]/DocumentPageRenderer.tsx @@ -5,6 +5,7 @@ import { PubLeafletBlocksBskyPost, PubLeafletDocument, PubLeafletPagesLinearDocument, + PubLeafletPagesCanvas, PubLeafletPublication, } from "lexicons/api"; import { QuoteHandler } from "./QuoteHandler"; @@ -109,12 +110,14 @@ export async function DocumentPageRenderer({ document.documents_in_publications[0]?.publications?.identity_did || did; let firstPage = record.pages[0]; - let blocks: PubLeafletPagesLinearDocument.Block[] = []; - if (PubLeafletPagesLinearDocument.isMain(firstPage)) { - blocks = firstPage.blocks || []; - } - let prerenderedCodeBlocks = await extractCodeBlocks(blocks); + let firstPageBlocks = + ( + firstPage as + | PubLeafletPagesLinearDocument.Main + | PubLeafletPagesCanvas.Main + ).blocks || []; + let prerenderedCodeBlocks = await extractCodeBlocks(firstPageBlocks); return ( @@ -129,7 +132,6 @@ export async function DocumentPageRenderer({ document={document} bskyPostData={bskyPostData} did={did} - blocks={blocks} prerenderedCodeBlocks={prerenderedCodeBlocks} pollData={pollData} /> diff --git a/app/lish/[did]/[publication]/[rkey]/LinearDocumentPage.tsx b/app/lish/[did]/[publication]/[rkey]/LinearDocumentPage.tsx index b252af36..18e4fdd0 100644 --- a/app/lish/[did]/[publication]/[rkey]/LinearDocumentPage.tsx +++ b/app/lish/[did]/[publication]/[rkey]/LinearDocumentPage.tsx @@ -23,38 +23,29 @@ import { useDrawerOpen } from "./Interactions/InteractionDrawer"; import { PageWrapper } from "components/Pages/Page"; import { decodeQuotePosition } from "./quotePosition"; import { PollData } from "./fetchPollData"; +import { SharedPageProps } from "./PostPages"; export function LinearDocumentPage({ - document, blocks, - did, - profile, - preferences, - pubRecord, - theme, - prerenderedCodeBlocks, - bskyPostData, - document_uri, - pageId, - pageOptions, - pollData, - fullPageScroll, -}: { - document_uri: string; - document: PostPageData; + ...props +}: Omit & { blocks: PubLeafletPagesLinearDocument.Block[]; - profile?: ProfileViewDetailed; - pubRecord?: PubLeafletPublication.Record; - theme?: PubLeafletPublication.Theme | null; - did: string; - prerenderedCodeBlocks?: Map; - bskyPostData: AppBskyFeedDefs.PostView[]; - pollData: PollData[]; - preferences: { showComments?: boolean }; - pageId?: string; - pageOptions?: React.ReactNode; - fullPageScroll: boolean; }) { + const { + document, + did, + profile, + preferences, + pubRecord, + theme, + prerenderedCodeBlocks, + bskyPostData, + pollData, + document_uri, + pageId, + pageOptions, + fullPageScroll, + } = props; let { identity } = useIdentityData(); let drawer = useDrawerOpen(document_uri); diff --git a/app/lish/[did]/[publication]/[rkey]/PostPages.tsx b/app/lish/[did]/[publication]/[rkey]/PostPages.tsx index 1bf3d8db..e599e241 100644 --- a/app/lish/[did]/[publication]/[rkey]/PostPages.tsx +++ b/app/lish/[did]/[publication]/[rkey]/PostPages.tsx @@ -98,9 +98,53 @@ export const closePage = (page: string) => }; }); +// Shared props type for both page components +export type SharedPageProps = { + document: PostPageData; + did: string; + profile: ProfileViewDetailed; + preferences: { showComments?: boolean }; + pubRecord?: PubLeafletPublication.Record; + theme?: PubLeafletPublication.Theme | null; + prerenderedCodeBlocks?: Map; + bskyPostData: AppBskyFeedDefs.PostView[]; + pollData: PollData[]; + document_uri: string; + fullPageScroll: boolean; + pageId?: string; + pageOptions?: React.ReactNode; + allPages: (PubLeafletPagesLinearDocument.Main | PubLeafletPagesCanvas.Main)[]; +}; + +// Component that renders either Canvas or Linear page based on page type +function PageRenderer({ + page, + ...sharedProps +}: { + page: PubLeafletPagesLinearDocument.Main | PubLeafletPagesCanvas.Main; +} & SharedPageProps) { + const isCanvas = PubLeafletPagesCanvas.isMain(page); + + if (isCanvas) { + return ( + + ); + } + + return ( + + ); +} + export function PostPages({ document, - blocks, did, profile, preferences, @@ -112,7 +156,6 @@ export function PostPages({ }: { document_uri: string; document: PostPageData; - blocks: PubLeafletPagesLinearDocument.Block[]; profile: ProfileViewDetailed; pubRecord?: PubLeafletPublication.Record; did: string; @@ -123,35 +166,42 @@ export function PostPages({ }) { let drawer = useDrawerOpen(document_uri); useInitializeOpenPages(); - let pages = useOpenPages(); + let openPageIds = useOpenPages(); if (!document) return null; let record = document.data as PubLeafletDocument.Record; - - // Get theme from publication or document (for standalone docs) let theme = pubRecord?.theme || record.theme || null; let hasPageBackground = !!theme?.showPageBackground; - let quotesAndMentions = document.quotesAndMentions; - let fullPageScroll = !hasPageBackground && !drawer && pages.length === 0; + let firstPage = record.pages[0] as + | PubLeafletPagesLinearDocument.Main + | PubLeafletPagesCanvas.Main; + + // Shared props used for all pages + const sharedProps: SharedPageProps = { + document, + did, + profile, + preferences, + pubRecord, + theme, + prerenderedCodeBlocks, + bskyPostData, + pollData, + document_uri, + allPages: record.pages as ( + | PubLeafletPagesLinearDocument.Main + | PubLeafletPagesCanvas.Main + )[], + fullPageScroll: !hasPageBackground && !drawer && openPageIds.length === 0, + }; + return ( <> - {!fullPageScroll && } - + {!sharedProps.fullPageScroll && } + + {drawer && !drawer.pageId && ( )} - {pages.map((p) => { + {openPageIds.map((pageId) => { let page = record.pages.find( - (page) => - ( - page as - | PubLeafletPagesLinearDocument.Main - | PubLeafletPagesCanvas.Main - ).id === p, + (p) => + (p as PubLeafletPagesLinearDocument.Main | PubLeafletPagesCanvas.Main) + .id === pageId, ) as | PubLeafletPagesLinearDocument.Main | PubLeafletPagesCanvas.Main | undefined; - if (!page) return null; - const isCanvas = PubLeafletPagesCanvas.isMain(page); + if (!page) return null; return ( - + - {isCanvas ? ( - closePage(page?.id!)} - hasPageBackground={hasPageBackground} - /> - } - /> - ) : ( - closePage(page?.id!)} - hasPageBackground={hasPageBackground} - /> - } - /> - )} + closePage(page.id!)} + hasPageBackground={hasPageBackground} + /> + } + /> {drawer && drawer.pageId === page.id && ( ); })} - {!fullPageScroll && } + + {!sharedProps.fullPageScroll && } ); } diff --git a/app/lish/[did]/[publication]/[rkey]/extractCodeBlocks.ts b/app/lish/[did]/[publication]/[rkey]/extractCodeBlocks.ts index 85e8df84..9c5ef740 100644 --- a/app/lish/[did]/[publication]/[rkey]/extractCodeBlocks.ts +++ b/app/lish/[did]/[publication]/[rkey]/extractCodeBlocks.ts @@ -1,16 +1,17 @@ import { PubLeafletDocument, PubLeafletPagesLinearDocument, + PubLeafletPagesCanvas, PubLeafletBlocksCode, } from "lexicons/api"; import { codeToHtml, bundledLanguagesInfo, bundledThemesInfo } from "shiki"; export async function extractCodeBlocks( - blocks: PubLeafletPagesLinearDocument.Block[], + blocks: PubLeafletPagesLinearDocument.Block[] | PubLeafletPagesCanvas.Block[], ): Promise> { const codeBlocks = new Map(); - // Process all pages in the document + // Process all blocks (works for both linear and canvas) for (let i = 0; i < blocks.length; i++) { const block = blocks[i]; const currentIndex = [i]; -- 2.51.2