diff --git a/lib/features/core/abstracts/router/app_router.dart b/lib/features/core/abstracts/router/app_router.dart index bcf84a7..35244a5 100644 --- a/lib/features/core/abstracts/router/app_router.dart +++ b/lib/features/core/abstracts/router/app_router.dart @@ -15,7 +15,7 @@ class McgRouter { key: state.pageKey, child: ErrorPageView(error: state.error), ), - //todo(mehul): Add Redirect + // TODO Add Redirect routes: [ GoRoute( path: Routes.home.routePath, diff --git a/lib/features/home/api/unsplash_images_api.dart b/lib/features/home/api/unsplash_images_api.dart index 5196ab2..5cde25c 100644 --- a/lib/features/home/api/unsplash_images_api.dart +++ b/lib/features/home/api/unsplash_images_api.dart @@ -1,37 +1,29 @@ import 'dart:async'; import 'dart:math'; -import 'package:mc_gallery/features/core/services/logging_service.dart'; -import 'package:mc_gallery/locator.dart'; - import '/features/core/data/constants/const_values.dart'; import '/l10n/generated/l10n.dart'; import '../abstracts/images_api.dart'; import '../data/models/image_model.dart'; -class UnsplashImagesApi with LoggingService implements ImagesApi { +class UnsplashImagesApi implements ImagesApi { @override FutureOr> fetchImageUri({required String token}) { final random = Random(); - try { - return Iterable.generate(ConstValues.numberOfImages).map((final imageIndex) { - // Drawing from a normal distribution - final imageSide = ConstValues.minImageSize + - random.nextInt((ConstValues.maxImageSize + 1) - ConstValues.minImageSize); + return Iterable.generate(ConstValues.numberOfImages).map((final imageIndex) { + // Drawing from a normal distribution + final imageSide = ConstValues.minImageSize + + random.nextInt((ConstValues.maxImageSize + 1) - ConstValues.minImageSize); - final imageUri = _imageUrlGenerator(imageSide: imageSide); + final imageUri = _imageUrlGenerator(imageSide: imageSide); - return ImageModel( - imageIndex: imageIndex, - uri: imageUri, - imageName: Strings.current.image, - ); - }); - } on Exception catch (ex, stackTrace) { - handleException(ex, stackTrace); - return const Iterable.empty(); - } + return ImageModel( + imageIndex: imageIndex, + uri: imageUri, + imageName: Strings.current.image, + ); + }); } Uri _imageUrlGenerator({required int imageSide}) => Uri( @@ -39,6 +31,4 @@ class UnsplashImagesApi with LoggingService implements ImagesApi { host: ConstValues.backendHost, pathSegments: [...ConstValues.backendUrlPathSegments, '${imageSide}x$imageSide'], ); - - static UnsplashImagesApi get locate => Locator.locate(); } diff --git a/lib/features/home/services/image_cache_manager_service.dart b/lib/features/home/services/image_cache_manager_service.dart deleted file mode 100644 index c0282e4..0000000 --- a/lib/features/home/services/image_cache_manager_service.dart +++ /dev/null @@ -1,37 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter_cache_manager/flutter_cache_manager.dart'; -import 'package:mc_gallery/features/core/services/app_lifecycle_service.dart'; -import 'package:mc_gallery/features/core/services/logging_service.dart'; -import 'package:mc_gallery/locator.dart'; - -class ImageCacheManagerService with LoggingService { - ImageCacheManagerService({ - required AppLifecycleService appLifecycleService, - }) : _appLifecycleService = appLifecycleService { - _init(); - } - - final AppLifecycleService _appLifecycleService; - - Future emptyCache() async => await DefaultCacheManager().emptyCache(); - - Future _init() async { - _appLifecycleService.addListener( - tag: runtimeType.toString(), - listener: (final appLifecycleState) async { - switch (appLifecycleState) { - case AppLifecycleState.resumed: - break; - case AppLifecycleState.inactive: - case AppLifecycleState.paused: - case AppLifecycleState.detached: - info('Discarding cached images'); - await DefaultCacheManager().emptyCache(); - } - }, - ); - } - - static ImageCacheManagerService get locate => Locator.locate(); -} diff --git a/lib/features/home/services/images_service.dart b/lib/features/home/services/images_service.dart index 0a138f9..0086262 100644 --- a/lib/features/home/services/images_service.dart +++ b/lib/features/home/services/images_service.dart @@ -1,4 +1,3 @@ -import 'package:mc_gallery/features/core/services/logging_service.dart'; import 'package:mc_gallery/features/home/data/models/image_model.dart'; import 'package:mc_gallery/locator.dart'; @@ -9,28 +8,18 @@ import '../abstracts/images_api.dart'; /// Since this is very simple use-case, this is the only interface. For complex (actual CRUD-based) I/O, /// an additional Repository layer interface can be used between [ImagesService] and [ImagesApi]. class ImagesService { - ImagesService({ - required ImagesApi imagesApi, - required LoggingService loggingService, - }) : _imagesApi = imagesApi, - _loggingService = loggingService { + ImagesService({required ImagesApi imagesApi}) : _imagesApi = imagesApi { _init(); } final ImagesApi _imagesApi; - final LoggingService _loggingService; late final Iterable _imageModels; Iterable get imageModels => _imageModels; Future _init() async { - _loggingService.info('Fetching and creating image models...'); _imageModels = await _imagesApi.fetchImageUri(token: ''); - _imageModels.isNotEmpty - ? _loggingService.good("Created ${_imageModels.length} images' models") - : _loggingService.warning('No images found'); - Locator.instance().signalReady(this); } diff --git a/lib/features/home/views/gallery/gallery_view_model.dart b/lib/features/home/views/gallery/gallery_view_model.dart index c78240e..fcacf41 100644 --- a/lib/features/home/views/gallery/gallery_view_model.dart +++ b/lib/features/home/views/gallery/gallery_view_model.dart @@ -1,7 +1,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart'; -import 'package:mc_gallery/features/home/services/image_cache_manager_service.dart'; +import 'package:mc_gallery/features/core/services/app_lifecycle_service.dart'; import '/features/core/abstracts/base_view_model.dart'; import '/features/core/services/logging_service.dart'; @@ -15,16 +15,16 @@ class GalleryViewModel extends BaseViewModel { GalleryViewModel({ required ImagesService imagesService, required NavigationService navigationService, - required ImageCacheManagerService imageCacheManagerService, + required AppLifecycleService appLifecycleService, required LoggingService loggingService, }) : _imagesService = imagesService, _navigationService = navigationService, - _imageCacheManagerService = imageCacheManagerService, + _appLifecycleService = appLifecycleService, _loggingService = loggingService; final ImagesService _imagesService; final NavigationService _navigationService; - final ImageCacheManagerService _imageCacheManagerService; + final AppLifecycleService _appLifecycleService; final LoggingService _loggingService; final ValueNotifier _isDisplayingPressingPrompt = ValueNotifier(true); @@ -32,11 +32,27 @@ class GalleryViewModel extends BaseViewModel { @override Future initialise(bool Function() mounted, [arguments]) async { + _appLifecycleService.addListener( + tag: runtimeType.toString(), + listener: (final appLifecycleState) async { + switch (appLifecycleState) { + case AppLifecycleState.resumed: + break; + case AppLifecycleState.inactive: + case AppLifecycleState.paused: + case AppLifecycleState.detached: + await DefaultCacheManager().emptyCache(); + } + }, + ); + super.initialise(mounted, arguments); } @override Future dispose() async { + await _appLifecycleService.removeListener(tag: runtimeType.toString()); + super.dispose(); } diff --git a/lib/features/home/views/image_carousel/image_carousel_view_model.dart b/lib/features/home/views/image_carousel/image_carousel_view_model.dart index 4302ff9..76dc40f 100644 --- a/lib/features/home/views/image_carousel/image_carousel_view_model.dart +++ b/lib/features/home/views/image_carousel/image_carousel_view_model.dart @@ -1,5 +1,8 @@ +import 'dart:ui'; + import 'package:flutter/foundation.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart'; +import 'package:mc_gallery/features/core/services/app_lifecycle_service.dart'; import '/features/core/abstracts/base_view_model.dart'; import '/features/core/services/logging_service.dart'; @@ -13,13 +16,16 @@ class ImageCarouselViewModel extends BaseViewModel { ImageCarouselViewModel({ required ImagesService imagesService, required NavigationService navigationService, + required AppLifecycleService appLifecycleService, required LoggingService loggingService, }) : _imagesService = imagesService, _navigationService = navigationService, + _appLifecycleService = appLifecycleService, _loggingService = loggingService; final ImagesService _imagesService; final NavigationService _navigationService; + final AppLifecycleService _appLifecycleService; final LoggingService _loggingService; late final ValueNotifier _currentImageModel; @@ -27,6 +33,19 @@ class ImageCarouselViewModel extends BaseViewModel { @override Future initialise(bool Function() mounted, [arguments]) async { + _appLifecycleService.addListener( + tag: runtimeType.toString(), + listener: (final appLifecycleState) async { + switch (appLifecycleState) { + case AppLifecycleState.resumed: + break; + case AppLifecycleState.inactive: + case AppLifecycleState.paused: + case AppLifecycleState.detached: + await DefaultCacheManager().emptyCache(); + } + }); + _currentImageModel = ValueNotifier(_imagesService.imageModels .elementAt((arguments! as ImageCarouselViewArguments).imageIndexKey)); @@ -35,6 +54,8 @@ class ImageCarouselViewModel extends BaseViewModel { @override Future dispose() async { + await _appLifecycleService.removeListener(tag: runtimeType.toString()); + super.dispose(); } diff --git a/lib/locator.dart b/lib/locator.dart index cb1b0f1..61b4482 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -7,7 +7,6 @@ import 'package:mc_gallery/features/core/abstracts/router/app_router.dart'; import 'package:mc_gallery/features/core/services/logging_service.dart'; import 'package:mc_gallery/features/core/services/navigation_service.dart'; import 'package:mc_gallery/features/home/api/unsplash_images_api.dart'; -import 'package:mc_gallery/features/home/services/image_cache_manager_service.dart'; import 'package:mc_gallery/features/home/services/images_service.dart'; import 'package:mc_gallery/features/home/views/gallery/gallery_view_model.dart'; import 'package:mc_gallery/features/home/views/image_carousel/image_carousel_view_model.dart'; @@ -45,7 +44,7 @@ class Locator { () => GalleryViewModel( imagesService: ImagesService.locate, navigationService: NavigationService.locate, - imageCacheManagerService: ImageCacheManagerService.locate, + appLifecycleService: AppLifecycleService.locate, loggingService: LoggingService.locate, ), ); @@ -53,6 +52,7 @@ class Locator { () => ImageCarouselViewModel( imagesService: ImagesService.locate, navigationService: NavigationService.locate, + appLifecycleService: AppLifecycleService.locate, loggingService: LoggingService.locate, ), ); @@ -86,13 +86,10 @@ class Locator { dispose: (param) async => await param.dispose(), ); it.registerSingleton( - ImagesService(imagesApi: UnsplashImagesApi.locate, loggingService: LoggingService.locate), - signalsReady: true, - ); - it.registerSingleton( - ImageCacheManagerService( - appLifecycleService: AppLifecycleService.locate, + ImagesService( + imagesApi: UnsplashImagesApi(), ), + signalsReady: true, ); }