Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
baaee68
Tims pre-join patch
tbscode Apr 29, 2024
f4ec238
updated patch package version
tbscode Apr 30, 2024
2064805
update ParticipantTile to alllow for custom placeholder
Simba14 Apr 30, 2024
b1638ef
update packages
Simba14 Apr 30, 2024
29afb7a
add build of new version
Simba14 Apr 30, 2024
acb1a4f
reversed version
tbscode May 4, 2024
a5f3ff3
update lock file
tbscode May 4, 2024
45e37fc
merged seans updates
tbscode May 4, 2024
7a7507e
resync fork with upstream
Simba14 Mar 25, 2025
ccd2775
Improve PreJoin screen
Simba14 Apr 4, 2025
2e43693
bump version
Simba14 Apr 4, 2025
ae713f3
pack react 2.9.0 package
Simba14 Apr 4, 2025
5296dc6
Merge pull request #1 from a-little-world/feat/pre-join-improvements
Simba14 Apr 4, 2025
785e4ec
remove packed packages
Simba14 Apr 15, 2025
8a0c30c
add changeset
Simba14 Apr 15, 2025
5945086
update with upstream/main
Simba14 Aug 11, 2025
14f87e1
WIP: connect device availability
Simba14 Aug 22, 2025
ebbba30
Improve PreJoin to when there are permission errors
Simba14 Nov 6, 2025
b2e8c43
add permissions logic to livekit room and toggle
Simba14 Nov 6, 2025
4e18da3
add more styles for prejoin
Simba14 Nov 7, 2025
d2de0a5
Update prejoin example
Simba14 Nov 8, 2025
84a53e4
Improve track toggle and Prejoin to allow for better permission handling
Simba14 Nov 11, 2025
76ec6df
Improve track toggle and Prejoin to allow for better permission handling
Simba14 Nov 11, 2025
5abc83f
update livekit to allow for re-call example in video call
Simba14 Nov 12, 2025
a18d9ac
delete old react build
Simba14 Nov 12, 2025
1b0ccd0
Merge pull request #3 from a-little-world/feat/improve-prejoin
Simba14 Apr 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/odd-files-talk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@livekit/components-react': minor
'@livekit/components-styles': minor
---

Improves the PreJoin component and allows for custom placeholders for each participant
8 changes: 8 additions & 0 deletions examples/nextjs/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ const EXAMPLE_ROUTES = {
title: 'Example usage of @livekit/track-processors for background blur',
href: () => `/processors`,
},
prejoin: {
title: 'Example usage of @livekit/prejoin',
href: () => `/prejoin`,
},
videoCall: {
title: 'Video call example (1:1 call structure)',
href: () => `/video-call-example`,
},
} as const;

const Home: NextPage = () => {
Expand Down
93 changes: 88 additions & 5 deletions examples/nextjs/pages/prejoin.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client';

import * as React from 'react';
import { PreJoin, setLogLevel } from '@livekit/components-react';
import { PreJoin, PreJoinValues, setLogLevel } from '@livekit/components-react';
import type { NextPage } from 'next';
import { Track, TrackProcessor } from 'livekit-client';
import { BackgroundBlur } from '@livekit/track-processors';
Expand All @@ -12,21 +12,104 @@ const PreJoinExample: NextPage = () => {
const [backgroundBlur, setBackgroundBlur] = React.useState<
TrackProcessor<Track.Kind.Video> | undefined
>(undefined);
const [errorMessage, setErrorMessage] = React.useState<string>('');
const [validationError, setValidationError] = React.useState<string>('');

React.useEffect(() => {
setBackgroundBlur(BackgroundBlur());
}, []);

const handleError = (error: Error) => {
console.log('error', error);
setErrorMessage(error.message);
// Clear validation error when a device error occurs
setValidationError('');
};

const handleValidate = (values: PreJoinValues) => {
const isValid = Boolean(values.audioAvailable || values.videoAvailable);
console.log('isValid', isValid, values);

if (!isValid) {
setValidationError('At least one device (audio or video) must be available to join.');
setErrorMessage(''); // Clear device error when validation fails
} else {
setValidationError(''); // Clear validation error on success
}

return isValid;
};

return (
<div data-lk-theme="default" style={{ height: '100vh' }}>
{(errorMessage || validationError) && (
<div
style={{
position: 'fixed',
top: '20px',
left: '50%',
transform: 'translateX(-50%)',
zIndex: 1000,
maxWidth: '500px',
width: '90%',
}}
>
<div
style={{
padding: '16px 20px',
backgroundColor: '#fee',
border: '2px solid #fcc',
borderRadius: '8px',
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
display: 'flex',
alignItems: 'flex-start',
gap: '12px',
}}
>
<span style={{ fontSize: '20px', lineHeight: 1 }}>⚠️</span>
<div style={{ flex: 1 }}>
<strong style={{ display: 'block', marginBottom: '4px', color: '#c00' }}>
{validationError ? 'Validation Error' : 'Device Error'}
</strong>
<p style={{ margin: 0, color: '#600', fontSize: '14px' }}>
{validationError || errorMessage}
</p>
</div>
<button
onClick={() => {
setErrorMessage('');
setValidationError('');
}}
style={{
background: 'transparent',
border: 'none',
fontSize: '20px',
cursor: 'pointer',
padding: '0',
lineHeight: 1,
color: '#999',
}}
>
×
</button>
</div>
</div>
)}

<PreJoin
onError={handleError}
onValidate={handleValidate}
videoProcessor={backgroundBlur}
defaults={{ videoDeviceId: '' }}
defaults={{
videoDeviceId: '',
videoEnabled: true,
audioEnabled: true,
}}
onSubmit={(values) => {
values.audioDeviceId;
}}
onValidate={(values) => {
return true;
// Clear errors on successful submit
setErrorMessage('');
setValidationError('');
}}
/>
</div>
Expand Down
Loading