Fixes #101 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
93 lines
2.9 KiB
TypeScript
93 lines
2.9 KiB
TypeScript
import React, { useEffect } from 'react';
|
|
import { Box, Button, Text, color, config } from 'folds';
|
|
|
|
export type ScreenshareConfirmProps = {
|
|
open: boolean;
|
|
onConfirm: () => void;
|
|
onCancel: () => void;
|
|
/**
|
|
* Horizontal placement relative to the trigger button. `Center` (the
|
|
* in-call bar's centered layout) transforms to center itself over the
|
|
* anchor; `Start` (the app-wide status bar, anchored to its own left edge)
|
|
* hugs the anchor's left edge instead.
|
|
*/
|
|
align?: 'Center' | 'Start';
|
|
};
|
|
|
|
/**
|
|
* [Gitea #101] Shared "Share your screen?" confirmation popover, used by both
|
|
* the in-call `CallControls` bar and the app-wide `CallStatus` bar's
|
|
* `CallControl`. Previously each bar carried its own near-identical copy;
|
|
* hoisted here so their behaviour (Escape / click-outside to close, confirm
|
|
* starts the share) can't drift apart.
|
|
*/
|
|
export function ScreenshareConfirm({
|
|
open,
|
|
onConfirm,
|
|
onCancel,
|
|
align = 'Center',
|
|
}: ScreenshareConfirmProps) {
|
|
useEffect(() => {
|
|
if (!open) return undefined;
|
|
const onKeyDown = (e: KeyboardEvent) => {
|
|
if (e.key === 'Escape') onCancel();
|
|
};
|
|
window.addEventListener('keydown', onKeyDown);
|
|
return () => window.removeEventListener('keydown', onKeyDown);
|
|
}, [open, onCancel]);
|
|
|
|
if (!open) return null;
|
|
|
|
return (
|
|
<>
|
|
<div
|
|
style={{ position: 'fixed', inset: 0, zIndex: 99 }}
|
|
onClick={onCancel}
|
|
aria-hidden="true"
|
|
/>
|
|
<Box
|
|
style={{
|
|
position: 'absolute',
|
|
bottom: '110%',
|
|
...(align === 'Center' ? { left: '50%', transform: 'translateX(-50%)' } : { left: 0 }),
|
|
background: color.Surface.Container,
|
|
border: `${config.borderWidth.B300} solid ${color.Surface.ContainerLine}`,
|
|
borderRadius: '0.75rem',
|
|
padding: '1rem 1.25rem',
|
|
zIndex: 100,
|
|
minWidth: '260px',
|
|
// Don't run past the screen edges on a narrow phone (centered via
|
|
// translateX(-50%)); clamp to the viewport minus a small margin.
|
|
maxWidth: `calc(100vw - 2 * ${config.space.S400})`,
|
|
boxShadow: '0 8px 32px rgba(0,0,0,0.35)',
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
gap: '0.75rem',
|
|
}}
|
|
>
|
|
<Text size="T300" style={{ fontWeight: 600 }}>
|
|
Share your screen?
|
|
</Text>
|
|
<Text size="T200" style={{ opacity: 0.75 }}>
|
|
Your screen will be visible to all participants in this call.
|
|
</Text>
|
|
<Box gap="200">
|
|
<Button size="300" variant="Success" fill="Solid" radii="300" onClick={onConfirm}>
|
|
<Text size="B300">Share</Text>
|
|
</Button>
|
|
<Button
|
|
size="300"
|
|
variant="Secondary"
|
|
fill="Soft"
|
|
radii="300"
|
|
outlined
|
|
onClick={onCancel}
|
|
>
|
|
<Text size="B300">Cancel</Text>
|
|
</Button>
|
|
</Box>
|
|
</Box>
|
|
</>
|
|
);
|
|
}
|