From b276dbf51c682d85330072e3cb43044a9f92504d Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Wed, 26 Jul 2023 11:10:26 +0800 Subject: [PATCH 1/2] Fix deep links to PDF highlights from the library --- .../templates/article/NotebookPresenter.tsx | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/packages/web/components/templates/article/NotebookPresenter.tsx b/packages/web/components/templates/article/NotebookPresenter.tsx index 985e62ab3..ec81bb501 100644 --- a/packages/web/components/templates/article/NotebookPresenter.tsx +++ b/packages/web/components/templates/article/NotebookPresenter.tsx @@ -5,6 +5,8 @@ import 'react-sliding-pane/dist/react-sliding-pane.css' import { NotebookContent } from './Notebook' import { NotebookHeader } from './NotebookHeader' import useGetWindowDimensions from '../../../lib/hooks/useGetWindowDimensions' +import { useRouter } from 'next/router' +import { showErrorToast } from '../../../lib/toastHelpers' type NotebookPresenterProps = { viewer: UserBasicData @@ -17,6 +19,7 @@ type NotebookPresenterProps = { export const NotebookPresenter = (props: NotebookPresenterProps) => { const windowDimensions = useGetWindowDimensions() + const router = useRouter() return ( { viewer={props.viewer} item={props.item} viewInReader={(highlightId) => { - // The timeout here is a bit of a hack to work around rerendering - setTimeout(() => { - const target = document.querySelector( - `[omnivore-highlight-id="${highlightId}"]` - ) - target?.scrollIntoView({ - block: 'center', - behavior: 'auto', - }) - }, 1) - history.replaceState( - undefined, - window.location.href, - `#${highlightId}` + if (!router || !router.isReady || !props.viewer) { + showErrorToast('Error navigating to highlight') + return + } + router.push( + { + pathname: '/[username]/[slug]', + query: { + username: props.viewer.profile.username, + slug: props.item.slug, + }, + hash: highlightId, + }, + `/${props.viewer.profile.username}/${props.item.slug}#${highlightId}`, + { + scroll: false, + } ) }} /> From a14560cb9a35ae81ebce43b2064bf1aa97130f7b Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Wed, 26 Jul 2023 12:11:16 +0800 Subject: [PATCH 2/2] Set initial page based on highlight deep link if possible --- .../templates/article/PdfArticleContainer.tsx | 53 +++++++------------ 1 file changed, 20 insertions(+), 33 deletions(-) diff --git a/packages/web/components/templates/article/PdfArticleContainer.tsx b/packages/web/components/templates/article/PdfArticleContainer.tsx index 9beff0387..6b0abd5fb 100644 --- a/packages/web/components/templates/article/PdfArticleContainer.tsx +++ b/packages/web/components/templates/article/PdfArticleContainer.tsx @@ -34,41 +34,12 @@ export default function PdfArticleContainer( props: PdfArticleContainerProps ): JSX.Element { const containerRef = useRef(null) - const [shareTarget, setShareTarget] = - useState(undefined) const [notebookKey, setNotebookKey] = useState(uuidv4()) const [noteTarget, setNoteTarget] = useState(undefined) - const [noteTargetPageIndex, setNoteTargetPageIndex] = - useState(undefined) + const [noteTargetPageIndex, setNoteTargetPageIndex] = useState< + number | undefined + >(undefined) const highlightsRef = useRef([]) - const canShareNative = useCanShareNative() - - // const getHighlightURL = useCallback( - // (highlightID: string): string => - // `${webBaseURL}/${props.viewerUsername}/${props.article.slug}/highlights/${highlightID}`, - // [props.article.slug, props.viewerUsername] - // ) - - // const nativeShare = useCallback( - // async (highlightID: string, title: string) => { - // await navigator?.share({ - // title: title, - // url: getHighlightURL(highlightID), - // }) - // }, - // [getHighlightURL] - // ) - - // const handleOpenShare = useCallback( - // (highlight: Highlight) => { - // if (canShareNative) { - // nativeShare(highlight.shortId, props.article.title) - // } else { - // setShareTarget(highlight) - // } - // }, - // [nativeShare, canShareNative, props.article.title] - // ) const annotationOmnivoreId = (annotation: Annotation): string | undefined => { if ( @@ -207,6 +178,22 @@ export default function PdfArticleContainer( blendMode: PSPDFKit.BlendMode.multiply, } + const initialPage = () => { + const highlightHref = window.location.hash + ? window.location.hash.split('#')[1] + : null + if (highlightHref) { + // find the page index if possible + const highlight = props.article.highlights.find( + (h) => h.id === highlightHref + ) + if (highlight) { + return highlight.highlightPositionAnchorIndex + } + } + return props.article.readingProgressAnchorIndex + } + instance = await PSPDFKit.load({ container: container || '.pdf-container', toolbarItems, @@ -219,7 +206,7 @@ export default function PdfArticleContainer( annotationTooltipCallback: annotationTooltipCallback, initialViewState: new PSPDFKit.ViewState({ zoom: PSPDFKit.ZoomMode.FIT_TO_WIDTH, - currentPageIndex: props.article.readingProgressAnchorIndex || 0, + currentPageIndex: initialPage() || 0, }), })