diff --git a/lib/widgets/common/action_mixins/feedback.dart b/lib/widgets/common/action_mixins/feedback.dart index cf29fccaf..a8ac02206 100644 --- a/lib/widgets/common/action_mixins/feedback.dart +++ b/lib/widgets/common/action_mixins/feedback.dart @@ -24,6 +24,7 @@ typedef MarginComputer = EdgeInsets Function(BuildContext context); mixin FeedbackMixin { static final ValueNotifier snackBarMarginOverrideNotifier = ValueNotifier(null); + static OverlaySupportEntry? _overlayNotificationEntry; static EdgeInsets snackBarMarginDefault(BuildContext context) { return EdgeInsets.only( @@ -31,7 +32,11 @@ mixin FeedbackMixin { ); } - void dismissFeedback(BuildContext context) => ScaffoldMessenger.of(context).hideCurrentSnackBar(); + void dismissFeedback(BuildContext context) { + ScaffoldMessenger.of(context).hideCurrentSnackBar(); + _overlayNotificationEntry?.dismiss(); + _overlayNotificationEntry = null; + } void showFeedback(BuildContext context, FeedbackType type, String message, [SnackBarAction? action]) { ScaffoldMessengerState? scaffoldMessenger; @@ -67,8 +72,7 @@ mixin FeedbackMixin { // and space under the snack bar `margin` does not receive gestures // (because it is used by the `Dismissible` wrapping the snack bar) // so we use `showOverlayNotification` instead - OverlaySupportEntry? notificationOverlayEntry; - notificationOverlayEntry = showOverlayNotification( + _overlayNotificationEntry = showOverlayNotification( (context) => SafeArea( bottom: false, child: ValueListenableBuilder( @@ -89,7 +93,7 @@ mixin FeedbackMixin { foregroundColor: WidgetStateProperty.all(snackBarTheme.actionTextColor), ), onPressed: () { - notificationOverlayEntry?.dismiss(); + dismissFeedback(context); action.onPressed(); }, child: Text(action.label), @@ -97,7 +101,7 @@ mixin FeedbackMixin { : null, animation: kAlwaysCompleteAnimation, dismissDirection: DismissDirection.horizontal, - onDismiss: () => notificationOverlayEntry?.dismiss(), + onDismiss: () => dismissFeedback(context), ), ), ), diff --git a/lib/widgets/viewer/controls/notifications.dart b/lib/widgets/viewer/controls/notifications.dart index 7d5d9006f..ab9c78fa3 100644 --- a/lib/widgets/viewer/controls/notifications.dart +++ b/lib/widgets/viewer/controls/notifications.dart @@ -126,3 +126,6 @@ class FullImageLoadedNotification extends Notification { const FullImageLoadedNotification(this.entry, this.image); } + +@immutable +class PopupMenuOpenedNotification extends Notification {} diff --git a/lib/widgets/viewer/entry_viewer_stack.dart b/lib/widgets/viewer/entry_viewer_stack.dart index 5eb4dfbe0..cbda6d91d 100644 --- a/lib/widgets/viewer/entry_viewer_stack.dart +++ b/lib/widgets/viewer/entry_viewer_stack.dart @@ -494,13 +494,6 @@ class _EntryViewerStackState extends State with EntryViewContr ); } }, - onActionMenuOpened: () { - // if the menu is opened while overlay is hiding, - // the popup menu button is disposed and menu items are ineffective, - // so we make sure overlay stays visible - _videoActionDelegate.stopOverlayHidingTimer(); - const ToggleOverlayNotification(visible: true).dispatch(context); - }, ), ); } else if (targetEntry.is360) { @@ -602,6 +595,13 @@ class _EntryViewerStackState extends State with EntryViewContr case MoveType.export: break; } + } else if (notification is PopupMenuOpenedNotification) { + // if the menu is opened while overlay is hiding, + // the popup menu button is disposed and menu items are ineffective, + // so we make sure overlay stays visible + _overlayVisible.value = true; + _videoActionDelegate.stopOverlayHidingTimer(); + dismissFeedback(context); } else if (notification is ToggleOverlayNotification) { _overlayVisible.value = notification.visible ?? !_overlayVisible.value; } else if (notification is LockViewNotification) { diff --git a/lib/widgets/viewer/overlay/video/video.dart b/lib/widgets/viewer/overlay/video/video.dart index 2d9b97d6b..eb38e103a 100644 --- a/lib/widgets/viewer/overlay/video/video.dart +++ b/lib/widgets/viewer/overlay/video/video.dart @@ -16,7 +16,6 @@ class VideoControlOverlay extends StatefulWidget { final AvesVideoController? controller; final Animation scale; final Function(EntryAction value) onActionSelected; - final VoidCallback onActionMenuOpened; const VideoControlOverlay({ super.key, @@ -24,7 +23,6 @@ class VideoControlOverlay extends StatefulWidget { required this.controller, required this.scale, required this.onActionSelected, - required this.onActionMenuOpened, }); @override diff --git a/lib/widgets/viewer/overlay/viewer_buttons.dart b/lib/widgets/viewer/overlay/viewer_buttons.dart index bcf6287d3..ae99d9a76 100644 --- a/lib/widgets/viewer/overlay/viewer_buttons.dart +++ b/lib/widgets/viewer/overlay/viewer_buttons.dart @@ -315,12 +315,7 @@ class _ViewerButtonRowContentState extends State { _popupExpandedNotifier.value = null; }, iconSize: IconTheme.of(context).size, - onMenuOpened: () { - // if the menu is opened while overlay is hiding, - // the popup menu button is disposed and menu items are ineffective, - // so we make sure overlay stays visible - const ToggleOverlayNotification(visible: true).dispatch(context); - }, + onMenuOpened: () => PopupMenuOpenedNotification().dispatch(context), popUpAnimationStyle: animations.popUpAnimationStyle, ), ), diff --git a/lib/widgets/wallpaper_page.dart b/lib/widgets/wallpaper_page.dart index 10763ee5a..7184edff7 100644 --- a/lib/widgets/wallpaper_page.dart +++ b/lib/widgets/wallpaper_page.dart @@ -187,13 +187,6 @@ class _EntryEditorState extends State with EntryViewControllerMixin controller: videoController, action: action, ), - onActionMenuOpened: () { - // if the menu is opened while overlay is hiding, - // the popup menu button is disposed and menu items are ineffective, - // so we make sure overlay stays visible - _videoActionDelegate.stopOverlayHidingTimer(); - const ToggleOverlayNotification(visible: true).dispatch(context); - }, ), ); }