From 10423cdc9b31913f03fb7a2884e8325afe9b2ed2 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Thu, 23 Jun 2022 18:56:28 +0200 Subject: [PATCH] Refresh the mobile unread indicator on DOM update MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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/ --- ts/WoltLabSuite/Core/Ui/Page/Menu/Main.ts | 28 ++++++++++++++++++- .../js/WoltLabSuite/Core/Ui/Page/Menu/Main.js | 21 +++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) 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); -- 2.20.1