Appearance
Video Call Controls Component Documentation
File: src/components/app/call/videoControls.svelte
Overview
This component provides the interactive control panel for video conferencing, offering buttons for all major call functions including audio/video control, screen sharing, recording, and participant management.
Key Features
Comprehensive Call Controls:
- Audio/video mute toggles
- Screen sharing
- Call termination
- Participant management
Role-based Features:
- Host-specific controls (recording, remote control)
- Participant features (raise hand, request host)
Peripheral Device Integration:
- Specialized device connection
- Status indicators
Responsive Design:
- Mobile-friendly layout
- Speed dial for secondary functions
- Tooltips for all controls
Component Structure
Props
typescript
export let audioOn: boolean; // Audio enabled state
export let videoOn: boolean; // Video enabled state
export let isRecording: boolean; // Recording status
export let isPresenting: boolean; // Screen sharing status
export let isPeripheralConnected: boolean; // Peripheral connection state
export let noAudio: boolean; // Audio disabled flag
export let noVideo: boolean; // Video disabled flag
export let me: IParticipant; // Current user data
export let isPeripheralLoading: boolean; // Peripheral loading state
export let handsRaised: number; // Raised hands count
export let canRequestHostAccess: boolean; // Host access request flag
export let peripherals: IPeripheral[]; // Peripheral devices
export let rapidUser: any; // Rapid user dataEvent Dispatchers
typescript
// Core controls
dispatch("endCall") // Terminate call
dispatch("toggleAudio") // Toggle microphone
dispatch("toggleVideo") // Toggle camera
// Advanced features
dispatch("openSettings") // Open settings panel
dispatch("toggleRecord") // Toggle recording
dispatch("captureScreen") // Take screenshot
dispatch("toggleScreenShare") // Toggle screen sharing
dispatch("toggleRaiseHand") // Raise/lower hand
dispatch("openParticipantsView") // Show participants
dispatch("openControlsView") // Show remote controls
dispatch("requestHostAccess") // Request host privileges
dispatch("togglePeripheral") // Toggle peripheral deviceComputed Properties
typescript
$: isHost = me?.role === "chair"; // Host status
$: showPeripheralButton = !!peripherals?.length; // Peripheral visibility
$: peripheralsIcon = // Dynamic peripheral icon
peripherals?.length == 1
? peripherals[0].icon
: isPeripheralLoading
? "svg-spinners:180-ring-with-bg"
: "hugeicons:audio-book-04";UI Components
Main Control Bar
svelte
<div class="flex gap-6 sm:gap-10 mx-auto -mt-4">
<!-- Primary controls -->
<CallEndButton on:click={endCall} />
<AudioToggleButton bind:audioOn on:toggle={toggleAudio} />
<VideoToggleButton bind:videoOn on:toggle={toggleVideo} />
<!-- Peripheral control -->
<PeripheralButton
bind:connected={isPeripheralConnected}
bind:loading={isPeripheralLoading}
on:toggle={togglePeripheral}
/>
<!-- Host controls -->
{#if isHost}
<RecordingButton bind:active={isRecording} on:toggle={toggleRecord} />
<ScreenShareButton bind:active={isPresenting} on:toggle={toggleScreenShare} />
{/if}
<!-- Participant controls -->
<RaiseHandButton
bind:raised={me?.buzz_time}
count={handsRaised}
on:toggle={toggleRaiseHand}
/>
<!-- Utility buttons -->
<SettingsButton on:click={openSettings} />
<ParticipantsButton on:click={openParticipantsView} />
<GalleryButton on:click={toggleGallery} />
</div>
<!-- Mobile speed dial -->
<SpeedDial
{endCall}
{toggleAudio}
{toggleVideo}
{openSettings}
{toggleRecord}
{captureScreen}
{toggleScreenShare}
{toggleRaiseHand}
{openParticipantsView}
{openControlsView}
{audioOn}
{videoOn}
{noAudio}
{isHost}
{isRecording}
{isPresenting}
{handsRaised}
{me}
/>Button Components
CallEndButton:
- Red circular button
- PhoneMissedCall icon
- "End Call" tooltip
AudioToggleButton:
- Toggles between Microphone/MicrophoneMute icons
- Dynamic tooltip ("Turn Microphone On/Off")
- Hidden when
noAudiois true
VideoToggleButton:
- Toggles between VideoCamera/VideoCameraOff icons
- Dynamic tooltip ("Turn Camera On/Off")
- Hidden when
noVideois true
PeripheralButton:
- Dynamic icon based on connected peripherals
- Loading state indicator
- Tooltip shows connection status
RecordingButton (Host-only):
- Toggles between RecordCircle/Stop icons
- Red accent when active
- "Start/Stop Recording" tooltip
ScreenShareButton (Host-only):
- Slideshow2 icon
- Red accent when active
- "Start/Stop Screenshare" tooltip
RaiseHandButton:
- Hand icon
- Badge counter for raised hands
- Gray background when user's hand is raised
HostRequestButton:
- Admin icon
- Visible when
canRequestHostAccessis true - "Request Host Access" tooltip
Technical Implementation
Responsive Design
- Uses flexbox for control bar layout
- Mobile devices show condensed controls via SpeedDial
- Hidden elements on small screens (sm:flex)
State Management
- Props control button visibility and state
- Computed properties handle dynamic behaviors
- Event dispatchers communicate with parent
Accessibility
- All buttons have tooltips
- Clear visual states for toggles
- Semantic HTML structure
Usage Example
svelte
<script>
import VideoControls from "./videoControls.svelte";
let audioOn = true;
let videoOn = true;
let isHost = true;
function handleEndCall() {
// Call termination logic
}
</script>
<VideoControls
bind:audioOn
bind:videoOn
{isHost}
on:endCall={handleEndCall}
/>Dependencies
- @steeze-ui icons
- Svelte transitions
- Custom tooltip action
- Permission service
- Keycloak user service
Styling Notes
- Circular buttons with consistent sizing
- Color-coded states (red for destructive actions)
- Smooth transitions
- Hidden scrollbars for clean appearance