Reduce the set of events the ParticipantToggle subscribes to, so it
does not re-render on every LocalParticipant event but only on the
ones that actually affect its rendering.
Refactor the connection observer, previously a hook consumed inside
the Videoconference component, into a dedicated leaf component in
the tree.
This avoids re-rendering the whole Videoconference component every
time the connection state changes; only the leaf reacts to it.
Reduce the set of events that trigger an update of the participant
list in the chat, keeping only those relevant to display: attribute
and name changes.
This avoids unnecessary re-renders when other, unrelated participant
events fire.
At this stage, the chat is kept mounted in the DOM at all times to
preserve state and keep receiving new messages. As a consequence,
every chat message ends up rendered in the DOM, which can bloat it
significantly in large meetings with hundreds of participants
exchanging messages.
Virtualize the chat message list so only the few messages actually
visible are rendered in the DOM.
The fact that the chat is always mounted in the DOM will be
addressed in a later commit.
The InviteDialog open state was managed very high in the React tree,
which triggered a re-render of the whole conference tree whenever
the dialog was opened or closed.
Push the state down to a narrower component to limit the scope of
re-renders.
Part of a broader effort to isolate as much as possible what should
re-render, so we can then focus on tackling the real performance
issues.
Extract the code responsible for announcing pinned track changes
(for accessibility) into a well-scoped leaf component.
Previously, calling the useScreenReaderAnnounce hook inside
StageLayout triggered a re-render of the whole layout subtree.
Encapsulating the announcement logic in a narrow component keeps
those re-renders local to that leaf.
Vendor the pinned track context and its associated hook from
LiveKit, and switch the underlying state management to a Valtio
store.
The LiveKit ContextProvider was injected high in the tree, so any
pinned track change triggered a re-render of a large portion of the
app. With a Valtio store, only the parts of the app that actually
subscribe to the pinned track or need to pin one re-render when
present in the DOM.
Move track manipulation into a leaf component to avoid re-rendering
the whole videoconference tree when a track update occurs.
The new StageLayout component is now responsible for rendering the
video tracks in the relevant layout, while the Videoconference
component keeps the responsibility of building the overall
conference view.
We save re-rendering the ControlBar for every track/layout changes
for example.
In previous version, webhook may not be called in case of failure,
because the task wouldn't be actually retried.
We know check the exception raised against the auto_retry for
config.
Analytics capture also happens in case of definitive failure.
Request may fail for other reasons than HTTPError (ConnectionError for
instance). This change switches to the more generalized error for the
retry logic on call webhook & transcribe audio
* Consider that HTTP 400 errors are due to corrupted
audio files by default.
* Properly reraise the http error otherwise so that
the retry mechanism actually works.
The existing manifest was not exposing the add-in tools when
creating a meeting in a shared calendar. Amend the manifest with the
missing instructions so the add-in shows up in that context as well.
Manifest changes generated with Claude's assistance.
Copy the MediaPipe WASM modules into the frontend build output and
serve them locally, instead of loading them from the Google CDN at
runtime.
Mediapipe was a transitive dependency, add it explicitly.
Requested by some members of the community.
It closes#1168
Add vite-plugin-static-copy as a dependency. It will be used to copy
and serve the WASM modules shipped by the MediaPipe JS dependency
from the frontend build output.
Inline the model weights instead of fetching them from a Google
remote location at runtime. The weights do not update frequently, so
inlining removes an external dependency.
Update the calls to the background processors imported from
livekit-track-processor so they use the new instantiation method
instead of the previous, now-deprecated one.
The info panel was crashing when opening a room that was not
registered in the database (with ALLOW_UNREGISTERED_ROOMS=true),
because the API response did not include the room slug.
Instead of adding frontend fallbacks, update the unregistered-room
response to include the slug, keeping the API contract consistent
with registered rooms.
Note: this still relies on the unregistered-room response staying
aligned with the registered-room schema. Any future divergence
between the two responses could introduce similar issues.
A refactoring on the backend side is needed.
It closes#1441.
Add a new setting that controls whether an authenticated user can
rename or modify their display name, or if they must use the one
returned by the SSO.
When the setting is disabled, only anonymous users can set a display
name freely; authenticated users always use their SSO display name.
Requested by many self-hosters.
Create a new dedicated store for user choices, starting with the
username, to decouple this part from any LiveKit elements. This is
better for tree-shaking, and depending on LiveKit for storing the
username brings no real value.
The refactoring will be continued later for the other user choices
that can be persisted.
In the external API, applications authenticate with a
client_id/secret and can provision users with only an email. In that
flow, users are not identified to PostHog, so the user DB id alone
is not enough to identify them in analytics afterwards.
The issue does not exist in the public API, where users are
authenticated and therefore already identified.
Inspired by @flochehab's approach in summary.