Following internal feedback, rename the "Premium" wording to
"Advanced" across the transcription and recording sidepanels, so the
label no longer implies a paid tier.
The core component of the PiP layout. Adapted from a simplified version
of @ovgodd's work in #890 — see that PR for context on the original design.
Co-authored-by: Cyril <c.gromoff@gmail.com>
The PiP control bar shares state with the main window's control
bar — most importantly, the reaction toolbar and the mic/camera
toggles, which are fully stateful.
Sharing state works naturally here because the PiP content is
rendered through a portal into the same React tree, so the
controls in both windows read from and write to the same stores.
Co-authored-by: Cyril <c.gromoff@gmail.com>
When the PiP window is active, replace the corresponding content
in the main window with a lightweight placeholder. This avoids
rendering the camera feed (and other expensive media) twice when
the user is only watching the PiP window.
Co-authored-by: Cyril <c.gromoff@gmail.com>
Add a hook that manages the logic needed to open a document
picture-in-picture window, stores a ref to the window in a global
store, and—once ready—mounts a portal to duplicate content into
the PiP document's container.
Mounting the PiP content via a portal lets us share the same React
tree as the main app, and therefore share application state. This
comes with some trade-offs, particularly around components that
rely on the DOM hierarchy: react-aria popovers and overlays may
not behave correctly across documents.
The logic is kept to a minimum here. This first commit does nothing
more than open a window containing a loading spinner. The topic is
new to us, so plenty is likely to be refined in follow-ups.
Co-authored-by: Cyril <c.gromoff@gmail.com>
Introduce a new room setting controlling whether all participants,
including non-privileged users, can mute others.
Update API validation accordingly and add the frontend controls
allowing administrators to toggle the option and persist the
configuration through the API.
Fixes#1126 - Inconsistent role terminology in localization files.
Standardize on 'host' as the primary role term across en, de, and nl
locales, replacing mixed usage of 'administrator', 'organizer', 'admin',
'Organisator:in', 'Organisierende', and 'organisator'.
Ensure screen recording is properly disabled when the feature
flag is set to false.
Previously, no feature flag was enforced, allowing unintended
access.
Also update the blocked-access message to be more generic and not
specific to public sector users.
Declare a dedicated ARIA region for call controls
to improve accessibility.
Extract this region into a reusable component for better
consistency and maintainability.
Add an aria-label to clearly describe the purpose of the toolbar.
Avoid redundant wording in reaction button labels to improve
clarity for screen reader users.
When uploading an image, depending on the available network
there might be a bit of wait while the image is being uploaded.
In this commit we add a preview (grayscale + spinner) to have
UI feedback that the upload is in progress.
The "Transcribe" and "Record" buttons had unclear and misleading
descriptions, both using the verb "record," which caused confusion,
especially for screen reader users.
Update descriptions to clearly reflect each action:
- Transcribe: generate a written transcript of the conversation
- Record: save the meeting as a video
This improves accessibility (RGAA 11.9) and reduces the risk of
users triggering the wrong action.
Closes#1173
The aria-label only announced the presence of a sidepanel without
including its title.
Append the sidepanel title to improve accessibility and context
for screen readers.
Closes#1176.
Add a custom virtual background feature.
If the backend supports uploading files, backgrounds are stored
in the backend for the user.
Otherwise, only one background image can be selected.
Work adapted from PR #859 and partially extracted to ship as a
smaller, focused PR.
This allows users to view the full list of available shortcuts.
An editor to customize these shortcuts may be introduced later.
Hide non-essential icons and refine the labels to emphasize that one option
applies a stronger blur than the other. This should provide clearer cues for
screen reader users.
Update the virtual background effects tooltip and ARIA label with more
descriptive and concise wording based on Sophie’s feedback. This helps all
users, especially those using assistive technologies, by improving how
each virtual background is vocalized.
Inspired by @ericboucher’s proposal, allow non-admin or non-owner participants
to request the start of a transcription or a recording.
All participants are notified of the request, but only the admin can actually
open the menu and start the recording.
This is a first simple and naive implementation and will be improved later.
Prefer opening the relevant recording menu for admins instead of offering a
direct quick action to start recording. With more options now tied to recording,
keeping the responsibility for starting it encapsulated within the side panel
felt cleaner.
This comes with some UX trade-offs, but it’s worth trying.
I also simplified the notification mechanism by disabling the action button for
the same duration as the notification, preventing duplicate triggers. This is
not perfect, since hovering the notification pauses its display, but it avoids
most accidental re-triggers.
Refactor literals in the recording status hook and introduce a new status.
Align the login prompt style with the newly introduced warning message, and
guide users by clearly indicating that the two modes are mutually exclusive.
Users are prompted to stop the other mode before starting a new one.
This situation should happen less often now that checkboxes allow users to start
transcription and recording together. Hopefully, the UX is clear enough.
The growing number of props passed to the controls buttons may become an issue
and will likely require refactoring later.
Mutualize and factorize the recording API error modal in a single place, and
extract all recording mutations into a dedicated hook exposing both start and
stop actions.
This hook is responsible for interacting with the API error dialog when needed.
Previously, this logic was duplicated across each side panel; centralizing it
clarifies responsibilities and reduces duplication.
Following the previous commit, refactor the frontend to rely on room metadata to
track which recording is running and update the interface accordingly. This
implementation is not fully functional yet.
The limit-reached dialog triggering mechanism is currently broken and will be
fixed in upcoming commits. I also simplified the interface lifecycle, but some
edge cases are not yet handled—for example, transcription controls should be
disabled when a screen recording is started. This will be improved soon.
Controls were extracted into a reusable component using early returns. This
makes the logic easier to read, but slightly increases the overall complexity of
the recording side panel component.
Relying on literals to manage recording statuses is quite poor, feel free to
enhance this part.
Refactor the screen recording side panel to align with the transcription UX,
ensuring a more consistent and homogeneous user experience.
This commit also introduces a checkbox allowing users to request transcription
of the screen recording, which is one of the most requested features.
The side panel will be enriched with more information soon, especially once
Fichier is integrated for storing recordings, so the destination can be made
explicit.
More recording settings (layout, quality, etc.) will be introduced in upcoming
commits.
A lot of duplication existed, so I started factorizing components
now that a proper user experience is clearer.
Without over-abstracting, the first step introduces a reusable
“no access” view with configurable message and image.
This is just the beginning: props passing is still not ideal, but
it’s sufficient to merge and significantly reduce duplication.
Add a key feature allowing users to choose the language
of their transcription via a setting.
The default value is set to French, the most commonly used
language across our user base.
Users can still select English or “Automatic,” which re-enables automatic
language detection if no default is configured on the microservice.
Not all self-hosted instances will configure this setting, so a default text is
shown when the destination is unknown.
This is important to let users quickly click the link and understand which
platform is used to handle the transcription documents.
Inspired by proprietary solutions, add clearer details on how transcription
works and what users can expect from the feature. This new presentation is much
simpler to read, parse, and understand than the previous large block of text
that users were not reading at all.
Using icons helps users quickly understand where the transcription is sent, how
they are notified, and which meeting language is used.
Some information is currently hardcoded and will be parameterized in upcoming
commits. This work is ongoing.