refactor: dynamic screen share engine with independent resolution/fps/mode axes

Replace rigid SCREEN_QUALITY_MAP (6 hardcoded VideoPreset strings) with a
builder function that computes bitrate, degradation preference, and content
hint from three independent axes (height, fps, content mode). Camera is
decoupled onto a fixed 720p30 preset so screen share changes no longer
affect camera quality. New ScreenShareSettingsPopover replaces the old
VideoQualityPopover with pill-style selectors. Store migrated to v5 with
backwards-compatible migration from videoQuality string.
This commit is contained in:
Jannis Braun
2026-02-24 02:16:15 +01:00
parent 9b0d319ab2
commit f808a204e7
8 changed files with 313 additions and 197 deletions
@@ -2,7 +2,7 @@ import React, { useRef, useEffect, useState, useCallback } from 'react';
import { Avatar } from '../ui/Avatar';
import { useVoiceStore } from '../../stores/voiceStore';
import { getActiveRoom, setStreamSubscription } from '../../hooks/useLiveKit';
import { VideoQualityPopover } from './VideoQualityPopover';
import { ScreenShareSettingsPopover } from './ScreenShareSettingsPopover';
import { stopScreenShare, changeScreenShare } from '../../utils/screenShare';
import type { StreamTile as StreamTileType } from '../../hooks/useLiveKit';
@@ -259,7 +259,7 @@ export function StreamTile({ tile, large }: StreamTileProps) {
onClick={() => setQualityPopoverOpen(!qualityPopoverOpen)}
className="w-full flex items-center justify-between px-2 py-1.5 text-sm text-discord-text-secondary hover:bg-discord-modifier-hover rounded transition-colors"
>
<span>{useVoiceStore.getState().videoQuality}</span>
<span>{`${useVoiceStore.getState().screenShareConfig.height}p ${useVoiceStore.getState().screenShareConfig.fps}fps`}</span>
<svg
width="12"
height="12"
@@ -270,7 +270,7 @@ export function StreamTile({ tile, large }: StreamTileProps) {
</svg>
</button>
{qualityPopoverOpen && (
<VideoQualityPopover
<ScreenShareSettingsPopover
open={qualityPopoverOpen}
onClose={() => setQualityPopoverOpen(false)}
/>