2026-06-02 19:31:30 -04:00
|
|
|
import React, { useCallback, useState } from 'react';
|
2026-06-19 18:12:25 -04:00
|
|
|
import { Box, Button, color, config, Icon, Icons, Text } from 'folds';
|
2026-06-02 19:31:30 -04:00
|
|
|
import { SequenceCard } from '../../../components/sequence-card';
|
|
|
|
|
import { SequenceCardStyle } from '../../room-settings/styles.css';
|
|
|
|
|
import { SettingTile } from '../../../components/setting-tile';
|
|
|
|
|
import { CutoutCard } from '../../../components/cutout-card';
|
|
|
|
|
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
|
|
|
|
import { useRoom } from '../../../hooks/useRoom';
|
|
|
|
|
import { getMatrixToRoom } from '../../../plugins/matrix-to';
|
|
|
|
|
|
|
|
|
|
export function RoomShareInvite() {
|
|
|
|
|
const mx = useMatrixClient();
|
|
|
|
|
const room = useRoom();
|
|
|
|
|
const [copied, setCopied] = useState(false);
|
2026-06-19 18:12:25 -04:00
|
|
|
const [qrError, setQrError] = useState(false);
|
2026-06-02 19:31:30 -04:00
|
|
|
|
|
|
|
|
const domain = mx.getDomain() ?? undefined;
|
|
|
|
|
const inviteUrl = getMatrixToRoom(room.roomId, domain ? [domain] : undefined);
|
|
|
|
|
const qrSrc = `https://api.qrserver.com/v1/create-qr-code/?size=160x160&data=${encodeURIComponent(inviteUrl)}`;
|
|
|
|
|
|
|
|
|
|
const handleCopy = useCallback(() => {
|
|
|
|
|
navigator.clipboard.writeText(inviteUrl).then(() => {
|
|
|
|
|
setCopied(true);
|
|
|
|
|
setTimeout(() => setCopied(false), 2000);
|
|
|
|
|
});
|
|
|
|
|
}, [inviteUrl]);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<SequenceCard
|
|
|
|
|
className={SequenceCardStyle}
|
|
|
|
|
variant="SurfaceVariant"
|
|
|
|
|
direction="Column"
|
|
|
|
|
gap="400"
|
|
|
|
|
>
|
|
|
|
|
<SettingTile
|
|
|
|
|
title="Share Room"
|
|
|
|
|
description="Share this invite link so others can join the room."
|
|
|
|
|
/>
|
|
|
|
|
<CutoutCard variant="Surface" style={{ padding: config.space.S300 }}>
|
|
|
|
|
<Box direction="Column" gap="300">
|
|
|
|
|
<Box gap="200" alignItems="Center">
|
|
|
|
|
<Box grow="Yes">
|
|
|
|
|
<Text
|
|
|
|
|
size="T200"
|
|
|
|
|
style={{
|
|
|
|
|
wordBreak: 'break-all',
|
|
|
|
|
userSelect: 'all',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{inviteUrl}
|
|
|
|
|
</Text>
|
|
|
|
|
</Box>
|
|
|
|
|
<Box shrink="No">
|
|
|
|
|
<Button
|
|
|
|
|
size="300"
|
|
|
|
|
variant={copied ? 'Success' : 'Secondary'}
|
|
|
|
|
fill={copied ? 'Solid' : 'Soft'}
|
|
|
|
|
radii="300"
|
|
|
|
|
onClick={handleCopy}
|
|
|
|
|
before={<Icon size="100" src={copied ? Icons.Check : Icons.Link} />}
|
|
|
|
|
>
|
|
|
|
|
<Text size="B300">{copied ? 'Copied!' : 'Copy Link'}</Text>
|
|
|
|
|
</Button>
|
|
|
|
|
</Box>
|
|
|
|
|
</Box>
|
|
|
|
|
<Box justifyContent="Center">
|
2026-06-19 18:12:25 -04:00
|
|
|
{qrError ? (
|
|
|
|
|
<Box
|
|
|
|
|
direction="Column"
|
|
|
|
|
alignItems="Center"
|
|
|
|
|
justifyContent="Center"
|
|
|
|
|
gap="100"
|
|
|
|
|
style={{
|
|
|
|
|
width: 160,
|
|
|
|
|
height: 160,
|
|
|
|
|
borderRadius: config.radii.R300,
|
|
|
|
|
background: color.SurfaceVariant.Container,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Icon size="400" src={Icons.Warning} />
|
|
|
|
|
<Text size="T200" priority="300" align="Center">
|
|
|
|
|
QR code unavailable
|
|
|
|
|
</Text>
|
|
|
|
|
</Box>
|
|
|
|
|
) : (
|
|
|
|
|
<img
|
|
|
|
|
src={qrSrc}
|
|
|
|
|
alt="QR code for room invite link"
|
|
|
|
|
width={160}
|
|
|
|
|
height={160}
|
|
|
|
|
loading="lazy"
|
|
|
|
|
onError={() => setQrError(true)}
|
|
|
|
|
style={{ display: 'block', borderRadius: config.radii.R300 }}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
2026-06-02 19:31:30 -04:00
|
|
|
</Box>
|
|
|
|
|
</Box>
|
|
|
|
|
</CutoutCard>
|
|
|
|
|
</SequenceCard>
|
|
|
|
|
);
|
|
|
|
|
}
|