Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ env:
# refer to https://docs.flutter.dev/development/tools/sdk/releases.
# Note: The version below should be manually updated to the latest second most recent version
# after a new stable version comes out.
# Current minimum is set to Flutter 3.32. Make the next version the new minimum once the next
# Current minimum is set to Flutter 3.38. Make the next version the new minimum once the next
# stable version is released
FLUTTER_VERSION_MINIMUM_DEFAULT: "3.32.8"
FLUTTER_VERSION_MINIMUM_DEFAULT: "3.38.10"
FLUTTER_VERSION_LATEST_STABLE_CHANNEL_DEFAULT: "3.x"

jobs:
Expand Down Expand Up @@ -64,7 +64,7 @@ jobs:
fail-fast: false
steps:
- name: 📚 Git Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: 🐦 Setup Flutter
uses: subosito/flutter-action@v2
Expand All @@ -91,6 +91,6 @@ jobs:
run: flutter test --no-pub --coverage --test-randomize-ordering-seed random

- name: 📁 Upload coverage to Codecov
uses: codecov/codecov-action@v5
uses: codecov/codecov-action@v6
# TODO: Remove the below once we have adequate tests for this library.
continue-on-error: true
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
## [Unreleased]
* ✨ Web: enter the browser's native (OS-level) fullscreen via the Fullscreen API instead of only expanding the Flutter view inside the browser window. Pressing Escape to leave browser fullscreen also exits Chewie's fullscreen. Controlled by the new `ChewieController.useNativeFullScreenOnWeb` flag (defaults to `true`; no effect on non-web platforms).

## [1.14.1]
* 🛠️ [#945](https://github.com/fluttercommunity/chewie/pull/945): Flutter 3.38 downgrade. Thanks [diegotori](https://github.com/diegotori).
* Library now supports Flutter and Dart versions `3.38.0` and `3.10` or higher respectively, restoring previous compatibility.

## [1.14.0]
* 🛠️ [#944](https://github.com/fluttercommunity/chewie/pull/944): Flutter 3.41 Upgrade. Thanks [diegotori](https://github.com/diegotori).
* **BREAKING CHANGE**: Library now requires at least Flutter version `3.41.0` or higher due to
`wakelock_plus`'s upgrade to version `1.6.0`, which now requires this minimum Flutter version.

## [1.13.1]
* 🛠️ [#940](https://github.com/fluttercommunity/chewie/pull/940): fix: add mounted check in _startHideTimer to prevent setState after dispose. Thanks [Cleparr](https://github.com/Cleparr).

## [1.13.0]
* 🛠️ [#927](https://github.com/fluttercommunity/chewie/pull/927): Fix(web): Keep playback when entering/exiting fullscreen on web. Thanks [victorspringer](https://github.com/victorspringer).
* **BREAKING CHANGE**: Library now requires at least Flutter version `3.32.0` or higher.
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ This library will at the very least make a solid effort to support the second mo
of Flutter released. In other words, it will adopt `N-1` version support at
the bare minimum.

However, this cannot be guaranteed due to major changes between Flutter versions. Should that occur,
future updates will be released as major or minor versions as needed.
However, this cannot be guaranteed either due to major changes between Flutter versions or
this library's dependencies. Should that occur, future updates will be released as major or minor
versions as needed.

## 🖼️ Preview

Expand Down
6 changes: 3 additions & 3 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ version: 1.0.0
publish_to: none

environment:
sdk: '>=3.8.0 <4.0.0'
flutter: ">=3.32.0"
sdk: '>=3.10.0 <4.0.0'
flutter: ">=3.38.0"

dependencies:
chewie:
path: ../
flutter:
sdk: flutter
video_player: ^2.10.0
video_player: ^2.11.1

dev_dependencies:
flutter_test:
Expand Down
38 changes: 38 additions & 0 deletions lib/src/chewie_player.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';

import 'package:chewie/src/chewie_progress_colors.dart';
import 'web_fullscreen.dart';
import 'package:chewie/src/models/option_item.dart';
import 'package:chewie/src/models/options_translation.dart';
import 'package:chewie/src/models/subtitle_model.dart';
Expand Down Expand Up @@ -44,16 +45,30 @@ class ChewieState extends State<Chewie> {

bool get isControllerFullScreen => widget.controller.isFullScreen;
late PlayerNotifier notifier;
late final void Function() _browserFsExitHandler;

@override
void initState() {
super.initState();
widget.controller.addListener(listener);
notifier = PlayerNotifier.init();
// When the user presses Escape, the browser exits its native fullscreen
// without Chewie knowing. Detect this and collapse the fullscreen route.
_browserFsExitHandler = () {
if (!browserInFullscreen && _isFullScreen) {
widget.controller.exitFullScreen();
}
};
if (widget.controller.useNativeFullScreenOnWeb) {
addBrowserFullscreenChangeListener(_browserFsExitHandler);
}
}

@override
void dispose() {
if (widget.controller.useNativeFullScreenOnWeb) {
removeBrowserFullscreenChangeListener(_browserFsExitHandler);
}
widget.controller.removeListener(listener);
notifier.dispose();
super.dispose();
Expand Down Expand Up @@ -182,6 +197,12 @@ class ChewieState extends State<Chewie> {
WakelockPlus.enable();
}

// Ask the browser to enter its native fullscreen. Must be called before the
// first await so we are still inside the user-gesture event handler.
if (widget.controller.useNativeFullScreenOnWeb) {
requestBrowserFullscreen();
}

await Navigator.of(
context,
rootNavigator: widget.controller.useRootNavigator,
Expand All @@ -191,6 +212,11 @@ class ChewieState extends State<Chewie> {

if (kIsWeb) {
await _reInitializeControllers(wasPlaying);
// Exit native browser fullscreen when the Chewie route pops (e.g. user
// clicked the fullscreen button again). No-op if Escape was already used.
if (widget.controller.useNativeFullScreenOnWeb) {
exitBrowserFullscreen();
}
}

_isFullScreen = false;
Expand Down Expand Up @@ -325,6 +351,7 @@ class ChewieController extends ChangeNotifier {
this.allowMuting = true,
this.allowPlaybackSpeedChanging = true,
this.useRootNavigator = true,
this.useNativeFullScreenOnWeb = true,
this.playbackSpeeds = const [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2],
this.systemOverlaysOnEnterFullScreen,
this.deviceOrientationsOnEnterFullScreen,
Expand Down Expand Up @@ -378,6 +405,7 @@ class ChewieController extends ChangeNotifier {
bool? allowMuting,
bool? allowPlaybackSpeedChanging,
bool? useRootNavigator,
bool? useNativeFullScreenOnWeb,
Duration? hideControlsTimer,
EdgeInsets? controlsSafeAreaMinimum,
List<double>? playbackSpeeds,
Expand Down Expand Up @@ -441,6 +469,8 @@ class ChewieController extends ChangeNotifier {
allowPlaybackSpeedChanging:
allowPlaybackSpeedChanging ?? this.allowPlaybackSpeedChanging,
useRootNavigator: useRootNavigator ?? this.useRootNavigator,
useNativeFullScreenOnWeb:
useNativeFullScreenOnWeb ?? this.useNativeFullScreenOnWeb,
playbackSpeeds: playbackSpeeds ?? this.playbackSpeeds,
systemOverlaysOnEnterFullScreen:
systemOverlaysOnEnterFullScreen ??
Expand Down Expand Up @@ -599,6 +629,14 @@ class ChewieController extends ChangeNotifier {
/// Defines if push/pop navigations use the rootNavigator
final bool useRootNavigator;

/// On Flutter Web, also enter the browser's native fullscreen (via the
/// Fullscreen API) when going fullscreen, instead of only expanding the
/// Flutter view inside the browser window. Pressing Escape to leave the
/// browser fullscreen also exits Chewie's fullscreen.
///
/// Has no effect on non-web platforms.
final bool useNativeFullScreenOnWeb;

/// Defines the [Duration] before the video controls are hidden. By default, this is set to three seconds.
final Duration hideControlsTimer;

Expand Down
1 change: 1 addition & 0 deletions lib/src/material/material_controls.dart
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,7 @@ class _MaterialControlsState extends State<MaterialControls>
? ChewieController.defaultHideControlsTimer
: chewieController.hideControlsTimer;
_hideTimer = Timer(hideControlsTimer, () {
if (!mounted) return;
setState(() {
notifier.hideStuff = true;
});
Expand Down
2 changes: 2 additions & 0 deletions lib/src/web_fullscreen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export 'web_fullscreen_stub.dart'
if (dart.library.js_interop) 'web_fullscreen_impl.dart';
30 changes: 30 additions & 0 deletions lib/src/web_fullscreen_impl.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import 'dart:js_interop';

import 'package:web/web.dart' as web;

final _handlers = <void Function(), JSFunction>{};

void requestBrowserFullscreen() {
web.document.documentElement?.requestFullscreen();
}

void exitBrowserFullscreen() {
if (web.document.fullscreenElement != null) {
web.document.exitFullscreen();
}
}

bool get browserInFullscreen => web.document.fullscreenElement != null;

void addBrowserFullscreenChangeListener(void Function() callback) {
final jsHandler = ((JSAny? _) => callback()).toJS;
_handlers[callback] = jsHandler;
web.document.addEventListener('fullscreenchange', jsHandler);
}

void removeBrowserFullscreenChangeListener(void Function() callback) {
final jsHandler = _handlers.remove(callback);
if (jsHandler != null) {
web.document.removeEventListener('fullscreenchange', jsHandler);
}
}
5 changes: 5 additions & 0 deletions lib/src/web_fullscreen_stub.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
void requestBrowserFullscreen() {}
void exitBrowserFullscreen() {}
bool get browserInFullscreen => false;
void addBrowserFullscreenChangeListener(void Function() callback) {}
void removeBrowserFullscreenChangeListener(void Function() callback) {}
13 changes: 7 additions & 6 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
name: chewie
description: A video player for Flutter with Cupertino and Material play controls
version: 1.13.0
version: 1.14.1
homepage: https://github.com/fluttercommunity/chewie

environment:
sdk: '>=3.8.0 <4.0.0'
flutter: ">=3.32.0"
sdk: '>=3.10.0 <4.0.0'
flutter: ">=3.38.0"

dependencies:
cupertino_icons: ^1.0.8
cupertino_icons: ^1.0.9
flutter:
sdk: flutter
provider: ^6.1.5+1
video_player: ^2.10.0
wakelock_plus: ^1.3.2
video_player: ^2.11.1
wakelock_plus: ^1.6.1
web: ^1.0.0

dev_dependencies:
flutter_test:
Expand Down