fix(语音日记): dictation 服务改 @State 防视图重建丢实例

struct View 重建时普通 let 属性会换成全新 SpeechDictationService,
stop() 落在没在录音的新实例上返回空串 → 误报「没听清,再试一次」,
且真正在录音的老实例关不掉(麦克风悬挂)。改 @State 保证实例唯一;
停止时若服务仍返回空,用 @State 实时字幕兜底(用户看到什么就用什么)。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
link2026
2026-06-10 08:04:15 +08:00
parent 6405733358
commit 477a64ecb4

View File

@@ -53,7 +53,10 @@ struct DiaryQuickSheet: View {
@State private var voiceDeniedAlert = false @State private var voiceDeniedAlert = false
@State private var voiceFlowTask: Task<Void, Never>? @State private var voiceFlowTask: Task<Void, Never>?
@State private var recordingWatchdog: Task<Void, Never>? @State private var recordingWatchdog: Task<Void, Never>?
private let dictation = SpeechDictationService() /// @State:struct View (/detent ) let
/// , stop() (),
/// @State
@State private var dictation = SpeechDictationService()
private var hasContent: Bool { private var hasContent: Bool {
!content.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty !content.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
@@ -590,8 +593,13 @@ struct DiaryQuickSheet: View {
guard voicePhase == .recording else { return } guard voicePhase == .recording else { return }
recordingWatchdog?.cancel() recordingWatchdog?.cancel()
voiceFlowTask = Task { @MainActor in voiceFlowTask = Task { @MainActor in
let transcript = (await dictation.stop()) // :(/),
// @State
var transcript = (await dictation.stop())
.trimmingCharacters(in: .whitespacesAndNewlines) .trimmingCharacters(in: .whitespacesAndNewlines)
if transcript.isEmpty {
transcript = liveTranscript.trimmingCharacters(in: .whitespacesAndNewlines)
}
liveTranscript = transcript liveTranscript = transcript
guard !transcript.isEmpty else { guard !transcript.isEmpty else {
withAnimation(.snappy(duration: 0.2)) { voicePhase = .idle } withAnimation(.snappy(duration: 0.2)) { voicePhase = .idle }