feat(ui): give CallParticipantSort an identity - #1364
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
7d1e529 to
e0e44d3
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## v2 #1364 +/- ##
=====================================
Coverage ? 35.21%
=====================================
Files ? 387
Lines ? 29567
Branches ? 0
=====================================
Hits ? 10413
Misses ? 19154
Partials ? 0 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
`didUpdateWidget` compared `sort` to decide whether the list had to be ordered
again, and a comparator cannot answer that: a closure written inline is a new
function on every build, so comparing those reordered the list every time.
Comparing the layout instead avoided that but missed a caller replacing their
own comparator, which nothing else would pick up — `Call.participantsStream` is
throttled and silent in a quiet call.
`CallParticipantSort` is a class now, pairing the comparator with an `identity`
that says when it has changed:
sort: CallParticipantSort(byName, identity: 'by-name')
Two sorts with equal identities are the same sort, whatever functions they
hold, so one built inline on every build reorders nothing. Without an identity
a sort is only equal to itself, which is the old behaviour and is documented as
such.
The SDK's own sorts move to `CallParticipantSorts`, held once and identified,
so `layoutMode.sorting` hands back the same instance for an unchanged layout.
`PictureInPictureConfiguration.sort` and
`StreamPictureInPictureUiKitView.participantSort` take one too, rather than a
bare `Comparator`.
Breaking: a closure no longer assigns to `sort`. There is no `dart fix` for it
— fix_data cannot wrap an expression — so call sites are migrated by hand.
All three behaviours now hold together: a layout change reorders, a caller's
new sort reorders, and neither an inline closure nor a rebuild does.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
e0e44d3 to
63d652c
Compare
Two PRs landed a re-sort rule in
StreamCallParticipants.didUpdateWidget, each asserting the opposite of the other, and each with a test:v2) compareslayoutMode.sorting, so picking a layout reorders and a comparator passed inline does not.main) comparessortby identity, so a caller's new comparator reorders on the spot.They only met when
mainwas merged intov2, where one had to give. This PR is the resolution that satisfies both.Supersedes the two earlier revisions of this PR. Those each traded one behaviour away; this gets all three, at the cost of a breaking type change.
The problem
StreamCallParticipants.didUpdateWidgethas to answer "has the sorting changed?" — a comparator cannot answer it. A closure written inline is a new function on every build, so comparing them reorders the list every time. ComparinglayoutMode.sortinginstead avoids that, but then a caller replacing their own comparator is never noticed, and nothing else picks it up:Call.participantsStreamis throttled and silent in a quiet call.The change
CallParticipantSortbecomes a class pairing the comparator with an identity:Two sorts with equal identities are the same sort, whatever functions they hold — so one constructed inline on every build reorders nothing, and one with a new identity reorders on the spot. Without an identity a sort is only equal to itself, which is the old behaviour, documented as such.
The SDK's own sorts move to
CallParticipantSorts(regular,speaker,pictureInPicture,livestreamOrAudioRoom), held once and identified, solayoutMode.sortinghands back the same instance for an unchanged layout.sortidentity (onv2now)layoutMode.sorting(rev 2)Breaking
A bare closure no longer assigns to
sort. There is nodart fixfor it —fix_data.yamlcan rename and drop parameters but cannot wrap an expression — so call sites are migrated by hand:PictureInPictureConfiguration.sortandStreamPictureInPictureUiKitView.participantSorttake aCallParticipantSorttoo, rather than a bareComparator, so there is one type across the API.Why the identity has to live on the sort
A wrapper that kept
CallParticipantSort = Comparatordoes not work. Dart implicitly tears offcallwhen an object is assigned to a function type, and the tear-off drops the custom equality:So the field has to hold the class, which is what makes this breaking rather than additive. An optional
sortKeyparameter alongside the comparator was the non-breaking alternative; it was passed over in favour of one coherent type while v2 is still open for breaking changes.Testing
melos run analyze:errorclean across the workspace. 501 tests pass instream_video_flutter— the same count asv2, with #1332's two tests and #1354's all passing together for the first time. Goldens not run locally.🤖 Generated with Claude Code