From 7bedb180b762fb8f5378db45865cd06f77fbc37d Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Wed, 03 Jun 2026 14:22:04 +0800
Subject: [PATCH] Mark Round 3 user acceptance complete
---
privatevoice.src/app.go | 47 ++++++++++++++++++++++++++++++++++-------------
1 files changed, 34 insertions(+), 13 deletions(-)
diff --git a/privatevoice.src/app.go b/privatevoice.src/app.go
index 40d79a1..1bff5ab 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.19"
- appBuild = "20260602.2022"
+ appVersion = "2.1.21"
+ appBuild = "20260603.1327"
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
@@ -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