#1102 accessibility: enable/disable more animations

This commit is contained in:
Thibault Deckers 2024-07-28 00:22:19 +02:00
parent e3f6644366
commit 36c0fd2a3d
4 changed files with 87 additions and 103 deletions

View file

@ -1,37 +0,0 @@
import 'package:flutter/material.dart';
class AvesPopupMenuButton<T> extends PopupMenuButton<T> {
final VoidCallback? onMenuOpened;
const AvesPopupMenuButton({
super.key,
required super.itemBuilder,
super.initialValue,
super.onSelected,
super.onCanceled,
super.tooltip,
super.elevation,
super.padding = const EdgeInsets.all(8),
super.child,
super.icon,
super.offset = Offset.zero,
super.enabled = true,
super.shape,
super.color,
super.enableFeedback,
super.iconSize,
this.onMenuOpened,
super.popUpAnimationStyle,
});
@override
PopupMenuButtonState<T> createState() => _AvesPopupMenuButtonState<T>();
}
class _AvesPopupMenuButtonState<T> extends PopupMenuButtonState<T> {
@override
void showButtonMenu() {
(widget as AvesPopupMenuButton).onMenuOpened?.call();
super.showButtonMenu();
}
}

View file

@ -40,6 +40,50 @@ class AvesAppBar extends StatelessWidget {
final colorScheme = theme.colorScheme; final colorScheme = theme.colorScheme;
final textScaler = MediaQuery.textScalerOf(context); final textScaler = MediaQuery.textScalerOf(context);
final useTvLayout = settings.useTvLayout; final useTvLayout = settings.useTvLayout;
Widget? _leading = leading;
if (_leading != null) {
_leading = FontSizeIconTheme(
child: _leading,
);
}
Widget _title = FontSizeIconTheme(
child: LayoutBuilder(
builder: (context, constraints) {
return Row(
key: ValueKey(transitionKey),
children: [
Expanded(child: title),
...(actions(context, max(0, constraints.maxWidth - _titleMinWidth))),
],
);
},
),
);
final animate = context.select<Settings, bool>((v) => v.animate);
if (animate) {
_title = Hero(
tag: titleHeroTag,
flightShuttleBuilder: _flightShuttleBuilder,
transitionOnUserGestures: true,
child: AnimatedSwitcher(
duration: context.read<DurationsData>().iconAnimation,
child: _title,
),
);
if (_leading != null) {
_leading = Hero(
tag: leadingHeroTag,
flightShuttleBuilder: _flightShuttleBuilder,
transitionOnUserGestures: true,
child: _leading,
);
}
}
return SliverPersistentHeader( return SliverPersistentHeader(
floating: !useTvLayout, floating: !useTvLayout,
pinned: pinned, pinned: pinned,
@ -70,43 +114,16 @@ class AvesAppBar extends StatelessWidget {
height: textScaler.scale(kToolbarHeight), height: textScaler.scale(kToolbarHeight),
child: Row( child: Row(
children: [ children: [
leading != null _leading != null
? Padding( ? Padding(
padding: const EdgeInsets.symmetric(horizontal: 4), padding: const EdgeInsets.symmetric(horizontal: 4),
child: Hero( child: _leading,
tag: leadingHeroTag,
flightShuttleBuilder: _flightShuttleBuilder,
transitionOnUserGestures: true,
child: FontSizeIconTheme(
child: leading!,
),
),
) )
: const SizedBox(width: 16), : const SizedBox(width: 16),
Expanded( Expanded(
child: DefaultTextStyle( child: DefaultTextStyle(
style: theme.appBarTheme.titleTextStyle!, style: theme.appBarTheme.titleTextStyle!,
child: Hero( child: _title,
tag: titleHeroTag,
flightShuttleBuilder: _flightShuttleBuilder,
transitionOnUserGestures: true,
child: AnimatedSwitcher(
duration: context.read<DurationsData>().iconAnimation,
child: FontSizeIconTheme(
child: LayoutBuilder(
builder: (context, constraints) {
return Row(
key: ValueKey(transitionKey),
children: [
Expanded(child: title),
...(actions(context, max(0, constraints.maxWidth - _titleMinWidth))),
],
);
},
),
),
),
),
), ),
), ),
], ],

View file

@ -75,42 +75,47 @@ class _AppBottomNavBarState extends State<AppBottomNavBar> {
const AvesBottomNavItem(route: AlbumListPage.routeName), const AvesBottomNavItem(route: AlbumListPage.routeName),
]; ];
Widget child = AvesFloatingBar( Widget child = FloatingNavBar(
builder: (context, backgroundColor, child) => BottomNavigationBar( scrollController: PrimaryScrollController.of(context),
items: items events: widget.events,
.map((item) => BottomNavigationBarItem( childHeight: AppBottomNavBar.height + context.select<MediaQueryData, double>((mq) => mq.effectiveBottomPadding),
icon: item.icon(context), child: SafeArea(
label: item.label(context), child: AvesFloatingBar(
tooltip: item.label(context), builder: (context, backgroundColor, child) => BottomNavigationBar(
)) items: items
.toList(), .map((item) => BottomNavigationBarItem(
onTap: (index) => _goTo(context, items, index), icon: item.icon(context),
currentIndex: _getCurrentIndex(context, items), label: item.label(context),
type: BottomNavigationBarType.fixed, tooltip: item.label(context),
backgroundColor: backgroundColor, ))
showSelectedLabels: false, .toList(),
showUnselectedLabels: false, onTap: (index) => _goTo(context, items, index),
), currentIndex: _getCurrentIndex(context, items),
); type: BottomNavigationBarType.fixed,
backgroundColor: backgroundColor,
return Hero( showSelectedLabels: false,
tag: 'nav-bar', showUnselectedLabels: false,
flightShuttleBuilder: (flight, animation, direction, fromHero, toHero) { ),
return MediaQuery.removeViewInsets(
context: context,
removeBottom: true,
child: toHero.widget,
);
},
child: FloatingNavBar(
scrollController: PrimaryScrollController.of(context),
events: widget.events,
childHeight: AppBottomNavBar.height + context.select<MediaQueryData, double>((mq) => mq.effectiveBottomPadding),
child: SafeArea(
child: child,
), ),
), ),
); );
final animate = context.select<Settings, bool>((v) => v.animate);
if (animate) {
child = Hero(
tag: 'nav-bar',
flightShuttleBuilder: (flight, animation, direction, fromHero, toHero) {
return MediaQuery.removeViewInsets(
context: context,
removeBottom: true,
child: toHero.widget,
);
},
child: child,
);
}
return child;
} }
void _onCollectionFilterChanged() => setState(() {}); void _onCollectionFilterChanged() => setState(() {});

View file

@ -19,7 +19,6 @@ import 'package:aves/widgets/common/action_controls/togglers/play.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/container.dart'; import 'package:aves/widgets/common/basic/popup/container.dart';
import 'package:aves/widgets/common/basic/popup/expansion_panel.dart'; import 'package:aves/widgets/common/basic/popup/expansion_panel.dart';
import 'package:aves/widgets/common/basic/popup/menu_button.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/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/common/identity/buttons/captioned_button.dart'; import 'package:aves/widgets/common/identity/buttons/captioned_button.dart';
@ -269,7 +268,7 @@ class _ViewerButtonRowContentState extends State<ViewerButtonRowContent> {
child: OverlayButton( child: OverlayButton(
scale: widget.scale, scale: widget.scale,
child: FontSizeIconTheme( child: FontSizeIconTheme(
child: AvesPopupMenuButton<EntryAction>( child: PopupMenuButton<EntryAction>(
key: const Key('entry-menu-button'), key: const Key('entry-menu-button'),
itemBuilder: (context) { itemBuilder: (context) {
final exportInternalActions = exportActions.whereNot(EntryActions.exportExternal.contains).toList(); final exportInternalActions = exportActions.whereNot(EntryActions.exportExternal.contains).toList();
@ -305,6 +304,7 @@ class _ViewerButtonRowContentState extends State<ViewerButtonRowContent> {
] ]
]; ];
}, },
onOpened: () => PopupMenuOpenedNotification().dispatch(context),
onSelected: (action) async { 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
@ -315,7 +315,6 @@ class _ViewerButtonRowContentState extends State<ViewerButtonRowContent> {
_popupExpandedNotifier.value = null; _popupExpandedNotifier.value = null;
}, },
iconSize: IconTheme.of(context).size, iconSize: IconTheme.of(context).size,
onMenuOpened: () => PopupMenuOpenedNotification().dispatch(context),
popUpAnimationStyle: animations.popUpAnimationStyle, popUpAnimationStyle: animations.popUpAnimationStyle,
), ),
), ),