diff --git a/app/src/protyle/util/compatibility.ts b/app/src/protyle/util/compatibility.ts
index 021658c42..2114532a5 100644
--- a/app/src/protyle/util/compatibility.ts
+++ b/app/src/protyle/util/compatibility.ts
@@ -154,7 +154,13 @@ export const getLocalStorage = (cb: () => void) => {
row: "",
layout: 0,
method: 0,
- types: [".txt", ".md", ".docx", ".xlsx", ".pptx"],
+ types: {
+ ".txt": true,
+ ".md": true,
+ ".docx": true,
+ ".xlsx": true,
+ ".pptx": true,
+ },
sort: 0,
k: "",
};
diff --git a/app/src/search/assets.ts b/app/src/search/assets.ts
index efd7bd36f..6144ae351 100644
--- a/app/src/search/assets.ts
+++ b/app/src/search/assets.ts
@@ -1,8 +1,10 @@
import {Constants} from "../constants";
import {fetchPost} from "../util/fetch";
+import {upDownHint} from "../util/upDownHint";
+import {escapeHtml} from "../util/escape";
export const openSearchAsset = (element: HTMLElement, isStick: boolean) => {
- const localSearch = window.siyuan.storage[Constants.LOCAL_SEARCHASSET]
+ const localSearch = window.siyuan.storage[Constants.LOCAL_SEARCHASSET] as ISearchAssetOption
let methodText = window.siyuan.languages.keyword;
if (localSearch.method === 1) {
methodText = window.siyuan.languages.querySyntax;
@@ -18,10 +20,10 @@ export const openSearchAsset = (element: HTMLElement, isStick: boolean) => {
-
-
+
+
-
+
@@ -56,7 +58,7 @@ export const openSearchAsset = (element: HTMLElement, isStick: boolean) => {
@@ -67,18 +69,133 @@ export const openSearchAsset = (element: HTMLElement, isStick: boolean) => {
`
element.previousElementSibling.classList.add("fn__none");
element.classList.remove("fn__none")
- if (element.querySelector("#searchList").innerHTML !== "") {
+ const searchPanelElement = element.querySelector("#searchAssetList");
+ if (element.querySelector("#searchAssetList").innerHTML !== "") {
return
}
+ const searchInputElement = element.querySelector("#searchAssetInput") as HTMLInputElement
+ searchInputElement.addEventListener("compositionend", (event: InputEvent) => {
+ if (event.isComposing) {
+ return;
+ }
+ inputEvent(localSearch, element, 1);
+ });
+ searchInputElement.addEventListener("input", (event: InputEvent) => {
+ if (event.isComposing) {
+ return;
+ }
+ inputEvent(localSearch, element, 1);
+ });
+ searchInputElement.addEventListener("blur", () => {
+ // saveKeyList("keys", searchInputElement.value);
+ });
+ const historyElement = element.querySelector("#searchAssetHistoryList")
+ const lineHeight = 30;
+ searchInputElement.addEventListener("keydown", (event: KeyboardEvent) => {
+ let currentList: HTMLElement = searchPanelElement.querySelector(".b3-list-item--focus");
+ if (!currentList || event.isComposing) {
+ return;
+ }
+ const isHistory = !historyElement.classList.contains("fn__none");
+ if (event.key === "Enter") {
+ if (!isHistory) {
+ // TODO open folder
+ } else {
+ searchInputElement.value = historyElement.querySelector(".b3-list-item--focus").textContent.trim();
+ inputEvent(localSearch, element, 1);
+ toggleSearchHistory(historyElement, searchInputElement);
+ }
+ event.preventDefault();
+ }
+ if (event.key === "ArrowDown" && event.altKey) {
+ toggleSearchHistory(historyElement, searchInputElement);
+ return;
+ }
+ if (isHistory) {
+ if (event.key === "Escape") {
+ toggleSearchHistory(historyElement, searchInputElement);
+ } else {
+ upDownHint(historyElement, event);
+ }
+ event.stopPropagation();
+ event.preventDefault();
+ return;
+ }
+ if (!isHistory) {
+ return;
+ }
+ if (event.key === "ArrowDown") {
+ currentList.classList.remove("b3-list-item--focus");
+ if (!currentList.nextElementSibling) {
+ searchPanelElement.firstElementChild.classList.add("b3-list-item--focus");
+ } else {
+ currentList.nextElementSibling.classList.add("b3-list-item--focus");
+ }
+ currentList = searchPanelElement.querySelector(".b3-list-item--focus");
+ if (searchPanelElement.scrollTop < currentList.offsetTop - searchPanelElement.clientHeight + lineHeight ||
+ searchPanelElement.scrollTop > currentList.offsetTop) {
+ searchPanelElement.scrollTop = currentList.offsetTop - searchPanelElement.clientHeight + lineHeight;
+ }
+ event.preventDefault();
+ } else if (event.key === "ArrowUp") {
+ currentList.classList.remove("b3-list-item--focus");
+ if (!currentList.previousElementSibling) {
+ searchPanelElement.lastElementChild.classList.add("b3-list-item--focus");
+ } else {
+ currentList.previousElementSibling.classList.add("b3-list-item--focus");
+ }
+ currentList = searchPanelElement.querySelector(".b3-list-item--focus");
+ if (searchPanelElement.scrollTop < currentList.offsetTop - searchPanelElement.clientHeight + lineHeight ||
+ searchPanelElement.scrollTop > currentList.offsetTop - lineHeight * 2) {
+ searchPanelElement.scrollTop = currentList.offsetTop - lineHeight * 2;
+ }
+ event.preventDefault();
+ }
+ });
+ inputEvent(localSearch, element);
+}
+
+const inputEvent = (localSearch: ISearchAssetOption, element: Element, page = 1) => {
+ const searchInputElement = element.querySelector("#searchAssetInput") as HTMLInputElement
fetchPost("/api/search/fullTextSearchAssetContent", {
- page: 1,
- query: localSearch.k,
+ page,
+ query: searchInputElement.value,
types: localSearch.types,
method: localSearch.method,
orderBy: localSearch.sort
}, (response) => {
- loadingElement.classList.remove("fn__none")
+ element.nextElementSibling.classList.add("fn__none")
console.log(response)
})
}
+
+
+export const reIndexAssets = (loadingElement: HTMLElement) => {
+ loadingElement.classList.remove("fn__none")
+ fetchPost("/api/asset/fullReindexAssetContent", {}, (response) => {
+ loadingElement.classList.add("fn__none")
+ })
+}
+
+const toggleSearchHistory = (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");
+ }
+};
diff --git a/app/src/search/util.ts b/app/src/search/util.ts
index 12f1ca36e..04952db40 100644
--- a/app/src/search/util.ts
+++ b/app/src/search/util.ts
@@ -19,7 +19,7 @@ import {matchHotKey} from "../protyle/util/hotKey";
import {filterMenu, getKeyByLiElement, initCriteriaMenu, moreMenu, queryMenu, saveCriterion} from "./menu";
import {App} from "../index";
import {upDownHint} from "../util/upDownHint";
-import {openSearchAsset} from "./assets";
+import {openSearchAsset, reIndexAssets} from "./assets";
const toggleReplaceHistory = (replaceHistoryElement: Element, historyElement: Element, replaceInputElement: HTMLInputElement) => {
if (replaceHistoryElement.classList.contains("fn__none")) {
@@ -642,6 +642,11 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo
event.stopPropagation();
event.preventDefault();
break;
+ } else if (type === "reindexAssets") {
+ reIndexAssets(element.querySelector(".fn__loading--top"));
+ event.stopPropagation();
+ event.preventDefault();
+ break;
} else if (target.id === "replaceBtn") {
replace(element, config, edit, false);
event.stopPropagation();
diff --git a/app/src/types/index.d.ts b/app/src/types/index.d.ts
index c143d1de9..8969a37c3 100644
--- a/app/src/types/index.d.ts
+++ b/app/src/types/index.d.ts
@@ -142,6 +142,23 @@ interface IPluginSettingOption {
createActionElement?(): HTMLElement
}
+interface ISearchAssetOption {
+ keys: string[],
+ col: string,
+ row: string,
+ layout: number,
+ method: number,
+ types: {
+ ".txt": boolean,
+ ".md": boolean,
+ ".docx": boolean,
+ ".xlsx": boolean,
+ ".pptx": boolean,
+ },
+ sort: number,
+ k: string,
+}
+
interface ISearchOption {
page: number
removed?: boolean // 移除后需记录搜索内容 https://github.com/siyuan-note/siyuan/issues/7745