From edceb92acc2b29e39066c3e67bfb581242d22526 Mon Sep 17 00:00:00 2001 From: mplorentz Date: Thu, 26 Mar 2026 10:49:14 -0400 Subject: [PATCH] add video to livekit calls --- src/app.css | 42 ++++++ src/app/components/VideoCallContent.svelte | 131 +++++++++++++++++++ src/app/components/VideoCallVideo.svelte | 27 ++++ src/app/components/VoiceWidget.svelte | 11 ++ src/app/voice.ts | 92 ++++++++++++- src/lib/components/PageContent.svelte | 13 +- src/routes/spaces/[relay]/[h]/+layout.svelte | 11 +- src/routes/spaces/[relay]/[h]/+page.svelte | 110 +++++++++++++++- 8 files changed, 424 insertions(+), 13 deletions(-) create mode 100644 src/app/components/VideoCallContent.svelte create mode 100644 src/app/components/VideoCallVideo.svelte diff --git a/src/app.css b/src/app.css index ae198f34..8e9d04a8 100644 --- a/src/app.css +++ b/src/app.css @@ -394,6 +394,35 @@ progress[value]::-webkit-progress-value { @apply w-full md:left-[18.5rem] md:w-[calc(100%-18.5rem-var(--sair))]; } +.cw-video-call-content { + @apply w-full md:left-[calc(18.5rem+18rem)] md:w-[calc(100%-18.5rem-18rem-var(--sair))]; +} + +/* Voice: desktop split — plain CSS so / in calc is not parsed as Tailwind slash syntax */ +.cw-split-video { + width: 100%; +} + +.cw-split-chat { + width: 100%; +} + +@media (min-width: 768px) { + .cw-split-video { + left: 18.5rem; + right: auto; + width: calc((100vw - 18.5rem - var(--sair)) / 2); + max-width: none; + } + + .cw-split-chat { + left: calc(18.5rem + (100vw - 18.5rem - var(--sair)) / 2); + right: auto; + width: calc((100vw - 18.5rem - var(--sair)) / 2); + max-width: none; + } +} + .cw-full { @apply w-full md:left-[4rem] md:w-[calc(100%-4rem-var(--sair))]; } @@ -430,6 +459,19 @@ body.keyboard-open .hide-on-keyboard { @apply min-w-0; } +.chat__compose-zone.cw-video-call-content { + @apply md:left-[calc(18.5rem+18rem)] md:w-[calc(100%-18.5rem-18rem-var(--sair))]; +} + +@media (min-width: 768px) { + .chat__compose-zone.cw-split-chat { + left: calc(18.5rem + (100vw - 18.5rem - var(--sair)) / 2); + right: auto; + width: calc((100vw - 18.5rem - var(--sair)) / 2); + max-width: none; + } +} + .chat__scroll-down { @apply pb-sai fixed bottom-28 right-4 z-feature md:bottom-16; } diff --git a/src/app/components/VideoCallContent.svelte b/src/app/components/VideoCallContent.svelte new file mode 100644 index 00000000..1da29813 --- /dev/null +++ b/src/app/components/VideoCallContent.svelte @@ -0,0 +1,131 @@ + + +{#if showPanel && (showTileGrid || allowEmptyPanel)} + +{/if} diff --git a/src/app/components/VideoCallVideo.svelte b/src/app/components/VideoCallVideo.svelte new file mode 100644 index 00000000..fbc3af89 --- /dev/null +++ b/src/app/components/VideoCallVideo.svelte @@ -0,0 +1,27 @@ + + + diff --git a/src/app/components/VoiceWidget.svelte b/src/app/components/VoiceWidget.svelte index ae3f3eb5..7ff0ebb7 100644 --- a/src/app/components/VoiceWidget.svelte +++ b/src/app/components/VoiceWidget.svelte @@ -3,6 +3,8 @@ import {displayRelayUrl} from "@welshman/util" import Microphone from "@assets/icons/microphone.svg?dataurl" import MicrophoneOff from "@assets/icons/microphone-off.svg?dataurl" + import Videocamera from "@assets/icons/videocamera.svg?dataurl" + import VideocameraRecord from "@assets/icons/videocamera-record.svg?dataurl" import PhoneRounded from "@assets/icons/phone-rounded.svg?dataurl" import PhoneCallingRounded from "@assets/icons/phone-calling-rounded.svg?dataurl" import CloseCircle from "@assets/icons/close-circle.svg?dataurl" @@ -15,6 +17,7 @@ voiceState, leaveVoiceRoom, toggleMute, + toggleCamera, rejoinVoiceRoom, cancelJoinVoiceRoom, } from "@app/voice" @@ -60,6 +63,14 @@ onclick={toggleMute}> + + + + + {/if}