#559 fixes for font scale

This commit is contained in:
Thibault Deckers 2023-03-19 19:38:07 +01:00
parent c6230df01d
commit 07e13bc8ac
18 changed files with 257 additions and 209 deletions

View file

@ -23,7 +23,6 @@ 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/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_row.dart'; import 'package:aves/widgets/common/basic/popup/menu_row.dart';
@ -145,7 +144,12 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
} }
@override @override
void didChangeMetrics() => _updateStatusBarHeight(); void didChangeMetrics() {
// when top padding changes
_updateStatusBarHeight();
// when text scale factor changes
_updateAppBarHeight();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -377,15 +381,12 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
final browsingQuickActions = settings.collectionBrowsingQuickActions; final browsingQuickActions = settings.collectionBrowsingQuickActions;
final selectionQuickActions = isTrash ? [EntrySetAction.delete, EntrySetAction.restore] : settings.collectionSelectionQuickActions; final selectionQuickActions = isTrash ? [EntrySetAction.delete, EntrySetAction.restore] : settings.collectionSelectionQuickActions;
final quickActionButtons = (isSelecting ? selectionQuickActions : browsingQuickActions).where(isVisible).map( final quickActionButtons = (isSelecting ? selectionQuickActions : browsingQuickActions).where(isVisible).map(
(action) => FontSizeIconTheme( (action) => _buildButtonIcon(context, action, enabled: canApply(action), selection: selection),
child: _buildButtonIcon(context, action, enabled: canApply(action), selection: selection),
),
); );
return [ return [
...quickActionButtons, ...quickActionButtons,
FontSizeIconTheme( PopupMenuButton<EntrySetAction>(
child: PopupMenuButton<EntrySetAction>(
// key is expected by test driver // key is expected by test driver
key: const Key('appbar-menu-button'), key: const Key('appbar-menu-button'),
itemBuilder: (context) { itemBuilder: (context) {
@ -437,7 +438,6 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
await _onActionSelected(action); await _onActionSelected(action);
}, },
), ),
),
]; ];
} }

View file

@ -299,6 +299,18 @@ class _CollectionSectionedContentState extends State<_CollectionSectionedContent
ScrollController get scrollController => widget.scrollController; ScrollController get scrollController => widget.scrollController;
@override
void initState() {
super.initState();
_appBarHeightNotifier.addListener(_onAppBarHeightChanged);
}
@override
void dispose() {
_appBarHeightNotifier.removeListener(_onAppBarHeightChanged);
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final scrollView = AnimationLimiter( final scrollView = AnimationLimiter(
@ -339,6 +351,8 @@ class _CollectionSectionedContentState extends State<_CollectionSectionedContent
child: selector, child: selector,
); );
} }
void _onAppBarHeightChanged() => setState(() {});
} }
class _CollectionScaler extends StatelessWidget { class _CollectionScaler extends StatelessWidget {
@ -485,7 +499,7 @@ class _CollectionScrollViewState extends State<_CollectionScrollView> with Widge
return settings.useTvLayout ? scrollView : _buildDraggableScrollView(scrollView, widget.collection); return settings.useTvLayout ? scrollView : _buildDraggableScrollView(scrollView, widget.collection);
} }
Widget _buildDraggableScrollView(ScrollView scrollView, CollectionLens collection) { Widget _buildDraggableScrollView(Widget scrollView, CollectionLens collection) {
return ValueListenableBuilder<double>( return ValueListenableBuilder<double>(
valueListenable: widget.appBarHeightNotifier, valueListenable: widget.appBarHeightNotifier,
builder: (context, appBarHeight, child) { builder: (context, appBarHeight, child) {
@ -550,7 +564,7 @@ class _CollectionScrollViewState extends State<_CollectionScrollView> with Widge
); );
} }
ScrollView _buildScrollView(Widget appBar, CollectionLens collection) { Widget _buildScrollView(Widget appBar, CollectionLens collection) {
return CustomScrollView( return CustomScrollView(
key: widget.scrollableKey, key: widget.scrollableKey,
primary: true, primary: true,

View file

@ -62,9 +62,9 @@ class DraggableScrollbar extends StatefulWidget {
final double Function(double scrollOffset, double offsetIncrement)? dragOffsetSnapper; final double Function(double scrollOffset, double offsetIncrement)? dragOffsetSnapper;
/// The view that will be scrolled with the scroll thumb /// The view that will be scrolled with the scroll thumb
final ScrollView child; final Widget child;
DraggableScrollbar({ const DraggableScrollbar({
super.key, super.key,
required this.backgroundColor, required this.backgroundColor,
required this.scrollThumbSize, required this.scrollThumbSize,
@ -78,7 +78,7 @@ class DraggableScrollbar extends StatefulWidget {
required this.labelTextBuilder, required this.labelTextBuilder,
required this.crumbTextBuilder, required this.crumbTextBuilder,
required this.child, required this.child,
}) : assert(child.scrollDirection == Axis.vertical); });
@override @override
State<DraggableScrollbar> createState() => _DraggableScrollbarState(); State<DraggableScrollbar> createState() => _DraggableScrollbarState();

View file

@ -25,8 +25,6 @@ class _WheelSelectorState<T> extends State<WheelSelector<T>> {
late final FixedExtentScrollController _controller; late final FixedExtentScrollController _controller;
final ValueNotifier<bool> _focusedNotifier = ValueNotifier(false); final ValueNotifier<bool> _focusedNotifier = ValueNotifier(false);
static const itemSize = Size(40, 40);
ValueNotifier<T> get valueNotifier => widget.valueNotifier; ValueNotifier<T> get valueNotifier => widget.valueNotifier;
List<T> get values => widget.values; List<T> get values => widget.values;
@ -51,6 +49,7 @@ class _WheelSelectorState<T> extends State<WheelSelector<T>> {
const background = Colors.transparent; const background = Colors.transparent;
final foreground = DefaultTextStyle.of(context).style.color!; final foreground = DefaultTextStyle.of(context).style.color!;
final transitionDuration = context.select<DurationsData, Duration>((v) => v.formTransition); final transitionDuration = context.select<DurationsData, Duration>((v) => v.formTransition);
final itemSize = Size.square(40 * context.select<MediaQueryData, double>((mq) => mq.textScaleFactor));
return FocusableActionDetector( return FocusableActionDetector(
shortcuts: const { shortcuts: const {

View file

@ -130,7 +130,7 @@ class SectionHeader<T> extends StatelessWidget {
final para = RenderParagraph( final para = RenderParagraph(
TextSpan( TextSpan(
children: [ children: [
// as of Flutter v2.8.1, `RenderParagraph` fails to lay out `WidgetSpan` offscreen // as of Flutter v3.7.7, `RenderParagraph` fails to lay out `WidgetSpan` offscreen
// so we use a hair space times a magic number to match width // so we use a hair space times a magic number to match width
TextSpan( TextSpan(
// 23 hair spaces match a width of 40.0 // 23 hair spaces match a width of 40.0

View file

@ -1,6 +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/theme/durations.dart';
import 'package:aves/widgets/aves_app.dart'; import 'package:aves/widgets/aves_app.dart';
import 'package:aves/widgets/common/basic/font_size_icon_theme.dart';
import 'package:aves/widgets/common/basic/insets.dart'; import 'package:aves/widgets/common/basic/insets.dart';
import 'package:aves/widgets/common/fx/blurred.dart'; import 'package:aves/widgets/common/fx/blurred.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -65,8 +66,10 @@ class AvesAppBar extends StatelessWidget {
tag: leadingHeroTag, tag: leadingHeroTag,
flightShuttleBuilder: _flightShuttleBuilder, flightShuttleBuilder: _flightShuttleBuilder,
transitionOnUserGestures: true, transitionOnUserGestures: true,
child: FontSizeIconTheme(
child: leading!, child: leading!,
), ),
),
) )
: const SizedBox(width: 16), : const SizedBox(width: 16),
Expanded( Expanded(
@ -78,6 +81,7 @@ class AvesAppBar extends StatelessWidget {
transitionOnUserGestures: true, transitionOnUserGestures: true,
child: AnimatedSwitcher( child: AnimatedSwitcher(
duration: context.read<DurationsData>().iconAnimation, duration: context.read<DurationsData>().iconAnimation,
child: FontSizeIconTheme(
child: Row( child: Row(
key: ValueKey(transitionKey), key: ValueKey(transitionKey),
children: [ children: [
@ -89,6 +93,7 @@ class AvesAppBar extends StatelessWidget {
), ),
), ),
), ),
),
], ],
), ),
), ),

View file

@ -13,7 +13,6 @@ 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/font_size_icon_theme.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';
@ -210,16 +209,13 @@ class _AlbumPickPageState extends State<_AlbumPickPage> {
return [ return [
if (widget.moveType != null) if (widget.moveType != null)
..._quickActions.where(isVisible).map( ..._quickActions.where(isVisible).map(
(action) => FontSizeIconTheme( (action) => IconButton(
child: IconButton(
icon: action.getIcon(), icon: action.getIcon(),
onPressed: () => onActionSelected(action), onPressed: () => onActionSelected(action),
tooltip: action.getText(context), tooltip: action.getText(context),
), ),
), ),
), PopupMenuButton<ChipSetAction>(
FontSizeIconTheme(
child: PopupMenuButton<ChipSetAction>(
itemBuilder: (context) { itemBuilder: (context) {
return _menuActions.where((v) => v == null || isVisible(v)).map((action) { return _menuActions.where((v) => v == null || isVisible(v)).map((action) {
if (action == null) return const PopupMenuDivider(); if (action == null) return const PopupMenuDivider();
@ -236,7 +232,6 @@ class _AlbumPickPageState extends State<_AlbumPickPage> {
onActionSelected(action); onActionSelected(action);
}, },
), ),
),
]; ];
} }

View file

@ -2,6 +2,7 @@ import 'package:aves/model/settings/settings.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/theme/themes.dart'; import 'package:aves/theme/themes.dart';
import 'package:aves/widgets/common/basic/font_size_icon_theme.dart';
import 'package:aves/widgets/common/basic/text_dropdown_button.dart'; import 'package:aves/widgets/common/basic/text_dropdown_button.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/transitions.dart'; import 'package:aves/widgets/common/fx/transitions.dart';
@ -168,6 +169,7 @@ class _TileViewDialogState<S, G, L> extends State<TileViewDialog<S, G, L>> with
final label = ConstrainedBox( final label = ConstrainedBox(
constraints: const BoxConstraints(minHeight: kMinInteractiveDimension), constraints: const BoxConstraints(minHeight: kMinInteractiveDimension),
child: FontSizeIconTheme(
child: Row( child: Row(
children: [ children: [
Icon(icon), Icon(icon),
@ -181,6 +183,7 @@ class _TileViewDialogState<S, G, L> extends State<TileViewDialog<S, G, L>> with
if (trailing != null) trailing, if (trailing != null) trailing,
], ],
), ),
),
); );
final selector = TextDropdownButton<T>( final selector = TextDropdownButton<T>(
values: options.map((v) => v.value).toList(), values: options.map((v) => v.value).toList(),

View file

@ -11,7 +11,6 @@ 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/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/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';
@ -75,7 +74,7 @@ class FilterGridAppBar<T extends CollectionFilter, CSAD extends ChipSetActionDel
} }
} }
class _FilterGridAppBarState<T extends CollectionFilter, CSAD extends ChipSetActionDelegate<T>> extends State<FilterGridAppBar<T, CSAD>> with SingleTickerProviderStateMixin { class _FilterGridAppBarState<T extends CollectionFilter, CSAD extends ChipSetActionDelegate<T>> extends State<FilterGridAppBar<T, CSAD>> with SingleTickerProviderStateMixin, WidgetsBindingObserver {
final List<StreamSubscription> _subscriptions = []; final List<StreamSubscription> _subscriptions = [];
late AnimationController _browseToSelectAnimation; late AnimationController _browseToSelectAnimation;
final ValueNotifier<bool> _isSelectingNotifier = ValueNotifier(false); final ValueNotifier<bool> _isSelectingNotifier = ValueNotifier(false);
@ -105,6 +104,7 @@ class _FilterGridAppBarState<T extends CollectionFilter, CSAD extends ChipSetAct
vsync: this, vsync: this,
); );
_isSelectingNotifier.addListener(_onActivityChanged); _isSelectingNotifier.addListener(_onActivityChanged);
WidgetsBinding.instance.addObserver(this);
WidgetsBinding.instance.addPostFrameCallback((_) => _updateAppBarHeight()); WidgetsBinding.instance.addPostFrameCallback((_) => _updateAppBarHeight());
} }
@ -118,9 +118,16 @@ class _FilterGridAppBarState<T extends CollectionFilter, CSAD extends ChipSetAct
_subscriptions _subscriptions
..forEach((sub) => sub.cancel()) ..forEach((sub) => sub.cancel())
..clear(); ..clear();
WidgetsBinding.instance.removeObserver(this);
super.dispose(); super.dispose();
} }
@override
void didChangeMetrics() {
// when text scale factor changes
_updateAppBarHeight();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final appMode = context.watch<ValueNotifier<AppMode>>().value; final appMode = context.watch<ValueNotifier<AppMode>>().value;
@ -320,15 +327,12 @@ class _FilterGridAppBarState<T extends CollectionFilter, CSAD extends ChipSetAct
final isSelecting = selection.isSelecting; final isSelecting = selection.isSelecting;
final quickActionButtons = (isSelecting ? selectionQuickActions : browsingQuickActions).where(isVisible).map( final quickActionButtons = (isSelecting ? selectionQuickActions : browsingQuickActions).where(isVisible).map(
(action) => FontSizeIconTheme( (action) => _buildButtonIcon(context, actionDelegate, action, enabled: canApply(action)),
child: _buildButtonIcon(context, actionDelegate, action, enabled: canApply(action)),
),
); );
return [ return [
...quickActionButtons, ...quickActionButtons,
FontSizeIconTheme( PopupMenuButton<ChipSetAction>(
child: PopupMenuButton<ChipSetAction>(
itemBuilder: (context) { itemBuilder: (context) {
final generalMenuItems = ChipSetActions.general.where(isVisible).map( final generalMenuItems = ChipSetActions.general.where(isVisible).map(
(action) => FilterGridAppBar.toMenuItem(context, action, enabled: canApply(action)), (action) => FilterGridAppBar.toMenuItem(context, action, enabled: canApply(action)),
@ -367,7 +371,6 @@ class _FilterGridAppBarState<T extends CollectionFilter, CSAD extends ChipSetAct
_onActionSelected(context, action, actionDelegate); _onActionSelected(context, action, actionDelegate);
}, },
), ),
),
]; ];
} }

View file

@ -485,9 +485,31 @@ class _FilterSectionedContentState<T extends CollectionFilter> extends State<_Fi
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_registerWidget(widget);
WidgetsBinding.instance.addPostFrameCallback((_) => _checkInitHighlight()); WidgetsBinding.instance.addPostFrameCallback((_) => _checkInitHighlight());
} }
@override
void didUpdateWidget(covariant _FilterSectionedContent<T> oldWidget) {
super.didUpdateWidget(oldWidget);
_unregisterWidget(oldWidget);
_registerWidget(widget);
}
@override
void dispose() {
_unregisterWidget(widget);
super.dispose();
}
void _registerWidget(_FilterSectionedContent<T> widget) {
widget.appBarHeightNotifier.addListener(_onAppBarHeightChanged);
}
void _unregisterWidget(_FilterSectionedContent<T> widget) {
widget.appBarHeightNotifier.removeListener(_onAppBarHeightChanged);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final scrollView = AnimationLimiter( final scrollView = AnimationLimiter(
@ -527,6 +549,8 @@ class _FilterSectionedContentState<T extends CollectionFilter> extends State<_Fi
); );
} }
void _onAppBarHeightChanged() => setState(() {});
Future<void> _checkInitHighlight() async { Future<void> _checkInitHighlight() async {
final highlightInfo = context.read<HighlightInfo>(); final highlightInfo = context.read<HighlightInfo>();
final filter = highlightInfo.clear(); final filter = highlightInfo.clear();
@ -631,7 +655,7 @@ class _FilterScrollView<T extends CollectionFilter> extends StatelessWidget {
return settings.useTvLayout ? scrollView : _buildDraggableScrollView(scrollView); return settings.useTvLayout ? scrollView : _buildDraggableScrollView(scrollView);
} }
Widget _buildDraggableScrollView(ScrollView scrollView) { Widget _buildDraggableScrollView(Widget scrollView) {
return ValueListenableBuilder<double>( return ValueListenableBuilder<double>(
valueListenable: appBarHeightNotifier, valueListenable: appBarHeightNotifier,
builder: (context, appBarHeight, child) { builder: (context, appBarHeight, child) {
@ -672,7 +696,7 @@ class _FilterScrollView<T extends CollectionFilter> extends StatelessWidget {
); );
} }
ScrollView _buildScrollView(BuildContext context) { Widget _buildScrollView(BuildContext context) {
return CustomScrollView( return CustomScrollView(
key: scrollableKey, key: scrollableKey,
controller: scrollController, controller: scrollController,

View file

@ -16,7 +16,6 @@ class MapInfoRow extends StatelessWidget {
final ValueNotifier<AvesEntry?> entryNotifier; final ValueNotifier<AvesEntry?> entryNotifier;
static const double iconPadding = 8.0; static const double iconPadding = 8.0;
static const double iconSize = 16.0;
static const double _interRowPadding = 2.0; static const double _interRowPadding = 2.0;
const MapInfoRow({ const MapInfoRow({
@ -66,6 +65,8 @@ class MapInfoRow extends StatelessWidget {
}, },
); );
} }
static double getIconSize(BuildContext context) => 16.0 * context.select<MediaQueryData, double>((mq) => mq.textScaleFactor);
} }
class _AddressRow extends StatefulWidget { class _AddressRow extends StatefulWidget {
@ -103,7 +104,7 @@ class _AddressRowState extends State<_AddressRow> {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
const SizedBox(width: MapInfoRow.iconPadding), const SizedBox(width: MapInfoRow.iconPadding),
const Icon(AIcons.location, size: MapInfoRow.iconSize), Icon(AIcons.location, size: MapInfoRow.getIconSize(context)),
const SizedBox(width: MapInfoRow.iconPadding), const SizedBox(width: MapInfoRow.iconPadding),
Expanded( Expanded(
child: Container( child: Container(
@ -173,7 +174,7 @@ class _DateRow extends StatelessWidget {
return Row( return Row(
children: [ children: [
const SizedBox(width: MapInfoRow.iconPadding), const SizedBox(width: MapInfoRow.iconPadding),
const Icon(AIcons.date, size: MapInfoRow.iconSize), Icon(AIcons.date, size: MapInfoRow.getIconSize(context)),
const SizedBox(width: MapInfoRow.iconPadding), const SizedBox(width: MapInfoRow.iconPadding),
Text( Text(
dateText, dateText,

View file

@ -2,6 +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/font_size_icon_theme.dart';
import 'package:aves_utils/aves_utils.dart'; import 'package:aves_utils/aves_utils.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/common/basic/scaffold.dart'; import 'package:aves/widgets/common/basic/scaffold.dart';
@ -151,7 +152,7 @@ class _QuickActionEditorBodyState<T extends Object> extends State<QuickActionEdi
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: Row( child: Row(
children: [ children: [
const Icon(AIcons.info), const FontSizeIconTheme(child: Icon(AIcons.info)),
const SizedBox(width: 16), const SizedBox(width: 16),
Expanded(child: Text(widget.bannerText)), Expanded(child: Text(widget.bannerText)),
], ],

View file

@ -1,4 +1,5 @@
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/common/basic/font_size_icon_theme.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -11,7 +12,7 @@ class DrawerEditorBanner extends StatelessWidget {
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: Row( child: Row(
children: [ children: [
const Icon(AIcons.info), const FontSizeIconTheme(child: Icon(AIcons.info)),
const SizedBox(width: 16), const SizedBox(width: 16),
Expanded(child: Text(context.l10n.settingsNavigationDrawerBanner)), Expanded(child: Text(context.l10n.settingsNavigationDrawerBanner)),
], ],

View file

@ -1,5 +1,6 @@
import 'package:aves/services/common/services.dart'; import 'package:aves/services/common/services.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/common/basic/font_size_icon_theme.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/empty.dart'; import 'package:aves/widgets/common/identity/empty.dart';
@ -96,7 +97,7 @@ class _Header extends StatelessWidget {
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
child: Row( child: Row(
children: [ children: [
const Icon(AIcons.info), const FontSizeIconTheme(child: Icon(AIcons.info)),
const SizedBox(width: 16), const SizedBox(width: 16),
Expanded(child: Text(context.l10n.settingsStorageAccessBanner)), Expanded(child: Text(context.l10n.settingsStorageAccessBanner)),
], ],

View file

@ -3,6 +3,7 @@ import 'package:aves/model/filters/path.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/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/common/basic/font_size_icon_theme.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/aves_filter_chip.dart'; import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
@ -176,7 +177,7 @@ class _Banner extends StatelessWidget {
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: Row( child: Row(
children: [ children: [
const Icon(AIcons.info), const FontSizeIconTheme(child: Icon(AIcons.info)),
const SizedBox(width: 16), const SizedBox(width: 16),
Expanded(child: Text(bannerText)), Expanded(child: Text(bannerText)),
], ],

View file

@ -128,8 +128,7 @@ class _SettingsPageState extends State<SettingsPage> with FeedbackMixin {
onPressed: () => _goToSearch(context), onPressed: () => _goToSearch(context),
tooltip: MaterialLocalizations.of(context).searchFieldLabel, tooltip: MaterialLocalizations.of(context).searchFieldLabel,
), ),
FontSizeIconTheme( PopupMenuButton<SettingsAction>(
child: PopupMenuButton<SettingsAction>(
itemBuilder: (context) { itemBuilder: (context) {
return [ return [
PopupMenuItem( PopupMenuItem(
@ -148,8 +147,7 @@ class _SettingsPageState extends State<SettingsPage> with FeedbackMixin {
_onActionSelected(action); _onActionSelected(action);
}, },
), ),
), ].map((v) => FontSizeIconTheme(child: v)).toList(),
],
), ),
body: GestureAreaProtectorStack( body: GestureAreaProtectorStack(
child: SafeArea( child: SafeArea(

View file

@ -97,7 +97,7 @@ class _InfoRowGroupState extends State<InfoRowGroup> {
// compute the size of keys and space in order to align values // compute the size of keys and space in order to align values
final textScaleFactor = MediaQuery.textScaleFactorOf(context); final textScaleFactor = MediaQuery.textScaleFactorOf(context);
final keySizes = Map.fromEntries(keyValues.keys.map((key) => MapEntry(key, _getSpanWidth(TextSpan(text: key, style: _keyStyle), textScaleFactor)))); final keySizes = Map.fromEntries(keyValues.keys.map((key) => MapEntry(key, _getSpanWidth(TextSpan(text: _buildTextValue(key), style: _keyStyle), textScaleFactor))));
final lastKey = keyValues.keys.last; final lastKey = keyValues.keys.last;
return LayoutBuilder( return LayoutBuilder(
@ -115,15 +115,11 @@ class _InfoRowGroupState extends State<InfoRowGroup> {
final spanBuilder = spanBuilders[key] ?? _buildTextValueSpans; final spanBuilder = spanBuilders[key] ?? _buildTextValueSpans;
final thisSpaceSize = max(0.0, (baseValueX - keySizes[key]!)) + InfoRowGroup.keyValuePadding; final thisSpaceSize = max(0.0, (baseValueX - keySizes[key]!)) + InfoRowGroup.keyValuePadding;
// each text span embeds and pops a Bidi isolate,
// so that layout of the spans follows the directionality of the locale
// (e.g. keys on the right for RTL locale, whatever the key intrinsic directionality)
// and each span respects the directionality of its inner text only
return [ return [
TextSpan(text: '${Constants.fsi}$key${Constants.pdi}', style: _keyStyle), TextSpan(text: _buildTextValue(key), style: _keyStyle),
WidgetSpan( WidgetSpan(
child: SizedBox( child: SizedBox(
width: thisSpaceSize, width: thisSpaceSize / textScaleFactor,
// as of Flutter v3.0.0, the underline decoration from the following `TextSpan` // as of Flutter v3.0.0, the underline decoration from the following `TextSpan`
// is applied to the `WidgetSpan` too, so we add a dummy `Text` as a workaround // is applied to the `WidgetSpan` too, so we add a dummy `Text` as a workaround
child: const Text(''), child: const Text(''),
@ -161,8 +157,14 @@ class _InfoRowGroupState extends State<InfoRowGroup> {
recognizer = TapGestureRecognizer()..onTap = () => setState(() => _expandedKeys.add(key)); recognizer = TapGestureRecognizer()..onTap = () => setState(() => _expandedKeys.add(key));
} }
return [TextSpan(text: '${Constants.fsi}$value${Constants.pdi}', recognizer: recognizer)]; return [TextSpan(text: _buildTextValue(value), recognizer: recognizer)];
} }
// each text span embeds and pops a Bidi isolate,
// so that layout of the spans follows the directionality of the locale
// (e.g. keys on the right for RTL locale, whatever the key intrinsic directionality)
// and each span respects the directionality of its inner text only
String _buildTextValue(String value) => '${Constants.fsi}$value${Constants.pdi}';
} }
typedef InfoValueSpanBuilder = List<InlineSpan> Function(BuildContext context, String key, String value); typedef InfoValueSpanBuilder = List<InlineSpan> Function(BuildContext context, String key, String value);

View file

@ -50,13 +50,15 @@ class InfoAppBar extends StatelessWidget {
return SliverAppBar( return SliverAppBar(
leading: useTvLayout leading: useTvLayout
? null ? null
: IconButton( : FontSizeIconTheme(
child: IconButton(
// key is expected by test driver // key is expected by test driver
key: const Key('back-button'), key: const Key('back-button'),
icon: const Icon(AIcons.goUp), icon: const Icon(AIcons.goUp),
onPressed: onBackPressed, onPressed: onBackPressed,
tooltip: context.l10n.viewerInfoBackToViewerTooltip, tooltip: context.l10n.viewerInfoBackToViewerTooltip,
), ),
),
automaticallyImplyLeading: false, automaticallyImplyLeading: false,
title: SliverAppBarTitleWrapper( title: SliverAppBarTitleWrapper(
child: InteractiveAppBarTitle( child: InteractiveAppBarTitle(
@ -73,8 +75,7 @@ class InfoAppBar extends StatelessWidget {
tooltip: MaterialLocalizations.of(context).searchFieldLabel, tooltip: MaterialLocalizations.of(context).searchFieldLabel,
), ),
if (entry.canEdit) if (entry.canEdit)
FontSizeIconTheme( PopupMenuButton<EntryAction>(
child: PopupMenuButton<EntryAction>(
itemBuilder: (context) => [ itemBuilder: (context) => [
...commonActions.map((action) => _toMenuItem(context, action, enabled: actionDelegate.canApply(entry, action))), ...commonActions.map((action) => _toMenuItem(context, action, enabled: actionDelegate.canApply(entry, action))),
if (formatSpecificActions.isNotEmpty) ...[ if (formatSpecificActions.isNotEmpty) ...[
@ -92,8 +93,7 @@ class InfoAppBar extends StatelessWidget {
actionDelegate.onActionSelected(context, entry, collection, action); actionDelegate.onActionSelected(context, entry, collection, action);
}, },
), ),
), ].map((v) => FontSizeIconTheme(child: v)).toList(),
],
floating: true, floating: true,
); );
} }