From 10756f5156b3631f3d194cb53616f9aa117d5b56 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Mon, 17 Apr 2023 23:24:11 +0200 Subject: [PATCH] tv: changed section header focus/highlight --- CHANGELOG.md | 1 + lib/widgets/common/expandable_filter_row.dart | 2 + lib/widgets/common/grid/header.dart | 40 +++++++++---------- .../navigation/drawer_tab_albums.dart | 6 +-- .../settings/navigation/drawer_tab_fixed.dart | 21 +++++----- .../settings/privacy/hidden_items_page.dart | 24 ++++++----- lib/widgets/stats/stats_page.dart | 28 +++++++++---- 7 files changed, 71 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fd58b7e4..089ef8e22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ All notable changes to this project will be documented in this file. - upgraded Flutter to stable v3.7.11 - when an album becomes empty, the folder will be deleted only if it is a non-app/common album +- TV: section header focus/highlight ### Fixed diff --git a/lib/widgets/common/expandable_filter_row.dart b/lib/widgets/common/expandable_filter_row.dart index d7dbd64d3..a3dccd4ce 100644 --- a/lib/widgets/common/expandable_filter_row.dart +++ b/lib/widgets/common/expandable_filter_row.dart @@ -49,6 +49,8 @@ class TitledExpandableFilterRow extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ header, + const SizedBox(width: 16), + Icon(isExpanded ? AIcons.collapse : AIcons.expand), ], ), ), diff --git a/lib/widgets/common/grid/header.dart b/lib/widgets/common/grid/header.dart index c7dd1b560..16be78103 100644 --- a/lib/widgets/common/grid/header.dart +++ b/lib/widgets/common/grid/header.dart @@ -32,27 +32,13 @@ class SectionHeader extends StatelessWidget { @override Widget build(BuildContext context) { - Widget child = _buildContent(context); - if (settings.useTvLayout) { - child = InkWell( - onTap: _onTap(context), - borderRadius: const BorderRadius.all(Radius.circular(123)), - child: child, - ); - } - return Container( - alignment: AlignmentDirectional.centerStart, - margin: margin, - child: child, - ); - } + final onTap = selectable ? () => _toggleSectionSelection(context) : null; - Widget _buildContent(BuildContext context) { - return Container( + Widget child = Container( padding: padding, constraints: BoxConstraints(minHeight: leadingSize.height), child: GestureDetector( - onTap: _onTap(context), + onTap: onTap, onLongPress: selectable ? () { final selection = context.read>(); @@ -80,7 +66,7 @@ class SectionHeader extends StatelessWidget { child: leading, ) : null, - onPressed: _onTap(context), + onPressed: onTap, ), ), TextSpan( @@ -100,10 +86,24 @@ class SectionHeader extends StatelessWidget { ), ), ); + if (settings.useTvLayout) { + // prevent ink response when tapping the header does nothing, + // because otherwise Play Store reviewers think it is broken navigation + child = context.select, bool>((v) => v.isSelecting) + ? InkWell( + onTap: onTap, + borderRadius: const BorderRadius.all(Radius.circular(123)), + child: child, + ) + : Focus(child: child); + } + return Container( + alignment: AlignmentDirectional.centerStart, + margin: margin, + child: child, + ); } - VoidCallback? _onTap(BuildContext context) => selectable ? () => _toggleSectionSelection(context) : null; - List _getSectionEntries(BuildContext context) => context.read>().sections[sectionKey] ?? []; void _toggleSectionSelection(BuildContext context) { diff --git a/lib/widgets/settings/navigation/drawer_tab_albums.dart b/lib/widgets/settings/navigation/drawer_tab_albums.dart index 1b62dcd2a..5ee754397 100644 --- a/lib/widgets/settings/navigation/drawer_tab_albums.dart +++ b/lib/widgets/settings/navigation/drawer_tab_albums.dart @@ -39,17 +39,17 @@ class _DrawerAlbumTabState extends State { itemBuilder: (context, index) { final album = items[index]; final filter = AlbumFilter(album, source.getAlbumDisplayName(context, album)); + void onPressed() => setState(() => items.remove(album)); return ListTile( key: ValueKey(album), leading: DrawerFilterIcon(filter: filter), title: DrawerFilterTitle(filter: filter), trailing: IconButton( icon: const Icon(AIcons.clear), - onPressed: () { - setState(() => items.remove(album)); - }, + onPressed: onPressed, tooltip: context.l10n.actionRemove, ), + onTap: settings.useTvLayout ? onPressed : null, ); }, itemCount: items.length, diff --git a/lib/widgets/settings/navigation/drawer_tab_fixed.dart b/lib/widgets/settings/navigation/drawer_tab_fixed.dart index 1069693a3..e583cb452 100644 --- a/lib/widgets/settings/navigation/drawer_tab_fixed.dart +++ b/lib/widgets/settings/navigation/drawer_tab_fixed.dart @@ -40,6 +40,16 @@ class _DrawerFixedListTabState extends State> { itemBuilder: (context, index) { final filter = widget.items[index]; final visible = visibleItems.contains(filter); + void onPressed() { + setState(() { + if (visible) { + visibleItems.remove(filter); + } else { + visibleItems.add(filter); + } + }); + } + return Opacity( key: ValueKey(filter), opacity: visible ? 1 : .4, @@ -48,17 +58,10 @@ class _DrawerFixedListTabState extends State> { title: widget.title(filter), trailing: IconButton( icon: Icon(visible ? AIcons.hide : AIcons.show), - onPressed: () { - setState(() { - if (visible) { - visibleItems.remove(filter); - } else { - visibleItems.add(filter); - } - }); - }, + onPressed: onPressed, tooltip: visible ? context.l10n.hideTooltip : context.l10n.showTooltip, ), + onTap: settings.useTvLayout ? onPressed : null, ), ); }, diff --git a/lib/widgets/settings/privacy/hidden_items_page.dart b/lib/widgets/settings/privacy/hidden_items_page.dart index d1227f512..0e94d6372 100644 --- a/lib/widgets/settings/privacy/hidden_items_page.dart +++ b/lib/widgets/settings/privacy/hidden_items_page.dart @@ -126,17 +126,19 @@ class _HiddenPaths extends StatelessWidget { child: ListView( shrinkWrap: true, children: [ - ...pathList.map((pathFilter) => ListTile( - title: Text(pathFilter.path), - dense: true, - trailing: IconButton( - icon: const Icon(AIcons.clear), - onPressed: () { - settings.changeFilterVisibility({pathFilter}, true); - }, - tooltip: context.l10n.actionRemove, - ), - )), + ...pathList.map((pathFilter) { + void onPressed() => settings.changeFilterVisibility({pathFilter}, true); + return ListTile( + title: Text(pathFilter.path), + dense: true, + trailing: IconButton( + icon: const Icon(AIcons.clear), + onPressed: onPressed, + tooltip: context.l10n.actionRemove, + ), + onTap: settings.useTvLayout ? onPressed : null, + ); + }), ], ), ), diff --git a/lib/widgets/stats/stats_page.dart b/lib/widgets/stats/stats_page.dart index e3c81ad43..a7f6cdb77 100644 --- a/lib/widgets/stats/stats_page.dart +++ b/lib/widgets/stats/stats_page.dart @@ -286,17 +286,29 @@ class _StatsPageState extends State with FeedbackMixin, VaultAwareMix style: AStyles.knownTitleText, ); if (settings.useTvLayout) { + header = Padding( + padding: const EdgeInsets.all(16), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + header, + const SizedBox(width: 16), + Icon(AIcons.next, color: hasMore ? null : Theme.of(context).disabledColor), + ], + ), + ); header = Container( padding: const EdgeInsets.symmetric(vertical: 12), alignment: AlignmentDirectional.centerStart, - child: InkWell( - onTap: onHeaderPressed, - borderRadius: const BorderRadius.all(Radius.circular(123)), - child: Padding( - padding: const EdgeInsets.all(16), - child: header, - ), - ), + // prevent ink response when tapping the header does nothing, + // because otherwise Play Store reviewers think it is broken navigation + child: onHeaderPressed != null + ? InkWell( + onTap: onHeaderPressed, + borderRadius: const BorderRadius.all(Radius.circular(123)), + child: header, + ) + : Focus(child: header), ); } else { header = Padding(