Files
dumpsterChat/web/src/components/VoicePanel.tsx
T
hobokenchicken 2b45b11ea8 fix: screenshare rendering, voice panel layout, SW cache bust with git SHA
- VideoGrid: add screen share track display with proper sizing
- participantToVoice: detect ScreenShare + ScreenShareAudio tracks
- VoicePanel: flex layout, no scroll, tiles dynamically fill space
- VoiceChannel: show screen/camera icons in participant list
- vite.config: inject git SHA into SW CACHE_VERSION on build
2026-07-06 17:49:17 +00:00

62 lines
2.4 KiB
TypeScript

import { useVoiceStore } from '../stores/voice.ts';
import { VoiceControls } from './VoiceControls.tsx';
import { VideoGrid } from './VideoGrid.tsx';
import { AudioRenderers } from './AudioRenderers.tsx';
export function VoicePanel() {
const isConnected = useVoiceStore((state) => state.isConnected);
const currentRoom = useVoiceStore((state) => state.currentRoom);
const currentRoomName = useVoiceStore((state) => state.currentRoomName);
const error = useVoiceStore((state) => state.error);
const whispers = useVoiceStore((state) => state.whispers);
const dismissWhisper = useVoiceStore((state) => state.dismissWhisper);
if (!currentRoom) return null;
return (
<div className="h-full flex flex-col bg-gb-bg-s font-mono text-sm">
{/* Header */}
<div className="px-3 py-1.5 border-b border-gb-bg-t flex items-center gap-2 shrink-0">
<span className="text-gb-fg-f text-xs">
<span className="text-gb-orange font-bold">VOICE</span>
</span>
<span className="text-gb-fg-s truncate flex-1 text-xs">
{currentRoomName || currentRoom}
</span>
<span className={`text-xxs ${isConnected ? 'text-gb-green' : 'text-gb-fg-f'}`}>
{isConnected ? '● LIVE' : '◐ connecting...'}
</span>
</div>
{error && (
<div className="px-3 py-1 text-gb-red text-xxs border-b border-gb-bg-t shrink-0">
! {error}
</div>
)}
{whispers.length > 0 && (
<div className="px-3 py-1.5 border-b border-gb-bg-t shrink-0">
<div className="text-xxs text-gb-fg-f mb-1"> whispers </div>
{whispers.map((w) => (
<div key={w.timestamp} className="flex items-center gap-2 py-0.5 text-xs text-gb-orange">
<span>🔊</span>
<span className="font-bold">{w.fromUsername}</span>
<span className="text-gb-fg-s truncate">{w.message || 'whispered'}</span>
<button className="ml-auto text-xxs text-gb-fg-f hover:text-gb-fg-s" onClick={() => dismissWhisper(w.timestamp)}>[x]</button>
</div>
))}
</div>
)}
{/* Video area — fills remaining space, never scrolls */}
<VideoGrid />
<AudioRenderers />
{/* Controls */}
<div className="px-3 py-1.5 border-t border-gb-bg-t shrink-0">
<VoiceControls />
</div>
</div>
);
}