Add action bar preview and all swipe actions; rename App lock
Check PR / check (pull_request) Successful in 56s

This commit is contained in:
Ayushya Amitabh
2026-10-07 23:14:21 -04:00
parent 91ab8b4a07
commit 2d244ce335
10 changed files with 277 additions and 82 deletions
+57 -1
View File
@@ -4,6 +4,7 @@ import '../../models/selection_action.dart';
import '../../providers/settings_controller.dart';
import '../../theme/design_tokens.dart';
import '../noo/lists/noo_tab_order_row.dart';
import '../noo/lists/noo_selection_bar.dart';
import '../noo/lists/noo_settings_row.dart';
import '../noo/lists/noo_grouped_list.dart';
import '../noo/core/noo_segmented_control.dart';
@@ -58,7 +59,11 @@ class SettingsActionBarSection extends StatelessWidget {
if (!desktop) {
return NooGroupedList(
footer: const Text(_subtitle),
children: [positionRow, orderList],
children: [
_ActionBarPreview(order: settings.selectionActionOrder),
positionRow,
orderList,
],
);
}
@@ -79,6 +84,8 @@ class SettingsActionBarSection extends StatelessWidget {
const SizedBox(height: 4),
Text(_subtitle, style: NooText.meta.copyWith(color: colors.fg3)),
const SizedBox(height: NooSpace.md),
_ActionBarPreview(order: settings.selectionActionOrder),
const SizedBox(height: NooSpace.md),
positionRow,
const SizedBox(height: NooSpace.md),
orderList,
@@ -88,6 +95,55 @@ class SettingsActionBarSection extends StatelessWidget {
}
}
class _ActionBarPreview extends StatelessWidget {
final List<SelectionActionKind> order;
const _ActionBarPreview({required this.order});
@override
Widget build(BuildContext context) {
final colors = context.nooColors;
final desktop = NooLayout.isDesktop(context);
return Container(
padding: const EdgeInsets.all(NooSpace.sm),
color: colors.surface2,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Preview', style: NooText.meta.copyWith(color: colors.fg3)),
const SizedBox(height: NooSpace.xs),
// Settings has a narrower column than the file browser. Scale the
// real bar to fit rather than changing its inline/overflow split.
FittedBox(
fit: BoxFit.scaleDown,
alignment: Alignment.centerLeft,
child: SizedBox(
width: desktop ? 1000 : 400,
child: NooSelectionBar(
count: 1,
isDesktop: desktop,
iosStyle: NooLayout.iosStyle(context),
onClose: () {},
actions: [
for (final kind in order)
SelectionAction(
kind: kind,
icon: kind.icon,
label: kind.label,
onTap: () => ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('${kind.label} preview')),
),
),
],
),
),
),
],
),
);
}
}
/// The reorderable [NooTabOrderRow] stack for [SelectionActionKind]s - same
/// radius-20, line-divided card `settings_tabs.dart`'s `_TabOrderList`
/// draws, minus the pin toggle (`showPin: false`): there's nothing to
+1 -22
View File
@@ -6,26 +6,6 @@ import '../noo/core/noo_toggle.dart';
import '../noo/lists/noo_settings_row.dart';
import 'settings_section.dart';
/// Per-platform copy for the login-lock row's label (DESIGN_SYSTEM.md 3's
/// "Biometric label" row, both the mobile table and the macOS/Windows
/// desktop table). Falls back to generic copy on platforms the spec
/// doesn't name (Linux, tests).
String biometricLabel(TargetPlatform platform) {
switch (platform) {
case TargetPlatform.iOS:
return 'Lock with Face ID';
case TargetPlatform.android:
return 'Lock with fingerprint';
case TargetPlatform.macOS:
return 'Touch ID';
case TargetPlatform.windows:
return 'Windows Hello';
case TargetPlatform.linux:
case TargetPlatform.fuchsia:
return 'Lock with device credential';
}
}
/// Settings section 3: three independent locks - opening the app, switching
/// accounts, and revealing hidden files - each behind the device's own PIN/
/// biometric credential (see `AppLockService` - this app never stores or
@@ -58,14 +38,13 @@ class SettingsSecuritySection extends StatelessWidget {
@override
Widget build(BuildContext context) {
final session = context.watch<SessionController>();
final platform = Theme.of(context).platform;
return SettingsSection(
title: 'Security',
children: [
NooSettingsRow(
icon: LucideIcons.lock,
label: Text(biometricLabel(platform)),
label: const Text('App lock'),
subtitle: const Text(
"Require this device's PIN or biometric to open Noo",
),
+4 -16
View File
@@ -6,19 +6,6 @@ import '../../theme/design_tokens.dart';
import '../noo/lists/noo_settings_row.dart';
import 'settings_section.dart';
String _swipeActionLabel(SwipeAction action) {
switch (action) {
case SwipeAction.none:
return 'None';
case SwipeAction.favorite:
return 'Favorite';
case SwipeAction.delete:
return 'Delete';
case SwipeAction.share:
return 'Share';
}
}
/// Settings section 8: what swiping a file left/right does in list view.
class SettingsSwipeSection extends StatelessWidget {
const SettingsSwipeSection({super.key});
@@ -35,7 +22,8 @@ class SettingsSwipeSection extends StatelessWidget {
options: [
for (final action in SwipeAction.values)
NooSettingsRow(
label: Text(_swipeActionLabel(action)),
icon: action.selectionKind?.icon,
label: Text(action.label),
trailing: action == current
? Icon(
LucideIcons.check,
@@ -64,7 +52,7 @@ class SettingsSwipeSection extends StatelessWidget {
NooSettingsRow(
icon: LucideIcons.chevronsRight,
label: const Text('Swipe right'),
value: _swipeActionLabel(settings.swipeRightAction),
value: settings.swipeRightAction.label,
onTap: () => _openPicker(
context,
title: 'Swipe right',
@@ -75,7 +63,7 @@ class SettingsSwipeSection extends StatelessWidget {
NooSettingsRow(
icon: LucideIcons.chevronsLeft,
label: const Text('Swipe left'),
value: _swipeActionLabel(settings.swipeLeftAction),
value: settings.swipeLeftAction.label,
onTap: () => _openPicker(
context,
title: 'Swipe left',