refactor(frontend): isolate audio meters and apply settings on save
This commit is contained in:
@@ -53,7 +53,6 @@ export interface AppState {
|
||||
notice: string;
|
||||
messages: Message[];
|
||||
muted: boolean;
|
||||
level: number;
|
||||
rag: string;
|
||||
queuePosition: number;
|
||||
joinDeadline: number;
|
||||
@@ -65,6 +64,8 @@ export class VoiceController {
|
||||
readonly caller: Caller;
|
||||
private state: AppState;
|
||||
private readonly listeners = new Set<() => void>();
|
||||
private readonly levelListeners = new Set<() => void>();
|
||||
private level = 0;
|
||||
private client: RealtimeClient | null = null;
|
||||
private subscriptions: (() => void)[] = [];
|
||||
private requests = new AbortController();
|
||||
@@ -98,7 +99,6 @@ export class VoiceController {
|
||||
notice: "",
|
||||
messages: [],
|
||||
muted: false,
|
||||
level: 0,
|
||||
rag: "",
|
||||
queuePosition: 0,
|
||||
joinDeadline: 0,
|
||||
@@ -106,6 +106,22 @@ export class VoiceController {
|
||||
};
|
||||
}
|
||||
getSnapshot = () => this.state;
|
||||
getLevel = () => this.level;
|
||||
subscribeLevel = (listener: () => void) => {
|
||||
this.levelListeners.add(listener);
|
||||
return () => {
|
||||
this.levelListeners.delete(listener);
|
||||
};
|
||||
};
|
||||
private updateLevel(level: number) {
|
||||
if (this.level === level) {
|
||||
return;
|
||||
}
|
||||
this.level = level;
|
||||
this.levelListeners.forEach((listener) => {
|
||||
listener();
|
||||
});
|
||||
}
|
||||
subscribe = (listener: () => void) => {
|
||||
this.listeners.add(listener);
|
||||
return () => {
|
||||
@@ -215,13 +231,28 @@ export class VoiceController {
|
||||
this.state.settings.voice,
|
||||
this.tools(),
|
||||
);
|
||||
this.client?.setGate(this.gate());
|
||||
}
|
||||
changeSettings(patch: Partial<Settings>) {
|
||||
const settings = { ...this.state.settings, ...patch };
|
||||
const changed = Object.fromEntries(
|
||||
Object.entries(patch).filter(([key, value]) => this.state.settings[key as keyof Settings] !== value),
|
||||
) as Partial<Settings>;
|
||||
if (!Object.keys(changed).length) {
|
||||
return;
|
||||
}
|
||||
const settings = { ...this.state.settings, ...changed };
|
||||
this.update({ settings });
|
||||
saveSettings(settings);
|
||||
this.pushSettings();
|
||||
saveSettings(changed);
|
||||
if (changed.noiseGate !== undefined) {
|
||||
this.client?.setGate(this.gate());
|
||||
}
|
||||
if (
|
||||
changed.voice !== undefined ||
|
||||
changed.instructions !== undefined ||
|
||||
changed.webSearch !== undefined ||
|
||||
changed.searchKey !== undefined
|
||||
) {
|
||||
this.pushSettings();
|
||||
}
|
||||
}
|
||||
setRag(rag: string) {
|
||||
this.update({ rag: rag.trim() });
|
||||
@@ -338,7 +369,7 @@ export class VoiceController {
|
||||
}
|
||||
if (Date.now() - this.lastMeter > 150) {
|
||||
this.lastMeter = Date.now();
|
||||
this.update({ level });
|
||||
this.updateLevel(level);
|
||||
}
|
||||
}),
|
||||
client.on("queue", ({ position }) => {
|
||||
@@ -574,10 +605,10 @@ export class VoiceController {
|
||||
this.requests.abort();
|
||||
this.cancelReasoning();
|
||||
window.speechSynthesis?.cancel();
|
||||
this.updateLevel(0);
|
||||
this.update({
|
||||
status,
|
||||
muted: false,
|
||||
level: 0,
|
||||
joinDeadline: 0,
|
||||
unlock: false,
|
||||
messages: this.state.messages.map((message) =>
|
||||
|
||||
Reference in New Issue
Block a user