diff --git a/src/main.ts b/src/main.ts index b509757..4e2abd4 100644 --- a/src/main.ts +++ b/src/main.ts @@ -151,6 +151,7 @@ export default class RemotelySavePlugin extends Plugin { vaultRandomID!: string; debugServerTemp?: string; syncEvent?: Events; + appContainerObserver?: MutationObserver; async syncRun(triggerSource: SyncTriggerSourceType = "manual") { const t = (x: TransItemType, vars?: any) => { @@ -820,6 +821,10 @@ export default class RemotelySavePlugin extends Plugin { async onunload() { console.info(`unloading plugin ${this.manifest.id}`); this.syncRibbon = undefined; + if (this.appContainerObserver !== undefined) { + this.appContainerObserver.disconnect(); + this.appContainerObserver = undefined; + } if (this.oauth2Info !== undefined) { this.oauth2Info.helperModal = undefined; this.oauth2Info = { @@ -1187,9 +1192,11 @@ export default class RemotelySavePlugin extends Plugin { } enableMobileStatusBarIfSet() { - if (Platform.isMobile && this.settings.enableMobileStatusBar) { - changeMobileStatusBar("enable"); - } + this.app.workspace.onLayoutReady(() => { + if (Platform.isMobile && this.settings.enableMobileStatusBar) { + this.appContainerObserver = changeMobileStatusBar("enable"); + } + }); } async saveAgreeToUseNewSyncAlgorithm() { diff --git a/src/misc.ts b/src/misc.ts index 2dab583..0b48995 100644 --- a/src/misc.ts +++ b/src/misc.ts @@ -4,6 +4,7 @@ import * as path from "path"; import { base32, base64url } from "rfc4648"; import XRegExp from "xregexp"; import emojiRegex from "emoji-regex"; +import delay from "delay"; declare global { interface Window { @@ -517,21 +518,80 @@ export const stringToFragment = (string: string) => { * https://forum.obsidian.md/t/css-to-show-status-bar-on-mobile-devices/77185 * @param op */ -export const changeMobileStatusBar = (op: "enable" | "disable") => { - const bar = document.querySelector( +export const changeMobileStatusBar = ( + op: "enable" | "disable", + oldAppContainerObserver?: MutationObserver +) => { + const appContainer = document.getElementsByClassName("app-container")[0] as + | HTMLElement + | undefined; + + const statusbar = document.querySelector( ".is-mobile .app-container .status-bar" - ) as HTMLElement; + ) as HTMLElement | undefined; + + if (appContainer === undefined || statusbar === undefined) { + // give up, exit + console.warn(`give up watching appContainer for statusbar`); + console.warn(`appContainer=${appContainer}, statusbar=${statusbar}`); + return undefined; + } + if (op === "enable") { - bar.style.setProperty("display", "flex"); - const navBar = document.getElementsByClassName( - "mobile-navbar" - )[0] as HTMLElement; - // thanks to community's solution - const height = window.getComputedStyle(navBar).getPropertyValue("height"); - bar.style.setProperty("margin-bottom", height); + const callback = async ( + mutationList: MutationRecord[], + observer: MutationObserver + ) => { + for (const mutation of mutationList) { + // console.debug(mutation); + if (mutation.type === "childList" && mutation.addedNodes.length > 0) { + const k = mutation.addedNodes[0] as Element; + if ( + k.className.contains("mobile-navbar") || + k.className.contains("mobile-toolbar") + ) { + await delay(300); // have to wait, otherwise the height is not correct?? + const height = window + .getComputedStyle(k as Element) + .getPropertyValue("height"); + + statusbar.style.setProperty("display", "flex"); + statusbar.style.setProperty("margin-bottom", height); + } + } + } + }; + const observer = new MutationObserver(callback); + observer.observe(appContainer, { + attributes: false, + childList: true, + characterData: false, + subtree: false, + }); + + try { + // init, manual call + const navBar = document.getElementsByClassName( + "mobile-navbar" + )[0] as HTMLElement; + // thanks to community's solution + const height = window.getComputedStyle(navBar).getPropertyValue("height"); + statusbar.style.setProperty("display", "flex"); + statusbar.style.setProperty("margin-bottom", height); + } catch (e) { + // skip + } + + return observer; } else { - bar.style.removeProperty("display"); - bar.style.removeProperty("margin-bottom"); + if (oldAppContainerObserver !== undefined) { + console.debug(`disconnect oldAppContainerObserver`); + oldAppContainerObserver.disconnect(); + oldAppContainerObserver = undefined; + } + statusbar.style.removeProperty("display"); + statusbar.style.removeProperty("margin-bottom"); + return undefined; } }; diff --git a/src/settings.ts b/src/settings.ts index 48e4809..cef8edc 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -2098,10 +2098,16 @@ export class RemotelySaveSettingTab extends PluginSettingTab { .onChange(async (val) => { if (val === "enable") { this.plugin.settings.enableMobileStatusBar = true; - changeMobileStatusBar("enable"); + this.plugin.appContainerObserver = + changeMobileStatusBar("enable"); } else { this.plugin.settings.enableMobileStatusBar = false; - changeMobileStatusBar("disable"); + changeMobileStatusBar( + "disable", + this.plugin.appContainerObserver + ); + this.plugin.appContainerObserver?.disconnect(); + this.plugin.appContainerObserver = undefined; } await this.plugin.saveSettings(); });