mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-24 19:35:28 -06:00
fix(macos): preserve voice ear boost expiry (#116196)
This commit is contained in:
@@ -329,7 +329,7 @@ final class AppState {
|
||||
didSet { self.ifNotPreview { UserDefaults.standard.set(self.remoteCliPath, forKey: remoteCliPathKey) } }
|
||||
}
|
||||
|
||||
private var earBoostTask: Task<Void, Never>?
|
||||
@ObservationIgnored private var earBoostTask: Task<Void, Never>?
|
||||
|
||||
init(
|
||||
preview: Bool = false,
|
||||
@@ -782,13 +782,20 @@ final class AppState {
|
||||
|
||||
func triggerVoiceEars(ttl: TimeInterval? = 5) {
|
||||
self.earBoostTask?.cancel()
|
||||
self.earBoostTask = nil
|
||||
self.earBoostActive = true
|
||||
|
||||
guard let ttl else { return }
|
||||
|
||||
self.earBoostTask = Task { [weak self] in
|
||||
try? await Task.sleep(nanoseconds: UInt64(ttl * 1_000_000_000))
|
||||
await MainActor.run { [weak self] in self?.earBoostActive = false }
|
||||
do {
|
||||
try await Task.sleep(nanoseconds: UInt64(ttl * 1_000_000_000))
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
guard !Task.isCancelled, let self else { return }
|
||||
self.earBoostTask = nil
|
||||
self.earBoostActive = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import Foundation
|
||||
import Testing
|
||||
@testable import OpenClaw
|
||||
|
||||
@Suite(.serialized)
|
||||
@MainActor
|
||||
struct AppStateVoiceEarsTests {
|
||||
@Test func `indefinite ear boost survives cancelled expiry`() async throws {
|
||||
let state = AppState(preview: true)
|
||||
state.triggerVoiceEars(ttl: 60)
|
||||
state.triggerVoiceEars(ttl: nil)
|
||||
|
||||
try await Task.sleep(for: .milliseconds(20))
|
||||
|
||||
#expect(state.earBoostActive)
|
||||
state.stopVoiceEars()
|
||||
}
|
||||
|
||||
@Test func `replacement expiry owns ear boost lifetime`() async throws {
|
||||
let state = AppState(preview: true)
|
||||
state.triggerVoiceEars(ttl: 60)
|
||||
state.triggerVoiceEars(ttl: 0.05)
|
||||
|
||||
try await Task.sleep(for: .milliseconds(20))
|
||||
#expect(state.earBoostActive)
|
||||
|
||||
try await Task.sleep(for: .milliseconds(60))
|
||||
#expect(!state.earBoostActive)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user