mirror of
https://github.com/immich-app/immich.git
synced 2024-12-25 10:43:13 +02:00
feat(mobile): long-press delete button to permanently delete asset (#6240)
* feat(mobile): delete assets from device only * mobile: add backed up only toggle for delete device only * remove toggle inside alert and show different content * mobile: change content color for local only * mobile: delete local only button to dialog * style: display bottom action in two lines * feat: separate delete buttons * fix: incorrect error message for ownedRemoteSelection * feat(mobile): long-press delete to permanently delete asset * chore: add todo to handle long press to delete in gallery_viewer * chore: rebase on deletion branch * feat(mobile): long-press delete to permanently delete asset * fix(mobile): update minChildSize of control bottom app bar --------- Co-authored-by: shalong-tanwen <139912620+shalong-tanwen@users.noreply.github.com> Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
parent
04c783f2f0
commit
f62678f58f
@ -633,6 +633,7 @@ class GalleryViewerPage extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Migrate to a custom bottom bar and handle long press to delete
|
||||||
Widget buildBottomBar() {
|
Widget buildBottomBar() {
|
||||||
// !!!! itemsList and actionlist should always be in sync
|
// !!!! itemsList and actionlist should always be in sync
|
||||||
final itemsList = [
|
final itemsList = [
|
||||||
|
@ -63,6 +63,22 @@ class ControlBottomAppBar extends ConsumerWidget {
|
|||||||
ref.watch(serverInfoProvider.select((v) => v.serverFeatures.trash));
|
ref.watch(serverInfoProvider.select((v) => v.serverFeatures.trash));
|
||||||
final albums = ref.watch(albumProvider).where((a) => a.isRemote).toList();
|
final albums = ref.watch(albumProvider).where((a) => a.isRemote).toList();
|
||||||
final sharedAlbums = ref.watch(sharedAlbumProvider);
|
final sharedAlbums = ref.watch(sharedAlbumProvider);
|
||||||
|
const bottomPadding = 0.20;
|
||||||
|
|
||||||
|
void showForceDeleteDialog(
|
||||||
|
Function(bool) deleteCb, {
|
||||||
|
String? alertMsg,
|
||||||
|
}) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return DeleteDialog(
|
||||||
|
alert: alertMsg,
|
||||||
|
onDelete: () => deleteCb(true),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void handleRemoteDelete(
|
void handleRemoteDelete(
|
||||||
bool force,
|
bool force,
|
||||||
@ -73,15 +89,7 @@ class ControlBottomAppBar extends ConsumerWidget {
|
|||||||
deleteCb(force);
|
deleteCb(force);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
showDialog(
|
return showForceDeleteDialog(deleteCb, alertMsg: alertMsg);
|
||||||
context: context,
|
|
||||||
builder: (BuildContext context) {
|
|
||||||
return DeleteDialog(
|
|
||||||
alert: alertMsg,
|
|
||||||
onDelete: () => deleteCb(force),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Widget> renderActionButtons() {
|
List<Widget> renderActionButtons() {
|
||||||
@ -132,6 +140,12 @@ class ControlBottomAppBar extends ConsumerWidget {
|
|||||||
alertMsg: "delete_dialog_alert_remote",
|
alertMsg: "delete_dialog_alert_remote",
|
||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
|
onLongPressed: enabled
|
||||||
|
? () => showForceDeleteDialog(
|
||||||
|
onDeleteServer!,
|
||||||
|
alertMsg: "delete_dialog_alert_remote",
|
||||||
|
)
|
||||||
|
: null,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (hasLocal && onDeleteLocal != null)
|
if (hasLocal && onDeleteLocal != null)
|
||||||
@ -167,6 +181,8 @@ class ControlBottomAppBar extends ConsumerWidget {
|
|||||||
onPressed: enabled
|
onPressed: enabled
|
||||||
? () => handleRemoteDelete(!trashEnabled, onDelete!)
|
? () => handleRemoteDelete(!trashEnabled, onDelete!)
|
||||||
: null,
|
: null,
|
||||||
|
onLongPressed:
|
||||||
|
enabled ? () => showForceDeleteDialog(onDelete!) : null,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (hasRemote && onEditTime != null)
|
if (hasRemote && onEditTime != null)
|
||||||
@ -214,9 +230,9 @@ class ControlBottomAppBar extends ConsumerWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return DraggableScrollableSheet(
|
return DraggableScrollableSheet(
|
||||||
initialChildSize: hasRemote ? 0.30 : 0.18,
|
initialChildSize: hasRemote ? 0.30 : bottomPadding,
|
||||||
minChildSize: 0.18,
|
minChildSize: bottomPadding,
|
||||||
maxChildSize: hasRemote ? 0.60 : 0.18,
|
maxChildSize: hasRemote ? 0.60 : bottomPadding,
|
||||||
snap: true,
|
snap: true,
|
||||||
builder: (
|
builder: (
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
|
@ -201,9 +201,9 @@ class MultiselectGrid extends HookConsumerWidget {
|
|||||||
msg: '${selection.value.length} $assetOrAssets $trashOrRemoved',
|
msg: '${selection.value.length} $assetOrAssets $trashOrRemoved',
|
||||||
gravity: ToastGravity.BOTTOM,
|
gravity: ToastGravity.BOTTOM,
|
||||||
);
|
);
|
||||||
|
selectionEnabledHook.value = false;
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
selectionEnabledHook.value = false;
|
|
||||||
processing.value = false;
|
processing.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,9 +224,9 @@ class MultiselectGrid extends HookConsumerWidget {
|
|||||||
'${localIds.length} $assetOrAssets removed permanently from your device',
|
'${localIds.length} $assetOrAssets removed permanently from your device',
|
||||||
gravity: ToastGravity.BOTTOM,
|
gravity: ToastGravity.BOTTOM,
|
||||||
);
|
);
|
||||||
|
selectionEnabledHook.value = false;
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
selectionEnabledHook.value = false;
|
|
||||||
processing.value = false;
|
processing.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,11 +23,13 @@ class ControlBoxButton extends StatelessWidget {
|
|||||||
required this.label,
|
required this.label,
|
||||||
required this.iconData,
|
required this.iconData,
|
||||||
this.onPressed,
|
this.onPressed,
|
||||||
|
this.onLongPressed,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final String label;
|
final String label;
|
||||||
final IconData iconData;
|
final IconData iconData;
|
||||||
final void Function()? onPressed;
|
final void Function()? onPressed;
|
||||||
|
final void Function()? onLongPressed;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -35,6 +37,7 @@ class ControlBoxButton extends StatelessWidget {
|
|||||||
padding: const EdgeInsets.all(10),
|
padding: const EdgeInsets.all(10),
|
||||||
shape: const CircleBorder(),
|
shape: const CircleBorder(),
|
||||||
onPressed: onPressed,
|
onPressed: onPressed,
|
||||||
|
onLongPress: onLongPressed,
|
||||||
minWidth: 75.0,
|
minWidth: 75.0,
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
Loading…
Reference in New Issue
Block a user