fix(mobile): show a partial success message when local copies are kept

This commit is contained in:
Santo Shakil
2026-07-24 00:48:42 +06:00
parent 65c17b14b8
commit 4cf0d88f35
4 changed files with 14 additions and 9 deletions
+1
View File
@@ -1459,6 +1459,7 @@
"move_to": "Move to",
"move_to_device_trash": "Move to device trash",
"move_to_lock_folder_action_prompt": "{count} added to the locked folder",
"move_to_lock_folder_partial_prompt": "{count} added to the locked folder, {kept} local copies were kept",
"move_to_locked_folder": "Move to locked folder",
"move_to_locked_folder_confirmation": "These photos and video will be removed from all albums, and only viewable from the locked folder",
"move_to_locked_folder_local_ios": "These items will be deleted from Photos, but will still be available on the Immich server. They will be in Recently Deleted for 30 days.",
@@ -27,10 +27,12 @@ Future<void> performMoveToLockFolderAction(BuildContext context, WidgetRef ref,
ref.read(multiSelectProvider.notifier).reset();
final successMessage = 'move_to_lock_folder_action_prompt'.t(
context: context,
args: {'count': result.count.toString()},
);
final successMessage = result.failedCount > 0
? 'move_to_lock_folder_partial_prompt'.t(
context: context,
args: {'count': result.count.toString(), 'kept': result.failedCount.toString()},
)
: 'move_to_lock_folder_action_prompt'.t(context: context, args: {'count': result.count.toString()});
if (context.mounted) {
ImmichToast.show(
@@ -201,7 +201,7 @@ class ActionNotifier extends Notifier<void> {
try {
final deletedCount = await _service.moveToLockFolder(ids, localIds);
return ActionResult(count: ids.length, success: deletedCount == localIds.length);
return ActionResult(count: ids.length, success: true, failedCount: localIds.length - deletedCount);
} catch (error, stack) {
_logger.severe('Failed to move assets to lock folder', error, stack);
return ActionResult(count: ids.length, success: false, error: error.toString());
@@ -138,18 +138,19 @@ void main() {
return result;
}
testWidgets('reports failure when local deletion is cancelled', (tester) async {
testWidgets('keeps success and reports kept local copies when the OS delete is declined', (tester) async {
final asset = _asset.copyWith(localId: 'local-owned');
container.read(multiSelectProvider.notifier).selectAsset(asset);
when(() => actionService.moveToLockFolder(any(), any())).thenAnswer((_) async => 0);
final result = await runAction(tester);
expect(result?.success, isFalse);
expect(result?.success, isTrue);
expect(result?.failedCount, 1);
verify(() => actionService.moveToLockFolder(['asset-1'], ['local-owned'])).called(1);
});
testWidgets('reports failure when only some local copies are deleted', (tester) async {
testWidgets('reports kept local copies when only some are deleted', (tester) async {
final first = _asset.copyWith(localId: 'local-1');
final second = _asset.copyWith(id: 'asset-2', localId: 'local-2', checksum: 'checksum-2');
container.read(multiSelectProvider.notifier)
@@ -159,7 +160,8 @@ void main() {
final result = await runAction(tester);
expect(result?.success, isFalse);
expect(result?.success, isTrue);
expect(result?.failedCount, 1);
});
testWidgets('deletes only owned local copies from a mixed selection', (tester) async {