mirror of
https://github.com/immich-app/immich
synced 2025-11-07 17:27:20 +00:00
refactor(mobile): reworked Asset, store all required fields from local & remote (#1539)
replace usage of AssetResponseDto with Asset Add new class ExifInfo to store data from ExifResponseDto
This commit is contained in:
parent
7bd2455175
commit
0048662182
28 changed files with 626 additions and 504 deletions
|
|
@ -4,8 +4,8 @@ import 'package:flutter/foundation.dart';
|
|||
import 'package:hive/hive.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/constants/hive_box.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/asset.service.dart';
|
||||
import 'package:immich_mobile/shared/services/asset_cache.service.dart';
|
||||
import 'package:immich_mobile/modules/home/ui/asset_grid/asset_grid_data_structure.dart';
|
||||
import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart';
|
||||
import 'package:immich_mobile/modules/settings/services/app_settings.service.dart';
|
||||
|
|
@ -36,7 +36,7 @@ class AssetsState {
|
|||
return AssetsState([...allAssets, ...toAdd]);
|
||||
}
|
||||
|
||||
_groupByDate() async {
|
||||
Future<Map<String, List<Asset>>> _groupByDate() async {
|
||||
sortCompare(List<Asset> assets) {
|
||||
assets.sortByCompare<DateTime>(
|
||||
(e) => e.createdAt,
|
||||
|
|
@ -50,11 +50,11 @@ class AssetsState {
|
|||
return await compute(sortCompare, allAssets.toList());
|
||||
}
|
||||
|
||||
static fromAssetList(List<Asset> assets) {
|
||||
static AssetsState fromAssetList(List<Asset> assets) {
|
||||
return AssetsState(assets);
|
||||
}
|
||||
|
||||
static empty() {
|
||||
static AssetsState empty() {
|
||||
return AssetsState([]);
|
||||
}
|
||||
}
|
||||
|
|
@ -82,7 +82,10 @@ class AssetNotifier extends StateNotifier<AssetsState> {
|
|||
this._settingsService,
|
||||
) : super(AssetsState.fromAssetList([]));
|
||||
|
||||
_updateAssetsState(List<Asset> newAssetList, {bool cache = true}) async {
|
||||
Future<void> _updateAssetsState(
|
||||
List<Asset> newAssetList, {
|
||||
bool cache = true,
|
||||
}) async {
|
||||
if (cache) {
|
||||
_assetCacheService.put(newAssetList);
|
||||
}
|
||||
|
|
@ -101,20 +104,26 @@ class AssetNotifier extends StateNotifier<AssetsState> {
|
|||
final stopwatch = Stopwatch();
|
||||
try {
|
||||
_getAllAssetInProgress = true;
|
||||
final bool isCacheValid = await _assetCacheService.isValid();
|
||||
bool isCacheValid = await _assetCacheService.isValid();
|
||||
stopwatch.start();
|
||||
final Box box = Hive.box(userInfoBox);
|
||||
if (isCacheValid && state.allAssets.isEmpty) {
|
||||
final List<Asset>? cachedData = await _assetCacheService.get();
|
||||
if (cachedData == null) {
|
||||
isCacheValid = false;
|
||||
log.warning("Cached asset data is invalid, fetching new data");
|
||||
} else {
|
||||
await _updateAssetsState(cachedData, cache: false);
|
||||
log.info(
|
||||
"Reading assets ${state.allAssets.length} from cache: ${stopwatch.elapsedMilliseconds}ms",
|
||||
);
|
||||
}
|
||||
stopwatch.reset();
|
||||
}
|
||||
final localTask = _assetService.getLocalAssets(urgent: !isCacheValid);
|
||||
final remoteTask = _assetService.getRemoteAssets(
|
||||
etag: isCacheValid ? box.get(assetEtagKey) : null,
|
||||
);
|
||||
if (isCacheValid && state.allAssets.isEmpty) {
|
||||
await _updateAssetsState(await _assetCacheService.get(), cache: false);
|
||||
log.info(
|
||||
"Reading assets ${state.allAssets.length} from cache: ${stopwatch.elapsedMilliseconds}ms",
|
||||
);
|
||||
stopwatch.reset();
|
||||
}
|
||||
|
||||
int remoteBegin = state.allAssets.indexWhere((a) => a.isRemote);
|
||||
remoteBegin = remoteBegin == -1 ? state.allAssets.length : remoteBegin;
|
||||
|
|
@ -184,7 +193,7 @@ class AssetNotifier extends StateNotifier<AssetsState> {
|
|||
_updateAssetsState([]);
|
||||
}
|
||||
|
||||
onNewAssetUploaded(AssetResponseDto newAsset) {
|
||||
void onNewAssetUploaded(Asset newAsset) {
|
||||
final int i = state.allAssets.indexWhere(
|
||||
(a) =>
|
||||
a.isRemote ||
|
||||
|
|
@ -192,13 +201,13 @@ class AssetNotifier extends StateNotifier<AssetsState> {
|
|||
);
|
||||
|
||||
if (i == -1 || state.allAssets[i].deviceAssetId != newAsset.deviceAssetId) {
|
||||
_updateAssetsState([...state.allAssets, Asset.remote(newAsset)]);
|
||||
_updateAssetsState([...state.allAssets, newAsset]);
|
||||
} else {
|
||||
// order is important to keep all local-only assets at the beginning!
|
||||
_updateAssetsState([
|
||||
...state.allAssets.slice(0, i),
|
||||
...state.allAssets.slice(i + 1),
|
||||
Asset.remote(newAsset),
|
||||
newAsset,
|
||||
]);
|
||||
// TODO here is a place to unify local/remote assets by replacing the
|
||||
// local-only asset in the state with a local&remote asset
|
||||
|
|
@ -230,7 +239,7 @@ class AssetNotifier extends StateNotifier<AssetsState> {
|
|||
// Delete asset from device
|
||||
for (final Asset asset in assetsToDelete) {
|
||||
if (asset.isLocal) {
|
||||
local.add(asset.id);
|
||||
local.add(asset.localId!);
|
||||
} else if (asset.deviceId == deviceId) {
|
||||
// Delete asset on device if it is still present
|
||||
var localAsset = await AssetEntity.fromId(asset.deviceAssetId);
|
||||
|
|
@ -252,8 +261,7 @@ class AssetNotifier extends StateNotifier<AssetsState> {
|
|||
Future<Iterable<String>> _deleteRemoteAssets(
|
||||
Set<Asset> assetsToDelete,
|
||||
) async {
|
||||
final Iterable<AssetResponseDto> remote =
|
||||
assetsToDelete.where((e) => e.isRemote).map((e) => e.remote!);
|
||||
final Iterable<Asset> remote = assetsToDelete.where((e) => e.isRemote);
|
||||
final List<DeleteAssetResponseDto> deleteAssetResult =
|
||||
await _assetService.deleteAssets(remote) ?? [];
|
||||
return deleteAssetResult
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue