diff --git a/src/app.css b/src/app.css index 7ed78c07..54c39834 100644 --- a/src/app.css +++ b/src/app.css @@ -410,7 +410,7 @@ progress[value]::-webkit-progress-value { transition: width 0.5s; } -/* Anchors for fixed overlays (compose, search, reply) — main scroll lives in Page / PageContent flow */ +/* content width for fixed elements */ .left-content { @apply md:left-[calc(18.5rem+var(--sail))]; diff --git a/src/app/components/VideoCallContent.svelte b/src/app/components/VideoCallContent.svelte index b947ce03..35217cb7 100644 --- a/src/app/components/VideoCallContent.svelte +++ b/src/app/components/VideoCallContent.svelte @@ -11,23 +11,22 @@ import { currentVoiceSession, currentVoiceRoom, + VideoCallLayout, videoCallLayoutRevision, videoPrimaryTileKey, toggleVideoPrimaryTile, pubkeyFromLiveKitIdentity, } from "@app/voice" - type Variant = "mobile" | "desktop-split" | "desktop-full" - type Props = { - variant: Variant + layout: VideoCallLayout + mobile?: boolean url: string h: string - visible?: boolean class?: string } - type Tile = { + type VideoTile = { identity: string isLocal: boolean trackSid: string @@ -37,11 +36,18 @@ type TileLayout = "spotlight" | "default" | "strip" - const {variant, url, h, visible = true, class: className = ""}: Props = $props() + const {layout, mobile = false, url, h, class: className = ""}: Props = $props() - const roomMatches = $derived($currentVoiceRoom?.url === url && $currentVoiceRoom?.h === h) + const isViewingCurrentCallRoom = $derived( + $currentVoiceRoom?.url === url && $currentVoiceRoom?.h === h, + ) - const showPanel = $derived(visible && roomMatches) + const showPanel = $derived( + isViewingCurrentCallRoom && + (mobile + ? layout === VideoCallLayout.Video + : layout === VideoCallLayout.Split || layout === VideoCallLayout.Video), + ) const tiles = $derived.by(() => { // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- re-run when remote video subscribes @@ -52,7 +58,7 @@ } const room = session.room - const out: Tile[] = [] + const out: VideoTile[] = [] const lp = room.localParticipant if (session.cameraOn) { @@ -104,7 +110,7 @@ }) /** Identity + source only — LiveKit can change trackSid after publish, which broke spotlight + stale-key effect. */ - const tileKey = (t: Tile) => `${t.identity}\x1f${t.source}` + const tileKey = (t: VideoTile) => `${t.identity}\x1f${t.source}` const primaryTile = $derived.by(() => { const k = $videoPrimaryTileKey @@ -137,7 +143,7 @@ } }) - const labelFor = (identity: string, source: Tile["source"]) => { + const labelFor = (identity: string, source: VideoTile["source"]) => { const pk = pubkeyFromLiveKitIdentity(identity) const name = pk ? displayProfileByPubkey(pk) : "Unknown" return source === Track.Source.ScreenShare ? `${name} · screen` : name @@ -151,18 +157,16 @@ const panelChrome = $derived( cx( - variant === "mobile" && + mobile && "flex min-h-0 w-full flex-1 flex-col gap-2 overflow-y-auto overflow-x-hidden bg-base-200 px-2 pt-4 md:hidden pb-[calc(3.5rem+var(--saib))]", - variant === "desktop-split" && - "flex min-h-0 w-full min-w-0 flex-1 flex-col gap-2 overflow-hidden bg-base-200 px-2 pb-2 pt-4", - variant === "desktop-full" && + !mobile && "flex min-h-0 w-full min-w-0 flex-1 flex-col gap-2 overflow-hidden bg-base-200 px-2 pb-2 pt-4", className, ), ) -{#snippet videoTile(tile: Tile, layout: TileLayout)} +{#snippet videoTile(tile: VideoTile, layout: TileLayout)}