Neeraj Gupta %!s(int64=3) %!d(string=hai) anos
pai
achega
1911f8fa83
Modificáronse 43 ficheiros con 631 adicións e 286 borrados
  1. 18 10
      lib/services/local_sync_service.dart
  2. 13 6
      lib/services/memories_service.dart
  3. 49 23
      lib/services/remote_sync_service.dart
  4. 2 1
      lib/services/sync_service.dart
  5. 12 5
      lib/ui/account/login_page.dart
  6. 9 4
      lib/ui/account/password_reentry_page.dart
  7. 8 4
      lib/ui/account/recovery_key_page.dart
  8. 4 2
      lib/ui/account/two_factor_setup_page.dart
  9. 65 29
      lib/ui/collections_gallery_widget.dart
  10. 2 1
      lib/ui/common/bottomShadow.dart
  11. 4 2
      lib/ui/common/dynamicFAB.dart
  12. 2 1
      lib/ui/common/gradientButton.dart
  13. 4 2
      lib/ui/common/progress_dialog.dart
  14. 4 2
      lib/ui/grant_permissions_widget.dart
  15. 62 28
      lib/ui/home_widget.dart
  16. 13 6
      lib/ui/huge_listview/lazy_loading_gallery.dart
  17. 11 4
      lib/ui/landing_page_widget.dart
  18. 4 2
      lib/ui/loading_photos_widget.dart
  19. 17 9
      lib/ui/nav_bar.dart
  20. 9 4
      lib/ui/payment/payment_web_page.dart
  21. 22 9
      lib/ui/payment/stripe_subscription_page.dart
  22. 4 2
      lib/ui/payment/subscription_common_widgets.dart
  23. 8 4
      lib/ui/settings/app_update_dialog.dart
  24. 2 1
      lib/ui/settings/app_version_widget.dart
  25. 2 1
      lib/ui/settings/debug_section_widget.dart
  26. 35 14
      lib/ui/settings/details_section_widget.dart
  27. 4 1
      lib/ui/settings/theme_switch_widget.dart
  28. 3 1
      lib/ui/settings_page.dart
  29. 32 16
      lib/ui/sharing/manage_links_widget.dart
  30. 24 11
      lib/ui/sharing/share_collection_widget.dart
  31. 14 8
      lib/ui/tools/editor/image_editor_page.dart
  32. 6 3
      lib/ui/tools/free_space_page.dart
  33. 2 1
      lib/ui/viewer/file/custom_app_bar.dart
  34. 4 1
      lib/ui/viewer/file/exif_info_dialog.dart
  35. 15 6
      lib/ui/viewer/file/fading_app_bar.dart
  36. 4 2
      lib/ui/viewer/file/video_controls.dart
  37. 2 1
      lib/ui/viewer/file/video_widget.dart
  38. 12 5
      lib/ui/viewer/file/zoomable_image.dart
  39. 13 5
      lib/ui/viewer/gallery/device_folder_page.dart
  40. 17 7
      lib/ui/viewer/gallery/gallery_app_bar_widget.dart
  41. 28 11
      lib/ui/viewer/gallery/gallery_overlay_widget.dart
  42. 2 1
      lib/utils/file_sync_util.dart
  43. 64 30
      lib/utils/file_uploader.dart

+ 18 - 10
lib/services/local_sync_service.dart

@@ -27,13 +27,14 @@ class LocalSyncService {
   static const kPermissionStateKey = "permission_state";
   static const kEditedFileIDsKey = "edited_file_ids";
   static const kDownloadedFileIDsKey = "downloaded_file_ids";
+
   // Adding `_2` as a suffic to pull files that were earlier ignored due to permission errors
   // See https://github.com/CaiJingLong/flutter_photo_manager/issues/589
   static const kInvalidFileIDsKey = "invalid_file_ids_2";
-
   LocalSyncService._privateConstructor();
 
-  static final LocalSyncService instance = LocalSyncService._privateConstructor();
+  static final LocalSyncService instance =
+      LocalSyncService._privateConstructor();
 
   Future<void> init() async {
     _prefs = await SharedPreferences.getInstance();
@@ -113,7 +114,8 @@ class LocalSyncService {
         !_prefs.getBool(kHasCompletedFirstImportKey)) {
       await _prefs.setBool(kHasCompletedFirstImportKey, true);
       _logger.fine("first gallery import finished");
-      Bus.instance.fire(SyncStatusUpdate(SyncStatus.completedFirstGalleryImport));
+      Bus.instance
+          .fire(SyncStatusUpdate(SyncStatus.completedFirstGalleryImport));
     }
     final endTime = DateTime.now().microsecondsSinceEpoch;
     final duration = Duration(microseconds: endTime - startTime);
@@ -136,7 +138,8 @@ class LocalSyncService {
     );
     final existingIDs = await _db.getExistingLocalFileIDs();
     final invalidIDs = getInvalidFileIDs().toSet();
-    final unsyncedFiles = await getUnsyncedFiles(localAssets, existingIDs, invalidIDs, _computer);
+    final unsyncedFiles =
+        await getUnsyncedFiles(localAssets, existingIDs, invalidIDs, _computer);
     if (unsyncedFiles.isNotEmpty) {
       await _db.insertMultiple(unsyncedFiles);
       _logger.info(
@@ -199,7 +202,8 @@ class LocalSyncService {
   }
 
   bool hasGrantedLimitedPermissions() {
-    return _prefs.getString(kPermissionStateKey) == PermissionState.limited.toString();
+    return _prefs.getString(kPermissionStateKey) ==
+        PermissionState.limited.toString();
   }
 
   Future<void> onPermissionGranted(PermissionState state) async {
@@ -228,10 +232,12 @@ class LocalSyncService {
     final files = await getDeviceFiles(fromTime, toTime, _computer);
     if (files.isNotEmpty) {
       _logger.info("Fetched " + files.length.toString() + " files.");
-      final updatedFiles =
-          files.where((file) => existingLocalFileIDs.contains(file.localID)).toList();
+      final updatedFiles = files
+          .where((file) => existingLocalFileIDs.contains(file.localID))
+          .toList();
       updatedFiles.removeWhere((file) => editedFileIDs.contains(file.localID));
-      updatedFiles.removeWhere((file) => downloadedFileIDs.contains(file.localID));
+      updatedFiles
+          .removeWhere((file) => downloadedFileIDs.contains(file.localID));
       if (updatedFiles.isNotEmpty) {
         _logger.info(
           updatedFiles.length.toString() + " local files were updated.",
@@ -269,13 +275,15 @@ class LocalSyncService {
       if (Platform.isIOS) {
         var assetEntity = await AssetEntity.fromId(file.localID);
         if (assetEntity != null) {
-          var isLocallyAvailable = await assetEntity.isLocallyAvailable(isOrigin: true);
+          var isLocallyAvailable =
+              await assetEntity.isLocallyAvailable(isOrigin: true);
           _logger.info(
             're-upload asset ${file.toString()} with localAvailableFlag '
             '$isLocallyAvailable and fav ${assetEntity.isFavorite}',
           );
         } else {
-          _logger.info('re-upload failed to fetch assetInfo ${file.toString()}');
+          _logger
+              .info('re-upload failed to fetch assetInfo ${file.toString()}');
         }
       }
     } catch (ignore) {

+ 13 - 6
lib/services/memories_service.dart

@@ -65,12 +65,16 @@ class MemoriesService extends ChangeNotifier {
     final List<List<int>> durations = [];
     for (var yearAgo = 1; yearAgo <= yearsBefore; yearAgo++) {
       final date = _getDate(present, yearAgo);
-      final startCreationTime = date.subtract(Duration(days: daysBefore)).microsecondsSinceEpoch;
-      final endCreationTime = date.add(Duration(days: daysAfter)).microsecondsSinceEpoch;
+      final startCreationTime =
+          date.subtract(Duration(days: daysBefore)).microsecondsSinceEpoch;
+      final endCreationTime =
+          date.add(Duration(days: daysAfter)).microsecondsSinceEpoch;
       durations.add([startCreationTime, endCreationTime]);
     }
-    final archivedCollectionIds = CollectionsService.instance.getArchivedCollections();
-    final files = await _filesDB.getFilesCreatedWithinDurations(durations, archivedCollectionIds);
+    final archivedCollectionIds =
+        CollectionsService.instance.getArchivedCollections();
+    final files = await _filesDB.getFilesCreatedWithinDurations(
+        durations, archivedCollectionIds);
     final seenTimes = await _memoriesDB.getSeenTimes();
     final List<Memory> memories = [];
     final filter = ImportantItemsFilter();
@@ -86,8 +90,11 @@ class MemoriesService extends ChangeNotifier {
 
   DateTime _getDate(DateTime present, int yearAgo) {
     final year = (present.year - yearAgo).toString();
-    final month = present.month > 9 ? present.month.toString() : "0" + present.month.toString();
-    final day = present.day > 9 ? present.day.toString() : "0" + present.day.toString();
+    final month = present.month > 9
+        ? present.month.toString()
+        : "0" + present.month.toString();
+    final day =
+        present.day > 9 ? present.day.toString() : "0" + present.day.toString();
     final date = DateTime.parse(year + "-" + month + "-" + day);
     return date;
   }

+ 49 - 23
lib/services/remote_sync_service.dart

@@ -32,7 +32,8 @@ class RemoteSyncService {
   final _uploader = FileUploader.instance;
   final _collectionsService = CollectionsService.instance;
   final _diffFetcher = DiffFetcher();
-  final FileMigrationService _fileMigrationService = FileMigrationService.instance;
+  final FileMigrationService _fileMigrationService =
+      FileMigrationService.instance;
   int _completedUploads = 0;
   SharedPreferences _prefs;
   Completer<void> _existingSync;
@@ -48,7 +49,8 @@ class RemoteSyncService {
 
   static const kMaximumPermissibleUploadsInThrottledMode = 4;
 
-  static final RemoteSyncService instance = RemoteSyncService._privateConstructor();
+  static final RemoteSyncService instance =
+      RemoteSyncService._privateConstructor();
 
   RemoteSyncService._privateConstructor();
 
@@ -139,7 +141,8 @@ class RemoteSyncService {
   }
 
   Future<void> _syncUpdatedCollections(bool silently) async {
-    final updatedCollections = await _collectionsService.getCollectionsToBeSynced();
+    final updatedCollections =
+        await _collectionsService.getCollectionsToBeSynced();
 
     if (updatedCollections.isNotEmpty && !silently) {
       Bus.instance.fire(SyncStatusUpdate(SyncStatus.applyingRemoteDiff));
@@ -166,10 +169,12 @@ class RemoteSyncService {
   }
 
   Future<void> _syncCollectionDiff(int collectionID, int sinceTime) async {
-    final diff = await _diffFetcher.getEncryptedFilesDiff(collectionID, sinceTime);
+    final diff =
+        await _diffFetcher.getEncryptedFilesDiff(collectionID, sinceTime);
     if (diff.deletedFiles.isNotEmpty) {
       final fileIDs = diff.deletedFiles.map((f) => f.uploadedFileID).toList();
-      final deletedFiles = (await FilesDB.instance.getFilesFromIDs(fileIDs)).values.toList();
+      final deletedFiles =
+          (await FilesDB.instance.getFilesFromIDs(fileIDs)).values.toList();
       await FilesDB.instance.deleteFilesFromCollection(collectionID, fileIDs);
       Bus.instance.fire(
         CollectionUpdatedEvent(
@@ -194,7 +199,8 @@ class RemoteSyncService {
             collectionID.toString(),
       );
       Bus.instance.fire(LocalPhotosUpdatedEvent(diff.updatedFiles));
-      Bus.instance.fire(CollectionUpdatedEvent(collectionID, diff.updatedFiles));
+      Bus.instance
+          .fire(CollectionUpdatedEvent(collectionID, diff.updatedFiles));
     }
 
     if (diff.latestUpdatedAtTime > 0) {
@@ -214,23 +220,28 @@ class RemoteSyncService {
   Future<List<File>> _getFilesToBeUploaded() async {
     final foldersToBackUp = Configuration.instance.getPathsToBackUp();
     List<File> filesToBeUploaded;
-    if (LocalSyncService.instance.hasGrantedLimitedPermissions() && foldersToBackUp.isEmpty) {
+    if (LocalSyncService.instance.hasGrantedLimitedPermissions() &&
+        foldersToBackUp.isEmpty) {
       filesToBeUploaded = await _db.getAllLocalFiles();
     } else {
-      filesToBeUploaded = await _db.getFilesToBeUploadedWithinFolders(foldersToBackUp);
+      filesToBeUploaded =
+          await _db.getFilesToBeUploadedWithinFolders(foldersToBackUp);
     }
     if (!Configuration.instance.shouldBackupVideos() || _shouldThrottleSync()) {
-      filesToBeUploaded.removeWhere((element) => element.fileType == FileType.video);
+      filesToBeUploaded
+          .removeWhere((element) => element.fileType == FileType.video);
     }
     if (filesToBeUploaded.isNotEmpty) {
       final int prevCount = filesToBeUploaded.length;
       final ignoredIDs = await IgnoredFilesService.instance.ignoredIDs;
       filesToBeUploaded.removeWhere(
-        (file) => IgnoredFilesService.instance.shouldSkipUpload(ignoredIDs, file),
+        (file) =>
+            IgnoredFilesService.instance.shouldSkipUpload(ignoredIDs, file),
       );
       if (prevCount != filesToBeUploaded.length) {
         _logger.info(
-          (prevCount - filesToBeUploaded.length).toString() + " files were ignored for upload",
+          (prevCount - filesToBeUploaded.length).toString() +
+              " files were ignored for upload",
         );
       }
     }
@@ -254,7 +265,8 @@ class RemoteSyncService {
     _logger.info(editedFiles.length.toString() + " files edited.");
 
     _completedUploads = 0;
-    int toBeUploaded = filesToBeUploaded.length + updatedFileIDs.length + editedFiles.length;
+    int toBeUploaded =
+        filesToBeUploaded.length + updatedFileIDs.length + editedFiles.length;
 
     if (toBeUploaded > 0) {
       Bus.instance.fire(SyncStatusUpdate(SyncStatus.preparingForUpload));
@@ -265,8 +277,10 @@ class RemoteSyncService {
     }
     final List<Future> futures = [];
     for (final uploadedFileID in updatedFileIDs) {
-      if (_shouldThrottleSync() && futures.length >= kMaximumPermissibleUploadsInThrottledMode) {
-        _logger.info("Skipping some updated files as we are throttling uploads");
+      if (_shouldThrottleSync() &&
+          futures.length >= kMaximumPermissibleUploadsInThrottledMode) {
+        _logger
+            .info("Skipping some updated files as we are throttling uploads");
         break;
       }
       final file = await _db.getUploadedFileInAnyCollection(uploadedFileID);
@@ -274,19 +288,23 @@ class RemoteSyncService {
     }
 
     for (final file in filesToBeUploaded) {
-      if (_shouldThrottleSync() && futures.length >= kMaximumPermissibleUploadsInThrottledMode) {
+      if (_shouldThrottleSync() &&
+          futures.length >= kMaximumPermissibleUploadsInThrottledMode) {
         _logger.info("Skipping some new files as we are throttling uploads");
         break;
       }
       // prefer existing collection ID for manually uploaded files.
       // See https://github.com/ente-io/frame/pull/187
       final collectionID = file.collectionID ??
-          (await CollectionsService.instance.getOrCreateForPath(file.deviceFolder)).id;
+          (await CollectionsService.instance
+                  .getOrCreateForPath(file.deviceFolder))
+              .id;
       _uploadFile(file, collectionID, futures);
     }
 
     for (final file in editedFiles) {
-      if (_shouldThrottleSync() && futures.length >= kMaximumPermissibleUploadsInThrottledMode) {
+      if (_shouldThrottleSync() &&
+          futures.length >= kMaximumPermissibleUploadsInThrottledMode) {
         _logger.info("Skipping some edited files as we are throttling uploads");
         break;
       }
@@ -314,15 +332,17 @@ class RemoteSyncService {
   }
 
   void _uploadFile(File file, int collectionID, List<Future> futures) {
-    final future =
-        _uploader.upload(file, collectionID).then((uploadedFile) => _onFileUploaded(uploadedFile));
+    final future = _uploader
+        .upload(file, collectionID)
+        .then((uploadedFile) => _onFileUploaded(uploadedFile));
     futures.add(future);
   }
 
   Future<void> _onFileUploaded(File file) async {
     Bus.instance.fire(CollectionUpdatedEvent(file.collectionID, [file]));
     _completedUploads++;
-    final toBeUploadedInThisSession = FileUploader.instance.getCurrentSessionUploadCount();
+    final toBeUploadedInThisSession =
+        FileUploader.instance.getCurrentSessionUploadCount();
     if (toBeUploadedInThisSession == 0) {
       return;
     }
@@ -360,7 +380,9 @@ class RemoteSyncService {
       final existingFiles = file.deviceFolder == null
           ? null
           : await _db.getMatchingFiles(file.title, file.deviceFolder);
-      if (existingFiles == null || existingFiles.isEmpty || userID != file.ownerID) {
+      if (existingFiles == null ||
+          existingFiles.isEmpty ||
+          userID != file.ownerID) {
         // File uploaded from a different device or uploaded by different user
         // Other rare possibilities : The local file is present on
         // device but it's not imported in local db due to missing permission
@@ -378,7 +400,10 @@ class RemoteSyncService {
         // case when localID for a file changes and the file is uploaded again in
         // the same collection
         final fileWithLocalID = existingFiles.firstWhere(
-          (e) => file.localID != null && e.localID != null && e.localID == file.localID,
+          (e) =>
+              file.localID != null &&
+              e.localID != null &&
+              e.localID == file.localID,
           orElse: () => existingFiles.firstWhere(
             (e) => e.localID != null,
             orElse: () => null,
@@ -462,7 +487,8 @@ class RemoteSyncService {
   // return true if the client needs to re-sync the collections from previous
   // version
   bool _hasReSynced() {
-    return _prefs.containsKey(kHasSyncedEditTime) && _prefs.containsKey(kHasSyncedArchiveKey);
+    return _prefs.containsKey(kHasSyncedEditTime) &&
+        _prefs.containsKey(kHasSyncedArchiveKey);
   }
 
   Future<void> _markReSyncAsDone() async {

+ 2 - 1
lib/services/sync_service.dart

@@ -82,7 +82,8 @@ class SyncService {
     try {
       await _doSync();
       if (_lastSyncStatusEvent != null &&
-          _lastSyncStatusEvent.status != SyncStatus.completedFirstGalleryImport &&
+          _lastSyncStatusEvent.status !=
+              SyncStatus.completedFirstGalleryImport &&
           _lastSyncStatusEvent.status != SyncStatus.completedBackup) {
         Bus.instance.fire(SyncStatusUpdate(SyncStatus.completedBackup));
       }

+ 12 - 5
lib/ui/account/login_page.dart

@@ -56,7 +56,8 @@ class _LoginPageState extends State<LoginPage> {
         buttonText: 'Log in',
         onPressedFunction: () {
           UserService.instance.setEmail(_email);
-          UserService.instance.getOtt(context, _email, isCreateAccountScreen: false);
+          UserService.instance
+              .getOtt(context, _email, isCreateAccountScreen: false);
           FocusScope.of(context).unfocus();
         },
       ),
@@ -72,7 +73,8 @@ class _LoginPageState extends State<LoginPage> {
           child: ListView(
             children: [
               Padding(
-                padding: const EdgeInsets.symmetric(vertical: 30, horizontal: 20),
+                padding:
+                    const EdgeInsets.symmetric(vertical: 30, horizontal: 20),
                 child: Text(
                   'Welcome back!',
                   style: Theme.of(context).textTheme.headline4,
@@ -86,7 +88,8 @@ class _LoginPageState extends State<LoginPage> {
                     fillColor: _emailInputFieldColor,
                     filled: true,
                     hintText: 'Email',
-                    contentPadding: EdgeInsets.symmetric(horizontal: 15, vertical: 15),
+                    contentPadding:
+                        EdgeInsets.symmetric(horizontal: 15, vertical: 15),
                     border: UnderlineInputBorder(
                       borderSide: BorderSide.none,
                       borderRadius: BorderRadius.circular(6),
@@ -108,7 +111,8 @@ class _LoginPageState extends State<LoginPage> {
                       _email = value.trim();
                       _emailIsValid = EmailValidator.validate(_email);
                       if (_emailIsValid) {
-                        _emailInputFieldColor = Color.fromRGBO(45, 194, 98, 0.2);
+                        _emailInputFieldColor =
+                            Color.fromRGBO(45, 194, 98, 0.2);
                       } else {
                         _emailInputFieldColor = null;
                       }
@@ -134,7 +138,10 @@ class _LoginPageState extends State<LoginPage> {
                       flex: 5,
                       child: RichText(
                         text: TextSpan(
-                          style: Theme.of(context).textTheme.subtitle1.copyWith(fontSize: 12),
+                          style: Theme.of(context)
+                              .textTheme
+                              .subtitle1
+                              .copyWith(fontSize: 12),
                           children: [
                             TextSpan(
                               text: "By clicking log in, I agree to the ",

+ 9 - 4
lib/ui/account/password_reentry_page.dart

@@ -99,7 +99,8 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
           child: ListView(
             children: [
               Padding(
-                padding: const EdgeInsets.symmetric(vertical: 30, horizontal: 20),
+                padding:
+                    const EdgeInsets.symmetric(vertical: 30, horizontal: 20),
                 child: Text(
                   'Welcome back!',
                   style: Theme.of(context).textTheme.headline4,
@@ -120,7 +121,9 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
                     suffixIcon: _passwordInFocus
                         ? IconButton(
                             icon: Icon(
-                              _passwordVisible ? Icons.visibility : Icons.visibility_off,
+                              _passwordVisible
+                                  ? Icons.visibility
+                                  : Icons.visibility_off,
                               color: Theme.of(context).iconTheme.color,
                               size: 20,
                             ),
@@ -181,11 +184,13 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
                     GestureDetector(
                       behavior: HitTestBehavior.opaque,
                       onTap: () async {
-                        final dialog = createProgressDialog(context, "Please wait...");
+                        final dialog =
+                            createProgressDialog(context, "Please wait...");
                         await dialog.show();
                         await Configuration.instance.logout();
                         await dialog.hide();
-                        Navigator.of(context).popUntil((route) => route.isFirst);
+                        Navigator.of(context)
+                            .popUntil((route) => route.isFirst);
                       },
                       child: Center(
                         child: Text(

+ 8 - 4
lib/ui/account/recovery_key_page.dart

@@ -66,7 +66,8 @@ class _RecoveryKeyPageState extends State<RecoveryKeyPage> {
                   currentStep: 3,
                   selectedColor: Theme.of(context).buttonColor,
                   roundedEdges: Radius.circular(10),
-                  unselectedColor: Theme.of(context).colorScheme.stepProgressUnselectedColor,
+                  unselectedColor:
+                      Theme.of(context).colorScheme.stepProgressUnselectedColor,
                 ),
               ),
             )
@@ -115,7 +116,8 @@ class _RecoveryKeyPageState extends State<RecoveryKeyPage> {
               child: SizedBox(
                 //inner container
                 height: 120, //height of inner container
-                width: double.infinity, //width to 100% match to parent container.
+                width:
+                    double.infinity, //width to 100% match to parent container.
                 // ignore: prefer_const_literals_to_create_immutables
                 child: Column(
                   children: [
@@ -137,7 +139,8 @@ class _RecoveryKeyPageState extends State<RecoveryKeyPage> {
                           borderRadius: BorderRadius.all(
                             Radius.circular(2),
                           ),
-                          color: Theme.of(context).colorScheme.recoveryKeyBoxColor,
+                          color:
+                              Theme.of(context).colorScheme.recoveryKeyBoxColor,
                         ),
                         height: 120,
                         padding: EdgeInsets.all(20),
@@ -158,7 +161,8 @@ class _RecoveryKeyPageState extends State<RecoveryKeyPage> {
               child: Padding(
                 padding: EdgeInsets.symmetric(vertical: 20),
                 child: Text(
-                  widget.subText ?? "We don’t store this key, please save this in a safe place.",
+                  widget.subText ??
+                      "We don’t store this key, please save this in a safe place.",
                   style: Theme.of(context).textTheme.bodyText1,
                 ),
               ),

+ 4 - 2
lib/ui/account/two_factor_setup_page.dart

@@ -253,7 +253,8 @@ class _TwoFactorSetupPageState extends State<TwoFactorSetupPage>
   }
 
   Future<void> _enableTwoFactor(String code) async {
-    final success = await UserService.instance.enableTwoFactor(context, widget.secretCode, code);
+    final success = await UserService.instance
+        .enableTwoFactor(context, widget.secretCode, code);
     if (success) {
       _showSuccessPage();
     }
@@ -270,7 +271,8 @@ class _TwoFactorSetupPageState extends State<TwoFactorSetupPage>
         onDone: () {},
         title: "⚡ setup complete",
         text: "save your recovery key if you haven't already",
-        subText: "this can be used to recover your account if you lose your second factor",
+        subText:
+            "this can be used to recover your account if you lose your second factor",
       ),
     );
   }

+ 65 - 29
lib/ui/collections_gallery_widget.dart

@@ -33,7 +33,8 @@ class CollectionsGalleryWidget extends StatefulWidget {
   const CollectionsGalleryWidget({Key key}) : super(key: key);
 
   @override
-  State<CollectionsGalleryWidget> createState() => _CollectionsGalleryWidgetState();
+  State<CollectionsGalleryWidget> createState() =>
+      _CollectionsGalleryWidgetState();
 }
 
 class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
@@ -48,11 +49,13 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
 
   @override
   void initState() {
-    _localFilesSubscription = Bus.instance.on<LocalPhotosUpdatedEvent>().listen((event) {
+    _localFilesSubscription =
+        Bus.instance.on<LocalPhotosUpdatedEvent>().listen((event) {
       _loadReason = (LocalPhotosUpdatedEvent).toString();
       setState(() {});
     });
-    _collectionUpdatesSubscription = Bus.instance.on<CollectionUpdatedEvent>().listen((event) {
+    _collectionUpdatesSubscription =
+        Bus.instance.on<CollectionUpdatedEvent>().listen((event) {
       _loadReason = (CollectionUpdatedEvent).toString();
       setState(() {});
     });
@@ -60,7 +63,8 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
       _loadReason = (UserLoggedOutEvent).toString();
       setState(() {});
     });
-    _backupFoldersUpdatedEvent = Bus.instance.on<BackupFoldersUpdatedEvent>().listen((event) {
+    _backupFoldersUpdatedEvent =
+        Bus.instance.on<BackupFoldersUpdatedEvent>().listen((event) {
       _loadReason = (BackupFoldersUpdatedEvent).toString();
       setState(() {});
     });
@@ -96,11 +100,13 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
       folders.add(DeviceFolder(file.deviceFolder, file.deviceFolder, file));
     }
     folders.sort(
-      (first, second) => second.thumbnail.creationTime.compareTo(first.thumbnail.creationTime),
+      (first, second) =>
+          second.thumbnail.creationTime.compareTo(first.thumbnail.creationTime),
     );
 
     final List<CollectionWithThumbnail> collectionsWithThumbnail = [];
-    final latestCollectionFiles = await collectionsService.getLatestCollectionFiles();
+    final latestCollectionFiles =
+        await collectionsService.getLatestCollectionFiles();
     for (final file in latestCollectionFiles) {
       final c = collectionsService.getCollectionByID(file.collectionID);
       if (c.owner.id == userID) {
@@ -113,9 +119,11 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
           // alphabetical ASC order
           return first.collection.name.compareTo(second.collection.name);
         } else if (sortKey == AlbumSortKey.newestPhoto) {
-          return second.thumbnail.creationTime.compareTo(first.thumbnail.creationTime);
+          return second.thumbnail.creationTime
+              .compareTo(first.thumbnail.creationTime);
         } else {
-          return second.collection.updationTime.compareTo(first.collection.updationTime);
+          return second.collection.updationTime
+              .compareTo(first.collection.updationTime);
         }
       },
     );
@@ -125,7 +133,10 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
   Widget _getCollectionsGalleryWidget(CollectionItems items) {
     const double horizontalPaddingOfGridRow = 16;
     const double crossAxisSpacingOfGrid = 9;
-    final TextStyle trashAndHiddenTextStyle = Theme.of(context).textTheme.subtitle1.copyWith(
+    final TextStyle trashAndHiddenTextStyle = Theme.of(context)
+        .textTheme
+        .subtitle1
+        .copyWith(
           color: Theme.of(context).textTheme.subtitle1.color.withOpacity(0.5),
         );
     Size size = MediaQuery.of(context).size;
@@ -199,7 +210,8 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
                         crossAxisCount: albumsCountInOneRow,
                         mainAxisSpacing: 12,
                         crossAxisSpacing: crossAxisSpacingOfGrid,
-                        childAspectRatio: sideOfThumbnail / (sideOfThumbnail + 24),
+                        childAspectRatio:
+                            sideOfThumbnail / (sideOfThumbnail + 24),
                       ), //24 is height of album title
                     ),
                   )
@@ -220,7 +232,8 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
                       padding: EdgeInsets.all(0),
                       side: BorderSide(
                         width: 0.5,
-                        color: Theme.of(context).iconTheme.color.withOpacity(0.24),
+                        color:
+                            Theme.of(context).iconTheme.color.withOpacity(0.24),
                       ),
                     ),
                     child: SizedBox(
@@ -248,7 +261,9 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
                                           children: [
                                             TextSpan(
                                               text: "Trash",
-                                              style: Theme.of(context).textTheme.subtitle1,
+                                              style: Theme.of(context)
+                                                  .textTheme
+                                                  .subtitle1,
                                             ),
                                             TextSpan(text: "  \u2022  "),
                                             TextSpan(
@@ -265,7 +280,9 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
                                           children: [
                                             TextSpan(
                                               text: "Trash",
-                                              style: Theme.of(context).textTheme.subtitle1,
+                                              style: Theme.of(context)
+                                                  .textTheme
+                                                  .subtitle1,
                                             ),
                                             //need to query in db and bring this value
                                           ],
@@ -301,7 +318,8 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
                       padding: EdgeInsets.all(0),
                       side: BorderSide(
                         width: 0.5,
-                        color: Theme.of(context).iconTheme.color.withOpacity(0.24),
+                        color:
+                            Theme.of(context).iconTheme.color.withOpacity(0.24),
                       ),
                     ),
                     child: SizedBox(
@@ -320,7 +338,8 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
                                 ),
                                 Padding(padding: EdgeInsets.all(6)),
                                 FutureBuilder<int>(
-                                  future: FilesDB.instance.fileCountWithVisibility(
+                                  future:
+                                      FilesDB.instance.fileCountWithVisibility(
                                     kVisibilityArchive,
                                     Configuration.instance.getUserID(),
                                   ),
@@ -332,7 +351,9 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
                                           children: [
                                             TextSpan(
                                               text: "Hidden",
-                                              style: Theme.of(context).textTheme.subtitle1,
+                                              style: Theme.of(context)
+                                                  .textTheme
+                                                  .subtitle1,
                                             ),
                                             TextSpan(text: "  \u2022  "),
                                             TextSpan(
@@ -349,7 +370,9 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
                                           children: [
                                             TextSpan(
                                               text: "Hidden",
-                                              style: Theme.of(context).textTheme.subtitle1,
+                                              style: Theme.of(context)
+                                                  .textTheme
+                                                  .subtitle1,
                                             ),
                                             //need to query in db and bring this value
                                           ],
@@ -488,7 +511,8 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
             "long press to select photos and click + to create an album",
             toastLength: Toast.LENGTH_LONG,
           );
-          Bus.instance.fire(TabChangedEvent(0, TabChangedEventSource.collectionsPage));
+          Bus.instance
+              .fire(TabChangedEvent(0, TabChangedEventSource.collectionsPage));
         },
       );
     }
@@ -542,7 +566,8 @@ class DeviceFolderIcon extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    final isBackedUp = Configuration.instance.getPathsToBackUp().contains(folder.path);
+    final isBackedUp =
+        Configuration.instance.getPathsToBackUp().contains(folder.path);
     return GestureDetector(
       child: Padding(
         padding: const EdgeInsets.symmetric(horizontal: 2),
@@ -558,14 +583,17 @@ class DeviceFolderIcon extends StatelessWidget {
                   height: 120,
                   width: 120,
                   child: Hero(
-                    tag: "device_folder:" + folder.path + folder.thumbnail.tag(),
+                    tag:
+                        "device_folder:" + folder.path + folder.thumbnail.tag(),
                     child: Stack(
                       children: [
                         ThumbnailWidget(
                           folder.thumbnail,
                           shouldShowSyncStatus: false,
                           key: Key(
-                            "device_folder:" + folder.path + folder.thumbnail.tag(),
+                            "device_folder:" +
+                                folder.path +
+                                folder.thumbnail.tag(),
                           ),
                         ),
                         isBackedUp ? Container() : kUnsyncedIconOverlay,
@@ -578,7 +606,10 @@ class DeviceFolderIcon extends StatelessWidget {
                 padding: const EdgeInsets.only(top: 10),
                 child: Text(
                   folder.name,
-                  style: Theme.of(context).textTheme.subtitle1.copyWith(fontSize: 12),
+                  style: Theme.of(context)
+                      .textTheme
+                      .subtitle1
+                      .copyWith(fontSize: 12),
                   overflow: TextOverflow.ellipsis,
                 ),
               ),
@@ -607,11 +638,12 @@ class CollectionItem extends StatelessWidget {
     const double crossAxisSpacingOfGrid = 9;
     Size size = MediaQuery.of(context).size;
     int albumsCountInOneRow = max(size.width ~/ 220.0, 2);
-    double totalWhiteSpaceOfRow =
-        (horizontalPaddingOfGridRow * 2) + (albumsCountInOneRow - 1) * crossAxisSpacingOfGrid;
-    TextStyle albumTitleTextStyle = Theme.of(context).textTheme.subtitle1.copyWith(fontSize: 14);
-    final double sideOfThumbnail =
-        (size.width / albumsCountInOneRow) - (totalWhiteSpaceOfRow / albumsCountInOneRow);
+    double totalWhiteSpaceOfRow = (horizontalPaddingOfGridRow * 2) +
+        (albumsCountInOneRow - 1) * crossAxisSpacingOfGrid;
+    TextStyle albumTitleTextStyle =
+        Theme.of(context).textTheme.subtitle1.copyWith(fontSize: 14);
+    final double sideOfThumbnail = (size.width / albumsCountInOneRow) -
+        (totalWhiteSpaceOfRow / albumsCountInOneRow);
     return GestureDetector(
       child: Column(
         crossAxisAlignment: CrossAxisAlignment.start,
@@ -697,7 +729,8 @@ class SectionTitle extends StatelessWidget {
             alignment: alignment,
             child: Text(
               title,
-              style: Theme.of(context).textTheme.headline6.copyWith(fontSize: 22),
+              style:
+                  Theme.of(context).textTheme.headline6.copyWith(fontSize: 22),
             ),
           ),
         ],
@@ -727,7 +760,10 @@ class EnteSectionTitle extends StatelessWidget {
                 children: [
                   TextSpan(
                     text: "On ",
-                    style: Theme.of(context).textTheme.headline6.copyWith(fontSize: 22),
+                    style: Theme.of(context)
+                        .textTheme
+                        .headline6
+                        .copyWith(fontSize: 22),
                   ),
                   TextSpan(
                     text: "ente",

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

@@ -3,7 +3,8 @@ import 'package:flutter/material.dart';
 class BottomShadowWidget extends StatelessWidget {
   final double offsetDy;
   final Color shadowColor;
-  const BottomShadowWidget({this.offsetDy = 28, this.shadowColor, Key key}) : super(key: key);
+  const BottomShadowWidget({this.offsetDy = 28, this.shadowColor, Key key})
+      : super(key: key);
 
   @override
   Widget build(BuildContext context) {

+ 4 - 2
lib/ui/common/dynamicFAB.dart

@@ -37,8 +37,10 @@ class DynamicFAB extends StatelessWidget {
           children: [
             FloatingActionButton(
               heroTag: 'FAB',
-              backgroundColor: Theme.of(context).colorScheme.dynamicFABBackgroundColor,
-              foregroundColor: Theme.of(context).colorScheme.dynamicFABTextColor,
+              backgroundColor:
+                  Theme.of(context).colorScheme.dynamicFABBackgroundColor,
+              foregroundColor:
+                  Theme.of(context).colorScheme.dynamicFABTextColor,
               onPressed: isFormValid
                   ? onPressedFunction
                   : () {

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

@@ -5,7 +5,8 @@ class GradientButton extends StatelessWidget {
   final List<Color> linearGradientColors;
   final Function onTap;
 
-  GradientButton({Key key, this.child, this.linearGradientColors, this.onTap}) : super(key: key);
+  GradientButton({Key key, this.child, this.linearGradientColors, this.onTap})
+      : super(key: key);
 
   @override
   Widget build(BuildContext context) {

+ 4 - 2
lib/ui/common/progress_dialog.dart

@@ -93,7 +93,8 @@ class ProgressDialog {
     _textAlign = textAlign ?? _textAlign;
     _progressWidget = child ?? _progressWidget;
     _dialogPadding = padding ?? _dialogPadding;
-    _progressWidgetAlignment = progressWidgetAlignment ?? _progressWidgetAlignment;
+    _progressWidgetAlignment =
+        progressWidgetAlignment ?? _progressWidgetAlignment;
   }
 
   void update({
@@ -157,7 +158,8 @@ class ProgressDialog {
                 insetAnimationDuration: Duration(milliseconds: 100),
                 elevation: _dialogElevation,
                 shape: RoundedRectangleBorder(
-                  borderRadius: BorderRadius.all(Radius.circular(_borderRadius)),
+                  borderRadius:
+                      BorderRadius.all(Radius.circular(_borderRadius)),
                 ),
                 child: _dialog,
               ),

+ 4 - 2
lib/ui/grant_permissions_widget.dart

@@ -8,7 +8,8 @@ class GrantPermissionsWidget extends StatelessWidget {
   const GrantPermissionsWidget({Key key}) : super(key: key);
   @override
   Widget build(BuildContext context) {
-    final isLightMode = MediaQuery.of(context).platformBrightness == Brightness.light;
+    final isLightMode =
+        MediaQuery.of(context).platformBrightness == Brightness.light;
     return Scaffold(
       body: SingleChildScrollView(
         child: Column(
@@ -95,7 +96,8 @@ class GrantPermissionsWidget extends StatelessWidget {
           child: Text("Grant permission"),
           onPressed: () async {
             final state = await PhotoManager.requestPermissionExtend();
-            if (state == PermissionState.authorized || state == PermissionState.limited) {
+            if (state == PermissionState.authorized ||
+                state == PermissionState.limited) {
               await SyncService.instance.onPermissionGranted(state);
             } else if (state == PermissionState.denied) {
               AlertDialog alert = AlertDialog(

+ 62 - 28
lib/ui/home_widget.dart

@@ -102,7 +102,8 @@ class _HomeWidgetState extends State<HomeWidget> {
         ],
       ),
     );
-    _tabChangedEventSubscription = Bus.instance.on<TabChangedEvent>().listen((event) {
+    _tabChangedEventSubscription =
+        Bus.instance.on<TabChangedEvent>().listen((event) {
       if (event.source != TabChangedEventSource.pageView) {
         _selectedTabIndex = event.selectedIndex;
         _pageController.animateToPage(
@@ -112,13 +113,16 @@ class _HomeWidgetState extends State<HomeWidget> {
         );
       }
     });
-    _subscriptionPurchaseEvent = Bus.instance.on<SubscriptionPurchasedEvent>().listen((event) {
+    _subscriptionPurchaseEvent =
+        Bus.instance.on<SubscriptionPurchasedEvent>().listen((event) {
       setState(() {});
     });
-    _accountConfiguredEvent = Bus.instance.on<AccountConfiguredEvent>().listen((event) {
+    _accountConfiguredEvent =
+        Bus.instance.on<AccountConfiguredEvent>().listen((event) {
       setState(() {});
     });
-    _triggerLogoutEvent = Bus.instance.on<TriggerLogoutEvent>().listen((event) async {
+    _triggerLogoutEvent =
+        Bus.instance.on<TriggerLogoutEvent>().listen((event) async {
       AlertDialog alert = AlertDialog(
         title: Text("Session expired"),
         content: Text("Please login again"),
@@ -155,12 +159,14 @@ class _HomeWidgetState extends State<HomeWidget> {
         setState(() {});
       }
     });
-    _permissionGrantedEvent = Bus.instance.on<PermissionGrantedEvent>().listen((event) async {
+    _permissionGrantedEvent =
+        Bus.instance.on<PermissionGrantedEvent>().listen((event) async {
       if (mounted) {
         setState(() {});
       }
     });
-    _firstImportEvent = Bus.instance.on<SyncStatusUpdate>().listen((event) async {
+    _firstImportEvent =
+        Bus.instance.on<SyncStatusUpdate>().listen((event) async {
       if (mounted && event.status == SyncStatus.completedFirstGalleryImport) {
         Duration delayInRefresh = Duration(milliseconds: 0);
         // Loading page will redirect to BackupFolderSelectionPage.
@@ -182,7 +188,8 @@ class _HomeWidgetState extends State<HomeWidget> {
         );
       }
     });
-    _backupFoldersUpdatedEvent = Bus.instance.on<BackupFoldersUpdatedEvent>().listen((event) async {
+    _backupFoldersUpdatedEvent =
+        Bus.instance.on<BackupFoldersUpdatedEvent>().listen((event) async {
       if (mounted) {
         setState(() {});
       }
@@ -222,7 +229,8 @@ class _HomeWidgetState extends State<HomeWidget> {
   }
 
   void _initMediaShareSubscription() {
-    _intentDataStreamSubscription = ReceiveSharingIntent.getMediaStream().listen(
+    _intentDataStreamSubscription =
+        ReceiveSharingIntent.getMediaStream().listen(
       (List<SharedMediaFile> value) {
         setState(() {
           _sharedFiles = value;
@@ -261,7 +269,8 @@ class _HomeWidgetState extends State<HomeWidget> {
             return true;
           }
         } else {
-          Bus.instance.fire(TabChangedEvent(0, TabChangedEventSource.backButton));
+          Bus.instance
+              .fire(TabChangedEvent(0, TabChangedEventSource.backButton));
           return false;
         }
       },
@@ -283,9 +292,10 @@ class _HomeWidgetState extends State<HomeWidget> {
       return CreateCollectionPage(null, _sharedFiles);
     }
 
-    final bool showBackupFolderHook = Configuration.instance.getPathsToBackUp().isEmpty &&
-        !LocalSyncService.instance.hasGrantedLimitedPermissions() &&
-        CollectionsService.instance.getActiveCollections().isEmpty;
+    final bool showBackupFolderHook =
+        Configuration.instance.getPathsToBackUp().isEmpty &&
+            !LocalSyncService.instance.hasGrantedLimitedPermissions() &&
+            CollectionsService.instance.getActiveCollections().isEmpty;
     return Stack(
       children: [
         ExtentsPageView(
@@ -299,7 +309,9 @@ class _HomeWidgetState extends State<HomeWidget> {
           },
           controller: _pageController,
           children: [
-            showBackupFolderHook ? _getBackupFolderSelectionHook() : _getMainGalleryWidget(),
+            showBackupFolderHook
+                ? _getBackupFolderSelectionHook()
+                : _getMainGalleryWidget(),
             _deviceFolderGalleryWidget,
             _sharedCollectionGallery,
             _settingsPage,
@@ -375,7 +387,8 @@ class _HomeWidgetState extends State<HomeWidget> {
       asyncLoader: (creationStartTime, creationEndTime, {limit, asc}) async {
         final importantPaths = Configuration.instance.getPathsToBackUp();
         final ownerID = Configuration.instance.getUserID();
-        final archivedCollectionIds = CollectionsService.instance.getArchivedCollections();
+        final archivedCollectionIds =
+            CollectionsService.instance.getArchivedCollections();
         FileLoadResult result;
         if (importantPaths.isNotEmpty) {
           result = await FilesDB.instance.getImportantFiles(
@@ -476,7 +489,8 @@ class _HomeWidgetState extends State<HomeWidget> {
                     Color(0xFF1DB954),
                   ],
                   onTap: () async {
-                    if (LocalSyncService.instance.hasGrantedLimitedPermissions()) {
+                    if (LocalSyncService.instance
+                        .hasGrantedLimitedPermissions()) {
                       PhotoManager.presentLimited();
                     } else {
                       routeToPage(
@@ -552,7 +566,8 @@ class HomeBottomNavigationBar extends StatefulWidget {
   final int selectedTabIndex;
 
   @override
-  State<HomeBottomNavigationBar> createState() => _HomeBottomNavigationBarState();
+  State<HomeBottomNavigationBar> createState() =>
+      _HomeBottomNavigationBarState();
 }
 
 class _HomeBottomNavigationBarState extends State<HomeBottomNavigationBar> {
@@ -566,7 +581,8 @@ class _HomeBottomNavigationBarState extends State<HomeBottomNavigationBar> {
     widget.selectedFiles.addListener(() {
       setState(() {});
     });
-    _tabChangedEventSubscription = Bus.instance.on<TabChangedEvent>().listen((event) {
+    _tabChangedEventSubscription =
+        Bus.instance.on<TabChangedEvent>().listen((event) {
       if (event.source != TabChangedEventSource.tabBar) {
         debugPrint('index changed to ${event.selectedIndex}');
         if (mounted) {
@@ -623,23 +639,32 @@ class _HomeBottomNavigationBarState extends State<HomeBottomNavigationBar> {
                           filter: ImageFilter.blur(sigmaX: 20, sigmaY: 20),
                           child: GNav(
                             curve: Curves.easeOutExpo,
-                            backgroundColor: Theme.of(context).colorScheme.gNavBackgroundColor,
+                            backgroundColor: Theme.of(context)
+                                .colorScheme
+                                .gNavBackgroundColor,
                             mainAxisAlignment: MainAxisAlignment.center,
                             rippleColor: Colors.white.withOpacity(0.1),
-                            activeColor: Theme.of(context).colorScheme.gNavBarActiveColor,
+                            activeColor: Theme.of(context)
+                                .colorScheme
+                                .gNavBarActiveColor,
                             iconSize: 24,
                             padding: EdgeInsets.fromLTRB(16, 8, 16, 8),
                             duration: Duration(milliseconds: 200),
                             gap: 0,
                             tabBorderRadius: 24,
-                            tabBackgroundColor: Theme.of(context).colorScheme.gNavBarActiveColor,
+                            tabBackgroundColor: Theme.of(context)
+                                .colorScheme
+                                .gNavBarActiveColor,
                             haptic: false,
                             tabs: [
                               GButton(
                                 margin: EdgeInsets.fromLTRB(6, 6, 0, 6),
                                 icon: Icons.home,
-                                iconColor: Theme.of(context).colorScheme.gNavIconColor,
-                                iconActiveColor: Theme.of(context).colorScheme.gNavActiveIconColor,
+                                iconColor:
+                                    Theme.of(context).colorScheme.gNavIconColor,
+                                iconActiveColor: Theme.of(context)
+                                    .colorScheme
+                                    .gNavActiveIconColor,
                                 text: '',
                                 onPressed: () {
                                   _onTabChange(
@@ -650,8 +675,11 @@ class _HomeBottomNavigationBarState extends State<HomeBottomNavigationBar> {
                               GButton(
                                 margin: EdgeInsets.fromLTRB(0, 6, 0, 6),
                                 icon: Icons.photo_library,
-                                iconColor: Theme.of(context).colorScheme.gNavIconColor,
-                                iconActiveColor: Theme.of(context).colorScheme.gNavActiveIconColor,
+                                iconColor:
+                                    Theme.of(context).colorScheme.gNavIconColor,
+                                iconActiveColor: Theme.of(context)
+                                    .colorScheme
+                                    .gNavActiveIconColor,
                                 text: '',
                                 onPressed: () {
                                   _onTabChange(
@@ -662,8 +690,11 @@ class _HomeBottomNavigationBarState extends State<HomeBottomNavigationBar> {
                               GButton(
                                 margin: EdgeInsets.fromLTRB(0, 6, 0, 6),
                                 icon: Icons.folder_shared,
-                                iconColor: Theme.of(context).colorScheme.gNavIconColor,
-                                iconActiveColor: Theme.of(context).colorScheme.gNavActiveIconColor,
+                                iconColor:
+                                    Theme.of(context).colorScheme.gNavIconColor,
+                                iconActiveColor: Theme.of(context)
+                                    .colorScheme
+                                    .gNavActiveIconColor,
                                 text: '',
                                 onPressed: () {
                                   _onTabChange(
@@ -674,8 +705,11 @@ class _HomeBottomNavigationBarState extends State<HomeBottomNavigationBar> {
                               GButton(
                                 margin: EdgeInsets.fromLTRB(0, 6, 6, 6),
                                 icon: Icons.person,
-                                iconColor: Theme.of(context).colorScheme.gNavIconColor,
-                                iconActiveColor: Theme.of(context).colorScheme.gNavActiveIconColor,
+                                iconColor:
+                                    Theme.of(context).colorScheme.gNavIconColor,
+                                iconActiveColor: Theme.of(context)
+                                    .colorScheme
+                                    .gNavActiveIconColor,
                                 text: '',
                                 onPressed: () {
                                   _onTabChange(

+ 13 - 6
lib/ui/huge_listview/lazy_loading_gallery.dart

@@ -70,8 +70,10 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
 
     _reloadEventSubscription = widget.reloadEvent.listen((e) => _onReload(e));
 
-    _currentIndexSubscription = widget.currentIndexStream.listen((currentIndex) {
-      bool shouldRender = (currentIndex - widget.index).abs() < kNumberOfDaysToRenderBeforeAndAfter;
+    _currentIndexSubscription =
+        widget.currentIndexStream.listen((currentIndex) {
+      bool shouldRender = (currentIndex - widget.index).abs() <
+          kNumberOfDaysToRenderBeforeAndAfter;
       if (mounted && shouldRender != _shouldRender) {
         setState(() {
           _shouldRender = shouldRender;
@@ -81,7 +83,8 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
   }
 
   Future _onReload(FilesUpdatedEvent event) async {
-    final galleryDate = DateTime.fromMicrosecondsSinceEpoch(_files[0].creationTime);
+    final galleryDate =
+        DateTime.fromMicrosecondsSinceEpoch(_files[0].creationTime);
     final filesUpdatedThisDay = event.updatedFiles.where((file) {
       final fileDate = DateTime.fromMicrosecondsSinceEpoch(file.creationTime);
       return fileDate.year == galleryDate.year &&
@@ -95,7 +98,8 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
             getDayTitle(galleryDate.microsecondsSinceEpoch),
       );
       if (event.type == EventType.addedOrUpdated) {
-        final dayStartTime = DateTime(galleryDate.year, galleryDate.month, galleryDate.day);
+        final dayStartTime =
+            DateTime(galleryDate.year, galleryDate.month, galleryDate.day);
         final result = await widget.asyncLoader(
           dayStartTime.microsecondsSinceEpoch,
           dayStartTime.microsecondsSinceEpoch + kMicroSecondsInDay - 1,
@@ -253,7 +257,9 @@ class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
           });
         }
       },
-      child: _shouldRender ? _getGridView() : PlaceHolderWidget(widget.files.length),
+      child: _shouldRender
+          ? _getGridView()
+          : PlaceHolderWidget(widget.files.length),
     );
   }
 
@@ -278,7 +284,8 @@ class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
   Widget _getGridView() {
     return GridView.builder(
       shrinkWrap: true,
-      physics: NeverScrollableScrollPhysics(), // to disable GridView's scrolling
+      physics:
+          NeverScrollableScrollPhysics(), // to disable GridView's scrolling
       itemBuilder: (context, index) {
         return _buildFile(context, widget.files[index]);
       },

+ 11 - 4
lib/ui/landing_page_widget.dart

@@ -51,7 +51,8 @@ class _LandingPageWidgetState extends State<LandingPageWidget> {
               dotsCount: 3,
               position: _featureIndex,
               decorator: DotsDecorator(
-                activeColor: Theme.of(context).colorScheme.dotsIndicatorActiveColor,
+                activeColor:
+                    Theme.of(context).colorScheme.dotsIndicatorActiveColor,
                 color: Theme.of(context).colorScheme.dotsIndicatorInactiveColor,
                 activeShape: RoundedRectangleBorder(
                   borderRadius: BorderRadius.circular(3),
@@ -74,7 +75,8 @@ class _LandingPageWidgetState extends State<LandingPageWidget> {
               child: Hero(
                 tag: "log_in",
                 child: ElevatedButton(
-                  style: Theme.of(context).colorScheme.optionalActionButtonStyle,
+                  style:
+                      Theme.of(context).colorScheme.optionalActionButtonStyle,
                   onPressed: _navigateToSignInPage,
                   child: Text(
                     "Existing user",
@@ -133,7 +135,9 @@ class _LandingPageWidgetState extends State<LandingPageWidget> {
             "assets/onboarding_lock.png",
             "Available",
             "everywhere",
-            Platform.isAndroid ? "Android, iOS, Web, Desktop" : "iOS, Android, Web, Desktop",
+            Platform.isAndroid
+                ? "Android, iOS, Web, Desktop"
+                : "iOS, Android, Web, Desktop",
           ),
         ],
         onPageChanged: (index) {
@@ -199,7 +203,10 @@ class _LandingPageWidgetState extends State<LandingPageWidget> {
 }
 
 class FeatureItemWidget extends StatelessWidget {
-  final String assetPath, featureTitleFirstLine, featureTitleSecondLine, subText;
+  final String assetPath,
+      featureTitleFirstLine,
+      featureTitleSecondLine,
+      subText;
 
   const FeatureItemWidget(
     this.assetPath,

+ 4 - 2
lib/ui/loading_photos_widget.dart

@@ -37,7 +37,8 @@ class _LoadingPhotosWidgetState extends State<LoadingPhotosWidget> {
   @override
   void initState() {
     super.initState();
-    _firstImportEvent = Bus.instance.on<SyncStatusUpdate>().listen((event) async {
+    _firstImportEvent =
+        Bus.instance.on<SyncStatusUpdate>().listen((event) async {
       if (mounted && event.status == SyncStatus.completedFirstGalleryImport) {
         if (LocalSyncService.instance.hasGrantedLimitedPermissions()) {
           // Do nothing, let HomeWidget refresh
@@ -78,7 +79,8 @@ class _LoadingPhotosWidgetState extends State<LoadingPhotosWidget> {
 
   @override
   Widget build(BuildContext context) {
-    final isLightMode = MediaQuery.of(context).platformBrightness == Brightness.light;
+    final isLightMode =
+        MediaQuery.of(context).platformBrightness == Brightness.light;
     return Scaffold(
       body: SingleChildScrollView(
         child: Center(

+ 17 - 9
lib/ui/nav_bar.dart

@@ -101,16 +101,20 @@ class _GNavState extends State<GNav> {
                 iconColor: t.iconColor ?? widget.color,
                 iconSize: t.iconSize ?? widget.iconSize,
                 textColor: t.textColor ?? widget.activeColor,
-                rippleColor: t.rippleColor ?? widget.rippleColor ?? Colors.transparent,
-                hoverColor: t.hoverColor ?? widget.hoverColor ?? Colors.transparent,
+                rippleColor:
+                    t.rippleColor ?? widget.rippleColor ?? Colors.transparent,
+                hoverColor:
+                    t.hoverColor ?? widget.hoverColor ?? Colors.transparent,
                 padding: t.padding ?? widget.padding,
                 icon: t.icon,
                 haptic: widget.haptic ?? true,
                 leading: t.leading,
                 curve: widget.curve ?? Curves.easeInCubic,
-                backgroundGradient: t.backgroundGradient ?? widget.tabBackgroundGradient,
-                backgroundColor:
-                    t.backgroundColor ?? widget.tabBackgroundColor ?? Colors.transparent,
+                backgroundGradient:
+                    t.backgroundGradient ?? widget.tabBackgroundGradient,
+                backgroundColor: t.backgroundColor ??
+                    widget.tabBackgroundColor ??
+                    Colors.transparent,
                 duration: widget.duration ?? const Duration(milliseconds: 500),
                 onPressed: () {
                   if (!clickable) return;
@@ -120,7 +124,8 @@ class _GNavState extends State<GNav> {
                   });
                   widget.onTabChange(selectedIndex);
 
-                  Future.delayed(widget.duration ?? const Duration(milliseconds: 500), () {
+                  Future.delayed(
+                      widget.duration ?? const Duration(milliseconds: 500), () {
                     setState(() {
                       clickable = true;
                     });
@@ -296,8 +301,9 @@ class _ButtonState extends State<Button> with TickerProviderStateMixin {
     super.initState();
     _expanded = widget.active;
 
-    expandController = AnimationController(vsync: this, duration: widget.duration)
-      ..addListener(() => setState(() {}));
+    expandController =
+        AnimationController(vsync: this, duration: widget.duration)
+          ..addListener(() => setState(() {}));
   }
 
   @override
@@ -344,7 +350,9 @@ class _ButtonState extends State<Button> with TickerProviderStateMixin {
             // curve: !_expanded ? widget.curve : widget.curve.flipped,
             decoration: BoxDecoration(
               boxShadow: widget.shadow,
-              border: widget.active ? (widget.activeBorder ?? widget.border) : widget.border,
+              border: widget.active
+                  ? (widget.activeBorder ?? widget.border)
+                  : widget.border,
               gradient: widget.gradient,
               color: _expanded
                   ? widget.color.withOpacity(0)

+ 9 - 4
lib/ui/payment/payment_web_page.dart

@@ -15,7 +15,8 @@ class PaymentWebPage extends StatefulWidget {
   final String planId;
   final String actionType;
 
-  const PaymentWebPage({Key key, this.planId, this.actionType}) : super(key: key);
+  const PaymentWebPage({Key key, this.planId, this.actionType})
+      : super(key: key);
 
   @override
   State<StatefulWidget> createState() => _PaymentWebPageState();
@@ -57,11 +58,14 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
         ),
         body: Column(
           children: <Widget>[
-            (progress != 1.0) ? LinearProgressIndicator(value: progress) : Container(),
+            (progress != 1.0)
+                ? LinearProgressIndicator(value: progress)
+                : Container(),
             Expanded(
               child: InAppWebView(
                 initialUrlRequest: URLRequest(url: initPaymentUrl),
-                onProgressChanged: (InAppWebViewController controller, int progress) {
+                onProgressChanged:
+                    (InAppWebViewController controller, int progress) {
                   setState(() {
                     this.progress = progress / 100;
                   });
@@ -94,7 +98,8 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
                     await _dialog.hide();
                   }
                 },
-                onLoadHttpError: (controller, navigationAction, code, msg) async {
+                onLoadHttpError:
+                    (controller, navigationAction, code, msg) async {
                   _logger.info("onHttpError with $code and msg = $msg");
                 },
                 onLoadStop: (controller, navigationAction) async {

+ 22 - 9
lib/ui/payment/stripe_subscription_page.dart

@@ -58,7 +58,9 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
   }
 
   Future<void> _fetchSub() async {
-    return _userService.getUserDetailsV2(memoryCount: false).then((userDetails) async {
+    return _userService
+        .getUserDetailsV2(memoryCount: false)
+        .then((userDetails) async {
       _userDetails = userDetails;
       _currentSubscription = userDetails.subscription;
       _showYearlyPlan = _currentSubscription.isYearlyPlan();
@@ -133,7 +135,9 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
                     currentStep: 4,
                     selectedColor: Theme.of(context).buttonColor,
                     roundedEdges: Radius.circular(10),
-                    unselectedColor: Theme.of(context).colorScheme.stepProgressUnselectedColor,
+                    unselectedColor: Theme.of(context)
+                        .colorScheme
+                        .stepProgressUnselectedColor,
                   ),
                 ),
               )
@@ -249,8 +253,9 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
                         color: Theme.of(context).colorScheme.onSurface,
                         fontFamily: 'Inter-Medium',
                         fontSize: 14,
-                        decoration:
-                            _isStripeSubscriber ? TextDecoration.underline : TextDecoration.none,
+                        decoration: _isStripeSubscriber
+                            ? TextDecoration.underline
+                            : TextDecoration.none,
                       ),
                     ),
                     textAlign: TextAlign.center,
@@ -347,13 +352,17 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
   }
 
   Widget _stripeRenewOrCancelButton() {
-    bool isRenewCancelled = _currentSubscription.attributes?.isCancelled ?? false;
-    String title = isRenewCancelled ? "Renew subscription" : "Cancel subscription";
+    bool isRenewCancelled =
+        _currentSubscription.attributes?.isCancelled ?? false;
+    String title =
+        isRenewCancelled ? "Renew subscription" : "Cancel subscription";
     return TextButton(
       child: Text(
         title,
         style: TextStyle(
-          color: (isRenewCancelled ? Colors.greenAccent : Theme.of(context).colorScheme.onSurface)
+          color: (isRenewCancelled
+                  ? Colors.greenAccent
+                  : Theme.of(context).colorScheme.onSurface)
               .withOpacity(isRenewCancelled ? 1.0 : 0.2),
         ),
       ),
@@ -410,7 +419,8 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
       if (productID == null || productID.isEmpty) {
         continue;
       }
-      final isActive = _hasActiveSubscription && _currentSubscription.productID == productID;
+      final isActive =
+          _hasActiveSubscription && _currentSubscription.productID == productID;
       if (isActive) {
         foundActivePlan = true;
       }
@@ -491,7 +501,10 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
         child: Text(
           title,
           style: TextStyle(
-            color: Theme.of(context).colorScheme.onSurface.withOpacity(reduceOpacity ? 0.5 : 1.0),
+            color: Theme.of(context)
+                .colorScheme
+                .onSurface
+                .withOpacity(reduceOpacity ? 0.5 : 1.0),
           ),
         ),
       );

+ 4 - 2
lib/ui/payment/subscription_common_widgets.dart

@@ -63,8 +63,10 @@ class _SubscriptionHeaderWidgetState extends State<SubscriptionHeaderWidget> {
                 ),
                 TextSpan(
                   text: formatBytes(widget.currentUsage),
-                  style:
-                      Theme.of(context).textTheme.subtitle1.copyWith(fontWeight: FontWeight.bold),
+                  style: Theme.of(context)
+                      .textTheme
+                      .subtitle1
+                      .copyWith(fontWeight: FontWeight.bold),
                 )
               ],
             ),

+ 8 - 4
lib/ui/settings/app_update_dialog.dart

@@ -78,7 +78,8 @@ class _AppUpdateDialogState extends State<AppUpdateDialog> {
         ),
       ],
     );
-    final shouldForceUpdate = UpdateService.instance.shouldForceUpdate(widget.latestVersionInfo);
+    final shouldForceUpdate =
+        UpdateService.instance.shouldForceUpdate(widget.latestVersionInfo);
     return WillPopScope(
       onWillPop: () async => !shouldForceUpdate,
       child: AlertDialog(
@@ -107,8 +108,10 @@ class _ApkDownloaderDialogState extends State<ApkDownloaderDialog> {
   @override
   void initState() {
     super.initState();
-    _saveUrl =
-        Configuration.instance.getTempDirectory() + "ente-" + widget.versionInfo.name + ".apk";
+    _saveUrl = Configuration.instance.getTempDirectory() +
+        "ente-" +
+        widget.versionInfo.name +
+        ".apk";
     _downloadApk();
   }
 
@@ -126,7 +129,8 @@ class _ApkDownloaderDialogState extends State<ApkDownloaderDialog> {
         ),
         content: LinearProgressIndicator(
           value: _downloadProgress,
-          valueColor: AlwaysStoppedAnimation<Color>(Theme.of(context).buttonColor),
+          valueColor:
+              AlwaysStoppedAnimation<Color>(Theme.of(context).buttonColor),
         ),
       ),
     );

+ 2 - 1
lib/ui/settings/app_version_widget.dart

@@ -29,7 +29,8 @@ class _AppVersionWidgetState extends State<AppVersionWidget> {
         if (now - (_lastTap ?? now) < kConsecutiveTapTimeWindowInMilliseconds) {
           _consecutiveTaps++;
           if (_consecutiveTaps == kTapThresholdForInspector) {
-            final dialog = createProgressDialog(context, "Starting network inspector...");
+            final dialog =
+                createProgressDialog(context, "Starting network inspector...");
             await dialog.show();
             await Future.delayed(
               Duration(milliseconds: kDummyDelayDurationInMilliseconds),

+ 2 - 1
lib/ui/settings/debug_section_widget.dart

@@ -56,7 +56,8 @@ class DebugSectionWidget extends StatelessWidget {
             Text("Key", style: TextStyle(fontWeight: FontWeight.bold)),
             Text(Sodium.bin2base64(Configuration.instance.getKey())),
             Padding(padding: EdgeInsets.all(12)),
-            Text("Encrypted Key", style: TextStyle(fontWeight: FontWeight.bold)),
+            Text("Encrypted Key",
+                style: TextStyle(fontWeight: FontWeight.bold)),
             Text(keyAttributes.encryptedKey),
             Padding(padding: EdgeInsets.all(12)),
             Text(

+ 35 - 14
lib/ui/settings/details_section_widget.dart

@@ -28,10 +28,12 @@ class _DetailsSectionWidgetState extends State<DetailsSectionWidget> {
   void initState() {
     super.initState();
     _fetchUserDetails();
-    _userDetailsChangedEvent = Bus.instance.on<UserDetailsChangedEvent>().listen((event) {
+    _userDetailsChangedEvent =
+        Bus.instance.on<UserDetailsChangedEvent>().listen((event) {
       _fetchUserDetails();
     });
-    _tabChangedEventSubscription = Bus.instance.on<TabChangedEvent>().listen((event) {
+    _tabChangedEventSubscription =
+        Bus.instance.on<TabChangedEvent>().listen((event) {
       if (event.selectedIndex == 3) {
         _fetchUserDetails();
       }
@@ -102,7 +104,8 @@ class _DetailsSectionWidgetState extends State<DetailsSectionWidget> {
           _userDetails == null
               ? const EnteLoadingWidget()
               : Padding(
-                  padding: EdgeInsets.only(top: 20, bottom: 20, left: 16, right: 16),
+                  padding:
+                      EdgeInsets.only(top: 20, bottom: 20, left: 16, right: 16),
                   child: Container(
                     color: Colors.transparent,
                     child: Column(
@@ -119,7 +122,8 @@ class _DetailsSectionWidgetState extends State<DetailsSectionWidget> {
                                 style: Theme.of(context)
                                     .textTheme
                                     .subtitle2
-                                    .copyWith(color: Colors.white.withOpacity(0.7)),
+                                    .copyWith(
+                                        color: Colors.white.withOpacity(0.7)),
                               ),
                               Text(
                                 "${convertBytesToReadableFormat(_userDetails.getFreeStorage())} of ${convertBytesToReadableFormat(_userDetails.getTotalStorage())} free",
@@ -146,14 +150,16 @@ class _DetailsSectionWidgetState extends State<DetailsSectionWidget> {
                                 Container(
                                   color: Colors.white.withOpacity(0.75),
                                   width: MediaQuery.of(context).size.width *
-                                      ((_userDetails.getFamilyOrPersonalUsage()) /
+                                      ((_userDetails
+                                              .getFamilyOrPersonalUsage()) /
                                           _userDetails.getTotalStorage()),
                                   height: 4,
                                 ),
                                 Container(
                                   color: Colors.white,
                                   width: MediaQuery.of(context).size.width *
-                                      (_userDetails.usage / _userDetails.getTotalStorage()),
+                                      (_userDetails.usage /
+                                          _userDetails.getTotalStorage()),
                                   height: 4,
                                 ),
                               ],
@@ -173,27 +179,39 @@ class _DetailsSectionWidgetState extends State<DetailsSectionWidget> {
                                               color: Colors.white,
                                             ),
                                           ),
-                                          Padding(padding: EdgeInsets.only(right: 4)),
+                                          Padding(
+                                              padding:
+                                                  EdgeInsets.only(right: 4)),
                                           Text(
                                             "You",
                                             style: Theme.of(context)
                                                 .textTheme
                                                 .bodyText1
-                                                .copyWith(color: Colors.white, fontSize: 12),
+                                                .copyWith(
+                                                    color: Colors.white,
+                                                    fontSize: 12),
                                           ),
-                                          Padding(padding: EdgeInsets.only(right: 12)),
+                                          Padding(
+                                              padding:
+                                                  EdgeInsets.only(right: 12)),
                                           Container(
                                             width: 8.71,
                                             height: 8.99,
                                             decoration: BoxDecoration(
                                               shape: BoxShape.circle,
-                                              color: Colors.white.withOpacity(0.75),
+                                              color: Colors.white
+                                                  .withOpacity(0.75),
                                             ),
                                           ),
-                                          Padding(padding: EdgeInsets.only(right: 4)),
+                                          Padding(
+                                              padding:
+                                                  EdgeInsets.only(right: 4)),
                                           Text(
                                             "Family",
-                                            style: Theme.of(context).textTheme.bodyText1.copyWith(
+                                            style: Theme.of(context)
+                                                .textTheme
+                                                .bodyText1
+                                                .copyWith(
                                                   color: Colors.white,
                                                   fontSize: 12,
                                                 ),
@@ -205,7 +223,9 @@ class _DetailsSectionWidgetState extends State<DetailsSectionWidget> {
                                         style: Theme.of(context)
                                             .textTheme
                                             .bodyText1
-                                            .copyWith(color: Colors.white, fontSize: 12),
+                                            .copyWith(
+                                                color: Colors.white,
+                                                fontSize: 12),
                                       ),
                                 Padding(
                                   padding: const EdgeInsets.only(right: 16.0),
@@ -214,7 +234,8 @@ class _DetailsSectionWidgetState extends State<DetailsSectionWidget> {
                                     style: Theme.of(context)
                                         .textTheme
                                         .bodyText1
-                                        .copyWith(color: Colors.white, fontSize: 12),
+                                        .copyWith(
+                                            color: Colors.white, fontSize: 12),
                                   ),
                                 )
                               ],

+ 4 - 1
lib/ui/settings/theme_switch_widget.dart

@@ -42,7 +42,10 @@ class ThemeSwitchWidget extends StatelessWidget {
       height: 36,
       indicatorSize: Size(36, 36),
       indicatorColor: Theme.of(context).colorScheme.themeSwitchIndicatorColor,
-      borderColor: Theme.of(context).colorScheme.themeSwitchInactiveIconColor.withOpacity(0.1),
+      borderColor: Theme.of(context)
+          .colorScheme
+          .themeSwitchInactiveIconColor
+          .withOpacity(0.1),
       borderWidth: 1,
     );
   }

+ 3 - 1
lib/ui/settings_page.dart

@@ -53,7 +53,9 @@ class SettingsPage extends StatelessWidget {
               },
             ),
 
-            (Platform.isAndroid) ? ThemeSwitchWidget() : const SizedBox.shrink(),
+            (Platform.isAndroid)
+                ? ThemeSwitchWidget()
+                : const SizedBox.shrink(),
           ],
         ),
       ),

+ 32 - 16
lib/ui/sharing/manage_links_widget.dart

@@ -104,7 +104,8 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
                             Text("Device limit"),
                             Padding(padding: EdgeInsets.all(4)),
                             Text(
-                              widget.collection.publicURLs.first.deviceLimit.toString(),
+                              widget.collection.publicURLs.first.deviceLimit
+                                  .toString(),
                               style: TextStyle(
                                 color: Colors.grey,
                               ),
@@ -125,10 +126,13 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
                       children: [
                         Text("Password lock"),
                         Switch.adaptive(
-                          value: widget.collection.publicURLs?.first?.passwordEnabled ?? false,
+                          value: widget.collection.publicURLs?.first
+                                  ?.passwordEnabled ??
+                              false,
                           onChanged: (enablePassword) async {
                             if (enablePassword) {
-                              var inputResult = await _displayLinkPasswordInput(context);
+                              var inputResult =
+                                  await _displayLinkPasswordInput(context);
                               if (inputResult != null &&
                                   inputResult == 'ok' &&
                                   _textFieldController.text.trim().isNotEmpty) {
@@ -159,7 +163,9 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
                       children: [
                         Text("File download"),
                         Switch.adaptive(
-                          value: widget.collection.publicURLs?.first?.enableDownload ?? true,
+                          value: widget.collection.publicURLs?.first
+                                  ?.enableDownload ??
+                              true,
                           onChanged: (value) async {
                             if (!value) {
                               final choice = await showChoiceDialog(
@@ -168,9 +174,11 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
                                 'Are you sure that you want to disable the download button for files?',
                                 firstAction: 'No',
                                 secondAction: 'Yes',
-                                firstActionColor: Theme.of(context).colorScheme.greenText,
-                                secondActionColor:
-                                    Theme.of(context).colorScheme.inverseBackgroundColor,
+                                firstActionColor:
+                                    Theme.of(context).colorScheme.greenText,
+                                secondActionColor: Theme.of(context)
+                                    .colorScheme
+                                    .inverseBackgroundColor,
                               );
                               if (choice != DialogUserChoice.secondChoice) {
                                 return;
@@ -245,7 +253,8 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
                       int expireAfterInMicroseconds = _selectedExpiry.item3;
                       // need to manually select time
                       if (expireAfterInMicroseconds < 0) {
-                        var timeInMicrosecondsFromEpoch = await _showDateTimePicker();
+                        var timeInMicrosecondsFromEpoch =
+                            await _showDateTimePicker();
                         if (timeInMicrosecondsFromEpoch != null) {
                           newValidTill = timeInMicrosecondsFromEpoch;
                         }
@@ -253,8 +262,8 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
                         // no expiry
                         newValidTill = 0;
                       } else {
-                        newValidTill =
-                            DateTime.now().microsecondsSinceEpoch + expireAfterInMicroseconds;
+                        newValidTill = DateTime.now().microsecondsSinceEpoch +
+                            expireAfterInMicroseconds;
                       }
                       if (newValidTill >= 0) {
                         await _updateUrlSettings(
@@ -281,9 +290,11 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
               height: 220.0,
               color: Color(0xfff7f7f7),
               child: CupertinoPicker(
-                backgroundColor: Theme.of(context).backgroundColor.withOpacity(0.95),
+                backgroundColor:
+                    Theme.of(context).backgroundColor.withOpacity(0.95),
                 onSelectedItemChanged: (value) {
-                  var firstWhere = _expiryOptions.firstWhere((element) => element.item1 == value);
+                  var firstWhere = _expiryOptions
+                      .firstWhere((element) => element.item1 == value);
                   setState(() {
                     _selectedExpiry = firstWhere;
                   });
@@ -292,7 +303,8 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
                 useMagnifier: true,
                 itemExtent: 25,
                 diameterRatio: 1,
-                children: _expiryOptions.map((e) => getOptionText(e.item2)).toList(),
+                children:
+                    _expiryOptions.map((e) => getOptionText(e.item2)).toList(),
               ),
             )
           ],
@@ -346,7 +358,9 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
                   contentPadding: EdgeInsets.all(12),
                   suffixIcon: IconButton(
                     icon: Icon(
-                      _passwordVisible ? Icons.visibility : Icons.visibility_off,
+                      _passwordVisible
+                          ? Icons.visibility
+                          : Icons.visibility_off,
                       color: Colors.white.withOpacity(0.5),
                       size: 20,
                     ),
@@ -376,7 +390,8 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
                   },
                 ),
                 TextButton(
-                  child: Text('Ok', style: Theme.of(context).textTheme.subtitle2),
+                  child:
+                      Text('Ok', style: Theme.of(context).textTheme.subtitle2),
                   onPressed: () {
                     if (_textFieldController.text.trim().isEmpty) {
                       return;
@@ -521,7 +536,8 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
               height: 220.0,
               color: Color(0xfff7f7f7),
               child: CupertinoPicker(
-                backgroundColor: Theme.of(context).backgroundColor.withOpacity(0.95),
+                backgroundColor:
+                    Theme.of(context).backgroundColor.withOpacity(0.95),
                 onSelectedItemChanged: (value) {
                   _selectedDeviceLimitIndex = value;
                 },

+ 24 - 11
lib/ui/sharing/share_collection_widget.dart

@@ -146,10 +146,13 @@ class _SharingDialogState extends State<SharingDialog> {
                     // Add local folder in backup patch before creating
                     // sharable link
                     if (widget.collection.type == CollectionType.folder) {
-                      final path =
-                          CollectionsService.instance.decryptCollectionPath(widget.collection);
-                      if (!Configuration.instance.getPathsToBackUp().contains(path)) {
-                        await Configuration.instance.addPathToFoldersToBeBackedUp(path);
+                      final path = CollectionsService.instance
+                          .decryptCollectionPath(widget.collection);
+                      if (!Configuration.instance
+                          .getPathsToBackUp()
+                          .contains(path)) {
+                        await Configuration.instance
+                            .addPathToFoldersToBeBackedUp(path);
                         Bus.instance.fire(BackupFoldersUpdatedEvent());
                       }
                     }
@@ -161,8 +164,10 @@ class _SharingDialogState extends State<SharingDialog> {
                   try {
                     await dialog.show();
                     enable
-                        ? await CollectionsService.instance.createShareUrl(widget.collection)
-                        : await CollectionsService.instance.disableShareUrl(widget.collection);
+                        ? await CollectionsService.instance
+                            .createShareUrl(widget.collection)
+                        : await CollectionsService.instance
+                            .disableShareUrl(widget.collection);
                     dialog.hide();
                     setState(() {});
                   } catch (e) {
@@ -291,7 +296,10 @@ class _SharingDialogState extends State<SharingDialog> {
                       style: TextStyle(
                         fontSize: 16,
                         fontFeatures: const [FontFeature.tabularFigures()],
-                        color: Theme.of(context).colorScheme.onSurface.withOpacity(0.68),
+                        color: Theme.of(context)
+                            .colorScheme
+                            .onSurface
+                            .withOpacity(0.68),
                         overflow: TextOverflow.ellipsis,
                       ),
                     ),
@@ -389,7 +397,9 @@ class _SharingDialogState extends State<SharingDialog> {
       final dialog = AlertDialog(
         title: Text("Invite to ente?"),
         content: Text(
-          "Looks like " + email + " hasn't signed up for ente yet. would you like to invite them?",
+          "Looks like " +
+              email +
+              " hasn't signed up for ente yet. would you like to invite them?",
           style: TextStyle(
             height: 1.4,
           ),
@@ -422,12 +432,14 @@ class _SharingDialogState extends State<SharingDialog> {
       final collection = widget.collection;
       try {
         if (collection.type == CollectionType.folder) {
-          final path = CollectionsService.instance.decryptCollectionPath(collection);
+          final path =
+              CollectionsService.instance.decryptCollectionPath(collection);
           if (!Configuration.instance.getPathsToBackUp().contains(path)) {
             await Configuration.instance.addPathToFoldersToBeBackedUp(path);
           }
         }
-        await CollectionsService.instance.share(widget.collection.id, email, publicKey);
+        await CollectionsService.instance
+            .share(widget.collection.id, email, publicKey);
         await dialog.hide();
         showShortToast(context, "Shared successfully!");
         setState(() {
@@ -449,7 +461,8 @@ class _SharingDialogState extends State<SharingDialog> {
   void _showUnSupportedAlert() {
     AlertDialog alert = AlertDialog(
       title: Text("Sorry"),
-      content: Text("Sharing is not permitted for free accounts, please subscribe"),
+      content:
+          Text("Sharing is not permitted for free accounts, please subscribe"),
       actions: [
         TextButton(
           child: Text(

+ 14 - 8
lib/ui/tools/editor/image_editor_page.dart

@@ -48,7 +48,8 @@ class _ImageEditorPageState extends State<ImageEditorPage> {
   static const double kSaturationMax = 2;
 
   final _logger = Logger("ImageEditor");
-  final GlobalKey<ExtendedImageEditorState> editorKey = GlobalKey<ExtendedImageEditorState>();
+  final GlobalKey<ExtendedImageEditorState> editorKey =
+      GlobalKey<ExtendedImageEditorState>();
 
   double _brightness = kBrightnessDefault;
   double _saturation = kSaturationDefault;
@@ -105,7 +106,9 @@ class _ImageEditorPageState extends State<ImageEditorPage> {
   }
 
   bool _hasBeenEdited() {
-    return _hasEdited || _saturation != kSaturationDefault || _brightness != kBrightnessDefault;
+    return _hasEdited ||
+        _saturation != kSaturationDefault ||
+        _brightness != kBrightnessDefault;
   }
 
   Widget _buildImage() {
@@ -331,15 +334,17 @@ class _ImageEditorPageState extends State<ImageEditorPage> {
       return;
     }
     try {
-      final fileName = path.basenameWithoutExtension(widget.originalFile.title) +
-          "_edited_" +
-          DateTime.now().microsecondsSinceEpoch.toString() +
-          path.extension(widget.originalFile.title);
+      final fileName =
+          path.basenameWithoutExtension(widget.originalFile.title) +
+              "_edited_" +
+              DateTime.now().microsecondsSinceEpoch.toString() +
+              path.extension(widget.originalFile.title);
       final newAsset = await PhotoManager.editor.saveImage(
         result,
         title: fileName,
       );
-      final newFile = await ente.File.fromAsset(widget.originalFile.deviceFolder, newAsset);
+      final newFile =
+          await ente.File.fromAsset(widget.originalFile.deviceFolder, newAsset);
       newFile.creationTime = widget.originalFile.creationTime;
       newFile.collectionID = widget.originalFile.collectionID;
       newFile.location = widget.originalFile.location;
@@ -368,7 +373,8 @@ class _ImageEditorPageState extends State<ImageEditorPage> {
         DetailPage(
           widget.detailPageConfig.copyWith(
             files: files,
-            selectedIndex: files.indexWhere((file) => file.generatedID == newFile.generatedID),
+            selectedIndex: files
+                .indexWhere((file) => file.generatedID == newFile.generatedID),
           ),
         ),
       );

+ 6 - 3
lib/ui/tools/free_space_page.dart

@@ -32,7 +32,8 @@ class _FreeSpacePageState extends State<FreeSpacePage> {
     Logger("FreeSpacePage").info(
       "Number of uploaded files: " + widget.status.localIDs.length.toString(),
     );
-    Logger("FreeSpacePage").info("Space consumed: " + widget.status.size.toString());
+    Logger("FreeSpacePage")
+        .info("Space consumed: " + widget.status.size.toString());
     return SingleChildScrollView(
       child: _getWidget(widget.status),
     );
@@ -47,7 +48,8 @@ class _FreeSpacePageState extends State<FreeSpacePage> {
       color: Theme.of(context).colorScheme.onSurface.withOpacity(0.8),
       fontWeight: FontWeight.w500,
     );
-    final isLightMode = MediaQuery.of(context).platformBrightness == Brightness.light;
+    final isLightMode =
+        MediaQuery.of(context).platformBrightness == Brightness.light;
     return Column(
       mainAxisAlignment: MainAxisAlignment.center,
       crossAxisAlignment: CrossAxisAlignment.center,
@@ -80,7 +82,8 @@ class _FreeSpacePageState extends State<FreeSpacePage> {
               Expanded(
                 child: Text(
                   count == 1
-                      ? formattedCount.toString() + " file on this device has been backed up safely"
+                      ? formattedCount.toString() +
+                          " file on this device has been backed up safely"
                       : formattedCount.toString() +
                           " files on this device have been backed up safely",
                   style: informationTextStyle,

+ 2 - 1
lib/ui/viewer/file/custom_app_bar.dart

@@ -4,7 +4,8 @@ class CustomAppBar extends PreferredSize {
   final Widget child;
   final double height;
 
-  const CustomAppBar(this.child, {Key key, this.height = kToolbarHeight}) : super(key: key);
+  const CustomAppBar(this.child, {Key key, this.height = kToolbarHeight})
+      : super(key: key);
 
   @override
   Size get preferredSize => Size.fromHeight(height);

+ 4 - 1
lib/ui/viewer/file/exif_info_dialog.dart

@@ -71,7 +71,10 @@ class _ExifInfoDialogState extends State<ExifInfoDialog> {
                       FontFeature.tabularFigures(),
                     ],
                     height: 1.4,
-                    color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7),
+                    color: Theme.of(context)
+                        .colorScheme
+                        .onSurface
+                        .withOpacity(0.7),
                   ),
                 ),
               ),

+ 15 - 6
lib/ui/viewer/file/fading_app_bar.dart

@@ -114,7 +114,9 @@ class FadingAppBarState extends State<FadingAppBar> {
                 child: Row(
                   children: [
                     Icon(
-                      Platform.isAndroid ? Icons.download : CupertinoIcons.cloud_download,
+                      Platform.isAndroid
+                          ? Icons.download
+                          : CupertinoIcons.cloud_download,
                       color: Theme.of(context).iconTheme.color,
                     ),
                     Padding(
@@ -127,7 +129,8 @@ class FadingAppBarState extends State<FadingAppBar> {
             );
           }
           // options for files owned by the user
-          if (widget.file.ownerID == null || widget.file.ownerID == widget.userID) {
+          if (widget.file.ownerID == null ||
+              widget.file.ownerID == widget.userID) {
             if (widget.file.uploadedFileID != null) {
               items.add(
                 PopupMenuItem(
@@ -135,7 +138,9 @@ class FadingAppBarState extends State<FadingAppBar> {
                   child: Row(
                     children: [
                       Icon(
-                        Platform.isAndroid ? Icons.access_time_rounded : CupertinoIcons.time,
+                        Platform.isAndroid
+                            ? Icons.access_time_rounded
+                            : CupertinoIcons.time,
                         color: Theme.of(context).iconTheme.color,
                       ),
                       Padding(
@@ -154,7 +159,9 @@ class FadingAppBarState extends State<FadingAppBar> {
                 child: Row(
                   children: [
                     Icon(
-                      Platform.isAndroid ? Icons.delete_outline : CupertinoIcons.delete,
+                      Platform.isAndroid
+                          ? Icons.delete_outline
+                          : CupertinoIcons.delete,
                       color: Theme.of(context).iconTheme.color,
                     ),
                     Padding(
@@ -238,7 +245,8 @@ class FadingAppBarState extends State<FadingAppBar> {
       likeBuilder: (isLiked) {
         return Icon(
           isLiked ? Icons.favorite_rounded : Icons.favorite_border_rounded,
-          color: isLiked ? Colors.pinkAccent : Colors.white, //same for both themes
+          color:
+              isLiked ? Colors.pinkAccent : Colors.white, //same for both themes
           size: 24,
         );
       },
@@ -351,7 +359,8 @@ class FadingAppBarState extends State<FadingAppBar> {
     io.File fileToSave = await getFile(file);
     final savedAsset = type == FileType.video
         ? (await PhotoManager.editor.saveVideo(fileToSave, title: file.title))
-        : (await PhotoManager.editor.saveImageWithPath(fileToSave.path, title: file.title));
+        : (await PhotoManager.editor
+            .saveImageWithPath(fileToSave.path, title: file.title));
     // immediately track assetID to avoid duplicate upload
     await LocalSyncService.instance.trackDownloadedFile(savedAsset.id);
     file.localID = savedAsset.id;

+ 4 - 2
lib/ui/viewer/file/video_controls.dart

@@ -156,7 +156,8 @@ class _VideoControlsState extends State<VideoControls> {
           color: Colors.transparent,
           child: Center(
             child: AnimatedOpacity(
-              opacity: _latestValue != null && !_hideStuff && !_dragging ? 1.0 : 0.0,
+              opacity:
+                  _latestValue != null && !_hideStuff && !_dragging ? 1.0 : 0.0,
               duration: Duration(milliseconds: 300),
               child: GestureDetector(
                 onTap: _playPause,
@@ -225,7 +226,8 @@ class _VideoControlsState extends State<VideoControls> {
 
     _updateState();
 
-    if ((controller.value != null && controller.value.isPlaying) || chewieController.autoPlay) {
+    if ((controller.value != null && controller.value.isPlaying) ||
+        chewieController.autoPlay) {
       _startHideTimer();
     }
 

+ 2 - 1
lib/ui/viewer/file/video_widget.dart

@@ -114,7 +114,8 @@ class _VideoWidgetState extends State<VideoWidget> {
 
   @override
   Widget build(BuildContext context) {
-    final content = _videoPlayerController != null && _videoPlayerController.value.isInitialized
+    final content = _videoPlayerController != null &&
+            _videoPlayerController.value.isInitialized
         ? _getVideoPlayer()
         : _getLoadingWidget();
     final contentWithDetector = GestureDetector(

+ 12 - 5
lib/ui/viewer/file/zoomable_image.dart

@@ -31,7 +31,8 @@ class ZoomableImage extends StatefulWidget {
   State<ZoomableImage> createState() => _ZoomableImageState();
 }
 
-class _ZoomableImageState extends State<ZoomableImage> with SingleTickerProviderStateMixin {
+class _ZoomableImageState extends State<ZoomableImage>
+    with SingleTickerProviderStateMixin {
   final Logger _logger = Logger("ZoomableImage");
   File _photo;
   ImageProvider _imageProvider;
@@ -88,7 +89,8 @@ class _ZoomableImageState extends State<ZoomableImage> with SingleTickerProvider
     GestureDragUpdateCallback verticalDragCallback = _isZooming
         ? null
         : (d) => {
-              if (!_isZooming && d.delta.dy > kDragSensitivity) {Navigator.of(context).pop()}
+              if (!_isZooming && d.delta.dy > kDragSensitivity)
+                {Navigator.of(context).pop()}
             };
     return GestureDetector(
       onVerticalDragUpdate: verticalDragCallback,
@@ -134,15 +136,20 @@ class _ZoomableImageState extends State<ZoomableImage> with SingleTickerProvider
   }
 
   void _loadLocalImage(BuildContext context) {
-    if (!_loadedSmallThumbnail && !_loadedLargeThumbnail && !_loadedFinalImage) {
-      final cachedThumbnail = ThumbnailLruCache.get(_photo, kThumbnailSmallSize);
+    if (!_loadedSmallThumbnail &&
+        !_loadedLargeThumbnail &&
+        !_loadedFinalImage) {
+      final cachedThumbnail =
+          ThumbnailLruCache.get(_photo, kThumbnailSmallSize);
       if (cachedThumbnail != null) {
         _imageProvider = Image.memory(cachedThumbnail).image;
         _loadedSmallThumbnail = true;
       }
     }
 
-    if (!_loadingLargeThumbnail && !_loadedLargeThumbnail && !_loadedFinalImage) {
+    if (!_loadingLargeThumbnail &&
+        !_loadedLargeThumbnail &&
+        !_loadedFinalImage) {
       _loadingLargeThumbnail = true;
       getThumbnailFromLocal(_photo, size: kThumbnailLargeSize, quality: 100)
           .then((cachedThumbnail) {

+ 13 - 5
lib/ui/viewer/gallery/device_folder_page.dart

@@ -38,7 +38,9 @@ class DeviceFolderPage extends StatelessWidget {
       },
       tagPrefix: "device_folder:" + folder.path,
       selectedFiles: _selectedFiles,
-      header: Configuration.instance.hasConfiguredAccount() ? _getHeaderWidget() : Container(),
+      header: Configuration.instance.hasConfiguredAccount()
+          ? _getHeaderWidget()
+          : Container(),
       initialFiles: [folder.thumbnail],
       footer: SizedBox(height: 32),
     );
@@ -76,13 +78,16 @@ class BackupConfigurationHeaderWidget extends StatefulWidget {
   BackupConfigurationHeaderWidget(this.path, {Key key}) : super(key: key);
 
   @override
-  State<BackupConfigurationHeaderWidget> createState() => _BackupConfigurationHeaderWidgetState();
+  State<BackupConfigurationHeaderWidget> createState() =>
+      _BackupConfigurationHeaderWidgetState();
 }
 
-class _BackupConfigurationHeaderWidgetState extends State<BackupConfigurationHeaderWidget> {
+class _BackupConfigurationHeaderWidgetState
+    extends State<BackupConfigurationHeaderWidget> {
   @override
   Widget build(BuildContext context) {
-    final isBackedUp = Configuration.instance.getPathsToBackUp().contains(widget.path);
+    final isBackedUp =
+        Configuration.instance.getPathsToBackUp().contains(widget.path);
     return Container(
       padding: EdgeInsets.only(left: 20, right: 12, top: 4, bottom: 4),
       margin: EdgeInsets.only(bottom: 12),
@@ -95,7 +100,10 @@ class _BackupConfigurationHeaderWidgetState extends State<BackupConfigurationHea
               : Text(
                   "Backup disabled",
                   style: TextStyle(
-                    color: Theme.of(context).colorScheme.defaultTextColor.withOpacity(0.7),
+                    color: Theme.of(context)
+                        .colorScheme
+                        .defaultTextColor
+                        .withOpacity(0.7),
                   ),
                 ),
           Switch(

+ 17 - 7
lib/ui/viewer/gallery/gallery_app_bar_widget.dart

@@ -47,7 +47,8 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
       setState(() {});
     };
     widget.selectedFiles.addListener(_selectedFilesListener);
-    _userAuthEventSubscription = Bus.instance.on<SubscriptionPurchasedEvent>().listen((event) {
+    _userAuthEventSubscription =
+        Bus.instance.on<SubscriptionPurchasedEvent>().listen((event) {
       setState(() {});
     });
     _appBarTitle = widget.title;
@@ -65,7 +66,8 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
   Widget build(BuildContext context) {
     // if (widget.selectedFiles.files.isEmpty) {
     return AppBar(
-      backgroundColor: widget.type == GalleryType.homepage ? Color(0x00000000) : null,
+      backgroundColor:
+          widget.type == GalleryType.homepage ? Color(0x00000000) : null,
       elevation: 0,
       centerTitle: false,
       title: widget.type == GalleryType.homepage
@@ -73,7 +75,10 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
           : TextButton(
               child: Text(
                 _appBarTitle,
-                style: Theme.of(context).textTheme.headline5.copyWith(fontSize: 16),
+                style: Theme.of(context)
+                    .textTheme
+                    .headline5
+                    .copyWith(fontSize: 16),
               ),
               onPressed: () => _renameAlbum(context),
             ),
@@ -116,7 +121,8 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
     List<Widget> actions = <Widget>[];
     if (Configuration.instance.hasConfiguredAccount() &&
         widget.selectedFiles.files.isEmpty &&
-        (widget.type == GalleryType.localFolder || widget.type == GalleryType.ownedCollection)) {
+        (widget.type == GalleryType.localFolder ||
+            widget.type == GalleryType.ownedCollection)) {
       actions.add(
         Tooltip(
           message: "Share",
@@ -175,7 +181,9 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
               await changeCollectionVisibility(
                 context,
                 widget.collection,
-                widget.collection.isArchived() ? kVisibilityVisible : kVisibilityArchive,
+                widget.collection.isArchived()
+                    ? kVisibilityVisible
+                    : kVisibilityArchive,
               );
             }
           },
@@ -192,14 +200,16 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
     try {
       if (collection == null) {
         if (widget.type == GalleryType.localFolder) {
-          collection = await CollectionsService.instance.getOrCreateForPath(widget.path);
+          collection =
+              await CollectionsService.instance.getOrCreateForPath(widget.path);
         } else {
           throw Exception(
             "Cannot create a collection of type" + widget.type.toString(),
           );
         }
       } else {
-        final sharees = await CollectionsService.instance.getSharees(collection.id);
+        final sharees =
+            await CollectionsService.instance.getSharees(collection.id);
         collection = collection.copyWith(sharees: sharees);
       }
       await dialog.hide();

+ 28 - 11
lib/ui/viewer/gallery/gallery_overlay_widget.dart

@@ -50,7 +50,8 @@ class _GalleryOverlayWidgetState extends State<GalleryOverlayWidget> {
       setState(() {});
     };
     widget.selectedFiles.addListener(_selectedFilesListener);
-    _userAuthEventSubscription = Bus.instance.on<SubscriptionPurchasedEvent>().listen((event) {
+    _userAuthEventSubscription =
+        Bus.instance.on<SubscriptionPurchasedEvent>().listen((event) {
       setState(() {});
     });
     super.initState();
@@ -121,7 +122,8 @@ class _OverlayWidgetState extends State<OverlayWidget> {
       setState(() {});
     };
     widget.selectedFiles.addListener(_selectedFilesListener);
-    _userAuthEventSubscription = Bus.instance.on<SubscriptionPurchasedEvent>().listen((event) {
+    _userAuthEventSubscription =
+        Bus.instance.on<SubscriptionPurchasedEvent>().listen((event) {
       setState(() {});
     });
     super.initState();
@@ -151,7 +153,9 @@ class _OverlayWidgetState extends State<OverlayWidget> {
                 child: BackdropFilter(
                   filter: ImageFilter.blur(sigmaX: 50, sigmaY: 50),
                   child: Container(
-                    color: Theme.of(context).colorScheme.frostyBlurBackdropFilterColor,
+                    color: Theme.of(context)
+                        .colorScheme
+                        .frostyBlurBackdropFilterColor,
                     width: double.infinity,
                     child: Row(
                       mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -159,10 +163,15 @@ class _OverlayWidgetState extends State<OverlayWidget> {
                         Padding(
                           padding: const EdgeInsets.fromLTRB(13, 13, 0, 13),
                           child: Text(
-                            widget.selectedFiles.files.length.toString() + ' selected',
-                            style: Theme.of(context).textTheme.subtitle2.copyWith(
+                            widget.selectedFiles.files.length.toString() +
+                                ' selected',
+                            style: Theme.of(context)
+                                .textTheme
+                                .subtitle2
+                                .copyWith(
                                   fontWeight: FontWeight.w600,
-                                  color: Theme.of(context).colorScheme.iconColor,
+                                  color:
+                                      Theme.of(context).colorScheme.iconColor,
                                 ),
                           ),
                         ),
@@ -190,7 +199,9 @@ class _OverlayWidgetState extends State<OverlayWidget> {
                       padding: EdgeInsets.symmetric(vertical: 8),
                       //height: 32,
                       width: 86,
-                      color: Theme.of(context).colorScheme.frostyBlurBackdropFilterColor,
+                      color: Theme.of(context)
+                          .colorScheme
+                          .frostyBlurBackdropFilterColor,
                       child: Center(
                         child: Text(
                           'Cancel',
@@ -256,7 +267,9 @@ class _OverlayWidgetState extends State<OverlayWidget> {
       // show upload icon instead of add for files selected in local gallery
       if (widget.type == GalleryType.localFolder) {
         msg = "Upload";
-        iconData = Platform.isAndroid ? Icons.cloud_upload : CupertinoIcons.cloud_upload;
+        iconData = Platform.isAndroid
+            ? Icons.cloud_upload
+            : CupertinoIcons.cloud_upload;
       }
       actions.add(
         Tooltip(
@@ -280,7 +293,9 @@ class _OverlayWidgetState extends State<OverlayWidget> {
           child: IconButton(
             color: Theme.of(context).colorScheme.iconColor,
             icon: Icon(
-              Platform.isAndroid ? Icons.arrow_forward : CupertinoIcons.arrow_right,
+              Platform.isAndroid
+                  ? Icons.arrow_forward
+                  : CupertinoIcons.arrow_right,
             ),
             onPressed: () {
               _moveFiles();
@@ -310,7 +325,8 @@ class _OverlayWidgetState extends State<OverlayWidget> {
           message: "Delete",
           child: IconButton(
             color: Theme.of(context).colorScheme.iconColor,
-            icon: Icon(Platform.isAndroid ? Icons.delete : CupertinoIcons.delete),
+            icon:
+                Icon(Platform.isAndroid ? Icons.delete : CupertinoIcons.delete),
             onPressed: () {
               _showDeleteSheet(context);
             },
@@ -351,7 +367,8 @@ class _OverlayWidgetState extends State<OverlayWidget> {
       }
     }
 
-    if (widget.type == GalleryType.homepage || widget.type == GalleryType.archive) {
+    if (widget.type == GalleryType.homepage ||
+        widget.type == GalleryType.archive) {
       bool showArchive = widget.type == GalleryType.homepage;
       actions.add(
         Tooltip(

+ 2 - 1
lib/utils/file_sync_util.dart

@@ -67,7 +67,8 @@ Future<List<File>> getUnsyncedFiles(
   args['assets'] = assets;
   args['existingIDs'] = existingIDs;
   args['invalidIDs'] = invalidIDs;
-  final unsyncedAssets = await computer.compute(_getUnsyncedAssets, param: args);
+  final unsyncedAssets =
+      await computer.compute(_getUnsyncedAssets, param: args);
   if (unsyncedAssets.isEmpty) {
     return [];
   }

+ 64 - 30
lib/utils/file_uploader.dart

@@ -68,17 +68,19 @@ class FileUploader {
   Future<void> init(bool isBackground) async {
     _prefs = await SharedPreferences.getInstance();
     _isBackground = isBackground;
-    _processType = isBackground ? ProcessType.background : ProcessType.foreground;
+    _processType =
+        isBackground ? ProcessType.background : ProcessType.foreground;
     final currentTime = DateTime.now().microsecondsSinceEpoch;
     await _uploadLocks.releaseLocksAcquiredByOwnerBefore(
       _processType.toString(),
       currentTime,
     );
-    await _uploadLocks.releaseAllLocksAcquiredBefore(currentTime - kSafeBufferForLockExpiry);
+    await _uploadLocks
+        .releaseAllLocksAcquiredBefore(currentTime - kSafeBufferForLockExpiry);
     if (!isBackground) {
       await _prefs.reload();
-      final isBGTaskDead =
-          (_prefs.getInt(kLastBGTaskHeartBeatTime) ?? 0) < (currentTime - kBGTaskDeathTimeout);
+      final isBGTaskDead = (_prefs.getInt(kLastBGTaskHeartBeatTime) ?? 0) <
+          (currentTime - kBGTaskDeathTimeout);
       if (isBGTaskDead) {
         await _uploadLocks.releaseLocksAcquiredByOwnerBefore(
           ProcessType.background.toString(),
@@ -136,7 +138,10 @@ class FileUploader {
 
   Future<File> forceUpload(File file, int collectionID) async {
     _logger.info(
-      "Force uploading " + file.toString() + " into collection " + collectionID.toString(),
+      "Force uploading " +
+          file.toString() +
+          " into collection " +
+          collectionID.toString(),
     );
     _totalCountInUploadSession++;
     // If the file hasn't been queued yet, ez.
@@ -153,13 +158,15 @@ class FileUploader {
     }
     var item = _queue[file.localID];
     // If the file is being uploaded right now, wait and proceed
-    if (item.status == UploadStatus.inProgress || item.status == UploadStatus.inBackground) {
+    if (item.status == UploadStatus.inProgress ||
+        item.status == UploadStatus.inBackground) {
       _totalCountInUploadSession--;
       final uploadedFile = await item.completer.future;
       if (uploadedFile.collectionID == collectionID) {
         // Do nothing
       } else {
-        await CollectionsService.instance.addToCollection(collectionID, [uploadedFile]);
+        await CollectionsService.instance
+            .addToCollection(collectionID, [uploadedFile]);
       }
       return uploadedFile;
     } else {
@@ -177,7 +184,8 @@ class FileUploader {
       if (item.collectionID == collectionID) {
         return uploadedFile;
       } else {
-        await CollectionsService.instance.addToCollection(item.collectionID, [uploadedFile]);
+        await CollectionsService.instance
+            .addToCollection(item.collectionID, [uploadedFile]);
         return uploadedFile;
       }
     }
@@ -266,7 +274,8 @@ class FileUploader {
     }
     final localID = file.localID;
     try {
-      final uploadedFile = await _tryToUpload(file, collectionID, forcedUpload).timeout(
+      final uploadedFile =
+          await _tryToUpload(file, collectionID, forcedUpload).timeout(
         kFileUploadTimeout,
         onTimeout: () {
           final message = "Upload timed out for file " + file.toString();
@@ -299,8 +308,9 @@ class FileUploader {
     bool forcedUpload,
   ) async {
     final connectivityResult = await (Connectivity().checkConnectivity());
-    var canUploadUnderCurrentNetworkConditions = (connectivityResult == ConnectivityResult.wifi ||
-        Configuration.instance.shouldBackupOverMobileData());
+    var canUploadUnderCurrentNetworkConditions =
+        (connectivityResult == ConnectivityResult.wifi ||
+            Configuration.instance.shouldBackupOverMobileData());
     if (!canUploadUnderCurrentNetworkConditions && !forcedUpload) {
       throw WiFiUnavailableError();
     }
@@ -324,8 +334,10 @@ class FileUploader {
     }
 
     final tempDirectory = Configuration.instance.getTempDirectory();
-    final encryptedFilePath =
-        tempDirectory + file.generatedID.toString() + (_isBackground ? "_bg" : "") + ".encrypted";
+    final encryptedFilePath = tempDirectory +
+        file.generatedID.toString() +
+        (_isBackground ? "_bg" : "") +
+        ".encrypted";
     final encryptedThumbnailPath = tempDirectory +
         file.generatedID.toString() +
         "_thumbnail" +
@@ -335,7 +347,10 @@ class FileUploader {
 
     try {
       _logger.info(
-        "Trying to upload " + file.toString() + ", isForced: " + forcedUpload.toString(),
+        "Trying to upload " +
+            file.toString() +
+            ", isForced: " +
+            forcedUpload.toString(),
       );
       try {
         mediaUploadData = await getUploadDataFromEnteFile(file);
@@ -347,7 +362,8 @@ class FileUploader {
         }
       }
       Uint8List key;
-      bool isUpdatedFile = file.uploadedFileID != null && file.updationTime == -1;
+      bool isUpdatedFile =
+          file.uploadedFileID != null && file.updationTime == -1;
       if (isUpdatedFile) {
         _logger.info("File was updated " + file.toString());
         key = decryptFileKey(file);
@@ -372,23 +388,29 @@ class FileUploader {
         await io.File(encryptedThumbnailPath).delete();
       }
       final encryptedThumbnailFile = io.File(encryptedThumbnailPath);
-      await encryptedThumbnailFile.writeAsBytes(encryptedThumbnailData.encryptedData);
+      await encryptedThumbnailFile
+          .writeAsBytes(encryptedThumbnailData.encryptedData);
 
       final thumbnailUploadURL = await _getUploadURL();
-      String thumbnailObjectKey = await _putFile(thumbnailUploadURL, encryptedThumbnailFile);
+      String thumbnailObjectKey =
+          await _putFile(thumbnailUploadURL, encryptedThumbnailFile);
 
       final fileUploadURL = await _getUploadURL();
       String fileObjectKey = await _putFile(fileUploadURL, encryptedFile);
 
-      final metadata = await file.getMetadataForUpload(mediaUploadData.sourceFile);
+      final metadata =
+          await file.getMetadataForUpload(mediaUploadData.sourceFile);
       final encryptedMetadataData = await CryptoUtil.encryptChaCha(
         utf8.encode(jsonEncode(metadata)),
         fileAttributes.key,
       );
       final fileDecryptionHeader = Sodium.bin2base64(fileAttributes.header);
-      final thumbnailDecryptionHeader = Sodium.bin2base64(encryptedThumbnailData.header);
-      final encryptedMetadata = Sodium.bin2base64(encryptedMetadataData.encryptedData);
-      final metadataDecryptionHeader = Sodium.bin2base64(encryptedMetadataData.header);
+      final thumbnailDecryptionHeader =
+          Sodium.bin2base64(encryptedThumbnailData.header);
+      final encryptedMetadata =
+          Sodium.bin2base64(encryptedMetadataData.encryptedData);
+      final metadataDecryptionHeader =
+          Sodium.bin2base64(encryptedMetadataData.header);
       if (SyncService.instance.shouldStopSync()) {
         throw SyncStopRequestedError();
       }
@@ -412,8 +434,10 @@ class FileUploader {
           fileAttributes.key,
           CollectionsService.instance.getCollectionKey(collectionID),
         );
-        final encryptedKey = Sodium.bin2base64(encryptedFileKeyData.encryptedData);
-        final keyDecryptionNonce = Sodium.bin2base64(encryptedFileKeyData.nonce);
+        final encryptedKey =
+            Sodium.bin2base64(encryptedFileKeyData.encryptedData);
+        final keyDecryptionNonce =
+            Sodium.bin2base64(encryptedFileKeyData.nonce);
         remoteFile = await _uploadFile(
           file,
           collectionID,
@@ -450,7 +474,9 @@ class FileUploader {
       }
       rethrow;
     } finally {
-      if (io.Platform.isIOS && mediaUploadData != null && mediaUploadData.sourceFile != null) {
+      if (io.Platform.isIOS &&
+          mediaUploadData != null &&
+          mediaUploadData.sourceFile != null) {
         await mediaUploadData.sourceFile.delete();
       }
       if (io.File(encryptedFilePath).existsSync()) {
@@ -654,7 +680,9 @@ class FileUploader {
             headers: {"X-Auth-Token": Configuration.instance.getToken()},
           ),
         );
-        final urls = (response.data["urls"] as List).map((e) => UploadURL.fromMap(e)).toList();
+        final urls = (response.data["urls"] as List)
+            .map((e) => UploadURL.fromMap(e))
+            .toList();
         _uploadURLs.addAll(urls);
       } on DioError catch (e, s) {
         if (e.response != null) {
@@ -691,7 +719,10 @@ class FileUploader {
   }) async {
     final fileSize = contentLength ?? await file.length();
     _logger.info(
-      "Putting object for " + file.toString() + " of size: " + fileSize.toString(),
+      "Putting object for " +
+          file.toString() +
+          " of size: " +
+          fileSize.toString(),
     );
     final startTime = DateTime.now().millisecondsSinceEpoch;
     try {
@@ -706,7 +737,8 @@ class FileUploader {
       );
       _logger.info(
         "Upload speed : " +
-            (fileSize / (DateTime.now().millisecondsSinceEpoch - startTime)).toString() +
+            (fileSize / (DateTime.now().millisecondsSinceEpoch - startTime))
+                .toString() +
             " kilo bytes per second",
       );
 
@@ -741,8 +773,9 @@ class FileUploader {
   }
 
   Future<void> _pollBackgroundUploadStatus() async {
-    final blockedUploads =
-        _queue.entries.where((e) => e.value.status == UploadStatus.inBackground).toList();
+    final blockedUploads = _queue.entries
+        .where((e) => e.value.status == UploadStatus.inBackground)
+        .toList();
     for (final upload in blockedUploads) {
       final file = upload.value.file;
       final isStillLocked = await _uploadLocks.isLocked(
@@ -751,7 +784,8 @@ class FileUploader {
       );
       if (!isStillLocked) {
         final completer = _queue.remove(upload.key).completer;
-        final dbFile = await FilesDB.instance.getFile(upload.value.file.generatedID);
+        final dbFile =
+            await FilesDB.instance.getFile(upload.value.file.generatedID);
         if (dbFile.uploadedFileID != null) {
           _logger.info("Background upload success detected");
           completer.complete(dbFile);