소스 검색

Merge pull request #114 from ente-io/trash_improvements

Trash improvements
Neeraj Gupta 3 년 전
부모
커밋
769b1222ff
6개의 변경된 파일76개의 추가작업 그리고 89개의 파일을 삭제
  1. 2 1
      lib/services/collections_service.dart
  2. 13 10
      lib/ui/common/dialogs.dart
  3. 3 1
      lib/ui/detail_page.dart
  4. 19 15
      lib/ui/gallery_app_bar_widget.dart
  5. 19 43
      lib/ui/trash_page.dart
  6. 20 19
      lib/utils/delete_file_util.dart

+ 2 - 1
lib/services/collections_service.dart

@@ -153,7 +153,8 @@ class CollectionsService {
   List<Collection> getActiveCollections() {
     return _collectionIDToCollections.values
         .toList()
-        .where((element) => !element.isDeleted);
+        .where((element) => !element.isDeleted)
+        .toList();
   }
 
   Future<List<User>> getSharees(int collectionID) {

+ 13 - 10
lib/ui/common/dialogs.dart

@@ -1,10 +1,7 @@
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 
-enum DialogUserChoice {
-  firstChoice,
-  secondChoice
-}
+enum DialogUserChoice { firstChoice, secondChoice }
 
 enum ActionType {
   confirm,
@@ -20,19 +17,25 @@ Future<T> showChoiceDialog<T>(
   ActionType actionType = ActionType.confirm,
 }) {
   AlertDialog alert = AlertDialog(
-    title: Text(title,
+    title: Text(
+      title,
       style: TextStyle(
-        color:
-            actionType == ActionType.critical ? Colors.red : Colors.white,
+        color: actionType == ActionType.critical ? Colors.red : Colors.white,
+      ),
+    ),
+    content: Text(
+      content,
+      style: TextStyle(
+        height: 1.4,
       ),
     ),
-    content: Text(content),
     actions: [
       TextButton(
         child: Text(
           firstAction,
           style: TextStyle(
-            color: actionType == ActionType.critical ? Colors.red : Colors.white,
+            color:
+                actionType == ActionType.critical ? Colors.red : Colors.white,
           ),
         ),
         onPressed: () {
@@ -62,4 +65,4 @@ Future<T> showChoiceDialog<T>(
     },
     barrierColor: Colors.black87,
   );
-}
+}

+ 3 - 1
lib/ui/detail_page.dart

@@ -201,7 +201,9 @@ class _DetailPageState extends State<DetailPage> {
           limit: kLoadLimit,
           asc: true);
       setState(() {
-        final files = result.files.reversed.toList();
+        // Returned result could be a subtype of File
+        // ignore: unnecessary_cast
+        final files = result.files.reversed.map((e) => e as File).toList();
         if (!result.hasMore) {
           _hasLoadedTillStart = true;
         }

+ 19 - 15
lib/ui/gallery_app_bar_widget.dart

@@ -93,6 +93,8 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
                   _appBarTitle,
                   style: TextStyle(
                     color: Colors.white.withOpacity(0.80),
+                    fontWeight: FontWeight.bold,
+                    fontSize: 16,
                   ),
                 ),
                 onPressed: () => _renameAlbum(context),
@@ -192,7 +194,7 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
         },
       ));
     }
-    if(widget.type == GalleryAppBarType.trash) {
+    if (widget.type == GalleryAppBarType.trash) {
       actions.add(
         Tooltip(
           message: "empty trash",
@@ -416,18 +418,20 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
         },
       ),
     ));
-    actions.add(Tooltip(
-      message: "delete permanently",
-      child: IconButton(
-        icon: Icon(Icons.delete_forever_outlined),
-        onPressed: () async {
-          if (await deleteFromTrash(
-              context, widget.selectedFiles.files.toList())) {
-            _clearSelectedFiles();
-          }
-        },
+    actions.add(
+      Tooltip(
+        message: "delete permanently",
+        child: IconButton(
+          icon: Icon(Icons.delete_forever_outlined),
+          onPressed: () async {
+            if (await deleteFromTrash(
+                context, widget.selectedFiles.files.toList())) {
+              _clearSelectedFiles();
+            }
+          },
+        ),
       ),
-    ));
+    );
   }
 
   Future<void> _handleVisibilityChangeRequest(
@@ -502,7 +506,7 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
     final actions = <Widget>[];
     if (containsUploadedFile && containsLocalFile) {
       actions.add(CupertinoActionSheetAction(
-        child: Text("this device"),
+        child: Text("device"),
         isDestructiveAction: true,
         onPressed: () async {
           Navigator.of(context, rootNavigator: true).pop();
@@ -520,7 +524,7 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
           await deleteFilesFromRemoteOnly(
               context, widget.selectedFiles.files.toList());
           _clearSelectedFiles();
-          showToast("deleted files are moved to trash");
+          showToast("moved to trash");
         },
       ));
       actions.add(CupertinoActionSheetAction(
@@ -535,7 +539,7 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
       ));
     } else {
       actions.add(CupertinoActionSheetAction(
-        child: Text("delete forever"),
+        child: Text("delete"),
         isDestructiveAction: true,
         onPressed: () async {
           Navigator.of(context, rootNavigator: true).pop();

+ 19 - 43
lib/ui/trash_page.dart

@@ -1,11 +1,8 @@
-import 'dart:io';
-
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:photos/core/event_bus.dart';
 import 'package:photos/db/trash_db.dart';
 import 'package:photos/events/files_updated_event.dart';
-import 'package:photos/models/file_load_result.dart';
 import 'package:photos/models/selected_files.dart';
 
 import 'gallery.dart';
@@ -25,31 +22,31 @@ class TrashPage extends StatelessWidget {
   @override
   Widget build(Object context) {
     final gallery = Gallery(
-        asyncLoader: (creationStartTime, creationEndTime, {limit, asc}) {
-          return TrashDB.instance.getTrashedFiles(
-              creationStartTime, creationEndTime,
-              limit: limit, asc: asc);
-        },
-        reloadEvent: Bus.instance.on<FilesUpdatedEvent>().where(
+      asyncLoader: (creationStartTime, creationEndTime, {limit, asc}) {
+        return TrashDB.instance.getTrashedFiles(
+            creationStartTime, creationEndTime,
+            limit: limit, asc: asc);
+      },
+      reloadEvent: Bus.instance.on<FilesUpdatedEvent>().where(
+            (event) =>
+                event.updatedFiles.firstWhere(
+                    (element) => element.uploadedFileID != null,
+                    orElse: () => null) !=
+                null,
+          ),
+      forceReloadEvents: [
+        Bus.instance.on<FilesUpdatedEvent>().where(
               (event) =>
                   event.updatedFiles.firstWhere(
                       (element) => element.uploadedFileID != null,
                       orElse: () => null) !=
                   null,
             ),
-        forceReloadEvents: [
-          Bus.instance.on<FilesUpdatedEvent>().where(
-                (event) =>
-                    event.updatedFiles.firstWhere(
-                        (element) => element.uploadedFileID != null,
-                        orElse: () => null) !=
-                    null,
-              ),
-        ],
-        tagPrefix: tagPrefix,
-        selectedFiles: _selectedFiles,
-        initialFiles: null,
-        footer: _footerWidget());
+      ],
+      tagPrefix: tagPrefix,
+      selectedFiles: _selectedFiles,
+      initialFiles: null,
+    );
 
     return Scaffold(
       appBar: PreferredSize(
@@ -63,25 +60,4 @@ class TrashPage extends StatelessWidget {
       body: gallery,
     );
   }
-
-  Widget _footerWidget() {
-    return FutureBuilder<FileLoadResult>(
-        future: TrashDB.instance
-            .getTrashedFiles(0, DateTime.now().microsecondsSinceEpoch),
-        builder: (context, snapshot) {
-          if (snapshot.hasData && snapshot.data.files.isNotEmpty) {
-            return Padding(
-              padding: EdgeInsets.all(15),
-              child: Text(
-                'memories shows the number the days after which they will be permanently deleted.',
-                style: TextStyle(
-                  fontSize: 16,
-                ),
-              ),
-            );
-          } else {
-            return Container();
-          }
-        });
-  }
 }

+ 20 - 19
lib/utils/delete_file_util.dart

@@ -16,7 +16,6 @@ import 'package:photos/events/collection_updated_event.dart';
 import 'package:photos/events/files_updated_event.dart';
 import 'package:photos/events/local_photos_updated_event.dart';
 import 'package:photos/models/file.dart';
-import 'package:photos/models/trash_file.dart';
 import 'package:photos/models/trash_item_request.dart';
 import 'package:photos/services/remote_sync_service.dart';
 import 'package:photos/services/sync_service.dart';
@@ -68,7 +67,8 @@ Future<void> deleteFilesFromEverywhere(
           alreadyDeletedIDs.contains(file.localID)) {
         deletedFiles.add(file);
         if (file.uploadedFileID != null) {
-          uploadedFilesToBeTrashed.add(TrashRequest(file.uploadedFileID, file.collectionID));
+          uploadedFilesToBeTrashed
+              .add(TrashRequest(file.uploadedFileID, file.collectionID));
           updatedCollectionIDs.add(file.collectionID);
         } else {
           await FilesDB.instance.deleteLocalFile(file);
@@ -77,16 +77,19 @@ Future<void> deleteFilesFromEverywhere(
     } else {
       updatedCollectionIDs.add(file.collectionID);
       deletedFiles.add(file);
-      uploadedFilesToBeTrashed.add(TrashRequest(file.uploadedFileID, file.collectionID));
+      uploadedFilesToBeTrashed
+          .add(TrashRequest(file.uploadedFileID, file.collectionID));
     }
   }
   if (uploadedFilesToBeTrashed.isNotEmpty) {
     try {
-      final fileIDs = uploadedFilesToBeTrashed.map((item) => item.fileID).toList();
-      await TrashSyncService.instance.trashFilesOnServer(uploadedFilesToBeTrashed);
+      final fileIDs =
+          uploadedFilesToBeTrashed.map((item) => item.fileID).toList();
+      await TrashSyncService.instance
+          .trashFilesOnServer(uploadedFilesToBeTrashed);
       // await SyncService.instance
       //     .deleteFilesOnServer(fileIDs);
-       await FilesDB.instance.deleteMultipleUploadedFiles(fileIDs);
+      await FilesDB.instance.deleteMultipleUploadedFiles(fileIDs);
     } catch (e) {
       _logger.severe(e);
       await dialog.hide();
@@ -108,7 +111,7 @@ Future<void> deleteFilesFromEverywhere(
         .fire(LocalPhotosUpdatedEvent(deletedFiles, type: EventType.deleted));
   }
   await dialog.hide();
-  showToast("deleted from everywhere");
+  showToast("moved to trash");
   if (uploadedFilesToBeTrashed.isNotEmpty) {
     RemoteSyncService.instance.sync(silently: true);
   }
@@ -117,7 +120,7 @@ Future<void> deleteFilesFromEverywhere(
 Future<void> deleteFilesFromRemoteOnly(
     BuildContext context, List<File> files) async {
   files.removeWhere((element) => element.uploadedFileID == null);
-  if(files.isEmpty) {
+  if (files.isEmpty) {
     showToast("selected files are not on ente");
     return;
   }
@@ -149,8 +152,7 @@ Future<void> deleteFilesFromRemoteOnly(
       type: EventType.deleted,
     ));
   }
-  Bus.instance
-        .fire(LocalPhotosUpdatedEvent(files, type: EventType.deleted));
+  Bus.instance.fire(LocalPhotosUpdatedEvent(files, type: EventType.deleted));
   SyncService.instance.sync();
   await dialog.hide();
   RemoteSyncService.instance.sync(silently: true);
@@ -201,10 +203,9 @@ Future<void> deleteFilesOnDeviceOnly(
   await dialog.hide();
 }
 
-Future<bool> deleteFromTrash(
-    BuildContext context, List<File> files) async {
-  final result = await showChoiceDialog(context, "delete permanently?",
-      "the files will be permanently removed from your ente account",
+Future<bool> deleteFromTrash(BuildContext context, List<File> files) async {
+  final result = await showChoiceDialog(
+      context, "delete permanently?", "this action cannot be undone",
       firstAction: "delete", actionType: ActionType.critical);
   if (result != DialogUserChoice.firstChoice) {
     return false;
@@ -225,11 +226,10 @@ Future<bool> deleteFromTrash(
   }
 }
 
-
 Future<bool> emptyTrash(BuildContext context) async {
   final result = await showChoiceDialog(context, "empty trash?",
-      "all files will be permanently removed from your ente account",
-      firstAction: "yes", actionType: ActionType.critical);
+      "these files will be permanently removed from your ente account",
+      firstAction: "empty", actionType: ActionType.critical);
   if (result != DialogUserChoice.firstChoice) {
     return false;
   }
@@ -237,9 +237,10 @@ Future<bool> emptyTrash(BuildContext context) async {
   await dialog.show();
   try {
     await TrashSyncService.instance.emptyTrash();
-    showToast("done");
+    showToast("trash emptied");
     await dialog.hide();
-    Bus.instance.fire(FilesUpdatedEvent((List<File>.empty()), type: EventType.deleted));
+    Bus.instance
+        .fire(FilesUpdatedEvent((List<File>.empty()), type: EventType.deleted));
     return true;
   } catch (e, s) {
     _logger.info("failed empty trash", e, s);