Skip to content

Create control to close the player and exit the current page like Instagram - #600

Open
AhmadFalahian wants to merge 470 commits into
feature-add-new-cupertino-skip-buttonsfrom
master
Open

Create control to close the player and exit the current page like Instagram#600
AhmadFalahian wants to merge 470 commits into
feature-add-new-cupertino-skip-buttonsfrom
master

Conversation

@AhmadFalahian

Copy link
Copy Markdown

There is no control in your player to close the video player. For example, suppose we are in full screen mode and we want to stop the whole player and exit it by pressing the close button, like the mode that Instagram has for its own player.

@diegotori

diegotori commented Feb 17, 2022

Copy link
Copy Markdown
Collaborator

@AhmadFalahian Looks like this change needs to be scoped to just the changes to the player. Please fork from master, then re-submit this PR. Thank in advance.

jweidner-mbible and others added 29 commits October 19, 2022 15:12
Allow Chewie controls to be positioned to allow for a larger safe area.
Added Dart Analysis fixes due to Flutter 3.7.
that causes usability issues
when controls are similar color as the video
diegotori and others added 30 commits May 15, 2026 20:25
When running as a Flutter Web app, the fullscreen button now triggers the
browser's native Fullscreen API (document.documentElement.requestFullscreen)
in addition to Chewie's internal route-based fullscreen. This gives users a
true OS-level fullscreen instead of just expanding within the browser window.

Pressing Escape to exit native fullscreen also collapses Chewie's fullscreen
route, keeping both states in sync.

Implemented via conditional import (dart.library.html): web_fullscreen.dart
uses package:web + dart:js_interop; web_fullscreen_stub.dart provides no-ops
for non-web platforms.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add ChewieController.useNativeFullScreenOnWeb (default true) so the native
browser Fullscreen behavior is opt-out rather than an unconditional change.
No effect on non-web platforms. Also adds a CHANGELOG entry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Remove `// ignore: uri_does_not_exist`; chewie_player.dart now imports
  the plain `web_fullscreen.dart` abstraction, which conditionally
  exports the stub or the real implementation.
- Use `dart.library.js_interop` instead of `dart.library.html` for the
  conditional export.
- Move the dart:js_interop / package:web implementation into
  web_fullscreen_impl.dart.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ullscreen

# Conflicts:
#	CHANGELOG.md
#	pubspec.yaml
On web and desktop, the play/pause, mute, subtitles, fullscreen buttons
and the seek/progress bar were built with `GestureDetector`, which does
not change the mouse cursor on hover. As a result the pointer stayed the
default arrow, giving no affordance that the controls are clickable.

Wrap the clickable child of each of these `GestureDetector`s in a
`MouseRegion(cursor: SystemMouseCursors.click)` so the cursor turns into
a pointer on hover, matching the existing `IconButton`-based controls
(options/subtitles) which already do this. The non-draggable progress
bar is left untouched.

Covers `MaterialControls`, `MaterialDesktopControls` and the shared
`VideoProgressBar`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cue text extracted from WebVTT and SubRip files carries inline markup, and
chewie rendered it with Text(text.toString()), so viewers read
"<i>The law is the law.</i>" instead of italics.

parseSubtitleMarkup turns a cue into an InlineSpan: <b>, <i>, <u> and
<font color> are applied on top of the caller's style, the remaining WebVTT
cue tags are dropped while their text is kept, and character escapes are
decoded. It parses the whole cue at once so a tag may span a line break, and
it is lenient — "5 < 10" and "<3" are left alone, an unclosed tag runs to the
end of the cue, and a stray closing tag is ignored.

Restyling subtitles used to mean replacing the renderer through
subtitleBuilder, which is also the only place markup could ever have been
handled. SubtitleStyle now covers text style, alignment, padding and the box
itself while chewie keeps rendering the cue, so presentation no longer costs
you semantics. subtitleBuilder is untouched: it still receives the cue exactly
as supplied, and parseSubtitleMarkup is exported so it can opt back in.

The three control skins duplicated the subtitle box; they now share
SubtitleOverlay and differ only in the margin they pass it.
feat(web): native browser fullscreen via the Fullscreen API
Addresses the review ask on #958: prove the parser is a passthrough for
ordinary cue text, at the parser and at the widget layer.

Also locks in the surrounding edges the purity sweep turned up: escape
handling at the Unicode boundaries, closing-tag leniency, hostile cue
text (nesting depth and unmatched brackets), ambient DefaultTextStyle
and text-scale inheritance, and ChewieController.copyWith carrying
subtitleStyle.

A sound effect written as a tag, such as <Sighs>, is dropped rather than
shown, matching browsers and ExoPlayer's Html.fromHtml path. Now tested
so it is deliberate.
feat: show click (pointer) cursor on hover over Material controls and progress bar
feat: render inline markup in subtitle cue text
Add showPlayButton parameter to ChewieController so users can hide the
center play button without needing to provide fully custom controls.

The value is forwarded through AdaptiveControls to MaterialControls,
MaterialDesktopControls, and CupertinoControls.
`VideoPlayerController.seekTo()` only writes the new position into
`value.position` once the platform has finished seeking. The progress bar
dropped the drag offset as soon as the seek was requested, so for the whole
duration of the seek it painted the stale reported position: the handle
snapped back to where playback was and then jumped forward when the seek
landed.

The window is longest on iOS, where `FVPVideoPlayer.seekTo` waits for
`AVPlayer.seekToTime` with zero tolerance to decode the exact target frame,
but the flicker is present on every platform.

Track the requested position and paint it until the controller reports it,
with a request counter so a slow seek completing after a newer one cannot
clear the newer position. Taps on the bar go through the same path, so the
handle now moves to the tapped point immediately. Playback resumes only once
the seek has landed, instead of briefly playing from the old position first.
Fix progress bar handle snapping back during a seek
…button

feat: Expose showPlayButton on ChewieController
The formatter shipped with Flutter 3.47 collapses this constructor onto a
single line, so 'dart format --set-exit-if-changed lib' fails on master.
Because the CI 'Check Formatting' step is enforced on the latest stable
channel, every open pull request currently fails CI regardless of its
contents.
Reformat _PlaybackSpeedDialog to satisfy dart format
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.