app_layout.dart 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_riverpod/flutter_riverpod.dart';
  3. import 'package:veloe_kemono_party_flutter/models/nav_item.dart';
  4. class AppLayout extends ConsumerStatefulWidget {
  5. final List<NavItem> navItems;
  6. const AppLayout({super.key, required this.navItems});
  7. @override
  8. ConsumerState<AppLayout> createState() => _AppLayoutState();
  9. }
  10. class _AppLayoutState extends ConsumerState<AppLayout> {
  11. final _navIndex = StateProvider<int>((ref) => 0);
  12. Widget _buildDesktopNavRail(int selectedIndex) {
  13. return NavigationRail(
  14. selectedIndex: selectedIndex,
  15. onDestinationSelected: (index) =>
  16. ref.read(_navIndex.notifier).state = index,
  17. labelType: NavigationRailLabelType.all,
  18. destinations: widget.navItems.map((item) =>
  19. NavigationRailDestination(
  20. icon: Icon(item.icon),
  21. label: Text(item.label),
  22. )).toList(),
  23. );
  24. }
  25. Widget _buildMobileDrawer(int selectedIndex) {
  26. return Drawer(
  27. child: ListView(
  28. children: [
  29. const DrawerHeader(
  30. decoration: BoxDecoration(color: Colors.blue),
  31. child: Text('Navigation', style: TextStyle(color: Colors.white)),
  32. ),
  33. ...widget.navItems.asMap().entries.map((entry) => ListTile(
  34. leading: Icon(entry.value.icon),
  35. title: Text(entry.value.label),
  36. selected: entry.key == selectedIndex,
  37. onTap: () {
  38. ref.read(_navIndex.notifier).state = entry.key;
  39. Navigator.pop(context);
  40. },
  41. )),
  42. ],
  43. ),
  44. );
  45. }
  46. @override
  47. Widget build(BuildContext context) {
  48. final selectedIndex = ref.watch(_navIndex);
  49. final isDesktop = MediaQuery.of(context).size.width >= 600;
  50. return Scaffold(
  51. appBar: AppBar(
  52. title: Text(widget.navItems[selectedIndex].label),
  53. leading: isDesktop ? null : Builder(
  54. builder: (context) => IconButton(
  55. icon: const Icon(Icons.menu),
  56. onPressed: () => Scaffold.of(context).openDrawer(),
  57. ),
  58. ),
  59. ),
  60. drawer: isDesktop ? null : _buildMobileDrawer(selectedIndex),
  61. body: Row(
  62. children: [
  63. if (isDesktop) _buildDesktopNavRail(selectedIndex),
  64. Expanded(child: widget.navItems[selectedIndex].page),
  65. ],
  66. ),
  67. );
  68. }
  69. }