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));