diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index 287ff57f..bfb3a14d 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -116,7 +116,7 @@ jobs: name: "Nightly-v${{ steps.generate.outputs.build-number }}-iOS/Android-Visit mxc1usd.com" generateReleaseNotes: true body: > - imageimage + imageimage - name: Upload APK to Waldo uses: waldoapp/gh-action-upload@v2 diff --git a/.github/workflows/submit.yml b/.github/workflows/submit.yml index e7ee3018..4179ad6f 100644 --- a/.github/workflows/submit.yml +++ b/.github/workflows/submit.yml @@ -46,7 +46,7 @@ jobs: - uses: r0adkll/upload-google-play@v1 with: serviceAccountJsonPlainText: ${{ secrets.SERVICE_ACCOUNT_JSON }} - packageName: com.moonchain.mxc + packageName: com.moonchain.app releaseFiles: build/app/outputs/bundle/googlePlayRelease/moonchain.aab track: alpha status: draft @@ -126,6 +126,6 @@ jobs: name: "Release-v${{ steps.generate.outputs.build-number }}-iOS/Android-Visit mxc1usd.com" generateReleaseNotes: true body: > - imageimage + imageimage diff --git a/android/app/build.gradle b/android/app/build.gradle index abd3f573..6f1b39c8 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -56,7 +56,7 @@ android { } defaultConfig { - applicationId "com.moonchain.mxc" + applicationId "com.moonchain.app" // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. minSdkVersion 21 diff --git a/android/app/google-services.json b/android/app/google-services.json index 2ec59ce5..e336ba86 100644 --- a/android/app/google-services.json +++ b/android/app/google-services.json @@ -5,6 +5,43 @@ "storage_bucket": "moonchain-app.appspot.com" }, "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:810578982053:android:dbfbe51474fccc2b21094c", + "android_client_info": { + "package_name": "com.moonchain.app" + } + }, + "oauth_client": [ + { + "client_id": "810578982053-5mthh5ep4k1601komn39hu7c4biu4chb.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCyny8vayQzMxTWnJcK7KIl7GKEwtloC8Q" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "810578982053-5mthh5ep4k1601komn39hu7c4biu4chb.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "810578982053-p196bn8p9ipg3709v4ftk2a28fcvi6ka.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "com.moonchain.mxc", + "app_store_id": "6736371768" + } + } + ] + } + } + }, { "client_info": { "mobilesdk_app_id": "1:810578982053:android:98b17812d3f86af721094c", @@ -12,7 +49,36 @@ "package_name": "com.moonchain.mxc" } }, - "oauth_client": [], + "oauth_client": [ + { + "client_id": "810578982053-ef7chugg2fct7l6io3d7tis321hi1hnd.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.moonchain.mxc", + "certificate_hash": "5c3aaff06b031aa5f90f61c1e1d3b79fc0294af0" + } + }, + { + "client_id": "810578982053-misr3ehc1l6mhef3s25botsd3v8jje9h.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.moonchain.mxc", + "certificate_hash": "2d7ddbcda8fff7b9cbc2b55d3b01e9ddc77c20e4" + } + }, + { + "client_id": "810578982053-se1jg0k7sstre57ejkh1fg551spvji2o.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.moonchain.mxc", + "certificate_hash": "b3d8f034c8319b877f83a2a44ff9141325ded9c3" + } + }, + { + "client_id": "810578982053-5mthh5ep4k1601komn39hu7c4biu4chb.apps.googleusercontent.com", + "client_type": 3 + } + ], "api_key": [ { "current_key": "AIzaSyCyny8vayQzMxTWnJcK7KIl7GKEwtloC8Q" @@ -20,10 +86,23 @@ ], "services": { "appinvite_service": { - "other_platform_oauth_client": [] + "other_platform_oauth_client": [ + { + "client_id": "810578982053-5mthh5ep4k1601komn39hu7c4biu4chb.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "810578982053-p196bn8p9ipg3709v4ftk2a28fcvi6ka.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "com.moonchain.mxc", + "app_store_id": "6736371768" + } + } + ] } } - }, + } ], "configuration_version": "1" } \ No newline at end of file diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml index 1422cf3c..d3950581 100644 --- a/android/app/src/debug/AndroidManifest.xml +++ b/android/app/src/debug/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="com.moonchain.app"> + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + + com.googleusercontent.apps.810578982053-p196bn8p9ipg3709v4ftk2a28fcvi6ka + + + + UIApplicationSupportsIndirectInputEvents UIBackgroundModes diff --git a/ios/Runner/Runner.entitlements b/ios/Runner/Runner.entitlements index 22d4a48a..ebd7d399 100644 --- a/ios/Runner/Runner.entitlements +++ b/ios/Runner/Runner.entitlements @@ -8,7 +8,19 @@ applinks:mxc1usd.com + com.apple.developer.icloud-container-identifiers + + iCloud.moonchain.mxc + + com.apple.developer.icloud-services + + CloudDocuments + com.apple.developer.networking.wifi-info + com.apple.developer.ubiquity-container-identifiers + + iCloud.moonchain.mxc + diff --git a/ios/Runner/RunnerDebug.entitlements b/ios/Runner/RunnerDebug.entitlements new file mode 100644 index 00000000..ebd7d399 --- /dev/null +++ b/ios/Runner/RunnerDebug.entitlements @@ -0,0 +1,26 @@ + + + + + aps-environment + development + com.apple.developer.associated-domains + + applinks:mxc1usd.com + + com.apple.developer.icloud-container-identifiers + + iCloud.moonchain.mxc + + com.apple.developer.icloud-services + + CloudDocuments + + com.apple.developer.networking.wifi-info + + com.apple.developer.ubiquity-container-identifiers + + iCloud.moonchain.mxc + + + diff --git a/ios/Runner/RunnerRelease.entitlements b/ios/Runner/RunnerRelease.entitlements new file mode 100644 index 00000000..ebd7d399 --- /dev/null +++ b/ios/Runner/RunnerRelease.entitlements @@ -0,0 +1,26 @@ + + + + + aps-environment + development + com.apple.developer.associated-domains + + applinks:mxc1usd.com + + com.apple.developer.icloud-container-identifiers + + iCloud.moonchain.mxc + + com.apple.developer.icloud-services + + CloudDocuments + + com.apple.developer.networking.wifi-info + + com.apple.developer.ubiquity-container-identifiers + + iCloud.moonchain.mxc + + + diff --git a/lib/core/src/firebase/firebase_options.dart b/lib/core/src/firebase/firebase_options.dart index 0c17b5db..551202d9 100644 --- a/lib/core/src/firebase/firebase_options.dart +++ b/lib/core/src/firebase/firebase_options.dart @@ -51,7 +51,7 @@ class DefaultFirebaseOptions { static const FirebaseOptions android = FirebaseOptions( apiKey: 'AIzaSyCyny8vayQzMxTWnJcK7KIl7GKEwtloC8Q', - appId: '1:810578982053:android:98b17812d3f86af721094c', + appId: '1:810578982053:android:dbfbe51474fccc2b21094c', messagingSenderId: '810578982053', projectId: 'moonchain-app', storageBucket: 'moonchain-app.appspot.com', @@ -63,6 +63,8 @@ class DefaultFirebaseOptions { messagingSenderId: '810578982053', projectId: 'moonchain-app', storageBucket: 'moonchain-app.appspot.com', + androidClientId: '810578982053-ef7chugg2fct7l6io3d7tis321hi1hnd.apps.googleusercontent.com', + iosClientId: '810578982053-p196bn8p9ipg3709v4ftk2a28fcvi6ka.apps.googleusercontent.com', iosBundleId: 'com.moonchain.mxc', ); } diff --git a/lib/features/common/app/launcher_use_case.dart b/lib/features/common/app/launcher_use_case.dart index b0d03f5f..6ead1da7 100644 --- a/lib/features/common/app/launcher_use_case.dart +++ b/lib/features/common/app/launcher_use_case.dart @@ -22,14 +22,23 @@ class LauncherUseCase extends ReactiveUseCase { final AccountUseCase _accountUseCase; final ChainConfigurationUseCase _chainConfigurationUseCase; - void viewTransactions() async { - final chainExplorerUrl = - _chainConfigurationUseCase.selectedNetwork.value!.explorerUrl!; - final address = _accountUseCase.account.value!.address; - final addressExplorer = Urls.addressExplorer(address); - final launchUri = MXCFormatter.mergeUrl(chainExplorerUrl, addressExplorer); - - openUrl(launchUri, LaunchMode.platformDefault); + void viewTransactions(List? txList) async { + // Account should have tx + if (txList != null && txList.isNotEmpty) { + final chainExplorerUrl = + _chainConfigurationUseCase.selectedNetwork.value!.explorerUrl!; + final address = _accountUseCase.account.value!.address; + final ethAddress = EthereumAddress.fromHex(address); + final addressExplorer = Urls.addressExplorer(ethAddress.hexEip55); + final launchUri = + MXCFormatter.mergeUrl(chainExplorerUrl, addressExplorer); + + openUrl(launchUri, LaunchMode.platformDefault); + } else { + final chainExplorerUrl = Uri.parse( + _chainConfigurationUseCase.selectedNetwork.value!.explorerUrl!); + openUrl(chainExplorerUrl, LaunchMode.platformDefault); + } } /// Launches the given txHash in the chains explorer tx page diff --git a/lib/features/common/app_nav_bar/app_nav_bar.dart b/lib/features/common/app_nav_bar/app_nav_bar.dart index 0eb28df5..18c8a343 100644 --- a/lib/features/common/app_nav_bar/app_nav_bar.dart +++ b/lib/features/common/app_nav_bar/app_nav_bar.dart @@ -1,10 +1,13 @@ import 'package:moonchain_wallet/common/common.dart'; +import 'package:moonchain_wallet/core/src/routing/route.dart'; import 'package:moonchain_wallet/features/settings/settings.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:moonchain_wallet/features/settings/subfeatures/accounts/show_accounts_dialog.dart'; import 'package:mxc_logic/mxc_logic.dart'; import 'package:mxc_ui/mxc_ui.dart'; +import '../../settings/subfeatures/accounts/subfeatures/import_account/import_account_page.dart'; import 'app_nav_bar_presenter.dart'; import 'app_nav_bar_state.dart'; @@ -47,7 +50,21 @@ class AppNavBar extends HookConsumerWidget { color: ColorsTheme.of(context).iconPrimary, ), child: GestureDetector( - onTap: () => presenter.copy(), + onTap: () => showAccountsDialog( + context: context, + currentAccount: state.account!, + accounts: state.accounts, + isLoading: state.isLoading, + onImport: () => Navigator.of(context).push( + route.featureDialog( + const ImportAccountPage(), + ), + ), + onAdd: () => presenter.addNewAccount(), + onSelect: (item) => presenter.changeAccount(item), + onRemove: (item) => presenter.removeAccount(item), + ), + onDoubleTap: () => presenter.copy(), child: Row( mainAxisSize: MainAxisSize.min, children: [ diff --git a/lib/features/common/app_nav_bar/app_nav_bar_presenter.dart b/lib/features/common/app_nav_bar/app_nav_bar_presenter.dart index d5f1bb78..50589ff6 100644 --- a/lib/features/common/app_nav_bar/app_nav_bar_presenter.dart +++ b/lib/features/common/app_nav_bar/app_nav_bar_presenter.dart @@ -1,5 +1,7 @@ import 'package:clipboard/clipboard.dart'; +import 'package:moonchain_wallet/common/dialogs/alert_dialog.dart'; import 'package:moonchain_wallet/core/core.dart'; +import 'package:moonchain_wallet/features/settings/domain/webview_use_case.dart'; import 'package:mxc_logic/mxc_logic.dart'; import 'app_nav_bar_state.dart'; @@ -10,6 +12,8 @@ final appNavBarContainer = PresenterContainer( class AppNavPresenter extends CompletePresenter { AppNavPresenter() : super(AppNavBarState()); + late final _webviewUseCase = WebviewUseCase(); + late final _authUseCase = ref.read(authUseCaseProvider); late final _accountUseCase = ref.read(accountUseCaseProvider); late final _tokenContractUseCase = ref.read(tokenContractUseCaseProvider); late final _chainConfigurationUseCase = @@ -25,6 +29,10 @@ class AppNavPresenter extends CompletePresenter { } }); + listen(_accountUseCase.accounts, (value) { + notify(() => state.accounts = value); + }); + listen(_chainConfigurationUseCase.selectedNetwork, (value) async { if (value != null) { _accountUseCase.getAccountsNames(); @@ -48,4 +56,57 @@ class AppNavPresenter extends CompletePresenter { final tip = translate('copied_x')!.replaceAll('{0}', translate('address')!); addMessage(tip); } + + void addNewAccount() async { + notify(() => state.isLoading = true); + + try { + final index = _accountUseCase.findAccountsLastIndex(); + + final newAccount = await _authUseCase.addNewAccount(index); + _accountUseCase.addAccount(newAccount, index: index); + loadCache(); + + notify(() => state.isLoading = false); + navigator!.pop(); + } catch (e, s) { + addError(e, s); + } + } + + void changeAccount(Account item, {bool shouldPop = true}) { + _accountUseCase.changeAccount(item); + _authUseCase.changeAccount(item); + loadCache(); + + if (shouldPop) navigator?.pop(); + } + + void removeAccount(Account item) async { + try { + final result = await showAlertDialog( + context: context!, + title: translate('removing_account')!, + content: translate('removing_account_warning')!, + ok: translate('remove')!, + ); + + if (result != null && result) { + _accountUseCase.removeAccount(item); + + final isSelected = _accountUseCase.isAccountSelected(item); + if (isSelected) { + changeAccount(state.accounts[0], shouldPop: false); + } + + navigator?.pop(); + } + } catch (e, s) { + addError(e, s); + } + } + + void loadCache() { + _webviewUseCase.clearCache(); + } } diff --git a/lib/features/common/app_nav_bar/app_nav_bar_state.dart b/lib/features/common/app_nav_bar/app_nav_bar_state.dart index 26791121..c88e737f 100644 --- a/lib/features/common/app_nav_bar/app_nav_bar_state.dart +++ b/lib/features/common/app_nav_bar/app_nav_bar_state.dart @@ -3,9 +3,13 @@ import 'package:mxc_logic/mxc_logic.dart'; class AppNavBarState with EquatableMixin { Account? account; + List accounts = []; + bool isLoading = false; @override List get props => [ account, + accounts, + isLoading, ]; } diff --git a/lib/features/common/packages/backup/google_drive_use_case.dart b/lib/features/common/packages/backup/google_drive_use_case.dart index 0847f33b..b9d176cf 100644 --- a/lib/features/common/packages/backup/google_drive_use_case.dart +++ b/lib/features/common/packages/backup/google_drive_use_case.dart @@ -8,6 +8,7 @@ class GoogleDriveUseCase extends ReactiveUseCase { ); final Web3Repository _repository; + Map? _googleAuthHeaders; Future initGoogleDriveAccess() async { final googleAuthHeaders = await singInToGoogleDrive(); @@ -16,7 +17,7 @@ class GoogleDriveUseCase extends ReactiveUseCase { return false; } - _repository.googleDriveRepository.initGoogleAuthHeaders(googleAuthHeaders); + _googleAuthHeaders = googleAuthHeaders; return true; } @@ -25,16 +26,18 @@ class GoogleDriveUseCase extends ReactiveUseCase { final googleAuthData = await GoogleSignIn( scopes: [ 'email', - 'https://www.googleapis.com/auth/drive', + 'https://www.googleapis.com/auth/drive.file', ], ).signIn(); - return await googleAuthData?.authHeaders; + final authHeaders = await googleAuthData?.authHeaders; + + return authHeaders; } Future uploadBackup(String mnemonic) async => - _repository.googleDriveRepository.uploadBackup(mnemonic); + _repository.googleDriveRepository.uploadBackup(mnemonic, _googleAuthHeaders); Future readBackupFile() async => - _repository.googleDriveRepository.readBackupFile(); + _repository.googleDriveRepository.readBackupFile(_googleAuthHeaders); } diff --git a/lib/features/settings/presentation/settings_page_presenter.dart b/lib/features/settings/presentation/settings_page_presenter.dart index 3799083f..53da949a 100644 --- a/lib/features/settings/presentation/settings_page_presenter.dart +++ b/lib/features/settings/presentation/settings_page_presenter.dart @@ -12,8 +12,6 @@ final settingsContainer = PresenterContainer( class SettingsPresenter extends CompletePresenter { SettingsPresenter() : super(SettingsState()); - late final _webviewUseCase = WebviewUseCase(); - late final _authUseCase = ref.read(authUseCaseProvider); late final _accountUserCase = ref.read(accountUseCaseProvider); late final blueberryRingBackgroundNotificationsUseCase = ref.read(blueberryRingBackgroundNotificationsUseCaseProvider); @@ -52,61 +50,6 @@ class SettingsPresenter extends CompletePresenter { notify(() => state.appVersion = ' $version ($buildNumber)'); } - void addNewAccount() async { - notify(() => state.isLoading = true); - - try { - final index = _accountUserCase.findAccountsLastIndex(); - - final newAccount = await _authUseCase.addNewAccount(index); - _accountUserCase.addAccount(newAccount, index: index); - loadCache(); - - notify(() => state.isLoading = false); - navigator?.popUntil((route) { - return route.settings.name?.contains('SettingsPage') ?? false; - }); - } catch (e, s) { - addError(e, s); - } - } - - void changeAccount(Account item, {bool shouldPop = true}) { - _accountUserCase.changeAccount(item); - _authUseCase.changeAccount(item); - loadCache(); - - if (shouldPop) navigator?.pop(); - } - - void removeAccount(Account item) async { - try { - final result = await showAlertDialog( - context: context!, - title: translate('removing_account')!, - content: translate('removing_account_warning')!, - ok: translate('remove')!, - ); - - if (result != null && result) { - _accountUserCase.removeAccount(item); - - final isSelected = _accountUserCase.isAccountSelected(item); - if (isSelected) { - changeAccount(state.accounts[0], shouldPop: false); - } - - navigator?.pop(); - } - } catch (e, s) { - addError(e, s); - } - } - - void loadCache() { - _webviewUseCase.clearCache(); - } - void testOnly() async { // await blueberryRingBackgroundNotificationsUseCase.checkLowBattery(); diff --git a/lib/features/settings/presentation/settings_page_state.dart b/lib/features/settings/presentation/settings_page_state.dart index 79d32c17..51f92a50 100644 --- a/lib/features/settings/presentation/settings_page_state.dart +++ b/lib/features/settings/presentation/settings_page_state.dart @@ -5,13 +5,11 @@ class SettingsState with EquatableMixin { Account? account; List accounts = []; String? appVersion; - bool isLoading = false; @override List get props => [ account, accounts, appVersion, - isLoading, ]; } diff --git a/lib/features/settings/presentation/widgets/account_managment/account_managment_panel.dart b/lib/features/settings/presentation/widgets/account_managment/account_managment_panel.dart index 66ecd1f2..36e6539b 100644 --- a/lib/features/settings/presentation/widgets/account_managment/account_managment_panel.dart +++ b/lib/features/settings/presentation/widgets/account_managment/account_managment_panel.dart @@ -1,5 +1,6 @@ import 'package:moonchain_wallet/common/common.dart'; import 'package:moonchain_wallet/core/core.dart'; +import 'package:moonchain_wallet/features/common/app_nav_bar/app_nav_bar_presenter.dart'; import 'package:moonchain_wallet/features/settings/settings.dart'; import 'package:moonchain_wallet/features/settings/subfeatures/accounts/show_accounts_dialog.dart'; import 'package:moonchain_wallet/features/settings/subfeatures/accounts/subfeatures/import_account/import_account_page.dart'; @@ -17,7 +18,9 @@ class AccountManagementPanel extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final presenter = ref.read(settingsContainer.actions); + final appNavBarPresenter = ref.read(appNavBarContainer.actions); final state = ref.watch(settingsContainer.state); + final appNavBarState = ref.watch(appNavBarContainer.state); final account = state.account; final walletAddress = MXCFormatter.formatWalletAddress( account?.address ?? '', @@ -40,15 +43,15 @@ class AccountManagementPanel extends HookConsumerWidget { context: context, currentAccount: state.account!, accounts: state.accounts, - isLoading: state.isLoading, + isLoading: appNavBarState.isLoading, onImport: () => Navigator.of(context).push( route.featureDialog( const ImportAccountPage(), ), ), - onAdd: () => presenter.addNewAccount(), - onSelect: (item) => presenter.changeAccount(item), - onRemove: (item) => presenter.removeAccount(item), + onAdd: () => appNavBarPresenter.addNewAccount(), + onSelect: (item) => appNavBarPresenter.changeAccount(item), + onRemove: (item) => appNavBarPresenter.removeAccount(item), ), child: Row( children: [ diff --git a/lib/features/settings/subfeatures/accounts/subfeatures/import_account/import_account_presenter.dart b/lib/features/settings/subfeatures/accounts/subfeatures/import_account/import_account_presenter.dart index f778e077..091ce40a 100644 --- a/lib/features/settings/subfeatures/accounts/subfeatures/import_account/import_account_presenter.dart +++ b/lib/features/settings/subfeatures/accounts/subfeatures/import_account/import_account_presenter.dart @@ -41,9 +41,7 @@ class ImportAccountPresenter extends CompletePresenter { notify(() => state.isLoading = false); BottomFlowDialog.of(context!).close(); - navigator?.popUntil((route) { - return route.settings.name?.contains('SettingsPage') ?? false; - }); + navigator!.pop(); } catch (error, stackTrace) { addError(error, stackTrace); } finally { 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 26fe02d5..25f2255a 100644 --- a/lib/features/splash/create_storage/presentation/create_storage_page.dart +++ b/lib/features/splash/create_storage/presentation/create_storage_page.dart @@ -114,7 +114,7 @@ class SplashStoragePage extends SplashBasePage { MxcButton.secondaryWhite( key: const ValueKey('GoogleDriveButton'), icon: MxcIcons.google_drive, - iconSize: 24, + iconSize: 32, titleSize: 18, title: FlutterI18n.translate(context, 'google_drive_secured_storage'), onTap: () => Navigator.of(context).push( @@ -130,7 +130,7 @@ class SplashStoragePage extends SplashBasePage { ? MxcButton.secondaryWhite( key: const ValueKey('icloudButton'), icon: MxcIcons.icloud, - iconSize: 18, + iconSize: 32, titleSize: 18, title: FlutterI18n.translate(context, 'icloud_secured_storage'), onTap: () => Navigator.of(context).push( diff --git a/lib/features/splash/import_storage/import_storage_page.dart b/lib/features/splash/import_storage/import_storage_page.dart index 556a5f69..eb0b4746 100644 --- a/lib/features/splash/import_storage/import_storage_page.dart +++ b/lib/features/splash/import_storage/import_storage_page.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:moonchain_wallet/core/core.dart'; import 'package:moonchain_wallet/features/splash/splash.dart'; import 'package:flutter/material.dart'; @@ -76,15 +78,17 @@ class SplashImportStoragePage extends SplashBasePage { onTap: () => ref.read(presenter).loadBackupFromGoogleDrive(), edgeType: getPageButtonsEdge(), ), - MxcButton.secondaryWhite( - key: const ValueKey('icloudButton'), - icon: MxcIcons.icloud, - iconSize: 32, - titleSize: 18, - title: FlutterI18n.translate(context, 'icloud_secured_storage'), - onTap: () => ref.read(presenter).loadBackupFromICloud(), - edgeType: getPageButtonsEdge(), - ), + Platform.isIOS + ? MxcButton.secondaryWhite( + key: const ValueKey('icloudButton'), + icon: MxcIcons.icloud, + iconSize: 32, + titleSize: 18, + title: FlutterI18n.translate(context, 'icloud_secured_storage'), + onTap: () => ref.read(presenter).loadBackupFromICloud(), + edgeType: getPageButtonsEdge(), + ) + : Container(), !isNoneAvailable ? MxcButton.secondaryWhite( key: const ValueKey('localButton'), diff --git a/lib/features/splash/secure_recovery_phrase/presentation/google_drive_recovery_phrase_alert/google_drive_recovery_phrase_page.dart b/lib/features/splash/secure_recovery_phrase/presentation/google_drive_recovery_phrase_alert/google_drive_recovery_phrase_page.dart index a880ef8f..01e405b5 100644 --- a/lib/features/splash/secure_recovery_phrase/presentation/google_drive_recovery_phrase_alert/google_drive_recovery_phrase_page.dart +++ b/lib/features/splash/secure_recovery_phrase/presentation/google_drive_recovery_phrase_alert/google_drive_recovery_phrase_page.dart @@ -56,16 +56,41 @@ class GoogleDriveRecoveryPhrasePage extends RecoveryPhraseBasePage { ), child: getIcon(context)), const SizedBox(height: 12), - Text( - FlutterI18n.translate(context, - 'make_sure_you_have_stored_your_keys_correctly_in_your_x') - .replaceFirst( - '{0}', FlutterI18n.translate(context, 'google_drive')), - style: FontTheme.of(context).body1().copyWith( - fontWeight: FontWeight.w500, - color: ColorsTheme.of(context).textPrimary, - ), - textAlign: TextAlign.center, + Text.rich( + TextSpan(children: [ + TextSpan( + text: FlutterI18n.translate( + context, 'tips_for_storing_keys_safely'), + style: FontTheme.of(context).body1().copyWith( + fontWeight: FontWeight.w700, + color: ColorsTheme.of(context).textPrimary, + ), + ), + const TextSpan( + text: '\n', + ), + TextSpan( + text: FlutterI18n.translate(context, + 'ensure_that_your_keys_are_stored_correctly_in_your_x') + .replaceFirst( + '{0}', FlutterI18n.translate(context, 'google_drive')), + style: FontTheme.of(context).body1().copyWith( + fontWeight: FontWeight.w500, + color: ColorsTheme.of(context).textPrimary, + ), + ), + const TextSpan( + text: '\n\n', + ), + TextSpan( + text: + FlutterI18n.translate(context, 'google_drive_backup_note'), + style: FontTheme.of(context).body1().copyWith( + fontWeight: FontWeight.w500, + color: ColorsTheme.of(context).textPrimary, + ), + ), + ]), ), ], ), diff --git a/lib/features/splash/secure_recovery_phrase/presentation/icloud_recovery_phrase_alert/icloud_recovery_phrase_page.dart b/lib/features/splash/secure_recovery_phrase/presentation/icloud_recovery_phrase_alert/icloud_recovery_phrase_page.dart index bff2033d..3ce20738 100644 --- a/lib/features/splash/secure_recovery_phrase/presentation/icloud_recovery_phrase_alert/icloud_recovery_phrase_page.dart +++ b/lib/features/splash/secure_recovery_phrase/presentation/icloud_recovery_phrase_alert/icloud_recovery_phrase_page.dart @@ -58,7 +58,7 @@ class ICloudRecoveryPhrasePage extends RecoveryPhraseBasePage { const SizedBox(height: 12), Text( FlutterI18n.translate(context, - 'make_sure_you_have_stored_your_keys_correctly_in_your_x') + 'ensure_that_your_keys_are_stored_correctly_in_your_x') .replaceFirst('{0}', FlutterI18n.translate(context, 'icloud')), style: FontTheme.of(context).body1().copyWith( fontWeight: FontWeight.w500, 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 b386bcf5..09d10f94 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 @@ -152,6 +152,7 @@ abstract class RecoveryPhraseBasePresenter } Future saveToGoogleDrive(bool settingsFlow) async { + loading = true; final mnemonic = getMnemonic(settingsFlow); // Trying to pass the auth headers to google drive use case for further api calls @@ -170,19 +171,25 @@ abstract class RecoveryPhraseBasePresenter addError(translate('unable_to_upload_backup_to_x')! .replaceFirst('{0}', translate('google_drive')!)); collectLog(e.toString()); + } finally { + loading = false; } } Future saveToICloud(bool settingsFlow) async { + loading = true; final mnemonic = getMnemonic(settingsFlow); try { + await Future.delayed(Duration(seconds: 5)); await _iCloudUseCase.uploadBackup(mnemonic); nextProcess(settingsFlow, mnemonic); } catch (e) { addError(translate('unable_to_upload_backup_to_x')! .replaceFirst('{0}', translate('icloud')!)); collectLog(e.toString()); + } finally { + loading = false; } } diff --git a/lib/features/wallet/presentation/wallet_page_presenter.dart b/lib/features/wallet/presentation/wallet_page_presenter.dart index 2b4dce18..46605ec9 100644 --- a/lib/features/wallet/presentation/wallet_page_presenter.dart +++ b/lib/features/wallet/presentation/wallet_page_presenter.dart @@ -198,7 +198,7 @@ class WalletPresenter extends CompletePresenter { } void getViewOtherTransactionsLink() async { - _launcherUseCase.viewTransactions(); + _launcherUseCase.viewTransactions(state.txList!); } void generateChartData(List balanceData) { diff --git a/packages/shared b/packages/shared index 886d7f2f..c2f8b7ff 160000 --- a/packages/shared +++ b/packages/shared @@ -1 +1 @@ -Subproject commit 886d7f2fdfb983ea7e0f35668ea5721714fa0557 +Subproject commit c2f8b7fff2841e10309eff5ab51f104d7066265b diff --git a/pubspec.yaml b/pubspec.yaml index c71fce26..d09bc96f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -19,7 +19,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 1.1.0 +version: 1.2.1 environment: