diff --git a/app/src/boot/globalEvent/searchKeydown.ts b/app/src/boot/globalEvent/searchKeydown.ts index 4d89b1a1b..c8bb6ed2b 100644 --- a/app/src/boot/globalEvent/searchKeydown.ts +++ b/app/src/boot/globalEvent/searchKeydown.ts @@ -63,11 +63,9 @@ export const searchKeydown = (app: App, event: KeyboardEvent) => { return true; } const targetId = (event.target as HTMLElement).id; - const assetHistoryElement = assetsElement.querySelector("#searchAssetHistoryList"); - const assetInputElement = assetsElement.querySelector("#searchAssetInput") as HTMLInputElement; if (event.key === "ArrowDown" && event.altKey) { if (isAsset) { - toggleAssetHistory(assetHistoryElement, assetInputElement); + toggleAssetHistory(assetsElement); } else { if (targetId === "replaceInput") { toggleReplaceHistory(element); diff --git a/app/src/search/assets.ts b/app/src/search/assets.ts index 84c3e39ef..98d0b478b 100644 --- a/app/src/search/assets.ts +++ b/app/src/search/assets.ts @@ -1,12 +1,14 @@ import {Constants} from "../constants"; import {fetchPost} from "../util/fetch"; import {escapeAriaLabel, escapeHtml} from "../util/escape"; -import {setStorageVal} from "../protyle/util/compatibility"; +import {setStorageVal, updateHotkeyTip} from "../protyle/util/compatibility"; /// #if !MOBILE import {getQueryTip} from "./util"; /// #endif import {MenuItem} from "../menus/Menu"; import {Dialog} from "../dialog"; +import {Menu} from "../plugin/Menu"; +import {hasClosestByClassName} from "../protyle/util/hasClosest"; export const openSearchAsset = (element: Element, isStick: boolean) => { /// #if !MOBILE @@ -41,12 +43,11 @@ export const openSearchAsset = (element: Element, isStick: boolean) => {
- + -
@@ -219,26 +220,72 @@ export const assetInputEvent = (element: Element, localSearch?: ISearchAssetOpti }, Constants.TIMEOUT_INPUT); }; -export const toggleAssetHistory = (historyElement: Element, searchInputElement: HTMLInputElement) => { - if (historyElement.classList.contains("fn__none")) { - const keys = window.siyuan.storage[Constants.LOCAL_SEARCHASSET].keys; - if (!keys || keys.length === 0) { - return; - } - let html = ""; - keys.forEach((s: string) => { - if (s !== searchInputElement.value && s) { - html += `
${escapeHtml(s)}
`; - } - }); - if (html === "") { - return; - } - historyElement.classList.remove("fn__none"); - historyElement.innerHTML = html; - } else { - historyElement.classList.add("fn__none"); +export const toggleAssetHistory = (assetElement: Element) => { + const keys = window.siyuan.storage[Constants.LOCAL_SEARCHASSET].keys; + if (!keys || keys.length === 0) { + return; } + const menu = new Menu("search-asset-history"); + if (menu.isOpen) { + return; + } + menu.addItem({ + iconHTML: "", + label: window.siyuan.languages.clearHistory, + click() { + window.siyuan.storage[Constants.LOCAL_SEARCHASSET].keys = []; + setStorageVal(Constants.LOCAL_SEARCHASSET, window.siyuan.storage[Constants.LOCAL_SEARCHASSET]); + } + }); + const separatorElement = menu.addSeparator(1); + let current = true; + const assetInputElement = assetElement.querySelector("#searchAssetInput") as HTMLInputElement; + keys.forEach((s: string) => { + if (s !== assetInputElement.value && s) { + const menuItem = menu.addItem({ + iconHTML: "", + label: escapeHtml(s), + action: "iconCloseRound", + bind(element) { + element.addEventListener("click", (itemEvent) => { + if (hasClosestByClassName(itemEvent.target as Element, "b3-menu__action")) { + keys.find((item: string, index: number) => { + if (item === s) { + keys.splice(index, 1); + return true; + } + }); + window.siyuan.storage[Constants.LOCAL_SEARCHASSET].keys = keys; + setStorageVal(Constants.LOCAL_SEARCHASSET, window.siyuan.storage[Constants.LOCAL_SEARCHASSET]); + if (element.previousElementSibling?.classList.contains("b3-menu__separator") && !element.nextElementSibling) { + window.siyuan.menus.menu.remove(); + } else { + element.remove(); + } + } else { + assetInputElement.value = element.textContent; + assetInputEvent(assetElement); + window.siyuan.menus.menu.remove(); + } + itemEvent.preventDefault(); + itemEvent.stopPropagation(); + }); + } + }); + if (current) { + menuItem.classList.add("b3-menu__item--current"); + } + current = false; + } + }); + if (current) { + separatorElement.remove(); + } + const rect = assetElement.querySelector("#assetHistoryBtn").getBoundingClientRect(); + menu.open({ + x: rect.left, + y: rect.bottom + }); }; export const renderPreview = (element: Element, id: string, query: string, queryMethod: number) => { diff --git a/app/src/search/util.ts b/app/src/search/util.ts index c0536a2d2..da1eadd69 100644 --- a/app/src/search/util.ts +++ b/app/src/search/util.ts @@ -798,7 +798,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo event.preventDefault(); return; } else if (target.id === "assetHistoryBtn") { - toggleAssetHistory(target.nextElementSibling.nextElementSibling, target.nextElementSibling as HTMLInputElement); + toggleAssetHistory(assetsElement); event.stopPropagation(); event.preventDefault(); return; @@ -830,10 +830,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo break; } else if (target.classList.contains("b3-list-item")) { const searchAssetInputElement = element.querySelector("#searchAssetInput") as HTMLInputElement; - if (target.parentElement.id === "searchAssetHistoryList") { - searchAssetInputElement.value = target.textContent; - assetInputEvent(assetsElement); - } else if (type === "search-new") { + if (type === "search-new") { newFileByName(app, searchInputElement.value); } else if (type === "search-item") { const isAsset = target.dataset.id; @@ -926,7 +923,6 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo } target = target.parentElement; } - element.querySelector("#searchAssetHistoryList")?.classList.add("fn__none"); }, false); searchInputElement.addEventListener("compositionend", (event: InputEvent) => {