The call-ended toast gets a Details button (and stays 10 s) that opens a card with who was in the call and the peak, connection verdict and reconnects, how long your / each person's / everyone's connection was poor (likely the server when everyone), RTT, packet loss and jitter, and your talk, mute, deafen and screenshare time, in technical wording. Deafened time is tracked by CallEmbed; the rest comes from the fork's new io.lotus.call_summary `details` (lotus.29). Settings → Calls gets "Summary After Calls" (on by default). Fixes #253 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
85 lines
2.7 KiB
TypeScript
85 lines
2.7 KiB
TypeScript
import React from 'react';
|
|
import FocusTrap from 'focus-trap-react';
|
|
import {
|
|
Box,
|
|
config,
|
|
Dialog,
|
|
Header,
|
|
Icon,
|
|
IconButton,
|
|
Icons,
|
|
Overlay,
|
|
OverlayBackdrop,
|
|
OverlayCenter,
|
|
Text,
|
|
} from 'folds';
|
|
import { useAtom } from 'jotai';
|
|
import { callSummaryViewAtom } from '../../state/callSummary';
|
|
import { useModalStyle } from '../../hooks/useModalStyle';
|
|
import { stopPropagation } from '../../utils/keyboard';
|
|
|
|
/**
|
|
* [Gitea #253] The post-call "Details" card: opened from the call-ended toast,
|
|
* shows who was in the call, connection quality and whose side it was on,
|
|
* network numbers and your own activity (technical wording).
|
|
*/
|
|
export function CallSummaryDialog() {
|
|
const [view, setView] = useAtom(callSummaryViewAtom);
|
|
const modalStyle = useModalStyle(400);
|
|
if (!view) return null;
|
|
const close = () => setView(undefined);
|
|
return (
|
|
<Overlay open backdrop={<OverlayBackdrop />}>
|
|
<OverlayCenter>
|
|
<FocusTrap
|
|
focusTrapOptions={{
|
|
initialFocus: false,
|
|
onDeactivate: close,
|
|
clickOutsideDeactivates: true,
|
|
escapeDeactivates: stopPropagation,
|
|
}}
|
|
>
|
|
<Dialog
|
|
variant="Surface"
|
|
role="dialog"
|
|
aria-modal="true"
|
|
aria-labelledby="call-summary-title"
|
|
style={modalStyle}
|
|
>
|
|
<Header
|
|
variant="Surface"
|
|
size="500"
|
|
style={{
|
|
padding: `0 ${config.space.S200} 0 ${config.space.S400}`,
|
|
borderBottomWidth: config.borderWidth.B300,
|
|
}}
|
|
>
|
|
<Box grow="Yes" alignItems="Center" gap="200">
|
|
<Icon src={Icons.Phone} size="100" />
|
|
<Text id="call-summary-title" size="H4" truncate>
|
|
Call summary · {view.roomName}
|
|
</Text>
|
|
</Box>
|
|
<IconButton size="300" radii="300" onClick={close} aria-label="Close">
|
|
<Icon src={Icons.Cross} />
|
|
</IconButton>
|
|
</Header>
|
|
<Box direction="Column" gap="400" style={{ padding: config.space.S400 }}>
|
|
{view.sections.map((section) => (
|
|
<Box key={section.title} direction="Column" gap="100">
|
|
<Text size="L400">{section.title}</Text>
|
|
{section.lines.map((line) => (
|
|
<Text key={line} size="T300" style={{ fontVariantNumeric: 'tabular-nums' }}>
|
|
{line}
|
|
</Text>
|
|
))}
|
|
</Box>
|
|
))}
|
|
</Box>
|
|
</Dialog>
|
|
</FocusTrap>
|
|
</OverlayCenter>
|
|
</Overlay>
|
|
);
|
|
}
|