diff --git a/CHANGELOG.md b/CHANGELOG.md index 87b437164..1ca067a75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ All notable changes to this project will be documented in this file. ### Fixed - transition between collection and viewer when cutout area is not used +- saving video playback state when leaving viewer ## [v1.7.8] - 2022-12-20 diff --git a/lib/widgets/viewer/entry_viewer_page.dart b/lib/widgets/viewer/entry_viewer_page.dart index 1a1eea9b9..a58dc6315 100644 --- a/lib/widgets/viewer/entry_viewer_page.dart +++ b/lib/widgets/viewer/entry_viewer_page.dart @@ -1,4 +1,3 @@ -import 'package:aves/app_mode.dart'; import 'package:aves/model/entry.dart'; import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/widgets/viewer/controller.dart'; @@ -96,9 +95,7 @@ class VideoConductorProvider extends StatelessWidget { @override Widget build(BuildContext context) { return Provider( - create: (context) => VideoConductor( - persistPlayback: context.read>().value == AppMode.main, - ), + create: (context) => VideoConductor(), dispose: (context, value) => value.dispose(), child: child, ); diff --git a/lib/widgets/viewer/entry_viewer_stack.dart b/lib/widgets/viewer/entry_viewer_stack.dart index 457a1bae0..07d077396 100644 --- a/lib/widgets/viewer/entry_viewer_stack.dart +++ b/lib/widgets/viewer/entry_viewer_stack.dart @@ -604,8 +604,7 @@ class _EntryViewerStackState extends State with EntryViewContr if (Navigator.canPop(context)) { Navigator.pop(context); } else { - // leave viewer - SystemNavigator.pop(); + _leaveViewer(); } } @@ -654,11 +653,18 @@ class _EntryViewerStackState extends State with EntryViewContr pop(); } } else { - // exit app when trying to pop a viewer page for a single entry - SystemNavigator.pop(); + // exit app when trying to pop a viewer page + _leaveViewer(); } } + Future _leaveViewer() async { + // widgets do not get disposed normally when popping the `SystemNavigator` + // so we manually clean video controllers and save playback state + await context.read().dispose(); + await SystemNavigator.pop(); + } + // track item when returning to collection, // if they are not fully visible already void _trackEntry() { diff --git a/lib/widgets/viewer/video/conductor.dart b/lib/widgets/viewer/video/conductor.dart index fb817ede9..08389e802 100644 --- a/lib/widgets/viewer/video/conductor.dart +++ b/lib/widgets/viewer/video/conductor.dart @@ -11,14 +11,13 @@ import 'package:collection/collection.dart'; class VideoConductor { final List _controllers = []; final List _subscriptions = []; - final bool persistPlayback; static const _defaultMaxControllerCount = 3; - VideoConductor({required this.persistPlayback}); + VideoConductor(); Future dispose() async { - await Future.forEach(_controllers, (controller) => controller.dispose()); + await disposeAll(); _subscriptions ..forEach((sub) => sub.cancel()) ..clear(); @@ -33,7 +32,7 @@ class VideoConductor { if (controller != null) { _controllers.remove(controller); } else { - controller = IjkPlayerAvesVideoController(entry, persistPlayback: persistPlayback); + controller = IjkPlayerAvesVideoController(entry, persistPlayback: true); _subscriptions.add(controller.statusStream.listen(_onControllerStatusChanged)); } _controllers.insert(0, controller); @@ -55,6 +54,8 @@ class VideoConductor { Future _applyToAll(FutureOr Function(AvesVideoController controller) action) => Future.forEach(_controllers, action); + Future disposeAll() => _applyToAll((controller) => controller.dispose()); + Future pauseAll() => _applyToAll((controller) => controller.pause()); Future muteAll(bool muted) => _applyToAll((controller) => controller.mute(muted));