Jump to the last item shown after exiting slideshow

This commit is contained in:
Ming Ming 2024-08-25 23:29:12 +08:00
parent 655ce1a3fe
commit 2a5e49c588
6 changed files with 70 additions and 20 deletions

View file

@ -49,7 +49,8 @@ class SlideshowViewerArguments {
class SlideshowViewer extends StatelessWidget { class SlideshowViewer extends StatelessWidget {
static const routeName = "/slideshow-viewer"; static const routeName = "/slideshow-viewer";
static Route buildRoute(SlideshowViewerArguments args) => MaterialPageRoute( static Route buildRoute(SlideshowViewerArguments args) =>
MaterialPageRoute<int>(
builder: (context) => SlideshowViewer.fromArgs(args), builder: (context) => SlideshowViewer.fromArgs(args),
); );
@ -116,15 +117,35 @@ class _WrappedSlideshowViewerState extends State<_WrappedSlideshowViewer>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Theme( return MultiBlocListener(
listeners: [
_BlocListenerT<bool>(
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: Theme(
data: buildDarkTheme(context), data: buildDarkTheme(context),
child: const AnnotatedRegion<SystemUiOverlayStyle>( child: AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle( value: const SystemUiOverlayStyle(
systemNavigationBarColor: Colors.black, systemNavigationBarColor: Colors.black,
systemNavigationBarIconBrightness: Brightness.dark, systemNavigationBarIconBrightness: Brightness.dark,
), ),
child: Scaffold( child: Scaffold(
body: _Body(), body: PopScope(
canPop: false,
onPopInvoked: (_) {
context.addEvent(const _RequestExit());
},
child: const _Body(),
),
),
), ),
), ),
); );

View file

@ -25,7 +25,8 @@ abstract class $_StateCopyWithWorker {
bool? hasPrev, bool? hasPrev,
bool? hasNext, bool? hasNext,
bool? isShowTimeline, bool? isShowTimeline,
bool? hasShownTimeline}); bool? hasShownTimeline,
bool? hasRequestExit});
} }
class _$_StateCopyWithWorkerImpl implements $_StateCopyWithWorker { class _$_StateCopyWithWorkerImpl implements $_StateCopyWithWorker {
@ -44,7 +45,8 @@ class _$_StateCopyWithWorkerImpl implements $_StateCopyWithWorker {
dynamic hasPrev, dynamic hasPrev,
dynamic hasNext, dynamic hasNext,
dynamic isShowTimeline, dynamic isShowTimeline,
dynamic hasShownTimeline}) { dynamic hasShownTimeline,
dynamic hasRequestExit}) {
return _State( return _State(
hasInit: hasInit as bool? ?? that.hasInit, hasInit: hasInit as bool? ?? that.hasInit,
page: page as int? ?? that.page, page: page as int? ?? that.page,
@ -58,7 +60,8 @@ class _$_StateCopyWithWorkerImpl implements $_StateCopyWithWorker {
hasPrev: hasPrev as bool? ?? that.hasPrev, hasPrev: hasPrev as bool? ?? that.hasPrev,
hasNext: hasNext as bool? ?? that.hasNext, hasNext: hasNext as bool? ?? that.hasNext,
isShowTimeline: isShowTimeline as bool? ?? that.isShowTimeline, 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; final _State that;
@ -101,7 +104,7 @@ extension _$_PageViewNpLog on _PageView {
extension _$_StateToString on _State { extension _$_StateToString on _State {
String _$toString() { String _$toString() {
// ignore: unnecessary_string_interpolations // 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}"; return "_RequestPage {value: $value}";
} }
} }
extension _$_RequestExitToString on _RequestExit {
String _$toString() {
// ignore: unnecessary_string_interpolations
return "_RequestExit {}";
}
}

View file

@ -22,6 +22,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
on<_NextPage>(_onNextPage); on<_NextPage>(_onNextPage);
on<_ToggleTimeline>(_onToggleTimeline); on<_ToggleTimeline>(_onToggleTimeline);
on<_RequestPage>(_onRequestPage); on<_RequestPage>(_onRequestPage);
on<_RequestExit>(_onRequestExit);
} }
@override @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<int> shuffled, int initial, int? count}) _parseConfig({ static ({List<int> shuffled, int initial, int? count}) _parseConfig({
required List<FileDescriptor> files, required List<FileDescriptor> files,
required int startIndex, required int startIndex,

View file

@ -16,6 +16,7 @@ class _State {
required this.hasNext, required this.hasNext,
required this.isShowTimeline, required this.isShowTimeline,
required this.hasShownTimeline, required this.hasShownTimeline,
required this.hasRequestExit,
}); });
factory _State.init({ factory _State.init({
@ -34,6 +35,7 @@ class _State {
hasNext: false, hasNext: false,
isShowTimeline: false, isShowTimeline: false,
hasShownTimeline: false, hasShownTimeline: false,
hasRequestExit: false,
); );
@override @override
@ -51,6 +53,7 @@ class _State {
final bool hasNext; final bool hasNext;
final bool isShowTimeline; final bool isShowTimeline;
final bool hasShownTimeline; final bool hasShownTimeline;
final bool hasRequestExit;
} }
abstract class _Event {} abstract class _Event {}
@ -158,3 +161,11 @@ class _RequestPage implements _Event {
final int value; final int value;
} }
@toString
class _RequestExit implements _Event {
const _RequestExit();
@override
String toString() => _$toString();
}

View file

@ -30,7 +30,7 @@ class _AppBar extends StatelessWidget {
icon: const Icon(Icons.close), icon: const Icon(Icons.close),
tooltip: MaterialLocalizations.of(context).closeButtonTooltip, tooltip: MaterialLocalizations.of(context).closeButtonTooltip,
onPressed: () { onPressed: () {
Navigator.of(context).pop(); context.addEvent(const _RequestExit());
}, },
), ),
), ),

View file

@ -858,13 +858,15 @@ class _ViewerState extends State<Viewer>
unawaited(Pref().setSlideshowShuffle(result.isShuffle)); unawaited(Pref().setSlideshowShuffle(result.isShuffle));
unawaited(Pref().setSlideshowRepeat(result.isRepeat)); unawaited(Pref().setSlideshowRepeat(result.isRepeat));
unawaited(Pref().setSlideshowReverse(result.isReverse)); unawaited(Pref().setSlideshowReverse(result.isReverse));
unawaited( final newIndex = await Navigator.of(context).pushNamed<int>(
Navigator.of(context).pushNamed(
SlideshowViewer.routeName, SlideshowViewer.routeName,
arguments: SlideshowViewerArguments(widget.account, widget.streamFiles, arguments: SlideshowViewerArguments(widget.account, widget.streamFiles,
_viewerController.currentPage, result), _viewerController.currentPage, result),
),
); );
_log.info("[_onSlideshowPressed] Slideshow ended, jump to: $newIndex");
if (newIndex != null && context.mounted) {
_viewerController.jumpToPage(newIndex);
}
} }
double _calcDetailPaneOffset(int index) { double _calcDetailPaneOffset(int index) {