Filters: three-way hidden files and external storage
Hidden: hide / only hidden / all + hidden. External: cloud only / only external / all + external; with 'all' Files shows the external items in a collapsible section. Old show-hidden bool prefs are still read as fallback. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
944b87b054
commit
3c60f8c709
@@ -5,7 +5,7 @@ import '../providers/files_controller.dart';
|
||||
import '../theme/design_tokens.dart';
|
||||
import 'noo/core/noo_chip.dart';
|
||||
import 'noo/core/noo_segmented_control.dart';
|
||||
import 'noo/core/noo_toggle.dart';
|
||||
import 'filter_mode_rows.dart';
|
||||
import 'noo/lists/noo_grouped_list.dart';
|
||||
import 'noo/lists/noo_settings_row.dart';
|
||||
import 'noo/overlays/noo_sheet.dart';
|
||||
@@ -54,7 +54,7 @@ class FilesControlsRow extends StatelessWidget {
|
||||
final files = context.watch<FilesController>();
|
||||
final filtersActive =
|
||||
files.filesTypeFilter != FilesTypeFilter.all ||
|
||||
files.showHiddenFiles ||
|
||||
files.hiddenFilter != HiddenFilesFilter.hide ||
|
||||
(showStorageScope && files.storageScope != StorageScope.cloud);
|
||||
|
||||
return SizedBox(
|
||||
@@ -196,29 +196,17 @@ class FilesControlsRow extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 22),
|
||||
NooGroupedList(
|
||||
children: [
|
||||
NooSettingsRow(
|
||||
icon: LucideIcons.eye,
|
||||
label: const Text('Show hidden files'),
|
||||
trailing: NooToggle(
|
||||
checked: files.showHiddenFiles,
|
||||
onChanged: (_) => files.toggleShowHiddenFiles(),
|
||||
),
|
||||
),
|
||||
if (showStorageScope)
|
||||
NooSettingsRow(
|
||||
icon: LucideIcons.hardDrive,
|
||||
label: const Text('External storage'),
|
||||
trailing: NooToggle(
|
||||
checked: files.storageScope == StorageScope.external,
|
||||
onChanged: (external) => files.setStorageScope(
|
||||
external ? StorageScope.external : StorageScope.cloud,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
HiddenFilesFilterRow(
|
||||
value: files.hiddenFilter,
|
||||
onChanged: files.setHiddenFilter,
|
||||
),
|
||||
if (showStorageScope) ...[
|
||||
const SizedBox(height: 22),
|
||||
StorageScopeRow(
|
||||
value: files.storageScope,
|
||||
onChanged: files.setStorageScope,
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lucide_icons_flutter/lucide_icons.dart';
|
||||
import '../providers/files_controller.dart';
|
||||
import '../theme/design_tokens.dart';
|
||||
import 'noo/core/noo_segmented_control.dart';
|
||||
|
||||
/// "Hidden files" row of the Files/Photos filter sheets: hide them (the
|
||||
/// default), show only them, or show them alongside everything else. Same
|
||||
/// icon-always/label-when-selected pill as the type filter above it in
|
||||
/// both sheets.
|
||||
class HiddenFilesFilterRow extends StatelessWidget {
|
||||
final HiddenFilesFilter value;
|
||||
final ValueChanged<HiddenFilesFilter> onChanged;
|
||||
|
||||
const HiddenFilesFilterRow({
|
||||
super.key,
|
||||
required this.value,
|
||||
required this.onChanged,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return _FilterModeRow<HiddenFilesFilter>(
|
||||
icon: LucideIcons.eye,
|
||||
title: 'Hidden files',
|
||||
value: value,
|
||||
onChanged: onChanged,
|
||||
options: const [
|
||||
NooSegmentOption(
|
||||
value: HiddenFilesFilter.hide,
|
||||
icon: LucideIcons.eyeOff,
|
||||
label: 'Hide',
|
||||
),
|
||||
NooSegmentOption(
|
||||
value: HiddenFilesFilter.only,
|
||||
icon: LucideIcons.eye,
|
||||
label: 'Only hidden',
|
||||
),
|
||||
NooSegmentOption(
|
||||
value: HiddenFilesFilter.include,
|
||||
icon: LucideIcons.layers,
|
||||
label: 'All + hidden',
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// "External storage" row of the Files/Photos filter sheets: cloud only
|
||||
/// (the default), only external storage, or both. Files shows the external
|
||||
/// items in a collapsible section for [StorageScope.all].
|
||||
class StorageScopeRow extends StatelessWidget {
|
||||
final StorageScope value;
|
||||
final ValueChanged<StorageScope> onChanged;
|
||||
|
||||
const StorageScopeRow({
|
||||
super.key,
|
||||
required this.value,
|
||||
required this.onChanged,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return _FilterModeRow<StorageScope>(
|
||||
icon: LucideIcons.hardDrive,
|
||||
title: 'External storage',
|
||||
value: value,
|
||||
onChanged: onChanged,
|
||||
options: const [
|
||||
NooSegmentOption(
|
||||
value: StorageScope.cloud,
|
||||
icon: LucideIcons.cloud,
|
||||
label: 'Cloud only',
|
||||
),
|
||||
NooSegmentOption(
|
||||
value: StorageScope.external,
|
||||
icon: LucideIcons.hardDrive,
|
||||
label: 'Only external',
|
||||
),
|
||||
NooSegmentOption(
|
||||
value: StorageScope.all,
|
||||
icon: LucideIcons.layers,
|
||||
label: 'All + external',
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _FilterModeRow<T> extends StatelessWidget {
|
||||
final IconData icon;
|
||||
final String title;
|
||||
final T value;
|
||||
final ValueChanged<T> onChanged;
|
||||
final List<NooSegmentOption<T>> options;
|
||||
|
||||
const _FilterModeRow({
|
||||
required this.icon,
|
||||
required this.title,
|
||||
required this.value,
|
||||
required this.onChanged,
|
||||
required this.options,
|
||||
});
|
||||
|
||||
@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<T>(
|
||||
fill: true,
|
||||
onSurface: true,
|
||||
labelOnlySelected: true,
|
||||
value: value,
|
||||
onChanged: onChanged,
|
||||
options: options,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user