tv: changed section header focus/highlight

This commit is contained in:
Thibault Deckers 2023-04-17 23:24:11 +02:00
parent 8b4f6e45f8
commit 10756f5156
7 changed files with 71 additions and 51 deletions

View file

@ -18,6 +18,7 @@ All notable changes to this project will be documented in this file.
- upgraded Flutter to stable v3.7.11 - 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 - 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 ### Fixed

View file

@ -49,6 +49,8 @@ class TitledExpandableFilterRow extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
header, header,
const SizedBox(width: 16),
Icon(isExpanded ? AIcons.collapse : AIcons.expand),
], ],
), ),
), ),

View file

@ -32,27 +32,13 @@ class SectionHeader<T> extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Widget child = _buildContent(context); final onTap = selectable ? () => _toggleSectionSelection(context) : null;
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,
);
}
Widget _buildContent(BuildContext context) { Widget child = Container(
return Container(
padding: padding, padding: padding,
constraints: BoxConstraints(minHeight: leadingSize.height), constraints: BoxConstraints(minHeight: leadingSize.height),
child: GestureDetector( child: GestureDetector(
onTap: _onTap(context), onTap: onTap,
onLongPress: selectable onLongPress: selectable
? () { ? () {
final selection = context.read<Selection<T>>(); final selection = context.read<Selection<T>>();
@ -80,7 +66,7 @@ class SectionHeader<T> extends StatelessWidget {
child: leading, child: leading,
) )
: null, : null,
onPressed: _onTap(context), onPressed: onTap,
), ),
), ),
TextSpan( TextSpan(
@ -100,10 +86,24 @@ class SectionHeader<T> 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<Selection<T>, 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<T> _getSectionEntries(BuildContext context) => context.read<SectionedListLayout<T>>().sections[sectionKey] ?? []; List<T> _getSectionEntries(BuildContext context) => context.read<SectionedListLayout<T>>().sections[sectionKey] ?? [];
void _toggleSectionSelection(BuildContext context) { void _toggleSectionSelection(BuildContext context) {

View file

@ -39,17 +39,17 @@ class _DrawerAlbumTabState extends State<DrawerAlbumTab> {
itemBuilder: (context, index) { itemBuilder: (context, index) {
final album = items[index]; final album = items[index];
final filter = AlbumFilter(album, source.getAlbumDisplayName(context, album)); final filter = AlbumFilter(album, source.getAlbumDisplayName(context, album));
void onPressed() => setState(() => items.remove(album));
return ListTile( return ListTile(
key: ValueKey(album), key: ValueKey(album),
leading: DrawerFilterIcon(filter: filter), leading: DrawerFilterIcon(filter: filter),
title: DrawerFilterTitle(filter: filter), title: DrawerFilterTitle(filter: filter),
trailing: IconButton( trailing: IconButton(
icon: const Icon(AIcons.clear), icon: const Icon(AIcons.clear),
onPressed: () { onPressed: onPressed,
setState(() => items.remove(album));
},
tooltip: context.l10n.actionRemove, tooltip: context.l10n.actionRemove,
), ),
onTap: settings.useTvLayout ? onPressed : null,
); );
}, },
itemCount: items.length, itemCount: items.length,

View file

@ -40,6 +40,16 @@ class _DrawerFixedListTabState<T> extends State<DrawerFixedListTab<T>> {
itemBuilder: (context, index) { itemBuilder: (context, index) {
final filter = widget.items[index]; final filter = widget.items[index];
final visible = visibleItems.contains(filter); final visible = visibleItems.contains(filter);
void onPressed() {
setState(() {
if (visible) {
visibleItems.remove(filter);
} else {
visibleItems.add(filter);
}
});
}
return Opacity( return Opacity(
key: ValueKey(filter), key: ValueKey(filter),
opacity: visible ? 1 : .4, opacity: visible ? 1 : .4,
@ -48,17 +58,10 @@ class _DrawerFixedListTabState<T> extends State<DrawerFixedListTab<T>> {
title: widget.title(filter), title: widget.title(filter),
trailing: IconButton( trailing: IconButton(
icon: Icon(visible ? AIcons.hide : AIcons.show), icon: Icon(visible ? AIcons.hide : AIcons.show),
onPressed: () { onPressed: onPressed,
setState(() {
if (visible) {
visibleItems.remove(filter);
} else {
visibleItems.add(filter);
}
});
},
tooltip: visible ? context.l10n.hideTooltip : context.l10n.showTooltip, tooltip: visible ? context.l10n.hideTooltip : context.l10n.showTooltip,
), ),
onTap: settings.useTvLayout ? onPressed : null,
), ),
); );
}, },

View file

@ -126,17 +126,19 @@ class _HiddenPaths extends StatelessWidget {
child: ListView( child: ListView(
shrinkWrap: true, shrinkWrap: true,
children: [ children: [
...pathList.map((pathFilter) => ListTile( ...pathList.map((pathFilter) {
title: Text(pathFilter.path), void onPressed() => settings.changeFilterVisibility({pathFilter}, true);
dense: true, return ListTile(
trailing: IconButton( title: Text(pathFilter.path),
icon: const Icon(AIcons.clear), dense: true,
onPressed: () { trailing: IconButton(
settings.changeFilterVisibility({pathFilter}, true); icon: const Icon(AIcons.clear),
}, onPressed: onPressed,
tooltip: context.l10n.actionRemove, tooltip: context.l10n.actionRemove,
), ),
)), onTap: settings.useTvLayout ? onPressed : null,
);
}),
], ],
), ),
), ),

View file

@ -286,17 +286,29 @@ class _StatsPageState extends State<StatsPage> with FeedbackMixin, VaultAwareMix
style: AStyles.knownTitleText, style: AStyles.knownTitleText,
); );
if (settings.useTvLayout) { 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( header = Container(
padding: const EdgeInsets.symmetric(vertical: 12), padding: const EdgeInsets.symmetric(vertical: 12),
alignment: AlignmentDirectional.centerStart, alignment: AlignmentDirectional.centerStart,
child: InkWell( // prevent ink response when tapping the header does nothing,
onTap: onHeaderPressed, // because otherwise Play Store reviewers think it is broken navigation
borderRadius: const BorderRadius.all(Radius.circular(123)), child: onHeaderPressed != null
child: Padding( ? InkWell(
padding: const EdgeInsets.all(16), onTap: onHeaderPressed,
child: header, borderRadius: const BorderRadius.all(Radius.circular(123)),
), child: header,
), )
: Focus(child: header),
); );
} else { } else {
header = Padding( header = Padding(