diff --git a/plugin.json b/plugin.json index 5f051b9..fc63bc8 100644 --- a/plugin.json +++ b/plugin.json @@ -2,7 +2,7 @@ "name": "syplugin-dual-doc-list", "author": "Misuzu2027", "url": "https://github.com/Misuzu2027/syplugin-dual-doc-list", - "version": "0.0.9", + "version": "0.0.10", "minAppVersion": "3.0.12", "backends": [ "all" diff --git a/src/components/doc-list/doc-list.svelte b/src/components/doc-list/doc-list.svelte index 244a93d..df8d29a 100644 --- a/src/components/doc-list/doc-list.svelte +++ b/src/components/doc-list/doc-list.svelte @@ -23,7 +23,7 @@ } from "@/service/search/search-util"; import { convertIconInIal } from "@/utils/icon-util"; import { SETTING_DOCUMENT_LIST_SORT_METHOD_ELEMENT } from "@/models/setting-constant"; - import { isArrayEmpty } from "@/utils/array-util"; + import { isArrayEmpty, isArrayNotEmpty } from "@/utils/array-util"; import { isStrBlank, isStrNotBlank, @@ -32,7 +32,7 @@ import { createDoc, getBlockByID, getDocInfo } from "@/utils/api"; import { SiyuanConstants } from "@/models/siyuan-constant"; import { - clearSyFileTreeItemFocus, + clearSyFileTreeItemFocusClass, convertNumberToSordMode, getParentPath, } from "@/utils/siyuan-util"; @@ -58,7 +58,8 @@ let lockPath: boolean = false; let lockSortOrder: boolean = false; - let showSubDocOfSubDoc: boolean = false; + let localShowSubDocOfSubDoc: boolean = false; + let localFullTextSearch: boolean = false; let showCurPath = "/"; let curPathNotebookId: string; @@ -70,8 +71,7 @@ let waitRefreshSelectDocId: string = null; onMount(async () => { - showSubDocOfSubDoc = - SettingService.ins.SettingConfig.showSubDocOfSubDoc; + initData(); initEvent(); initSiyuanEventBus(); switchPath(null, null, null); @@ -81,6 +81,11 @@ destorySiyuanEventBus(); }); + function initData() { + let settingConfig = SettingService.ins.SettingConfig; + localShowSubDocOfSubDoc = settingConfig.showSubDocOfSubDoc; + localFullTextSearch = settingConfig.fullTextSearch; + } function initEvent() { rootElement.addEventListener("mousedown", () => { window.siyuan.menus.menu.remove(); @@ -490,12 +495,13 @@ if (lastOpenBlockId == blockId) { previewProtyleMatchFocusIndex++; } else { - previewProtyleMatchFocusIndex = 0; + previewProtyleMatchFocusIndex = -1; } lastOpenBlockId = blockId; + // 优化定位,搜索出来打开,第一次打开不定位,这样默认会是上一次的界面,防止一点开就定位到开头。 // 如果被查找节点不是聚焦状态,节点文档是当前查看文档,节点的文档element 存在,文档element 包含查找的节点 let activeDocTab = getActiveTab(); - if (activeDocTab) { + if (isArrayNotEmpty(lastKeywords) && activeDocTab) { let activeDocContentElement = activeDocTab.querySelector( "div.protyle-content", ) as HTMLElement; @@ -508,15 +514,14 @@ lastKeywords, previewProtyleMatchFocusIndex, ); - - matchFocusRangePromise.then((focusRange) => { - renderNextSearchMarkByRange(focusRange); - }); - + if (previewProtyleMatchFocusIndex >= 0) { + matchFocusRangePromise.then((focusRange) => { + renderNextSearchMarkByRange(focusRange); + }); + } return; } } - let docTabPromise: Promise = openTab({ app: EnvConfig.ins.app, doc: { @@ -663,7 +668,12 @@ } async function switchShowSubDocOfSubDoc() { - showSubDocOfSubDoc = !showSubDocOfSubDoc; + localShowSubDocOfSubDoc = !localShowSubDocOfSubDoc; + refreshDocList(); + } + + async function switchFullTextSearch() { + localFullTextSearch = !localFullTextSearch; refreshDocList(); } @@ -708,9 +718,10 @@ searchKey: string, docSortMethod: DocumentSortMode, ) { - let settingConfig = SettingService.ins.SettingConfig; - let showSubDocuments = showSubDocOfSubDoc; - let fullTextSearch = settingConfig.fullTextSearch; + // let settingConfig = SettingService.ins.SettingConfig; + let showSubDocuments = localShowSubDocOfSubDoc; + let fullTextSearch = localFullTextSearch; + // let fullTextSearch = settingConfig.fullTextSearch; let keywords = splitKeywordStringToArray(searchKey); waitRefreshByDatabase = false; @@ -764,7 +775,7 @@ docPath, keywords, showSubDocuments, - fullTextSearch, + localFullTextSearch, docSortMethod, ).then((docTreeInfoArray) => { documentItems = docTreeInfoArray; @@ -872,21 +883,20 @@ function handleKeyDownDefault() {} async function afterOpenDocTab(docTabPromise: Promise) { + if (isArrayEmpty(lastKeywords)) { + return; + } + previewProtyleMatchFocusIndex = -1; let docTab = await docTabPromise; - // console.log("afterOpenDocTab"); let lastDocumentContentElement = docTab.panelElement .children[1] as HTMLElement; delayedTwiceRefresh(() => { - let matchFocusRangePromise = highlightElementTextByCss( + highlightElementTextByCss( lastDocumentContentElement, lastKeywords, - 0, + null, ); - - matchFocusRangePromise.then((focusRange) => { - renderFirstSearchMarkByRange(focusRange); - }); }, 50); } @@ -913,7 +923,7 @@ .forEach((item) => { item.remove(); }); - clearSyFileTreeItemFocus(); + clearSyFileTreeItemFocusClass(); // 下面全抄官方的,把 this.element 换成了 rootElement // https://github.com/siyuan-note/siyuan/blob/f3b0ee51d5fb505c852c7378ba85776d15e22b86/app/src/layout/dock/Files.ts#L371 @@ -989,7 +999,7 @@ } function localIsQueryDocByPathApi(): boolean { - let showSubDocuments = showSubDocOfSubDoc; + let showSubDocuments = localShowSubDocOfSubDoc; let fullTextSearch = SettingService.ins.SettingConfig.fullTextSearch; return isQueryDocByPathApi( @@ -1004,6 +1014,8 @@ + +
+ + +
@@ -1269,15 +1311,27 @@ // box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); /* 添加阴影效果 */ } - .block__icon { - padding: 4px 1px; - } - label.block__icon span.fn__space { - width: 4px; + // .block__icon { + // padding: 4px 1px; + // } + // label.block__icon span.fn__space { + // width: 4px; + // } + + .misuzu2027__doc-list label.label-selected { + // border: 1px solid #66ccff; rgba(102, 204, 255, 0.5) + // box-shadow: inset 0 0 5px 2px var(--b3-theme-primary-light); + background-color: var(--b3-theme-primary-light); + transition: box-shadow 0.5s ease-in-out; } .b3-switch:hover:not(:disabled):before, .b3-switch:focus:not(:disabled):before { content: none; } + + .misuzu2027__doc-list .flat_doc_tree--top .block__icon svg { + height: 14px; + width: 14px; + } diff --git a/src/models/icon-constant.ts b/src/models/icon-constant.ts index b879145..dcd59f5 100644 --- a/src/models/icon-constant.ts +++ b/src/models/icon-constant.ts @@ -9,11 +9,15 @@ export const CUSTOM_ICON_MAP = }, iconShowSubDoc: { id: "iconShowSubDoc", - source: ` + source: ` + + + ` + /* - ` + */ }, iconLockPath: { id: "iconLockPath", @@ -31,6 +35,13 @@ export const CUSTOM_ICON_MAP = ` }, + iconFullTextSearch: { + id: "iconFullTextSearch", + source: ` + + + ` + } }; \ No newline at end of file diff --git a/src/service/doc-list/DocListManager.ts b/src/service/doc-list/DocListManager.ts index 183595c..36022d9 100644 --- a/src/service/doc-list/DocListManager.ts +++ b/src/service/doc-list/DocListManager.ts @@ -6,7 +6,7 @@ import { SettingConfig } from "@/models/setting-model"; import { SettingService } from "@/service/setting/SettingService"; import { findParentElementWithAttribute, getAttributeRecursively } from "@/utils/html-util"; import Instance from "@/utils/Instance"; -import { clearSyFileTreeItemFocus, isElementHidden } from "@/utils/siyuan-util"; +import { clearSyFileTreeItemFocusClass, isElementHidden } from "@/utils/siyuan-util"; const EmbedDualDocListElementAttrName = "data-misuzu2027-embed-dualDocList"; @@ -178,7 +178,7 @@ export class DocListManager { } // 如果是笔记本,判断一下是否启用双击切换文档折叠。 if (targetLiElementType == "navigation-root") { - if (this.handleNotebookDoubleClick(event)) { + if (this.handleNotebookDoubleClick(event, targetLiElement)) { return; } } @@ -187,7 +187,7 @@ export class DocListManager { } // return : 是否双击 - private handleNotebookDoubleClick(event: MouseEvent): boolean { + private handleNotebookDoubleClick(event: MouseEvent, targetLiElement: HTMLElement): boolean { let settingConfig = SettingService.ins.SettingConfig; if (!settingConfig || !settingConfig.doubleClickToggleNotebook) { return false; @@ -200,6 +200,8 @@ export class DocListManager { setTimeout(() => { this.clickCount = 0; }, doubleClickTimeout); + clearSyFileTreeItemFocusClass(); + targetLiElement.classList.add("b3-list-item--focus"); return false; } return true; @@ -278,7 +280,7 @@ function getDragElement(): HTMLElement { if (!fileTreeDocElement || !docListElement) { return; } - clearSyFileTreeItemFocus(); + clearSyFileTreeItemFocusClass(); startX = e.clientX; // 获取当前 flex-item 的初始宽度 startWidth = docListElement.offsetWidth; diff --git a/src/utils/html-util.ts b/src/utils/html-util.ts index 12553d9..1049930 100644 --- a/src/utils/html-util.ts +++ b/src/utils/html-util.ts @@ -1,4 +1,5 @@ import { isArrayEmpty } from "./array-util"; +import { isNumberValid } from "./number-util"; import { isStrBlank } from "./string-util"; export const escapeAttr = (html: string) => { @@ -13,14 +14,14 @@ export function escapeHTML(html: string): string { let start = 0; let i = 0; let inited = false; - + let ret: Uint8Array | string = html; - + const amp = new TextEncoder().encode('&'); const lt = new TextEncoder().encode('<'); const gt = new TextEncoder().encode('>'); const quot = new TextEncoder().encode('"'); - + const htmlBytes = new TextEncoder().encode(html); for (; i < length; i++) { @@ -165,8 +166,10 @@ export async function highlightElementTextByCss( return; } let matchFocusRange: Range; - let nextMatchIndexRemainder = - nextMatchFocusIndex % targetElementMatchRanges.length; + let nextMatchIndexRemainder = null; + if (isNumberValid(nextMatchFocusIndex) && targetElementMatchRanges.length > 0) { + nextMatchIndexRemainder = nextMatchFocusIndex % targetElementMatchRanges.length; + } for (let i = 0; i < targetElementMatchRanges.length; i++) { if (i == nextMatchIndexRemainder) { matchFocusRange = targetElementMatchRanges[i]; @@ -174,6 +177,7 @@ export async function highlightElementTextByCss( } } + allMatchRanges = allMatchRanges.filter( (obj) => obj !== matchFocusRange, ); diff --git a/src/utils/siyuan-util.ts b/src/utils/siyuan-util.ts index 391b6ea..662c4e4 100644 --- a/src/utils/siyuan-util.ts +++ b/src/utils/siyuan-util.ts @@ -383,7 +383,7 @@ export function getParentPath(path: string): string { -export function clearSyFileTreeItemFocus() { +export function clearSyFileTreeItemFocusClass() { document .querySelector("div.file-tree.sy__file") .querySelectorAll("li.b3-list-item--focus")