diff --git a/app/lib/widget/slideshow_viewer.dart b/app/lib/widget/slideshow_viewer.dart index da3ca0e5..bc41403a 100644 --- a/app/lib/widget/slideshow_viewer.dart +++ b/app/lib/widget/slideshow_viewer.dart @@ -49,7 +49,8 @@ class SlideshowViewerArguments { class SlideshowViewer extends StatelessWidget { static const routeName = "/slideshow-viewer"; - static Route buildRoute(SlideshowViewerArguments args) => MaterialPageRoute( + static Route buildRoute(SlideshowViewerArguments args) => + MaterialPageRoute( builder: (context) => SlideshowViewer.fromArgs(args), ); @@ -116,15 +117,35 @@ class _WrappedSlideshowViewerState extends State<_WrappedSlideshowViewer> @override Widget build(BuildContext context) { - return Theme( - data: buildDarkTheme(context), - child: const AnnotatedRegion( - value: SystemUiOverlayStyle( - systemNavigationBarColor: Colors.black, - systemNavigationBarIconBrightness: Brightness.dark, + return MultiBlocListener( + listeners: [ + _BlocListenerT( + selector: (state) => state.hasRequestExit, + listener: (context, hasRequestExit) { + if (hasRequestExit) { + final pageIndex = context.state.page; + final fileIndex = context.bloc.convertPageToFileIndex(pageIndex); + Navigator.of(context).pop(fileIndex); + } + }, ), - child: Scaffold( - body: _Body(), + ], + child: Theme( + data: buildDarkTheme(context), + child: AnnotatedRegion( + value: const SystemUiOverlayStyle( + systemNavigationBarColor: Colors.black, + systemNavigationBarIconBrightness: Brightness.dark, + ), + child: Scaffold( + body: PopScope( + canPop: false, + onPopInvoked: (_) { + context.addEvent(const _RequestExit()); + }, + child: const _Body(), + ), + ), ), ), ); diff --git a/app/lib/widget/slideshow_viewer.g.dart b/app/lib/widget/slideshow_viewer.g.dart index ee27cb64..88735d34 100644 --- a/app/lib/widget/slideshow_viewer.g.dart +++ b/app/lib/widget/slideshow_viewer.g.dart @@ -25,7 +25,8 @@ abstract class $_StateCopyWithWorker { bool? hasPrev, bool? hasNext, bool? isShowTimeline, - bool? hasShownTimeline}); + bool? hasShownTimeline, + bool? hasRequestExit}); } class _$_StateCopyWithWorkerImpl implements $_StateCopyWithWorker { @@ -44,7 +45,8 @@ class _$_StateCopyWithWorkerImpl implements $_StateCopyWithWorker { dynamic hasPrev, dynamic hasNext, dynamic isShowTimeline, - dynamic hasShownTimeline}) { + dynamic hasShownTimeline, + dynamic hasRequestExit}) { return _State( hasInit: hasInit as bool? ?? that.hasInit, page: page as int? ?? that.page, @@ -58,7 +60,8 @@ class _$_StateCopyWithWorkerImpl implements $_StateCopyWithWorker { hasPrev: hasPrev as bool? ?? that.hasPrev, hasNext: hasNext as bool? ?? that.hasNext, isShowTimeline: isShowTimeline as bool? ?? that.isShowTimeline, - hasShownTimeline: hasShownTimeline as bool? ?? that.hasShownTimeline); + hasShownTimeline: hasShownTimeline as bool? ?? that.hasShownTimeline, + hasRequestExit: hasRequestExit as bool? ?? that.hasRequestExit); } final _State that; @@ -101,7 +104,7 @@ extension _$_PageViewNpLog on _PageView { extension _$_StateToString on _State { String _$toString() { // ignore: unnecessary_string_interpolations - return "_State {hasInit: $hasInit, page: $page, nextPage: $nextPage, shouldAnimateNextPage: $shouldAnimateNextPage, currentFile: ${currentFile.fdPath}, isShowUi: $isShowUi, isPlay: $isPlay, isVideoCompleted: $isVideoCompleted, hasPrev: $hasPrev, hasNext: $hasNext, isShowTimeline: $isShowTimeline, hasShownTimeline: $hasShownTimeline}"; + return "_State {hasInit: $hasInit, page: $page, nextPage: $nextPage, shouldAnimateNextPage: $shouldAnimateNextPage, currentFile: ${currentFile.fdPath}, isShowUi: $isShowUi, isPlay: $isPlay, isVideoCompleted: $isVideoCompleted, hasPrev: $hasPrev, hasNext: $hasNext, isShowTimeline: $isShowTimeline, hasShownTimeline: $hasShownTimeline, hasRequestExit: $hasRequestExit}"; } } @@ -188,3 +191,10 @@ extension _$_RequestPageToString on _RequestPage { return "_RequestPage {value: $value}"; } } + +extension _$_RequestExitToString on _RequestExit { + String _$toString() { + // ignore: unnecessary_string_interpolations + return "_RequestExit {}"; + } +} diff --git a/app/lib/widget/slideshow_viewer/bloc.dart b/app/lib/widget/slideshow_viewer/bloc.dart index 2561b5d3..643dda99 100644 --- a/app/lib/widget/slideshow_viewer/bloc.dart +++ b/app/lib/widget/slideshow_viewer/bloc.dart @@ -22,6 +22,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger { on<_NextPage>(_onNextPage); on<_ToggleTimeline>(_onToggleTimeline); on<_RequestPage>(_onRequestPage); + on<_RequestExit>(_onRequestExit); } @override @@ -179,6 +180,11 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger { )); } + void _onRequestExit(_RequestExit ev, Emitter<_State> emit) { + _log.info(ev); + emit(state.copyWith(hasRequestExit: true)); + } + static ({List shuffled, int initial, int? count}) _parseConfig({ required List files, required int startIndex, diff --git a/app/lib/widget/slideshow_viewer/state_event.dart b/app/lib/widget/slideshow_viewer/state_event.dart index 00fd8a41..44915f7e 100644 --- a/app/lib/widget/slideshow_viewer/state_event.dart +++ b/app/lib/widget/slideshow_viewer/state_event.dart @@ -16,6 +16,7 @@ class _State { required this.hasNext, required this.isShowTimeline, required this.hasShownTimeline, + required this.hasRequestExit, }); factory _State.init({ @@ -34,6 +35,7 @@ class _State { hasNext: false, isShowTimeline: false, hasShownTimeline: false, + hasRequestExit: false, ); @override @@ -51,6 +53,7 @@ class _State { final bool hasNext; final bool isShowTimeline; final bool hasShownTimeline; + final bool hasRequestExit; } abstract class _Event {} @@ -158,3 +161,11 @@ class _RequestPage implements _Event { final int value; } + +@toString +class _RequestExit implements _Event { + const _RequestExit(); + + @override + String toString() => _$toString(); +} diff --git a/app/lib/widget/slideshow_viewer/view.dart b/app/lib/widget/slideshow_viewer/view.dart index e791ef4e..df0a30a3 100644 --- a/app/lib/widget/slideshow_viewer/view.dart +++ b/app/lib/widget/slideshow_viewer/view.dart @@ -30,7 +30,7 @@ class _AppBar extends StatelessWidget { icon: const Icon(Icons.close), tooltip: MaterialLocalizations.of(context).closeButtonTooltip, onPressed: () { - Navigator.of(context).pop(); + context.addEvent(const _RequestExit()); }, ), ), diff --git a/app/lib/widget/viewer.dart b/app/lib/widget/viewer.dart index 9202aa1b..3019216a 100644 --- a/app/lib/widget/viewer.dart +++ b/app/lib/widget/viewer.dart @@ -858,13 +858,15 @@ class _ViewerState extends State unawaited(Pref().setSlideshowShuffle(result.isShuffle)); unawaited(Pref().setSlideshowRepeat(result.isRepeat)); unawaited(Pref().setSlideshowReverse(result.isReverse)); - unawaited( - Navigator.of(context).pushNamed( - SlideshowViewer.routeName, - arguments: SlideshowViewerArguments(widget.account, widget.streamFiles, - _viewerController.currentPage, result), - ), + final newIndex = await Navigator.of(context).pushNamed( + SlideshowViewer.routeName, + arguments: SlideshowViewerArguments(widget.account, widget.streamFiles, + _viewerController.currentPage, result), ); + _log.info("[_onSlideshowPressed] Slideshow ended, jump to: $newIndex"); + if (newIndex != null && context.mounted) { + _viewerController.jumpToPage(newIndex); + } } double _calcDetailPaneOffset(int index) {