#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 textScaler = MediaQuery.textScalerOf(context);
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(
floating: !useTvLayout,
pinned: pinned,
@ -70,43 +114,16 @@ class AvesAppBar extends StatelessWidget {
height: textScaler.scale(kToolbarHeight),
child: Row(
children: [
leading != null
_leading != null
? Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Hero(
tag: leadingHeroTag,
flightShuttleBuilder: _flightShuttleBuilder,
transitionOnUserGestures: true,
child: FontSizeIconTheme(
child: leading!,
),
),
child: _leading,
)
: const SizedBox(width: 16),
Expanded(
child: DefaultTextStyle(
style: theme.appBarTheme.titleTextStyle!,
child: Hero(
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))),
],
);
},
),
),
),
),
child: _title,
),
),
],

View file

@ -75,42 +75,47 @@ class _AppBottomNavBarState extends State<AppBottomNavBar> {
const AvesBottomNavItem(route: AlbumListPage.routeName),
];
Widget child = AvesFloatingBar(
builder: (context, backgroundColor, child) => BottomNavigationBar(
items: items
.map((item) => BottomNavigationBarItem(
icon: item.icon(context),
label: item.label(context),
tooltip: item.label(context),
))
.toList(),
onTap: (index) => _goTo(context, items, index),
currentIndex: _getCurrentIndex(context, items),
type: BottomNavigationBarType.fixed,
backgroundColor: backgroundColor,
showSelectedLabels: false,
showUnselectedLabels: false,
),
);
return Hero(
tag: 'nav-bar',
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,
Widget child = FloatingNavBar(
scrollController: PrimaryScrollController.of(context),
events: widget.events,
childHeight: AppBottomNavBar.height + context.select<MediaQueryData, double>((mq) => mq.effectiveBottomPadding),
child: SafeArea(
child: AvesFloatingBar(
builder: (context, backgroundColor, child) => BottomNavigationBar(
items: items
.map((item) => BottomNavigationBarItem(
icon: item.icon(context),
label: item.label(context),
tooltip: item.label(context),
))
.toList(),
onTap: (index) => _goTo(context, items, index),
currentIndex: _getCurrentIndex(context, items),
type: BottomNavigationBarType.fixed,
backgroundColor: backgroundColor,
showSelectedLabels: false,
showUnselectedLabels: false,
),
),
),
);
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(() {});

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