Explorar el Código

Merge pull request #241 from ente-io/delete_confirmation

Prompt user to confirm the deletion of local-only files
Neeraj Gupta hace 3 años
padre
commit
a26d9c5d7a
Se han modificado 2 ficheros con 44 adiciones y 8 borrados
  1. 1 2
      lib/ui/common/dialogs.dart
  2. 43 6
      lib/utils/delete_file_util.dart

+ 1 - 2
lib/ui/common/dialogs.dart

@@ -1,4 +1,3 @@
-import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 
 
 enum DialogUserChoice { firstChoice, secondChoice }
 enum DialogUserChoice { firstChoice, secondChoice }
@@ -8,7 +7,7 @@ enum ActionType {
   critical,
   critical,
 }
 }
 // if dialog is dismissed by tapping outside, this will return null
 // if dialog is dismissed by tapping outside, this will return null
-Future<T> showChoiceDialog<T>(
+Future<DialogUserChoice> showChoiceDialog<T>(
   BuildContext context,
   BuildContext context,
   String title,
   String title,
   String content, {
   String content, {

+ 43 - 6
lib/utils/delete_file_util.dart

@@ -5,7 +5,6 @@ import 'dart:math';
 
 
 import 'package:device_info/device_info.dart';
 import 'package:device_info/device_info.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter/widgets.dart';
 import 'package:logging/logging.dart';
 import 'package:logging/logging.dart';
 import 'package:photo_manager/photo_manager.dart';
 import 'package:photo_manager/photo_manager.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/configuration.dart';
@@ -36,6 +35,7 @@ Future<void> deleteFilesFromEverywhere(
   final List<String> localAssetIDs = [];
   final List<String> localAssetIDs = [];
   final List<String> localSharedMediaIDs = [];
   final List<String> localSharedMediaIDs = [];
   final List<String> alreadyDeletedIDs = []; // to ignore already deleted files
   final List<String> alreadyDeletedIDs = []; // to ignore already deleted files
+  bool hasLocalOnlyFiles = false;
   for (final file in files) {
   for (final file in files) {
     if (file.localID != null) {
     if (file.localID != null) {
       if (!(await _localFileExist(file))) {
       if (!(await _localFileExist(file))) {
@@ -47,6 +47,16 @@ Future<void> deleteFilesFromEverywhere(
         localAssetIDs.add(file.localID);
         localAssetIDs.add(file.localID);
       }
       }
     }
     }
+    if (file.uploadedFileID == null) {
+      hasLocalOnlyFiles = true;
+    }
+  }
+  if (hasLocalOnlyFiles && Platform.isAndroid) {
+    final shouldProceed = await shouldProceedWithDeletion(context);
+    if (!shouldProceed) {
+      await dialog.hide();
+      return;
+    }
   }
   }
   Set<String> deletedIDs = <String>{};
   Set<String> deletedIDs = <String>{};
   try {
   try {
@@ -108,7 +118,11 @@ Future<void> deleteFilesFromEverywhere(
   if (deletedFiles.isNotEmpty) {
   if (deletedFiles.isNotEmpty) {
     Bus.instance.fire(LocalPhotosUpdatedEvent(deletedFiles,
     Bus.instance.fire(LocalPhotosUpdatedEvent(deletedFiles,
         type: EventType.deletedFromEverywhere));
         type: EventType.deletedFromEverywhere));
-    showShortToast("moved to trash");
+    if (hasLocalOnlyFiles && Platform.isAndroid) {
+      showShortToast("files deleted");
+    } else {
+      showShortToast("moved to trash");
+    }
   }
   }
   await dialog.hide();
   await dialog.hide();
   if (uploadedFilesToBeTrashed.isNotEmpty) {
   if (uploadedFilesToBeTrashed.isNotEmpty) {
@@ -151,8 +165,8 @@ Future<void> deleteFilesFromRemoteOnly(
       type: EventType.deletedFromRemote,
       type: EventType.deletedFromRemote,
     ));
     ));
   }
   }
-  Bus.instance.fire(
-      LocalPhotosUpdatedEvent(files, type: EventType.deletedFromRemote));
+  Bus.instance
+      .fire(LocalPhotosUpdatedEvent(files, type: EventType.deletedFromRemote));
   SyncService.instance.sync();
   SyncService.instance.sync();
   await dialog.hide();
   await dialog.hide();
   RemoteSyncService.instance.sync(silently: true);
   RemoteSyncService.instance.sync(silently: true);
@@ -166,6 +180,7 @@ Future<void> deleteFilesOnDeviceOnly(
   final List<String> localAssetIDs = [];
   final List<String> localAssetIDs = [];
   final List<String> localSharedMediaIDs = [];
   final List<String> localSharedMediaIDs = [];
   final List<String> alreadyDeletedIDs = []; // to ignore already deleted files
   final List<String> alreadyDeletedIDs = []; // to ignore already deleted files
+  bool hasLocalOnlyFiles = false;
   for (final file in files) {
   for (final file in files) {
     if (file.localID != null) {
     if (file.localID != null) {
       if (!(await _localFileExist(file))) {
       if (!(await _localFileExist(file))) {
@@ -177,6 +192,16 @@ Future<void> deleteFilesOnDeviceOnly(
         localAssetIDs.add(file.localID);
         localAssetIDs.add(file.localID);
       }
       }
     }
     }
+    if (file.uploadedFileID == null) {
+      hasLocalOnlyFiles = true;
+    }
+  }
+  if (hasLocalOnlyFiles && Platform.isAndroid) {
+    final shouldProceed = await shouldProceedWithDeletion(context);
+    if (!shouldProceed) {
+      await dialog.hide();
+      return;
+    }
   }
   }
   Set<String> deletedIDs = <String>{};
   Set<String> deletedIDs = <String>{};
   try {
   try {
@@ -216,8 +241,8 @@ Future<bool> deleteFromTrash(BuildContext context, List<File> files) async {
     await TrashSyncService.instance.deleteFromTrash(files);
     await TrashSyncService.instance.deleteFromTrash(files);
     showToast("successfully deleted");
     showToast("successfully deleted");
     await dialog.hide();
     await dialog.hide();
-    Bus.instance.fire(
-        FilesUpdatedEvent(files, type: EventType.deletedFromEverywhere));
+    Bus.instance
+        .fire(FilesUpdatedEvent(files, type: EventType.deletedFromEverywhere));
     return true;
     return true;
   } catch (e, s) {
   } catch (e, s) {
     _logger.info("failed to delete from trash", e, s);
     _logger.info("failed to delete from trash", e, s);
@@ -390,3 +415,15 @@ Future<List<String>> _tryDeleteSharedMediaFiles(List<String> localIDs) {
     return Future.value(actuallyDeletedIDs);
     return Future.value(actuallyDeletedIDs);
   }
   }
 }
 }
+
+Future<bool> shouldProceedWithDeletion(BuildContext context) async {
+  final choice = await showChoiceDialog(
+    context,
+    "are you sure?",
+    "some of the files you are trying to delete are only available on your device and cannot be recovered if deleted",
+    firstAction: "cancel",
+    secondAction: "delete",
+    secondActionColor: Colors.red,
+  );
+  return choice == DialogUserChoice.secondChoice;
+}