feat: YouTube-style tap gestures (double-tap seek zones on mobile, double-click fullscreen on desktop) - #964
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #964 +/- ##
==========================================
+ Coverage 77.70% 79.47% +1.76%
==========================================
Files 43 44 +1
Lines 2687 2738 +51
==========================================
+ Hits 2088 2176 +88
+ Misses 599 562 -37 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@Ortes you still have changelog conflicts in this PR. Thanks. |
a73ab57 to
219aace
Compare
219aace to
015352e
Compare
|
@Ortes looks like every time I merge your PRs, it always conflicts with the changelog entries that you make ahead of time. Please re-sync them. Thanks. |
|
@diegotori The conflicts are structural rather than stale branches: every PR inserts at line 1 of Since you re-file the entries under the release version anyway (#959 → 1.16.2, #966 → 1.16.0, #970 → 1.16.3), would you rather I drop the CHANGELOG hunk from my PRs entirely and put the proposed entry in the PR description instead? That removes the conflict class completely. Happy to keep writing them if you prefer — just say which. Meanwhile I'll re-sync all the open ones now. |
|
@Ortes, usually I have Gemini create the changelog entries before publishing. Ideally, I usually take point on releasing new versions to If you want, you can omit those messages from your PR so that I can update it when I publish it. |
bad3c7b to
425e1cf
Compare
|
@diegotori Unrelated to this PR, and easy to say no to: would you consider adding me as a collaborator on chewie? I asked in #953 and #946 but it probably got lost in the PR noise. Where I'm at: 17 PRs merged, 7 of them in the last two days. This week I re-synced the whole open stack onto the 1.17.x cast refactor, and dropped the CHANGELOG entries from my PRs as you asked — so that particular friction is gone from your side. What I'd use it for: triaging incoming issues and PRs (labels, duplicates, asking for reproductions) and reviewing other people's PRs, so the queue moves without everything waiting on you. Releases and pub.dev publishing stay yours — I'm not asking for those. Merge rights only if and when you'd want that. If it needs the fluttercommunity org rather than you, tell me the process and I'll do the legwork. And if the answer is no, or not now, just say so and I'll drop it. |
diegotori
left a comment
There was a problem hiding this comment.
You need to add some test coverage before we can move forward with this.
Thanks.
I'll have to think about this. You'll have to go through them, and we'll need to make sure not to step on each other's toes. Once they speak to me about it, then we'll see what happens. |
|
@diegotori Added |
Mobile (MaterialControls): - Double-tapping the left/right side of the video seeks backward/forward, flashing the accumulating seek indicator. The middle band is a dead zone. - While the indicator is visible, further single taps in the same zone keep seeking (10s -> 20s -> 30s), like YouTube. - Gated by ChewieController.allowDoubleTapSeek (default true) with the step set by ChewieController.doubleTapSeekDuration (default 10s). Disabled on live streams and when playback is finished. Desktop (MaterialDesktopControls): - Double-clicking the video toggles fullscreen, like the YouTube desktop player. Gated by ChewieController.allowDoubleTapToggleFullScreen (default true) and allowFullScreen. The keyboard seek indicator state introduced by fluttercommunity#953 moves from _MaterialDesktopControlsState into a shared SeekIndicatorStateMixin so both control sets drive the same SeekIndicator. Double-tap-to-seek was first explored by punit1111 in fluttercommunity#717.
pauseOnBackgroundTap, the display-tapped hide toggle, and the backward tap-to-repeat zone check were the 8 lines codecov flagged as uncovered in material_controls.dart's patch.
|
@Ortes looks like you still have conflicts to deal with. Thanks. |
f8ba2c0 to
62d9d8f
Compare
What
YouTube-style tap gestures for the Material controls:
MaterialControls)10s→20s→30sMaterialDesktopControls)New
ChewieControlleroptions, all default-on:allowDoubleTapSeek(defaulttrue) — mobile double-tap seek zones.doubleTapSeekDuration(default 10s) — the per-tap seek step.allowDoubleTapToggleFullScreen(defaulttrue) — desktop double-click fullscreen; only honored whenallowFullScreenistrue.Double-tap seek is disabled on live streams and when playback is finished, and seeks are clamped to
[0, duration]via the existing_seekRelative.How
_MaterialDesktopControlsStatemoves into a sharedSeekIndicatorStateMixin(lib/src/helpers/seek_indicator_mixin.dart), so both control sets drive the sameSeekIndicatorwidget and share the accumulate/reset/auto-hide logic.MaterialControls._buildHitAreawraps itsGestureDetectorin aLayoutBuilder;onDoubleTapDownrecords the tap'sdxandonDoubleTapdispatches by zone (< 0.4back,> 0.6forward, middle dead). The double-tap recognizers are only attached while double-tap seek is applicable, so single-tap latency is unchanged when the feature is off or the stream is live.onDoubleTap → _onExpandCollapseon its hit area. Desktop single-click behavior is deliberately unchanged —pauseOnBackgroundTapalready lets apps opt into click-to-pause.Notes
AbsorbPointer). Matching YouTube's double-tap-while-hidden would need the recognizer above the absorber, which would add tap latency to every control button — out of scope here.Tests
test/double_tap_seek_test.dartadds a fakeVideoPlayerPlatform(modeled on video_player's own test fake, hence thevideo_player_platform_interfacedev dependency) so the controller really initializes and positions can be asserted. Covers: both zones seek and clamp, the configured step, the dead zone, live/flag gating, tap-to-repeat (same zone accumulates, opposite zone falls through, faded indicator does not repeat), single-tap regression, desktop double-click fullscreen on/off, and option defaults +copyWithround-trips.dart format,flutter analyze lib test, and the fullflutter testsuite (105 tests) are clean.