diff --git a/app/src/mobile/util/MobileBookmarks.ts b/app/src/mobile/util/MobileBookmarks.ts
index b92adf27e..5d483460d 100644
--- a/app/src/mobile/util/MobileBookmarks.ts
+++ b/app/src/mobile/util/MobileBookmarks.ts
@@ -2,9 +2,11 @@ import {Tree} from "../../util/Tree";
import {fetchPost} from "../../util/fetch";
import {Constants} from "../../constants";
import {hasClosestByClassName} from "../../protyle/util/hasClosest";
-import {onGet} from "../../protyle/util/onGet";
import {openMobileFileById} from "../editor";
-import {MenuItem} from "../../menus/Menu";
+import {confirmDialog} from "../../dialog/confirmDialog";
+import {escapeHtml} from "../../util/escape";
+import {Dialog} from "../../dialog";
+import {isMobile} from "../../util/functions";
export class MobileBookmarks {
public element: HTMLElement;
@@ -29,9 +31,66 @@ export class MobileBookmarks {
this.tree = new Tree({
element: this.element.querySelector(".bookmarkList") as HTMLElement,
data: null,
- click(element: HTMLElement) {
- openMobileFileById(element.getAttribute("data-node-id"), true, [Constants.CB_GET_FOCUS]);
- }
+ click: (element: HTMLElement, event: MouseEvent) => {
+ const id = element.getAttribute("data-node-id");
+ const actionElement = hasClosestByClassName(event.target as HTMLElement, "b3-list-item__action");
+ if (actionElement) {
+ const bookmark = (id ? element.parentElement.previousElementSibling : element).querySelector(".b3-list-item__text").textContent;
+ if (actionElement.getAttribute("data-type") === "remove") {
+ confirmDialog(window.siyuan.languages.delete, `${window.siyuan.languages.confirmDelete} ${escapeHtml(bookmark)}?`, () => {
+ if (id) {
+ fetchPost("/api/attr/setBlockAttrs", {id, attrs: {bookmark: ""}}, () => {
+ this.update();
+ });
+ document.querySelectorAll(`.protyle-wysiwyg [data-node-id="${id}"]`).forEach((item) => {
+ item.setAttribute("bookmark", "");
+ const bookmarkElement = item.querySelector(".protyle-attr--bookmark");
+ if (bookmarkElement) {
+ bookmarkElement.remove();
+ }
+ });
+ } else {
+ fetchPost("/api/bookmark/removeBookmark", {bookmark}, () => {
+ this.update();
+ });
+ }
+ });
+ } else {
+ const dialog = new Dialog({
+ title: window.siyuan.languages.rename,
+ content: `
+
+
+
+
`,
+ width: isMobile() ? "80vw" : "520px",
+ });
+ const btnsElement = dialog.element.querySelectorAll(".b3-button");
+ btnsElement[0].addEventListener("click", () => {
+ dialog.destroy();
+ });
+ const inputElement = dialog.element.querySelector("input");
+ dialog.bindInput(inputElement, () => {
+ (btnsElement[1] as HTMLButtonElement).click();
+ });
+ inputElement.value = bookmark;
+ inputElement.focus();
+ inputElement.select();
+ btnsElement[1].addEventListener("click", () => {
+ fetchPost("/api/bookmark/renameBookmark", {
+ oldBookmark: bookmark,
+ newBookmark: inputElement.value
+ }, () => {
+ dialog.destroy();
+ });
+ });
+ }
+ } else {
+ openMobileFileById(id, true, [Constants.CB_GET_FOCUS]);
+ }
+ },
+ blockExtHTML: '',
+ topExtHTML: ''
});
this.element.addEventListener("click", (event) => {
let target = event.target as HTMLElement;
diff --git a/app/src/util/Tree.ts b/app/src/util/Tree.ts
index c1d1c3c0a..9f537e878 100644
--- a/app/src/util/Tree.ts
+++ b/app/src/util/Tree.ts
@@ -1,5 +1,5 @@
import {getIconByType} from "../editor/getIcon";
-import {hasClosestByTag} from "../protyle/util/hasClosest";
+import {hasClosestByMatchTag, hasClosestByTag} from "../protyle/util/hasClosest";
import {isMobile} from "./functions";
import {mathRender} from "../protyle/markdown/mathRender";
import {unicode2Emoji} from "../emoji";
@@ -9,6 +9,7 @@ export class Tree {
public element: HTMLElement;
private data: IBlockTree[];
private blockExtHTML: string;
+ private topExtHTML: string;
private click: (element: HTMLElement, event: MouseEvent) => void;
@@ -21,6 +22,7 @@ export class Tree {
element: HTMLElement,
data: IBlockTree[],
blockExtHTML?: string,
+ topExtHTML?: string,
click?(element: HTMLElement, event: MouseEvent): void
ctrlClick?(element: HTMLElement): void
altClick?(element: HTMLElement): void
@@ -34,6 +36,7 @@ export class Tree {
this.rightClick = options.rightClick;
this.element = options.element;
this.blockExtHTML = options.blockExtHTML;
+ this.topExtHTML = options.topExtHTML;
this.updateData(options.data);
this.bindEvent();
}
@@ -78,6 +81,7 @@ ${item.label ? "data-label='" + item.label + "'" : ""}>
${iconHTML}
${item.name}
${countHTML}
+ ${this.topExtHTML || ""}
`;
if (item.children && item.children.length > 0) {
html += this.genHTML(item.children) + "";
@@ -184,8 +188,16 @@ data-def-path="${item.defPath}">
event.preventDefault();
break;
}
-
- if (target.tagName === "LI") {
+ if (target.classList.contains("b3-list-item__action") && this.click) {
+ // 移动端书签父节点删除按钮
+ const liElement = hasClosestByMatchTag(target, "LI")
+ if (liElement) {
+ this.click(liElement, event);
+ }
+ event.preventDefault();
+ event.stopPropagation();
+ break;
+ } else if (target.tagName === "LI") {
this.setCurrent(target);
if (target.getAttribute("data-node-id") || target.getAttribute("data-treetype") === "tag") {
if (this.ctrlClick && window.siyuan.ctrlIsPressed) {