refactor: stricter domain: voice-session

This commit is contained in:
2026-04-11 15:12:54 +02:00
parent 7a0664b3c4
commit 52912327ae
9 changed files with 30 additions and 25 deletions
@@ -0,0 +1,131 @@
/* eslint-disable @typescript-eslint/member-ordering */
import {
Injectable,
computed,
effect,
inject,
signal
} from '@angular/core';
import { VoiceSessionFacade } from '../facades/voice-session.facade';
export type VoiceWorkspaceMode = 'hidden' | 'expanded' | 'minimized';
export interface VoiceWorkspacePosition {
left: number;
top: number;
}
const DEFAULT_MINI_WINDOW_POSITION: VoiceWorkspacePosition = {
left: 24,
top: 24
};
@Injectable({ providedIn: 'root' })
export class VoiceWorkspaceService {
private readonly voiceSession = inject(VoiceSessionFacade);
private readonly _mode = signal<VoiceWorkspaceMode>('hidden');
private readonly _focusedStreamId = signal<string | null>(null);
private readonly _connectRemoteShares = signal(false);
private readonly _miniWindowPosition = signal<VoiceWorkspacePosition>(
DEFAULT_MINI_WINDOW_POSITION
);
private readonly _hasCustomMiniWindowPosition = signal(false);
readonly mode = computed<VoiceWorkspaceMode>(() => {
if (!this.voiceSession.voiceSession() || !this.voiceSession.isViewingVoiceServer()) {
return 'hidden';
}
return this._mode();
});
readonly isExpanded = computed(() => this.mode() === 'expanded');
readonly isMinimized = computed(() => this.mode() === 'minimized');
readonly isVisible = computed(() => this.mode() !== 'hidden');
readonly focusedStreamId = computed(() => this._focusedStreamId());
readonly shouldConnectRemoteShares = computed(
() => this.isVisible() && this._connectRemoteShares()
);
readonly miniWindowPosition = computed(() => this._miniWindowPosition());
readonly hasCustomMiniWindowPosition = computed(() => this._hasCustomMiniWindowPosition());
constructor() {
effect(
() => {
if (this.voiceSession.voiceSession()) {
return;
}
this.reset();
},
{ allowSignalWrites: true }
);
}
open(
focusedStreamId: string | null = null,
options?: { connectRemoteShares?: boolean }
): void {
if (!this.voiceSession.voiceSession()) {
return;
}
if (options && Object.prototype.hasOwnProperty.call(options, 'connectRemoteShares')) {
this._connectRemoteShares.set(options.connectRemoteShares === true);
}
this._focusedStreamId.set(focusedStreamId);
this._mode.set('expanded');
}
focusStream(streamId: string, options?: { connectRemoteShares?: boolean }): void {
this.open(streamId, options);
}
minimize(): void {
if (!this.voiceSession.voiceSession()) {
return;
}
this._mode.set('minimized');
}
restore(): void {
this.open(this._focusedStreamId());
}
close(): void {
this._mode.set('hidden');
this._connectRemoteShares.set(false);
}
showChat(): void {
if (this._mode() === 'expanded') {
this._mode.set('hidden');
this._connectRemoteShares.set(false);
}
}
clearFocusedStream(): void {
this._focusedStreamId.set(null);
}
setMiniWindowPosition(position: VoiceWorkspacePosition, markCustom = true): void {
this._miniWindowPosition.set(position);
this._hasCustomMiniWindowPosition.set(markCustom);
}
resetMiniWindowPosition(): void {
this._miniWindowPosition.set(DEFAULT_MINI_WINDOW_POSITION);
this._hasCustomMiniWindowPosition.set(false);
}
reset(): void {
this._mode.set('hidden');
this._focusedStreamId.set(null);
this._connectRemoteShares.set(false);
this.resetMiniWindowPosition();
}
}