mirror of
https://github.com/immich-app/immich.git
synced 2025-01-04 02:46:47 +01:00
Add asset response cache
This commit is contained in:
parent
d43a08eb71
commit
1156290377
4 changed files with 100 additions and 2 deletions
|
@ -25,3 +25,7 @@ const String backgroundBackupInfoBox = "immichBackgroundBackupInfoBox"; // Box
|
||||||
const String backupFailedSince = "immichBackupFailedSince"; // Key 1
|
const String backupFailedSince = "immichBackupFailedSince"; // Key 1
|
||||||
const String backupRequireWifi = "immichBackupRequireWifi"; // Key 2
|
const String backupRequireWifi = "immichBackupRequireWifi"; // Key 2
|
||||||
const String backupRequireCharging = "immichBackupRequireCharging"; // Key 3
|
const String backupRequireCharging = "immichBackupRequireCharging"; // Key 3
|
||||||
|
|
||||||
|
// Asset cache
|
||||||
|
const String assetListCacheBox = "assetListCacheBox";
|
||||||
|
const String assetListCachedAssets = "assetListCachedAssets";
|
||||||
|
|
|
@ -37,6 +37,7 @@ void main() async {
|
||||||
await Hive.openBox<HiveBackupAlbums>(hiveBackupInfoBox);
|
await Hive.openBox<HiveBackupAlbums>(hiveBackupInfoBox);
|
||||||
await Hive.openBox(hiveGithubReleaseInfoBox);
|
await Hive.openBox(hiveGithubReleaseInfoBox);
|
||||||
await Hive.openBox(userSettingInfoBox);
|
await Hive.openBox(userSettingInfoBox);
|
||||||
|
await Hive.openBox(assetListCacheBox);
|
||||||
|
|
||||||
SystemChrome.setSystemUIOverlayStyle(
|
SystemChrome.setSystemUIOverlayStyle(
|
||||||
const SystemUiOverlayStyle(
|
const SystemUiOverlayStyle(
|
||||||
|
|
84
mobile/lib/modules/home/services/asset_cache.service.dart
Normal file
84
mobile/lib/modules/home/services/asset_cache.service.dart
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:hive_flutter/hive_flutter.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:immich_mobile/constants/hive_box.dart';
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void putAssets(List<AssetResponseDto> assets) {
|
||||||
|
_rawPut(assets.map((e) => _serialize(e)).toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
List<AssetResponseDto> getAssets() {
|
||||||
|
return _rawGet().map((e) => _deserialize(e)).whereNotNull().toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/modules/home/services/asset.service.dart';
|
import 'package:immich_mobile/modules/home/services/asset.service.dart';
|
||||||
|
import 'package:immich_mobile/modules/home/services/asset_cache.service.dart';
|
||||||
import 'package:immich_mobile/shared/services/device_info.service.dart';
|
import 'package:immich_mobile/shared/services/device_info.service.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
@ -9,15 +10,22 @@ import 'package:photo_manager/photo_manager.dart';
|
||||||
|
|
||||||
class AssetNotifier extends StateNotifier<List<AssetResponseDto>> {
|
class AssetNotifier extends StateNotifier<List<AssetResponseDto>> {
|
||||||
final AssetService _assetService;
|
final AssetService _assetService;
|
||||||
|
final AssetCacheService _assetCacheService;
|
||||||
|
|
||||||
final DeviceInfoService _deviceInfoService = DeviceInfoService();
|
final DeviceInfoService _deviceInfoService = DeviceInfoService();
|
||||||
|
|
||||||
AssetNotifier(this._assetService) : super([]);
|
AssetNotifier(this._assetService, this._assetCacheService) : super([]);
|
||||||
|
|
||||||
getAllAsset() async {
|
getAllAsset() async {
|
||||||
|
if (_assetCacheService.isValid() && state.isEmpty) {
|
||||||
|
state = await _assetCacheService.getAssetsAsync();
|
||||||
|
}
|
||||||
|
|
||||||
var allAssets = await _assetService.getAllAsset();
|
var allAssets = await _assetService.getAllAsset();
|
||||||
|
|
||||||
if (allAssets != null) {
|
if (allAssets != null) {
|
||||||
state = allAssets;
|
state = allAssets;
|
||||||
|
_assetCacheService.putAssets(allAssets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +78,8 @@ class AssetNotifier extends StateNotifier<List<AssetResponseDto>> {
|
||||||
|
|
||||||
final assetProvider =
|
final assetProvider =
|
||||||
StateNotifierProvider<AssetNotifier, List<AssetResponseDto>>((ref) {
|
StateNotifierProvider<AssetNotifier, List<AssetResponseDto>>((ref) {
|
||||||
return AssetNotifier(ref.watch(assetServiceProvider));
|
return AssetNotifier(
|
||||||
|
ref.watch(assetServiceProvider), ref.watch(assetCacheServiceProvider));
|
||||||
});
|
});
|
||||||
|
|
||||||
final assetGroupByDateTimeProvider = StateProvider((ref) {
|
final assetGroupByDateTimeProvider = StateProvider((ref) {
|
||||||
|
|
Loading…
Reference in a new issue