// tablet_shell.dart — 平板外壳(侧栏 4 项触控 + 内容区),对照 ui_kits/tablet/tabapp.jsx // // 与 desktop 区别:侧栏 232 触控尺寸、4 项(无联系/设置)、顶栏无主题切换; // 连接页自动走双栏(connect_page 在 formFactor==tablet 时进 isWide 分支)。 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/content_top_bar.dart'; import '../widgets/nav_sidebar.dart'; import '../widgets/pangolin_icons.dart'; class TabletShell extends ConsumerWidget { const TabletShell({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.barChart, label: t.tabStats, view: NavView.stats), (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.settings: t.settingsTitle, NavView.contact: t.contactTitle, }; 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.settings: return const SettingsPage(); case NavView.contact: return const ContactPage(); default: // account / plans / redeem / devices → 账户(其余下钻在账户页内) return const AccountPage(isWide: true); } } return ColoredBox( color: c.bg, // iPad 上内容会顶到状态栏(时间/电量/notch)。SafeArea 加顶部安全区,避开重叠; // 底部留给页面自行处理(home indicator)。 child: SafeArea( bottom: false, child: Row(children: [ NavSidebar(items: items, width: 232, dense: false), Expanded( child: Column(children: [ ContentTopBar(title: titles[view] ?? t.tabMe, showThemeToggle: false, titleSize: 19), Expanded(child: content()), ]), ), ]), ), ); } }