Kaynağa Gözat

resolved merge conflicts

ashilkn 3 yıl önce
ebeveyn
işleme
47a6a4b19a
100 değiştirilmiş dosya ile 1336 ekleme ve 1734 silme
  1. 16 4
      analysis_options.yaml
  2. 2 2
      lib/app.dart
  3. 7 4
      lib/core/configuration.dart
  4. 28 4
      lib/core/error-reporting/super_logging.dart
  5. 2 1
      lib/core/error-reporting/tunneled_transport.dart
  6. 1 0
      lib/core/network.dart
  7. 22 22
      lib/db/collections_db.dart
  8. 4 4
      lib/db/file_migration_db.dart
  9. 33 33
      lib/db/files_db.dart
  10. 7 7
      lib/db/ignored_files_db.dart
  11. 5 5
      lib/db/memories_db.dart
  12. 5 5
      lib/db/public_keys_db.dart
  13. 22 22
      lib/db/trash_db.dart
  14. 74 81
      lib/ente_theme_data.dart
  15. 6 6
      lib/events/sync_status_update_event.dart
  16. 4 4
      lib/events/tab_changed_event.dart
  17. 5 8
      lib/main.dart
  18. 4 4
      lib/models/gallery_type.dart
  19. 2 2
      lib/services/collections_service.dart
  20. 0 3
      lib/services/favorites_service.dart
  21. 1 1
      lib/services/file_migration_service.dart
  22. 3 4
      lib/services/local_sync_service.dart
  23. 11 8
      lib/services/memories_service.dart
  24. 1 1
      lib/services/notification_service.dart
  25. 4 4
      lib/services/remote_sync_service.dart
  26. 5 5
      lib/services/sync_service.dart
  27. 16 16
      lib/services/user_service.dart
  28. 5 5
      lib/ui/account/change_email_dialog.dart
  29. 41 32
      lib/ui/account/email_entry_page.dart
  30. 20 18
      lib/ui/account/login_page.dart
  31. 8 8
      lib/ui/account/ott_verification_page.dart
  32. 15 15
      lib/ui/account/password_entry_page.dart
  33. 25 31
      lib/ui/account/password_reentry_page.dart
  34. 18 24
      lib/ui/account/recovery_key_page.dart
  35. 10 10
      lib/ui/account/recovery_page.dart
  36. 14 15
      lib/ui/account/sessions_page.dart
  37. 12 12
      lib/ui/account/two_factor_authentication_page.dart
  38. 9 9
      lib/ui/account/two_factor_recovery_page.dart
  39. 24 24
      lib/ui/account/two_factor_setup_page.dart
  40. 22 22
      lib/ui/backup_folder_selection_page.dart
  41. 0 36
      lib/ui/circular_network_image_widget.dart
  42. 42 50
      lib/ui/collections_gallery_widget.dart
  43. 1 3
      lib/ui/common/bottom_shadow.dart
  44. 1 1
      lib/ui/common/dialogs.dart
  45. 10 10
      lib/ui/common/dynamic_fab.dart
  46. 0 30
      lib/ui/common/gradientButton.dart
  47. 80 0
      lib/ui/common/gradient_button.dart
  48. 1 1
      lib/ui/common/linear_progress_dialog.dart
  49. 15 0
      lib/ui/common/loading_widget.dart
  50. 0 32
      lib/ui/common/onlyOuterShadow.dart
  51. 12 14
      lib/ui/common/progress_dialog.dart
  52. 5 5
      lib/ui/common/rename_dialog.dart
  53. 6 10
      lib/ui/common/web_page.dart
  54. 0 90
      lib/ui/common_elements.dart
  55. 20 39
      lib/ui/create_collection_page.dart
  56. 0 232
      lib/ui/expansion_card.dart
  57. 3 3
      lib/ui/extents_page_view.dart
  58. 8 7
      lib/ui/grant_permissions_widget.dart
  59. 19 19
      lib/ui/header_error_widget.dart
  60. 53 57
      lib/ui/home_widget.dart
  61. 7 7
      lib/ui/huge_listview/draggable_scrollbar.dart
  62. 1 1
      lib/ui/huge_listview/huge_listview.dart
  63. 12 11
      lib/ui/huge_listview/lazy_loading_gallery.dart
  64. 4 4
      lib/ui/huge_listview/place_holder_widget.dart
  65. 15 15
      lib/ui/huge_listview/scroll_bar_thumb.dart
  66. 32 39
      lib/ui/landing_page_widget.dart
  67. 8 9
      lib/ui/loading_photos_widget.dart
  68. 0 9
      lib/ui/loading_widget.dart
  69. 17 17
      lib/ui/memories_widget.dart
  70. 6 13
      lib/ui/nav_bar.dart
  71. 7 7
      lib/ui/payment/billing_questions_widget.dart
  72. 17 16
      lib/ui/payment/child_subscription_widget.dart
  73. 7 8
      lib/ui/payment/payment_web_page.dart
  74. 2 2
      lib/ui/payment/skip_subscription_widget.dart
  75. 17 18
      lib/ui/payment/stripe_subscription_page.dart
  76. 5 3
      lib/ui/payment/subscription_common_widgets.dart
  77. 9 11
      lib/ui/payment/subscription_page.dart
  78. 5 5
      lib/ui/payment/subscription_plan_widget.dart
  79. 17 14
      lib/ui/settings/account_section_widget.dart
  80. 17 17
      lib/ui/settings/app_update_dialog.dart
  81. 1 2
      lib/ui/settings/app_version_widget.dart
  82. 13 13
      lib/ui/settings/backup_section_widget.dart
  83. 1 1
      lib/ui/settings/common_settings.dart
  84. 13 12
      lib/ui/settings/danger_section_widget.dart
  85. 25 15
      lib/ui/settings/debug_section_widget.dart
  86. 39 27
      lib/ui/settings/details_section_widget.dart
  87. 18 12
      lib/ui/settings/info_section_widget.dart
  88. 16 15
      lib/ui/settings/security_section_widget.dart
  89. 2 2
      lib/ui/settings/settings_section_title.dart
  90. 8 5
      lib/ui/settings/social_section_widget.dart
  91. 9 5
      lib/ui/settings/support_section_widget.dart
  92. 2 2
      lib/ui/settings/theme_switch_widget.dart
  93. 0 25
      lib/ui/settings_button.dart
  94. 24 23
      lib/ui/settings_page.dart
  95. 43 76
      lib/ui/shared_collections_gallery.dart
  96. 54 54
      lib/ui/sharing/manage_links_widget.dart
  97. 37 61
      lib/ui/sharing/share_collection_widget.dart
  98. 26 26
      lib/ui/status_bar_widget.dart
  99. 4 1
      lib/ui/tools/app_lock.dart
  100. 7 7
      lib/ui/tools/debug/log_file_viewer.dart

+ 16 - 4
analysis_options.yaml

@@ -2,7 +2,7 @@
 # or https://pub.dev/packages/lint (Effective dart)
 # use "flutter analyze ." or "dart  analyze ." for running lint checks
 
-include: package:lints/recommended.yaml
+include: package:flutter_lints/flutter.yaml
 linter:
   rules:
     # Ref https://github.com/flutter/packages/blob/master/packages/flutter_lints/lib/flutter.yaml
@@ -18,6 +18,7 @@ linter:
     - sized_box_for_whitespace
     - use_full_hex_values_for_flutter_colors
     - use_key_in_widget_constructors
+    - cancel_subscriptions
 
     - avoid_empty_else
     - exhaustive_cases
@@ -35,15 +36,26 @@ analyzer:
     exhaustive_cases: error
     curly_braces_in_flow_control_structures: error
     directives_ordering: error
+    require_trailing_commas: warning
     always_use_package_imports: error
     prefer_final_fields: error
     unused_import: error
+    camel_case_types: error
     prefer_is_empty: warning
     use_rethrow_when_possible: info
+    unused_field: warning
+    use_key_in_widget_constructors: warning
+    sort_child_properties_last: warning
+    library_private_types_in_public_api: warning
+    constant_identifier_names: warning
+    prefer_const_constructors: warning
+    prefer_const_declarations: warning
+    prefer_const_constructors_in_immutables: warning
+    unnecessary_const: error
+    cancel_subscriptions: error
 
-    prefer_const_constructors: ignore # too many warnings
-    prefer_const_declarations: ignore # too many warnings
-    prefer_const_constructors_in_immutables: ignore # too many warnings
+    use_build_context_synchronously: ignore # experimental lint, requires many changes
+    prefer_interpolation_to_compose_strings: ignore # later too many warnings
     prefer_double_quotes: ignore # too many warnings
     avoid_renaming_method_parameters: ignore # incorrect warnings for `equals` overrides
 

+ 2 - 2
lib/app.dart

@@ -20,14 +20,14 @@ class EnteApp extends StatefulWidget {
   final Future<void> Function(String) runBackgroundTask;
   final Future<void> Function(String) killBackgroundTask;
 
-  EnteApp(
+  const EnteApp(
     this.runBackgroundTask,
     this.killBackgroundTask, {
     Key key,
   }) : super(key: key);
 
   @override
-  _EnteAppState createState() => _EnteAppState();
+  State<EnteApp> createState() => _EnteAppState();
 }
 
 class _EnteAppState extends State<EnteApp> with WidgetsBindingObserver {

+ 7 - 4
lib/core/configuration.dart

@@ -64,7 +64,7 @@ class Configuration {
       "has_selected_all_folders_for_backup";
   static const anonymousUserIDKey = "anonymous_user_id";
 
-  final kTempFolderDeletionTimeBuffer = Duration(days: 1).inMicroseconds;
+  final kTempFolderDeletionTimeBuffer = const Duration(days: 1).inMicroseconds;
 
   static final _logger = Logger("Configuration");
 
@@ -80,11 +80,11 @@ class Configuration {
   String _volatilePassword;
 
   final _secureStorageOptionsIOS =
-      IOSOptions(accessibility: IOSAccessibility.first_unlock);
+      const IOSOptions(accessibility: IOSAccessibility.first_unlock);
 
   Future<void> init() async {
     _preferences = await SharedPreferences.getInstance();
-    _secureStorage = FlutterSecureStorage();
+    _secureStorage = const FlutterSecureStorage();
     _documentsDirectory = (await getApplicationDocumentsDirectory()).path;
     _tempDirectory = _documentsDirectory + "/temp/";
     final tempDirectory = io.Directory(_tempDirectory);
@@ -128,7 +128,9 @@ class Configuration {
     if (SyncService.instance.isSyncInProgress()) {
       SyncService.instance.stopSync();
       try {
-        await SyncService.instance.existingSync().timeout(Duration(seconds: 5));
+        await SyncService.instance
+            .existingSync()
+            .timeout(const Duration(seconds: 5));
       } catch (e) {
         // ignore
       }
@@ -590,6 +592,7 @@ class Configuration {
 
   Future<String> _getOrCreateAnonymousUserID() async {
     if (!_preferences.containsKey(anonymousUserIDKey)) {
+      //ignore: prefer_const_constructors
       await _preferences.setString(anonymousUserIDKey, Uuid().v4());
     }
     return _preferences.getString(anonymousUserIDKey);

+ 28 - 4
lib/core/error-reporting/super_logging.dart

@@ -149,9 +149,14 @@ class SuperLogging {
     WidgetsFlutterBinding.ensureInitialized();
 
     appVersion ??= await getAppVersion();
+    final isFDroidClient = await isFDroidBuild();
+    if (isFDroidClient) {
+      config.sentryDsn = null;
+      config.tunnel = null;
+    }
 
     final enable = config.enableInDebugMode || kReleaseMode;
-    sentryIsEnabled = enable && config.sentryDsn != null;
+    sentryIsEnabled = enable && config.sentryDsn != null && !isFDroidClient;
     fileIsEnabled = enable && config.logDirPath != null;
 
     if (fileIsEnabled) {
@@ -164,6 +169,14 @@ class SuperLogging {
     Logger.root.level = Level.ALL;
     Logger.root.onRecord.listen(onLogRecord);
 
+    if (isFDroidClient) {
+      assert(
+        sentryIsEnabled == false,
+        "sentry dsn should be disabled for "
+        "f-droid config  ${config.sentryDsn} & ${config.tunnel}",
+      );
+    }
+
     if (!enable) {
       $.info("detected debug mode; sentry & file logging disabled.");
     }
@@ -193,9 +206,11 @@ class SuperLogging {
     }
   }
 
-  static void setUserID(String userID) {
-    Sentry.configureScope((scope) => scope.user = SentryUser(id: userID));
-    $.info("setting sentry user ID to: $userID");
+  static void setUserID(String userID) async {
+    if (config.sentryDsn != null) {
+      Sentry.configureScope((scope) => scope.user = SentryUser(id: userID));
+      $.info("setting sentry user ID to: $userID");
+    }
   }
 
   static Future<void> _sendErrorToSentry(Object error, StackTrace stack) async {
@@ -351,4 +366,13 @@ class SuperLogging {
     var pkgInfo = await PackageInfo.fromPlatform();
     return "${pkgInfo.version}+${pkgInfo.buildNumber}";
   }
+
+  // disable sentry on f-droid. We need to make it opt-in preference
+  static Future<bool> isFDroidBuild() async {
+    if (!Platform.isAndroid) {
+      return false;
+    }
+    var pkgName = (await PackageInfo.fromPlatform()).packageName;
+    return pkgName.startsWith("io.ente.photos.fdroid");
+  }
 }

+ 2 - 1
lib/core/error-reporting/tunneled_transport.dart

@@ -1,4 +1,5 @@
 import 'dart:convert';
+
 import 'package:http/http.dart';
 import 'package:sentry/sentry.dart';
 
@@ -47,7 +48,7 @@ class TunneledTransport implements Transport {
           'body = ${response.body}',
         );
       }
-      return SentryId.empty();
+      return const SentryId.empty();
     } else {
       _options.logger(
         SentryLevel.debug,

+ 1 - 0
lib/core/network.dart

@@ -43,6 +43,7 @@ class Network {
 class RequestIdInterceptor extends Interceptor {
   @override
   void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
+    // ignore: prefer_const_constructors
     options.headers.putIfAbsent("x-request-id", () => Uuid().v4().toString());
     return super.onRequest(options, handler);
   }

+ 22 - 22
lib/db/collections_db.dart

@@ -8,30 +8,30 @@ import 'package:sqflite/sqflite.dart';
 import 'package:sqflite_migration/sqflite_migration.dart';
 
 class CollectionsDB {
-  static final _databaseName = "ente.collections.db";
-  static final table = 'collections';
-  static final tempTable = 'temp_collections';
-  static final _sqlBoolTrue = 1;
-  static final _sqlBoolFalse = 0;
+  static const _databaseName = "ente.collections.db";
+  static const table = 'collections';
+  static const tempTable = 'temp_collections';
+  static const _sqlBoolTrue = 1;
+  static const _sqlBoolFalse = 0;
 
-  static final columnID = 'collection_id';
-  static final columnOwner = 'owner';
-  static final columnEncryptedKey = 'encrypted_key';
-  static final columnKeyDecryptionNonce = 'key_decryption_nonce';
-  static final columnName = 'name';
-  static final columnEncryptedName = 'encrypted_name';
-  static final columnNameDecryptionNonce = 'name_decryption_nonce';
-  static final columnType = 'type';
-  static final columnEncryptedPath = 'encrypted_path';
-  static final columnPathDecryptionNonce = 'path_decryption_nonce';
-  static final columnVersion = 'version';
-  static final columnSharees = 'sharees';
-  static final columnPublicURLs = 'public_urls';
+  static const columnID = 'collection_id';
+  static const columnOwner = 'owner';
+  static const columnEncryptedKey = 'encrypted_key';
+  static const columnKeyDecryptionNonce = 'key_decryption_nonce';
+  static const columnName = 'name';
+  static const columnEncryptedName = 'encrypted_name';
+  static const columnNameDecryptionNonce = 'name_decryption_nonce';
+  static const columnType = 'type';
+  static const columnEncryptedPath = 'encrypted_path';
+  static const columnPathDecryptionNonce = 'path_decryption_nonce';
+  static const columnVersion = 'version';
+  static const columnSharees = 'sharees';
+  static const columnPublicURLs = 'public_urls';
   // MMD -> Magic Metadata
-  static final columnMMdEncodedJson = 'mmd_encoded_json';
-  static final columnMMdVersion = 'mmd_ver';
-  static final columnUpdationTime = 'updation_time';
-  static final columnIsDeleted = 'is_deleted';
+  static const columnMMdEncodedJson = 'mmd_encoded_json';
+  static const columnMMdVersion = 'mmd_ver';
+  static const columnUpdationTime = 'updation_time';
+  static const columnIsDeleted = 'is_deleted';
 
   static final intitialScript = [...createTable(table)];
   static final migrationScripts = [

+ 4 - 4
lib/db/file_migration_db.dart

@@ -6,12 +6,12 @@ import 'package:path_provider/path_provider.dart';
 import 'package:sqflite/sqflite.dart';
 
 class FilesMigrationDB {
-  static final _databaseName = "ente.files_migration.db";
-  static final _databaseVersion = 1;
+  static const _databaseName = "ente.files_migration.db";
+  static const _databaseVersion = 1;
   static final Logger _logger = Logger((FilesMigrationDB).toString());
-  static final tableName = 're_upload_tracker';
+  static const tableName = 're_upload_tracker';
 
-  static final columnLocalID = 'local_id';
+  static const columnLocalID = 'local_id';
 
   Future _onCreate(Database db, int version) async {
     await db.execute(

+ 33 - 33
lib/db/files_db.dart

@@ -20,49 +20,49 @@ class FilesDB {
   duplicate entries for un-uploaded files that were created due to a collision
   in background and foreground syncs.
   */
-  static final _databaseName = "ente.files.db";
+  static const _databaseName = "ente.files.db";
 
   static final Logger _logger = Logger("FilesDB");
 
-  static final table = 'files';
-  static final tempTable = 'temp_files';
-
-  static final columnGeneratedID = '_id';
-  static final columnUploadedFileID = 'uploaded_file_id';
-  static final columnOwnerID = 'owner_id';
-  static final columnCollectionID = 'collection_id';
-  static final columnLocalID = 'local_id';
-  static final columnTitle = 'title';
-  static final columnDeviceFolder = 'device_folder';
-  static final columnLatitude = 'latitude';
-  static final columnLongitude = 'longitude';
-  static final columnFileType = 'file_type';
-  static final columnFileSubType = 'file_sub_type';
-  static final columnDuration = 'duration';
-  static final columnExif = 'exif';
-  static final columnHash = 'hash';
-  static final columnMetadataVersion = 'metadata_version';
-  static final columnIsDeleted = 'is_deleted';
-  static final columnCreationTime = 'creation_time';
-  static final columnModificationTime = 'modification_time';
-  static final columnUpdationTime = 'updation_time';
-  static final columnEncryptedKey = 'encrypted_key';
-  static final columnKeyDecryptionNonce = 'key_decryption_nonce';
-  static final columnFileDecryptionHeader = 'file_decryption_header';
-  static final columnThumbnailDecryptionHeader = 'thumbnail_decryption_header';
-  static final columnMetadataDecryptionHeader = 'metadata_decryption_header';
+  static const table = 'files';
+  static const tempTable = 'temp_files';
+
+  static const columnGeneratedID = '_id';
+  static const columnUploadedFileID = 'uploaded_file_id';
+  static const columnOwnerID = 'owner_id';
+  static const columnCollectionID = 'collection_id';
+  static const columnLocalID = 'local_id';
+  static const columnTitle = 'title';
+  static const columnDeviceFolder = 'device_folder';
+  static const columnLatitude = 'latitude';
+  static const columnLongitude = 'longitude';
+  static const columnFileType = 'file_type';
+  static const columnFileSubType = 'file_sub_type';
+  static const columnDuration = 'duration';
+  static const columnExif = 'exif';
+  static const columnHash = 'hash';
+  static const columnMetadataVersion = 'metadata_version';
+  static const columnIsDeleted = 'is_deleted';
+  static const columnCreationTime = 'creation_time';
+  static const columnModificationTime = 'modification_time';
+  static const columnUpdationTime = 'updation_time';
+  static const columnEncryptedKey = 'encrypted_key';
+  static const columnKeyDecryptionNonce = 'key_decryption_nonce';
+  static const columnFileDecryptionHeader = 'file_decryption_header';
+  static const columnThumbnailDecryptionHeader = 'thumbnail_decryption_header';
+  static const columnMetadataDecryptionHeader = 'metadata_decryption_header';
 
   // MMD -> Magic Metadata
-  static final columnMMdEncodedJson = 'mmd_encoded_json';
-  static final columnMMdVersion = 'mmd_ver';
+  static const columnMMdEncodedJson = 'mmd_encoded_json';
+  static const columnMMdVersion = 'mmd_ver';
 
-  static final columnPubMMdEncodedJson = 'pub_mmd_encoded_json';
-  static final columnPubMMdVersion = 'pub_mmd_ver';
+  static const columnPubMMdEncodedJson = 'pub_mmd_encoded_json';
+  static const columnPubMMdVersion = 'pub_mmd_ver';
 
   // part of magic metadata
   // Only parse & store selected fields from JSON in separate columns if
   // we need to write query based on that field
-  static final columnMMdVisibility = 'mmd_visibility';
+  static const columnMMdVisibility = 'mmd_visibility';
 
   static final initializationScript = [...createTable(table)];
   static final migrationScripts = [

+ 7 - 7
lib/db/ignored_files_db.dart

@@ -11,15 +11,15 @@ import 'package:sqflite/sqflite.dart';
 // Common use case:
 // when a user deletes a file just from ente on current or different device.
 class IgnoredFilesDB {
-  static final _databaseName = "ente.ignored_files.db";
-  static final _databaseVersion = 1;
+  static const _databaseName = "ente.ignored_files.db";
+  static const _databaseVersion = 1;
   static final Logger _logger = Logger("IgnoredFilesDB");
-  static final tableName = 'ignored_files';
+  static const tableName = 'ignored_files';
 
-  static final columnLocalID = 'local_id';
-  static final columnTitle = 'title';
-  static final columnDeviceFolder = 'device_folder';
-  static final columnReason = 'reason';
+  static const columnLocalID = 'local_id';
+  static const columnTitle = 'title';
+  static const columnDeviceFolder = 'device_folder';
+  static const columnReason = 'reason';
 
   Future _onCreate(Database db, int version) async {
     await db.execute(

+ 5 - 5
lib/db/memories_db.dart

@@ -7,13 +7,13 @@ import 'package:photos/models/memory.dart';
 import 'package:sqflite/sqflite.dart';
 
 class MemoriesDB {
-  static final _databaseName = "ente.memories.db";
-  static final _databaseVersion = 1;
+  static const _databaseName = "ente.memories.db";
+  static const _databaseVersion = 1;
 
-  static final table = 'memories';
+  static const table = 'memories';
 
-  static final columnFileID = 'file_id';
-  static final columnSeenTime = 'seen_time';
+  static const columnFileID = 'file_id';
+  static const columnSeenTime = 'seen_time';
 
   MemoriesDB._privateConstructor();
   static final MemoriesDB instance = MemoriesDB._privateConstructor();

+ 5 - 5
lib/db/public_keys_db.dart

@@ -7,13 +7,13 @@ import 'package:photos/models/public_key.dart';
 import 'package:sqflite/sqflite.dart';
 
 class PublicKeysDB {
-  static final _databaseName = "ente.public_keys.db";
-  static final _databaseVersion = 1;
+  static const _databaseName = "ente.public_keys.db";
+  static const _databaseVersion = 1;
 
-  static final table = 'public_keys';
+  static const table = 'public_keys';
 
-  static final columnEmail = 'email';
-  static final columnPublicKey = 'public_key';
+  static const columnEmail = 'email';
+  static const columnPublicKey = 'public_key';
 
   PublicKeysDB._privateConstructor();
   static final PublicKeysDB instance = PublicKeysDB._privateConstructor();

+ 22 - 22
lib/db/trash_db.dart

@@ -13,33 +13,33 @@ import 'package:sqflite/sqflite.dart';
 // column or not while showing trashed items. Even if we miss storing any new attributes,
 // during restore, all file attributes will be fetched & stored as required.
 class TrashDB {
-  static final _databaseName = "ente.trash.db";
-  static final _databaseVersion = 1;
+  static const _databaseName = "ente.trash.db";
+  static const _databaseVersion = 1;
   static final Logger _logger = Logger("TrashDB");
-  static final tableName = 'trash';
-
-  static final columnUploadedFileID = 'uploaded_file_id';
-  static final columnCollectionID = 'collection_id';
-  static final columnOwnerID = 'owner_id';
-  static final columnTrashUpdatedAt = 't_updated_at';
-  static final columnTrashDeleteBy = 't_delete_by';
-  static final columnEncryptedKey = 'encrypted_key';
-  static final columnKeyDecryptionNonce = 'key_decryption_nonce';
-  static final columnFileDecryptionHeader = 'file_decryption_header';
-  static final columnThumbnailDecryptionHeader = 'thumbnail_decryption_header';
-  static final columnUpdationTime = 'updation_time';
-
-  static final columnCreationTime = 'creation_time';
-  static final columnLocalID = 'local_id';
+  static const tableName = 'trash';
+
+  static const columnUploadedFileID = 'uploaded_file_id';
+  static const columnCollectionID = 'collection_id';
+  static const columnOwnerID = 'owner_id';
+  static const columnTrashUpdatedAt = 't_updated_at';
+  static const columnTrashDeleteBy = 't_delete_by';
+  static const columnEncryptedKey = 'encrypted_key';
+  static const columnKeyDecryptionNonce = 'key_decryption_nonce';
+  static const columnFileDecryptionHeader = 'file_decryption_header';
+  static const columnThumbnailDecryptionHeader = 'thumbnail_decryption_header';
+  static const columnUpdationTime = 'updation_time';
+
+  static const columnCreationTime = 'creation_time';
+  static const columnLocalID = 'local_id';
 
   // standard file metadata, which isn't editable
-  static final columnFileMetadata = 'file_metadata';
+  static const columnFileMetadata = 'file_metadata';
 
-  static final columnMMdEncodedJson = 'mmd_encoded_json';
-  static final columnMMdVersion = 'mmd_ver';
+  static const columnMMdEncodedJson = 'mmd_encoded_json';
+  static const columnMMdVersion = 'mmd_ver';
 
-  static final columnPubMMdEncodedJson = 'pub_mmd_encoded_json';
-  static final columnPubMMdVersion = 'pub_mmd_ver';
+  static const columnPubMMdEncodedJson = 'pub_mmd_encoded_json';
+  static const columnPubMMdVersion = 'pub_mmd_ver';
 
   Future _onCreate(Database db, int version) async {
     await db.execute(

+ 74 - 81
lib/ente_theme_data.dart

@@ -7,14 +7,15 @@ final lightThemeData = ThemeData(
   hintColor: Colors.grey,
   primaryColor: Colors.deepOrangeAccent,
   primaryColorLight: Colors.black54,
-  iconTheme: IconThemeData(color: Colors.black),
-  primaryIconTheme: IconThemeData(color: Colors.red, opacity: 1.0, size: 50.0),
-  colorScheme: ColorScheme.light(
+  iconTheme: const IconThemeData(color: Colors.black),
+  primaryIconTheme:
+      const IconThemeData(color: Colors.red, opacity: 1.0, size: 50.0),
+  colorScheme: const ColorScheme.light(
     primary: Colors.black,
     secondary: Color.fromARGB(255, 163, 163, 163),
   ),
-  accentColor: Color.fromRGBO(0, 0, 0, 0.6),
-  buttonColor: Color.fromRGBO(45, 194, 98, 1.0),
+  accentColor: const Color.fromRGBO(0, 0, 0, 0.6),
+  buttonColor: const Color.fromRGBO(45, 194, 98, 1.0),
   outlinedButtonTheme: buildOutlinedButtonThemeData(
     bgDisabled: Colors.grey.shade500,
     bgEnabled: Colors.black,
@@ -28,27 +29,27 @@ final lightThemeData = ThemeData(
   toggleableActiveColor: Colors.green[400],
   scaffoldBackgroundColor: Colors.white,
   backgroundColor: Colors.white,
-  appBarTheme: AppBarTheme().copyWith(
+  appBarTheme: const AppBarTheme().copyWith(
     backgroundColor: Colors.white,
     foregroundColor: Colors.black,
-    iconTheme: IconThemeData(color: Colors.black),
+    iconTheme: const IconThemeData(color: Colors.black),
     elevation: 0,
   ),
   //https://api.flutter.dev/flutter/material/TextTheme-class.html
   textTheme: _buildTextTheme(Colors.black),
-  primaryTextTheme: TextTheme().copyWith(
-    bodyText2: TextStyle(color: Colors.yellow),
-    bodyText1: TextStyle(color: Colors.orange),
+  primaryTextTheme: const TextTheme().copyWith(
+    bodyText2: const TextStyle(color: Colors.yellow),
+    bodyText1: const TextStyle(color: Colors.orange),
   ),
-  cardColor: Color.fromRGBO(250, 250, 250, 1.0),
-  dialogTheme: DialogTheme().copyWith(
-    backgroundColor: Color.fromRGBO(250, 250, 250, 1.0), //
-    titleTextStyle: TextStyle(
+  cardColor: const Color.fromRGBO(250, 250, 250, 1.0),
+  dialogTheme: const DialogTheme().copyWith(
+    backgroundColor: const Color.fromRGBO(250, 250, 250, 1.0), //
+    titleTextStyle: const TextStyle(
       color: Colors.black,
       fontSize: 24,
       fontWeight: FontWeight.w600,
     ),
-    contentTextStyle: TextStyle(
+    contentTextStyle: const TextStyle(
       fontFamily: 'Inter-Medium',
       color: Colors.black,
       fontSize: 16,
@@ -56,15 +57,15 @@ final lightThemeData = ThemeData(
     ),
     shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
   ),
-  inputDecorationTheme: InputDecorationTheme().copyWith(
-    focusedBorder: UnderlineInputBorder(
+  inputDecorationTheme: const InputDecorationTheme().copyWith(
+    focusedBorder: const UnderlineInputBorder(
       borderSide: BorderSide(
         color: Color.fromRGBO(45, 194, 98, 1.0),
       ),
     ),
   ),
   checkboxTheme: CheckboxThemeData(
-    side: BorderSide(
+    side: const BorderSide(
       color: Colors.black,
       width: 2,
     ),
@@ -85,14 +86,15 @@ final darkThemeData = ThemeData(
   fontFamily: 'Inter',
   brightness: Brightness.dark,
   primaryColorLight: Colors.white70,
-  iconTheme: IconThemeData(color: Colors.white),
-  primaryIconTheme: IconThemeData(color: Colors.red, opacity: 1.0, size: 50.0),
+  iconTheme: const IconThemeData(color: Colors.white),
+  primaryIconTheme:
+      const IconThemeData(color: Colors.red, opacity: 1.0, size: 50.0),
   hintColor: Colors.grey,
-  colorScheme: ColorScheme.dark(primary: Colors.white),
-  accentColor: Color.fromRGBO(45, 194, 98, 0.2),
-  buttonColor: Color.fromRGBO(45, 194, 98, 1.0),
-  buttonTheme: ButtonThemeData().copyWith(
-    buttonColor: Color.fromRGBO(45, 194, 98, 1.0),
+  colorScheme: const ColorScheme.dark(primary: Colors.white),
+  accentColor: const Color.fromRGBO(45, 194, 98, 0.2),
+  buttonColor: const Color.fromRGBO(45, 194, 98, 1.0),
+  buttonTheme: const ButtonThemeData().copyWith(
+    buttonColor: const Color.fromRGBO(45, 194, 98, 1.0),
   ),
   textTheme: _buildTextTheme(Colors.white),
   toggleableActiveColor: Colors.green[400],
@@ -108,19 +110,19 @@ final darkThemeData = ThemeData(
   ),
   scaffoldBackgroundColor: Colors.black,
   backgroundColor: Colors.black,
-  appBarTheme: AppBarTheme().copyWith(
+  appBarTheme: const AppBarTheme().copyWith(
     color: Colors.black,
     elevation: 0,
   ),
-  cardColor: Color.fromRGBO(10, 15, 15, 1.0),
-  dialogTheme: DialogTheme().copyWith(
-    backgroundColor: Color.fromRGBO(15, 15, 15, 1.0),
-    titleTextStyle: TextStyle(
+  cardColor: const Color.fromRGBO(10, 15, 15, 1.0),
+  dialogTheme: const DialogTheme().copyWith(
+    backgroundColor: const Color.fromRGBO(15, 15, 15, 1.0),
+    titleTextStyle: const TextStyle(
       color: Colors.white,
       fontSize: 24,
       fontWeight: FontWeight.w600,
     ),
-    contentTextStyle: TextStyle(
+    contentTextStyle: const TextStyle(
       fontFamily: 'Inter-Medium',
       color: Colors.white,
       fontSize: 16,
@@ -128,15 +130,15 @@ final darkThemeData = ThemeData(
     ),
     shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
   ),
-  inputDecorationTheme: InputDecorationTheme().copyWith(
-    focusedBorder: UnderlineInputBorder(
+  inputDecorationTheme: const InputDecorationTheme().copyWith(
+    focusedBorder: const UnderlineInputBorder(
       borderSide: BorderSide(
         color: Color.fromRGBO(45, 194, 98, 1.0),
       ),
     ),
   ),
   checkboxTheme: CheckboxThemeData(
-    side: BorderSide(
+    side: const BorderSide(
       color: Colors.grey,
       width: 2,
     ),
@@ -158,7 +160,7 @@ final darkThemeData = ThemeData(
 );
 
 TextTheme _buildTextTheme(Color textColor) {
-  return TextTheme().copyWith(
+  return const TextTheme().copyWith(
     headline4: TextStyle(
       color: textColor,
       fontSize: 32,
@@ -233,12 +235,12 @@ extension CustomColorScheme on ColorScheme {
       brightness == Brightness.light ? Colors.black : Colors.white;
 
   Color get boxSelectColor => brightness == Brightness.light
-      ? Color.fromRGBO(67, 186, 108, 1)
-      : Color.fromRGBO(16, 32, 32, 1);
+      ? const Color.fromRGBO(67, 186, 108, 1)
+      : const Color.fromRGBO(16, 32, 32, 1);
 
   Color get boxUnSelectColor => brightness == Brightness.light
-      ? Color.fromRGBO(240, 240, 240, 1)
-      : Color.fromRGBO(8, 18, 18, 0.4);
+      ? const Color.fromRGBO(240, 240, 240, 1)
+      : const Color.fromRGBO(8, 18, 18, 0.4);
 
   Color get dynamicFABBackgroundColor =>
       brightness == Brightness.light ? Colors.black : Colors.grey[850];
@@ -247,18 +249,18 @@ extension CustomColorScheme on ColorScheme {
 
   // todo: use brightness == Brightness.light for changing color for dark/light theme
   ButtonStyle get optionalActionButtonStyle => buildElevatedButtonThemeData(
-        onPrimary: Color(0xFF777777),
-        primary: Color(0xFFF0F0F0),
+        onPrimary: const Color(0xFF777777),
+        primary: const Color(0xFFF0F0F0),
         elevation: 0,
       ).style;
 
   Color get recoveryKeyBoxColor => brightness == Brightness.light
-      ? Color.fromRGBO(49, 155, 86, 0.2)
-      : Color(0xFF1DB954);
+      ? const Color.fromRGBO(49, 155, 86, 0.2)
+      : const Color(0xFF1DB954);
 
   Color get frostyBlurBackdropFilterColor => brightness == Brightness.light
-      ? Color.fromRGBO(238, 238, 238, 0.5)
-      : Color.fromRGBO(48, 48, 48, 0.5);
+      ? const Color.fromRGBO(238, 238, 238, 0.5)
+      : const Color.fromRGBO(48, 48, 48, 0.5);
 
   Color get iconColor => brightness == Brightness.light
       ? Colors.black.withOpacity(0.75)
@@ -266,57 +268,57 @@ extension CustomColorScheme on ColorScheme {
 
   Color get bgColorForQuestions => brightness == Brightness.light
       ? Colors.white
-      : Color.fromRGBO(10, 15, 15, 1.0);
+      : const Color.fromRGBO(10, 15, 15, 1.0);
 
-  Color get greenText => Color.fromARGB(255, 40, 190, 113);
+  Color get greenText => const Color.fromARGB(255, 40, 190, 113);
 
   Color get cupertinoPickerTopColor => brightness == Brightness.light
-      ? Color.fromARGB(255, 238, 238, 238)
+      ? const Color.fromARGB(255, 238, 238, 238)
       : Colors.white.withOpacity(0.1);
 
   DatePickerTheme get dateTimePickertheme => brightness == Brightness.light
-      ? DatePickerTheme(
+      ? const DatePickerTheme(
           backgroundColor: Colors.white,
           itemStyle: TextStyle(color: Colors.black),
           cancelStyle: TextStyle(color: Colors.black),
         )
-      : DatePickerTheme(
+      : const DatePickerTheme(
           backgroundColor: Colors.black,
           itemStyle: TextStyle(color: Colors.white),
           cancelStyle: TextStyle(color: Colors.white),
         );
 
   Color get stepProgressUnselectedColor => brightness == Brightness.light
-      ? Color.fromRGBO(196, 196, 196, 0.6)
-      : Color.fromRGBO(255, 255, 255, 0.7);
+      ? const Color.fromRGBO(196, 196, 196, 0.6)
+      : const Color.fromRGBO(255, 255, 255, 0.7);
 
   Color get gNavBackgroundColor => brightness == Brightness.light
-      ? Color.fromRGBO(196, 196, 196, 0.6)
-      : Color.fromRGBO(40, 40, 40, 0.6);
+      ? const Color.fromRGBO(196, 196, 196, 0.6)
+      : const Color.fromRGBO(40, 40, 40, 0.6);
 
   Color get gNavBarActiveColor => brightness == Brightness.light
-      ? Color.fromRGBO(255, 255, 255, 0.6)
-      : Color.fromRGBO(255, 255, 255, 0.9);
+      ? const Color.fromRGBO(255, 255, 255, 0.6)
+      : const Color.fromRGBO(255, 255, 255, 0.9);
 
   Color get gNavIconColor => brightness == Brightness.light
-      ? Color.fromRGBO(0, 0, 0, 0.8)
-      : Color.fromRGBO(255, 255, 255, 0.8);
+      ? const Color.fromRGBO(0, 0, 0, 0.8)
+      : const Color.fromRGBO(255, 255, 255, 0.8);
 
   Color get gNavActiveIconColor => brightness == Brightness.light
-      ? Color.fromRGBO(0, 0, 0, 0.8)
-      : Color.fromRGBO(0, 0, 0, 0.8);
+      ? const Color.fromRGBO(0, 0, 0, 0.8)
+      : const Color.fromRGBO(0, 0, 0, 0.8);
 
   Color get galleryThumbBackgroundColor => brightness == Brightness.light
-      ? Color.fromRGBO(240, 240, 240, 1)
-      : Color.fromRGBO(20, 20, 20, 1);
+      ? const Color.fromRGBO(240, 240, 240, 1)
+      : const Color.fromRGBO(20, 20, 20, 1);
 
   Color get galleryThumbDrawColor => brightness == Brightness.light
       ? Colors.black.withOpacity(0.8)
       : Colors.white.withOpacity(0.5);
 
   Color get backupEnabledBgColor => brightness == Brightness.light
-      ? Color.fromRGBO(230, 230, 230, 0.95)
-      : Color.fromRGBO(10, 40, 40, 0.3);
+      ? const Color.fromRGBO(230, 230, 230, 0.95)
+      : const Color.fromRGBO(10, 40, 40, 0.3);
 
   Color get dotsIndicatorActiveColor => brightness == Brightness.light
       ? Colors.black.withOpacity(0.5)
@@ -330,12 +332,12 @@ extension CustomColorScheme on ColorScheme {
       brightness == Brightness.light ? Colors.white : Colors.black;
 
   Color get toastBackgroundColor => brightness == Brightness.light
-      ? Color.fromRGBO(24, 24, 24, 0.95)
-      : Color.fromRGBO(255, 255, 255, 0.95);
+      ? const Color.fromRGBO(24, 24, 24, 0.95)
+      : const Color.fromRGBO(255, 255, 255, 0.95);
 
   Color get subTextColor => brightness == Brightness.light
-      ? Color.fromRGBO(180, 180, 180, 1)
-      : Color.fromRGBO(100, 100, 100, 1);
+      ? const Color.fromRGBO(180, 180, 180, 1)
+      : const Color.fromRGBO(100, 100, 100, 1);
 
   Color get themeSwitchIndicatorColor => brightness == Brightness.light
       ? Colors.black.withOpacity(0.75)
@@ -361,8 +363,8 @@ OutlinedButtonThemeData buildOutlinedButtonThemeData({
         borderRadius: BorderRadius.circular(8),
       ),
       alignment: Alignment.center,
-      padding: EdgeInsets.fromLTRB(50, 16, 50, 16),
-      textStyle: TextStyle(
+      padding: const EdgeInsets.fromLTRB(50, 16, 50, 16),
+      textStyle: const TextStyle(
         fontWeight: FontWeight.w600,
         fontFamily: 'Inter-SemiBold',
         fontSize: 18,
@@ -400,24 +402,15 @@ ElevatedButtonThemeData buildElevatedButtonThemeData({
       onPrimary: onPrimary,
       primary: primary,
       alignment: Alignment.center,
-      textStyle: TextStyle(
+      textStyle: const TextStyle(
         fontWeight: FontWeight.w600,
         fontFamily: 'Inter-SemiBold',
         fontSize: 18,
       ),
-      padding: EdgeInsets.symmetric(vertical: 18),
+      padding: const EdgeInsets.symmetric(vertical: 18),
       shape: const RoundedRectangleBorder(
         borderRadius: BorderRadius.all(Radius.circular(8)),
       ),
     ),
   );
 }
-
-TextStyle gradientButtonTextTheme() {
-  return TextStyle(
-    color: Colors.white,
-    fontWeight: FontWeight.w600,
-    fontFamily: 'Inter-SemiBold',
-    fontSize: 18,
-  );
-}

+ 6 - 6
lib/events/sync_status_update_event.dart

@@ -27,12 +27,12 @@ class SyncStatusUpdate extends Event {
 }
 
 enum SyncStatus {
-  started_first_gallery_import,
-  completed_first_gallery_import,
-  applying_remote_diff,
-  preparing_for_upload,
-  in_progress,
+  startedFirstGalleryImport,
+  completedFirstGalleryImport,
+  applyingRemoteDiff,
+  preparingForUpload,
+  inProgress,
   paused,
-  completed_backup,
+  completedBackup,
   error,
 }

+ 4 - 4
lib/events/tab_changed_event.dart

@@ -16,8 +16,8 @@ class TabChangedEvent extends Event {
 }
 
 enum TabChangedEventSource {
-  tab_bar,
-  page_view,
-  collections_page,
-  back_button,
+  tabBar,
+  pageView,
+  collectionsPage,
+  backButton,
 }

+ 5 - 8
lib/main.dart

@@ -1,7 +1,6 @@
 import 'dart:async';
 import 'dart:io';
 
-import 'package:adaptive_theme/adaptive_theme.dart';
 import 'package:background_fetch/background_fetch.dart';
 import 'package:firebase_messaging/firebase_messaging.dart';
 import 'package:flutter/foundation.dart';
@@ -30,8 +29,8 @@ import 'package:photos/services/sync_service.dart';
 import 'package:photos/services/trash_sync_service.dart';
 import 'package:photos/services/update_service.dart';
 import 'package:photos/services/user_service.dart';
-import 'package:photos/ui/app_lock.dart';
-import 'package:photos/ui/lock_screen.dart';
+import 'package:photos/ui/tools/app_lock.dart';
+import 'package:photos/ui/tools/lock_screen.dart';
 import 'package:photos/utils/crypto_util.dart';
 import 'package:photos/utils/file_uploader.dart';
 import 'package:photos/utils/local_settings.dart';
@@ -40,7 +39,6 @@ import 'package:shared_preferences/shared_preferences.dart';
 final _logger = Logger("main");
 
 bool _isProcessRunning = false;
-AdaptiveThemeMode _savedThemeMode;
 const kLastBGTaskHeartBeatTime = "bg_task_hb_time";
 const kLastFGTaskHeartBeatTime = "fg_task_hb_time";
 const kHeartBeatFrequency = Duration(seconds: 1);
@@ -62,8 +60,8 @@ Future<void> _runInForeground() async {
     _scheduleFGSync('appStart in FG');
     runApp(
       AppLock(
-        builder: (args) => EnteApp(_runBackgroundTask, _killBGTask),
-        lockScreen: LockScreen(),
+        builder: (args) => const EnteApp(_runBackgroundTask, _killBGTask),
+        lockScreen: const LockScreen(),
         enabled: Configuration.instance.shouldShowLockScreen(),
         lightTheme: lightThemeData,
         darkTheme: darkThemeData,
@@ -89,7 +87,7 @@ Future<void> _runBackgroundTask(String taskId) async {
 }
 
 Future<void> _runInBackground(String taskId) async {
-  await Future.delayed(Duration(seconds: 3));
+  await Future.delayed(const Duration(seconds: 3));
   if (await _isRunningInForeground()) {
     _logger.info("FG task running, skipping BG taskID: $taskId");
     BackgroundFetch.finish(taskId);
@@ -120,7 +118,6 @@ Future<void> _init(bool isBackground, {String via = ''}) async {
   _isProcessRunning = true;
   _logger.info("Initializing...  inBG =$isBackground via: $via");
   await _logFGHeartBeatInfo();
-  _savedThemeMode = await AdaptiveTheme.getThemeMode();
   _scheduleHeartBeat(isBackground);
   if (isBackground) {
     AppLifecycleService.instance.onAppInBackground('init via: $via');

+ 4 - 4
lib/models/galleryType.dart → lib/models/gallery_type.dart

@@ -2,9 +2,9 @@ enum GalleryType {
   homepage,
   archive,
   trash,
-  local_folder,
+  localFolder,
   // indicator for gallery view of collections shared with the user
-  shared_collection,
-  owned_collection,
-  search_results
+  sharedCollection,
+  ownedCollection,
+  searchResults
 }

+ 2 - 2
lib/services/collections_service.dart

@@ -29,8 +29,8 @@ import 'package:photos/utils/file_download_util.dart';
 import 'package:shared_preferences/shared_preferences.dart';
 
 class CollectionsService {
-  static final _collectionSyncTimeKeyPrefix = "collection_sync_time_";
-  static final _collectionsSyncTimeKey = "collections_sync_time_x";
+  static const _collectionSyncTimeKeyPrefix = "collection_sync_time_";
+  static const _collectionsSyncTimeKey = "collections_sync_time_x";
 
   static const int kMaximumWriteAttempts = 5;
 

+ 0 - 3
lib/services/favorites_service.dart

@@ -10,19 +10,16 @@ import 'package:photos/models/file.dart';
 import 'package:photos/services/collections_service.dart';
 import 'package:photos/services/remote_sync_service.dart';
 import 'package:photos/utils/crypto_util.dart';
-import 'package:photos/utils/file_uploader.dart';
 
 class FavoritesService {
   Configuration _config;
   CollectionsService _collectionsService;
-  FileUploader _fileUploader;
   FilesDB _filesDB;
   int _cachedFavoritesCollectionID;
 
   FavoritesService._privateConstructor() {
     _config = Configuration.instance;
     _collectionsService = CollectionsService.instance;
-    _fileUploader = FileUploader.instance;
     _filesDB = FilesDB.instance;
   }
   static FavoritesService instance = FavoritesService._privateConstructor();

+ 1 - 1
lib/services/file_migration_service.dart

@@ -68,7 +68,7 @@ class FileMigrationService {
       await _importLocalFilesForMigration();
       final sTime = DateTime.now().microsecondsSinceEpoch;
       bool hasData = true;
-      final int limitInBatch = 100;
+      const int limitInBatch = 100;
       while (hasData) {
         var localIDsToProcess = await _filesMigrationDB
             .getLocalIDsForPotentialReUpload(limitInBatch);

+ 3 - 4
lib/services/local_sync_service.dart

@@ -27,10 +27,10 @@ class LocalSyncService {
   static const kPermissionStateKey = "permission_state";
   static const kEditedFileIDsKey = "edited_file_ids";
   static const kDownloadedFileIDsKey = "downloaded_file_ids";
+
   // Adding `_2` as a suffic to pull files that were earlier ignored due to permission errors
   // See https://github.com/CaiJingLong/flutter_photo_manager/issues/589
   static const kInvalidFileIDsKey = "invalid_file_ids_2";
-
   LocalSyncService._privateConstructor();
 
   static final LocalSyncService instance =
@@ -86,8 +86,7 @@ class LocalSyncService {
       );
     } else {
       // Load from 0 - 01.01.2010
-      Bus.instance
-          .fire(SyncStatusUpdate(SyncStatus.started_first_gallery_import));
+      Bus.instance.fire(SyncStatusUpdate(SyncStatus.startedFirstGalleryImport));
       var startTime = 0;
       var toYear = 2010;
       var toTime = DateTime(toYear).microsecondsSinceEpoch;
@@ -116,7 +115,7 @@ class LocalSyncService {
       await _prefs.setBool(kHasCompletedFirstImportKey, true);
       _logger.fine("first gallery import finished");
       Bus.instance
-          .fire(SyncStatusUpdate(SyncStatus.completed_first_gallery_import));
+          .fire(SyncStatusUpdate(SyncStatus.completedFirstGalleryImport));
     }
     final endTime = DateTime.now().microsecondsSinceEpoch;
     final duration = Duration(microseconds: endTime - startTime);

+ 11 - 8
lib/services/memories_service.dart

@@ -11,10 +11,10 @@ class MemoriesService extends ChangeNotifier {
   final _logger = Logger("MemoryService");
   final _memoriesDB = MemoriesDB.instance;
   final _filesDB = FilesDB.instance;
-  static final daysInAYear = 365;
-  static final yearsBefore = 30;
-  static final daysBefore = 7;
-  static final daysAfter = 1;
+  static const daysInAYear = 365;
+  static const yearsBefore = 30;
+  static const daysBefore = 7;
+  static const daysAfter = 1;
 
   List<Memory> _cachedMemories;
   Future<List<Memory>> _future;
@@ -65,16 +65,19 @@ class MemoriesService extends ChangeNotifier {
     final List<List<int>> durations = [];
     for (var yearAgo = 1; yearAgo <= yearsBefore; yearAgo++) {
       final date = _getDate(present, yearAgo);
-      final startCreationTime =
-          date.subtract(Duration(days: daysBefore)).microsecondsSinceEpoch;
+      final startCreationTime = date
+          .subtract(const Duration(days: daysBefore))
+          .microsecondsSinceEpoch;
       final endCreationTime =
-          date.add(Duration(days: daysAfter)).microsecondsSinceEpoch;
+          date.add(const Duration(days: daysAfter)).microsecondsSinceEpoch;
       durations.add([startCreationTime, endCreationTime]);
     }
     final archivedCollectionIds =
         CollectionsService.instance.getArchivedCollections();
     final files = await _filesDB.getFilesCreatedWithinDurations(
-        durations, archivedCollectionIds);
+      durations,
+      archivedCollectionIds,
+    );
     final seenTimes = await _memoriesDB.getSeenTimes();
     final List<Memory> memories = [];
     final filter = ImportantItemsFilter();

+ 1 - 1
lib/services/notification_service.dart

@@ -16,7 +16,7 @@ class NotificationService {
     }
     const AndroidInitializationSettings initializationSettingsAndroid =
         AndroidInitializationSettings('notification_icon');
-    final InitializationSettings initializationSettings =
+    const InitializationSettings initializationSettings =
         InitializationSettings(
       android: initializationSettingsAndroid,
     );

+ 4 - 4
lib/services/remote_sync_service.dart

@@ -98,7 +98,7 @@ class RemoteSyncService {
           // session are not processed now
           sync();
         } else {
-          Bus.instance.fire(SyncStatusUpdate(SyncStatus.completed_backup));
+          Bus.instance.fire(SyncStatusUpdate(SyncStatus.completedBackup));
         }
       } else {
         _existingSync.complete();
@@ -145,7 +145,7 @@ class RemoteSyncService {
         await _collectionsService.getCollectionsToBeSynced();
 
     if (updatedCollections.isNotEmpty && !silently) {
-      Bus.instance.fire(SyncStatusUpdate(SyncStatus.applying_remote_diff));
+      Bus.instance.fire(SyncStatusUpdate(SyncStatus.applyingRemoteDiff));
     }
     for (final c in updatedCollections) {
       await _syncCollectionDiff(
@@ -269,7 +269,7 @@ class RemoteSyncService {
         filesToBeUploaded.length + updatedFileIDs.length + editedFiles.length;
 
     if (toBeUploaded > 0) {
-      Bus.instance.fire(SyncStatusUpdate(SyncStatus.preparing_for_upload));
+      Bus.instance.fire(SyncStatusUpdate(SyncStatus.preparingForUpload));
       // verify if files upload is allowed based on their subscription plan and
       // storage limit. To avoid creating new endpoint, we are using
       // fetchUploadUrls as alternative method.
@@ -360,7 +360,7 @@ class RemoteSyncService {
     }
     Bus.instance.fire(
       SyncStatusUpdate(
-        SyncStatus.in_progress,
+        SyncStatus.inProgress,
         completed: _completedUploads,
         total: toBeUploadedInThisSession,
       ),

+ 5 - 5
lib/services/sync_service.dart

@@ -83,9 +83,9 @@ class SyncService {
       await _doSync();
       if (_lastSyncStatusEvent != null &&
           _lastSyncStatusEvent.status !=
-              SyncStatus.completed_first_gallery_import &&
-          _lastSyncStatusEvent.status != SyncStatus.completed_backup) {
-        Bus.instance.fire(SyncStatusUpdate(SyncStatus.completed_backup));
+              SyncStatus.completedFirstGalleryImport &&
+          _lastSyncStatusEvent.status != SyncStatus.completedBackup) {
+        Bus.instance.fire(SyncStatusUpdate(SyncStatus.completedBackup));
       }
       successful = true;
     } on WiFiUnavailableError {
@@ -96,7 +96,7 @@ class SyncService {
     } on SyncStopRequestedError {
       _syncStopRequested = false;
       Bus.instance.fire(
-        SyncStatusUpdate(SyncStatus.completed_backup, wasStopped: true),
+        SyncStatusUpdate(SyncStatus.completedBackup, wasStopped: true),
       );
     } on NoActiveSubscriptionError {
       Bus.instance.fire(
@@ -116,7 +116,7 @@ class SyncService {
     } on UnauthorizedError {
       _logger.info("Logging user out");
       Bus.instance.fire(TriggerLogoutEvent());
-    } catch (e, s) {
+    } catch (e) {
       if (e is DioError) {
         if (e.type == DioErrorType.connectTimeout ||
             e.type == DioErrorType.sendTimeout ||

+ 16 - 16
lib/services/user_service.dart

@@ -17,13 +17,13 @@ import 'package:photos/models/sessions.dart';
 import 'package:photos/models/set_keys_request.dart';
 import 'package:photos/models/set_recovery_key_request.dart';
 import 'package:photos/models/user_details.dart';
-import 'package:photos/ui/login_page.dart';
-import 'package:photos/ui/ott_verification_page.dart';
-import 'package:photos/ui/password_entry_page.dart';
-import 'package:photos/ui/password_reentry_page.dart';
-import 'package:photos/ui/two_factor_authentication_page.dart';
-import 'package:photos/ui/two_factor_recovery_page.dart';
-import 'package:photos/ui/two_factor_setup_page.dart';
+import 'package:photos/ui/account/login_page.dart';
+import 'package:photos/ui/account/ott_verification_page.dart';
+import 'package:photos/ui/account/password_entry_page.dart';
+import 'package:photos/ui/account/password_reentry_page.dart';
+import 'package:photos/ui/account/two_factor_authentication_page.dart';
+import 'package:photos/ui/account/two_factor_recovery_page.dart';
+import 'package:photos/ui/account/two_factor_setup_page.dart';
 import 'package:photos/utils/crypto_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/navigation_util.dart';
@@ -230,9 +230,9 @@ class UserService {
         } else {
           await _saveConfiguration(response);
           if (Configuration.instance.getEncryptedToken() != null) {
-            page = PasswordReentryPage();
+            page = const PasswordReentryPage();
           } else {
-            page = PasswordEntryPage();
+            page = const PasswordEntryPage();
           }
         }
         Navigator.of(context).pushAndRemoveUntil(
@@ -418,7 +418,7 @@ class UserService {
         Navigator.of(context).pushAndRemoveUntil(
           MaterialPageRoute(
             builder: (BuildContext context) {
-              return PasswordReentryPage();
+              return const PasswordReentryPage();
             },
           ),
           (route) => route.isFirst,
@@ -432,7 +432,7 @@ class UserService {
         Navigator.of(context).pushAndRemoveUntil(
           MaterialPageRoute(
             builder: (BuildContext context) {
-              return LoginPage();
+              return const LoginPage();
             },
           ),
           (route) => route.isFirst,
@@ -486,7 +486,7 @@ class UserService {
         Navigator.of(context).pushAndRemoveUntil(
           MaterialPageRoute(
             builder: (BuildContext context) {
-              return LoginPage();
+              return const LoginPage();
             },
           ),
           (route) => route.isFirst,
@@ -551,7 +551,7 @@ class UserService {
         Navigator.of(context).pushAndRemoveUntil(
           MaterialPageRoute(
             builder: (BuildContext context) {
-              return PasswordReentryPage();
+              return const PasswordReentryPage();
             },
           ),
           (route) => route.isFirst,
@@ -564,7 +564,7 @@ class UserService {
         Navigator.of(context).pushAndRemoveUntil(
           MaterialPageRoute(
             builder: (BuildContext context) {
-              return LoginPage();
+              return const LoginPage();
             },
           ),
           (route) => route.isFirst,
@@ -740,7 +740,7 @@ class UserService {
   Future<String> getPaymentToken() async {
     try {
       var response = await _dio.get(
-        _config.getHttpEndpoint() + "/users/payment-token",
+        "${_config.getHttpEndpoint()}/users/payment-token",
         options: Options(
           headers: {
             "X-Auth-Token": _config.getToken(),
@@ -761,7 +761,7 @@ class UserService {
   Future<String> getFamiliesToken() async {
     try {
       var response = await _dio.get(
-        _config.getHttpEndpoint() + "/users/families-token",
+        "${_config.getHttpEndpoint()}/users/families-token",
         options: Options(
           headers: {
             "X-Auth-Token": _config.getToken(),

+ 5 - 5
lib/ui/change_email_dialog.dart → lib/ui/account/change_email_dialog.dart

@@ -7,7 +7,7 @@ class ChangeEmailDialog extends StatefulWidget {
   const ChangeEmailDialog({Key key}) : super(key: key);
 
   @override
-  _ChangeEmailDialogState createState() => _ChangeEmailDialogState();
+  State<ChangeEmailDialog> createState() => _ChangeEmailDialogState();
 }
 
 class _ChangeEmailDialogState extends State<ChangeEmailDialog> {
@@ -16,14 +16,14 @@ class _ChangeEmailDialogState extends State<ChangeEmailDialog> {
   @override
   Widget build(BuildContext context) {
     return AlertDialog(
-      title: Text("Enter your email address"),
+      title: const Text("Enter your email address"),
       content: SingleChildScrollView(
         child: Column(
           mainAxisAlignment: MainAxisAlignment.start,
           crossAxisAlignment: CrossAxisAlignment.start,
           children: [
             TextFormField(
-              decoration: InputDecoration(
+              decoration: const InputDecoration(
                 hintText: 'Email',
                 hintStyle: TextStyle(
                   color: Colors.white30,
@@ -45,7 +45,7 @@ class _ChangeEmailDialogState extends State<ChangeEmailDialog> {
       ),
       actions: [
         TextButton(
-          child: Text(
+          child: const Text(
             "Cancel",
             style: TextStyle(
               color: Colors.redAccent,
@@ -56,7 +56,7 @@ class _ChangeEmailDialogState extends State<ChangeEmailDialog> {
           },
         ),
         TextButton(
-          child: Text(
+          child: const Text(
             "Verify",
             style: TextStyle(
               color: Colors.green,

+ 41 - 32
lib/ui/email_entry_page.dart → lib/ui/account/email_entry_page.dart

@@ -10,17 +10,17 @@ import 'package:photos/ente_theme_data.dart';
 import 'package:photos/models/billing_plan.dart';
 import 'package:photos/services/billing_service.dart';
 import 'package:photos/services/user_service.dart';
-import 'package:photos/ui/common/dynamicFAB.dart';
-import 'package:photos/ui/loading_widget.dart';
-import 'package:photos/ui/web_page.dart';
+import 'package:photos/ui/common/dynamic_fab.dart';
+import 'package:photos/ui/common/loading_widget.dart';
+import 'package:photos/ui/common/web_page.dart';
 import 'package:photos/utils/data_util.dart';
 import 'package:step_progress_indicator/step_progress_indicator.dart';
 
 class EmailEntryPage extends StatefulWidget {
-  EmailEntryPage({Key key}) : super(key: key);
+  const EmailEntryPage({Key key}) : super(key: key);
 
   @override
-  _EmailEntryPageState createState() => _EmailEntryPageState();
+  State<EmailEntryPage> createState() => _EmailEntryPageState();
 }
 
 class _EmailEntryPageState extends State<EmailEntryPage> {
@@ -30,7 +30,7 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
   final _config = Configuration.instance;
   final _passwordController1 = TextEditingController();
   final _passwordController2 = TextEditingController();
-  final Color _validFieldValueColor = Color.fromRGBO(45, 194, 98, 0.2);
+  final Color _validFieldValueColor = const Color.fromRGBO(45, 194, 98, 0.2);
 
   String _email;
   String _password;
@@ -80,7 +80,7 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
     final appBar = AppBar(
       elevation: 0,
       leading: IconButton(
-        icon: Icon(Icons.arrow_back),
+        icon: const Icon(Icons.arrow_back),
         color: Theme.of(context).iconTheme.color,
         onPressed: () {
           Navigator.of(context).pop();
@@ -92,7 +92,7 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
           totalSteps: 4,
           currentStep: 1,
           selectedColor: Theme.of(context).buttonColor,
-          roundedEdges: Radius.circular(10),
+          roundedEdges: const Radius.circular(10),
           unselectedColor:
               Theme.of(context).colorScheme.stepProgressUnselectedColor,
         ),
@@ -152,8 +152,10 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
                       fillColor: _emailIsValid ? _validFieldValueColor : null,
                       filled: true,
                       hintText: 'Email',
-                      contentPadding:
-                          EdgeInsets.symmetric(horizontal: 16, vertical: 14),
+                      contentPadding: const EdgeInsets.symmetric(
+                        horizontal: 16,
+                        vertical: 14,
+                      ),
                       border: UnderlineInputBorder(
                         borderSide: BorderSide.none,
                         borderRadius: BorderRadius.circular(6),
@@ -184,7 +186,7 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
                     textInputAction: TextInputAction.next,
                   ),
                 ),
-                Padding(padding: EdgeInsets.all(4)),
+                const Padding(padding: EdgeInsets.all(4)),
                 Padding(
                   padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
                   child: TextFormField(
@@ -198,8 +200,10 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
                           _passwordIsValid ? _validFieldValueColor : null,
                       filled: true,
                       hintText: "Password",
-                      contentPadding:
-                          EdgeInsets.symmetric(horizontal: 16, vertical: 14),
+                      contentPadding: const EdgeInsets.symmetric(
+                        horizontal: 16,
+                        vertical: 14,
+                      ),
                       suffixIcon: _password1InFocus
                           ? IconButton(
                               icon: Icon(
@@ -263,8 +267,10 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
                       fillColor: _passwordsMatch ? _validFieldValueColor : null,
                       filled: true,
                       hintText: "Confirm password",
-                      contentPadding:
-                          EdgeInsets.symmetric(horizontal: 16, vertical: 14),
+                      contentPadding: const EdgeInsets.symmetric(
+                        horizontal: 16,
+                        vertical: 14,
+                      ),
                       suffixIcon: _password2InFocus
                           ? IconButton(
                               icon: Icon(
@@ -369,12 +375,12 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
             child: RichText(
               text: TextSpan(
                 children: [
-                  TextSpan(
+                  const TextSpan(
                     text: "I agree to the ",
                   ),
                   TextSpan(
                     text: "terms of service",
-                    style: TextStyle(
+                    style: const TextStyle(
                       decoration: TextDecoration.underline,
                     ),
                     recognizer: TapGestureRecognizer()
@@ -382,16 +388,19 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
                         Navigator.of(context).push(
                           MaterialPageRoute(
                             builder: (BuildContext context) {
-                              return WebPage("Terms", "https://ente.io/terms");
+                              return const WebPage(
+                                "Terms",
+                                "https://ente.io/terms",
+                              );
                             },
                           ),
                         );
                       },
                   ),
-                  TextSpan(text: " and "),
+                  const TextSpan(text: " and "),
                   TextSpan(
                     text: "privacy policy",
-                    style: TextStyle(
+                    style: const TextStyle(
                       decoration: TextDecoration.underline,
                     ),
                     recognizer: TapGestureRecognizer()
@@ -399,7 +408,7 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
                         Navigator.of(context).push(
                           MaterialPageRoute(
                             builder: (BuildContext context) {
-                              return WebPage(
+                              return const WebPage(
                                 "Privacy",
                                 "https://ente.io/privacy",
                               );
@@ -445,13 +454,13 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
             child: RichText(
               text: TextSpan(
                 children: [
-                  TextSpan(
+                  const TextSpan(
                     text:
                         "I understand that if I lose my password, I may lose my data since my data is ",
                   ),
                   TextSpan(
                     text: "end-to-end encrypted",
-                    style: TextStyle(
+                    style: const TextStyle(
                       decoration: TextDecoration.underline,
                     ),
                     recognizer: TapGestureRecognizer()
@@ -459,7 +468,7 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
                         Navigator.of(context).push(
                           MaterialPageRoute(
                             builder: (BuildContext context) {
-                              return WebPage(
+                              return const WebPage(
                                 "Encryption",
                                 "https://ente.io/architecture",
                               );
@@ -468,7 +477,7 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
                         );
                       },
                   ),
-                  TextSpan(text: " with ente"),
+                  const TextSpan(text: " with ente"),
                 ],
                 style: Theme.of(context)
                     .textTheme
@@ -505,9 +514,9 @@ class PricingWidget extends StatelessWidget {
         if (snapshot.hasData) {
           return _buildPlans(context, snapshot.data);
         } else if (snapshot.hasError) {
-          return Text("Oops, Something went wrong.");
+          return const Text("Oops, Something went wrong.");
         }
-        return loadWidget;
+        return const EnteLoadingWidget();
       },
     );
   }
@@ -527,7 +536,7 @@ class PricingWidget extends StatelessWidget {
       child: Column(
         mainAxisAlignment: MainAxisAlignment.spaceEvenly,
         children: <Widget>[
-          Text(
+          const Text(
             "Pricing",
             style: TextStyle(
               fontWeight: FontWeight.bold,
@@ -594,23 +603,23 @@ class BillingPlanWidget extends StatelessWidget {
         ),
         color: Colors.black.withOpacity(0.2),
         child: Container(
-          padding: EdgeInsets.fromLTRB(12, 20, 12, 20),
+          padding: const EdgeInsets.fromLTRB(12, 20, 12, 20),
           child: Column(
             children: [
               Text(
                 convertBytesToGBs(plan.storage, precision: 0).toString() +
                     " GB",
-                style: TextStyle(
+                style: const TextStyle(
                   fontWeight: FontWeight.bold,
                   fontSize: 16,
                 ),
               ),
-              Padding(
+              const Padding(
                 padding: EdgeInsets.all(4),
               ),
               Text(
                 plan.price + " / " + plan.period,
-                style: TextStyle(
+                style: const TextStyle(
                   fontSize: 12,
                   color: Colors.white70,
                 ),

+ 20 - 18
lib/ui/login_page.dart → lib/ui/account/login_page.dart

@@ -3,21 +3,21 @@ import 'package:flutter/gestures.dart';
 import 'package:flutter/material.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/services/user_service.dart';
-import 'package:photos/ui/common/dynamicFAB.dart';
-import 'package:photos/ui/web_page.dart';
+import 'package:photos/ui/common/dynamic_fab.dart';
+import 'package:photos/ui/common/web_page.dart';
 
 class LoginPage extends StatefulWidget {
-  LoginPage({Key key}) : super(key: key);
+  const LoginPage({Key key}) : super(key: key);
 
   @override
-  _LoginPageState createState() => _LoginPageState();
+  State<LoginPage> createState() => _LoginPageState();
 }
 
 class _LoginPageState extends State<LoginPage> {
   final _config = Configuration.instance;
   bool _emailIsValid = false;
   String _email;
-  Color _emailInputFieldColor = null;
+  Color _emailInputFieldColor;
 
   @override
   void initState() {
@@ -42,7 +42,7 @@ class _LoginPageState extends State<LoginPage> {
       appBar: AppBar(
         elevation: 0,
         leading: IconButton(
-          icon: Icon(Icons.arrow_back),
+          icon: const Icon(Icons.arrow_back),
           color: Theme.of(context).iconTheme.color,
           onPressed: () {
             Navigator.of(context).pop();
@@ -88,8 +88,10 @@ class _LoginPageState extends State<LoginPage> {
                     fillColor: _emailInputFieldColor,
                     filled: true,
                     hintText: 'Email',
-                    contentPadding:
-                        EdgeInsets.symmetric(horizontal: 15, vertical: 15),
+                    contentPadding: const EdgeInsets.symmetric(
+                      horizontal: 15,
+                      vertical: 15,
+                    ),
                     border: UnderlineInputBorder(
                       borderSide: BorderSide.none,
                       borderRadius: BorderRadius.circular(6),
@@ -112,7 +114,7 @@ class _LoginPageState extends State<LoginPage> {
                       _emailIsValid = EmailValidator.validate(_email);
                       if (_emailIsValid) {
                         _emailInputFieldColor =
-                            Color.fromRGBO(45, 194, 98, 0.2);
+                            const Color.fromRGBO(45, 194, 98, 0.2);
                       } else {
                         _emailInputFieldColor = null;
                       }
@@ -124,8 +126,8 @@ class _LoginPageState extends State<LoginPage> {
                   autofocus: true,
                 ),
               ),
-              Padding(
-                padding: const EdgeInsets.symmetric(vertical: 18),
+              const Padding(
+                padding: EdgeInsets.symmetric(vertical: 18),
                 child: Divider(
                   thickness: 1,
                 ),
@@ -143,12 +145,12 @@ class _LoginPageState extends State<LoginPage> {
                               .subtitle1
                               .copyWith(fontSize: 12),
                           children: [
-                            TextSpan(
+                            const TextSpan(
                               text: "By clicking log in, I agree to the ",
                             ),
                             TextSpan(
                               text: "terms of service",
-                              style: TextStyle(
+                              style: const TextStyle(
                                 decoration: TextDecoration.underline,
                               ),
                               recognizer: TapGestureRecognizer()
@@ -156,7 +158,7 @@ class _LoginPageState extends State<LoginPage> {
                                   Navigator.of(context).push(
                                     MaterialPageRoute(
                                       builder: (BuildContext context) {
-                                        return WebPage(
+                                        return const WebPage(
                                           "terms",
                                           "https://ente.io/terms",
                                         );
@@ -165,10 +167,10 @@ class _LoginPageState extends State<LoginPage> {
                                   );
                                 },
                             ),
-                            TextSpan(text: " and "),
+                            const TextSpan(text: " and "),
                             TextSpan(
                               text: "privacy policy",
-                              style: TextStyle(
+                              style: const TextStyle(
                                 decoration: TextDecoration.underline,
                               ),
                               recognizer: TapGestureRecognizer()
@@ -176,7 +178,7 @@ class _LoginPageState extends State<LoginPage> {
                                   Navigator.of(context).push(
                                     MaterialPageRoute(
                                       builder: (BuildContext context) {
-                                        return WebPage(
+                                        return const WebPage(
                                           "privacy",
                                           "https://ente.io/privacy",
                                         );
@@ -200,7 +202,7 @@ class _LoginPageState extends State<LoginPage> {
             ],
           ),
         ),
-        Padding(padding: EdgeInsets.all(8)),
+        const Padding(padding: EdgeInsets.all(8)),
       ],
     );
   }

+ 8 - 8
lib/ui/ott_verification_page.dart → lib/ui/account/ott_verification_page.dart

@@ -1,7 +1,7 @@
 import 'package:flutter/material.dart';
 import 'package:photos/ente_theme_data.dart';
 import 'package:photos/services/user_service.dart';
-import 'package:photos/ui/common/dynamicFAB.dart';
+import 'package:photos/ui/common/dynamic_fab.dart';
 import 'package:step_progress_indicator/step_progress_indicator.dart';
 
 class OTTVerificationPage extends StatefulWidget {
@@ -9,7 +9,7 @@ class OTTVerificationPage extends StatefulWidget {
   final bool isChangeEmail;
   final bool isCreateAccountScreen;
 
-  OTTVerificationPage(
+  const OTTVerificationPage(
     this.email, {
     this.isChangeEmail = false,
     this.isCreateAccountScreen = false,
@@ -17,7 +17,7 @@ class OTTVerificationPage extends StatefulWidget {
   }) : super(key: key);
 
   @override
-  _OTTVerificationPageState createState() => _OTTVerificationPageState();
+  State<OTTVerificationPage> createState() => _OTTVerificationPageState();
 }
 
 class _OTTVerificationPageState extends State<OTTVerificationPage> {
@@ -40,7 +40,7 @@ class _OTTVerificationPageState extends State<OTTVerificationPage> {
       appBar: AppBar(
         elevation: 0,
         leading: IconButton(
-          icon: Icon(Icons.arrow_back),
+          icon: const Icon(Icons.arrow_back),
           color: Theme.of(context).iconTheme.color,
           onPressed: () {
             Navigator.of(context).pop();
@@ -53,7 +53,7 @@ class _OTTVerificationPageState extends State<OTTVerificationPage> {
                   totalSteps: 4,
                   currentStep: 2,
                   selectedColor: Theme.of(context).buttonColor,
-                  roundedEdges: Radius.circular(10),
+                  roundedEdges: const Radius.circular(10),
                   unselectedColor:
                       Theme.of(context).colorScheme.stepProgressUnselectedColor,
                 ),
@@ -115,7 +115,7 @@ class _OTTVerificationPageState extends State<OTTVerificationPage> {
                                   .subtitle1
                                   .copyWith(fontSize: 14),
                               children: [
-                                TextSpan(text: "We've sent a mail to "),
+                                const TextSpan(text: "We've sent a mail to "),
                                 TextSpan(
                                   text: widget.email,
                                   style: TextStyle(
@@ -150,7 +150,7 @@ class _OTTVerificationPageState extends State<OTTVerificationPage> {
                 decoration: InputDecoration(
                   filled: true,
                   hintText: 'Tap to enter code',
-                  contentPadding: EdgeInsets.all(15),
+                  contentPadding: const EdgeInsets.all(15),
                   border: UnderlineInputBorder(
                     borderSide: BorderSide.none,
                     borderRadius: BorderRadius.circular(6),
@@ -165,7 +165,7 @@ class _OTTVerificationPageState extends State<OTTVerificationPage> {
                 },
               ),
             ),
-            Divider(
+            const Divider(
               thickness: 1,
             ),
             Padding(

+ 15 - 15
lib/ui/password_entry_page.dart → lib/ui/account/password_entry_page.dart

@@ -7,10 +7,10 @@ import 'package:photos/core/event_bus.dart';
 import 'package:photos/events/account_configured_event.dart';
 import 'package:photos/events/subscription_purchased_event.dart';
 import 'package:photos/services/user_service.dart';
-import 'package:photos/ui/common/dynamicFAB.dart';
+import 'package:photos/ui/account/recovery_key_page.dart';
+import 'package:photos/ui/common/dynamic_fab.dart';
+import 'package:photos/ui/common/web_page.dart';
 import 'package:photos/ui/payment/subscription.dart';
-import 'package:photos/ui/recovery_key_page.dart';
-import 'package:photos/ui/web_page.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/navigation_util.dart';
 import 'package:photos/utils/toast_util.dart';
@@ -24,11 +24,11 @@ enum PasswordEntryMode {
 class PasswordEntryPage extends StatefulWidget {
   final PasswordEntryMode mode;
 
-  PasswordEntryPage({this.mode = PasswordEntryMode.set, Key key})
+  const PasswordEntryPage({this.mode = PasswordEntryMode.set, Key key})
       : super(key: key);
 
   @override
-  _PasswordEntryPageState createState() => _PasswordEntryPageState();
+  State<PasswordEntryPage> createState() => _PasswordEntryPageState();
 }
 
 class _PasswordEntryPageState extends State<PasswordEntryPage> {
@@ -38,7 +38,7 @@ class _PasswordEntryPageState extends State<PasswordEntryPage> {
   final _logger = Logger((_PasswordEntryPageState).toString());
   final _passwordController1 = TextEditingController(),
       _passwordController2 = TextEditingController();
-  final Color _validFieldValueColor = Color.fromRGBO(45, 194, 98, 0.2);
+  final Color _validFieldValueColor = const Color.fromRGBO(45, 194, 98, 0.2);
   String _volatilePassword;
   String _passwordInInputBox = '';
   String _passwordInInputConfirmationBox = '';
@@ -101,7 +101,7 @@ class _PasswordEntryPageState extends State<PasswordEntryPage> {
         leading: widget.mode == PasswordEntryMode.reset
             ? Container()
             : IconButton(
-                icon: Icon(Icons.arrow_back),
+                icon: const Icon(Icons.arrow_back),
                 color: Theme.of(context).iconTheme.color,
                 onPressed: () {
                   Navigator.of(context).pop();
@@ -169,7 +169,7 @@ class _PasswordEntryPageState extends State<PasswordEntryPage> {
                         .copyWith(fontSize: 14),
                   ),
                 ),
-                Padding(padding: EdgeInsets.all(8)),
+                const Padding(padding: EdgeInsets.all(8)),
                 Padding(
                   padding: const EdgeInsets.symmetric(horizontal: 20),
                   child: RichText(
@@ -179,7 +179,7 @@ class _PasswordEntryPageState extends State<PasswordEntryPage> {
                           .subtitle1
                           .copyWith(fontSize: 14),
                       children: [
-                        TextSpan(
+                        const TextSpan(
                           text:
                               "We don't store this password, so if you forget, ",
                         ),
@@ -194,7 +194,7 @@ class _PasswordEntryPageState extends State<PasswordEntryPage> {
                     ),
                   ),
                 ),
-                Padding(padding: EdgeInsets.all(12)),
+                const Padding(padding: EdgeInsets.all(12)),
                 Visibility(
                   // hidden textForm for suggesting auto-fill service for saving
                   // password
@@ -218,7 +218,7 @@ class _PasswordEntryPageState extends State<PasswordEntryPage> {
                           _isPasswordValid ? _validFieldValueColor : null,
                       filled: true,
                       hintText: "Password",
-                      contentPadding: EdgeInsets.all(20),
+                      contentPadding: const EdgeInsets.all(20),
                       border: UnderlineInputBorder(
                         borderSide: BorderSide.none,
                         borderRadius: BorderRadius.circular(6),
@@ -281,7 +281,7 @@ class _PasswordEntryPageState extends State<PasswordEntryPage> {
                       fillColor: _passwordsMatch ? _validFieldValueColor : null,
                       filled: true,
                       hintText: "Confirm password",
-                      contentPadding: EdgeInsets.symmetric(
+                      contentPadding: const EdgeInsets.symmetric(
                         horizontal: 20,
                         vertical: 20,
                       ),
@@ -349,7 +349,7 @@ class _PasswordEntryPageState extends State<PasswordEntryPage> {
                     Navigator.of(context).push(
                       MaterialPageRoute(
                         builder: (BuildContext context) {
-                          return WebPage(
+                          return const WebPage(
                             "How it works",
                             "https://ente.io/architecture",
                           );
@@ -358,7 +358,7 @@ class _PasswordEntryPageState extends State<PasswordEntryPage> {
                     );
                   },
                   child: Container(
-                    padding: EdgeInsets.symmetric(horizontal: 20),
+                    padding: const EdgeInsets.symmetric(horizontal: 20),
                     child: RichText(
                       text: TextSpan(
                         text: "How it works",
@@ -370,7 +370,7 @@ class _PasswordEntryPageState extends State<PasswordEntryPage> {
                     ),
                   ),
                 ),
-                Padding(padding: EdgeInsets.all(20)),
+                const Padding(padding: EdgeInsets.all(20)),
               ],
             ),
           ),

+ 25 - 31
lib/ui/password_reentry_page.dart → lib/ui/account/password_reentry_page.dart

@@ -3,16 +3,16 @@ import 'package:logging/logging.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/event_bus.dart';
 import 'package:photos/events/subscription_purchased_event.dart';
-import 'package:photos/ui/common/dynamicFAB.dart';
+import 'package:photos/ui/account/recovery_page.dart';
+import 'package:photos/ui/common/dynamic_fab.dart';
 import 'package:photos/ui/home_widget.dart';
-import 'package:photos/ui/recovery_page.dart';
 import 'package:photos/utils/dialog_util.dart';
 
 class PasswordReentryPage extends StatefulWidget {
-  PasswordReentryPage({Key key}) : super(key: key);
+  const PasswordReentryPage({Key key}) : super(key: key);
 
   @override
-  _PasswordReentryPageState createState() => _PasswordReentryPageState();
+  State<PasswordReentryPage> createState() => _PasswordReentryPageState();
 }
 
 class _PasswordReentryPageState extends State<PasswordReentryPage> {
@@ -48,7 +48,7 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
       appBar: AppBar(
         elevation: 0,
         leading: IconButton(
-          icon: Icon(Icons.arrow_back),
+          icon: const Icon(Icons.arrow_back),
           color: Theme.of(context).iconTheme.color,
           onPressed: () {
             Navigator.of(context).pop();
@@ -80,7 +80,7 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
           Navigator.of(context).pushAndRemoveUntil(
             MaterialPageRoute(
               builder: (BuildContext context) {
-                return HomeWidget();
+                return const HomeWidget();
               },
             ),
             (route) => false,
@@ -113,7 +113,7 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
                   decoration: InputDecoration(
                     hintText: "Enter your password",
                     filled: true,
-                    contentPadding: EdgeInsets.all(20),
+                    contentPadding: const EdgeInsets.all(20),
                     border: UnderlineInputBorder(
                       borderSide: BorderSide.none,
                       borderRadius: BorderRadius.circular(6),
@@ -135,7 +135,7 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
                           )
                         : null,
                   ),
-                  style: TextStyle(
+                  style: const TextStyle(
                     fontSize: 14,
                   ),
                   controller: _passwordController,
@@ -149,8 +149,8 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
                   },
                 ),
               ),
-              Padding(
-                padding: const EdgeInsets.symmetric(vertical: 18),
+              const Padding(
+                padding: EdgeInsets.symmetric(vertical: 18),
                 child: Divider(
                   thickness: 1,
                 ),
@@ -166,21 +166,18 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
                         Navigator.of(context).push(
                           MaterialPageRoute(
                             builder: (BuildContext context) {
-                              return RecoveryPage();
+                              return const RecoveryPage();
                             },
                           ),
                         );
                       },
-                      child: Container(
-                        child: Center(
-                          child: Text(
-                            "Forgot password",
-                            style:
-                                Theme.of(context).textTheme.subtitle1.copyWith(
-                                      fontSize: 14,
-                                      decoration: TextDecoration.underline,
-                                    ),
-                          ),
+                      child: Center(
+                        child: Text(
+                          "Forgot password",
+                          style: Theme.of(context).textTheme.subtitle1.copyWith(
+                                fontSize: 14,
+                                decoration: TextDecoration.underline,
+                              ),
                         ),
                       ),
                     ),
@@ -195,16 +192,13 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
                         Navigator.of(context)
                             .popUntil((route) => route.isFirst);
                       },
-                      child: Container(
-                        child: Center(
-                          child: Text(
-                            "Change email",
-                            style:
-                                Theme.of(context).textTheme.subtitle1.copyWith(
-                                      fontSize: 14,
-                                      decoration: TextDecoration.underline,
-                                    ),
-                          ),
+                      child: Center(
+                        child: Text(
+                          "Change email",
+                          style: Theme.of(context).textTheme.subtitle1.copyWith(
+                                fontSize: 14,
+                                decoration: TextDecoration.underline,
+                              ),
                         ),
                       ),
                     ),

+ 18 - 24
lib/ui/recovery_key_page.dart → lib/ui/account/recovery_key_page.dart

@@ -1,4 +1,5 @@
 import 'dart:io' as io;
+
 import 'package:bip39/bip39.dart' as bip39;
 import 'package:dotted_border/dotted_border.dart';
 import 'package:flutter/material.dart';
@@ -6,7 +7,7 @@ import 'package:flutter/services.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/constants.dart';
 import 'package:photos/ente_theme_data.dart';
-import 'package:photos/ui/common/gradientButton.dart';
+import 'package:photos/ui/common/gradient_button.dart';
 import 'package:photos/utils/toast_util.dart';
 import 'package:share_plus/share_plus.dart';
 import 'package:step_progress_indicator/step_progress_indicator.dart';
@@ -36,7 +37,7 @@ class RecoveryKeyPage extends StatefulWidget {
   }) : super(key: key);
 
   @override
-  _RecoveryKeyPageState createState() => _RecoveryKeyPageState();
+  State<RecoveryKeyPage> createState() => _RecoveryKeyPageState();
 }
 
 class _RecoveryKeyPageState extends State<RecoveryKeyPage> {
@@ -64,7 +65,7 @@ class _RecoveryKeyPageState extends State<RecoveryKeyPage> {
                   totalSteps: 4,
                   currentStep: 3,
                   selectedColor: Theme.of(context).buttonColor,
-                  roundedEdges: Radius.circular(10),
+                  roundedEdges: const Radius.circular(10),
                   unselectedColor:
                       Theme.of(context).colorScheme.stepProgressUnselectedColor,
                 ),
@@ -103,14 +104,14 @@ class _RecoveryKeyPageState extends State<RecoveryKeyPage> {
                   "If you forget your password, the only way you can recover your data is with this key.",
               style: Theme.of(context).textTheme.subtitle1,
             ),
-            Padding(padding: EdgeInsets.only(top: 24)),
+            const Padding(padding: EdgeInsets.only(top: 24)),
             DottedBorder(
-              color: Color.fromRGBO(17, 127, 56, 1),
+              color: const Color.fromRGBO(17, 127, 56, 1),
               //color of dotted/dash line
               strokeWidth: 1,
               //thickness of dash/dots
               dashPattern: const [6, 6],
-              radius: Radius.circular(8),
+              radius: const Radius.circular(8),
               //dash patterns, 10 is dash width, 6 is space width
               child: SizedBox(
                 //inner container
@@ -133,16 +134,16 @@ class _RecoveryKeyPageState extends State<RecoveryKeyPage> {
                       child: Container(
                         decoration: BoxDecoration(
                           border: Border.all(
-                            color: Color.fromRGBO(49, 155, 86, .2),
+                            color: const Color.fromRGBO(49, 155, 86, .2),
                           ),
-                          borderRadius: BorderRadius.all(
+                          borderRadius: const BorderRadius.all(
                             Radius.circular(2),
                           ),
                           color:
                               Theme.of(context).colorScheme.recoveryKeyBoxColor,
                         ),
                         height: 120,
-                        padding: EdgeInsets.all(20),
+                        padding: const EdgeInsets.all(20),
                         width: double.infinity,
                         child: Text(
                           recoveryKey,
@@ -158,19 +159,19 @@ class _RecoveryKeyPageState extends State<RecoveryKeyPage> {
               height: 80,
               width: double.infinity,
               child: Padding(
+                padding: const EdgeInsets.symmetric(vertical: 20),
                 child: Text(
                   widget.subText ??
                       "We don’t store this key, please save this in a safe place.",
                   style: Theme.of(context).textTheme.bodyText1,
                 ),
-                padding: EdgeInsets.symmetric(vertical: 20),
               ),
             ),
             Expanded(
               child: Container(
                 alignment: Alignment.bottomCenter,
                 width: double.infinity,
-                padding: EdgeInsets.fromLTRB(10, 10, 10, 24),
+                padding: const EdgeInsets.fromLTRB(10, 10, 10, 24),
                 child: Column(
                   mainAxisAlignment: MainAxisAlignment.end,
                   crossAxisAlignment: CrossAxisAlignment.stretch,
@@ -189,33 +190,26 @@ class _RecoveryKeyPageState extends State<RecoveryKeyPage> {
     if (!_hasTriedToSave) {
       childrens.add(
         ElevatedButton(
-          child: Text('Do this later'),
           style: Theme.of(context).colorScheme.optionalActionButtonStyle,
           onPressed: () async {
             await _saveKeys();
           },
+          child: const Text('Do this later'),
         ),
       );
-      childrens.add(SizedBox(height: 10));
+      childrens.add(const SizedBox(height: 10));
     }
 
     childrens.add(
       GradientButton(
-        child: Text(
-          'Save key',
-          style: gradientButtonTextTheme(),
-        ),
-        linearGradientColors: const [
-          Color(0xFF2CD267),
-          Color(0xFF1DB954),
-        ],
         onTap: () async {
           await _shareRecoveryKey(recoveryKey);
         },
+        text: 'Save key',
       ),
     );
     if (_hasTriedToSave) {
-      childrens.add(SizedBox(height: 10));
+      childrens.add(const SizedBox(height: 10));
       childrens.add(
         ElevatedButton(
           child: Text(widget.doneText),
@@ -225,7 +219,7 @@ class _RecoveryKeyPageState extends State<RecoveryKeyPage> {
         ),
       );
     }
-    childrens.add(SizedBox(height: 12));
+    childrens.add(const SizedBox(height: 12));
     return childrens;
   }
 
@@ -235,7 +229,7 @@ class _RecoveryKeyPageState extends State<RecoveryKeyPage> {
     }
     _recoveryKeyFile.writeAsStringSync(recoveryKey);
     await Share.shareFiles([_recoveryKeyFile.path]);
-    Future.delayed(Duration(milliseconds: 500), () {
+    Future.delayed(const Duration(milliseconds: 500), () {
       if (mounted) {
         setState(() {
           _hasTriedToSave = true;

+ 10 - 10
lib/ui/recovery_page.dart → lib/ui/account/recovery_page.dart

@@ -2,8 +2,8 @@ import 'dart:ui';
 
 import 'package:flutter/material.dart';
 import 'package:photos/core/configuration.dart';
-import 'package:photos/ui/common/dynamicFAB.dart';
-import 'package:photos/ui/password_entry_page.dart';
+import 'package:photos/ui/account/password_entry_page.dart';
+import 'package:photos/ui/common/dynamic_fab.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/toast_util.dart';
 
@@ -11,7 +11,7 @@ class RecoveryPage extends StatefulWidget {
   const RecoveryPage({Key key}) : super(key: key);
 
   @override
-  _RecoveryPageState createState() => _RecoveryPageState();
+  State<RecoveryPage> createState() => _RecoveryPageState();
 }
 
 class _RecoveryPageState extends State<RecoveryPage> {
@@ -33,7 +33,7 @@ class _RecoveryPageState extends State<RecoveryPage> {
       appBar: AppBar(
         elevation: 0,
         leading: IconButton(
-          icon: Icon(Icons.arrow_back),
+          icon: const Icon(Icons.arrow_back),
           color: Theme.of(context).iconTheme.color,
           onPressed: () {
             Navigator.of(context).pop();
@@ -57,7 +57,7 @@ class _RecoveryPageState extends State<RecoveryPage> {
                 builder: (BuildContext context) {
                   return WillPopScope(
                     onWillPop: () async => false,
-                    child: PasswordEntryPage(
+                    child: const PasswordEntryPage(
                       mode: PasswordEntryMode.reset,
                     ),
                   );
@@ -95,13 +95,13 @@ class _RecoveryPageState extends State<RecoveryPage> {
                     decoration: InputDecoration(
                       filled: true,
                       hintText: "Enter your recovery key",
-                      contentPadding: EdgeInsets.all(20),
+                      contentPadding: const EdgeInsets.all(20),
                       border: UnderlineInputBorder(
                         borderSide: BorderSide.none,
                         borderRadius: BorderRadius.circular(6),
                       ),
                     ),
-                    style: TextStyle(
+                    style: const TextStyle(
                       fontSize: 14,
                       fontFeatures: [FontFeature.tabularFigures()],
                     ),
@@ -115,8 +115,8 @@ class _RecoveryPageState extends State<RecoveryPage> {
                     },
                   ),
                 ),
-                Padding(
-                  padding: const EdgeInsets.symmetric(vertical: 18),
+                const Padding(
+                  padding: EdgeInsets.symmetric(vertical: 18),
                   child: Divider(
                     thickness: 1,
                   ),
@@ -133,7 +133,7 @@ class _RecoveryPageState extends State<RecoveryPage> {
                         );
                       },
                       child: Container(
-                        padding: EdgeInsets.symmetric(horizontal: 20),
+                        padding: const EdgeInsets.symmetric(horizontal: 20),
                         child: Center(
                           child: Text(
                             "No recovery key?",

+ 14 - 15
lib/ui/sessions_page.dart → lib/ui/account/sessions_page.dart

@@ -1,20 +1,19 @@
 import 'package:flutter/material.dart';
-import 'package:flutter/widgets.dart';
 import 'package:logging/logging.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/ente_theme_data.dart';
 import 'package:photos/models/sessions.dart';
 import 'package:photos/services/user_service.dart';
-import 'package:photos/ui/loading_widget.dart';
+import 'package:photos/ui/common/loading_widget.dart';
 import 'package:photos/utils/date_time_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/toast_util.dart';
 
 class SessionsPage extends StatefulWidget {
-  SessionsPage({Key key}) : super(key: key);
+  const SessionsPage({Key key}) : super(key: key);
 
   @override
-  _SessionsPageState createState() => _SessionsPageState();
+  State<SessionsPage> createState() => _SessionsPageState();
 }
 
 class _SessionsPageState extends State<SessionsPage> {
@@ -32,7 +31,7 @@ class _SessionsPageState extends State<SessionsPage> {
     return Scaffold(
       appBar: AppBar(
         elevation: 0,
-        title: Text("Active sessions"),
+        title: const Text("Active sessions"),
       ),
       body: _getBody(),
     );
@@ -40,10 +39,10 @@ class _SessionsPageState extends State<SessionsPage> {
 
   Widget _getBody() {
     if (_sessions == null) {
-      return Center(child: loadWidget);
+      return const Center(child: EnteLoadingWidget());
     }
     List<Widget> rows = [];
-    rows.add(Padding(padding: const EdgeInsets.all(4)));
+    rows.add(const Padding(padding: EdgeInsets.all(4)));
     for (final session in _sessions.sessions) {
       rows.add(_getSessionWidget(session));
     }
@@ -69,7 +68,7 @@ class _SessionsPageState extends State<SessionsPage> {
               crossAxisAlignment: CrossAxisAlignment.start,
               children: [
                 _getUAWidget(session),
-                Padding(padding: EdgeInsets.all(4)),
+                const Padding(padding: EdgeInsets.all(4)),
                 Row(
                   mainAxisAlignment: MainAxisAlignment.spaceBetween,
                   children: [
@@ -85,7 +84,7 @@ class _SessionsPageState extends State<SessionsPage> {
                         ),
                       ),
                     ),
-                    Padding(padding: EdgeInsets.all(8)),
+                    const Padding(padding: EdgeInsets.all(8)),
                     Flexible(
                       child: Text(
                         getFormattedTime(lastUsedTime),
@@ -104,7 +103,7 @@ class _SessionsPageState extends State<SessionsPage> {
             ),
           ),
         ),
-        Divider(),
+        const Divider(),
       ],
     );
   }
@@ -145,17 +144,17 @@ class _SessionsPageState extends State<SessionsPage> {
         session.token == Configuration.instance.getToken();
     Widget text;
     if (isLoggingOutFromThisDevice) {
-      text = Text(
+      text = const Text(
         "This will log you out of this device!",
       );
     } else {
       text = SingleChildScrollView(
         child: Column(
           children: [
-            Text(
+            const Text(
               "This will log you out of the following device:",
             ),
-            Padding(padding: EdgeInsets.all(8)),
+            const Padding(padding: EdgeInsets.all(8)),
             Text(
               session.ua,
               style: Theme.of(context).textTheme.caption,
@@ -165,11 +164,11 @@ class _SessionsPageState extends State<SessionsPage> {
       );
     }
     AlertDialog alert = AlertDialog(
-      title: Text("Terminate session?"),
+      title: const Text("Terminate session?"),
       content: text,
       actions: [
         TextButton(
-          child: Text(
+          child: const Text(
             "Terminate",
             style: TextStyle(
               color: Colors.red,

+ 12 - 12
lib/ui/two_factor_authentication_page.dart → lib/ui/account/two_factor_authentication_page.dart

@@ -11,7 +11,7 @@ class TwoFactorAuthenticationPage extends StatefulWidget {
       : super(key: key);
 
   @override
-  _TwoFactorAuthenticationPageState createState() =>
+  State<TwoFactorAuthenticationPage> createState() =>
       _TwoFactorAuthenticationPageState();
 }
 
@@ -19,7 +19,7 @@ class _TwoFactorAuthenticationPageState
     extends State<TwoFactorAuthenticationPage> {
   final _pinController = TextEditingController();
   final _pinPutDecoration = BoxDecoration(
-    border: Border.all(color: Color.fromRGBO(45, 194, 98, 1.0)),
+    border: Border.all(color: const Color.fromRGBO(45, 194, 98, 1.0)),
     borderRadius: BorderRadius.circular(15.0),
   );
   String _code = "";
@@ -51,7 +51,7 @@ class _TwoFactorAuthenticationPageState
   Widget build(BuildContext context) {
     return Scaffold(
       appBar: AppBar(
-        title: Text(
+        title: const Text(
           "Two-factor authentication",
         ),
       ),
@@ -65,7 +65,7 @@ class _TwoFactorAuthenticationPageState
       mainAxisAlignment: MainAxisAlignment.center,
       mainAxisSize: MainAxisSize.max,
       children: [
-        Text(
+        const Text(
           "Enter the 6-digit code from\nyour authenticator app",
           style: TextStyle(
             height: 1.4,
@@ -73,7 +73,7 @@ class _TwoFactorAuthenticationPageState
           ),
           textAlign: TextAlign.center,
         ),
-        Padding(padding: EdgeInsets.all(32)),
+        const Padding(padding: EdgeInsets.all(32)),
         Padding(
           padding: const EdgeInsets.fromLTRB(40, 0, 40, 0),
           child: PinPut(
@@ -94,10 +94,10 @@ class _TwoFactorAuthenticationPageState
             followingFieldDecoration: _pinPutDecoration.copyWith(
               borderRadius: BorderRadius.circular(5.0),
               border: Border.all(
-                color: Color.fromRGBO(45, 194, 98, 0.5),
+                color: const Color.fromRGBO(45, 194, 98, 0.5),
               ),
             ),
-            inputDecoration: InputDecoration(
+            inputDecoration: const InputDecoration(
               focusedBorder: InputBorder.none,
               border: InputBorder.none,
               counterText: '',
@@ -105,29 +105,29 @@ class _TwoFactorAuthenticationPageState
             autofocus: true,
           ),
         ),
-        Padding(padding: EdgeInsets.all(24)),
+        const Padding(padding: EdgeInsets.all(24)),
         Container(
           padding: const EdgeInsets.fromLTRB(80, 0, 80, 0),
           width: double.infinity,
           height: 64,
           child: OutlinedButton(
-            child: Text("Verify"),
             onPressed: _code.length == 6
                 ? () async {
                     _verifyTwoFactorCode(_code);
                   }
                 : null,
+            child: const Text("Verify"),
           ),
         ),
-        Padding(padding: EdgeInsets.all(30)),
+        const Padding(padding: EdgeInsets.all(30)),
         GestureDetector(
           behavior: HitTestBehavior.opaque,
           onTap: () {
             UserService.instance.recoverTwoFactor(context, widget.sessionID);
           },
           child: Container(
-            padding: EdgeInsets.all(10),
-            child: Center(
+            padding: const EdgeInsets.all(10),
+            child: const Center(
               child: Text(
                 "Lost device?",
                 style: TextStyle(

+ 9 - 9
lib/ui/two_factor_recovery_page.dart → lib/ui/account/two_factor_recovery_page.dart

@@ -9,7 +9,7 @@ class TwoFactorRecoveryPage extends StatefulWidget {
   final String encryptedSecret;
   final String secretDecryptionNonce;
 
-  TwoFactorRecoveryPage(
+  const TwoFactorRecoveryPage(
     this.sessionID,
     this.encryptedSecret,
     this.secretDecryptionNonce, {
@@ -17,7 +17,7 @@ class TwoFactorRecoveryPage extends StatefulWidget {
   }) : super(key: key);
 
   @override
-  _TwoFactorRecoveryPageState createState() => _TwoFactorRecoveryPageState();
+  State<TwoFactorRecoveryPage> createState() => _TwoFactorRecoveryPageState();
 }
 
 class _TwoFactorRecoveryPageState extends State<TwoFactorRecoveryPage> {
@@ -27,7 +27,7 @@ class _TwoFactorRecoveryPageState extends State<TwoFactorRecoveryPage> {
   Widget build(BuildContext context) {
     return Scaffold(
       appBar: AppBar(
-        title: Text(
+        title: const Text(
           "Recover account",
           style: TextStyle(
             fontSize: 18,
@@ -42,13 +42,13 @@ class _TwoFactorRecoveryPageState extends State<TwoFactorRecoveryPage> {
           Padding(
             padding: const EdgeInsets.fromLTRB(60, 0, 60, 0),
             child: TextFormField(
-              decoration: InputDecoration(
+              decoration: const InputDecoration(
                 hintText: "Enter your recovery key",
                 contentPadding: EdgeInsets.all(20),
               ),
-              style: TextStyle(
+              style: const TextStyle(
                 fontSize: 14,
-                fontFeatures: const [FontFeature.tabularFigures()],
+                fontFeatures: [FontFeature.tabularFigures()],
               ),
               controller: _recoveryKey,
               autofocus: false,
@@ -60,13 +60,12 @@ class _TwoFactorRecoveryPageState extends State<TwoFactorRecoveryPage> {
               },
             ),
           ),
-          Padding(padding: EdgeInsets.all(24)),
+          const Padding(padding: EdgeInsets.all(24)),
           Container(
             padding: const EdgeInsets.fromLTRB(80, 0, 80, 0),
             width: double.infinity,
             height: 64,
             child: OutlinedButton(
-              child: Text("Recover"),
               onPressed: _recoveryKey.text.isNotEmpty
                   ? () async {
                       await UserService.instance.removeTwoFactor(
@@ -78,6 +77,7 @@ class _TwoFactorRecoveryPageState extends State<TwoFactorRecoveryPage> {
                       );
                     }
                   : null,
+              child: const Text("Recover"),
             ),
           ),
           GestureDetector(
@@ -90,7 +90,7 @@ class _TwoFactorRecoveryPageState extends State<TwoFactorRecoveryPage> {
               );
             },
             child: Container(
-              padding: EdgeInsets.all(40),
+              padding: const EdgeInsets.all(40),
               child: Center(
                 child: Text(
                   "No recovery key?",

+ 24 - 24
lib/ui/two_factor_setup_page.dart → lib/ui/account/two_factor_setup_page.dart

@@ -1,13 +1,12 @@
 import 'dart:ui';
 
-import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/services/user_service.dart';
+import 'package:photos/ui/account/recovery_key_page.dart';
 import 'package:photos/ui/lifecycle_event_handler.dart';
-import 'package:photos/ui/recovery_key_page.dart';
 import 'package:photos/utils/navigation_util.dart';
 import 'package:photos/utils/toast_util.dart';
 import 'package:pinput/pin_put/pin_put.dart';
@@ -16,10 +15,11 @@ class TwoFactorSetupPage extends StatefulWidget {
   final String secretCode;
   final String qrCode;
 
-  TwoFactorSetupPage(this.secretCode, this.qrCode, {Key key}) : super(key: key);
+  const TwoFactorSetupPage(this.secretCode, this.qrCode, {Key key})
+      : super(key: key);
 
   @override
-  _TwoFactorSetupPageState createState() => _TwoFactorSetupPageState();
+  State<TwoFactorSetupPage> createState() => _TwoFactorSetupPageState();
 }
 
 class _TwoFactorSetupPageState extends State<TwoFactorSetupPage>
@@ -27,7 +27,7 @@ class _TwoFactorSetupPageState extends State<TwoFactorSetupPage>
   TabController _tabController;
   final _pinController = TextEditingController();
   final _pinPutDecoration = BoxDecoration(
-    border: Border.all(color: Color.fromRGBO(45, 194, 98, 1.0)),
+    border: Border.all(color: const Color.fromRGBO(45, 194, 98, 1.0)),
     borderRadius: BorderRadius.circular(15.0),
   );
   String _code = "";
@@ -67,7 +67,7 @@ class _TwoFactorSetupPageState extends State<TwoFactorSetupPage>
     return Scaffold(
       appBar: AppBar(
         elevation: 0,
-        title: Text(
+        title: const Text(
           "Two-factor setup",
         ),
       ),
@@ -102,11 +102,11 @@ class _TwoFactorSetupPageState extends State<TwoFactorSetupPage>
                   ),
                   Expanded(
                     child: TabBarView(
+                      controller: _tabController,
                       children: [
                         _getSecretCode(),
                         _getBarCode(),
                       ],
-                      controller: _tabController,
                     ),
                   ),
                 ],
@@ -134,8 +134,8 @@ class _TwoFactorSetupPageState extends State<TwoFactorSetupPage>
       child: Column(
         mainAxisAlignment: MainAxisAlignment.center,
         children: [
-          Padding(padding: EdgeInsets.all(12)),
-          Text(
+          const Padding(padding: EdgeInsets.all(12)),
+          const Text(
             "Copy-paste this code\nto your authenticator app",
             style: TextStyle(
               height: 1.4,
@@ -143,11 +143,12 @@ class _TwoFactorSetupPageState extends State<TwoFactorSetupPage>
             ),
             textAlign: TextAlign.center,
           ),
-          Padding(padding: EdgeInsets.all(16)),
+          const Padding(padding: EdgeInsets.all(16)),
           Padding(
             padding: const EdgeInsets.only(left: 10, right: 10),
             child: Container(
-              padding: EdgeInsets.all(16),
+              padding: const EdgeInsets.all(16),
+              color: textColor.withOpacity(0.1),
               child: Center(
                 child: Text(
                   widget.secretCode,
@@ -158,10 +159,9 @@ class _TwoFactorSetupPageState extends State<TwoFactorSetupPage>
                   ),
                 ),
               ),
-              color: textColor.withOpacity(0.1),
             ),
           ),
-          Padding(padding: EdgeInsets.all(6)),
+          const Padding(padding: EdgeInsets.all(6)),
           Text(
             "tap to copy",
             style: TextStyle(color: textColor.withOpacity(0.5)),
@@ -175,8 +175,8 @@ class _TwoFactorSetupPageState extends State<TwoFactorSetupPage>
     return Center(
       child: Column(
         children: [
-          Padding(padding: EdgeInsets.all(12)),
-          Text(
+          const Padding(padding: EdgeInsets.all(12)),
+          const Text(
             "Scan this barcode with\nyour authenticator app",
             style: TextStyle(
               height: 1.4,
@@ -184,7 +184,7 @@ class _TwoFactorSetupPageState extends State<TwoFactorSetupPage>
             ),
             textAlign: TextAlign.center,
           ),
-          Padding(padding: EdgeInsets.all(12)),
+          const Padding(padding: EdgeInsets.all(12)),
           Image(
             image: _imageProvider,
             height: 180,
@@ -198,8 +198,8 @@ class _TwoFactorSetupPageState extends State<TwoFactorSetupPage>
   Widget _getVerificationWidget() {
     return Column(
       children: [
-        Padding(padding: EdgeInsets.all(12)),
-        Text(
+        const Padding(padding: EdgeInsets.all(12)),
+        const Text(
           "Enter the 6-digit code from\nyour authenticator app",
           style: TextStyle(
             height: 1.4,
@@ -207,7 +207,7 @@ class _TwoFactorSetupPageState extends State<TwoFactorSetupPage>
           ),
           textAlign: TextAlign.center,
         ),
-        Padding(padding: EdgeInsets.all(16)),
+        const Padding(padding: EdgeInsets.all(16)),
         Padding(
           padding: const EdgeInsets.fromLTRB(40, 0, 40, 0),
           child: PinPut(
@@ -228,26 +228,26 @@ class _TwoFactorSetupPageState extends State<TwoFactorSetupPage>
             followingFieldDecoration: _pinPutDecoration.copyWith(
               borderRadius: BorderRadius.circular(5.0),
               border: Border.all(
-                color: Color.fromRGBO(45, 194, 98, 0.5),
+                color: const Color.fromRGBO(45, 194, 98, 0.5),
               ),
             ),
-            inputDecoration: InputDecoration(
+            inputDecoration: const InputDecoration(
               focusedBorder: InputBorder.none,
               border: InputBorder.none,
               counterText: '',
             ),
           ),
         ),
-        Padding(padding: EdgeInsets.all(24)),
+        const Padding(padding: EdgeInsets.all(24)),
         OutlinedButton(
-          child: Text("Confirm"),
           onPressed: _code.length == 6
               ? () async {
                   _enableTwoFactor(_code);
                 }
               : null,
+          child: const Text("Confirm"),
         ),
-        Padding(padding: EdgeInsets.only(bottom: 24)),
+        const Padding(padding: EdgeInsets.only(bottom: 24)),
       ],
     );
   }

+ 22 - 22
lib/ui/backup_folder_selection_page.dart

@@ -10,8 +10,8 @@ import 'package:photos/db/files_db.dart';
 import 'package:photos/ente_theme_data.dart';
 import 'package:photos/events/backup_folders_updated_event.dart';
 import 'package:photos/models/file.dart';
-import 'package:photos/ui/loading_widget.dart';
-import 'package:photos/ui/thumbnail_widget.dart';
+import 'package:photos/ui/common/loading_widget.dart';
+import 'package:photos/ui/viewer/file/thumbnail_widget.dart';
 
 class BackupFolderSelectionPage extends StatefulWidget {
   final bool isOnboarding;
@@ -24,7 +24,7 @@ class BackupFolderSelectionPage extends StatefulWidget {
   }) : super(key: key);
 
   @override
-  _BackupFolderSelectionPageState createState() =>
+  State<BackupFolderSelectionPage> createState() =>
       _BackupFolderSelectionPageState();
 }
 
@@ -65,17 +65,17 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
           ? null
           : AppBar(
               elevation: 0,
-              title: Text(""),
+              title: const Text(""),
             ),
       body: Column(
         mainAxisAlignment: MainAxisAlignment.center,
         children: [
-          SizedBox(
+          const SizedBox(
             height: 0,
           ),
           SafeArea(
             child: Container(
-              padding: EdgeInsets.fromLTRB(24, 32, 24, 8),
+              padding: const EdgeInsets.fromLTRB(24, 32, 24, 8),
               child: Text(
                 'Select folders for backup',
                 textAlign: TextAlign.left,
@@ -95,7 +95,7 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
               style: Theme.of(context).textTheme.caption.copyWith(height: 1.3),
             ),
           ),
-          Padding(
+          const Padding(
             padding: EdgeInsets.all(10),
           ),
           _latestFiles == null
@@ -111,7 +111,7 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
                             ? "Unselect all"
                             : "Select all",
                         textAlign: TextAlign.right,
-                        style: TextStyle(
+                        style: const TextStyle(
                           decoration: TextDecoration.underline,
                           fontSize: 16,
                         ),
@@ -147,13 +147,13 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
                       BoxShadow(
                         color: Theme.of(context).backgroundColor,
                         blurRadius: 24,
-                        offset: Offset(0, -8),
+                        offset: const Offset(0, -8),
                         spreadRadius: 4,
                       )
                     ],
                   ),
                   padding: widget.isOnboarding
-                      ? EdgeInsets.only(left: 20, right: 20)
+                      ? const EdgeInsets.only(left: 20, right: 20)
                       : EdgeInsets.only(
                           top: 16,
                           left: 20,
@@ -161,7 +161,6 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
                           bottom: Platform.isIOS ? 60 : 32,
                         ),
                   child: OutlinedButton(
-                    child: Text(widget.buttonText),
                     onPressed: _selectedFolders.isEmpty
                         ? null
                         : () async {
@@ -170,6 +169,7 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
                             Bus.instance.fire(BackupFoldersUpdatedEvent());
                             Navigator.of(context).pop();
                           },
+                    child: Text(widget.buttonText),
                   ),
                 ),
               ),
@@ -201,12 +201,12 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
 
   Widget _getFolders() {
     if (_latestFiles == null) {
-      return loadWidget;
+      return const EnteLoadingWidget();
     }
     _sortFiles();
     final scrollController = ScrollController();
     return Container(
-      padding: EdgeInsets.symmetric(horizontal: 20),
+      padding: const EdgeInsets.symmetric(horizontal: 20),
       child: Scrollbar(
         controller: scrollController,
         thumbVisibility: true,
@@ -262,15 +262,15 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
           border: Border.all(
             color: Theme.of(context).colorScheme.boxUnSelectColor,
           ),
-          borderRadius: BorderRadius.all(
+          borderRadius: const BorderRadius.all(
             Radius.circular(12),
           ),
           // color: isSelected
           //     ? Theme.of(context).colorScheme.boxSelectColor
           //     : Theme.of(context).colorScheme.boxUnSelectColor,
           gradient: isSelected
-              ? LinearGradient(
-                  colors: const [Color(0xFF00DD4D), Color(0xFF43BA6C)],
+              ? const LinearGradient(
+                  colors: [Color(0xFF00DD4D), Color(0xFF43BA6C)],
                 ) //same for both themes
               : LinearGradient(
                   colors: [
@@ -279,7 +279,7 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
                   ],
                 ),
         ),
-        padding: EdgeInsets.fromLTRB(8, 4, 4, 4),
+        padding: const EdgeInsets.fromLTRB(8, 4, 4, 4),
         child: InkWell(
           child: Row(
             mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -303,7 +303,7 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
                     crossAxisAlignment: CrossAxisAlignment.start,
                     children: [
                       Container(
-                        constraints: BoxConstraints(maxWidth: 180),
+                        constraints: const BoxConstraints(maxWidth: 180),
                         child: Text(
                           file.deviceFolder,
                           textAlign: TextAlign.left,
@@ -322,7 +322,7 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
                           maxLines: 2,
                         ),
                       ),
-                      Padding(padding: EdgeInsets.only(top: 2)),
+                      const Padding(padding: EdgeInsets.only(top: 2)),
                       Text(
                         _itemCount[file.deviceFolder].toString() +
                             " item" +
@@ -378,6 +378,8 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
     return ClipRRect(
       borderRadius: BorderRadius.circular(8),
       child: SizedBox(
+        height: 88,
+        width: 88,
         child: Stack(
           alignment: AlignmentDirectional.bottomEnd,
           children: [
@@ -389,7 +391,7 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
             Padding(
               padding: const EdgeInsets.all(9),
               child: isSelected
-                  ? Icon(
+                  ? const Icon(
                       Icons.local_police,
                       color: Colors.white,
                     )
@@ -397,8 +399,6 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
             ),
           ],
         ),
-        height: 88,
-        width: 88,
       ),
     );
   }

+ 0 - 36
lib/ui/circular_network_image_widget.dart

@@ -1,36 +0,0 @@
-import 'package:cached_network_image/cached_network_image.dart';
-import 'package:flutter/material.dart';
-import 'package:photos/ui/loading_widget.dart';
-
-class CircularNetworkImageWidget extends StatelessWidget {
-  final String _url;
-  final double _size;
-
-  const CircularNetworkImageWidget(String url, double size, {Key key})
-      : this._url = url,
-        this._size = size,
-        super(key: key);
-
-  @override
-  Widget build(BuildContext context) {
-    return CachedNetworkImage(
-      imageUrl: _url,
-      imageBuilder: (context, imageProvider) => Container(
-        width: _size,
-        height: _size,
-        margin: const EdgeInsets.only(right: 8),
-        decoration: BoxDecoration(
-          shape: BoxShape.circle,
-          image: DecorationImage(
-            image: imageProvider,
-            fit: BoxFit.contain,
-          ),
-        ),
-      ),
-      placeholder: (context, url) => Container(
-        width: _size,
-        child: loadWidget,
-      ),
-    );
-  }
-}

+ 42 - 50
lib/ui/collections_gallery_widget.dart

@@ -18,13 +18,13 @@ import 'package:photos/models/collection_items.dart';
 import 'package:photos/models/device_folder.dart';
 import 'package:photos/models/magic_metadata.dart';
 import 'package:photos/services/collections_service.dart';
-import 'package:photos/ui/archive_page.dart';
-import 'package:photos/ui/collection_page.dart';
-import 'package:photos/ui/common_elements.dart';
-import 'package:photos/ui/device_folder_page.dart';
-import 'package:photos/ui/loading_widget.dart';
-import 'package:photos/ui/thumbnail_widget.dart';
-import 'package:photos/ui/trash_page.dart';
+import 'package:photos/ui/common/loading_widget.dart';
+import 'package:photos/ui/viewer/file/thumbnail_widget.dart';
+import 'package:photos/ui/viewer/gallery/archive_page.dart';
+import 'package:photos/ui/viewer/gallery/collection_page.dart';
+import 'package:photos/ui/viewer/gallery/device_folder_page.dart';
+import 'package:photos/ui/viewer/gallery/empte_state.dart';
+import 'package:photos/ui/viewer/gallery/trash_page.dart';
 import 'package:photos/utils/local_settings.dart';
 import 'package:photos/utils/navigation_util.dart';
 import 'package:photos/utils/toast_util.dart';
@@ -33,7 +33,7 @@ class CollectionsGalleryWidget extends StatefulWidget {
   const CollectionsGalleryWidget({Key key}) : super(key: key);
 
   @override
-  _CollectionsGalleryWidgetState createState() =>
+  State<CollectionsGalleryWidget> createState() =>
       _CollectionsGalleryWidgetState();
 }
 
@@ -84,7 +84,7 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
         } else if (snapshot.hasError) {
           return Text(snapshot.error.toString());
         } else {
-          return loadWidget;
+          return const EnteLoadingWidget();
         }
       },
     );
@@ -150,14 +150,12 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
         child: Column(
           children: [
             const SizedBox(height: 12),
-            SectionTitle("On device"),
+            const SectionTitle("On device"),
             const SizedBox(height: 12),
             items.folders.isEmpty
-                ? Padding(
-                    padding: const EdgeInsets.all(22),
-                    child: nothingToSeeHere(
-                      textColor: Theme.of(context).colorScheme.defaultTextColor,
-                    ),
+                ? const Padding(
+                    padding: EdgeInsets.all(22),
+                    child: EmptyState(),
                   )
                 : Padding(
                     padding: const EdgeInsets.symmetric(horizontal: 8),
@@ -166,16 +164,12 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
                       child: Align(
                         alignment: Alignment.centerLeft,
                         child: items.folders.isEmpty
-                            ? nothingToSeeHere(
-                                textColor: Theme.of(context)
-                                    .colorScheme
-                                    .defaultTextColor,
-                              )
+                            ? const EmptyState()
                             : ListView.builder(
                                 shrinkWrap: true,
                                 scrollDirection: Axis.horizontal,
-                                padding: EdgeInsets.fromLTRB(6, 0, 6, 0),
-                                physics: ScrollPhysics(),
+                                padding: const EdgeInsets.fromLTRB(6, 0, 6, 0),
+                                physics: const ScrollPhysics(),
                                 // to disable GridView's scrolling
                                 itemBuilder: (context, index) {
                                   return DeviceFolderIcon(items.folders[index]);
@@ -191,7 +185,7 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
               mainAxisAlignment: MainAxisAlignment.spaceBetween,
               crossAxisAlignment: CrossAxisAlignment.end,
               children: [
-                EnteSectionTitle(),
+                const EnteSectionTitle(),
                 _sortMenu(),
               ],
             ),
@@ -201,7 +195,7 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
                     padding: const EdgeInsets.symmetric(horizontal: 16),
                     child: GridView.builder(
                       shrinkWrap: true,
-                      physics: ScrollPhysics(),
+                      physics: const ScrollPhysics(),
                       // to disable GridView's scrolling
                       itemBuilder: (context, index) {
                         return _buildCollection(
@@ -221,9 +215,7 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
                       ), //24 is height of album title
                     ),
                   )
-                : nothingToSeeHere(
-                    textColor: Theme.of(context).colorScheme.defaultTextColor,
-                  ),
+                : const EmptyState(),
             const SizedBox(height: 10),
             const Divider(),
             const SizedBox(height: 16),
@@ -237,7 +229,7 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
                       shape: RoundedRectangleBorder(
                         borderRadius: BorderRadius.circular(8),
                       ),
-                      padding: EdgeInsets.all(0),
+                      padding: const EdgeInsets.all(0),
                       side: BorderSide(
                         width: 0.5,
                         color:
@@ -258,7 +250,7 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
                                   Icons.delete,
                                   color: Theme.of(context).iconTheme.color,
                                 ),
-                                Padding(padding: EdgeInsets.all(6)),
+                                const Padding(padding: EdgeInsets.all(6)),
                                 FutureBuilder<int>(
                                   future: TrashDB.instance.count(),
                                   builder: (context, snapshot) {
@@ -273,7 +265,7 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
                                                   .textTheme
                                                   .subtitle1,
                                             ),
-                                            TextSpan(text: "  \u2022  "),
+                                            const TextSpan(text: "  \u2022  "),
                                             TextSpan(
                                               text: snapshot.data.toString(),
                                             ),
@@ -316,21 +308,21 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
                       );
                     },
                   ),
-                  SizedBox(height: 12),
+                  const SizedBox(height: 12),
                   OutlinedButton(
                     style: OutlinedButton.styleFrom(
                       backgroundColor: Theme.of(context).backgroundColor,
                       shape: RoundedRectangleBorder(
                         borderRadius: BorderRadius.circular(8),
                       ),
-                      padding: EdgeInsets.all(0),
+                      padding: const EdgeInsets.all(0),
                       side: BorderSide(
                         width: 0.5,
                         color:
                             Theme.of(context).iconTheme.color.withOpacity(0.24),
                       ),
                     ),
-                    child: Container(
+                    child: SizedBox(
                       height: 48,
                       width: double.infinity,
                       child: Padding(
@@ -344,7 +336,7 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
                                   Icons.visibility_off,
                                   color: Theme.of(context).iconTheme.color,
                                 ),
-                                Padding(padding: EdgeInsets.all(6)),
+                                const Padding(padding: EdgeInsets.all(6)),
                                 FutureBuilder<int>(
                                   future:
                                       FilesDB.instance.fileCountWithVisibility(
@@ -363,7 +355,7 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
                                                   .textTheme
                                                   .subtitle1,
                                             ),
-                                            TextSpan(text: "  \u2022  "),
+                                            const TextSpan(text: "  \u2022  "),
                                             TextSpan(
                                               text: snapshot.data.toString(),
                                             ),
@@ -409,7 +401,7 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
                 ],
               ),
             ),
-            Padding(padding: EdgeInsets.fromLTRB(12, 12, 12, 36)),
+            const Padding(padding: EdgeInsets.fromLTRB(12, 12, 12, 36)),
           ],
         ),
       ),
@@ -441,14 +433,14 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
     return Padding(
       padding: const EdgeInsets.only(right: 24),
       child: PopupMenuButton(
-        offset: Offset(10, 50),
+        offset: const Offset(10, 50),
         initialValue: sortKey?.index ?? 0,
         child: Align(
           child: Row(
             mainAxisAlignment: MainAxisAlignment.end,
             crossAxisAlignment: CrossAxisAlignment.center,
             children: [
-              Padding(
+              const Padding(
                 padding: EdgeInsets.only(left: 5.0),
               ),
               Container(
@@ -495,14 +487,14 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
     } else {
       return InkWell(
         child: Container(
-          margin: EdgeInsets.fromLTRB(30, 30, 30, 54),
+          margin: const EdgeInsets.fromLTRB(30, 30, 30, 54),
           decoration: BoxDecoration(
             color: Theme.of(context).backgroundColor,
             boxShadow: [
               BoxShadow(
                 blurRadius: 2,
                 spreadRadius: 0,
-                offset: Offset(0, 0),
+                offset: const Offset(0, 0),
                 color: Theme.of(context).iconTheme.color.withOpacity(0.3),
               )
             ],
@@ -520,7 +512,7 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
             toastLength: Toast.LENGTH_LONG,
           );
           Bus.instance
-              .fire(TabChangedEvent(0, TabChangedEventSource.collections_page));
+              .fire(TabChangedEvent(0, TabChangedEventSource.collectionsPage));
         },
       );
     }
@@ -579,7 +571,7 @@ class DeviceFolderIcon extends StatelessWidget {
     return GestureDetector(
       child: Padding(
         padding: const EdgeInsets.symmetric(horizontal: 2),
-        child: Container(
+        child: SizedBox(
           height: 140,
           width: 120,
           // padding: const EdgeInsets.all(8.0),
@@ -588,6 +580,8 @@ class DeviceFolderIcon extends StatelessWidget {
               ClipRRect(
                 borderRadius: BorderRadius.circular(4),
                 child: SizedBox(
+                  height: 120,
+                  width: 120,
                   child: Hero(
                     tag:
                         "device_folder:" + folder.path + folder.thumbnail.tag(),
@@ -606,8 +600,6 @@ class DeviceFolderIcon extends StatelessWidget {
                       ],
                     ),
                   ),
-                  height: 120,
-                  width: 120,
                 ),
               ),
               Padding(
@@ -659,6 +651,8 @@ class CollectionItem extends StatelessWidget {
           ClipRRect(
             borderRadius: BorderRadius.circular(4),
             child: SizedBox(
+              height: sideOfThumbnail,
+              width: sideOfThumbnail,
               child: Hero(
                 tag: "collection" + c.thumbnail.tag(),
                 child: ThumbnailWidget(
@@ -669,11 +663,9 @@ class CollectionItem extends StatelessWidget {
                   ),
                 ),
               ),
-              height: sideOfThumbnail,
-              width: sideOfThumbnail,
             ),
           ),
-          SizedBox(height: 4),
+          const SizedBox(height: 4),
           Row(
             children: [
               Container(
@@ -694,7 +686,7 @@ class CollectionItem extends StatelessWidget {
                           color: albumTitleTextStyle.color.withOpacity(0.5),
                         ),
                         children: [
-                          TextSpan(text: "  \u2022  "),
+                          const TextSpan(text: "  \u2022  "),
                           TextSpan(text: snapshot.data.toString()),
                         ],
                       ),
@@ -730,7 +722,7 @@ class SectionTitle extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     return Container(
-      margin: EdgeInsets.fromLTRB(16, 12, 0, 0),
+      margin: const EdgeInsets.fromLTRB(16, 12, 0, 0),
       child: Column(
         children: [
           Align(
@@ -758,7 +750,7 @@ class EnteSectionTitle extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     return Container(
-      margin: EdgeInsets.fromLTRB(16, 12, 0, 0),
+      margin: const EdgeInsets.fromLTRB(16, 12, 0, 0),
       child: Column(
         children: [
           Align(

+ 1 - 3
lib/ui/common/bottomShadow.dart → lib/ui/common/bottom_shadow.dart

@@ -14,9 +14,7 @@ class BottomShadowWidget extends StatelessWidget {
         color: Colors.transparent,
         boxShadow: [
           BoxShadow(
-            color: shadowColor == null
-                ? Theme.of(context).backgroundColor
-                : shadowColor,
+            color: shadowColor ?? Theme.of(context).backgroundColor,
             spreadRadius: 42,
             blurRadius: 42,
             offset: Offset(0, offsetDy), // changes position of shadow

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

@@ -29,7 +29,7 @@ Future<DialogUserChoice> showChoiceDialog<T>(
     ),
     content: Text(
       content,
-      style: TextStyle(
+      style: const TextStyle(
         height: 1.4,
       ),
     ),

+ 10 - 10
lib/ui/common/dynamicFAB.dart → lib/ui/common/dynamic_fab.dart

@@ -9,7 +9,7 @@ class DynamicFAB extends StatelessWidget {
   final String buttonText;
   final Function onPressedFunction;
 
-  DynamicFAB({
+  const DynamicFAB({
     Key key,
     this.isKeypadOpen,
     this.buttonText,
@@ -27,7 +27,7 @@ class DynamicFAB extends StatelessWidget {
               color: Theme.of(context).backgroundColor,
               spreadRadius: 200,
               blurRadius: 100,
-              offset: Offset(0, 230),
+              offset: const Offset(0, 230),
             )
           ],
         ),
@@ -41,18 +41,18 @@ class DynamicFAB extends StatelessWidget {
                   Theme.of(context).colorScheme.dynamicFABBackgroundColor,
               foregroundColor:
                   Theme.of(context).colorScheme.dynamicFABTextColor,
+              onPressed: isFormValid
+                  ? onPressedFunction
+                  : () {
+                      FocusScope.of(context).unfocus();
+                    },
               child: Transform.rotate(
                 angle: isFormValid ? 0 : math.pi / 2,
-                child: Icon(
+                child: const Icon(
                   Icons.chevron_right,
                   size: 36,
                 ),
-              ),
-              onPressed: isFormValid
-                  ? onPressedFunction
-                  : () {
-                      FocusScope.of(context).unfocus();
-                    }, //keypad down here
+              ), //keypad down here
             ),
           ],
         ),
@@ -61,7 +61,7 @@ class DynamicFAB extends StatelessWidget {
       return Container(
         width: double.infinity,
         height: 56,
-        padding: EdgeInsets.symmetric(horizontal: 20),
+        padding: const EdgeInsets.symmetric(horizontal: 20),
         child: OutlinedButton(
           onPressed: isFormValid //var here
               ? onPressedFunction

+ 0 - 30
lib/ui/common/gradientButton.dart

@@ -1,30 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter/widgets.dart';
-
-class GradientButton extends StatelessWidget {
-  final Widget child;
-  final List<Color> linearGradientColors;
-  final Function onTap;
-
-  GradientButton({Key key, this.child, this.linearGradientColors, this.onTap})
-      : super(key: key);
-
-  @override
-  Widget build(BuildContext context) {
-    return InkWell(
-      onTap: onTap,
-      child: Container(
-        height: 56,
-        decoration: BoxDecoration(
-          gradient: LinearGradient(
-            begin: Alignment(0.1, -0.9),
-            end: Alignment(-0.6, 0.9),
-            colors: linearGradientColors,
-          ),
-          borderRadius: BorderRadius.circular(8),
-        ),
-        child: Center(child: child),
-      ),
-    );
-  }
-}

+ 80 - 0
lib/ui/common/gradient_button.dart

@@ -0,0 +1,80 @@
+import 'package:flutter/material.dart';
+
+class GradientButton extends StatelessWidget {
+  final List<Color> linearGradientColors;
+  final Function onTap;
+  final Widget child;
+  // text is ignored if child is specified
+  final String text;
+  // nullable
+  final IconData iconData;
+  // padding between the text and icon
+  final double paddingValue;
+
+  const GradientButton({
+    Key key,
+    this.child,
+    this.linearGradientColors = const [
+      Color(0xFF2CD267),
+      Color(0xFF1DB954),
+    ],
+    this.onTap,
+    this.text,
+    this.iconData,
+    this.paddingValue = 0.0,
+  }) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    Widget buttonContent;
+    if (child != null) {
+      buttonContent = child;
+    } else if (iconData == null) {
+      buttonContent = Text(
+        text,
+        style: const TextStyle(
+          color: Colors.white,
+          fontWeight: FontWeight.w600,
+          fontFamily: 'Inter-SemiBold',
+          fontSize: 18,
+        ),
+      );
+    } else {
+      buttonContent = Row(
+        mainAxisAlignment: MainAxisAlignment.center,
+        crossAxisAlignment: CrossAxisAlignment.center,
+        children: [
+          Icon(
+            iconData,
+            color: Colors.white,
+          ),
+          Padding(padding: EdgeInsets.all(paddingValue)),
+          Text(
+            text,
+            style: const TextStyle(
+              color: Colors.white,
+              fontWeight: FontWeight.w600,
+              fontFamily: 'Inter-SemiBold',
+              fontSize: 18,
+            ),
+          ),
+        ],
+      );
+    }
+    return InkWell(
+      onTap: onTap,
+      child: Container(
+        height: 56,
+        decoration: BoxDecoration(
+          gradient: LinearGradient(
+            begin: const Alignment(0.1, -0.9),
+            end: const Alignment(-0.6, 0.9),
+            colors: linearGradientColors,
+          ),
+          borderRadius: BorderRadius.circular(8),
+        ),
+        child: Center(child: buttonContent),
+      ),
+    );
+  }
+}

+ 1 - 1
lib/ui/linear_progress_dialog.dart → lib/ui/common/linear_progress_dialog.dart

@@ -31,7 +31,7 @@ class LinearProgressDialogState extends State<LinearProgressDialog> {
       child: AlertDialog(
         title: Text(
           widget.message,
-          style: TextStyle(
+          style: const TextStyle(
             fontSize: 16,
           ),
           textAlign: TextAlign.center,

+ 15 - 0
lib/ui/common/loading_widget.dart

@@ -0,0 +1,15 @@
+import 'package:flutter/cupertino.dart';
+
+class EnteLoadingWidget extends StatelessWidget {
+  const EnteLoadingWidget({Key key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return Center(
+      child: SizedBox.fromSize(
+        size: const Size.square(30),
+        child: const CupertinoActivityIndicator(),
+      ),
+    );
+  }
+}

+ 0 - 32
lib/ui/common/onlyOuterShadow.dart

@@ -1,32 +0,0 @@
-import 'package:flutter/material.dart';
-
-class onlyOuterShadow extends BoxShadow {
-  final BlurStyle blurStyle;
-
-  const onlyOuterShadow({
-    Color color = const Color(0xFF000000),
-    Offset offset = Offset.zero,
-    double blurRadius = 0.0,
-    double spreadRadius = 0.0,
-    this.blurStyle = BlurStyle.normal,
-  }) : super(
-          color: color,
-          offset: offset,
-          blurRadius: blurRadius,
-          spreadRadius: spreadRadius,
-        );
-
-  @override
-  Paint toPaint() {
-    final Paint result = Paint()
-      ..color = color
-      ..maskFilter = MaskFilter.blur(this.blurStyle, blurSigma);
-    assert(
-      () {
-        if (debugDisableShadows) result.maskFilter = null;
-        return true;
-      }(),
-    );
-    return result;
-  }
-}

+ 12 - 14
lib/ui/progress_dialog.dart → lib/ui/common/progress_dialog.dart

@@ -1,8 +1,6 @@
-import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter/painting.dart';
 
-enum ProgressDialogType { Normal, Download }
+enum ProgressDialogType { normal, download }
 
 String _dialogMessage = "Loading...";
 double _progress = 0.0, _maxProgress = 100.0;
@@ -20,12 +18,12 @@ ProgressDialogType _progressDialogType;
 bool _barrierDismissible = true, _showLogs = false;
 Color _barrierColor;
 
-TextStyle _progressTextStyle = TextStyle(
+TextStyle _progressTextStyle = const TextStyle(
       color: Colors.black,
       fontSize: 12.0,
       fontWeight: FontWeight.w400,
     ),
-    _messageStyle = TextStyle(
+    _messageStyle = const TextStyle(
       color: Colors.black,
       fontSize: 18.0,
       fontWeight: FontWeight.w600,
@@ -54,7 +52,7 @@ class ProgressDialog {
     Color barrierColor,
   }) {
     _context = context;
-    _progressDialogType = type ?? ProgressDialogType.Normal;
+    _progressDialogType = type ?? ProgressDialogType.normal;
     _barrierDismissible = isDismissible ?? true;
     _showLogs = showLogs ?? false;
     _customBody = customBody ?? null;
@@ -79,7 +77,7 @@ class ProgressDialog {
     Alignment progressWidgetAlignment,
   }) {
     if (_isShowing) return;
-    if (_progressDialogType == ProgressDialogType.Download) {
+    if (_progressDialogType == ProgressDialogType.download) {
       _progress = progress ?? _progress;
     }
 
@@ -107,7 +105,7 @@ class ProgressDialog {
     TextStyle progressTextStyle,
     TextStyle messageTextStyle,
   }) {
-    if (_progressDialogType == ProgressDialogType.Download) {
+    if (_progressDialogType == ProgressDialogType.download) {
       _progress = progress ?? _progress;
     }
 
@@ -145,7 +143,7 @@ class ProgressDialog {
   Future<bool> show() async {
     try {
       if (!_isShowing) {
-        _dialog = new _Body();
+        _dialog = _Body();
         showDialog<dynamic>(
           context: _context,
           barrierDismissible: _barrierDismissible,
@@ -157,7 +155,7 @@ class ProgressDialog {
               child: Dialog(
                 backgroundColor: _backgroundColor,
                 insetAnimationCurve: _insetAnimCurve,
-                insetAnimationDuration: Duration(milliseconds: 100),
+                insetAnimationDuration: const Duration(milliseconds: 100),
                 elevation: _dialogElevation,
                 shape: RoundedRectangleBorder(
                   borderRadius:
@@ -170,7 +168,7 @@ class ProgressDialog {
         );
         // Delaying the function for 200 milliseconds
         // [Default transitionDuration of DialogRoute]
-        await Future.delayed(Duration(milliseconds: 200));
+        await Future.delayed(const Duration(milliseconds: 200));
         if (_showLogs) debugPrint('ProgressDialog shown');
         _isShowing = true;
         return true;
@@ -225,7 +223,7 @@ class _BodyState extends State<_Body> {
     );
 
     final text = Expanded(
-      child: _progressDialogType == ProgressDialogType.Normal
+      child: _progressDialogType == ProgressDialogType.normal
           ? Text(
               _dialogMessage,
               textAlign: _textAlign,
@@ -237,7 +235,7 @@ class _BodyState extends State<_Body> {
               child: Column(
                 mainAxisSize: MainAxisSize.min,
                 children: <Widget>[
-                  SizedBox(height: 8.0),
+                  const SizedBox(height: 8.0),
                   Row(
                     children: <Widget>[
                       Expanded(
@@ -249,7 +247,7 @@ class _BodyState extends State<_Body> {
                       ),
                     ],
                   ),
-                  SizedBox(height: 4.0),
+                  const SizedBox(height: 4.0),
                   Align(
                     alignment: Alignment.bottomRight,
                     child: Text(

+ 5 - 5
lib/ui/rename_dialog.dart → lib/ui/common/rename_dialog.dart

@@ -10,7 +10,7 @@ class RenameDialog extends StatefulWidget {
       : super(key: key);
 
   @override
-  _RenameDialogState createState() => _RenameDialogState();
+  State<RenameDialog> createState() => _RenameDialogState();
 }
 
 class _RenameDialogState extends State<RenameDialog> {
@@ -25,7 +25,7 @@ class _RenameDialogState extends State<RenameDialog> {
   @override
   Widget build(BuildContext context) {
     return AlertDialog(
-      title: Text("Enter a new name"),
+      title: const Text("Enter a new name"),
       content: SingleChildScrollView(
         child: Column(
           mainAxisAlignment: MainAxisAlignment.start,
@@ -34,10 +34,10 @@ class _RenameDialogState extends State<RenameDialog> {
             TextFormField(
               decoration: InputDecoration(
                 hintText: '${widget.type} name',
-                hintStyle: TextStyle(
+                hintStyle: const TextStyle(
                   color: Colors.white30,
                 ),
-                contentPadding: EdgeInsets.all(12),
+                contentPadding: const EdgeInsets.all(12),
               ),
               onChanged: (value) {
                 setState(() {
@@ -54,7 +54,7 @@ class _RenameDialogState extends State<RenameDialog> {
       ),
       actions: [
         TextButton(
-          child: Text(
+          child: const Text(
             "Cancel",
             style: TextStyle(
               color: Colors.redAccent,

+ 6 - 10
lib/ui/web_page.dart → lib/ui/common/web_page.dart

@@ -1,6 +1,6 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_inappwebview/flutter_inappwebview.dart';
-import 'package:photos/ui/loading_widget.dart';
+import 'package:photos/ui/common/loading_widget.dart';
 
 class WebPage extends StatefulWidget {
   final String title;
@@ -9,7 +9,7 @@ class WebPage extends StatefulWidget {
   const WebPage(this.title, this.url, {Key key}) : super(key: key);
 
   @override
-  _WebPageState createState() => _WebPageState();
+  State<WebPage> createState() => _WebPageState();
 }
 
 class _WebPageState extends State<WebPage> {
@@ -19,16 +19,12 @@ class _WebPageState extends State<WebPage> {
   Widget build(BuildContext context) {
     return Scaffold(
       appBar: AppBar(
-        backgroundColor: Color.fromRGBO(
-          10,
-          20,
-          20,
-          1.0,
-        ), // force dark theme for appBar till website/family plans add supports for light theme
+        // force dark theme for appBar till website/family plans add supports for light theme
+        backgroundColor: const Color.fromRGBO(10, 20, 20, 1.0),
         foregroundColor: Colors.white,
-        iconTheme: IconThemeData(color: Colors.white),
+        iconTheme: const IconThemeData(color: Colors.white),
         title: Text(widget.title),
-        actions: [_hasLoadedPage ? Container() : loadWidget],
+        actions: [_hasLoadedPage ? Container() : const EnteLoadingWidget()],
       ),
       backgroundColor: Colors.black,
       body: InAppWebView(

+ 0 - 90
lib/ui/common_elements.dart

@@ -1,90 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter/widgets.dart';
-
-Widget nothingToSeeHere({Color textColor}) {
-  return Center(
-    child: Padding(
-      padding: const EdgeInsets.all(8.0),
-      child: Text(
-        "Nothing to see here! 👀",
-        style: TextStyle(
-          color: textColor.withOpacity(0.35),
-        ),
-      ),
-    ),
-  );
-}
-
-Widget button(
-  String text, {
-  double fontSize = 14,
-  VoidCallback onPressed,
-  double lineHeight,
-  EdgeInsets padding,
-}) {
-  return InkWell(
-    child: OutlinedButton(
-      style: OutlinedButton.styleFrom(
-        shape: RoundedRectangleBorder(
-          borderRadius: BorderRadius.circular(8),
-        ),
-        padding: padding ?? EdgeInsets.fromLTRB(50, 16, 50, 16),
-        textStyle: TextStyle(
-          fontWeight: FontWeight.w600,
-          fontFamily: 'Inter-SemiBold',
-          fontSize: fontSize,
-          height: lineHeight,
-        ),
-      ).copyWith(
-        backgroundColor: MaterialStateProperty.resolveWith<Color>(
-          (Set<MaterialState> states) {
-            if (states.contains(MaterialState.disabled)) {
-              return Colors.grey;
-            }
-            // return Color.fromRGBO(29, 184, 80, 1);
-            return Colors.white;
-          },
-        ),
-        foregroundColor: MaterialStateProperty.resolveWith<Color>(
-          (Set<MaterialState> states) {
-            if (states.contains(MaterialState.disabled)) {
-              return Colors.white;
-            }
-            return Colors.black;
-          },
-        ),
-        alignment: Alignment.center,
-      ),
-      child: Text(text),
-      onPressed: onPressed,
-    ),
-  );
-}
-
-final emptyContainer = const SizedBox.shrink();
-
-Animatable<Color> passwordStrengthColors = TweenSequence<Color>(
-  [
-    TweenSequenceItem(
-      weight: 1.0,
-      tween: ColorTween(
-        begin: Colors.red,
-        end: Colors.yellow,
-      ),
-    ),
-    TweenSequenceItem(
-      weight: 1.0,
-      tween: ColorTween(
-        begin: Colors.yellow,
-        end: Colors.lightGreen,
-      ),
-    ),
-    TweenSequenceItem(
-      weight: 1.0,
-      tween: ColorTween(
-        begin: Colors.lightGreen,
-        end: Color.fromRGBO(45, 194, 98, 1.0),
-      ),
-    ),
-  ],
-);

+ 20 - 39
lib/ui/create_collection_page.dart

@@ -2,17 +2,16 @@ import 'package:flutter/material.dart';
 import 'package:logging/logging.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/db/files_db.dart';
-import 'package:photos/ente_theme_data.dart';
 import 'package:photos/models/collection.dart';
 import 'package:photos/models/collection_items.dart';
 import 'package:photos/models/file.dart';
 import 'package:photos/models/selected_files.dart';
 import 'package:photos/services/collections_service.dart';
 import 'package:photos/services/remote_sync_service.dart';
-import 'package:photos/ui/collection_page.dart';
-import 'package:photos/ui/common/gradientButton.dart';
-import 'package:photos/ui/loading_widget.dart';
-import 'package:photos/ui/thumbnail_widget.dart';
+import 'package:photos/ui/common/gradient_button.dart';
+import 'package:photos/ui/common/loading_widget.dart';
+import 'package:photos/ui/viewer/file/thumbnail_widget.dart';
+import 'package:photos/ui/viewer/gallery/collection_page.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/navigation_util.dart';
 import 'package:photos/utils/share_util.dart';
@@ -51,7 +50,7 @@ class CreateCollectionPage extends StatefulWidget {
   }) : super(key: key);
 
   @override
-  _CreateCollectionPageState createState() => _CreateCollectionPageState();
+  State<CreateCollectionPage> createState() => _CreateCollectionPageState();
 }
 
 class _CreateCollectionPageState extends State<CreateCollectionPage> {
@@ -87,43 +86,25 @@ class _CreateCollectionPageState extends State<CreateCollectionPage> {
                     right: 40,
                   ),
                   child: GradientButton(
-                    child: Row(
-                      mainAxisAlignment: MainAxisAlignment.center,
-                      crossAxisAlignment: CrossAxisAlignment.center,
-                      //mainAxisSize: MainAxisSize.min,
-                      children: [
-                        Icon(
-                          Icons.create_new_folder_outlined,
-                          color: Colors.white,
-                        ),
-                        Padding(padding: EdgeInsets.all(6)),
-                        Text(
-                          "To a new album",
-                          style: gradientButtonTextTheme(),
-                        ),
-                      ],
-                    ),
-                    linearGradientColors: const [
-                      Color(0xFF2CD267),
-                      Color(0xFF1DB954),
-                    ],
                     onTap: () async {
                       _showNameAlbumDialog();
                     },
+                    iconData: Icons.create_new_folder_outlined,
+                    paddingValue: 6,
+                    text: "To a new album",
                   ),
                 ),
               ),
             ],
           ),
-          Padding(
-            padding: const EdgeInsets.fromLTRB(40, 24, 40, 20),
+          const Padding(
+            padding: EdgeInsets.fromLTRB(40, 24, 40, 20),
             child: Align(
               alignment: Alignment.centerLeft,
               child: Text(
                 "To an existing album",
                 style: TextStyle(
                   fontWeight: FontWeight.bold,
-                  // color: Theme.of(context).primaryColorLight.withOpacity(0.8),
                 ),
               ),
             ),
@@ -150,10 +131,10 @@ class _CreateCollectionPageState extends State<CreateCollectionPage> {
             },
             itemCount: snapshot.data.length,
             shrinkWrap: true,
-            physics: NeverScrollableScrollPhysics(),
+            physics: const NeverScrollableScrollPhysics(),
           );
         } else {
-          return loadWidget;
+          return const EnteLoadingWidget();
         }
       },
     );
@@ -161,7 +142,7 @@ class _CreateCollectionPageState extends State<CreateCollectionPage> {
 
   Widget _buildCollectionItem(CollectionWithThumbnail item) {
     return Container(
-      padding: EdgeInsets.only(left: 24, bottom: 16),
+      padding: const EdgeInsets.only(left: 24, bottom: 16),
       child: GestureDetector(
         behavior: HitTestBehavior.translucent,
         child: Row(
@@ -169,17 +150,17 @@ class _CreateCollectionPageState extends State<CreateCollectionPage> {
             ClipRRect(
               borderRadius: BorderRadius.circular(2.0),
               child: SizedBox(
-                child: ThumbnailWidget(item.thumbnail),
                 height: 64,
                 width: 64,
                 key: Key("collection_item:" + item.thumbnail.tag()),
+                child: ThumbnailWidget(item.thumbnail),
               ),
             ),
-            Padding(padding: EdgeInsets.all(8)),
+            const Padding(padding: EdgeInsets.all(8)),
             Expanded(
               child: Text(
                 item.collection.name,
-                style: TextStyle(
+                style: const TextStyle(
                   fontSize: 16,
                 ),
               ),
@@ -221,9 +202,9 @@ class _CreateCollectionPageState extends State<CreateCollectionPage> {
 
   void _showNameAlbumDialog() async {
     AlertDialog alert = AlertDialog(
-      title: Text("Album title"),
+      title: const Text("Album title"),
       content: TextFormField(
-        decoration: InputDecoration(
+        decoration: const InputDecoration(
           hintText: "Christmas 2020 / Dinner at Alice's",
           contentPadding: EdgeInsets.all(8),
         ),
@@ -313,7 +294,7 @@ class _CreateCollectionPageState extends State<CreateCollectionPage> {
       widget.selectedFiles?.clearAll();
 
       return true;
-    } on AssertionError catch (e, s) {
+    } on AssertionError catch (e) {
       await dialog.hide();
       showErrorDialog(context, "Oops", e.message);
       return false;
@@ -335,7 +316,7 @@ class _CreateCollectionPageState extends State<CreateCollectionPage> {
       widget.selectedFiles?.clearAll();
       await dialog.hide();
       return true;
-    } on AssertionError catch (e, s) {
+    } on AssertionError catch (e) {
       await dialog.hide();
       showErrorDialog(context, "Oops", e.message);
       return false;

+ 0 - 232
lib/ui/expansion_card.dart

@@ -1,232 +0,0 @@
-import 'package:flutter/material.dart';
-
-const Duration _kExpand = Duration(milliseconds: 200);
-
-/// A single-line [ListTile] with a trailing button that expands or collapses
-/// the tile to reveal or hide the [children].
-///
-/// This widget is typically used with [ListView] to create an
-/// "expand / collapse" list entry. When used with scrolling widgets like
-/// [ListView], a unique [PageStorageKey] must be specified to enable the
-/// [ExpansionTile] to save and restore its expanded state when it is scrolled
-/// in and out of view.
-///
-/// See also:
-///
-///  * [ListTile], useful for creating expansion tile [children] when the
-///    expansion tile represents a sublist.
-///  * The "Expand/collapse" section of
-///    <https://material.io/guidelines/components/lists-controls.html>.
-class ExpansionCard extends StatefulWidget {
-  /// Creates a single-line [ListTile] with a trailing button that expands or collapses
-  /// the tile to reveal or hide the [children]. The [initiallyExpanded] property must
-  /// be non-null.
-  const ExpansionCard({
-    Key key,
-    this.leading,
-    @required this.title,
-    this.background,
-    this.backgroundColor,
-    this.margin = const EdgeInsets.only(top: 30),
-    this.borderRadius = 30.0,
-    this.onExpansionChanged,
-    this.children = const <Widget>[],
-    this.trailing,
-    this.initiallyExpanded = false,
-    this.color,
-  })  : assert(initiallyExpanded != null),
-        super(key: key);
-
-  /// Adds margin to content of the card.
-  final EdgeInsets margin;
-
-  /// Provides CircularRadius to the border of the card.
-  final double borderRadius;
-
-  /// A widget to add background.
-  /// it can be a gif or image.
-  final Widget background;
-
-  /// A widget to display before the title.
-  ///
-  /// Typically a [CircleAvatar] widget.
-  final Widget leading;
-
-  /// The primary content of the list item.
-  ///
-  /// Typically a [Text] widget.
-  final Widget title;
-
-  /// Called when the tile expands or collapses.
-  ///
-  /// When the tile starts expanding, this function is called with the value
-  /// true. When the tile starts collapsing, this function is called with
-  /// the value false.
-  final ValueChanged<bool> onExpansionChanged;
-
-  /// The widgets that are displayed when the tile expands.
-  ///
-  /// Typically [ListTile] widgets.
-  final List<Widget> children;
-
-  /// The color to display behind the sublist when expanded.
-  final Color backgroundColor;
-
-  /// A widget to display instead of a rotating arrow icon.
-  final Widget trailing;
-
-  /// Specifies if the list tile is initially expanded (true) or collapsed (false, the default).
-  final bool initiallyExpanded;
-
-  /// Color of the expanded heading and icon
-  final Color color;
-
-  @override
-  _ExpansionTileState createState() => _ExpansionTileState();
-}
-
-class _ExpansionTileState extends State<ExpansionCard>
-    with SingleTickerProviderStateMixin {
-  static final Animatable<double> _easeOutTween =
-      CurveTween(curve: Curves.easeOut);
-  static final Animatable<double> _easeInTween =
-      CurveTween(curve: Curves.easeIn);
-  static final Animatable<double> _halfTween =
-      Tween<double>(begin: 0.0, end: 0.5);
-
-  final ColorTween _borderColorTween = ColorTween();
-  final ColorTween _headerColorTween = ColorTween();
-  final ColorTween _iconColorTween = ColorTween();
-  final ColorTween _backgroundColorTween = ColorTween();
-
-  AnimationController _controller;
-  Animation<double> _iconTurns;
-  Animation<double> _heightFactor;
-  Animation<Color> _headerColor;
-  Animation<Color> _iconColor;
-  Animation<Color> _backgroundColor;
-
-  bool _isExpanded = false;
-
-  @override
-  void initState() {
-    super.initState();
-    _controller = AnimationController(duration: _kExpand, vsync: this);
-    _heightFactor = _controller.drive(_easeInTween);
-    _iconTurns = _controller.drive(_halfTween.chain(_easeInTween));
-    _headerColor = _controller.drive(_headerColorTween.chain(_easeInTween));
-    _iconColor = _controller.drive(_iconColorTween.chain(_easeInTween));
-    _backgroundColor =
-        _controller.drive(_backgroundColorTween.chain(_easeOutTween));
-
-    _isExpanded =
-        PageStorage.of(context)?.readState(context) ?? widget.initiallyExpanded;
-    if (_isExpanded) _controller.value = 1.0;
-  }
-
-  @override
-  void dispose() {
-    _controller.dispose();
-    super.dispose();
-  }
-
-  void _handleTap() {
-    setState(() {
-      _isExpanded = !_isExpanded;
-      if (_isExpanded) {
-        _controller.forward();
-      } else {
-        _controller.reverse().then<void>((void value) {
-          if (!mounted) return;
-          setState(() {
-            // Rebuild without widget.children.
-          });
-        });
-      }
-      PageStorage.of(context)?.writeState(context, _isExpanded);
-    });
-    if (widget.onExpansionChanged != null) {
-      widget.onExpansionChanged(_isExpanded);
-    }
-  }
-
-  Widget _buildChildren(BuildContext context, Widget child) {
-    final Color borderSideColor = Colors.transparent; // _borderColor.value ??
-
-    return Stack(
-      children: <Widget>[
-        widget.background == null
-            ? Container()
-            : ClipRRect(
-                borderRadius: BorderRadius.circular(widget.borderRadius),
-                child: Align(
-                  heightFactor:
-                      _heightFactor.value < 0.5 ? 0.5 : _heightFactor.value,
-                  child: widget.background,
-                ),
-              ),
-        Container(
-          decoration: BoxDecoration(
-            color: _backgroundColor.value ?? Colors.transparent,
-            border: Border(
-              top: BorderSide(color: borderSideColor),
-              bottom: BorderSide(color: borderSideColor),
-            ),
-          ),
-          child: Column(
-            mainAxisSize: MainAxisSize.min,
-            children: <Widget>[
-              ListTileTheme.merge(
-                iconColor: _iconColor.value,
-                textColor: _headerColor.value,
-                child: Container(
-                  margin: widget.margin,
-                  child: ListTile(
-                    onTap: _handleTap,
-                    leading: widget.leading,
-                    title: widget.title,
-                    trailing: widget.trailing ??
-                        RotationTransition(
-                          turns: _iconTurns,
-                          child: const Icon(Icons.expand_more),
-                        ),
-                  ),
-                ),
-              ),
-              ClipRect(
-                child: Align(
-                  heightFactor: _heightFactor.value,
-                  child: child,
-                ),
-              ),
-            ],
-          ),
-        )
-      ],
-    );
-  }
-
-  @override
-  void didChangeDependencies() {
-    final ThemeData theme = Theme.of(context);
-    _borderColorTween..end = theme.dividerColor;
-    _headerColorTween
-      ..begin = Colors.white
-      ..end = widget.color ?? Color(0xff60c9df);
-    _iconColorTween
-      ..begin = Colors.white
-      ..end = widget.color ?? Color(0xff60c9df);
-    _backgroundColorTween..end = widget.backgroundColor;
-    super.didChangeDependencies();
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    final bool closed = !_isExpanded && _controller.isDismissed;
-    return AnimatedBuilder(
-      animation: _controller.view,
-      builder: _buildChildren,
-      child: closed ? null : Column(children: widget.children),
-    );
-  }
-}

+ 3 - 3
lib/ui/extents_page_view.dart

@@ -126,7 +126,7 @@ class ExtentsPageView extends StatefulWidget {
   /// ```dart
   /// class MyPageView extends StatefulWidget {
   ///   @override
-  ///   _MyPageViewState createState() => _MyPageViewState();
+  ///   _MyPageView> createState() => _MyPageViewState();
   /// }
   ///
   /// class _MyPageViewState extends State<MyPageView> {
@@ -180,7 +180,7 @@ class ExtentsPageView extends StatefulWidget {
   ///   final String data;
   ///
   ///   @override
-  ///   _KeepAliveState createState() => _KeepAliveState();
+  ///   _KeepAlive> createState() => _KeepAliveState();
   /// }
   ///
   /// class _KeepAliveState extends State<KeepAlive> with AutomaticKeepAliveClientMixin{
@@ -271,7 +271,7 @@ class ExtentsPageView extends StatefulWidget {
   final DragStartBehavior dragStartBehavior;
 
   @override
-  _PageViewState createState() => _PageViewState();
+  State<ExtentsPageView> createState() => _PageViewState();
 }
 
 class _PageViewState extends State<ExtentsPageView> {

+ 8 - 7
lib/ui/grant_permissions_widget.dart

@@ -31,7 +31,8 @@ class GrantPermissionsWidget extends StatelessWidget {
                                 colorBlendMode: BlendMode.modulate,
                               )
                             : Image.asset(
-                                'assets/loading_photos_background_dark.png'),
+                                'assets/loading_photos_background_dark.png',
+                              ),
                         Center(
                           child: Column(
                             children: [
@@ -56,7 +57,7 @@ class GrantPermissionsWidget extends StatelessWidget {
                           .headline5
                           .copyWith(fontWeight: FontWeight.w700),
                       children: [
-                        TextSpan(text: 'ente '),
+                        const TextSpan(text: 'ente '),
                         TextSpan(
                           text: "needs permission to ",
                           style: Theme.of(context)
@@ -64,7 +65,7 @@ class GrantPermissionsWidget extends StatelessWidget {
                               .headline5
                               .copyWith(fontWeight: FontWeight.w400),
                         ),
-                        TextSpan(text: 'preserve your photos'),
+                        const TextSpan(text: 'preserve your photos'),
                       ],
                     ),
                   ),
@@ -81,7 +82,7 @@ class GrantPermissionsWidget extends StatelessWidget {
               color: Theme.of(context).backgroundColor,
               spreadRadius: 190,
               blurRadius: 30,
-              offset: Offset(0, 170),
+              offset: const Offset(0, 170),
             )
           ],
         ),
@@ -92,7 +93,7 @@ class GrantPermissionsWidget extends StatelessWidget {
           bottom: Platform.isIOS ? 40 : 16,
         ),
         child: OutlinedButton(
-          child: Text("Grant permission"),
+          child: const Text("Grant permission"),
           onPressed: () async {
             final state = await PhotoManager.requestPermissionExtend();
             if (state == PermissionState.authorized ||
@@ -100,8 +101,8 @@ class GrantPermissionsWidget extends StatelessWidget {
               await SyncService.instance.onPermissionGranted(state);
             } else if (state == PermissionState.denied) {
               AlertDialog alert = AlertDialog(
-                title: Text("Please grant permissions"),
-                content: Text(
+                title: const Text("Please grant permissions"),
+                content: const Text(
                   "ente can encrypt and preserve files only if you grant access to them",
                 ),
                 actions: [

+ 19 - 19
lib/ui/header_error_widget.dart

@@ -15,7 +15,7 @@ class HeaderErrorWidget extends StatelessWidget {
   Widget build(BuildContext context) {
     if (_error is NoActiveSubscriptionError) {
       return Container(
-        margin: EdgeInsets.only(top: 8),
+        margin: const EdgeInsets.only(top: 8),
         child: Column(
           children: [
             Row(
@@ -30,13 +30,13 @@ class HeaderErrorWidget extends StatelessWidget {
                 Text("Your subscription has expired"),
               ],
             ),
-            Padding(padding: EdgeInsets.all(8)),
+            const Padding(padding: EdgeInsets.all(8)),
             Container(
               width: 400,
               height: 52,
               padding: const EdgeInsets.fromLTRB(80, 0, 80, 0),
               child: OutlinedButton(
-                child: Text("Subscribe"),
+                child: const Text("Subscribe"),
                 onPressed: () {
                   Navigator.of(context).push(
                     MaterialPageRoute(
@@ -48,18 +48,18 @@ class HeaderErrorWidget extends StatelessWidget {
                 },
               ),
             ),
-            Padding(padding: EdgeInsets.all(12)),
-            Divider(
+            const Padding(padding: EdgeInsets.all(12)),
+            const Divider(
               thickness: 2,
               height: 0,
             ),
-            Padding(padding: EdgeInsets.all(12)),
+            const Padding(padding: EdgeInsets.all(12)),
           ],
         ),
       );
     } else if (_error is StorageLimitExceededError) {
       return Container(
-        margin: EdgeInsets.only(top: 8),
+        margin: const EdgeInsets.only(top: 8),
         child: Column(
           children: [
             Row(
@@ -74,13 +74,13 @@ class HeaderErrorWidget extends StatelessWidget {
                 Text("Storage limit exceeded"),
               ],
             ),
-            Padding(padding: EdgeInsets.all(8)),
+            const Padding(padding: EdgeInsets.all(8)),
             Container(
               width: 400,
               height: 52,
               padding: const EdgeInsets.fromLTRB(80, 0, 80, 0),
               child: OutlinedButton(
-                child: Text("Upgrade"),
+                child: const Text("Upgrade"),
                 onPressed: () {
                   Navigator.of(context).push(
                     MaterialPageRoute(
@@ -92,12 +92,12 @@ class HeaderErrorWidget extends StatelessWidget {
                 },
               ),
             ),
-            Padding(padding: EdgeInsets.all(12)),
-            Divider(
+            const Padding(padding: EdgeInsets.all(12)),
+            const Divider(
               thickness: 2,
               height: 0,
             ),
-            Padding(padding: EdgeInsets.all(12)),
+            const Padding(padding: EdgeInsets.all(12)),
           ],
         ),
       );
@@ -109,13 +109,13 @@ class HeaderErrorWidget extends StatelessWidget {
               Icons.error_outline,
               color: Colors.red[400],
             ),
-            Padding(padding: EdgeInsets.all(4)),
-            Text(
+            const Padding(padding: EdgeInsets.all(4)),
+            const Text(
               "We could not backup your data.\nWe will retry later.",
               style: TextStyle(height: 1.4),
               textAlign: TextAlign.center,
             ),
-            Padding(padding: EdgeInsets.all(8)),
+            const Padding(padding: EdgeInsets.all(8)),
             InkWell(
               child: OutlinedButton(
                 style: OutlinedButton.styleFrom(
@@ -124,7 +124,7 @@ class HeaderErrorWidget extends StatelessWidget {
                   shape: RoundedRectangleBorder(
                     borderRadius: BorderRadius.circular(10),
                   ),
-                  padding: EdgeInsets.fromLTRB(50, 16, 50, 16),
+                  padding: const EdgeInsets.fromLTRB(50, 16, 50, 16),
                   side: BorderSide(
                     width: 2,
                     color: Colors.orange[600],
@@ -149,12 +149,12 @@ class HeaderErrorWidget extends StatelessWidget {
                 },
               ),
             ),
-            Padding(padding: EdgeInsets.all(16)),
-            Divider(
+            const Padding(padding: EdgeInsets.all(16)),
+            const Divider(
               thickness: 2,
               height: 0,
             ),
-            Padding(padding: EdgeInsets.all(12)),
+            const Padding(padding: EdgeInsets.all(12)),
           ],
         ),
       );

+ 53 - 57
lib/ui/home_widget.dart

@@ -23,32 +23,32 @@ import 'package:photos/events/tab_changed_event.dart';
 import 'package:photos/events/trigger_logout_event.dart';
 import 'package:photos/events/user_logged_out_event.dart';
 import 'package:photos/models/file_load_result.dart';
-import 'package:photos/models/galleryType.dart';
+import 'package:photos/models/gallery_type.dart';
 import 'package:photos/models/selected_files.dart';
 import 'package:photos/services/collections_service.dart';
 import 'package:photos/services/ignored_files_service.dart';
 import 'package:photos/services/local_sync_service.dart';
 import 'package:photos/services/update_service.dart';
 import 'package:photos/services/user_service.dart';
-import 'package:photos/ui/app_update_dialog.dart';
 import 'package:photos/ui/backup_folder_selection_page.dart';
 import 'package:photos/ui/collections_gallery_widget.dart';
-import 'package:photos/ui/common/bottomShadow.dart';
-import 'package:photos/ui/common/gradientButton.dart';
+import 'package:photos/ui/common/bottom_shadow.dart';
+import 'package:photos/ui/common/gradient_button.dart';
 import 'package:photos/ui/create_collection_page.dart';
 import 'package:photos/ui/extents_page_view.dart';
-import 'package:photos/ui/gallery.dart';
-import 'package:photos/ui/gallery_app_bar_widget.dart';
-import 'package:photos/ui/gallery_footer_widget.dart';
-import 'package:photos/ui/gallery_overlay_widget.dart';
 import 'package:photos/ui/grant_permissions_widget.dart';
 import 'package:photos/ui/landing_page_widget.dart';
 import 'package:photos/ui/loading_photos_widget.dart';
 import 'package:photos/ui/memories_widget.dart';
 import 'package:photos/ui/nav_bar.dart';
+import 'package:photos/ui/settings/app_update_dialog.dart';
 import 'package:photos/ui/settings_page.dart';
 import 'package:photos/ui/shared_collections_gallery.dart';
 import 'package:photos/ui/status_bar_widget.dart';
+import 'package:photos/ui/viewer/gallery/gallery.dart';
+import 'package:photos/ui/viewer/gallery/gallery_app_bar_widget.dart';
+import 'package:photos/ui/viewer/gallery/gallery_footer_widget.dart';
+import 'package:photos/ui/viewer/gallery/gallery_overlay_widget.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/navigation_util.dart';
 import 'package:receive_sharing_intent/receive_sharing_intent.dart';
@@ -78,6 +78,7 @@ class _HomeWidgetState extends State<HomeWidget> {
   Widget _headerWidgetWithSettingsButton;
 
   // for receiving media files
+  // ignore: unused_field
   StreamSubscription _intentDataStreamSubscription;
   List<SharedMediaFile> _sharedFiles;
 
@@ -103,11 +104,11 @@ class _HomeWidgetState extends State<HomeWidget> {
     );
     _tabChangedEventSubscription =
         Bus.instance.on<TabChangedEvent>().listen((event) {
-      if (event.source != TabChangedEventSource.page_view) {
+      if (event.source != TabChangedEventSource.pageView) {
         _selectedTabIndex = event.selectedIndex;
         _pageController.animateToPage(
           event.selectedIndex,
-          duration: Duration(milliseconds: 100),
+          duration: const Duration(milliseconds: 100),
           curve: Curves.easeIn,
         );
       }
@@ -123,8 +124,8 @@ class _HomeWidgetState extends State<HomeWidget> {
     _triggerLogoutEvent =
         Bus.instance.on<TriggerLogoutEvent>().listen((event) async {
       AlertDialog alert = AlertDialog(
-        title: Text("Session expired"),
-        content: Text("Please login again"),
+        title: const Text("Session expired"),
+        content: const Text("Please login again"),
         actions: [
           TextButton(
             child: Text(
@@ -166,14 +167,13 @@ class _HomeWidgetState extends State<HomeWidget> {
     });
     _firstImportEvent =
         Bus.instance.on<SyncStatusUpdate>().listen((event) async {
-      if (mounted &&
-          event.status == SyncStatus.completed_first_gallery_import) {
-        Duration delayInRefresh = Duration(milliseconds: 0);
+      if (mounted && event.status == SyncStatus.completedFirstGalleryImport) {
+        Duration delayInRefresh = const Duration(milliseconds: 0);
         // Loading page will redirect to BackupFolderSelectionPage.
         // To avoid showing folder hook in middle during routing,
         // delay state refresh for home page
         if (!LocalSyncService.instance.hasGrantedLimitedPermissions()) {
-          delayInRefresh = Duration(milliseconds: 250);
+          delayInRefresh = const Duration(milliseconds: 250);
         }
         Future.delayed(
           delayInRefresh,
@@ -225,6 +225,7 @@ class _HomeWidgetState extends State<HomeWidget> {
     _firstImportEvent.cancel();
     _backupFoldersUpdatedEvent.cancel();
     _accountConfiguredEvent.cancel();
+    _intentDataStreamSubscription?.cancel();
     super.dispose();
   }
 
@@ -255,7 +256,7 @@ class _HomeWidgetState extends State<HomeWidget> {
     return WillPopScope(
       child: Scaffold(
         appBar: PreferredSize(
-          preferredSize: Size.fromHeight(0),
+          preferredSize: const Size.fromHeight(0),
           child: Container(),
         ),
         body: _getBody(),
@@ -270,7 +271,7 @@ class _HomeWidgetState extends State<HomeWidget> {
           }
         } else {
           Bus.instance
-              .fire(TabChangedEvent(0, TabChangedEventSource.back_button));
+              .fire(TabChangedEvent(0, TabChangedEventSource.backButton));
           return false;
         }
       },
@@ -279,13 +280,13 @@ class _HomeWidgetState extends State<HomeWidget> {
 
   Widget _getBody() {
     if (!Configuration.instance.hasConfiguredAccount()) {
-      return LandingPageWidget();
+      return const LandingPageWidget();
     }
     if (!LocalSyncService.instance.hasGrantedPermissions()) {
-      return GrantPermissionsWidget();
+      return const GrantPermissionsWidget();
     }
     if (!LocalSyncService.instance.hasCompletedFirstImport()) {
-      return LoadingPhotosWidget();
+      return const LoadingPhotosWidget();
     }
     if (_sharedFiles != null && _sharedFiles.isNotEmpty) {
       ReceiveSharingIntent.reset();
@@ -299,29 +300,32 @@ class _HomeWidgetState extends State<HomeWidget> {
     return Stack(
       children: [
         ExtentsPageView(
-          children: [
-            showBackupFolderHook
-                ? _getBackupFolderSelectionHook()
-                : _getMainGalleryWidget(),
-            _deviceFolderGalleryWidget,
-            _sharedCollectionGallery,
-            _settingsPage,
-          ],
           onPageChanged: (page) {
             Bus.instance.fire(
               TabChangedEvent(
                 page,
-                TabChangedEventSource.page_view,
+                TabChangedEventSource.pageView,
               ),
             );
           },
           controller: _pageController,
+          children: [
+            showBackupFolderHook
+                ? _getBackupFolderSelectionHook()
+                : _getMainGalleryWidget(),
+            _deviceFolderGalleryWidget,
+            _sharedCollectionGallery,
+            _settingsPage,
+          ],
+        ),
+        const Align(
+          alignment: Alignment.bottomCenter,
+          child: BottomShadowWidget(),
         ),
-        Align(alignment: Alignment.bottomCenter, child: BottomShadowWidget()),
         Align(
           alignment: Alignment.bottomCenter,
           child: SafeArea(
-            minimum: EdgeInsets.only(bottom: 8),
+            minimum: const EdgeInsets.only(bottom: 8),
             child: HomeBottomNavigationBar(
               _selectedFiles,
               selectedTabIndex: _selectedTabIndex,
@@ -443,7 +447,7 @@ class _HomeWidgetState extends State<HomeWidget> {
       tagPrefix: "home_gallery",
       selectedFiles: _selectedFiles,
       header: header,
-      footer: GalleryFooterWidget(),
+      footer: const GalleryFooterWidget(),
     );
     return Stack(
       children: [
@@ -484,14 +488,6 @@ class _HomeWidgetState extends State<HomeWidget> {
                 height: 64,
                 padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
                 child: GradientButton(
-                  child: Text(
-                    'Start backup',
-                    style: gradientButtonTextTheme(),
-                  ),
-                  linearGradientColors: const [
-                    Color(0xFF2CD267),
-                    Color(0xFF1DB954),
-                  ],
                   onTap: () async {
                     if (LocalSyncService.instance
                         .hasGrantedLimitedPermissions()) {
@@ -499,18 +495,19 @@ class _HomeWidgetState extends State<HomeWidget> {
                     } else {
                       routeToPage(
                         context,
-                        BackupFolderSelectionPage(
+                        const BackupFolderSelectionPage(
                           buttonText: "Start backup",
                         ),
                       );
                     }
                   },
+                  text: "Start backup",
                 ),
               ),
             ),
           ),
         ),
-        Padding(padding: EdgeInsets.all(50)),
+        const Padding(padding: EdgeInsets.all(50)),
       ],
     );
   }
@@ -525,7 +522,7 @@ class HomePageAppBar extends StatefulWidget {
   final SelectedFiles selectedFiles;
 
   @override
-  _HomePageAppBarState createState() => _HomePageAppBarState();
+  State<HomePageAppBar> createState() => _HomePageAppBarState();
 }
 
 class _HomePageAppBarState extends State<HomePageAppBar> {
@@ -566,13 +563,12 @@ class HomeBottomNavigationBar extends StatefulWidget {
   final int selectedTabIndex;
 
   @override
-  _HomeBottomNavigationBarState createState() =>
+  State<HomeBottomNavigationBar> createState() =>
       _HomeBottomNavigationBarState();
 }
 
 class _HomeBottomNavigationBarState extends State<HomeBottomNavigationBar> {
   StreamSubscription<TabChangedEvent> _tabChangedEventSubscription;
-  final _logger = Logger((_HomeBottomNavigationBarState).toString());
   int currentTabIndex = 0;
 
   @override
@@ -584,7 +580,7 @@ class _HomeBottomNavigationBarState extends State<HomeBottomNavigationBar> {
     });
     _tabChangedEventSubscription =
         Bus.instance.on<TabChangedEvent>().listen((event) {
-      if (event.source != TabChangedEventSource.tab_bar) {
+      if (event.source != TabChangedEventSource.tabBar) {
         debugPrint('index changed to ${event.selectedIndex}');
         if (mounted) {
           setState(() {
@@ -605,7 +601,7 @@ class _HomeBottomNavigationBarState extends State<HomeBottomNavigationBar> {
     Bus.instance.fire(
       TabChangedEvent(
         index,
-        TabChangedEventSource.tab_bar,
+        TabChangedEventSource.tabBar,
       ),
     );
   }
@@ -614,11 +610,11 @@ class _HomeBottomNavigationBarState extends State<HomeBottomNavigationBar> {
   Widget build(BuildContext context) {
     bool filesAreSelected = widget.selectedFiles.files.isNotEmpty;
     return AnimatedContainer(
-      duration: Duration(milliseconds: 300),
+      duration: const Duration(milliseconds: 300),
       curve: Curves.easeInOut,
       height: filesAreSelected ? 0 : 52,
       child: AnimatedOpacity(
-        duration: Duration(milliseconds: 100),
+        duration: const Duration(milliseconds: 100),
         opacity: filesAreSelected ? 0.0 : 1.0,
         curve: Curves.easeIn,
         child: IgnorePointer(
@@ -649,8 +645,8 @@ class _HomeBottomNavigationBarState extends State<HomeBottomNavigationBar> {
                                 .colorScheme
                                 .gNavBarActiveColor,
                             iconSize: 24,
-                            padding: EdgeInsets.fromLTRB(16, 8, 16, 8),
-                            duration: Duration(milliseconds: 200),
+                            padding: const EdgeInsets.fromLTRB(16, 8, 16, 8),
+                            duration: const Duration(milliseconds: 200),
                             gap: 0,
                             tabBorderRadius: 24,
                             tabBackgroundColor: Theme.of(context)
@@ -659,7 +655,7 @@ class _HomeBottomNavigationBarState extends State<HomeBottomNavigationBar> {
                             haptic: false,
                             tabs: [
                               GButton(
-                                margin: EdgeInsets.fromLTRB(6, 6, 0, 6),
+                                margin: const EdgeInsets.fromLTRB(6, 6, 0, 6),
                                 icon: Icons.home,
                                 iconColor:
                                     Theme.of(context).colorScheme.gNavIconColor,
@@ -674,7 +670,7 @@ class _HomeBottomNavigationBarState extends State<HomeBottomNavigationBar> {
                                 },
                               ),
                               GButton(
-                                margin: EdgeInsets.fromLTRB(0, 6, 0, 6),
+                                margin: const EdgeInsets.fromLTRB(0, 6, 0, 6),
                                 icon: Icons.photo_library,
                                 iconColor:
                                     Theme.of(context).colorScheme.gNavIconColor,
@@ -689,7 +685,7 @@ class _HomeBottomNavigationBarState extends State<HomeBottomNavigationBar> {
                                 },
                               ),
                               GButton(
-                                margin: EdgeInsets.fromLTRB(0, 6, 0, 6),
+                                margin: const EdgeInsets.fromLTRB(0, 6, 0, 6),
                                 icon: Icons.folder_shared,
                                 iconColor:
                                     Theme.of(context).colorScheme.gNavIconColor,
@@ -704,7 +700,7 @@ class _HomeBottomNavigationBarState extends State<HomeBottomNavigationBar> {
                                 },
                               ),
                               GButton(
-                                margin: EdgeInsets.fromLTRB(0, 6, 6, 6),
+                                margin: const EdgeInsets.fromLTRB(0, 6, 6, 6),
                                 icon: Icons.person,
                                 iconColor:
                                     Theme.of(context).colorScheme.gNavIconColor,
@@ -752,8 +748,8 @@ class HeaderWidget extends StatelessWidget {
       _memoriesWidget,
     ];
     return Column(
-      children: list,
       crossAxisAlignment: CrossAxisAlignment.start,
+      children: list,
     );
   }
 }

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

@@ -18,7 +18,7 @@ class DraggableScrollbar extends StatefulWidget {
   final String Function(int) labelTextBuilder;
   final bool isEnabled;
 
-  DraggableScrollbar({
+  const DraggableScrollbar({
     Key key,
     @required this.child,
     this.backgroundColor = Colors.white,
@@ -39,8 +39,8 @@ class DraggableScrollbar extends StatefulWidget {
 
 class DraggableScrollbarState extends State<DraggableScrollbar>
     with TickerProviderStateMixin {
-  static final thumbAnimationDuration = Duration(milliseconds: 1000);
-  static final labelAnimationDuration = Duration(milliseconds: 1000);
+  static const thumbAnimationDuration = Duration(milliseconds: 1000);
+  static const labelAnimationDuration = Duration(milliseconds: 1000);
   double thumbOffset = 0.0;
   bool isDragging = false;
   int currentFirstIndex;
@@ -194,28 +194,28 @@ class DraggableScrollbarState extends State<DraggableScrollbar>
         onDragUpdate(
           DragUpdateDetails(
             globalPosition: Offset.zero,
-            delta: Offset(0, 2),
+            delta: const Offset(0, 2),
           ),
         );
       } else if (value.logicalKey == LogicalKeyboardKey.arrowUp) {
         onDragUpdate(
           DragUpdateDetails(
             globalPosition: Offset.zero,
-            delta: Offset(0, -2),
+            delta: const Offset(0, -2),
           ),
         );
       } else if (value.logicalKey == LogicalKeyboardKey.pageDown) {
         onDragUpdate(
           DragUpdateDetails(
             globalPosition: Offset.zero,
-            delta: Offset(0, 25),
+            delta: const Offset(0, 25),
           ),
         );
       } else if (value.logicalKey == LogicalKeyboardKey.pageUp) {
         onDragUpdate(
           DragUpdateDetails(
             globalPosition: Offset.zero,
-            delta: Offset(0, -25),
+            delta: const Offset(0, -25),
           ),
         );
       }

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

@@ -54,7 +54,7 @@ class HugeListView<T> extends StatefulWidget {
 
   final bool isDraggableScrollbarEnabled;
 
-  HugeListView({
+  const HugeListView({
     Key key,
     this.controller,
     @required this.startIndex,

+ 12 - 11
lib/ui/huge_listview/lazy_loading_gallery.dart

@@ -1,6 +1,5 @@
 import 'dart:async';
 import 'dart:math';
-import 'dart:ui';
 
 import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
@@ -10,10 +9,10 @@ import 'package:photos/core/constants.dart';
 import 'package:photos/events/files_updated_event.dart';
 import 'package:photos/models/file.dart';
 import 'package:photos/models/selected_files.dart';
-import 'package:photos/ui/detail_page.dart';
-import 'package:photos/ui/gallery.dart';
 import 'package:photos/ui/huge_listview/place_holder_widget.dart';
-import 'package:photos/ui/thumbnail_widget.dart';
+import 'package:photos/ui/viewer/file/detail_page.dart';
+import 'package:photos/ui/viewer/file/thumbnail_widget.dart';
+import 'package:photos/ui/viewer/gallery/gallery.dart';
 import 'package:photos/utils/date_time_util.dart';
 import 'package:photos/utils/navigation_util.dart';
 import 'package:visibility_detector/visibility_detector.dart';
@@ -43,7 +42,7 @@ class LazyLoadingGallery extends StatefulWidget {
   }) : super(key: key ?? UniqueKey());
 
   @override
-  _LazyLoadingGalleryState createState() => _LazyLoadingGalleryState();
+  State<LazyLoadingGallery> createState() => _LazyLoadingGalleryState();
 }
 
 class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
@@ -170,7 +169,9 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
         LazyLoadingGridView(
           widget.tag,
           _files.sublist(
-              index, min(index + kSubGalleryItemLimit, _files.length)),
+            index,
+            min(index + kSubGalleryItemLimit, _files.length),
+          ),
           widget.asyncLoader,
           widget.selectedFiles,
           index == 0,
@@ -204,7 +205,7 @@ class LazyLoadingGridView extends StatefulWidget {
   }) : super(key: key ?? UniqueKey());
 
   @override
-  _LazyLoadingGridViewState createState() => _LazyLoadingGridViewState();
+  State<LazyLoadingGridView> createState() => _LazyLoadingGridViewState();
 }
 
 class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
@@ -283,15 +284,15 @@ class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
     return GridView.builder(
       shrinkWrap: true,
       physics:
-          NeverScrollableScrollPhysics(), // to disable GridView's scrolling
+          const NeverScrollableScrollPhysics(), // to disable GridView's scrolling
       itemBuilder: (context, index) {
         return _buildFile(context, widget.files[index]);
       },
       itemCount: widget.files.length,
-      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
+      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
         crossAxisCount: 4,
       ),
-      padding: EdgeInsets.all(0),
+      padding: const EdgeInsets.all(0),
     );
   }
 
@@ -337,7 +338,7 @@ class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
               ),
               Visibility(
                 visible: widget.selectedFiles.isFileSelected(file),
-                child: Positioned(
+                child: const Positioned(
                   right: 4,
                   top: 4,
                   child: Icon(

+ 4 - 4
lib/ui/huge_listview/place_holder_widget.dart

@@ -8,15 +8,15 @@ class PlaceHolderWidget extends StatelessWidget {
 
   final int count;
 
-  static final _gridViewCache = Map<int, GridView>();
+  static final _gridViewCache = <int, GridView>{};
 
   @override
   Widget build(BuildContext context) {
     if (!_gridViewCache.containsKey(count)) {
       _gridViewCache[count] = GridView.builder(
-        padding: EdgeInsets.all(0),
+        padding: const EdgeInsets.all(0),
         shrinkWrap: true,
-        physics: NeverScrollableScrollPhysics(),
+        physics: const NeverScrollableScrollPhysics(),
         itemBuilder: (context, index) {
           return Container(
             margin: const EdgeInsets.all(2.0),
@@ -24,7 +24,7 @@ class PlaceHolderWidget extends StatelessWidget {
           );
         },
         itemCount: count,
-        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
+        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
           crossAxisCount: 4,
         ),
       );

+ 15 - 15
lib/ui/huge_listview/scroll_bar_thumb.dart

@@ -1,12 +1,12 @@
 import 'package:flutter/material.dart';
 
 class ScrollBarThumb extends StatelessWidget {
-  final backgroundColor;
-  final drawColor;
-  final height;
-  final title;
-  final labelAnimation;
-  final thumbAnimation;
+  final Color backgroundColor;
+  final Color drawColor;
+  final double height;
+  final String title;
+  final Animation labelAnimation;
+  final Animation thumbAnimation;
   final Function(DragStartDetails details) onDragStart;
   final Function(DragUpdateDetails details) onDragUpdate;
   final Function(DragEndDetails details) onDragEnd;
@@ -32,7 +32,7 @@ class ScrollBarThumb extends StatelessWidget {
         FadeTransition(
           opacity: labelAnimation,
           child: Container(
-            padding: EdgeInsets.fromLTRB(20, 12, 20, 12),
+            padding: const EdgeInsets.fromLTRB(20, 12, 20, 12),
             decoration: BoxDecoration(
               borderRadius: BorderRadius.circular(10),
               color: backgroundColor,
@@ -48,7 +48,7 @@ class ScrollBarThumb extends StatelessWidget {
             ),
           ),
         ),
-        Padding(
+        const Padding(
           padding: EdgeInsets.all(12),
         ),
         GestureDetector(
@@ -61,15 +61,15 @@ class ScrollBarThumb extends StatelessWidget {
               foregroundPainter: _ArrowCustomPainter(drawColor),
               child: Material(
                 elevation: 4.0,
-                child: Container(
-                  constraints: BoxConstraints.tight(Size(height * 0.6, height)),
-                ),
                 color: backgroundColor,
                 borderRadius: BorderRadius.only(
                   topLeft: Radius.circular(height),
                   bottomLeft: Radius.circular(height),
-                  topRight: Radius.circular(4.0),
-                  bottomRight: Radius.circular(4.0),
+                  topRight: const Radius.circular(4.0),
+                  bottomRight: const Radius.circular(4.0),
+                ),
+                child: Container(
+                  constraints: BoxConstraints.tight(Size(height * 0.6, height)),
                 ),
               ),
             ),
@@ -143,8 +143,8 @@ class SlideFadeTransition extends StatelessWidget {
       builder: (context, child) => animation.value == 0.0 ? Container() : child,
       child: SlideTransition(
         position: Tween(
-          begin: Offset(0.3, 0.0),
-          end: Offset(0.0, 0.0),
+          begin: const Offset(0.3, 0.0),
+          end: const Offset(0.0, 0.0),
         ).animate(animation),
         child: FadeTransition(
           opacity: animation,

+ 32 - 39
lib/ui/landing_page_widget.dart

@@ -4,18 +4,18 @@ import 'package:dots_indicator/dots_indicator.dart';
 import 'package:flutter/material.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/ente_theme_data.dart';
-import 'package:photos/ui/common/gradientButton.dart';
-import 'package:photos/ui/email_entry_page.dart';
-import 'package:photos/ui/login_page.dart';
-import 'package:photos/ui/password_entry_page.dart';
-import 'package:photos/ui/password_reentry_page.dart';
+import 'package:photos/ui/account/email_entry_page.dart';
+import 'package:photos/ui/account/login_page.dart';
+import 'package:photos/ui/account/password_entry_page.dart';
+import 'package:photos/ui/account/password_reentry_page.dart';
+import 'package:photos/ui/common/gradient_button.dart';
 import 'package:photos/ui/payment/subscription.dart';
 
 class LandingPageWidget extends StatefulWidget {
   const LandingPageWidget({Key key}) : super(key: key);
 
   @override
-  _LandingPageWidgetState createState() => _LandingPageWidgetState();
+  State<LandingPageWidget> createState() => _LandingPageWidgetState();
 }
 
 class _LandingPageWidgetState extends State<LandingPageWidget> {
@@ -31,8 +31,8 @@ class _LandingPageWidgetState extends State<LandingPageWidget> {
       child: SingleChildScrollView(
         child: Column(
           children: [
-            Padding(padding: const EdgeInsets.all(12)),
-            Text(
+            const Padding(padding: EdgeInsets.all(12)),
+            const Text(
               "ente",
               style: TextStyle(
                 fontWeight: FontWeight.bold,
@@ -40,11 +40,11 @@ class _LandingPageWidgetState extends State<LandingPageWidget> {
                 fontSize: 42,
               ),
             ),
-            Padding(
+            const Padding(
               padding: EdgeInsets.all(28),
             ),
             _getFeatureSlider(),
-            Padding(
+            const Padding(
               padding: EdgeInsets.all(12),
             ),
             DotsIndicator(
@@ -60,34 +60,34 @@ class _LandingPageWidgetState extends State<LandingPageWidget> {
                 shape: RoundedRectangleBorder(
                   borderRadius: BorderRadius.circular(3),
                 ),
-                size: Size(100, 5),
-                activeSize: Size(100, 5),
-                spacing: EdgeInsets.all(3),
+                size: const Size(100, 5),
+                activeSize: const Size(100, 5),
+                spacing: const EdgeInsets.all(3),
               ),
             ),
-            Padding(
+            const Padding(
               padding: EdgeInsets.all(28),
             ),
             _getSignUpButton(context),
             Container(
               width: double.infinity,
-              padding: EdgeInsets.fromLTRB(20, 12, 20, 28),
+              padding: const EdgeInsets.fromLTRB(20, 12, 20, 28),
               child: Hero(
                 tag: "log_in",
                 child: ElevatedButton(
                   style:
                       Theme.of(context).colorScheme.optionalActionButtonStyle,
-                  child: Text(
+                  onPressed: _navigateToSignInPage,
+                  child: const Text(
                     "Existing user",
                     style: TextStyle(
                       color: Colors.black, // same for both themes
                     ),
                   ),
-                  onPressed: _navigateToSignInPage,
                 ),
               ),
             ),
-            Padding(
+            const Padding(
               padding: EdgeInsets.all(20),
             ),
           ],
@@ -99,33 +99,26 @@ class _LandingPageWidgetState extends State<LandingPageWidget> {
   Widget _getSignUpButton(BuildContext context) {
     return Container(
       width: double.infinity,
-      padding: EdgeInsets.symmetric(horizontal: 20),
+      padding: const EdgeInsets.symmetric(horizontal: 20),
       child: GradientButton(
-        child: Text(
-          "New to ente",
-          style: gradientButtonTextTheme(),
-        ),
-        linearGradientColors: const [
-          Color(0xFF2CD267),
-          Color(0xFF1DB954),
-        ],
         onTap: _navigateToSignUpPage,
+        text: "New to ente",
       ),
     );
   }
 
   Widget _getFeatureSlider() {
     return ConstrainedBox(
-      constraints: BoxConstraints(maxHeight: 320),
+      constraints: const BoxConstraints(maxHeight: 320),
       child: PageView(
         children: [
-          FeatureItemWidget(
+          const FeatureItemWidget(
             "assets/onboarding_lock.png",
             "Private backups",
             "for your memories",
             "End-to-end encrypted by default",
           ),
-          FeatureItemWidget(
+          const FeatureItemWidget(
             "assets/onboarding_safe.png",
             "Safely stored",
             "at a fallout shelter",
@@ -152,15 +145,15 @@ class _LandingPageWidgetState extends State<LandingPageWidget> {
   void _navigateToSignUpPage() {
     Widget page;
     if (Configuration.instance.getEncryptedToken() == null) {
-      page = EmailEntryPage();
+      page = const EmailEntryPage();
     } else {
       // No key
       if (Configuration.instance.getKeyAttributes() == null) {
         // Never had a key
-        page = PasswordEntryPage();
+        page = const PasswordEntryPage();
       } else if (Configuration.instance.getKey() == null) {
         // Yet to decrypt the key
-        page = PasswordReentryPage();
+        page = const PasswordReentryPage();
       } else {
         // All is well, user just has not subscribed
         page = getSubscriptionPage(isOnBoarding: true);
@@ -178,15 +171,15 @@ class _LandingPageWidgetState extends State<LandingPageWidget> {
   void _navigateToSignInPage() {
     Widget page;
     if (Configuration.instance.getEncryptedToken() == null) {
-      page = LoginPage();
+      page = const LoginPage();
     } else {
       // No key
       if (Configuration.instance.getKeyAttributes() == null) {
         // Never had a key
-        page = PasswordEntryPage();
+        page = const PasswordEntryPage();
       } else if (Configuration.instance.getKey() == null) {
         // Yet to decrypt the key
-        page = PasswordReentryPage();
+        page = const PasswordReentryPage();
       } else {
         // All is well, user just has not subscribed
         page = getSubscriptionPage(isOnBoarding: true);
@@ -225,7 +218,7 @@ class FeatureItemWidget extends StatelessWidget {
           assetPath,
           height: 160,
         ),
-        Padding(padding: EdgeInsets.all(16)),
+        const Padding(padding: EdgeInsets.all(16)),
         Column(
           crossAxisAlignment: CrossAxisAlignment.center,
           mainAxisAlignment: MainAxisAlignment.start,
@@ -234,12 +227,12 @@ class FeatureItemWidget extends StatelessWidget {
               featureTitleFirstLine,
               style: Theme.of(context).textTheme.headline5,
             ),
-            Padding(padding: EdgeInsets.all(2)),
+            const Padding(padding: EdgeInsets.all(2)),
             Text(
               featureTitleSecondLine,
               style: Theme.of(context).textTheme.headline5,
             ),
-            Padding(padding: EdgeInsets.all(12)),
+            const Padding(padding: EdgeInsets.all(12)),
             Text(
               subText,
               textAlign: TextAlign.center,

+ 8 - 9
lib/ui/loading_photos_widget.dart

@@ -7,14 +7,14 @@ import 'package:photos/ente_theme_data.dart';
 import 'package:photos/events/sync_status_update_event.dart';
 import 'package:photos/services/local_sync_service.dart';
 import 'package:photos/ui/backup_folder_selection_page.dart';
-import 'package:photos/ui/common/bottomShadow.dart';
+import 'package:photos/ui/common/bottom_shadow.dart';
 import 'package:photos/utils/navigation_util.dart';
 
 class LoadingPhotosWidget extends StatefulWidget {
   const LoadingPhotosWidget({Key key}) : super(key: key);
 
   @override
-  _LoadingPhotosWidgetState createState() => _LoadingPhotosWidgetState();
+  State<LoadingPhotosWidget> createState() => _LoadingPhotosWidgetState();
 }
 
 class _LoadingPhotosWidgetState extends State<LoadingPhotosWidget> {
@@ -39,14 +39,13 @@ class _LoadingPhotosWidgetState extends State<LoadingPhotosWidget> {
     super.initState();
     _firstImportEvent =
         Bus.instance.on<SyncStatusUpdate>().listen((event) async {
-      if (mounted &&
-          event.status == SyncStatus.completed_first_gallery_import) {
+      if (mounted && event.status == SyncStatus.completedFirstGalleryImport) {
         if (LocalSyncService.instance.hasGrantedLimitedPermissions()) {
           // Do nothing, let HomeWidget refresh
         } else {
           routeToPage(
             context,
-            BackupFolderSelectionPage(
+            const BackupFolderSelectionPage(
               isOnboarding: true,
               buttonText: "Start backup",
             ),
@@ -54,7 +53,7 @@ class _LoadingPhotosWidgetState extends State<LoadingPhotosWidget> {
         }
       }
     });
-    Timer.periodic(Duration(seconds: 5), (Timer timer) {
+    Timer.periodic(const Duration(seconds: 5), (Timer timer) {
       if (!mounted) {
         return;
       }
@@ -66,7 +65,7 @@ class _LoadingPhotosWidgetState extends State<LoadingPhotosWidget> {
 
       _pageController.animateToPage(
         _currentPage,
-        duration: Duration(milliseconds: 300),
+        duration: const Duration(milliseconds: 300),
         curve: Curves.easeIn,
       );
     });
@@ -150,9 +149,9 @@ class _LoadingPhotosWidgetState extends State<LoadingPhotosWidget> {
                               return _getMessage(_messages[index]);
                             },
                             itemCount: _messages.length,
-                            physics: NeverScrollableScrollPhysics(),
+                            physics: const NeverScrollableScrollPhysics(),
                           ),
-                          Positioned(
+                          const Positioned(
                             bottom: 0,
                             left: 0,
                             right: 0,

+ 0 - 9
lib/ui/loading_widget.dart

@@ -1,9 +0,0 @@
-import 'package:flutter/cupertino.dart';
-import 'package:flutter/material.dart';
-
-final loadWidget = Center(
-  child: SizedBox.fromSize(
-    size: Size.square(30),
-    child: CupertinoActivityIndicator(),
-  ),
-);

+ 17 - 17
lib/ui/memories_widget.dart

@@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
 import 'package:photos/models/memory.dart';
 import 'package:photos/services/memories_service.dart';
 import 'package:photos/ui/extents_page_view.dart';
-import 'package:photos/ui/file_widget.dart';
-import 'package:photos/ui/thumbnail_widget.dart';
+import 'package:photos/ui/viewer/file/file_widget.dart';
+import 'package:photos/ui/viewer/file/thumbnail_widget.dart';
 import 'package:photos/utils/date_time_util.dart';
 import 'package:photos/utils/file_util.dart';
 import 'package:photos/utils/navigation_util.dart';
@@ -25,7 +25,7 @@ class MemoriesWidget extends StatelessWidget {
             crossAxisAlignment: CrossAxisAlignment.start,
             children: [
               _buildMemories(snapshot.data),
-              Divider(),
+              const Divider(),
             ],
           );
         }
@@ -106,7 +106,7 @@ class _MemoryWidgetState extends State<MemoryWidget> {
           child: Column(
             children: [
               _buildMemoryItem(context, index),
-              Padding(padding: EdgeInsets.all(4)),
+              const Padding(padding: EdgeInsets.all(4)),
               Hero(
                 tag: title,
                 child: Material(
@@ -134,7 +134,7 @@ class _MemoryWidgetState extends State<MemoryWidget> {
     return Container(
       decoration: BoxDecoration(
         border: isSeen
-            ? Border()
+            ? const Border()
             : Border.all(
                 color: Theme.of(context).buttonColor,
                 width: isSeen ? 0 : 2,
@@ -197,11 +197,11 @@ class FullScreenMemory extends StatefulWidget {
   final List<Memory> memories;
   final int index;
 
-  FullScreenMemory(this.title, this.memories, this.index, {Key key})
+  const FullScreenMemory(this.title, this.memories, this.index, {Key key})
       : super(key: key);
 
   @override
-  _FullScreenMemoryState createState() => _FullScreenMemoryState();
+  State<FullScreenMemory> createState() => _FullScreenMemoryState();
 }
 
 class _FullScreenMemoryState extends State<FullScreenMemory> {
@@ -218,7 +218,7 @@ class _FullScreenMemoryState extends State<FullScreenMemory> {
   void initState() {
     super.initState();
     _index = widget.index;
-    Future.delayed(Duration(seconds: 3), () {
+    Future.delayed(const Duration(seconds: 3), () {
       if (mounted) {
         setState(() {
           _opacity = 0;
@@ -246,7 +246,7 @@ class _FullScreenMemoryState extends State<FullScreenMemory> {
               selectedColor: Colors.white, //same for both themes
               unselectedColor: Colors.white.withOpacity(0.4),
             ),
-            SizedBox(
+            const SizedBox(
               height: 18,
             ),
             Row(
@@ -257,7 +257,7 @@ class _FullScreenMemoryState extends State<FullScreenMemory> {
                     onTap: () {
                       Navigator.pop(context);
                     },
-                    child: Icon(
+                    child: const Icon(
                       Icons.close,
                       color: Colors.white, //same for both themes
                     ),
@@ -290,7 +290,7 @@ class _FullScreenMemoryState extends State<FullScreenMemory> {
             ),
           ),
         ),
-        backgroundColor: Color(0x00000000),
+        backgroundColor: const Color(0x00000000),
         elevation: 0,
       ),
       extendBodyBehindAppBar: true,
@@ -314,7 +314,7 @@ class _FullScreenMemoryState extends State<FullScreenMemory> {
       tag: widget.title,
       child: Container(
         alignment: Alignment.bottomCenter,
-        padding: EdgeInsets.fromLTRB(0, 0, 0, 28),
+        padding: const EdgeInsets.fromLTRB(0, 0, 0, 28),
         child: _showCounter
             ? Text(
                 '${_index + 1}/${widget.memories.length}',
@@ -325,7 +325,7 @@ class _FullScreenMemoryState extends State<FullScreenMemory> {
               )
             : AnimatedOpacity(
                 opacity: _opacity,
-                duration: Duration(milliseconds: 500),
+                duration: const Duration(milliseconds: 500),
                 child: Text(
                   widget.title,
                   style: Theme.of(context)
@@ -342,7 +342,7 @@ class _FullScreenMemoryState extends State<FullScreenMemory> {
     final file = widget.memories[_index].file;
     return Container(
       alignment: Alignment.bottomRight,
-      padding: EdgeInsets.fromLTRB(0, 0, 26, 20),
+      padding: const EdgeInsets.fromLTRB(0, 0, 26, 20),
       child: IconButton(
         icon: Icon(
           Icons.adaptive.share,
@@ -392,7 +392,7 @@ class _FullScreenMemoryState extends State<FullScreenMemory> {
               _shouldDisableScroll = value;
             });
           },
-          backgroundDecoration: BoxDecoration(
+          backgroundDecoration: const BoxDecoration(
             color: Colors.transparent,
           ),
         );
@@ -407,8 +407,8 @@ class _FullScreenMemoryState extends State<FullScreenMemory> {
         });
       },
       physics: _shouldDisableScroll
-          ? NeverScrollableScrollPhysics()
-          : PageScrollPhysics(),
+          ? const NeverScrollableScrollPhysics()
+          : const PageScrollPhysics(),
     );
   }
 }

+ 6 - 13
lib/ui/nav_bar.dart

@@ -60,7 +60,7 @@ class GNav extends StatefulWidget {
   final MainAxisAlignment mainAxisAlignment;
 
   @override
-  _GNavState createState() => _GNavState();
+  State<GNav> createState() => _GNavState();
 }
 
 class _GNavState extends State<GNav> {
@@ -74,12 +74,13 @@ class _GNavState extends State<GNav> {
 
   @override
   Widget build(BuildContext context) {
+    debugPrint(
+      '${(_GNavState).toString()} - build with index ${widget.selectedIndex}',
+    );
     selectedIndex = widget.selectedIndex;
 
     return Container(
       color: widget.backgroundColor ?? Colors.transparent,
-      // padding: EdgeInsets.all(12),
-      // alignment: Alignment.center,
       child: Row(
         mainAxisAlignment: widget.mainAxisAlignment,
         children: widget.tabs
@@ -198,7 +199,7 @@ class GButton extends StatefulWidget {
   }) : super(key: key);
 
   @override
-  _GButtonState createState() => _GButtonState();
+  State<GButton> createState() => _GButtonState();
 }
 
 class _GButtonState extends State<GButton> {
@@ -287,7 +288,7 @@ class Button extends StatefulWidget {
   final List<BoxShadow> shadow;
 
   @override
-  _ButtonState createState() => _ButtonState();
+  State<Button> createState() => _ButtonState();
 }
 
 class _ButtonState extends State<Button> with TickerProviderStateMixin {
@@ -300,7 +301,6 @@ class _ButtonState extends State<Button> with TickerProviderStateMixin {
   void initState() {
     super.initState();
     _expanded = widget.active;
-
     expandController =
         AnimationController(vsync: this, duration: widget.duration)
           ..addListener(() => setState(() {}));
@@ -309,18 +309,11 @@ class _ButtonState extends State<Button> with TickerProviderStateMixin {
   @override
   void dispose() {
     expandController.dispose();
-
     super.dispose();
   }
 
   @override
   Widget build(BuildContext context) {
-    var curveValue = expandController
-        .drive(
-          CurveTween(curve: _expanded ? widget.curve : widget.curve.flipped),
-        )
-        .value;
-
     _expanded = !widget.active;
     if (_expanded) {
       expandController.reverse();

+ 7 - 7
lib/ui/billing_questions_widget.dart → lib/ui/payment/billing_questions_widget.dart

@@ -3,7 +3,7 @@ import 'dart:convert';
 import 'package:expansion_tile_card/expansion_tile_card.dart';
 import 'package:flutter/material.dart';
 import 'package:photos/core/network.dart';
-import 'package:photos/ui/loading_widget.dart';
+import 'package:photos/ui/common/loading_widget.dart';
 
 class BillingQuestionsWidget extends StatelessWidget {
   const BillingQuestionsWidget({
@@ -27,8 +27,8 @@ class BillingQuestionsWidget extends StatelessWidget {
         if (snapshot.hasData) {
           final faqs = <Widget>[];
           faqs.add(
-            Padding(
-              padding: const EdgeInsets.all(24),
+            const Padding(
+              padding: EdgeInsets.all(24),
               child: Text(
                 "FAQs",
                 style: TextStyle(
@@ -42,7 +42,7 @@ class BillingQuestionsWidget extends StatelessWidget {
             faqs.add(FaqWidget(faq: faq));
           }
           faqs.add(
-            Padding(
+            const Padding(
               padding: EdgeInsets.all(16),
             ),
           );
@@ -52,7 +52,7 @@ class BillingQuestionsWidget extends StatelessWidget {
             ),
           );
         } else {
-          return loadWidget;
+          return const EnteLoadingWidget();
         }
       },
     );
@@ -70,7 +70,7 @@ class FaqWidget extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     return Padding(
-      padding: EdgeInsets.all(2),
+      padding: const EdgeInsets.all(2),
       child: ExpansionTileCard(
         elevation: 0,
         title: Text(faq.q),
@@ -85,7 +85,7 @@ class FaqWidget extends StatelessWidget {
             ),
             child: Text(
               faq.a,
-              style: TextStyle(
+              style: const TextStyle(
                 height: 1.5,
               ),
             ),

+ 17 - 16
lib/ui/payment/child_subscription_widget.dart

@@ -28,23 +28,24 @@ class ChildSubscriptionWidget extends StatelessWidget {
               style: Theme.of(context).textTheme.bodyText1,
             ),
           ),
-          Padding(
-            padding: const EdgeInsets.symmetric(vertical: 8),
+          const Padding(
+            padding: EdgeInsets.symmetric(vertical: 8),
           ),
           Padding(
-            padding: EdgeInsets.symmetric(horizontal: 16),
+            padding: const EdgeInsets.symmetric(horizontal: 16),
             child: RichText(
               textAlign: TextAlign.center,
               text: TextSpan(
                 children: [
-                  TextSpan(
+                  const TextSpan(
                     text: "Please contact ",
                   ),
                   TextSpan(
                     text: familyAdmin,
-                    style: TextStyle(color: Color.fromRGBO(29, 185, 84, 1)),
+                    style:
+                        const TextStyle(color: Color.fromRGBO(29, 185, 84, 1)),
                   ),
-                  TextSpan(
+                  const TextSpan(
                     text: " to manage your subscription",
                   ),
                 ],
@@ -52,15 +53,15 @@ class ChildSubscriptionWidget extends StatelessWidget {
               ),
             ),
           ),
-          Padding(
-            padding: const EdgeInsets.symmetric(vertical: 8),
+          const Padding(
+            padding: EdgeInsets.symmetric(vertical: 8),
           ),
           Image.asset(
             "assets/family_plan_leave.png",
             height: 256,
           ),
-          Padding(
-            padding: const EdgeInsets.symmetric(vertical: 0),
+          const Padding(
+            padding: EdgeInsets.symmetric(vertical: 0),
           ),
           InkWell(
             child: OutlinedButton(
@@ -68,10 +69,11 @@ class ChildSubscriptionWidget extends StatelessWidget {
                 shape: RoundedRectangleBorder(
                   borderRadius: BorderRadius.circular(10),
                 ),
-                padding: EdgeInsets.symmetric(vertical: 18, horizontal: 100),
+                padding:
+                    const EdgeInsets.symmetric(vertical: 18, horizontal: 100),
                 backgroundColor: Colors.red[500],
               ),
-              child: Text(
+              child: const Text(
                 "Leave Family",
                 style: TextStyle(
                   fontWeight: FontWeight.bold,
@@ -96,10 +98,9 @@ class ChildSubscriptionWidget extends StatelessWidget {
                     ),
                     TextSpan(
                       text: "support@ente.io",
-                      style: Theme.of(context)
-                          .textTheme
-                          .bodyText2
-                          .copyWith(color: Color.fromRGBO(29, 185, 84, 1)),
+                      style: Theme.of(context).textTheme.bodyText2.copyWith(
+                            color: const Color.fromRGBO(29, 185, 84, 1),
+                          ),
                     ),
                     TextSpan(
                       text: " for help",

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

@@ -1,6 +1,5 @@
 import 'dart:io';
 
-import 'package:flutter/cupertino.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_inappwebview/flutter_inappwebview.dart';
@@ -8,8 +7,8 @@ import 'package:logging/logging.dart';
 import 'package:photos/models/subscription.dart';
 import 'package:photos/services/billing_service.dart';
 import 'package:photos/services/user_service.dart';
-import 'package:photos/ui/loading_widget.dart';
-import 'package:photos/ui/progress_dialog.dart';
+import 'package:photos/ui/common/loading_widget.dart';
+import 'package:photos/ui/common/progress_dialog.dart';
 import 'package:photos/utils/dialog_util.dart';
 
 class PaymentWebPage extends StatefulWidget {
@@ -49,7 +48,7 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
   Widget build(BuildContext context) {
     _dialog = createProgressDialog(context, "Please wait...");
     if (initPaymentUrl == null) {
-      return loadWidget;
+      return const EnteLoadingWidget();
     }
     return WillPopScope(
       onWillPop: () async => _buildPageExitWidget(context),
@@ -143,10 +142,10 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
     return showDialog(
       context: context,
       builder: (context) => AlertDialog(
-        title: Text('Are you sure you want to exit?'),
+        title: const Text('Are you sure you want to exit?'),
         actions: <Widget>[
           TextButton(
-            child: Text(
+            child: const Text(
               'Yes',
               style: TextStyle(
                 color: Colors.redAccent,
@@ -193,11 +192,11 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
       context: context,
       barrierDismissible: false,
       builder: (context) => AlertDialog(
-        title: Text('Payment failed'),
+        title: const Text('Payment failed'),
         content: Text("Unfortunately your payment failed due to $reason"),
         actions: <Widget>[
           TextButton(
-            child: Text('Ok'),
+            child: const Text('Ok'),
             onPressed: () {
               Navigator.of(context).pop('dialog');
             },

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

@@ -22,7 +22,6 @@ class SkipSubscriptionWidget extends StatelessWidget {
       margin: const EdgeInsets.fromLTRB(0, 30, 0, 0),
       padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
       child: OutlinedButton(
-        child: Text("Continue on free plan"),
         style: Theme.of(context).outlinedButtonTheme.style.copyWith(
           textStyle: MaterialStateProperty.resolveWith<TextStyle>(
             (Set<MaterialState> states) {
@@ -35,7 +34,7 @@ class SkipSubscriptionWidget extends StatelessWidget {
           Navigator.of(context).pushAndRemoveUntil(
             MaterialPageRoute(
               builder: (BuildContext context) {
-                return HomeWidget();
+                return const HomeWidget();
               },
             ),
             (route) => false,
@@ -43,6 +42,7 @@ class SkipSubscriptionWidget extends StatelessWidget {
           BillingService.instance
               .verifySubscription(kFreeProductID, "", paymentProvider: "ente");
         },
+        child: const Text("Continue on free plan"),
       ),
     );
   }

+ 17 - 18
lib/ui/payment/stripe_subscription_page.dart

@@ -1,7 +1,6 @@
 import 'dart:async';
 
 import 'package:flutter/material.dart';
-import 'package:flutter/widgets.dart';
 import 'package:logging/logging.dart';
 import 'package:photos/ente_theme_data.dart';
 import 'package:photos/models/billing_plan.dart';
@@ -9,16 +8,16 @@ import 'package:photos/models/subscription.dart';
 import 'package:photos/models/user_details.dart';
 import 'package:photos/services/billing_service.dart';
 import 'package:photos/services/user_service.dart';
-import 'package:photos/ui/common/bottomShadow.dart';
+import 'package:photos/ui/common/bottom_shadow.dart';
 import 'package:photos/ui/common/dialogs.dart';
-import 'package:photos/ui/loading_widget.dart';
+import 'package:photos/ui/common/loading_widget.dart';
+import 'package:photos/ui/common/progress_dialog.dart';
+import 'package:photos/ui/common/web_page.dart';
 import 'package:photos/ui/payment/child_subscription_widget.dart';
 import 'package:photos/ui/payment/payment_web_page.dart';
 import 'package:photos/ui/payment/skip_subscription_widget.dart';
 import 'package:photos/ui/payment/subscription_common_widgets.dart';
 import 'package:photos/ui/payment/subscription_plan_widget.dart';
-import 'package:photos/ui/progress_dialog.dart';
-import 'package:photos/ui/web_page.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/toast_util.dart';
 import 'package:step_progress_indicator/step_progress_indicator.dart';
@@ -33,7 +32,7 @@ class StripeSubscriptionPage extends StatefulWidget {
   }) : super(key: key);
 
   @override
-  _StripeSubscriptionPageState createState() => _StripeSubscriptionPageState();
+  State<StripeSubscriptionPage> createState() => _StripeSubscriptionPageState();
 }
 
 class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
@@ -115,14 +114,14 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
   @override
   Widget build(BuildContext context) {
     final appBar = PreferredSize(
-      preferredSize: Size(double.infinity, 60),
+      preferredSize: const Size(double.infinity, 60),
       child: Container(
         decoration: BoxDecoration(
           boxShadow: [
             BoxShadow(
               color: Theme.of(context).backgroundColor,
               blurRadius: 16,
-              offset: Offset(0, 8),
+              offset: const Offset(0, 8),
             )
           ],
         ),
@@ -135,7 +134,7 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
                     totalSteps: 4,
                     currentStep: 4,
                     selectedColor: Theme.of(context).buttonColor,
-                    roundedEdges: Radius.circular(10),
+                    roundedEdges: const Radius.circular(10),
                     unselectedColor: Theme.of(context)
                         .colorScheme
                         .stepProgressUnselectedColor,
@@ -144,7 +143,7 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
               )
             : AppBar(
                 elevation: 0,
-                title: Text("Subscription"),
+                title: const Text("Subscription"),
               ),
       ),
     );
@@ -154,7 +153,7 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
         alignment: Alignment.bottomCenter,
         children: [
           _getBody(),
-          BottomShadowWidget(
+          const BottomShadowWidget(
             offsetDy: 40,
           )
         ],
@@ -175,7 +174,7 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
         return _buildPlans();
       }
     }
-    return loadWidget;
+    return const EnteLoadingWidget();
   }
 
   Widget _buildPlans() {
@@ -193,7 +192,7 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
         mainAxisAlignment: MainAxisAlignment.center,
         children: _getStripePlanWidgets(),
       ),
-      Padding(padding: EdgeInsets.all(4)),
+      const Padding(padding: EdgeInsets.all(4)),
     ]);
 
     widgets.add(_showSubscriptionToggle());
@@ -206,7 +205,7 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
       if (widget.isOnboarding) {
         widgets.add(SkipSubscriptionWidget(freePlan: _freePlan));
       }
-      widgets.add(SubFaqWidget());
+      widgets.add(const SubFaqWidget());
     }
 
     // only active subscription can be renewed/canceled
@@ -242,7 +241,7 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
               }
             },
             child: Container(
-              padding: EdgeInsets.fromLTRB(40, 80, 40, 20),
+              padding: const EdgeInsets.fromLTRB(40, 80, 40, 20),
               child: Column(
                 children: [
                   RichText(
@@ -278,7 +277,7 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
               await _launchFamilyPortal();
             },
             child: Container(
-              padding: EdgeInsets.fromLTRB(40, 0, 40, 80),
+              padding: const EdgeInsets.fromLTRB(40, 0, 40, 80),
               child: Column(
                 children: [
                   RichText(
@@ -512,8 +511,8 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
     }
 
     return Container(
-      padding: EdgeInsets.only(left: 8, right: 8, top: 4, bottom: 4),
-      margin: EdgeInsets.only(bottom: 12),
+      padding: const EdgeInsets.only(left: 8, right: 8, top: 4, bottom: 4),
+      margin: const EdgeInsets.only(bottom: 12),
       // color: Color.fromRGBO(10, 40, 40, 0.3),
       child: Row(
         mainAxisAlignment: MainAxisAlignment.center,

+ 5 - 3
lib/ui/payment/subscription_common_widgets.dart

@@ -1,7 +1,7 @@
 import 'package:flutter/material.dart';
 import 'package:photos/ente_theme_data.dart';
 import 'package:photos/models/subscription.dart';
-import 'package:photos/ui/billing_questions_widget.dart';
+import 'package:photos/ui/payment/billing_questions_widget.dart';
 import 'package:photos/utils/data_util.dart';
 import 'package:photos/utils/date_time_util.dart';
 
@@ -107,6 +107,8 @@ class ValidityWidget extends StatelessWidget {
 }
 
 class SubFaqWidget extends StatelessWidget {
+  const SubFaqWidget({Key key}) : super(key: key);
+
   @override
   Widget build(BuildContext context) {
     return Align(
@@ -119,12 +121,12 @@ class SubFaqWidget extends StatelessWidget {
             barrierColor: Colors.black87,
             context: context,
             builder: (context) {
-              return BillingQuestionsWidget();
+              return const BillingQuestionsWidget();
             },
           );
         },
         child: Container(
-          padding: EdgeInsets.all(40),
+          padding: const EdgeInsets.all(40),
           child: RichText(
             text: TextSpan(
               text: "Questions?",

+ 9 - 11
lib/ui/payment/subscription_page.dart

@@ -1,9 +1,7 @@
 import 'dart:async';
 import 'dart:io';
 
-import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter/widgets.dart';
 import 'package:in_app_purchase/in_app_purchase.dart';
 import 'package:logging/logging.dart';
 import 'package:photos/core/event_bus.dart';
@@ -13,13 +11,13 @@ import 'package:photos/models/subscription.dart';
 import 'package:photos/models/user_details.dart';
 import 'package:photos/services/billing_service.dart';
 import 'package:photos/services/user_service.dart';
-import 'package:photos/ui/loading_widget.dart';
+import 'package:photos/ui/common/loading_widget.dart';
+import 'package:photos/ui/common/progress_dialog.dart';
+import 'package:photos/ui/common/web_page.dart';
 import 'package:photos/ui/payment/child_subscription_widget.dart';
 import 'package:photos/ui/payment/skip_subscription_widget.dart';
 import 'package:photos/ui/payment/subscription_common_widgets.dart';
 import 'package:photos/ui/payment/subscription_plan_widget.dart';
-import 'package:photos/ui/progress_dialog.dart';
-import 'package:photos/ui/web_page.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/toast_util.dart';
 import 'package:url_launcher/url_launcher.dart';
@@ -132,7 +130,7 @@ class _SubscriptionPageState extends State<SubscriptionPage> {
     }
     _dialog = createProgressDialog(context, "Please wait...");
     final appBar = AppBar(
-      title: widget.isOnboarding ? null : Text("Subscription"),
+      title: widget.isOnboarding ? null : const Text("Subscription"),
     );
     return Scaffold(
       appBar: appBar,
@@ -171,7 +169,7 @@ class _SubscriptionPageState extends State<SubscriptionPage> {
         return _buildPlans();
       }
     }
-    return loadWidget;
+    return const EnteLoadingWidget();
   }
 
   Widget _buildPlans() {
@@ -190,7 +188,7 @@ class _SubscriptionPageState extends State<SubscriptionPage> {
             ? _getStripePlanWidgets()
             : _getMobilePlanWidgets(),
       ),
-      Padding(padding: EdgeInsets.all(8)),
+      const Padding(padding: EdgeInsets.all(8)),
     ]);
 
     if (_hasActiveSubscription) {
@@ -201,7 +199,7 @@ class _SubscriptionPageState extends State<SubscriptionPage> {
       if (widget.isOnboarding) {
         widgets.add(SkipSubscriptionWidget(freePlan: _freePlan));
       }
-      widgets.add(SubFaqWidget());
+      widgets.add(const SubFaqWidget());
     }
 
     if (_hasActiveSubscription &&
@@ -225,7 +223,7 @@ class _SubscriptionPageState extends State<SubscriptionPage> {
               }
             },
             child: Container(
-              padding: EdgeInsets.fromLTRB(40, 80, 40, 20),
+              padding: const EdgeInsets.fromLTRB(40, 80, 40, 20),
               child: Column(
                 children: [
                   RichText(
@@ -260,7 +258,7 @@ class _SubscriptionPageState extends State<SubscriptionPage> {
               _launchFamilyPortal();
             },
             child: Container(
-              padding: EdgeInsets.fromLTRB(40, 0, 40, 80),
+              padding: const EdgeInsets.fromLTRB(40, 0, 40, 80),
               child: Column(
                 children: [
                   RichText(

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

@@ -1,4 +1,3 @@
-import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:photos/utils/data_util.dart';
 
@@ -30,13 +29,14 @@ class SubscriptionPlanWidget extends StatelessWidget {
       padding: EdgeInsets.symmetric(horizontal: isActive ? 8 : 16, vertical: 4),
       child: Container(
         decoration: BoxDecoration(
-          color:
-              isActive ? Color(0xFF22763F) : Color.fromRGBO(240, 240, 240, 1.0),
+          color: isActive
+              ? const Color(0xFF22763F)
+              : const Color.fromRGBO(240, 240, 240, 1.0),
           gradient: isActive
-              ? LinearGradient(
+              ? const LinearGradient(
                   begin: Alignment.centerLeft,
                   end: Alignment.centerRight,
-                  colors: const [
+                  colors: [
                     Color(0xFF2CD267),
                     Color(0xFF1DB954),
                   ],

+ 17 - 14
lib/ui/settings/account_section_widget.dart

@@ -1,23 +1,22 @@
 import 'package:expandable/expandable.dart';
-import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/services/user_service.dart';
-import 'package:photos/ui/app_lock.dart';
-import 'package:photos/ui/change_email_dialog.dart';
-import 'package:photos/ui/password_entry_page.dart';
-import 'package:photos/ui/recovery_key_page.dart';
+import 'package:photos/ui/account/change_email_dialog.dart';
+import 'package:photos/ui/account/password_entry_page.dart';
+import 'package:photos/ui/account/recovery_key_page.dart';
 import 'package:photos/ui/settings/common_settings.dart';
 import 'package:photos/ui/settings/settings_section_title.dart';
 import 'package:photos/ui/settings/settings_text_item.dart';
+import 'package:photos/ui/tools/app_lock.dart';
 import 'package:photos/utils/auth_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/navigation_util.dart';
 import 'package:photos/utils/toast_util.dart';
 
 class AccountSectionWidget extends StatefulWidget {
-  AccountSectionWidget({Key key}) : super(key: key);
+  const AccountSectionWidget({Key key}) : super(key: key);
 
   @override
   AccountSectionWidgetState createState() => AccountSectionWidgetState();
@@ -27,7 +26,7 @@ class AccountSectionWidgetState extends State<AccountSectionWidget> {
   @override
   Widget build(BuildContext context) {
     return ExpandablePanel(
-      header: SettingsSectionTitle("Account"),
+      header: const SettingsSectionTitle("Account"),
       collapsed: Container(),
       expanded: _getSectionOptions(context),
       theme: getExpandableTheme(context),
@@ -67,8 +66,10 @@ class AccountSectionWidgetState extends State<AccountSectionWidget> {
               ),
             );
           },
-          child:
-              SettingsTextItem(text: "Recovery key", icon: Icons.navigate_next),
+          child: const SettingsTextItem(
+            text: "Recovery key",
+            icon: Icons.navigate_next,
+          ),
         ),
         sectionOptionDivider,
         GestureDetector(
@@ -86,14 +87,16 @@ class AccountSectionWidgetState extends State<AccountSectionWidget> {
             showDialog(
               context: context,
               builder: (BuildContext context) {
-                return ChangeEmailDialog();
+                return const ChangeEmailDialog();
               },
               barrierColor: Colors.black.withOpacity(0.85),
               barrierDismissible: false,
             );
           },
-          child:
-              SettingsTextItem(text: "Change email", icon: Icons.navigate_next),
+          child: const SettingsTextItem(
+            text: "Change email",
+            icon: Icons.navigate_next,
+          ),
         ),
         sectionOptionDivider,
         GestureDetector(
@@ -111,14 +114,14 @@ class AccountSectionWidgetState extends State<AccountSectionWidget> {
             Navigator.of(context).push(
               MaterialPageRoute(
                 builder: (BuildContext context) {
-                  return PasswordEntryPage(
+                  return const PasswordEntryPage(
                     mode: PasswordEntryMode.update,
                   );
                 },
               ),
             );
           },
-          child: SettingsTextItem(
+          child: const SettingsTextItem(
             text: "Change password",
             icon: Icons.navigate_next,
           ),

+ 17 - 17
lib/ui/app_update_dialog.dart → lib/ui/settings/app_update_dialog.dart

@@ -8,10 +8,10 @@ import 'package:photos/services/update_service.dart';
 class AppUpdateDialog extends StatefulWidget {
   final LatestVersionInfo latestVersionInfo;
 
-  AppUpdateDialog(this.latestVersionInfo, {Key key}) : super(key: key);
+  const AppUpdateDialog(this.latestVersionInfo, {Key key}) : super(key: key);
 
   @override
-  _AppUpdateDialogState createState() => _AppUpdateDialogState();
+  State<AppUpdateDialog> createState() => _AppUpdateDialogState();
 }
 
 class _AppUpdateDialogState extends State<AppUpdateDialog> {
@@ -32,31 +32,28 @@ class _AppUpdateDialogState extends State<AppUpdateDialog> {
       children: [
         Text(
           widget.latestVersionInfo.name,
-          style: TextStyle(
+          style: const TextStyle(
             fontSize: 20,
             fontWeight: FontWeight.bold,
           ),
         ),
-        Padding(padding: EdgeInsets.all(8)),
-        Text(
+        const Padding(padding: EdgeInsets.all(8)),
+        const Text(
           "Changelog",
           style: TextStyle(
             fontSize: 18,
           ),
         ),
-        Padding(padding: EdgeInsets.all(4)),
+        const Padding(padding: EdgeInsets.all(4)),
         Column(
           crossAxisAlignment: CrossAxisAlignment.start,
           children: changelog,
         ),
-        Padding(padding: EdgeInsets.all(8)),
-        Container(
+        const Padding(padding: EdgeInsets.all(8)),
+        SizedBox(
           width: double.infinity,
           height: 64,
           child: OutlinedButton(
-            child: Text(
-              "Update",
-            ),
             style: Theme.of(context).outlinedButtonTheme.style.copyWith(
               textStyle: MaterialStateProperty.resolveWith<TextStyle>(
                 (Set<MaterialState> states) {
@@ -74,6 +71,9 @@ class _AppUpdateDialogState extends State<AppUpdateDialog> {
                 barrierDismissible: false,
               );
             },
+            child: const Text(
+              "Update",
+            ),
           ),
         ),
       ],
@@ -95,10 +95,10 @@ class _AppUpdateDialogState extends State<AppUpdateDialog> {
 class ApkDownloaderDialog extends StatefulWidget {
   final LatestVersionInfo versionInfo;
 
-  ApkDownloaderDialog(this.versionInfo, {Key key}) : super(key: key);
+  const ApkDownloaderDialog(this.versionInfo, {Key key}) : super(key: key);
 
   @override
-  _ApkDownloaderDialogState createState() => _ApkDownloaderDialogState();
+  State<ApkDownloaderDialog> createState() => _ApkDownloaderDialogState();
 }
 
 class _ApkDownloaderDialogState extends State<ApkDownloaderDialog> {
@@ -120,7 +120,7 @@ class _ApkDownloaderDialogState extends State<ApkDownloaderDialog> {
     return WillPopScope(
       onWillPop: () async => false,
       child: AlertDialog(
-        title: Text(
+        title: const Text(
           "Downloading...",
           style: TextStyle(
             fontSize: 16,
@@ -152,11 +152,11 @@ class _ApkDownloaderDialogState extends State<ApkDownloaderDialog> {
     } catch (e) {
       Logger("ApkDownloader").severe(e);
       AlertDialog alert = AlertDialog(
-        title: Text("Sorry"),
-        content: Text("The download could not be completed"),
+        title: const Text("Sorry"),
+        content: const Text("The download could not be completed"),
         actions: [
           TextButton(
-            child: Text(
+            child: const Text(
               "Ignore",
               style: TextStyle(
                 color: Colors.white,

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

@@ -1,5 +1,4 @@
 import 'package:flutter/material.dart';
-import 'package:flutter/widgets.dart';
 import 'package:package_info_plus/package_info_plus.dart';
 import 'package:photos/core/network.dart';
 import 'package:photos/utils/dialog_util.dart';
@@ -34,7 +33,7 @@ class _AppVersionWidgetState extends State<AppVersionWidget> {
                 createProgressDialog(context, "Starting network inspector...");
             await dialog.show();
             await Future.delayed(
-              Duration(milliseconds: kDummyDelayDurationInMilliseconds),
+              const Duration(milliseconds: kDummyDelayDurationInMilliseconds),
             );
             await dialog.hide();
             Network.instance.getAlice().showInspector();

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

@@ -9,11 +9,11 @@ import 'package:photos/services/deduplication_service.dart';
 import 'package:photos/services/sync_service.dart';
 import 'package:photos/ui/backup_folder_selection_page.dart';
 import 'package:photos/ui/common/dialogs.dart';
-import 'package:photos/ui/deduplicate_page.dart';
-import 'package:photos/ui/free_space_page.dart';
 import 'package:photos/ui/settings/common_settings.dart';
 import 'package:photos/ui/settings/settings_section_title.dart';
 import 'package:photos/ui/settings/settings_text_item.dart';
+import 'package:photos/ui/tools/deduplicate_page.dart';
+import 'package:photos/ui/tools/free_space_page.dart';
 import 'package:photos/utils/data_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/navigation_util.dart';
@@ -21,7 +21,7 @@ import 'package:photos/utils/toast_util.dart';
 import 'package:url_launcher/url_launcher.dart';
 
 class BackupSectionWidget extends StatefulWidget {
-  BackupSectionWidget({Key key}) : super(key: key);
+  const BackupSectionWidget({Key key}) : super(key: key);
 
   @override
   BackupSectionWidgetState createState() => BackupSectionWidgetState();
@@ -31,7 +31,7 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
   @override
   Widget build(BuildContext context) {
     return ExpandablePanel(
-      header: SettingsSectionTitle("Backup"),
+      header: const SettingsSectionTitle("Backup"),
       collapsed: Container(),
       expanded: _getSectionOptions(context),
       theme: getExpandableTheme(context),
@@ -45,12 +45,12 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
         onTap: () async {
           routeToPage(
             context,
-            BackupFolderSelectionPage(
+            const BackupFolderSelectionPage(
               buttonText: "Backup",
             ),
           );
         },
-        child: SettingsTextItem(
+        child: const SettingsTextItem(
           text: "Backed up folders",
           icon: Icons.navigate_next,
         ),
@@ -143,7 +143,7 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
             BackupStatus status;
             try {
               status = await SyncService.instance.getBackupStatus();
-            } catch (e, s) {
+            } catch (e) {
               await dialog.hide();
               showGenericErrorDialog(context);
               return;
@@ -163,7 +163,7 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
               }
             }
           },
-          child: SettingsTextItem(
+          child: const SettingsTextItem(
             text: "Free up space",
             icon: Icons.navigate_next,
           ),
@@ -199,7 +199,7 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
               }
             }
           },
-          child: SettingsTextItem(
+          child: const SettingsTextItem(
             text: "Deduplicate files",
             icon: Icons.navigate_next,
           ),
@@ -213,7 +213,7 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
 
   void _showSpaceFreedDialog(BackupStatus status) {
     AlertDialog alert = AlertDialog(
-      title: Text("Success"),
+      title: const Text("Success"),
       content: Text(
         "You have successfully freed up " + formatBytes(status.size) + "!",
       ),
@@ -238,7 +238,7 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
           },
         ),
         TextButton(
-          child: Text(
+          child: const Text(
             "Ok",
           ),
           onPressed: () {
@@ -269,7 +269,7 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
         " duplicate file" +
         (result.count == 1 ? "" : "s");
     AlertDialog alert = AlertDialog(
-      title: Text("✨ Success"),
+      title: const Text("✨ Success"),
       content: Text(
         "You have cleaned up " +
             countText +
@@ -298,7 +298,7 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
           },
         ),
         TextButton(
-          child: Text(
+          child: const Text(
             "Ok",
           ),
           onPressed: () {

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

@@ -12,7 +12,7 @@ ExpandableThemeData getExpandableTheme(BuildContext context) {
   return ExpandableThemeData(
     expandIcon: CupertinoIcons.chevron_down,
     collapseIcon: CupertinoIcons.chevron_up,
-    iconPadding: EdgeInsets.all(4),
+    iconPadding: const EdgeInsets.all(4),
     iconColor: Theme.of(context).colorScheme.onSurface,
     iconSize: 20.0,
     iconRotationAngle: -3.14 / 2,

+ 13 - 12
lib/ui/settings/danger_section_widget.dart

@@ -8,17 +8,17 @@ import 'package:photos/ui/settings/settings_text_item.dart';
 import 'package:url_launcher/url_launcher.dart';
 
 class DangerSectionWidget extends StatefulWidget {
-  DangerSectionWidget({Key key}) : super(key: key);
+  const DangerSectionWidget({Key key}) : super(key: key);
 
   @override
-  _DangerSectionWidgetState createState() => _DangerSectionWidgetState();
+  State<DangerSectionWidget> createState() => _DangerSectionWidgetState();
 }
 
 class _DangerSectionWidgetState extends State<DangerSectionWidget> {
   @override
   Widget build(BuildContext context) {
     return ExpandablePanel(
-      header: SettingsSectionTitle("Exit", color: Colors.red),
+      header: const SettingsSectionTitle("Exit", color: Colors.red),
       collapsed: Container(),
       expanded: _getSectionOptions(context),
       theme: getExpandableTheme(context),
@@ -33,7 +33,8 @@ class _DangerSectionWidgetState extends State<DangerSectionWidget> {
           onTap: () {
             _onLogoutTapped();
           },
-          child: SettingsTextItem(text: "Logout", icon: Icons.navigate_next),
+          child:
+              const SettingsTextItem(text: "Logout", icon: Icons.navigate_next),
         ),
         sectionOptionDivider,
         GestureDetector(
@@ -41,7 +42,7 @@ class _DangerSectionWidgetState extends State<DangerSectionWidget> {
           onTap: () {
             _onDeleteAccountTapped();
           },
-          child: SettingsTextItem(
+          child: const SettingsTextItem(
             text: "Delete account",
             icon: Icons.navigate_next,
           ),
@@ -52,7 +53,7 @@ class _DangerSectionWidgetState extends State<DangerSectionWidget> {
 
   Future<void> _onDeleteAccountTapped() async {
     AlertDialog alert = AlertDialog(
-      title: Text(
+      title: const Text(
         "Delete account",
         style: TextStyle(
           color: Colors.red,
@@ -61,7 +62,7 @@ class _DangerSectionWidgetState extends State<DangerSectionWidget> {
       content: RichText(
         text: TextSpan(
           children: [
-            TextSpan(
+            const TextSpan(
               text: "Please send an email to ",
             ),
             TextSpan(
@@ -70,7 +71,7 @@ class _DangerSectionWidgetState extends State<DangerSectionWidget> {
                 color: Colors.orange[300],
               ),
             ),
-            TextSpan(
+            const TextSpan(
               text:
                   " from your registered email address.\n\nYour request will be processed within 72 hours.",
             ),
@@ -84,7 +85,7 @@ class _DangerSectionWidgetState extends State<DangerSectionWidget> {
       ),
       actions: [
         TextButton(
-          child: Text(
+          child: const Text(
             "Send email",
             style: TextStyle(
               color: Colors.red,
@@ -127,16 +128,16 @@ class _DangerSectionWidgetState extends State<DangerSectionWidget> {
 
   Future<void> _onLogoutTapped() async {
     AlertDialog alert = AlertDialog(
-      title: Text(
+      title: const Text(
         "Logout",
         style: TextStyle(
           color: Colors.red,
         ),
       ),
-      content: Text("Are you sure you want to logout?"),
+      content: const Text("Are you sure you want to logout?"),
       actions: [
         TextButton(
-          child: Text(
+          child: const Text(
             "Yes, logout",
             style: TextStyle(
               color: Colors.red,

+ 25 - 15
lib/ui/settings/debug_section_widget.dart

@@ -12,7 +12,7 @@ class DebugSectionWidget extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     return ExpandablePanel(
-      header: SettingsSectionTitle("Debug"),
+      header: const SettingsSectionTitle("Debug"),
       collapsed: Container(),
       expanded: _getSectionOptions(context),
       theme: getExpandableTheme(context),
@@ -27,15 +27,17 @@ class DebugSectionWidget extends StatelessWidget {
           onTap: () async {
             _showKeyAttributesDialog(context);
           },
-          child: SettingsTextItem(
-              text: "Key attributes", icon: Icons.navigate_next),
+          child: const SettingsTextItem(
+            text: "Key attributes",
+            icon: Icons.navigate_next,
+          ),
         ),
         GestureDetector(
           behavior: HitTestBehavior.translucent,
           onTap: () async {
             Network.instance.getAlice().showInspector();
           },
-          child: SettingsTextItem(
+          child: const SettingsTextItem(
             text: "Network requests",
             icon: Icons.navigate_next,
           ),
@@ -47,32 +49,40 @@ class DebugSectionWidget extends StatelessWidget {
   void _showKeyAttributesDialog(BuildContext context) {
     final keyAttributes = Configuration.instance.getKeyAttributes();
     AlertDialog alert = AlertDialog(
-      title: Text("key attributes"),
+      title: const Text("key attributes"),
       content: SingleChildScrollView(
         child: Column(
           children: [
-            Text("Key", style: TextStyle(fontWeight: FontWeight.bold)),
+            const Text(
+              "Key",
+              style: TextStyle(fontWeight: FontWeight.bold),
+            ),
             Text(Sodium.bin2base64(Configuration.instance.getKey())),
-            Padding(padding: EdgeInsets.all(12)),
-            Text("Encrypted Key",
-                style: TextStyle(fontWeight: FontWeight.bold)),
+            const Padding(padding: EdgeInsets.all(12)),
+            const Text(
+              "Encrypted Key",
+              style: TextStyle(fontWeight: FontWeight.bold),
+            ),
             Text(keyAttributes.encryptedKey),
-            Padding(padding: EdgeInsets.all(12)),
-            Text(
+            const Padding(padding: EdgeInsets.all(12)),
+            const Text(
               "Key Decryption Nonce",
               style: TextStyle(fontWeight: FontWeight.bold),
             ),
             Text(keyAttributes.keyDecryptionNonce),
-            Padding(padding: EdgeInsets.all(12)),
-            Text("KEK Salt", style: TextStyle(fontWeight: FontWeight.bold)),
+            const Padding(padding: EdgeInsets.all(12)),
+            const Text(
+              "KEK Salt",
+              style: TextStyle(fontWeight: FontWeight.bold),
+            ),
             Text(keyAttributes.kekSalt),
-            Padding(padding: EdgeInsets.all(12)),
+            const Padding(padding: EdgeInsets.all(12)),
           ],
         ),
       ),
       actions: [
         TextButton(
-          child: Text("OK"),
+          child: const Text("OK"),
           onPressed: () {
             Navigator.of(context, rootNavigator: true).pop('dialog');
           },

+ 39 - 27
lib/ui/settings/details_section_widget.dart

@@ -7,15 +7,15 @@ import 'package:photos/events/tab_changed_event.dart';
 import 'package:photos/events/user_details_changed_event.dart';
 import 'package:photos/models/user_details.dart';
 import 'package:photos/services/user_service.dart';
-import 'package:photos/ui/loading_widget.dart';
+import 'package:photos/ui/common/loading_widget.dart';
 import 'package:photos/ui/payment/subscription.dart';
 import 'package:photos/utils/data_util.dart';
 
 class DetailsSectionWidget extends StatefulWidget {
-  DetailsSectionWidget({Key key}) : super(key: key);
+  const DetailsSectionWidget({Key key}) : super(key: key);
 
   @override
-  _DetailsSectionWidgetState createState() => _DetailsSectionWidgetState();
+  State<DetailsSectionWidget> createState() => _DetailsSectionWidgetState();
 }
 
 class _DetailsSectionWidgetState extends State<DetailsSectionWidget> {
@@ -38,7 +38,7 @@ class _DetailsSectionWidgetState extends State<DetailsSectionWidget> {
         _fetchUserDetails();
       }
     });
-    _background = Image(
+    _background = const Image(
       image: AssetImage("assets/storage_card_background.png"),
       fit: BoxFit.fill,
     );
@@ -102,10 +102,14 @@ class _DetailsSectionWidgetState extends State<DetailsSectionWidget> {
             ),
           ),
           _userDetails == null
-              ? loadWidget
+              ? const EnteLoadingWidget()
               : Padding(
-                  padding:
-                      EdgeInsets.only(top: 20, bottom: 20, left: 16, right: 16),
+                  padding: const EdgeInsets.only(
+                    top: 20,
+                    bottom: 20,
+                    left: 16,
+                    right: 16,
+                  ),
                   child: Container(
                     color: Colors.transparent,
                     child: Column(
@@ -123,7 +127,8 @@ class _DetailsSectionWidgetState extends State<DetailsSectionWidget> {
                                     .textTheme
                                     .subtitle2
                                     .copyWith(
-                                        color: Colors.white.withOpacity(0.7)),
+                                      color: Colors.white.withOpacity(0.7),
+                                    ),
                               ),
                               Text(
                                 "${convertBytesToReadableFormat(_userDetails.getFreeStorage())} of ${convertBytesToReadableFormat(_userDetails.getTotalStorage())} free",
@@ -164,7 +169,9 @@ class _DetailsSectionWidgetState extends State<DetailsSectionWidget> {
                                 ),
                               ],
                             ),
-                            Padding(padding: EdgeInsets.symmetric(vertical: 8)),
+                            const Padding(
+                              padding: EdgeInsets.symmetric(vertical: 8),
+                            ),
                             Row(
                               mainAxisAlignment: MainAxisAlignment.spaceBetween,
                               children: [
@@ -174,26 +181,27 @@ class _DetailsSectionWidgetState extends State<DetailsSectionWidget> {
                                           Container(
                                             width: 8.71,
                                             height: 8.99,
-                                            decoration: BoxDecoration(
+                                            decoration: const BoxDecoration(
                                               shape: BoxShape.circle,
                                               color: Colors.white,
                                             ),
                                           ),
-                                          Padding(
-                                              padding:
-                                                  EdgeInsets.only(right: 4)),
+                                          const Padding(
+                                            padding: EdgeInsets.only(right: 4),
+                                          ),
                                           Text(
                                             "You",
                                             style: Theme.of(context)
                                                 .textTheme
                                                 .bodyText1
                                                 .copyWith(
-                                                    color: Colors.white,
-                                                    fontSize: 12),
+                                                  color: Colors.white,
+                                                  fontSize: 12,
+                                                ),
+                                          ),
+                                          const Padding(
+                                            padding: EdgeInsets.only(right: 12),
                                           ),
-                                          Padding(
-                                              padding:
-                                                  EdgeInsets.only(right: 12)),
                                           Container(
                                             width: 8.71,
                                             height: 8.99,
@@ -203,17 +211,18 @@ class _DetailsSectionWidgetState extends State<DetailsSectionWidget> {
                                                   .withOpacity(0.75),
                                             ),
                                           ),
-                                          Padding(
-                                              padding:
-                                                  EdgeInsets.only(right: 4)),
+                                          const Padding(
+                                            padding: EdgeInsets.only(right: 4),
+                                          ),
                                           Text(
                                             "Family",
                                             style: Theme.of(context)
                                                 .textTheme
                                                 .bodyText1
                                                 .copyWith(
-                                                    color: Colors.white,
-                                                    fontSize: 12),
+                                                  color: Colors.white,
+                                                  fontSize: 12,
+                                                ),
                                           ),
                                         ],
                                       )
@@ -223,8 +232,9 @@ class _DetailsSectionWidgetState extends State<DetailsSectionWidget> {
                                             .textTheme
                                             .bodyText1
                                             .copyWith(
-                                                color: Colors.white,
-                                                fontSize: 12),
+                                              color: Colors.white,
+                                              fontSize: 12,
+                                            ),
                                       ),
                                 Padding(
                                   padding: const EdgeInsets.only(right: 16.0),
@@ -234,7 +244,9 @@ class _DetailsSectionWidgetState extends State<DetailsSectionWidget> {
                                         .textTheme
                                         .bodyText1
                                         .copyWith(
-                                            color: Colors.white, fontSize: 12),
+                                          color: Colors.white,
+                                          fontSize: 12,
+                                        ),
                                   ),
                                 )
                               ],
@@ -245,7 +257,7 @@ class _DetailsSectionWidgetState extends State<DetailsSectionWidget> {
                     ),
                   ),
                 ),
-          Align(
+          const Align(
             alignment: Alignment.centerRight,
             child: Icon(
               Icons.chevron_right,

+ 18 - 12
lib/ui/settings/info_section_widget.dart

@@ -1,11 +1,11 @@
 import 'package:expandable/expandable.dart';
 import 'package:flutter/material.dart';
 import 'package:photos/services/update_service.dart';
-import 'package:photos/ui/app_update_dialog.dart';
+import 'package:photos/ui/common/web_page.dart';
+import 'package:photos/ui/settings/app_update_dialog.dart';
 import 'package:photos/ui/settings/common_settings.dart';
 import 'package:photos/ui/settings/settings_section_title.dart';
 import 'package:photos/ui/settings/settings_text_item.dart';
-import 'package:photos/ui/web_page.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/toast_util.dart';
 import 'package:url_launcher/url_launcher.dart';
@@ -16,7 +16,7 @@ class InfoSectionWidget extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     return ExpandablePanel(
-      header: SettingsSectionTitle("About"),
+      header: const SettingsSectionTitle("About"),
       collapsed: Container(),
       expanded: _getSectionOptions(context),
       theme: getExpandableTheme(context),
@@ -32,12 +32,12 @@ class InfoSectionWidget extends StatelessWidget {
             Navigator.of(context).push(
               MaterialPageRoute(
                 builder: (BuildContext context) {
-                  return WebPage("FAQ", "https://ente.io/faq");
+                  return const WebPage("FAQ", "https://ente.io/faq");
                 },
               ),
             );
           },
-          child: SettingsTextItem(text: "FAQ", icon: Icons.navigate_next),
+          child: const SettingsTextItem(text: "FAQ", icon: Icons.navigate_next),
         ),
         sectionOptionDivider,
         GestureDetector(
@@ -46,12 +46,13 @@ class InfoSectionWidget extends StatelessWidget {
             Navigator.of(context).push(
               MaterialPageRoute(
                 builder: (BuildContext context) {
-                  return WebPage("terms", "https://ente.io/terms");
+                  return const WebPage("terms", "https://ente.io/terms");
                 },
               ),
             );
           },
-          child: SettingsTextItem(text: "Terms", icon: Icons.navigate_next),
+          child:
+              const SettingsTextItem(text: "Terms", icon: Icons.navigate_next),
         ),
         sectionOptionDivider,
         GestureDetector(
@@ -60,12 +61,15 @@ class InfoSectionWidget extends StatelessWidget {
             Navigator.of(context).push(
               MaterialPageRoute(
                 builder: (BuildContext context) {
-                  return WebPage("privacy", "https://ente.io/privacy");
+                  return const WebPage("privacy", "https://ente.io/privacy");
                 },
               ),
             );
           },
-          child: SettingsTextItem(text: "Privacy", icon: Icons.navigate_next),
+          child: const SettingsTextItem(
+            text: "Privacy",
+            icon: Icons.navigate_next,
+          ),
         ),
         sectionOptionDivider,
         GestureDetector(
@@ -73,8 +77,10 @@ class InfoSectionWidget extends StatelessWidget {
           onTap: () async {
             launchUrl(Uri.parse("https://github.com/ente-io/frame"));
           },
-          child:
-              SettingsTextItem(text: "Source code", icon: Icons.navigate_next),
+          child: const SettingsTextItem(
+            text: "Source code",
+            icon: Icons.navigate_next,
+          ),
         ),
         sectionOptionDivider,
         UpdateService.instance.isIndependent()
@@ -103,7 +109,7 @@ class InfoSectionWidget extends StatelessWidget {
                         showToast(context, "You are on the latest version");
                       }
                     },
-                    child: SettingsTextItem(
+                    child: const SettingsTextItem(
                       text: "Check for updates",
                       icon: Icons.navigate_next,
                     ),

+ 16 - 15
lib/ui/settings/security_section_widget.dart

@@ -9,20 +9,20 @@ import 'package:photos/core/event_bus.dart';
 import 'package:photos/ente_theme_data.dart';
 import 'package:photos/events/two_factor_status_change_event.dart';
 import 'package:photos/services/user_service.dart';
-import 'package:photos/ui/app_lock.dart';
-import 'package:photos/ui/loading_widget.dart';
-import 'package:photos/ui/sessions_page.dart';
+import 'package:photos/ui/account/sessions_page.dart';
+import 'package:photos/ui/common/loading_widget.dart';
 import 'package:photos/ui/settings/common_settings.dart';
 import 'package:photos/ui/settings/settings_section_title.dart';
 import 'package:photos/ui/settings/settings_text_item.dart';
+import 'package:photos/ui/tools/app_lock.dart';
 import 'package:photos/utils/auth_util.dart';
 import 'package:photos/utils/toast_util.dart';
 
 class SecuritySectionWidget extends StatefulWidget {
-  SecuritySectionWidget({Key key}) : super(key: key);
+  const SecuritySectionWidget({Key key}) : super(key: key);
 
   @override
-  _SecuritySectionWidgetState createState() => _SecuritySectionWidgetState();
+  State<SecuritySectionWidget> createState() => _SecuritySectionWidgetState();
 }
 
 class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
@@ -53,7 +53,7 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
   @override
   Widget build(BuildContext context) {
     return ExpandablePanel(
-      header: SettingsSectionTitle("Security"),
+      header: const SettingsSectionTitle("Security"),
       collapsed: Container(),
       expanded: _getSectionOptions(context),
       theme: getExpandableTheme(context),
@@ -65,7 +65,7 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
     if (_config.hasConfiguredAccount()) {
       children.addAll(
         [
-          Padding(padding: EdgeInsets.all(2)),
+          const Padding(padding: EdgeInsets.all(2)),
           SizedBox(
             height: 48,
             child: Row(
@@ -106,7 +106,7 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
                         color: Colors.white.withOpacity(0.8),
                       );
                     }
-                    return loadWidget;
+                    return const EnteLoadingWidget();
                   },
                 ),
               ],
@@ -165,7 +165,7 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
                   onChanged: (value) async {
                     if (value) {
                       AlertDialog alert = AlertDialog(
-                        title: Text("Hide from recents?"),
+                        title: const Text("Hide from recents?"),
                         content: SingleChildScrollView(
                           child: Column(
                             mainAxisAlignment: MainAxisAlignment.start,
@@ -261,12 +261,12 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
           Navigator.of(context).push(
             MaterialPageRoute(
               builder: (BuildContext context) {
-                return SessionsPage();
+                return const SessionsPage();
               },
             ),
           );
         },
-        child: SettingsTextItem(
+        child: const SettingsTextItem(
           text: "Active sessions",
           icon: Icons.navigate_next,
         ),
@@ -279,9 +279,10 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
 
   void _disableTwoFactor() {
     AlertDialog alert = AlertDialog(
-      title: Text("Disable two-factor"),
-      content:
-          Text("Are you sure you want to disable two-factor authentication?"),
+      title: const Text("Disable two-factor"),
+      content: const Text(
+        "Are you sure you want to disable two-factor authentication?",
+      ),
       actions: [
         TextButton(
           child: Text(
@@ -295,7 +296,7 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
           },
         ),
         TextButton(
-          child: Text(
+          child: const Text(
             "Yes",
             style: TextStyle(
               color: Colors.red,

+ 2 - 2
lib/ui/settings/settings_section_title.dart

@@ -14,7 +14,7 @@ class SettingsSectionTitle extends StatelessWidget {
   Widget build(BuildContext context) {
     return Column(
       children: [
-        Padding(padding: EdgeInsets.all(4)),
+        const Padding(padding: EdgeInsets.all(4)),
         Align(
           alignment: Alignment.centerLeft,
           child: Text(
@@ -27,7 +27,7 @@ class SettingsSectionTitle extends StatelessWidget {
                 : Theme.of(context).textTheme.headline6,
           ),
         ),
-        Padding(padding: EdgeInsets.all(4)),
+        const Padding(padding: EdgeInsets.all(4)),
       ],
     );
   }

+ 8 - 5
lib/ui/settings/social_section_widget.dart

@@ -14,7 +14,7 @@ class SocialSectionWidget extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     return ExpandablePanel(
-      header: SettingsSectionTitle("Social"),
+      header: const SettingsSectionTitle("Social"),
       collapsed: Container(),
       expanded: _getSectionOptions(context),
       theme: getExpandableTheme(context),
@@ -28,7 +28,8 @@ class SocialSectionWidget extends StatelessWidget {
         onTap: () {
           launch("https://twitter.com/enteio");
         },
-        child: SettingsTextItem(text: "Twitter", icon: Icons.navigate_next),
+        child:
+            const SettingsTextItem(text: "Twitter", icon: Icons.navigate_next),
       ),
       sectionOptionDivider,
       GestureDetector(
@@ -36,7 +37,8 @@ class SocialSectionWidget extends StatelessWidget {
         onTap: () {
           launch("https://ente.io/discord");
         },
-        child: SettingsTextItem(text: "Discord", icon: Icons.navigate_next),
+        child:
+            const SettingsTextItem(text: "Discord", icon: Icons.navigate_next),
       ),
       sectionOptionDivider,
       GestureDetector(
@@ -44,7 +46,8 @@ class SocialSectionWidget extends StatelessWidget {
         onTap: () {
           launch("https://reddit.com/r/enteio");
         },
-        child: SettingsTextItem(text: "Reddit", icon: Icons.navigate_next),
+        child:
+            const SettingsTextItem(text: "Reddit", icon: Icons.navigate_next),
       ),
     ];
     if (!UpdateService.instance.isIndependent()) {
@@ -64,7 +67,7 @@ class SocialSectionWidget extends StatelessWidget {
                 );
               }
             },
-            child: SettingsTextItem(
+            child: const SettingsTextItem(
               text: "Rate us! ✨",
               icon: Icons.navigate_next,
             ),

+ 9 - 5
lib/ui/settings/support_section_widget.dart

@@ -5,10 +5,10 @@ import 'package:flutter/material.dart';
 import 'package:logging/logging.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/constants.dart';
+import 'package:photos/ui/common/web_page.dart';
 import 'package:photos/ui/settings/common_settings.dart';
 import 'package:photos/ui/settings/settings_section_title.dart';
 import 'package:photos/ui/settings/settings_text_item.dart';
-import 'package:photos/ui/web_page.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/email_util.dart';
 import 'package:url_launcher/url_launcher.dart';
@@ -19,7 +19,7 @@ class SupportSectionWidget extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     return ExpandablePanel(
-      header: SettingsSectionTitle("Support"),
+      header: const SettingsSectionTitle("Support"),
       collapsed: Container(),
       expanded: _getSectionOptions(context),
       theme: getExpandableTheme(context),
@@ -45,7 +45,8 @@ class SupportSectionWidget extends StatelessWidget {
               showErrorDialog(context, "", "Please email us at $kSupportEmail");
             }
           },
-          child: SettingsTextItem(text: "Email", icon: Icons.navigate_next),
+          child:
+              const SettingsTextItem(text: "Email", icon: Icons.navigate_next),
         ),
         sectionOptionDivider,
         GestureDetector(
@@ -65,7 +66,10 @@ class SupportSectionWidget extends StatelessWidget {
               ),
             );
           },
-          child: SettingsTextItem(text: "Roadmap", icon: Icons.navigate_next),
+          child: const SettingsTextItem(
+            text: "Roadmap",
+            icon: Icons.navigate_next,
+          ),
         ),
         sectionOptionDivider,
         GestureDetector(
@@ -77,7 +81,7 @@ class SupportSectionWidget extends StatelessWidget {
             final zipFilePath = await getZippedLogsFile(context);
             await shareLogs(context, bugsEmail, zipFilePath);
           },
-          child: SettingsTextItem(
+          child: const SettingsTextItem(
             text: "Report bug 🐞",
             icon: Icons.navigate_next,
           ),

+ 2 - 2
lib/ui/settings/theme_switch_widget.dart

@@ -16,7 +16,7 @@ class ThemeSwitchWidget extends StatelessWidget {
       current: selectedTheme,
       values: const [0, 1],
       onChanged: (i) {
-        print("Changed to ${i}, selectedTheme is ${selectedTheme} ");
+        debugPrint("Changed to {i}, selectedTheme is {selectedTheme} ");
         if (i == 0) {
           AdaptiveTheme.of(context).setLight();
         } else {
@@ -40,7 +40,7 @@ class ThemeSwitchWidget extends StatelessWidget {
         }
       },
       height: 36,
-      indicatorSize: Size(36, 36),
+      indicatorSize: const Size(36, 36),
       indicatorColor: Theme.of(context).colorScheme.themeSwitchIndicatorColor,
       borderColor: Theme.of(context)
           .colorScheme

+ 0 - 25
lib/ui/settings_button.dart

@@ -1,25 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter/widgets.dart';
-import 'package:photos/ui/settings_page.dart';
-import 'package:photos/utils/navigation_util.dart';
-
-class SettingsButton extends StatelessWidget {
-  const SettingsButton({Key key}) : super(key: key);
-
-  @override
-  Widget build(BuildContext context) {
-    return Align(
-      alignment: Alignment.topRight,
-      child: IconButton(
-        icon: Icon(
-          Icons.settings,
-          color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6),
-        ),
-        padding: EdgeInsets.fromLTRB(16, 4, 16, 18),
-        onPressed: () async {
-          routeToPage(context, SettingsPage());
-        },
-      ),
-    );
-  }
-}

+ 24 - 23
lib/ui/settings_page.dart

@@ -31,7 +31,7 @@ class SettingsPage extends StatelessWidget {
     final List<Widget> contents = [];
     contents.add(
       Container(
-        padding: EdgeInsets.symmetric(horizontal: 2, vertical: 6),
+        padding: const EdgeInsets.symmetric(horizontal: 2, vertical: 6),
         child: Row(
           mainAxisAlignment: MainAxisAlignment.spaceBetween,
           crossAxisAlignment: CrossAxisAlignment.center,
@@ -54,7 +54,7 @@ class SettingsPage extends StatelessWidget {
             ),
 
             (Platform.isAndroid)
-                ? ThemeSwitchWidget()
+                ? const ThemeSwitchWidget()
                 : const SizedBox.shrink(),
           ],
         ),
@@ -64,54 +64,55 @@ class SettingsPage extends StatelessWidget {
       height: 20,
       color: Theme.of(context).colorScheme.onSurface.withOpacity(0.12),
     );
-    contents.add(Padding(padding: EdgeInsets.all(4)));
+    contents.add(const Padding(padding: EdgeInsets.all(4)));
     if (hasLoggedIn) {
       contents.addAll([
-        DetailsSectionWidget(),
-        Padding(padding: EdgeInsets.only(bottom: 24)),
-        BackupSectionWidget(),
+        const DetailsSectionWidget(),
+        const Padding(padding: EdgeInsets.only(bottom: 24)),
+        const BackupSectionWidget(),
         sectionDivider,
-        AccountSectionWidget(),
+        const AccountSectionWidget(),
         sectionDivider,
       ]);
     }
     contents.addAll([
-      SecuritySectionWidget(),
+      const SecuritySectionWidget(),
       sectionDivider,
-      SupportSectionWidget(),
+      const SupportSectionWidget(),
       sectionDivider,
-      SocialSectionWidget(),
+      const SocialSectionWidget(),
       sectionDivider,
-      InfoSectionWidget(),
+      const InfoSectionWidget(),
     ]);
     if (hasLoggedIn) {
       contents.addAll([
         sectionDivider,
-        DangerSectionWidget(),
+        const DangerSectionWidget(),
       ]);
     }
 
     if (kDebugMode && hasLoggedIn) {
-      contents.addAll([sectionDivider, DebugSectionWidget()]);
+      contents.addAll([sectionDivider, const DebugSectionWidget()]);
     }
-    contents.add(AppVersionWidget());
+    contents.add(const AppVersionWidget());
     contents.add(
-      Padding(
+      const Padding(
         padding: EdgeInsets.only(bottom: 60),
       ),
     );
 
     return SingleChildScrollView(
       child: Padding(
-          padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 20),
-          child: Center(
-            child: ConstrainedBox(
-              constraints: BoxConstraints(maxWidth: 350),
-              child: Column(
-                children: contents,
-              ),
+        padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 20),
+        child: Center(
+          child: ConstrainedBox(
+            constraints: const BoxConstraints(maxWidth: 350),
+            child: Column(
+              children: contents,
             ),
-          )),
+          ),
+        ),
+      ),
     );
   }
 }

+ 43 - 76
lib/ui/shared_collections_gallery.dart

@@ -13,13 +13,13 @@ import 'package:photos/events/local_photos_updated_event.dart';
 import 'package:photos/events/tab_changed_event.dart';
 import 'package:photos/events/user_logged_out_event.dart';
 import 'package:photos/models/collection_items.dart';
-import 'package:photos/models/galleryType.dart';
+import 'package:photos/models/gallery_type.dart';
 import 'package:photos/services/collections_service.dart';
-import 'package:photos/ui/collection_page.dart';
 import 'package:photos/ui/collections_gallery_widget.dart';
-import 'package:photos/ui/common/gradientButton.dart';
-import 'package:photos/ui/loading_widget.dart';
-import 'package:photos/ui/thumbnail_widget.dart';
+import 'package:photos/ui/common/gradient_button.dart';
+import 'package:photos/ui/common/loading_widget.dart';
+import 'package:photos/ui/viewer/file/thumbnail_widget.dart';
+import 'package:photos/ui/viewer/gallery/collection_page.dart';
 import 'package:photos/utils/navigation_util.dart';
 import 'package:photos/utils/share_util.dart';
 import 'package:photos/utils/toast_util.dart';
@@ -28,7 +28,7 @@ class SharedCollectionGallery extends StatefulWidget {
   const SharedCollectionGallery({Key key}) : super(key: key);
 
   @override
-  _SharedCollectionGalleryState createState() =>
+  State<SharedCollectionGallery> createState() =>
       _SharedCollectionGalleryState();
 }
 
@@ -103,7 +103,7 @@ class _SharedCollectionGalleryState extends State<SharedCollectionGallery>
           _logger.shout(snapshot.error);
           return Center(child: Text(snapshot.error.toString()));
         } else {
-          return loadWidget;
+          return const EnteLoadingWidget();
         }
       },
     );
@@ -124,14 +124,14 @@ class _SharedCollectionGalleryState extends State<SharedCollectionGallery>
         child: Column(
           children: [
             const SizedBox(height: 12),
-            SectionTitle("Shared with me"),
+            const SectionTitle("Shared with me"),
             const SizedBox(height: 12),
             collections.incoming.isNotEmpty
                 ? Padding(
                     padding: const EdgeInsets.symmetric(horizontal: 16),
                     child: GridView.builder(
                       shrinkWrap: true,
-                      physics: NeverScrollableScrollPhysics(),
+                      physics: const NeverScrollableScrollPhysics(),
                       itemBuilder: (context, index) {
                         return IncomingCollectionItem(
                           collections.incoming[index],
@@ -148,13 +148,13 @@ class _SharedCollectionGalleryState extends State<SharedCollectionGallery>
                     ),
                   )
                 : _getIncomingCollectionEmptyState(),
-            SectionTitle("Shared by me"),
+            const SectionTitle("Shared by me"),
             const SizedBox(height: 12),
             collections.outgoing.isNotEmpty
                 ? ListView.builder(
                     shrinkWrap: true,
-                    padding: EdgeInsets.only(bottom: 12),
-                    physics: NeverScrollableScrollPhysics(),
+                    padding: const EdgeInsets.only(bottom: 12),
+                    physics: const NeverScrollableScrollPhysics(),
                     itemBuilder: (context, index) {
                       return OutgoingCollectionItem(
                         collections.outgoing[index],
@@ -180,33 +180,17 @@ class _SharedCollectionGalleryState extends State<SharedCollectionGallery>
             "Ask your loved ones to share",
             style: Theme.of(context).textTheme.caption,
           ),
-          Padding(padding: EdgeInsets.only(top: 14)),
+          const Padding(padding: EdgeInsets.only(top: 14)),
           SizedBox(
             width: 200,
             height: 50,
             child: GradientButton(
-              child: Row(
-                mainAxisAlignment: MainAxisAlignment.center,
-                crossAxisAlignment: CrossAxisAlignment.center,
-                children: [
-                  Icon(
-                    Icons.outgoing_mail,
-                    color: Colors.white,
-                  ),
-                  Padding(padding: EdgeInsets.all(2)),
-                  Text(
-                    "Invite",
-                    style: gradientButtonTextTheme().copyWith(fontSize: 16),
-                  ),
-                ],
-              ),
-              linearGradientColors: const [
-                Color(0xFF2CD267),
-                Color(0xFF1DB954),
-              ],
               onTap: () async {
                 shareText("Check out https://ente.io");
               },
+              iconData: Icons.outgoing_mail,
+              paddingValue: 2,
+              text: "Invite",
             ),
           ),
           const SizedBox(height: 60),
@@ -225,31 +209,11 @@ class _SharedCollectionGalleryState extends State<SharedCollectionGallery>
             "Share your first album",
             style: Theme.of(context).textTheme.caption,
           ),
-          Padding(padding: EdgeInsets.only(top: 14)),
+          const Padding(padding: EdgeInsets.only(top: 14)),
           SizedBox(
             width: 200,
             height: 50,
             child: GradientButton(
-              child: Row(
-                mainAxisAlignment: MainAxisAlignment.center,
-                crossAxisAlignment: CrossAxisAlignment.center,
-                mainAxisSize: MainAxisSize.min,
-                children: [
-                  Icon(
-                    Icons.person_add,
-                    color: Colors.white,
-                  ),
-                  Padding(padding: EdgeInsets.all(2)),
-                  Text(
-                    "Share",
-                    style: gradientButtonTextTheme().copyWith(fontSize: 16),
-                  ),
-                ],
-              ),
-              linearGradientColors: const [
-                Color(0xFF2CD267),
-                Color(0xFF1DB954),
-              ],
               onTap: () async {
                 await showToast(
                   context,
@@ -257,9 +221,12 @@ class _SharedCollectionGalleryState extends State<SharedCollectionGallery>
                   toastLength: Toast.LENGTH_LONG,
                 );
                 Bus.instance.fire(
-                  TabChangedEvent(1, TabChangedEventSource.collections_page),
+                  TabChangedEvent(1, TabChangedEventSource.collectionsPage),
                 );
               },
+              iconData: Icons.person_add,
+              paddingValue: 2,
+              text: "Share",
             ),
           ),
           const SizedBox(height: 60),
@@ -316,12 +283,14 @@ class OutgoingCollectionItem extends StatelessWidget {
     return GestureDetector(
       behavior: HitTestBehavior.opaque,
       child: Container(
-        margin: EdgeInsets.fromLTRB(16, 12, 16, 12),
+        margin: const EdgeInsets.fromLTRB(16, 12, 16, 12),
         child: Row(
           children: <Widget>[
             ClipRRect(
               borderRadius: BorderRadius.circular(3),
               child: SizedBox(
+                height: 60,
+                width: 60,
                 child: Hero(
                   tag: "outgoing_collection" + c.thumbnail.tag(),
                   child: ThumbnailWidget(
@@ -329,11 +298,9 @@ class OutgoingCollectionItem extends StatelessWidget {
                     key: Key("outgoing_collection" + c.thumbnail.tag()),
                   ),
                 ),
-                height: 60,
-                width: 60,
               ),
             ),
-            Padding(padding: EdgeInsets.all(8)),
+            const Padding(padding: EdgeInsets.all(8)),
             Expanded(
               child: Column(
                 crossAxisAlignment: CrossAxisAlignment.start,
@@ -342,20 +309,20 @@ class OutgoingCollectionItem extends StatelessWidget {
                     children: [
                       Text(
                         c.collection.name,
-                        style: TextStyle(
+                        style: const TextStyle(
                           fontSize: 16,
                         ),
                       ),
-                      Padding(padding: EdgeInsets.all(2)),
+                      const Padding(padding: EdgeInsets.all(2)),
                       c.collection.publicURLs.isEmpty
                           ? Container()
-                          : Icon(Icons.link),
+                          : const Icon(Icons.link),
                     ],
                   ),
                   sharees.isEmpty
                       ? Container()
                       : Padding(
-                          padding: EdgeInsets.fromLTRB(0, 4, 0, 0),
+                          padding: const EdgeInsets.fromLTRB(0, 4, 0, 0),
                           child: Text(
                             "Shared with " + sharees.join(", "),
                             style: TextStyle(
@@ -375,7 +342,7 @@ class OutgoingCollectionItem extends StatelessWidget {
       onTap: () {
         final page = CollectionPage(
           c,
-          appBarType: GalleryType.owned_collection,
+          appBarType: GalleryType.ownedCollection,
           tagPrefix: "outgoing_collection",
         );
         routeToPage(context, page);
@@ -411,6 +378,8 @@ class IncomingCollectionItem extends StatelessWidget {
           ClipRRect(
             borderRadius: BorderRadius.circular(4),
             child: SizedBox(
+              height: sideOfThumbnail,
+              width: sideOfThumbnail,
               child: Stack(
                 children: [
                   Hero(
@@ -423,6 +392,14 @@ class IncomingCollectionItem extends StatelessWidget {
                   Align(
                     alignment: Alignment.bottomRight,
                     child: Container(
+                      padding: const EdgeInsets.all(8),
+                      margin: const EdgeInsets.fromLTRB(0, 0, 4, 0),
+                      decoration: BoxDecoration(
+                        shape: BoxShape.circle,
+                        color: Theme.of(context)
+                            .colorScheme
+                            .defaultBackgroundColor,
+                      ),
                       child: Text(
                         c.collection.owner.name == null ||
                                 c.collection.owner.name.isEmpty
@@ -430,23 +407,13 @@ class IncomingCollectionItem extends StatelessWidget {
                             : c.collection.owner.name.substring(0, 1),
                         textAlign: TextAlign.center,
                       ),
-                      padding: EdgeInsets.all(8),
-                      margin: EdgeInsets.fromLTRB(0, 0, 4, 0),
-                      decoration: BoxDecoration(
-                        shape: BoxShape.circle,
-                        color: Theme.of(context)
-                            .colorScheme
-                            .defaultBackgroundColor,
-                      ),
                     ),
                   ),
                 ],
               ),
-              height: sideOfThumbnail,
-              width: sideOfThumbnail,
             ),
           ),
-          SizedBox(height: 4),
+          const SizedBox(height: 4),
           Row(
             children: [
               Container(
@@ -467,7 +434,7 @@ class IncomingCollectionItem extends StatelessWidget {
                           color: albumTitleTextStyle.color.withOpacity(0.5),
                         ),
                         children: [
-                          TextSpan(text: "  \u2022  "),
+                          const TextSpan(text: "  \u2022  "),
                           TextSpan(text: snapshot.data.toString()),
                         ],
                       ),
@@ -486,7 +453,7 @@ class IncomingCollectionItem extends StatelessWidget {
           context,
           CollectionPage(
             c,
-            appBarType: GalleryType.shared_collection,
+            appBarType: GalleryType.sharedCollection,
             tagPrefix: "shared_collection",
           ),
         );

+ 54 - 54
lib/ui/manage_links_widget.dart → lib/ui/sharing/manage_links_widget.dart

@@ -17,23 +17,23 @@ import 'package:tuple/tuple.dart';
 class ManageSharedLinkWidget extends StatefulWidget {
   final Collection collection;
 
-  ManageSharedLinkWidget({Key key, this.collection}) : super(key: key);
+  const ManageSharedLinkWidget({Key key, this.collection}) : super(key: key);
 
   @override
-  _ManageSharedLinkWidgetState createState() => _ManageSharedLinkWidgetState();
+  State<ManageSharedLinkWidget> createState() => _ManageSharedLinkWidgetState();
 }
 
 class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
   // index, title, milliseconds in future post which link should expire (when >0)
   final List<Tuple3<int, String, int>> _expiryOptions = [
-    Tuple3(0, "Never", 0),
-    Tuple3(1, "After 1 hour", Duration(hours: 1).inMicroseconds),
-    Tuple3(2, "After 1 day", Duration(days: 1).inMicroseconds),
-    Tuple3(3, "After 1 week", Duration(days: 7).inMicroseconds),
+    const Tuple3(0, "Never", 0),
+    Tuple3(1, "After 1 hour", const Duration(hours: 1).inMicroseconds),
+    Tuple3(2, "After 1 day", const Duration(days: 1).inMicroseconds),
+    Tuple3(3, "After 1 week", const Duration(days: 7).inMicroseconds),
     // todo: make this time calculation perfect
-    Tuple3(4, "After 1 month", Duration(days: 30).inMicroseconds),
-    Tuple3(5, "After 1 year", Duration(days: 365).inMicroseconds),
-    Tuple3(6, "Custom", -1),
+    Tuple3(4, "After 1 month", const Duration(days: 30).inMicroseconds),
+    Tuple3(5, "After 1 year", const Duration(days: 365).inMicroseconds),
+    const Tuple3(6, "Custom", -1),
   ];
 
   Tuple3<int, String, int> _selectedExpiry;
@@ -51,7 +51,7 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
       backgroundColor: Theme.of(context).backgroundColor,
       appBar: AppBar(
         elevation: 0,
-        title: Text(
+        title: const Text(
           "Manage link",
         ),
       ),
@@ -62,7 +62,7 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
               padding: const EdgeInsets.fromLTRB(16, 12, 16, 12),
               child: Column(
                 children: [
-                  Padding(padding: EdgeInsets.all(4)),
+                  const Padding(padding: EdgeInsets.all(4)),
                   GestureDetector(
                     behavior: HitTestBehavior.translucent,
                     onTap: () async {
@@ -76,18 +76,18 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
                           mainAxisAlignment: MainAxisAlignment.center,
                           crossAxisAlignment: CrossAxisAlignment.start,
                           children: [
-                            Text("Link expiry"),
-                            Padding(padding: EdgeInsets.all(4)),
+                            const Text("Link expiry"),
+                            const Padding(padding: EdgeInsets.all(4)),
                             _getLinkExpiryTimeWidget(),
                           ],
                         ),
-                        Icon(Icons.navigate_next),
+                        const Icon(Icons.navigate_next),
                       ],
                     ),
                   ),
-                  Padding(padding: EdgeInsets.all(4)),
-                  Divider(height: 4),
-                  Padding(padding: EdgeInsets.all(4)),
+                  const Padding(padding: EdgeInsets.all(4)),
+                  const Divider(height: 4),
+                  const Padding(padding: EdgeInsets.all(4)),
                   GestureDetector(
                     behavior: HitTestBehavior.translucent,
                     onTap: () {
@@ -101,30 +101,30 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
                           mainAxisAlignment: MainAxisAlignment.center,
                           crossAxisAlignment: CrossAxisAlignment.start,
                           children: [
-                            Text("Device limit"),
-                            Padding(padding: EdgeInsets.all(4)),
+                            const Text("Device limit"),
+                            const Padding(padding: EdgeInsets.all(4)),
                             Text(
                               widget.collection.publicURLs.first.deviceLimit
                                   .toString(),
-                              style: TextStyle(
+                              style: const TextStyle(
                                 color: Colors.grey,
                               ),
                             ),
                           ],
                         ),
-                        Icon(Icons.navigate_next),
+                        const Icon(Icons.navigate_next),
                       ],
                     ),
                   ),
-                  Padding(padding: EdgeInsets.all(4)),
-                  Divider(height: 4),
-                  Padding(padding: EdgeInsets.all(4)),
+                  const Padding(padding: EdgeInsets.all(4)),
+                  const Divider(height: 4),
+                  const Padding(padding: EdgeInsets.all(4)),
                   SizedBox(
                     height: 36,
                     child: Row(
                       mainAxisAlignment: MainAxisAlignment.spaceBetween,
                       children: [
-                        Text("Password lock"),
+                        const Text("Password lock"),
                         Switch.adaptive(
                           value: widget.collection.publicURLs?.first
                                   ?.passwordEnabled ??
@@ -153,15 +153,15 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
                       ],
                     ),
                   ),
-                  Padding(padding: EdgeInsets.all(4)),
-                  Divider(height: 4),
-                  Padding(padding: EdgeInsets.all(4)),
+                  const Padding(padding: EdgeInsets.all(4)),
+                  const Divider(height: 4),
+                  const Padding(padding: EdgeInsets.all(4)),
                   SizedBox(
                     height: 36,
                     child: Row(
                       mainAxisAlignment: MainAxisAlignment.spaceBetween,
                       children: [
-                        Text("File download"),
+                        const Text("File download"),
                         Switch.adaptive(
                           value: widget.collection.publicURLs?.first
                                   ?.enableDownload ??
@@ -224,7 +224,7 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
             Container(
               decoration: BoxDecoration(
                 color: Theme.of(context).colorScheme.cupertinoPickerTopColor,
-                border: Border(
+                border: const Border(
                   bottom: BorderSide(
                     color: Color(0xff999999),
                     width: 0.0,
@@ -235,10 +235,6 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
                 mainAxisAlignment: MainAxisAlignment.spaceBetween,
                 children: <Widget>[
                   CupertinoButton(
-                    child: Text(
-                      'Cancel',
-                      style: Theme.of(context).textTheme.subtitle1,
-                    ),
                     onPressed: () {
                       Navigator.of(context).pop('cancel');
                     },
@@ -246,12 +242,12 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
                       horizontal: 8.0,
                       vertical: 5.0,
                     ),
-                  ),
-                  CupertinoButton(
                     child: Text(
-                      'Confirm',
+                      'Cancel',
                       style: Theme.of(context).textTheme.subtitle1,
                     ),
+                  ),
+                  CupertinoButton(
                     onPressed: () async {
                       int newValidTill = -1;
                       int expireAfterInMicroseconds = _selectedExpiry.item3;
@@ -282,18 +278,20 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
                       horizontal: 16.0,
                       vertical: 2.0,
                     ),
+                    child: Text(
+                      'Confirm',
+                      style: Theme.of(context).textTheme.subtitle1,
+                    ),
                   )
                 ],
               ),
             ),
             Container(
               height: 220.0,
-              color: Color(0xfff7f7f7),
+              color: const Color(0xfff7f7f7),
               child: CupertinoPicker(
                 backgroundColor:
                     Theme.of(context).backgroundColor.withOpacity(0.95),
-                children:
-                    _expiryOptions.map((e) => getOptionText(e.item2)).toList(),
                 onSelectedItemChanged: (value) {
                   var firstWhere = _expiryOptions
                       .firstWhere((element) => element.item1 == value);
@@ -305,6 +303,8 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
                 useMagnifier: true,
                 itemExtent: 25,
                 diameterRatio: 1,
+                children:
+                    _expiryOptions.map((e) => getOptionText(e.item2)).toList(),
               ),
             )
           ],
@@ -350,12 +350,12 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
         return StatefulBuilder(
           builder: (context, setState) {
             return AlertDialog(
-              title: Text('Enter password'),
+              title: const Text('Enter password'),
               content: TextFormField(
                 autofillHints: const [AutofillHints.newPassword],
                 decoration: InputDecoration(
                   hintText: "Password",
-                  contentPadding: EdgeInsets.all(12),
+                  contentPadding: const EdgeInsets.all(12),
                   suffixIcon: IconButton(
                     icon: Icon(
                       _passwordVisible
@@ -448,7 +448,7 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
   Text _getLinkExpiryTimeWidget() {
     int validTill = widget.collection.publicURLs?.first?.validTill ?? 0;
     if (validTill == 0) {
-      return Text(
+      return const Text(
         'Never',
         style: TextStyle(
           color: Colors.grey,
@@ -465,7 +465,7 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
     }
     return Text(
       getFormattedTime(DateTime.fromMicrosecondsSinceEpoch(validTill)),
-      style: TextStyle(
+      style: const TextStyle(
         color: Colors.grey,
       ),
     );
@@ -487,7 +487,7 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
             Container(
               decoration: BoxDecoration(
                 color: Theme.of(context).colorScheme.cupertinoPickerTopColor,
-                border: Border(
+                border: const Border(
                   bottom: BorderSide(
                     color: Color(0xff999999),
                     width: 0.0,
@@ -498,10 +498,6 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
                 mainAxisAlignment: MainAxisAlignment.spaceBetween,
                 children: <Widget>[
                   CupertinoButton(
-                    child: Text(
-                      'Cancel',
-                      style: Theme.of(context).textTheme.subtitle1,
-                    ),
                     onPressed: () {
                       Navigator.of(context).pop('cancel');
                     },
@@ -509,12 +505,12 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
                       horizontal: 8.0,
                       vertical: 5.0,
                     ),
-                  ),
-                  CupertinoButton(
                     child: Text(
-                      'Confirm',
+                      'Cancel',
                       style: Theme.of(context).textTheme.subtitle1,
                     ),
+                  ),
+                  CupertinoButton(
                     onPressed: () async {
                       await _updateUrlSettings(context, {
                         'deviceLimit': int.tryParse(
@@ -528,17 +524,20 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
                       horizontal: 16.0,
                       vertical: 2.0,
                     ),
+                    child: Text(
+                      'Confirm',
+                      style: Theme.of(context).textTheme.subtitle1,
+                    ),
                   )
                 ],
               ),
             ),
             Container(
               height: 220.0,
-              color: Color(0xfff7f7f7),
+              color: const Color(0xfff7f7f7),
               child: CupertinoPicker(
                 backgroundColor:
                     Theme.of(context).backgroundColor.withOpacity(0.95),
-                children: options,
                 onSelectedItemChanged: (value) {
                   _selectedDeviceLimitIndex = value;
                 },
@@ -546,6 +545,7 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
                 useMagnifier: true,
                 itemExtent: 25,
                 diameterRatio: 1,
+                children: options,
               ),
             )
           ],

+ 37 - 61
lib/ui/share_collection_widget.dart → lib/ui/sharing/share_collection_widget.dart

@@ -16,10 +16,10 @@ import 'package:photos/services/collections_service.dart';
 import 'package:photos/services/feature_flag_service.dart';
 import 'package:photos/services/user_service.dart';
 import 'package:photos/ui/common/dialogs.dart';
-import 'package:photos/ui/common/gradientButton.dart';
-import 'package:photos/ui/loading_widget.dart';
-import 'package:photos/ui/manage_links_widget.dart';
+import 'package:photos/ui/common/gradient_button.dart';
+import 'package:photos/ui/common/loading_widget.dart';
 import 'package:photos/ui/payment/subscription.dart';
+import 'package:photos/ui/sharing/manage_links_widget.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/email_util.dart';
 import 'package:photos/utils/navigation_util.dart';
@@ -29,10 +29,10 @@ import 'package:photos/utils/toast_util.dart';
 class SharingDialog extends StatefulWidget {
   final Collection collection;
 
-  SharingDialog(this.collection, {Key key}) : super(key: key);
+  const SharingDialog(this.collection, {Key key}) : super(key: key);
 
   @override
-  _SharingDialogState createState() => _SharingDialogState();
+  State<SharingDialog> createState() => _SharingDialogState();
 }
 
 class _SharingDialogState extends State<SharingDialog> {
@@ -56,7 +56,7 @@ class _SharingDialogState extends State<SharingDialog> {
       children.add(_getEmailField());
     }
     children.add(
-      Padding(
+      const Padding(
         padding: EdgeInsets.all(8),
       ),
     );
@@ -65,38 +65,13 @@ class _SharingDialogState extends State<SharingDialog> {
         SizedBox(
           width: 220,
           child: GradientButton(
-            child: Row(
-              mainAxisAlignment: MainAxisAlignment.center,
-              crossAxisAlignment: CrossAxisAlignment.center,
-              children: const [
-                Icon(
-                  Icons.add,
-                  color: Colors.white,
-                ),
-              ],
-            ),
-            linearGradientColors: const [
-              Color(0xFF2CD267),
-              Color(0xFF1DB954),
-            ],
             onTap: () async {
               setState(() {
                 _showEntryField = true;
               });
             },
+            iconData: Icons.add,
           ),
-          // child: OutlinedButton(
-          //   child: Icon(
-          //     Icons.add,
-          //     color: Colors.pink,
-          //   ),
-          //   onPressed: () {
-          //     setState(() {
-          //       _showEntryField = true;
-          //     });
-          //   },
-          // ),
-          // ),
         ),
       );
     } else {
@@ -105,7 +80,7 @@ class _SharingDialogState extends State<SharingDialog> {
           width: 240,
           height: 50,
           child: OutlinedButton(
-            child: Text("Add"),
+            child: const Text("Add"),
             onPressed: () {
               _addEmailToCollection(_email?.trim() ?? '');
             },
@@ -117,15 +92,15 @@ class _SharingDialogState extends State<SharingDialog> {
     if (!FeatureFlagService.instance.disableUrlSharing()) {
       bool hasUrl = widget.collection.publicURLs?.isNotEmpty ?? false;
       children.addAll([
-        Padding(padding: EdgeInsets.all(16)),
-        Divider(height: 1),
-        Padding(padding: EdgeInsets.all(12)),
+        const Padding(padding: EdgeInsets.all(16)),
+        const Divider(height: 1),
+        const Padding(padding: EdgeInsets.all(12)),
         SizedBox(
           height: 36,
           child: Row(
             mainAxisAlignment: MainAxisAlignment.center,
             children: [
-              Text("Public link"),
+              const Text("Public link"),
               Switch(
                 value: hasUrl,
                 onChanged: (enable) async {
@@ -184,11 +159,11 @@ class _SharingDialogState extends State<SharingDialog> {
             ],
           ),
         ),
-        Padding(padding: EdgeInsets.all(8)),
+        const Padding(padding: EdgeInsets.all(8)),
       ]);
       if (widget.collection.publicURLs?.isNotEmpty ?? false) {
         children.add(
-          Padding(
+          const Padding(
             padding: EdgeInsets.all(2),
           ),
         );
@@ -197,7 +172,7 @@ class _SharingDialogState extends State<SharingDialog> {
     }
 
     return AlertDialog(
-      title: Text("Sharing"),
+      title: const Text("Sharing"),
       content: SingleChildScrollView(
         child: ListBody(
           children: <Widget>[
@@ -210,7 +185,7 @@ class _SharingDialogState extends State<SharingDialog> {
           ],
         ),
       ),
-      contentPadding: EdgeInsets.fromLTRB(24, 24, 24, 4),
+      contentPadding: const EdgeInsets.fromLTRB(24, 24, 24, 4),
     );
   }
 
@@ -219,7 +194,7 @@ class _SharingDialogState extends State<SharingDialog> {
       children: [
         Expanded(
           child: TypeAheadField(
-            textFieldConfiguration: TextFieldConfiguration(
+            textFieldConfiguration: const TextFieldConfiguration(
               keyboardType: TextInputType.emailAddress,
               decoration: InputDecoration(
                 border: InputBorder.none,
@@ -228,7 +203,7 @@ class _SharingDialogState extends State<SharingDialog> {
             ),
             hideOnEmpty: true,
             loadingBuilder: (context) {
-              return loadWidget;
+              return const EnteLoadingWidget();
             },
             suggestionsCallback: (pattern) async {
               _email = pattern;
@@ -236,7 +211,7 @@ class _SharingDialogState extends State<SharingDialog> {
             },
             itemBuilder: (context, suggestion) {
               return Container(
-                padding: EdgeInsets.fromLTRB(12, 8, 12, 8),
+                padding: const EdgeInsets.fromLTRB(12, 8, 12, 8),
                 child: Text(
                   suggestion.email,
                   overflow: TextOverflow.clip,
@@ -251,7 +226,7 @@ class _SharingDialogState extends State<SharingDialog> {
             },
           ),
         ),
-        Padding(padding: EdgeInsets.all(8)),
+        const Padding(padding: EdgeInsets.all(8)),
         IconButton(
           icon: Icon(
             Icons.contact_mail_outlined,
@@ -278,14 +253,15 @@ class _SharingDialogState extends State<SharingDialog> {
         mainAxisAlignment: MainAxisAlignment.start,
         crossAxisAlignment: CrossAxisAlignment.start,
         children: [
-          Padding(padding: EdgeInsets.all(4)),
+          const Padding(padding: EdgeInsets.all(4)),
           GestureDetector(
             onTap: () async {
               await Clipboard.setData(ClipboardData(text: url));
               showToast(context, "Link copied to clipboard");
             },
             child: Container(
-              padding: EdgeInsets.all(16),
+              padding: const EdgeInsets.all(16),
+              color: Theme.of(context).colorScheme.onSurface.withOpacity(0.02),
               child: Row(
                 crossAxisAlignment: CrossAxisAlignment.end,
                 children: [
@@ -303,17 +279,16 @@ class _SharingDialogState extends State<SharingDialog> {
                       ),
                     ),
                   ),
-                  Padding(padding: EdgeInsets.all(2)),
-                  Icon(
+                  const Padding(padding: EdgeInsets.all(2)),
+                  const Icon(
                     Icons.copy,
                     size: 18,
                   ),
                 ],
               ),
-              color: Theme.of(context).colorScheme.onSurface.withOpacity(0.02),
             ),
           ),
-          Padding(padding: EdgeInsets.all(2)),
+          const Padding(padding: EdgeInsets.all(2)),
           TextButton(
             child: Padding(
               padding: const EdgeInsets.all(12),
@@ -324,7 +299,7 @@ class _SharingDialogState extends State<SharingDialog> {
                     Icons.adaptive.share,
                     color: Theme.of(context).buttonColor,
                   ),
-                  Padding(
+                  const Padding(
                     padding: EdgeInsets.all(4),
                   ),
                   Text(
@@ -340,7 +315,7 @@ class _SharingDialogState extends State<SharingDialog> {
               shareText(url);
             },
           ),
-          Padding(padding: EdgeInsets.all(4)),
+          const Padding(padding: EdgeInsets.all(4)),
           TextButton(
             child: Center(
               child: Text(
@@ -395,12 +370,12 @@ class _SharingDialogState extends State<SharingDialog> {
     if (publicKey == null) {
       Navigator.of(context, rootNavigator: true).pop('dialog');
       final dialog = AlertDialog(
-        title: Text("Invite to ente?"),
+        title: const Text("Invite to ente?"),
         content: Text(
           "Looks like " +
               email +
               " hasn't signed up for ente yet. would you like to invite them?",
-          style: TextStyle(
+          style: const TextStyle(
             height: 1.4,
           ),
         ),
@@ -460,9 +435,10 @@ class _SharingDialogState extends State<SharingDialog> {
 
   void _showUnSupportedAlert() {
     AlertDialog alert = AlertDialog(
-      title: Text("Sorry"),
-      content:
-          Text("Sharing is not permitted for free accounts, please subscribe"),
+      title: const Text("Sorry"),
+      content: const Text(
+        "Sharing is not permitted for free accounts, please subscribe",
+      ),
       actions: [
         TextButton(
           child: Text(
@@ -523,12 +499,12 @@ class EmailItemWidget extends StatelessWidget {
           padding: const EdgeInsets.fromLTRB(8, 0, 0, 0),
           child: Text(
             email,
-            style: TextStyle(fontSize: 16),
+            style: const TextStyle(fontSize: 16),
           ),
         ),
-        Expanded(child: SizedBox()),
+        const Expanded(child: SizedBox()),
         IconButton(
-          icon: Icon(Icons.delete_forever),
+          icon: const Icon(Icons.delete_forever),
           color: Colors.redAccent,
           onPressed: () async {
             final dialog = createProgressDialog(context, "Please wait...");

+ 26 - 26
lib/ui/status_bar_widget.dart

@@ -22,9 +22,9 @@ class _StatusBarWidgetState extends State<StatusBarWidget> {
   @override
   void initState() {
     _subscription = Bus.instance.on<SyncStatusUpdate>().listen((event) {
-      if (event.status == SyncStatus.completed_first_gallery_import ||
-          event.status == SyncStatus.completed_backup) {
-        Future.delayed(Duration(milliseconds: 2000), () {
+      if (event.status == SyncStatus.completedFirstGalleryImport ||
+          event.status == SyncStatus.completedBackup) {
+        Future.delayed(const Duration(milliseconds: 2000), () {
           if (mounted) {
             setState(() {
               _showStatus = false;
@@ -56,20 +56,20 @@ class _StatusBarWidgetState extends State<StatusBarWidget> {
             children: [
               AnimatedOpacity(
                 opacity: _showStatus ? 0 : 1,
-                duration: Duration(milliseconds: 1000),
-                child: StatusBarBrandingWidget(),
+                duration: const Duration(milliseconds: 1000),
+                child: const StatusBarBrandingWidget(),
               ),
               AnimatedOpacity(
                 opacity: _showStatus ? 1 : 0,
-                duration: Duration(milliseconds: 1000),
-                child: SyncStatusWidget(),
+                duration: const Duration(milliseconds: 1000),
+                child: const SyncStatusWidget(),
               ),
             ],
           ),
           AnimatedOpacity(
             opacity: _showStatus ? 1 : 0,
-            duration: Duration(milliseconds: 1000),
-            child: Divider(),
+            duration: const Duration(milliseconds: 1000),
+            child: const Divider(),
           ),
         ],
       ),
@@ -81,7 +81,7 @@ class SyncStatusWidget extends StatefulWidget {
   const SyncStatusWidget({Key key}) : super(key: key);
 
   @override
-  _SyncStatusWidgetState createState() => _SyncStatusWidgetState();
+  State<SyncStatusWidget> createState() => _SyncStatusWidgetState();
 }
 
 class _SyncStatusWidgetState extends State<SyncStatusWidget> {
@@ -110,8 +110,8 @@ class _SyncStatusWidgetState extends State<SyncStatusWidget> {
   @override
   Widget build(BuildContext context) {
     bool isNotOutdatedEvent = _event != null &&
-        (_event.status == SyncStatus.completed_backup ||
-            _event.status == SyncStatus.completed_first_gallery_import) &&
+        (_event.status == SyncStatus.completedBackup ||
+            _event.status == SyncStatus.completedFirstGalleryImport) &&
         (DateTime.now().microsecondsSinceEpoch - _event.timestamp >
             kSleepDuration.inMicroseconds);
     if (_event == null || isNotOutdatedEvent) {
@@ -120,8 +120,8 @@ class _SyncStatusWidgetState extends State<SyncStatusWidget> {
     if (_event.status == SyncStatus.error) {
       return HeaderErrorWidget(error: _event.error);
     }
-    if (_event.status == SyncStatus.completed_backup) {
-      return SyncStatusCompletedWidget();
+    if (_event.status == SyncStatus.completedBackup) {
+      return const SyncStatusCompletedWidget();
     }
     return RefreshIndicatorWidget(_event);
   }
@@ -144,7 +144,7 @@ class RefreshIndicatorWidget extends StatelessWidget {
       width: double.infinity,
       alignment: Alignment.center,
       child: SingleChildScrollView(
-        physics: NeverScrollableScrollPhysics(),
+        physics: const NeverScrollableScrollPhysics(),
         child: Column(
           mainAxisAlignment: MainAxisAlignment.center,
           crossAxisAlignment: CrossAxisAlignment.center,
@@ -154,7 +154,7 @@ class RefreshIndicatorWidget extends StatelessWidget {
               crossAxisAlignment: CrossAxisAlignment.center,
               children: [
                 Container(
-                  padding: EdgeInsets.all(2),
+                  padding: const EdgeInsets.all(2),
                   width: 22,
                   height: 22,
                   child: _inProgressIcon,
@@ -172,17 +172,17 @@ class RefreshIndicatorWidget extends StatelessWidget {
   }
 
   String _getRefreshingText() {
-    if (event.status == SyncStatus.started_first_gallery_import ||
-        event.status == SyncStatus.completed_first_gallery_import) {
+    if (event.status == SyncStatus.startedFirstGalleryImport ||
+        event.status == SyncStatus.completedFirstGalleryImport) {
       return "Loading gallery...";
     }
-    if (event.status == SyncStatus.applying_remote_diff) {
+    if (event.status == SyncStatus.applyingRemoteDiff) {
       return "Syncing...";
     }
-    if (event.status == SyncStatus.preparing_for_upload) {
+    if (event.status == SyncStatus.preparingForUpload) {
       return "Encrypting backup...";
     }
-    if (event.status == SyncStatus.in_progress) {
+    if (event.status == SyncStatus.inProgress) {
       return event.completed.toString() +
           "/" +
           event.total.toString() +
@@ -194,7 +194,7 @@ class RefreshIndicatorWidget extends StatelessWidget {
     if (event.status == SyncStatus.error) {
       return event.reason ?? "Upload failed";
     }
-    if (event.status == SyncStatus.completed_backup) {
+    if (event.status == SyncStatus.completedBackup) {
       if (event.wasStopped) {
         return "Sync stopped";
       }
@@ -210,8 +210,8 @@ class StatusBarBrandingWidget extends StatelessWidget {
   Widget build(BuildContext context) {
     return Container(
       height: kContainerHeight,
-      padding: EdgeInsets.only(left: 12),
-      child: Align(
+      padding: const EdgeInsets.only(left: 12),
+      child: const Align(
         alignment: Alignment.centerLeft,
         child: Text(
           "ente",
@@ -249,8 +249,8 @@ class SyncStatusCompletedWidget extends StatelessWidget {
                   color: Theme.of(context).buttonColor,
                   size: 22,
                 ),
-                Padding(
-                  padding: const EdgeInsets.only(left: 12),
+                const Padding(
+                  padding: EdgeInsets.only(left: 12),
                   child: Text("All memories preserved"),
                 ),
               ],

+ 4 - 1
lib/ui/app_lock.dart → lib/ui/tools/app_lock.dart

@@ -21,6 +21,9 @@ import 'package:flutter/material.dart';
 /// [backgroundLockLatency] determines how much time is allowed to pass when
 /// the app is in the background state before the [lockScreen] widget should be
 /// shown upon returning. It defaults to instantly.
+///
+
+// ignore_for_file: unnecessary_this, library_private_types_in_public_api
 class AppLock extends StatefulWidget {
   final Widget Function(Object) builder;
   final Widget lockScreen;
@@ -43,7 +46,7 @@ class AppLock extends StatefulWidget {
       context.findAncestorStateOfType<_AppLockState>();
 
   @override
-  _AppLockState createState() => _AppLockState();
+  State<AppLock> createState() => _AppLockState();
 }
 
 class _AppLockState extends State<AppLock> with WidgetsBindingObserver {

+ 7 - 7
lib/ui/log_file_viewer.dart → lib/ui/tools/debug/log_file_viewer.dart

@@ -2,14 +2,14 @@ import 'dart:io';
 import 'dart:ui';
 
 import 'package:flutter/material.dart';
-import 'package:photos/ui/loading_widget.dart';
+import 'package:photos/ui/common/loading_widget.dart';
 
 class LogFileViewer extends StatefulWidget {
   final File file;
   const LogFileViewer(this.file, {Key key}) : super(key: key);
 
   @override
-  _LogFileViewerState createState() => _LogFileViewerState();
+  State<LogFileViewer> createState() => _LogFileViewerState();
 }
 
 class _LogFileViewerState extends State<LogFileViewer> {
@@ -29,7 +29,7 @@ class _LogFileViewerState extends State<LogFileViewer> {
     return Scaffold(
       appBar: AppBar(
         elevation: 0,
-        title: Text("Today's logs"),
+        title: const Text("Today's logs"),
       ),
       body: _getBody(),
     );
@@ -37,15 +37,15 @@ class _LogFileViewerState extends State<LogFileViewer> {
 
   Widget _getBody() {
     if (_logs == null) {
-      return loadWidget;
+      return const EnteLoadingWidget();
     }
     return Container(
-      padding: EdgeInsets.only(left: 12, top: 8, right: 12),
+      padding: const EdgeInsets.only(left: 12, top: 8, right: 12),
       child: SingleChildScrollView(
         child: Text(
           _logs,
-          style: TextStyle(
-            fontFeatures: const [
+          style: const TextStyle(
+            fontFeatures: [
               FontFeature.tabularFigures(),
             ],
             height: 1.2,

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor