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
- 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

View file

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

View file

@ -32,27 +32,13 @@ class SectionHeader<T> 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<Selection<T>>();
@ -80,7 +66,7 @@ class SectionHeader<T> extends StatelessWidget {
child: leading,
)
: null,
onPressed: _onTap(context),
onPressed: onTap,
),
),
TextSpan(
@ -100,9 +86,23 @@ 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] ?? [];

View file

@ -39,17 +39,17 @@ class _DrawerAlbumTabState extends State<DrawerAlbumTab> {
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,

View file

@ -40,6 +40,16 @@ class _DrawerFixedListTabState<T> extends State<DrawerFixedListTab<T>> {
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<T> extends State<DrawerFixedListTab<T>> {
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,
),
);
},

View file

@ -126,17 +126,19 @@ class _HiddenPaths extends StatelessWidget {
child: ListView(
shrinkWrap: true,
children: [
...pathList.map((pathFilter) => ListTile(
...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: () {
settings.changeFilterVisibility({pathFilter}, true);
},
onPressed: onPressed,
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,
);
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(
// 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: Padding(
padding: const EdgeInsets.all(16),
child: header,
),
),
)
: Focus(child: header),
);
} else {
header = Padding(