From 5fbac333d577655327e867c409fdd39acbee5117 Mon Sep 17 00:00:00 2001 From: Ayushya Amitabh Date: Mon, 5 Oct 2026 22:38:37 -0400 Subject: [PATCH] Filter sheets: 'Type' label above the type control; shorten 'All + ...' to 'All' Co-Authored-By: Claude Sonnet 5.5 --- lib/views/photos_view.dart | 56 ++++++++++--------- lib/widgets/files_controls_row.dart | 50 +++++++++-------- lib/widgets/filter_mode_rows.dart | 71 +++++++++++++++++-------- test/widgets/filter_mode_rows_test.dart | 6 +-- 4 files changed, 108 insertions(+), 75 deletions(-) diff --git a/lib/views/photos_view.dart b/lib/views/photos_view.dart index a358b61..e618056 100644 --- a/lib/views/photos_view.dart +++ b/lib/views/photos_view.dart @@ -522,32 +522,36 @@ class _PhotosViewState extends State { // Same "icon always, label only when selected" pill as // Files' own type filter - not a fully-labelled track, so // the two screens' filter sheets look and behave the same. - NooSegmentedControl<_PhotoTypeFilter>( - fill: true, - onSurface: true, - labelOnlySelected: true, - value: _typeFilter, - onChanged: (filter) => setState(() { - _typeFilter = filter; - setSheetState(() {}); - }), - options: const [ - NooSegmentOption( - value: _PhotoTypeFilter.all, - icon: LucideIcons.layoutGrid, - label: 'All', - ), - NooSegmentOption( - value: _PhotoTypeFilter.image, - icon: LucideIcons.image, - label: 'Photos', - ), - NooSegmentOption( - value: _PhotoTypeFilter.video, - icon: LucideIcons.film, - label: 'Videos', - ), - ], + FilterSection( + icon: LucideIcons.layoutGrid, + title: 'Type', + child: NooSegmentedControl<_PhotoTypeFilter>( + fill: true, + onSurface: true, + labelOnlySelected: true, + value: _typeFilter, + onChanged: (filter) => setState(() { + _typeFilter = filter; + setSheetState(() {}); + }), + options: const [ + NooSegmentOption( + value: _PhotoTypeFilter.all, + icon: LucideIcons.layoutGrid, + label: 'All', + ), + NooSegmentOption( + value: _PhotoTypeFilter.image, + icon: LucideIcons.image, + label: 'Photos', + ), + NooSegmentOption( + value: _PhotoTypeFilter.video, + icon: LucideIcons.film, + label: 'Videos', + ), + ], + ), ), const SizedBox(height: 22), NooGroupedList( diff --git a/lib/widgets/files_controls_row.dart b/lib/widgets/files_controls_row.dart index ac69d60..f2db4a6 100644 --- a/lib/widgets/files_controls_row.dart +++ b/lib/widgets/files_controls_row.dart @@ -171,29 +171,33 @@ class FilesControlsRow extends StatelessWidget { // Same "icon always, label only when selected" pill as // Photos' own type filter below - not a checkmark list, so // the two screens' filter sheets look and behave the same. - NooSegmentedControl( - fill: true, - onSurface: true, - labelOnlySelected: true, - value: files.filesTypeFilter, - onChanged: files.setFilesTypeFilter, - options: const [ - NooSegmentOption( - value: FilesTypeFilter.all, - icon: LucideIcons.layoutGrid, - label: 'All', - ), - NooSegmentOption( - value: FilesTypeFilter.filesOnly, - icon: LucideIcons.file, - label: 'Files', - ), - NooSegmentOption( - value: FilesTypeFilter.foldersOnly, - icon: LucideIcons.folder, - label: 'Folders', - ), - ], + FilterSection( + icon: LucideIcons.layoutGrid, + title: 'Type', + child: NooSegmentedControl( + fill: true, + onSurface: true, + labelOnlySelected: true, + value: files.filesTypeFilter, + onChanged: files.setFilesTypeFilter, + options: const [ + NooSegmentOption( + value: FilesTypeFilter.all, + icon: LucideIcons.layoutGrid, + label: 'All', + ), + NooSegmentOption( + value: FilesTypeFilter.filesOnly, + icon: LucideIcons.file, + label: 'Files', + ), + NooSegmentOption( + value: FilesTypeFilter.foldersOnly, + icon: LucideIcons.folder, + label: 'Folders', + ), + ], + ), ), const SizedBox(height: 22), HiddenFilesFilterRow( diff --git a/lib/widgets/filter_mode_rows.dart b/lib/widgets/filter_mode_rows.dart index d2ed936..a02eba3 100644 --- a/lib/widgets/filter_mode_rows.dart +++ b/lib/widgets/filter_mode_rows.dart @@ -39,7 +39,7 @@ class HiddenFilesFilterRow extends StatelessWidget { NooSegmentOption( value: HiddenFilesFilter.include, icon: LucideIcons.layers, - label: 'All + hidden', + label: 'All', ), ], ); @@ -80,13 +80,48 @@ class StorageScopeRow extends StatelessWidget { NooSegmentOption( value: StorageScope.all, icon: LucideIcons.layers, - label: 'All + external', + label: 'All', ), ], ); } } +/// An icon + title line above [child] - the shape every row of the Files/ +/// Photos filter sheets shares, including their type (All/Files/Folders) +/// control, which lives in its own file. +class FilterSection extends StatelessWidget { + final IconData icon; + final String title; + final Widget child; + + const FilterSection({ + super.key, + required this.icon, + required this.title, + required this.child, + }); + + @override + Widget build(BuildContext context) { + final colors = context.nooColors; + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon(icon, size: 18, color: colors.fg2), + const SizedBox(width: 10), + Text(title, style: NooText.bodyL.copyWith(color: colors.fg1)), + ], + ), + const SizedBox(height: 10), + child, + ], + ); + } +} + class _FilterModeRow extends StatelessWidget { final IconData icon; final String title; @@ -104,27 +139,17 @@ class _FilterModeRow extends StatelessWidget { @override Widget build(BuildContext context) { - final colors = context.nooColors; - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Icon(icon, size: 18, color: colors.fg2), - const SizedBox(width: 10), - Text(title, style: NooText.bodyL.copyWith(color: colors.fg1)), - ], - ), - const SizedBox(height: 10), - NooSegmentedControl( - fill: true, - onSurface: true, - labelOnlySelected: true, - value: value, - onChanged: onChanged, - options: options, - ), - ], + return FilterSection( + icon: icon, + title: title, + child: NooSegmentedControl( + fill: true, + onSurface: true, + labelOnlySelected: true, + value: value, + onChanged: onChanged, + options: options, + ), ); } } diff --git a/test/widgets/filter_mode_rows_test.dart b/test/widgets/filter_mode_rows_test.dart index ac51644..e55fd1b 100644 --- a/test/widgets/filter_mode_rows_test.dart +++ b/test/widgets/filter_mode_rows_test.dart @@ -34,13 +34,13 @@ void main() { await tester.tap(find.byIcon(LucideIcons.layers)); await tester.pumpAndSettle(); expect(value, HiddenFilesFilter.include); - expect(find.text('All + hidden'), findsOneWidget); + expect(find.text('All'), findsOneWidget); }, ); }); group('StorageScopeRow', () { - testNooWidgets('offers cloud only / only external / all + external', ( + testNooWidgets('offers cloud only / only external / all', ( tester, theme, c, @@ -70,7 +70,7 @@ void main() { await tester.tap(find.byIcon(LucideIcons.layers)); await tester.pumpAndSettle(); expect(value, StorageScope.all); - expect(find.text('All + external'), findsOneWidget); + expect(find.text('All'), findsOneWidget); }); }); }