// 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/nodes_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); final items = [ (icon: PangolinIcons.power, label: t.tabConnect, view: NavView.connect), (icon: PangolinIcons.globe, label: t.tabServers, view: NavView.servers), (icon: PangolinIcons.barChart, label: t.tabStats, view: NavView.stats), (icon: PangolinIcons.user, label: t.tabMe, view: NavView.account), (icon: PangolinIcons.messageCircle, label: t.contactTitle, view: NavView.contact), (icon: PangolinIcons.settings, label: t.settingsTitle, view: NavView.settings), ]; 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.plans: t.choosePlan, NavView.redeem: t.redeemTitle, NavView.devices: t.myDevices, }; 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.plans: return PlansScreen(t: t, embedded: true, onChoose: (_) => go(NavView.redeem)); case NavView.redeem: return RedeemScreen(t: t, embedded: true); case NavView.devices: return DevicesScreen(t: t, embedded: true); } } final isSub = kAccountSubViews.contains(view); return ColoredBox( color: c.bg, child: Row(children: [ NavSidebar(items: items), Expanded( child: Column(children: [ ContentTopBar( title: titles[view] ?? t.brand, onBack: isSub ? () => go(NavView.account) : null, ), Expanded(child: content()), ]), ), ]), ); } }