mobile: add backed up only toggle for delete device only

This commit is contained in:
shalong-tanwen 2023-10-21 03:13:24 +05:30
parent 3d7c13b30f
commit 5219f55b6a
5 changed files with 112 additions and 36 deletions

View file

@ -144,6 +144,7 @@
"date_format": "E, LLL d, y • h:mm a",
"delete_dialog_alert": "These items will be permanently deleted from Immich and from your device",
"delete_dialog_alert_local": "These items will be permanently removed from your device",
"delete_dialog_alert_merged_only": "Delete only backed up assets",
"delete_dialog_cancel": "Cancel",
"delete_dialog_ok": "Delete",
"delete_dialog_title": "Delete Permanently",

View file

@ -16,7 +16,7 @@ class ControlBottomAppBar extends ConsumerWidget {
final void Function() onFavorite;
final void Function() onArchive;
final void Function() onDelete;
final void Function() onDeleteLocal;
final void Function(bool onlyMerged) onDeleteLocal;
final Function(Album album) onAddToAlbum;
final void Function() onCreateNewAlbum;
final void Function() onUpload;
@ -47,7 +47,8 @@ class ControlBottomAppBar extends ConsumerWidget {
var isDarkMode = Theme.of(context).brightness == Brightness.dark;
var hasRemote = selectionAssetState == AssetState.remote ||
selectionAssetState == AssetState.merged;
var hasMerged = selectionAssetState == AssetState.merged;
var hasLocal = selectionAssetState == AssetState.merged ||
selectionAssetState == AssetState.local;
final trashEnabled =
ref.watch(serverInfoProvider.select((v) => v.serverFeatures.trash));
@ -72,27 +73,28 @@ class ControlBottomAppBar extends ConsumerWidget {
label: "control_bottom_app_bar_favorite".tr(),
onPressed: enabled ? onFavorite : null,
),
ControlBoxButton(
iconData: Icons.delete_outline_rounded,
label: "control_bottom_app_bar_delete".tr(),
onPressed: enabled
? () {
if (!trashEnabled) {
showDialog(
context: context,
builder: (BuildContext context) {
return DeleteDialog(
onDelete: onDelete,
);
},
);
} else {
onDelete();
if (hasRemote)
ControlBoxButton(
iconData: Icons.delete_outline_rounded,
label: "control_bottom_app_bar_delete".tr(),
onPressed: enabled
? () {
if (!trashEnabled) {
showDialog(
context: context,
builder: (BuildContext context) {
return DeleteDialog(
onDelete: onDelete,
);
},
);
} else {
onDelete();
}
}
}
: null,
),
if (hasMerged)
: null,
),
if (hasLocal)
ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 100),
child: ControlBoxButton(
@ -103,8 +105,7 @@ class ControlBottomAppBar extends ConsumerWidget {
showDialog(
context: context,
builder: (BuildContext context) {
return DeleteDialog(
content: 'delete_dialog_alert_local',
return DeleteLocalDialog(
onDelete: onDeleteLocal,
);
},
@ -161,7 +162,7 @@ class ControlBottomAppBar extends ConsumerWidget {
const CustomDraggingHandle(),
const SizedBox(height: 12),
SizedBox(
height: hasMerged ? 90 : 75,
height: hasLocal ? 90 : 75,
child: ListView(
scrollDirection: Axis.horizontal,
children: renderActionButtons(),

View file

@ -1,16 +1,86 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/shared/ui/confirm_dialog.dart';
class DeleteDialog extends ConfirmDialog {
final Function onDelete;
const DeleteDialog({Key? key, required this.onDelete, String? content})
const DeleteDialog({Key? key, required this.onDelete})
: super(
key: key,
title: "delete_dialog_title",
content: content ?? "delete_dialog_alert",
content: "delete_dialog_alert",
cancel: "delete_dialog_cancel",
ok: "delete_dialog_ok",
onOk: onDelete,
);
}
class DeleteLocalDialog extends HookConsumerWidget {
final Function(bool onlyMerged) onDelete;
const DeleteLocalDialog({
Key? key,
required this.onDelete,
}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final themeData = Theme.of(context);
final onlyMerged = useState(true);
return AlertDialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
title: const Text("delete_dialog_title").tr(),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Text("delete_dialog_alert_local").tr(),
Padding(
padding: const EdgeInsets.only(top: 20),
child: SwitchListTile.adaptive(
value: onlyMerged.value,
onChanged: (value) {
onlyMerged.value = value;
},
activeColor: themeData.primaryColor,
dense: true,
title: Text(
"delete_dialog_alert_merged_only",
style: themeData.textTheme.labelLarge
?.copyWith(fontWeight: FontWeight.bold),
).tr(),
),
),
],
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(false),
child: Text(
"delete_dialog_cancel",
style: TextStyle(
color: Theme.of(context).primaryColor,
fontWeight: FontWeight.bold,
),
).tr(),
),
TextButton(
onPressed: () {
onDelete(onlyMerged.value);
Navigator.of(context).pop(true);
},
child: Text(
"delete_dialog_ok",
style: TextStyle(
color: Colors.red[400],
fontWeight: FontWeight.bold,
),
).tr(),
),
],
);
}
}

View file

@ -163,22 +163,20 @@ class HomePage extends HookConsumerWidget {
}
}
void onDeleteLocal() async {
void onDeleteLocal(bool onlyMerged) async {
processing.value = true;
try {
final mergedIds = selection.value
.where((a) => a.storage == AssetState.merged)
.toList();
final localIds = selection.value.where((a) => a.isLocal).toList();
final isDeleted = await ref
.read(assetProvider.notifier)
.deleteLocalAssets(mergedIds);
.deleteLocalAssets(localIds, onlyMerged: onlyMerged);
if (isDeleted) {
final assetOrAssets = mergedIds.length > 1 ? 'assets' : 'asset';
final assetOrAssets = localIds.length > 1 ? 'assets' : 'asset';
ImmichToast.show(
context: context,
msg:
'${mergedIds.length} $assetOrAssets removed permanently from your device',
'${localIds.length} $assetOrAssets removed permanently from your device',
gravity: ToastGravity.BOTTOM,
);
}

View file

@ -91,11 +91,17 @@ class AssetNotifier extends StateNotifier<bool> {
await _syncService.syncNewAssetToDb(newAsset);
}
Future<bool> deleteLocalAssets(Iterable<Asset> deleteAssets) async {
Future<bool> deleteLocalAssets(
Iterable<Asset> deleteAssets, {
bool onlyMerged = true,
}) async {
_deleteInProgress = true;
state = true;
try {
final localDeleted = await _deleteLocalAssets(deleteAssets);
final assets = onlyMerged
? deleteAssets.where((e) => e.storage == AssetState.merged)
: deleteAssets;
final localDeleted = await _deleteLocalAssets(assets);
if (localDeleted.isNotEmpty) {
final localOnlyIds = deleteAssets
.where((e) => e.storage == AssetState.local)