Skip to content

feat: YouTube-style seek indicator for keyboard seeking - #953

Merged
diegotori merged 5 commits into
fluttercommunity:masterfrom
Fullphysio:feat/keyboard-seek-indicator
Sep 16, 2026
Merged

diegotori merged 5 commits into
fluttercommunity:masterfrom
Fullphysio:feat/keyboard-seek-indicator

Conversation

@Ortes

@Ortes Ortes commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

What

Adds a YouTube-style seek indicator that flashes on screen when the user seeks with the keyboard arrows on the desktop controls (MaterialDesktopControls).

  • Pressing → / ← shows a small pill with a directional icon and the amount seeked.
  • Repeated presses in the same direction keep the pill visible and accumulate the total (e.g. 10s → 20s → 30s), just like YouTube.
  • Pressing the opposite direction (or after the pill fades ~0.9s) resets the counter.

How

  • New reusable widget lib/src/seek_indicator.dart (fades via AnimatedOpacity, mirrors the existing CenterSeekButton style; purely visual — wrapped in IgnorePointer).
  • _MaterialDesktopControlsState accumulates the seeked seconds in _seekForward/_seekBackward (kept in sync with the existing Duration seek step) and auto-hides via a Timer, mirroring the existing buffering-indicator pattern.
  • Gated by a new ChewieController.showSeekIndicator option (default true), wired through copyWith.

Tests

test/seek_indicator_test.dart covers accumulation on repeated presses, direction reset, auto fade-out, the showSeekIndicator: false opt-out, and the option default/copyWith.

dart format, flutter analyze lib test, and the full flutter test suite are clean.

Ortes added a commit to Fullphysio/chewie that referenced this pull request Jul 9, 2026
@codecov

codecov Bot commented Jul 9, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 72.73%. Comparing base (e776ce7) to head (7fb5885).
⚠️ Report is 4 commits behind head on master.

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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Ortes

Ortes commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

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 🙏

@diegotori

Copy link
Copy Markdown
Collaborator

@Ortes please fix the conflicts here. Thanks.

Ortes added a commit to Fullphysio/chewie that referenced this pull request Aug 12, 2026
@Ortes
Ortes force-pushed the feat/keyboard-seek-indicator branch from 44f8404 to eea8876 Compare August 12, 2026 07:25
Ortes added a commit to Fullphysio/chewie that referenced this pull request Aug 15, 2026
@Ortes
Ortes force-pushed the feat/keyboard-seek-indicator branch from eea8876 to d82e366 Compare August 15, 2026 11:13
@Ortes

Ortes commented Aug 28, 2026

Copy link
Copy Markdown
Contributor Author

Heads-up: #964 is stacked on this branch — it extracts the indicator state into a shared mixin and reuses SeekIndicator for YouTube-style double-tap seeking on mobile. This PR stays reviewable standalone; #964 rebases once this lands.

@diegotori

Copy link
Copy Markdown
Collaborator

@Ortes please resolve conflicts. Thanks.

Ortes added a commit to Fullphysio/chewie that referenced this pull request Sep 1, 2026
Ortes added a commit to Fullphysio/chewie that referenced this pull request Sep 1, 2026
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.
@Ortes
Ortes force-pushed the feat/keyboard-seek-indicator branch from d82e366 to 63c5d2d Compare September 1, 2026 12:10
Ortes added a commit to Fullphysio/chewie that referenced this pull request Sep 1, 2026
Ortes added a commit to Fullphysio/chewie that referenced this pull request Sep 1, 2026
Ortes added a commit to Fullphysio/chewie that referenced this pull request Sep 1, 2026
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.
Ortes added a commit to Fullphysio/chewie that referenced this pull request Sep 1, 2026
@Ortes
Ortes force-pushed the feat/keyboard-seek-indicator branch from 63c5d2d to d8ce115 Compare September 1, 2026 19:56
Ortes added a commit to Fullphysio/chewie that referenced this pull request Sep 9, 2026
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.
@Ortes
Ortes force-pushed the feat/keyboard-seek-indicator branch from d8ce115 to 713ada7 Compare September 9, 2026 09:34

@ibrahim-iqbal ibrahim-iqbal left a comment

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.

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

  • SeekIndicator wrapped in IgnorePointer — correct, the pill would otherwise soak up clicks on the middle of the video.
  • AnimatedOpacity with a 300 ms fade + a 900 ms hide-timer is the same rhythm as YouTube's own; long enough to read 30 s after a triple-tap, short enough not to overlap a subsequent tap sequence.
  • Colors.black.withValues(alpha: 0.55) — good use of the new withValues (the deprecated withOpacity would also work but the current API is right).

Controls plumbing

  • _seekIndicatorTimer is cancelled in dispose alongside the existing _hideTimer / _initTimer / _showAfterExpandCollapseTimer — no leak.
  • _bumpSeekIndicator gate on chewieController.showSeekIndicator first is right: an embed that disables the feature stays entirely off the setState path, so the widget cost is zero when opted out.
  • keyboardSeekDuration is threaded into both directions (the hardcoded Duration(seconds: -10) / Duration(seconds: 10) becomes user-configurable) — nice bonus, plays well with ChewieController.copyWith for downstream users.

Small notes, non-blocking:

  • _seekIndicatorSeconds is an int while keyboardSeekDuration is a Duration. If someone sets keyboardSeekDuration: const Duration(milliseconds: 5500), step becomes 5 (via .inSeconds) and the label reads 5 s / 10 s / …, quietly under-counting. Documenting keyboardSeekDuration as "whole seconds" on the field, or clamping the display to duration.inMilliseconds ~/ 1000 explicitly, 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 / _Backward constants 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.

@Ortes
Ortes force-pushed the feat/keyboard-seek-indicator branch from 713ada7 to e2905c5 Compare September 14, 2026 21:16
Ortes added a commit to Fullphysio/chewie that referenced this pull request Sep 14, 2026
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.
@Ortes
Ortes force-pushed the feat/keyboard-seek-indicator branch from e2905c5 to 85603d3 Compare September 14, 2026 21:29
Ortes added a commit to Fullphysio/chewie that referenced this pull request Sep 14, 2026
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.
@Ortes
Ortes force-pushed the feat/keyboard-seek-indicator branch from 85603d3 to 7fb5885 Compare September 15, 2026 06:13
Ortes added a commit to Fullphysio/chewie that referenced this pull request Sep 15, 2026
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.

@diegotori diegotori left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM.

@diegotori
diegotori merged commit 2d80324 into fluttercommunity:master Sep 16, 2026
5 checks passed
Ortes added a commit to Fullphysio/chewie that referenced this pull request Sep 16, 2026
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.
diegotori added a commit that referenced this pull request Sep 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants