#603 fixed switching to PiP when going home with gesture navigation
This commit is contained in:
parent
192cae3c1b
commit
e7985c5ea5
3 changed files with 40 additions and 30 deletions
|
@ -15,6 +15,7 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
### Fixed
|
||||
|
||||
- Video: switching to PiP when going home with gesture navigation
|
||||
- Viewer: multi-page context update when removing burst entries
|
||||
- prevent editing item when Exif editing changes mime type
|
||||
- parsing videos with skippable boxes in `meta` box
|
||||
|
|
|
@ -61,6 +61,11 @@ class AvesApp extends StatefulWidget {
|
|||
static final List<Locale> supportedLocales = AppLocalizations.supportedLocales.where((v) => !_unsupportedLocales.contains(v)).toList();
|
||||
static final ValueNotifier<EdgeInsets> cutoutInsetsNotifier = ValueNotifier(EdgeInsets.zero);
|
||||
|
||||
// children widgets registering as `WidgetsBinding` observers and implementing `didChangeAppLifecycleState`
|
||||
// do not receive events fast enough for time sensitive actions (like PiP when leaving by gesture to home)
|
||||
// so we use this notifier to propagate events as soon as received by the top widget `AvesApp`
|
||||
static final ValueNotifier<AppLifecycleState> lifecycleStateNotifier = ValueNotifier(AppLifecycleState.detached);
|
||||
|
||||
// do not monitor all `ModalRoute`s, which would include popup menus,
|
||||
// so that we can react to fullscreen `PageRoute`s only
|
||||
static final RouteObserver<PageRoute> pageRouteObserver = RouteObserver<PageRoute>();
|
||||
|
@ -364,6 +369,7 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
|||
@override
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
reportService.log('Lifecycle ${state.name}');
|
||||
AvesApp.lifecycleStateNotifier.value = state;
|
||||
switch (state) {
|
||||
case AppLifecycleState.inactive:
|
||||
switch (_appModeNotifier.value) {
|
||||
|
|
|
@ -62,7 +62,7 @@ class EntryViewerStack extends StatefulWidget {
|
|||
State<EntryViewerStack> createState() => _EntryViewerStackState();
|
||||
}
|
||||
|
||||
class _EntryViewerStackState extends State<EntryViewerStack> with EntryViewControllerMixin, FeedbackMixin, SingleTickerProviderStateMixin, WidgetsBindingObserver {
|
||||
class _EntryViewerStackState extends State<EntryViewerStack> with EntryViewControllerMixin, FeedbackMixin, SingleTickerProviderStateMixin {
|
||||
final Floating _floating = Floating();
|
||||
late int _currentEntryIndex;
|
||||
late ValueNotifier<int> _currentVerticalPage;
|
||||
|
@ -155,7 +155,7 @@ class _EntryViewerStackState extends State<EntryViewerStack> with EntryViewContr
|
|||
);
|
||||
initEntryControllers(entry);
|
||||
_registerWidget(widget);
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
AvesApp.lifecycleStateNotifier.addListener(_onAppLifecycleStateChanged);
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => _initOverlay());
|
||||
}
|
||||
|
||||
|
@ -178,7 +178,7 @@ class _EntryViewerStackState extends State<EntryViewerStack> with EntryViewContr
|
|||
_verticalPager.dispose();
|
||||
_heroInfoNotifier.dispose();
|
||||
_stopOverlayHidingTimer();
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
AvesApp.lifecycleStateNotifier.removeListener(_onAppLifecycleStateChanged);
|
||||
_unregisterWidget(widget);
|
||||
super.dispose();
|
||||
}
|
||||
|
@ -191,33 +191,6 @@ class _EntryViewerStackState extends State<EntryViewerStack> with EntryViewContr
|
|||
widget.collection?.removeListener(_onCollectionChanged);
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
switch (state) {
|
||||
case AppLifecycleState.inactive:
|
||||
_onAppInactive();
|
||||
break;
|
||||
case AppLifecycleState.paused:
|
||||
case AppLifecycleState.detached:
|
||||
pauseVideoControllers();
|
||||
break;
|
||||
case AppLifecycleState.resumed:
|
||||
availability.onResume();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onAppInactive() async {
|
||||
viewerController.autopilot = false;
|
||||
bool enabledPip = false;
|
||||
if (settings.videoBackgroundMode == VideoBackgroundMode.pip) {
|
||||
enabledPip |= await _enablePictureInPicture();
|
||||
}
|
||||
if (!enabledPip) {
|
||||
await pauseVideoControllers();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final viewStateConductor = context.read<ViewStateConductor>();
|
||||
|
@ -292,6 +265,36 @@ class _EntryViewerStackState extends State<EntryViewerStack> with EntryViewContr
|
|||
);
|
||||
}
|
||||
|
||||
void _onAppLifecycleStateChanged() {
|
||||
switch (AvesApp.lifecycleStateNotifier.value) {
|
||||
case AppLifecycleState.inactive:
|
||||
_onAppInactive();
|
||||
break;
|
||||
case AppLifecycleState.paused:
|
||||
case AppLifecycleState.detached:
|
||||
pauseVideoControllers();
|
||||
break;
|
||||
case AppLifecycleState.resumed:
|
||||
availability.onResume();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onAppInactive() async {
|
||||
final playingController = context.read<VideoConductor>().getPlayingController();
|
||||
viewerController.autopilot = false;
|
||||
bool enabledPip = false;
|
||||
if (settings.videoBackgroundMode == VideoBackgroundMode.pip) {
|
||||
enabledPip |= await _enablePictureInPicture();
|
||||
}
|
||||
if (enabledPip) {
|
||||
// ensure playback, in case lifecycle paused/resumed events happened when switching to PiP
|
||||
await playingController?.play();
|
||||
} else {
|
||||
await pauseVideoControllers();
|
||||
}
|
||||
}
|
||||
|
||||
Widget _decorateOverlay(Widget overlay) {
|
||||
return ValueListenableBuilder<double>(
|
||||
valueListenable: _overlayAnimationController,
|
||||
|
|
Loading…
Reference in a new issue