Filter sheets: 'Type' label above the type control; shorten 'All + ...' to 'All'
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
3c60f8c709
commit
5fbac333d5
@@ -522,7 +522,10 @@ class _PhotosViewState extends State<PhotosView> {
|
|||||||
// Same "icon always, label only when selected" pill as
|
// Same "icon always, label only when selected" pill as
|
||||||
// Files' own type filter - not a fully-labelled track, so
|
// Files' own type filter - not a fully-labelled track, so
|
||||||
// the two screens' filter sheets look and behave the same.
|
// the two screens' filter sheets look and behave the same.
|
||||||
NooSegmentedControl<_PhotoTypeFilter>(
|
FilterSection(
|
||||||
|
icon: LucideIcons.layoutGrid,
|
||||||
|
title: 'Type',
|
||||||
|
child: NooSegmentedControl<_PhotoTypeFilter>(
|
||||||
fill: true,
|
fill: true,
|
||||||
onSurface: true,
|
onSurface: true,
|
||||||
labelOnlySelected: true,
|
labelOnlySelected: true,
|
||||||
@@ -549,6 +552,7 @@ class _PhotosViewState extends State<PhotosView> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
const SizedBox(height: 22),
|
const SizedBox(height: 22),
|
||||||
NooGroupedList(
|
NooGroupedList(
|
||||||
children: [
|
children: [
|
||||||
|
|||||||
@@ -171,7 +171,10 @@ class FilesControlsRow extends StatelessWidget {
|
|||||||
// Same "icon always, label only when selected" pill as
|
// Same "icon always, label only when selected" pill as
|
||||||
// Photos' own type filter below - not a checkmark list, so
|
// Photos' own type filter below - not a checkmark list, so
|
||||||
// the two screens' filter sheets look and behave the same.
|
// the two screens' filter sheets look and behave the same.
|
||||||
NooSegmentedControl<FilesTypeFilter>(
|
FilterSection(
|
||||||
|
icon: LucideIcons.layoutGrid,
|
||||||
|
title: 'Type',
|
||||||
|
child: NooSegmentedControl<FilesTypeFilter>(
|
||||||
fill: true,
|
fill: true,
|
||||||
onSurface: true,
|
onSurface: true,
|
||||||
labelOnlySelected: true,
|
labelOnlySelected: true,
|
||||||
@@ -195,6 +198,7 @@ class FilesControlsRow extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
const SizedBox(height: 22),
|
const SizedBox(height: 22),
|
||||||
HiddenFilesFilterRow(
|
HiddenFilesFilterRow(
|
||||||
value: files.hiddenFilter,
|
value: files.hiddenFilter,
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class HiddenFilesFilterRow extends StatelessWidget {
|
|||||||
NooSegmentOption(
|
NooSegmentOption(
|
||||||
value: HiddenFilesFilter.include,
|
value: HiddenFilesFilter.include,
|
||||||
icon: LucideIcons.layers,
|
icon: LucideIcons.layers,
|
||||||
label: 'All + hidden',
|
label: 'All',
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -80,13 +80,48 @@ class StorageScopeRow extends StatelessWidget {
|
|||||||
NooSegmentOption(
|
NooSegmentOption(
|
||||||
value: StorageScope.all,
|
value: StorageScope.all,
|
||||||
icon: LucideIcons.layers,
|
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<T> extends StatelessWidget {
|
class _FilterModeRow<T> extends StatelessWidget {
|
||||||
final IconData icon;
|
final IconData icon;
|
||||||
final String title;
|
final String title;
|
||||||
@@ -104,19 +139,10 @@ class _FilterModeRow<T> extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final colors = context.nooColors;
|
return FilterSection(
|
||||||
return Column(
|
icon: icon,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
title: title,
|
||||||
children: [
|
child: NooSegmentedControl<T>(
|
||||||
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<T>(
|
|
||||||
fill: true,
|
fill: true,
|
||||||
onSurface: true,
|
onSurface: true,
|
||||||
labelOnlySelected: true,
|
labelOnlySelected: true,
|
||||||
@@ -124,7 +150,6 @@ class _FilterModeRow<T> extends StatelessWidget {
|
|||||||
onChanged: onChanged,
|
onChanged: onChanged,
|
||||||
options: options,
|
options: options,
|
||||||
),
|
),
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,13 +34,13 @@ void main() {
|
|||||||
await tester.tap(find.byIcon(LucideIcons.layers));
|
await tester.tap(find.byIcon(LucideIcons.layers));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(value, HiddenFilesFilter.include);
|
expect(value, HiddenFilesFilter.include);
|
||||||
expect(find.text('All + hidden'), findsOneWidget);
|
expect(find.text('All'), findsOneWidget);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('StorageScopeRow', () {
|
group('StorageScopeRow', () {
|
||||||
testNooWidgets('offers cloud only / only external / all + external', (
|
testNooWidgets('offers cloud only / only external / all', (
|
||||||
tester,
|
tester,
|
||||||
theme,
|
theme,
|
||||||
c,
|
c,
|
||||||
@@ -70,7 +70,7 @@ void main() {
|
|||||||
await tester.tap(find.byIcon(LucideIcons.layers));
|
await tester.tap(find.byIcon(LucideIcons.layers));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(value, StorageScope.all);
|
expect(value, StorageScope.all);
|
||||||
expect(find.text('All + external'), findsOneWidget);
|
expect(find.text('All'), findsOneWidget);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user