Comments only render inside TranscriptionEditView, so a deep-link into a document with existing reviewed transcriptions landed the user in read mode with no comment element in the DOM — the scroll target silently missed. scrollToCommentFromQuery now takes a setPanelMode callback and calls it with 'edit' whenever both query params are present. The page's own transcribe-mode $effect checks a skipInitialPanelMode flag the deep-link flow sets, so its default-panel-mode logic doesn't race against the explicit override. Two new helper tests pin the contract: panel mode is forced to 'edit' both when transcribe mode is off (entering fresh) and when it is already on (same-page notification click). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
47 lines
1.4 KiB
TypeScript
47 lines
1.4 KiB
TypeScript
export type DeepLinkScrollOptions = {
|
|
transcribeMode: boolean;
|
|
setTranscribeMode: (value: boolean) => void;
|
|
setPanelMode: (mode: 'read' | 'edit') => void;
|
|
loadBlocks: () => Promise<void>;
|
|
setActiveAnnotationId: (id: string) => void;
|
|
flashAnnotation: (annotationId: string) => void;
|
|
prefersReducedMotion: boolean;
|
|
afterTick: () => Promise<void>;
|
|
getElement: (id: string) => HTMLElement | null;
|
|
onStripUrl: () => void;
|
|
};
|
|
|
|
export async function scrollToCommentFromQuery(
|
|
url: URL,
|
|
opts: DeepLinkScrollOptions
|
|
): Promise<void> {
|
|
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();
|
|
}
|