stoat-for-desktop/components/state/stores/Voice.ts

222 lines
4.7 KiB
TypeScript

import { State } from "..";
import { AbstractStore } from ".";
export interface TypeVoice {
preferredAudioInputDevice?: string;
preferredAudioOutputDevice?: string;
echoCancellation: boolean;
noiseSupression: boolean;
inputVolume: number;
outputVolume: number;
userVolumes: Record<string, number>;
userMutes: Record<string, boolean>;
}
/**
* Handles enabling and disabling client experiments.
*/
export class Voice extends AbstractStore<"voice", TypeVoice> {
/**
* Construct store
* @param state State
*/
constructor(state: State) {
super(state, "voice");
}
/**
* Hydrate external context
*/
hydrate(): void {
/** nothing needs to be done */
}
/**
* Generate default values
*/
default(): TypeVoice {
return {
echoCancellation: true,
noiseSupression: true,
inputVolume: 1.0,
outputVolume: 1.0,
userVolumes: {},
userMutes: {},
};
}
/**
* Validate the given data to see if it is compliant and return a compliant object
*/
clean(input: Partial<TypeVoice>): TypeVoice {
const data = this.default();
if (typeof input.preferredAudioInputDevice === "string") {
data.preferredAudioInputDevice = input.preferredAudioInputDevice;
}
if (typeof input.preferredAudioOutputDevice === "string") {
data.preferredAudioOutputDevice = input.preferredAudioOutputDevice;
}
if (typeof input.echoCancellation === "boolean") {
data.echoCancellation = input.echoCancellation;
}
if (typeof input.noiseSupression === "boolean") {
data.noiseSupression = input.noiseSupression;
}
if (typeof input.inputVolume === "number") {
data.inputVolume = input.inputVolume;
}
if (typeof input.outputVolume === "number") {
data.outputVolume = input.outputVolume;
}
if (typeof input.userVolumes === "object") {
Object.entries(input.userVolumes)
.filter(
([userId, volume]) =>
typeof userId === "string" && typeof volume === "number",
)
.forEach(([k, v]) => (data.userVolumes[k] = v));
}
if (typeof input.userMutes === "object") {
Object.entries(input.userMutes)
.filter(
([userId, muted]) => typeof userId === "string" && muted === true,
)
.forEach(([k, v]) => (data.userMutes[k] = v));
}
return data;
}
/**
* Set a user's volume
* @param userId User ID
* @param volume Volume
*/
setUserVolume(userId: string, volume: number) {
this.set("userVolumes", userId, volume);
}
/**
* Get a user's volume
* @param userId User ID
* @returns Volume or default
*/
getUserVolume(userId: string): number {
return this.get().userVolumes[userId] || 1.0;
}
/**
* Set whether a user is muted
* @param userId User ID
* @param muted Whether they should be muted
*/
setUserMuted(userId: string, muted: boolean) {
this.set("userMutes", userId, muted);
}
/**
* Get whether a user is muted
* @param userId User ID
* @returns Whether muted
*/
getUserMuted(userId: string): boolean {
return this.get().userMutes[userId] || false;
}
/**
* Set the preferred audio input device
*/
set preferredAudioInputDevice(value: string) {
this.set("preferredAudioInputDevice", value);
}
/**
* Set the preferred audio output device
*/
set preferredAudioOutputDevice(value: string) {
this.set("preferredAudioOutputDevice", value);
}
/**
* Set echo cancellation
*/
set echoCancellation(value: boolean) {
this.set("echoCancellation", value);
}
/**
* Set noise cancellation
*/
set noiseSupression(value: boolean) {
this.set("noiseSupression", value);
}
/**
* Set input volume
*/
set inputVolume(value: number) {
this.set("inputVolume", value);
}
/**
* Set output volume
*/
set outputVolume(value: number) {
this.set("outputVolume", value);
}
/**
* Get the preferred audio input device
*/
get preferredAudioInputDevice(): string | undefined {
return this.get().preferredAudioInputDevice;
}
/**
* Get the preferred audio output device
*/
get preferredAudioOutputDevice(): string | undefined {
return this.get().preferredAudioInputDevice;
}
/**
* Get echo cancellation
*/
get echoCancellation(): boolean | undefined {
return this.get().echoCancellation;
}
/**
* Get noise supression
*/
get noiseSupression(): boolean | undefined {
return this.get().noiseSupression;
}
/**
* Get input volume
*/
get inputVolume(): number {
return this.get().inputVolume;
}
/**
* Get noise supression
*/
get outputVolume(): number {
return this.get().outputVolume;
}
}