import {useEffect, useRef, useState} from 'react' import {VIDEO_QUALITIES, type VideoQuality} from './p2p/settings' import {useNetwork} from './useNetwork' const short = (id: string) => id.slice(0, 8) + '…' // Screen capture is desktop-only in practice; hide the button where the API // doesn't exist (most mobile browsers). const canShareScreen = typeof navigator.mediaDevices?.getDisplayMedia === 'function' const btn: React.CSSProperties = { padding: '0.4rem 1rem', borderRadius: 6, border: '1px solid #888', background: '#fff', cursor: 'pointer', fontSize: '1rem' } const primaryBtn: React.CSSProperties = { ...btn, background: '#1a7f37', borderColor: '#1a7f37', color: '#fff' } const dangerBtn: React.CSSProperties = { ...btn, background: '#c62828', borderColor: '#c62828', color: '#fff' } // Merged into a button's style whenever it is disabled, so the explicit // background colors above don't leave a disabled button looking clickable. const disabledStyle: React.CSSProperties = { opacity: 0.4, cursor: 'not-allowed' } // Square icon-only buttons for the in-call bar. Their meaning is carried by // the icon plus a title tooltip and aria-label. const iconBtn: React.CSSProperties = { ...btn, padding: '0.45rem', display: 'inline-flex', alignItems: 'center', justifyContent: 'center' } // An icon button whose state is engaged (muted / sharing). const engagedIconBtn: React.CSSProperties = { ...iconBtn, background: '#555', borderColor: '#555', color: '#fff' } const dangerIconBtn: React.CSSProperties = { ...iconBtn, background: '#c62828', borderColor: '#c62828', color: '#fff' } // Badge overlaid on the remote video reporting the other party's mute state. const muteChip: React.CSSProperties = { background: 'rgba(0, 0, 0, 0.65)', color: '#fff', borderRadius: 999, padding: '0.3rem', display: 'inline-flex', alignItems: 'center' } // Stroke-style icon paths (Feather icons, MIT), drawn with currentColor. const ICONS = { mic: ( <> ), micOff: ( <> ), video: ( <> ), videoOff: ( <> ), monitor: ( <> ), phone: ( ) } as const function Icon({ name, size = 18, style }: { name: keyof typeof ICONS size?: number style?: React.CSSProperties }) { return ( {ICONS[name]} ) } function VideoView({ stream, muted, style }: { stream: MediaStream | null muted: boolean style: React.CSSProperties }) { const ref = useRef(null) useEffect(() => { if (ref.current && ref.current.srcObject !== stream) { ref.current.srcObject = stream } }, [stream]) return