refactoring
This commit is contained in:
		
							parent
							
								
									68d7f70ded
								
							
						
					
					
						commit
						895a34d9f3
					
				
					 13 changed files with 75 additions and 48 deletions
				
			
		|  | @ -4,6 +4,7 @@ import 'package:flutter/material.dart'; | |||
| abstract class ConstColours { | ||||
|   /// Smoke Gray => a neutral grey with neutral warmth/cold | ||||
|   static const galleryBackgroundColour = Color.fromRGBO(127, 127, 125, 1.0); | ||||
|   static const red = Colors.red; | ||||
| 
 | ||||
|   static const white = Colors.white; | ||||
|   static const black = Colors.black; | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ abstract class ConstValues { | |||
|   static const String backendHost = 'source.unsplash.com'; | ||||
|   static const List<String> backendUrlPathSegments = ['user', 'c_v_r']; | ||||
| 
 | ||||
|   static const int numberOfImages = 20; | ||||
|   static const int numberOfImages = 25; | ||||
|   static const int minImageSize = 50; | ||||
|   static const int maxImageSize = 100; | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,6 +7,7 @@ import '../data/dtos/image_model_dto.dart'; | |||
| /// Since I used a site that was more obscure than the ones in the examples, this (otherwise pointless | ||||
| /// and convoluting) interface is for adding a bit of flexibility to change strategy to some other site. | ||||
| abstract class ImagesApi { | ||||
|   /// Returns images fetched through an API as [ImageModelDTO]s. | ||||
|   FutureOr<Iterable<ImageModelDTO>> fetchImageUri({required String token}); | ||||
| 
 | ||||
|   FutureOr<Iterable<ImageModelDTO>> searchImages({ | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| import '/l10n/generated/l10n.dart'; | ||||
| 
 | ||||
| /// Represents an option for specifying a search strategy, for an [ImageModel] | ||||
| enum SearchOption { | ||||
|   local, | ||||
|   web; | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| import '../dtos/image_model_dto.dart'; | ||||
| 
 | ||||
| /// Represents an Image, that would be displayed in the gallery. | ||||
| class ImageModel { | ||||
|   const ImageModel({ | ||||
|     required this.uri, | ||||
|  |  | |||
|  | @ -2,7 +2,6 @@ import 'dart:async'; | |||
| import 'dart:collection'; | ||||
| 
 | ||||
| import 'package:collection/collection.dart'; | ||||
| import 'package:mc_gallery/features/home/data/dtos/image_model_dto.dart'; | ||||
| 
 | ||||
| import '/features/core/data/constants/const_sorters.dart'; | ||||
| import '/features/core/data/extensions/iterable_extensions.dart'; | ||||
|  | @ -11,6 +10,7 @@ import '/features/core/data/extensions/string_extensions.dart'; | |||
| import '/features/core/services/local_storage_service.dart'; | ||||
| import '/features/core/services/logging_service.dart'; | ||||
| import '/features/core/utils/mutex.dart'; | ||||
| import '/features/home/data/dtos/image_model_dto.dart'; | ||||
| import '/locator.dart'; | ||||
| import '../abstracts/images_api.dart'; | ||||
| import '../data/enums/search_option.dart'; | ||||
|  |  | |||
|  | @ -18,12 +18,7 @@ class _DownloadedGalleryView extends StatelessWidget { | |||
|         child: ValueListenableBuilder<bool>( | ||||
|           valueListenable: galleryViewModel.isViewingFavouriteListenable, | ||||
|           builder: (context, final isViewingFavourites, _) => !isViewingFavourites | ||||
|               ? Wrap( | ||||
|                   runSpacing: 24, | ||||
|                   spacing: 8, | ||||
|                   alignment: WrapAlignment.center, | ||||
|                   runAlignment: WrapAlignment.center, | ||||
|                   crossAxisAlignment: WrapCrossAlignment.center, | ||||
|               ? CustomWrap( | ||||
|                   children: [ | ||||
|                     for (final imageModel in galleryViewModel.imageModels) | ||||
|                       _StarrableImage( | ||||
|  | @ -33,12 +28,7 @@ class _DownloadedGalleryView extends StatelessWidget { | |||
|                       ), | ||||
|                   ], | ||||
|                 ) | ||||
|               : Wrap( | ||||
|                   runSpacing: 24, | ||||
|                   spacing: 8, | ||||
|                   alignment: WrapAlignment.center, | ||||
|                   runAlignment: WrapAlignment.center, | ||||
|                   crossAxisAlignment: WrapCrossAlignment.center, | ||||
|               : CustomWrap( | ||||
|                   children: [ | ||||
|                     for (final favouriteImageModel in galleryViewModel.favouriteImageModels) | ||||
|                       _StarrableImage( | ||||
|  |  | |||
|  | @ -1,13 +1,14 @@ | |||
| import 'package:cached_network_image/cached_network_image.dart'; | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:mc_gallery/features/core/data/constants/const_media.dart'; | ||||
| 
 | ||||
| import '/features/core/data/constants/const_colors.dart'; | ||||
| import '/features/core/data/constants/const_durations.dart'; | ||||
| import '/features/core/data/constants/const_media.dart'; | ||||
| import '/features/core/widgets/gap.dart'; | ||||
| import '/features/core/widgets/mcg_scaffold.dart'; | ||||
| import '/features/core/widgets/state/multi_value_listenable_builder.dart'; | ||||
| import '/features/core/widgets/state/view_model_builder.dart'; | ||||
| import '/features/home/widgets/custom_wrap.dart'; | ||||
| import '../../data/enums/search_option.dart'; | ||||
| import '../../data/models/image_model.dart'; | ||||
| import 'gallery_view_model.dart'; | ||||
|  | @ -81,21 +82,38 @@ class GalleryView extends StatelessWidget { | |||
|                                 valueListenable: model.isSearchingListenable, | ||||
|                                 builder: (context, final isSearching, _) => AnimatedSwitcher( | ||||
|                                   duration: ConstDurations.oneAndHalfDefaultAnimationDuration, | ||||
|                                   child: Column( | ||||
|                                     children: [ | ||||
|                                       ValueListenableBuilder<bool>( | ||||
|                                         valueListenable: model.isViewingFavouriteListenable, | ||||
|                                         builder: (context, final isViewingFavourites, child) => | ||||
|                                             Switch( | ||||
|                                           value: isViewingFavourites, | ||||
|                                           onChanged: model.onFavouriteViewChange, | ||||
|                                         ), | ||||
|                                       ), | ||||
|                                       !isSearching | ||||
|                                           ? _DownloadedGalleryView(galleryViewModel: model) | ||||
|                                           : _SearchGalleryView(galleryViewModel: model), | ||||
|                                     ], | ||||
|                                   ), | ||||
|                                   child: !isSearching | ||||
|                                       ? Column( | ||||
|                                           mainAxisAlignment: MainAxisAlignment.spaceEvenly, | ||||
|                                           children: [ | ||||
|                                             ValueListenableBuilder<bool>( | ||||
|                                               valueListenable: model.isViewingFavouriteListenable, | ||||
|                                               builder: | ||||
|                                                   (context, final isViewingFavourites, child) => | ||||
|                                                       Row( | ||||
|                                                 mainAxisAlignment: MainAxisAlignment.center, | ||||
|                                                 children: [ | ||||
|                                                   ConstMedia.buildIcon( | ||||
|                                                     ConstMedia.favStarOutline, | ||||
|                                                     width: 24, | ||||
|                                                     height: 24, | ||||
|                                                   ), | ||||
|                                                   Switch( | ||||
|                                                     value: isViewingFavourites, | ||||
|                                                     onChanged: model.onFavouriteViewChange, | ||||
|                                                   ), | ||||
|                                                   ConstMedia.buildIcon( | ||||
|                                                     ConstMedia.favStarFilled, | ||||
|                                                     width: 24, | ||||
|                                                     height: 24, | ||||
|                                                   ), | ||||
|                                                 ], | ||||
|                                               ), | ||||
|                                             ), | ||||
|                                             _DownloadedGalleryView(galleryViewModel: model), | ||||
|                                           ], | ||||
|                                         ) | ||||
|                                       : _SearchGalleryView(galleryViewModel: model), | ||||
|                                 ), | ||||
|                               ); | ||||
|                           } | ||||
|  |  | |||
|  | @ -3,9 +3,9 @@ import 'dart:async'; | |||
| import 'package:flutter/foundation.dart'; | ||||
| import 'package:flutter/widgets.dart'; | ||||
| import 'package:flutter_cache_manager/flutter_cache_manager.dart'; | ||||
| import 'package:mc_gallery/features/core/data/extensions/value_notifier_extensions.dart'; | ||||
| 
 | ||||
| import '/features/core/abstracts/base_view_model.dart'; | ||||
| import '/features/core/data/extensions/value_notifier_extensions.dart'; | ||||
| import '/features/core/services/logging_service.dart'; | ||||
| import '/features/core/services/navigation_service.dart'; | ||||
| import '/locator.dart'; | ||||
|  |  | |||
|  | @ -29,12 +29,7 @@ class _SearchGalleryView extends StatelessWidget { | |||
|                 builder: (context, final searchOption, child) { | ||||
|                   switch (searchOption) { | ||||
|                     case SearchOption.local: | ||||
|                       return Wrap( | ||||
|                         runSpacing: 24, | ||||
|                         spacing: 8, | ||||
|                         alignment: WrapAlignment.center, | ||||
|                         runAlignment: WrapAlignment.center, | ||||
|                         crossAxisAlignment: WrapCrossAlignment.center, | ||||
|                       return CustomWrap( | ||||
|                         children: [ | ||||
|                           for (final resultsImageModel in resultsImageModels) | ||||
|                             CachedNetworkImage( | ||||
|  | @ -48,12 +43,7 @@ class _SearchGalleryView extends StatelessWidget { | |||
|                         ], | ||||
|                       ); | ||||
|                     case SearchOption.web: | ||||
|                       return Wrap( | ||||
|                         runSpacing: 24, | ||||
|                         spacing: 8, | ||||
|                         alignment: WrapAlignment.center, | ||||
|                         runAlignment: WrapAlignment.center, | ||||
|                         crossAxisAlignment: WrapCrossAlignment.center, | ||||
|                       return CustomWrap( | ||||
|                         children: [ | ||||
|                           for (final imageResult in resultsImageModels) | ||||
|                             Image.network( | ||||
|  |  | |||
|  | @ -3,7 +3,6 @@ import 'package:flutter_cache_manager/flutter_cache_manager.dart'; | |||
| 
 | ||||
| import '/features/core/abstracts/base_view_model.dart'; | ||||
| import '/features/core/services/logging_service.dart'; | ||||
| import '/features/core/services/navigation_service.dart'; | ||||
| import '/features/home/services/images_service.dart'; | ||||
| import '/features/home/views/image_carousel/image_carousel_view.dart'; | ||||
| import '/locator.dart'; | ||||
|  | @ -12,14 +11,11 @@ import '../../data/models/image_model.dart'; | |||
| class ImageCarouselViewModel extends BaseViewModel { | ||||
|   ImageCarouselViewModel({ | ||||
|     required ImagesService imagesService, | ||||
|     required NavigationService navigationService, | ||||
|     required LoggingService loggingService, | ||||
|   })  : _imagesService = imagesService, | ||||
|         _navigationService = navigationService, | ||||
|         _loggingService = loggingService; | ||||
| 
 | ||||
|   final ImagesService _imagesService; | ||||
|   final NavigationService _navigationService; | ||||
|   final LoggingService _loggingService; | ||||
| 
 | ||||
|   late final ValueNotifier<ImageModel> _currentImageModelNotifier; | ||||
|  |  | |||
							
								
								
									
										30
									
								
								lib/features/home/widgets/custom_wrap.dart
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								lib/features/home/widgets/custom_wrap.dart
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,30 @@ | |||
| import 'package:flutter/material.dart'; | ||||
| 
 | ||||
| import '/features/core/data/constants/const_colors.dart'; | ||||
| 
 | ||||
| class CustomWrap extends StatelessWidget { | ||||
|   const CustomWrap({ | ||||
|     required this.children, | ||||
|     super.key, | ||||
|   }); | ||||
| 
 | ||||
|   final List<Widget> children; | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return children.isNotEmpty | ||||
|         ? Wrap( | ||||
|             runSpacing: 24, | ||||
|             spacing: 8, | ||||
|             alignment: WrapAlignment.center, | ||||
|             runAlignment: WrapAlignment.center, | ||||
|             crossAxisAlignment: WrapCrossAlignment.center, | ||||
|             children: children, | ||||
|           ) | ||||
|         : const Icon( | ||||
|             Icons.not_interested_sharp, | ||||
|             size: 80, | ||||
|             color: ConstColours.red, | ||||
|           ); | ||||
|   } | ||||
| } | ||||
|  | @ -53,7 +53,6 @@ class Locator { | |||
|     instance().registerFactory( | ||||
|       () => ImageCarouselViewModel( | ||||
|         imagesService: ImagesService.locate, | ||||
|         navigationService: NavigationService.locate, | ||||
|         loggingService: LoggingService.locate, | ||||
|       ), | ||||
|     ); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue