mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-26 13:28:39 +00:00
refactor(macos): dedupe UI, pairing, and runtime helpers
This commit is contained in:
@@ -170,7 +170,11 @@ struct MenuContent: View {
|
||||
await self.loadBrowserControlEnabled()
|
||||
}
|
||||
.onAppear {
|
||||
self.startMicObserver()
|
||||
MicRefreshSupport.startObserver(self.micObserver) {
|
||||
MicRefreshSupport.schedule(refreshTask: &self.micRefreshTask) {
|
||||
await self.loadMicrophones(force: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onDisappear {
|
||||
self.micRefreshTask?.cancel()
|
||||
@@ -425,11 +429,7 @@ struct MenuContent: View {
|
||||
}
|
||||
|
||||
private var voiceWakeBinding: Binding<Bool> {
|
||||
Binding(
|
||||
get: { self.state.swabbleEnabled },
|
||||
set: { newValue in
|
||||
Task { await self.state.setVoiceWakeEnabled(newValue) }
|
||||
})
|
||||
MicRefreshSupport.voiceWakeBinding(for: self.state)
|
||||
}
|
||||
|
||||
private var showVoiceWakeMicPicker: Bool {
|
||||
@@ -546,46 +546,20 @@ struct MenuContent: View {
|
||||
}
|
||||
.map { AudioInputDevice(uid: $0.uniqueID, name: $0.localizedName) }
|
||||
self.availableMics = self.filterAliveInputs(self.availableMics)
|
||||
self.updateSelectedMicName()
|
||||
self.state.voiceWakeMicName = MicRefreshSupport.selectedMicName(
|
||||
selectedID: self.state.voiceWakeMicID,
|
||||
in: self.availableMics,
|
||||
uid: \.uid,
|
||||
name: \.name)
|
||||
self.loadingMics = false
|
||||
}
|
||||
|
||||
private func startMicObserver() {
|
||||
self.micObserver.start {
|
||||
Task { @MainActor in
|
||||
self.scheduleMicRefresh()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
private func scheduleMicRefresh() {
|
||||
self.micRefreshTask?.cancel()
|
||||
self.micRefreshTask = Task { @MainActor in
|
||||
try? await Task.sleep(nanoseconds: 300_000_000)
|
||||
guard !Task.isCancelled else { return }
|
||||
await self.loadMicrophones(force: true)
|
||||
}
|
||||
}
|
||||
|
||||
private func filterAliveInputs(_ inputs: [AudioInputDevice]) -> [AudioInputDevice] {
|
||||
let aliveUIDs = AudioInputDeviceObserver.aliveInputDeviceUIDs()
|
||||
guard !aliveUIDs.isEmpty else { return inputs }
|
||||
return inputs.filter { aliveUIDs.contains($0.uid) }
|
||||
}
|
||||
|
||||
@MainActor
|
||||
private func updateSelectedMicName() {
|
||||
let selected = self.state.voiceWakeMicID
|
||||
if selected.isEmpty {
|
||||
self.state.voiceWakeMicName = ""
|
||||
return
|
||||
}
|
||||
if let match = self.availableMics.first(where: { $0.uid == selected }) {
|
||||
self.state.voiceWakeMicName = match.name
|
||||
}
|
||||
}
|
||||
|
||||
private struct AudioInputDevice: Identifiable, Equatable {
|
||||
let uid: String
|
||||
let name: String
|
||||
|
||||
Reference in New Issue
Block a user