Browse Source

Merge branch 'migrate-to-null-safety' into migrate-to-null-safety-2

ashilkn 2 years ago
parent
commit
51eb2cceff
41 changed files with 717 additions and 379 deletions
  1. 0 59
      ios/Podfile.lock
  2. 0 18
      ios/Runner.xcodeproj/project.pbxproj
  3. 0 3
      lib/app.dart
  4. 4 4
      lib/core/cache/thumbnail_cache.dart
  5. 2 2
      lib/core/configuration.dart
  6. 22 22
      lib/core/constants.dart
  7. 0 8
      lib/core/network.dart
  8. 23 0
      lib/ente_theme_data.dart
  9. 5 0
      lib/events/notification_event.dart
  10. 4 2
      lib/main.dart
  11. 2 2
      lib/models/file.dart
  12. 3 0
      lib/services/collections_service.dart
  13. 1 1
      lib/services/memories_service.dart
  14. 1 2
      lib/services/push_service.dart
  15. 1 1
      lib/services/sync_service.dart
  16. 1 1
      lib/services/update_service.dart
  17. 123 0
      lib/services/user_remote_flag_service.dart
  18. 138 124
      lib/ui/account/recovery_key_page.dart
  19. 241 0
      lib/ui/account/verify_recovery_page.dart
  20. 76 0
      lib/ui/components/notification_warning_widget.dart
  21. 3 3
      lib/ui/huge_listview/lazy_loading_gallery.dart
  22. 2 2
      lib/ui/settings/app_update_dialog.dart
  23. 0 2
      lib/ui/settings/app_version_widget.dart
  24. 0 11
      lib/ui/settings/debug_section_widget.dart
  25. 2 2
      lib/ui/settings/support_section_widget.dart
  26. 27 0
      lib/ui/status_bar_widget.dart
  27. 2 3
      lib/ui/tools/deduplicate_page.dart
  28. 1 1
      lib/ui/viewer/file/detail_page.dart
  29. 2 2
      lib/ui/viewer/file/thumbnail_widget.dart
  30. 1 1
      lib/ui/viewer/file/video_widget.dart
  31. 3 4
      lib/ui/viewer/file/zoomable_image.dart
  32. 3 3
      lib/ui/viewer/file/zoomable_live_image.dart
  33. 2 2
      lib/ui/viewer/gallery/gallery.dart
  34. 1 0
      lib/utils/crypto_util.dart
  35. 3 3
      lib/utils/delete_file_util.dart
  36. 5 5
      lib/utils/file_uploader_util.dart
  37. 5 5
      lib/utils/file_util.dart
  38. 3 2
      lib/utils/share_util.dart
  39. 3 3
      lib/utils/thumbnail_util.dart
  40. 0 72
      pubspec.lock
  41. 2 4
      pubspec.yaml

+ 0 - 59
ios/Podfile.lock

@@ -1,13 +1,6 @@
 PODS:
 PODS:
   - background_fetch (1.1.0):
   - background_fetch (1.1.0):
     - Flutter
     - Flutter
-  - better_player (0.0.1):
-    - Cache (~> 6.0.0)
-    - Flutter
-    - GCDWebServer
-    - HLSCachingReverseProxyServer
-    - PINCache
-  - Cache (6.0.0)
   - connectivity (0.0.1):
   - connectivity (0.0.1):
     - Flutter
     - Flutter
     - Reachability
     - Reachability
@@ -83,9 +76,6 @@ PODS:
   - FMDB (2.7.5):
   - FMDB (2.7.5):
     - FMDB/standard (= 2.7.5)
     - FMDB/standard (= 2.7.5)
   - FMDB/standard (2.7.5)
   - FMDB/standard (2.7.5)
-  - GCDWebServer (3.5.4):
-    - GCDWebServer/Core (= 3.5.4)
-  - GCDWebServer/Core (3.5.4)
   - GoogleDataTransport (9.1.4):
   - GoogleDataTransport (9.1.4):
     - GoogleUtilities/Environment (~> 7.7)
     - GoogleUtilities/Environment (~> 7.7)
     - nanopb (< 2.30910.0, >= 2.30908.0)
     - nanopb (< 2.30910.0, >= 2.30908.0)
@@ -107,9 +97,6 @@ PODS:
     - GoogleUtilities/Logger
     - GoogleUtilities/Logger
   - GoogleUtilities/UserDefaults (7.7.0):
   - GoogleUtilities/UserDefaults (7.7.0):
     - GoogleUtilities/Logger
     - GoogleUtilities/Logger
-  - HLSCachingReverseProxyServer (0.1.0):
-    - GCDWebServer (~> 3.5)
-    - PINCache (>= 3.0.1-beta.3)
   - image_editor (0.0.1):
   - image_editor (0.0.1):
     - Flutter
     - Flutter
   - in_app_purchase (0.0.1):
   - in_app_purchase (0.0.1):
@@ -137,8 +124,6 @@ PODS:
     - nanopb/encode (= 2.30908.0)
     - nanopb/encode (= 2.30908.0)
   - nanopb/decode (2.30908.0)
   - nanopb/decode (2.30908.0)
   - nanopb/encode (2.30908.0)
   - nanopb/encode (2.30908.0)
-  - open_file (0.0.1):
-    - Flutter
   - open_mail_app (0.0.1):
   - open_mail_app (0.0.1):
     - Flutter
     - Flutter
   - OrderedSet (5.0.0)
   - OrderedSet (5.0.0)
@@ -146,19 +131,9 @@ PODS:
     - Flutter
     - Flutter
   - path_provider_ios (0.0.1):
   - path_provider_ios (0.0.1):
     - Flutter
     - Flutter
-  - "permission_handler (5.1.0+2)":
-    - Flutter
   - photo_manager (2.0.0):
   - photo_manager (2.0.0):
     - Flutter
     - Flutter
     - FlutterMacOS
     - FlutterMacOS
-  - PINCache (3.0.3):
-    - PINCache/Arc-exception-safe (= 3.0.3)
-    - PINCache/Core (= 3.0.3)
-  - PINCache/Arc-exception-safe (3.0.3):
-    - PINCache/Core
-  - PINCache/Core (3.0.3):
-    - PINOperation (~> 1.2.1)
-  - PINOperation (1.2.1)
   - PromisesObjC (2.1.0)
   - PromisesObjC (2.1.0)
   - Reachability (3.2)
   - Reachability (3.2)
   - receive_sharing_intent (0.0.1):
   - receive_sharing_intent (0.0.1):
@@ -169,8 +144,6 @@ PODS:
   - SDWebImageWebPCoder (0.8.4):
   - SDWebImageWebPCoder (0.8.4):
     - libwebp (~> 1.0)
     - libwebp (~> 1.0)
     - SDWebImage/Core (~> 5.10)
     - SDWebImage/Core (~> 5.10)
-  - sensors (0.0.1):
-    - Flutter
   - Sentry (7.11.0):
   - Sentry (7.11.0):
     - Sentry/Core (= 7.11.0)
     - Sentry/Core (= 7.11.0)
   - Sentry/Core (7.11.0)
   - Sentry/Core (7.11.0)
@@ -178,8 +151,6 @@ PODS:
     - Flutter
     - Flutter
     - FlutterMacOS
     - FlutterMacOS
     - Sentry (~> 7.11.0)
     - Sentry (~> 7.11.0)
-  - share (0.0.1):
-    - Flutter
   - share_plus (0.0.1):
   - share_plus (0.0.1):
     - Flutter
     - Flutter
   - shared_preferences_ios (0.0.1):
   - shared_preferences_ios (0.0.1):
@@ -202,7 +173,6 @@ PODS:
 
 
 DEPENDENCIES:
 DEPENDENCIES:
   - background_fetch (from `.symlinks/plugins/background_fetch/ios`)
   - background_fetch (from `.symlinks/plugins/background_fetch/ios`)
-  - better_player (from `.symlinks/plugins/better_player/ios`)
   - connectivity (from `.symlinks/plugins/connectivity/ios`)
   - connectivity (from `.symlinks/plugins/connectivity/ios`)
   - device_info (from `.symlinks/plugins/device_info/ios`)
   - device_info (from `.symlinks/plugins/device_info/ios`)
   - firebase_core (from `.symlinks/plugins/firebase_core/ios`)
   - firebase_core (from `.symlinks/plugins/firebase_core/ios`)
@@ -224,16 +194,12 @@ DEPENDENCIES:
   - local_auth (from `.symlinks/plugins/local_auth/ios`)
   - local_auth (from `.symlinks/plugins/local_auth/ios`)
   - motionphoto (from `.symlinks/plugins/motionphoto/ios`)
   - motionphoto (from `.symlinks/plugins/motionphoto/ios`)
   - move_to_background (from `.symlinks/plugins/move_to_background/ios`)
   - move_to_background (from `.symlinks/plugins/move_to_background/ios`)
-  - open_file (from `.symlinks/plugins/open_file/ios`)
   - open_mail_app (from `.symlinks/plugins/open_mail_app/ios`)
   - open_mail_app (from `.symlinks/plugins/open_mail_app/ios`)
   - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
   - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
   - path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
   - path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
-  - permission_handler (from `.symlinks/plugins/permission_handler/ios`)
   - photo_manager (from `.symlinks/plugins/photo_manager/ios`)
   - photo_manager (from `.symlinks/plugins/photo_manager/ios`)
   - receive_sharing_intent (from `.symlinks/plugins/receive_sharing_intent/ios`)
   - receive_sharing_intent (from `.symlinks/plugins/receive_sharing_intent/ios`)
-  - sensors (from `.symlinks/plugins/sensors/ios`)
   - sentry_flutter (from `.symlinks/plugins/sentry_flutter/ios`)
   - sentry_flutter (from `.symlinks/plugins/sentry_flutter/ios`)
-  - share (from `.symlinks/plugins/share/ios`)
   - share_plus (from `.symlinks/plugins/share_plus/ios`)
   - share_plus (from `.symlinks/plugins/share_plus/ios`)
   - shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`)
   - shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`)
   - sqflite (from `.symlinks/plugins/sqflite/ios`)
   - sqflite (from `.symlinks/plugins/sqflite/ios`)
@@ -245,23 +211,18 @@ DEPENDENCIES:
 
 
 SPEC REPOS:
 SPEC REPOS:
   trunk:
   trunk:
-    - Cache
     - Firebase
     - Firebase
     - FirebaseCore
     - FirebaseCore
     - FirebaseCoreDiagnostics
     - FirebaseCoreDiagnostics
     - FirebaseInstallations
     - FirebaseInstallations
     - FirebaseMessaging
     - FirebaseMessaging
     - FMDB
     - FMDB
-    - GCDWebServer
     - GoogleDataTransport
     - GoogleDataTransport
     - GoogleUtilities
     - GoogleUtilities
-    - HLSCachingReverseProxyServer
     - libwebp
     - libwebp
     - Mantle
     - Mantle
     - nanopb
     - nanopb
     - OrderedSet
     - OrderedSet
-    - PINCache
-    - PINOperation
     - PromisesObjC
     - PromisesObjC
     - Reachability
     - Reachability
     - SDWebImage
     - SDWebImage
@@ -272,8 +233,6 @@ SPEC REPOS:
 EXTERNAL SOURCES:
 EXTERNAL SOURCES:
   background_fetch:
   background_fetch:
     :path: ".symlinks/plugins/background_fetch/ios"
     :path: ".symlinks/plugins/background_fetch/ios"
-  better_player:
-    :path: ".symlinks/plugins/better_player/ios"
   connectivity:
   connectivity:
     :path: ".symlinks/plugins/connectivity/ios"
     :path: ".symlinks/plugins/connectivity/ios"
   device_info:
   device_info:
@@ -316,26 +275,18 @@ EXTERNAL SOURCES:
     :path: ".symlinks/plugins/motionphoto/ios"
     :path: ".symlinks/plugins/motionphoto/ios"
   move_to_background:
   move_to_background:
     :path: ".symlinks/plugins/move_to_background/ios"
     :path: ".symlinks/plugins/move_to_background/ios"
-  open_file:
-    :path: ".symlinks/plugins/open_file/ios"
   open_mail_app:
   open_mail_app:
     :path: ".symlinks/plugins/open_mail_app/ios"
     :path: ".symlinks/plugins/open_mail_app/ios"
   package_info_plus:
   package_info_plus:
     :path: ".symlinks/plugins/package_info_plus/ios"
     :path: ".symlinks/plugins/package_info_plus/ios"
   path_provider_ios:
   path_provider_ios:
     :path: ".symlinks/plugins/path_provider_ios/ios"
     :path: ".symlinks/plugins/path_provider_ios/ios"
-  permission_handler:
-    :path: ".symlinks/plugins/permission_handler/ios"
   photo_manager:
   photo_manager:
     :path: ".symlinks/plugins/photo_manager/ios"
     :path: ".symlinks/plugins/photo_manager/ios"
   receive_sharing_intent:
   receive_sharing_intent:
     :path: ".symlinks/plugins/receive_sharing_intent/ios"
     :path: ".symlinks/plugins/receive_sharing_intent/ios"
-  sensors:
-    :path: ".symlinks/plugins/sensors/ios"
   sentry_flutter:
   sentry_flutter:
     :path: ".symlinks/plugins/sentry_flutter/ios"
     :path: ".symlinks/plugins/sentry_flutter/ios"
-  share:
-    :path: ".symlinks/plugins/share/ios"
   share_plus:
   share_plus:
     :path: ".symlinks/plugins/share_plus/ios"
     :path: ".symlinks/plugins/share_plus/ios"
   shared_preferences_ios:
   shared_preferences_ios:
@@ -355,8 +306,6 @@ EXTERNAL SOURCES:
 
 
 SPEC CHECKSUMS:
 SPEC CHECKSUMS:
   background_fetch: 3795af8a49054dc526477cc2f60d2ed41de60587
   background_fetch: 3795af8a49054dc526477cc2f60d2ed41de60587
-  better_player: 2406bfe8175203c7a46fa15f9d778d73b12e1646
-  Cache: 4ca7e00363fca5455f26534e5607634c820ffc2d
   connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467
   connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467
   device_info: d7d233b645a32c40dfdc212de5cf646ca482f175
   device_info: d7d233b645a32c40dfdc212de5cf646ca482f175
   Firebase: 5f8193dff4b5b7c5d5ef72ae54bb76c08e2b841d
   Firebase: 5f8193dff4b5b7c5d5ef72ae54bb76c08e2b841d
@@ -379,10 +328,8 @@ SPEC CHECKSUMS:
   fluttercontactpicker: d582836dea6b5d489f3d259f35d7817ae82ee5e6
   fluttercontactpicker: d582836dea6b5d489f3d259f35d7817ae82ee5e6
   fluttertoast: 16fbe6039d06a763f3533670197d01fc73459037
   fluttertoast: 16fbe6039d06a763f3533670197d01fc73459037
   FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
   FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
-  GCDWebServer: 2c156a56c8226e2d5c0c3f208a3621ccffbe3ce4
   GoogleDataTransport: 5fffe35792f8b96ec8d6775f5eccd83c998d5a3b
   GoogleDataTransport: 5fffe35792f8b96ec8d6775f5eccd83c998d5a3b
   GoogleUtilities: e0913149f6b0625b553d70dae12b49fc62914fd1
   GoogleUtilities: e0913149f6b0625b553d70dae12b49fc62914fd1
-  HLSCachingReverseProxyServer: 59935e1e0244ad7f3375d75b5ef46e8eb26ab181
   image_editor: c1d038630eedea60d2dee9c14f36aa66c7f9cfab
   image_editor: c1d038630eedea60d2dee9c14f36aa66c7f9cfab
   in_app_purchase: 3e2155afa9d03d4fa32d9e62d567885080ce97d6
   in_app_purchase: 3e2155afa9d03d4fa32d9e62d567885080ce97d6
   libwebp: 98a37e597e40bfdb4c911fc98f2c53d0b12d05fc
   libwebp: 98a37e597e40bfdb4c911fc98f2c53d0b12d05fc
@@ -391,24 +338,18 @@ SPEC CHECKSUMS:
   motionphoto: d4a432b8c8f22fb3ad966258597c0103c9c5ff16
   motionphoto: d4a432b8c8f22fb3ad966258597c0103c9c5ff16
   move_to_background: 39a5b79b26d577b0372cbe8a8c55e7aa9fcd3a2d
   move_to_background: 39a5b79b26d577b0372cbe8a8c55e7aa9fcd3a2d
   nanopb: a0ba3315591a9ae0a16a309ee504766e90db0c96
   nanopb: a0ba3315591a9ae0a16a309ee504766e90db0c96
-  open_file: 02eb5cb6b21264bd3a696876f5afbfb7ca4f4b7d
   open_mail_app: 794172f6a22cd16319d3ddaf45e945b2f74952b0
   open_mail_app: 794172f6a22cd16319d3ddaf45e945b2f74952b0
   OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
   OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
   package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
   package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
   path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02
   path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02
-  permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0
   photo_manager: 4f6810b7dfc4feb03b461ac1a70dacf91fba7604
   photo_manager: 4f6810b7dfc4feb03b461ac1a70dacf91fba7604
-  PINCache: 7a8fc1a691173d21dbddbf86cd515de6efa55086
-  PINOperation: 00c935935f1e8cf0d1e2d6b542e75b88fc3e5e20
   PromisesObjC: 99b6f43f9e1044bd87a95a60beff28c2c44ddb72
   PromisesObjC: 99b6f43f9e1044bd87a95a60beff28c2c44ddb72
   Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
   Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
   receive_sharing_intent: c0d87310754e74c0f9542947e7cbdf3a0335a3b1
   receive_sharing_intent: c0d87310754e74c0f9542947e7cbdf3a0335a3b1
   SDWebImage: 0905f1b7760fc8ac4198cae0036600d67478751e
   SDWebImage: 0905f1b7760fc8ac4198cae0036600d67478751e
   SDWebImageWebPCoder: f93010f3f6c031e2f8fb3081ca4ee6966c539815
   SDWebImageWebPCoder: f93010f3f6c031e2f8fb3081ca4ee6966c539815
-  sensors: 84eb7a30e47a649e4172b71d6e81be614c280336
   Sentry: 0c5cd63d714187b4a39c331c1f0eb04ba7868341
   Sentry: 0c5cd63d714187b4a39c331c1f0eb04ba7868341
   sentry_flutter: efb3df2c203cd03aad255892a8d628a458656d14
   sentry_flutter: efb3df2c203cd03aad255892a8d628a458656d14
-  share: 0b2c3e82132f5888bccca3351c504d0003b3b410
   share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68
   share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68
   shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad
   shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad
   sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
   sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904

+ 0 - 18
ios/Runner.xcodeproj/project.pbxproj

@@ -256,20 +256,15 @@
 			);
 			);
 			inputPaths = (
 			inputPaths = (
 				"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
 				"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
-				"${BUILT_PRODUCTS_DIR}/Cache/Cache.framework",
 				"${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework",
 				"${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework",
 				"${BUILT_PRODUCTS_DIR}/FirebaseCore/FirebaseCore.framework",
 				"${BUILT_PRODUCTS_DIR}/FirebaseCore/FirebaseCore.framework",
 				"${BUILT_PRODUCTS_DIR}/FirebaseCoreDiagnostics/FirebaseCoreDiagnostics.framework",
 				"${BUILT_PRODUCTS_DIR}/FirebaseCoreDiagnostics/FirebaseCoreDiagnostics.framework",
 				"${BUILT_PRODUCTS_DIR}/FirebaseInstallations/FirebaseInstallations.framework",
 				"${BUILT_PRODUCTS_DIR}/FirebaseInstallations/FirebaseInstallations.framework",
 				"${BUILT_PRODUCTS_DIR}/FirebaseMessaging/FirebaseMessaging.framework",
 				"${BUILT_PRODUCTS_DIR}/FirebaseMessaging/FirebaseMessaging.framework",
-				"${BUILT_PRODUCTS_DIR}/GCDWebServer/GCDWebServer.framework",
 				"${BUILT_PRODUCTS_DIR}/GoogleDataTransport/GoogleDataTransport.framework",
 				"${BUILT_PRODUCTS_DIR}/GoogleDataTransport/GoogleDataTransport.framework",
 				"${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework",
 				"${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework",
-				"${BUILT_PRODUCTS_DIR}/HLSCachingReverseProxyServer/HLSCachingReverseProxyServer.framework",
 				"${BUILT_PRODUCTS_DIR}/Mantle/Mantle.framework",
 				"${BUILT_PRODUCTS_DIR}/Mantle/Mantle.framework",
 				"${BUILT_PRODUCTS_DIR}/OrderedSet/OrderedSet.framework",
 				"${BUILT_PRODUCTS_DIR}/OrderedSet/OrderedSet.framework",
-				"${BUILT_PRODUCTS_DIR}/PINCache/PINCache.framework",
-				"${BUILT_PRODUCTS_DIR}/PINOperation/PINOperation.framework",
 				"${BUILT_PRODUCTS_DIR}/PromisesObjC/FBLPromises.framework",
 				"${BUILT_PRODUCTS_DIR}/PromisesObjC/FBLPromises.framework",
 				"${BUILT_PRODUCTS_DIR}/Reachability/Reachability.framework",
 				"${BUILT_PRODUCTS_DIR}/Reachability/Reachability.framework",
 				"${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework",
 				"${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework",
@@ -277,7 +272,6 @@
 				"${BUILT_PRODUCTS_DIR}/Sentry/Sentry.framework",
 				"${BUILT_PRODUCTS_DIR}/Sentry/Sentry.framework",
 				"${BUILT_PRODUCTS_DIR}/Toast/Toast.framework",
 				"${BUILT_PRODUCTS_DIR}/Toast/Toast.framework",
 				"${BUILT_PRODUCTS_DIR}/background_fetch/background_fetch.framework",
 				"${BUILT_PRODUCTS_DIR}/background_fetch/background_fetch.framework",
-				"${BUILT_PRODUCTS_DIR}/better_player/better_player.framework",
 				"${BUILT_PRODUCTS_DIR}/connectivity/connectivity.framework",
 				"${BUILT_PRODUCTS_DIR}/connectivity/connectivity.framework",
 				"${BUILT_PRODUCTS_DIR}/device_info/device_info.framework",
 				"${BUILT_PRODUCTS_DIR}/device_info/device_info.framework",
 				"${BUILT_PRODUCTS_DIR}/fk_user_agent/fk_user_agent.framework",
 				"${BUILT_PRODUCTS_DIR}/fk_user_agent/fk_user_agent.framework",
@@ -298,15 +292,12 @@
 				"${BUILT_PRODUCTS_DIR}/motionphoto/motionphoto.framework",
 				"${BUILT_PRODUCTS_DIR}/motionphoto/motionphoto.framework",
 				"${BUILT_PRODUCTS_DIR}/move_to_background/move_to_background.framework",
 				"${BUILT_PRODUCTS_DIR}/move_to_background/move_to_background.framework",
 				"${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework",
 				"${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework",
-				"${BUILT_PRODUCTS_DIR}/open_file/open_file.framework",
 				"${BUILT_PRODUCTS_DIR}/open_mail_app/open_mail_app.framework",
 				"${BUILT_PRODUCTS_DIR}/open_mail_app/open_mail_app.framework",
 				"${BUILT_PRODUCTS_DIR}/package_info_plus/package_info_plus.framework",
 				"${BUILT_PRODUCTS_DIR}/package_info_plus/package_info_plus.framework",
 				"${BUILT_PRODUCTS_DIR}/path_provider_ios/path_provider_ios.framework",
 				"${BUILT_PRODUCTS_DIR}/path_provider_ios/path_provider_ios.framework",
 				"${BUILT_PRODUCTS_DIR}/photo_manager/photo_manager.framework",
 				"${BUILT_PRODUCTS_DIR}/photo_manager/photo_manager.framework",
 				"${BUILT_PRODUCTS_DIR}/receive_sharing_intent/receive_sharing_intent.framework",
 				"${BUILT_PRODUCTS_DIR}/receive_sharing_intent/receive_sharing_intent.framework",
-				"${BUILT_PRODUCTS_DIR}/sensors/sensors.framework",
 				"${BUILT_PRODUCTS_DIR}/sentry_flutter/sentry_flutter.framework",
 				"${BUILT_PRODUCTS_DIR}/sentry_flutter/sentry_flutter.framework",
-				"${BUILT_PRODUCTS_DIR}/share/share.framework",
 				"${BUILT_PRODUCTS_DIR}/share_plus/share_plus.framework",
 				"${BUILT_PRODUCTS_DIR}/share_plus/share_plus.framework",
 				"${BUILT_PRODUCTS_DIR}/shared_preferences_ios/shared_preferences_ios.framework",
 				"${BUILT_PRODUCTS_DIR}/shared_preferences_ios/shared_preferences_ios.framework",
 				"${BUILT_PRODUCTS_DIR}/sqflite/sqflite.framework",
 				"${BUILT_PRODUCTS_DIR}/sqflite/sqflite.framework",
@@ -318,20 +309,15 @@
 			);
 			);
 			name = "[CP] Embed Pods Frameworks";
 			name = "[CP] Embed Pods Frameworks";
 			outputPaths = (
 			outputPaths = (
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cache.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCore.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCore.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCoreDiagnostics.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCoreDiagnostics.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseInstallations.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseInstallations.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseMessaging.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseMessaging.framework",
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GCDWebServer.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleDataTransport.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleDataTransport.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleUtilities.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleUtilities.framework",
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/HLSCachingReverseProxyServer.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Mantle.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Mantle.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OrderedSet.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OrderedSet.framework",
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PINCache.framework",
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PINOperation.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBLPromises.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBLPromises.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Reachability.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Reachability.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework",
@@ -339,7 +325,6 @@
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Sentry.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Sentry.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Toast.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Toast.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/background_fetch.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/background_fetch.framework",
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/better_player.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/connectivity.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/connectivity.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/device_info.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/device_info.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/fk_user_agent.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/fk_user_agent.framework",
@@ -360,15 +345,12 @@
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/motionphoto.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/motionphoto.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/move_to_background.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/move_to_background.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework",
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/open_file.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/open_mail_app.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/open_mail_app.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/package_info_plus.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/package_info_plus.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_ios.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_ios.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/photo_manager.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/photo_manager.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/receive_sharing_intent.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/receive_sharing_intent.framework",
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sensors.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sentry_flutter.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sentry_flutter.framework",
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/share.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/share_plus.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/share_plus.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences_ios.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences_ios.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqflite.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqflite.framework",

+ 0 - 3
lib/app.dart

@@ -10,7 +10,6 @@ import 'package:flutter_easyloading/flutter_easyloading.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 import 'package:flutter_localizations/flutter_localizations.dart';
 import 'package:flutter_localizations/flutter_localizations.dart';
 import 'package:logging/logging.dart';
 import 'package:logging/logging.dart';
-import 'package:photos/core/network.dart';
 import 'package:photos/ente_theme_data.dart';
 import 'package:photos/ente_theme_data.dart';
 import 'package:photos/l10n/l10n.dart';
 import 'package:photos/l10n/l10n.dart';
 import 'package:photos/services/app_lifecycle_service.dart';
 import 'package:photos/services/app_lifecycle_service.dart';
@@ -58,7 +57,6 @@ class _EnteAppState extends State<EnteApp> with WidgetsBindingObserver {
           darkTheme: dartTheme,
           darkTheme: dartTheme,
           home: EnteApp._homeWidget,
           home: EnteApp._homeWidget,
           debugShowCheckedModeBanner: false,
           debugShowCheckedModeBanner: false,
-          navigatorKey: Network.instance.getAlice().getNavigatorKey(),
           builder: EasyLoading.init(),
           builder: EasyLoading.init(),
           supportedLocales: L10n.all,
           supportedLocales: L10n.all,
           localizationsDelegates: const [
           localizationsDelegates: const [
@@ -77,7 +75,6 @@ class _EnteAppState extends State<EnteApp> with WidgetsBindingObserver {
         darkTheme: darkThemeData,
         darkTheme: darkThemeData,
         home: EnteApp._homeWidget,
         home: EnteApp._homeWidget,
         debugShowCheckedModeBanner: false,
         debugShowCheckedModeBanner: false,
-        navigatorKey: Network.instance.getAlice().getNavigatorKey(),
         builder: EasyLoading.init(),
         builder: EasyLoading.init(),
         supportedLocales: L10n.all,
         supportedLocales: L10n.all,
         localizationsDelegates: const [
         localizationsDelegates: const [

+ 4 - 4
lib/core/cache/thumbnail_cache.dart

@@ -13,7 +13,7 @@ class ThumbnailLruCache {
     return _map.get(
     return _map.get(
       enteFile.cacheKey() +
       enteFile.cacheKey() +
           "_" +
           "_" +
-          (size != null ? size.toString() : kThumbnailLargeSize.toString()),
+          (size != null ? size.toString() : thumbnailLargeSize.toString()),
     );
     );
   }
   }
 
 
@@ -25,17 +25,17 @@ class ThumbnailLruCache {
     _map.put(
     _map.put(
       enteFile.cacheKey() +
       enteFile.cacheKey() +
           "_" +
           "_" +
-          (size != null ? size.toString() : kThumbnailLargeSize.toString()),
+          (size != null ? size.toString() : thumbnailLargeSize.toString()),
       imageData,
       imageData,
     );
     );
   }
   }
 
 
   static void clearCache(EnteFile enteFile) {
   static void clearCache(EnteFile enteFile) {
     _map.remove(
     _map.remove(
-      enteFile.cacheKey() + "_" + kThumbnailLargeSize.toString(),
+      enteFile.cacheKey() + "_" + thumbnailLargeSize.toString(),
     );
     );
     _map.remove(
     _map.remove(
-      enteFile.cacheKey() + "_" + kThumbnailSmallSize.toString(),
+      enteFile.cacheKey() + "_" + thumbnailSmallSize.toString(),
     );
     );
   }
   }
 }
 }

+ 2 - 2
lib/core/configuration.dart

@@ -334,9 +334,9 @@ class Configuration {
   Future<void> recover(String recoveryKey) async {
   Future<void> recover(String recoveryKey) async {
     // check if user has entered mnemonic code
     // check if user has entered mnemonic code
     if (recoveryKey.contains(' ')) {
     if (recoveryKey.contains(' ')) {
-      if (recoveryKey.split(' ').length != kMnemonicKeyWordCount) {
+      if (recoveryKey.split(' ').length != mnemonicKeyWordCount) {
         throw AssertionError(
         throw AssertionError(
-          'recovery code should have $kMnemonicKeyWordCount words',
+          'recovery code should have $mnemonicKeyWordCount words',
         );
         );
       }
       }
       recoveryKey = bip39.mnemonicToEntropy(recoveryKey);
       recoveryKey = bip39.mnemonicToEntropy(recoveryKey);

+ 22 - 22
lib/core/constants.dart

@@ -1,40 +1,40 @@
 // @dart = 2.7
 // @dart = 2.7
 
 
-const int kThumbnailSmallSize = 256;
-const int kThumbnailQuality = 50;
-const int kThumbnailLargeSize = 512;
-const int kCompressedThumbnailResolution = 1080;
-const int kThumbnailDataLimit = 100 * 1024;
-const String kSentryDSN =
+const int thumbnailSmallSize = 256;
+const int thumbnailQuality = 50;
+const int thumbnailLargeSize = 512;
+const int compressedThumbnailResolution = 1080;
+const int thumbnailDataLimit = 100 * 1024;
+const String sentryDSN =
     "https://2235e5c99219488ea93da34b9ac1cb68@sentry.ente.io/4";
     "https://2235e5c99219488ea93da34b9ac1cb68@sentry.ente.io/4";
-const String kSentryDebugDSN =
+const String sentryDebugDSN =
     "https://ca5e686dd7f149d9bf94e620564cceba@sentry.ente.io/3";
     "https://ca5e686dd7f149d9bf94e620564cceba@sentry.ente.io/3";
-const String kSentryTunnel = "https://sentry-reporter.ente.io";
-const String kRoadmapURL = "https://roadmap.ente.io";
-const int kMicroSecondsInDay = 86400000000;
-const int kAndroid11SDKINT = 30;
-const int kGalleryLoadStartTime = -8000000000000000; // Wednesday, March 6, 1748
-const int kGalleryLoadEndTime = 9223372036854775807; // 2^63 -1
+const String sentryTunnel = "https://sentry-reporter.ente.io";
+const String roadmapURL = "https://roadmap.ente.io";
+const int microSecondsInDay = 86400000000;
+const int android11SDKINT = 30;
+const int galleryLoadStartTime = -8000000000000000; // Wednesday, March 6, 1748
+const int galleryLoadEndTime = 9223372036854775807; // 2^63 -1
 
 
 // used to identify which ente file are available in app cache
 // used to identify which ente file are available in app cache
 // todo: 6Jun22: delete old media identifier after 3 months
 // todo: 6Jun22: delete old media identifier after 3 months
-const String kOldSharedMediaIdentifier = 'ente-shared://';
-const String kSharedMediaIdentifier = 'ente-shared-media://';
+const String oldSharedMediaIdentifier = 'ente-shared://';
+const String sharedMediaIdentifier = 'ente-shared-media://';
 
 
-const int kMaxLivePhotoToastCount = 2;
-const String kLivePhotoToastCounterKey = "show_live_photo_toast";
+const int maxLivePhotoToastCount = 2;
+const String livePhotoToastCounterKey = "show_live_photo_toast";
 
 
-const kThumbnailDiskLoadDeferDuration = Duration(milliseconds: 40);
-const kThumbnailServerLoadDeferDuration = Duration(milliseconds: 80);
+const thumbnailDiskLoadDeferDuration = Duration(milliseconds: 40);
+const thumbnailServerLoadDeferDuration = Duration(milliseconds: 80);
 
 
 // 256 bit key maps to 24 words
 // 256 bit key maps to 24 words
 // https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki#Generating_the_mnemonic
 // https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki#Generating_the_mnemonic
-const kMnemonicKeyWordCount = 24;
+const mnemonicKeyWordCount = 24;
 
 
 // https://stackoverflow.com/a/61162219
 // https://stackoverflow.com/a/61162219
-const kDragSensitivity = 8;
+const dragSensitivity = 8;
 
 
-const kSupportEmail = 'support@ente.io';
+const supportEmail = 'support@ente.io';
 
 
 // Default values for various feature flags
 // Default values for various feature flags
 class FFDefault {
 class FFDefault {

+ 0 - 8
lib/core/network.dart

@@ -1,11 +1,8 @@
 // @dart=2.9
 // @dart=2.9
 
 
 import 'dart:io';
 import 'dart:io';
-
-import 'package:alice/alice.dart';
 import 'package:dio/dio.dart';
 import 'package:dio/dio.dart';
 import 'package:fk_user_agent/fk_user_agent.dart';
 import 'package:fk_user_agent/fk_user_agent.dart';
-import 'package:flutter/foundation.dart';
 import 'package:package_info_plus/package_info_plus.dart';
 import 'package:package_info_plus/package_info_plus.dart';
 import 'package:uuid/uuid.dart';
 import 'package:uuid/uuid.dart';
 
 
@@ -13,10 +10,8 @@ int kConnectTimeout = 15000;
 
 
 class Network {
 class Network {
   Dio _dio;
   Dio _dio;
-  Alice _alice;
 
 
   Future<void> init() async {
   Future<void> init() async {
-    _alice = Alice(darkTheme: true, showNotification: kDebugMode);
     await FkUserAgent.init();
     await FkUserAgent.init();
     final packageInfo = await PackageInfo.fromPlatform();
     final packageInfo = await PackageInfo.fromPlatform();
     _dio = Dio(
     _dio = Dio(
@@ -30,7 +25,6 @@ class Network {
       ),
       ),
     );
     );
     _dio.interceptors.add(RequestIdInterceptor());
     _dio.interceptors.add(RequestIdInterceptor());
-    _dio.interceptors.add(_alice.getDioInterceptor());
   }
   }
 
 
   Network._privateConstructor();
   Network._privateConstructor();
@@ -38,8 +32,6 @@ class Network {
   static Network instance = Network._privateConstructor();
   static Network instance = Network._privateConstructor();
 
 
   Dio getDio() => _dio;
   Dio getDio() => _dio;
-
-  Alice getAlice() => _alice;
 }
 }
 
 
 class RequestIdInterceptor extends Interceptor {
 class RequestIdInterceptor extends Interceptor {

+ 23 - 0
lib/ente_theme_data.dart

@@ -362,6 +362,29 @@ extension CustomColorScheme on ColorScheme {
   Color get searchResultsBackgroundColor => brightness == Brightness.light
   Color get searchResultsBackgroundColor => brightness == Brightness.light
       ? Colors.black.withOpacity(0.32)
       ? Colors.black.withOpacity(0.32)
       : Colors.black.withOpacity(0.64);
       : Colors.black.withOpacity(0.64);
+
+  Color get fillFaint => brightness == Brightness.light
+      ? Colors.white.withOpacity(0.04)
+      : Colors.black.withOpacity(0.12);
+  Color get warning500 => const Color.fromRGBO(255, 101, 101, 1);
+
+  List<BoxShadow> get shadowMenu => brightness == Brightness.light
+      ? [
+          BoxShadow(blurRadius: 6, color: Colors.white.withOpacity(0.16)),
+          BoxShadow(
+            blurRadius: 6,
+            color: Colors.white.withOpacity(0.12),
+            offset: const Offset(0, 3),
+          ),
+        ]
+      : [
+          BoxShadow(blurRadius: 6, color: Colors.black.withOpacity(0.50)),
+          BoxShadow(
+            blurRadius: 6,
+            color: Colors.black.withOpacity(0.25),
+            offset: const Offset(0, 3),
+          ),
+        ];
 }
 }
 
 
 OutlinedButtonThemeData buildOutlinedButtonThemeData({
 OutlinedButtonThemeData buildOutlinedButtonThemeData({

+ 5 - 0
lib/events/notification_event.dart

@@ -0,0 +1,5 @@
+import 'package:photos/events/event.dart';
+
+// NotificationEvent event is used to re-fresh the UI to show latest notification
+// (if any)
+class NotificationEvent extends Event {}

+ 4 - 2
lib/main.dart

@@ -31,6 +31,7 @@ import 'package:photos/services/search_service.dart';
 import 'package:photos/services/sync_service.dart';
 import 'package:photos/services/sync_service.dart';
 import 'package:photos/services/trash_sync_service.dart';
 import 'package:photos/services/trash_sync_service.dart';
 import 'package:photos/services/update_service.dart';
 import 'package:photos/services/update_service.dart';
+import 'package:photos/services/user_remote_flag_service.dart';
 import 'package:photos/services/user_service.dart';
 import 'package:photos/services/user_service.dart';
 import 'package:photos/ui/tools/app_lock.dart';
 import 'package:photos/ui/tools/app_lock.dart';
 import 'package:photos/ui/tools/lock_screen.dart';
 import 'package:photos/ui/tools/lock_screen.dart';
@@ -133,6 +134,7 @@ Future<void> _init(bool isBackground, {String via = ''}) async {
   await Network.instance.init();
   await Network.instance.init();
   await Configuration.instance.init();
   await Configuration.instance.init();
   await UserService.instance.init();
   await UserService.instance.init();
+  await UserRemoteFlagService.instance.init();
   await UpdateService.instance.init();
   await UpdateService.instance.init();
   await BillingService.instance.init();
   await BillingService.instance.init();
   await CollectionsService.instance.init();
   await CollectionsService.instance.init();
@@ -175,8 +177,8 @@ Future _runWithLogs(Function() function, {String prefix = ""}) async {
       body: function,
       body: function,
       logDirPath: (await getApplicationSupportDirectory()).path + "/logs",
       logDirPath: (await getApplicationSupportDirectory()).path + "/logs",
       maxLogFiles: 5,
       maxLogFiles: 5,
-      sentryDsn: kDebugMode ? kSentryDebugDSN : kSentryDSN,
-      tunnel: kSentryTunnel,
+      sentryDsn: kDebugMode ? sentryDebugDSN : sentryDSN,
+      tunnel: sentryTunnel,
       enableInDebugMode: true,
       enableInDebugMode: true,
       prefix: prefix,
       prefix: prefix,
     ),
     ),

+ 2 - 2
lib/models/file.dart

@@ -234,8 +234,8 @@ class File extends EnteFile {
 
 
   bool isSharedMediaToAppSandbox() {
   bool isSharedMediaToAppSandbox() {
     return localID != null &&
     return localID != null &&
-        (localID.startsWith(kOldSharedMediaIdentifier) ||
-            localID.startsWith(kSharedMediaIdentifier));
+        (localID.startsWith(oldSharedMediaIdentifier) ||
+            localID.startsWith(sharedMediaIdentifier));
   }
   }
 
 
   bool hasLocation() {
   bool hasLocation() {

+ 3 - 0
lib/services/collections_service.dart

@@ -292,6 +292,9 @@ class CollectionsService {
   Uint8List _getDecryptedKey(Collection collection) {
   Uint8List _getDecryptedKey(Collection collection) {
     final encryptedKey = Sodium.base642bin(collection.encryptedKey);
     final encryptedKey = Sodium.base642bin(collection.encryptedKey);
     if (collection.owner.id == _config.getUserID()) {
     if (collection.owner.id == _config.getUserID()) {
+      if(_config.getKey() == null) {
+        throw Exception("key can not be null");
+      }
       return CryptoUtil.decryptSync(
       return CryptoUtil.decryptSync(
         encryptedKey,
         encryptedKey,
         _config.getKey(),
         _config.getKey(),

+ 1 - 1
lib/services/memories_service.dart

@@ -33,7 +33,7 @@ class MemoriesService extends ChangeNotifier {
     // Intention of delay is to give more CPU cycles to other tasks
     // Intention of delay is to give more CPU cycles to other tasks
     Future.delayed(const Duration(seconds: 5), () {
     Future.delayed(const Duration(seconds: 5), () {
       _memoriesDB.clearMemoriesSeenBeforeTime(
       _memoriesDB.clearMemoriesSeenBeforeTime(
-        DateTime.now().microsecondsSinceEpoch - (7 * kMicroSecondsInDay),
+        DateTime.now().microsecondsSinceEpoch - (7 * microSecondsInDay),
       );
       );
     });
     });
   }
   }

+ 1 - 2
lib/services/push_service.dart

@@ -15,8 +15,7 @@ import 'package:shared_preferences/shared_preferences.dart';
 class PushService {
 class PushService {
   static const kFCMPushToken = "fcm_push_token";
   static const kFCMPushToken = "fcm_push_token";
   static const kLastFCMTokenUpdationTime = "fcm_push_token_updation_time";
   static const kLastFCMTokenUpdationTime = "fcm_push_token_updation_time";
-  static const kFCMTokenUpdationIntervalInMicroSeconds =
-      30 * kMicroSecondsInDay;
+  static const kFCMTokenUpdationIntervalInMicroSeconds = 30 * microSecondsInDay;
   static const kPushAction = "action";
   static const kPushAction = "action";
   static const kSync = "sync";
   static const kSync = "sync";
 
 

+ 1 - 1
lib/services/sync_service.dart

@@ -252,7 +252,7 @@ class SyncService {
     final lastNotificationShownTime =
     final lastNotificationShownTime =
         _prefs.getInt(kLastStorageLimitExceededNotificationPushTime) ?? 0;
         _prefs.getInt(kLastStorageLimitExceededNotificationPushTime) ?? 0;
     final now = DateTime.now().microsecondsSinceEpoch;
     final now = DateTime.now().microsecondsSinceEpoch;
-    if ((now - lastNotificationShownTime) > kMicroSecondsInDay) {
+    if ((now - lastNotificationShownTime) > microSecondsInDay) {
       await _prefs.setInt(kLastStorageLimitExceededNotificationPushTime, now);
       await _prefs.setInt(kLastStorageLimitExceededNotificationPushTime, now);
       NotificationService.instance.showNotification(
       NotificationService.instance.showNotification(
         "storage limit exceeded",
         "storage limit exceeded",

+ 1 - 1
lib/services/update_service.dart

@@ -66,7 +66,7 @@ class UpdateService {
         _prefs.getInt(kUpdateAvailableShownTimeKey) ?? 0;
         _prefs.getInt(kUpdateAvailableShownTimeKey) ?? 0;
     final now = DateTime.now().microsecondsSinceEpoch;
     final now = DateTime.now().microsecondsSinceEpoch;
     final hasBeen3DaysSinceLastNotification =
     final hasBeen3DaysSinceLastNotification =
-        (now - lastNotificationShownTime) > (3 * kMicroSecondsInDay);
+        (now - lastNotificationShownTime) > (3 * microSecondsInDay);
     if (shouldUpdate &&
     if (shouldUpdate &&
         hasBeen3DaysSinceLastNotification &&
         hasBeen3DaysSinceLastNotification &&
         _latestVersion.shouldNotify) {
         _latestVersion.shouldNotify) {

+ 123 - 0
lib/services/user_remote_flag_service.dart

@@ -0,0 +1,123 @@
+import 'dart:async';
+import 'dart:io';
+
+import 'package:collection/collection.dart';
+import 'package:dio/dio.dart';
+import 'package:logging/logging.dart';
+import 'package:photos/core/configuration.dart';
+import 'package:photos/core/network.dart';
+import 'package:photos/services/user_service.dart';
+import 'package:shared_preferences/shared_preferences.dart';
+
+class UserRemoteFlagService {
+  final _dio = Network.instance.getDio();
+  final _logger = Logger((UserRemoteFlagService).toString());
+  final _config = Configuration.instance;
+  late SharedPreferences _prefs;
+
+  UserRemoteFlagService._privateConstructor();
+
+  static final UserRemoteFlagService instance =
+      UserRemoteFlagService._privateConstructor();
+
+  static const String recoveryVerificationFlag = "recoveryKeyVerified";
+  static const String needRecoveryKeyVerification =
+      "needRecoveryKeyVerification";
+
+  Future<void> init() async {
+    _prefs = await SharedPreferences.getInstance();
+  }
+
+  bool shouldShowRecoveryVerification() {
+    if (!_prefs.containsKey(needRecoveryKeyVerification)) {
+      // fetch the status from remote
+      unawaited(_refreshRecoveryVerificationFlag());
+      return false;
+    }
+    return _prefs.getBool(needRecoveryKeyVerification)!;
+  }
+
+  // markRecoveryVerificationAsDone is used to track if user has verified their
+  // recovery key in the past or not. This helps in avoid showing the same
+  // prompt to the user on re-install or signing into a different device
+  Future<void> markRecoveryVerificationAsDone() async {
+    await _updateKeyValue(recoveryVerificationFlag, true.toString());
+    await _prefs.setBool(needRecoveryKeyVerification, false);
+  }
+
+  Future<void> _refreshRecoveryVerificationFlag() async {
+    final remoteStatusValue =
+        await _getValue(recoveryVerificationFlag, "false");
+    if (remoteStatusValue.toLowerCase() == "true") {
+      await _prefs.setBool(needRecoveryKeyVerification, false);
+    } else {
+      // check the session creationTime. If any active session is older than
+      // 1 day, set the need to verification as true
+      final activeSessions = await UserService.instance.getActiveSessions();
+      final int microSecondsInADay = const Duration(days: 1).inMicroseconds;
+      final bool anyActiveSessionOlderThanADay =
+          activeSessions.sessions.firstWhereOrNull(
+                (e) =>
+                    (e.creationTime + microSecondsInADay) <
+                    DateTime.now().microsecondsSinceEpoch,
+              ) !=
+              null;
+      if (anyActiveSessionOlderThanADay) {
+        await _prefs.setBool(needRecoveryKeyVerification, true);
+      } else {
+        // continue defaulting to no verification prompt
+        _logger.finest('No active session older than 1 day');
+      }
+    }
+  }
+
+  Future<String> _getValue(String key, String? defaultValue) async {
+    try {
+      final Map<String, dynamic> queryParams = {"key": key};
+      if (defaultValue != null) {
+        queryParams["defaultValue"] = defaultValue;
+      }
+      final response = await _dio.get(
+        _config.getHttpEndpoint() + "/remote-store",
+        queryParameters: queryParams,
+        options: Options(
+          headers: {
+            "X-Auth-Token": _config.getToken(),
+          },
+        ),
+      );
+      if (response.statusCode != HttpStatus.ok) {
+        throw Exception("Unexpected status code ${response.statusCode}");
+      }
+      return response.data["value"];
+    } catch (e) {
+      _logger.info("Error while fetching bool status for $key", e);
+      rethrow;
+    }
+  }
+
+  // _setBooleanFlag sets the corresponding flag on remote
+  // to mark recovery as completed
+  Future<void> _updateKeyValue(String key, String value) async {
+    try {
+      final response = await _dio.post(
+        _config.getHttpEndpoint() + "/remote-store/update",
+        data: {
+          "key": key,
+          "value": value,
+        },
+        options: Options(
+          headers: {
+            "X-Auth-Token": _config.getToken(),
+          },
+        ),
+      );
+      if (response.statusCode != HttpStatus.ok) {
+        throw Exception("Unexpected state");
+      }
+    } catch (e) {
+      _logger.warning("Failed to set flag for $key", e);
+      rethrow;
+    }
+  }
+}

+ 138 - 124
lib/ui/account/recovery_key_page.dart

@@ -51,140 +51,154 @@ class _RecoveryKeyPageState extends State<RecoveryKeyPage> {
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
     final String recoveryKey = bip39.entropyToMnemonic(widget.recoveryKey);
     final String recoveryKey = bip39.entropyToMnemonic(widget.recoveryKey);
-    if (recoveryKey.split(' ').length != kMnemonicKeyWordCount) {
+    if (recoveryKey.split(' ').length != mnemonicKeyWordCount) {
       throw AssertionError(
       throw AssertionError(
-        'recovery code should have $kMnemonicKeyWordCount words',
+        'recovery code should have $mnemonicKeyWordCount words',
       );
       );
     }
     }
+    final double topPadding = widget.showAppBar
+        ? 40
+        : widget.showProgressBar
+            ? 32
+            : 120;
 
 
     return Scaffold(
     return Scaffold(
-      appBar: widget.showProgressBar
-          ? AppBar(
-              elevation: 0,
-              title: Hero(
-                tag: "recovery_key",
-                child: StepProgressIndicator(
-                  totalSteps: 4,
-                  currentStep: 3,
-                  selectedColor: Theme.of(context).colorScheme.greenAlternative,
-                  roundedEdges: const Radius.circular(10),
-                  unselectedColor:
-                      Theme.of(context).colorScheme.stepProgressUnselectedColor,
-                ),
-              ),
-            )
-          : widget.showAppBar
-              ? AppBar(
-                  elevation: 0,
-                  title: Text(widget.title ?? "Recovery key"),
-                )
-              : null,
-      body: Padding(
-        padding: EdgeInsets.fromLTRB(
-          20,
-          widget.showAppBar
-              ? 40
-              : widget.showProgressBar
-                  ? 32
-                  : 120,
-          20,
-          20,
-        ),
-        child: Column(
-          crossAxisAlignment: CrossAxisAlignment.stretch,
-          mainAxisSize: MainAxisSize.max,
-          children: [
-            widget.showAppBar
-                ? const SizedBox.shrink()
-                : Text(
-                    widget.title ?? "Recovery key",
-                    style: Theme.of(context).textTheme.headline4,
+        appBar: widget.showProgressBar
+            ? AppBar(
+                elevation: 0,
+                title: Hero(
+                  tag: "recovery_key",
+                  child: StepProgressIndicator(
+                    totalSteps: 4,
+                    currentStep: 3,
+                    selectedColor:
+                        Theme.of(context).colorScheme.greenAlternative,
+                    roundedEdges: const Radius.circular(10),
+                    unselectedColor: Theme.of(context)
+                        .colorScheme
+                        .stepProgressUnselectedColor,
                   ),
                   ),
-            Padding(padding: EdgeInsets.all(widget.showAppBar ? 0 : 12)),
-            Text(
-              widget.text ??
-                  "If you forget your password, the only way you can recover your data is with this key.",
-              style: Theme.of(context).textTheme.subtitle1,
-            ),
-            const Padding(padding: EdgeInsets.only(top: 24)),
-            DottedBorder(
-              color: const Color.fromRGBO(17, 127, 56, 1),
-              //color of dotted/dash line
-              strokeWidth: 1,
-              //thickness of dash/dots
-              dashPattern: const [6, 6],
-              radius: const Radius.circular(8),
-              //dash patterns, 10 is dash width, 6 is space width
-              child: SizedBox(
-                //inner container
-                height: 120, //height of inner container
-                width:
-                    double.infinity, //width to 100% match to parent container.
-                // ignore: prefer_const_literals_to_create_immutables
-                child: Column(
-                  children: [
-                    GestureDetector(
-                      onTap: () async {
-                        await Clipboard.setData(
-                          ClipboardData(text: recoveryKey),
-                        );
-                        showToast(context, "Recovery key copied to clipboard");
-                        setState(() {
-                          _hasTriedToSave = true;
-                        });
-                      },
-                      child: Container(
-                        decoration: BoxDecoration(
-                          border: Border.all(
-                            color: const Color.fromRGBO(49, 155, 86, .2),
-                          ),
-                          borderRadius: const BorderRadius.all(
-                            Radius.circular(2),
+                ),
+              )
+            : widget.showAppBar
+                ? AppBar(
+                    elevation: 0,
+                    title: Text(widget.title ?? "Recovery key"),
+                  )
+                : null,
+        body: Padding(
+          padding: EdgeInsets.fromLTRB(20, topPadding, 20, 20),
+          child: LayoutBuilder(
+            builder: (context, constraints) {
+              return SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                      minWidth: constraints.maxWidth,
+                      minHeight: constraints.maxHeight),
+                  child: IntrinsicHeight(
+                    child: Column(
+                      mainAxisSize: MainAxisSize.max,
+                      children: [
+                        widget.showAppBar
+                            ? const SizedBox.shrink()
+                            : Text(
+                                widget.title ?? "Recovery key",
+                                style: Theme.of(context).textTheme.headline4,
+                              ),
+                        Padding(
+                            padding:
+                                EdgeInsets.all(widget.showAppBar ? 0 : 12)),
+                        Text(
+                          widget.text ??
+                              "If you forget your password, the only way you can recover your data is with this key.",
+                          style: Theme.of(context).textTheme.subtitle1,
+                        ),
+                        const Padding(padding: EdgeInsets.only(top: 24)),
+                        DottedBorder(
+                          color: const Color.fromRGBO(17, 127, 56, 1),
+                          //color of dotted/dash line
+                          strokeWidth: 1,
+                          //thickness of dash/dots
+                          dashPattern: const [6, 6],
+                          radius: const Radius.circular(8),
+                          //dash patterns, 10 is dash width, 6 is space width
+                          child: SizedBox(
+                            //inner container
+                            // height: 120, //height of inner container
+                            width: double
+                                .infinity, //width to 100% match to parent container.
+                            // ignore: prefer_const_literals_to_create_immutables
+                            child: Column(
+                              children: [
+                                GestureDetector(
+                                  onTap: () async {
+                                    await Clipboard.setData(
+                                      ClipboardData(text: recoveryKey),
+                                    );
+                                    showToast(context,
+                                        "Recovery key copied to clipboard");
+                                    setState(() {
+                                      _hasTriedToSave = true;
+                                    });
+                                  },
+                                  child: Container(
+                                    decoration: BoxDecoration(
+                                      border: Border.all(
+                                        color: const Color.fromRGBO(
+                                            49, 155, 86, .2),
+                                      ),
+                                      borderRadius: const BorderRadius.all(
+                                        Radius.circular(2),
+                                      ),
+                                      color: Theme.of(context)
+                                          .colorScheme
+                                          .recoveryKeyBoxColor,
+                                    ),
+                                    padding: const EdgeInsets.all(20),
+                                    width: double.infinity,
+                                    child: Text(
+                                      recoveryKey,
+                                      style:
+                                          Theme.of(context).textTheme.bodyText1,
+                                    ),
+                                  ),
+                                ),
+                              ],
+                            ),
                           ),
                           ),
-                          color:
-                              Theme.of(context).colorScheme.recoveryKeyBoxColor,
                         ),
                         ),
-                        height: 120,
-                        padding: const EdgeInsets.all(20),
-                        width: double.infinity,
-                        child: Text(
-                          recoveryKey,
-                          style: Theme.of(context).textTheme.bodyText1,
+                        SizedBox(
+                          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,
+                            ),
+                          ),
                         ),
                         ),
-                      ),
-                    ),
-                  ],
-                ),
-              ),
-            ),
-            SizedBox(
-              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,
-                ),
-              ),
-            ),
-            Expanded(
-              child: Container(
-                alignment: Alignment.bottomCenter,
-                width: double.infinity,
-                padding: const EdgeInsets.fromLTRB(10, 10, 10, 24),
-                child: Column(
-                  mainAxisAlignment: MainAxisAlignment.end,
-                  crossAxisAlignment: CrossAxisAlignment.stretch,
-                  children: _saveOptions(context, recoveryKey),
+                        Expanded(
+                          child: Container(
+                            alignment: Alignment.bottomCenter,
+                            width: double.infinity,
+                            padding: const EdgeInsets.fromLTRB(10, 10, 10, 42),
+                            child: Column(
+                              mainAxisAlignment: MainAxisAlignment.end,
+                              crossAxisAlignment: CrossAxisAlignment.stretch,
+                              children: _saveOptions(context, recoveryKey),
+                            ),
+                          ),
+                        )
+                      ],
+                    ), // columnEnds
+                  ),
                 ),
                 ),
-              ),
-            )
-          ],
-        ),
-      ),
-    );
+              );
+            },
+          ),
+        ));
   }
   }
 
 
   List<Widget> _saveOptions(BuildContext context, String recoveryKey) {
   List<Widget> _saveOptions(BuildContext context, String recoveryKey) {

+ 241 - 0
lib/ui/account/verify_recovery_page.dart

@@ -0,0 +1,241 @@
+import 'dart:ui';
+
+import 'package:bip39/bip39.dart' as bip39;
+import 'package:dio/dio.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_sodium/flutter_sodium.dart';
+import 'package:logging/logging.dart';
+import 'package:photos/core/event_bus.dart';
+import 'package:photos/ente_theme_data.dart';
+import 'package:photos/events/notification_event.dart';
+import 'package:photos/services/local_authentication_service.dart';
+import 'package:photos/services/user_remote_flag_service.dart';
+import 'package:photos/services/user_service.dart';
+import 'package:photos/ui/account/recovery_key_page.dart';
+import 'package:photos/ui/common/dialogs.dart';
+import 'package:photos/ui/common/gradient_button.dart';
+import 'package:photos/utils/dialog_util.dart';
+import 'package:photos/utils/navigation_util.dart';
+
+class VerifyRecoveryPage extends StatefulWidget {
+  const VerifyRecoveryPage({Key? key}) : super(key: key);
+
+  @override
+  State<VerifyRecoveryPage> createState() => _VerifyRecoveryPageState();
+}
+
+class _VerifyRecoveryPageState extends State<VerifyRecoveryPage> {
+  final _recoveryKey = TextEditingController();
+  final Logger _logger = Logger((_VerifyRecoveryPageState).toString());
+
+  void _verifyRecoveryKey() async {
+    final dialog = createProgressDialog(context, "Verifying recovery key...");
+    await dialog.show();
+    try {
+      final String inputKey = _recoveryKey.text.trim();
+      final String recoveryKey = Sodium.bin2hex(
+        await UserService.instance.getOrCreateRecoveryKey(context),
+      );
+      final String recoveryKeyWords = bip39.entropyToMnemonic(recoveryKey);
+      if (inputKey == recoveryKey || inputKey == recoveryKeyWords) {
+        try {
+          await UserRemoteFlagService.instance.markRecoveryVerificationAsDone();
+        } catch (e) {
+          await dialog.hide();
+          if (e is DioError && e.type == DioErrorType.other) {
+            await showErrorDialog(
+              context,
+              "No internet connection",
+              "Please check your internet connection and try again.",
+            );
+          } else {
+            await showGenericErrorDialog(context);
+          }
+          return;
+        }
+        Bus.instance.fire(NotificationEvent());
+        await dialog.hide();
+        // todo: change this as per figma once the component is ready
+        await showErrorDialog(
+          context,
+          "Recovery key verified",
+          "Great! Your recovery key is valid. Thank you for verifying.\n"
+              "\nPlease"
+              " remember to keep your recovery key safely backed up.",
+        );
+        Navigator.of(context).pop();
+      } else {
+        throw Exception("recovery key didn't match");
+      }
+    } catch (e, s) {
+      _logger.severe("failed to verify recovery key", e, s);
+      await dialog.hide();
+      const String errMessage =
+          "The recovery key you entered is not valid. Please make sure it "
+          "contains 24 words, and check the spelling of each.\n\nIf you "
+          "entered an older recovery code, make sure it is 64 characters long, and check each of them.";
+      final result = await showChoiceDialog(
+        context,
+        "Invalid key",
+        errMessage,
+        firstAction: "Try again",
+        secondAction: "View recovery key",
+      );
+      if (result == DialogUserChoice.secondChoice) {
+        await _onViewRecoveryKeyClick();
+      }
+    }
+  }
+
+  Future<void> _onViewRecoveryKeyClick() async {
+    final hasAuthenticated =
+        await LocalAuthenticationService.instance.requestLocalAuthentication(
+      context,
+      "Please authenticate to view your recovery key",
+    );
+    if (hasAuthenticated) {
+      String recoveryKey;
+      try {
+        recoveryKey = Sodium.bin2hex(
+          await UserService.instance.getOrCreateRecoveryKey(context),
+        );
+        routeToPage(
+          context,
+          RecoveryKeyPage(
+            recoveryKey,
+            "OK",
+            showAppBar: true,
+            onDone: () {
+              Navigator.of(context).pop();
+            },
+          ),
+        );
+      } catch (e) {
+        showGenericErrorDialog(context);
+        return;
+      }
+    }
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        elevation: 0,
+        leading: IconButton(
+          icon: const Icon(Icons.arrow_back),
+          color: Theme.of(context).iconTheme.color,
+          onPressed: () {
+            Navigator.of(context).pop();
+          },
+        ),
+      ),
+      body: Padding(
+        padding: const EdgeInsets.symmetric(horizontal: 16.0),
+        child: LayoutBuilder(
+          builder: (context, constraints) {
+            return SingleChildScrollView(
+              child: ConstrainedBox(
+                constraints: BoxConstraints(
+                  minWidth: constraints.maxWidth,
+                  minHeight: constraints.maxHeight,
+                ),
+                child: IntrinsicHeight(
+                  child: Column(
+                    children: [
+                      const SizedBox(height: 12),
+                      SizedBox(
+                        width: double.infinity,
+                        child: Text(
+                          'Verify recovery key',
+                          style: Theme.of(context).textTheme.headline5,
+                          textAlign: TextAlign.left,
+                        ),
+                      ),
+                      const SizedBox(height: 12),
+                      Text(
+                        "If you forget your password, your recovery key is the "
+                        "only way to recover your photos.\n\nPlease verify that "
+                        "you have safely backed up your 24 word recovery key by re-entering it.",
+                        style: Theme.of(context).textTheme.subtitle2,
+                      ),
+                      const SizedBox(height: 12),
+                      TextFormField(
+                        decoration: InputDecoration(
+                          filled: true,
+                          hintText: "Enter your recovery key",
+                          contentPadding: const EdgeInsets.all(20),
+                          border: UnderlineInputBorder(
+                            borderSide: BorderSide.none,
+                            borderRadius: BorderRadius.circular(6),
+                          ),
+                        ),
+                        style: const TextStyle(
+                          fontSize: 14,
+                          fontFeatures: [FontFeature.tabularFigures()],
+                        ),
+                        controller: _recoveryKey,
+                        autofocus: false,
+                        autocorrect: false,
+                        keyboardType: TextInputType.multiline,
+                        minLines: 4,
+                        maxLines: null,
+                        onChanged: (_) {
+                          setState(() {});
+                        },
+                      ),
+                      const SizedBox(height: 12),
+                      Text(
+                        "If you saved the recovery key from older app versions, you might have a 64 character recovery code instead of 24 words. You can enter that too.",
+                        style: Theme.of(context).textTheme.caption,
+                      ),
+                      const SizedBox(height: 8),
+                      Expanded(
+                        child: Container(
+                          alignment: Alignment.bottomCenter,
+                          width: double.infinity,
+                          padding: const EdgeInsets.fromLTRB(0, 12, 0, 40),
+                          child: Column(
+                            mainAxisAlignment: MainAxisAlignment.end,
+                            crossAxisAlignment: CrossAxisAlignment.stretch,
+                            children: [
+                              GradientButton(
+                                onTap: _verifyRecoveryKey,
+                                text: "Verify",
+                                paddingValue: 6,
+                                iconData: Icons.shield_outlined,
+                              ),
+                              const SizedBox(height: 8),
+                              SizedBox(
+                                width: double.infinity,
+                                child: Hero(
+                                  tag: "recovery_key",
+                                  child: ElevatedButton(
+                                    style: Theme.of(context)
+                                        .colorScheme
+                                        .optionalActionButtonStyle,
+                                    onPressed: _onViewRecoveryKeyClick,
+                                    child: const Text(
+                                      "View recovery key",
+                                      // same for both themes
+                                      style: TextStyle(color: Colors.black),
+                                    ),
+                                  ),
+                                ),
+                              ),
+                            ],
+                          ),
+                        ),
+                      ),
+                      const SizedBox(height: 20)
+                    ],
+                  ),
+                ),
+              ),
+            );
+          },
+        ),
+      ),
+    );
+  }
+}

+ 76 - 0
lib/ui/components/notification_warning_widget.dart

@@ -0,0 +1,76 @@
+import 'package:flutter/material.dart';
+import 'package:photos/ente_theme_data.dart';
+
+class NotificationWarningWidget extends StatelessWidget {
+  final IconData warningIcon;
+  final IconData actionIcon;
+  final String text;
+  final GestureTapCallback onTap;
+
+  const NotificationWarningWidget({
+    Key? key,
+    required this.warningIcon,
+    required this.actionIcon,
+    required this.text,
+    required this.onTap,
+  }) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return Center(
+      child: GestureDetector(
+        onTap: onTap,
+        child: Padding(
+          padding: const EdgeInsets.all(10.0),
+          child: Container(
+            decoration: BoxDecoration(
+              borderRadius: const BorderRadius.all(
+                Radius.circular(8),
+              ),
+              boxShadow: Theme.of(context).colorScheme.shadowMenu,
+              color: Theme.of(context).colorScheme.warning500,
+            ),
+            child: Padding(
+              padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
+              child: Row(
+                children: [
+                  Icon(
+                    warningIcon,
+                    size: 36,
+                    color: Colors.white,
+                  ),
+                  const SizedBox(width: 10),
+                  Flexible(
+                    child: Text(
+                      text,
+                      style: const TextStyle(height: 1.4, color: Colors.white),
+                      textAlign: TextAlign.left,
+                    ),
+                  ),
+                  const SizedBox(width: 10),
+                  ClipOval(
+                    child: Material(
+                      color: Theme.of(context).colorScheme.fillFaint,
+                      child: InkWell(
+                        splashColor: Colors.red, // Splash color
+                        onTap: onTap,
+                        child: SizedBox(
+                          width: 40,
+                          height: 40,
+                          child: Icon(
+                            actionIcon,
+                            color: Colors.white,
+                          ),
+                        ),
+                      ),
+                    ),
+                  ),
+                ],
+              ),
+            ),
+          ),
+        ),
+      ),
+    );
+  }
+}

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

@@ -103,7 +103,7 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
             DateTime(galleryDate.year, galleryDate.month, galleryDate.day);
             DateTime(galleryDate.year, galleryDate.month, galleryDate.day);
         final result = await widget.asyncLoader(
         final result = await widget.asyncLoader(
           dayStartTime.microsecondsSinceEpoch,
           dayStartTime.microsecondsSinceEpoch,
-          dayStartTime.microsecondsSinceEpoch + kMicroSecondsInDay - 1,
+          dayStartTime.microsecondsSinceEpoch + microSecondsInDay - 1,
         );
         );
         if (mounted) {
         if (mounted) {
           setState(() {
           setState(() {
@@ -331,8 +331,8 @@ class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
                   ),
                   ),
                   child: ThumbnailWidget(
                   child: ThumbnailWidget(
                     file,
                     file,
-                    diskLoadDeferDuration: kThumbnailDiskLoadDeferDuration,
-                    serverLoadDeferDuration: kThumbnailServerLoadDeferDuration,
+                    diskLoadDeferDuration: thumbnailDiskLoadDeferDuration,
+                    serverLoadDeferDuration: thumbnailServerLoadDeferDuration,
                     shouldShowLivePhotoOverlay: true,
                     shouldShowLivePhotoOverlay: true,
                     key: Key(widget.tag + file.tag()),
                     key: Key(widget.tag + file.tag()),
                   ),
                   ),

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

@@ -2,7 +2,7 @@
 
 
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:logging/logging.dart';
 import 'package:logging/logging.dart';
-import 'package:open_file/open_file.dart';
+// import 'package:open_file/open_file.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/network.dart';
 import 'package:photos/core/network.dart';
 import 'package:photos/ente_theme_data.dart';
 import 'package:photos/ente_theme_data.dart';
@@ -152,7 +152,7 @@ class _ApkDownloaderDialogState extends State<ApkDownloaderDialog> {
         },
         },
       );
       );
       Navigator.of(context, rootNavigator: true).pop('dialog');
       Navigator.of(context, rootNavigator: true).pop('dialog');
-      OpenFile.open(_saveUrl);
+      // OpenFile.open(_saveUrl);
     } catch (e) {
     } catch (e) {
       Logger("ApkDownloader").severe(e);
       Logger("ApkDownloader").severe(e);
       final AlertDialog alert = AlertDialog(
       final AlertDialog alert = AlertDialog(

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

@@ -2,7 +2,6 @@
 
 
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:package_info_plus/package_info_plus.dart';
 import 'package:package_info_plus/package_info_plus.dart';
-import 'package:photos/core/network.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 
 
 class AppVersionWidget extends StatefulWidget {
 class AppVersionWidget extends StatefulWidget {
@@ -38,7 +37,6 @@ class _AppVersionWidgetState extends State<AppVersionWidget> {
               const Duration(milliseconds: kDummyDelayDurationInMilliseconds),
               const Duration(milliseconds: kDummyDelayDurationInMilliseconds),
             );
             );
             await dialog.hide();
             await dialog.hide();
-            Network.instance.getAlice().showInspector();
           }
           }
         } else {
         } else {
           _consecutiveTaps = 1;
           _consecutiveTaps = 1;

+ 0 - 11
lib/ui/settings/debug_section_widget.dart

@@ -4,7 +4,6 @@ import 'package:expandable/expandable.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/configuration.dart';
-import 'package:photos/core/network.dart';
 import 'package:photos/services/ignored_files_service.dart';
 import 'package:photos/services/ignored_files_service.dart';
 import 'package:photos/services/local_sync_service.dart';
 import 'package:photos/services/local_sync_service.dart';
 import 'package:photos/services/sync_service.dart';
 import 'package:photos/services/sync_service.dart';
@@ -38,16 +37,6 @@ class DebugSectionWidget extends StatelessWidget {
             icon: Icons.navigate_next,
             icon: Icons.navigate_next,
           ),
           ),
         ),
         ),
-        GestureDetector(
-          behavior: HitTestBehavior.translucent,
-          onTap: () async {
-            Network.instance.getAlice().showInspector();
-          },
-          child: const SettingsTextItem(
-            text: "Network requests",
-            icon: Icons.navigate_next,
-          ),
-        ),
         GestureDetector(
         GestureDetector(
           behavior: HitTestBehavior.translucent,
           behavior: HitTestBehavior.translucent,
           onTap: () async {
           onTap: () async {

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

@@ -33,7 +33,7 @@ class SupportSectionWidget extends StatelessWidget {
         GestureDetector(
         GestureDetector(
           behavior: HitTestBehavior.translucent,
           behavior: HitTestBehavior.translucent,
           onTap: () async {
           onTap: () async {
-            await sendEmail(context, to: kSupportEmail);
+            await sendEmail(context, to: supportEmail);
           },
           },
           child:
           child:
               const SettingsTextItem(text: "Email", icon: Icons.navigate_next),
               const SettingsTextItem(text: "Email", icon: Icons.navigate_next),
@@ -50,7 +50,7 @@ class SupportSectionWidget extends StatelessWidget {
                   final isLoggedIn = Configuration.instance.getToken() != null;
                   final isLoggedIn = Configuration.instance.getToken() != null;
                   final url = isLoggedIn
                   final url = isLoggedIn
                       ? endpoint + "?token=" + Configuration.instance.getToken()
                       ? endpoint + "?token=" + Configuration.instance.getToken()
-                      : kRoadmapURL;
+                      : roadmapURL;
                   return WebPage("Roadmap", url);
                   return WebPage("Roadmap", url);
                 },
                 },
               ),
               ),

+ 27 - 0
lib/ui/status_bar_widget.dart

@@ -5,10 +5,15 @@ import 'dart:async';
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:photos/core/event_bus.dart';
 import 'package:photos/core/event_bus.dart';
 import 'package:photos/ente_theme_data.dart';
 import 'package:photos/ente_theme_data.dart';
+import 'package:photos/events/notification_event.dart';
 import 'package:photos/events/sync_status_update_event.dart';
 import 'package:photos/events/sync_status_update_event.dart';
 import 'package:photos/services/sync_service.dart';
 import 'package:photos/services/sync_service.dart';
+import 'package:photos/services/user_remote_flag_service.dart';
+import 'package:photos/ui/account/verify_recovery_page.dart';
+import 'package:photos/ui/components/notification_warning_widget.dart';
 import 'package:photos/ui/header_error_widget.dart';
 import 'package:photos/ui/header_error_widget.dart';
 import 'package:photos/ui/viewer/search/search_widget.dart';
 import 'package:photos/ui/viewer/search/search_widget.dart';
+import 'package:photos/utils/navigation_util.dart';
 
 
 const double kContainerHeight = 36;
 const double kContainerHeight = 36;
 
 
@@ -21,6 +26,7 @@ class StatusBarWidget extends StatefulWidget {
 
 
 class _StatusBarWidgetState extends State<StatusBarWidget> {
 class _StatusBarWidgetState extends State<StatusBarWidget> {
   StreamSubscription<SyncStatusUpdate> _subscription;
   StreamSubscription<SyncStatusUpdate> _subscription;
+  StreamSubscription<NotificationEvent> _notificationSubscription;
   bool _showStatus = false;
   bool _showStatus = false;
   bool _showErrorBanner = false;
   bool _showErrorBanner = false;
 
 
@@ -51,12 +57,19 @@ class _StatusBarWidgetState extends State<StatusBarWidget> {
         });
         });
       }
       }
     });
     });
+    _notificationSubscription =
+        Bus.instance.on<NotificationEvent>().listen((event) {
+      if (mounted) {
+        setState(() {});
+      }
+    });
     super.initState();
     super.initState();
   }
   }
 
 
   @override
   @override
   void dispose() {
   void dispose() {
     _subscription.cancel();
     _subscription.cancel();
+    _notificationSubscription.cancel();
     super.dispose();
     super.dispose();
   }
   }
 
 
@@ -96,6 +109,20 @@ class _StatusBarWidgetState extends State<StatusBarWidget> {
           duration: const Duration(milliseconds: 1000),
           duration: const Duration(milliseconds: 1000),
           child: const Divider(),
           child: const Divider(),
         ),
         ),
+        UserRemoteFlagService.instance.shouldShowRecoveryVerification()
+            ? NotificationWarningWidget(
+                warningIcon: Icons.gpp_maybe,
+                actionIcon: Icons.arrow_forward,
+                text: "Please ensure that you have your 24 word recovery key",
+                onTap: () async => {
+                  await routeToPage(
+                    context,
+                    const VerifyRecoveryPage(),
+                    forceCustomPageRoute: true,
+                  )
+                },
+              )
+            : const SizedBox.shrink()
       ],
       ],
     );
     );
   }
   }

+ 2 - 3
lib/ui/tools/deduplicate_page.dart

@@ -450,9 +450,8 @@ class _DeduplicatePageState extends State<DeduplicatePage> {
                     borderRadius: BorderRadius.circular(4),
                     borderRadius: BorderRadius.circular(4),
                     child: ThumbnailWidget(
                     child: ThumbnailWidget(
                       file,
                       file,
-                      diskLoadDeferDuration: kThumbnailDiskLoadDeferDuration,
-                      serverLoadDeferDuration:
-                          kThumbnailServerLoadDeferDuration,
+                      diskLoadDeferDuration: thumbnailDiskLoadDeferDuration,
+                      serverLoadDeferDuration: thumbnailServerLoadDeferDuration,
                       shouldShowLivePhotoOverlay: true,
                       shouldShowLivePhotoOverlay: true,
                       key: Key("deduplicate_" + file.tag()),
                       key: Key("deduplicate_" + file.tag()),
                     ),
                     ),

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

@@ -229,7 +229,7 @@ class _DetailPageState extends State<DetailPage> {
     }
     }
     if (_selectedIndex == _files.length - 1 && !_hasLoadedTillEnd) {
     if (_selectedIndex == _files.length - 1 && !_hasLoadedTillEnd) {
       final result = await widget.config.asyncLoader(
       final result = await widget.config.asyncLoader(
-        kGalleryLoadStartTime,
+        galleryLoadStartTime,
         _files[_selectedIndex].creationTime - 1,
         _files[_selectedIndex].creationTime - 1,
         limit: kLoadLimit,
         limit: kLoadLimit,
       );
       );

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

@@ -138,7 +138,7 @@ class _ThumbnailWidgetState extends State<ThumbnailWidget> {
         !_isLoadingLocalThumbnail) {
         !_isLoadingLocalThumbnail) {
       _isLoadingLocalThumbnail = true;
       _isLoadingLocalThumbnail = true;
       final cachedSmallThumbnail =
       final cachedSmallThumbnail =
-          ThumbnailLruCache.get(widget.file, kThumbnailSmallSize);
+          ThumbnailLruCache.get(widget.file, thumbnailSmallSize);
       if (cachedSmallThumbnail != null) {
       if (cachedSmallThumbnail != null) {
         _imageProvider = Image.memory(cachedSmallThumbnail).image;
         _imageProvider = Image.memory(cachedSmallThumbnail).image;
         _hasLoadedThumbnail = true;
         _hasLoadedThumbnail = true;
@@ -187,7 +187,7 @@ class _ThumbnailWidgetState extends State<ThumbnailWidget> {
         final imageProvider = Image.memory(thumbData).image;
         final imageProvider = Image.memory(thumbData).image;
         _cacheAndRender(imageProvider);
         _cacheAndRender(imageProvider);
       }
       }
-      ThumbnailLruCache.put(widget.file, thumbData, kThumbnailSmallSize);
+      ThumbnailLruCache.put(widget.file, thumbData, thumbnailSmallSize);
     }).catchError((e) {
     }).catchError((e) {
       _logger.warning("Could not load image: ", e);
       _logger.warning("Could not load image: ", e);
       _errorLoadingLocalThumbnail = true;
       _errorLoadingLocalThumbnail = true;

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

@@ -123,7 +123,7 @@ class _VideoWidgetState extends State<VideoWidget> {
     final contentWithDetector = GestureDetector(
     final contentWithDetector = GestureDetector(
       child: content,
       child: content,
       onVerticalDragUpdate: (d) => {
       onVerticalDragUpdate: (d) => {
-        if (d.delta.dy > kDragSensitivity) {Navigator.of(context).pop()}
+        if (d.delta.dy > dragSensitivity) {Navigator.of(context).pop()}
       },
       },
     );
     );
     return VisibilityDetector(
     return VisibilityDetector(

+ 3 - 4
lib/ui/viewer/file/zoomable_image.dart

@@ -93,7 +93,7 @@ class _ZoomableImageState extends State<ZoomableImage>
     final GestureDragUpdateCallback verticalDragCallback = _isZooming
     final GestureDragUpdateCallback verticalDragCallback = _isZooming
         ? null
         ? null
         : (d) => {
         : (d) => {
-              if (!_isZooming && d.delta.dy > kDragSensitivity)
+              if (!_isZooming && d.delta.dy > dragSensitivity)
                 {Navigator.of(context).pop()}
                 {Navigator.of(context).pop()}
             };
             };
     return GestureDetector(
     return GestureDetector(
@@ -143,8 +143,7 @@ class _ZoomableImageState extends State<ZoomableImage>
     if (!_loadedSmallThumbnail &&
     if (!_loadedSmallThumbnail &&
         !_loadedLargeThumbnail &&
         !_loadedLargeThumbnail &&
         !_loadedFinalImage) {
         !_loadedFinalImage) {
-      final cachedThumbnail =
-          ThumbnailLruCache.get(_photo, kThumbnailSmallSize);
+      final cachedThumbnail = ThumbnailLruCache.get(_photo, thumbnailSmallSize);
       if (cachedThumbnail != null) {
       if (cachedThumbnail != null) {
         _imageProvider = Image.memory(cachedThumbnail).image;
         _imageProvider = Image.memory(cachedThumbnail).image;
         _loadedSmallThumbnail = true;
         _loadedSmallThumbnail = true;
@@ -155,7 +154,7 @@ class _ZoomableImageState extends State<ZoomableImage>
         !_loadedLargeThumbnail &&
         !_loadedLargeThumbnail &&
         !_loadedFinalImage) {
         !_loadedFinalImage) {
       _loadingLargeThumbnail = true;
       _loadingLargeThumbnail = true;
-      getThumbnailFromLocal(_photo, size: kThumbnailLargeSize, quality: 100)
+      getThumbnailFromLocal(_photo, size: thumbnailLargeSize, quality: 100)
           .then((cachedThumbnail) {
           .then((cachedThumbnail) {
         if (cachedThumbnail != null) {
         if (cachedThumbnail != null) {
           _onLargeThumbnailLoaded(Image.memory(cachedThumbnail).image, context);
           _onLargeThumbnailLoaded(Image.memory(cachedThumbnail).image, context);

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

@@ -167,10 +167,10 @@ class _ZoomableLiveImageState extends State<ZoomableLiveImage>
 
 
   void _showLivePhotoToast() async {
   void _showLivePhotoToast() async {
     final preferences = await SharedPreferences.getInstance();
     final preferences = await SharedPreferences.getInstance();
-    final int promptTillNow = preferences.getInt(kLivePhotoToastCounterKey) ?? 0;
-    if (promptTillNow < kMaxLivePhotoToastCount && mounted) {
+    final int promptTillNow = preferences.getInt(livePhotoToastCounterKey) ?? 0;
+    if (promptTillNow < maxLivePhotoToastCount && mounted) {
       showToast(context, "Press and hold to play video");
       showToast(context, "Press and hold to play video");
-      preferences.setInt(kLivePhotoToastCounterKey, promptTillNow + 1);
+      preferences.setInt(livePhotoToastCounterKey, promptTillNow + 1);
     }
     }
   }
   }
 }
 }

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

@@ -118,8 +118,8 @@ class _GalleryState extends State<Gallery> {
     try {
     try {
       final startTime = DateTime.now().microsecondsSinceEpoch;
       final startTime = DateTime.now().microsecondsSinceEpoch;
       final result = await widget.asyncLoader(
       final result = await widget.asyncLoader(
-        kGalleryLoadStartTime,
-        kGalleryLoadEndTime,
+        galleryLoadStartTime,
+        galleryLoadEndTime,
         limit: limit,
         limit: limit,
       );
       );
       final endTime = DateTime.now().microsecondsSinceEpoch;
       final endTime = DateTime.now().microsecondsSinceEpoch;

+ 1 - 0
lib/utils/crypto_util.dart

@@ -204,6 +204,7 @@ class CryptoUtil {
     Uint8List key,
     Uint8List key,
     Uint8List nonce,
     Uint8List nonce,
   ) {
   ) {
+    assert(key != null, "key can not be null");
     final args = <String, dynamic>{};
     final args = <String, dynamic>{};
     args["cipher"] = cipher;
     args["cipher"] = cipher;
     args["nonce"] = nonce;
     args["nonce"] = nonce;

+ 3 - 3
lib/utils/delete_file_util.dart

@@ -311,8 +311,8 @@ Future<bool> deleteLocalFiles(
   final List<String> localAssetIDs = [];
   final List<String> localAssetIDs = [];
   final List<String> localSharedMediaIDs = [];
   final List<String> localSharedMediaIDs = [];
   for (String id in localIDs) {
   for (String id in localIDs) {
-    if (id.startsWith(kOldSharedMediaIdentifier) ||
-        id.startsWith(kSharedMediaIdentifier)) {
+    if (id.startsWith(oldSharedMediaIdentifier) ||
+        id.startsWith(sharedMediaIdentifier)) {
       localSharedMediaIDs.add(id);
       localSharedMediaIDs.add(id);
     } else {
     } else {
       localAssetIDs.add(id);
       localAssetIDs.add(id);
@@ -322,7 +322,7 @@ Future<bool> deleteLocalFiles(
 
 
   if (Platform.isAndroid) {
   if (Platform.isAndroid) {
     final androidInfo = await DeviceInfoPlugin().androidInfo;
     final androidInfo = await DeviceInfoPlugin().androidInfo;
-    if (androidInfo.version.sdkInt < kAndroid11SDKINT) {
+    if (androidInfo.version.sdkInt < android11SDKINT) {
       deletedIDs
       deletedIDs
           .addAll(await _deleteLocalFilesInBatches(context, localAssetIDs));
           .addAll(await _deleteLocalFilesInBatches(context, localAssetIDs));
     } else {
     } else {

+ 5 - 5
lib/utils/file_uploader_util.dart

@@ -128,14 +128,14 @@ Future<MediaUploadData> _getMediaUploadDataFromAssetFile(ente.File file) async {
   }
   }
 
 
   thumbnailData = await asset.thumbnailDataWithSize(
   thumbnailData = await asset.thumbnailDataWithSize(
-    const ThumbnailSize(kThumbnailLargeSize, kThumbnailLargeSize),
-    quality: kThumbnailQuality,
+    const ThumbnailSize(thumbnailLargeSize, thumbnailLargeSize),
+    quality: thumbnailQuality,
   );
   );
   if (thumbnailData == null) {
   if (thumbnailData == null) {
     throw InvalidFileError("unable to get asset thumbData");
     throw InvalidFileError("unable to get asset thumbData");
   }
   }
   int compressionAttempts = 0;
   int compressionAttempts = 0;
-  while (thumbnailData.length > kThumbnailDataLimit &&
+  while (thumbnailData.length > thumbnailDataLimit &&
       compressionAttempts < kMaximumThumbnailCompressionAttempts) {
       compressionAttempts < kMaximumThumbnailCompressionAttempts) {
     _logger.info("Thumbnail size " + thumbnailData.length.toString());
     _logger.info("Thumbnail size " + thumbnailData.length.toString());
     thumbnailData = await compressThumbnail(thumbnailData);
     thumbnailData = await compressThumbnail(thumbnailData);
@@ -204,14 +204,14 @@ Future<Uint8List> getThumbnailFromInAppCacheFile(ente.File file) async {
       video: localFile.path,
       video: localFile.path,
       imageFormat: ImageFormat.JPEG,
       imageFormat: ImageFormat.JPEG,
       thumbnailPath: (await getTemporaryDirectory()).path,
       thumbnailPath: (await getTemporaryDirectory()).path,
-      maxWidth: kThumbnailLargeSize,
+      maxWidth: thumbnailLargeSize,
       quality: 80,
       quality: 80,
     );
     );
     localFile = io.File(thumbnailFilePath);
     localFile = io.File(thumbnailFilePath);
   }
   }
   var thumbnailData = await localFile.readAsBytes();
   var thumbnailData = await localFile.readAsBytes();
   int compressionAttempts = 0;
   int compressionAttempts = 0;
-  while (thumbnailData.length > kThumbnailDataLimit &&
+  while (thumbnailData.length > thumbnailDataLimit &&
       compressionAttempts < kMaximumThumbnailCompressionAttempts) {
       compressionAttempts < kMaximumThumbnailCompressionAttempts) {
     _logger.info("Thumbnail size " + thumbnailData.length.toString());
     _logger.info("Thumbnail size " + thumbnailData.length.toString());
     thumbnailData = await compressThumbnail(thumbnailData);
     thumbnailData = await compressThumbnail(thumbnailData);

+ 5 - 5
lib/utils/file_util.dart

@@ -92,14 +92,14 @@ String getSharedMediaFilePath(ente.File file) {
 }
 }
 
 
 String getSharedMediaPathFromLocalID(String localID) {
 String getSharedMediaPathFromLocalID(String localID) {
-  if (localID.startsWith(kOldSharedMediaIdentifier)) {
+  if (localID.startsWith(oldSharedMediaIdentifier)) {
     return Configuration.instance.getOldSharedMediaCacheDirectory() +
     return Configuration.instance.getOldSharedMediaCacheDirectory() +
         "/" +
         "/" +
-        localID.replaceAll(kOldSharedMediaIdentifier, '');
+        localID.replaceAll(oldSharedMediaIdentifier, '');
   } else {
   } else {
     return Configuration.instance.getSharedMediaDirectory() +
     return Configuration.instance.getSharedMediaDirectory() +
         "/" +
         "/" +
-        localID.replaceAll(kSharedMediaIdentifier, '');
+        localID.replaceAll(sharedMediaIdentifier, '');
   }
   }
 }
 }
 
 
@@ -301,8 +301,8 @@ String getExtension(String nameOrPath) {
 Future<Uint8List> compressThumbnail(Uint8List thumbnail) {
 Future<Uint8List> compressThumbnail(Uint8List thumbnail) {
   return FlutterImageCompress.compressWithList(
   return FlutterImageCompress.compressWithList(
     thumbnail,
     thumbnail,
-    minHeight: kCompressedThumbnailResolution,
-    minWidth: kCompressedThumbnailResolution,
+    minHeight: compressedThumbnailResolution,
+    minWidth: compressedThumbnailResolution,
     quality: 25,
     quality: 25,
   );
   );
 }
 }

+ 3 - 2
lib/utils/share_util.dart

@@ -46,7 +46,8 @@ Future<void> share(
 
 
 Rect shareButtonRect(BuildContext context, GlobalKey shareButtonKey) {
 Rect shareButtonRect(BuildContext context, GlobalKey shareButtonKey) {
   Size size = MediaQuery.of(context).size;
   Size size = MediaQuery.of(context).size;
-  final RenderBox renderBox = shareButtonKey?.currentContext?.findRenderObject();
+  final RenderBox renderBox =
+      shareButtonKey?.currentContext?.findRenderObject();
   if (renderBox == null) {
   if (renderBox == null) {
     return Rect.fromLTWH(0, 0, size.width, size.height / 2);
     return Rect.fromLTWH(0, 0, size.width, size.height / 2);
   }
   }
@@ -83,7 +84,7 @@ Future<List<File>> convertIncomingSharedMediaToFile(
     ioFile = ioFile.renameSync(
     ioFile = ioFile.renameSync(
       Configuration.instance.getSharedMediaDirectory() + "/" + enteFile.title,
       Configuration.instance.getSharedMediaDirectory() + "/" + enteFile.title,
     );
     );
-    enteFile.localID = kSharedMediaIdentifier + enteFile.title;
+    enteFile.localID = sharedMediaIdentifier + enteFile.title;
     enteFile.collectionID = collectionID;
     enteFile.collectionID = collectionID;
     enteFile.fileType =
     enteFile.fileType =
         media.type == SharedMediaType.IMAGE ? FileType.image : FileType.video;
         media.type == SharedMediaType.IMAGE ? FileType.image : FileType.video;

+ 3 - 3
lib/utils/thumbnail_util.dart

@@ -62,8 +62,8 @@ Future<Uint8List> getThumbnailFromServer(File file) async {
 
 
 Future<Uint8List> getThumbnailFromLocal(
 Future<Uint8List> getThumbnailFromLocal(
   File file, {
   File file, {
-  int size = kThumbnailSmallSize,
-  int quality = kThumbnailQuality,
+  int size = thumbnailSmallSize,
+  int quality = thumbnailQuality,
 }) async {
 }) async {
   final lruCachedThumbnail = ThumbnailLruCache.get(file, size);
   final lruCachedThumbnail = ThumbnailLruCache.get(file, size);
   if (lruCachedThumbnail != null) {
   if (lruCachedThumbnail != null) {
@@ -154,7 +154,7 @@ Future<void> _downloadAndDecryptThumbnail(FileDownloadItem item) async {
     Sodium.base642bin(file.thumbnailDecryptionHeader),
     Sodium.base642bin(file.thumbnailDecryptionHeader),
   );
   );
   final thumbnailSize = data.length;
   final thumbnailSize = data.length;
-  if (thumbnailSize > kThumbnailDataLimit) {
+  if (thumbnailSize > thumbnailDataLimit) {
     data = await compressThumbnail(data);
     data = await compressThumbnail(data);
   }
   }
   ThumbnailLruCache.put(item.file, data);
   ThumbnailLruCache.put(item.file, data);

+ 0 - 72
pubspec.lock

@@ -8,15 +8,6 @@ packages:
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
     version: "3.1.0"
     version: "3.1.0"
-  alice:
-    dependency: "direct main"
-    description:
-      path: "."
-      ref: HEAD
-      resolved-ref: "42c97aebbea93d1944a199b453b41bbed1f3013a"
-      url: "https://github.com/jhomlala/alice.git"
-    source: git
-    version: "0.2.5"
   animate_do:
   animate_do:
     dependency: "direct main"
     dependency: "direct main"
     description:
     description:
@@ -52,13 +43,6 @@ packages:
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
     version: "1.1.0"
     version: "1.1.0"
-  better_player:
-    dependency: transitive
-    description:
-      name: better_player
-      url: "https://pub.dartlang.org"
-    source: hosted
-    version: "0.0.81"
   bip39:
   bip39:
     dependency: "direct main"
     dependency: "direct main"
     description:
     description:
@@ -115,13 +99,6 @@ packages:
       relative: true
       relative: true
     source: path
     source: path
     version: "1.2.2"
     version: "1.2.2"
-  chopper:
-    dependency: transitive
-    description:
-      name: chopper
-      url: "https://pub.dartlang.org"
-    source: hosted
-    version: "4.0.5"
   clock:
   clock:
     dependency: transitive
     dependency: transitive
     description:
     description:
@@ -562,13 +539,6 @@ packages:
     description: flutter
     description: flutter
     source: sdk
     source: sdk
     version: "0.0.0"
     version: "0.0.0"
-  flutter_widget_from_html_core:
-    dependency: transitive
-    description:
-      name: flutter_widget_from_html_core
-      url: "https://pub.dartlang.org"
-    source: hosted
-    version: "0.8.5+3"
   flutter_windowmanager:
   flutter_windowmanager:
     dependency: "direct main"
     dependency: "direct main"
     description:
     description:
@@ -590,13 +560,6 @@ packages:
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
     version: "8.0.9"
     version: "8.0.9"
-  fwfh_text_style:
-    dependency: transitive
-    description:
-      name: fwfh_text_style
-      url: "https://pub.dartlang.org"
-    source: hosted
-    version: "2.7.3+2"
   google_nav_bar:
   google_nav_bar:
     dependency: "direct main"
     dependency: "direct main"
     description:
     description:
@@ -795,13 +758,6 @@ packages:
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
     version: "1.0.2"
     version: "1.0.2"
-  open_file:
-    dependency: "direct main"
-    description:
-      name: open_file
-      url: "https://pub.dartlang.org"
-    source: hosted
-    version: "3.2.1"
   open_mail_app:
   open_mail_app:
     dependency: "direct main"
     dependency: "direct main"
     description:
     description:
@@ -942,20 +898,6 @@ packages:
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
     version: "1.11.1"
     version: "1.11.1"
-  permission_handler:
-    dependency: transitive
-    description:
-      name: permission_handler
-      url: "https://pub.dartlang.org"
-    source: hosted
-    version: "8.3.0"
-  permission_handler_platform_interface:
-    dependency: transitive
-    description:
-      name: permission_handler_platform_interface
-      url: "https://pub.dartlang.org"
-    source: hosted
-    version: "3.7.0"
   petitparser:
   petitparser:
     dependency: transitive
     dependency: transitive
     description:
     description:
@@ -1047,13 +989,6 @@ packages:
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
     version: "0.2.3"
     version: "0.2.3"
-  sensors:
-    dependency: transitive
-    description:
-      name: sensors
-      url: "https://pub.dartlang.org"
-    source: hosted
-    version: "2.0.3"
   sentry:
   sentry:
     dependency: "direct main"
     dependency: "direct main"
     description:
     description:
@@ -1068,13 +1003,6 @@ packages:
       relative: true
       relative: true
     source: path
     source: path
     version: "6.5.1"
     version: "6.5.1"
-  share:
-    dependency: transitive
-    description:
-      name: share
-      url: "https://pub.dartlang.org"
-    source: hosted
-    version: "2.0.4"
   share_plus:
   share_plus:
     dependency: "direct main"
     dependency: "direct main"
     description:
     description:

+ 2 - 4
pubspec.yaml

@@ -11,15 +11,13 @@ description: ente photos application
 # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
 # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
 # Read more about iOS versioning at
 # Read more about iOS versioning at
 # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
 # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
-version: 0.6.31+361
+version: 0.6.32+362
 
 
 environment:
 environment:
   sdk: '>=2.12.0 <3.0.0'
   sdk: '>=2.12.0 <3.0.0'
 
 
 dependencies:
 dependencies:
   adaptive_theme: ^3.1.0
   adaptive_theme: ^3.1.0
-  alice:
-    git: "https://github.com/jhomlala/alice.git"
   animate_do: ^2.0.0
   animate_do: ^2.0.0
   archive: ^3.1.2
   archive: ^3.1.2
   background_fetch: ^1.0.1
   background_fetch: ^1.0.1
@@ -82,7 +80,7 @@ dependencies:
     git: "https://github.com/ente-io/motionphoto.git"
     git: "https://github.com/ente-io/motionphoto.git"
   move_to_background: ^1.0.2
   move_to_background: ^1.0.2
 
 
-  open_file: ^3.2.1
+  # open_file: ^3.2.1
   open_mail_app: ^0.4.5
   open_mail_app: ^0.4.5
   package_info_plus: ^1.0.1
   package_info_plus: ^1.0.1
   page_transition: ^2.0.2
   page_transition: ^2.0.2