import React, { useMemo } from 'react'; import { Box, Spinner, Text, color } from 'folds'; import { useAtomValue } from 'jotai'; import classNames from 'classnames'; import { LiveChip } from './LiveChip'; import * as css from './styles.css'; import { CallRoomName } from './CallRoomName'; import { CallControl } from './CallControl'; import { ContainerColor } from '../../styles/ContainerColor.css'; import { useCallMembers, useCallSession } from '../../hooks/useCall'; import { ScreenSize, useScreenSize } from '../../hooks/useScreenSize'; import { MemberGlance } from './MemberGlance'; import { StatusDivider } from './components'; import { CallEmbed } from '../../plugins/call/CallEmbed'; import { useCallJoined } from '../../hooks/useCallEmbed'; import { useCallSpeakers } from '../../hooks/useCallSpeakers'; import { useMatrixClient } from '../../hooks/useMatrixClient'; import { MemberSpeaking } from './MemberSpeaking'; import { clockSkewAtom } from '../../state/clockSkew'; import { describeSkewVsServer } from '../../utils/clockSkew'; type CallStatusProps = { callEmbed: CallEmbed; }; export function CallStatus({ callEmbed }: CallStatusProps) { const { room } = callEmbed; const callSession = useCallSession(room); const callMembers = useCallMembers(callSession); const screenSize = useScreenSize(); const callJoined = useCallJoined(callEmbed); const speakers = useCallSpeakers(callEmbed); // [Gitea #146] Your own voice is on the mic button's level meter; the // "… is speaking" line is for everyone else. (Avatar rings still include you.) const mx = useMatrixClient(); const myUserId = mx.getUserId(); const otherSpeakers = useMemo( () => new Set([...speakers].filter((id) => id !== myUserId)), [speakers, myUserId], ); // [Gitea #158] Same warning as the top banner, where the user is looking during a call. const clockSkew = useAtomValue(clockSkewAtom); const compact = screenSize === ScreenSize.Mobile; const memberVisible = callJoined && callMembers.length > 0; return ( {memberVisible ? ( ) : ( )} {!compact && ( <> {clockSkew.warning && clockSkew.skewMs !== null && ( <> Device clock {describeSkewVsServer(clockSkew.skewMs)}: calls may fail )} {otherSpeakers.size > 0 && ( <> )} )} {memberVisible && ( )} {memberVisible && !compact && } {compact && ( )} ); }