Files
Toju/toju-app/src/app/domains/voice-session/feature/voice-controls/voice-controls.component.html
2026-04-17 03:06:44 +02:00

170 lines
5.0 KiB
HTML

<div 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">
<span class="w-2 h-2 rounded-full bg-destructive animate-pulse"></span>
<span class="text-xs text-destructive">{{ connectionErrorMessage() || 'Connection error' }}</span>
<button
type="button"
(click)="retryConnection()"
class="ml-auto text-xs text-destructive hover:underline"
>
Retry
</button>
</div>
}
<!-- User Info -->
<div 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"
(click)="toggleProfileCard(); $event.stopPropagation()"
>
<app-user-avatar
[name]="currentUser()?.displayName || '?'"
[avatarUrl]="currentUser()?.avatarUrl"
size="sm"
[status]="currentUser()?.status"
[showStatusBadge]="true"
/>
<div class="flex-1 min-w-0">
<p class="font-medium text-sm text-foreground truncate text-left">
{{ currentUser()?.displayName || 'Unknown' }}
</p>
@if (showConnectionError() || isConnected()) {
<p class="text-xs text-muted-foreground text-left">
@if (showConnectionError()) {
<span class="text-destructive">Connection Error</span>
} @else if (isConnected()) {
<span class="text-green-500">Connected</span>
}
</p>
}
</div>
</button>
<div class="flex items-center gap-1">
<app-debug-console
launcherVariant="inline"
[showPanel]="false"
/>
<button
type="button"
(click)="toggleSettings()"
class="grid h-8 w-8 place-items-center rounded-md transition-colors hover:bg-secondary"
>
<ng-icon
name="lucideSettings"
class="w-4 h-4 text-muted-foreground"
/>
</button>
</div>
</div>
<!-- Voice Controls -->
<div
class="grid overflow-hidden duration-200 ease-out motion-reduce:transition-none"
style="transition-property: grid-template-rows, opacity, margin-top"
[style.gridTemplateRows]="isConnected() ? '1fr' : '0fr'"
[style.opacity]="isConnected() ? '1' : '0'"
[style.marginTop.rem]="isConnected() ? 0.5 : 0"
[style.visibility]="isConnected() ? 'visible' : 'hidden'"
[class.pointer-events-none]="!isConnected()"
[attr.aria-hidden]="isConnected() ? null : 'true'"
>
<div class="overflow-hidden">
<div class="flex items-center justify-center gap-2">
<!-- Mute Toggle -->
<button
type="button"
(click)="toggleMute()"
[class]="getMuteButtonClass()"
>
@if (isMuted()) {
<ng-icon
name="lucideMicOff"
class="w-5 h-5"
/>
} @else {
<ng-icon
name="lucideMic"
class="w-5 h-5"
/>
}
</button>
<!-- Deafen Toggle -->
<button
type="button"
(click)="toggleDeafen()"
[class]="getDeafenButtonClass()"
>
<ng-icon
name="lucideHeadphones"
class="w-5 h-5"
/>
</button>
<!-- Camera Toggle -->
<button
type="button"
(click)="toggleCamera()"
[class]="getCameraButtonClass()"
>
@if (isCameraEnabled()) {
<ng-icon
name="lucideVideoOff"
class="w-5 h-5"
/>
} @else {
<ng-icon
name="lucideVideo"
class="w-5 h-5"
/>
}
</button>
<!-- Screen Share Toggle -->
<button
type="button"
(click)="toggleScreenShare()"
[class]="getScreenShareButtonClass()"
>
@if (isScreenSharing()) {
<ng-icon
name="lucideMonitorOff"
class="w-5 h-5"
/>
} @else {
<ng-icon
name="lucideMonitor"
class="w-5 h-5"
/>
}
</button>
<!-- Disconnect -->
<button
type="button"
(click)="disconnect()"
class="inline-flex h-10 w-10 items-center justify-center rounded-md border border-destructive/20 bg-destructive/10 text-destructive transition-colors hover:bg-destructive/15"
>
<ng-icon
name="lucidePhoneOff"
class="w-5 h-5"
/>
</button>
</div>
</div>
</div>
</div>
@if (showScreenShareQualityDialog()) {
<app-screen-share-quality-dialog
[selectedQuality]="screenShareQuality()"
[includeSystemAudio]="includeSystemAudio()"
(cancelled)="onScreenShareQualityCancelled()"
(confirmed)="onScreenShareQualityConfirmed($event)"
/>
}