From 2cf1d2e1b2d4495929399d4f6f4047d28e14d880 Mon Sep 17 00:00:00 2001 From: reasje Date: Thu, 19 Oct 2023 10:39:10 +0330 Subject: [PATCH 1/4] feat: Added utils with email app launch & check --- lib/common/utils/utils.dart | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lib/common/utils/utils.dart b/lib/common/utils/utils.dart index 069b264f..dcc80ba4 100644 --- a/lib/common/utils/utils.dart +++ b/lib/common/utils/utils.dart @@ -1,3 +1,24 @@ +import 'package:datadashwallet/common/common.dart'; +import 'package:url_launcher/url_launcher.dart'; + export 'formatter.dart'; export 'permission.dart'; export 'validation.dart'; + +class Utils { + static Future isEmailAppAvailable() async { + final url = Uri.parse(Urls.emailApp); + + return await canLaunchUrl(url); + } + + static Future launchEmailApp() async { + final url = Uri.parse(Urls.emailApp); + + if (await canLaunchUrl(url)) { + await launchUrl(url); + } else { + throw 'unable_to_launch_email_app'; + } + } +} From bafa7ec465bc484db6757c3b0a513291e0ecefb5 Mon Sep 17 00:00:00 2001 From: reasje Date: Thu, 19 Oct 2023 10:39:31 +0330 Subject: [PATCH 2/4] feat: Added email app url --- lib/common/urls.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/common/urls.dart b/lib/common/urls.dart index 2d98a0af..ef9d7ea2 100644 --- a/lib/common/urls.dart +++ b/lib/common/urls.dart @@ -8,4 +8,6 @@ class Urls { static const String iOSUrl = 'https://apps.apple.com/us/app/axs-decentralized-wallet/id6460891587'; + + static const String emailApp = 'mailto:'; } From 16bb77b6b826af82ef760eb23ee28fa76789945d Mon Sep 17 00:00:00 2001 From: reasje Date: Thu, 19 Oct 2023 10:44:17 +0330 Subject: [PATCH 3/4] fix: Disable email button if there is no email app --- .../presentation/create_storage_page.dart | 16 +++++++++------- .../presentation/create_storage_presenter.dart | 2 +- .../splash_base/splash_base_presenter.dart | 9 ++++----- .../splash/splash_base/splash_base_state.dart | 5 +++-- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/lib/features/splash/create_storage/presentation/create_storage_page.dart b/lib/features/splash/create_storage/presentation/create_storage_page.dart index 856e17cd..c374630e 100644 --- a/lib/features/splash/create_storage/presentation/create_storage_page.dart +++ b/lib/features/splash/create_storage/presentation/create_storage_page.dart @@ -65,13 +65,15 @@ class SplashStoragePage extends SplashBasePage { icon: MxcIcons.email, iconSize: 18, title: FlutterI18n.translate(context, 'email_secured_storage'), - onTap: () => Navigator.of(context).push( - route.featureDialog( - EmailRecoveryPhrasePage( - settingsFlow: settingsFlow, - ), - ), - ), + onTap: ref.watch(state).isEmailAppAvailable == true + ? () => Navigator.of(context).push( + route.featureDialog( + EmailRecoveryPhrasePage( + settingsFlow: settingsFlow, + ), + ), + ) + : null, ), ]; } diff --git a/lib/features/splash/create_storage/presentation/create_storage_presenter.dart b/lib/features/splash/create_storage/presentation/create_storage_presenter.dart index 677a2624..60012c93 100644 --- a/lib/features/splash/create_storage/presentation/create_storage_presenter.dart +++ b/lib/features/splash/create_storage/presentation/create_storage_presenter.dart @@ -11,7 +11,7 @@ class SplashStoragePresenter extends SplashBasePresenter { @override void initState() { super.initState(); - isInstallApps(); + checkEmailAppAvailability(); } } diff --git a/lib/features/splash/splash_base/splash_base_presenter.dart b/lib/features/splash/splash_base/splash_base_presenter.dart index 910438c3..885b9f56 100644 --- a/lib/features/splash/splash_base/splash_base_presenter.dart +++ b/lib/features/splash/splash_base/splash_base_presenter.dart @@ -1,3 +1,4 @@ +import '../../../common/common.dart'; import '../../../core/core.dart'; import 'package:appinio_social_share/appinio_social_share.dart'; import 'package:flutter_mailer/flutter_mailer.dart'; @@ -16,11 +17,9 @@ abstract class SplashBasePresenter notify(() => state.applist = applist); } - Future isInstallEmail() async { - final result = await FlutterMailer.canSendMail() || - await FlutterMailer.isAppInstalled('mailto:'); - - notify(() => state.isInstallEmail = result); + void checkEmailAppAvailability() async { + final isEmailAppAvailable = await Utils.isEmailAppAvailable(); + notify(() => state.isEmailAppAvailable = isEmailAppAvailable); } } diff --git a/lib/features/splash/splash_base/splash_base_state.dart b/lib/features/splash/splash_base/splash_base_state.dart index 84117503..719b6294 100644 --- a/lib/features/splash/splash_base/splash_base_state.dart +++ b/lib/features/splash/splash_base/splash_base_state.dart @@ -2,10 +2,11 @@ import 'package:equatable/equatable.dart'; class SplashBaseState with EquatableMixin { Map applist = {}; - bool isInstallEmail = false; + bool isEmailAppAvailable = false; bool animate = false; @override - List get props => [applist, isInstallEmail, animate]; + List get props => + [applist, animate, isEmailAppAvailable]; } From 6a4a74db7729d91b2185c2bfe3192431a01aecb1 Mon Sep 17 00:00:00 2001 From: reasje Date: Thu, 19 Oct 2023 10:46:00 +0330 Subject: [PATCH 4/4] fix: Launch email app if not logged in IOS --- assets/flutter_i18n/en.json | 3 ++- .../recovery_phrase_base_presenter.dart | 24 +++++++++++++------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/assets/flutter_i18n/en.json b/assets/flutter_i18n/en.json index 97bf7f83..0add92cf 100644 --- a/assets/flutter_i18n/en.json +++ b/assets/flutter_i18n/en.json @@ -299,5 +299,6 @@ "removing_account": "Removing account", "removing_account_warning": "Are you sure you want to remove this account?", "remove": "Remove", - "duplicate_account_import_notice": "The account you are trying to import is a duplicate" + "duplicate_account_import_notice": "The account you are trying to import is a duplicate", + "unable_to_launch_email_app": "Unable to launch email app" } \ No newline at end of file diff --git a/lib/features/splash/secure_recovery_phrase/presentation/recovery_phrase_base/recovery_phrase_base_presenter.dart b/lib/features/splash/secure_recovery_phrase/presentation/recovery_phrase_base/recovery_phrase_base_presenter.dart index 6a46efc4..742a1756 100644 --- a/lib/features/splash/secure_recovery_phrase/presentation/recovery_phrase_base/recovery_phrase_base_presenter.dart +++ b/lib/features/splash/secure_recovery_phrase/presentation/recovery_phrase_base/recovery_phrase_base_presenter.dart @@ -114,15 +114,25 @@ abstract class RecoveryPhraseBasePresenter ); try { - MailerResponse sendResult = await FlutterMailer.send(email); - // only [ios] can return sent | saved | cancelled - // [android] will return android there is no way of knowing on android - // if the intent was sent saved or even cancelled. - if (MailerResponse.cancelled != sendResult) { - nextProcess(settingsFlow, res['phrases']); + bool canSend = await FlutterMailer.canSendMail(); + + if (Platform.isIOS && !canSend) { + await Utils.launchEmailApp(); + } else { + MailerResponse sendResult = await FlutterMailer.send(email); + // only [ios] can return sent | saved | cancelled + // [android] will return android there is no way of knowing on android + // if the intent was sent saved or even cancelled. + if (MailerResponse.cancelled != sendResult) { + nextProcess(settingsFlow, res['phrases']); + } } } catch (e, s) { - addError(e, s); + if (e == 'unable_to_launch_email_app') { + addError(translate('unable_to_launch_email_app')); + } else { + addError(e, s); + } } } }