// desktop_shell.dart — 桌面外壳(左侧栏 + 顶栏 + 内容区) // // 对照 ui_kits/desktop/dapp.jsx:920×600 窗口、204 侧栏(6 项)、52 顶栏、内容区。 import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../pangolin_theme.dart'; import '../screens/account_page.dart'; import '../screens/connect_page.dart'; import '../screens/contact_page.dart'; import '../screens/invite_page.dart'; import '../screens/nodes_page.dart'; import '../screens/notifications_page.dart'; import '../screens/orders_page.dart'; import '../screens/payment_page.dart'; import '../screens/purchase_page.dart'; import '../screens/settings_page.dart'; import '../screens/stats_page.dart'; import '../state/app_providers.dart'; import '../state/navigation_provider.dart'; import '../widgets/account_screens.dart'; import '../widgets/content_top_bar.dart'; import '../widgets/nav_sidebar.dart'; import '../widgets/pangolin_icons.dart'; class DesktopShell extends ConsumerWidget { const DesktopShell({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final c = context.pangolin; final t = ref.watch(appTextProvider); final view = ref.watch(navViewProvider); // 「我的」移到侧栏顶部品牌按钮(见 NavSidebar);联系放设置下面。 final items = [ (icon: PangolinIcons.power, label: t.tabConnect, view: NavView.connect), (icon: PangolinIcons.globe, label: t.tabServers, view: NavView.servers), (icon: PangolinIcons.chartNoAxesColumn, label: t.tabStats, view: NavView.stats), (icon: PangolinIcons.user, label: t.tabMe, view: NavView.account), (icon: PangolinIcons.settings, label: t.settingsTitle, view: NavView.settings), (icon: PangolinIcons.messageCircle, label: t.contactTitle, view: NavView.contact), ]; final titles = { NavView.connect: t.tabConnect, NavView.servers: t.tabServers, NavView.stats: t.tabStats, NavView.account: t.tabMe, NavView.contact: t.contactTitle, NavView.settings: t.settingsTitle, NavView.redeem: t.redeemTitle, NavView.devices: t.myDevices, NavView.purchase: t.purchaseTitle, NavView.payment: t.paymentTitle, NavView.orders: t.ordersTitle, NavView.invite: t.inviteTitle, NavView.notifications: t.notifTitle, }; void go(NavView v) => ref.read(navViewProvider.notifier).state = v; Widget content() { switch (view) { case NavView.connect: return ConnectPage(isWide: true, onOpenNodes: () => go(NavView.servers)); case NavView.servers: return NodesPage(isWide: true, onPicked: () => go(NavView.connect)); case NavView.stats: return const StatsPage(isWide: true); case NavView.account: return const AccountPage(isWide: true); case NavView.contact: return const ContactPage(); case NavView.settings: return const SettingsPage(); // 账户下钻子页(内容区,顶栏带返回) case NavView.redeem: return RedeemScreen(t: t, embedded: true); case NavView.devices: return DevicesScreen(t: t, embedded: true); case NavView.purchase: return PurchaseScreen(t: t, embedded: true, onOrderCreated: () => go(NavView.payment)); case NavView.payment: return PaymentScreen(t: t, embedded: true, onDone: () => go(NavView.account)); case NavView.orders: return OrdersScreen(t: t, embedded: true); case NavView.invite: return InviteScreen(t: t, embedded: true); case NavView.notifications: return NotificationsScreen(t: t, embedded: true); } } // 子页返回目标:payment → purchase(换方式/失败重试仍在购买语境内); // 其余下钻子页(含 purchase 本身)→ account。 VoidCallback? backTarget() { if (view == NavView.payment) return () => go(NavView.purchase); if (view == NavView.notifications) return () => go(NavView.account); if (kAccountSubViews.contains(view)) return () => go(NavView.account); return null; } return ColoredBox( color: c.bg, child: Row(children: [ NavSidebar(items: items), Expanded( child: Column(children: [ ContentTopBar( title: titles[view] ?? t.brand, onBack: backTarget(), onBell: () => go(NavView.notifications), ), Expanded(child: content()), ]), ), ]), ); } }