feat: Theme studio v2

This commit is contained in:
2026-04-27 03:02:13 +02:00
parent 11c2588e45
commit 1b91eacb5b
52 changed files with 2792 additions and 844 deletions

View File

@@ -1,4 +1,7 @@
<div class="flex flex-col rounded-md border border-border bg-background px-3 py-2.5">
<div
appThemeNode="voiceControlsPanel"
class="flex flex-col rounded-md border border-border bg-background px-3 py-2.5"
>
<!-- Connection Error Banner -->
@if (showConnectionError()) {
<div class="mb-3 flex items-center gap-2 rounded-md border border-destructive/30 bg-destructive/10 p-2">
@@ -15,7 +18,10 @@
}
<!-- User Info -->
<div class="relative flex items-center gap-3">
<div
appThemeNode="voiceControlsUserRow"
class="relative flex items-center gap-3"
>
<button
type="button"
class="flex items-center gap-3 flex-1 min-w-0 rounded-md px-1 py-0.5 hover:bg-secondary/60 transition-colors cursor-pointer"
@@ -73,7 +79,10 @@
[attr.aria-hidden]="isConnected() ? null : 'true'"
>
<div class="overflow-hidden">
<div class="flex items-center justify-center gap-2">
<div
appThemeNode="voiceControlsButtons"
class="flex items-center justify-center gap-2"
>
<!-- Mute Toggle -->
<button
type="button"

View File

@@ -28,6 +28,7 @@ import { loadVoiceSettingsFromStorage, saveVoiceSettingsToStorage } from '../../
import { VoiceActivityService, VoiceConnectionFacade } from '../../../../domains/voice-connection';
import { PlaybackOptions, VoicePlaybackService } from '../../../../domains/voice-connection';
import { ScreenShareFacade, ScreenShareQuality } from '../../../../domains/screen-share';
import { ThemeNodeDirective } from '../../../theme';
import { UsersActions } from '../../../../store/users/users.actions';
import { selectCurrentUser } from '../../../../store/users/users.selectors';
import { selectCurrentRoom } from '../../../../store/rooms/rooms.selectors';
@@ -52,7 +53,8 @@ interface AudioDevice {
NgIcon,
DebugConsoleComponent,
ScreenShareQualityDialogComponent,
UserAvatarComponent
UserAvatarComponent,
ThemeNodeDirective
],
viewProviders: [
provideIcons({
@@ -145,17 +147,11 @@ export class VoiceControlsComponent implements OnInit, OnDestroy {
const devices = await navigator.mediaDevices.enumerateDevices();
this.inputDevices.set(
devices
.filter((device) => device.kind === 'audioinput')
.map((device) => ({ deviceId: device.deviceId,
label: device.label }))
devices.filter((device) => device.kind === 'audioinput').map((device) => ({ deviceId: device.deviceId, label: device.label }))
);
this.outputDevices.set(
devices
.filter((device) => device.kind === 'audiooutput')
.map((device) => ({ deviceId: device.deviceId,
label: device.label }))
devices.filter((device) => device.kind === 'audiooutput').map((device) => ({ deviceId: device.deviceId, label: device.label }))
);
} catch (_error) {}
}
@@ -238,9 +234,7 @@ export class VoiceControlsComponent implements OnInit, OnDestroy {
this.webrtcService.clearConnectionError();
this.saveSettings();
} catch (error) {
const message = error instanceof Error
? error.message
: 'Failed to connect voice session.';
const message = error instanceof Error ? error.message : 'Failed to connect voice session.';
this.webrtcService.reportConnectionError(message);
}