Bläddra i källkod

Merge branch 'master' into rewrite_device_sync_remote

Neeraj Gupta 2 år sedan
förälder
incheckning
19832b82b5
93 ändrade filer med 411 tillägg och 318 borttagningar
  1. 1 0
      analysis_options.yaml
  2. 3 3
      lib/core/cache/lru_map.dart
  3. 15 1
      lib/core/configuration.dart
  4. 10 10
      lib/core/error-reporting/super_logging.dart
  5. 5 5
      lib/db/collections_db.dart
  6. 8 8
      lib/db/device_files_db.dart
  7. 4 3
      lib/db/file_migration_db.dart
  8. 18 14
      lib/db/files_db.dart
  9. 2 2
      lib/db/ignored_files_db.dart
  10. 3 3
      lib/db/memories_db.dart
  11. 3 3
      lib/db/public_keys_db.dart
  12. 4 4
      lib/db/trash_db.dart
  13. 2 2
      lib/db/upload_locks_db.dart
  14. 6 6
      lib/main.dart
  15. 1 1
      lib/models/collection.dart
  16. 2 2
      lib/models/file.dart
  17. 3 3
      lib/models/selected_files.dart
  18. 1 1
      lib/models/subscription.dart
  19. 2 2
      lib/services/collections_service.dart
  20. 1 1
      lib/services/deduplication_service.dart
  21. 1 1
      lib/services/favorites_service.dart
  22. 1 1
      lib/services/feature_flag_service.dart
  23. 4 4
      lib/services/file_magic_service.dart
  24. 4 4
      lib/services/ignored_files_service.dart
  25. 18 18
      lib/services/local/local_sync_util.dart
  26. 9 9
      lib/services/local_file_update_service.dart
  27. 4 4
      lib/services/local_sync_service.dart
  28. 15 16
      lib/services/remote_sync_service.dart
  29. 2 2
      lib/services/user_service.dart
  30. 2 2
      lib/ui/account/delete_account_page.dart
  31. 29 2
      lib/ui/account/password_reentry_page.dart
  32. 1 1
      lib/ui/account/recovery_key_page.dart
  33. 2 2
      lib/ui/account/sessions_page.dart
  34. 2 2
      lib/ui/account/two_factor_setup_page.dart
  35. 1 1
      lib/ui/backup_folder_selection_page.dart
  36. 4 4
      lib/ui/collections/collection_item_widget.dart
  37. 2 2
      lib/ui/collections/remote_collections_grid_view_widget.dart
  38. 1 1
      lib/ui/common/dialogs.dart
  39. 2 2
      lib/ui/create_collection_page.dart
  40. 1 1
      lib/ui/grant_permissions_widget.dart
  41. 3 3
      lib/ui/home_widget.dart
  42. 1 1
      lib/ui/huge_listview/draggable_scrollbar.dart
  43. 1 1
      lib/ui/huge_listview/huge_listview.dart
  44. 2 2
      lib/ui/huge_listview/lazy_loading_gallery.dart
  45. 2 2
      lib/ui/memories_widget.dart
  46. 1 1
      lib/ui/nav_bar.dart
  47. 8 8
      lib/ui/payment/payment_web_page.dart
  48. 6 6
      lib/ui/payment/stripe_subscription_page.dart
  49. 1 1
      lib/ui/payment/subscription_common_widgets.dart
  50. 2 2
      lib/ui/payment/subscription_plan_widget.dart
  51. 3 3
      lib/ui/settings/account_section_widget.dart
  52. 1 1
      lib/ui/settings/app_update_dialog.dart
  53. 1 1
      lib/ui/settings/app_version_widget.dart
  54. 6 6
      lib/ui/settings/backup_section_widget.dart
  55. 1 1
      lib/ui/settings/danger_section_widget.dart
  56. 1 1
      lib/ui/settings/debug_section_widget.dart
  57. 3 3
      lib/ui/settings/security_section_widget.dart
  58. 1 1
      lib/ui/settings/social_section_widget.dart
  59. 7 7
      lib/ui/shared_collections_gallery.dart
  60. 9 9
      lib/ui/sharing/manage_links_widget.dart
  61. 4 4
      lib/ui/sharing/share_collection_widget.dart
  62. 1 1
      lib/ui/status_bar_widget.dart
  63. 5 5
      lib/ui/tools/editor/filtered_image.dart
  64. 9 9
      lib/ui/tools/editor/image_editor_page.dart
  65. 1 0
      lib/ui/viewer/file/custom_app_bar.dart
  66. 1 1
      lib/ui/viewer/file/detail_page.dart
  67. 3 3
      lib/ui/viewer/file/fading_app_bar.dart
  68. 3 3
      lib/ui/viewer/file/fading_bottom_bar.dart
  69. 2 2
      lib/ui/viewer/file/file_info_dialog.dart
  70. 2 2
      lib/ui/viewer/file/thumbnail_widget.dart
  71. 1 1
      lib/ui/viewer/file/video_controls.dart
  72. 1 1
      lib/ui/viewer/file/zoomable_image.dart
  73. 3 3
      lib/ui/viewer/file/zoomable_live_image.dart
  74. 0 4
      lib/ui/viewer/gallery/device_folder_page.dart
  75. 3 3
      lib/ui/viewer/gallery/gallery.dart
  76. 2 2
      lib/ui/viewer/gallery/gallery_app_bar_widget.dart
  77. 3 3
      lib/ui/viewer/gallery/gallery_overlay_widget.dart
  78. 1 1
      lib/ui/viewer/gallery/trash_page.dart
  79. 2 2
      lib/utils/data_util.dart
  80. 6 6
      lib/utils/date_time_util.dart
  81. 2 2
      lib/utils/delete_file_util.dart
  82. 2 2
      lib/utils/dialog_util.dart
  83. 1 1
      lib/utils/diff_fetcher.dart
  84. 6 6
      lib/utils/email_util.dart
  85. 12 12
      lib/utils/file_uploader.dart
  86. 4 4
      lib/utils/file_uploader_util.dart
  87. 10 10
      lib/utils/file_util.dart
  88. 4 4
      lib/utils/hex.dart
  89. 2 2
      lib/utils/magic_util.dart
  90. 4 4
      lib/utils/share_util.dart
  91. 1 1
      lib/utils/trash_diff_fetcher.dart
  92. 50 0
      lib/utils/validator_util.dart
  93. 1 1
      pubspec.yaml

+ 1 - 0
analysis_options.yaml

@@ -15,6 +15,7 @@ linter:
     - prefer_const_constructors_in_immutables
     - prefer_const_constructors_in_immutables
     - prefer_const_declarations
     - prefer_const_declarations
     - prefer_const_literals_to_create_immutables
     - prefer_const_literals_to_create_immutables
+    - prefer_final_locals
     - require_trailing_commas
     - require_trailing_commas
     - sized_box_for_whitespace
     - sized_box_for_whitespace
     - use_full_hex_values_for_flutter_colors
     - use_full_hex_values_for_flutter_colors

+ 3 - 3
lib/core/cache/lru_map.dart

@@ -10,7 +10,7 @@ class LRUMap<K, V> {
   LRUMap(this._maxSize, [this._handler]);
   LRUMap(this._maxSize, [this._handler]);
 
 
   V get(K key) {
   V get(K key) {
-    V value = _map.remove(key);
+    final V value = _map.remove(key);
     if (value != null) {
     if (value != null) {
       _map[key] = value;
       _map[key] = value;
     }
     }
@@ -21,8 +21,8 @@ class LRUMap<K, V> {
     _map.remove(key);
     _map.remove(key);
     _map[key] = value;
     _map[key] = value;
     if (_map.length > _maxSize) {
     if (_map.length > _maxSize) {
-      K evictedKey = _map.keys.first;
-      V evictedValue = _map.remove(evictedKey);
+      final K evictedKey = _map.keys.first;
+      final V evictedValue = _map.remove(evictedKey);
       if (_handler != null) {
       if (_handler != null) {
         _handler(evictedKey, evictedValue);
         _handler(evictedKey, evictedValue);
       }
       }

+ 15 - 1
lib/core/configuration.dart

@@ -29,6 +29,7 @@ import 'package:photos/services/memories_service.dart';
 import 'package:photos/services/search_service.dart';
 import 'package:photos/services/search_service.dart';
 import 'package:photos/services/sync_service.dart';
 import 'package:photos/services/sync_service.dart';
 import 'package:photos/utils/crypto_util.dart';
 import 'package:photos/utils/crypto_util.dart';
+import 'package:photos/utils/validator_util.dart';
 import 'package:shared_preferences/shared_preferences.dart';
 import 'package:shared_preferences/shared_preferences.dart';
 import 'package:uuid/uuid.dart';
 import 'package:uuid/uuid.dart';
 import 'package:wakelock/wakelock.dart';
 import 'package:wakelock/wakelock.dart';
@@ -111,7 +112,7 @@ class Configuration {
       _logger.warning(e);
       _logger.warning(e);
     }
     }
     tempDirectory.createSync(recursive: true);
     tempDirectory.createSync(recursive: true);
-    var tempDirectoryPath = (await getTemporaryDirectory()).path;
+    final tempDirectoryPath = (await getTemporaryDirectory()).path;
     _thumbnailCacheDirectory = tempDirectoryPath + "/thumbnail-cache";
     _thumbnailCacheDirectory = tempDirectoryPath + "/thumbnail-cache";
     io.Directory(_thumbnailCacheDirectory).createSync(recursive: true);
     io.Directory(_thumbnailCacheDirectory).createSync(recursive: true);
     _sharedTempMediaDirectory = tempDirectoryPath + "/ente-shared-media";
     _sharedTempMediaDirectory = tempDirectoryPath + "/ente-shared-media";
@@ -242,12 +243,21 @@ class Configuration {
     String password,
     String password,
     KeyAttributes attributes,
     KeyAttributes attributes,
   ) async {
   ) async {
+    _logger.info('Start decryptAndSaveSecrets');
+    validatePreVerificationStateCheck(
+      attributes,
+      password,
+      getEncryptedToken(),
+    );
+    _logger.info('state validation done');
     final kek = await CryptoUtil.deriveKey(
     final kek = await CryptoUtil.deriveKey(
       utf8.encode(password),
       utf8.encode(password),
       Sodium.base642bin(attributes.kekSalt),
       Sodium.base642bin(attributes.kekSalt),
       attributes.memLimit,
       attributes.memLimit,
       attributes.opsLimit,
       attributes.opsLimit,
     );
     );
+
+    _logger.info('user-key done');
     Uint8List key;
     Uint8List key;
     try {
     try {
       key = CryptoUtil.decryptSync(
       key = CryptoUtil.decryptSync(
@@ -256,20 +266,24 @@ class Configuration {
         Sodium.base642bin(attributes.keyDecryptionNonce),
         Sodium.base642bin(attributes.keyDecryptionNonce),
       );
       );
     } catch (e) {
     } catch (e) {
+      _logger.severe('master-key failed, incorrect password?', e);
       throw Exception("Incorrect password");
       throw Exception("Incorrect password");
     }
     }
+    _logger.info("master-key done");
     await setKey(Sodium.bin2base64(key));
     await setKey(Sodium.bin2base64(key));
     final secretKey = CryptoUtil.decryptSync(
     final secretKey = CryptoUtil.decryptSync(
       Sodium.base642bin(attributes.encryptedSecretKey),
       Sodium.base642bin(attributes.encryptedSecretKey),
       key,
       key,
       Sodium.base642bin(attributes.secretKeyDecryptionNonce),
       Sodium.base642bin(attributes.secretKeyDecryptionNonce),
     );
     );
+    _logger.info("secret-key done");
     await setSecretKey(Sodium.bin2base64(secretKey));
     await setSecretKey(Sodium.bin2base64(secretKey));
     final token = CryptoUtil.openSealSync(
     final token = CryptoUtil.openSealSync(
       Sodium.base642bin(getEncryptedToken()),
       Sodium.base642bin(getEncryptedToken()),
       Sodium.base642bin(attributes.publicKey),
       Sodium.base642bin(attributes.publicKey),
       secretKey,
       secretKey,
     );
     );
+    _logger.info('appToken done');
     await setToken(
     await setToken(
       Sodium.bin2base64(token, variant: Sodium.base64VariantUrlsafe),
       Sodium.bin2base64(token, variant: Sodium.base64VariantUrlsafe),
     );
     );

+ 10 - 10
lib/core/error-reporting/super_logging.dart

@@ -23,7 +23,7 @@ extension SuperString on String {
     var start = 0;
     var start = 0;
 
 
     while (true) {
     while (true) {
-      var stop = start + chunkSize;
+      final stop = start + chunkSize;
       if (stop > length) break;
       if (stop > length) break;
       yield substring(start, stop);
       yield substring(start, stop);
       start = stop;
       start = stop;
@@ -37,7 +37,7 @@ extension SuperString on String {
 
 
 extension SuperLogRecord on LogRecord {
 extension SuperLogRecord on LogRecord {
   String toPrettyString([String extraLines]) {
   String toPrettyString([String extraLines]) {
-    var header = "[$loggerName] [$level] [$time]";
+    final header = "[$loggerName] [$level] [$time]";
 
 
     var msg = "$header $message";
     var msg = "$header $message";
 
 
@@ -236,7 +236,7 @@ class SuperLogging {
       extraLines = null;
       extraLines = null;
     }
     }
 
 
-    var str = config.prefix + " " + rec.toPrettyString(extraLines);
+    final str = config.prefix + " " + rec.toPrettyString(extraLines);
 
 
     // write to stdout
     // write to stdout
     printLog(str);
     printLog(str);
@@ -316,21 +316,21 @@ class SuperLogging {
 
 
     // choose [logDir]
     // choose [logDir]
     if (dirPath.isEmpty) {
     if (dirPath.isEmpty) {
-      var root = await getExternalStorageDirectory();
+      final root = await getExternalStorageDirectory();
       dirPath = '${root.path}/logs';
       dirPath = '${root.path}/logs';
     }
     }
 
 
     // create [logDir]
     // create [logDir]
-    var dir = Directory(dirPath);
+    final dir = Directory(dirPath);
     await dir.create(recursive: true);
     await dir.create(recursive: true);
 
 
-    var files = <File>[];
-    var dates = <File, DateTime>{};
+    final files = <File>[];
+    final dates = <File, DateTime>{};
 
 
     // collect all log files with valid names
     // collect all log files with valid names
     await for (final file in dir.list()) {
     await for (final file in dir.list()) {
       try {
       try {
-        var date = config.dateFmt.parse(basename(file.path));
+        final date = config.dateFmt.parse(basename(file.path));
         dates[file as File] = date;
         dates[file as File] = date;
         files.add(file);
         files.add(file);
       } on FormatException {}
       } on FormatException {}
@@ -363,7 +363,7 @@ class SuperLogging {
   static String appVersion;
   static String appVersion;
 
 
   static Future<String> getAppVersion() async {
   static Future<String> getAppVersion() async {
-    var pkgInfo = await PackageInfo.fromPlatform();
+    final pkgInfo = await PackageInfo.fromPlatform();
     return "${pkgInfo.version}+${pkgInfo.buildNumber}";
     return "${pkgInfo.version}+${pkgInfo.buildNumber}";
   }
   }
 
 
@@ -372,7 +372,7 @@ class SuperLogging {
     if (!Platform.isAndroid) {
     if (!Platform.isAndroid) {
       return false;
       return false;
     }
     }
-    var pkgName = (await PackageInfo.fromPlatform()).packageName;
+    final pkgName = (await PackageInfo.fromPlatform()).packageName;
     return pkgName.startsWith("io.ente.photos.fdroid");
     return pkgName.startsWith("io.ente.photos.fdroid");
   }
   }
 }
 }

+ 5 - 5
lib/db/collections_db.dart

@@ -60,8 +60,8 @@ class CollectionsDB {
   }
   }
 
 
   Future<Database> _initDatabase() async {
   Future<Database> _initDatabase() async {
-    Directory documentsDirectory = await getApplicationDocumentsDirectory();
-    String path = join(documentsDirectory.path, _databaseName);
+    final Directory documentsDirectory = await getApplicationDocumentsDirectory();
+    final String path = join(documentsDirectory.path, _databaseName);
     return await openDatabaseWithMigration(path, dbConfig);
     return await openDatabaseWithMigration(path, dbConfig);
   }
   }
 
 
@@ -157,7 +157,7 @@ class CollectionsDB {
 
 
   Future<List<dynamic>> insert(List<Collection> collections) async {
   Future<List<dynamic>> insert(List<Collection> collections) async {
     final db = await instance.database;
     final db = await instance.database;
-    var batch = db.batch();
+    final batch = db.batch();
     for (final collection in collections) {
     for (final collection in collections) {
       batch.insert(
       batch.insert(
         table,
         table,
@@ -202,7 +202,7 @@ class CollectionsDB {
   }
   }
 
 
   Map<String, dynamic> _getRowForCollection(Collection collection) {
   Map<String, dynamic> _getRowForCollection(Collection collection) {
-    var row = <String, dynamic>{};
+    final row = <String, dynamic>{};
     row[columnID] = collection.id;
     row[columnID] = collection.id;
     row[columnOwner] = collection.owner.toJson();
     row[columnOwner] = collection.owner.toJson();
     row[columnEncryptedKey] = collection.encryptedKey;
     row[columnEncryptedKey] = collection.encryptedKey;
@@ -230,7 +230,7 @@ class CollectionsDB {
   }
   }
 
 
   Collection _convertToCollection(Map<String, dynamic> row) {
   Collection _convertToCollection(Map<String, dynamic> row) {
-    Collection result = Collection(
+    final Collection result = Collection(
       row[columnID],
       row[columnID],
       User.fromJson(row[columnOwner]),
       User.fromJson(row[columnOwner]),
       row[columnEncryptedKey],
       row[columnEncryptedKey],

+ 8 - 8
lib/db/device_files_db.dart

@@ -25,7 +25,7 @@ extension DeviceFiles on FilesDB {
     var batch = db.batch();
     var batch = db.batch();
     int batchCounter = 0;
     int batchCounter = 0;
     for (MapEntry e in mappingToAdd.entries) {
     for (MapEntry e in mappingToAdd.entries) {
-      String pathID = e.key;
+      final String pathID = e.key;
       for (String localID in e.value) {
       for (String localID in e.value) {
         if (batchCounter == 400) {
         if (batchCounter == 400) {
           await batch.commit(noResult: true);
           await batch.commit(noResult: true);
@@ -54,7 +54,7 @@ extension DeviceFiles on FilesDB {
     var batch = db.batch();
     var batch = db.batch();
     int batchCounter = 0;
     int batchCounter = 0;
     for (MapEntry e in mappingsToRemove.entries) {
     for (MapEntry e in mappingsToRemove.entries) {
-      String pathID = e.key;
+      final String pathID = e.key;
       for (String localID in e.value) {
       for (String localID in e.value) {
         if (batchCounter == 400) {
         if (batchCounter == 400) {
           await batch.commit(noResult: true);
           await batch.commit(noResult: true);
@@ -188,9 +188,9 @@ extension DeviceFiles on FilesDB {
       final Database db = await database;
       final Database db = await database;
       final Set<String> existingPathIds = await getDevicePathIDs();
       final Set<String> existingPathIds = await getDevicePathIDs();
       for (Tuple2<AssetPathEntity, String> tup in devicePathInfo) {
       for (Tuple2<AssetPathEntity, String> tup in devicePathInfo) {
-        AssetPathEntity pathEntity = tup.item1;
-        String localID = tup.item2;
-        bool shouldUpdate = existingPathIds.contains(pathEntity.id);
+        final AssetPathEntity pathEntity = tup.item1;
+        final String localID = tup.item2;
+        final bool shouldUpdate = existingPathIds.contains(pathEntity.id);
         if (shouldUpdate) {
         if (shouldUpdate) {
           await db.rawUpdate(
           await db.rawUpdate(
             "UPDATE device_path_collections SET name = ?, cover_id = ?, count"
             "UPDATE device_path_collections SET name = ?, cover_id = ?, count"
@@ -241,7 +241,7 @@ extension DeviceFiles on FilesDB {
     var batch = db.batch();
     var batch = db.batch();
     int batchCounter = 0;
     int batchCounter = 0;
     for (MapEntry e in syncStatus.entries) {
     for (MapEntry e in syncStatus.entries) {
-      String pathID = e.key;
+      final String pathID = e.key;
       if (batchCounter == 400) {
       if (batchCounter == 400) {
         await batch.commit(noResult: true);
         await batch.commit(noResult: true);
         batch = db.batch();
         batch = db.batch();
@@ -283,7 +283,7 @@ extension DeviceFiles on FilesDB {
   }) async {
   }) async {
     final db = await database;
     final db = await database;
     final order = (asc ?? false ? 'ASC' : 'DESC');
     final order = (asc ?? false ? 'ASC' : 'DESC');
-    String rawQuery = '''
+    final String rawQuery = '''
     SELECT *
     SELECT *
           FROM ${FilesDB.filesTable}
           FROM ${FilesDB.filesTable}
           WHERE ${FilesDB.columnLocalID} IS NOT NULL AND
           WHERE ${FilesDB.columnLocalID} IS NOT NULL AND
@@ -314,7 +314,7 @@ extension DeviceFiles on FilesDB {
       );
       );
       final List<DevicePathCollection> deviceCollections = [];
       final List<DevicePathCollection> deviceCollections = [];
       for (var row in devicePathRows) {
       for (var row in devicePathRows) {
-        DevicePathCollection devicePathCollection = DevicePathCollection(
+        final DevicePathCollection devicePathCollection = DevicePathCollection(
           row["id"],
           row["id"],
           row['name'],
           row['name'],
           count: row['count'],
           count: row['count'],

+ 4 - 3
lib/db/file_migration_db.dart

@@ -65,8 +65,9 @@ class FilesMigrationDB {
 
 
   // this opens the database (and creates it if it doesn't exist)
   // this opens the database (and creates it if it doesn't exist)
   Future<Database> _initDatabase() async {
   Future<Database> _initDatabase() async {
-    Directory documentsDirectory = await getApplicationDocumentsDirectory();
-    String path = join(documentsDirectory.path, _databaseName);
+    final Directory documentsDirectory =
+        await getApplicationDocumentsDirectory();
+    final String path = join(documentsDirectory.path, _databaseName);
     debugPrint("DB path " + path);
     debugPrint("DB path " + path);
     return await openDatabaseWithMigration(path, dbConfig);
     return await openDatabaseWithMigration(path, dbConfig);
   }
   }
@@ -132,7 +133,7 @@ class FilesMigrationDB {
     String reason,
     String reason,
   ) async {
   ) async {
     final db = await instance.database;
     final db = await instance.database;
-    String whereClause = '$_columnReason = "$reason"';
+    final String whereClause = '$_columnReason = "$reason"';
     final rows = await db.query(
     final rows = await db.query(
       tableName,
       tableName,
       limit: limit,
       limit: limit,

+ 18 - 14
lib/db/files_db.dart

@@ -1,4 +1,5 @@
 import 'dart:io' as io;
 import 'dart:io' as io;
+import 'dart:io';
 
 
 import 'package:flutter/foundation.dart';
 import 'package:flutter/foundation.dart';
 import 'package:logging/logging.dart';
 import 'package:logging/logging.dart';
@@ -97,8 +98,9 @@ class FilesDB {
 
 
   // this opens the database (and creates it if it doesn't exist)
   // this opens the database (and creates it if it doesn't exist)
   Future<Database> _initDatabase() async {
   Future<Database> _initDatabase() async {
-    io.Directory documentsDirectory = await getApplicationDocumentsDirectory();
-    String path = join(documentsDirectory.path, _databaseName);
+    final Directory documentsDirectory =
+        await getApplicationDocumentsDirectory();
+    final String path = join(documentsDirectory.path, _databaseName);
     _logger.info("DB path " + path);
     _logger.info("DB path " + path);
     return await openDatabaseWithMigration(path, dbConfig);
     return await openDatabaseWithMigration(path, dbConfig);
   }
   }
@@ -333,9 +335,9 @@ class FilesDB {
   Future<void> deleteDB() async {
   Future<void> deleteDB() async {
     if (kDebugMode) {
     if (kDebugMode) {
       debugPrint("Deleting files db");
       debugPrint("Deleting files db");
-      io.Directory documentsDirectory =
+      final io.Directory documentsDirectory =
           await getApplicationDocumentsDirectory();
           await getApplicationDocumentsDirectory();
-      String path = join(documentsDirectory.path, _databaseName);
+      final String path = join(documentsDirectory.path, _databaseName);
       io.File(path).deleteSync(recursive: true);
       io.File(path).deleteSync(recursive: true);
       _dbFuture = null;
       _dbFuture = null;
     }
     }
@@ -471,7 +473,7 @@ class FilesDB {
       limit: limit,
       limit: limit,
     );
     );
     final files = convertToFiles(results);
     final files = convertToFiles(results);
-    List<File> deduplicatedFiles =
+    final List<File> deduplicatedFiles =
         _deduplicatedAndFilterIgnoredFiles(files, ignoredCollectionIDs);
         _deduplicatedAndFilterIgnoredFiles(files, ignoredCollectionIDs);
     return FileLoadResult(deduplicatedFiles, files.length == limit);
     return FileLoadResult(deduplicatedFiles, files.length == limit);
   }
   }
@@ -496,8 +498,9 @@ class FilesDB {
           '$columnCreationTime ' + order + ', $columnModificationTime ' + order,
           '$columnCreationTime ' + order + ', $columnModificationTime ' + order,
       limit: limit,
       limit: limit,
     );
     );
+
     final files = convertToFiles(results);
     final files = convertToFiles(results);
-    List<File> deduplicatedFiles =
+    final List<File> deduplicatedFiles =
         _deduplicatedAndFilterIgnoredFiles(files, ignoredCollectionIDs);
         _deduplicatedAndFilterIgnoredFiles(files, ignoredCollectionIDs);
     return FileLoadResult(deduplicatedFiles, files.length == limit);
     return FileLoadResult(deduplicatedFiles, files.length == limit);
   }
   }
@@ -529,7 +532,7 @@ class FilesDB {
       limit: limit,
       limit: limit,
     );
     );
     final files = convertToFiles(results);
     final files = convertToFiles(results);
-    List<File> deduplicatedFiles =
+    final List<File> deduplicatedFiles =
         _deduplicatedAndFilterIgnoredFiles(files, ignoredCollectionIDs);
         _deduplicatedAndFilterIgnoredFiles(files, ignoredCollectionIDs);
     return FileLoadResult(deduplicatedFiles, files.length == limit);
     return FileLoadResult(deduplicatedFiles, files.length == limit);
   }
   }
@@ -708,7 +711,7 @@ class FilesDB {
       orderBy: '$columnCreationTime DESC',
       orderBy: '$columnCreationTime DESC',
       groupBy: columnLocalID,
       groupBy: columnLocalID,
     );
     );
-    var files = convertToFiles(results);
+    final files = convertToFiles(results);
     // future-safe filter just to ensure that the query doesn't end up  returning files
     // future-safe filter just to ensure that the query doesn't end up  returning files
     // which should not be backed up
     // which should not be backed up
     files.removeWhere(
     files.removeWhere(
@@ -887,7 +890,8 @@ class FilesDB {
     // look up two hash at max, for handling live photos
     // look up two hash at max, for handling live photos
     assert(hash.length < 3, "number of hash can not be more than 2");
     assert(hash.length < 3, "number of hash can not be more than 2");
     final db = await instance.database;
     final db = await instance.database;
-    String rawQuery = 'SELECT * from files where ($columnUploadedFileID != '
+    final String rawQuery =
+        'SELECT * from files where ($columnUploadedFileID != '
         'NULL OR $columnUploadedFileID != -1) AND $columnOwnerID = $ownerID '
         'NULL OR $columnUploadedFileID != -1) AND $columnOwnerID = $ownerID '
         'AND ($columnHash = "${hash.first}" OR $columnHash = "${hash.last}")';
         'AND ($columnHash = "${hash.first}" OR $columnHash = "${hash.last}")';
     final rows = await db.rawQuery(rawQuery, []);
     final rows = await db.rawQuery(rawQuery, []);
@@ -1032,7 +1036,7 @@ class FilesDB {
 
 
   Future<int> collectionFileCount(int collectionID) async {
   Future<int> collectionFileCount(int collectionID) async {
     final db = await instance.database;
     final db = await instance.database;
-    var count = Sqflite.firstIntValue(
+    final count = Sqflite.firstIntValue(
       await db.rawQuery(
       await db.rawQuery(
         'SELECT COUNT(*) FROM $filesTable where $columnCollectionID = $collectionID',
         'SELECT COUNT(*) FROM $filesTable where $columnCollectionID = $collectionID',
       ),
       ),
@@ -1042,7 +1046,7 @@ class FilesDB {
 
 
   Future<int> fileCountWithVisibility(int visibility, int ownerID) async {
   Future<int> fileCountWithVisibility(int visibility, int ownerID) async {
     final db = await instance.database;
     final db = await instance.database;
-    var count = Sqflite.firstIntValue(
+    final count = Sqflite.firstIntValue(
       await db.rawQuery(
       await db.rawQuery(
         'SELECT COUNT(*) FROM $filesTable where $columnMMdVisibility = $visibility AND $columnOwnerID = $ownerID',
         'SELECT COUNT(*) FROM $filesTable where $columnMMdVisibility = $visibility AND $columnOwnerID = $ownerID',
       ),
       ),
@@ -1248,9 +1252,9 @@ class FilesDB {
 
 
   Future<List<File>> getAllFilesFromDB() async {
   Future<List<File>> getAllFilesFromDB() async {
     final db = await instance.database;
     final db = await instance.database;
-    List<Map<String, dynamic>> result = await db.query(filesTable);
-    List<File> files = convertToFiles(result);
-    List<File> deduplicatedFiles =
+    final List<Map<String, dynamic>> result = await db.query(filesTable);
+    final List<File> files = convertToFiles(result);
+    final List<File> deduplicatedFiles =
         _deduplicatedAndFilterIgnoredFiles(files, null);
         _deduplicatedAndFilterIgnoredFiles(files, null);
     return deduplicatedFiles;
     return deduplicatedFiles;
   }
   }

+ 2 - 2
lib/db/ignored_files_db.dart

@@ -52,8 +52,8 @@ class IgnoredFilesDB {
 
 
   // this opens the database (and creates it if it doesn't exist)
   // this opens the database (and creates it if it doesn't exist)
   Future<Database> _initDatabase() async {
   Future<Database> _initDatabase() async {
-    Directory documentsDirectory = await getApplicationDocumentsDirectory();
-    String path = join(documentsDirectory.path, _databaseName);
+    final Directory documentsDirectory = await getApplicationDocumentsDirectory();
+    final String path = join(documentsDirectory.path, _databaseName);
     return await openDatabase(
     return await openDatabase(
       path,
       path,
       version: _databaseVersion,
       version: _databaseVersion,

+ 3 - 3
lib/db/memories_db.dart

@@ -25,8 +25,8 @@ class MemoriesDB {
   }
   }
 
 
   Future<Database> _initDatabase() async {
   Future<Database> _initDatabase() async {
-    Directory documentsDirectory = await getApplicationDocumentsDirectory();
-    String path = join(documentsDirectory.path, _databaseName);
+    final Directory documentsDirectory = await getApplicationDocumentsDirectory();
+    final String path = join(documentsDirectory.path, _databaseName);
     return await openDatabase(
     return await openDatabase(
       path,
       path,
       version: _databaseVersion,
       version: _databaseVersion,
@@ -74,7 +74,7 @@ class MemoriesDB {
   }
   }
 
 
   Map<String, dynamic> _getRowForSeenMemory(Memory memory, int timestamp) {
   Map<String, dynamic> _getRowForSeenMemory(Memory memory, int timestamp) {
-    var row = <String, dynamic>{};
+    final row = <String, dynamic>{};
     row[columnFileID] = memory.file.generatedID;
     row[columnFileID] = memory.file.generatedID;
     row[columnSeenTime] = timestamp;
     row[columnSeenTime] = timestamp;
     return row;
     return row;

+ 3 - 3
lib/db/public_keys_db.dart

@@ -26,8 +26,8 @@ class PublicKeysDB {
   }
   }
 
 
   Future<Database> _initDatabase() async {
   Future<Database> _initDatabase() async {
-    Directory documentsDirectory = await getApplicationDocumentsDirectory();
-    String path = join(documentsDirectory.path, _databaseName);
+    final Directory documentsDirectory = await getApplicationDocumentsDirectory();
+    final String path = join(documentsDirectory.path, _databaseName);
     return await openDatabase(
     return await openDatabase(
       path,
       path,
       version: _databaseVersion,
       version: _databaseVersion,
@@ -72,7 +72,7 @@ class PublicKeysDB {
   }
   }
 
 
   Map<String, dynamic> _getRow(PublicKey key) {
   Map<String, dynamic> _getRow(PublicKey key) {
-    var row = <String, dynamic>{};
+    final row = <String, dynamic>{};
     row[columnEmail] = key.email;
     row[columnEmail] = key.email;
     row[columnPublicKey] = key.publicKey;
     row[columnPublicKey] = key.publicKey;
     return row;
     return row;

+ 4 - 4
lib/db/trash_db.dart

@@ -85,8 +85,8 @@ class TrashDB {
 
 
   // this opens the database (and creates it if it doesn't exist)
   // this opens the database (and creates it if it doesn't exist)
   Future<Database> _initDatabase() async {
   Future<Database> _initDatabase() async {
-    Directory documentsDirectory = await getApplicationDocumentsDirectory();
-    String path = join(documentsDirectory.path, _databaseName);
+    final Directory documentsDirectory = await getApplicationDocumentsDirectory();
+    final String path = join(documentsDirectory.path, _databaseName);
     _logger.info("DB path " + path);
     _logger.info("DB path " + path);
     return await openDatabase(
     return await openDatabase(
       path,
       path,
@@ -103,7 +103,7 @@ class TrashDB {
   // getRecentlyTrashedFile returns the file which was trashed recently
   // getRecentlyTrashedFile returns the file which was trashed recently
   Future<TrashFile> getRecentlyTrashedFile() async {
   Future<TrashFile> getRecentlyTrashedFile() async {
     final db = await instance.database;
     final db = await instance.database;
-    var rows = await db.query(
+    final rows = await db.query(
       tableName,
       tableName,
       orderBy: '$columnTrashDeleteBy DESC',
       orderBy: '$columnTrashDeleteBy DESC',
       limit: 1,
       limit: 1,
@@ -116,7 +116,7 @@ class TrashDB {
 
 
   Future<int> count() async {
   Future<int> count() async {
     final db = await instance.database;
     final db = await instance.database;
-    var count = Sqflite.firstIntValue(
+    final count = Sqflite.firstIntValue(
       await db.rawQuery('SELECT COUNT(*) FROM $tableName'),
       await db.rawQuery('SELECT COUNT(*) FROM $tableName'),
     );
     );
     return count;
     return count;

+ 2 - 2
lib/db/upload_locks_db.dart

@@ -24,8 +24,8 @@ class UploadLocksDB {
   }
   }
 
 
   Future<Database> _initDatabase() async {
   Future<Database> _initDatabase() async {
-    Directory documentsDirectory = await getApplicationDocumentsDirectory();
-    String path = join(documentsDirectory.path, _databaseName);
+    final Directory documentsDirectory = await getApplicationDocumentsDirectory();
+    final String path = join(documentsDirectory.path, _databaseName);
     return await openDatabase(
     return await openDatabase(
       path,
       path,
       version: _databaseVersion,
       version: _databaseVersion,

+ 6 - 6
lib/main.dart

@@ -231,8 +231,8 @@ Future<void> _killBGTask([String taskId]) async {
 }
 }
 
 
 Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
 Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
-  bool isRunningInFG = await _isRunningInForeground(); // hb
-  bool isInForeground = AppLifecycleService.instance.isForeground;
+  final bool isRunningInFG = await _isRunningInForeground(); // hb
+  final bool isInForeground = AppLifecycleService.instance.isForeground;
   if (_isProcessRunning) {
   if (_isProcessRunning) {
     _logger.info(
     _logger.info(
       "Background push received when app is alive and runningInFS: $isRunningInFG inForeground: $isInForeground",
       "Background push received when app is alive and runningInFS: $isRunningInFG inForeground: $isInForeground",
@@ -259,18 +259,18 @@ Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
 }
 }
 
 
 Future<void> _logFGHeartBeatInfo() async {
 Future<void> _logFGHeartBeatInfo() async {
-  bool isRunningInFG = await _isRunningInForeground();
+  final bool isRunningInFG = await _isRunningInForeground();
   final prefs = await SharedPreferences.getInstance();
   final prefs = await SharedPreferences.getInstance();
   await prefs.reload();
   await prefs.reload();
-  var lastFGTaskHeartBeatTime = prefs.getInt(kLastFGTaskHeartBeatTime) ?? 0;
-  String lastRun = lastFGTaskHeartBeatTime == 0
+  final lastFGTaskHeartBeatTime = prefs.getInt(kLastFGTaskHeartBeatTime) ?? 0;
+  final String lastRun = lastFGTaskHeartBeatTime == 0
       ? 'never'
       ? 'never'
       : DateTime.fromMicrosecondsSinceEpoch(lastFGTaskHeartBeatTime).toString();
       : DateTime.fromMicrosecondsSinceEpoch(lastFGTaskHeartBeatTime).toString();
   _logger.info('isAlreaduunningFG: $isRunningInFG, last Beat: $lastRun');
   _logger.info('isAlreaduunningFG: $isRunningInFG, last Beat: $lastRun');
 }
 }
 
 
 void _scheduleSuicide(Duration duration, [String taskID]) {
 void _scheduleSuicide(Duration duration, [String taskID]) {
-  var taskIDVal = taskID ?? 'no taskID';
+  final taskIDVal = taskID ?? 'no taskID';
   _logger.warning("Schedule seppuku taskID: $taskIDVal");
   _logger.warning("Schedule seppuku taskID: $taskIDVal");
   Future.delayed(duration, () {
   Future.delayed(duration, () {
     _logger.warning("TLE, committing seppuku for taskID: $taskIDVal");
     _logger.warning("TLE, committing seppuku for taskID: $taskIDVal");

+ 1 - 1
lib/models/collection.dart

@@ -85,7 +85,7 @@ class Collection {
     String mMdEncodedJson,
     String mMdEncodedJson,
     int mMdVersion,
     int mMdVersion,
   }) {
   }) {
-    Collection result = Collection(
+    final Collection result = Collection(
       id ?? this.id,
       id ?? this.id,
       owner ?? this.owner,
       owner ?? this.owner,
       encryptedKey ?? this.encryptedKey,
       encryptedKey ?? this.encryptedKey,

+ 2 - 2
lib/models/file.dart

@@ -58,8 +58,8 @@ class File extends EnteFile {
 
 
   File();
   File();
 
 
-  static File fromAsset(String pathName, AssetEntity asset) {
-    File file = File();
+  static Future<File> fromAsset(String pathName, AssetEntity asset) async {
+    final File file = File();
     file.localID = asset.id;
     file.localID = asset.id;
     file.title = asset.title;
     file.title = asset.title;
     file.deviceFolder = pathName;
     file.deviceFolder = pathName;

+ 3 - 3
lib/models/selected_files.dart

@@ -9,7 +9,7 @@ class SelectedFiles extends ChangeNotifier {
     // To handle the cases, where the file might have changed due to upload
     // To handle the cases, where the file might have changed due to upload
     // or any other update, using file.generatedID to track if this file was already
     // or any other update, using file.generatedID to track if this file was already
     // selected or not
     // selected or not
-    File alreadySelected = files.firstWhere(
+    final File alreadySelected = files.firstWhere(
       (element) => element.generatedID == file.generatedID,
       (element) => element.generatedID == file.generatedID,
       orElse: () => null,
       orElse: () => null,
     );
     );
@@ -24,7 +24,7 @@ class SelectedFiles extends ChangeNotifier {
   }
   }
 
 
   bool isFileSelected(File file) {
   bool isFileSelected(File file) {
-    File alreadySelected = files.firstWhere(
+    final File alreadySelected = files.firstWhere(
       (element) => element.generatedID == file.generatedID,
       (element) => element.generatedID == file.generatedID,
       orElse: () => null,
       orElse: () => null,
     );
     );
@@ -32,7 +32,7 @@ class SelectedFiles extends ChangeNotifier {
   }
   }
 
 
   bool isPartOfLastSection(File file) {
   bool isPartOfLastSection(File file) {
-    File alreadySelected = lastSelections.firstWhere(
+    final File alreadySelected = lastSelections.firstWhere(
       (element) => element.generatedID == file.generatedID,
       (element) => element.generatedID == file.generatedID,
       orElse: () => null,
       orElse: () => null,
     );
     );

+ 1 - 1
lib/models/subscription.dart

@@ -144,7 +144,7 @@ class Attributes {
   }
   }
 
 
   Map<String, dynamic> toJson() {
   Map<String, dynamic> toJson() {
-    var map = <String, dynamic>{};
+    final map = <String, dynamic>{};
     map["isCancelled"] = isCancelled;
     map["isCancelled"] = isCancelled;
     map["customerID"] = customerID;
     map["customerID"] = customerID;
     return map;
     return map;

+ 2 - 2
lib/services/collections_service.dart

@@ -308,7 +308,7 @@ class CollectionsService {
       // read the existing magic metadata and apply new updates to existing data
       // read the existing magic metadata and apply new updates to existing data
       // current update is simple replace. This will be enhanced in the future,
       // current update is simple replace. This will be enhanced in the future,
       // as required.
       // as required.
-      Map<String, dynamic> jsonToUpdate =
+      final Map<String, dynamic> jsonToUpdate =
           jsonDecode(collection.mMdEncodedJson ?? '{}');
           jsonDecode(collection.mMdEncodedJson ?? '{}');
       newMetadataUpdate.forEach((key, value) {
       newMetadataUpdate.forEach((key, value) {
         jsonToUpdate[key] = value;
         jsonToUpdate[key] = value;
@@ -325,7 +325,7 @@ class CollectionsService {
       );
       );
       // for required field, the json validator on golang doesn't treat 0 as valid
       // for required field, the json validator on golang doesn't treat 0 as valid
       // value. Instead of changing version to ptr, decided to start version with 1.
       // value. Instead of changing version to ptr, decided to start version with 1.
-      int currentVersion = max(collection.mMdVersion, 1);
+      final int currentVersion = max(collection.mMdVersion, 1);
       final params = UpdateMagicMetadataRequest(
       final params = UpdateMagicMetadataRequest(
         id: collection.id,
         id: collection.id,
         magicMetadata: MetadataRequest(
         magicMetadata: MetadataRequest(

+ 1 - 1
lib/services/deduplication_service.dart

@@ -18,7 +18,7 @@ class DeduplicationService {
 
 
   Future<List<DuplicateFiles>> getDuplicateFiles() async {
   Future<List<DuplicateFiles>> getDuplicateFiles() async {
     try {
     try {
-      DuplicateFilesResponse dupes = await _fetchDuplicateFileIDs();
+      final DuplicateFilesResponse dupes = await _fetchDuplicateFileIDs();
       final ids = <int>[];
       final ids = <int>[];
       for (final dupe in dupes.duplicates) {
       for (final dupe in dupes.duplicates) {
         ids.addAll(dupe.fileIDs);
         ids.addAll(dupe.fileIDs);

+ 1 - 1
lib/services/favorites_service.dart

@@ -53,7 +53,7 @@ class FavoritesService {
 
 
   Future<void> removeFromFavorites(File file) async {
   Future<void> removeFromFavorites(File file) async {
     final collectionID = await _getOrCreateFavoriteCollectionID();
     final collectionID = await _getOrCreateFavoriteCollectionID();
-    var fileID = file.uploadedFileID;
+    final fileID = file.uploadedFileID;
     if (fileID == null) {
     if (fileID == null) {
       // Do nothing, ignore
       // Do nothing, ignore
     } else {
     } else {

+ 1 - 1
lib/services/feature_flag_service.dart

@@ -94,7 +94,7 @@ class FeatureFlagService {
   }
   }
 
 
   bool _isInternalUserOrDebugBuild() {
   bool _isInternalUserOrDebugBuild() {
-    String email = Configuration.instance.getEmail();
+    final String email = Configuration.instance.getEmail();
     return (email != null && email.endsWith("@ente.io")) || kDebugMode;
     return (email != null && email.endsWith("@ente.io")) || kDebugMode;
   }
   }
 
 

+ 4 - 4
lib/services/file_magic_service.dart

@@ -30,7 +30,7 @@ class FileMagicService {
       FileMagicService._privateConstructor();
       FileMagicService._privateConstructor();
 
 
   Future<void> changeVisibility(List<File> files, int visibility) async {
   Future<void> changeVisibility(List<File> files, int visibility) async {
-    Map<String, dynamic> update = {kMagicKeyVisibility: visibility};
+    final Map<String, dynamic> update = {kMagicKeyVisibility: visibility};
     await _updateMagicData(files, update);
     await _updateMagicData(files, update);
     if (visibility == kVisibilityVisible) {
     if (visibility == kVisibilityVisible) {
       // Force reload home gallery to pull in the now unarchived files
       // Force reload home gallery to pull in the now unarchived files
@@ -62,7 +62,7 @@ class FileMagicService {
         // read the existing magic metadata and apply new updates to existing data
         // read the existing magic metadata and apply new updates to existing data
         // current update is simple replace. This will be enhanced in the future,
         // current update is simple replace. This will be enhanced in the future,
         // as required.
         // as required.
-        Map<String, dynamic> jsonToUpdate = jsonDecode(file.pubMmdEncodedJson);
+        final Map<String, dynamic> jsonToUpdate = jsonDecode(file.pubMmdEncodedJson);
         newMetadataUpdate.forEach((key, value) {
         newMetadataUpdate.forEach((key, value) {
           jsonToUpdate[key] = value;
           jsonToUpdate[key] = value;
         });
         });
@@ -132,7 +132,7 @@ class FileMagicService {
         // read the existing magic metadata and apply new updates to existing data
         // read the existing magic metadata and apply new updates to existing data
         // current update is simple replace. This will be enhanced in the future,
         // current update is simple replace. This will be enhanced in the future,
         // as required.
         // as required.
-        Map<String, dynamic> jsonToUpdate = jsonDecode(file.mMdEncodedJson);
+        final Map<String, dynamic> jsonToUpdate = jsonDecode(file.mMdEncodedJson);
         newMetadataUpdate.forEach((key, value) {
         newMetadataUpdate.forEach((key, value) {
           jsonToUpdate[key] = value;
           jsonToUpdate[key] = value;
         });
         });
@@ -224,7 +224,7 @@ class MetadataRequest {
   }
   }
 
 
   Map<String, dynamic> toJson() {
   Map<String, dynamic> toJson() {
-    var map = <String, dynamic>{};
+    final map = <String, dynamic>{};
     map['version'] = version;
     map['version'] = version;
     map['count'] = count;
     map['count'] = count;
     map['data'] = data;
     map['data'] = data;

+ 4 - 4
lib/services/ignored_files_service.dart

@@ -48,8 +48,8 @@ class IgnoredFilesService {
   }
   }
 
 
   Future<void> removeIgnoredMappings(List<File> files) async {
   Future<void> removeIgnoredMappings(List<File> files) async {
-    List<IgnoredFile> ignoredFiles = [];
-    Set<String> idsToRemoveFromCache = {};
+    final List<IgnoredFile> ignoredFiles = [];
+    final Set<String> idsToRemoveFromCache = {};
     for (var file in files) {
     for (var file in files) {
       if (Platform.isIOS && file.localID != null) {
       if (Platform.isIOS && file.localID != null) {
         // in IOS, the imported file might not have title fetched by default.
         // in IOS, the imported file might not have title fetched by default.
@@ -58,10 +58,10 @@ class IgnoredFilesService {
           file.title = 'dummyTitle';
           file.title = 'dummyTitle';
         }
         }
       }
       }
-      var ignoredFile = IgnoredFile.fromFile(file);
+      final ignoredFile = IgnoredFile.fromFile(file);
       if (ignoredFile != null) {
       if (ignoredFile != null) {
         ignoredFiles.add(ignoredFile);
         ignoredFiles.add(ignoredFile);
-        var id = _idForIgnoredFile(ignoredFile);
+        final id = _idForIgnoredFile(ignoredFile);
         if (id != null) {
         if (id != null) {
           idsToRemoveFromCache.add(id);
           idsToRemoveFromCache.add(id);
         }
         }

+ 18 - 18
lib/services/local/local_sync_util.dart

@@ -20,16 +20,16 @@ Future<Tuple2<List<LocalPathAsset>, List<File>>> getLocalPathAssetsAndFiles(
     updateFromTime: fromTime,
     updateFromTime: fromTime,
     updateToTime: toTime,
     updateToTime: toTime,
   );
   );
-  List<LocalPathAsset> localPathAssets = [];
+  final List<LocalPathAsset> localPathAssets = [];
 
 
   // alreadySeenLocalIDs is used to track and ignore file with particular
   // alreadySeenLocalIDs is used to track and ignore file with particular
   // localID if it's already present in another album. This only impacts iOS
   // localID if it's already present in another album. This only impacts iOS
   // devices where a file can belong to multiple
   // devices where a file can belong to multiple
-  Set<String> alreadySeenLocalIDs = {};
-  List<File> uniqueFiles = [];
+  final Set<String> alreadySeenLocalIDs = {};
+  final List<File> uniqueFiles = [];
   for (AssetPathEntity pathEntity in pathEntities) {
   for (AssetPathEntity pathEntity in pathEntities) {
-    List<AssetEntity> assetsInPath = await _getAllAssetLists(pathEntity);
-    Tuple2<Set<String>, List<File>> result = await computer.compute(
+    final List<AssetEntity> assetsInPath = await _getAllAssetLists(pathEntity);
+    final Tuple2<Set<String>, List<File>> result = await computer.compute(
       _getLocalIDsAndFilesFromAssets,
       _getLocalIDsAndFilesFromAssets,
       param: <String, dynamic>{
       param: <String, dynamic>{
         "pathEntity": pathEntity,
         "pathEntity": pathEntity,
@@ -58,7 +58,7 @@ Future<Tuple2<List<LocalPathAsset>, List<File>>> getLocalPathAssetsAndFiles(
 // identify (in future) which AssetPath needs to be re-synced again.
 // identify (in future) which AssetPath needs to be re-synced again.
 Future<List<Tuple2<AssetPathEntity, String>>>
 Future<List<Tuple2<AssetPathEntity, String>>>
     getDeviceFolderWithCountAndCoverID() async {
     getDeviceFolderWithCountAndCoverID() async {
-  List<Tuple2<AssetPathEntity, String>> result = [];
+  final List<Tuple2<AssetPathEntity, String>> result = [];
   final pathEntities = await _getGalleryList(
   final pathEntities = await _getGalleryList(
     needsTitle: false,
     needsTitle: false,
     containsModifiedPath: true,
     containsModifiedPath: true,
@@ -67,11 +67,11 @@ Future<List<Tuple2<AssetPathEntity, String>>>
   );
   );
   for (AssetPathEntity pathEntity in pathEntities) {
   for (AssetPathEntity pathEntity in pathEntities) {
     //todo: test and handle empty album case
     //todo: test and handle empty album case
-    var latestEntity = await pathEntity.getAssetListPaged(
+    final latestEntity = await pathEntity.getAssetListPaged(
       page: 0,
       page: 0,
       size: 1,
       size: 1,
     );
     );
-    String localCoverID = latestEntity.first.id;
+    final String localCoverID = latestEntity.first.id;
     result.add(Tuple2(pathEntity, localCoverID));
     result.add(Tuple2(pathEntity, localCoverID));
   }
   }
   return result;
   return result;
@@ -95,7 +95,7 @@ Future<List<LocalPathAsset>> getAllLocalAssets() async {
   );
   );
   final List<LocalPathAsset> localPathAssets = [];
   final List<LocalPathAsset> localPathAssets = [];
   for (final assetPath in assetPaths) {
   for (final assetPath in assetPaths) {
-    Set<String> localIDs = <String>{};
+    final Set<String> localIDs = <String>{};
     for (final asset in await _getAllAssetLists(assetPath)) {
     for (final asset in await _getAllAssetLists(assetPath)) {
       localIDs.add(asset.id);
       localIDs.add(asset.id);
     }
     }
@@ -147,12 +147,12 @@ LocalUnSyncResult _getUnsyncedAssets(Map<String, dynamic> args) {
   final List<LocalPathAsset> unsyncedAssets = [];
   final List<LocalPathAsset> unsyncedAssets = [];
 
 
   for (final localPathAsset in onDeviceLocalPathAsset) {
   for (final localPathAsset in onDeviceLocalPathAsset) {
-    String pathID = localPathAsset.pathID;
+    final String pathID = localPathAsset.pathID;
     // Start identifying pathID to localID mapping changes which needs to be
     // Start identifying pathID to localID mapping changes which needs to be
     // synced
     // synced
-    Set<String> candidateLocalIDsForRemoval =
+    final Set<String> candidateLocalIDsForRemoval =
         pathToLocalIDs[pathID] ?? <String>{};
         pathToLocalIDs[pathID] ?? <String>{};
-    Set<String> missingLocalIDsInPath = <String>{};
+    final Set<String> missingLocalIDsInPath = <String>{};
     for (final String localID in localPathAsset.localIDs) {
     for (final String localID in localPathAsset.localIDs) {
       if (candidateLocalIDsForRemoval.contains(localID)) {
       if (candidateLocalIDsForRemoval.contains(localID)) {
         // remove the localID after checking. Any pending existing ID indicates
         // remove the localID after checking. Any pending existing ID indicates
@@ -189,12 +189,12 @@ Future<List<File>> _convertLocalAssetsToUniqueFiles(
   final Set<String> alreadySeenLocalIDs = <String>{};
   final Set<String> alreadySeenLocalIDs = <String>{};
   final List<File> files = [];
   final List<File> files = [];
   for (LocalPathAsset localPathAsset in assets) {
   for (LocalPathAsset localPathAsset in assets) {
-    String localPathName = localPathAsset.pathName;
+    final String localPathName = localPathAsset.pathName;
     for (final String localID in localPathAsset.localIDs) {
     for (final String localID in localPathAsset.localIDs) {
       if (!alreadySeenLocalIDs.contains(localID)) {
       if (!alreadySeenLocalIDs.contains(localID)) {
-        var assetEntity = await AssetEntity.fromId(localID);
+        final assetEntity = await AssetEntity.fromId(localID);
         files.add(
         files.add(
-          File.fromAsset(localPathName, assetEntity),
+          await File.fromAsset(localPathName, assetEntity),
         );
         );
         alreadySeenLocalIDs.add(localID);
         alreadySeenLocalIDs.add(localID);
       }
       }
@@ -250,7 +250,7 @@ Future<List<AssetPathEntity>> _getGalleryList({
 }
 }
 
 
 Future<List<AssetEntity>> _getAllAssetLists(AssetPathEntity pathEntity) async {
 Future<List<AssetEntity>> _getAllAssetLists(AssetPathEntity pathEntity) async {
-  List<AssetEntity> result = [];
+  final List<AssetEntity> result = [];
   int currentPage = 0;
   int currentPage = 0;
   List<AssetEntity> currentPageResult = [];
   List<AssetEntity> currentPageResult = [];
   do {
   do {
@@ -277,7 +277,7 @@ Future<Tuple2<Set<String>, List<File>>> _getLocalIDsAndFilesFromAssets(
   final Set<String> localIDs = {};
   final Set<String> localIDs = {};
   for (AssetEntity entity in assetList) {
   for (AssetEntity entity in assetList) {
     localIDs.add(entity.id);
     localIDs.add(entity.id);
-    bool assetCreatedOrUpdatedAfterGivenTime = max(
+    final bool assetCreatedOrUpdatedAfterGivenTime = max(
           entity.createDateTime.microsecondsSinceEpoch,
           entity.createDateTime.microsecondsSinceEpoch,
           entity.modifiedDateTime.microsecondsSinceEpoch,
           entity.modifiedDateTime.microsecondsSinceEpoch,
         ) >
         ) >
@@ -285,7 +285,7 @@ Future<Tuple2<Set<String>, List<File>>> _getLocalIDsAndFilesFromAssets(
     if (!alreadySeenLocalIDs.contains(entity.id) &&
     if (!alreadySeenLocalIDs.contains(entity.id) &&
         assetCreatedOrUpdatedAfterGivenTime) {
         assetCreatedOrUpdatedAfterGivenTime) {
       try {
       try {
-        final file = File.fromAsset(pathEntity.name, entity);
+        final file = await File.fromAsset(pathEntity.name, entity);
         files.add(file);
         files.add(file);
       } catch (e) {
       } catch (e) {
         _logger.severe(e);
         _logger.severe(e);

+ 9 - 9
lib/services/local_file_update_service.dart

@@ -73,7 +73,7 @@ class LocalFileUpdateService {
     bool hasData = true;
     bool hasData = true;
     const int limitInBatch = 100;
     const int limitInBatch = 100;
     while (hasData) {
     while (hasData) {
-      var localIDsToProcess =
+      final localIDsToProcess =
           await _filesMigrationDB.getLocalIDsForPotentialReUpload(
           await _filesMigrationDB.getLocalIDsForPotentialReUpload(
         limitInBatch,
         limitInBatch,
         FilesMigrationDB.modificationTimeUpdated,
         FilesMigrationDB.modificationTimeUpdated,
@@ -97,8 +97,8 @@ class LocalFileUpdateService {
     List<String> localIDsToProcess,
     List<String> localIDsToProcess,
   ) async {
   ) async {
     _logger.info("files to process ${localIDsToProcess.length} for reupload");
     _logger.info("files to process ${localIDsToProcess.length} for reupload");
-    var localFiles = await FilesDB.instance.getLocalFiles(localIDsToProcess);
-    Set<String> processedIDs = {};
+    final localFiles = await FilesDB.instance.getLocalFiles(localIDsToProcess);
+    final Set<String> processedIDs = {};
     for (var file in localFiles) {
     for (var file in localFiles) {
       if (processedIDs.contains(file.localID)) {
       if (processedIDs.contains(file.localID)) {
         continue;
         continue;
@@ -150,14 +150,14 @@ class LocalFileUpdateService {
     }
     }
     // migration only needs to run if Android API Level is 29 or higher
     // migration only needs to run if Android API Level is 29 or higher
     final int version = int.parse(await PhotoManager.systemVersion());
     final int version = int.parse(await PhotoManager.systemVersion());
-    bool isMigrationRequired = version >= 29;
+    final bool isMigrationRequired = version >= 29;
     if (isMigrationRequired) {
     if (isMigrationRequired) {
       await _importLocalFilesForMigration();
       await _importLocalFilesForMigration();
       final sTime = DateTime.now().microsecondsSinceEpoch;
       final sTime = DateTime.now().microsecondsSinceEpoch;
       bool hasData = true;
       bool hasData = true;
       const int limitInBatch = 100;
       const int limitInBatch = 100;
       while (hasData) {
       while (hasData) {
-        var localIDsToProcess =
+        final localIDsToProcess =
             await _filesMigrationDB.getLocalIDsForPotentialReUpload(
             await _filesMigrationDB.getLocalIDsForPotentialReUpload(
           limitInBatch,
           limitInBatch,
           FilesMigrationDB.missingLocation,
           FilesMigrationDB.missingLocation,
@@ -181,15 +181,15 @@ class LocalFileUpdateService {
     List<String> localIDsToProcess,
     List<String> localIDsToProcess,
   ) async {
   ) async {
     _logger.info("files to process ${localIDsToProcess.length}");
     _logger.info("files to process ${localIDsToProcess.length}");
-    var localIDsWithLocation = <String>[];
+    final localIDsWithLocation = <String>[];
     for (var localID in localIDsToProcess) {
     for (var localID in localIDsToProcess) {
       bool hasLocation = false;
       bool hasLocation = false;
       try {
       try {
-        var assetEntity = await AssetEntity.fromId(localID);
+        final assetEntity = await AssetEntity.fromId(localID);
         if (assetEntity == null) {
         if (assetEntity == null) {
           continue;
           continue;
         }
         }
-        var latLng = await assetEntity.latlngAsync();
+        final latLng = await assetEntity.latlngAsync();
         if ((latLng.longitude ?? 0.0) != 0.0 ||
         if ((latLng.longitude ?? 0.0) != 0.0 ||
             (latLng.longitude ?? 0.0) != 0.0) {
             (latLng.longitude ?? 0.0) != 0.0) {
           _logger.finest(
           _logger.finest(
@@ -218,7 +218,7 @@ class LocalFileUpdateService {
     }
     }
     final sTime = DateTime.now().microsecondsSinceEpoch;
     final sTime = DateTime.now().microsecondsSinceEpoch;
     _logger.info('importing files without location info');
     _logger.info('importing files without location info');
-    var fileLocalIDs = await _filesDB.getLocalFilesBackedUpWithoutLocation();
+    final fileLocalIDs = await _filesDB.getLocalFilesBackedUpWithoutLocation();
     await _filesMigrationDB.insertMultiple(
     await _filesMigrationDB.insertMultiple(
       fileLocalIDs,
       fileLocalIDs,
       FilesMigrationDB.missingLocation,
       FilesMigrationDB.missingLocation,

+ 4 - 4
lib/services/local_sync_service.dart

@@ -134,7 +134,7 @@ class LocalSyncService {
   }
   }
 
 
   Future<bool> refreshDeviceFolderCountAndCover() async {
   Future<bool> refreshDeviceFolderCountAndCover() async {
-    List<Tuple2<AssetPathEntity, String>> result =
+    final List<Tuple2<AssetPathEntity, String>> result =
         await getDeviceFolderWithCountAndCoverID();
         await getDeviceFolderWithCountAndCoverID();
     return await _db.updateDeviceCoverWithCount(
     return await _db.updateDeviceCoverWithCount(
       result,
       result,
@@ -174,7 +174,7 @@ class LocalSyncService {
           .deletePathIDToLocalIDMapping(localUnSyncResult.deletePathToLocalIDs);
           .deletePathIDToLocalIDMapping(localUnSyncResult.deletePathToLocalIDs);
       hasAnyMappingChanged = true;
       hasAnyMappingChanged = true;
     }
     }
-    bool hasUnsyncedFiles =
+    final bool hasUnsyncedFiles =
         localUnSyncResult.uniqueLocalFiles?.isNotEmpty ?? false;
         localUnSyncResult.uniqueLocalFiles?.isNotEmpty ?? false;
     if (hasUnsyncedFiles) {
     if (hasUnsyncedFiles) {
       await _db.insertMultiple(
       await _db.insertMultiple(
@@ -209,7 +209,7 @@ class LocalSyncService {
     if (_prefs.containsKey(kEditedFileIDsKey)) {
     if (_prefs.containsKey(kEditedFileIDsKey)) {
       return _prefs.getStringList(kEditedFileIDsKey);
       return _prefs.getStringList(kEditedFileIDsKey);
     } else {
     } else {
-      List<String> editedIDs = [];
+      final List<String> editedIDs = [];
       return editedIDs;
       return editedIDs;
     }
     }
   }
   }
@@ -335,7 +335,7 @@ class LocalSyncService {
       _logger.info(
       _logger.info(
         updatedFiles.length.toString() + " local files were updated.",
         updatedFiles.length.toString() + " local files were updated.",
       );
       );
-      List<String> updatedLocalIDs = [];
+      final List<String> updatedLocalIDs = [];
       for (final file in updatedFiles) {
       for (final file in updatedFiles) {
         if (file.localID != null) {
         if (file.localID != null) {
           updatedLocalIDs.add(file.localID);
           updatedLocalIDs.add(file.localID);

+ 15 - 16
lib/services/remote_sync_service.dart

@@ -228,7 +228,7 @@ class RemoteSyncService {
     final devicePathCollections = await fileDb.getDevicePathCollections();
     final devicePathCollections = await fileDb.getDevicePathCollections();
     devicePathCollections.removeWhere((element) => !element.sync);
     devicePathCollections.removeWhere((element) => !element.sync);
     await _createCollectionsForDevicePath(devicePathCollections);
     await _createCollectionsForDevicePath(devicePathCollections);
-    Map<String, Set<String>> unSyncedPathIdToLocalIDs =
+    final Map<String, Set<String>> unSyncedPathIdToLocalIDs =
         await fileDb.getDevicePathIDToLocalIDMap(syncStatus: false);
         await fileDb.getDevicePathIDToLocalIDMap(syncStatus: false);
     /*
     /*
        A) Check if mapping for localID already exist in the collection
        A) Check if mapping for localID already exist in the collection
@@ -236,8 +236,8 @@ class RemoteSyncService {
      */
      */
     for (final eachDevicePath in devicePathCollections) {
     for (final eachDevicePath in devicePathCollections) {
       debugPrint("Processing ${eachDevicePath.name}");
       debugPrint("Processing ${eachDevicePath.name}");
-      String pathID = eachDevicePath.id;
-      Set<String> unSyncedLocalIDs =
+      final String pathID = eachDevicePath.id;
+      final Set<String> unSyncedLocalIDs =
           unSyncedPathIdToLocalIDs[eachDevicePath.id] ?? {};
           unSyncedPathIdToLocalIDs[eachDevicePath.id] ?? {};
       if (unSyncedLocalIDs.isNotEmpty && eachDevicePath.collectionID != -1) {
       if (unSyncedLocalIDs.isNotEmpty && eachDevicePath.collectionID != -1) {
         await fileDb.setCollectionIDForUnMappedLocalFiles(
         await fileDb.setCollectionIDForUnMappedLocalFiles(
@@ -248,9 +248,9 @@ class RemoteSyncService {
         // mark IDs as already synced if corresponding entry is present in
         // mark IDs as already synced if corresponding entry is present in
         // the collection. This can happen when a user has marked a folder
         // the collection. This can happen when a user has marked a folder
         // for sync, then un-synced it and again tries to mark if for sync.
         // for sync, then un-synced it and again tries to mark if for sync.
-        Set<String> existingMapping = await fileDb
+        final Set<String> existingMapping = await fileDb
             .getLocalFileIDsForCollection(eachDevicePath.collectionID);
             .getLocalFileIDsForCollection(eachDevicePath.collectionID);
-        Set<String> commonElements =
+        final Set<String> commonElements =
             unSyncedLocalIDs.intersection(existingMapping);
             unSyncedLocalIDs.intersection(existingMapping);
         if (commonElements.isNotEmpty) {
         if (commonElements.isNotEmpty) {
           debugPrint(
           debugPrint(
@@ -273,12 +273,12 @@ class RemoteSyncService {
             'Adding new entries for ${unSyncedLocalIDs.length} files'
             'Adding new entries for ${unSyncedLocalIDs.length} files'
             ' for ${eachDevicePath.name}',
             ' for ${eachDevicePath.name}',
           );
           );
-          var filesWithPotentialCollectionID =
+          final filesWithPotentialCollectionID =
               await fileDb.getLocalFiles(unSyncedLocalIDs.toList());
               await fileDb.getLocalFiles(unSyncedLocalIDs.toList());
-          List<File> newFilesToInsert = [];
+          final List<File> newFilesToInsert = [];
           final Set<String> fileFoundForLocalIDs = {};
           final Set<String> fileFoundForLocalIDs = {};
           for (var existingFile in filesWithPotentialCollectionID) {
           for (var existingFile in filesWithPotentialCollectionID) {
-            String localID = existingFile.localID;
+            final String localID = existingFile.localID;
             if (localID != null && !fileFoundForLocalIDs.contains(localID)) {
             if (localID != null && !fileFoundForLocalIDs.contains(localID)) {
               existingFile.collectionID = eachDevicePath.collectionID;
               existingFile.collectionID = eachDevicePath.collectionID;
               existingFile.uploadedFileID = -1;
               existingFile.uploadedFileID = -1;
@@ -313,7 +313,7 @@ class RemoteSyncService {
     for (var devicePathCollection in devicePathCollections) {
     for (var devicePathCollection in devicePathCollections) {
       int deviceCollectionID = devicePathCollection.collectionID;
       int deviceCollectionID = devicePathCollection.collectionID;
       if (deviceCollectionID != -1) {
       if (deviceCollectionID != -1) {
-        var collectionByID =
+        final collectionByID =
             CollectionsService.instance.getCollectionByID(deviceCollectionID);
             CollectionsService.instance.getCollectionByID(deviceCollectionID);
         if (collectionByID == null || collectionByID.isDeleted) {
         if (collectionByID == null || collectionByID.isDeleted) {
           _logger.info(
           _logger.info(
@@ -324,7 +324,7 @@ class RemoteSyncService {
         }
         }
       }
       }
       if (deviceCollectionID == -1) {
       if (deviceCollectionID == -1) {
-        var collection = await CollectionsService.instance
+        final collection = await CollectionsService.instance
             .getOrCreateForPath(devicePathCollection.name);
             .getOrCreateForPath(devicePathCollection.name);
         await FilesDB.instance
         await FilesDB.instance
             .updateDevicePathCollection(devicePathCollection.id, collection.id);
             .updateDevicePathCollection(devicePathCollection.id, collection.id);
@@ -370,15 +370,14 @@ class RemoteSyncService {
   }
   }
 
 
   Future<bool> _uploadFiles(List<File> filesToBeUploaded) async {
   Future<bool> _uploadFiles(List<File> filesToBeUploaded) async {
-    int ownerID = Configuration.instance.getUserID();
+    final int ownerID = Configuration.instance.getUserID();
     final updatedFileIDs = await _db.getUploadedFileIDsToBeUpdated(ownerID);
     final updatedFileIDs = await _db.getUploadedFileIDsToBeUpdated(ownerID);
     if (updatedFileIDs.isNotEmpty) {
     if (updatedFileIDs.isNotEmpty) {
       _logger.info("Identified ${updatedFileIDs.length} files for reupload");
       _logger.info("Identified ${updatedFileIDs.length} files for reupload");
     }
     }
 
 
     _completedUploads = 0;
     _completedUploads = 0;
-    int toBeUploaded = filesToBeUploaded.length + updatedFileIDs.length;
-
+    final int toBeUploaded = filesToBeUploaded.length + updatedFileIDs.length;
     if (toBeUploaded > 0) {
     if (toBeUploaded > 0) {
       Bus.instance.fire(SyncStatusUpdate(SyncStatus.preparingForUpload));
       Bus.instance.fire(SyncStatusUpdate(SyncStatus.preparingForUpload));
       // verify if files upload is allowed based on their subscription plan and
       // verify if files upload is allowed based on their subscription plan and
@@ -476,8 +475,8 @@ class RemoteSyncService {
         localButUpdatedOnRemote = 0,
         localButUpdatedOnRemote = 0,
         localButAddedToNewCollectionOnRemote = 0;
         localButAddedToNewCollectionOnRemote = 0;
     bool hasAnyCreationTimeChanged = false;
     bool hasAnyCreationTimeChanged = false;
-    List<File> toBeInserted = [];
-    int userID = Configuration.instance.getUserID();
+    final List<File> toBeInserted = [];
+    final int userID = Configuration.instance.getUserID();
     for (File file in diff) {
     for (File file in diff) {
       final existingFiles = file.deviceFolder == null
       final existingFiles = file.deviceFolder == null
           ? null
           ? null
@@ -522,7 +521,7 @@ class RemoteSyncService {
         } else {
         } else {
           file.localID = null;
           file.localID = null;
         }
         }
-        bool wasUploadedOnAPreviousInstallation =
+        final bool wasUploadedOnAPreviousInstallation =
             existingFiles.length == 1 && existingFiles[0].collectionID == null;
             existingFiles.length == 1 && existingFiles[0].collectionID == null;
         if (wasUploadedOnAPreviousInstallation) {
         if (wasUploadedOnAPreviousInstallation) {
           file.generatedID = existingFiles[0].generatedID;
           file.generatedID = existingFiles[0].generatedID;

+ 2 - 2
lib/services/user_service.dart

@@ -806,7 +806,7 @@ class UserService {
 
 
   Future<String> getPaymentToken() async {
   Future<String> getPaymentToken() async {
     try {
     try {
-      var response = await _dio.get(
+      final response = await _dio.get(
         "${_config.getHttpEndpoint()}/users/payment-token",
         "${_config.getHttpEndpoint()}/users/payment-token",
         options: Options(
         options: Options(
           headers: {
           headers: {
@@ -827,7 +827,7 @@ class UserService {
 
 
   Future<String> getFamiliesToken() async {
   Future<String> getFamiliesToken() async {
     try {
     try {
-      var response = await _dio.get(
+      final response = await _dio.get(
         "${_config.getHttpEndpoint()}/users/families-token",
         "${_config.getHttpEndpoint()}/users/families-token",
         options: Options(
         options: Options(
           headers: {
           headers: {

+ 2 - 2
lib/ui/account/delete_account_page.dart

@@ -145,7 +145,7 @@ class DeleteAccountPage extends StatelessWidget {
     DeleteChallengeResponse response,
     DeleteChallengeResponse response,
   ) async {
   ) async {
     AppLock.of(context).setEnabled(false);
     AppLock.of(context).setEnabled(false);
-    String reason = "Please authenticate to initiate account deletion";
+    const String reason = "Please authenticate to initiate account deletion";
     final result = await requestAuthentication(reason);
     final result = await requestAuthentication(reason);
     AppLock.of(context).setEnabled(
     AppLock.of(context).setEnabled(
       Configuration.instance.shouldShowLockScreen(),
       Configuration.instance.shouldShowLockScreen(),
@@ -177,7 +177,7 @@ class DeleteAccountPage extends StatelessWidget {
   }
   }
 
 
   Future<void> _requestEmailForDeletion(BuildContext context) async {
   Future<void> _requestEmailForDeletion(BuildContext context) async {
-    AlertDialog alert = AlertDialog(
+    final AlertDialog alert = AlertDialog(
       title: const Text(
       title: const Text(
         "Delete account",
         "Delete account",
         style: TextStyle(
         style: TextStyle(

+ 29 - 2
lib/ui/account/password_reentry_page.dart

@@ -3,10 +3,13 @@ import 'package:logging/logging.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/event_bus.dart';
 import 'package:photos/core/event_bus.dart';
 import 'package:photos/events/subscription_purchased_event.dart';
 import 'package:photos/events/subscription_purchased_event.dart';
+import 'package:photos/models/key_attributes.dart';
 import 'package:photos/ui/account/recovery_page.dart';
 import 'package:photos/ui/account/recovery_page.dart';
+import 'package:photos/ui/common/dialogs.dart';
 import 'package:photos/ui/common/dynamic_fab.dart';
 import 'package:photos/ui/common/dynamic_fab.dart';
 import 'package:photos/ui/home_widget.dart';
 import 'package:photos/ui/home_widget.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/dialog_util.dart';
+import 'package:photos/utils/email_util.dart';
 
 
 class PasswordReentryPage extends StatefulWidget {
 class PasswordReentryPage extends StatefulWidget {
   const PasswordReentryPage({Key key}) : super(key: key);
   const PasswordReentryPage({Key key}) : super(key: key);
@@ -16,6 +19,7 @@ class PasswordReentryPage extends StatefulWidget {
 }
 }
 
 
 class _PasswordReentryPageState extends State<PasswordReentryPage> {
 class _PasswordReentryPageState extends State<PasswordReentryPage> {
+  final _logger = Logger((_PasswordReentryPageState).toString());
   final _passwordController = TextEditingController();
   final _passwordController = TextEditingController();
   final FocusNode _passwordFocusNode = FocusNode();
   final FocusNode _passwordFocusNode = FocusNode();
   String email;
   String email;
@@ -72,9 +76,26 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
               Configuration.instance.getKeyAttributes(),
               Configuration.instance.getKeyAttributes(),
             );
             );
           } catch (e, s) {
           } catch (e, s) {
-            Logger("PRP").severe("Password verification failed", e, s);
+            _logger.severe("Password verification failed", e, s);
             await dialog.hide();
             await dialog.hide();
-            showErrorDialog(context, "Incorrect password", "Please try again");
+
+            final dialogUserChoice = await showChoiceDialog(
+              context,
+              "Incorrect password",
+              "Please try again",
+              firstAction: "Contact Support",
+              firstActionColor: Theme.of(context).colorScheme.primary,
+              secondAction: "Ok",
+              secondActionColor: Theme.of(context).colorScheme.primary,
+            );
+            if (dialogUserChoice == DialogUserChoice.firstChoice) {
+              await sendLogs(
+                context,
+                "Contact support",
+                "support@ente.io",
+                postShare: () {},
+              );
+            }
             return;
             return;
           }
           }
           await dialog.hide();
           await dialog.hide();
@@ -231,4 +252,10 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
       ],
       ],
     );
     );
   }
   }
+
+  void validatePreVerificationState(KeyAttributes keyAttributes) {
+    if (keyAttributes == null) {
+      throw Exception("Key Attributes can not be null");
+    }
+  }
 }
 }

+ 1 - 1
lib/ui/account/recovery_key_page.dart

@@ -186,7 +186,7 @@ class _RecoveryKeyPageState extends State<RecoveryKeyPage> {
   }
   }
 
 
   List<Widget> _saveOptions(BuildContext context, String recoveryKey) {
   List<Widget> _saveOptions(BuildContext context, String recoveryKey) {
-    List<Widget> childrens = [];
+    final List<Widget> childrens = [];
     if (!_hasTriedToSave) {
     if (!_hasTriedToSave) {
       childrens.add(
       childrens.add(
         ElevatedButton(
         ElevatedButton(

+ 2 - 2
lib/ui/account/sessions_page.dart

@@ -41,7 +41,7 @@ class _SessionsPageState extends State<SessionsPage> {
     if (_sessions == null) {
     if (_sessions == null) {
       return const Center(child: EnteLoadingWidget());
       return const Center(child: EnteLoadingWidget());
     }
     }
-    List<Widget> rows = [];
+    final List<Widget> rows = [];
     rows.add(const Padding(padding: EdgeInsets.all(4)));
     rows.add(const Padding(padding: EdgeInsets.all(4)));
     for (final session in _sessions.sessions) {
     for (final session in _sessions.sessions) {
       rows.add(_getSessionWidget(session));
       rows.add(_getSessionWidget(session));
@@ -163,7 +163,7 @@ class _SessionsPageState extends State<SessionsPage> {
         ),
         ),
       );
       );
     }
     }
-    AlertDialog alert = AlertDialog(
+    final AlertDialog alert = AlertDialog(
       title: const Text("Terminate session?"),
       title: const Text("Terminate session?"),
       content: text,
       content: text,
       actions: [
       actions: [

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

@@ -116,7 +116,7 @@ class _TwoFactorSetupPageState extends State<TwoFactorSetupPage>
             Divider(
             Divider(
               height: 1,
               height: 1,
               thickness: 1,
               thickness: 1,
-              color: Theme.of(context).accentColor,
+              color: Theme.of(context).colorScheme.secondary,
             ),
             ),
             _getVerificationWidget(),
             _getVerificationWidget(),
           ],
           ],
@@ -126,7 +126,7 @@ class _TwoFactorSetupPageState extends State<TwoFactorSetupPage>
   }
   }
 
 
   Widget _getSecretCode() {
   Widget _getSecretCode() {
-    Color textColor = Theme.of(context).colorScheme.onSurface;
+    final Color textColor = Theme.of(context).colorScheme.onSurface;
     return GestureDetector(
     return GestureDetector(
       onTap: () async {
       onTap: () async {
         await Clipboard.setData(ClipboardData(text: widget.secretCode));
         await Clipboard.setData(ClipboardData(text: widget.secretCode));

+ 1 - 1
lib/ui/backup_folder_selection_page.dart

@@ -172,7 +172,7 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
                     onPressed: _selectedDevicePathIDs.isEmpty
                     onPressed: _selectedDevicePathIDs.isEmpty
                         ? null
                         ? null
                         : () async {
                         : () async {
-                            Map<String, bool> syncStatus = {};
+                            final Map<String, bool> syncStatus = {};
                             for (String pathID in _allDevicePathIDs) {
                             for (String pathID in _allDevicePathIDs) {
                               syncStatus[pathID] =
                               syncStatus[pathID] =
                                   _selectedDevicePathIDs.contains(pathID);
                                   _selectedDevicePathIDs.contains(pathID);

+ 4 - 4
lib/ui/collections/collection_item_widget.dart

@@ -19,11 +19,11 @@ class CollectionItem extends StatelessWidget {
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
     const double horizontalPaddingOfGridRow = 16;
     const double horizontalPaddingOfGridRow = 16;
     const double crossAxisSpacingOfGrid = 9;
     const double crossAxisSpacingOfGrid = 9;
-    Size size = MediaQuery.of(context).size;
-    int albumsCountInOneRow = max(size.width ~/ 220.0, 2);
-    double totalWhiteSpaceOfRow = (horizontalPaddingOfGridRow * 2) +
+    final Size size = MediaQuery.of(context).size;
+    final int albumsCountInOneRow = max(size.width ~/ 220.0, 2);
+    final double totalWhiteSpaceOfRow = (horizontalPaddingOfGridRow * 2) +
         (albumsCountInOneRow - 1) * crossAxisSpacingOfGrid;
         (albumsCountInOneRow - 1) * crossAxisSpacingOfGrid;
-    TextStyle albumTitleTextStyle =
+    final TextStyle albumTitleTextStyle =
         Theme.of(context).textTheme.subtitle1.copyWith(fontSize: 14);
         Theme.of(context).textTheme.subtitle1.copyWith(fontSize: 14);
     final double sideOfThumbnail = (size.width / albumsCountInOneRow) -
     final double sideOfThumbnail = (size.width / albumsCountInOneRow) -
         (totalWhiteSpaceOfRow / albumsCountInOneRow);
         (totalWhiteSpaceOfRow / albumsCountInOneRow);

+ 2 - 2
lib/ui/collections/remote_collections_grid_view_widget.dart

@@ -17,8 +17,8 @@ class RemoteCollectionsGridViewWidget extends StatelessWidget {
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
     const double horizontalPaddingOfGridRow = 16;
     const double horizontalPaddingOfGridRow = 16;
     const double crossAxisSpacingOfGrid = 9;
     const double crossAxisSpacingOfGrid = 9;
-    Size size = MediaQuery.of(context).size;
-    int albumsCountInOneRow = max(size.width ~/ 220.0, 2);
+    final Size size = MediaQuery.of(context).size;
+    final int albumsCountInOneRow = max(size.width ~/ 220.0, 2);
     final double sideOfThumbnail = (size.width / albumsCountInOneRow) -
     final double sideOfThumbnail = (size.width / albumsCountInOneRow) -
         horizontalPaddingOfGridRow -
         horizontalPaddingOfGridRow -
         ((crossAxisSpacingOfGrid / 2) * (albumsCountInOneRow - 1));
         ((crossAxisSpacingOfGrid / 2) * (albumsCountInOneRow - 1));

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

@@ -19,7 +19,7 @@ Future<DialogUserChoice> showChoiceDialog<T>(
   Color secondActionColor,
   Color secondActionColor,
   ActionType actionType = ActionType.confirm,
   ActionType actionType = ActionType.confirm,
 }) {
 }) {
-  AlertDialog alert = AlertDialog(
+  final AlertDialog alert = AlertDialog(
     title: Text(
     title: Text(
       title,
       title,
       style: TextStyle(
       style: TextStyle(

+ 2 - 2
lib/ui/create_collection_page.dart

@@ -203,7 +203,7 @@ class _CreateCollectionPageState extends State<CreateCollectionPage> {
   }
   }
 
 
   void _showNameAlbumDialog() async {
   void _showNameAlbumDialog() async {
-    AlertDialog alert = AlertDialog(
+    final AlertDialog alert = AlertDialog(
       title: const Text("Album title"),
       title: const Text("Album title"),
       content: TextFormField(
       content: TextFormField(
         decoration: const InputDecoration(
         decoration: const InputDecoration(
@@ -285,7 +285,7 @@ class _CreateCollectionPageState extends State<CreateCollectionPage> {
     final dialog = createProgressDialog(context, "Moving files to album...");
     final dialog = createProgressDialog(context, "Moving files to album...");
     await dialog.show();
     await dialog.show();
     try {
     try {
-      int fromCollectionID = widget.selectedFiles.files?.first?.collectionID;
+      final int fromCollectionID = widget.selectedFiles.files?.first?.collectionID;
       await CollectionsService.instance.move(
       await CollectionsService.instance.move(
         toCollectionID,
         toCollectionID,
         fromCollectionID,
         fromCollectionID,

+ 1 - 1
lib/ui/grant_permissions_widget.dart

@@ -94,7 +94,7 @@ class GrantPermissionsWidget extends StatelessWidget {
                 state == PermissionState.limited) {
                 state == PermissionState.limited) {
               await SyncService.instance.onPermissionGranted(state);
               await SyncService.instance.onPermissionGranted(state);
             } else if (state == PermissionState.denied) {
             } else if (state == PermissionState.denied) {
-              AlertDialog alert = AlertDialog(
+              final AlertDialog alert = AlertDialog(
                 title: const Text("Please grant permissions"),
                 title: const Text("Please grant permissions"),
                 content: const Text(
                 content: const Text(
                   "ente can encrypt and preserve files only if you grant access to them",
                   "ente can encrypt and preserve files only if you grant access to them",

+ 3 - 3
lib/ui/home_widget.dart

@@ -123,7 +123,7 @@ class _HomeWidgetState extends State<HomeWidget> {
     });
     });
     _triggerLogoutEvent =
     _triggerLogoutEvent =
         Bus.instance.on<TriggerLogoutEvent>().listen((event) async {
         Bus.instance.on<TriggerLogoutEvent>().listen((event) async {
-      AlertDialog alert = AlertDialog(
+      final AlertDialog alert = AlertDialog(
         title: const Text("Session expired"),
         title: const Text("Session expired"),
         content: const Text("Please login again"),
         content: const Text("Please login again"),
         actions: [
         actions: [
@@ -344,7 +344,7 @@ class _HomeWidgetState extends State<HomeWidget> {
   Future<bool> _initDeepLinks() async {
   Future<bool> _initDeepLinks() async {
     // Platform messages may fail, so we use a try/catch PlatformException.
     // Platform messages may fail, so we use a try/catch PlatformException.
     try {
     try {
-      String initialLink = await getInitialLink();
+      final String initialLink = await getInitialLink();
       // Parse the link and warn the user, if it is not correct,
       // Parse the link and warn the user, if it is not correct,
       // but keep in mind it could be `null`.
       // but keep in mind it could be `null`.
       if (initialLink != null) {
       if (initialLink != null) {
@@ -609,7 +609,7 @@ class _HomeBottomNavigationBarState extends State<HomeBottomNavigationBar> {
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
-    bool filesAreSelected = widget.selectedFiles.files.isNotEmpty;
+    final bool filesAreSelected = widget.selectedFiles.files.isNotEmpty;
     return AnimatedContainer(
     return AnimatedContainer(
       duration: const Duration(milliseconds: 300),
       duration: const Duration(milliseconds: 300),
       curve: Curves.easeInOut,
       curve: Curves.easeInOut,

+ 1 - 1
lib/ui/huge_listview/draggable_scrollbar.dart

@@ -175,7 +175,7 @@ class DraggableScrollbarState extends State<DraggableScrollbar>
       if (isDragging && details.delta.dy != 0) {
       if (isDragging && details.delta.dy != 0) {
         thumbOffset += details.delta.dy;
         thumbOffset += details.delta.dy;
         thumbOffset = thumbOffset.clamp(thumbMin, thumbMax);
         thumbOffset = thumbOffset.clamp(thumbMin, thumbMax);
-        double position = thumbOffset / (thumbMax - thumbMin);
+        final double position = thumbOffset / (thumbMax - thumbMin);
         widget.onChange?.call(position);
         widget.onChange?.call(position);
       }
       }
     });
     });

+ 1 - 1
lib/ui/huge_listview/huge_listview.dart

@@ -97,7 +97,7 @@ class HugeListViewState<T> extends State<HugeListView<T>> {
   }
   }
 
 
   void _sendScroll() {
   void _sendScroll() {
-    int current = _currentFirst();
+    final int current = _currentFirst();
     widget.firstShown?.call(current);
     widget.firstShown?.call(current);
     scrollKey.currentState?.setPosition(current / widget.totalCount, current);
     scrollKey.currentState?.setPosition(current / widget.totalCount, current);
   }
   }

+ 2 - 2
lib/ui/huge_listview/lazy_loading_gallery.dart

@@ -71,7 +71,7 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
 
 
     _currentIndexSubscription =
     _currentIndexSubscription =
         widget.currentIndexStream.listen((currentIndex) {
         widget.currentIndexStream.listen((currentIndex) {
-      bool shouldRender = (currentIndex - widget.index).abs() <
+      final bool shouldRender = (currentIndex - widget.index).abs() <
           kNumberOfDaysToRenderBeforeAndAfter;
           kNumberOfDaysToRenderBeforeAndAfter;
       if (mounted && shouldRender != _shouldRender) {
       if (mounted && shouldRender != _shouldRender) {
         setState(() {
         setState(() {
@@ -163,7 +163,7 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
   }
   }
 
 
   Widget _getGallery() {
   Widget _getGallery() {
-    List<Widget> childGalleries = [];
+    final List<Widget> childGalleries = [];
     for (int index = 0; index < _files.length; index += kSubGalleryItemLimit) {
     for (int index = 0; index < _files.length; index += kSubGalleryItemLimit) {
       childGalleries.add(
       childGalleries.add(
         LazyLoadingGridView(
         LazyLoadingGridView(

+ 2 - 2
lib/ui/memories_widget.dart

@@ -66,9 +66,9 @@ class MemoriesWidget extends StatelessWidget {
   }
   }
 
 
   bool _areMemoriesFromSameYear(Memory first, Memory second) {
   bool _areMemoriesFromSameYear(Memory first, Memory second) {
-    var firstDate =
+    final firstDate =
         DateTime.fromMicrosecondsSinceEpoch(first.file.creationTime);
         DateTime.fromMicrosecondsSinceEpoch(first.file.creationTime);
-    var secondDate =
+    final secondDate =
         DateTime.fromMicrosecondsSinceEpoch(second.file.creationTime);
         DateTime.fromMicrosecondsSinceEpoch(second.file.creationTime);
     return firstDate.year == secondDate.year;
     return firstDate.year == secondDate.year;
   }
   }

+ 1 - 1
lib/ui/nav_bar.dart

@@ -321,7 +321,7 @@ class _ButtonState extends State<Button> with TickerProviderStateMixin {
       expandController.forward();
       expandController.forward();
     }
     }
 
 
-    Widget icon = widget.leading ??
+    final Widget icon = widget.leading ??
         Icon(
         Icon(
           widget.icon,
           widget.icon,
           color: _expanded ? widget.iconColor : widget.iconActiveColor,
           color: _expanded ? widget.iconColor : widget.iconActiveColor,

+ 8 - 8
lib/ui/payment/payment_web_page.dart

@@ -77,7 +77,7 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
                   ),
                   ),
                 ),
                 ),
                 shouldOverrideUrlLoading: (controller, navigationAction) async {
                 shouldOverrideUrlLoading: (controller, navigationAction) async {
-                  var loadingUri = navigationAction.request.url;
+                  final loadingUri = navigationAction.request.url;
                   _logger.info("Loading url $loadingUri");
                   _logger.info("Loading url $loadingUri");
                   // handle the payment response
                   // handle the payment response
                   if (_isPaymentActionComplete(loadingUri)) {
                   if (_isPaymentActionComplete(loadingUri)) {
@@ -130,7 +130,7 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
       'action': widget.actionType,
       'action': widget.actionType,
       'redirectURL': kWebPaymentRedirectUrl,
       'redirectURL': kWebPaymentRedirectUrl,
     };
     };
-    var tryParse = Uri.tryParse(kWebPaymentBaseEndpoint);
+    final tryParse = Uri.tryParse(kWebPaymentBaseEndpoint);
     if (kDebugMode && kWebPaymentBaseEndpoint.startsWith("http://")) {
     if (kDebugMode && kWebPaymentBaseEndpoint.startsWith("http://")) {
       return Uri.http(tryParse.authority, tryParse.path, queryParameters);
       return Uri.http(tryParse.authority, tryParse.path, queryParameters);
     } else {
     } else {
@@ -173,13 +173,13 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
   }
   }
 
 
   Future<void> _handlePaymentResponse(Uri uri) async {
   Future<void> _handlePaymentResponse(Uri uri) async {
-    var queryParams = uri.queryParameters;
-    var paymentStatus = uri.queryParameters['status'] ?? '';
+    final queryParams = uri.queryParameters;
+    final paymentStatus = uri.queryParameters['status'] ?? '';
     _logger.fine('handle payment response with status $paymentStatus');
     _logger.fine('handle payment response with status $paymentStatus');
     if (paymentStatus == 'success') {
     if (paymentStatus == 'success') {
       await _handlePaymentSuccess(queryParams);
       await _handlePaymentSuccess(queryParams);
     } else if (paymentStatus == 'fail') {
     } else if (paymentStatus == 'fail') {
-      var reason = queryParams['reason'] ?? '';
+      final reason = queryParams['reason'] ?? '';
       await _handlePaymentFailure(reason);
       await _handlePaymentFailure(reason);
     } else {
     } else {
       // should never reach here
       // should never reach here
@@ -210,17 +210,17 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
 
 
   // return true if verifySubscription didn't throw any exceptions
   // return true if verifySubscription didn't throw any exceptions
   Future<void> _handlePaymentSuccess(Map<String, String> queryParams) async {
   Future<void> _handlePaymentSuccess(Map<String, String> queryParams) async {
-    var checkoutSessionID = queryParams['session_id'] ?? '';
+    final checkoutSessionID = queryParams['session_id'] ?? '';
     await _dialog.show();
     await _dialog.show();
     try {
     try {
-      var response = await billingService.verifySubscription(
+      final response = await billingService.verifySubscription(
         widget.planId,
         widget.planId,
         checkoutSessionID,
         checkoutSessionID,
         paymentProvider: kStripe,
         paymentProvider: kStripe,
       );
       );
       await _dialog.hide();
       await _dialog.hide();
       if (response != null) {
       if (response != null) {
-        var content = widget.actionType == 'buy'
+        final content = widget.actionType == 'buy'
             ? 'Your purchase was successful'
             ? 'Your purchase was successful'
             : 'Your subscription was updated successfully';
             : 'Your subscription was updated successfully';
         await _showExitPageDialog(title: 'Thank you', content: content);
         await _showExitPageDialog(title: 'Thank you', content: content);

+ 6 - 6
lib/ui/payment/stripe_subscription_page.dart

@@ -307,7 +307,7 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
   Future<void> _launchStripePortal() async {
   Future<void> _launchStripePortal() async {
     await _dialog.show();
     await _dialog.show();
     try {
     try {
-      String url = await _billingService.getStripeCustomerPortalUrl();
+      final String url = await _billingService.getStripeCustomerPortalUrl();
       Navigator.of(context).push(
       Navigator.of(context).push(
         MaterialPageRoute(
         MaterialPageRoute(
           builder: (BuildContext context) {
           builder: (BuildContext context) {
@@ -353,9 +353,9 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
   }
   }
 
 
   Widget _stripeRenewOrCancelButton() {
   Widget _stripeRenewOrCancelButton() {
-    bool isRenewCancelled =
+    final bool isRenewCancelled =
         _currentSubscription.attributes?.isCancelled ?? false;
         _currentSubscription.attributes?.isCancelled ?? false;
-    String title =
+    final String title =
         isRenewCancelled ? "Renew subscription" : "Cancel subscription";
         isRenewCancelled ? "Renew subscription" : "Cancel subscription";
     return TextButton(
     return TextButton(
       child: Text(
       child: Text(
@@ -370,7 +370,7 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
       onPressed: () async {
       onPressed: () async {
         bool confirmAction = false;
         bool confirmAction = false;
         if (isRenewCancelled) {
         if (isRenewCancelled) {
-          var choice = await showChoiceDialog(
+          final choice = await showChoiceDialog(
             context,
             context,
             title,
             title,
             "Are you sure you want to renew?",
             "Are you sure you want to renew?",
@@ -379,7 +379,7 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
           );
           );
           confirmAction = choice == DialogUserChoice.secondChoice;
           confirmAction = choice == DialogUserChoice.secondChoice;
         } else {
         } else {
-          var choice = await showChoiceDialog(
+          final choice = await showChoiceDialog(
             context,
             context,
             title,
             title,
             'Are you sure you want to cancel?',
             'Are you sure you want to cancel?',
@@ -455,7 +455,7 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
               String stripPurChaseAction = 'buy';
               String stripPurChaseAction = 'buy';
               if (_isStripeSubscriber && _hasActiveSubscription) {
               if (_isStripeSubscriber && _hasActiveSubscription) {
                 // confirm if user wants to change plan or not
                 // confirm if user wants to change plan or not
-                var result = await showChoiceDialog(
+                final result = await showChoiceDialog(
                   context,
                   context,
                   "Confirm plan change",
                   "Confirm plan change",
                   "Are you sure you want to change your plan?",
                   "Are you sure you want to change your plan?",

+ 1 - 1
lib/ui/payment/subscription_common_widgets.dart

@@ -87,7 +87,7 @@ class ValidityWidget extends StatelessWidget {
     if (currentSubscription == null) {
     if (currentSubscription == null) {
       return Container();
       return Container();
     }
     }
-    var endDate = getDateAndMonthAndYear(
+    final endDate = getDateAndMonthAndYear(
       DateTime.fromMicrosecondsSinceEpoch(currentSubscription.expiryTime),
       DateTime.fromMicrosecondsSinceEpoch(currentSubscription.expiryTime),
     );
     );
     var message = "Renews on $endDate";
     var message = "Renews on $endDate";

+ 2 - 2
lib/ui/payment/subscription_plan_widget.dart

@@ -16,13 +16,13 @@ class SubscriptionPlanWidget extends StatelessWidget {
   final bool isActive;
   final bool isActive;
 
 
   String _displayPrice() {
   String _displayPrice() {
-    var result = price + (period.isNotEmpty ? " / " + period : "");
+    final result = price + (period.isNotEmpty ? " / " + period : "");
     return result.isNotEmpty ? result : "Trial plan";
     return result.isNotEmpty ? result : "Trial plan";
   }
   }
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
-    Color textColor = isActive ? Colors.white : Colors.black;
+    final Color textColor = isActive ? Colors.white : Colors.black;
     return Container(
     return Container(
       width: double.infinity,
       width: double.infinity,
       color: Theme.of(context).colorScheme.onPrimary,
       color: Theme.of(context).colorScheme.onPrimary,

+ 3 - 3
lib/ui/settings/account_section_widget.dart

@@ -40,7 +40,7 @@ class AccountSectionWidgetState extends State<AccountSectionWidget> {
           behavior: HitTestBehavior.translucent,
           behavior: HitTestBehavior.translucent,
           onTap: () async {
           onTap: () async {
             AppLock.of(context).setEnabled(false);
             AppLock.of(context).setEnabled(false);
-            String reason = "Please authenticate to view your recovery key";
+            const String reason = "Please authenticate to view your recovery key";
             final result = await requestAuthentication(reason);
             final result = await requestAuthentication(reason);
             AppLock.of(context)
             AppLock.of(context)
                 .setEnabled(Configuration.instance.shouldShowLockScreen());
                 .setEnabled(Configuration.instance.shouldShowLockScreen());
@@ -76,7 +76,7 @@ class AccountSectionWidgetState extends State<AccountSectionWidget> {
           behavior: HitTestBehavior.translucent,
           behavior: HitTestBehavior.translucent,
           onTap: () async {
           onTap: () async {
             AppLock.of(context).setEnabled(false);
             AppLock.of(context).setEnabled(false);
-            String reason = "Please authenticate to change your email";
+            const String reason = "Please authenticate to change your email";
             final result = await requestAuthentication(reason);
             final result = await requestAuthentication(reason);
             AppLock.of(context)
             AppLock.of(context)
                 .setEnabled(Configuration.instance.shouldShowLockScreen());
                 .setEnabled(Configuration.instance.shouldShowLockScreen());
@@ -103,7 +103,7 @@ class AccountSectionWidgetState extends State<AccountSectionWidget> {
           behavior: HitTestBehavior.translucent,
           behavior: HitTestBehavior.translucent,
           onTap: () async {
           onTap: () async {
             AppLock.of(context).setEnabled(false);
             AppLock.of(context).setEnabled(false);
-            String reason = "Please authenticate to change your password";
+            const String reason = "Please authenticate to change your password";
             final result = await requestAuthentication(reason);
             final result = await requestAuthentication(reason);
             AppLock.of(context)
             AppLock.of(context)
                 .setEnabled(Configuration.instance.shouldShowLockScreen());
                 .setEnabled(Configuration.instance.shouldShowLockScreen());

+ 1 - 1
lib/ui/settings/app_update_dialog.dart

@@ -153,7 +153,7 @@ class _ApkDownloaderDialogState extends State<ApkDownloaderDialog> {
       OpenFile.open(_saveUrl);
       OpenFile.open(_saveUrl);
     } catch (e) {
     } catch (e) {
       Logger("ApkDownloader").severe(e);
       Logger("ApkDownloader").severe(e);
-      AlertDialog alert = AlertDialog(
+      final AlertDialog alert = AlertDialog(
         title: const Text("Sorry"),
         title: const Text("Sorry"),
         content: const Text("The download could not be completed"),
         content: const Text("The download could not be completed"),
         actions: [
         actions: [

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

@@ -25,7 +25,7 @@ class _AppVersionWidgetState extends State<AppVersionWidget> {
     return GestureDetector(
     return GestureDetector(
       behavior: HitTestBehavior.translucent,
       behavior: HitTestBehavior.translucent,
       onTap: () async {
       onTap: () async {
-        int now = DateTime.now().millisecondsSinceEpoch;
+        final int now = DateTime.now().millisecondsSinceEpoch;
         if (now - (_lastTap ?? now) < kConsecutiveTapTimeWindowInMilliseconds) {
         if (now - (_lastTap ?? now) < kConsecutiveTapTimeWindowInMilliseconds) {
           _consecutiveTaps++;
           _consecutiveTaps++;
           if (_consecutiveTaps == kTapThresholdForInspector) {
           if (_consecutiveTaps == kTapThresholdForInspector) {

+ 6 - 6
lib/ui/settings/backup_section_widget.dart

@@ -113,7 +113,7 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
                 value: Configuration.instance.shouldKeepDeviceAwake(),
                 value: Configuration.instance.shouldKeepDeviceAwake(),
                 onChanged: (value) async {
                 onChanged: (value) async {
                   if (value) {
                   if (value) {
-                    var choice = await showChoiceDialog(
+                    final choice = await showChoiceDialog(
                       context,
                       context,
                       "Disable automatic screen lock when ente is running?",
                       "Disable automatic screen lock when ente is running?",
                       "This will ensure faster uploads by ensuring your device does not sleep when uploads are in progress.",
                       "This will ensure faster uploads by ensuring your device does not sleep when uploads are in progress.",
@@ -158,7 +158,7 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
                 "You've no files on this device that can be deleted",
                 "You've no files on this device that can be deleted",
               );
               );
             } else {
             } else {
-              bool result = await routeToPage(context, FreeSpacePage(status));
+              final bool result = await routeToPage(context, FreeSpacePage(status));
               if (result == true) {
               if (result == true) {
                 _showSpaceFreedDialog(status);
                 _showSpaceFreedDialog(status);
               }
               }
@@ -193,7 +193,7 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
                 "You've no duplicate files that can be cleared",
                 "You've no duplicate files that can be cleared",
               );
               );
             } else {
             } else {
-              DeduplicationResult result =
+              final DeduplicationResult result =
                   await routeToPage(context, DeduplicatePage(duplicates));
                   await routeToPage(context, DeduplicatePage(duplicates));
               if (result != null) {
               if (result != null) {
                 _showDuplicateFilesDeletedDialog(result);
                 _showDuplicateFilesDeletedDialog(result);
@@ -213,7 +213,7 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
   }
   }
 
 
   void _showSpaceFreedDialog(BackupStatus status) {
   void _showSpaceFreedDialog(BackupStatus status) {
-    AlertDialog alert = AlertDialog(
+    final AlertDialog alert = AlertDialog(
       title: const Text("Success"),
       title: const Text("Success"),
       content: Text(
       content: Text(
         "You have successfully freed up " + formatBytes(status.size) + "!",
         "You have successfully freed up " + formatBytes(status.size) + "!",
@@ -268,10 +268,10 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
   }
   }
 
 
   void _showDuplicateFilesDeletedDialog(DeduplicationResult result) {
   void _showDuplicateFilesDeletedDialog(DeduplicationResult result) {
-    String countText = result.count.toString() +
+    final String countText = result.count.toString() +
         " duplicate file" +
         " duplicate file" +
         (result.count == 1 ? "" : "s");
         (result.count == 1 ? "" : "s");
-    AlertDialog alert = AlertDialog(
+    final AlertDialog alert = AlertDialog(
       title: const Text("✨ Success"),
       title: const Text("✨ Success"),
       content: Text(
       content: Text(
         "You have cleaned up " +
         "You have cleaned up " +

+ 1 - 1
lib/ui/settings/danger_section_widget.dart

@@ -53,7 +53,7 @@ class _DangerSectionWidgetState extends State<DangerSectionWidget> {
   }
   }
 
 
   Future<void> _onLogoutTapped() async {
   Future<void> _onLogoutTapped() async {
-    AlertDialog alert = AlertDialog(
+    final AlertDialog alert = AlertDialog(
       title: const Text(
       title: const Text(
         "Logout",
         "Logout",
         style: TextStyle(
         style: TextStyle(

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

@@ -61,7 +61,7 @@ class DebugSectionWidget extends StatelessWidget {
 
 
   void _showKeyAttributesDialog(BuildContext context) {
   void _showKeyAttributesDialog(BuildContext context) {
     final keyAttributes = Configuration.instance.getKeyAttributes();
     final keyAttributes = Configuration.instance.getKeyAttributes();
-    AlertDialog alert = AlertDialog(
+    final AlertDialog alert = AlertDialog(
       title: const Text("key attributes"),
       title: const Text("key attributes"),
       content: SingleChildScrollView(
       content: SingleChildScrollView(
         child: Column(
         child: Column(

+ 3 - 3
lib/ui/settings/security_section_widget.dart

@@ -83,7 +83,7 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
                         value: snapshot.data,
                         value: snapshot.data,
                         onChanged: (value) async {
                         onChanged: (value) async {
                           AppLock.of(context).setEnabled(false);
                           AppLock.of(context).setEnabled(false);
-                          String reason =
+                          const String reason =
                               "Please authenticate to configure two-factor authentication";
                               "Please authenticate to configure two-factor authentication";
                           final result = await requestAuthentication(reason);
                           final result = await requestAuthentication(reason);
                           AppLock.of(context).setEnabled(
                           AppLock.of(context).setEnabled(
@@ -164,7 +164,7 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
                   value: _config.shouldHideFromRecents(),
                   value: _config.shouldHideFromRecents(),
                   onChanged: (value) async {
                   onChanged: (value) async {
                     if (value) {
                     if (value) {
-                      AlertDialog alert = AlertDialog(
+                      final AlertDialog alert = AlertDialog(
                         title: const Text("Hide from recents?"),
                         title: const Text("Hide from recents?"),
                         content: SingleChildScrollView(
                         content: SingleChildScrollView(
                           child: Column(
                           child: Column(
@@ -278,7 +278,7 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
   }
   }
 
 
   void _disableTwoFactor() {
   void _disableTwoFactor() {
-    AlertDialog alert = AlertDialog(
+    final AlertDialog alert = AlertDialog(
       title: const Text("Disable two-factor"),
       title: const Text("Disable two-factor"),
       content: const Text(
       content: const Text(
         "Are you sure you want to disable two-factor authentication?",
         "Are you sure you want to disable two-factor authentication?",

+ 1 - 1
lib/ui/settings/social_section_widget.dart

@@ -22,7 +22,7 @@ class SocialSectionWidget extends StatelessWidget {
   }
   }
 
 
   Widget _getSectionOptions(BuildContext context) {
   Widget _getSectionOptions(BuildContext context) {
-    List<Widget> options = [
+    final List<Widget> options = [
       GestureDetector(
       GestureDetector(
         behavior: HitTestBehavior.translucent,
         behavior: HitTestBehavior.translucent,
         onTap: () {
         onTap: () {

+ 7 - 7
lib/ui/shared_collections_gallery.dart

@@ -112,9 +112,9 @@ class _SharedCollectionGalleryState extends State<SharedCollectionGallery>
   Widget _getSharedCollectionsGallery(SharedCollections collections) {
   Widget _getSharedCollectionsGallery(SharedCollections collections) {
     const double horizontalPaddingOfGridRow = 16;
     const double horizontalPaddingOfGridRow = 16;
     const double crossAxisSpacingOfGrid = 9;
     const double crossAxisSpacingOfGrid = 9;
-    Size size = MediaQuery.of(context).size;
-    int albumsCountInOneRow = max(size.width ~/ 220.0, 2);
-    double totalWhiteSpaceOfRow = (horizontalPaddingOfGridRow * 2) +
+    final Size size = MediaQuery.of(context).size;
+    final int albumsCountInOneRow = max(size.width ~/ 220.0, 2);
+    final double totalWhiteSpaceOfRow = (horizontalPaddingOfGridRow * 2) +
         (albumsCountInOneRow - 1) * crossAxisSpacingOfGrid;
         (albumsCountInOneRow - 1) * crossAxisSpacingOfGrid;
     final double sideOfThumbnail = (size.width / albumsCountInOneRow) -
     final double sideOfThumbnail = (size.width / albumsCountInOneRow) -
         (totalWhiteSpaceOfRow / albumsCountInOneRow);
         (totalWhiteSpaceOfRow / albumsCountInOneRow);
@@ -363,11 +363,11 @@ class IncomingCollectionItem extends StatelessWidget {
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
     const double horizontalPaddingOfGridRow = 16;
     const double horizontalPaddingOfGridRow = 16;
     const double crossAxisSpacingOfGrid = 9;
     const double crossAxisSpacingOfGrid = 9;
-    TextStyle albumTitleTextStyle =
+    final TextStyle albumTitleTextStyle =
         Theme.of(context).textTheme.subtitle1.copyWith(fontSize: 14);
         Theme.of(context).textTheme.subtitle1.copyWith(fontSize: 14);
-    Size size = MediaQuery.of(context).size;
-    int albumsCountInOneRow = max(size.width ~/ 220.0, 2);
-    double totalWhiteSpaceOfRow = (horizontalPaddingOfGridRow * 2) +
+    final Size size = MediaQuery.of(context).size;
+    final int albumsCountInOneRow = max(size.width ~/ 220.0, 2);
+    final double totalWhiteSpaceOfRow = (horizontalPaddingOfGridRow * 2) +
         (albumsCountInOneRow - 1) * crossAxisSpacingOfGrid;
         (albumsCountInOneRow - 1) * crossAxisSpacingOfGrid;
     final double sideOfThumbnail = (size.width / albumsCountInOneRow) -
     final double sideOfThumbnail = (size.width / albumsCountInOneRow) -
         (totalWhiteSpaceOfRow / albumsCountInOneRow);
         (totalWhiteSpaceOfRow / albumsCountInOneRow);

+ 9 - 9
lib/ui/sharing/manage_links_widget.dart

@@ -131,12 +131,12 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
                               false,
                               false,
                           onChanged: (enablePassword) async {
                           onChanged: (enablePassword) async {
                             if (enablePassword) {
                             if (enablePassword) {
-                              var inputResult =
+                              final inputResult =
                                   await _displayLinkPasswordInput(context);
                                   await _displayLinkPasswordInput(context);
                               if (inputResult != null &&
                               if (inputResult != null &&
                                   inputResult == 'ok' &&
                                   inputResult == 'ok' &&
                                   _textFieldController.text.trim().isNotEmpty) {
                                   _textFieldController.text.trim().isNotEmpty) {
-                                var propToUpdate = await _getEncryptedPassword(
+                                final propToUpdate = await _getEncryptedPassword(
                                   _textFieldController.text,
                                   _textFieldController.text,
                                 );
                                 );
                                 await _updateUrlSettings(context, propToUpdate);
                                 await _updateUrlSettings(context, propToUpdate);
@@ -250,10 +250,10 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
                   CupertinoButton(
                   CupertinoButton(
                     onPressed: () async {
                     onPressed: () async {
                       int newValidTill = -1;
                       int newValidTill = -1;
-                      int expireAfterInMicroseconds = _selectedExpiry.item3;
+                      final int expireAfterInMicroseconds = _selectedExpiry.item3;
                       // need to manually select time
                       // need to manually select time
                       if (expireAfterInMicroseconds < 0) {
                       if (expireAfterInMicroseconds < 0) {
-                        var timeInMicrosecondsFromEpoch =
+                        final timeInMicrosecondsFromEpoch =
                             await _showDateTimePicker();
                             await _showDateTimePicker();
                         if (timeInMicrosecondsFromEpoch != null) {
                         if (timeInMicrosecondsFromEpoch != null) {
                           newValidTill = timeInMicrosecondsFromEpoch;
                           newValidTill = timeInMicrosecondsFromEpoch;
@@ -293,7 +293,7 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
                 backgroundColor:
                 backgroundColor:
                     Theme.of(context).backgroundColor.withOpacity(0.95),
                     Theme.of(context).backgroundColor.withOpacity(0.95),
                 onSelectedItemChanged: (value) {
                 onSelectedItemChanged: (value) {
-                  var firstWhere = _expiryOptions
+                  final firstWhere = _expiryOptions
                       .firstWhere((element) => element.item1 == value);
                       .firstWhere((element) => element.item1 == value);
                   setState(() {
                   setState(() {
                     _selectedExpiry = firstWhere;
                     _selectedExpiry = firstWhere;
@@ -410,8 +410,8 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
       Sodium.cryptoPwhashAlgArgon2id13 == Sodium.cryptoPwhashAlgDefault,
       Sodium.cryptoPwhashAlgArgon2id13 == Sodium.cryptoPwhashAlgDefault,
       "mismatch in expected default pw hashing algo",
       "mismatch in expected default pw hashing algo",
     );
     );
-    int memLimit = Sodium.cryptoPwhashMemlimitInteractive;
-    int opsLimit = Sodium.cryptoPwhashOpslimitInteractive;
+    final int memLimit = Sodium.cryptoPwhashMemlimitInteractive;
+    final int opsLimit = Sodium.cryptoPwhashOpslimitInteractive;
     final kekSalt = CryptoUtil.getSaltToDeriveKey();
     final kekSalt = CryptoUtil.getSaltToDeriveKey();
     final result = await CryptoUtil.deriveKey(
     final result = await CryptoUtil.deriveKey(
       utf8.encode(pass),
       utf8.encode(pass),
@@ -444,7 +444,7 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
   }
   }
 
 
   Text _getLinkExpiryTimeWidget() {
   Text _getLinkExpiryTimeWidget() {
-    int validTill = widget.collection.publicURLs?.first?.validTill ?? 0;
+    final int validTill = widget.collection.publicURLs?.first?.validTill ?? 0;
     if (validTill == 0) {
     if (validTill == 0) {
       return const Text(
       return const Text(
         'Never',
         'Never',
@@ -470,7 +470,7 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
   }
   }
 
 
   Future<void> _showDeviceLimitPicker() async {
   Future<void> _showDeviceLimitPicker() async {
-    List<Text> options = [];
+    final List<Text> options = [];
     for (int i = 50; i > 0; i--) {
     for (int i = 50; i > 0; i--) {
       options.add(
       options.add(
         Text(i.toString(), style: Theme.of(context).textTheme.subtitle1),
         Text(i.toString(), style: Theme.of(context).textTheme.subtitle1),

+ 4 - 4
lib/ui/sharing/share_collection_widget.dart

@@ -96,7 +96,7 @@ class _SharingDialogState extends State<SharingDialog> {
     }
     }
 
 
     if (!FeatureFlagService.instance.disableUrlSharing()) {
     if (!FeatureFlagService.instance.disableUrlSharing()) {
-      bool hasUrl = widget.collection.publicURLs?.isNotEmpty ?? false;
+      final bool hasUrl = widget.collection.publicURLs?.isNotEmpty ?? false;
       children.addAll([
       children.addAll([
         const Padding(padding: EdgeInsets.all(16)),
         const Padding(padding: EdgeInsets.all(16)),
         const Divider(height: 1),
         const Divider(height: 1),
@@ -249,10 +249,10 @@ class _SharingDialogState extends State<SharingDialog> {
   }
   }
 
 
   Widget _getShareableUrlWidget(BuildContext parentContext) {
   Widget _getShareableUrlWidget(BuildContext parentContext) {
-    String collectionKey = Base58Encode(
+    final String collectionKey = Base58Encode(
       CollectionsService.instance.getCollectionKey(widget.collection.id),
       CollectionsService.instance.getCollectionKey(widget.collection.id),
     );
     );
-    String url = "${widget.collection.publicURLs.first.url}#$collectionKey";
+    final String url = "${widget.collection.publicURLs.first.url}#$collectionKey";
     return SingleChildScrollView(
     return SingleChildScrollView(
       child: Column(
       child: Column(
         mainAxisAlignment: MainAxisAlignment.start,
         mainAxisAlignment: MainAxisAlignment.start,
@@ -441,7 +441,7 @@ class _SharingDialogState extends State<SharingDialog> {
   }
   }
 
 
   void _showUnSupportedAlert() {
   void _showUnSupportedAlert() {
-    AlertDialog alert = AlertDialog(
+    final AlertDialog alert = AlertDialog(
       title: const Text("Sorry"),
       title: const Text("Sorry"),
       content: const Text(
       content: const Text(
         "Sharing is not permitted for free accounts, please subscribe",
         "Sharing is not permitted for free accounts, please subscribe",

+ 1 - 1
lib/ui/status_bar_widget.dart

@@ -135,7 +135,7 @@ class _SyncStatusWidgetState extends State<SyncStatusWidget> {
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
-    bool isNotOutdatedEvent = _event != null &&
+    final bool isNotOutdatedEvent = _event != null &&
         (_event.status == SyncStatus.completedBackup ||
         (_event.status == SyncStatus.completedBackup ||
             _event.status == SyncStatus.completedFirstGalleryImport) &&
             _event.status == SyncStatus.completedFirstGalleryImport) &&
         (DateTime.now().microsecondsSinceEpoch - _event.timestamp >
         (DateTime.now().microsecondsSinceEpoch - _event.timestamp >

+ 5 - 5
lib/ui/tools/editor/filtered_image.dart

@@ -70,11 +70,11 @@ class ColorFilterGenerator {
         0,
         0,
       ];
       ];
     }
     }
-    double cosVal = cos(value);
-    double sinVal = sin(value);
-    double lumR = 0.213;
-    double lumG = 0.715;
-    double lumB = 0.072;
+    final double cosVal = cos(value);
+    final double sinVal = sin(value);
+    const double lumR = 0.213;
+    const double lumG = 0.715;
+    const double lumB = 0.072;
 
 
     return List<double>.from(<double>[
     return List<double>.from(<double>[
       (lumR + (cosVal * (1 - lumR))) + (sinVal * (-lumR)),
       (lumR + (cosVal * (1 - lumR))) + (sinVal * (-lumR)),

+ 9 - 9
lib/ui/tools/editor/image_editor_page.dart

@@ -157,7 +157,7 @@ class _ImageEditorPageState extends State<ImageEditorPage> {
   }
   }
 
 
   Widget _buildFlipButton() {
   Widget _buildFlipButton() {
-    TextStyle subtitle2 = Theme.of(context).textTheme.subtitle2;
+    final TextStyle subtitle2 = Theme.of(context).textTheme.subtitle2;
 
 
     return GestureDetector(
     return GestureDetector(
       behavior: HitTestBehavior.translucent,
       behavior: HitTestBehavior.translucent,
@@ -191,7 +191,7 @@ class _ImageEditorPageState extends State<ImageEditorPage> {
   }
   }
 
 
   Widget _buildRotateLeftButton() {
   Widget _buildRotateLeftButton() {
-    TextStyle subtitle2 = Theme.of(context).textTheme.subtitle2;
+    final TextStyle subtitle2 = Theme.of(context).textTheme.subtitle2;
 
 
     return GestureDetector(
     return GestureDetector(
       behavior: HitTestBehavior.translucent,
       behavior: HitTestBehavior.translucent,
@@ -221,7 +221,7 @@ class _ImageEditorPageState extends State<ImageEditorPage> {
   }
   }
 
 
   Widget _buildRotateRightButton() {
   Widget _buildRotateRightButton() {
-    TextStyle subtitle2 = Theme.of(context).textTheme.subtitle2;
+    final TextStyle subtitle2 = Theme.of(context).textTheme.subtitle2;
 
 
     return GestureDetector(
     return GestureDetector(
       behavior: HitTestBehavior.translucent,
       behavior: HitTestBehavior.translucent,
@@ -251,7 +251,7 @@ class _ImageEditorPageState extends State<ImageEditorPage> {
   }
   }
 
 
   Widget _buildSaveButton() {
   Widget _buildSaveButton() {
-    TextStyle subtitle2 = Theme.of(context).textTheme.subtitle2;
+    final TextStyle subtitle2 = Theme.of(context).textTheme.subtitle2;
 
 
     return GestureDetector(
     return GestureDetector(
       behavior: HitTestBehavior.translucent,
       behavior: HitTestBehavior.translucent,
@@ -344,12 +344,12 @@ class _ImageEditorPageState extends State<ImageEditorPage> {
         title: fileName,
         title: fileName,
       );
       );
       final newFile =
       final newFile =
-          ente.File.fromAsset(widget.originalFile.deviceFolder, newAsset);
+          await ente.File.fromAsset(widget.originalFile.deviceFolder, newAsset);
       newFile.creationTime = widget.originalFile.creationTime;
       newFile.creationTime = widget.originalFile.creationTime;
       newFile.collectionID = widget.originalFile.collectionID;
       newFile.collectionID = widget.originalFile.collectionID;
       newFile.location = widget.originalFile.location;
       newFile.location = widget.originalFile.location;
       if (!newFile.hasLocation() && widget.originalFile.localID != null) {
       if (!newFile.hasLocation() && widget.originalFile.localID != null) {
-        var assetEntity = await widget.originalFile.getAsset();
+        final assetEntity = await widget.originalFile.getAsset();
         if (assetEntity != null) {
         if (assetEntity != null) {
           final latLong = await assetEntity.latlngAsync();
           final latLong = await assetEntity.latlngAsync();
           newFile.location = Location(latLong.latitude, latLong.longitude);
           newFile.location = Location(latLong.latitude, latLong.longitude);
@@ -394,7 +394,7 @@ class _ImageEditorPageState extends State<ImageEditorPage> {
   }
   }
 
 
   Widget _buildSat() {
   Widget _buildSat() {
-    TextStyle subtitle2 = Theme.of(context).textTheme.subtitle2;
+    final TextStyle subtitle2 = Theme.of(context).textTheme.subtitle2;
 
 
     return Container(
     return Container(
       padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
       padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
@@ -440,7 +440,7 @@ class _ImageEditorPageState extends State<ImageEditorPage> {
   }
   }
 
 
   Widget _buildBrightness() {
   Widget _buildBrightness() {
-    TextStyle subtitle2 = Theme.of(context).textTheme.subtitle2;
+    final TextStyle subtitle2 = Theme.of(context).textTheme.subtitle2;
 
 
     return Container(
     return Container(
       padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
       padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
@@ -486,7 +486,7 @@ class _ImageEditorPageState extends State<ImageEditorPage> {
   }
   }
 
 
   Future<void> _showExitConfirmationDialog() async {
   Future<void> _showExitConfirmationDialog() async {
-    AlertDialog alert = AlertDialog(
+    final AlertDialog alert = AlertDialog(
       title: const Text("Discard edits?"),
       title: const Text("Discard edits?"),
       actions: [
       actions: [
         TextButton(
         TextButton(

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

@@ -1,6 +1,7 @@
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 
 
 class CustomAppBar extends PreferredSize {
 class CustomAppBar extends PreferredSize {
+  @override
   final Widget child;
   final Widget child;
   final double height;
   final double height;
 
 

+ 1 - 1
lib/ui/viewer/file/detail_page.dart

@@ -139,7 +139,7 @@ class _DetailPageState extends State<DetailPage> {
     return PageView.builder(
     return PageView.builder(
       itemBuilder: (context, index) {
       itemBuilder: (context, index) {
         final file = _files[index];
         final file = _files[index];
-        Widget content = FileWidget(
+        final Widget content = FileWidget(
           file,
           file,
           autoPlay: !_hasPageChanged,
           autoPlay: !_hasPageChanged,
           tagPrefix: widget.config.tagPrefix,
           tagPrefix: widget.config.tagPrefix,

+ 3 - 3
lib/ui/viewer/file/fading_app_bar.dart

@@ -300,9 +300,9 @@ class FadingAppBarState extends State<FadingAppBar> {
   Future<void> _download(File file) async {
   Future<void> _download(File file) async {
     final dialog = createProgressDialog(context, "Downloading...");
     final dialog = createProgressDialog(context, "Downloading...");
     await dialog.show();
     await dialog.show();
-    FileType type = file.fileType;
+    final FileType type = file.fileType;
     // save and track image for livePhoto/image and video for FileType.video
     // save and track image for livePhoto/image and video for FileType.video
-    io.File fileToSave = await getFile(file);
+    final io.File fileToSave = await getFile(file);
     final savedAsset = type == FileType.video
     final savedAsset = type == FileType.video
         ? (await PhotoManager.editor.saveVideo(fileToSave, title: file.title))
         ? (await PhotoManager.editor.saveVideo(fileToSave, title: file.title))
         : (await PhotoManager.editor
         : (await PhotoManager.editor
@@ -313,7 +313,7 @@ class FadingAppBarState extends State<FadingAppBar> {
     await FilesDB.instance.insert(file);
     await FilesDB.instance.insert(file);
 
 
     if (type == FileType.livePhoto) {
     if (type == FileType.livePhoto) {
-      io.File liveVideo = await getFileFromServer(file, liveVideo: true);
+      final io.File liveVideo = await getFileFromServer(file, liveVideo: true);
       if (liveVideo == null) {
       if (liveVideo == null) {
         _logger.warning("Failed to find live video" + file.tag());
         _logger.warning("Failed to find live video" + file.tag());
       } else {
       } else {

+ 3 - 3
lib/ui/viewer/file/fading_bottom_bar.dart

@@ -59,7 +59,7 @@ class FadingBottomBarState extends State<FadingBottomBar> {
   }
   }
 
 
   Widget _getBottomBar() {
   Widget _getBottomBar() {
-    List<Widget> children = [];
+    final List<Widget> children = [];
     children.add(
     children.add(
       Tooltip(
       Tooltip(
         message: "Info",
         message: "Info",
@@ -103,7 +103,7 @@ class FadingBottomBarState extends State<FadingBottomBar> {
       }
       }
       if (widget.file.uploadedFileID != null &&
       if (widget.file.uploadedFileID != null &&
           widget.file.ownerID == Configuration.instance.getUserID()) {
           widget.file.ownerID == Configuration.instance.getUserID()) {
-        bool isArchived =
+        final bool isArchived =
             widget.file.magicMetadata.visibility == kVisibilityArchive;
             widget.file.magicMetadata.visibility == kVisibilityArchive;
         children.add(
         children.add(
           Tooltip(
           Tooltip(
@@ -151,7 +151,7 @@ class FadingBottomBarState extends State<FadingBottomBar> {
         ),
         ),
       );
       );
     }
     }
-    var safeAreaBottomPadding = MediaQuery.of(context).padding.bottom * .5;
+    final safeAreaBottomPadding = MediaQuery.of(context).padding.bottom * .5;
     return IgnorePointer(
     return IgnorePointer(
       ignoring: _shouldHide,
       ignoring: _shouldHide,
       child: AnimatedOpacity(
       child: AnimatedOpacity(

+ 2 - 2
lib/ui/viewer/file/file_info_dialog.dart

@@ -76,7 +76,7 @@ class _FileInfoWidgetState extends State<FileInfoWidget> {
         _exifData["ISO"] != null;
         _exifData["ISO"] != null;
     final bool showDimension =
     final bool showDimension =
         _exifData["resolution"] != null && _exifData["megaPixels"] != null;
         _exifData["resolution"] != null && _exifData["megaPixels"] != null;
-    var listTiles = <Widget>[
+    final listTiles = <Widget>[
       ListTile(
       ListTile(
         leading: const Padding(
         leading: const Padding(
           padding: EdgeInsets.only(top: 8, left: 6),
           padding: EdgeInsets.only(top: 8, left: 6),
@@ -207,7 +207,7 @@ class _FileInfoWidgetState extends State<FileInfoWidget> {
           onTap: () {
           onTap: () {
             if (file.collectionID != null) {
             if (file.collectionID != null) {
               Navigator.pop(context); // info dialog
               Navigator.pop(context); // info dialog
-              Collection c = CollectionsService.instance
+              final Collection c = CollectionsService.instance
                   .getCollectionByID(file.collectionID);
                   .getCollectionByID(file.collectionID);
               routeToPage(
               routeToPage(
                 context,
                 context,

+ 2 - 2
lib/ui/viewer/file/thumbnail_widget.dart

@@ -91,7 +91,7 @@ class _ThumbnailWidgetState extends State<ThumbnailWidget> {
     // If yes, parent thumbnail widget can be stateless
     // If yes, parent thumbnail widget can be stateless
     Widget content;
     Widget content;
     if (image != null) {
     if (image != null) {
-      List<Widget> contentChildren = [image];
+      final List<Widget> contentChildren = [image];
       if (widget.file.fileType == FileType.video) {
       if (widget.file.fileType == FileType.video) {
         contentChildren.add(const VideoOverlayIcon());
         contentChildren.add(const VideoOverlayIcon());
       } else if (widget.file.fileType == FileType.livePhoto &&
       } else if (widget.file.fileType == FileType.livePhoto &&
@@ -105,7 +105,7 @@ class _ThumbnailWidgetState extends State<ThumbnailWidget> {
               children: contentChildren,
               children: contentChildren,
             );
             );
     }
     }
-    List<Widget> viewChildren = [
+    final List<Widget> viewChildren = [
       const ThumbnailPlaceHolder(),
       const ThumbnailPlaceHolder(),
       AnimatedOpacity(
       AnimatedOpacity(
         opacity: content == null ? 0 : 1.0,
         opacity: content == null ? 0 : 1.0,

+ 1 - 1
lib/ui/viewer/file/video_controls.dart

@@ -242,7 +242,7 @@ class _VideoControlsState extends State<VideoControls> {
   }
   }
 
 
   void _playPause() {
   void _playPause() {
-    bool isFinished = _latestValue.position >= _latestValue.duration;
+    final bool isFinished = _latestValue.position >= _latestValue.duration;
 
 
     setState(() {
     setState(() {
       if (controller.value.isPlaying) {
       if (controller.value.isPlaying) {

+ 1 - 1
lib/ui/viewer/file/zoomable_image.dart

@@ -88,7 +88,7 @@ class _ZoomableImageState extends State<ZoomableImage>
       content = const EnteLoadingWidget();
       content = const EnteLoadingWidget();
     }
     }
 
 
-    GestureDragUpdateCallback verticalDragCallback = _isZooming
+    final GestureDragUpdateCallback verticalDragCallback = _isZooming
         ? null
         ? null
         : (d) => {
         : (d) => {
               if (!_isZooming && d.delta.dy > kDragSensitivity)
               if (!_isZooming && d.delta.dy > kDragSensitivity)

+ 3 - 3
lib/ui/viewer/file/zoomable_live_image.dart

@@ -152,7 +152,7 @@ class _ZoomableLiveImageState extends State<ZoomableLiveImage>
   }
   }
 
 
   VideoPlayerController _setVideoPlayerController({io.File file}) {
   VideoPlayerController _setVideoPlayerController({io.File file}) {
-    var videoPlayerController = VideoPlayerController.file(file);
+    final videoPlayerController = VideoPlayerController.file(file);
     return _videoPlayerController = videoPlayerController
     return _videoPlayerController = videoPlayerController
       ..initialize().whenComplete(() {
       ..initialize().whenComplete(() {
         if (mounted) {
         if (mounted) {
@@ -164,8 +164,8 @@ class _ZoomableLiveImageState extends State<ZoomableLiveImage>
   }
   }
 
 
   void _showLivePhotoToast() async {
   void _showLivePhotoToast() async {
-    var preferences = await SharedPreferences.getInstance();
-    int promptTillNow = preferences.getInt(kLivePhotoToastCounterKey) ?? 0;
+    final preferences = await SharedPreferences.getInstance();
+    final int promptTillNow = preferences.getInt(kLivePhotoToastCounterKey) ?? 0;
     if (promptTillNow < kMaxLivePhotoToastCount && mounted) {
     if (promptTillNow < kMaxLivePhotoToastCount && mounted) {
       showToast(context, "Press and hold to play video");
       showToast(context, "Press and hold to play video");
       preferences.setInt(kLivePhotoToastCounterKey, promptTillNow + 1);
       preferences.setInt(kLivePhotoToastCounterKey, promptTillNow + 1);

+ 0 - 4
lib/ui/viewer/gallery/device_folder_page.dart

@@ -66,10 +66,6 @@ class DeviceFolderPage extends StatelessWidget {
       ),
       ),
     );
     );
   }
   }
-
-  Widget _getHeaderWidget() {
-    return BackupConfigurationHeaderWidget(devicePathCollection);
-  }
 }
 }
 
 
 class BackupConfigurationHeaderWidget extends StatefulWidget {
 class BackupConfigurationHeaderWidget extends StatefulWidget {

+ 3 - 3
lib/ui/viewer/gallery/gallery.dart

@@ -183,7 +183,7 @@ class _GalleryState extends State<Gallery> {
         return const EnteLoadingWidget();
         return const EnteLoadingWidget();
       },
       },
       emptyResultBuilder: (_) {
       emptyResultBuilder: (_) {
-        List<Widget> children = [];
+        final List<Widget> children = [];
         if (widget.header != null) {
         if (widget.header != null) {
           children.add(widget.header);
           children.add(widget.header);
         }
         }
@@ -269,8 +269,8 @@ class _GalleryState extends State<Gallery> {
   }
   }
 
 
   bool _areFromSameDay(int firstCreationTime, int secondCreationTime) {
   bool _areFromSameDay(int firstCreationTime, int secondCreationTime) {
-    var firstDate = DateTime.fromMicrosecondsSinceEpoch(firstCreationTime);
-    var secondDate = DateTime.fromMicrosecondsSinceEpoch(secondCreationTime);
+    final firstDate = DateTime.fromMicrosecondsSinceEpoch(firstCreationTime);
+    final secondDate = DateTime.fromMicrosecondsSinceEpoch(secondCreationTime);
     return firstDate.year == secondDate.year &&
     return firstDate.year == secondDate.year &&
         firstDate.month == secondDate.month &&
         firstDate.month == secondDate.month &&
         firstDate.day == secondDate.day;
         firstDate.day == secondDate.day;

+ 2 - 2
lib/ui/viewer/gallery/gallery_app_bar_widget.dart

@@ -119,7 +119,7 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
   }
   }
 
 
   List<Widget> _getDefaultActions(BuildContext context) {
   List<Widget> _getDefaultActions(BuildContext context) {
-    List<Widget> actions = <Widget>[];
+    final List<Widget> actions = <Widget>[];
     if (Configuration.instance.hasConfiguredAccount() &&
     if (Configuration.instance.hasConfiguredAccount() &&
         widget.selectedFiles.files.isEmpty &&
         widget.selectedFiles.files.isEmpty &&
         (widget.type == GalleryType.localFolder ||
         (widget.type == GalleryType.localFolder ||
@@ -157,7 +157,7 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
                 ),
                 ),
               );
               );
             }
             }
-            bool isArchived = widget.collection.isArchived();
+            final bool isArchived = widget.collection.isArchived();
             items.add(
             items.add(
               PopupMenuItem(
               PopupMenuItem(
                 value: 2,
                 value: 2,

+ 3 - 3
lib/ui/viewer/gallery/gallery_overlay_widget.dart

@@ -66,7 +66,7 @@ class _GalleryOverlayWidgetState extends State<GalleryOverlayWidget> {
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
-    bool filesAreSelected = widget.selectedFiles.files.isNotEmpty;
+    final bool filesAreSelected = widget.selectedFiles.files.isNotEmpty;
     final bottomPadding = Platform.isAndroid ? 0.0 : 12.0;
     final bottomPadding = Platform.isAndroid ? 0.0 : 12.0;
     return Padding(
     return Padding(
       padding: EdgeInsets.only(bottom: bottomPadding),
       padding: EdgeInsets.only(bottom: bottomPadding),
@@ -254,7 +254,7 @@ class _OverlayWidgetState extends State<OverlayWidget> {
   }
   }
 
 
   List<Widget> _getActions(BuildContext context) {
   List<Widget> _getActions(BuildContext context) {
-    List<Widget> actions = <Widget>[];
+    final List<Widget> actions = <Widget>[];
     if (widget.type == GalleryType.trash) {
     if (widget.type == GalleryType.trash) {
       _addTrashAction(actions);
       _addTrashAction(actions);
       return actions;
       return actions;
@@ -372,7 +372,7 @@ class _OverlayWidgetState extends State<OverlayWidget> {
 
 
     if (widget.type == GalleryType.homepage ||
     if (widget.type == GalleryType.homepage ||
         widget.type == GalleryType.archive) {
         widget.type == GalleryType.archive) {
-      bool showArchive = widget.type == GalleryType.homepage;
+      final bool showArchive = widget.type == GalleryType.homepage;
       actions.add(
       actions.add(
         Tooltip(
         Tooltip(
           message: showArchive ? "Hide" : "Unhide",
           message: showArchive ? "Hide" : "Unhide",

+ 1 - 1
lib/ui/viewer/gallery/trash_page.dart

@@ -48,7 +48,7 @@ class _TrashPageState extends State<TrashPage> {
 
 
   @override
   @override
   Widget build(Object context) {
   Widget build(Object context) {
-    bool filesAreSelected = widget._selectedFiles.files.isNotEmpty;
+    final bool filesAreSelected = widget._selectedFiles.files.isNotEmpty;
 
 
     final gallery = Gallery(
     final gallery = Gallery(
       asyncLoader: (creationStartTime, creationEndTime, {limit, asc}) {
       asyncLoader: (creationStartTime, creationEndTime, {limit, asc}) {

+ 2 - 2
lib/utils/data_util.dart

@@ -20,7 +20,7 @@ String convertBytesToReadableFormat(int bytes) {
 String formatBytes(int bytes, [int decimals = 2]) {
 String formatBytes(int bytes, [int decimals = 2]) {
   if (bytes == 0) return '0 bytes';
   if (bytes == 0) return '0 bytes';
   const k = 1024;
   const k = 1024;
-  int dm = decimals < 0 ? 0 : decimals;
-  int i = (log(bytes) / log(k)).floor();
+  final int dm = decimals < 0 ? 0 : decimals;
+  final int i = (log(bytes) / log(k)).floor();
   return ((bytes / pow(k, i)).toStringAsFixed(dm)) + ' ' + kStorageUnits[i];
   return ((bytes / pow(k, i)).toStringAsFixed(dm)) + ' ' + kStorageUnits[i];
 }
 }

+ 6 - 6
lib/utils/date_time_util.dart

@@ -131,7 +131,7 @@ String getFullDate(DateTime dateTime) {
 }
 }
 
 
 String daysLeft(int futureTime) {
 String daysLeft(int futureTime) {
-  int daysLeft = ((futureTime - DateTime.now().microsecondsSinceEpoch) /
+  final int daysLeft = ((futureTime - DateTime.now().microsecondsSinceEpoch) /
           Duration.microsecondsPerDay)
           Duration.microsecondsPerDay)
       .ceil();
       .ceil();
   return '$daysLeft day' + (daysLeft <= 1 ? "" : "s");
   return '$daysLeft day' + (daysLeft <= 1 ? "" : "s");
@@ -143,7 +143,7 @@ String formatDuration(Duration position) {
   int seconds = ms ~/ 1000;
   int seconds = ms ~/ 1000;
   final int hours = seconds ~/ 3600;
   final int hours = seconds ~/ 3600;
   seconds = seconds % 3600;
   seconds = seconds % 3600;
-  var minutes = seconds ~/ 60;
+  final minutes = seconds ~/ 60;
   seconds = seconds % 60;
   seconds = seconds % 60;
 
 
   final hoursString = hours >= 10
   final hoursString = hours >= 10
@@ -230,15 +230,15 @@ String secondsToHHMMSS(int value) {
   h = value ~/ 3600;
   h = value ~/ 3600;
   m = ((value - h * 3600)) ~/ 60;
   m = ((value - h * 3600)) ~/ 60;
   s = value - (h * 3600) - (m * 60);
   s = value - (h * 3600) - (m * 60);
-  String hourLeft = h.toString().length < 2 ? "0" + h.toString() : h.toString();
+  final String hourLeft = h.toString().length < 2 ? "0" + h.toString() : h.toString();
 
 
-  String minuteLeft =
+  final String minuteLeft =
       m.toString().length < 2 ? "0" + m.toString() : m.toString();
       m.toString().length < 2 ? "0" + m.toString() : m.toString();
 
 
-  String secondsLeft =
+  final String secondsLeft =
       s.toString().length < 2 ? "0" + s.toString() : s.toString();
       s.toString().length < 2 ? "0" + s.toString() : s.toString();
 
 
-  String result = "$hourLeft:$minuteLeft:$secondsLeft";
+  final String result = "$hourLeft:$minuteLeft:$secondsLeft";
 
 
   return result;
   return result;
 }
 }

+ 2 - 2
lib/utils/delete_file_util.dart

@@ -418,7 +418,7 @@ Future<List<String>> _deleteLocalFilesInBatches(
 
 
 Future<bool> _localFileExist(File file) {
 Future<bool> _localFileExist(File file) {
   if (file.isSharedMediaToAppSandbox()) {
   if (file.isSharedMediaToAppSandbox()) {
-    var localFile = io.File(getSharedMediaFilePath(file));
+    final localFile = io.File(getSharedMediaFilePath(file));
     return localFile.exists();
     return localFile.exists();
   } else {
   } else {
     return file.getAsset().then((asset) {
     return file.getAsset().then((asset) {
@@ -434,7 +434,7 @@ Future<List<String>> _tryDeleteSharedMediaFiles(List<String> localIDs) {
   final List<String> actuallyDeletedIDs = [];
   final List<String> actuallyDeletedIDs = [];
   try {
   try {
     return Future.forEach(localIDs, (id) async {
     return Future.forEach(localIDs, (id) async {
-      String localPath = getSharedMediaPathFromLocalID(id);
+      final String localPath = getSharedMediaPathFromLocalID(id);
       try {
       try {
         // verify the file exists as the OS may have already deleted it from cache
         // verify the file exists as the OS may have already deleted it from cache
         if (io.File(localPath).existsSync()) {
         if (io.File(localPath).existsSync()) {

+ 2 - 2
lib/utils/dialog_util.dart

@@ -29,7 +29,7 @@ Future<dynamic> showErrorDialog(
   String title,
   String title,
   String content,
   String content,
 ) {
 ) {
-  AlertDialog alert = AlertDialog(
+  final AlertDialog alert = AlertDialog(
     shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
     shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
     title: Text(
     title: Text(
       title,
       title,
@@ -77,7 +77,7 @@ Future<T> showConfettiDialog<T>({
   final pageBuilder = Builder(
   final pageBuilder = Builder(
     builder: builder,
     builder: builder,
   );
   );
-  ConfettiController confettiController =
+  final ConfettiController confettiController =
       ConfettiController(duration: const Duration(seconds: 1));
       ConfettiController(duration: const Duration(seconds: 1));
   confettiController.play();
   confettiController.play();
   return showDialog(
   return showDialog(

+ 1 - 1
lib/utils/diff_fetcher.dart

@@ -76,7 +76,7 @@ class DiffFetcher {
             fileDecryptionKey,
             fileDecryptionKey,
             Sodium.base642bin(file.metadataDecryptionHeader),
             Sodium.base642bin(file.metadataDecryptionHeader),
           );
           );
-          Map<String, dynamic> metadata =
+          final Map<String, dynamic> metadata =
               jsonDecode(utf8.decode(encodedMetadata));
               jsonDecode(utf8.decode(encodedMetadata));
           file.applyMetadata(metadata);
           file.applyMetadata(metadata);
           if (item['magicMetadata'] != null) {
           if (item['magicMetadata'] != null) {

+ 6 - 6
lib/utils/email_util.dart

@@ -126,7 +126,7 @@ Future<void> _sendLogs(
   String subject,
   String subject,
   String body,
   String body,
 ) async {
 ) async {
-  String zipFilePath = await getZippedLogsFile(context);
+  final String zipFilePath = await getZippedLogsFile(context);
   final Email email = Email(
   final Email email = Email(
     recipients: [toEmail],
     recipients: [toEmail],
     subject: subject,
     subject: subject,
@@ -150,7 +150,7 @@ Future<String> getZippedLogsFile(BuildContext context) async {
   final tempPath = (await getTemporaryDirectory()).path;
   final tempPath = (await getTemporaryDirectory()).path;
   final zipFilePath =
   final zipFilePath =
       tempPath + "/logs-${Configuration.instance.getUserID() ?? 0}.zip";
       tempPath + "/logs-${Configuration.instance.getUserID() ?? 0}.zip";
-  var encoder = ZipFileEncoder();
+  final encoder = ZipFileEncoder();
   encoder.create(zipFilePath);
   encoder.create(zipFilePath);
   encoder.addDirectory(logsDirectory);
   encoder.addDirectory(logsDirectory);
   encoder.close();
   encoder.close();
@@ -187,8 +187,8 @@ Future<void> sendEmail(
   String body,
   String body,
 }) async {
 }) async {
   try {
   try {
-    String clientDebugInfo = await _clientInfo();
-    EmailContent email = EmailContent(
+    final String clientDebugInfo = await _clientInfo();
+    final EmailContent email = EmailContent(
       to: [
       to: [
         to,
         to,
       ],
       ],
@@ -210,7 +210,7 @@ Future<void> sendEmail(
         throw Exception('Could not launch ${params.toString()}');
         throw Exception('Could not launch ${params.toString()}');
       }
       }
     } else {
     } else {
-      OpenMailAppResult result = await OpenMailApp.composeNewEmailInMailApp(
+      final OpenMailAppResult result = await OpenMailApp.composeNewEmailInMailApp(
         nativePickerTitle: 'Select email app',
         nativePickerTitle: 'Select email app',
         emailContent: email,
         emailContent: email,
       );
       );
@@ -257,7 +257,7 @@ Future<void> sendEmail(
 
 
 Future<String> _clientInfo() async {
 Future<String> _clientInfo() async {
   final packageInfo = await PackageInfo.fromPlatform();
   final packageInfo = await PackageInfo.fromPlatform();
-  String debugInfo = '\n\n\n\n ------------------- \nFollowing information can '
+  final String debugInfo = '\n\n\n\n ------------------- \nFollowing information can '
       'help us in debugging if you are facing any issue '
       'help us in debugging if you are facing any issue '
       '\nRegistered email: ${Configuration.instance.getEmail()}'
       '\nRegistered email: ${Configuration.instance.getEmail()}'
       '\nClient: ${packageInfo.packageName}'
       '\nClient: ${packageInfo.packageName}'

+ 12 - 12
lib/utils/file_uploader.dart

@@ -155,7 +155,7 @@ class FileUploader {
   }
   }
 
 
   void removeFromQueueWhere(final bool Function(File) fn, final Error reason) {
   void removeFromQueueWhere(final bool Function(File) fn, final Error reason) {
-    List<String> uploadsToBeRemoved = [];
+    final List<String> uploadsToBeRemoved = [];
     _queue.entries
     _queue.entries
         .where((entry) => entry.value.status == UploadStatus.notStarted)
         .where((entry) => entry.value.status == UploadStatus.notStarted)
         .forEach((pendingUpload) {
         .forEach((pendingUpload) {
@@ -254,7 +254,7 @@ class FileUploader {
     bool forcedUpload,
     bool forcedUpload,
   ) async {
   ) async {
     final connectivityResult = await (Connectivity().checkConnectivity());
     final connectivityResult = await (Connectivity().checkConnectivity());
-    var canUploadUnderCurrentNetworkConditions =
+    final canUploadUnderCurrentNetworkConditions =
         (connectivityResult == ConnectivityResult.wifi ||
         (connectivityResult == ConnectivityResult.wifi ||
             Configuration.instance.shouldBackupOverMobileData());
             Configuration.instance.shouldBackupOverMobileData());
     if (!canUploadUnderCurrentNetworkConditions && !forcedUpload) {
     if (!canUploadUnderCurrentNetworkConditions && !forcedUpload) {
@@ -311,7 +311,7 @@ class FileUploader {
       }
       }
 
 
       Uint8List key;
       Uint8List key;
-      bool isUpdatedFile =
+      final bool isUpdatedFile =
           file.uploadedFileID != null && file.updationTime == -1;
           file.uploadedFileID != null && file.updationTime == -1;
       if (isUpdatedFile) {
       if (isUpdatedFile) {
         _logger.info("File was updated " + file.toString());
         _logger.info("File was updated " + file.toString());
@@ -342,7 +342,7 @@ class FileUploader {
         encryptedFilePath,
         encryptedFilePath,
         key: key,
         key: key,
       );
       );
-      var thumbnailData = mediaUploadData.thumbnail;
+      final thumbnailData = mediaUploadData.thumbnail;
 
 
       final encryptedThumbnailData =
       final encryptedThumbnailData =
           await CryptoUtil.encryptChaCha(thumbnailData, fileAttributes.key);
           await CryptoUtil.encryptChaCha(thumbnailData, fileAttributes.key);
@@ -354,11 +354,11 @@ class FileUploader {
           .writeAsBytes(encryptedThumbnailData.encryptedData);
           .writeAsBytes(encryptedThumbnailData.encryptedData);
 
 
       final thumbnailUploadURL = await _getUploadURL();
       final thumbnailUploadURL = await _getUploadURL();
-      String thumbnailObjectKey =
+      final String thumbnailObjectKey =
           await _putFile(thumbnailUploadURL, encryptedThumbnailFile);
           await _putFile(thumbnailUploadURL, encryptedThumbnailFile);
 
 
       final fileUploadURL = await _getUploadURL();
       final fileUploadURL = await _getUploadURL();
-      String fileObjectKey = await _putFile(fileUploadURL, encryptedFile);
+      final String fileObjectKey = await _putFile(fileUploadURL, encryptedFile);
 
 
       final metadata = await file.getMetadataForUpload(mediaUploadData);
       final metadata = await file.getMetadataForUpload(mediaUploadData);
       final encryptedMetadataData = await CryptoUtil.encryptChaCha(
       final encryptedMetadataData = await CryptoUtil.encryptChaCha(
@@ -474,11 +474,11 @@ class FileUploader {
       _logger.warning('file is already uploaded, skipping mapping logic');
       _logger.warning('file is already uploaded, skipping mapping logic');
       return false;
       return false;
     }
     }
-    List<String> hash = [mediaUploadData.fileHash];
+    final List<String> hash = [mediaUploadData.fileHash];
     if (fileToUpload.fileType == FileType.livePhoto) {
     if (fileToUpload.fileType == FileType.livePhoto) {
       hash.add(mediaUploadData.zipHash);
       hash.add(mediaUploadData.zipHash);
     }
     }
-    List<File> existingFiles =
+    final List<File> existingFiles =
         await FilesDB.instance.getUploadedFilesWithHashes(
         await FilesDB.instance.getUploadedFilesWithHashes(
       hash,
       hash,
       fileToUpload.fileType,
       fileToUpload.fileType,
@@ -490,7 +490,7 @@ class FileUploader {
       debugPrint("Found some matches");
       debugPrint("Found some matches");
     }
     }
     // case a
     // case a
-    File sameLocalSameCollection = existingFiles.firstWhere(
+    final File sameLocalSameCollection = existingFiles.firstWhere(
       (element) =>
       (element) =>
           element.uploadedFileID != -1 &&
           element.uploadedFileID != -1 &&
           element.collectionID == toCollectionID &&
           element.collectionID == toCollectionID &&
@@ -508,7 +508,7 @@ class FileUploader {
     }
     }
 
 
     // case b
     // case b
-    File fileMissingLocalButSameCollection = existingFiles.firstWhere(
+    final File fileMissingLocalButSameCollection = existingFiles.firstWhere(
       (element) =>
       (element) =>
           element.uploadedFileID != -1 &&
           element.uploadedFileID != -1 &&
           element.collectionID == toCollectionID &&
           element.collectionID == toCollectionID &&
@@ -529,7 +529,7 @@ class FileUploader {
     }
     }
 
 
     // case c and d
     // case c and d
-    File fileExistsButDifferentCollection = existingFiles.firstWhere(
+    final File fileExistsButDifferentCollection = existingFiles.firstWhere(
       (element) =>
       (element) =>
           element.uploadedFileID != -1 &&
           element.uploadedFileID != -1 &&
           element.collectionID != toCollectionID,
           element.collectionID != toCollectionID,
@@ -575,7 +575,7 @@ class FileUploader {
   }
   }
 
 
   Future _onInvalidFileError(File file, InvalidFileError e) async {
   Future _onInvalidFileError(File file, InvalidFileError e) async {
-    String ext = file.title == null ? "no title" : extension(file.title);
+    final String ext = file.title == null ? "no title" : extension(file.title);
     _logger.severe(
     _logger.severe(
       "Invalid file: (ext: $ext) encountered: " + file.toString(),
       "Invalid file: (ext: $ext) encountered: " + file.toString(),
       e,
       e,

+ 4 - 4
lib/utils/file_uploader_util.dart

@@ -92,7 +92,7 @@ Future<MediaUploadData> _getMediaUploadDataFromAssetFile(ente.File file) async {
   if (file.fileType == FileType.livePhoto && io.Platform.isIOS) {
   if (file.fileType == FileType.livePhoto && io.Platform.isIOS) {
     final io.File videoUrl = await Motionphoto.getLivePhotoFile(file.localID);
     final io.File videoUrl = await Motionphoto.getLivePhotoFile(file.localID);
     if (videoUrl == null || !videoUrl.existsSync()) {
     if (videoUrl == null || !videoUrl.existsSync()) {
-      String errMsg =
+      final String errMsg =
           "missing livePhoto url for  ${file.toString()} with subType ${file.fileSubType}";
           "missing livePhoto url for  ${file.toString()} with subType ${file.fileSubType}";
       _logger.severe(errMsg);
       _logger.severe(errMsg);
       throw InvalidFileUploadState(errMsg);
       throw InvalidFileUploadState(errMsg);
@@ -102,7 +102,7 @@ Future<MediaUploadData> _getMediaUploadDataFromAssetFile(ente.File file) async {
     // .elp -> ente live photo
     // .elp -> ente live photo
     final livePhotoPath = tempPath + file.generatedID.toString() + ".elp";
     final livePhotoPath = tempPath + file.generatedID.toString() + ".elp";
     _logger.fine("Uploading zipped live photo from " + livePhotoPath);
     _logger.fine("Uploading zipped live photo from " + livePhotoPath);
-    var encoder = ZipFileEncoder();
+    final encoder = ZipFileEncoder();
     encoder.create(livePhotoPath);
     encoder.create(livePhotoPath);
     encoder.addFile(videoUrl, "video" + extension(videoUrl.path));
     encoder.addFile(videoUrl, "video" + extension(videoUrl.path));
     encoder.addFile(sourceFile, "image" + extension(sourceFile.path));
     encoder.addFile(sourceFile, "image" + extension(sourceFile.path));
@@ -161,8 +161,8 @@ Future<void> _decorateEnteFileData(ente.File file, AssetEntity asset) async {
 Future<MediaUploadData> _getMediaUploadDataFromAppCache(ente.File file) async {
 Future<MediaUploadData> _getMediaUploadDataFromAppCache(ente.File file) async {
   io.File sourceFile;
   io.File sourceFile;
   Uint8List thumbnailData;
   Uint8List thumbnailData;
-  bool isDeleted = false;
-  var localPath = getSharedMediaFilePath(file);
+  const bool isDeleted = false;
+  final localPath = getSharedMediaFilePath(file);
   sourceFile = io.File(localPath);
   sourceFile = io.File(localPath);
   if (!sourceFile.existsSync()) {
   if (!sourceFile.existsSync()) {
     _logger.warning("File doesn't exist in app sandbox");
     _logger.warning("File doesn't exist in app sandbox");

+ 10 - 10
lib/utils/file_util.dart

@@ -40,7 +40,7 @@ Future<io.File> getFile(
   if (file.isRemoteFile()) {
   if (file.isRemoteFile()) {
     return getFileFromServer(file, liveVideo: liveVideo);
     return getFileFromServer(file, liveVideo: liveVideo);
   } else {
   } else {
-    String key = file.tag() + liveVideo.toString() + isOrigin.toString();
+    final String key = file.tag() + liveVideo.toString() + isOrigin.toString();
     final cachedFile = FileLruCache.get(key);
     final cachedFile = FileLruCache.get(key);
     if (cachedFile == null) {
     if (cachedFile == null) {
       final diskFile = await _getLocalDiskFile(
       final diskFile = await _getLocalDiskFile(
@@ -69,7 +69,7 @@ Future<io.File> _getLocalDiskFile(
   bool isOrigin = false,
   bool isOrigin = false,
 }) async {
 }) async {
   if (file.isSharedMediaToAppSandbox()) {
   if (file.isSharedMediaToAppSandbox()) {
-    var localFile = io.File(getSharedMediaFilePath(file));
+    final localFile = io.File(getSharedMediaFilePath(file));
     return localFile.exists().then((exist) {
     return localFile.exists().then((exist) {
       return exist ? localFile : null;
       return exist ? localFile : null;
     });
     });
@@ -194,17 +194,17 @@ Future<_LivePhoto> _downloadLivePhoto(
     }
     }
     _logger.fine("Decoded zipped live photo from " + decryptedFile.path);
     _logger.fine("Decoded zipped live photo from " + decryptedFile.path);
     io.File imageFileCache, videoFileCache;
     io.File imageFileCache, videoFileCache;
-    List<int> bytes = await decryptedFile.readAsBytes();
-    Archive archive = ZipDecoder().decodeBytes(bytes);
+    final List<int> bytes = await decryptedFile.readAsBytes();
+    final Archive archive = ZipDecoder().decodeBytes(bytes);
     final tempPath = Configuration.instance.getTempDirectory();
     final tempPath = Configuration.instance.getTempDirectory();
     // Extract the contents of Zip compressed archive to disk
     // Extract the contents of Zip compressed archive to disk
     for (ArchiveFile archiveFile in archive) {
     for (ArchiveFile archiveFile in archive) {
       if (archiveFile.isFile) {
       if (archiveFile.isFile) {
-        String filename = archiveFile.name;
-        String fileExtension = getExtension(archiveFile.name);
-        String decodePath =
+        final String filename = archiveFile.name;
+        final String fileExtension = getExtension(archiveFile.name);
+        final String decodePath =
             tempPath + file.uploadedFileID.toString() + filename;
             tempPath + file.uploadedFileID.toString() + filename;
-        List<int> data = archiveFile.content;
+        final List<int> data = archiveFile.content;
         if (filename.startsWith("image")) {
         if (filename.startsWith("image")) {
           final imageFile = io.File(decodePath);
           final imageFile = io.File(decodePath);
           await imageFile.create(recursive: true);
           await imageFile.create(recursive: true);
@@ -259,8 +259,8 @@ Future<io.File> _downloadAndCache(
     if (decryptedFile == null) {
     if (decryptedFile == null) {
       return null;
       return null;
     }
     }
-    var decryptedFilePath = decryptedFile.path;
-    String fileExtension = getExtension(file.title);
+    final decryptedFilePath = decryptedFile.path;
+    final String fileExtension = getExtension(file.title);
     var outputFile = decryptedFile;
     var outputFile = decryptedFile;
     if ((fileExtension == "unknown" && file.fileType == FileType.image) ||
     if ((fileExtension == "unknown" && file.fileType == FileType.image) ||
         (io.Platform.isAndroid && fileExtension == "heic")) {
         (io.Platform.isAndroid && fileExtension == "heic")) {

+ 4 - 4
lib/utils/hex.dart

@@ -27,7 +27,7 @@ class HexEncoder extends Converter<List<int>, String> {
 
 
   @override
   @override
   String convert(List<int> bytes) {
   String convert(List<int> bytes) {
-    StringBuffer buffer = StringBuffer();
+    final StringBuffer buffer = StringBuffer();
     for (int part in bytes) {
     for (int part in bytes) {
       if (part & 0xff != part) {
       if (part & 0xff != part) {
         throw const FormatException("Non-byte integer detected");
         throw const FormatException("Non-byte integer detected");
@@ -53,10 +53,10 @@ class HexDecoder extends Converter<String, List<int>> {
     if (str.length % 2 != 0) {
     if (str.length % 2 != 0) {
       str = "0" + str;
       str = "0" + str;
     }
     }
-    Uint8List result = Uint8List(str.length ~/ 2);
+    final Uint8List result = Uint8List(str.length ~/ 2);
     for (int i = 0; i < result.length; i++) {
     for (int i = 0; i < result.length; i++) {
-      int firstDigit = _alphabet.indexOf(str[i * 2]);
-      int secondDigit = _alphabet.indexOf(str[i * 2 + 1]);
+      final int firstDigit = _alphabet.indexOf(str[i * 2]);
+      final int secondDigit = _alphabet.indexOf(str[i * 2 + 1]);
       if (firstDigit == -1 || secondDigit == -1) {
       if (firstDigit == -1 || secondDigit == -1) {
         throw FormatException("Non-hex character detected in $hex");
         throw FormatException("Non-hex character detected in $hex");
       }
       }

+ 2 - 2
lib/utils/magic_util.dart

@@ -52,7 +52,7 @@ Future<void> changeCollectionVisibility(
   );
   );
   await dialog.show();
   await dialog.show();
   try {
   try {
-    Map<String, dynamic> update = {kMagicKeyVisibility: newVisibility};
+    final Map<String, dynamic> update = {kMagicKeyVisibility: newVisibility};
     await CollectionsService.instance.updateMagicMetadata(collection, update);
     await CollectionsService.instance.updateMagicMetadata(collection, update);
     // Force reload home gallery to pull in the now unarchived files
     // Force reload home gallery to pull in the now unarchived files
     Bus.instance.fire(ForceReloadHomeGalleryEvent());
     Bus.instance.fire(ForceReloadHomeGalleryEvent());
@@ -135,7 +135,7 @@ Future<void> _updatePublicMetadata(
   final dialog = createProgressDialog(context, 'please wait...');
   final dialog = createProgressDialog(context, 'please wait...');
   await dialog.show();
   await dialog.show();
   try {
   try {
-    Map<String, dynamic> update = {key: value};
+    final Map<String, dynamic> update = {key: value};
     await FileMagicService.instance.updatePublicMagicMetadata(files, update);
     await FileMagicService.instance.updatePublicMagicMetadata(files, update);
     showShortToast(context, 'done');
     showShortToast(context, 'done');
     await dialog.hide();
     await dialog.hide();

+ 4 - 4
lib/utils/share_util.dart

@@ -44,12 +44,12 @@ Future<void> share(
 
 
 Rect shareButtonRect(BuildContext context, GlobalKey shareButtonKey) {
 Rect shareButtonRect(BuildContext context, GlobalKey shareButtonKey) {
   Size size = MediaQuery.of(context).size;
   Size size = MediaQuery.of(context).size;
-  RenderBox renderBox = shareButtonKey?.currentContext?.findRenderObject();
+  final RenderBox renderBox = shareButtonKey?.currentContext?.findRenderObject();
   if (renderBox == null) {
   if (renderBox == null) {
     return Rect.fromLTWH(0, 0, size.width, size.height / 2);
     return Rect.fromLTWH(0, 0, size.width, size.height / 2);
   }
   }
   size = renderBox.size;
   size = renderBox.size;
-  Offset position = renderBox.localToGlobal(Offset.zero);
+  final Offset position = renderBox.localToGlobal(Offset.zero);
   return Rect.fromCenter(
   return Rect.fromCenter(
     center: position + Offset(size.width / 2, size.height / 2),
     center: position + Offset(size.width / 2, size.height / 2),
     width: size.width,
     width: size.width,
@@ -65,7 +65,7 @@ Future<List<File>> convertIncomingSharedMediaToFile(
   List<SharedMediaFile> sharedMedia,
   List<SharedMediaFile> sharedMedia,
   int collectionID,
   int collectionID,
 ) async {
 ) async {
-  List<File> localFiles = [];
+  final List<File> localFiles = [];
   for (var media in sharedMedia) {
   for (var media in sharedMedia) {
     if (!(media.type == SharedMediaType.IMAGE ||
     if (!(media.type == SharedMediaType.IMAGE ||
         media.type == SharedMediaType.VIDEO)) {
         media.type == SharedMediaType.VIDEO)) {
@@ -74,7 +74,7 @@ Future<List<File>> convertIncomingSharedMediaToFile(
       );
       );
       continue;
       continue;
     }
     }
-    var enteFile = File();
+    final enteFile = File();
     // fileName: img_x.jpg
     // fileName: img_x.jpg
     enteFile.title = basename(media.path);
     enteFile.title = basename(media.path);
     var ioFile = dartio.File(media.path);
     var ioFile = dartio.File(media.path);

+ 1 - 1
lib/utils/trash_diff_fetcher.dart

@@ -62,7 +62,7 @@ class TrashDiffFetcher {
             fileDecryptionKey,
             fileDecryptionKey,
             Sodium.base642bin(trash.metadataDecryptionHeader),
             Sodium.base642bin(trash.metadataDecryptionHeader),
           );
           );
-          Map<String, dynamic> metadata =
+          final Map<String, dynamic> metadata =
               jsonDecode(utf8.decode(encodedMetadata));
               jsonDecode(utf8.decode(encodedMetadata));
           trash.applyMetadata(metadata);
           trash.applyMetadata(metadata);
           if (item["file"]['magicMetadata'] != null) {
           if (item["file"]['magicMetadata'] != null) {

+ 50 - 0
lib/utils/validator_util.dart

@@ -0,0 +1,50 @@
+import 'dart:convert';
+import 'dart:typed_data';
+
+import 'package:logging/logging.dart';
+import 'package:photos/models/key_attributes.dart';
+
+Logger _logger = Logger("Validator");
+
+void validatePreVerificationStateCheck(
+  KeyAttributes keyAttr,
+  String password,
+  String encryptedToken,
+) {
+  nullOrEmptyArgCheck(encryptedToken, "encryptedToken");
+  nullOrEmptyArgCheck(password, "userPassword");
+  if (keyAttr == null) {
+    throw ArgumentError("key Attributes can not be null");
+  }
+  nullOrEmptyArgCheck(keyAttr.kekSalt, "keySalt");
+  nullOrEmptyArgCheck(keyAttr.encryptedKey, "encryptedKey");
+  nullOrEmptyArgCheck(keyAttr.keyDecryptionNonce, "keyDecryptionNonce");
+  nullOrEmptyArgCheck(keyAttr.encryptedSecretKey, "encryptedSecretKey");
+  nullOrEmptyArgCheck(
+    keyAttr.secretKeyDecryptionNonce,
+    "secretKeyDecryptionNonce",
+  );
+  nullOrEmptyArgCheck(keyAttr.publicKey, "publicKey");
+  if ((keyAttr.memLimit ?? 0) <= 0 || (keyAttr.opsLimit ?? 0) <= 0) {
+    throw ArgumentError("Key mem/OpsLimit can not be null or <0");
+  }
+  // check password encoding issues
+  try {
+    final Uint8List passwordL = utf8.encode(password);
+    try {
+      utf8.decode(passwordL);
+    } catch (e) {
+      _logger.severe("CRITICAL: password decode failed", e);
+      rethrow;
+    }
+  } catch (e) {
+    _logger.severe('CRITICAL: password encode failed');
+    rethrow;
+  }
+}
+
+void nullOrEmptyArgCheck(String value, String name) {
+  if (value == null || value.isEmpty) {
+    throw ArgumentError("Critical: $name is nullOrEmpty");
+  }
+}

+ 1 - 1
pubspec.yaml

@@ -11,7 +11,7 @@ description: ente photos application
 # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
 # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
 # Read more about iOS versioning at
 # Read more about iOS versioning at
 # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
 # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
-version: 0.6.25+355
+version: 0.6.29+359
 
 
 environment:
 environment:
   sdk: ">=2.10.0 <3.0.0"
   sdk: ">=2.10.0 <3.0.0"