Bladeren bron

Add option to delete file from just the device

Vishnu Mohandas 4 jaren geleden
bovenliggende
commit
e7821d605d
3 gewijzigde bestanden met toevoegingen van 111 en 31 verwijderingen
  1. 33 10
      lib/ui/detail_page.dart
  2. 48 20
      lib/ui/gallery_app_bar_widget.dart
  3. 30 1
      lib/utils/file_util.dart

+ 33 - 10
lib/ui/detail_page.dart

@@ -319,17 +319,41 @@ class _DetailPageState extends State<DetailPage> {
   }
 
   void _showDeleteSheet() {
-    final action = CupertinoActionSheet(
-      title: Text("Delete file?"),
-      actions: <Widget>[
-        CupertinoActionSheetAction(
-          child: Text("Delete"),
+    final fileToBeDeleted = _files[_selectedIndex];
+    final actions = List<Widget>();
+    if (fileToBeDeleted.uploadedFileID == null) {
+      actions.add(CupertinoActionSheetAction(
+        child: Text("Everywhere"),
+        isDestructiveAction: true,
+        onPressed: () async {
+          await deleteFilesFromEverywhere(context, [fileToBeDeleted]);
+          _onFileDeleted();
+        },
+      ));
+    } else {
+      if (fileToBeDeleted.localID != null) {
+        actions.add(CupertinoActionSheetAction(
+          child: Text("On this device"),
           isDestructiveAction: true,
           onPressed: () async {
-            await _delete();
+            await deleteFilesOnDeviceOnly(context, [fileToBeDeleted]);
+            showToast("File deleted from device");
+            Navigator.of(context, rootNavigator: true).pop();
           },
-        ),
-      ],
+        ));
+      }
+      actions.add(CupertinoActionSheetAction(
+        child: Text("Everywhere"),
+        isDestructiveAction: true,
+        onPressed: () async {
+          await deleteFilesFromEverywhere(context, [fileToBeDeleted]);
+          _onFileDeleted();
+        },
+      ));
+    }
+    final action = CupertinoActionSheet(
+      title: Text("Delete file?"),
+      actions: actions,
       cancelButton: CupertinoActionSheetAction(
         child: Text("Cancel"),
         onPressed: () {
@@ -340,9 +364,8 @@ class _DetailPageState extends State<DetailPage> {
     showCupertinoModalPopup(context: context, builder: (_) => action);
   }
 
-  Future _delete() async {
+  Future _onFileDeleted() async {
     final file = _files[_selectedIndex];
-    await deleteFilesFromEverywhere([file]);
     final totalFiles = _files.length;
     if (totalFiles == 1) {
       // Deleted the only file

+ 48 - 20
lib/ui/gallery_app_bar_widget.dart

@@ -15,6 +15,7 @@ import 'package:photos/ui/share_collection_widget.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/file_util.dart';
 import 'package:photos/utils/share_util.dart';
+import 'package:photos/utils/toast_util.dart';
 
 enum GalleryAppBarType {
   homepage,
@@ -284,20 +285,56 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
 
   void _showDeleteSheet(BuildContext context) {
     final count = widget.selectedFiles.files.length;
+    bool containsUploadedFile = false;
+    for (final file in widget.selectedFiles.files) {
+      if (file.uploadedFileID != null) {
+        containsUploadedFile = true;
+      }
+    }
+    final actions = List<Widget>();
+    if (containsUploadedFile) {
+      actions.add(CupertinoActionSheetAction(
+        child: Text("This Device"),
+        isDestructiveAction: true,
+        onPressed: () async {
+          await deleteFilesOnDeviceOnly(
+              context, widget.selectedFiles.files.toList());
+          _clearSelectedFiles();
+          showToast("Files deleted from device");
+          Navigator.of(context, rootNavigator: true).pop();
+        },
+      ));
+      actions.add(CupertinoActionSheetAction(
+        child: Text("Everywhere"),
+        isDestructiveAction: true,
+        onPressed: () async {
+          await deleteFilesFromEverywhere(
+              context, widget.selectedFiles.files.toList());
+          _clearSelectedFiles();
+          showToast("Files deleted from everywhere");
+          Navigator.of(context, rootNavigator: true).pop();
+        },
+      ));
+    } else {
+      actions.add(CupertinoActionSheetAction(
+        child: Text("Delete forever"),
+        isDestructiveAction: true,
+        onPressed: () async {
+          await deleteFilesFromEverywhere(
+              context, widget.selectedFiles.files.toList());
+          _clearSelectedFiles();
+          showToast("Files deleted from everywhere");
+          Navigator.of(context, rootNavigator: true).pop();
+        },
+      ));
+    }
     final action = CupertinoActionSheet(
-      title: Text("Permanently delete " +
+      title: Text("Delete " +
           count.toString() +
           " file" +
-          (count == 1 ? "?" : "s?")),
-      actions: <Widget>[
-        CupertinoActionSheetAction(
-          child: Text("Delete"),
-          isDestructiveAction: true,
-          onPressed: () async {
-            await _deleteSelected();
-          },
-        ),
-      ],
+          (count == 1 ? "" : "s") +
+          (containsUploadedFile ? " from" : "?")),
+      actions: actions,
       cancelButton: CupertinoActionSheetAction(
         child: Text("Cancel"),
         onPressed: () {
@@ -308,15 +345,6 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
     showCupertinoModalPopup(context: context, builder: (_) => action);
   }
 
-  _deleteSelected() async {
-    Navigator.of(context, rootNavigator: true).pop();
-    final dialog = createProgressDialog(context, "Deleting...");
-    await dialog.show();
-    await deleteFilesFromEverywhere(widget.selectedFiles.files.toList());
-    _clearSelectedFiles();
-    await dialog.hide();
-  }
-
   void _clearSelectedFiles() {
     widget.selectedFiles.clearAll();
   }

+ 30 - 1
lib/utils/file_util.dart

@@ -2,6 +2,7 @@ import 'dart:io' as io;
 import 'dart:io';
 import 'dart:typed_data';
 
+import 'package:flutter/widgets.dart';
 import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:logging/logging.dart';
 import 'package:path/path.dart';
@@ -24,12 +25,16 @@ import 'package:photos/models/file_type.dart';
 import 'package:photos/repositories/file_repository.dart';
 import 'package:photos/services/collections_service.dart';
 import 'package:photos/services/sync_service.dart';
+import 'package:photos/utils/dialog_util.dart';
 
 import 'crypto_util.dart';
 
 final _logger = Logger("FileUtil");
 
-Future<void> deleteFilesFromEverywhere(List<File> files) async {
+Future<void> deleteFilesFromEverywhere(
+    BuildContext context, List<File> files) async {
+  final dialog = createProgressDialog(context, "Deleting...");
+  await dialog.show();
   final localIDs = List<String>();
   for (final file in files) {
     if (file.localID != null) {
@@ -54,6 +59,7 @@ Future<void> deleteFilesFromEverywhere(List<File> files) async {
       hasUploadedFiles = true;
       await FilesDB.instance.markForDeletion(file.uploadedFileID);
     }
+    await dialog.hide();
   }
 
   await FileRepository.instance.reloadFiles();
@@ -64,6 +70,29 @@ Future<void> deleteFilesFromEverywhere(List<File> files) async {
   }
 }
 
+Future<void> deleteFilesOnDeviceOnly(
+    BuildContext context, List<File> files) async {
+  final dialog = createProgressDialog(context, "Deleting...");
+  await dialog.show();
+  final localIDs = List<String>();
+  for (final file in files) {
+    if (file.localID != null) {
+      localIDs.add(file.localID);
+    }
+  }
+  final deletedIDs =
+      (await PhotoManager.editor.deleteWithIds(localIDs)).toSet();
+  for (final file in files) {
+    // Remove only those files that have been removed from disk
+    if (deletedIDs.contains(file.localID)) {
+      file.localID = null;
+      FilesDB.instance.update(file);
+    }
+  }
+  await FileRepository.instance.reloadFiles();
+  await dialog.hide();
+}
+
 void preloadFile(File file) {
   if (file.fileType == FileType.video) {
     return;