Rebuild UI on the Noo design system
Replaces the Material 3 screens with the Noo design system: warm neutrals, one violet accent, pill controls, Schibsted Grotesk/ Instrument Sans, Lucide icons, no gradients/shadows. - New lib/widgets/noo/ component kit (core, lists, files, media, nav, overlays) plus lib/theme/design_tokens.dart for the color/type/space/ radius/motion tokens. - Rebuilt the app shell (top/bottom bars, drawer, desktop sidebar and toolbar), every tab (Files/Offline, Photos, Favorites, Recent, Activity, Trash, Shares), Settings, the lock and login screens, the media viewer, search, the details/share sheets, and the share-upload and move/copy destination pickers. - Added a design canvas (linked from DESIGN_SYSTEM.md) covering the screens the spec didn't already describe, with matching Android and iOS chrome; wrote up the approved recipes into DESIGN_SYSTEM.md §4. - Removed now-dead legacy widgets (media_grid_tile, swipeable_item, sync_status_badge, selectable_thumbnail) and updated architecture.md/styling.md/standards.md to describe the new structure and component/testing conventions. - Added widget tests for the noo/ component kit. This is a UI-only rework: no provider/model/service behavior changed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lucide_icons_flutter/lucide_icons.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../models/app_tab.dart';
|
||||
import '../providers/files_controller.dart';
|
||||
import '../providers/session_controller.dart';
|
||||
import '../providers/settings_controller.dart';
|
||||
import '../providers/trash_controller.dart';
|
||||
import 'noo/core/noo_avatar.dart';
|
||||
import 'noo/nav/noo_drawer.dart';
|
||||
import 'shell/shell_common.dart';
|
||||
|
||||
/// The mobile drawer (DESIGN_SYSTEM.md 2 "Drawer" / 3; `drawer` in
|
||||
/// `Mobile Screen.dc.html`): account block, storage bar, the tabs not
|
||||
/// pinned to the bottom nav bar ("More"), Settings, and an "Edit tabs"
|
||||
/// link. Opened the same way as before (menu icon in [AppTopBar]), but
|
||||
/// built on [NooDrawer] instead of the old Material [Drawer] + ad hoc rows.
|
||||
///
|
||||
/// Tapping a "More" tab switches the shell straight to it (rather than
|
||||
/// pushing it as a standalone screen, like the pre-rework `MoreTabsButton`
|
||||
/// did) via `SettingsController.requestTab` - the same one-shot mechanism
|
||||
/// `SearchView`/`FavoritesView`/`ShareUploadView` already use to jump the
|
||||
/// shell to a tab from outside it, so `MainShellView` needs no extra
|
||||
/// plumbing to support it.
|
||||
class AppDrawer extends StatelessWidget {
|
||||
const AppDrawer({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final session = context.watch<SessionController>();
|
||||
final settings = context.watch<SettingsController>();
|
||||
final quota = context.watch<FilesController>().quota;
|
||||
// Cheap and already loaded when the Trash tab has been visited this
|
||||
// session - not worth a fetch just to populate a drawer badge.
|
||||
final trashCount = context.watch<TrashController>().items.length;
|
||||
final hiddenTabs = settings.tabOrder
|
||||
.where((t) => settings.hiddenTabs.contains(t))
|
||||
.toList();
|
||||
|
||||
void closeAndOpenSettings() {
|
||||
Navigator.pop(context);
|
||||
openSettings(context);
|
||||
}
|
||||
|
||||
return NooDrawer(
|
||||
account: NooDrawerAccount(
|
||||
avatar: NooAvatar(
|
||||
initials: accountInitial(session.username),
|
||||
current: true,
|
||||
size: 48,
|
||||
),
|
||||
name: session.username,
|
||||
subtitle: serverHost(session.serverUrl),
|
||||
onTap: closeAndOpenSettings,
|
||||
onSwitchAccount: () => showAccountSwitcher(context),
|
||||
),
|
||||
storage: NooDrawerStorage(
|
||||
value: quotaFraction(quota),
|
||||
label: quotaUsedLabel(quota),
|
||||
),
|
||||
moreItems: [
|
||||
for (final tab in hiddenTabs)
|
||||
NooDrawerItem(
|
||||
icon: tab.icon,
|
||||
label: tab.label,
|
||||
count: tab == AppTab.trash && trashCount > 0
|
||||
? '$trashCount'
|
||||
: null,
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
settings.requestTab(tab);
|
||||
},
|
||||
),
|
||||
],
|
||||
settings: NooDrawerItem(
|
||||
icon: LucideIcons.settings,
|
||||
label: 'Settings',
|
||||
onTap: closeAndOpenSettings,
|
||||
),
|
||||
footer: NooDrawerLink(onTap: closeAndOpenSettings),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user