Files
2026-10-18 19:17:40 +07:00

53 lines
1.8 KiB
TypeScript

import type { AudioOutputInfo } from '../src/types/screen.js'
export class AudioOutput {
devices: AudioOutputInfo[] = []
notice = ''
private pending: Promise<unknown> = Promise.resolve()
constructor(
public selected: string,
private enumerate: () => Promise<AudioOutputInfo[]>,
private apply: (id: string) => Promise<void>,
private save: (id: string) => void,
) {}
private enqueue<T>(operation: () => Promise<T>): Promise<T> {
const result = this.pending.then(operation)
this.pending = result.catch(() => {})
return result
}
refresh() {
return this.enqueue(async () => {
this.devices = await this.enumerate()
if (this.selected && !this.devices.some((device) => device.id === this.selected)) {
await this.apply('')
this.selected = ''
this.notice = 'Устройство звука отключено. Используется устройство по умолчанию в системе.'
this.save('')
}
})
}
select(id: unknown) {
return this.enqueue(async () => {
if (typeof id !== 'string' || (id !== '' && !this.devices.some((d) => d.id === id)))
throw new Error('Устройство вывода звука недоступно')
const previous = this.selected
try {
await this.apply(id)
this.save(id)
} catch (error) {
try {
await this.apply(previous)
} catch {
this.notice = 'Не удалось восстановить устройство звука. Выберите устройство заново.'
}
throw error
}
this.selected = id
this.notice = ''
})
}
prepare(apply: (id: string) => Promise<void>) {
return this.enqueue(() => apply(this.selected))
}
}