fix(ui): show no tile chrome in the Android picture-in-picture window - #1344
fix(ui): show no tile chrome in the Android picture-in-picture window#1344renefloor wants to merge 10 commits into
Conversation
The PiP overlay draws a StreamParticipantTile, which at the window's size carries its full chrome: the name pill, the connection quality indicator and — for an app registering a `participantTile` builder that adds actions, as the dogfooding app does — an overflow button nothing in PiP can tap. Suppressed through the style, so the app-wide builder does not put the menu back, the same way the lobby preview does it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
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 |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## v2 #1344 +/- ##
=====================================
Coverage ? 31.38%
=====================================
Files ? 376
Lines ? 28830
Branches ? 0
=====================================
Hits ? 9048
Misses ? 19782
Partials ? 0 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
`StreamPictureInPictureThemeData` on `StreamVideoTheme`, carrying a `tileStyle` merged over the window's own choices — so an app can restyle the tile the Android PiP window draws, and put back the name pill, connection quality indicator or overflow button it leaves out. The window is inserted into the nearest Overlay, which sits above the route showing the call, so a theme wrapped around the call screen is not an ancestor of it. Documented on the theme: set it on `StreamVideoTheme`, or above the Navigator. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…re window The window draws the name pill and the connection quality indicator again, without the camera-off icon or the sound indicator, and still without the overflow button. Adds `StreamParticipantLabelStyle.showVideoOffIcon` for the camera-off icon, which had no switch of its own. The pill also draws nothing at all now when it has neither a name nor an indicator to show, rather than an empty rounded rectangle over the video. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The system rounds the window, so the tile's own corner clip left the Material behind it showing through as black wedges, and an outline drawn square had its corners clipped away, leaving a border down the sides. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The name pill and the connection quality indicator sit flush against the window's edges, each square on the corner it occupies and rounded only on the inner one, which also gives the name the width the inset was taking. The indicator's shape comes off the decoration it would otherwise have drawn, so an app's own fill survives the change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`StreamParticipantLabelStyle.borderRadius` takes a `BorderRadiusGeometry`, so a corner-anchored pill no longer resolves the text direction itself. The widget passes it to a `ClipRRect` and a `BoxDecoration`, both of which took one already. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The theme's accessor, wrap, updateShouldNotify and lerp, and the branch StreamVideoTheme.lerp carries it through. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
At the size Android gives it — 128x228dp — over video, with the camera off, muted and on a poor connection. No golden rendered the window before, so nothing in the suite noticed what its chrome did. The style it draws with moves to `pictureInPictureTileStyle`, internal and unexported, so the snapshot and the widget tests assert the shape the window actually uses rather than restating it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The Android PiP window drew a participant tile with its full chrome: the name pill, the connection quality indicator, and an overflow button that nothing in PiP can tap — Android routes taps to the window itself, not to the Flutter view.
The button is the new part.
StreamParticipantTilegrows an overflow menu whenever actions exist, and an app that registers aparticipantTilebuilder adding actions to every tile — as the dogfooding app does with Pin/Mute — got one in PiP too. Onmainthe overlay usedStreamCallParticipant, which has no menu, but it did show the name pill and the connection indicator: those two defaults aretrue, and both stay. What goes with the button is the camera-off icon and the sound indicator, which is also what removes the doubled overlay inside the pill — the indicator's box fills with the same 75%-black token the pill uses, so on top of it the two composite to ~94%.Suppressed through the style rather than the props, so the app-wide builder does not put the menu back — the same way
StreamLobbyViewdoes it for its preview tile. The overlay's screen-share branch draws no chrome and needed nothing.The window's shape is the system's, so the tile no longer draws a shape of its own: square corners, because a rounded tile inside a rounded window left the black
Materialshowing through as wedges, and no outline, because one drawn square has its corners clipped away and reads as a border down the sides. The name pill and the indicator then sit flush in the corners, each square on the corner it occupies and rounded only on the inner one — which is also whatstream-video-swiftdoes (cornerRadius(8, corners: [.topRight])and[.topLeft]), and it gives the name the width the inset was taking.Both are configurable rather than fixed:
StreamPictureInPictureThemeDataonStreamVideoTheme, whoseStreamPictureInPictureStyle.tileStylerestyles the tile and can put any of the chrome back. The window is inserted into the nearestOverlay, above the route showing the call, so it has to be set on the theme or above theNavigator— aStreamPictureInPictureThemearound the call screen is not an ancestor of it.StreamParticipantLabelStyle.showVideoOffIcon, for the camera-off icon, which had no switch of its own next toshowAudioIndicator.The name pill also draws nothing at all now when it has neither a name nor an indicator, rather than an empty rounded rectangle over the video.
CallParticipantState.namehas no userId fallback, so with both icons off an unnamed participant would have hit that.iOS is untouched: its native PiP renders from
IOSPictureInPictureConfiguration, whoseshowParticipantName,showMicrophoneIndicatorandshowConnectionQualityIndicatorall default totrue.stream-video-swiftshows the same — name, mic and connection quality — and its name pill has no flag to turn off at all, so Android now reads closer to iOS than it did before this PR, not further from it.Testing
Seven widget tests on the overlay: the name and indicator are drawn; the overflow button, camera icon and sound indicator are not; the tile is square and draws no outline, speaking or not; the chrome is anchored in the corners; the indicator is squared without dropping a fill an app themed it with; and everything the window suppresses comes back when the picture-in-picture theme asks for it. Three more on the label cover the new
showVideoOffIconand the empty pill.Verified on a Pixel 8 in a real PiP window, camera on and off, cropped to the window's own bounds (128x228 dp).
🤖 Generated with Claude Code