immich/mobile/lib/providers/cleanup.provider.dart
Alex 1d6a9f6e80
feat: free up space (#24999)
* feat(server): Support camera `make`, `model`, and `lensModel` in Storage Template (#24650)

* add support for make, model, lensModel in storage template

* no pkg lock

* Apply suggestion from @danieldietzler

Co-authored-by: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com>

* query and formatting

---------

Co-authored-by: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com>

* wip: copy-writing

* feat: cutoff date preset options and filter options

* fix: don't include iCloud Shared Album

* chore: message about excluding shared album assets

* feat: show preview in a separate page

* feat: show clean up hint modal after success deletion

* pr feedback

* pr feedback

* pr feedback

---------

Co-authored-by: Rahul Kumar Saini <rahul-kumar-saini@users.noreply.github.com>
Co-authored-by: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com>
2026-01-07 20:55:28 -06:00

107 lines
3.0 KiB
Dart

import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/constants/enums.dart';
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
import 'package:immich_mobile/providers/user.provider.dart';
import 'package:immich_mobile/services/cleanup.service.dart';
class CleanupState {
final DateTime? selectedDate;
final List<LocalAsset> assetsToDelete;
final bool isScanning;
final bool isDeleting;
final AssetFilterType filterType;
final bool keepFavorites;
const CleanupState({
this.selectedDate,
this.assetsToDelete = const [],
this.isScanning = false,
this.isDeleting = false,
this.filterType = AssetFilterType.all,
this.keepFavorites = true,
});
CleanupState copyWith({
DateTime? selectedDate,
List<LocalAsset>? assetsToDelete,
bool? isScanning,
bool? isDeleting,
AssetFilterType? filterType,
bool? keepFavorites,
}) {
return CleanupState(
selectedDate: selectedDate ?? this.selectedDate,
assetsToDelete: assetsToDelete ?? this.assetsToDelete,
isScanning: isScanning ?? this.isScanning,
isDeleting: isDeleting ?? this.isDeleting,
filterType: filterType ?? this.filterType,
keepFavorites: keepFavorites ?? this.keepFavorites,
);
}
}
final cleanupProvider = StateNotifierProvider<CleanupNotifier, CleanupState>((ref) {
return CleanupNotifier(ref.watch(cleanupServiceProvider), ref.watch(currentUserProvider)?.id);
});
class CleanupNotifier extends StateNotifier<CleanupState> {
final CleanupService _cleanupService;
final String? _userId;
CleanupNotifier(this._cleanupService, this._userId) : super(const CleanupState());
void setSelectedDate(DateTime? date) {
state = state.copyWith(selectedDate: date, assetsToDelete: []);
}
void setFilterType(AssetFilterType filterType) {
state = state.copyWith(filterType: filterType, assetsToDelete: []);
}
void setKeepFavorites(bool keepFavorites) {
state = state.copyWith(keepFavorites: keepFavorites, assetsToDelete: []);
}
Future<void> scanAssets() async {
if (_userId == null || state.selectedDate == null) {
return;
}
state = state.copyWith(isScanning: true);
try {
final assets = await _cleanupService.getRemovalCandidates(
_userId,
state.selectedDate!,
filterType: state.filterType,
keepFavorites: state.keepFavorites,
);
state = state.copyWith(assetsToDelete: assets, isScanning: false);
} catch (e) {
state = state.copyWith(isScanning: false);
rethrow;
}
}
Future<int> deleteAssets() async {
if (state.assetsToDelete.isEmpty) {
return 0;
}
state = state.copyWith(isDeleting: true);
try {
final deletedCount = await _cleanupService.deleteLocalAssets(state.assetsToDelete.map((a) => a.id).toList());
state = state.copyWith(assetsToDelete: [], isDeleting: false);
return deletedCount;
} catch (e) {
state = state.copyWith(isDeleting: false);
rethrow;
}
}
void reset() {
state = const CleanupState();
}
}