From: Alexander Ebert Date: Thu, 23 Jun 2022 16:56:28 +0000 (+0200) Subject: Refresh the mobile unread indicator on DOM update X-Git-Tag: 5.5.0_RC_3~18 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=10423cdc9b31913f03fb7a2884e8325afe9b2ed2;p=GitHub%2FWoltLab%2FWCF.git Refresh the mobile unread indicator on DOM update The unread indicator might become out of sync if the menu is closed, but an action causes the last remaining element(s) to be marked as read. Using a `MutationObserver` removes the need of signaling such change directly by all actions, for example a “Mark All as Read” button. See https://www.woltlab.com/community/thread/296063-alle-als-gelesen-markieren-entfernt-badge-nicht/ --- diff --git a/ts/WoltLabSuite/Core/Ui/Page/Menu/Main.ts b/ts/WoltLabSuite/Core/Ui/Page/Menu/Main.ts index ffd827d66b..d407aaaec1 100644 --- a/ts/WoltLabSuite/Core/Ui/Page/Menu/Main.ts +++ b/ts/WoltLabSuite/Core/Ui/Page/Menu/Main.ts @@ -20,6 +20,7 @@ export class PageMenuMain implements PageMenuProvider { private readonly container: PageMenuContainer; private readonly mainMenu: HTMLElement; private readonly menuItemProvider: PageMenuMainProvider; + private readonly observer: MutationObserver; constructor(menuItemProvider: PageMenuMainProvider) { this.mainMenu = document.querySelector(".mainMenu")!; @@ -33,6 +34,22 @@ export class PageMenuMain implements PageMenuProvider { this.container.toggle(); }; + + this.observer = new MutationObserver((mutations) => { + let refreshUnreadIndicator = false; + + mutations.forEach((mutation) => { + if (mutation.addedNodes.length > 0 || mutation.removedNodes.length > 0 || mutation.type === "characterData") { + refreshUnreadIndicator = true; + } + }); + + if (refreshUnreadIndicator) { + this.refreshUnreadIndicator(); + } + }); + + this.watchForChanges(); } enable(): void { @@ -84,13 +101,22 @@ export class PageMenuMain implements PageMenuProvider { } sleep(): void { - /* Does nothing */ + this.watchForChanges(); } wakeup(): void { + this.observer.disconnect(); + this.refreshUnreadIndicator(); } + private watchForChanges(): void { + this.observer.observe(this.mainMenu, { + childList: true, + subtree: true, + }); + } + private buildMainMenu(): HTMLElement { const boxMenu = this.mainMenu.querySelector(".boxMenu") as HTMLElement; diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Menu/Main.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Menu/Main.js index 3e050ab660..962fa9c6cf 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Menu/Main.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Menu/Main.js @@ -23,6 +23,18 @@ define(["require", "exports", "tslib", "./Container", "../../../Language", "../. event.stopPropagation(); this.container.toggle(); }; + this.observer = new MutationObserver((mutations) => { + let refreshUnreadIndicator = false; + mutations.forEach((mutation) => { + if (mutation.addedNodes.length > 0 || mutation.removedNodes.length > 0 || mutation.type === "characterData") { + refreshUnreadIndicator = true; + } + }); + if (refreshUnreadIndicator) { + this.refreshUnreadIndicator(); + } + }); + this.watchForChanges(); } enable() { this.mainMenu.setAttribute("aria-expanded", "false"); @@ -62,11 +74,18 @@ define(["require", "exports", "tslib", "./Container", "../../../Language", "../. return this.mainMenu; } sleep() { - /* Does nothing */ + this.watchForChanges(); } wakeup() { + this.observer.disconnect(); this.refreshUnreadIndicator(); } + watchForChanges() { + this.observer.observe(this.mainMenu, { + childList: true, + subtree: true, + }); + } buildMainMenu() { const boxMenu = this.mainMenu.querySelector(".boxMenu"); const nav = this.buildMenu(boxMenu);