Sync the unread counters of the main menu and the mobile menu
authorAlexander Ebert <ebert@woltlab.com>
Wed, 29 Jun 2022 16:23:13 +0000 (18:23 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Wed, 29 Jun 2022 16:23:13 +0000 (18:23 +0200)
ts/WoltLabSuite/Core/Ui/Page/Menu/Main.ts
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Menu/Main.js

index d407aaaec19bce066b592ac265d9afdc52c9b45c..d803b10fbdb1763bb77a99c7b01d611a4680dad3 100644 (file)
@@ -19,6 +19,7 @@ export class PageMenuMain implements PageMenuProvider {
   private readonly callbackOpen: CallbackOpen;
   private readonly container: PageMenuContainer;
   private readonly mainMenu: HTMLElement;
+  private readonly menuItemBadges = new Map<string, HTMLElement>();
   private readonly menuItemProvider: PageMenuMainProvider;
   private readonly observer: MutationObserver;
 
@@ -220,6 +221,10 @@ export class PageMenuMain implements PageMenuProvider {
         counter.setAttribute("aria-hidden", "true");
         counter.textContent = menuItem.counter.toString();
 
+        if (menuItem.identifier !== false) {
+          this.menuItemBadges.set(menuItem.identifier, counter);
+        }
+
         link.append(counter);
       }
 
@@ -314,6 +319,28 @@ export class PageMenuMain implements PageMenuProvider {
     } else {
       this.mainMenu.classList.remove("pageMenuMobileButtonHasContent");
     }
+
+    const menuItems = this.menuItemProvider.getMenuItems(this.mainMenu);
+    menuItems.forEach((menuItem) => this.refreshUnreadBage(menuItem));
+  }
+
+  private refreshUnreadBage(menuItem: MenuItem): void {
+    if (menuItem.identifier !== false) {
+      const counter = this.menuItemBadges.get(menuItem.identifier);
+      if (counter) {
+        if (menuItem.counter === 0) {
+          counter.remove();
+          this.menuItemBadges.delete(menuItem.identifier);
+        } else {
+          const value = parseInt(counter.textContent!, 10);
+          if (value !== menuItem.counter) {
+            counter.textContent = menuItem.counter.toString();
+          }
+        }
+      }
+    }
+
+    menuItem.children.forEach((child) => this.refreshUnreadBage(child));
   }
 
   private updateOverflowIndicator(container: HTMLElement): void {
index 962fa9c6cfd0223603932f1327594bc8543e45c2..a1d2ebfc0ed88d1013b110f5230f2d3e4d52a014 100644 (file)
@@ -15,6 +15,7 @@ define(["require", "exports", "tslib", "./Container", "../../../Language", "../.
     Util_1 = tslib_1.__importDefault(Util_1);
     class PageMenuMain {
         constructor(menuItemProvider) {
+            this.menuItemBadges = new Map();
             this.mainMenu = document.querySelector(".mainMenu");
             this.menuItemProvider = menuItemProvider;
             this.container = new Container_1.default(this);
@@ -167,6 +168,9 @@ define(["require", "exports", "tslib", "./Container", "../../../Language", "../.
                     counter.classList.add("pageMenuMainItemCounter", "badge", "badgeUpdate");
                     counter.setAttribute("aria-hidden", "true");
                     counter.textContent = menuItem.counter.toString();
+                    if (menuItem.identifier !== false) {
+                        this.menuItemBadges.set(menuItem.identifier, counter);
+                    }
                     link.append(counter);
                 }
                 listItem.append(link);
@@ -245,6 +249,26 @@ define(["require", "exports", "tslib", "./Container", "../../../Language", "../.
             else {
                 this.mainMenu.classList.remove("pageMenuMobileButtonHasContent");
             }
+            const menuItems = this.menuItemProvider.getMenuItems(this.mainMenu);
+            menuItems.forEach((menuItem) => this.refreshUnreadBage(menuItem));
+        }
+        refreshUnreadBage(menuItem) {
+            if (menuItem.identifier !== false) {
+                const counter = this.menuItemBadges.get(menuItem.identifier);
+                if (counter) {
+                    if (menuItem.counter === 0) {
+                        counter.remove();
+                        this.menuItemBadges.delete(menuItem.identifier);
+                    }
+                    else {
+                        const value = parseInt(counter.textContent, 10);
+                        if (value !== menuItem.counter) {
+                            counter.textContent = menuItem.counter.toString();
+                        }
+                    }
+                }
+            }
+            menuItem.children.forEach((child) => this.refreshUnreadBage(child));
         }
         updateOverflowIndicator(container) {
             const hasOverflow = container.clientHeight < container.scrollHeight;