From 04b4be88168e0b3a89783ad4a8b0154e3728848f Mon Sep 17 00:00:00 2001 From: SiriusXT <1160925501@qq.com> Date: Wed, 13 Aug 2025 15:41:31 +0800 Subject: [PATCH] Fix: activate the nearest path when opening a cloned note --- apps/client/src/entities/fnote.ts | 24 +++++++++++++++++++++--- apps/client/src/services/tree.ts | 4 ++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/apps/client/src/entities/fnote.ts b/apps/client/src/entities/fnote.ts index 6099cba35..c459515c6 100644 --- a/apps/client/src/entities/fnote.ts +++ b/apps/client/src/entities/fnote.ts @@ -416,7 +416,7 @@ class FNote { return notePaths; } - getSortedNotePathRecords(hoistedNoteId = "root"): NotePathRecord[] { + getSortedNotePathRecords(hoistedNoteId = "root", activeNotePath: string | null = null): NotePathRecord[] { const isHoistedRoot = hoistedNoteId === "root"; const notePaths: NotePathRecord[] = this.getAllNotePaths().map((path) => ({ @@ -427,7 +427,24 @@ class FNote { isHidden: path.includes("_hidden") })); + // Calculate the length of the prefix match between two arrays + const prefixMatchLength = (path: string[], target: string[]) => + path.findIndex((seg, i) => seg !== target[i]) === -1 + ? Math.min(path.length, target.length) + : path.findIndex((seg, i) => seg !== target[i]); + notePaths.sort((a, b) => { + if (activeNotePath){ + const activeSegments = activeNotePath.split('/'); + const aOverlap = prefixMatchLength(a.notePath, activeSegments); + const bOverlap = prefixMatchLength(b.notePath, activeSegments); + + // Paths with more matching prefix segments are prioritized + // when the match count is equal, other criteria are used for sorting + if (bOverlap !== aOverlap) { + return bOverlap - aOverlap; + } + } if (a.isInHoistedSubTree !== b.isInHoistedSubTree) { return a.isInHoistedSubTree ? -1 : 1; } else if (a.isArchived !== b.isArchived) { @@ -448,10 +465,11 @@ class FNote { * Returns the note path considered to be the "best" * * @param {string} [hoistedNoteId='root'] + * @param {string|null} [activeNotePath=null] * @return {string[]} array of noteIds constituting the particular note path */ - getBestNotePath(hoistedNoteId = "root") { - return this.getSortedNotePathRecords(hoistedNoteId)[0]?.notePath; + getBestNotePath(hoistedNoteId = "root", activeNotePath: string | null = null) { + return this.getSortedNotePathRecords(hoistedNoteId, activeNotePath)[0]?.notePath; } /** diff --git a/apps/client/src/services/tree.ts b/apps/client/src/services/tree.ts index c508654f5..743d0c79d 100644 --- a/apps/client/src/services/tree.ts +++ b/apps/client/src/services/tree.ts @@ -79,8 +79,8 @@ async function resolveNotePathToSegments(notePath: string, hoistedNoteId = "root You can ignore this message as it is mostly harmless.` ); } - - const bestNotePath = child.getBestNotePath(hoistedNoteId); + const activeNotePath = appContext.tabManager.getActiveContextNotePath(); + const bestNotePath = child.getBestNotePath(hoistedNoteId, activeNotePath); if (bestNotePath) { const pathToRoot = bestNotePath.reverse().slice(1);