























@@ -20,6 +20,7 @@ struct VoiceWakeSettings: View {
2020private let meter = MicLevelMonitor()
2121@State private var micObserver = AudioInputDeviceObserver()
2222@State private var micRefreshTask: Task<Void, Never>?
23+@State private var meterStartupTask: Task<Void, Never>?
2324@State private var availableLocales: [Locale] = []
2425@State private var triggerEntries: [TriggerEntry] = []
2526private let fieldLabelWidth: CGFloat = 140
@@ -188,59 +189,68 @@ struct VoiceWakeSettings: View {
188189}
189190.settingsDetailContent()
190191}
191-.task {
192-guard !self.isPreview else { return }
193-await self.loadMicsIfNeeded()
194-}
195-.task {
196-guard !self.isPreview else { return }
197-await self.loadLocalesIfNeeded()
198-}
199-.task {
200-guard !self.isPreview else { return }
201-await self.restartMeter()
202-}
203192.onAppear {
204193guard !self.isPreview else { return }
205-self.startMicObserver()
206-self.loadTriggerEntries()
194+guard self.isActive else { return }
195+self.activateLivePreview()
207196}
208197.onChange(of: self.state.voiceWakeMicID) { _, _ in
209198guard !self.isPreview else { return }
210199self.updateSelectedMicName()
211-Task { await self.restartMeter() }
200+guard self.isActive else { return }
201+self.scheduleMeterRestart()
212202}
213203.onChange(of: self.isActive) { _, active in
214204guard !self.isPreview else { return }
215205if !active {
216-self.tester.stop()
217-self.isTesting = false
218-self.testState = .idle
219-self.testTimeoutTask?.cancel()
220-self.micRefreshTask?.cancel()
221-self.micRefreshTask = nil
222-Task { await self.meter.stop() }
223-self.micObserver.stop()
206+self.deactivateLivePreview()
224207self.syncTriggerEntriesToState()
225208} else {
226-self.startMicObserver()
227-self.loadTriggerEntries()
209+self.activateLivePreview()
228210}
229211}
230212.onDisappear {
231213guard !self.isPreview else { return }
232-self.tester.stop()
233-self.isTesting = false
234-self.testState = .idle
235-self.testTimeoutTask?.cancel()
236-self.micRefreshTask?.cancel()
237-self.micRefreshTask = nil
238-self.micObserver.stop()
239-Task { await self.meter.stop() }
214+self.deactivateLivePreview()
240215self.syncTriggerEntriesToState()
241216}
242217}
243218219+private func activateLivePreview() {
220+self.meterStartupTask?.cancel()
221+self.startMicObserver()
222+self.loadTriggerEntries()
223+self.meterStartupTask = Task { @MainActor in
224+await self.loadMicsIfNeeded()
225+guard !Task.isCancelled, self.isActive else { return }
226+await self.loadLocalesIfNeeded()
227+guard !Task.isCancelled, self.isActive else { return }
228+await self.restartMeter()
229+}
230+}
231+232+private func deactivateLivePreview() {
233+self.tester.stop()
234+self.isTesting = false
235+self.testState = .idle
236+self.testTimeoutTask?.cancel()
237+self.micRefreshTask?.cancel()
238+self.micRefreshTask = nil
239+self.meterStartupTask?.cancel()
240+self.meterStartupTask = nil
241+self.micObserver.stop()
242+self.state.voiceWakeMeterActive = false
243+Task { await self.meter.stop() }
244+}
245+246+private func scheduleMeterRestart() {
247+self.meterStartupTask?.cancel()
248+self.meterStartupTask = Task { @MainActor in
249+guard !Task.isCancelled, self.isActive else { return }
250+await self.restartMeter()
251+}
252+}
253+244254private func loadTriggerEntries() {
245255self.triggerEntries = self.state.swabbleTriggerWords.map { TriggerEntry(id: UUID(), value: $0) }
246256}
@@ -652,6 +662,7 @@ struct VoiceWakeSettings: View {
652662653663@MainActor
654664private func scheduleMicRefresh() {
665+guard self.isActive else { return }
655666MicRefreshSupport.schedule(refreshTask: &self.micRefreshTask) {
656667await self.loadMicsIfNeeded(force: true)
657668await self.restartMeter()
@@ -713,16 +724,32 @@ struct VoiceWakeSettings: View {
713724714725@MainActor
715726private func restartMeter() async {
727+guard self.isActive else {
728+self.state.voiceWakeMeterActive = false
729+await self.meter.stop()
730+return
731+}
716732self.meterError = nil
717733await self.meter.stop()
734+guard !Task.isCancelled, self.isActive else {
735+self.state.voiceWakeMeterActive = false
736+return
737+}
718738do {
719739try await self.meter.start { [weak state] level in
720740Task { @MainActor in
721741guard state != nil else { return }
722742self.meterLevel = level
723743}
724744}
745+guard !Task.isCancelled, self.isActive else {
746+self.state.voiceWakeMeterActive = false
747+await self.meter.stop()
748+return
749+}
750+self.state.voiceWakeMeterActive = true
725751} catch {
752+self.state.voiceWakeMeterActive = false
726753self.meterError = error.localizedDescription
727754}
728755}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。