Keep the unread indicator of user menu tabs in sync
authorAlexander Ebert <ebert@woltlab.com>
Mon, 4 Jul 2022 13:18:13 +0000 (15:18 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Mon, 4 Jul 2022 13:18:13 +0000 (15:18 +0200)
See https://www.woltlab.com/community/thread/295243-pro-und-kontra-neues-kontrollzentrum/?postID=1897875#post1897875

ts/WoltLabSuite/Core/Ui/Page/Menu/User.ts
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Menu/User.js

index b7eea34c1853eb7fdf792361b3545c9475d544b1..620289ae96c70441acc59f6237390942345abfc1 100644 (file)
@@ -45,6 +45,7 @@ export class PageMenuUser implements PageMenuProvider {
   private readonly callbackOpen: CallbackOpen;
   private readonly container: PageMenuContainer;
   private readonly legacyUserPanels = new Map<Tab, LegacyUserPanelApi>();
+  private readonly observer: MutationObserver;
   private readonly userMenuProviders = new Map<Tab, UserMenuProvider>();
   private readonly tabOrigins = new Map<HTMLElement, HTMLElement>();
   private readonly tabPanels = new Map<Tab, HTMLElement>();
@@ -81,6 +82,10 @@ export class PageMenuUser implements PageMenuProvider {
       match: () => this.detachViewsFromPanel(),
       unmatch: () => this.detachViewsFromPanel(),
     });
+
+    this.observer = new MutationObserver(() => {
+      this.refreshTabUnreadIndicators();
+    });
   }
 
   enable(): void {
@@ -171,6 +176,11 @@ export class PageMenuUser implements PageMenuProvider {
     this.attachViewToPanel(tab);
 
     this.activeTab = tab;
+    this.observer.observe(tabPanel, {
+      attributeFilter: ["data-is-unread"],
+      childList: true,
+      subtree: true,
+    });
   }
 
   private closeActiveTab(): void {
@@ -195,6 +205,7 @@ export class PageMenuUser implements PageMenuProvider {
       legacyPanel.close();
     }
 
+    this.observer.disconnect();
     this.refreshTabUnreadIndicators();
   }
 
index eebb1bb4c532a65565d0a3f11e1cb8696bed0cec..36f7e72e3aa28393d1087d12736e9466b016ea1c 100644 (file)
@@ -48,6 +48,9 @@ define(["require", "exports", "tslib", "./Container", "../../../Language", "../.
                 match: () => this.detachViewsFromPanel(),
                 unmatch: () => this.detachViewsFromPanel(),
             });
+            this.observer = new MutationObserver(() => {
+                this.refreshTabUnreadIndicators();
+            });
         }
         enable() {
             this.userMenu.setAttribute("aria-expanded", "false");
@@ -119,6 +122,11 @@ define(["require", "exports", "tslib", "./Container", "../../../Language", "../.
             }
             this.attachViewToPanel(tab);
             this.activeTab = tab;
+            this.observer.observe(tabPanel, {
+                attributeFilter: ["data-is-unread"],
+                childList: true,
+                subtree: true,
+            });
         }
         closeActiveTab() {
             if (!this.activeTab) {
@@ -136,6 +144,7 @@ define(["require", "exports", "tslib", "./Container", "../../../Language", "../.
             if (legacyPanel) {
                 legacyPanel.close();
             }
+            this.observer.disconnect();
             this.refreshTabUnreadIndicators();
         }
         attachViewToPanel(tab) {