Skip to content

feat(call): multi speaker view - #18966

Open
DorraJaouad wants to merge 8 commits into
mainfrom
feat/noid/multi-speaker-view
Open

feat(call): multi speaker view#18966
DorraJaouad wants to merge 8 commits into
mainfrom
feat/noid/multi-speaker-view

Conversation

@DorraJaouad

@DorraJaouad DorraJaouad commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

☑️ Resolves

It is a big PR bc it is a giant feature. The logic behind multi speaker is to use automation based on speaking. The demotion happens after 1 min of silence. It is max 4 speakers.

AI (if applicable)

  • The content of this PR was partly or fully generated using AI

I prepared a simulation in the last commit to help test, you can alter it to test edge cases of course (I included the case of 5 to 6 speakers). This is what is expected

image

🖌️ UI Checklist

🖼️ Screenshots / Screencasts

Screen.Recording.2026-08-09.at.18.37.52.mov

🏁 Checklist

  • 🌏 Tested with different browsers / clients:
    • Chromium (Chrome / Edge / Opera / Brave)
    • Firefox
    • Safari
    • Talk Desktop
    • Integrations with Files sidebar and other apps
    • Not risky to browser differences / client
  • 🖌️ Design was reviewed, approved or inspired by the design team
  • ⛑️ Tests are included or not possible
  • 📗 User documentation in https://github.com/nextcloud/documentation/tree/master/user_manual/talk has been updated or is not required

@DorraJaouad DorraJaouad added this to the ⛅ Next Major (35) milestone Aug 9, 2026
@DorraJaouad
DorraJaouad requested a review from Antreesy August 9, 2026 16:41
@DorraJaouad DorraJaouad self-assigned this Aug 9, 2026
Base automatically changed from feat/noid/center-last-row-tiles to main August 10, 2026 12:16
Speaker view will be able to promote several active speakers at once
instead of a single one. Add the state driving it, persisted next to the
grid preference so it survives rejoining a call.

The flag is only meaningful while speaker view is active, so switching
between grid and speaker view leaves it untouched.

Assisted-by: ClaudeCode:claude-opus-5
Signed-off-by: Dorra Jaouad <dorra.jaoued7@gmail.com>
A participant speaking without interruption for 3 seconds becomes active,
and stops being active after a minute of silence, so that short
interjections never disturb the view and listeners make room on their own.

The active speakers are kept in the order they became active and only the
first four are promoted. A fifth speaker is therefore queued rather than
dropped: it slides in as soon as one of the speakers ahead is demoted,
which keeps the promoted tiles stable instead of letting a single word
evict someone mid-sentence.

Participants that leave free their spot immediately, as the speaking flag
is not guaranteed to be reset on disconnection.

Assisted-by: ClaudeCode:claude-opus-5
Signed-off-by: Dorra Jaouad <dorra.jaoued7@gmail.com>
Whether a slot has to be reserved for the local video is a property of the
grid being laid out, not something the layout can derive on its own. Move
the decision to the caller so that grids other than the participant one can
be measured with the same composable.

No functional change: the videos grid passes the very condition the
composable used to compute.

Assisted-by: ClaudeCode:claude-opus-5
Signed-off-by: Dorra Jaouad <dorra.jaoued7@gmail.com>
The component lays out the handful of promoted speakers in the main area,
reusing the grid layout helpers: the number of columns and rows follows the
available space and the target tile aspect ratio, and the half column
placement centers a row that leaves an odd number of columns empty, so
three speakers show one centered tile below two.

It is deliberately not the videos grid: no pagination, no local video and
no tile ordering, as the caller already hands over the tiles to show in the
order they should appear.

Assisted-by: ClaudeCode:claude-opus-5
Signed-off-by: Dorra Jaouad <dorra.jaoued7@gmail.com>
In multi-speaker mode the promoted speakers are laid out in the main area
instead of the single last speaker, and are taken out of the stripe: a tile
is only ever in one place, so it reads as having moved up rather than as
being duplicated.

A screen share or a manually selected video still takes the whole main area,
and the single speaker layout is kept until a second speaker becomes active,
so the view only splits once there really is a conversation.

Speakers shown in the main area now also get the video quality a promoted
participant gets, otherwise all but one of the tiles would be upscaled from
the lowest simulcast layer.

Assisted-by: ClaudeCode:claude-opus-5
Signed-off-by: Dorra Jaouad <dorra.jaoued7@gmail.com>
The layout button used to toggle between the grid and speaker view, which
leaves no room for a third option. Turn it into a menu listing the three
layouts, so the current one is also readable at a glance instead of being
implied by the icon.

Picking the grid leaves the speaker view preference alone, so returning to
it restores the layout that was in use.

Assisted-by: ClaudeCode:claude-opus-5
Signed-off-by: Dorra Jaouad <dorra.jaoued7@gmail.com>
A promoted tile is rendered by the stripe before the change and by the
speakers grid after it, so it cannot simply be transitioned: it is a new
element in a new place, and it used to appear in its slot out of nowhere.

Put the new tile back over the old one with a transform and release it, so
that it reads as a single tile travelling from the stripe into its slot,
and back into the stripe once its speaker is demoted.

The animation is skipped for users who asked not to be shown motion.

Assisted-by: ClaudeCode:claude-opus-5
Signed-off-by: Dorra Jaouad <dorra.jaoued7@gmail.com>
Signed-off-by: Dorra Jaouad <dorra.jaoued7@gmail.com>
@DorraJaouad
DorraJaouad force-pushed the feat/noid/multi-speaker-view branch from aa1d47d to a69cca7 Compare August 10, 2026 12:17
@nextcloud-command nextcloud-command added the AI assisted This PR contains AI-assisted commits label Aug 10, 2026
Comment thread src/components/CallView/useActiveSpeakers.ts
Comment thread src/components/CallView/useActiveSpeakers.ts
Comment thread src/components/CallView/useActiveSpeakers.ts
Comment thread src/components/CallView/useActiveSpeakers.spec.ts
Comment thread src/components/CallView/Grid/SpeakersGrid.vue
:token="token"
:isOverlap="showFullPage"
:callParticipantModels="callParticipantModels"
:callParticipantModels="stripeParticipantModels"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VideosGrid can now receive only one model (because the rest are filtered) and give false positive on isLessThanTwoVideos computed

Comment thread src/components/CallView/Grid/tilePromotionTransition.ts
Comment thread src/components/CallView/BottomBar.vue
Comment thread src/components/CallView/BottomBar.vue
Comment thread src/components/CallView/CallView.vue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI assisted This PR contains AI-assisted commits enhancement feature: call 📹 Voice and video calls feature: frontend 🖌️ "Web UI" client

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants