this repo has no description
at main 198 lines 7.0 kB view raw
1import 'package:flutter/material.dart'; 2import 'package:grain/api.dart'; 3import 'package:grain/app_icons.dart'; 4import 'package:grain/screens/log_page.dart'; 5import 'package:grain/widgets/app_version_text.dart'; 6 7class AppDrawer extends StatelessWidget { 8 final ThemeData theme; 9 final String? avatarUrl; 10 final int activeIndex; // 0: Home, 1: Explore, 2: Notifications, 3: Profile 11 final VoidCallback onHome; 12 final VoidCallback onExplore; 13 final VoidCallback onNotifications; 14 final VoidCallback onProfile; 15 16 const AppDrawer({ 17 super.key, 18 required this.theme, 19 required this.avatarUrl, 20 required this.activeIndex, 21 required this.onHome, 22 required this.onExplore, 23 required this.onNotifications, 24 required this.onProfile, 25 }); 26 27 @override 28 Widget build(BuildContext context) { 29 return Drawer( 30 child: ListView( 31 padding: EdgeInsets.zero, 32 children: [ 33 Container( 34 height: 250, 35 decoration: BoxDecoration( 36 color: theme.colorScheme.surface, 37 border: Border(bottom: BorderSide(color: theme.dividerColor, width: 1)), 38 ), 39 padding: const EdgeInsets.fromLTRB(16, 115, 16, 16), 40 child: Column( 41 crossAxisAlignment: CrossAxisAlignment.start, 42 mainAxisAlignment: MainAxisAlignment.center, 43 children: [ 44 CircleAvatar( 45 radius: 22, 46 backgroundColor: theme.scaffoldBackgroundColor, 47 backgroundImage: (avatarUrl?.isNotEmpty ?? false) 48 ? NetworkImage(avatarUrl!) 49 : null, 50 child: (avatarUrl?.isEmpty ?? true) 51 ? Icon(AppIcons.person, size: 44, color: theme.hintColor) 52 : null, 53 ), 54 const SizedBox(height: 6), 55 Text( 56 apiService.currentUser?.displayName ?? '', 57 style: theme.textTheme.bodyLarge?.copyWith( 58 fontWeight: FontWeight.bold, 59 color: theme.colorScheme.onSurface, 60 ), 61 ), 62 if (apiService.currentUser?.handle != null) 63 Text( 64 '@${apiService.currentUser!.handle}', 65 style: theme.textTheme.bodySmall?.copyWith(color: theme.hintColor), 66 ), 67 const SizedBox(height: 6), 68 Row( 69 mainAxisAlignment: MainAxisAlignment.start, 70 children: [ 71 Text( 72 (apiService.currentUser?.followersCount ?? 0).toString(), 73 style: theme.textTheme.bodyMedium?.copyWith( 74 fontWeight: FontWeight.bold, 75 color: theme.colorScheme.onSurface, 76 ), 77 ), 78 const SizedBox(width: 4), 79 Text( 80 'Followers', 81 style: theme.textTheme.bodySmall?.copyWith(color: theme.hintColor), 82 ), 83 const SizedBox(width: 16), 84 Text( 85 (apiService.currentUser?.followsCount ?? 0).toString(), 86 style: theme.textTheme.bodyMedium?.copyWith( 87 fontWeight: FontWeight.bold, 88 color: theme.colorScheme.onSurface, 89 ), 90 ), 91 const SizedBox(width: 4), 92 Text( 93 'Following', 94 style: theme.textTheme.bodySmall?.copyWith(color: theme.hintColor), 95 ), 96 ], 97 ), 98 ], 99 ), 100 ), 101 ListTile( 102 leading: Icon( 103 AppIcons.house, 104 size: 18, 105 color: activeIndex == 0 ? theme.colorScheme.primary : theme.iconTheme.color, 106 ), 107 title: Text( 108 'Home', 109 style: TextStyle( 110 color: activeIndex == 0 111 ? theme.colorScheme.primary 112 : theme.textTheme.bodyLarge?.color, 113 fontWeight: activeIndex == 0 ? FontWeight.bold : FontWeight.normal, 114 ), 115 ), 116 onTap: () { 117 Navigator.pop(context); 118 onHome(); 119 }, 120 ), 121 ListTile( 122 leading: Icon( 123 AppIcons.magnifyingGlass, 124 size: 18, 125 color: activeIndex == 1 ? theme.colorScheme.primary : theme.iconTheme.color, 126 ), 127 title: Text( 128 'Explore', 129 style: TextStyle( 130 color: activeIndex == 1 131 ? theme.colorScheme.primary 132 : theme.textTheme.bodyLarge?.color, 133 fontWeight: activeIndex == 1 ? FontWeight.bold : FontWeight.normal, 134 ), 135 ), 136 onTap: () { 137 Navigator.pop(context); 138 onExplore(); 139 }, 140 ), 141 ListTile( 142 leading: Icon( 143 AppIcons.solidBell, 144 size: 18, 145 color: activeIndex == 2 ? theme.colorScheme.primary : theme.iconTheme.color, 146 ), 147 title: Text( 148 'Notifications', 149 style: TextStyle( 150 color: activeIndex == 2 151 ? theme.colorScheme.primary 152 : theme.textTheme.bodyLarge?.color, 153 fontWeight: activeIndex == 2 ? FontWeight.bold : FontWeight.normal, 154 ), 155 ), 156 onTap: () { 157 Navigator.pop(context); 158 onNotifications(); 159 }, 160 ), 161 ListTile( 162 leading: Icon( 163 AppIcons.user, 164 size: 18, 165 color: activeIndex == 3 ? theme.colorScheme.primary : theme.iconTheme.color, 166 ), 167 title: Text( 168 'Profile', 169 style: TextStyle( 170 color: activeIndex == 3 171 ? theme.colorScheme.primary 172 : theme.textTheme.bodyLarge?.color, 173 fontWeight: activeIndex == 3 ? FontWeight.bold : FontWeight.normal, 174 ), 175 ), 176 onTap: () { 177 Navigator.pop(context); 178 onProfile(); 179 }, 180 ), 181 ListTile( 182 leading: const Icon(AppIcons.list, size: 18), 183 title: const Text('Logs'), 184 onTap: () { 185 Navigator.pop(context); 186 Navigator.of(context).push(MaterialPageRoute(builder: (context) => const LogPage())); 187 }, 188 ), 189 const SizedBox(height: 16), 190 Padding( 191 padding: const EdgeInsets.only(bottom: 16.0), 192 child: Center(child: AppVersionText()), 193 ), 194 ], 195 ), 196 ); 197 } 198}