From 3360994356b44aab9bfb8cb3d199202c094b5acb Mon Sep 17 00:00:00 2001 From: Jared Pereira Date: Fri, 17 Oct 2025 16:04:55 -0400 Subject: [PATCH] open sub-page if quoted --- .../[did]/[publication]/[rkey]/PostPages.tsx | 49 +++++++++++++++++-- .../[rkey]/PublishedPageBlock.tsx | 5 +- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/app/lish/[did]/[publication]/[rkey]/PostPages.tsx b/app/lish/[did]/[publication]/[rkey]/PostPages.tsx index c5f41da5..d9fa394f 100644 --- a/app/lish/[did]/[publication]/[rkey]/PostPages.tsx +++ b/app/lish/[did]/[publication]/[rkey]/PostPages.tsx @@ -24,13 +24,53 @@ import { CSS } from "@react-spring/web"; import { PageOptionButton } from "components/Pages/PageOptions"; import { CloseTiny } from "components/Icons/CloseTiny"; import { PageWrapper } from "components/Pages/Page"; -import { Fragment } from "react"; +import { Fragment, useEffect } from "react"; import { flushSync } from "react-dom"; import { scrollIntoView } from "src/utils/scrollIntoView"; -export const usePostPageUIState = create(() => ({ +import { useParams } from "next/navigation"; +import { decodeQuotePosition } from "./quotePosition"; + +const usePostPageUIState = create(() => ({ pages: [] as string[], + initialized: false, })); +export const useOpenPages = () => { + const { quote } = useParams(); + const state = usePostPageUIState((s) => s); + + if (!state.initialized && quote) { + const decodedQuote = decodeQuotePosition(quote as string); + if (decodedQuote?.pageId) { + return [decodedQuote.pageId]; + } + } + + return state.pages; +}; + +export const useInitializeOpenPages = () => { + const { quote } = useParams(); + + useEffect(() => { + const state = usePostPageUIState.getState(); + if (!state.initialized) { + if (quote) { + const decodedQuote = decodeQuotePosition(quote as string); + if (decodedQuote?.pageId) { + usePostPageUIState.setState({ + pages: [decodedQuote.pageId], + initialized: true, + }); + return; + } + } + // Mark as initialized even if no pageId found + usePostPageUIState.setState({ initialized: true }); + } + }, [quote]); +}; + export const openPage = (parent: string | undefined, page: string) => { flushSync(() => { usePostPageUIState.setState((state) => { @@ -40,6 +80,7 @@ export const openPage = (parent: string | undefined, page: string) => { parentPosition === -1 ? [page] : [...state.pages.slice(0, parentPosition + 1), page], + initialized: true, }; }); }); @@ -52,6 +93,7 @@ export const closePage = (page: string) => let parentPosition = state.pages.findIndex((s) => s == page); return { pages: state.pages.slice(0, parentPosition), + initialized: true, }; }); @@ -78,7 +120,8 @@ export function PostPages({ }) { let { identity } = useIdentityData(); let drawerOpen = useDrawerOpen(document_uri); - let pages = usePostPageUIState((s) => s.pages); + useInitializeOpenPages(); + let pages = useOpenPages(); if (!document || !document.documents_in_publications[0].publications) return null; diff --git a/app/lish/[did]/[publication]/[rkey]/PublishedPageBlock.tsx b/app/lish/[did]/[publication]/[rkey]/PublishedPageBlock.tsx index 3a66db80..e7de2b88 100644 --- a/app/lish/[did]/[publication]/[rkey]/PublishedPageBlock.tsx +++ b/app/lish/[did]/[publication]/[rkey]/PublishedPageBlock.tsx @@ -14,7 +14,7 @@ import { import { AppBskyFeedDefs } from "@atproto/api"; import { TextBlock } from "./TextBlock"; import { PostPageContext } from "./PostPageContext"; -import { openPage, usePostPageUIState } from "./PostPages"; +import { openPage, useOpenPages } from "./PostPages"; export function PublishedPageLinkBlock(props: { blocks: PubLeafletPagesLinearDocument.Block[]; @@ -27,7 +27,8 @@ export function PublishedPageLinkBlock(props: { bskyPostData: AppBskyFeedDefs.PostView[]; }) { //switch to use actually state - let isOpen = usePostPageUIState((s) => s.pages.includes(props.pageId)); + let openPages = useOpenPages(); + let isOpen = openPages.includes(props.pageId); return (