feat: YouTube-style seek indicator for keyboard seeking - #953
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #953 +/- ##
==========================================
+ Coverage 71.68% 72.73% +1.05%
==========================================
Files 40 41 +1
Lines 2518 2560 +42
==========================================
+ Hits 1805 1862 +57
+ Misses 713 698 -15 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Hi @diegotori 👋 Beyond this PR, I'd like to offer to help with maintenance on chewie if you're open to it. A bit of context:
I know the open-PR queue is long, and I'd be glad to take some of that load off you: triaging and reviewing PRs, keeping the package current with new Flutter releases, and helping land fixes. Would you be open to adding me as a co-maintainer (or triage access to start)? Happy to do whatever works best for you and the Flutter Community org. Either way, thanks for maintaining this 🙏 |
|
@Ortes please fix the conflicts here. Thanks. |
44f8404 to
eea8876
Compare
eea8876 to
d82e366
Compare
|
@Ortes please resolve conflicts. Thanks. |
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.
d82e366 to
63c5d2d
Compare
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.
63c5d2d to
d8ce115
Compare
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.
d8ce115 to
713ada7
Compare
ibrahim-iqbal
left a comment
There was a problem hiding this comment.
Nice feature — the accumulate-in-same-direction, reset-on-opposite behaviour matches YouTube exactly, and the pill layout at Alignment(±0.6, 0) gives the same off-centre placement.
Widget shape
SeekIndicatorwrapped inIgnorePointer— correct, the pill would otherwise soak up clicks on the middle of the video.AnimatedOpacitywith a 300 ms fade + a 900 ms hide-timer is the same rhythm as YouTube's own; long enough to read30 safter a triple-tap, short enough not to overlap a subsequent tap sequence.Colors.black.withValues(alpha: 0.55)— good use of the newwithValues(the deprecatedwithOpacitywould also work but the current API is right).
Controls plumbing
_seekIndicatorTimeris cancelled indisposealongside the existing_hideTimer/_initTimer/_showAfterExpandCollapseTimer— no leak._bumpSeekIndicatorgate onchewieController.showSeekIndicatorfirst is right: an embed that disables the feature stays entirely off the setState path, so the widget cost is zero when opted out.keyboardSeekDurationis threaded into both directions (the hardcodedDuration(seconds: -10)/Duration(seconds: 10)becomes user-configurable) — nice bonus, plays well withChewieController.copyWithfor downstream users.
Small notes, non-blocking:
_seekIndicatorSecondsis anintwhilekeyboardSeekDurationis aDuration. If someone setskeyboardSeekDuration: const Duration(milliseconds: 5500),stepbecomes5(via.inSeconds) and the label reads5 s / 10 s / …, quietly under-counting. DocumentingkeyboardSeekDurationas "whole seconds" on the field, or clamping the display toduration.inMilliseconds ~/ 1000explicitly, would make that surprise less likely.- The
Text('$seconds s')label reads correctly in English but ignores locale (Arabic-Indic digits, RTLس, etc.). Fine as-is — chewie doesn't currently localise button/hover strings — but worth a comment if you want to leave a hook for future i18n. - Two
Alignment(±0.6, 0)magic values — arguably nicer as_kIndicatorAlignmentForward/_Backwardconstants at the top of the file so a designer tweak lands in one place. Nit.
Test file (seek_indicator_test.dart, 133 lines) covers the accumulate/reset behaviour end-to-end, which is exactly what a future refactor of the timer logic will need to preserve. LGTM.
713ada7 to
e2905c5
Compare
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.
e2905c5 to
85603d3
Compare
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.
Flash a pill showing the seeked amount when seeking with the arrow keys on the desktop controls. Repeated presses in the same direction keep it visible and accumulate the total (10s, 20s, 30s, ...); the opposite direction resets it. Gated by the new ChewieController.showSeekIndicator option (default true).
Replace the hardcoded 10s seek step with a new ChewieController.keyboardSeekDuration option (default 10 seconds) that drives both the arrow-key seek and the amount shown by the indicator.
85603d3 to
7fb5885
Compare
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.
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.
What
Adds a YouTube-style seek indicator that flashes on screen when the user seeks with the keyboard arrows on the desktop controls (
MaterialDesktopControls).10s→20s→30s), just like YouTube.How
lib/src/seek_indicator.dart(fades viaAnimatedOpacity, mirrors the existingCenterSeekButtonstyle; purely visual — wrapped inIgnorePointer)._MaterialDesktopControlsStateaccumulates the seeked seconds in_seekForward/_seekBackward(kept in sync with the existingDurationseek step) and auto-hides via aTimer, mirroring the existing buffering-indicator pattern.ChewieController.showSeekIndicatoroption (defaulttrue), wired throughcopyWith.Tests
test/seek_indicator_test.dartcovers accumulation on repeated presses, direction reset, auto fade-out, theshowSeekIndicator: falseopt-out, and the option default/copyWith.dart format,flutter analyze lib test, and the fullflutter testsuite are clean.