Sfoglia il codice sorgente

Merge branch 'main' into keychain_migration

Neeraj Gupta 2 anni fa
parent
commit
18f4731eb3
55 ha cambiato i file con 335 aggiunte e 465 eliminazioni
  1. 3 2
      hooks/pre-commit
  2. 0 1
      lib/models/filters/gallery_items_filter.dart
  3. 4 3
      lib/models/filters/important_items_filter.dart
  4. 3 6
      lib/services/billing_service.dart
  5. 0 1
      lib/services/hidden_service.dart
  6. 0 1
      lib/services/user_service.dart
  7. 2 4
      lib/ui/account/change_email_dialog.dart
  8. 1 1
      lib/ui/account/delete_account_page.dart
  9. 0 1
      lib/ui/account/password_entry_page.dart
  10. 2 0
      lib/ui/account/recovery_key_page.dart
  11. 10 10
      lib/ui/account/sessions_page.dart
  12. 4 6
      lib/ui/account/two_factor_authentication_page.dart
  13. 1 3
      lib/ui/account/two_factor_recovery_page.dart
  14. 6 8
      lib/ui/account/two_factor_setup_page.dart
  15. 0 1
      lib/ui/account/verify_recovery_page.dart
  16. 3 2
      lib/ui/actions/collection/collection_file_actions.dart
  17. 0 1
      lib/ui/actions/collection/collection_sharing_actions.dart
  18. 0 1
      lib/ui/backup_folder_selection_page.dart
  19. 3 5
      lib/ui/collections/archived_collections_button_widget.dart
  20. 3 7
      lib/ui/collections/create_new_album_widget.dart
  21. 3 5
      lib/ui/collections/device_folder_icon_widget.dart
  22. 5 7
      lib/ui/collections/trash_button_widget.dart
  23. 5 29
      lib/ui/components/action_sheet_widget.dart
  24. 4 63
      lib/ui/components/dialog_widget.dart
  25. 0 1
      lib/ui/create_collection_page.dart
  26. 4 6
      lib/ui/home/grant_permissions_widget.dart
  27. 2 4
      lib/ui/huge_listview/place_holder_widget.dart
  28. 0 1
      lib/ui/notification/prompts/password_reminder.dart
  29. 4 7
      lib/ui/payment/child_subscription_widget.dart
  30. 0 1
      lib/ui/payment/payment_web_page.dart
  31. 4 6
      lib/ui/payment/skip_subscription_widget.dart
  32. 0 1
      lib/ui/payment/stripe_subscription_page.dart
  33. 1 3
      lib/ui/payment/subscription.dart
  34. 0 1
      lib/ui/payment/subscription_page.dart
  35. 5 7
      lib/ui/settings/about_section_widget.dart
  36. 2 4
      lib/ui/settings/account_section_widget.dart
  37. 4 6
      lib/ui/settings/app_version_widget.dart
  38. 46 76
      lib/ui/settings/backup_section_widget.dart
  39. 3 5
      lib/ui/settings/debug_section_widget.dart
  40. 1 3
      lib/ui/settings/general_section_widget.dart
  41. 3 4
      lib/ui/settings/security_section_widget.dart
  42. 0 35
      lib/ui/settings/settings_text_item.dart
  43. 2 4
      lib/ui/settings/social_section_widget.dart
  44. 4 4
      lib/ui/settings/support_section_widget.dart
  45. 0 1
      lib/ui/sharing/manage_links_widget.dart
  46. 9 11
      lib/ui/sharing/share_collection_page.dart
  47. 2 0
      lib/ui/tools/debug/app_storage_viewer.dart
  48. 0 1
      lib/ui/viewer/file/fading_app_bar.dart
  49. 23 37
      lib/ui/viewer/gallery/gallery_app_bar_widget.dart
  50. 0 1
      lib/ui/viewer/gallery/gallery_overlay_widget.dart
  51. 1 3
      lib/ui/viewer/search/result/no_result_widget.dart
  52. 0 1
      lib/utils/delete_file_util.dart
  53. 153 61
      lib/utils/dialog_util.dart
  54. 0 1
      lib/utils/email_util.dart
  55. 0 1
      lib/utils/share_util.dart

+ 3 - 2
hooks/pre-commit

@@ -2,8 +2,9 @@
 # This git hook fails if a user is trying to add a new file which is
 # This git hook fails if a user is trying to add a new file which is
 # not null safe.
 # not null safe.
 
 
-# Check the contents of each file that is being added or modified
-for file in `git diff --name-only --cached`; do
+# Check the contents of each file that is being added(A) or modified(N) or
+# copied (C)
+for file in `git diff --name-only --diff-filter=ACM --cached`; do
   # Ignore the hooks from any pre-commit check
   # Ignore the hooks from any pre-commit check
   if echo "$file" | grep -q 'hooks/'; then
   if echo "$file" | grep -q 'hooks/'; then
     continue
     continue

+ 0 - 1
lib/models/filters/gallery_items_filter.dart

@@ -1,4 +1,3 @@
-// @dart=2.9
 import 'package:photos/models/file.dart';
 import 'package:photos/models/file.dart';
 
 
 class GalleryItemsFilter {
 class GalleryItemsFilter {

+ 4 - 3
lib/models/filters/important_items_filter.dart

@@ -1,5 +1,3 @@
-// @dart=2.9
-
 import 'dart:io';
 import 'dart:io';
 
 
 import 'package:path/path.dart';
 import 'package:path/path.dart';
@@ -15,7 +13,10 @@ class ImportantItemsFilter implements GalleryItemsFilter {
     if (file.uploadedFileID != null) {
     if (file.uploadedFileID != null) {
       return true;
       return true;
     }
     }
-    final String folder = basename(file.deviceFolder);
+    if (file.deviceFolder == null) {
+      return false;
+    }
+    final String folder = basename(file.deviceFolder!);
     if (_importantPaths.isEmpty && Platform.isAndroid) {
     if (_importantPaths.isEmpty && Platform.isAndroid) {
       return folder == "Camera" ||
       return folder == "Camera" ||
           folder == "Recents" ||
           folder == "Recents" ||

+ 3 - 6
lib/services/billing_service.dart

@@ -1,5 +1,3 @@
-// @dart=2.9
-
 import 'dart:io';
 import 'dart:io';
 
 
 import 'package:dio/dio.dart';
 import 'package:dio/dio.dart';
@@ -15,7 +13,6 @@ import 'package:photos/models/subscription.dart';
 import 'package:photos/models/user_details.dart';
 import 'package:photos/models/user_details.dart';
 import 'package:photos/services/user_service.dart';
 import 'package:photos/services/user_service.dart';
 import 'package:photos/ui/common/web_page.dart';
 import 'package:photos/ui/common/web_page.dart';
-import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 
 
 const kWebPaymentRedirectUrl = "https://payments.ente.io/frameRedirect";
 const kWebPaymentRedirectUrl = "https://payments.ente.io/frameRedirect";
@@ -39,7 +36,7 @@ class BillingService {
 
 
   bool _isOnSubscriptionPage = false;
   bool _isOnSubscriptionPage = false;
 
 
-  Future<BillingPlans> _future;
+  Future<BillingPlans>? _future;
 
 
   void init() {
   void init() {
     // if (Platform.isIOS && kDebugMode) {
     // if (Platform.isIOS && kDebugMode) {
@@ -75,7 +72,7 @@ class BillingService {
     _future ??= _fetchBillingPlans().then((response) {
     _future ??= _fetchBillingPlans().then((response) {
       return BillingPlans.fromMap(response.data);
       return BillingPlans.fromMap(response.data);
     });
     });
-    return _future;
+    return _future!;
   }
   }
 
 
   Future<Response<dynamic>> _fetchBillingPlans() {
   Future<Response<dynamic>> _fetchBillingPlans() {
@@ -99,7 +96,7 @@ class BillingService {
       );
       );
       return Subscription.fromMap(response.data["subscription"]);
       return Subscription.fromMap(response.data["subscription"]);
     } on DioError catch (e) {
     } on DioError catch (e) {
-      if (e.response != null && e.response.statusCode == 409) {
+      if (e.response != null && e.response!.statusCode == 409) {
         throw SubscriptionAlreadyClaimedError();
         throw SubscriptionAlreadyClaimedError();
       } else {
       } else {
         rethrow;
         rethrow;

+ 0 - 1
lib/services/hidden_service.dart

@@ -14,7 +14,6 @@ import 'package:photos/models/file.dart';
 import 'package:photos/models/magic_metadata.dart';
 import 'package:photos/models/magic_metadata.dart';
 import 'package:photos/services/collections_service.dart';
 import 'package:photos/services/collections_service.dart';
 import 'package:photos/services/file_magic_service.dart';
 import 'package:photos/services/file_magic_service.dart';
-import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/utils/crypto_util.dart';
 import 'package:photos/utils/crypto_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 
 

+ 0 - 1
lib/services/user_service.dart

@@ -30,7 +30,6 @@ import 'package:photos/ui/account/password_reentry_page.dart';
 import 'package:photos/ui/account/two_factor_authentication_page.dart';
 import 'package:photos/ui/account/two_factor_authentication_page.dart';
 import 'package:photos/ui/account/two_factor_recovery_page.dart';
 import 'package:photos/ui/account/two_factor_recovery_page.dart';
 import 'package:photos/ui/account/two_factor_setup_page.dart';
 import 'package:photos/ui/account/two_factor_setup_page.dart';
-import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/utils/crypto_util.dart';
 import 'package:photos/utils/crypto_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/navigation_util.dart';
 import 'package:photos/utils/navigation_util.dart';

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

@@ -1,19 +1,17 @@
-// @dart=2.9
-
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:photos/services/user_service.dart';
 import 'package:photos/services/user_service.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/email_util.dart';
 import 'package:photos/utils/email_util.dart';
 
 
 class ChangeEmailDialog extends StatefulWidget {
 class ChangeEmailDialog extends StatefulWidget {
-  const ChangeEmailDialog({Key key}) : super(key: key);
+  const ChangeEmailDialog({Key? key}) : super(key: key);
 
 
   @override
   @override
   State<ChangeEmailDialog> createState() => _ChangeEmailDialogState();
   State<ChangeEmailDialog> createState() => _ChangeEmailDialogState();
 }
 }
 
 
 class _ChangeEmailDialogState extends State<ChangeEmailDialog> {
 class _ChangeEmailDialogState extends State<ChangeEmailDialog> {
-  String _email;
+  String? _email;
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {

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

@@ -10,9 +10,9 @@ import 'package:photos/services/local_authentication_service.dart';
 import 'package:photos/services/user_service.dart';
 import 'package:photos/services/user_service.dart';
 import 'package:photos/theme/ente_theme.dart';
 import 'package:photos/theme/ente_theme.dart';
 import 'package:photos/ui/components/button_widget.dart';
 import 'package:photos/ui/components/button_widget.dart';
-import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/ui/components/models/button_type.dart';
 import 'package:photos/ui/components/models/button_type.dart';
 import 'package:photos/utils/crypto_util.dart';
 import 'package:photos/utils/crypto_util.dart';
+import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/email_util.dart';
 import 'package:photos/utils/email_util.dart';
 
 
 class DeleteAccountPage extends StatelessWidget {
 class DeleteAccountPage extends StatelessWidget {

+ 0 - 1
lib/ui/account/password_entry_page.dart

@@ -12,7 +12,6 @@ import 'package:photos/services/user_service.dart';
 import 'package:photos/ui/account/recovery_key_page.dart';
 import 'package:photos/ui/account/recovery_key_page.dart';
 import 'package:photos/ui/common/dynamic_fab.dart';
 import 'package:photos/ui/common/dynamic_fab.dart';
 import 'package:photos/ui/common/web_page.dart';
 import 'package:photos/ui/common/web_page.dart';
-import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/ui/payment/subscription.dart';
 import 'package:photos/ui/payment/subscription.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/navigation_util.dart';
 import 'package:photos/utils/navigation_util.dart';

+ 2 - 0
lib/ui/account/recovery_key_page.dart

@@ -65,6 +65,7 @@ class _RecoveryKeyPageState extends State<RecoveryKeyPage> {
     return Scaffold(
     return Scaffold(
       appBar: widget.showProgressBar
       appBar: widget.showProgressBar
           ? AppBar(
           ? AppBar(
+              automaticallyImplyLeading: false,
               elevation: 0,
               elevation: 0,
               title: Hero(
               title: Hero(
                 tag: "recovery_key",
                 tag: "recovery_key",
@@ -97,6 +98,7 @@ class _RecoveryKeyPageState extends State<RecoveryKeyPage> {
                 child: IntrinsicHeight(
                 child: IntrinsicHeight(
                   child: Column(
                   child: Column(
                     mainAxisSize: MainAxisSize.max,
                     mainAxisSize: MainAxisSize.max,
+                    crossAxisAlignment: CrossAxisAlignment.start,
                     children: [
                     children: [
                       widget.showAppBar
                       widget.showAppBar
                           ? const SizedBox.shrink()
                           ? const SizedBox.shrink()

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

@@ -1,5 +1,3 @@
-// @dart=2.9
-
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:logging/logging.dart';
 import 'package:logging/logging.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/configuration.dart';
@@ -12,14 +10,14 @@ import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/toast_util.dart';
 import 'package:photos/utils/toast_util.dart';
 
 
 class SessionsPage extends StatefulWidget {
 class SessionsPage extends StatefulWidget {
-  const SessionsPage({Key key}) : super(key: key);
+  const SessionsPage({Key? key}) : super(key: key);
 
 
   @override
   @override
   State<SessionsPage> createState() => _SessionsPageState();
   State<SessionsPage> createState() => _SessionsPageState();
 }
 }
 
 
 class _SessionsPageState extends State<SessionsPage> {
 class _SessionsPageState extends State<SessionsPage> {
-  Sessions _sessions;
+  Sessions? _sessions;
   final Logger _logger = Logger("SessionsPageState");
   final Logger _logger = Logger("SessionsPageState");
 
 
   @override
   @override
@@ -45,7 +43,7 @@ class _SessionsPageState extends State<SessionsPage> {
     }
     }
     final List<Widget> rows = [];
     final List<Widget> rows = [];
     rows.add(const Padding(padding: EdgeInsets.all(4)));
     rows.add(const Padding(padding: EdgeInsets.all(4)));
-    for (final session in _sessions.sessions) {
+    for (final session in _sessions!.sessions) {
       rows.add(_getSessionWidget(session));
       rows.add(_getSessionWidget(session));
     }
     }
     return SingleChildScrollView(
     return SingleChildScrollView(
@@ -133,12 +131,14 @@ class _SessionsPageState extends State<SessionsPage> {
         .getActiveSessions()
         .getActiveSessions()
         .onError((error, stackTrace) {
         .onError((error, stackTrace) {
       showToast(context, "Failed to fetch active sessions");
       showToast(context, "Failed to fetch active sessions");
-      throw error;
-    });
-    _sessions.sessions.sort((first, second) {
-      return second.lastUsedTime.compareTo(first.lastUsedTime);
+      throw error!;
     });
     });
-    setState(() {});
+    if (_sessions != null) {
+      _sessions!.sessions.sort((first, second) {
+        return second.lastUsedTime.compareTo(first.lastUsedTime);
+      });
+      setState(() {});
+    }
   }
   }
 
 
   void _showSessionTerminationDialog(Session session) {
   void _showSessionTerminationDialog(Session session) {

+ 4 - 6
lib/ui/account/two_factor_authentication_page.dart

@@ -1,5 +1,3 @@
-// @dart=2.9
-
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter/services.dart';
 import 'package:photos/services/user_service.dart';
 import 'package:photos/services/user_service.dart';
@@ -9,7 +7,7 @@ import 'package:pinput/pin_put/pin_put.dart';
 class TwoFactorAuthenticationPage extends StatefulWidget {
 class TwoFactorAuthenticationPage extends StatefulWidget {
   final String sessionID;
   final String sessionID;
 
 
-  const TwoFactorAuthenticationPage(this.sessionID, {Key key})
+  const TwoFactorAuthenticationPage(this.sessionID, {Key? key})
       : super(key: key);
       : super(key: key);
 
 
   @override
   @override
@@ -25,7 +23,7 @@ class _TwoFactorAuthenticationPageState
     borderRadius: BorderRadius.circular(15.0),
     borderRadius: BorderRadius.circular(15.0),
   );
   );
   String _code = "";
   String _code = "";
-  LifecycleEventHandler _lifecycleEventHandler;
+  late LifecycleEventHandler _lifecycleEventHandler;
 
 
   @override
   @override
   void initState() {
   void initState() {
@@ -33,8 +31,8 @@ class _TwoFactorAuthenticationPageState
       resumeCallBack: () async {
       resumeCallBack: () async {
         if (mounted) {
         if (mounted) {
           final data = await Clipboard.getData(Clipboard.kTextPlain);
           final data = await Clipboard.getData(Clipboard.kTextPlain);
-          if (data != null && data.text != null && data.text.length == 6) {
-            _pinController.text = data.text;
+          if (data != null && data.text != null && data.text!.length == 6) {
+            _pinController.text = data.text!;
           }
           }
         }
         }
       },
       },

+ 1 - 3
lib/ui/account/two_factor_recovery_page.dart

@@ -1,5 +1,3 @@
-// @dart=2.9
-
 import 'dart:ui';
 import 'dart:ui';
 
 
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
@@ -15,7 +13,7 @@ class TwoFactorRecoveryPage extends StatefulWidget {
     this.sessionID,
     this.sessionID,
     this.encryptedSecret,
     this.encryptedSecret,
     this.secretDecryptionNonce, {
     this.secretDecryptionNonce, {
-    Key key,
+    Key? key,
   }) : super(key: key);
   }) : super(key: key);
 
 
   @override
   @override

+ 6 - 8
lib/ui/account/two_factor_setup_page.dart

@@ -1,5 +1,3 @@
-// @dart=2.9
-
 import 'dart:async';
 import 'dart:async';
 import 'dart:ui';
 import 'dart:ui';
 
 
@@ -24,7 +22,7 @@ class TwoFactorSetupPage extends StatefulWidget {
     this.secretCode,
     this.secretCode,
     this.qrCode,
     this.qrCode,
     this.completer, {
     this.completer, {
-    Key key,
+    Key? key,
   }) : super(key: key);
   }) : super(key: key);
 
 
   @override
   @override
@@ -33,15 +31,15 @@ class TwoFactorSetupPage extends StatefulWidget {
 
 
 class _TwoFactorSetupPageState extends State<TwoFactorSetupPage>
 class _TwoFactorSetupPageState extends State<TwoFactorSetupPage>
     with SingleTickerProviderStateMixin {
     with SingleTickerProviderStateMixin {
-  TabController _tabController;
+  late TabController _tabController;
   final _pinController = TextEditingController();
   final _pinController = TextEditingController();
   final _pinPutDecoration = BoxDecoration(
   final _pinPutDecoration = BoxDecoration(
     border: Border.all(color: const Color.fromRGBO(45, 194, 98, 1.0)),
     border: Border.all(color: const Color.fromRGBO(45, 194, 98, 1.0)),
     borderRadius: BorderRadius.circular(15.0),
     borderRadius: BorderRadius.circular(15.0),
   );
   );
   String _code = "";
   String _code = "";
-  ImageProvider _imageProvider;
-  LifecycleEventHandler _lifecycleEventHandler;
+  late ImageProvider _imageProvider;
+  late LifecycleEventHandler _lifecycleEventHandler;
 
 
   @override
   @override
   void initState() {
   void initState() {
@@ -55,8 +53,8 @@ class _TwoFactorSetupPageState extends State<TwoFactorSetupPage>
       resumeCallBack: () async {
       resumeCallBack: () async {
         if (mounted) {
         if (mounted) {
           final data = await Clipboard.getData(Clipboard.kTextPlain);
           final data = await Clipboard.getData(Clipboard.kTextPlain);
-          if (data != null && data.text != null && data.text.length == 6) {
-            _pinController.text = data.text;
+          if (data != null && data.text != null && data.text!.length == 6) {
+            _pinController.text = data.text!;
           }
           }
         }
         }
       },
       },

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

@@ -14,7 +14,6 @@ import 'package:photos/services/user_service.dart';
 import 'package:photos/ui/account/recovery_key_page.dart';
 import 'package:photos/ui/account/recovery_key_page.dart';
 import 'package:photos/ui/common/dialogs.dart';
 import 'package:photos/ui/common/dialogs.dart';
 import 'package:photos/ui/common/gradient_button.dart';
 import 'package:photos/ui/common/gradient_button.dart';
-import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/navigation_util.dart';
 import 'package:photos/utils/navigation_util.dart';
 
 

+ 3 - 2
lib/ui/actions/collection/collection_file_actions.dart

@@ -8,7 +8,6 @@ import 'package:photos/services/favorites_service.dart';
 import 'package:photos/theme/ente_theme.dart';
 import 'package:photos/theme/ente_theme.dart';
 import 'package:photos/ui/actions/collection/collection_sharing_actions.dart';
 import 'package:photos/ui/actions/collection/collection_sharing_actions.dart';
 import 'package:photos/ui/common/progress_dialog.dart';
 import 'package:photos/ui/common/progress_dialog.dart';
-import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/toast_util.dart';
 import 'package:photos/utils/toast_util.dart';
 
 
@@ -21,7 +20,9 @@ extension CollectionFileActions on CollectionActions {
     final count = selectedFiles.files.length;
     final count = selectedFiles.files.length;
     final textTheme = getEnteTextTheme(context);
     final textTheme = getEnteTextTheme(context);
     final showDeletePrompt = await _anyItemPresentOnlyInCurrentAlbum(
     final showDeletePrompt = await _anyItemPresentOnlyInCurrentAlbum(
-        selectedFiles.files, collection.id);
+      selectedFiles.files,
+      collection.id,
+    );
     final String title =
     final String title =
         showDeletePrompt ? "Delete items?" : "Remove from album?";
         showDeletePrompt ? "Delete items?" : "Remove from album?";
     final String message1 = showDeletePrompt
     final String message1 = showDeletePrompt

+ 0 - 1
lib/ui/actions/collection/collection_sharing_actions.dart

@@ -11,7 +11,6 @@ import 'package:photos/services/hidden_service.dart';
 import 'package:photos/services/user_service.dart';
 import 'package:photos/services/user_service.dart';
 import 'package:photos/theme/ente_theme.dart';
 import 'package:photos/theme/ente_theme.dart';
 import 'package:photos/ui/common/dialogs.dart';
 import 'package:photos/ui/common/dialogs.dart';
-import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/ui/payment/subscription.dart';
 import 'package:photos/ui/payment/subscription.dart';
 import 'package:photos/utils/date_time_util.dart';
 import 'package:photos/utils/date_time_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/dialog_util.dart';

+ 0 - 1
lib/ui/backup_folder_selection_page.dart

@@ -16,7 +16,6 @@ import 'package:photos/models/device_collection.dart';
 import 'package:photos/models/file.dart';
 import 'package:photos/models/file.dart';
 import 'package:photos/services/remote_sync_service.dart';
 import 'package:photos/services/remote_sync_service.dart';
 import 'package:photos/ui/common/loading_widget.dart';
 import 'package:photos/ui/common/loading_widget.dart';
-import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/ui/viewer/file/thumbnail_widget.dart';
 import 'package:photos/ui/viewer/file/thumbnail_widget.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 
 

+ 3 - 5
lib/ui/collections/archived_collections_button_widget.dart

@@ -1,5 +1,3 @@
-// @dart=2.9
-
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/db/files_db.dart';
 import 'package:photos/db/files_db.dart';
@@ -12,7 +10,7 @@ class ArchivedCollectionsButtonWidget extends StatelessWidget {
 
 
   const ArchivedCollectionsButtonWidget(
   const ArchivedCollectionsButtonWidget(
     this.textStyle, {
     this.textStyle, {
-    Key key,
+    Key? key,
   }) : super(key: key);
   }) : super(key: key);
 
 
   @override
   @override
@@ -26,7 +24,7 @@ class ArchivedCollectionsButtonWidget extends StatelessWidget {
         padding: const EdgeInsets.all(0),
         padding: const EdgeInsets.all(0),
         side: BorderSide(
         side: BorderSide(
           width: 0.5,
           width: 0.5,
-          color: Theme.of(context).iconTheme.color.withOpacity(0.24),
+          color: Theme.of(context).iconTheme.color!.withOpacity(0.24),
         ),
         ),
       ),
       ),
       child: SizedBox(
       child: SizedBox(
@@ -50,7 +48,7 @@ class ArchivedCollectionsButtonWidget extends StatelessWidget {
                       Configuration.instance.getUserID(),
                       Configuration.instance.getUserID(),
                     ),
                     ),
                     builder: (context, snapshot) {
                     builder: (context, snapshot) {
-                      if (snapshot.hasData && snapshot.data > 0) {
+                      if (snapshot.hasData && snapshot.data! > 0) {
                         return RichText(
                         return RichText(
                           text: TextSpan(
                           text: TextSpan(
                             style: textStyle,
                             style: textStyle,

+ 3 - 7
lib/ui/collections/create_new_album_widget.dart

@@ -1,5 +1,3 @@
-// @dart=2.9
-
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:fluttertoast/fluttertoast.dart';
 import 'package:fluttertoast/fluttertoast.dart';
 import 'package:photos/core/event_bus.dart';
 import 'package:photos/core/event_bus.dart';
@@ -7,9 +5,7 @@ import 'package:photos/events/tab_changed_event.dart';
 import 'package:photos/utils/toast_util.dart';
 import 'package:photos/utils/toast_util.dart';
 
 
 class CreateNewAlbumWidget extends StatelessWidget {
 class CreateNewAlbumWidget extends StatelessWidget {
-  const CreateNewAlbumWidget({
-    Key key,
-  }) : super(key: key);
+  const CreateNewAlbumWidget({Key? key}) : super(key: key);
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
@@ -23,14 +19,14 @@ class CreateNewAlbumWidget extends StatelessWidget {
               blurRadius: 2,
               blurRadius: 2,
               spreadRadius: 0,
               spreadRadius: 0,
               offset: const Offset(0, 0),
               offset: const Offset(0, 0),
-              color: Theme.of(context).iconTheme.color.withOpacity(0.3),
+              color: Theme.of(context).iconTheme.color!.withOpacity(0.3),
             )
             )
           ],
           ],
           borderRadius: BorderRadius.circular(4),
           borderRadius: BorderRadius.circular(4),
         ),
         ),
         child: Icon(
         child: Icon(
           Icons.add,
           Icons.add,
-          color: Theme.of(context).iconTheme.color.withOpacity(0.25),
+          color: Theme.of(context).iconTheme.color!.withOpacity(0.25),
         ),
         ),
       ),
       ),
       onTap: () async {
       onTap: () async {

+ 3 - 5
lib/ui/collections/device_folder_icon_widget.dart

@@ -1,5 +1,3 @@
-// @dart=2.9
-
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:photos/ente_theme_data.dart';
 import 'package:photos/ente_theme_data.dart';
 import 'package:photos/models/device_collection.dart';
 import 'package:photos/models/device_collection.dart';
@@ -12,7 +10,7 @@ class DeviceFolderIcon extends StatelessWidget {
   final DeviceCollection deviceCollection;
   final DeviceCollection deviceCollection;
   const DeviceFolderIcon(
   const DeviceFolderIcon(
     this.deviceCollection, {
     this.deviceCollection, {
-    Key key,
+    Key? key,
   }) : super(key: key);
   }) : super(key: key);
 
 
   @override
   @override
@@ -35,7 +33,7 @@ class DeviceFolderIcon extends StatelessWidget {
                   child: Hero(
                   child: Hero(
                     tag: "device_folder:" +
                     tag: "device_folder:" +
                         deviceCollection.name +
                         deviceCollection.name +
-                        deviceCollection.thumbnail.tag,
+                        deviceCollection.thumbnail!.tag,
                     child: Stack(
                     child: Stack(
                       children: [
                       children: [
                         ThumbnailWidget(
                         ThumbnailWidget(
@@ -44,7 +42,7 @@ class DeviceFolderIcon extends StatelessWidget {
                           key: Key(
                           key: Key(
                             "device_folder:" +
                             "device_folder:" +
                                 deviceCollection.name +
                                 deviceCollection.name +
-                                deviceCollection.thumbnail.tag,
+                                deviceCollection.thumbnail!.tag,
                           ),
                           ),
                         ),
                         ),
                         isBackedUp ? Container() : const UnSyncedIcon(),
                         isBackedUp ? Container() : const UnSyncedIcon(),

+ 5 - 7
lib/ui/collections/trash_button_widget.dart

@@ -1,5 +1,3 @@
-// @dart=2.9
-
 import 'dart:async';
 import 'dart:async';
 
 
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
@@ -12,7 +10,7 @@ import 'package:photos/utils/navigation_util.dart';
 class TrashButtonWidget extends StatefulWidget {
 class TrashButtonWidget extends StatefulWidget {
   const TrashButtonWidget(
   const TrashButtonWidget(
     this.textStyle, {
     this.textStyle, {
-    Key key,
+    Key? key,
   }) : super(key: key);
   }) : super(key: key);
 
 
   final TextStyle textStyle;
   final TextStyle textStyle;
@@ -22,7 +20,7 @@ class TrashButtonWidget extends StatefulWidget {
 }
 }
 
 
 class _TrashButtonWidgetState extends State<TrashButtonWidget> {
 class _TrashButtonWidgetState extends State<TrashButtonWidget> {
-  StreamSubscription<TrashUpdatedEvent> _trashUpdatedEventSubscription;
+  late StreamSubscription<TrashUpdatedEvent> _trashUpdatedEventSubscription;
 
 
   @override
   @override
   void initState() {
   void initState() {
@@ -37,7 +35,7 @@ class _TrashButtonWidgetState extends State<TrashButtonWidget> {
 
 
   @override
   @override
   void dispose() {
   void dispose() {
-    _trashUpdatedEventSubscription?.cancel();
+    _trashUpdatedEventSubscription.cancel();
     super.dispose();
     super.dispose();
   }
   }
 
 
@@ -52,7 +50,7 @@ class _TrashButtonWidgetState extends State<TrashButtonWidget> {
         padding: const EdgeInsets.all(0),
         padding: const EdgeInsets.all(0),
         side: BorderSide(
         side: BorderSide(
           width: 0.5,
           width: 0.5,
-          color: Theme.of(context).iconTheme.color.withOpacity(0.24),
+          color: Theme.of(context).iconTheme.color!.withOpacity(0.24),
         ),
         ),
       ),
       ),
       child: SizedBox(
       child: SizedBox(
@@ -73,7 +71,7 @@ class _TrashButtonWidgetState extends State<TrashButtonWidget> {
                   FutureBuilder<int>(
                   FutureBuilder<int>(
                     future: TrashDB.instance.count(),
                     future: TrashDB.instance.count(),
                     builder: (context, snapshot) {
                     builder: (context, snapshot) {
-                      if (snapshot.hasData && snapshot.data > 0) {
+                      if (snapshot.hasData && snapshot.data! > 0) {
                         return RichText(
                         return RichText(
                           text: TextSpan(
                           text: TextSpan(
                             style: widget.textStyle,
                             style: widget.textStyle,

+ 5 - 29
lib/ui/components/action_sheet_widget.dart

@@ -14,37 +14,13 @@ enum ActionSheetType {
   iconOnly,
   iconOnly,
 }
 }
 
 
-Future<ButtonAction?> showCommonActionSheet({
-  required BuildContext context,
-  required List<ButtonWidget> buttons,
-  required ActionSheetType actionSheetType,
-  bool isCheckIconGreen = false,
-  String? title,
-  String? body,
-}) {
-  return showMaterialModalBottomSheet(
-    backgroundColor: Colors.transparent,
-    barrierColor: backdropFaintDark,
-    useRootNavigator: true,
-    context: context,
-    builder: (_) {
-      return ActionSheetWidget(
-        title: title,
-        body: body,
-        actionButtons: buttons,
-        actionSheetType: actionSheetType,
-        isCheckIconGreen: isCheckIconGreen,
-      );
-    },
-    isDismissible: false,
-    enableDrag: false,
-  );
-}
-
+///Returns null if dismissed
 Future<ButtonAction?> showActionSheet({
 Future<ButtonAction?> showActionSheet({
   required BuildContext context,
   required BuildContext context,
   required List<ButtonWidget> buttons,
   required List<ButtonWidget> buttons,
   required ActionSheetType actionSheetType,
   required ActionSheetType actionSheetType,
+  bool enableDrag = true,
+  bool isDismissible = true,
   bool isCheckIconGreen = false,
   bool isCheckIconGreen = false,
   String? title,
   String? title,
   String? body,
   String? body,
@@ -54,6 +30,8 @@ Future<ButtonAction?> showActionSheet({
     barrierColor: backdropFaintDark,
     barrierColor: backdropFaintDark,
     useRootNavigator: true,
     useRootNavigator: true,
     context: context,
     context: context,
+    isDismissible: isDismissible,
+    enableDrag: enableDrag,
     builder: (_) {
     builder: (_) {
       return ActionSheetWidget(
       return ActionSheetWidget(
         title: title,
         title: title,
@@ -63,8 +41,6 @@ Future<ButtonAction?> showActionSheet({
         isCheckIconGreen: isCheckIconGreen,
         isCheckIconGreen: isCheckIconGreen,
       );
       );
     },
     },
-    isDismissible: false,
-    enableDrag: false,
   );
   );
 }
 }
 
 

+ 4 - 63
lib/ui/components/dialog_widget.dart

@@ -6,76 +6,19 @@ import 'package:photos/theme/colors.dart';
 import 'package:photos/theme/effects.dart';
 import 'package:photos/theme/effects.dart';
 import 'package:photos/theme/ente_theme.dart';
 import 'package:photos/theme/ente_theme.dart';
 import 'package:photos/ui/components/button_widget.dart';
 import 'package:photos/ui/components/button_widget.dart';
-import 'package:photos/ui/components/models/button_type.dart';
 import 'package:photos/utils/separators_util.dart';
 import 'package:photos/utils/separators_util.dart';
 
 
-Future<ButtonAction?> showGenericErrorDialog({
-  required BuildContext context,
-}) async {
-  return showDialogWidget(
-    context: context,
-    title: "Error",
-    icon: Icons.error_outline_outlined,
-    body: "It looks like something went wrong. Please try again.",
-    buttons: const [
-      ButtonWidget(
-        buttonType: ButtonType.secondary,
-        labelText: "OK",
-        isInAlert: true,
-      ),
-    ],
-  );
-}
-
-Future<ButtonAction?> showNewChoiceDialog({
-  required BuildContext context,
-  required String title,
-  String? body,
-  required String firstButtonLabel,
-  String secondButtonLabel = "Cancel",
-  ButtonType firstButtonType = ButtonType.neutral,
-  ButtonType secondButtonType = ButtonType.secondary,
-  ButtonAction firstButtonAction = ButtonAction.first,
-  ButtonAction secondButtonAction = ButtonAction.cancel,
-  FutureVoidCallback? firstButtonOnTap,
-  FutureVoidCallback? secondButtonOnTap,
-  bool isCritical = false,
-  IconData? icon,
-}) async {
-  final buttons = [
-    ButtonWidget(
-      buttonType: isCritical ? ButtonType.critical : firstButtonType,
-      labelText: firstButtonLabel,
-      isInAlert: true,
-      onTap: firstButtonOnTap,
-      buttonAction: firstButtonAction,
-    ),
-    ButtonWidget(
-      buttonType: secondButtonType,
-      labelText: secondButtonLabel,
-      isInAlert: true,
-      onTap: secondButtonOnTap,
-      buttonAction: secondButtonAction,
-    ),
-  ];
-  return showDialogWidget(
-    context: context,
-    title: title,
-    body: body,
-    buttons: buttons,
-    icon: icon,
-  );
-}
-
+///Will return null if dismissed by tapping outside
 Future<ButtonAction?> showDialogWidget({
 Future<ButtonAction?> showDialogWidget({
   required BuildContext context,
   required BuildContext context,
   required String title,
   required String title,
   String? body,
   String? body,
   required List<ButtonWidget> buttons,
   required List<ButtonWidget> buttons,
   IconData? icon,
   IconData? icon,
+  bool isDismissible = true,
 }) {
 }) {
   return showDialog(
   return showDialog(
-    barrierDismissible: false,
+    barrierDismissible: isDismissible,
     barrierColor: backdropFaintDark,
     barrierColor: backdropFaintDark,
     context: context,
     context: context,
     builder: (context) {
     builder: (context) {
@@ -89,7 +32,6 @@ Future<ButtonAction?> showDialogWidget({
             title: title,
             title: title,
             body: body,
             body: body,
             buttons: buttons,
             buttons: buttons,
-            isMobileSmall: isMobileSmall,
             icon: icon,
             icon: icon,
           ),
           ),
         ),
         ),
@@ -103,12 +45,10 @@ class DialogWidget extends StatelessWidget {
   final String? body;
   final String? body;
   final List<ButtonWidget> buttons;
   final List<ButtonWidget> buttons;
   final IconData? icon;
   final IconData? icon;
-  final bool isMobileSmall;
   const DialogWidget({
   const DialogWidget({
     required this.title,
     required this.title,
     this.body,
     this.body,
     required this.buttons,
     required this.buttons,
-    required this.isMobileSmall,
     this.icon,
     this.icon,
     super.key,
     super.key,
   });
   });
@@ -116,6 +56,7 @@ class DialogWidget extends StatelessWidget {
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
     final widthOfScreen = MediaQuery.of(context).size.width;
     final widthOfScreen = MediaQuery.of(context).size.width;
+    final isMobileSmall = widthOfScreen <= mobileSmallThreshold;
     final colorScheme = getEnteColorScheme(context);
     final colorScheme = getEnteColorScheme(context);
     return Container(
     return Container(
       width: min(widthOfScreen, 320),
       width: min(widthOfScreen, 320),

+ 0 - 1
lib/ui/create_collection_page.dart

@@ -14,7 +14,6 @@ import 'package:photos/services/ignored_files_service.dart';
 import 'package:photos/services/remote_sync_service.dart';
 import 'package:photos/services/remote_sync_service.dart';
 import 'package:photos/ui/common/gradient_button.dart';
 import 'package:photos/ui/common/gradient_button.dart';
 import 'package:photos/ui/common/loading_widget.dart';
 import 'package:photos/ui/common/loading_widget.dart';
-import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/ui/viewer/file/no_thumbnail_widget.dart';
 import 'package:photos/ui/viewer/file/no_thumbnail_widget.dart';
 import 'package:photos/ui/viewer/file/thumbnail_widget.dart';
 import 'package:photos/ui/viewer/file/thumbnail_widget.dart';
 import 'package:photos/ui/viewer/gallery/collection_page.dart';
 import 'package:photos/ui/viewer/gallery/collection_page.dart';

+ 4 - 6
lib/ui/home/grant_permissions_widget.dart

@@ -1,5 +1,3 @@
-// @dart=2.9
-
 import 'dart:io';
 import 'dart:io';
 
 
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
@@ -7,7 +5,7 @@ import 'package:photo_manager/photo_manager.dart';
 import 'package:photos/services/sync_service.dart';
 import 'package:photos/services/sync_service.dart';
 
 
 class GrantPermissionsWidget extends StatelessWidget {
 class GrantPermissionsWidget extends StatelessWidget {
-  const GrantPermissionsWidget({Key key}) : super(key: key);
+  const GrantPermissionsWidget({Key? key}) : super(key: key);
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
     final isLightMode =
     final isLightMode =
@@ -55,7 +53,7 @@ class GrantPermissionsWidget extends StatelessWidget {
                   text: TextSpan(
                   text: TextSpan(
                     style: Theme.of(context)
                     style: Theme.of(context)
                         .textTheme
                         .textTheme
-                        .headline5
+                        .headline5!
                         .copyWith(fontWeight: FontWeight.w700),
                         .copyWith(fontWeight: FontWeight.w700),
                     children: [
                     children: [
                       const TextSpan(text: 'ente '),
                       const TextSpan(text: 'ente '),
@@ -63,7 +61,7 @@ class GrantPermissionsWidget extends StatelessWidget {
                         text: "needs permission to ",
                         text: "needs permission to ",
                         style: Theme.of(context)
                         style: Theme.of(context)
                             .textTheme
                             .textTheme
-                            .headline5
+                            .headline5!
                             .copyWith(fontWeight: FontWeight.w400),
                             .copyWith(fontWeight: FontWeight.w400),
                       ),
                       ),
                       const TextSpan(text: 'preserve your photos'),
                       const TextSpan(text: 'preserve your photos'),
@@ -109,7 +107,7 @@ class GrantPermissionsWidget extends StatelessWidget {
                   TextButton(
                   TextButton(
                     child: Text(
                     child: Text(
                       "OK",
                       "OK",
-                      style: Theme.of(context).textTheme.subtitle1.copyWith(
+                      style: Theme.of(context).textTheme.subtitle1!.copyWith(
                             fontSize: 14,
                             fontSize: 14,
                             fontWeight: FontWeight.w700,
                             fontWeight: FontWeight.w700,
                           ),
                           ),

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

@@ -1,12 +1,10 @@
-// @dart=2.9
-
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 
 
 class PlaceHolderWidget extends StatelessWidget {
 class PlaceHolderWidget extends StatelessWidget {
   const PlaceHolderWidget(
   const PlaceHolderWidget(
     this.count,
     this.count,
     this.columns, {
     this.columns, {
-    Key key,
+    Key? key,
   }) : super(key: key);
   }) : super(key: key);
 
 
   final int count, columns;
   final int count, columns;
@@ -33,7 +31,7 @@ class PlaceHolderWidget extends StatelessWidget {
         ),
         ),
       );
       );
     }
     }
-    return _gridViewCache[key];
+    return _gridViewCache[key]!;
   }
   }
 
 
   String _getCacheKey(int totalCount, int columns) {
   String _getCacheKey(int totalCount, int columns) {

+ 0 - 1
lib/ui/notification/prompts/password_reminder.dart

@@ -11,7 +11,6 @@ import 'package:photos/theme/colors.dart';
 import 'package:photos/theme/ente_theme.dart';
 import 'package:photos/theme/ente_theme.dart';
 import 'package:photos/ui/account/password_entry_page.dart';
 import 'package:photos/ui/account/password_entry_page.dart';
 import 'package:photos/ui/common/gradient_button.dart';
 import 'package:photos/ui/common/gradient_button.dart';
-import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/ui/home_widget.dart';
 import 'package:photos/ui/home_widget.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/navigation_util.dart';
 import 'package:photos/utils/navigation_util.dart';

+ 4 - 7
lib/ui/payment/child_subscription_widget.dart

@@ -1,24 +1,21 @@
-// @dart=2.9
-
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:photos/ente_theme_data.dart';
 import 'package:photos/ente_theme_data.dart';
 import 'package:photos/models/user_details.dart';
 import 'package:photos/models/user_details.dart';
 import 'package:photos/services/user_service.dart';
 import 'package:photos/services/user_service.dart';
 import 'package:photos/ui/common/dialogs.dart';
 import 'package:photos/ui/common/dialogs.dart';
-import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 
 
 class ChildSubscriptionWidget extends StatelessWidget {
 class ChildSubscriptionWidget extends StatelessWidget {
   const ChildSubscriptionWidget({
   const ChildSubscriptionWidget({
-    Key key,
-    @required this.userDetails,
+    Key? key,
+    required this.userDetails,
   }) : super(key: key);
   }) : super(key: key);
 
 
   final UserDetails userDetails;
   final UserDetails userDetails;
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
-    final String familyAdmin = userDetails.familyData.members
+    final String familyAdmin = userDetails.familyData!.members!
         .firstWhere((element) => element.isAdmin)
         .firstWhere((element) => element.isAdmin)
         .email;
         .email;
     return Padding(
     return Padding(
@@ -102,7 +99,7 @@ class ChildSubscriptionWidget extends StatelessWidget {
                     ),
                     ),
                     TextSpan(
                     TextSpan(
                       text: "support@ente.io",
                       text: "support@ente.io",
-                      style: Theme.of(context).textTheme.bodyText2.copyWith(
+                      style: Theme.of(context).textTheme.bodyText2?.copyWith(
                             color: const Color.fromRGBO(29, 185, 84, 1),
                             color: const Color.fromRGBO(29, 185, 84, 1),
                           ),
                           ),
                     ),
                     ),

+ 0 - 1
lib/ui/payment/payment_web_page.dart

@@ -12,7 +12,6 @@ import 'package:photos/services/billing_service.dart';
 import 'package:photos/services/user_service.dart';
 import 'package:photos/services/user_service.dart';
 import 'package:photos/ui/common/loading_widget.dart';
 import 'package:photos/ui/common/loading_widget.dart';
 import 'package:photos/ui/common/progress_dialog.dart';
 import 'package:photos/ui/common/progress_dialog.dart';
-import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 
 
 class PaymentWebPage extends StatefulWidget {
 class PaymentWebPage extends StatefulWidget {

+ 4 - 6
lib/ui/payment/skip_subscription_widget.dart

@@ -1,5 +1,3 @@
-// @dart=2.9
-
 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/events/subscription_purchased_event.dart';
 import 'package:photos/events/subscription_purchased_event.dart';
@@ -10,8 +8,8 @@ import 'package:photos/ui/home_widget.dart';
 
 
 class SkipSubscriptionWidget extends StatelessWidget {
 class SkipSubscriptionWidget extends StatelessWidget {
   const SkipSubscriptionWidget({
   const SkipSubscriptionWidget({
-    Key key,
-    @required this.freePlan,
+    Key? key,
+    required this.freePlan,
   }) : super(key: key);
   }) : super(key: key);
 
 
   final FreePlan freePlan;
   final FreePlan freePlan;
@@ -24,10 +22,10 @@ class SkipSubscriptionWidget extends StatelessWidget {
       margin: const EdgeInsets.fromLTRB(0, 30, 0, 0),
       margin: const EdgeInsets.fromLTRB(0, 30, 0, 0),
       padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
       padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
       child: OutlinedButton(
       child: OutlinedButton(
-        style: Theme.of(context).outlinedButtonTheme.style.copyWith(
+        style: Theme.of(context).outlinedButtonTheme.style?.copyWith(
           textStyle: MaterialStateProperty.resolveWith<TextStyle>(
           textStyle: MaterialStateProperty.resolveWith<TextStyle>(
             (Set<MaterialState> states) {
             (Set<MaterialState> states) {
-              return Theme.of(context).textTheme.subtitle1;
+              return Theme.of(context).textTheme.subtitle1!;
             },
             },
           ),
           ),
         ),
         ),

+ 0 - 1
lib/ui/payment/stripe_subscription_page.dart

@@ -15,7 +15,6 @@ import 'package:photos/ui/common/dialogs.dart';
 import 'package:photos/ui/common/loading_widget.dart';
 import 'package:photos/ui/common/loading_widget.dart';
 import 'package:photos/ui/common/progress_dialog.dart';
 import 'package:photos/ui/common/progress_dialog.dart';
 import 'package:photos/ui/common/web_page.dart';
 import 'package:photos/ui/common/web_page.dart';
-import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/ui/payment/child_subscription_widget.dart';
 import 'package:photos/ui/payment/child_subscription_widget.dart';
 import 'package:photos/ui/payment/payment_web_page.dart';
 import 'package:photos/ui/payment/payment_web_page.dart';
 import 'package:photos/ui/payment/skip_subscription_widget.dart';
 import 'package:photos/ui/payment/skip_subscription_widget.dart';

+ 1 - 3
lib/ui/payment/subscription.dart

@@ -1,5 +1,3 @@
-// @dart=2.9
-
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/services/feature_flag_service.dart';
 import 'package:photos/services/feature_flag_service.dart';
@@ -24,5 +22,5 @@ StatefulWidget getSubscriptionPage({bool isOnBoarding = false}) {
 // users who might have paid via playStore. This method should be removed once
 // users who might have paid via playStore. This method should be removed once
 // we have better handling for active play/app store subscription & stripe plans.
 // we have better handling for active play/app store subscription & stripe plans.
 bool _isUserCreatedPostStripeSupport() {
 bool _isUserCreatedPostStripeSupport() {
-  return Configuration.instance.getUserID() > 1580559962386460;
+  return Configuration.instance.getUserID()! > 1580559962386460;
 }
 }

+ 0 - 1
lib/ui/payment/subscription_page.dart

@@ -16,7 +16,6 @@ import 'package:photos/services/billing_service.dart';
 import 'package:photos/services/user_service.dart';
 import 'package:photos/services/user_service.dart';
 import 'package:photos/ui/common/loading_widget.dart';
 import 'package:photos/ui/common/loading_widget.dart';
 import 'package:photos/ui/common/progress_dialog.dart';
 import 'package:photos/ui/common/progress_dialog.dart';
-import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/ui/payment/child_subscription_widget.dart';
 import 'package:photos/ui/payment/child_subscription_widget.dart';
 import 'package:photos/ui/payment/skip_subscription_widget.dart';
 import 'package:photos/ui/payment/skip_subscription_widget.dart';
 import 'package:photos/ui/payment/subscription_common_widgets.dart';
 import 'package:photos/ui/payment/subscription_common_widgets.dart';

+ 5 - 7
lib/ui/settings/about_section_widget.dart

@@ -1,5 +1,3 @@
-// @dart=2.9
-
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:photos/services/update_service.dart';
 import 'package:photos/services/update_service.dart';
 import 'package:photos/theme/ente_theme.dart';
 import 'package:photos/theme/ente_theme.dart';
@@ -14,7 +12,7 @@ import 'package:photos/utils/toast_util.dart';
 import 'package:url_launcher/url_launcher.dart';
 import 'package:url_launcher/url_launcher.dart';
 
 
 class AboutSectionWidget extends StatelessWidget {
 class AboutSectionWidget extends StatelessWidget {
-  const AboutSectionWidget({Key key}) : super(key: key);
+  const AboutSectionWidget({Key? key}) : super(key: key);
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
@@ -96,12 +94,12 @@ class AboutSectionWidget extends StatelessWidget {
 class AboutMenuItemWidget extends StatelessWidget {
 class AboutMenuItemWidget extends StatelessWidget {
   final String title;
   final String title;
   final String url;
   final String url;
-  final String webPageTitle;
+  final String? webPageTitle;
   const AboutMenuItemWidget({
   const AboutMenuItemWidget({
-    @required this.title,
-    @required this.url,
+    required this.title,
+    required this.url,
     this.webPageTitle,
     this.webPageTitle,
-    Key key,
+    Key? key,
   }) : super(key: key);
   }) : super(key: key);
 
 
   @override
   @override

+ 2 - 4
lib/ui/settings/account_section_widget.dart

@@ -1,5 +1,3 @@
-// @dart=2.9
-
 import 'dart:async';
 import 'dart:async';
 
 
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
@@ -13,14 +11,14 @@ import 'package:photos/ui/account/delete_account_page.dart';
 import 'package:photos/ui/account/password_entry_page.dart';
 import 'package:photos/ui/account/password_entry_page.dart';
 import 'package:photos/ui/account/recovery_key_page.dart';
 import 'package:photos/ui/account/recovery_key_page.dart';
 import 'package:photos/ui/components/captioned_text_widget.dart';
 import 'package:photos/ui/components/captioned_text_widget.dart';
-import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/ui/components/expandable_menu_item_widget.dart';
 import 'package:photos/ui/components/expandable_menu_item_widget.dart';
 import 'package:photos/ui/components/menu_item_widget.dart';
 import 'package:photos/ui/components/menu_item_widget.dart';
 import 'package:photos/ui/settings/common_settings.dart';
 import 'package:photos/ui/settings/common_settings.dart';
+import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/navigation_util.dart';
 import 'package:photos/utils/navigation_util.dart';
 
 
 class AccountSectionWidget extends StatelessWidget {
 class AccountSectionWidget extends StatelessWidget {
-  const AccountSectionWidget({Key key}) : super(key: key);
+  const AccountSectionWidget({Key? key}) : super(key: key);
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {

+ 4 - 6
lib/ui/settings/app_version_widget.dart

@@ -1,11 +1,9 @@
-// @dart=2.9
-
 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';
 
 
 class AppVersionWidget extends StatefulWidget {
 class AppVersionWidget extends StatefulWidget {
   const AppVersionWidget({
   const AppVersionWidget({
-    Key key,
+    Key? key,
   }) : super(key: key);
   }) : super(key: key);
 
 
   @override
   @override
@@ -16,7 +14,7 @@ class _AppVersionWidgetState extends State<AppVersionWidget> {
   static const kTapThresholdForInspector = 5;
   static const kTapThresholdForInspector = 5;
   static const kConsecutiveTapTimeWindowInMilliseconds = 2000;
   static const kConsecutiveTapTimeWindowInMilliseconds = 2000;
 
 
-  int _lastTap;
+  int? _lastTap;
   int _consecutiveTaps = 0;
   int _consecutiveTaps = 0;
 
 
   @override
   @override
@@ -35,14 +33,14 @@ class _AppVersionWidgetState extends State<AppVersionWidget> {
         }
         }
         _lastTap = now;
         _lastTap = now;
       },
       },
-      child: FutureBuilder(
+      child: FutureBuilder<String>(
         future: _getAppVersion(),
         future: _getAppVersion(),
         builder: (context, snapshot) {
         builder: (context, snapshot) {
           if (snapshot.hasData) {
           if (snapshot.hasData) {
             return Padding(
             return Padding(
               padding: const EdgeInsets.all(20),
               padding: const EdgeInsets.all(20),
               child: Text(
               child: Text(
-                "Version: " + snapshot.data,
+                "Version: " + snapshot.data!,
                 style: Theme.of(context).textTheme.caption,
                 style: Theme.of(context).textTheme.caption,
               ),
               ),
             );
             );

+ 46 - 76
lib/ui/settings/backup_section_widget.dart

@@ -3,7 +3,6 @@
 import 'dart:io';
 import 'dart:io';
 
 
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
-import 'package:photos/ente_theme_data.dart';
 import 'package:photos/models/backup_status.dart';
 import 'package:photos/models/backup_status.dart';
 import 'package:photos/models/duplicate_files.dart';
 import 'package:photos/models/duplicate_files.dart';
 import 'package:photos/services/deduplication_service.dart';
 import 'package:photos/services/deduplication_service.dart';
@@ -16,6 +15,7 @@ import 'package:photos/ui/components/captioned_text_widget.dart';
 import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/ui/components/expandable_menu_item_widget.dart';
 import 'package:photos/ui/components/expandable_menu_item_widget.dart';
 import 'package:photos/ui/components/menu_item_widget.dart';
 import 'package:photos/ui/components/menu_item_widget.dart';
+import 'package:photos/ui/components/models/button_type.dart';
 import 'package:photos/ui/settings/common_settings.dart';
 import 'package:photos/ui/settings/common_settings.dart';
 import 'package:photos/ui/tools/deduplicate_page.dart';
 import 'package:photos/ui/tools/deduplicate_page.dart';
 import 'package:photos/ui/tools/free_space_page.dart';
 import 'package:photos/ui/tools/free_space_page.dart';
@@ -162,45 +162,30 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
   }
   }
 
 
   void _showSpaceFreedDialog(BackupStatus status) {
   void _showSpaceFreedDialog(BackupStatus status) {
-    final AlertDialog alert = AlertDialog(
-      title: const Text("Success"),
-      content: Text(
-        "You have successfully freed up " + formatBytes(status.size) + "!",
-      ),
-      actions: [
-        TextButton(
-          child: Text(
-            "Rate us",
-            style: TextStyle(
-              color: Theme.of(context).colorScheme.greenAlternative,
-            ),
-          ),
-          onPressed: () {
-            Navigator.of(context, rootNavigator: true).pop('dialog');
-            final url = UpdateService.instance.getRateDetails().item2;
-            launchUrlString(url);
-          },
-        ),
-        TextButton(
-          child: const Text(
-            "Ok",
-          ),
-          onPressed: () {
-            if (Platform.isIOS) {
-              showToast(
-                context,
-                "Also empty \"Recently Deleted\" from \"Settings\" -> \"Storage\" to claim the freed space",
-              );
-            }
-            Navigator.of(context, rootNavigator: true).pop('dialog');
-          },
-        ),
-      ],
+    final DialogWidget dialog = choiceDialog(
+      title: "Success",
+      body: "You have successfully freed up " + formatBytes(status.size) + "!",
+      firstButtonLabel: "Rate us",
+      firstButtonOnTap: () async {
+        final url = UpdateService.instance.getRateDetails().item2;
+        launchUrlString(url);
+      },
+      firstButtonType: ButtonType.primary,
+      secondButtonLabel: "OK",
+      secondButtonOnTap: () async {
+        if (Platform.isIOS) {
+          showToast(
+            context,
+            "Also empty \"Recently Deleted\" from \"Settings\" -> \"Storage\" to claim the freed space",
+          );
+        }
+      },
     );
     );
+
     showConfettiDialog(
     showConfettiDialog(
       context: context,
       context: context,
-      builder: (BuildContext context) {
-        return alert;
+      dialogBuilder: (BuildContext context) {
+        return dialog;
       },
       },
       barrierColor: Colors.black87,
       barrierColor: Colors.black87,
       confettiAlignment: Alignment.topCenter,
       confettiAlignment: Alignment.topCenter,
@@ -212,48 +197,33 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
     final String countText = result.count.toString() +
     final String countText = result.count.toString() +
         " duplicate file" +
         " duplicate file" +
         (result.count == 1 ? "" : "s");
         (result.count == 1 ? "" : "s");
-    final AlertDialog alert = AlertDialog(
-      title: const Text("✨ Success"),
-      content: Text(
-        "You have cleaned up " +
-            countText +
-            ", saving " +
-            formatBytes(result.size) +
-            "!",
-      ),
-      actions: [
-        TextButton(
-          child: Text(
-            "Rate us",
-            style: TextStyle(
-              color: Theme.of(context).colorScheme.greenAlternative,
-            ),
-          ),
-          onPressed: () {
-            Navigator.of(context, rootNavigator: true).pop('dialog');
-            // TODO: Replace with https://pub.dev/packages/in_app_review
-            final url = UpdateService.instance.getRateDetails().item2;
-            launchUrlString(url);
-          },
-        ),
-        TextButton(
-          child: const Text(
-            "Ok",
-          ),
-          onPressed: () {
-            showShortToast(
-              context,
-              "Also empty your \"Trash\" to claim the freed up space",
-            );
-            Navigator.of(context, rootNavigator: true).pop('dialog');
-          },
-        ),
-      ],
+    final DialogWidget dialog = choiceDialog(
+      title: "✨ Success",
+      body: "You have cleaned up " +
+          countText +
+          ", saving " +
+          formatBytes(result.size) +
+          "!",
+      firstButtonLabel: "Rate us",
+      firstButtonOnTap: () async {
+        // TODO: Replace with https://pub.dev/packages/in_app_review
+        final url = UpdateService.instance.getRateDetails().item2;
+        launchUrlString(url);
+      },
+      firstButtonType: ButtonType.primary,
+      secondButtonLabel: "OK",
+      secondButtonOnTap: () async {
+        showShortToast(
+          context,
+          "Also empty your \"Trash\" to claim the freed up space",
+        );
+      },
     );
     );
+
     showConfettiDialog(
     showConfettiDialog(
       context: context,
       context: context,
-      builder: (BuildContext context) {
-        return alert;
+      dialogBuilder: (BuildContext context) {
+        return dialog;
       },
       },
       barrierColor: Colors.black87,
       barrierColor: Colors.black87,
       confettiAlignment: Alignment.topCenter,
       confettiAlignment: Alignment.topCenter,

+ 3 - 5
lib/ui/settings/debug_section_widget.dart

@@ -1,5 +1,3 @@
-// @dart=2.9
-
 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';
@@ -15,7 +13,7 @@ import 'package:photos/ui/settings/common_settings.dart';
 import 'package:photos/utils/toast_util.dart';
 import 'package:photos/utils/toast_util.dart';
 
 
 class DebugSectionWidget extends StatelessWidget {
 class DebugSectionWidget extends StatelessWidget {
-  const DebugSectionWidget({Key key}) : super(key: key);
+  const DebugSectionWidget({Key? key}) : super(key: key);
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
@@ -75,7 +73,7 @@ class DebugSectionWidget extends StatelessWidget {
   }
   }
 
 
   void _showKeyAttributesDialog(BuildContext context) {
   void _showKeyAttributesDialog(BuildContext context) {
-    final keyAttributes = Configuration.instance.getKeyAttributes();
+    final keyAttributes = Configuration.instance.getKeyAttributes()!;
     final AlertDialog alert = AlertDialog(
     final AlertDialog alert = AlertDialog(
       title: const Text("key attributes"),
       title: const Text("key attributes"),
       content: SingleChildScrollView(
       content: SingleChildScrollView(
@@ -85,7 +83,7 @@ class DebugSectionWidget extends StatelessWidget {
               "Key",
               "Key",
               style: TextStyle(fontWeight: FontWeight.bold),
               style: TextStyle(fontWeight: FontWeight.bold),
             ),
             ),
-            Text(Sodium.bin2base64(Configuration.instance.getKey())),
+            Text(Sodium.bin2base64(Configuration.instance.getKey()!)),
             const Padding(padding: EdgeInsets.all(12)),
             const Padding(padding: EdgeInsets.all(12)),
             const Text(
             const Text(
               "Encrypted Key",
               "Encrypted Key",

+ 1 - 3
lib/ui/settings/general_section_widget.dart

@@ -1,5 +1,3 @@
-// @dart=2.9
-
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:photos/services/billing_service.dart';
 import 'package:photos/services/billing_service.dart';
 import 'package:photos/services/user_service.dart';
 import 'package:photos/services/user_service.dart';
@@ -14,7 +12,7 @@ import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/navigation_util.dart';
 import 'package:photos/utils/navigation_util.dart';
 
 
 class GeneralSectionWidget extends StatelessWidget {
 class GeneralSectionWidget extends StatelessWidget {
-  const GeneralSectionWidget({Key key}) : super(key: key);
+  const GeneralSectionWidget({Key? key}) : super(key: key);
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {

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

@@ -1,5 +1,3 @@
-// @dart=2.9
-
 import 'dart:async';
 import 'dart:async';
 import 'dart:io';
 import 'dart:io';
 
 
@@ -20,7 +18,7 @@ import 'package:photos/ui/components/toggle_switch_widget.dart';
 import 'package:photos/ui/settings/common_settings.dart';
 import 'package:photos/ui/settings/common_settings.dart';
 
 
 class SecuritySectionWidget extends StatefulWidget {
 class SecuritySectionWidget extends StatefulWidget {
-  const SecuritySectionWidget({Key key}) : super(key: key);
+  const SecuritySectionWidget({Key? key}) : super(key: key);
 
 
   @override
   @override
   State<SecuritySectionWidget> createState() => _SecuritySectionWidgetState();
   State<SecuritySectionWidget> createState() => _SecuritySectionWidgetState();
@@ -29,7 +27,8 @@ class SecuritySectionWidget extends StatefulWidget {
 class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
 class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
   final _config = Configuration.instance;
   final _config = Configuration.instance;
 
 
-  StreamSubscription<TwoFactorStatusChangeEvent> _twoFactorStatusChangeEvent;
+  late StreamSubscription<TwoFactorStatusChangeEvent>
+      _twoFactorStatusChangeEvent;
 
 
   @override
   @override
   void initState() {
   void initState() {

+ 0 - 35
lib/ui/settings/settings_text_item.dart

@@ -1,35 +0,0 @@
-// @dart=2.9
-
-import 'dart:io';
-
-import 'package:flutter/material.dart';
-
-class SettingsTextItem extends StatelessWidget {
-  final String text;
-  final IconData icon;
-  const SettingsTextItem({
-    Key key,
-    @required this.text,
-    @required this.icon,
-  }) : super(key: key);
-
-  @override
-  Widget build(BuildContext context) {
-    return Column(
-      children: [
-        Padding(padding: EdgeInsets.all(Platform.isIOS ? 4 : 6)),
-        Row(
-          mainAxisAlignment: MainAxisAlignment.spaceBetween,
-          children: [
-            Align(
-              alignment: Alignment.centerLeft,
-              child: Text(text, style: Theme.of(context).textTheme.subtitle1),
-            ),
-            Icon(icon),
-          ],
-        ),
-        Padding(padding: EdgeInsets.all(Platform.isIOS ? 4 : 6)),
-      ],
-    );
-  }
-}

+ 2 - 4
lib/ui/settings/social_section_widget.dart

@@ -1,5 +1,3 @@
-// @dart=2.9
-
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:photos/services/update_service.dart';
 import 'package:photos/services/update_service.dart';
 import 'package:photos/theme/ente_theme.dart';
 import 'package:photos/theme/ente_theme.dart';
@@ -10,7 +8,7 @@ import 'package:photos/ui/settings/common_settings.dart';
 import 'package:url_launcher/url_launcher_string.dart';
 import 'package:url_launcher/url_launcher_string.dart';
 
 
 class SocialSectionWidget extends StatelessWidget {
 class SocialSectionWidget extends StatelessWidget {
-  const SocialSectionWidget({Key key}) : super(key: key);
+  const SocialSectionWidget({Key? key}) : super(key: key);
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
@@ -60,7 +58,7 @@ class SocialSectionWidget extends StatelessWidget {
 class SocialsMenuItemWidget extends StatelessWidget {
 class SocialsMenuItemWidget extends StatelessWidget {
   final String text;
   final String text;
   final String urlSring;
   final String urlSring;
-  const SocialsMenuItemWidget(this.text, this.urlSring, {Key key})
+  const SocialsMenuItemWidget(this.text, this.urlSring, {Key? key})
       : super(key: key);
       : super(key: key);
 
 
   @override
   @override

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

@@ -1,5 +1,3 @@
-// @dart=2.9
-
 import 'dart:io';
 import 'dart:io';
 
 
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
@@ -15,7 +13,7 @@ import 'package:photos/ui/settings/common_settings.dart';
 import 'package:photos/utils/email_util.dart';
 import 'package:photos/utils/email_util.dart';
 
 
 class SupportSectionWidget extends StatelessWidget {
 class SupportSectionWidget extends StatelessWidget {
-  const SupportSectionWidget({Key key}) : super(key: key);
+  const SupportSectionWidget({Key? key}) : super(key: key);
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
@@ -63,7 +61,9 @@ class SupportSectionWidget extends StatelessWidget {
                   final endpoint = Configuration.instance.getHttpEndpoint() +
                   final endpoint = Configuration.instance.getHttpEndpoint() +
                       "/users/roadmap";
                       "/users/roadmap";
                   final url = Configuration.instance.isLoggedIn()
                   final url = Configuration.instance.isLoggedIn()
-                      ? endpoint + "?token=" + Configuration.instance.getToken()
+                      ? endpoint +
+                          "?token=" +
+                          Configuration.instance.getToken()!
                       : roadmapURL;
                       : roadmapURL;
                   return WebPage("Suggest features", url);
                   return WebPage("Suggest features", url);
                 },
                 },

+ 0 - 1
lib/ui/sharing/manage_links_widget.dart

@@ -15,7 +15,6 @@ import 'package:photos/theme/ente_theme.dart';
 import 'package:photos/ui/actions/collection/collection_sharing_actions.dart';
 import 'package:photos/ui/actions/collection/collection_sharing_actions.dart';
 import 'package:photos/ui/common/dialogs.dart';
 import 'package:photos/ui/common/dialogs.dart';
 import 'package:photos/ui/components/captioned_text_widget.dart';
 import 'package:photos/ui/components/captioned_text_widget.dart';
-import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/ui/components/divider_widget.dart';
 import 'package:photos/ui/components/divider_widget.dart';
 import 'package:photos/ui/components/menu_item_widget.dart';
 import 'package:photos/ui/components/menu_item_widget.dart';
 import 'package:photos/ui/components/menu_section_description_widget.dart';
 import 'package:photos/ui/components/menu_section_description_widget.dart';

+ 9 - 11
lib/ui/sharing/share_collection_page.dart

@@ -1,5 +1,3 @@
-// @dart=2.9
-
 import 'package:collection/collection.dart';
 import 'package:collection/collection.dart';
 import 'package:fast_base58/fast_base58.dart';
 import 'package:fast_base58/fast_base58.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
@@ -25,14 +23,14 @@ import 'package:photos/utils/toast_util.dart';
 class ShareCollectionPage extends StatefulWidget {
 class ShareCollectionPage extends StatefulWidget {
   final Collection collection;
   final Collection collection;
 
 
-  const ShareCollectionPage(this.collection, {Key key}) : super(key: key);
+  const ShareCollectionPage(this.collection, {Key? key}) : super(key: key);
 
 
   @override
   @override
   State<ShareCollectionPage> createState() => _ShareCollectionPageState();
   State<ShareCollectionPage> createState() => _ShareCollectionPageState();
 }
 }
 
 
 class _ShareCollectionPageState extends State<ShareCollectionPage> {
 class _ShareCollectionPageState extends State<ShareCollectionPage> {
-  List<User> _sharees;
+  late List<User?> _sharees;
   final Logger _logger = Logger("SharingDialogState");
   final Logger _logger = Logger("SharingDialogState");
   final CollectionActions collectionActions =
   final CollectionActions collectionActions =
       CollectionActions(CollectionsService.instance);
       CollectionActions(CollectionsService.instance);
@@ -132,7 +130,7 @@ class _ShareCollectionPageState extends State<ShareCollectionPage> {
           CollectionsService.instance.getCollectionKey(widget.collection.id),
           CollectionsService.instance.getCollectionKey(widget.collection.id),
         );
         );
         final String url =
         final String url =
-            "${widget.collection.publicURLs.first.url}#$collectionKey";
+            "${widget.collection.publicURLs!.first!.url}#$collectionKey";
         children.addAll(
         children.addAll(
           [
           [
             MenuItemWidget(
             MenuItemWidget(
@@ -235,8 +233,8 @@ class _ShareCollectionPageState extends State<ShareCollectionPage> {
     return Scaffold(
     return Scaffold(
       appBar: AppBar(
       appBar: AppBar(
         title: Text(
         title: Text(
-          widget.collection.name,
-          style: Theme.of(context).textTheme.headline5.copyWith(fontSize: 16),
+          widget.collection.name ?? "Unnamed",
+          style: Theme.of(context).textTheme.headline5?.copyWith(fontSize: 16),
         ),
         ),
         elevation: 0,
         elevation: 0,
         centerTitle: false,
         centerTitle: false,
@@ -260,12 +258,12 @@ class _ShareCollectionPageState extends State<ShareCollectionPage> {
 
 
 class EmailItemWidget extends StatelessWidget {
 class EmailItemWidget extends StatelessWidget {
   final Collection collection;
   final Collection collection;
-  final Function onTap;
+  final Function? onTap;
 
 
   const EmailItemWidget(
   const EmailItemWidget(
     this.collection, {
     this.collection, {
     this.onTap,
     this.onTap,
-    Key key,
+    Key? key,
   }) : super(key: key);
   }) : super(key: key);
 
 
   @override
   @override
@@ -291,7 +289,7 @@ class EmailItemWidget extends StatelessWidget {
             trailingIcon: Icons.chevron_right,
             trailingIcon: Icons.chevron_right,
             onTap: () async {
             onTap: () async {
               if (onTap != null) {
               if (onTap != null) {
-                onTap();
+                onTap!();
               }
               }
             },
             },
             isBottomBorderRadiusRemoved: true,
             isBottomBorderRadiusRemoved: true,
@@ -317,7 +315,7 @@ class EmailItemWidget extends StatelessWidget {
             trailingIcon: Icons.chevron_right,
             trailingIcon: Icons.chevron_right,
             onTap: () async {
             onTap: () async {
               if (onTap != null) {
               if (onTap != null) {
-                onTap();
+                onTap!();
               }
               }
             },
             },
             isBottomBorderRadiusRemoved: true,
             isBottomBorderRadiusRemoved: true,

+ 2 - 0
lib/ui/tools/debug/app_storage_viewer.dart

@@ -158,6 +158,8 @@ class _AppStorageViewerState extends State<AppStorageViewer> {
                             ),
                             ),
                             menuItemColor:
                             menuItemColor:
                                 getEnteColorScheme(context).fillFaint,
                                 getEnteColorScheme(context).fillFaint,
+                            pressedColor:
+                                getEnteColorScheme(context).fillFaintPressed,
                             borderRadius: 8,
                             borderRadius: 8,
                             onTap: () async {
                             onTap: () async {
                               for (var pathItem in paths) {
                               for (var pathItem in paths) {

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

@@ -25,7 +25,6 @@ import 'package:photos/services/hidden_service.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/ui/common/progress_dialog.dart';
 import 'package:photos/ui/common/progress_dialog.dart';
-import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/ui/create_collection_page.dart';
 import 'package:photos/ui/create_collection_page.dart';
 import 'package:photos/ui/viewer/file/custom_app_bar.dart';
 import 'package:photos/ui/viewer/file/custom_app_bar.dart';
 import 'package:photos/utils/delete_file_util.dart';
 import 'package:photos/utils/delete_file_util.dart';

+ 23 - 37
lib/ui/viewer/gallery/gallery_app_bar_widget.dart

@@ -22,6 +22,7 @@ import 'package:photos/services/update_service.dart';
 import 'package:photos/ui/common/dialogs.dart';
 import 'package:photos/ui/common/dialogs.dart';
 import 'package:photos/ui/common/rename_dialog.dart';
 import 'package:photos/ui/common/rename_dialog.dart';
 import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/ui/components/dialog_widget.dart';
+import 'package:photos/ui/components/models/button_type.dart';
 import 'package:photos/ui/sharing/album_participants_page.dart';
 import 'package:photos/ui/sharing/album_participants_page.dart';
 import 'package:photos/ui/sharing/share_collection_page.dart';
 import 'package:photos/ui/sharing/share_collection_page.dart';
 import 'package:photos/ui/tools/free_space_page.dart';
 import 'package:photos/ui/tools/free_space_page.dart';
@@ -200,46 +201,31 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
   }
   }
 
 
   void _showSpaceFreedDialog(BackupStatus status) {
   void _showSpaceFreedDialog(BackupStatus status) {
-    final AlertDialog alert = AlertDialog(
-      title: const Text("Success"),
-      content: Text(
-        "You have successfully freed up " + formatBytes(status.size) + "!",
-      ),
-      actions: [
-        TextButton(
-          child: Text(
-            "Rate us",
-            style: TextStyle(
-              color: Theme.of(context).colorScheme.greenAlternative,
-            ),
-          ),
-          onPressed: () {
-            Navigator.of(context, rootNavigator: true).pop('dialog');
-            // TODO: Replace with https://pub.dev/packages/in_app_review
-            final url = UpdateService.instance.getRateDetails().item2;
-            launchUrlString(url);
-          },
-        ),
-        TextButton(
-          child: const Text(
-            "Ok",
-          ),
-          onPressed: () {
-            if (Platform.isIOS) {
-              showToast(
-                context,
-                "Also empty \"Recently Deleted\" from \"Settings\" -> \"Storage\" to claim the freed space",
-              );
-            }
-            Navigator.of(context, rootNavigator: true).pop('dialog');
-          },
-        ),
-      ],
+    final DialogWidget dialog = choiceDialog(
+      title: "Success",
+      body: "You have successfully freed up " + formatBytes(status.size) + "!",
+      firstButtonLabel: "Rate us",
+      firstButtonOnTap: () async {
+        // TODO: Replace with https://pub.dev/packages/in_app_review
+        final url = UpdateService.instance.getRateDetails().item2;
+        launchUrlString(url);
+      },
+      firstButtonType: ButtonType.primary,
+      secondButtonLabel: "OK",
+      secondButtonOnTap: () async {
+        if (Platform.isIOS) {
+          showToast(
+            context,
+            "Also empty \"Recently Deleted\" from \"Settings\" -> \"Storage\" to claim the freed space",
+          );
+        }
+      },
     );
     );
+
     showConfettiDialog(
     showConfettiDialog(
       context: context,
       context: context,
-      builder: (BuildContext context) {
-        return alert;
+      dialogBuilder: (BuildContext context) {
+        return dialog;
       },
       },
       barrierColor: Colors.black87,
       barrierColor: Colors.black87,
       confettiAlignment: Alignment.topCenter,
       confettiAlignment: Alignment.topCenter,

+ 0 - 1
lib/ui/viewer/gallery/gallery_overlay_widget.dart

@@ -18,7 +18,6 @@ import 'package:photos/models/magic_metadata.dart';
 import 'package:photos/models/selected_files.dart';
 import 'package:photos/models/selected_files.dart';
 import 'package:photos/services/collections_service.dart';
 import 'package:photos/services/collections_service.dart';
 import 'package:photos/services/hidden_service.dart';
 import 'package:photos/services/hidden_service.dart';
-import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/ui/create_collection_page.dart';
 import 'package:photos/ui/create_collection_page.dart';
 import 'package:photos/utils/delete_file_util.dart';
 import 'package:photos/utils/delete_file_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/dialog_util.dart';

+ 1 - 3
lib/ui/viewer/search/result/no_result_widget.dart

@@ -1,10 +1,8 @@
-// @dart=2.9
-
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:photos/ente_theme_data.dart';
 import 'package:photos/ente_theme_data.dart';
 
 
 class NoResultWidget extends StatelessWidget {
 class NoResultWidget extends StatelessWidget {
-  const NoResultWidget({Key key}) : super(key: key);
+  const NoResultWidget({Key? key}) : super(key: key);
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {

+ 0 - 1
lib/utils/delete_file_util.dart

@@ -24,7 +24,6 @@ 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/ui/common/dialogs.dart';
 import 'package:photos/ui/common/dialogs.dart';
 import 'package:photos/ui/common/linear_progress_dialog.dart';
 import 'package:photos/ui/common/linear_progress_dialog.dart';
-import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/file_util.dart';
 import 'package:photos/utils/file_util.dart';
 import 'package:photos/utils/toast_util.dart';
 import 'package:photos/utils/toast_util.dart';

+ 153 - 61
lib/utils/dialog_util.dart

@@ -1,11 +1,136 @@
-// @dart=2.9
-
 import 'dart:math';
 import 'dart:math';
 
 
 import 'package:confetti/confetti.dart';
 import 'package:confetti/confetti.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
+import 'package:photos/core/constants.dart';
 import 'package:photos/ui/common/loading_widget.dart';
 import 'package:photos/ui/common/loading_widget.dart';
 import 'package:photos/ui/common/progress_dialog.dart';
 import 'package:photos/ui/common/progress_dialog.dart';
+import 'package:photos/ui/components/button_widget.dart';
+import 'package:photos/ui/components/dialog_widget.dart';
+import 'package:photos/ui/components/models/button_type.dart';
+
+typedef DialogBuilder = DialogWidget Function(BuildContext context);
+
+///Will return null if dismissed by tapping outside
+Future<ButtonAction?> showErrorDialog(
+  BuildContext context,
+  String title,
+  String? body, {
+  bool isDismissable = true,
+}) async {
+  return showDialogWidget(
+    context: context,
+    title: title,
+    body: body,
+    isDismissible: isDismissable,
+    buttons: const [
+      ButtonWidget(
+        buttonType: ButtonType.secondary,
+        labelText: "OK",
+        isInAlert: true,
+        buttonAction: ButtonAction.first,
+      ),
+    ],
+  );
+}
+
+///Will return null if dismissed by tapping outside
+Future<ButtonAction?> showGenericErrorDialog({
+  required BuildContext context,
+  bool isDismissible = true,
+}) async {
+  return showDialogWidget(
+    context: context,
+    title: "Error",
+    icon: Icons.error_outline_outlined,
+    body: "It looks like something went wrong. Please try again.",
+    isDismissible: isDismissible,
+    buttons: const [
+      ButtonWidget(
+        buttonType: ButtonType.secondary,
+        labelText: "OK",
+        isInAlert: true,
+      ),
+    ],
+  );
+}
+
+DialogWidget choiceDialog({
+  required String title,
+  String? body,
+  required String firstButtonLabel,
+  String secondButtonLabel = "Cancel",
+  ButtonType firstButtonType = ButtonType.neutral,
+  ButtonType secondButtonType = ButtonType.secondary,
+  ButtonAction firstButtonAction = ButtonAction.first,
+  ButtonAction secondButtonAction = ButtonAction.cancel,
+  FutureVoidCallback? firstButtonOnTap,
+  FutureVoidCallback? secondButtonOnTap,
+  bool isCritical = false,
+  IconData? icon,
+}) {
+  final buttons = [
+    ButtonWidget(
+      buttonType: isCritical ? ButtonType.critical : firstButtonType,
+      labelText: firstButtonLabel,
+      isInAlert: true,
+      onTap: firstButtonOnTap,
+      buttonAction: firstButtonAction,
+    ),
+    ButtonWidget(
+      buttonType: secondButtonType,
+      labelText: secondButtonLabel,
+      isInAlert: true,
+      onTap: secondButtonOnTap,
+      buttonAction: secondButtonAction,
+    ),
+  ];
+
+  return DialogWidget(title: title, body: body, buttons: buttons, icon: icon);
+}
+
+///Will return null if dismissed by tapping outside
+Future<ButtonAction?> showNewChoiceDialog({
+  required BuildContext context,
+  required String title,
+  String? body,
+  required String firstButtonLabel,
+  String secondButtonLabel = "Cancel",
+  ButtonType firstButtonType = ButtonType.neutral,
+  ButtonType secondButtonType = ButtonType.secondary,
+  ButtonAction firstButtonAction = ButtonAction.first,
+  ButtonAction secondButtonAction = ButtonAction.cancel,
+  FutureVoidCallback? firstButtonOnTap,
+  FutureVoidCallback? secondButtonOnTap,
+  bool isCritical = false,
+  IconData? icon,
+  bool isDismissible = true,
+}) async {
+  final buttons = [
+    ButtonWidget(
+      buttonType: isCritical ? ButtonType.critical : firstButtonType,
+      labelText: firstButtonLabel,
+      isInAlert: true,
+      onTap: firstButtonOnTap,
+      buttonAction: firstButtonAction,
+    ),
+    ButtonWidget(
+      buttonType: secondButtonType,
+      labelText: secondButtonLabel,
+      isInAlert: true,
+      onTap: secondButtonOnTap,
+      buttonAction: secondButtonAction,
+    ),
+  ];
+  return showDialogWidget(
+    context: context,
+    title: title,
+    body: body,
+    buttons: buttons,
+    icon: icon,
+    isDismissible: isDismissible,
+  );
+}
 
 
 ProgressDialog createProgressDialog(
 ProgressDialog createProgressDialog(
   BuildContext context,
   BuildContext context,
@@ -30,56 +155,20 @@ ProgressDialog createProgressDialog(
   return dialog;
   return dialog;
 }
 }
 
 
-Future<dynamic> showErrorDialog(
-  BuildContext context,
-  String title,
-  String content,
-) {
-  final AlertDialog alert = AlertDialog(
-    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
-    title: title.isEmpty
-        ? const SizedBox.shrink()
-        : Text(
-            title,
-            style: Theme.of(context).textTheme.headline6,
-          ),
-    content: Text(content),
-    actions: [
-      TextButton(
-        child: Text(
-          "Ok",
-          style: TextStyle(
-            color: Theme.of(context).colorScheme.onSurface,
-          ),
-        ),
-        onPressed: () {
-          Navigator.of(context, rootNavigator: true).pop('dialog');
-        },
-      ),
-    ],
-  );
-
-  return showDialog(
-    context: context,
-    builder: (BuildContext context) {
-      return alert;
-    },
-    barrierColor: Colors.black12,
-  );
-}
-
-Future<T> showConfettiDialog<T>({
-  @required BuildContext context,
-  WidgetBuilder builder,
+Future<ButtonAction?> showConfettiDialog<T>({
+  required BuildContext context,
+  required DialogBuilder dialogBuilder,
   bool barrierDismissible = true,
   bool barrierDismissible = true,
-  Color barrierColor,
+  Color? barrierColor,
   bool useSafeArea = true,
   bool useSafeArea = true,
   bool useRootNavigator = true,
   bool useRootNavigator = true,
-  RouteSettings routeSettings,
+  RouteSettings? routeSettings,
   Alignment confettiAlignment = Alignment.center,
   Alignment confettiAlignment = Alignment.center,
 }) {
 }) {
+  final widthOfScreen = MediaQuery.of(context).size.width;
+  final isMobileSmall = widthOfScreen <= mobileSmallThreshold;
   final pageBuilder = Builder(
   final pageBuilder = Builder(
-    builder: builder,
+    builder: dialogBuilder,
   );
   );
   final ConfettiController confettiController =
   final ConfettiController confettiController =
       ConfettiController(duration: const Duration(seconds: 1));
       ConfettiController(duration: const Duration(seconds: 1));
@@ -87,22 +176,25 @@ Future<T> showConfettiDialog<T>({
   return showDialog(
   return showDialog(
     context: context,
     context: context,
     builder: (BuildContext buildContext) {
     builder: (BuildContext buildContext) {
-      return Stack(
-        children: [
-          pageBuilder,
-          Align(
-            alignment: confettiAlignment,
-            child: ConfettiWidget(
-              confettiController: confettiController,
-              blastDirection: pi / 2,
-              emissionFrequency: 0,
-              numberOfParticles: 100,
-              // a lot of particles at once
-              gravity: 1,
-              blastDirectionality: BlastDirectionality.explosive,
+      return Padding(
+        padding: EdgeInsets.symmetric(horizontal: isMobileSmall ? 8 : 0),
+        child: Stack(
+          children: [
+            Align(alignment: Alignment.center, child: pageBuilder),
+            Align(
+              alignment: confettiAlignment,
+              child: ConfettiWidget(
+                confettiController: confettiController,
+                blastDirection: pi / 2,
+                emissionFrequency: 0,
+                numberOfParticles: 100,
+                // a lot of particles at once
+                gravity: 1,
+                blastDirectionality: BlastDirectionality.explosive,
+              ),
             ),
             ),
-          ),
-        ],
+          ],
+        ),
       );
       );
     },
     },
     barrierDismissible: barrierDismissible,
     barrierDismissible: barrierDismissible,

+ 0 - 1
lib/utils/email_util.dart

@@ -16,7 +16,6 @@ import 'package:photos/core/configuration.dart';
 import 'package:photos/core/error-reporting/super_logging.dart';
 import 'package:photos/core/error-reporting/super_logging.dart';
 import 'package:photos/ente_theme_data.dart';
 import 'package:photos/ente_theme_data.dart';
 import 'package:photos/ui/common/dialogs.dart';
 import 'package:photos/ui/common/dialogs.dart';
-import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/ui/tools/debug/log_file_viewer.dart';
 import 'package:photos/ui/tools/debug/log_file_viewer.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/toast_util.dart';
 import 'package:photos/utils/toast_util.dart';

+ 0 - 1
lib/utils/share_util.dart

@@ -10,7 +10,6 @@ import 'package:photos/core/configuration.dart';
 import 'package:photos/core/constants.dart';
 import 'package:photos/core/constants.dart';
 import 'package:photos/models/file.dart';
 import 'package:photos/models/file.dart';
 import 'package:photos/models/file_type.dart';
 import 'package:photos/models/file_type.dart';
-import 'package:photos/ui/components/dialog_widget.dart';
 import 'package:photos/utils/date_time_util.dart';
 import 'package:photos/utils/date_time_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/exif_util.dart';
 import 'package:photos/utils/exif_util.dart';