accessibility: fixed navigation with TalkBack

This commit is contained in:
Thibault Deckers 2023-03-01 22:04:22 +01:00
parent 7797c03170
commit 64e153ef5c
23 changed files with 241 additions and 198 deletions

View file

@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
## <a id="unreleased"></a>[Unreleased] ## <a id="unreleased"></a>[Unreleased]
### Fixed
- Accessibility: navigation with TalkBack
## <a id="v1.8.2"></a>[v1.8.2] - 2023-02-28 ## <a id="v1.8.2"></a>[v1.8.2] - 2023-02-28
### Added ### Added

View file

@ -23,7 +23,9 @@ import 'package:aves/widgets/common/action_controls/togglers/favourite.dart';
import 'package:aves/widgets/common/action_controls/togglers/title_search.dart'; import 'package:aves/widgets/common/action_controls/togglers/title_search.dart';
import 'package:aves/widgets/common/app_bar/app_bar_subtitle.dart'; import 'package:aves/widgets/common/app_bar/app_bar_subtitle.dart';
import 'package:aves/widgets/common/app_bar/app_bar_title.dart'; import 'package:aves/widgets/common/app_bar/app_bar_title.dart';
import 'package:aves/widgets/common/basic/menu.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_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/aves_app_bar.dart'; import 'package:aves/widgets/common/identity/aves_app_bar.dart';
import 'package:aves/widgets/common/identity/buttons/captioned_button.dart'; import 'package:aves/widgets/common/identity/buttons/captioned_button.dart';
@ -405,10 +407,7 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
}, },
), ),
if (isSelecting && !settings.isReadOnly && appMode == AppMode.main && !isTrash) if (isSelecting && !settings.isReadOnly && appMode == AppMode.main && !isTrash)
PopupMenuItem<EntrySetAction>( PopupMenuExpansionPanel<EntrySetAction>(
enabled: hasSelection,
padding: EdgeInsets.zero,
child: PopupMenuItemExpansionPanel<EntrySetAction>(
enabled: hasSelection, enabled: hasSelection,
value: 'edit', value: 'edit',
icon: AIcons.edit, icon: AIcons.edit,
@ -418,7 +417,6 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
...EntrySetActions.edit.where((v) => isVisible(v) && !selectionQuickActions.contains(v)).map((action) => _toMenuItem(action, enabled: canApply(action), selection: selection)), ...EntrySetActions.edit.where((v) => isVisible(v) && !selectionQuickActions.contains(v)).map((action) => _toMenuItem(action, enabled: canApply(action), selection: selection)),
], ],
), ),
),
]; ];
return [ return [
@ -529,7 +527,7 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
); );
} }
PopupMenuItem<EntrySetAction> _buildRotateAndFlipMenuItems( PopupMenuEntry<EntrySetAction> _buildRotateAndFlipMenuItems(
BuildContext context, { BuildContext context, {
required bool Function(EntrySetAction action) canApply, required bool Function(EntrySetAction action) canApply,
}) { }) {
@ -558,11 +556,7 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
), ),
); );
return PopupMenuItem( return PopupMenuItemContainer(
child: TooltipTheme(
data: TooltipTheme.of(context).copyWith(
preferBelow: false,
),
child: Row( child: Row(
children: [ children: [
buildDivider(), buildDivider(),
@ -574,7 +568,6 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
buildDivider(), buildDivider(),
], ],
), ),
),
); );
} }

View file

@ -56,6 +56,19 @@ abstract class ChooserQuickButtonState<T extends ChooserQuickButton<U>, U> exten
Widget build(BuildContext context) { Widget build(BuildContext context) {
final _hasChooser = hasChooser; final _hasChooser = hasChooser;
Widget child = IconButton(
icon: icon,
onPressed: widget.onPressed,
focusNode: widget.focusNode,
tooltip: _hasChooser ? null : tooltip,
);
if (_hasChooser) {
child = Semantics(
tooltip: tooltip,
child: child,
);
}
return GestureDetector( return GestureDetector(
behavior: HitTestBehavior.opaque, behavior: HitTestBehavior.opaque,
onLongPressStart: _hasChooser ? _showChooser : null, onLongPressStart: _hasChooser ? _showChooser : null,
@ -70,12 +83,7 @@ abstract class ChooserQuickButtonState<T extends ChooserQuickButton<U>, U> exten
} }
: null, : null,
onLongPressCancel: _clearChooserOverlayEntry, onLongPressCancel: _clearChooserOverlayEntry,
child: IconButton( child: child,
icon: icon,
onPressed: widget.onPressed,
focusNode: widget.focusNode,
tooltip: _hasChooser ? null : tooltip,
),
); );
} }

View file

@ -2,7 +2,7 @@ import 'dart:async';
import 'package:aves/model/actions/share_actions.dart'; import 'package:aves/model/actions/share_actions.dart';
import 'package:aves/widgets/common/action_controls/quick_choosers/common/menu.dart'; import 'package:aves/widgets/common/action_controls/quick_choosers/common/menu.dart';
import 'package:aves/widgets/common/basic/menu.dart'; import 'package:aves/widgets/common/basic/popup/menu_row.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class ShareQuickChooser extends StatelessWidget { class ShareQuickChooser extends StatelessWidget {

View file

@ -2,7 +2,7 @@ import 'package:aves/model/entry.dart';
import 'package:aves/model/favourites.dart'; import 'package:aves/model/favourites.dart';
import 'package:aves/theme/colors.dart'; import 'package:aves/theme/colors.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/common/basic/menu.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/fx/sweeper.dart'; import 'package:aves/widgets/common/fx/sweeper.dart';
import 'package:aves/widgets/common/identity/buttons/captioned_button.dart'; import 'package:aves/widgets/common/identity/buttons/captioned_button.dart';

View file

@ -1,7 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/common/basic/menu.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';
import 'package:aves/widgets/viewer/video/controller.dart'; import 'package:aves/widgets/viewer/video/controller.dart';

View file

@ -2,7 +2,7 @@ import 'dart:async';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/common/basic/menu.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';
import 'package:aves/widgets/viewer/video/controller.dart'; import 'package:aves/widgets/viewer/video/controller.dart';

View file

@ -1,6 +1,6 @@
import 'package:aves/model/query.dart'; import 'package:aves/model/query.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/common/basic/menu.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';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';

View file

@ -212,7 +212,9 @@ class _DraggableScrollbarState extends State<DraggableScrollbar> with TickerProv
), ),
); );
}), }),
RepaintBoundary( // exclude semantics, otherwise this layer will block access to content layers below when using TalkBack
ExcludeSemantics(
child: RepaintBoundary(
child: GestureDetector( child: GestureDetector(
onLongPressStart: (details) { onLongPressStart: (details) {
_longPressLastGlobalPosition = details.globalPosition; _longPressLastGlobalPosition = details.globalPosition;
@ -248,6 +250,7 @@ class _DraggableScrollbarState extends State<DraggableScrollbar> with TickerProv
), ),
), ),
), ),
),
], ],
), ),
); );

View file

@ -0,0 +1,35 @@
import 'package:flutter/material.dart';
class PopupMenuItemContainer<T> extends PopupMenuEntry<T> {
final Widget child;
const PopupMenuItemContainer({
super.key,
this.height = kMinInteractiveDimension,
required this.child,
});
@override
final double height;
@override
bool represents(void value) => false;
@override
State<PopupMenuItemContainer> createState() => _TransitionPopupMenuItemState();
}
class _TransitionPopupMenuItemState extends State<PopupMenuItemContainer> {
@override
Widget build(BuildContext context) {
return TooltipTheme(
data: TooltipTheme.of(context).copyWith(
preferBelow: false,
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: widget.child,
),
);
}
}

View file

@ -1,62 +1,9 @@
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/widgets/common/basic/popup/menu_row.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class MenuRow extends StatelessWidget { class PopupMenuExpansionPanel<T> extends PopupMenuEntry<T> {
final String text;
final Widget? icon;
const MenuRow({
super.key,
required this.text,
this.icon,
});
@override
Widget build(BuildContext context) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
if (icon != null)
Padding(
padding: const EdgeInsetsDirectional.only(end: 12),
child: IconTheme.merge(
data: IconThemeData(
color: ListTileTheme.of(context).iconColor,
),
child: icon!,
),
),
Flexible(
child: Text(text),
),
],
);
}
}
// scale icons according to text scale
class MenuIconTheme extends StatelessWidget {
final Widget child;
const MenuIconTheme({
super.key,
required this.child,
});
@override
Widget build(BuildContext context) {
final iconTheme = IconTheme.of(context);
return IconTheme(
data: iconTheme.copyWith(
size: iconTheme.size! * MediaQuery.textScaleFactorOf(context),
),
child: child,
);
}
}
class PopupMenuItemExpansionPanel<T> extends StatefulWidget {
final bool enabled; final bool enabled;
final String value; final String value;
final ValueNotifier<String?> expandedNotifier; final ValueNotifier<String?> expandedNotifier;
@ -64,9 +11,10 @@ class PopupMenuItemExpansionPanel<T> extends StatefulWidget {
final String title; final String title;
final List<PopupMenuEntry<T>> items; final List<PopupMenuEntry<T>> items;
PopupMenuItemExpansionPanel({ PopupMenuExpansionPanel({
super.key, super.key,
this.enabled = true, this.enabled = true,
this.height = kMinInteractiveDimension,
required this.value, required this.value,
ValueNotifier<String?>? expandedNotifier, ValueNotifier<String?>? expandedNotifier,
required this.icon, required this.icon,
@ -75,10 +23,16 @@ class PopupMenuItemExpansionPanel<T> extends StatefulWidget {
}) : expandedNotifier = expandedNotifier ?? ValueNotifier(null); }) : expandedNotifier = expandedNotifier ?? ValueNotifier(null);
@override @override
State<PopupMenuItemExpansionPanel<T>> createState() => _PopupMenuItemExpansionPanelState<T>(); final double height;
@override
bool represents(void value) => false;
@override
State<PopupMenuExpansionPanel<T>> createState() => _PopupMenuExpansionPanelState<T>();
} }
class _PopupMenuItemExpansionPanelState<T> extends State<PopupMenuItemExpansionPanel<T>> { class _PopupMenuExpansionPanelState<T> extends State<PopupMenuExpansionPanel<T>> {
// ref `_kMenuHorizontalPadding` used in `PopupMenuItem` // ref `_kMenuHorizontalPadding` used in `PopupMenuItem`
static const double _horizontalPadding = 16; static const double _horizontalPadding = 16;
@ -103,8 +57,13 @@ class _PopupMenuItemExpansionPanelState<T> extends State<PopupMenuItemExpansionP
elevation: 0, elevation: 0,
children: [ children: [
ExpansionPanel( ExpansionPanel(
headerBuilder: (context, isExpanded) => DefaultTextStyle( headerBuilder: (context, isExpanded) {
return DefaultTextStyle(
style: style, style: style,
child: IconTheme.merge(
data: IconThemeData(
color: widget.enabled ? null : Theme.of(context).disabledColor,
),
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: _horizontalPadding), padding: const EdgeInsets.symmetric(horizontal: _horizontalPadding),
child: MenuRow( child: MenuRow(
@ -113,6 +72,8 @@ class _PopupMenuItemExpansionPanelState<T> extends State<PopupMenuItemExpansionP
), ),
), ),
), ),
);
},
body: Column( body: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [

View file

@ -0,0 +1,55 @@
import 'package:flutter/material.dart';
class MenuRow extends StatelessWidget {
final String text;
final Widget? icon;
const MenuRow({
super.key,
required this.text,
this.icon,
});
@override
Widget build(BuildContext context) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
if (icon != null)
Padding(
padding: const EdgeInsetsDirectional.only(end: 12),
child: IconTheme.merge(
data: IconThemeData(
color: ListTileTheme.of(context).iconColor,
),
child: icon!,
),
),
Flexible(
child: Text(text),
),
],
);
}
}
// scale icons according to text scale
class MenuIconTheme extends StatelessWidget {
final Widget child;
const MenuIconTheme({
super.key,
required this.child,
});
@override
Widget build(BuildContext context) {
final iconTheme = IconTheme.of(context);
return IconTheme(
data: iconTheme.copyWith(
size: iconTheme.size! * MediaQuery.textScaleFactorOf(context),
),
child: child,
);
}
}

View file

@ -14,7 +14,7 @@ import 'package:aves/theme/colors.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/collection/filter_bar.dart'; import 'package:aves/widgets/collection/filter_bar.dart';
import 'package:aves/widgets/common/basic/menu.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/providers/media_query_data_provider.dart'; import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
import 'package:aves/widgets/filter_grids/common/action_delegates/chip.dart'; import 'package:aves/widgets/filter_grids/common/action_delegates/chip.dart';

View file

@ -8,7 +8,7 @@ import 'package:aves/model/source/collection_source.dart';
import 'package:aves/services/analysis_service.dart'; import 'package:aves/services/analysis_service.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/utils/android_file_utils.dart';
import 'package:aves/widgets/common/basic/menu.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';
import 'package:aves/widgets/common/behaviour/pop/scope.dart'; import 'package:aves/widgets/common/behaviour/pop/scope.dart';
import 'package:aves/widgets/common/behaviour/pop/tv_navigation.dart'; import 'package:aves/widgets/common/behaviour/pop/tv_navigation.dart';

View file

@ -7,7 +7,7 @@ import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/collection/collection_grid.dart'; import 'package:aves/widgets/collection/collection_grid.dart';
import 'package:aves/widgets/common/basic/menu.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';
import 'package:aves/widgets/common/extensions/build_context.dart'; 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';

View file

@ -13,7 +13,7 @@ import 'package:aves/model/vaults/details.dart';
import 'package:aves/model/vaults/vaults.dart'; import 'package:aves/model/vaults/vaults.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/common/basic/menu.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/aves_filter_chip.dart'; import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
import 'package:aves/widgets/common/identity/buttons/captioned_button.dart'; import 'package:aves/widgets/common/identity/buttons/captioned_button.dart';

View file

@ -11,7 +11,7 @@ import 'package:aves/theme/durations.dart';
import 'package:aves/widgets/common/action_controls/togglers/title_search.dart'; import 'package:aves/widgets/common/action_controls/togglers/title_search.dart';
import 'package:aves/widgets/common/app_bar/app_bar_subtitle.dart'; import 'package:aves/widgets/common/app_bar/app_bar_subtitle.dart';
import 'package:aves/widgets/common/app_bar/app_bar_title.dart'; import 'package:aves/widgets/common/app_bar/app_bar_title.dart';
import 'package:aves/widgets/common/basic/menu.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/aves_app_bar.dart'; import 'package:aves/widgets/common/identity/aves_app_bar.dart';
import 'package:aves/widgets/common/identity/buttons/captioned_button.dart'; import 'package:aves/widgets/common/identity/buttons/captioned_button.dart';

View file

@ -18,7 +18,7 @@ import 'package:aves/utils/debouncer.dart';
import 'package:aves/widgets/collection/collection_page.dart'; import 'package:aves/widgets/collection/collection_page.dart';
import 'package:aves/widgets/collection/entry_set_action_delegate.dart'; import 'package:aves/widgets/collection/entry_set_action_delegate.dart';
import 'package:aves/widgets/common/basic/insets.dart'; import 'package:aves/widgets/common/basic/insets.dart';
import 'package:aves/widgets/common/basic/menu.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';
import 'package:aves/widgets/common/behaviour/routes.dart'; import 'package:aves/widgets/common/behaviour/routes.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';

View file

@ -6,7 +6,7 @@ import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/utils/android_file_utils.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/common/basic/menu.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';
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/outlined_button.dart'; import 'package:aves/widgets/common/identity/buttons/outlined_button.dart';

View file

@ -12,7 +12,7 @@ import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/common/action_mixins/feedback.dart'; import 'package:aves/widgets/common/action_mixins/feedback.dart';
import 'package:aves/widgets/common/app_bar/app_bar_title.dart'; import 'package:aves/widgets/common/app_bar/app_bar_title.dart';
import 'package:aves/widgets/common/basic/insets.dart'; import 'package:aves/widgets/common/basic/insets.dart';
import 'package:aves/widgets/common/basic/menu.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';
import 'package:aves/widgets/common/behaviour/pop/scope.dart'; import 'package:aves/widgets/common/behaviour/pop/scope.dart';
import 'package:aves/widgets/common/behaviour/pop/tv_navigation.dart'; import 'package:aves/widgets/common/behaviour/pop/tv_navigation.dart';

View file

@ -6,7 +6,7 @@ import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/common/app_bar/app_bar_title.dart'; import 'package:aves/widgets/common/app_bar/app_bar_title.dart';
import 'package:aves/widgets/common/app_bar/sliver_app_bar_title.dart'; import 'package:aves/widgets/common/app_bar/sliver_app_bar_title.dart';
import 'package:aves/widgets/common/basic/menu.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/viewer/action/entry_info_action_delegate.dart'; import 'package:aves/widgets/viewer/action/entry_info_action_delegate.dart';
import 'package:aves/widgets/viewer/info/info_search.dart'; import 'package:aves/widgets/viewer/info/info_search.dart';

View file

@ -11,8 +11,10 @@ import 'package:aves/widgets/common/action_controls/quick_choosers/tag_button.da
import 'package:aves/widgets/common/action_controls/togglers/favourite.dart'; import 'package:aves/widgets/common/action_controls/togglers/favourite.dart';
import 'package:aves/widgets/common/action_controls/togglers/mute.dart'; import 'package:aves/widgets/common/action_controls/togglers/mute.dart';
import 'package:aves/widgets/common/action_controls/togglers/play.dart'; import 'package:aves/widgets/common/action_controls/togglers/play.dart';
import 'package:aves/widgets/common/basic/menu.dart'; import 'package:aves/widgets/common/basic/popup/container.dart';
import 'package:aves/widgets/common/basic/popup_menu_button.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/extensions/build_context.dart';
import 'package:aves/widgets/common/identity/buttons/captioned_button.dart'; import 'package:aves/widgets/common/identity/buttons/captioned_button.dart';
import 'package:aves/widgets/common/identity/buttons/overlay_button.dart'; import 'package:aves/widgets/common/identity/buttons/overlay_button.dart';
@ -231,9 +233,7 @@ class ViewerButtonRowContent extends StatelessWidget {
if (pageEntry.canRotate || pageEntry.canFlip) _buildRotateAndFlipMenuItems(context), if (pageEntry.canRotate || pageEntry.canFlip) _buildRotateAndFlipMenuItems(context),
...topLevelActions.map((action) => _buildPopupMenuItem(context, action, videoController)), ...topLevelActions.map((action) => _buildPopupMenuItem(context, action, videoController)),
if (exportActions.isNotEmpty) if (exportActions.isNotEmpty)
PopupMenuItem<EntryAction>( PopupMenuExpansionPanel<EntryAction>(
padding: EdgeInsets.zero,
child: PopupMenuItemExpansionPanel<EntryAction>(
value: 'export', value: 'export',
expandedNotifier: _popupExpandedNotifier, expandedNotifier: _popupExpandedNotifier,
icon: AIcons.export, icon: AIcons.export,
@ -244,11 +244,8 @@ class ViewerButtonRowContent extends StatelessWidget {
...exportExternalActions.map((action) => _buildPopupMenuItem(context, action, videoController)).toList(), ...exportExternalActions.map((action) => _buildPopupMenuItem(context, action, videoController)).toList(),
], ],
), ),
),
if (videoActions.isNotEmpty) if (videoActions.isNotEmpty)
PopupMenuItem<EntryAction>( PopupMenuExpansionPanel<EntryAction>(
padding: EdgeInsets.zero,
child: PopupMenuItemExpansionPanel<EntryAction>(
value: 'video', value: 'video',
expandedNotifier: _popupExpandedNotifier, expandedNotifier: _popupExpandedNotifier,
icon: AIcons.video, icon: AIcons.video,
@ -257,7 +254,6 @@ class ViewerButtonRowContent extends StatelessWidget {
...videoActions.map((action) => _buildPopupMenuItem(context, action, videoController)).toList(), ...videoActions.map((action) => _buildPopupMenuItem(context, action, videoController)).toList(),
], ],
), ),
),
if (!kReleaseMode) ...[ if (!kReleaseMode) ...[
const PopupMenuDivider(), const PopupMenuDivider(),
_buildPopupMenuItem(context, EntryAction.debug, videoController), _buildPopupMenuItem(context, EntryAction.debug, videoController),
@ -357,7 +353,7 @@ class ViewerButtonRowContent extends StatelessWidget {
); );
} }
PopupMenuItem<EntryAction> _buildRotateAndFlipMenuItems(BuildContext context) { PopupMenuEntry<EntryAction> _buildRotateAndFlipMenuItems(BuildContext context) {
Widget buildDivider() => const SizedBox( Widget buildDivider() => const SizedBox(
height: 16, height: 16,
child: VerticalDivider( child: VerticalDivider(
@ -383,16 +379,7 @@ class ViewerButtonRowContent extends StatelessWidget {
), ),
); );
return PopupMenuItem( return PopupMenuItemContainer(
padding: EdgeInsets.zero,
child: IconTheme.merge(
data: IconThemeData(
color: ListTileTheme.of(context).iconColor,
),
child: ColoredBox(
color: PopupMenuTheme.of(context).color!,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Row( child: Row(
children: [ children: [
buildDivider(), buildDivider(),
@ -404,9 +391,6 @@ class ViewerButtonRowContent extends StatelessWidget {
buildDivider(), buildDivider(),
], ],
), ),
),
),
),
); );
} }