Grain flutter app

feat: Refactor remaining icon usage to utilize AppIcons class across multiple screens and update icon references

+22 -13
+5 -1
lib/app_icons.dart
··· 3 4 class AppIcons { 5 // Material Icons 6 static const IconData person = Icons.person; 7 static const IconData accountCircle = Icons.account_circle; 8 static const IconData close = Icons.close; ··· 15 static const IconData notifications = Icons.notifications; 16 static const IconData search = Icons.search; 17 static const IconData settings = Icons.settings; 18 // FontAwesome Icons 19 static const IconData house = FontAwesomeIcons.house; 20 static const IconData magnifyingGlass = FontAwesomeIcons.magnifyingGlass; ··· 29 static const IconData arrowUpFromBracket = FontAwesomeIcons.arrowUpFromBracket; 30 static const IconData bars = FontAwesomeIcons.bars; 31 static const IconData arrowRightFromBracket = FontAwesomeIcons.arrowRightFromBracket; 32 - static const IconData checkCircle = FontAwesomeIcons.checkCircle; 33 }
··· 3 4 class AppIcons { 5 // Material Icons 6 + static const IconData edit = Icons.edit; 7 + static const IconData sort = Icons.sort; 8 static const IconData person = Icons.person; 9 static const IconData accountCircle = Icons.account_circle; 10 static const IconData close = Icons.close; ··· 17 static const IconData notifications = Icons.notifications; 18 static const IconData search = Icons.search; 19 static const IconData settings = Icons.settings; 20 + static const IconData photoLibrary = Icons.photo_library; 21 + static const IconData moreVertical = Icons.more_vert; 22 // FontAwesome Icons 23 static const IconData house = FontAwesomeIcons.house; 24 static const IconData magnifyingGlass = FontAwesomeIcons.magnifyingGlass; ··· 33 static const IconData arrowUpFromBracket = FontAwesomeIcons.arrowUpFromBracket; 34 static const IconData bars = FontAwesomeIcons.bars; 35 static const IconData arrowRightFromBracket = FontAwesomeIcons.arrowRightFromBracket; 36 + static const IconData checkCircle = FontAwesomeIcons.circleCheck; 37 }
+2 -1
lib/screens/explore_page.dart
··· 2 3 import 'package:flutter/material.dart'; 4 import 'package:grain/api.dart'; 5 import 'package:grain/models/profile.dart'; 6 import 'package:grain/widgets/app_image.dart'; 7 import 'package:grain/widgets/plain_text_field.dart'; ··· 130 : CircleAvatar( 131 radius: 16, 132 backgroundColor: theme.colorScheme.surfaceContainerHighest, 133 - child: Icon(Icons.account_circle, color: theme.iconTheme.color), 134 ), 135 title: Text( 136 profile.displayName?.isNotEmpty == true ? profile.displayName! : '@${profile.handle}',
··· 2 3 import 'package:flutter/material.dart'; 4 import 'package:grain/api.dart'; 5 + import 'package:grain/app_icons.dart'; 6 import 'package:grain/models/profile.dart'; 7 import 'package:grain/widgets/app_image.dart'; 8 import 'package:grain/widgets/plain_text_field.dart'; ··· 131 : CircleAvatar( 132 radius: 16, 133 backgroundColor: theme.colorScheme.surfaceContainerHighest, 134 + child: Icon(AppIcons.accountCircle, color: theme.iconTheme.color), 135 ), 136 title: Text( 137 profile.displayName?.isNotEmpty == true ? profile.displayName! : '@${profile.handle}',
+5 -4
lib/screens/gallery_action_sheet.dart
··· 1 import 'package:flutter/material.dart'; 2 3 class GalleryActionSheet extends StatelessWidget { 4 final VoidCallback? onEditDetails; ··· 23 mainAxisSize: MainAxisSize.min, 24 children: [ 25 ListTile( 26 - leading: const Icon(Icons.edit), 27 title: const Text('Edit details'), 28 onTap: () { 29 Navigator.of(context).pop(); ··· 31 }, 32 ), 33 ListTile( 34 - leading: const Icon(Icons.photo_library), 35 title: const Text('Edit photos'), 36 onTap: () { 37 Navigator.of(context).pop(); ··· 39 }, 40 ), 41 ListTile( 42 - leading: const Icon(Icons.sort), 43 title: const Text('Edit sort order'), 44 onTap: () { 45 Navigator.of(context).pop(); ··· 47 }, 48 ), 49 ListTile( 50 - leading: const Icon(Icons.delete, color: Colors.red), 51 title: const Text('Delete gallery', style: TextStyle(color: Colors.red)), 52 onTap: () async { 53 Navigator.of(context).pop();
··· 1 import 'package:flutter/material.dart'; 2 + import 'package:grain/app_icons.dart'; 3 4 class GalleryActionSheet extends StatelessWidget { 5 final VoidCallback? onEditDetails; ··· 24 mainAxisSize: MainAxisSize.min, 25 children: [ 26 ListTile( 27 + leading: Icon(AppIcons.edit), 28 title: const Text('Edit details'), 29 onTap: () { 30 Navigator.of(context).pop(); ··· 32 }, 33 ), 34 ListTile( 35 + leading: Icon(AppIcons.photoLibrary), 36 title: const Text('Edit photos'), 37 onTap: () { 38 Navigator.of(context).pop(); ··· 40 }, 41 ), 42 ListTile( 43 + leading: Icon(AppIcons.sort), 44 title: const Text('Edit sort order'), 45 onTap: () { 46 Navigator.of(context).pop(); ··· 48 }, 49 ), 50 ListTile( 51 + leading: Icon(AppIcons.delete, color: Colors.red), 52 title: const Text('Delete gallery', style: TextStyle(color: Colors.red)), 53 onTap: () async { 54 Navigator.of(context).pop();
+3 -2
lib/screens/gallery_edit_photos_sheet.dart
··· 3 import 'package:flutter/services.dart'; 4 import 'package:flutter_riverpod/flutter_riverpod.dart'; 5 import 'package:grain/api.dart'; 6 import 'package:grain/models/gallery_photo.dart'; 7 import 'package:grain/providers/gallery_cache_provider.dart'; 8 import 'package:grain/widgets/app_button.dart'; ··· 101 clipBehavior: Clip.antiAlias, 102 child: photo.thumb != null && photo.thumb!.isNotEmpty 103 ? AppImage(url: photo.thumb!, fit: BoxFit.cover) 104 - : const Icon(Icons.photo, size: 48), 105 ), 106 Positioned( 107 top: 8, ··· 162 valueColor: AlwaysStoppedAnimation<Color>(Colors.white), 163 ), 164 ) 165 - : const Icon(Icons.close, color: Colors.white, size: 20), 166 ), 167 ), 168 ),
··· 3 import 'package:flutter/services.dart'; 4 import 'package:flutter_riverpod/flutter_riverpod.dart'; 5 import 'package:grain/api.dart'; 6 + import 'package:grain/app_icons.dart'; 7 import 'package:grain/models/gallery_photo.dart'; 8 import 'package:grain/providers/gallery_cache_provider.dart'; 9 import 'package:grain/widgets/app_button.dart'; ··· 102 clipBehavior: Clip.antiAlias, 103 child: photo.thumb != null && photo.thumb!.isNotEmpty 104 ? AppImage(url: photo.thumb!, fit: BoxFit.cover) 105 + : const Icon(AppIcons.photo, size: 48), 106 ), 107 Positioned( 108 top: 8, ··· 163 valueColor: AlwaysStoppedAnimation<Color>(Colors.white), 164 ), 165 ) 166 + : const Icon(AppIcons.close, color: Colors.white, size: 20), 167 ), 168 ), 169 ),
+3 -2
lib/screens/gallery_page.dart
··· 1 import 'package:flutter/material.dart'; 2 import 'package:flutter_riverpod/flutter_riverpod.dart'; 3 import 'package:grain/api.dart'; 4 import 'package:grain/models/gallery_photo.dart'; 5 import 'package:grain/providers/gallery_cache_provider.dart'; 6 import 'package:grain/providers/profile_provider.dart'; ··· 119 actions: [ 120 if (gallery.creator?.did == widget.currentUserDid) 121 IconButton( 122 - icon: const Icon(Icons.more_vert), 123 tooltip: 'Gallery Actions', 124 onPressed: () async { 125 showModalBottomSheet( ··· 225 (gallery.creator == null || 226 (gallery.creator!.avatar?.isNotEmpty != true)) 227 ? Icon( 228 - Icons.account_circle, 229 size: 24, 230 color: theme.colorScheme.onSurface.withOpacity(0.4), 231 )
··· 1 import 'package:flutter/material.dart'; 2 import 'package:flutter_riverpod/flutter_riverpod.dart'; 3 import 'package:grain/api.dart'; 4 + import 'package:grain/app_icons.dart'; 5 import 'package:grain/models/gallery_photo.dart'; 6 import 'package:grain/providers/gallery_cache_provider.dart'; 7 import 'package:grain/providers/profile_provider.dart'; ··· 120 actions: [ 121 if (gallery.creator?.did == widget.currentUserDid) 122 IconButton( 123 + icon: const Icon(AppIcons.moreVertical), 124 tooltip: 'Gallery Actions', 125 onPressed: () async { 126 showModalBottomSheet( ··· 226 (gallery.creator == null || 227 (gallery.creator!.avatar?.isNotEmpty != true)) 228 ? Icon( 229 + AppIcons.accountCircle, 230 size: 24, 231 color: theme.colorScheme.onSurface.withOpacity(0.4), 232 )