From a19e8d996efac4052b4ea87da16330e8f98934b9 Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Wed, 03 Jun 2026 16:46:10 +0800
Subject: [PATCH] Record Round 4 user acceptance
---
privatevoice.src/app.go | 49 +++++++++++++++++++++++++++++++++++--------------
1 files changed, 35 insertions(+), 14 deletions(-)
diff --git a/privatevoice.src/app.go b/privatevoice.src/app.go
index 54bbc93..e0f641f 100755
--- a/privatevoice.src/app.go
+++ b/privatevoice.src/app.go
@@ -14,6 +14,7 @@
"voicesnap/internal/history"
"voicesnap/internal/hotkey"
"voicesnap/internal/input"
+ "voicesnap/internal/language"
"voicesnap/internal/logger"
"voicesnap/internal/overlay"
"voicesnap/internal/sound"
@@ -26,8 +27,8 @@
)
const (
- appVersion = "2.1.18"
- appBuild = "20260601.1905"
+ appVersion = "2.1.22"
+ appBuild = "20260603.1608"
appDisplayVersion = appVersion + " (build " + appBuild + ")"
appName = "PrivateVoice Input"
@@ -47,6 +48,7 @@
cfg *config.Config
recorder *audio.Recorder
eng engine.Engine
+ engineMu sync.Mutex
hk hotkey.Listener
paster input.Paster
history *history.Store
@@ -110,7 +112,7 @@
// Create services for Wails bindings
appService := services.NewAppService(app.cfg, appDisplayVersion)
configService := services.NewConfigService(app.cfg)
- engineService := services.NewEngineService()
+ engineService := services.NewEngineService(app.cfg)
app.engineService = engineService
hotkeyService := services.NewHotkeyService(app.cfg)
permissionService := services.NewPermissionService()
@@ -186,7 +188,7 @@
tray.SetTemplateIcon(trayIcon)
showLabel, exitLabel := "Show Settings", "Exit"
- if isChinese() {
+ if language.Resolve(app.cfg.LanguageMode, app.cfg.LanguageID, language.NewSystemDetector()).UILocale == "zh" {
showLabel, exitLabel = "显示设置", "退出"
}
@@ -596,7 +598,17 @@
return
}
- text, err := a.eng.Recognize(samples)
+ a.engineMu.Lock()
+ eng := a.eng
+ if eng == nil {
+ a.engineMu.Unlock()
+ logger.Error("Recognition skipped: engine not ready")
+ a.indicator.SetStatus(overlay.StatusError, "引擎未就绪")
+ a.delayedHideIf(autoHide, 2000)
+ return
+ }
+ text, err := eng.Recognize(samples)
+ a.engineMu.Unlock()
if err != nil {
logger.Error("Recognition failed: %v", err)
a.indicator.SetStatus(overlay.StatusError, "错误")
@@ -686,6 +698,7 @@
eng, err := engine.New()
if err != nil {
logger.Error("Engine initialization failed: %v", err)
+ a.replaceEngine(nil)
status := "need_model"
if modelExists {
status = "error"
@@ -700,9 +713,7 @@
return
}
- a.mu.Lock()
- a.eng = eng
- a.mu.Unlock()
+ a.replaceEngine(eng)
logger.Info("ASR engine ready: %s", eng.HardwareInfo())
if a.engineService != nil {
@@ -727,6 +738,20 @@
a.indicator.SetStatus(overlay.StatusReady, hotkeyReadyText(keyName, hotkeyMode))
a.indicator.Show()
a.delayedHideIf(autoHide, 2000)
+}
+
+func (a *App) replaceEngine(eng engine.Engine) {
+ a.engineMu.Lock()
+ defer a.engineMu.Unlock()
+
+ a.mu.Lock()
+ old := a.eng
+ a.eng = eng
+ a.mu.Unlock()
+
+ if old != nil && old != eng {
+ old.Close()
+ }
}
func hotkeyReadyText(keyName, mode string) string {
@@ -910,9 +935,7 @@
if a.recorder != nil {
a.recorder.Close()
}
- if a.eng != nil {
- a.eng.Close()
- }
+ a.replaceEngine(nil)
a.wg.Wait()
logger.Info("Cleanup complete")
}
@@ -945,7 +968,5 @@
// SetEngine sets the engine after model download.
func (a *App) SetEngine(eng engine.Engine) {
- a.mu.Lock()
- defer a.mu.Unlock()
- a.eng = eng
+ a.replaceEngine(eng)
}
--
Gitblit v1.9.3