meet/app/dual-rooms/page.tsx
2026-01-13 16:40:33 +01:00

128 lines
4.6 KiB
TypeScript

'use client';
import { useRouter } from 'next/navigation';
import React, { Suspense, useState } from 'react';
import Link from 'next/link';
import { encodePassphrase, generateRoomId, randomString } from '@/lib/client-utils';
import styles from '../../styles/Home.module.css';
function DualRoomSetupContent() {
const router = useRouter();
const [e2ee, setE2ee] = useState(false);
const [sharedPassphrase, setSharedPassphrase] = useState(randomString(64));
const [primaryRoomName, setPrimaryRoomName] = useState('');
const [secondaryRoomName, setSecondaryRoomName] = useState('');
const startDualRoomMeeting = () => {
const primary = primaryRoomName || generateRoomId();
const secondary = secondaryRoomName || generateRoomId();
if (e2ee) {
router.push(
`/dual-rooms/session?primary=${primary}&secondary=${secondary}#${encodePassphrase(sharedPassphrase)}`,
);
} else {
router.push(`/dual-rooms/session?primary=${primary}&secondary=${secondary}`);
}
};
return (
<main className={styles.main} data-lk-theme="default">
<div className="header">
<img src="/images/livekit-meet-home.svg" alt="LiveKit Meet" width="360" height="45" />
<h2>Dual Room Video Conference</h2>
<p style={{ margin: '1rem 0', maxWidth: '600px' }}>
Connect to two rooms simultaneously - perfect for monitoring multiple sessions or watching
screen shares from a separate room.
</p>
</div>
<div className={styles.tabContainer}>
<div className={styles.tabContent}>
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem', marginBottom: '1rem' }}>
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
<label htmlFor="primaryRoom">
<strong>Primary Room</strong> (with full controls)
</label>
<input
id="primaryRoom"
type="text"
placeholder="Leave empty for random room name"
value={primaryRoomName}
onChange={(ev) => setPrimaryRoomName(ev.target.value)}
/>
</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
<label htmlFor="secondaryRoom">
<strong>Secondary Room</strong> (view-only, presentation mode)
</label>
<input
id="secondaryRoom"
type="text"
placeholder="Leave empty for random room name"
value={secondaryRoomName}
onChange={(ev) => setSecondaryRoomName(ev.target.value)}
/>
<small style={{ color: 'rgba(255, 255, 255, 0.6)', fontSize: '0.85rem' }}>
Audio muted by default. Camera/mic can be enabled on hover.
</small>
</div>
</div>
<button
style={{ marginTop: '1rem', width: '100%' }}
className="lk-button"
onClick={startDualRoomMeeting}
>
Start Dual Room Session
</button>
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem', marginTop: '1.5rem' }}>
<div style={{ display: 'flex', flexDirection: 'row', gap: '1rem' }}>
<input
id="use-e2ee"
type="checkbox"
checked={e2ee}
onChange={(ev) => setE2ee(ev.target.checked)}
/>
<label htmlFor="use-e2ee">Enable end-to-end encryption</label>
</div>
{e2ee && (
<div style={{ display: 'flex', flexDirection: 'row', gap: '1rem' }}>
<label htmlFor="passphrase">Passphrase</label>
<input
id="passphrase"
type="password"
value={sharedPassphrase}
onChange={(ev) => setSharedPassphrase(ev.target.value)}
/>
</div>
)}
</div>
</div>
</div>
<footer data-lk-theme="default">
<Link href="/" style={{ marginRight: '1rem' }}>
Back to Home
</Link>
Hosted on{' '}
<a href="https://livekit.io/cloud?ref=meet" rel="noopener">
LiveKit Cloud
</a>
. Source code on{' '}
<a href="https://github.com/livekit/meet?ref=meet" rel="noopener">
GitHub
</a>
.
</footer>
</main>
);
}
export default function DualRoomSetupPage() {
return (
<Suspense fallback="Loading">
<DualRoomSetupContent />
</Suspense>
);
}