export type DeepLinkScrollOptions = { transcribeMode: boolean; setTranscribeMode: (value: boolean) => void; setPanelMode: (mode: 'read' | 'edit') => void; loadBlocks: () => Promise; setActiveAnnotationId: (id: string) => void; flashAnnotation: (annotationId: string) => void; prefersReducedMotion: boolean; afterTick: () => Promise; getElement: (id: string) => HTMLElement | null; onStripUrl: () => void; }; export async function scrollToCommentFromQuery( url: URL, opts: DeepLinkScrollOptions ): Promise { const commentId = url.searchParams.get('commentId'); if (!commentId) return; const annotationId = url.searchParams.get('annotationId'); if (!annotationId) return; if (!opts.transcribeMode) { opts.setTranscribeMode(true); await opts.loadBlocks(); } // Comments only render in edit mode — force it so the deep-link target // exists in the DOM even if the document already has reviewed transcriptions // (which default the panel to read mode). opts.setPanelMode('edit'); opts.setActiveAnnotationId(annotationId); await opts.afterTick(); const el = opts.getElement(`comment-${commentId}`); if (el) { const behavior: ScrollBehavior = opts.prefersReducedMotion ? 'instant' : 'smooth'; el.scrollIntoView({ behavior, block: 'center' }); el.focus({ preventScroll: true }); opts.flashAnnotation(annotationId); } opts.onStripUrl(); }