From 0ffbf1935c9d091cce22a5583275ac0902f7a693 Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Thu, 02 Jul 2026 03:04:51 +0800
Subject: [PATCH] Add Cantonese language model support

---
 privatevoice.src/frontend/src/App.svelte |   51 +++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/privatevoice.src/frontend/src/App.svelte b/privatevoice.src/frontend/src/App.svelte
index e6dc993..8406d60 100755
--- a/privatevoice.src/frontend/src/App.svelte
+++ b/privatevoice.src/frontend/src/App.svelte
@@ -11,10 +11,12 @@
   import { deviceName, engineHardwareInfo } from './lib/stores/app'
   import { setLocale, localeRevision } from './lib/i18n'
   import { languageMode, languageID, effectiveLanguageID, uiLocale } from './lib/stores/config'
+  import type { UILocale } from './lib/stores/config'
 
   let isIndicatorRoute = $state(window.location.hash === '#/indicator')
   let showUpdateDialog = $state(false)
   let languageReady = $state(false)
+  let showOnboarding = $state(false)
 
   onMount(() => {
     Call.ByName('voicesnap/services.ConfigService.GetLanguageSettings').then((settings: any) => {
@@ -52,6 +54,9 @@
       const data = ev?.data
       if (data?.status) {
         engineStatus.set(data.status as any)
+        if (data.status === 'ready') {
+          showOnboarding = false
+        }
       }
       if (data?.hardwareInfo) {
         engineHardwareInfo.set(data.hardwareInfo)
@@ -78,17 +83,16 @@
     Call.ByName('voicesnap/services.EngineService.GetStatus').then((data: any) => {
       if (data?.status) {
         engineStatus.set(data.status as any)
+        if (data.status === 'ready') {
+          showOnboarding = false
+        }
       }
       if (data?.hardwareInfo) {
         engineHardwareInfo.set(data.hardwareInfo)
       }
     })
 
-    Call.ByName('voicesnap/services.EngineService.ModelExists').then((exists: any) => {
-      if (!exists) {
-        engineStatus.set('need_model')
-      }
-    })
+    refreshCurrentModelAvailability()
 
     // Load actual hotkey name from backend (store default is generic "Ctrl")
     Call.ByName('voicesnap/services.HotkeyService.GetHotkeyName').then((name: any) => {
@@ -100,15 +104,42 @@
 
   function applyLanguageSettings(settings: any) {
     const mode = settings?.languageMode === 'manual' ? 'manual' : 'auto'
-    const configured = settings?.languageID === 'en' ? 'en' : 'zh-CN'
-    const effective = settings?.effectiveLanguageID === 'en' ? 'en' : 'zh-CN'
-    const locale = settings?.uiLocale === 'en' ? 'en' : 'zh'
+    const configured = typeof settings?.languageID === 'string' && settings.languageID ? settings.languageID : 'zh-CN'
+    const effective = typeof settings?.effectiveLanguageID === 'string' && settings.effectiveLanguageID ? settings.effectiveLanguageID : configured
+    const locale = typeof settings?.uiLocale === 'string' && settings.uiLocale ? settings.uiLocale : 'en'
     languageMode.set(mode)
     languageID.set(configured)
     effectiveLanguageID.set(effective)
-    uiLocale.set(locale)
+    uiLocale.set(locale as UILocale)
     setLocale(locale)
     languageReady = true
+  }
+
+  async function refreshCurrentModelAvailability() {
+    try {
+      const current: any = await Call.ByName('voicesnap/services.EngineService.GetCurrentModelStatus')
+      if (!current?.installed) {
+        const hasAnyInstalled: any = await Call.ByName('voicesnap/services.EngineService.HasAnyInstalledModel')
+        showOnboarding = !hasAnyInstalled
+        if (!hasAnyInstalled) {
+          engineStatus.set('need_model')
+        }
+      } else {
+        showOnboarding = false
+      }
+    } catch {
+      try {
+        const exists: any = await Call.ByName('voicesnap/services.EngineService.ModelExists')
+        if (!exists) {
+          const hasAnyInstalled: any = await Call.ByName('voicesnap/services.EngineService.HasAnyInstalledModel')
+            .catch(() => false)
+          showOnboarding = !hasAnyInstalled
+          if (!hasAnyInstalled) {
+            engineStatus.set('need_model')
+          }
+        }
+      } catch {}
+    }
   }
 </script>
 
@@ -117,7 +148,7 @@
 {:else}
   {#if languageReady}
     {#key $localeRevision}
-      {#if $engineStatus === 'need_model'}
+      {#if showOnboarding && $engineStatus === 'need_model'}
         <OnboardingView />
       {:else}
         <SettingsWindow />

--
Gitblit v1.9.3