Skip to content

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

  1. Comprehensive Call Controls:

    • Audio/video mute toggles
    • Screen sharing
    • Call termination
    • Participant management
  2. Role-based Features:

    • Host-specific controls (recording, remote control)
    • Participant features (raise hand, request host)
  3. Peripheral Device Integration:

    • Specialized device connection
    • Status indicators
  4. 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 data

Event 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 device

Computed 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

  1. CallEndButton:

    • Red circular button
    • PhoneMissedCall icon
    • "End Call" tooltip
  2. AudioToggleButton:

    • Toggles between Microphone/MicrophoneMute icons
    • Dynamic tooltip ("Turn Microphone On/Off")
    • Hidden when noAudio is true
  3. VideoToggleButton:

    • Toggles between VideoCamera/VideoCameraOff icons
    • Dynamic tooltip ("Turn Camera On/Off")
    • Hidden when noVideo is true
  4. PeripheralButton:

    • Dynamic icon based on connected peripherals
    • Loading state indicator
    • Tooltip shows connection status
  5. RecordingButton (Host-only):

    • Toggles between RecordCircle/Stop icons
    • Red accent when active
    • "Start/Stop Recording" tooltip
  6. ScreenShareButton (Host-only):

    • Slideshow2 icon
    • Red accent when active
    • "Start/Stop Screenshare" tooltip
  7. RaiseHandButton:

    • Hand icon
    • Badge counter for raised hands
    • Gray background when user's hand is raised
  8. HostRequestButton:

    • Admin icon
    • Visible when canRequestHostAccess is 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

Released under the MIT License.