JSON based caching

This commit is contained in:
Matthias Rupp 2022-10-15 23:20:15 +02:00
parent 1156290377
commit 894eea739e
2 changed files with 33 additions and 59 deletions

View file

@ -1,4 +1,7 @@
import 'dart:convert';
import 'package:collection/collection.dart';
import 'package:flutter/foundation.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/constants/hive_box.dart';
@ -8,77 +11,40 @@ final assetCacheServiceProvider = Provider(
(ref) => AssetCacheService(),
);
typedef CacheEntry = Map<dynamic, dynamic>;
typedef CacheList = List<CacheEntry>;
class AssetCacheService {
final _cacheBox = Hive.box(assetListCacheBox);
bool isValid() {
return _cacheBox.containsKey(assetListCachedAssets) && _rawGet().isNotEmpty;
return _cacheBox.containsKey(assetListCachedAssets) &&
_cacheBox.get(assetListCachedAssets) is String;
}
void putAssets(List<AssetResponseDto> assets) {
_rawPut(assets.map((e) => _serialize(e)).toList());
final mapList = assets.map((e) => e.toJson()).toList();
final jsonString = json.encode(mapList);
_cacheBox.put(assetListCachedAssets, jsonString);
}
List<AssetResponseDto> getAssets() {
return _rawGet().map((e) => _deserialize(e)).whereNotNull().toList();
try {
final jsonString = _cacheBox.get(assetListCachedAssets);
final mapList = json.decode(jsonString) as List<dynamic>;
final responseData = mapList
.map((e) => AssetResponseDto.fromJson(e))
.whereNotNull()
.toList();
return responseData;
} catch (e) {
debugPrint(e.toString());
return [];
}
}
Future<List<AssetResponseDto>> getAssetsAsync() async {
return Future.microtask(() => getAssets());
}
List<dynamic> _rawGet() {
return _cacheBox.get(assetListCachedAssets) as List<dynamic>;
}
void _rawPut(CacheList data) {
_cacheBox.put(assetListCachedAssets, data);
}
CacheEntry _serialize(AssetResponseDto a) {
return {
"id": a.id,
"cat": a.createdAt,
"did": a.deviceAssetId,
"oid": a.ownerId,
"dev": a.deviceId,
"dur": a.duration,
"mat": a.modifiedAt,
"opa": a.originalPath,
"typ": a.type.value,
"exif": a.exifInfo?.toJson(),
"fav": a.isFavorite,
"evp": a.encodedVideoPath,
"mim": a.mimeType,
"rsp": a.resizePath,
"wbp": a.webpPath,
};
}
AssetResponseDto? _deserialize(CacheEntry map) {
try {
return AssetResponseDto(
type: AssetTypeEnum.values
.firstWhere((element) => element.value == map["typ"]),
id: map["id"],
deviceAssetId: map["did"],
ownerId: map["oid"],
deviceId: map["dev"],
originalPath: map["opa"],
resizePath: map["rsp"],
createdAt: map["cat"],
modifiedAt: map["mat"],
isFavorite: map["fav"],
mimeType: map["mim"],
duration: map["dur"],
webpPath: map["wbp"],
encodedVideoPath: map["evp"],
);
} catch (e) {
return null;
}
}
}

View file

@ -16,6 +16,10 @@ class AssetNotifier extends StateNotifier<List<AssetResponseDto>> {
AssetNotifier(this._assetService, this._assetCacheService) : super([]);
_cacheState() {
_assetCacheService.putAssets(state);
}
getAllAsset() async {
if (_assetCacheService.isValid() && state.isEmpty) {
state = await _assetCacheService.getAssetsAsync();
@ -25,16 +29,18 @@ class AssetNotifier extends StateNotifier<List<AssetResponseDto>> {
if (allAssets != null) {
state = allAssets;
_assetCacheService.putAssets(allAssets);
_cacheState();
}
}
clearAllAsset() {
state = [];
_cacheState();
}
onNewAssetUploaded(AssetResponseDto newAsset) {
state = [...state, newAsset];
_cacheState();
}
deleteAssets(Set<AssetResponseDto> deleteAssets) async {
@ -73,6 +79,8 @@ class AssetNotifier extends StateNotifier<List<AssetResponseDto>> {
state.where((immichAsset) => immichAsset.id != asset.id).toList();
}
}
_cacheState();
}
}