From 2d1d4ad406228ef62ab078724cb7d1556e003d01 Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Mon, 13 Jul 2026 16:03:19 +0800
Subject: [PATCH] chore: point independent project metadata to unified root

---
 C1.source/privatevoice.src/frontend/src/App.svelte |   40 ++++++++++++++++++++++++----------------
 1 files changed, 24 insertions(+), 16 deletions(-)

diff --git a/C1.source/privatevoice.src/frontend/src/App.svelte b/C1.source/privatevoice.src/frontend/src/App.svelte
index 8406d60..e91d231 100755
--- a/C1.source/privatevoice.src/frontend/src/App.svelte
+++ b/C1.source/privatevoice.src/frontend/src/App.svelte
@@ -19,24 +19,26 @@
   let showOnboarding = $state(false)
 
   onMount(() => {
+    const offEvents: Array<() => void> = []
+
     Call.ByName('voicesnap/services.ConfigService.GetLanguageSettings').then((settings: any) => {
       applyLanguageSettings(settings)
     }).catch(() => {
       languageReady = true
     })
 
-    Events.On('indicator:show', (ev: any) => {
+    offEvents.push(Events.On('indicator:show', (ev: any) => {
       indicatorVisible.set(true)
       if (ev?.data?.status) {
         indicatorStatus.set(ev.data.status)
       }
-    })
+    }))
 
-    Events.On('indicator:hide', () => {
+    offEvents.push(Events.On('indicator:hide', () => {
       indicatorVisible.set(false)
-    })
+    }))
 
-    Events.On('indicator:status', (ev: any) => {
+    offEvents.push(Events.On('indicator:status', (ev: any) => {
       const data = ev?.data
       if (data?.status) {
         indicatorStatus.set(data.status)
@@ -44,13 +46,13 @@
       if (data?.hotkeyName) {
         hotkeyName.set(data.hotkeyName)
       }
-    })
+    }))
 
-    Events.On('indicator:volume', (ev: any) => {
+    offEvents.push(Events.On('indicator:volume', (ev: any) => {
       indicatorVolume.set(ev?.data ?? 0)
-    })
+    }))
 
-    Events.On('engine:status', (ev: any) => {
+    offEvents.push(Events.On('engine:status', (ev: any) => {
       const data = ev?.data
       if (data?.status) {
         engineStatus.set(data.status as any)
@@ -61,23 +63,24 @@
       if (data?.hardwareInfo) {
         engineHardwareInfo.set(data.hardwareInfo)
       }
-    })
+    }))
 
-    Events.On('device:changed', (ev: any) => {
+    offEvents.push(Events.On('device:changed', (ev: any) => {
       if (ev?.data?.name) {
         deviceName.set(ev.data.name)
       }
-    })
+    }))
 
-    Events.On('update:available', (ev: any) => {
+    offEvents.push(Events.On('update:available', (ev: any) => {
       const data = ev?.data as UpdateInfo
       updateAvailable.set(data)
       showUpdateDialog = true
-    })
+    }))
 
-    window.addEventListener('hashchange', () => {
+    const onHashChange = () => {
       isIndicatorRoute = window.location.hash === '#/indicator'
-    })
+    }
+    window.addEventListener('hashchange', onHashChange)
 
     // Query engine status on mount (events emitted before frontend load are lost)
     Call.ByName('voicesnap/services.EngineService.GetStatus').then((data: any) => {
@@ -100,6 +103,11 @@
         hotkeyName.set(name)
       }
     })
+
+    return () => {
+      for (const off of offEvents) off()
+      window.removeEventListener('hashchange', onHashChange)
+    }
   })
 
   function applyLanguageSettings(settings: any) {

--
Gitblit v1.9.3