refactor(navigation): scrollToFocusedNote takes an options object

Smooth-scroll for the anchor jump when the target note is already
stacked, instant otherwise. While threading the new flag, the four
positional params got hard to read, so collapse them into
{ noteId, notes, hash, smoothHash } and update all call sites.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Julien Calixte
2026-04-26 09:56:32 +02:00
parent 4ce8c30649
commit c00065ce4a
4 changed files with 30 additions and 13 deletions

View File

@@ -142,7 +142,7 @@ watch(mode, async (newMode) => {
> >
<a <a
class="title-stacked-note-link" class="title-stacked-note-link"
@click.prevent="scrollToFocusedNote(props.sha)" @click.prevent="scrollToFocusedNote({ noteId: props.sha })"
> >
<div <div
class="title-stacked-note breadcrumbs text-sm" class="title-stacked-note breadcrumbs text-sm"

View File

@@ -97,7 +97,7 @@ watch(
> >
<a <a
class="title-stacked-note-link" class="title-stacked-note-link"
@click.prevent="scrollToFocusedNote(didrkey)" @click.prevent="scrollToFocusedNote({ noteId: didrkey })"
> >
<div <div
class="title-stacked-note breadcrumbs text-sm" class="title-stacked-note breadcrumbs text-sm"

View File

@@ -50,7 +50,7 @@ export const useATProtoLinks = (
: `${params.shortDid}-${params.rkey}` : `${params.shortDid}-${params.rkey}`
if (noteId === toValue(mainNoteId)) { if (noteId === toValue(mainNoteId)) {
scrollToFocusedNote(null) scrollToFocusedNote()
return return
} }
@@ -67,7 +67,7 @@ export const useATProtoLinks = (
const noteId = `${toShortDid(did)}-${rkey}` const noteId = `${toShortDid(did)}-${rkey}`
if (noteId === toValue(mainNoteId)) { if (noteId === toValue(mainNoteId)) {
scrollToFocusedNote(null) scrollToFocusedNote()
return return
} }

View File

@@ -23,6 +23,7 @@ export const useRouteQueryStackedNotes = () => {
const scrollToHashInNote = ( const scrollToHashInNote = (
cleanSha: string, cleanSha: string,
hash: string, hash: string,
smooth: boolean,
attempts = 30 attempts = 30
) => { ) => {
if (attempts <= 0) { if (attempts <= 0) {
@@ -33,20 +34,32 @@ export const useRouteQueryStackedNotes = () => {
`.note-${cleanSha} #${CSS.escape(hash)}` `.note-${cleanSha} #${CSS.escape(hash)}`
) )
if (heading) { if (heading) {
heading.scrollIntoView({ block: "start", inline: "nearest" }) heading.scrollIntoView({
block: "start",
inline: "nearest",
behavior: smooth ? "smooth" : "auto"
})
return return
} }
requestAnimationFrame(() => { requestAnimationFrame(() => {
scrollToHashInNote(cleanSha, hash, attempts - 1) scrollToHashInNote(cleanSha, hash, smooth, attempts - 1)
}) })
} }
const scrollToFocusedNote = ( type ScrollToFocusedNoteOptions = {
noteId: string | null = null, noteId?: string | null
notes: string[] = stackedNotes.value, notes?: string[]
hash?: string hash?: string
) => { smoothHash?: boolean
}
const scrollToFocusedNote = ({
noteId = null,
notes = stackedNotes.value,
hash,
smoothHash = false
}: ScrollToFocusedNoteOptions = {}) => {
nextTick(() => { nextTick(() => {
const index = noteId ? notes.findIndex((nid) => nid === noteId) : 0 const index = noteId ? notes.findIndex((nid) => nid === noteId) : 0
@@ -72,7 +85,7 @@ export const useRouteQueryStackedNotes = () => {
} }
if (hash && noteId) { if (hash && noteId) {
scrollToHashInNote(noteId.replaceAll(":", "-"), hash) scrollToHashInNote(noteId.replaceAll(":", "-"), hash, smoothHash)
} }
}) })
} }
@@ -84,7 +97,11 @@ export const useRouteQueryStackedNotes = () => {
hash?: string hash?: string
) => { ) => {
if (stackedNotes.value.includes(sha)) { if (stackedNotes.value.includes(sha)) {
scrollToFocusedNote(selector ?? sha, stackedNotes.value, hash) scrollToFocusedNote({
noteId: selector ?? sha,
hash,
smoothHash: true
})
return return
} }
@@ -104,7 +121,7 @@ export const useRouteQueryStackedNotes = () => {
stackedNotes.value = newStackedNotes stackedNotes.value = newStackedNotes
} }
scrollToFocusedNote(selector ?? sha, stackedNotes.value, hash) scrollToFocusedNote({ noteId: selector ?? sha, hash })
} }
return { return {