a11y: disabling animations also applies to pop up menus

This commit is contained in:
Thibault Deckers 2024-02-24 18:38:15 +01:00
parent 786335ede3
commit 535936666c
15 changed files with 78 additions and 23 deletions

View file

@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
## <a id="unreleased"></a>[Unreleased] ## <a id="unreleased"></a>[Unreleased]
### Changed
- check Media Store changes when resuming app
- disabling animations also applies to pop up menus
## <a id="v1.10.5"></a>[v1.10.5] - 2024-02-22 ## <a id="v1.10.5"></a>[v1.10.5] - 2024-02-22
### Added ### Added

View file

@ -1,5 +1,7 @@
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/theme/durations.dart';
import 'package:aves_model/aves_model.dart'; import 'package:aves_model/aves_model.dart';
import 'package:flutter/widgets.dart';
extension ExtraAccessibilityAnimations on AccessibilityAnimations { extension ExtraAccessibilityAnimations on AccessibilityAnimations {
bool get animate { bool get animate {
@ -14,4 +16,17 @@ extension ExtraAccessibilityAnimations on AccessibilityAnimations {
return true; return true;
} }
} }
Duration get popUpAnimationDuration => animate ? ADurations.popupMenuAnimation : Duration.zero;
Duration get popUpAnimationDelay => popUpAnimationDuration + const Duration(milliseconds: ADurations.transitionMarginMillis);
AnimationStyle get popUpAnimationStyle {
return animate
? AnimationStyle(
curve: Curves.easeInOutCubic,
duration: popUpAnimationDuration,
)
: AnimationStyle.noAnimation;
}
} }

View file

@ -2,12 +2,13 @@ import 'package:flutter/foundation.dart';
class ADurations { class ADurations {
// Flutter animations (with margin) // Flutter animations (with margin)
static const popupMenuAnimation = Duration(milliseconds: 300 + 20); // ref `_kMenuDuration` used in `_PopupMenuRoute` static const transitionMarginMillis = 20;
// page transition duration also available via `ModalRoute.of(context)!.transitionDuration * timeDilation` // page transition duration also available via `ModalRoute.of(context)!.transitionDuration * timeDilation`
static const pageTransitionAnimation = Duration(milliseconds: 300 + 20); // ref `transitionDuration` used in `MaterialRouteTransitionMixin` static const pageTransitionAnimation = Duration(milliseconds: 300 + transitionMarginMillis); // ref `transitionDuration` used in `MaterialRouteTransitionMixin`
static const dialogTransitionAnimation = Duration(milliseconds: 150 + 20); // ref `transitionDuration` used in `DialogRoute` static const dialogTransitionAnimation = Duration(milliseconds: 150 + transitionMarginMillis); // ref `transitionDuration` used in `DialogRoute`
static const drawerTransitionAnimation = Duration(milliseconds: 246 + 20); // ref `_kBaseSettleDuration` used in `DrawerControllerState` static const drawerTransitionAnimation = Duration(milliseconds: 246 + transitionMarginMillis); // ref `_kBaseSettleDuration` used in `DrawerControllerState`
static const toggleableTransitionAnimation = Duration(milliseconds: 200 + 20); // ref `_kToggleDuration` used in `ToggleableStateMixin` static const toggleableTransitionAnimation = Duration(milliseconds: 200 + transitionMarginMillis); // ref `_kToggleDuration` used in `ToggleableStateMixin`
// common animations // common animations
static const sweeperOpacityAnimation = Duration(milliseconds: 150); static const sweeperOpacityAnimation = Duration(milliseconds: 150);
@ -16,6 +17,7 @@ class ADurations {
static const appBarTitleAnimation = Duration(milliseconds: 300); static const appBarTitleAnimation = Duration(milliseconds: 300);
static const appBarActionChangeAnimation = Duration(milliseconds: 200); static const appBarActionChangeAnimation = Duration(milliseconds: 200);
static const popupMenuAnimation = Duration(milliseconds: 300);
// filter grids animations // filter grids animations
static const chipDecorationAnimation = Duration(milliseconds: 200); static const chipDecorationAnimation = Duration(milliseconds: 200);

View file

@ -7,6 +7,7 @@ import 'package:aves/model/filters/query.dart';
import 'package:aves/model/filters/trash.dart'; import 'package:aves/model/filters/trash.dart';
import 'package:aves/model/query.dart'; import 'package:aves/model/query.dart';
import 'package:aves/model/selection.dart'; import 'package:aves/model/selection.dart';
import 'package:aves/model/settings/enums/accessibility_animations.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/collection_source.dart';
@ -382,6 +383,7 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
(action) => _buildButtonIcon(context, action, enabled: canApply(action), selection: selection), (action) => _buildButtonIcon(context, action, enabled: canApply(action), selection: selection),
); );
final animations = context.select<Settings, AccessibilityAnimations>((s) => s.accessibilityAnimations);
return [ return [
...quickActionButtons, ...quickActionButtons,
PopupMenuButton<EntrySetAction>( PopupMenuButton<EntrySetAction>(
@ -432,9 +434,10 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
}, },
onSelected: (action) async { onSelected: (action) async {
// wait for the popup menu to hide before proceeding with the action // wait for the popup menu to hide before proceeding with the action
await Future.delayed(ADurations.popupMenuAnimation * timeDilation); await Future.delayed(animations.popUpAnimationDelay * timeDilation);
await _onActionSelected(action); await _onActionSelected(action);
}, },
popUpAnimationStyle: animations.popUpAnimationStyle,
), ),
]; ];
} }

View file

@ -21,6 +21,7 @@ class AvesPopupMenuButton<T> extends PopupMenuButton<T> {
super.enableFeedback, super.enableFeedback,
super.iconSize, super.iconSize,
this.onMenuOpened, this.onMenuOpened,
super.popUpAnimationStyle,
}); });
@override @override

View file

@ -11,7 +11,6 @@ import 'package:aves/model/filters/tag.dart';
import 'package:aves/model/settings/enums/accessibility_animations.dart'; import 'package:aves/model/settings/enums/accessibility_animations.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/theme/colors.dart'; import 'package:aves/theme/colors.dart';
import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/view/view.dart'; import 'package:aves/view/view.dart';
import 'package:aves/widgets/collection/filter_bar.dart'; import 'package:aves/widgets/collection/filter_bar.dart';
@ -117,6 +116,7 @@ class AvesFilterChip extends StatefulWidget {
final overlay = Overlay.of(context).context.findRenderObject() as RenderBox; final overlay = Overlay.of(context).context.findRenderObject() as RenderBox;
const touchArea = Size(kMinInteractiveDimension, kMinInteractiveDimension); const touchArea = Size(kMinInteractiveDimension, kMinInteractiveDimension);
final actionDelegate = ChipActionDelegate(); final actionDelegate = ChipActionDelegate();
final animations = context.read<Settings>().accessibilityAnimations;
final selectedAction = await showMenu<ChipAction>( final selectedAction = await showMenu<ChipAction>(
context: context, context: context,
position: RelativeRect.fromRect(tapPosition & touchArea, Offset.zero & overlay.size), position: RelativeRect.fromRect(tapPosition & touchArea, Offset.zero & overlay.size),
@ -149,10 +149,11 @@ class AvesFilterChip extends StatefulWidget {
); );
}), }),
], ],
popUpAnimationStyle: animations.popUpAnimationStyle,
); );
if (selectedAction != null) { if (selectedAction != null) {
// wait for the popup menu to hide before proceeding with the action // wait for the popup menu to hide before proceeding with the action
await Future.delayed(ADurations.popupMenuAnimation * timeDilation); await Future.delayed(animations.popUpAnimationDelay * timeDilation);
actionDelegate.onActionSelected(context, filter, selectedAction); actionDelegate.onActionSelected(context, filter, selectedAction);
} }
} }

View file

@ -4,9 +4,9 @@ import 'package:aves/model/favourites.dart';
import 'package:aves/model/filters/location.dart'; import 'package:aves/model/filters/location.dart';
import 'package:aves/model/filters/path.dart'; import 'package:aves/model/filters/path.dart';
import 'package:aves/model/filters/tag.dart'; import 'package:aves/model/filters/tag.dart';
import 'package:aves/model/settings/enums/accessibility_animations.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/collection_source.dart';
import 'package:aves/theme/durations.dart';
import 'package:aves/widgets/common/basic/font_size_icon_theme.dart'; import 'package:aves/widgets/common/basic/font_size_icon_theme.dart';
import 'package:aves/widgets/common/basic/popup/menu_row.dart'; import 'package:aves/widgets/common/basic/popup/menu_row.dart';
import 'package:aves/widgets/common/basic/scaffold.dart'; import 'package:aves/widgets/common/basic/scaffold.dart';
@ -25,6 +25,7 @@ import 'package:aves/widgets/debug/media_store_scan_dialog.dart';
import 'package:aves/widgets/debug/report.dart'; import 'package:aves/widgets/debug/report.dart';
import 'package:aves/widgets/debug/settings.dart'; import 'package:aves/widgets/debug/settings.dart';
import 'package:aves/widgets/debug/storage.dart'; import 'package:aves/widgets/debug/storage.dart';
import 'package:aves_model/aves_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -36,6 +37,7 @@ class AppDebugPage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final animations = context.select<Settings, AccessibilityAnimations>((s) => s.accessibilityAnimations);
return Directionality( return Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: AvesScaffold( child: AvesScaffold(
@ -56,9 +58,10 @@ class AppDebugPage extends StatelessWidget {
.toList(), .toList(),
onSelected: (action) async { onSelected: (action) async {
// wait for the popup menu to hide before proceeding with the action // wait for the popup menu to hide before proceeding with the action
await Future.delayed(ADurations.popupMenuAnimation * timeDilation); await Future.delayed(animations.popUpAnimationDelay * timeDilation);
unawaited(_onActionSelected(context, action)); unawaited(_onActionSelected(context, action));
}, },
popUpAnimationStyle: animations.popUpAnimationStyle,
), ),
), ),
], ],

View file

@ -2,8 +2,8 @@ import 'dart:math';
import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/entry/entry.dart';
import 'package:aves/model/naming_pattern.dart'; import 'package:aves/model/naming_pattern.dart';
import 'package:aves/model/settings/enums/accessibility_animations.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/theme/styles.dart'; import 'package:aves/theme/styles.dart';
import 'package:aves/widgets/collection/collection_grid.dart'; import 'package:aves/widgets/collection/collection_grid.dart';
@ -14,8 +14,10 @@ import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/common/grid/theme.dart'; import 'package:aves/widgets/common/grid/theme.dart';
import 'package:aves/widgets/common/identity/buttons/outlined_button.dart'; import 'package:aves/widgets/common/identity/buttons/outlined_button.dart';
import 'package:aves/widgets/common/thumbnail/decorated.dart'; import 'package:aves/widgets/common/thumbnail/decorated.dart';
import 'package:aves_model/aves_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
import 'package:provider/provider.dart';
class RenameEntrySetPage extends StatefulWidget { class RenameEntrySetPage extends StatefulWidget {
static const routeName = '/rename_entry_set'; static const routeName = '/rename_entry_set';
@ -62,6 +64,7 @@ class _RenameEntrySetPageState extends State<RenameEntrySetPage> {
final l10n = context.l10n; final l10n = context.l10n;
final textScaler = MediaQuery.textScalerOf(context); final textScaler = MediaQuery.textScalerOf(context);
final effectiveThumbnailExtent = max(thumbnailExtent, textScaler.scale(thumbnailExtent)); final effectiveThumbnailExtent = max(thumbnailExtent, textScaler.scale(thumbnailExtent));
final animations = context.select<Settings, AccessibilityAnimations>((s) => s.accessibilityAnimations);
return AvesScaffold( return AvesScaffold(
appBar: AppBar( appBar: AppBar(
title: Text(l10n.renameEntrySetPageTitle), title: Text(l10n.renameEntrySetPageTitle),
@ -104,11 +107,12 @@ class _RenameEntrySetPageState extends State<RenameEntrySetPage> {
}, },
onSelected: (key) async { onSelected: (key) async {
// wait for the popup menu to hide before proceeding with the action // wait for the popup menu to hide before proceeding with the action
await Future.delayed(ADurations.popupMenuAnimation * timeDilation); await Future.delayed(animations.popUpAnimationDelay * timeDilation);
_insertProcessor(key); _insertProcessor(key);
}, },
tooltip: l10n.renameEntrySetPageInsertTooltip, tooltip: l10n.renameEntrySetPageInsertTooltip,
icon: const Icon(AIcons.add), icon: const Icon(AIcons.add),
popUpAnimationStyle: animations.popUpAnimationStyle,
), ),
), ),
], ],

View file

@ -2,6 +2,7 @@ import 'package:aves/app_mode.dart';
import 'package:aves/model/filters/album.dart'; import 'package:aves/model/filters/album.dart';
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/selection.dart'; import 'package:aves/model/selection.dart';
import 'package:aves/model/settings/enums/accessibility_animations.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/model/source/album.dart'; import 'package:aves/model/source/album.dart';
import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/collection_source.dart';
@ -205,6 +206,7 @@ class _AlbumPickPageState extends State<_AlbumPickPage> {
required bool Function(ChipSetAction action) isVisible, required bool Function(ChipSetAction action) isVisible,
required void Function(ChipSetAction action) onActionSelected, required void Function(ChipSetAction action) onActionSelected,
}) { }) {
final animations = context.select<Settings, AccessibilityAnimations>((s) => s.accessibilityAnimations);
return [ return [
if (widget.moveType != null) if (widget.moveType != null)
..._quickActions.where(isVisible).map( ..._quickActions.where(isVisible).map(
@ -227,9 +229,10 @@ class _AlbumPickPageState extends State<_AlbumPickPage> {
FocusManager.instance.primaryFocus?.unfocus(); FocusManager.instance.primaryFocus?.unfocus();
// wait for the popup menu to hide before proceeding with the action // wait for the popup menu to hide before proceeding with the action
await Future.delayed(ADurations.popupMenuAnimation * timeDilation); await Future.delayed(animations.popUpAnimationDelay * timeDilation);
onActionSelected(action); onActionSelected(action);
}, },
popUpAnimationStyle: animations.popUpAnimationStyle,
), ),
]; ];
} }

View file

@ -4,6 +4,7 @@ import 'package:aves/app_mode.dart';
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/query.dart'; import 'package:aves/model/query.dart';
import 'package:aves/model/selection.dart'; import 'package:aves/model/selection.dart';
import 'package:aves/model/settings/enums/accessibility_animations.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/collection_source.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
@ -329,6 +330,7 @@ class _FilterGridAppBarState<T extends CollectionFilter, CSAD extends ChipSetAct
(action) => _buildButtonIcon(context, actionDelegate, action, enabled: canApply(action)), (action) => _buildButtonIcon(context, actionDelegate, action, enabled: canApply(action)),
); );
final animations = context.select<Settings, AccessibilityAnimations>((s) => s.accessibilityAnimations);
return [ return [
...quickActionButtons, ...quickActionButtons,
PopupMenuButton<ChipSetAction>( PopupMenuButton<ChipSetAction>(
@ -366,9 +368,10 @@ class _FilterGridAppBarState<T extends CollectionFilter, CSAD extends ChipSetAct
FocusManager.instance.primaryFocus?.unfocus(); FocusManager.instance.primaryFocus?.unfocus();
// wait for the popup menu to hide before proceeding with the action // wait for the popup menu to hide before proceeding with the action
await Future.delayed(ADurations.popupMenuAnimation * timeDilation); await Future.delayed(animations.popUpAnimationDelay * timeDilation);
_onActionSelected(context, action, actionDelegate); _onActionSelected(context, action, actionDelegate);
}, },
popUpAnimationStyle: animations.popUpAnimationStyle,
), ),
]; ];
} }

View file

@ -7,6 +7,7 @@ import 'package:aves/model/filters/coordinate.dart';
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/geotiff.dart'; import 'package:aves/model/geotiff.dart';
import 'package:aves/model/highlight.dart'; import 'package:aves/model/highlight.dart';
import 'package:aves/model/settings/enums/accessibility_animations.dart';
import 'package:aves/model/settings/enums/map_style.dart'; import 'package:aves/model/settings/enums/map_style.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_lens.dart';
@ -462,6 +463,7 @@ class _ContentState extends State<_Content> with SingleTickerProviderStateMixin
) async { ) async {
final overlay = Overlay.of(context).context.findRenderObject() as RenderBox; final overlay = Overlay.of(context).context.findRenderObject() as RenderBox;
const touchArea = Size(kMinInteractiveDimension, kMinInteractiveDimension); const touchArea = Size(kMinInteractiveDimension, kMinInteractiveDimension);
final animations = context.read<Settings>().accessibilityAnimations;
final selectedAction = await showMenu<MapClusterAction>( final selectedAction = await showMenu<MapClusterAction>(
context: context, context: context,
position: RelativeRect.fromRect(tapLocalPosition & touchArea, Offset.zero & overlay.size), position: RelativeRect.fromRect(tapLocalPosition & touchArea, Offset.zero & overlay.size),
@ -482,10 +484,11 @@ class _ContentState extends State<_Content> with SingleTickerProviderStateMixin
MapClusterAction.removeLocation, MapClusterAction.removeLocation,
].map(_buildMenuItem), ].map(_buildMenuItem),
], ],
popUpAnimationStyle: animations.popUpAnimationStyle,
); );
if (selectedAction != null) { if (selectedAction != null) {
// wait for the popup menu to hide before proceeding with the action // wait for the popup menu to hide before proceeding with the action
await Future.delayed(ADurations.popupMenuAnimation * timeDilation); await Future.delayed(animations.popUpAnimationDelay * timeDilation);
final delegate = EntrySetActionDelegate(); final delegate = EntrySetActionDelegate();
switch (selectedAction) { switch (selectedAction) {
case MapClusterAction.editLocation: case MapClusterAction.editLocation:

View file

@ -1,5 +1,6 @@
import 'dart:io'; import 'dart:io';
import 'package:aves/model/settings/enums/accessibility_animations.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/services/common/services.dart'; import 'package:aves/services/common/services.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
@ -18,6 +19,7 @@ import 'package:collection/collection.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
import 'package:provider/provider.dart';
class FilePickerPage extends StatefulWidget { class FilePickerPage extends StatefulWidget {
static const routeName = '/file_picker'; static const routeName = '/file_picker';
@ -57,6 +59,7 @@ class _FilePickerPageState extends State<FilePickerPage> {
return !isHidden; return !isHidden;
} }
}).toList(); }).toList();
final animations = context.select<Settings, AccessibilityAnimations>((s) => s.accessibilityAnimations);
return PopScope( return PopScope(
canPop: _directory.relativeDir.isEmpty, canPop: _directory.relativeDir.isEmpty,
onPopInvoked: (didPop) { onPopInvoked: (didPop) {
@ -82,13 +85,14 @@ class _FilePickerPageState extends State<FilePickerPage> {
}, },
onSelected: (action) async { onSelected: (action) async {
// wait for the popup menu to hide before proceeding with the action // wait for the popup menu to hide before proceeding with the action
await Future.delayed(ADurations.popupMenuAnimation * timeDilation); await Future.delayed(animations.popUpAnimationDelay * timeDilation);
switch (action) { switch (action) {
case _PickerAction.toggleHiddenView: case _PickerAction.toggleHiddenView:
settings.filePickerShowHiddenFiles = !showHidden; settings.filePickerShowHiddenFiles = !showHidden;
setState(() {}); setState(() {});
} }
}, },
popUpAnimationStyle: animations.popUpAnimationStyle,
), ),
), ),
], ],

View file

@ -1,10 +1,11 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:aves/model/settings/enums/accessibility_animations.dart';
import 'package:aves/model/settings/settings.dart';
import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/collection_source.dart';
import 'package:aves/ref/mime_types.dart'; import 'package:aves/ref/mime_types.dart';
import 'package:aves/services/common/services.dart'; import 'package:aves/services/common/services.dart';
import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/theme/themes.dart'; import 'package:aves/theme/themes.dart';
import 'package:aves/widgets/common/action_mixins/feedback.dart'; import 'package:aves/widgets/common/action_mixins/feedback.dart';
@ -45,6 +46,7 @@ class _SettingsMobilePageState extends State<SettingsMobilePage> with FeedbackMi
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final animations = context.select<Settings, AccessibilityAnimations>((s) => s.accessibilityAnimations);
return AvesScaffold( return AvesScaffold(
appBar: AppBar( appBar: AppBar(
title: InteractiveAppBarTitle( title: InteractiveAppBarTitle(
@ -72,9 +74,10 @@ class _SettingsMobilePageState extends State<SettingsMobilePage> with FeedbackMi
}, },
onSelected: (action) async { onSelected: (action) async {
// wait for the popup menu to hide before proceeding with the action // wait for the popup menu to hide before proceeding with the action
await Future.delayed(ADurations.popupMenuAnimation * timeDilation); await Future.delayed(animations.popUpAnimationDelay * timeDilation);
_onActionSelected(action); _onActionSelected(action);
}, },
popUpAnimationStyle: animations.popUpAnimationStyle,
), ),
].map((v) => FontSizeIconTheme(child: v)).toList(), ].map((v) => FontSizeIconTheme(child: v)).toList(),
), ),

View file

@ -2,9 +2,9 @@ import 'package:aves/app_mode.dart';
import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/entry/entry.dart';
import 'package:aves/model/entry/extensions/props.dart'; import 'package:aves/model/entry/extensions/props.dart';
import 'package:aves/model/selection.dart'; import 'package:aves/model/selection.dart';
import 'package:aves/model/settings/enums/accessibility_animations.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/theme/themes.dart'; import 'package:aves/theme/themes.dart';
import 'package:aves/view/view.dart'; import 'package:aves/view/view.dart';
@ -49,6 +49,7 @@ class InfoAppBar extends StatelessWidget {
final commonActions = EntryActions.commonMetadataActions.where(isVisible); final commonActions = EntryActions.commonMetadataActions.where(isVisible);
final formatSpecificActions = EntryActions.formatSpecificMetadataActions.where(isVisible); final formatSpecificActions = EntryActions.formatSpecificMetadataActions.where(isVisible);
final useTvLayout = settings.useTvLayout; final useTvLayout = settings.useTvLayout;
final animations = context.select<Settings, AccessibilityAnimations>((s) => s.accessibilityAnimations);
return SliverAppBar( return SliverAppBar(
leading: useTvLayout leading: useTvLayout
? null ? null
@ -91,9 +92,10 @@ class InfoAppBar extends StatelessWidget {
], ],
onSelected: (action) async { onSelected: (action) async {
// wait for the popup menu to hide before proceeding with the action // wait for the popup menu to hide before proceeding with the action
await Future.delayed(ADurations.popupMenuAnimation * timeDilation); await Future.delayed(animations.popUpAnimationDelay * timeDilation);
actionDelegate.onActionSelected(context, entry, collection, action); actionDelegate.onActionSelected(context, entry, collection, action);
}, },
popUpAnimationStyle: animations.popUpAnimationStyle,
), ),
].map((v) => FontSizeIconTheme(child: v)).toList(), ].map((v) => FontSizeIconTheme(child: v)).toList(),
floating: true, floating: true,

View file

@ -4,9 +4,9 @@ import 'package:aves/app_mode.dart';
import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/entry/entry.dart';
import 'package:aves/model/entry/extensions/multipage.dart'; import 'package:aves/model/entry/extensions/multipage.dart';
import 'package:aves/model/entry/extensions/props.dart'; import 'package:aves/model/entry/extensions/props.dart';
import 'package:aves/model/settings/enums/accessibility_animations.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/view/view.dart'; import 'package:aves/view/view.dart';
import 'package:aves/widgets/common/action_controls/quick_choosers/move_button.dart'; import 'package:aves/widgets/common/action_controls/quick_choosers/move_button.dart';
@ -250,6 +250,7 @@ class _ViewerButtonRowContentState extends State<ViewerButtonRowContent> {
final exportActions = widget.exportActions; final exportActions = widget.exportActions;
final videoActions = widget.videoActions; final videoActions = widget.videoActions;
final hasOverflowMenu = pageEntry.canRotate || pageEntry.canFlip || topLevelActions.isNotEmpty || exportActions.isNotEmpty || videoActions.isNotEmpty; final hasOverflowMenu = pageEntry.canRotate || pageEntry.canFlip || topLevelActions.isNotEmpty || exportActions.isNotEmpty || videoActions.isNotEmpty;
final animations = context.select<Settings, AccessibilityAnimations>((s) => s.accessibilityAnimations);
return Selector<VideoConductor, AvesVideoController?>( return Selector<VideoConductor, AvesVideoController?>(
selector: (context, vc) => vc.getController(pageEntry), selector: (context, vc) => vc.getController(pageEntry),
builder: (context, videoController, child) { builder: (context, videoController, child) {
@ -301,10 +302,11 @@ class _ViewerButtonRowContentState extends State<ViewerButtonRowContent> {
] ]
]; ];
}, },
onSelected: (action) { onSelected: (action) async {
_popupExpandedNotifier.value = null; _popupExpandedNotifier.value = null;
// wait for the popup menu to hide before proceeding with the action // wait for the popup menu to hide before proceeding with the action
Future.delayed(ADurations.popupMenuAnimation * timeDilation, () => widget.actionDelegate.onActionSelected(context, action)); await Future.delayed(animations.popUpAnimationDelay * timeDilation);
widget.actionDelegate.onActionSelected(context, action);
}, },
onCanceled: () { onCanceled: () {
_popupExpandedNotifier.value = null; _popupExpandedNotifier.value = null;
@ -316,6 +318,7 @@ class _ViewerButtonRowContentState extends State<ViewerButtonRowContent> {
// so we make sure overlay stays visible // so we make sure overlay stays visible
const ToggleOverlayNotification(visible: true).dispatch(context); const ToggleOverlayNotification(visible: true).dispatch(context);
}, },
popUpAnimationStyle: animations.popUpAnimationStyle,
), ),
), ),
), ),