Introduce speaker selection component requested by users to allow audio
output device configuration before entering calls.
Enables users to test and configure their preferred audio output device
during prejoin setup, ensuring proper audio routing before call begins.
Improves user experience by preventing audio issues during meetings.
Implement audio output device persistence in localStorage since LiveKit
doesn't handle this by default.
Ensures user's preferred audio output selection is remembered across
sessions, improving user experience by maintaining device preferences
without requiring re-selection on each visit.
Add symmetric shadows at top and bottom of white circle buttons to
ensure sufficient visual contrast against varying background colors.
Improves button visibility and accessibility by providing consistent
visual definition regardless of background context.
Major refactor of device select component with several key improvements:
* Set permission=true for Firefox compatibility - without this flag,
device list returns empty on Firefox
* Implement controlled component pattern for active device selection,
ensuring sync with preview track state
* Remove default device handling as controlled behavior eliminates need
* Render selectors only after permissions granted to prevent double
permission prompts (separate for mic/camera)
Ensures usePreviewTrack handles initial permission request, then
selectors allow specific device choice once access is granted.
Update default device IDs when preview track starts to match the
actual device being used. LiveKit returns 'default' string which may
not exist in device list, causing ID mismatch.
Prevents misleading situation where default device ID doesn't
correspond to the device actually used by the preview track. Now
synchronizes IDs once preview starts for accurate device tracking.
Reset video element reference when track stops to ensure "camera
starting" to "camera started" message transitions work correctly on
repeated camera toggles.
Previously only worked on initial video element load. Now properly
handles state transitions for multiple camera enable/disable cycles.
Update select toggle device component used in conference to display
upward arrow when dropdown menu opens above the select component.
Improves visual consistency by matching arrow direction with actual
menu opening direction, providing clearer user interface feedback.
Fix useTrackToggle hook that wasn't properly muting/unmuting tracks
outside room context. Previously only toggled boolean state via
setUpManualToggle without actual track control.
This caused misleading visual feedback where prejoin showed "camera
disabled" while hardware remained active. Users could see camera/mic
LEDs still on despite UI indicating otherwise.
Refactor provides genuine track muting for accurate user feedback.
Decouple prejoin components from conference context to enable different
behaviors when inside vs outside room environments. Components can now
evolve independently with lighter coupling.
Refactor layout structure to prepare for upcoming speaker selector
introduction. This decoupling allows for more flexible component
evolution and cleaner architecture.
Provides Safari-specific UI guidance that matches the browser's unique
permission flow, ensuring users receive appropriate instructions for
their specific browser environment.
Attempt to resolve React aria warnings by adding aria-label to form
components. Visual label should be reusable by screen readers, but
warning persists with only form wrapper as apparent difference.
Uncertain if warning is harmful. Added aria-label as potential fix but
removed after feedback from Sophie and Manu. Warning remains annoying
during development.
Add polling mechanism to detect permission changes on Safari where
permission change events are not reliably fired when users interact
with system prompts.
Implements 500ms polling when permissions are in 'prompt' state to
catch grant/deny actions that Safari's event system misses. Polling
stops when permissions resolve to prevent performance impact.
Fixes UI inconsistency where Safari users' permission changes weren't
detected, leaving outdated status displays.
Add explicit messaging on join screen explaining why users should
allow camera/microphone access, with quick button to open permission
modal dialog.
Targets first-time users who need guidance on permission requirements.
Message persists until permissions are granted to ensure proper user
onboarding and reduce support issues.
Introduce accessible visual indicator on device toggle buttons to hint
when users have permission issues that require action.
Provides clear visual warning to help users understand they need to
resolve permissions before using camera/microphone features. Follows
accessibility guidelines for proper user guidance.
Introduce guided permissions dialog to help users understand and
resolve camera/microphone access issues step-by-step.
Addresses common user support requests where users cannot enable their
hardware and don't understand the permission requirements. Provides
clear instructions to reduce confusion and support burden.
Image was quickly prototyped. It will be updated later on.
Introduce permissions watcher that continuously monitors browser
permission changes and keeps the valtio global store synchronized
with actual browser permission state.
Introduce new global state management to watch and expose browser
permissions status across the application.
Sets foundation for upcoming changes that will prevent the app from
offering hardware features (camera/microphone) when permissions are
not granted, improving user experience and reducing confusion.
Major refactoring of prejoin interface to improve user onboarding and
camera/microphone permission handling:
* Create extensible hint message system for easier addition of
permission-related guidance.
* Design flexible layout structure to accommodate future camera/mic
options and component selection features.
* Establish foundation for comprehensive prejoin redesign
In upcoming commits, UX will be enhanced to a smoother user
experience when joining calls and requesting media permissions.
Extract clipboard content logic from UI components into a separate
custom hook to decouple interface elements from clipboard functionality.
Creates a reusable hook that can better adapt to future UX changes
without requiring modifications to individual UI components.
Update PIN formatting to remove space before the # symbol to clearly
indicate that # is part of the complete PIN code.
Improves user understanding that the hash symbol is an integral part
of the PIN entry sequence, not a separate element.
Add telephony information to the share dialog when available to help
users take advantage of the newly introduced phone join feature.
Promotes phone participation as an alternative connection method when
users need it, improving meeting accessibility and user adoption of
telephony capabilities.
Change secondaryText button style from default to medium font weight
for improved visual comfort and better readability.
I haven't tested this change with Marianne.
Remove incorrect public room warning that was always displayed
regardless of room privacy settings.
Warning should only appear for genuinely public rooms since the lobby
system introduction changed room privacy behavior.
Prevents user confusion about room privacy settings.
Add telephony information display to the later meeting dialog while
preserving existing layout when telephony is disabled.
Prevent layout shift on modal close by collapsing all modal content
immediately when room becomes undefined.
Critical enhancement for users creating meeting links to have complete
connection information available.
Remove ProConnect mentions from frontend locale and enhance the meeting
dialog description text to clearly explain that meeting links are
permanent and persistent.
Improves user understanding of meeting link permanence and cleans up
branding references.
Change UI text to use "room information" instead of "room address"
to better reflect the functionality whether copying just the meeting
link or complete meeting details.
Remove protocol prefix from room URLs in the information sidepanel to
match the syntax used in the meeting dialog.
This creates consistent URL display formatting across both UI components
for better user experience.
Rework clipboard functionality to copy complete meeting information when
users click the copy button in the information side panel.
Previously only partial data was copied, causing user confusion. Now
includes all relevant meeting details as expected.
Improves user experience by meeting user expectations for copy behavior.
Add default telephony configuration to the tilt stack to enable
development workflow around authentication features.
Note: This is a fake/mock configuration and is not functional for
production use. It's intended solely for development purposes.
We've introduced simplifications that improve performance, enhance ux,
and contribute to the overall perception of experience quality.
Previously, our processor handling was overly complex. LiveKit allows us to set
a processor before starting the local video preview track, which eliminates
the black blink glitch that appeared when loading the join component
with a default processor.
This change prevents the unnecessary stopping and restarting
of the local video track.
I'm glad this issue is now resolved.
We also simplified component communication by avoiding props drilling.
Now, we use a single flag to indicate when the user is ready to enter the room.
This significantly reduces the complexity of props passed through components.
Users requested an enhanced visual indicator
for raised hands on the participant tile.
Most major video conferencing platforms display the position of a raised hand
in the queue. This helps hosts quickly see who is requesting to speak,
and in what order, without needing to open the full participant list.
While a minor feature, this improvement is especially valuable for power user
Previously, the participant list was sorted alphabetically by name.
This unintentionally affected the raised hands list,
which inherited the same sorting behavior.
Users requested that raised hands be sorted by order of arrival.
This simple change improves the UX by ensuring that raised hands
are displayed in the correct order.
Previously managed participant hand raised using raw metadata. LiveKit
introduced attributes concept, saves as metadata under hood but makes
update/handling easier.
Still pain that attributes must be strings, cannot pass boolean…
Refactor whole app to use attributes instead of metadata for the raised
hand feature. This commit might introduce regressions. I've double
checked participant list side pannel and the notification features.
Previously I persisted a boolean, I now persist the timestamp at which
the hand was raised. This will be useful in upcoming commits, especially
for sorting raised hands by order of arrival.
The LiveKit API URL is necessary to interact with the API. It uses https
protocol.
Eplicit wss protocol is necessary in Websocket constructor for some
older browsers.
This resolves critical compatibility issues with legacy browsers
(notably Firefox <124, Chrome <125, Edge <125) that lack support
for HTTPS URLs in the WebSocket() constructor. Without explicit WSS
URLs, WebSocket signaling connections may fail, crash, or be blocked
entirely in these environments.
The setting is optional and defaults to the current behavior when
not specified, ensuring zero breaking changes for existing deployments.
Replace hardcoded true values with supportsAdaptiveStream() and
supportsDynacast() checks. LiveKit SDK supports broad browser range but
requires specific APIs - modern features need explicit compatibility checks.
Prevents enabling unsupported WebRTC features on incompatible browsers,
which could led to a poor user experience.
One alternative solution could be to install polyfills.
Connection warmup wasn't working properly - only works when trying to
establish WebSocket first, then workaround kicks in. Call WebSocket
endpoint without auth info expecting 401 error, but enough to initiate
cache for subsequent WebSocket functionality.
Scope this **dirty** trick to Firefox users only. Haven't figured out
how to detect proxy from JS code simply.
Tested in staging and works on our constrained WiFi.
Implement HTTPS prefetch before joining rooms to resolve WebSocket
handshake failures where Firefox+proxy returns HTTP 200 instead of 101.
Reproduced locally with Squid container. No proxy configuration fixes
found - HTTPS warmup is only working workaround. Issue doesn't occur
when signaling server shares webapp domain, making warmup unnecessary.
Use HEAD request to minimize bandwidth.
Test tracking signaling failures to determine root causes when connection
fails. Will remove if it spams analytics - goal is understanding failure
patterns and reasons.