viewer: reset multipage controllers when entry metadata change
This commit is contained in:
parent
b6af664f52
commit
7ef87c125c
4 changed files with 40 additions and 5 deletions
|
@ -738,7 +738,12 @@ class AvesEntry {
|
|||
}
|
||||
|
||||
// when the MIME type or the image itself changed (e.g. after rotation)
|
||||
Future<void> _onVisualFieldChanged(String oldMimeType, int? oldDateModifiedSecs, int oldRotationDegrees, bool oldIsFlipped) async {
|
||||
Future<void> _onVisualFieldChanged(
|
||||
String oldMimeType,
|
||||
int? oldDateModifiedSecs,
|
||||
int oldRotationDegrees,
|
||||
bool oldIsFlipped,
|
||||
) async {
|
||||
if ((!MimeTypes.refersToSameType(oldMimeType, mimeType) && !MimeTypes.isVideo(oldMimeType)) || oldDateModifiedSecs != dateModifiedSecs || oldRotationDegrees != rotationDegrees || oldIsFlipped != isFlipped) {
|
||||
await EntryCache.evict(uri, oldMimeType, oldDateModifiedSecs, oldRotationDegrees, oldIsFlipped);
|
||||
imageChangeNotifier.notify();
|
||||
|
|
|
@ -71,6 +71,9 @@ class _EntryViewerStackState extends State<EntryViewerStack> with EntryViewContr
|
|||
final ValueNotifier<HeroInfo?> _heroInfoNotifier = ValueNotifier(null);
|
||||
bool _isEntryTracked = true;
|
||||
|
||||
@override
|
||||
bool get isViewingImage => _currentVerticalPage.value == imagePage;
|
||||
|
||||
@override
|
||||
late final ValueNotifier<AvesEntry?> entryNotifier;
|
||||
|
||||
|
|
|
@ -14,8 +14,11 @@ import 'package:provider/provider.dart';
|
|||
|
||||
// state controllers/monitors
|
||||
mixin EntryViewControllerMixin<T extends StatefulWidget> on State<T> {
|
||||
final Map<AvesEntry, VoidCallback> _metadataChangeListeners = {};
|
||||
final Map<MultiPageController, Future<void> Function()> _multiPageControllerPageListeners = {};
|
||||
|
||||
bool get isViewingImage;
|
||||
|
||||
ValueNotifier<AvesEntry?> get entryNotifier;
|
||||
|
||||
Future<void> initEntryControllers(AvesEntry? entry) async {
|
||||
|
@ -27,16 +30,29 @@ mixin EntryViewControllerMixin<T extends StatefulWidget> on State<T> {
|
|||
if (entry.isMultiPage) {
|
||||
await _initMultiPageController(entry);
|
||||
}
|
||||
void listener() => _onMetadataChange(entry);
|
||||
_metadataChangeListeners[entry] = listener;
|
||||
entry.metadataChangeNotifier.addListener(listener);
|
||||
}
|
||||
|
||||
void cleanEntryControllers(AvesEntry? entry) {
|
||||
if (entry == null) return;
|
||||
|
||||
final listener = _metadataChangeListeners.remove(entry);
|
||||
if (listener != null) {
|
||||
entry.metadataChangeNotifier.removeListener(listener);
|
||||
}
|
||||
if (entry.isMultiPage) {
|
||||
_cleanMultiPageController(entry);
|
||||
}
|
||||
}
|
||||
|
||||
void _onMetadataChange(AvesEntry entry) {
|
||||
debugPrint('reinitialize controllers for entry=$entry because metadata changed');
|
||||
cleanEntryControllers(entry);
|
||||
initEntryControllers(entry);
|
||||
}
|
||||
|
||||
SlideshowVideoPlayback? get videoPlaybackOverride {
|
||||
if (!mounted) return null;
|
||||
final appMode = context.read<ValueNotifier<AppMode>>().value;
|
||||
|
@ -50,7 +66,9 @@ mixin EntryViewControllerMixin<T extends StatefulWidget> on State<T> {
|
|||
}
|
||||
}
|
||||
|
||||
bool _shouldAutoPlay(BuildContext context) {
|
||||
bool _shouldAutoPlayVideo(BuildContext context) {
|
||||
if (!isViewingImage) return false;
|
||||
|
||||
switch (videoPlaybackOverride) {
|
||||
case SlideshowVideoPlayback.skip:
|
||||
return false;
|
||||
|
@ -62,11 +80,17 @@ mixin EntryViewControllerMixin<T extends StatefulWidget> on State<T> {
|
|||
}
|
||||
}
|
||||
|
||||
bool _shouldAutoPlayMotionPhoto(BuildContext context) {
|
||||
if (!isViewingImage) return false;
|
||||
|
||||
return settings.enableMotionPhotoAutoPlay;
|
||||
}
|
||||
|
||||
Future<void> _initVideoController(AvesEntry entry) async {
|
||||
final controller = context.read<VideoConductor>().getOrCreateController(entry);
|
||||
setState(() {});
|
||||
|
||||
if (_shouldAutoPlay(context)) {
|
||||
if (_shouldAutoPlayVideo(context)) {
|
||||
final resumeTimeMillis = await controller.getResumeTime(context);
|
||||
await _playVideo(controller, () => entry == entryNotifier.value, resumeTimeMillis: resumeTimeMillis);
|
||||
}
|
||||
|
@ -93,7 +117,7 @@ mixin EntryViewControllerMixin<T extends StatefulWidget> on State<T> {
|
|||
// auto play/pause when changing page
|
||||
Future<void> _onPageChange() async {
|
||||
await pauseVideoControllers();
|
||||
if (_shouldAutoPlay(context) || (entry.isMotionPhoto && settings.enableMotionPhotoAutoPlay)) {
|
||||
if (_shouldAutoPlayVideo(context) || (entry.isMotionPhoto && _shouldAutoPlayMotionPhoto(context))) {
|
||||
final page = multiPageController.page;
|
||||
final pageInfo = multiPageInfo.getByIndex(page)!;
|
||||
if (pageInfo.isVideo) {
|
||||
|
@ -111,7 +135,7 @@ mixin EntryViewControllerMixin<T extends StatefulWidget> on State<T> {
|
|||
multiPageController.pageNotifier.addListener(_onPageChange);
|
||||
await _onPageChange();
|
||||
|
||||
if (entry.isMotionPhoto && settings.enableMotionPhotoAutoPlay) {
|
||||
if (entry.isMotionPhoto && _shouldAutoPlayMotionPhoto(context)) {
|
||||
await Future.delayed(Durations.motionPhotoAutoPlayDelay);
|
||||
if (entry == entryNotifier.value) {
|
||||
multiPageController.page = 1;
|
||||
|
|
|
@ -75,6 +75,9 @@ class _EntryEditorState extends State<EntryEditor> with EntryViewControllerMixin
|
|||
late VideoActionDelegate _videoActionDelegate;
|
||||
late final ViewerController _viewerController;
|
||||
|
||||
@override
|
||||
bool get isViewingImage => true;
|
||||
|
||||
@override
|
||||
final ValueNotifier<AvesEntry?> entryNotifier = ValueNotifier(null);
|
||||
|
||||
|
|
Loading…
Reference in a new issue