This commit is contained in:
Vanessa 2023-08-20 23:28:35 +08:00
parent 6172a5f892
commit 4d445250f9
6 changed files with 173 additions and 18 deletions

View file

@ -25,6 +25,7 @@
@import "business/card";
@import "business/custom";
@import "business/av";
@import "business/search";
.block__popover {
width: 80vw;

View file

@ -15,6 +15,15 @@ import {showMessage} from "../../dialog/message";
import {reloadProtyle} from "../../protyle/util/reload";
import {activeBlur, hideKeyboardToolbar} from "../util/keyboardToolbar";
import {App} from "../../index";
import {
assetFilterMenu,
assetInputEvent,
assetMethodMenu, assetMoreMenu,
renderNextAssetMark,
renderPreview,
toggleAssetHistory
} from "../../search/assets";
import {getQueryTip} from "../../search/util";
const replace = (element: Element, config: ISearchOption, isAll: boolean) => {
if (config.method === 1 || config.method === 2) {
@ -193,9 +202,9 @@ ${unicode2Emoji(childItem.ial.icon, "b3-list-item__graphic", true)}
listElement.scrollTop = 0;
let countHTML = "";
if (response) {
countHTML = `${window.siyuan.languages.findInDoc.replace("${x}", response.data.matchedRootCount).replace("${y}", response.data.matchedBlockCount)}
countHTML = `<span class="fn__flex-center">${window.siyuan.languages.findInDoc.replace("${x}", response.data.matchedRootCount).replace("${y}", response.data.matchedBlockCount)}</span>
<span class="fn__flex-1"></span>
${config.page}/${response.data.pageCount || 1}`;
<span class="fn__flex-center">${config.page}/${response.data.pageCount || 1}</span>`;
}
listElement.previousElementSibling.querySelector('[data-type="result"]').innerHTML = countHTML;
};
@ -279,7 +288,9 @@ const initSearchEvent = (app: App, element: Element, config: ISearchOption) => {
const criteriaData: ISearchOption[] = [];
initCriteriaMenu(element.querySelector("#criteria"), criteriaData, config);
const assetsElement = document.querySelector("#searchAssetsPanel")
const searchListElement = element.querySelector("#searchList") as HTMLElement;
const localSearch = window.siyuan.storage[Constants.LOCAL_SEARCHASSET] as ISearchAssetOption;
element.addEventListener("click", (event: MouseEvent) => {
let target = event.target as HTMLElement;
while (target && !target.isSameNode(element)) {
@ -485,6 +496,51 @@ const initSearchEvent = (app: App, element: Element, config: ISearchOption) => {
event.stopPropagation();
event.preventDefault();
break;
} else if (type === "queryAsset") {
assetMethodMenu(target, () => {
assetInputEvent(assetsElement, localSearch);
setStorageVal(Constants.LOCAL_SEARCHASSET, localSearch);
});
event.stopPropagation();
event.preventDefault();
break;
} else if (type === "filterAsset") {
assetFilterMenu(assetsElement);
event.stopPropagation();
event.preventDefault();
break;
} else if (type === "moreAsset") {
assetMoreMenu(target, assetsElement, () => {
assetInputEvent(assetsElement);
setStorageVal(Constants.LOCAL_SEARCHASSET, localSearch);
});
event.stopPropagation();
event.preventDefault();
break;
} else if (type === "goAsset") {
goAsset();
event.stopPropagation();
event.preventDefault();
break;
} else if (type === "goSearch") {
assetsElement.classList.add("fn__none");
event.stopPropagation();
event.preventDefault();
break;
} else if (type === "assetPrevious") {
if (!target.getAttribute("disabled")) {
assetInputEvent(assetsElement, localSearch, parseInt(assetsElement.querySelector("#searchAssetResult .fn__flex-center").textContent.split("/")[1]) - 1);
}
event.stopPropagation();
event.preventDefault();
break;
} else if (type === "assetNext") {
if (!target.getAttribute("disabled")) {
assetInputEvent(assetsElement, localSearch, parseInt(assetsElement.querySelector("#searchAssetResult .fn__flex-center").textContent.split("/")[1]) + 1);
}
event.stopPropagation();
event.preventDefault();
break;
} else if (type === "replace") {
replace(element, config, false);
event.stopPropagation();
@ -501,13 +557,23 @@ const initSearchEvent = (app: App, element: Element, config: ISearchOption) => {
newFileByName(app, searchInputElement.value);
} else if (target.getAttribute("data-type") === "search-item") {
const id = target.getAttribute("data-node-id");
if (window.siyuan.mobile.editor.protyle) {
preventScroll(window.siyuan.mobile.editor.protyle);
if (id) {
if (window.siyuan.mobile.editor.protyle) {
preventScroll(window.siyuan.mobile.editor.protyle);
}
fetchPost("/api/block/checkBlockFold", {id}, (foldResponse) => {
openMobileFileById(app, id, foldResponse.data ? [Constants.CB_GET_ALL, Constants.CB_GET_HL] : [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]);
});
closePanel();
} else {
if (!target.classList.contains("b3-list-item--focus")) {
element.querySelector("#searchAssetList .b3-list-item--focus").classList.remove("b3-list-item--focus");
target.classList.add("b3-list-item--focus");
renderPreview(element.querySelector("#searchAssetPreview"), target.dataset.id, (element.querySelector("#searchAssetInput") as HTMLInputElement).value, window.siyuan.storage[Constants.LOCAL_SEARCHASSET].method);
} else if (target.classList.contains("b3-list-item--focus")) {
renderNextAssetMark(element.querySelector("#searchAssetPreview"));
}
}
fetchPost("/api/block/checkBlockFold", {id}, (foldResponse) => {
openMobileFileById(app, id, foldResponse.data ? [Constants.CB_GET_ALL, Constants.CB_GET_HL] : [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]);
});
closePanel();
} else if (target.querySelector(".b3-list-item__toggle")) {
target.nextElementSibling.classList.toggle("fn__none");
target.firstElementChild.firstElementChild.classList.toggle("b3-list-item__arrow--open");
@ -574,8 +640,35 @@ export const popSearch = (app: App, config = window.siyuan.storage[Constants.LOC
<svg data-type="expand" class="toolbar__icon${config.group === 0 ? " fn__none" : ""}"><use xlink:href="#iconExpand"></use></svg>
<svg data-type="contract" class="toolbar__icon${config.group === 0 ? " fn__none" : ""}"><use xlink:href="#iconContract"></use></svg>
<svg data-type="more" class="toolbar__icon"><use xlink:href="#iconMore"></use></svg>
<svg data-type="goAsset" class="toolbar__icon"><use xlink:href="#iconExact"></use></svg>
<span class="fn__flex-1"></span>
</div>
<div class="fn__none fn__flex-column" style="position: fixed;top: 0;width: 100%;background: var(--b3-theme-surface);height: 100%;" id="searchAssetsPanel">
<div class="toolbar toolbar--border">
<svg class="toolbar__icon"><use xlink:href="#iconSearch"></use></svg>
<span class="toolbar__text"><input id="searchAssetInput" placeholder="${window.siyuan.languages.keyword}" class="toolbar__title fn__block"></span>
<svg class="toolbar__icon" data-type="goSearch">
<use xlink:href="#iconCloseRound"></use>
</svg>
</div>
<div class="toolbar">
<span class="fn__space"></span>
<span id="searchAssetResult" class="fn__flex-1 fn__flex"><span class="fn__flex-1"></span></span>
<span class="fn__space"></span>
<svg data-type="assetPrevious" disabled="disabled" class="toolbar__icon"><use xlink:href="#iconLeft"></use></svg>
<svg data-type="assetNext" disabled="disabled" class="toolbar__icon"><use xlink:href="#iconRight"></use></svg>
</div>
<div id="searchAssetList" style="overflow:auto;" class="fn__flex-1 b3-list b3-list--background"></div>
<div id="searchAssetPreview" class="fn__flex-1 search__preview b3-typography" style="padding: 8px;border-bottom: 1px solid var(--b3-border-color);"></div>
<div class="toolbar">
<span class="fn__flex-1"></span>
<svg data-type="queryAsset" class="toolbar__icon"><use xlink:href="#iconRegex"></use></svg>
<svg data-type="filterAsset" class="toolbar__icon"><use xlink:href="#iconFilter"></use></svg>
<svg data-type="moreAsset" class="toolbar__icon"><use xlink:href="#iconMore"></use></svg>
<svg data-type="goSearch" class="toolbar__icon"><use xlink:href="#iconBack"></use></svg>
<span class="fn__flex-1"></span>
</div>
</div>
<div class="fn__loading fn__loading--top"><img width="120px" src="/stage/loading-pure.svg"></div>
</div>`,
bindEvent(element) {
@ -584,3 +677,28 @@ export const popSearch = (app: App, config = window.siyuan.storage[Constants.LOC
}
});
};
const goAsset = () => {
const assetsElement = document.querySelector("#searchAssetsPanel")
assetsElement.classList.remove("fn__none")
const listElement = assetsElement.querySelector("#searchAssetList")
if (listElement.innerHTML) {
return
}
const localSearch = window.siyuan.storage[Constants.LOCAL_SEARCHASSET] as ISearchAssetOption;
const inputElement = assetsElement.querySelector("input")
inputElement.value = localSearch.k;
inputElement.addEventListener("compositionend", (event: InputEvent) => {
if (event.isComposing) {
return;
}
assetInputEvent(assetsElement, localSearch);
});
inputElement.addEventListener("input", (event: InputEvent) => {
if (event.isComposing) {
return;
}
assetInputEvent(assetsElement, localSearch);
});
assetInputEvent(assetsElement, localSearch);
}

View file

@ -123,7 +123,11 @@ export const goBack = () => {
window.siyuan.menus.menu.element.dispatchEvent(new CustomEvent("click", {detail: "back"}));
return;
} else if (document.getElementById("model").style.transform === "translateY(0px)") {
document.getElementById("model").style.transform = "";
if (document.getElementById("searchAssetsPanel").classList.contains("fn__none")) {
document.getElementById("model").style.transform = "";
} else {
document.getElementById("searchAssetsPanel").classList.add("fn__none");
}
return;
} else if (window.siyuan.viewer && !window.siyuan.viewer.destroyed) {
window.siyuan.viewer.destroy();

View file

@ -7,11 +7,14 @@ import {fetchPost} from "../util/fetch";
import {upDownHint} from "../util/upDownHint";
import {escapeHtml} from "../util/escape";
import {setStorageVal} from "../protyle/util/compatibility";
/// #if !MOBILE
import {getQueryTip} from "./util";
/// #endif
import {MenuItem} from "../menus/Menu";
import {Dialog} from "../dialog";
export const openSearchAsset = (element: Element, isStick: boolean) => {
/// #if !MOBILE
window.siyuan.menus.menu.remove();
element.previousElementSibling.classList.add("fn__none");
element.classList.remove("fn__none");
@ -224,6 +227,7 @@ export const openSearchAsset = (element: Element, isStick: boolean) => {
setStorageVal(Constants.LOCAL_SEARCHASSET, window.siyuan.storage[Constants.LOCAL_SEARCHASSET]);
};
});
/// #endif
};
let inputTimeout: number;
@ -250,7 +254,6 @@ export const assetInputEvent = (element: Element, localSearch?: ISearchAssetOpti
}, (response) => {
element.nextElementSibling.classList.add("fn__none");
const nextElement = element.querySelector('[data-type="assetNext"]');
const previewElement = element.querySelector("#searchAssetPreview");
if (page < response.data.pageCount) {
nextElement.removeAttribute("disabled");
} else {
@ -273,15 +276,16 @@ export const assetInputEvent = (element: Element, localSearch?: ISearchAssetOpti
<span class="b3-list-item__meta b3-list-item__meta--ellipsis b3-tooltips__w b3-tooltips" aria-label="${item.path}">${item.name}</span>
</div>`;
});
const previewElement = element.querySelector("#searchAssetPreview");
if (response.data.assetContents.length > 0) {
previewElement.classList.remove("fn__none");
element.querySelector(".search__drag").classList.remove("fn__none");
element.querySelector(".search__drag")?.classList.remove("fn__none");
renderPreview(previewElement, response.data.assetContents[0].id, searchInputElement.value, localSearch.method);
} else {
previewElement.classList.add("fn__none");
element.querySelector(".search__drag").classList.add("fn__none");
element.querySelector(".search__drag")?.classList.add("fn__none");
}
element.querySelector("#searchAssetResult").innerHTML = `${page}/${response.data.pageCount || 1}<span class="fn__space"></span>
element.querySelector("#searchAssetResult").innerHTML = `<span class="fn__flex-center">${page}/${response.data.pageCount || 1}</span><span class="fn__space"></span>
<span class="ft__on-surface">${window.siyuan.languages.total} ${response.data.matchedAssetCount}</span>`;
element.querySelector("#searchAssetList").innerHTML = resultHTML || `<div class="search__empty">
${window.siyuan.languages.emptyContent}
@ -314,7 +318,7 @@ export const toggleAssetHistory = (historyElement: Element, searchInputElement:
export const renderPreview = (element: Element, id: string, query: string, queryMethod: number) => {
fetchPost("/api/search/getAssetContent", {id, query, queryMethod}, (response) => {
element.innerHTML = `<p style="white-space: pre;">${response.data.assetContent.content}</p>`;
element.innerHTML = `<p style="white-space: pre-wrap;">${response.data.assetContent.content}</p>`;
const matchElement = element.querySelector("mark");
if (matchElement) {
matchElement.classList.add("mark--hl");
@ -380,8 +384,13 @@ export const assetMethodMenu = (target: HTMLElement, cb: () => void) => {
cb();
}
}).element);
/// #if MOBILE
window.siyuan.menus.menu.element.style.zIndex = "221"
window.siyuan.menus.menu.fullscreen()
/// #else
const rect = target.getBoundingClientRect();
window.siyuan.menus.menu.popup({x: rect.right, y: rect.bottom}, true);
/// #endif
};
const filterTypesHTML = (types: IObject) => {
@ -474,6 +483,7 @@ export const assetMoreMenu = (target: Element, element: Element, cb: () => void)
type: "submenu",
submenu: sortMenu,
}).element);
/// #if !MOBILE
window.siyuan.menus.menu.append(new MenuItem({
iconHTML: Constants.ZWSP,
label: window.siyuan.languages.layout,
@ -514,6 +524,7 @@ export const assetMoreMenu = (target: Element, element: Element, cb: () => void)
}
}]
}).element);
/// #endif
window.siyuan.menus.menu.append(new MenuItem({
iconHTML: Constants.ZWSP,
label: window.siyuan.languages.rebuildIndex,
@ -524,6 +535,11 @@ export const assetMoreMenu = (target: Element, element: Element, cb: () => void)
});
},
}).element);
/// #if MOBILE
window.siyuan.menus.menu.element.style.zIndex = "221"
window.siyuan.menus.menu.fullscreen()
/// #else
const rect = target.getBoundingClientRect();
window.siyuan.menus.menu.popup({x: rect.right, y: rect.bottom}, true);
/// #endif
};

View file

@ -201,6 +201,7 @@ const saveCriterionData = (config: ISearchOption,
fetchPost("/api/storage/setCriterion", {criterion}, () => {
saveDialog.destroy();
const criteriaElement = element.querySelector("#criteria").firstElementChild;
criteriaElement.classList.remove("fn__none");
criteriaElement.querySelector(".b3-chip--current")?.classList.remove("b3-chip--current");
criteriaElement.insertAdjacentHTML("beforeend", `<div data-type="set-criteria" class="b3-chip b3-chip--current b3-chip--middle b3-chip--pointer b3-chip--${["secondary", "primary", "info", "success", "warning", "error", ""][(criteriaElement.childElementCount) % 7]}">${criterion.name}<svg class="b3-chip__close" data-type="remove-criteria"><use xlink:href="#iconCloseRound"></use></svg></div>`);
});

View file

@ -328,6 +328,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo
};
});
const localSearch = window.siyuan.storage[Constants.LOCAL_SEARCHASSET] as ISearchAssetOption;
const assetsElement = element.querySelector("#searchAssets");
element.addEventListener("click", (event: MouseEvent) => {
let target = event.target as HTMLElement;
@ -636,10 +637,24 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo
event.stopPropagation();
event.preventDefault();
break;
} else if (type === "assetPrevious") {
if (!target.getAttribute("disabled")) {
assetInputEvent(assetsElement, localSearch, parseInt(assetsElement.querySelector("#searchAssetResult .fn__flex-center").textContent.split("/")[1]) - 1);
}
event.stopPropagation();
event.preventDefault();
break;
} else if (type === "assetNext") {
if (!target.getAttribute("disabled")) {
assetInputEvent(assetsElement, localSearch, parseInt(assetsElement.querySelector("#searchAssetResult .fn__flex-center").textContent.split("/")[1]) + 1);
}
event.stopPropagation();
event.preventDefault();
break;
} else if (target.id === "assetMore") {
assetMoreMenu(target, assetsElement, () => {
assetInputEvent(assetsElement);
setStorageVal(Constants.LOCAL_SEARCHASSET, window.siyuan.storage[Constants.LOCAL_SEARCHASSET]);
setStorageVal(Constants.LOCAL_SEARCHASSET, localSearch);
});
event.stopPropagation();
event.preventDefault();
@ -651,9 +666,9 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo
break;
} else if (target.id === "assetSyntaxCheck") {
assetMethodMenu(target, () => {
element.querySelector("#assetSyntaxCheck").setAttribute("aria-label", getQueryTip(window.siyuan.storage[Constants.LOCAL_SEARCHASSET].method));
assetInputEvent(assetsElement);
setStorageVal(Constants.LOCAL_SEARCHASSET, window.siyuan.storage[Constants.LOCAL_SEARCHASSET]);
element.querySelector("#assetSyntaxCheck").setAttribute("aria-label", getQueryTip(localSearch.method));
assetInputEvent(assetsElement, localSearch);
setStorageVal(Constants.LOCAL_SEARCHASSET, localSearch);
});
event.stopPropagation();
event.preventDefault();