diff --git a/app/src/mobile/menu/search.ts b/app/src/mobile/menu/search.ts
index 107099c77..da2f99d95 100644
--- a/app/src/mobile/menu/search.ts
+++ b/app/src/mobile/menu/search.ts
@@ -301,6 +301,7 @@ const initSearchEvent = (app: App, element: Element, config: ISearchOption) => {
initCriteriaMenu(element.querySelector("#criteria"), criteriaData, config);
const assetsElement = document.querySelector("#searchAssetsPanel");
+ const unRefElement = document.querySelector("#searchUnRefPanel");
const searchListElement = element.querySelector("#searchList") as HTMLElement;
const localSearch = window.siyuan.storage[Constants.LOCAL_SEARCHASSET] as ISearchAssetOption;
element.addEventListener("click", (event: MouseEvent) => {
@@ -510,6 +511,32 @@ const initSearchEvent = (app: App, element: Element, config: ISearchOption) => {
event.stopPropagation();
event.preventDefault();
break;
+ } else if (type === "refreshUnRef") {
+ getUnRefListMobile(unRefElement);
+ event.stopPropagation();
+ event.preventDefault();
+ break;
+ } else if (type === "unRefPrevious") {
+ if (!target.getAttribute("disabled")) {
+ let currentPage = parseInt(unRefElement.querySelector("#searchUnRefResult").lastElementChild.textContent);
+ if (currentPage > 1) {
+ currentPage--;
+ getUnRefListMobile(unRefElement, currentPage);
+ }
+ }
+ event.stopPropagation();
+ event.preventDefault();
+ break;
+ } else if (type === "unRefNext") {
+ const unRefRageElement = unRefElement.querySelector("#searchUnRefResult").lastElementChild
+ let currentPage = parseInt(unRefRageElement.textContent);
+ if (currentPage < parseInt(unRefRageElement.textContent.split("/")[1])) {
+ currentPage++;
+ getUnRefListMobile(unRefElement, currentPage);
+ }
+ event.stopPropagation();
+ event.preventDefault();
+ break;
} else if (type === "queryAsset") {
assetMethodMenu(target, () => {
assetInputEvent(assetsElement, localSearch);
@@ -538,6 +565,7 @@ const initSearchEvent = (app: App, element: Element, config: ISearchOption) => {
break;
} else if (type === "goSearch") {
assetsElement.classList.add("fn__none");
+ unRefElement.classList.add("fn__none");
event.stopPropagation();
event.preventDefault();
break;
@@ -681,6 +709,22 @@ export const popSearch = (app: App, config = window.siyuan.storage[Constants.LOC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
`,
@@ -725,3 +769,52 @@ const goAsset = () => {
}
});
};
+
+export const goUnRef = () => {
+ window.siyuan.menus.menu.remove();
+ const unRefElement = document.querySelector("#searchUnRefPanel");
+ unRefElement.classList.remove("fn__none");
+ const listElement = unRefElement.querySelector("#searchUnRefList");
+ if (listElement.innerHTML) {
+ return;
+ }
+ getUnRefListMobile(unRefElement);
+}
+
+const getUnRefListMobile = (element: Element, page = 1) => {
+ const previousElement = element.querySelector('[data-type="unRefPrevious"]');
+ if (page > 1) {
+ previousElement.removeAttribute("disabled");
+ } else {
+ previousElement.setAttribute("disabled", "disabled");
+ }
+ fetchPost("/api/search/listInvalidBlockRefs", {
+ page,
+ }, (response) => {
+ element.parentElement.querySelector(".fn__loading--top").classList.add("fn__none");
+ const nextElement = element.querySelector('[data-type="unRefNext"]');
+ if (page < response.data.pageCount) {
+ nextElement.removeAttribute("disabled");
+ } else {
+ nextElement.setAttribute("disabled", "disabled");
+ }
+ let resultHTML = "";
+ response.data.blocks.forEach((item: IBlock, index: number) => {
+ const title = getNotebookName(item.box) + getDisplayName(item.hPath, false);
+ resultHTML += `
+
+
+ ${unicode2Emoji(item.ial.icon, "b3-list-item__graphic", true)}
+ ${item.content}
+
+
${escapeGreat(title)}
+
`;
+ });
+ element.querySelector("#searchUnRefResult").innerHTML = `${window.siyuan.languages.findInDoc.replace("${x}", response.data.matchedRootCount).replace("${y}", response.data.matchedBlockCount)}
+
+${page}/${response.data.pageCount || 1}`;
+ element.querySelector("#searchUnRefList").innerHTML = resultHTML || `
+ ${window.siyuan.languages.emptyContent}
+
`;
+ });
+}
diff --git a/app/src/search/menu.ts b/app/src/search/menu.ts
index d1c036373..cd7fd2481 100644
--- a/app/src/search/menu.ts
+++ b/app/src/search/menu.ts
@@ -7,7 +7,7 @@ import {fetchPost} from "../util/fetch";
import {escapeHtml} from "../util/escape";
import {setStorageVal} from "../protyle/util/compatibility";
import {confirmDialog} from "../dialog/confirmDialog";
-import {updateSearchResult} from "../mobile/menu/search";
+import {goUnRef, updateSearchResult} from "../mobile/menu/search";
export const filterMenu = (config: ISearchOption, cb: () => void) => {
const filterDialog = new Dialog({
@@ -371,6 +371,14 @@ export const moreMenu = async (config: ISearchOption,
window.siyuan.menus.menu.remove();
window.siyuan.menus.menu.element.setAttribute("data-name", "searchMore");
/// #if MOBILE
+ window.siyuan.menus.menu.append(new MenuItem({
+ iconHTML: "",
+ label: window.siyuan.languages.listInvalidRefBlocks,
+ click() {
+ goUnRef();
+ }
+ }).element);
+ window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
window.siyuan.menus.menu.append(new MenuItem({
iconHTML: "",
label: window.siyuan.languages.searchType,
diff --git a/app/src/search/unRef.ts b/app/src/search/unRef.ts
index dc29ba8e3..2f3aac25a 100644
--- a/app/src/search/unRef.ts
+++ b/app/src/search/unRef.ts
@@ -1,10 +1,7 @@
import {Constants} from "../constants";
import {fetchPost} from "../util/fetch";
-import {setStorageVal, updateHotkeyTip} from "../protyle/util/compatibility";
+import {setStorageVal} from "../protyle/util/compatibility";
import {getArticle, getAttr} from "./util";
-import {MenuItem} from "../menus/Menu";
-import {isPaidUser} from "../util/needSubscribe";
-import {showMessage} from "../dialog/message";
import {escapeAriaLabel, escapeGreat} from "../util/escape";
import {getIconByType} from "../editor/getIcon";
import {unicode2Emoji} from "../emoji";