Fix share copy-link, destination-picker filters, and type-filter UX

- SharesController's fetchShares() built NextcloudShare objects through
  its own thin inline parser instead of _shareFromJson, so url/token/
  permissions/expireDate were always null - a public link share could
  never show "Copy link" in the Shares tab. Reuses _shareFromJson.
- Upload/Move/Copy's destination picker hid External storage in its
  filter sheet (showStorageScope: false) unlike Files' own controls
  row, despite the design doc already calling for full parity.
- Files' and Photos' type filter (All/Files/Folders, All/Photos/Videos)
  now render as one consistent style in both filter sheets: every icon
  always shown, label only on the selected segment
  (NooSegmentedControl's new labelOnlySelected), replacing Files' old
  checkmark list and Photos' own always-labelled track.
- Fixes Photos' type filter only visually updating after closing and
  reopening the filter sheet - it lived on PhotosView's own State, so
  Listenable.merge([photos, files]) never rebuilt the sheet when it
  changed; a StatefulBuilder now gives it that trigger.
- Replaces Settings' trailing section jump rail with per-section
  collapsible cards (NooGroupedList's new collapsible param, expanded
  by default) - one less parallel way to navigate a long screen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-29 03:49:24 -04:00
co-authored by Claude Sonnet 5
parent 4e6477a3ae
commit f9653bc0f2
14 changed files with 417 additions and 326 deletions
+5 -21
View File
@@ -5,6 +5,7 @@ import '../../providers/settings_controller.dart';
import '../../theme/design_tokens.dart';
import '../noo/lists/noo_tab_order_row.dart';
import '../noo/noo_layout.dart';
import 'settings_section.dart';
/// Settings section: the priority order bulk actions (favorite, share,
/// download, ...) show in on the Files/Photos/Favorites multi-select
@@ -40,27 +41,10 @@ class SettingsActionBarSection extends StatelessWidget {
final colors = context.nooColors;
if (!desktop) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Text(
'Action bar',
style: NooText.label.copyWith(color: colors.fg2),
),
),
const SizedBox(height: 4),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Text(
_subtitle,
style: NooText.meta.copyWith(color: colors.fg3),
),
),
const SizedBox(height: 8),
orderList,
],
return SettingsSection(
title: 'Action bar',
subtitle: _subtitle,
children: [orderList],
);
}
+14 -2
View File
@@ -31,6 +31,11 @@ class SettingsSection extends StatelessWidget {
return NooGroupedList(
label: title,
footer: subtitle != null ? Text(subtitle!) : null,
// Every mobile Settings section is individually collapsible,
// expanded by default - replaces the old trailing jump rail (see
// `account_view.dart`'s doc comment) as the way to navigate a long
// Settings screen quickly.
collapsible: true,
children: children,
);
}
@@ -99,8 +104,15 @@ void showSettingsPicker(
required List<Widget> options,
}) {
if (NooLayout.isDesktop(context)) {
showNooDialog(context, title: title, children: [Column(children: options)]);
showNooDialog(
context,
title: title,
children: [Column(children: options)],
);
} else {
showNooSheet(context, children: [NooGroupedList(label: title, children: options)]);
showNooSheet(
context,
children: [NooGroupedList(label: title, children: options)],
);
}
}