diff --git a/app/src/menus/protyle.ts b/app/src/menus/protyle.ts index 34d1e27bb..f61b4f8f1 100644 --- a/app/src/menus/protyle.ts +++ b/app/src/menus/protyle.ts @@ -37,6 +37,7 @@ import {blockRender} from "../protyle/markdown/blockRender"; import {renameAsset} from "../editor/rename"; import {hasNextSibling} from "../protyle/wysiwyg/getBlock"; import {electronUndo} from "../protyle/undo"; +import {pushBack} from "../mobile/util/MobileBackFoward"; export const refMenu = (protyle: IProtyle, element: HTMLElement) => { const nodeElement = hasClosestBlock(element); @@ -383,11 +384,9 @@ export const zoomOut = (protyle: IProtyle, id: string, focusId?: string, isPushB id, action: id === protyle.block.rootID ? [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT] : [Constants.CB_GET_ALL] })); - window.siyuan.backStack.push({ - id: protyle.block.id, - scrollTop: protyle.contentElement.scrollTop, - callback: id === protyle.block.rootID ? [Constants.CB_GET_HL] : [Constants.CB_GET_ALL], - }); + if (isPushBack) { + pushBack(); + } } fetchPost("/api/filetree/getDoc", { id, diff --git a/app/src/mobile/editor.ts b/app/src/mobile/editor.ts index 78a54f141..2b7e4d8d6 100644 --- a/app/src/mobile/editor.ts +++ b/app/src/mobile/editor.ts @@ -11,8 +11,9 @@ import {lockFile} from "../dialog/processSystem"; import {hasClosestByAttribute} from "../protyle/util/hasClosest"; import {setEditMode} from "../protyle/util/setEditMode"; import {hideElements} from "../protyle/ui/hideElements"; +import {pushBack} from "./util/MobileBackFoward"; -export const openMobileFileById = (id: string, action = [Constants.CB_GET_HL], pushStack = true) => { +export const openMobileFileById = (id: string, action = [Constants.CB_GET_HL]) => { window.localStorage.setItem(Constants.LOCAL_DOCINFO, JSON.stringify({id, action})); if (window.siyuan.mobileEditor) { hideElements(["toolbar", "hint", "util"], window.siyuan.mobileEditor.protyle); @@ -27,14 +28,7 @@ export const openMobileFileById = (id: string, action = [Constants.CB_GET_HL], p } }); if (blockElement) { - // https://github.com/siyuan-note/siyuan/issues/4327 - if (pushStack) { - window.siyuan.backStack.push({ - id, - scrollTop: window.siyuan.mobileEditor.protyle.contentElement.scrollTop, - callback: action, - }); - } + pushBack(); focusBlock(blockElement); scrollCenter(window.siyuan.mobileEditor.protyle, blockElement, true); closePanel(); @@ -49,6 +43,7 @@ export const openMobileFileById = (id: string, action = [Constants.CB_GET_HL], p return; } if (window.siyuan.mobileEditor) { + pushBack(); addLoading(window.siyuan.mobileEditor.protyle); fetchPost("/api/filetree/getDoc", { id, @@ -84,12 +79,5 @@ export const openMobileFileById = (id: string, action = [Constants.CB_GET_HL], p (document.getElementById("toolbarName") as HTMLInputElement).value = data.data.rootTitle === "Untitled" ? "" : data.data.rootTitle; setEditor(); closePanel(); - if (pushStack) { - window.siyuan.backStack.push({ - id, - scrollTop: window.siyuan.mobileEditor.protyle.contentElement.scrollTop, - callback: action, - }); - } }); }; diff --git a/app/src/mobile/index.ts b/app/src/mobile/index.ts index 8b62e4bd4..f7b40f681 100644 --- a/app/src/mobile/index.ts +++ b/app/src/mobile/index.ts @@ -11,10 +11,10 @@ import {handleTouchEnd, handleTouchMove, handleTouchStart} from "./util/touch"; import {fetchGet, fetchPost} from "../util/fetch"; import {initFramework} from "./util/initFramework"; import {initAssets, loadAssets} from "../util/assets"; -import {openMobileFileById} from "./editor"; import {promiseTransactions} from "../protyle/wysiwyg/transaction"; import {bootSync} from "../dialog/processSystem"; import {initMessage} from "../dialog/message"; +import {goBack} from "./util/MobileBackFoward"; class App { constructor() { @@ -75,20 +75,4 @@ class App { new App(); -let previousBackStack: IBackStack; -window.goBack = () => { - if (window.JSAndroid && window.siyuan.backStack.length < 2) { - window.JSAndroid.returnDesktop(); - return; - } - previousBackStack = window.siyuan.backStack.pop(); - const item = window.siyuan.backStack[window.siyuan.backStack.length - 1]; - openMobileFileById(item.id, item.callback, false); - setTimeout(() => { - window.siyuan.mobileEditor.protyle.contentElement.scrollTo({ - top: previousBackStack?.scrollTop || 0, - behavior: "smooth" - }); - previousBackStack = item; - }, 300); -}; +window.goBack = goBack; diff --git a/app/src/mobile/util/MobileBackFoward.ts b/app/src/mobile/util/MobileBackFoward.ts new file mode 100644 index 000000000..87bdec0b2 --- /dev/null +++ b/app/src/mobile/util/MobileBackFoward.ts @@ -0,0 +1,118 @@ +import {Constants} from "../../constants"; +import {hideElements} from "../../protyle/ui/hideElements"; +import {setEditMode} from "../../protyle/util/setEditMode"; +import {fetchPost} from "../../util/fetch"; +import {zoomOut} from "../../menus/protyle"; +import {processRender} from "../../protyle/util/processCode"; +import {highlightRender} from "../../protyle/markdown/highlightRender"; +import {blockRender} from "../../protyle/markdown/blockRender"; +import {disabledProtyle, enableProtyle} from "../../protyle/util/onGet"; + +const forwardStack: IBackStack[] = []; + +const focusStack = (backStack: IBackStack) => { + const protyle = window.siyuan.mobileEditor.protyle; + window.localStorage.setItem(Constants.LOCAL_DOCINFO, JSON.stringify({ + id: backStack.id, + action: backStack.callback, + })); + hideElements(["toolbar", "hint", "util"], window.siyuan.mobileEditor.protyle); + if (protyle.contentElement.classList.contains("fn__none")) { + setEditMode(protyle, "wysiwyg"); + } + + const startEndId = backStack.endId.split(Constants.ZWSP); + if (startEndId[0] === protyle.wysiwyg.element.firstElementChild.getAttribute("data-node-id") && + startEndId[1] === protyle.wysiwyg.element.lastElementChild.getAttribute("data-node-id")) { + window.siyuan.mobileEditor.protyle.contentElement.scrollTo({ + top: backStack.scrollTop, + behavior: "smooth" + }); + return; + } + + if (backStack.id !== protyle.block.rootID) { + fetchPost("/api/block/getDocInfo", { + id: backStack.id, + }, (response) => { + (document.getElementById("toolbarName") as HTMLInputElement).value = response.data.name === "Untitled" ? "" : response.data.name; + protyle.background.render(response.data.ial, protyle.block.rootID); + protyle.wysiwyg.renderCustom(response.data.ial); + }); + } + + if (backStack.isZoom) { + fetchPost("/api/block/checkBlockExist", {id: backStack.id}, existResponse => { + if (existResponse.data) { + zoomOut(protyle, backStack.id, undefined, false, () => { + protyle.contentElement.scrollTop = backStack.scrollTop; + }); + } + }); + return; + } + fetchPost("/api/filetree/getDoc", { + id: backStack.id, + startID: startEndId[0], + endID: startEndId[1], + }, getResponse => { + protyle.block.showAll = false; + protyle.wysiwyg.element.innerHTML = getResponse.data.content; + processRender(protyle.wysiwyg.element); + highlightRender(protyle.wysiwyg.element); + blockRender(protyle, protyle.wysiwyg.element); + if (protyle.disabled) { + disabledProtyle(protyle); + } else { + enableProtyle(protyle); + } + protyle.contentElement.scrollTop = backStack.scrollTop; + window.siyuan.mobileEditor.protyle.breadcrumb.render(protyle); + }); +} + +export const pushBack = () => { + const protyle = window.siyuan.mobileEditor.protyle; + window.siyuan.backStack.push({ + id: protyle.block.showAll ? protyle.block.id : protyle.block.rootID, + endId: protyle.wysiwyg.element.firstElementChild.getAttribute("data-node-id") + Constants.ZWSP + protyle.wysiwyg.element.lastElementChild.getAttribute("data-node-id"), + scrollTop: protyle.contentElement.scrollTop, + callback: protyle.block.action, + isZoom: protyle.block.showAll + }); +} + +export const goForward = () => { + if (window.JSAndroid && forwardStack.length < 2) { + window.JSAndroid.returnDesktop(); + return; + } + if (forwardStack.length < 2) { + return; + } + window.siyuan.backStack.push(forwardStack.pop()) + focusStack(forwardStack[forwardStack.length - 1]) +} + +export const goBack = () => { + if (window.JSAndroid && window.siyuan.backStack.length < 1) { + window.JSAndroid.returnDesktop(); + return; + } + if (window.siyuan.backStack.length < 1) { + return; + } + const protyle = window.siyuan.mobileEditor.protyle; + if (forwardStack.length === 0) { + forwardStack.push({ + id: protyle.block.showAll ? protyle.block.id : protyle.block.rootID, + endId: protyle.wysiwyg.element.firstElementChild.getAttribute("data-node-id") + Constants.ZWSP + protyle.wysiwyg.element.lastElementChild.getAttribute("data-node-id"), + scrollTop: protyle.contentElement.scrollTop, + callback: protyle.block.action, + isZoom: protyle.block.showAll + }); + } + const item = window.siyuan.backStack.pop(); + forwardStack.push(item); + focusStack(item) +}; diff --git a/app/src/mobile/util/touch.ts b/app/src/mobile/util/touch.ts index 1aa090be2..2d3127e80 100644 --- a/app/src/mobile/util/touch.ts +++ b/app/src/mobile/util/touch.ts @@ -1,13 +1,10 @@ -import {openMobileFileById} from "../editor"; +import {goBack, goForward} from "./MobileBackFoward"; let clientX: number; let clientY: number; let xDiff: number; let yDiff: number; -const forwardStack: IBackStack[] = []; -let previousIsBack = false; - export const handleTouchEnd = () => { if (window.siyuan.mobileEditor) { window.siyuan.mobileEditor.protyle.breadcrumb.show(); @@ -19,44 +16,10 @@ export const handleTouchEnd = () => { if (Math.abs(xDiff) > Math.abs(yDiff) && Math.abs(xDiff) > window.innerWidth / 2) { if (xDiff > 0) { - if (forwardStack.length === 0) { - window.JSAndroid?.returnDesktop(); - return; - } - if (previousIsBack) { - window.siyuan.backStack.push(forwardStack.pop()); - } - const item = forwardStack.pop(); - item.scrollTop = window.siyuan.mobileEditor.protyle.contentElement.scrollTop; - window.siyuan.backStack.push(item); - openMobileFileById(item.id, item.callback, false); - setTimeout(() => { - window.siyuan.mobileEditor.protyle.contentElement.scrollTo({ - top: window.siyuan.backStack[window.siyuan.backStack.length - 2]?.scrollTop || 0, - behavior: "smooth" - }); - }, 200); - previousIsBack = false; + goForward(); } else { // 后退 - if (window.siyuan.backStack.length === 0 || (window.siyuan.backStack.length === 1 && forwardStack.length === 0)) { - window.JSAndroid?.returnDesktop(); - return; - } - if (!previousIsBack) { - forwardStack.push(window.siyuan.backStack.pop()); - } - const item = window.siyuan.backStack.pop(); - item.scrollTop = window.siyuan.mobileEditor.protyle.contentElement.scrollTop; - forwardStack.push(item); - openMobileFileById(item.id, item.callback, false); - setTimeout(() => { - window.siyuan.mobileEditor.protyle.contentElement.scrollTo({ - top: forwardStack[forwardStack.length - 2]?.scrollTop || 0, - behavior: "smooth" - }); - }, 200); - previousIsBack = true; + goBack(); } } diff --git a/app/src/protyle/util/onGet.ts b/app/src/protyle/util/onGet.ts index 676274a6a..4f171d139 100644 --- a/app/src/protyle/util/onGet.ts +++ b/app/src/protyle/util/onGet.ts @@ -69,6 +69,7 @@ export const onGet = (data: IWebSocketData, protyle: IProtyle, action: string[] protyle.block.showAll = false; protyle.block.mode = data.data.mode; protyle.block.blockCount = data.data.blockCount; + protyle.block.action = action; if (!action.includes(Constants.CB_GET_UNCHANGEID)) { protyle.block.id = data.data.id; protyle.scroll.lastScrollTop = 0; diff --git a/app/src/types/index.d.ts b/app/src/types/index.d.ts index 7be13812d..5d0049e6f 100644 --- a/app/src/types/index.d.ts +++ b/app/src/types/index.d.ts @@ -47,6 +47,7 @@ interface IPdfAnno { interface IBackStack { id: string, + endId?: string, scrollTop?: number, callback?: string[], position?: { start: number, end: number } diff --git a/app/src/types/protyle.d.ts b/app/src/types/protyle.d.ts index 15b0a102d..afdbf7250 100644 --- a/app/src/types/protyle.d.ts +++ b/app/src/types/protyle.d.ts @@ -394,6 +394,7 @@ interface IProtyle { showAll?: boolean mode?: number blockCount?: number + action?: string[] }, disabled: boolean, selectElement?: HTMLElement,