Line data Source code
1 : import * as React from 'react';
2 :
3 : import * as styles from './session_url_share_overlay.module.css';
4 :
5 : import { CheckIcon, PaperclipIcon } from '../../ui/foundations/symbol_icon.js';
6 : import { IconButton } from '../../ui/foundations/button.js';
7 : import { TextInput } from '../../ui/foundations/text_input.js';
8 : import { sleep } from '../../utils/sleep.js';
9 :
10 1 : const COPY_CHECKMARK_DURATION_MS = 1000;
11 :
12 : interface Props {
13 : /// The link, null while it is generated
14 : url: string | null;
15 : /// The label of the link
16 : ariaLabel: string;
17 : /// The copy button, the overlay focuses it
18 : buttonRef?: React.Ref<HTMLButtonElement>;
19 : }
20 :
21 : /// A shared link with a button that copies it to the clipboard
22 1 : export const ShareURLField: React.FC<Props> = ({ url, ariaLabel, buttonRef }) => {
23 : // Did the last copy finish and the checkmark still shows?
24 1 : const [copied, setCopied] = React.useState(false);
25 :
26 1 : const copyURL = React.useCallback((event: React.MouseEvent) => {
27 1 : if (!url) return;
28 1 : event.stopPropagation();
29 1 : const copy = async () => {
30 1 : try {
31 1 : await navigator.clipboard.writeText(url);
32 1 : } catch {
33 : // The checkmark shows either way
34 0 : }
35 1 : setCopied(true);
36 1 : await sleep(COPY_CHECKMARK_DURATION_MS);
37 1 : setCopied(false);
38 1 : };
39 1 : void copy();
40 1 : }, [url]);
41 :
42 1 : const ButtonIcon = copied ? CheckIcon : PaperclipIcon;
43 1 : return (
44 1 : <div className={styles.sharing_url}>
45 1 : <TextInput disabled={true} aria-label={ariaLabel} value={url ?? ''} />
46 1 : <IconButton
47 1 : ref={buttonRef}
48 1 : onClick={copyURL}
49 1 : disabled={url == null}
50 1 : aria-label="Copy to Clipboard"
51 : >
52 1 : <ButtonIcon />
53 1 : </IconButton>
54 1 : <div className={styles.sharing_url_stats}>{url?.length ?? 0} characters</div>
55 1 : </div>
56 : );
57 1 : };
|