Favourites
This commit is contained in:
parent
6a84a9bef0
commit
1747ab0245
23 changed files with 469 additions and 67 deletions
|
@ -1,10 +1,14 @@
|
|||
import 'dart:async';
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:mc_gallery/features/core/data/extensions/string_extensions.dart';
|
||||
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';
|
||||
import '/features/core/data/extensions/map_extensions.dart';
|
||||
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 '/locator.dart';
|
||||
|
@ -19,16 +23,19 @@ import '../data/models/image_model.dart';
|
|||
class ImagesService {
|
||||
ImagesService({
|
||||
required ImagesApi imagesApi,
|
||||
required LocalStorageService localStorageService,
|
||||
required LoggingService loggingService,
|
||||
}) : _imagesApi = imagesApi,
|
||||
_localStorageService = localStorageService,
|
||||
_loggingService = loggingService {
|
||||
_init();
|
||||
}
|
||||
|
||||
final ImagesApi _imagesApi;
|
||||
final LocalStorageService _localStorageService;
|
||||
final LoggingService _loggingService;
|
||||
|
||||
late final Map<String, ImageModel> _imageModels;
|
||||
late final LinkedHashMap<String, ImageModel> _imageModels;
|
||||
Iterable<ImageModel> get imageModels => _imageModels.values.deepCopy;
|
||||
|
||||
final Mutex _searchMutex = Mutex();
|
||||
|
@ -41,11 +48,37 @@ class ImagesService {
|
|||
|
||||
Future<void> _init() async {
|
||||
_loggingService.info('Fetching and creating image models...');
|
||||
_imageModels = {
|
||||
for (final imageModel in (await _imagesApi.fetchImageUri(token: ''))
|
||||
.map((final emulatedModelSerialized) => ImageModel.fromJson(emulatedModelSerialized)))
|
||||
imageModel.imageName: imageModel
|
||||
};
|
||||
|
||||
final fetchedImageModelDtos = await _imagesApi.fetchImageUri(token: '');
|
||||
final favouritesStatuses = _localStorageService.storedFavouritesStates;
|
||||
|
||||
// Prefill from stored values
|
||||
if (favouritesStatuses.isNotEmpty) {
|
||||
_loggingService.good('Found favourites statuses on device -> Prefilling');
|
||||
assert(fetchedImageModelDtos.length == favouritesStatuses.length);
|
||||
_imageModels = LinkedHashMap.of({
|
||||
for (final pair in IterableZip([fetchedImageModelDtos, favouritesStatuses]))
|
||||
(pair[0] as ImageModelDTO).imageName: ImageModel.fromDto(
|
||||
imageModelDto: pair[0] as ImageModelDTO,
|
||||
isFavourite: pair[1] as bool,
|
||||
)
|
||||
});
|
||||
|
||||
// Set to false and create the stored values
|
||||
} else {
|
||||
_loggingService.good('NO favourites statuses found -> creating new');
|
||||
_imageModels = LinkedHashMap.of({
|
||||
for (final fetchedImageModelDto in fetchedImageModelDtos)
|
||||
fetchedImageModelDto.imageName: ImageModel.fromDto(
|
||||
imageModelDto: fetchedImageModelDto,
|
||||
isFavourite: false,
|
||||
)
|
||||
});
|
||||
|
||||
_localStorageService.initNewFavourites(
|
||||
newValues: _imageModels.values.map((final imageModel) => imageModel.isFavourite),
|
||||
);
|
||||
}
|
||||
|
||||
_imageModels.isNotEmpty
|
||||
? _loggingService.good("Created ${_imageModels.length} images' models")
|
||||
|
@ -89,14 +122,20 @@ class ImagesService {
|
|||
..sort((final a, final b) =>
|
||||
ConstSorters.stringsSimilarityTarget(targetWord: imageNamePart, a, b))
|
||||
..reversed;
|
||||
|
||||
return _imageModels.valuesByKeys(keys: rankedKeys).toList(growable: false);
|
||||
|
||||
case SearchOption.web:
|
||||
return (await _imagesApi.searchImages(
|
||||
searchStr: imageNamePart,
|
||||
token: '',
|
||||
))
|
||||
.map(
|
||||
(final emulatedModelSerialized) => ImageModel.fromJson(emulatedModelSerialized))
|
||||
(final imageModelDto) => ImageModel.fromDto(
|
||||
imageModelDto: imageModelDto,
|
||||
isFavourite: false,
|
||||
),
|
||||
)
|
||||
.toList(growable: false);
|
||||
}
|
||||
} finally {
|
||||
|
@ -105,5 +144,19 @@ class ImagesService {
|
|||
});
|
||||
}
|
||||
|
||||
void updateImageFavouriteStatus({
|
||||
required ImageModel imageModel,
|
||||
required bool newFavouriteStatus,
|
||||
}) {
|
||||
_imageModels.updateValueAt(
|
||||
valueIndex: imageModel.imageIndex,
|
||||
newValue: imageModel.copyWith(isFavourite: newFavouriteStatus),
|
||||
);
|
||||
|
||||
//todo(mehul): Consider adding an update listener to _imageModels, sync with _localStorageService
|
||||
_localStorageService.updateFavourite(
|
||||
index: imageModel.imageIndex, newValue: newFavouriteStatus);
|
||||
}
|
||||
|
||||
static ImagesService get locate => Locator.locate();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue