forked from Cutlery/immich
		
	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() {
 | 
			
		||||
      // !!!! itemsList and actionlist should always be in sync
 | 
			
		||||
      final itemsList = [
 | 
			
		||||
 | 
			
		||||
@ -63,6 +63,22 @@ class ControlBottomAppBar extends ConsumerWidget {
 | 
			
		||||
        ref.watch(serverInfoProvider.select((v) => v.serverFeatures.trash));
 | 
			
		||||
    final albums = ref.watch(albumProvider).where((a) => a.isRemote).toList();
 | 
			
		||||
    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(
 | 
			
		||||
      bool force,
 | 
			
		||||
@ -73,15 +89,7 @@ class ControlBottomAppBar extends ConsumerWidget {
 | 
			
		||||
        deleteCb(force);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      showDialog(
 | 
			
		||||
        context: context,
 | 
			
		||||
        builder: (BuildContext context) {
 | 
			
		||||
          return DeleteDialog(
 | 
			
		||||
            alert: alertMsg,
 | 
			
		||||
            onDelete: () => deleteCb(force),
 | 
			
		||||
          );
 | 
			
		||||
        },
 | 
			
		||||
      );
 | 
			
		||||
      return showForceDeleteDialog(deleteCb, alertMsg: alertMsg);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    List<Widget> renderActionButtons() {
 | 
			
		||||
@ -132,6 +140,12 @@ class ControlBottomAppBar extends ConsumerWidget {
 | 
			
		||||
                        alertMsg: "delete_dialog_alert_remote",
 | 
			
		||||
                      )
 | 
			
		||||
                  : null,
 | 
			
		||||
              onLongPressed: enabled
 | 
			
		||||
                  ? () => showForceDeleteDialog(
 | 
			
		||||
                        onDeleteServer!,
 | 
			
		||||
                        alertMsg: "delete_dialog_alert_remote",
 | 
			
		||||
                      )
 | 
			
		||||
                  : null,
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        if (hasLocal && onDeleteLocal != null)
 | 
			
		||||
@ -167,6 +181,8 @@ class ControlBottomAppBar extends ConsumerWidget {
 | 
			
		||||
              onPressed: enabled
 | 
			
		||||
                  ? () => handleRemoteDelete(!trashEnabled, onDelete!)
 | 
			
		||||
                  : null,
 | 
			
		||||
              onLongPressed:
 | 
			
		||||
                  enabled ? () => showForceDeleteDialog(onDelete!) : null,
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        if (hasRemote && onEditTime != null)
 | 
			
		||||
@ -214,9 +230,9 @@ class ControlBottomAppBar extends ConsumerWidget {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return DraggableScrollableSheet(
 | 
			
		||||
      initialChildSize: hasRemote ? 0.30 : 0.18,
 | 
			
		||||
      minChildSize: 0.18,
 | 
			
		||||
      maxChildSize: hasRemote ? 0.60 : 0.18,
 | 
			
		||||
      initialChildSize: hasRemote ? 0.30 : bottomPadding,
 | 
			
		||||
      minChildSize: bottomPadding,
 | 
			
		||||
      maxChildSize: hasRemote ? 0.60 : bottomPadding,
 | 
			
		||||
      snap: true,
 | 
			
		||||
      builder: (
 | 
			
		||||
        BuildContext context,
 | 
			
		||||
 | 
			
		||||
@ -201,9 +201,9 @@ class MultiselectGrid extends HookConsumerWidget {
 | 
			
		||||
            msg: '${selection.value.length} $assetOrAssets $trashOrRemoved',
 | 
			
		||||
            gravity: ToastGravity.BOTTOM,
 | 
			
		||||
          );
 | 
			
		||||
          selectionEnabledHook.value = false;
 | 
			
		||||
        }
 | 
			
		||||
      } finally {
 | 
			
		||||
        selectionEnabledHook.value = false;
 | 
			
		||||
        processing.value = false;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@ -224,9 +224,9 @@ class MultiselectGrid extends HookConsumerWidget {
 | 
			
		||||
                '${localIds.length} $assetOrAssets removed permanently from your device',
 | 
			
		||||
            gravity: ToastGravity.BOTTOM,
 | 
			
		||||
          );
 | 
			
		||||
          selectionEnabledHook.value = false;
 | 
			
		||||
        }
 | 
			
		||||
      } finally {
 | 
			
		||||
        selectionEnabledHook.value = false;
 | 
			
		||||
        processing.value = false;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -23,11 +23,13 @@ class ControlBoxButton extends StatelessWidget {
 | 
			
		||||
    required this.label,
 | 
			
		||||
    required this.iconData,
 | 
			
		||||
    this.onPressed,
 | 
			
		||||
    this.onLongPressed,
 | 
			
		||||
  }) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  final String label;
 | 
			
		||||
  final IconData iconData;
 | 
			
		||||
  final void Function()? onPressed;
 | 
			
		||||
  final void Function()? onLongPressed;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
@ -35,6 +37,7 @@ class ControlBoxButton extends StatelessWidget {
 | 
			
		||||
      padding: const EdgeInsets.all(10),
 | 
			
		||||
      shape: const CircleBorder(),
 | 
			
		||||
      onPressed: onPressed,
 | 
			
		||||
      onLongPress: onLongPressed,
 | 
			
		||||
      minWidth: 75.0,
 | 
			
		||||
      child: Column(
 | 
			
		||||
        mainAxisAlignment: MainAxisAlignment.start,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user