From e1fe03ca28c19bb6fc39776665ced8d09975664f Mon Sep 17 00:00:00 2001 From: Serhii Date: Thu, 29 Jun 2023 14:00:12 +0300 Subject: [PATCH 1/4] fix routing and context issue --- .../dashboard/widgets/present_receive_option_picker.dart | 2 +- lib/src/screens/receive/anonpay_receive_page.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/screens/dashboard/widgets/present_receive_option_picker.dart b/lib/src/screens/dashboard/widgets/present_receive_option_picker.dart index c29442450..cf2ae7e3d 100644 --- a/lib/src/screens/dashboard/widgets/present_receive_option_picker.dart +++ b/lib/src/screens/dashboard/widgets/present_receive_option_picker.dart @@ -138,7 +138,7 @@ class PresentReceiveOptionPicker extends StatelessWidget { Container( margin: EdgeInsets.only(bottom: 40), child: InkWell( - onTap: () => Navigator.pop(context), + onTap: () => Navigator.pop(popUpContext), child: CircleAvatar( child: Icon( Icons.close, diff --git a/lib/src/screens/receive/anonpay_receive_page.dart b/lib/src/screens/receive/anonpay_receive_page.dart index 0c175eb19..b2b267805 100644 --- a/lib/src/screens/receive/anonpay_receive_page.dart +++ b/lib/src/screens/receive/anonpay_receive_page.dart @@ -49,7 +49,7 @@ class AnonPayReceivePage extends BasePage { minWidth: double.minPositive, child: TextButton( onPressed: () => - Navigator.pushNamedAndRemoveUntil(context, Routes.dashboard, (route) => false), + Navigator.popUntil(context, (route) => route.isFirst), child: _backButton), ), ); From 02eead0014b8433ccb877f803c744563de8f0b71 Mon Sep 17 00:00:00 2001 From: Serhii Date: Thu, 29 Jun 2023 16:38:36 +0300 Subject: [PATCH 2/4] Revert " fix routing and context issue" This reverts commit e1fe03ca28c19bb6fc39776665ced8d09975664f. --- .../dashboard/widgets/present_receive_option_picker.dart | 2 +- lib/src/screens/receive/anonpay_receive_page.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/screens/dashboard/widgets/present_receive_option_picker.dart b/lib/src/screens/dashboard/widgets/present_receive_option_picker.dart index cf2ae7e3d..c29442450 100644 --- a/lib/src/screens/dashboard/widgets/present_receive_option_picker.dart +++ b/lib/src/screens/dashboard/widgets/present_receive_option_picker.dart @@ -138,7 +138,7 @@ class PresentReceiveOptionPicker extends StatelessWidget { Container( margin: EdgeInsets.only(bottom: 40), child: InkWell( - onTap: () => Navigator.pop(popUpContext), + onTap: () => Navigator.pop(context), child: CircleAvatar( child: Icon( Icons.close, diff --git a/lib/src/screens/receive/anonpay_receive_page.dart b/lib/src/screens/receive/anonpay_receive_page.dart index b2b267805..0c175eb19 100644 --- a/lib/src/screens/receive/anonpay_receive_page.dart +++ b/lib/src/screens/receive/anonpay_receive_page.dart @@ -49,7 +49,7 @@ class AnonPayReceivePage extends BasePage { minWidth: double.minPositive, child: TextButton( onPressed: () => - Navigator.popUntil(context, (route) => route.isFirst), + Navigator.pushNamedAndRemoveUntil(context, Routes.dashboard, (route) => false), child: _backButton), ), ); From 1ca09e692d7dce0293364a5ca05db867673ab899 Mon Sep 17 00:00:00 2001 From: Serhii Date: Thu, 29 Jun 2023 16:44:31 +0300 Subject: [PATCH 3/4] Revert "Merge branch 'linux/password-direct-input' of https://github.com/cake-tech/cake_wallet into linux/password-direct-input" This reverts commit 424cf2e635d91c0a8ee98877ee532dc2877bfdcf, reversing changes made to e1fe03ca28c19bb6fc39776665ced8d09975664f. --- .github/workflows/pr_test_build.yml | 1 + assets/images/flags/{nga.png => yor.png} | Bin assets/text/Monerocom_Release_Notes.txt | 9 +- assets/text/Release_Notes.txt | 10 +- .../lib/electrum_transaction_history.dart | 18 +- cw_bitcoin/lib/electrum_wallet.dart | 15 +- cw_core/lib/wallet_base.dart | 2 - ios/Podfile | 1 - ios/Podfile.lock | 40 +- ios/Runner.xcodeproj/project.pbxproj | 60 +- .../AppIcon.appiconset/Contents.json | 13 - .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 880 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 1997 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 3332 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 1399 -> 0 bytes .../Icon-App-29x29@2x 1.png | Bin 3203 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 3203 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 5030 -> 0 bytes .../Icon-App-40x40@1x 1.png | Bin 1997 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 1997 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 7194 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 4305 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 9427 -> 0 bytes .../Icon-App-83.5x83.5@2x.png | Bin 10439 -> 0 bytes lib/buy/moonpay/moonpay_buy_provider.dart | 31 +- lib/di.dart | 15 +- lib/entities/language_service.dart | 4 +- lib/entities/main_actions.dart | 25 +- .../changenow_exchange_provider.dart | 8 +- .../sideshift_exchange_provider.dart | 192 +++---- lib/main.dart | 5 +- lib/reactions/check_connection.dart | 3 +- lib/router.dart | 22 +- lib/routes.dart | 3 +- .../{webview_page.dart => onramper_page.dart} | 25 +- lib/src/screens/buy/payfura_page.dart | 58 ++ lib/src/screens/dashboard/dashboard_page.dart | 13 +- .../desktop_dashboard_actions.dart | 7 +- .../dashboard/widgets/address_page.dart | 8 +- .../dashboard/widgets/balance_page.dart | 29 +- .../dashboard/widgets/market_place_page.dart | 24 +- .../dashboard/widgets/transactions_page.dart | 201 +++---- lib/src/screens/exchange/exchange_page.dart | 8 +- .../ionia/auth/ionia_welcome_page.dart | 14 +- .../ionia/cards/ionia_manage_cards_page.dart | 17 +- .../screens/receive/anonpay_invoice_page.dart | 156 +++-- .../receive/widgets/currency_input_field.dart | 34 +- .../screens/restore/wallet_restore_page.dart | 2 - lib/src/screens/send/send_page.dart | 542 ++++++++---------- lib/src/screens/send/widgets/send_card.dart | 6 +- .../settings/display_settings_page.dart | 25 +- .../setup_2fa/setup_2fa_enter_code_page.dart | 30 +- .../screens/wallet_list/wallet_list_page.dart | 28 +- lib/src/widgets/add_template_button.dart | 2 +- lib/src/widgets/address_text_field.dart | 4 +- lib/store/app_store.dart | 2 - lib/store/settings_store.dart | 1 + lib/utils/exception_handler.dart | 21 +- lib/utils/responsive_layout_util.dart | 16 +- .../dashboard/dashboard_view_model.dart | 3 +- .../dashboard/market_place_view_model.dart | 17 - .../dashboard/transaction_list_item.dart | 3 +- .../exchange/exchange_trade_view_model.dart | 9 +- .../exchange/exchange_view_model.dart | 4 +- .../ionia_gift_cards_list_view_model.dart | 11 +- lib/view_model/trade_details_view_model.dart | 15 +- macos/Flutter/GeneratedPluginRegistrant.swift | 2 +- macos/Podfile | 4 - macos/Podfile.lock | 20 +- macos/Runner.xcodeproj/project.pbxproj | 2 + pubspec_base.yaml | 4 +- res/values/strings_ar.arb | 2 +- res/values/strings_bg.arb | 2 +- res/values/strings_cs.arb | 2 +- res/values/strings_de.arb | 2 +- res/values/strings_en.arb | 2 +- res/values/strings_es.arb | 2 +- res/values/strings_fr.arb | 34 +- res/values/strings_ha.arb | 2 +- res/values/strings_hi.arb | 2 +- res/values/strings_hr.arb | 2 +- res/values/strings_id.arb | 2 +- res/values/strings_it.arb | 2 +- res/values/strings_ja.arb | 2 +- res/values/strings_ko.arb | 2 +- res/values/strings_my.arb | 2 +- res/values/strings_nl.arb | 2 +- res/values/strings_pl.arb | 2 +- res/values/strings_pt.arb | 2 +- res/values/strings_ru.arb | 2 +- res/values/strings_th.arb | 2 +- res/values/strings_tr.arb | 2 +- res/values/strings_uk.arb | 2 +- res/values/strings_ur.arb | 2 +- res/values/strings_yo.arb | 2 +- res/values/strings_zh.arb | 2 +- scripts/android/app_env.sh | 8 +- scripts/ios/app_env.sh | 8 +- scripts/linux/app_env.sh | 4 +- scripts/macos/app_env.sh | 4 +- tool/utils/secret_key.dart | 1 + 101 files changed, 910 insertions(+), 1041 deletions(-) rename assets/images/flags/{nga.png => yor.png} (100%) delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x 1.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x 1.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png rename lib/src/screens/buy/{webview_page.dart => onramper_page.dart} (68%) create mode 100644 lib/src/screens/buy/payfura_page.dart delete mode 100644 lib/view_model/dashboard/market_place_view_model.dart diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml index 4ca762c12..076fc2ea1 100644 --- a/.github/workflows/pr_test_build.yml +++ b/.github/workflows/pr_test_build.yml @@ -106,6 +106,7 @@ jobs: echo "const moonPayApiKey = '${{ secrets.MOON_PAY_API_KEY }}';" >> lib/.secrets.g.dart echo "const moonPaySecretKey = '${{ secrets.MOON_PAY_SECRET_KEY }}';" >> lib/.secrets.g.dart echo "const sideShiftAffiliateId = '${{ secrets.SIDE_SHIFT_AFFILIATE_ID }}';" >> lib/.secrets.g.dart + echo "const sideShiftApiKey = '${{ secrets.SIDE_SHIFT_API_KEY }}';" >> lib/.secrets.g.dart echo "const simpleSwapApiKey = '${{ secrets.SIMPLE_SWAP_API_KEY }}';" >> lib/.secrets.g.dart echo "const simpleSwapApiKeyDesktop = '${{ secrets.SIMPLE_SWAP_API_KEY_DESKTOP }}';" >> lib/.secrets.g.dart echo "const onramperApiKey = '${{ secrets.ONRAMPER_API_KEY }}';" >> lib/.secrets.g.dart diff --git a/assets/images/flags/nga.png b/assets/images/flags/yor.png similarity index 100% rename from assets/images/flags/nga.png rename to assets/images/flags/yor.png diff --git a/assets/text/Monerocom_Release_Notes.txt b/assets/text/Monerocom_Release_Notes.txt index d95478116..178fa45ea 100644 --- a/assets/text/Monerocom_Release_Notes.txt +++ b/assets/text/Monerocom_Release_Notes.txt @@ -1,3 +1,6 @@ -Enable iPad/Tablet separate layout from mobile UI -SideShift update and fixes -Bug Fixes \ No newline at end of file +Opt-in to Cake 2FA for security. More info: https://guides.cakewallet.com/docs/advanced-features/authentication/#cake-2fa +Auto generate restore height for Monero restore QR codes +Hausa and Yoruba languages +Additional privacy settings +Update Monero to 0.18.2.2 +Refactoring and bug fixes \ No newline at end of file diff --git a/assets/text/Release_Notes.txt b/assets/text/Release_Notes.txt index 38e3e21df..178fa45ea 100644 --- a/assets/text/Release_Notes.txt +++ b/assets/text/Release_Notes.txt @@ -1,4 +1,6 @@ -Enable iPad/Tablet separate layout from mobile UI -SideShift update and fixes -Add MoonPay sell -Bug Fixes \ No newline at end of file +Opt-in to Cake 2FA for security. More info: https://guides.cakewallet.com/docs/advanced-features/authentication/#cake-2fa +Auto generate restore height for Monero restore QR codes +Hausa and Yoruba languages +Additional privacy settings +Update Monero to 0.18.2.2 +Refactoring and bug fixes \ No newline at end of file diff --git a/cw_bitcoin/lib/electrum_transaction_history.dart b/cw_bitcoin/lib/electrum_transaction_history.dart index da8f369ec..b8b7ad5ee 100644 --- a/cw_bitcoin/lib/electrum_transaction_history.dart +++ b/cw_bitcoin/lib/electrum_transaction_history.dart @@ -35,7 +35,7 @@ abstract class ElectrumTransactionHistoryBase @override void addMany(Map transactions) => - transactions.forEach((_, tx) => _update(tx)); + transactions.forEach((_, tx) => _updateOrInsert(tx)); @override Future save() async { @@ -74,7 +74,7 @@ abstract class ElectrumTransactionHistoryBase if (val is Map) { final tx = ElectrumTransactionInfo.fromJson(val, walletInfo.type); - _update(tx); + _updateOrInsert(tx); } }); @@ -84,6 +84,18 @@ abstract class ElectrumTransactionHistoryBase } } - void _update(ElectrumTransactionInfo transaction) => + void _updateOrInsert(ElectrumTransactionInfo transaction) { + + if (transactions[transaction.id] == null) { transactions[transaction.id] = transaction; + } else { + final originalTx = transactions[transaction.id]; + originalTx?.confirmations = transaction.confirmations; + originalTx?.amount = transaction.amount; + originalTx?.height = transaction.height; + originalTx?.date ??= transaction.date; + originalTx?.isPending = transaction.isPending; + originalTx?.direction = transaction.direction; + } + } } diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index 0cc739f29..ba59c982e 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -15,6 +15,7 @@ import 'package:cw_core/pathForWallet.dart'; import 'package:cw_bitcoin/address_to_output_script.dart'; import 'package:cw_bitcoin/bitcoin_address_record.dart'; import 'package:cw_bitcoin/electrum_balance.dart'; +import 'package:cw_bitcoin/bitcoin_mnemonic.dart'; import 'package:cw_bitcoin/bitcoin_transaction_credentials.dart'; import 'package:cw_bitcoin/electrum_transaction_history.dart'; import 'package:cw_bitcoin/bitcoin_transaction_no_inputs_exception.dart'; @@ -127,8 +128,6 @@ abstract class ElectrumWalletBase extends WalletBase?> _scripthashesUpdateSubject; bool _isTransactionUpdating; - void Function(FlutterErrorDetails)? _onError; - Future init() async { await walletAddresses.init(); await transactionHistory.init(); @@ -331,7 +330,7 @@ abstract class ElectrumWalletBase extends WalletBase minAmount) { @@ -650,13 +649,8 @@ abstract class ElectrumWalletBase extends WalletBase _onError = onError; } diff --git a/cw_core/lib/wallet_base.dart b/cw_core/lib/wallet_base.dart index ba1842357..b6b05df36 100644 --- a/cw_core/lib/wallet_base.dart +++ b/cw_core/lib/wallet_base.dart @@ -75,6 +75,4 @@ abstract class WalletBase< String get password; Future? updateBalance(); - - void setExceptionHandler(void Function(FlutterErrorDetails) onError) => null; } diff --git a/ios/Podfile b/ios/Podfile index 027d48ceb..b29d40484 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -44,7 +44,6 @@ post_install do |installer| flutter_additional_ios_build_settings(target) target.build_configurations.each do |config| - config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0' config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [ '$(inherited)', diff --git a/ios/Podfile.lock b/ios/Podfile.lock index d5453bd06..62074faed 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -4,10 +4,10 @@ PODS: - MTBBarcodeScanner - SwiftProtobuf - BigInt (5.2.0) - - connectivity_plus (0.0.1): + - connectivity (0.0.1): - Flutter - - ReachabilitySwift - - CryptoSwift (1.7.1) + - Reachability + - CryptoSwift (1.6.0) - cw_haven (0.0.1): - cw_haven/Boost (= 0.0.1) - cw_haven/Haven (= 0.0.1) @@ -126,20 +126,20 @@ PODS: - path_provider_foundation (0.0.1): - Flutter - FlutterMacOS - - permission_handler_apple (9.1.0): + - permission_handler_apple (9.0.4): - Flutter - platform_device_id (0.0.1): - Flutter - - ReachabilitySwift (5.0.0) - - SDWebImage (5.16.0): - - SDWebImage/Core (= 5.16.0) - - SDWebImage/Core (5.16.0) + - Reachability (3.2) + - SDWebImage (5.15.5): + - SDWebImage/Core (= 5.15.5) + - SDWebImage/Core (5.15.5) - share_plus (0.0.1): - Flutter - shared_preferences_foundation (0.0.1): - Flutter - FlutterMacOS - - SwiftProtobuf (1.22.0) + - SwiftProtobuf (1.21.0) - SwiftyGif (5.4.4) - uni_links (0.0.1): - Flutter @@ -153,7 +153,7 @@ PODS: DEPENDENCIES: - barcode_scan2 (from `.symlinks/plugins/barcode_scan2/ios`) - - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) + - connectivity (from `.symlinks/plugins/connectivity/ios`) - CryptoSwift - cw_haven (from `.symlinks/plugins/cw_haven/ios`) - cw_monero (from `.symlinks/plugins/cw_monero/ios`) @@ -188,7 +188,7 @@ SPEC REPOS: - DKPhotoGallery - MTBBarcodeScanner - OrderedSet - - ReachabilitySwift + - Reachability - SDWebImage - SwiftProtobuf - SwiftyGif @@ -197,8 +197,8 @@ SPEC REPOS: EXTERNAL SOURCES: barcode_scan2: :path: ".symlinks/plugins/barcode_scan2/ios" - connectivity_plus: - :path: ".symlinks/plugins/connectivity_plus/ios" + connectivity: + :path: ".symlinks/plugins/connectivity/ios" cw_haven: :path: ".symlinks/plugins/cw_haven/ios" cw_monero: @@ -249,8 +249,8 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: barcode_scan2: 0af2bb63c81b4565aab6cd78278e4c0fa136dbb0 BigInt: f668a80089607f521586bbe29513d708491ef2f7 - connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e - CryptoSwift: d3d18dc357932f7e6d580689e065cf1f176007c1 + connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467 + CryptoSwift: 562f8eceb40e80796fffc668b0cad9313284cfa6 cw_haven: b3e54e1fbe7b8e6fda57a93206bc38f8e89b898a cw_monero: 4cf3b96f2da8e95e2ef7d6703dd4d2c509127b7d cw_shared_external: 2972d872b8917603478117c9957dfca611845a92 @@ -271,19 +271,19 @@ SPEC CHECKSUMS: OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62 path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8 - permission_handler_apple: 8f116445eff3c0e7c65ad60f5fef5490aa94b4e4 + permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce platform_device_id: 81b3e2993881f87d0c82ef151dc274df4869aef5 - ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 - SDWebImage: 2aea163b50bfcb569a2726b6a754c54a4506fcf6 + Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 + SDWebImage: fd7e1a22f00303e058058278639bf6196ee431fe share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68 shared_preferences_foundation: e2dae3258e06f44cc55f49d42024fd8dd03c590c - SwiftProtobuf: 40bd808372cb8706108f22d28f8ab4a6b9bc6989 + SwiftProtobuf: afced68785854575756db965e9da52bbf3dc45e7 SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f uni_links: d97da20c7701486ba192624d99bffaaffcfc298a UnstoppableDomainsResolution: c3c67f4d0a5e2437cb00d4bd50c2e00d6e743841 url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4 wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f -PODFILE CHECKSUM: 09df1114e7c360f55770d35a79356bf5446e0100 +PODFILE CHECKSUM: ae71bdf0eb731a1ffc399c122f6aa4dea0cb5f6f COCOAPODS: 1.11.3 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 05cf659e8..50b9da031 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -10,8 +10,8 @@ 0C44A71A2518EF8000B570ED /* decrypt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C44A7192518EF8000B570ED /* decrypt.swift */; }; 0C9D68C9264854B60011B691 /* secRandom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C9D68C8264854B60011B691 /* secRandom.swift */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 20ED0868E1BD7E12278C0CB3 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B26E3F56D69167FBB1DC160A /* Pods_Runner.framework */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 4DFD1BB54A3A50573E19A583 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C663361C56EBB242598F609 /* Pods_Runner.framework */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; @@ -23,13 +23,13 @@ 0C44A7192518EF8000B570ED /* decrypt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = decrypt.swift; sourceTree = ""; }; 0C9986A3251A932F00D566FD /* CryptoSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CryptoSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 0C9D68C8264854B60011B691 /* secRandom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = secRandom.swift; sourceTree = ""; }; - 11F9FC13F9EE2A705B213FA9 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 1F083F2041D1F553F2AF8B62 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 20F67A1B2C2FCB2A3BB048C1 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 3C663361C56EBB242598F609 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 501EA9286675DC8636978EA4 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 5AFFEBFC279AD49C00F906A4 /* wakeLock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = wakeLock.swift; sourceTree = ""; }; + 61CAA8652B54F23356F7592A /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; @@ -40,7 +40,7 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - AD0937B0140D5A4C24E73BEA /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + B26E3F56D69167FBB1DC160A /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -48,7 +48,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4DFD1BB54A3A50573E19A583 /* Pods_Runner.framework in Frameworks */, + 20ED0868E1BD7E12278C0CB3 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -59,7 +59,7 @@ isa = PBXGroup; children = ( 0C9986A3251A932F00D566FD /* CryptoSwift.framework */, - 3C663361C56EBB242598F609 /* Pods_Runner.framework */, + B26E3F56D69167FBB1DC160A /* Pods_Runner.framework */, ); name = Frameworks; sourceTree = ""; @@ -77,9 +77,9 @@ 84389F1A05D5860790D82820 /* Pods */ = { isa = PBXGroup; children = ( - 11F9FC13F9EE2A705B213FA9 /* Pods-Runner.debug.xcconfig */, - 1F083F2041D1F553F2AF8B62 /* Pods-Runner.release.xcconfig */, - AD0937B0140D5A4C24E73BEA /* Pods-Runner.profile.xcconfig */, + 20F67A1B2C2FCB2A3BB048C1 /* Pods-Runner.debug.xcconfig */, + 501EA9286675DC8636978EA4 /* Pods-Runner.release.xcconfig */, + 61CAA8652B54F23356F7592A /* Pods-Runner.profile.xcconfig */, ); path = Pods; sourceTree = ""; @@ -138,13 +138,13 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - B91154210ADCED81FBF06A85 /* [CP] Check Pods Manifest.lock */, + 0843B0813AFBAF53935AD24E /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 32D0076A9969C0C38D68AF62 /* [CP] Embed Pods Frameworks */, + DD8DB3179CA4E511F9954A6F /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -203,21 +203,26 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 32D0076A9969C0C38D68AF62 /* [CP] Embed Pods Frameworks */ = { + 0843B0813AFBAF53935AD24E /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Embed Pods Frameworks"; + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { @@ -250,26 +255,21 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n"; }; - B91154210ADCED81FBF06A85 /* [CP] Check Pods Manifest.lock */ = { + DD8DB3179CA4E511F9954A6F /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -390,7 +390,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = 1; VALID_ARCHS = arm64; VERSIONING_SYSTEM = "apple-generic"; }; @@ -537,7 +537,7 @@ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = 1; VALID_ARCHS = arm64; VERSIONING_SYSTEM = "apple-generic"; }; @@ -574,7 +574,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = 1; VALID_ARCHS = arm64; VERSIONING_SYSTEM = "apple-generic"; }; diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json index df5cf1cc5..6d834d4ee 100644 --- a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,25 +1,21 @@ { "images" : [ { - "filename" : "Icon-App-40x40@1x.png", "idiom" : "iphone", "scale" : "2x", "size" : "20x20" }, { - "filename" : "Icon-App-20x20@3x.png", "idiom" : "iphone", "scale" : "3x", "size" : "20x20" }, { - "filename" : "Icon-App-29x29@2x 1.png", "idiom" : "iphone", "scale" : "2x", "size" : "29x29" }, { - "filename" : "Icon-App-29x29@3x.png", "idiom" : "iphone", "scale" : "3x", "size" : "29x29" @@ -30,7 +26,6 @@ "size" : "40x40" }, { - "filename" : "Icon-App-40x40@3x.png", "idiom" : "iphone", "scale" : "3x", "size" : "40x40" @@ -48,31 +43,26 @@ "size" : "60x60" }, { - "filename" : "Icon-App-20x20@1x.png", "idiom" : "ipad", "scale" : "1x", "size" : "20x20" }, { - "filename" : "Icon-App-20x20@2x.png", "idiom" : "ipad", "scale" : "2x", "size" : "20x20" }, { - "filename" : "Icon-App-29x29@1x.png", "idiom" : "ipad", "scale" : "1x", "size" : "29x29" }, { - "filename" : "Icon-App-29x29@2x.png", "idiom" : "ipad", "scale" : "2x", "size" : "29x29" }, { - "filename" : "Icon-App-40x40@1x 1.png", "idiom" : "ipad", "scale" : "1x", "size" : "40x40" @@ -83,19 +73,16 @@ "size" : "40x40" }, { - "filename" : "Icon-App-76x76@1x.png", "idiom" : "ipad", "scale" : "1x", "size" : "76x76" }, { - "filename" : "Icon-App-76x76@2x.png", "idiom" : "ipad", "scale" : "2x", "size" : "76x76" }, { - "filename" : "Icon-App-83.5x83.5@2x.png", "idiom" : "ipad", "scale" : "2x", "size" : "83.5x83.5" diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png deleted file mode 100644 index 369d8d9a419ebc36e95c5cbfb488377456e99094..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 880 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 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index fb14bfc557bd6dbe135f1f9166839e8133a5cbb1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3332 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 FV1gC{mz)3q diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x 1.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x 1.png deleted file mode 100644 index 07acd0a82816d11e8ce99ae5896deadf6083da1d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3203 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 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png deleted file mode 100644 index 65ed7f3db173ea8f307efd0be90e41a9405a9158..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1997 zcmV;;2Qv7HP)yU(<&8d`%QI6*7R@CzG6K<;5k9e8DuaN^6?ur^ z#ulG6aHrg*kC@<6D8VxxO9Ky(9fq0zJOBSY6=nV~jI^E4=YIZwF6aL5cka38+;gr3 ze{hlf-T<9R_W+t(8e@>tDD)pb6utY%A?+!Js;LE4%5oIv-Nv13xwu!}^xFc;@hZ4_EJ9r93LM#) z^yGjNBN0|aZN&6tAz&Dh!EkNG#LNnBes&0>CQe4=@*p%fv>FB|mM{oC5Qhmby-I&E z-2(Se7)*ZU4cxw(jnv3E0|1F9I3|+d7Iib&ePMAdE*fdkI^j6!7|=6#38pRx(sMEm zD$DXvT5tyqHML|yQ}lIkgq7WJ+7@D+a9{6=z_!3OU|GSB3Ih%t{WKPB_#B;?wXv=o z8L`ng8NU~Ie=G*8dH6quhT0G61I0pL{M~;w%w+Zt;L>9{h3gn_d3Xfxal*pl;^BB~ z4P1rFl4`!k-q8k*W1T2)%g|6)hkxhZK;exd>|Gy)w9jJTAHErGzJUZ6PH^vZ1}6+S z*3AiH+~#%&cWBER#D_(2uW*?)5x(ofFldb8F)wFPoPUKJ;3FK3`w|~7U5U)ZgUCLS zr4O7i;GDOD(UECSB}5^99k;?F1aAKr(-sB`gdc`h^*Pc>!K8U9*zCO+SB_`tMJ5Pn zDesAK?jC|8N(*wxJQNR!Cv;y7Cd_$Fk9io3Re0jVW7c?E@i#Qpw-^rS3*w`6!9s_i#k1rbps9< zF+x!L+BZkhO4f0i{UW7R11nT40{TlZ&_qLkYF=frod|yY#c(v$5TLft+g5~tr^UFG z(+b`?Q|8Y_azw0QfY$a;32OgzEr)-Oc)^7Wayhj?UOfwi6$5h$#dXBv*;nf;6J-qK zM!+vB^0__?>RVZUrM2T-I4cQK8PC834PcDLlVQH-y`XTCv-%+(Zffv_RSEILFx3;yt_NXeplYhVKMjeY= z)MnZ+s8%ub4qPN>NGEg7p%t{?Oi$*`sA%)Mi}Ul_eOqrp<p2Q0|Fj%TNN z>C|?bG6Np@cQ{P@K~)|+r(UsS$+$VOv&Z;pjG(fTUQuK&GH+8^>;K-6Jf#sYd3B?uA$W& zVaD*Vys#P#cK#y(Elq0O6X*qa_A;eVO3LT@=p5no?j~d&O2h5!JVg6@Vb$(b%DSZ+ z3pMRjV@tG7qlF{qJNQvB&Lr!-db$A{YSlQKoIq8Z?qxLXWs8u6c&wc<7pM29qpnJU zpdEW)X**bOmWCQ7V&8oe8M{-u0;e00ldraYifOL~@a3W|d1lgVtWAu^2R=)Ym2m+} zM~=j-WxjBI#R~(5kE6ofl0r!>O7e4Y@vATCd;dbUvX;+&f_FyX`nhvBwkOSSz=GT& zGUF~xrQ}jbo}aM*TQ3j6=K;%+do~9tQSp3}(D5Oq!?&fG;$8DY{h{NBAYkhbN*MkE zH}3$lgdb9)zc37tleo|@IJ>_L3+sM@I{k(@W6Ozb+`4oGC%)K+>)(EZijqpy*8oPw zfV`gtM!8O=y2ghhz&x^u5kHQ5`fb?*3rj2P35zleu(I?X)vG=TOU``oVO_$A#2ESF z9KLZL(cDl$URuL>H+q=ba5%chQ9?OCp!lQ(C`*f^rOh zUUe=E?LQm7=_d?k`G-Mj)(cU~f}v?2eL64Plfq*u^g@za?WJpTuLggp1MG$)q6U_ zZ&=k-Uwof=g>Rh5Y>XjyaNw_idzeZo+_a#&TnS}iAu5$k`WEWl2l%*DmA6pKqqn?n f`zHPbxBUMDPrkd7gh*1O00000NkvXXu0mjf{)@mP diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png deleted file mode 100644 index 80e78be415a375258c3aef7d46658f5906bf1f2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7194 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 cfUCLw2Qr_Ii_@%07*qoM6N<$f(zy0?*IS* diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png deleted file mode 100644 index e06998b675c1d3c62e7006480a526c509e28a92d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4305 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 secrets.moonPayApiKey; static String get _secretKey => secrets.moonPaySecretKey; final bool isTest; final String baseUrl; - Future requestUrl( - {required CryptoCurrency currency, - required String refundWalletAddress, - required SettingsStore settingsStore}) async { - - final customParams = { - 'theme': themeToMoonPayTheme(settingsStore.currentTheme), - 'language': settingsStore.languageCode, - 'colorCode': settingsStore.currentTheme.type == ThemeType.dark - ? '#${Palette.blueCraiola.value.toRadixString(16).substring(2, 8)}' - : '#${Palette.moderateSlateBlue.value.toRadixString(16).substring(2, 8)}', - }; - + Future requestUrl({required CryptoCurrency currency, required String refundWalletAddress}) async { final originalUri = Uri.https( baseUrl, '', { 'apiKey': _apiKey, 'defaultBaseCurrencyCode': currency.toString().toLowerCase(), 'refundWalletAddress': refundWalletAddress - }..addAll(customParams)); + }); final messageBytes = utf8.encode('?${originalUri.query}'); final key = utf8.encode(_secretKey); final hmac = Hmac(sha256, key); diff --git a/lib/di.dart b/lib/di.dart index 6e68346df..4bcef4982 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -18,9 +18,10 @@ import 'package:cake_wallet/ionia/ionia_gift_card.dart'; import 'package:cake_wallet/ionia/ionia_tip.dart'; import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/src/screens/anonpay_details/anonpay_details_page.dart'; -import 'package:cake_wallet/src/screens/buy/webview_page.dart'; +import 'package:cake_wallet/src/screens/buy/onramper_page.dart'; import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/transactions_page.dart'; +import 'package:cake_wallet/src/screens/buy/payfura_page.dart'; import 'package:cake_wallet/src/screens/dashboard/desktop_dashboard_page.dart'; import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart'; import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart'; @@ -47,11 +48,9 @@ import 'package:cake_wallet/themes/theme_list.dart'; import 'package:cake_wallet/utils/device_info.dart'; import 'package:cake_wallet/store/anonpay/anonpay_transactions_store.dart'; import 'package:cake_wallet/utils/payment_request.dart'; -import 'package:cake_wallet/utils/responsive_layout_util.dart'; import 'package:cake_wallet/view_model/dashboard/desktop_sidebar_view_model.dart'; import 'package:cake_wallet/view_model/anon_invoice_page_view_model.dart'; import 'package:cake_wallet/view_model/anonpay_details_view_model.dart'; -import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/receive_option_view_model.dart'; import 'package:cake_wallet/view_model/ionia/ionia_auth_view_model.dart'; import 'package:cake_wallet/view_model/ionia/ionia_buy_card_view_model.dart'; @@ -261,7 +260,7 @@ Future setup({ nodeSource: _nodeSource, isBitcoinBuyEnabled: isBitcoinBuyEnabled, // Enforce darkTheme on platforms other than mobile till the design for other themes is completed - initialTheme: ResponsiveLayoutUtil.instance.isMobile && DeviceInfo.instance.isMobile ? null : ThemeList.darkTheme, + initialTheme: DeviceInfo.instance.isMobile ? null : ThemeList.darkTheme, ); if (_isSetupFinished) { @@ -692,13 +691,15 @@ Future setup({ wallet: getIt.get().wallet!, )); - getIt.registerFactoryParam((title, uri) => WebViewPage(title, uri)); + getIt.registerFactory(() => OnRamperPage(getIt.get())); getIt.registerFactory(() => PayfuraBuyProvider( settingsStore: getIt.get().settingsStore, wallet: getIt.get().wallet!, )); + getIt.registerFactory(() => PayFuraPage(getIt.get())); + getIt.registerFactory(() => ExchangeViewModel( getIt.get().wallet!, _tradesSource, @@ -895,8 +896,6 @@ Future setup({ getIt.registerFactory(() => IoniaGiftCardsListViewModel(ioniaService: getIt.get())); - getIt.registerFactory(()=> MarketPlaceViewModel(getIt.get())); - getIt.registerFactory(() => IoniaAuthViewModel(ioniaService: getIt.get())); getIt.registerFactoryParam( @@ -926,7 +925,7 @@ Future setup({ return IoniaVerifyIoniaOtp(getIt.get(), email, isSignIn); }); - getIt.registerFactory(() => IoniaWelcomePage()); + getIt.registerFactory(() => IoniaWelcomePage(getIt.get())); getIt.registerFactoryParam((List args, _) { final merchant = args.first as IoniaMerchant; diff --git a/lib/entities/language_service.dart b/lib/entities/language_service.dart index 87ee99ff5..05e84cef9 100644 --- a/lib/entities/language_service.dart +++ b/lib/entities/language_service.dart @@ -55,11 +55,11 @@ class LanguageService { 'cs': 'czk', 'ur': 'pak', 'id': 'idn', - 'yo': 'nga', + 'yo': 'yor', 'ha': 'hau' }; - static final list = {}; + static final list = {}; static void loadLocaleList() { supportedLocales.forEach((key, value) { diff --git a/lib/entities/main_actions.dart b/lib/entities/main_actions.dart index 0cf3cead4..f7a322096 100644 --- a/lib/entities/main_actions.dart +++ b/lib/entities/main_actions.dart @@ -1,5 +1,6 @@ import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart'; import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart'; +import 'package:cake_wallet/buy/payfura/payfura_buy_provider.dart'; import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/routes.dart'; @@ -47,20 +48,22 @@ class MainActions { case WalletType.bitcoin: case WalletType.litecoin: if (viewModel.isEnabledBuyAction) { - final uri = getIt.get().requestUrl(); if (DeviceInfo.instance.isMobile) { - Navigator.of(context) - .pushNamed(Routes.webViewPage, arguments: [S.of(context).buy, uri]); + Navigator.of(context).pushNamed(Routes.onramperPage); } else { + final uri = getIt.get().requestUrl(); await launchUrl(uri); } } break; case WalletType.monero: if (viewModel.isEnabledBuyAction) { - // final uri = getIt.get().requestUrl(); - final uri = Uri.parse("https://monero.com/trade"); - await launchUrl(uri); + if (DeviceInfo.instance.isMobile) { + Navigator.of(context).pushNamed(Routes.payfuraPage); + } else { + final uri = getIt.get().requestUrl(); + await launchUrl(uri); + } } break; default: @@ -115,22 +118,14 @@ class MainActions { switch (walletType) { case WalletType.bitcoin: - case WalletType.litecoin: if (viewModel.isEnabledSellAction) { final moonPaySellProvider = MoonPaySellProvider(); final uri = await moonPaySellProvider.requestUrl( currency: viewModel.wallet.currency, refundWalletAddress: viewModel.wallet.walletAddresses.address, - settingsStore: viewModel.settingsStore, ); - if (DeviceInfo.instance.isMobile) { - Navigator.of(context).pushNamed(Routes.webViewPage, - arguments: [S.of(context).sell, uri]); - } else { - await launchUrl(uri); - } + await launchUrl(uri); } - break; default: await showPopUp( diff --git a/lib/exchange/changenow/changenow_exchange_provider.dart b/lib/exchange/changenow/changenow_exchange_provider.dart index b37a513ac..89d32fa09 100644 --- a/lib/exchange/changenow/changenow_exchange_provider.dart +++ b/lib/exchange/changenow/changenow_exchange_provider.dart @@ -192,11 +192,11 @@ class ChangeNowExchangeProvider extends ExchangeProvider { final expectedSendAmount = responseJSON['expectedAmountFrom'].toString(); final status = responseJSON['status'] as String; final state = TradeState.deserialize(raw: status); - final extraId = responseJSON['payinExtraId'] as String?; - final outputTransaction = responseJSON['payoutHash'] as String?; - final expiredAtRaw = responseJSON['validUntil'] as String?; + final extraId = responseJSON['payinExtraId'] as String; + final outputTransaction = responseJSON['payoutHash'] as String; + final expiredAtRaw = responseJSON['validUntil'] as String; final payoutAddress = responseJSON['payoutAddress'] as String; - final expiredAt = DateTime.tryParse(expiredAtRaw ?? '')?.toLocal(); + final expiredAt = DateTime.tryParse(expiredAtRaw)?.toLocal(); return Trade( id: id, diff --git a/lib/exchange/sideshift/sideshift_exchange_provider.dart b/lib/exchange/sideshift/sideshift_exchange_provider.dart index 26575f2c1..a5b0c990f 100644 --- a/lib/exchange/sideshift/sideshift_exchange_provider.dart +++ b/lib/exchange/sideshift/sideshift_exchange_provider.dart @@ -19,10 +19,10 @@ class SideShiftExchangeProvider extends ExchangeProvider { static const affiliateId = secrets.sideShiftAffiliateId; static const apiBaseUrl = 'https://sideshift.ai/api'; - static const rangePath = '/v2/pair'; - static const orderPath = '/v2/shifts'; - static const quotePath = '/v2/quotes'; - static const permissionPath = '/v2/permissions'; + static const rangePath = '/v1/pairs'; + static const orderPath = '/v1/orders'; + static const quotePath = '/v1/quotes'; + static const permissionPath = '/v1/permissions'; static const List _notSupported = [ CryptoCurrency.xhv, @@ -36,22 +36,23 @@ class SideShiftExchangeProvider extends ExchangeProvider { CryptoCurrency.scrt, CryptoCurrency.stx, CryptoCurrency.bttc, - CryptoCurrency.usdt, - CryptoCurrency.eos, ]; static List _supportedPairs() { - final supportedCurrencies = - CryptoCurrency.all.where((element) => !_notSupported.contains(element)).toList(); + final supportedCurrencies = CryptoCurrency.all + .where((element) => !_notSupported.contains(element)) + .toList(); return supportedCurrencies - .map((i) => supportedCurrencies.map((k) => ExchangePair(from: i, to: k, reverse: true))) + .map((i) => supportedCurrencies + .map((k) => ExchangePair(from: i, to: k, reverse: true))) .expand((i) => i) .toList(); } @override - ExchangeProviderDescription get description => ExchangeProviderDescription.sideShift; + ExchangeProviderDescription get description => + ExchangeProviderDescription.sideShift; @override Future fetchRate( @@ -64,18 +65,17 @@ class SideShiftExchangeProvider extends ExchangeProvider { if (amount == 0) { return 0.0; } - - final fromCurrency = from.title.toLowerCase(); - final toCurrency = to.title.toLowerCase(); - final depositNetwork = _networkFor(from); - final settleNetwork = _networkFor(to); - - final url = "$apiBaseUrl$rangePath/$fromCurrency-$depositNetwork/$toCurrency-$settleNetwork"; - + final fromCurrency = _normalizeCryptoCurrency(from); + final toCurrency = _normalizeCryptoCurrency(to); + final url = + apiBaseUrl + rangePath + '/' + fromCurrency + '/' + toCurrency; final uri = Uri.parse(url); final response = await get(uri); final responseJSON = json.decode(response.body) as Map; final rate = double.parse(responseJSON['rate'] as String); + final max = double.parse(responseJSON['max'] as String); + + if (amount > max) return 0.00; return rate; } catch (_) { @@ -101,38 +101,25 @@ class SideShiftExchangeProvider extends ExchangeProvider { } final responseJSON = json.decode(response.body) as Map; - final cancreateShift = responseJSON['createShift'] as bool; - return cancreateShift; + final canCreateOrder = responseJSON['createOrder'] as bool; + final canCreateQuote = responseJSON['createQuote'] as bool; + return canCreateOrder && canCreateQuote; } @override - Future createTrade({required TradeRequest request, required bool isFixedRateMode}) async { + Future createTrade( + {required TradeRequest request, required bool isFixedRateMode}) async { final _request = request as SideShiftRequest; - String url = ''; - final depositCoin = request.depositMethod.title.toLowerCase(); - final settleCoin = request.settleMethod.title.toLowerCase(); + final quoteId = await _createQuote(_request); + final url = apiBaseUrl + orderPath; + final headers = {'Content-Type': 'application/json'}; final body = { + 'type': 'fixed', + 'quoteId': quoteId, 'affiliateId': affiliateId, 'settleAddress': _request.settleAddress, - 'refundAddress': _request.refundAddress, + 'refundAddress': _request.refundAddress }; - - if (isFixedRateMode) { - final quoteId = await _createQuote(_request); - body['quoteId'] = quoteId; - - url = apiBaseUrl + orderPath + '/fixed'; - } else { - url = apiBaseUrl + orderPath + '/variable'; - final depositNetwork = _networkFor(request.depositMethod); - final settleNetwork = _networkFor(request.settleMethod); - body["depositCoin"] = depositCoin; - body["settleCoin"] = settleCoin; - body["settleNetwork"] = settleNetwork; - body["depositNetwork"] = depositNetwork; - } - final headers = {'Content-Type': 'application/json'}; - final uri = Uri.parse(url); final response = await post(uri, headers: headers, body: json.encode(body)); @@ -149,9 +136,8 @@ class SideShiftExchangeProvider extends ExchangeProvider { final responseJSON = json.decode(response.body) as Map; final id = responseJSON['id'] as String; - final inputAddress = responseJSON['depositAddress'] as String; - final settleAddress = responseJSON['settleAddress'] as String; - final depositAmount = responseJSON['depositAmount'] as String?; + final inputAddress = responseJSON['depositAddress']['address'] as String; + final settleAddress = responseJSON['settleAddress']['address'] as String; return Trade( id: id, @@ -161,7 +147,7 @@ class SideShiftExchangeProvider extends ExchangeProvider { inputAddress: inputAddress, refundAddress: settleAddress, state: TradeState.created, - amount: depositAmount ?? _request.depositAmount, + amount: _request.depositAmount, payoutAddress: settleAddress, createdAt: DateTime.now(), ); @@ -170,17 +156,13 @@ class SideShiftExchangeProvider extends ExchangeProvider { Future _createQuote(SideShiftRequest request) async { final url = apiBaseUrl + quotePath; final headers = {'Content-Type': 'application/json'}; - final depositMethod = request.depositMethod.title.toLowerCase(); - final settleMethod = request.settleMethod.title.toLowerCase(); - final depositNetwork = _networkFor(request.depositMethod); - final settleNetwork = _networkFor(request.settleMethod); + final depositMethod = _normalizeCryptoCurrency(request.depositMethod); + final settleMethod = _normalizeCryptoCurrency(request.settleMethod); final body = { - 'depositCoin': depositMethod, - 'settleCoin': settleMethod, + 'depositMethod': depositMethod, + 'settleMethod': settleMethod, 'affiliateId': affiliateId, - 'settleAmount': request.depositAmount, - 'settleNetwork': settleNetwork, - 'depositNetwork': depositNetwork, + 'depositAmount': request.depositAmount, }; final uri = Uri.parse(url); final response = await post(uri, headers: headers, body: json.encode(body)); @@ -207,15 +189,9 @@ class SideShiftExchangeProvider extends ExchangeProvider { {required CryptoCurrency from, required CryptoCurrency to, required bool isFixedRateMode}) async { - final fromCurrency = isFixedRateMode ? to : from; - final toCurrency = isFixedRateMode ? from : to; - - final fromNetwork = _networkFor(fromCurrency); - final toNetwork = _networkFor(toCurrency); - - final url = - "$apiBaseUrl$rangePath/${fromCurrency.title.toLowerCase()}-$fromNetwork/${toCurrency.title.toLowerCase()}-$toNetwork"; - + final fromCurrency = _normalizeCryptoCurrency(from); + final toCurrency = _normalizeCryptoCurrency(to); + final url = apiBaseUrl + rangePath + '/' + fromCurrency + '/' + toCurrency; final uri = Uri.parse(url); final response = await get(uri); @@ -234,14 +210,6 @@ class SideShiftExchangeProvider extends ExchangeProvider { final min = double.tryParse(responseJSON['min'] as String? ?? ''); final max = double.tryParse(responseJSON['max'] as String? ?? ''); - if (isFixedRateMode) { - final currentRate = double.parse(responseJSON['rate'] as String); - return Limits( - min: min != null ? (min * currentRate) : null, - max: max != null ? (max * currentRate) : null, - ); - } - return Limits(min: min, max: max); } @@ -259,7 +227,8 @@ class SideShiftExchangeProvider extends ExchangeProvider { final responseJSON = json.decode(response.body) as Map; final error = responseJSON['error']['message'] as String; - throw TradeNotFoundException(id, provider: description, description: error); + throw TradeNotFoundException(id, + provider: description, description: error); } if (response.statusCode != 200) { @@ -267,32 +236,36 @@ class SideShiftExchangeProvider extends ExchangeProvider { } final responseJSON = json.decode(response.body) as Map; - final fromCurrency = responseJSON['depositCoin'] as String; + final fromCurrency = responseJSON['depositMethodId'] as String; final from = CryptoCurrency.fromString(fromCurrency); - final toCurrency = responseJSON['settleCoin'] as String; + final toCurrency = responseJSON['settleMethodId'] as String; final to = CryptoCurrency.fromString(toCurrency); - final inputAddress = responseJSON['depositAddress'] as String; - final expectedSendAmount = responseJSON['depositAmount'] as String?; - final status = responseJSON['status'] as String?; - final settleAddress = responseJSON['settleAddress'] as String; + final inputAddress = responseJSON['depositAddress']['address'] as String; + final expectedSendAmount = responseJSON['depositAmount'].toString(); + final deposits = responseJSON['deposits'] as List?; + final settleAddress = responseJSON['settleAddress']['address'] as String; TradeState? state; + String? status; + if (deposits?.isNotEmpty ?? false) { + status = deposits![0]['status'] as String?; + } state = TradeState.deserialize(raw: status ?? 'created'); - final isVariable = (responseJSON['type'] as String) == 'variable'; - final expiredAtRaw = responseJSON['expiresAt'] as String; - final expiredAt = isVariable ? null : DateTime.tryParse(expiredAtRaw)?.toLocal(); + final expiredAtRaw = responseJSON['expiresAtISO'] as String; + final expiredAt = DateTime.tryParse(expiredAtRaw)?.toLocal(); return Trade( - id: id, - from: from, - to: to, - provider: description, - inputAddress: inputAddress, - amount: expectedSendAmount ?? '', - state: state, - expiredAt: expiredAt, - payoutAddress: settleAddress); + id: id, + from: from, + to: to, + provider: description, + inputAddress: inputAddress, + amount: expectedSendAmount, + state: state, + expiredAt: expiredAt, + payoutAddress: settleAddress + ); } @override @@ -307,25 +280,28 @@ class SideShiftExchangeProvider extends ExchangeProvider { @override String get title => 'SideShift'; - String _networkFor(CryptoCurrency currency) => - currency.tag != null ? _normalizeTag(currency.tag!) : 'mainnet'; - - String _normalizeTag(String tag) { - switch (tag) { - case 'ETH': - return 'ethereum'; - case 'TRX': - return 'tron'; - case 'LN': - return 'lightning'; - case 'POLY': + static String _normalizeCryptoCurrency(CryptoCurrency currency) { + switch (currency) { + case CryptoCurrency.zaddr: + return 'zaddr'; + case CryptoCurrency.zec: + return 'zec'; + case CryptoCurrency.bnb: + return currency.tag!.toLowerCase(); + case CryptoCurrency.usdterc20: + return 'usdtErc20'; + case CryptoCurrency.usdttrc20: + return 'usdtTrc20'; + case CryptoCurrency.usdcpoly: + return 'usdcpolygon'; + case CryptoCurrency.usdcsol: + return 'usdcsol'; + case CryptoCurrency.maticpoly: return 'polygon'; - case 'ZEC': - return 'zcash'; - case 'AVAXC': - return 'avax'; + case CryptoCurrency.btcln: + return 'ln'; default: - return tag.toLowerCase(); + return currency.title.toLowerCase(); } } } diff --git a/lib/main.dart b/lib/main.dart index b8e901d15..bb7b673d6 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -6,7 +6,6 @@ import 'package:cake_wallet/buy/order.dart'; import 'package:cake_wallet/locales/locale.dart'; import 'package:cake_wallet/store/yat/yat_store.dart'; import 'package:cake_wallet/utils/exception_handler.dart'; -import 'package:cake_wallet/utils/responsive_layout_util.dart'; import 'package:cw_core/root_dir.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; @@ -196,9 +195,7 @@ class App extends StatefulWidget { class AppState extends State with SingleTickerProviderStateMixin { AppState() : yatStore = getIt.get() { SystemChrome.setPreferredOrientations( - ResponsiveLayoutUtil.instance.isIpad ? - [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight] : - [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]); + [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]); } YatStore yatStore; diff --git a/lib/reactions/check_connection.dart b/lib/reactions/check_connection.dart index 9185ffe15..6b7b79941 100644 --- a/lib/reactions/check_connection.dart +++ b/lib/reactions/check_connection.dart @@ -1,9 +1,10 @@ import 'dart:async'; -import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/sync_status.dart'; import 'package:cake_wallet/store/settings_store.dart'; +import 'package:connectivity/connectivity.dart'; + Timer? _checkConnectionTimer; void startCheckConnectionReaction( diff --git a/lib/router.dart b/lib/router.dart index 7abfe7e64..db7843d6d 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -8,7 +8,8 @@ import 'package:cake_wallet/src/screens/anonpay_details/anonpay_details_page.dar import 'package:cake_wallet/src/screens/backup/backup_page.dart'; import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart'; import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart'; -import 'package:cake_wallet/src/screens/buy/webview_page.dart'; +import 'package:cake_wallet/src/screens/buy/onramper_page.dart'; +import 'package:cake_wallet/src/screens/buy/payfura_page.dart'; import 'package:cake_wallet/src/screens/buy/pre_order_page.dart'; import 'package:cake_wallet/src/screens/restore/sweeping_wallet_page.dart'; import 'package:cake_wallet/src/screens/receive/anonpay_invoice_page.dart'; @@ -189,6 +190,7 @@ Route createRoute(RouteSettings settings) { fullscreenDialog: true); } else if (isSingleCoin) { return MaterialPageRoute( + fullscreenDialog: true, builder: (_) => getIt.get( param1: availableWalletTypes.first )); @@ -209,6 +211,7 @@ Route createRoute(RouteSettings settings) { case Routes.restoreWallet: return MaterialPageRoute( + fullscreenDialog: true, builder: (_) => getIt.get( param1: settings.arguments as WalletType)); @@ -218,7 +221,6 @@ Route createRoute(RouteSettings settings) { case Routes.dashboard: return CupertinoPageRoute( - settings: settings, builder: (_) => getIt.get()); case Routes.send: @@ -504,8 +506,7 @@ Route createRoute(RouteSettings settings) { return CupertinoPageRoute( builder: (_) => getIt.get()); case Routes.ioniaManageCardsPage: - return CupertinoPageRoute( - builder: (_) => getIt.get()); + return CupertinoPageRoute(builder: (_) => getIt.get()); case Routes.ioniaBuyGiftCardPage: final args = settings.arguments as List; @@ -555,13 +556,11 @@ Route createRoute(RouteSettings settings) { param1: paymentInfo, param2: commitedInfo)); - case Routes.webViewPage: - final args = settings.arguments as List; - final title = args.first as String; - final url = args[1] as Uri; - return CupertinoPageRoute(builder: (_) => getIt.get( - param1: title, - param2: url)); + case Routes.onramperPage: + return CupertinoPageRoute(builder: (_) => getIt.get()); + + case Routes.payfuraPage: + return CupertinoPageRoute(builder: (_) => getIt.get()); case Routes.advancedPrivacySettings: final type = settings.arguments as WalletType; @@ -575,6 +574,7 @@ Route createRoute(RouteSettings settings) { case Routes.anonPayInvoicePage: final args = settings.arguments as List; return CupertinoPageRoute( + fullscreenDialog: true, builder: (_) => getIt.get(param1: args)); case Routes.anonPayReceivePage: diff --git a/lib/routes.dart b/lib/routes.dart index 6b2effb88..9b7e89c20 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -70,7 +70,7 @@ class Routes { static const ioniaPaymentStatusPage = '/ionia_payment_status_page'; static const ioniaMoreOptionsPage = '/ionia_more_options_page'; static const ioniaCustomRedeemPage = '/ionia_custom_redeem_page'; - static const webViewPage = '/web_view_page'; + static const onramperPage = '/onramper'; static const connectionSync = '/connection_sync_page'; static const securityBackupPage = '/security_and_backup_page'; static const privacyPage = '/privacy_page'; @@ -83,6 +83,7 @@ class Routes { static const anonPayInvoicePage = '/anon_pay_invoice_page'; static const anonPayReceivePage = '/anon_pay_receive_page'; static const anonPayDetailsPage = '/anon_pay_details_page'; + static const payfuraPage = '/pay_fura_page'; static const desktop_actions = '/desktop_actions'; static const transactionsPage = '/transactions_page'; static const setup_2faPage = '/setup_2fa_page'; diff --git a/lib/src/screens/buy/webview_page.dart b/lib/src/screens/buy/onramper_page.dart similarity index 68% rename from lib/src/screens/buy/webview_page.dart rename to lib/src/screens/buy/onramper_page.dart index 205b87c47..cbdf9e1b1 100644 --- a/lib/src/screens/buy/webview_page.dart +++ b/lib/src/screens/buy/onramper_page.dart @@ -5,32 +5,33 @@ import 'package:flutter/material.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:permission_handler/permission_handler.dart'; -class WebViewPage extends BasePage { - WebViewPage(this._title, this._url); +class OnRamperPage extends BasePage { + OnRamperPage(this._onRamperBuyProvider); - final String _title; - final Uri _url; + final OnRamperBuyProvider _onRamperBuyProvider; @override - String get title => _title; + String get title => S.current.buy; @override Widget body(BuildContext context) { - return WebViewPageBody(_url); + return OnRamperPageBody(_onRamperBuyProvider); } } -class WebViewPageBody extends StatefulWidget { - WebViewPageBody(this.uri); +class OnRamperPageBody extends StatefulWidget { + OnRamperPageBody(this.onRamperBuyProvider); - final Uri uri; + final OnRamperBuyProvider onRamperBuyProvider; + + Uri get uri => onRamperBuyProvider.requestUrl(); @override - WebViewPageBodyState createState() => WebViewPageBodyState(); + OnRamperPageBodyState createState() => OnRamperPageBodyState(); } -class WebViewPageBodyState extends State { - WebViewPageBodyState(); +class OnRamperPageBodyState extends State { + OnRamperPageBodyState(); @override Widget build(BuildContext context) { diff --git a/lib/src/screens/buy/payfura_page.dart b/lib/src/screens/buy/payfura_page.dart new file mode 100644 index 000000000..a974aec25 --- /dev/null +++ b/lib/src/screens/buy/payfura_page.dart @@ -0,0 +1,58 @@ +import 'package:cake_wallet/buy/payfura/payfura_buy_provider.dart'; +import 'package:cake_wallet/generated/i18n.dart'; +import 'package:cake_wallet/src/screens/base_page.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:permission_handler/permission_handler.dart'; + +class PayFuraPage extends BasePage { + PayFuraPage(this._PayfuraBuyProvider); + + final PayfuraBuyProvider _PayfuraBuyProvider; + + @override + String get title => S.current.buy; + + @override + Widget body(BuildContext context) { + return PayFuraPageBody(_PayfuraBuyProvider); + } +} + +class PayFuraPageBody extends StatefulWidget { + PayFuraPageBody(this._PayfuraBuyProvider); + + final PayfuraBuyProvider _PayfuraBuyProvider; + + Uri get uri => _PayfuraBuyProvider.requestUrl(); + + @override + PayFuraPageBodyState createState() => PayFuraPageBodyState(); +} + +class PayFuraPageBodyState extends State { + PayFuraPageBodyState(); + + @override + Widget build(BuildContext context) { + return InAppWebView( + initialOptions: InAppWebViewGroupOptions( + crossPlatform: InAppWebViewOptions(transparentBackground: true), + ), + initialUrlRequest: URLRequest(url: widget.uri), + androidOnPermissionRequest: (_, __, resources) async { + bool permissionGranted = await Permission.camera.status == PermissionStatus.granted; + if (!permissionGranted) { + permissionGranted = await Permission.camera.request().isGranted; + } + + return PermissionRequestResponse( + resources: resources, + action: permissionGranted + ? PermissionRequestResponseAction.GRANT + : PermissionRequestResponseAction.DENY, + ); + }, + ); + } +} diff --git a/lib/src/screens/dashboard/dashboard_page.dart b/lib/src/screens/dashboard/dashboard_page.dart index 94717f93f..2b485aa7a 100644 --- a/lib/src/screens/dashboard/dashboard_page.dart +++ b/lib/src/screens/dashboard/dashboard_page.dart @@ -5,7 +5,7 @@ import 'package:cake_wallet/entities/main_actions.dart'; import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/market_place_page.dart'; import 'package:cake_wallet/utils/version_comparator.dart'; -import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart'; +import 'package:cake_wallet/wallet_type_utils.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/src/screens/yat_emoji_id.dart'; @@ -27,6 +27,8 @@ import 'package:mobx/mobx.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:smooth_page_indicator/smooth_page_indicator.dart'; import 'package:cake_wallet/main.dart'; +import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart'; +import 'package:url_launcher/url_launcher.dart'; import 'package:cake_wallet/src/screens/release_notes/release_notes_screen.dart'; class DashboardPage extends StatelessWidget { @@ -43,7 +45,7 @@ class DashboardPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - body: ResponsiveLayoutUtil.instance.isMobile + body: ResponsiveLayoutUtil.instance.isMobile(context) ? _DashboardPageView( balancePage: balancePage, dashboardViewModel: dashboardViewModel, @@ -249,12 +251,7 @@ class _DashboardPageView extends BasePage { if (dashboardViewModel.shouldShowMarketPlaceInDashboard) { pages.add(Semantics( label: 'Marketplace Page', - child: MarketPlacePage( - dashboardViewModel: dashboardViewModel, - marketPlaceViewModel: getIt.get(), - ), - ), - ); + child: MarketPlacePage(dashboardViewModel: dashboardViewModel))); } pages.add(Semantics(label: 'Balance Page', child: balancePage)); pages.add(Semantics( diff --git a/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart b/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart index e8fa54b49..e5fa42390 100644 --- a/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart +++ b/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart @@ -1,9 +1,7 @@ -import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/entities/main_actions.dart'; import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_action_button.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/market_place_page.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; -import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart'; import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; @@ -72,10 +70,7 @@ class DesktopDashboardActions extends StatelessWidget { ], ), Expanded( - child: MarketPlacePage( - dashboardViewModel: dashboardViewModel, - marketPlaceViewModel: getIt.get(), - ), + child: MarketPlacePage(dashboardViewModel: dashboardViewModel), ), ], ); diff --git a/lib/src/screens/dashboard/widgets/address_page.dart b/lib/src/screens/dashboard/widgets/address_page.dart index a047e9f29..a5fac2053 100644 --- a/lib/src/screens/dashboard/widgets/address_page.dart +++ b/lib/src/screens/dashboard/widgets/address_page.dart @@ -73,7 +73,7 @@ class AddressPage extends BasePage { ? closeButtonImageDarkTheme : closeButtonImage; - bool isMobileView = ResponsiveLayoutUtil.instance.isMobile; + bool isMobileView = ResponsiveLayoutUtil.instance.isMobile(context); return MergeSemantics( child: SizedBox( @@ -273,7 +273,7 @@ class AddressPage extends BasePage { reaction((_) => receiveOptionViewModel.selectedReceiveOption, (ReceivePageOption option) { switch (option) { case ReceivePageOption.anonPayInvoice: - Navigator.pushNamed( + Navigator.pushReplacementNamed( context, Routes.anonPayInvoicePage, arguments: [addressListViewModel.address.address, option], @@ -285,7 +285,7 @@ class AddressPage extends BasePage { final onionUrl = sharedPreferences.getString(PreferencesKey.onionDonationLink); if (clearnetUrl != null && onionUrl != null) { - Navigator.pushNamed( + Navigator.pushReplacementNamed( context, Routes.anonPayReceivePage, arguments: AnonpayDonationLinkInfo( @@ -295,7 +295,7 @@ class AddressPage extends BasePage { ), ); } else { - Navigator.pushNamed( + Navigator.pushReplacementNamed( context, Routes.anonPayInvoicePage, arguments: [addressListViewModel.address.address, option], diff --git a/lib/src/screens/dashboard/widgets/balance_page.dart b/lib/src/screens/dashboard/widgets/balance_page.dart index 85d0fb0a1..6e2893429 100644 --- a/lib/src/screens/dashboard/widgets/balance_page.dart +++ b/lib/src/screens/dashboard/widgets/balance_page.dart @@ -120,22 +120,19 @@ class BalancePage extends StatelessWidget { .backgroundColor!, height: 1)), SizedBox(height: 5), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Expanded( - child: AutoSizeText(availableBalance, - style: TextStyle( - fontSize: 24, - fontFamily: 'Lato', - fontWeight: FontWeight.w900, - color: Theme.of(context) - .accentTextTheme! - .displayMedium! - .backgroundColor!, - height: 1), - maxLines: 1, - textAlign: TextAlign.start), - ), + Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ + AutoSizeText(availableBalance, + style: TextStyle( + fontSize: 24, + fontFamily: 'Lato', + fontWeight: FontWeight.w900, + color: Theme.of(context) + .accentTextTheme! + .displayMedium! + .backgroundColor!, + height: 1), + maxLines: 1, + textAlign: TextAlign.center), Text(currency, style: TextStyle( fontSize: 28, diff --git a/lib/src/screens/dashboard/widgets/market_place_page.dart b/lib/src/screens/dashboard/widgets/market_place_page.dart index 34250fe7e..a13193d6f 100644 --- a/lib/src/screens/dashboard/widgets/market_place_page.dart +++ b/lib/src/screens/dashboard/widgets/market_place_page.dart @@ -4,20 +4,16 @@ import 'package:cake_wallet/src/widgets/market_place_item.dart'; import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; -import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart'; import 'package:cw_core/wallet_type.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:url_launcher/url_launcher.dart'; class MarketPlacePage extends StatelessWidget { - MarketPlacePage({ - required this.dashboardViewModel, - required this.marketPlaceViewModel, - }); + + MarketPlacePage({required this.dashboardViewModel}); final DashboardViewModel dashboardViewModel; - final MarketPlaceViewModel marketPlaceViewModel; final _scrollController = ScrollController(); @override @@ -54,7 +50,7 @@ class MarketPlacePage extends StatelessWidget { if (!SettingsStoreBase.walletPasswordDirectInput) ...[SizedBox(height: 20), MarketPlaceItem( - onTap: () => _navigatorToGiftCardsPage(context), + onTap: () =>_navigatorToGiftCardsPage(context), title: S.of(context).cake_pay_title, subTitle: S.of(context).cake_pay_subtitle, )], @@ -76,13 +72,12 @@ class MarketPlacePage extends StatelessWidget { ), ); } - void _navigatorToGiftCardsPage(BuildContext context) { final walletType = dashboardViewModel.type; switch (walletType) { case WalletType.haven: - showPopUp( + showPopUp( context: context, builder: (BuildContext context) { return AlertWithOneAction( @@ -92,14 +87,9 @@ class MarketPlacePage extends StatelessWidget { buttonAction: () => Navigator.of(context).pop()); }); break; - default: - marketPlaceViewModel.isIoniaUserAuthenticated().then((value) { - if (value) { - Navigator.pushNamed(context, Routes.ioniaManageCardsPage); - return; - } - Navigator.of(context).pushNamed(Routes.ioniaWelcomePage); - }); + default: + Navigator.of(context).pushNamed(Routes.ioniaWelcomePage); } } + } diff --git a/lib/src/screens/dashboard/widgets/transactions_page.dart b/lib/src/screens/dashboard/widgets/transactions_page.dart index e92e97f04..c80edc8d9 100644 --- a/lib/src/screens/dashboard/widgets/transactions_page.dart +++ b/lib/src/screens/dashboard/widgets/transactions_page.dart @@ -25,126 +25,107 @@ class TransactionsPage extends StatelessWidget { @override Widget build(BuildContext context) { - return GestureDetector( - onLongPress: () => dashboardViewModel.balanceViewModel.isReversing = - !dashboardViewModel.balanceViewModel.isReversing, - onLongPressUp: () => dashboardViewModel.balanceViewModel.isReversing = - !dashboardViewModel.balanceViewModel.isReversing, - child: Container( - color: ResponsiveLayoutUtil.instance.isMobile - ? null - : Theme.of(context).colorScheme.background, - padding: EdgeInsets.only(top: 24, bottom: 24), - child: Column( - children: [ - HeaderRow(dashboardViewModel: dashboardViewModel), - Expanded(child: Observer(builder: (_) { - final items = dashboardViewModel.items; + return Container( + color: ResponsiveLayoutUtil.instance.isMobile(context) + ? null + : Theme.of(context).colorScheme.background, + padding: EdgeInsets.only(top: 24, bottom: 24), + child: Column( + children: [ + HeaderRow(dashboardViewModel: dashboardViewModel), + Expanded(child: Observer(builder: (_) { + final items = dashboardViewModel.items; - return items.isNotEmpty - ? ListView.builder( - itemCount: items.length, - itemBuilder: (context, index) { - final item = items[index]; + return items.isNotEmpty + ? ListView.builder( + itemCount: items.length, + itemBuilder: (context, index) { + final item = items[index]; - if (item is DateSectionItem) { - return DateSectionRaw(date: item.date); - } + if (item is DateSectionItem) { + return DateSectionRaw(date: item.date); + } - if (item is TransactionListItem) { - final transaction = item.transaction; + if (item is TransactionListItem) { + final transaction = item.transaction; - return Observer( - builder: (_) => TransactionRow( - onTap: () => Navigator.of(context).pushNamed( - Routes.transactionDetails, - arguments: transaction), - direction: transaction.direction, - formattedDate: DateFormat('HH:mm') - .format(transaction.date), - formattedAmount: item.formattedCryptoAmount, - formattedFiatAmount: dashboardViewModel - .balanceViewModel.isFiatDisabled - ? '' - : item.formattedFiatAmount, - isPending: transaction.isPending, - title: item.formattedTitle + - item.formattedStatus)); - } + return Observer( + builder: (_) => TransactionRow( + onTap: () => Navigator.of(context) + .pushNamed(Routes.transactionDetails, arguments: transaction), + direction: transaction.direction, + formattedDate: DateFormat('HH:mm').format(transaction.date), + formattedAmount: item.formattedCryptoAmount, + formattedFiatAmount: + dashboardViewModel.balanceViewModel.isFiatDisabled + ? '' + : item.formattedFiatAmount, + isPending: transaction.isPending, + title: item.formattedTitle + item.formattedStatus)); + } - if (item is AnonpayTransactionListItem) { - final transactionInfo = item.transaction; + if (item is AnonpayTransactionListItem) { + final transactionInfo = item.transaction; - return AnonpayTransactionRow( - onTap: () => Navigator.of(context).pushNamed( - Routes.anonPayDetailsPage, - arguments: transactionInfo), - currency: transactionInfo.fiatAmount != null - ? transactionInfo.fiatEquiv ?? '' - : CryptoCurrency.fromFullName( - transactionInfo.coinTo) - .name - .toUpperCase(), - provider: transactionInfo.provider, - amount: transactionInfo.fiatAmount?.toString() ?? - (transactionInfo.amountTo?.toString() ?? ''), - createdAt: DateFormat('HH:mm') - .format(transactionInfo.createdAt), - ); - } + return AnonpayTransactionRow( + onTap: () => Navigator.of(context) + .pushNamed(Routes.anonPayDetailsPage, arguments: transactionInfo), + currency: transactionInfo.fiatAmount != null + ? transactionInfo.fiatEquiv ?? '' + : CryptoCurrency.fromFullName(transactionInfo.coinTo) + .name + .toUpperCase(), + provider: transactionInfo.provider, + amount: transactionInfo.fiatAmount?.toString() ?? + (transactionInfo.amountTo?.toString() ?? ''), + createdAt: DateFormat('HH:mm').format(transactionInfo.createdAt), + ); + } - if (item is TradeListItem) { - final trade = item.trade; + if (item is TradeListItem) { + final trade = item.trade; - return Observer( - builder: (_) => TradeRow( - onTap: () => Navigator.of(context).pushNamed( - Routes.tradeDetails, - arguments: trade), - provider: trade.provider, - from: trade.from, - to: trade.to, + return Observer( + builder: (_) => TradeRow( + onTap: () => Navigator.of(context) + .pushNamed(Routes.tradeDetails, arguments: trade), + provider: trade.provider, + from: trade.from, + to: trade.to, + createdAtFormattedDate: trade.createdAt != null + ? DateFormat('HH:mm').format(trade.createdAt!) + : null, + formattedAmount: item.tradeFormattedAmount)); + } + + if (item is OrderListItem) { + final order = item.order; + + return Observer( + builder: (_) => OrderRow( + onTap: () => Navigator.of(context) + .pushNamed(Routes.orderDetails, arguments: order), + provider: order.provider, + from: order.from!, + to: order.to!, createdAtFormattedDate: - trade.createdAt != null - ? DateFormat('HH:mm') - .format(trade.createdAt!) - : null, - formattedAmount: item.tradeFormattedAmount)); - } + DateFormat('HH:mm').format(order.createdAt), + formattedAmount: item.orderFormattedAmount, + )); + } - if (item is OrderListItem) { - final order = item.order; - - return Observer( - builder: (_) => OrderRow( - onTap: () => Navigator.of(context) - .pushNamed(Routes.orderDetails, - arguments: order), - provider: order.provider, - from: order.from!, - to: order.to!, - createdAtFormattedDate: DateFormat('HH:mm') - .format(order.createdAt), - formattedAmount: item.orderFormattedAmount, - )); - } - - return Container(color: Colors.transparent, height: 1); - }) - : Center( - child: Text( - S.of(context).placeholder_transactions, - style: TextStyle( - fontSize: 14, - color: Theme.of(context) - .primaryTextTheme - .labelSmall! - .decorationColor!), - ), - ); - })) - ], - ), + return Container(color: Colors.transparent, height: 1); + }) + : Center( + child: Text( + S.of(context).placeholder_transactions, + style: TextStyle( + fontSize: 14, + color: Theme.of(context).primaryTextTheme!.labelSmall!.decorationColor!), + ), + ); + })) + ], ), ); } diff --git a/lib/src/screens/exchange/exchange_page.dart b/lib/src/screens/exchange/exchange_page.dart index 04d7d1201..6eea29b42 100644 --- a/lib/src/screens/exchange/exchange_page.dart +++ b/lib/src/screens/exchange/exchange_page.dart @@ -117,7 +117,7 @@ class ExchangePage extends BasePage { final _closeButton = currentTheme.type == ThemeType.dark ? closeButtonImageDarkTheme : closeButtonImage; - bool isMobileView = ResponsiveLayoutUtil.instance.isMobile; + bool isMobileView = ResponsiveLayoutUtil.instance.isMobile(context); return MergeSemantics( child: SizedBox( @@ -599,8 +599,8 @@ class ExchangePage extends BasePage { alertContent: S.of(context).low_fee_alert, leftButtonText: S.of(context).ignor, rightButtonText: S.of(context).use_suggested, - actionLeftButton: () => Navigator.of(dialogContext).pop(false), - actionRightButton: () => Navigator.of(dialogContext).pop(true)); + actionLeftButton: () => Navigator.of(context).pop(false), + actionRightButton: () => Navigator.of(context).pop(true)); }) ?? false; if (confirmed) { exchangeViewModel.setDefaultTransactionPriority(); @@ -731,7 +731,7 @@ class ExchangePage extends BasePage { }, )); - if (ResponsiveLayoutUtil.instance.isMobile) { + if (ResponsiveLayoutUtil.instance.isMobile(context)) { return MobileExchangeCardsSection( firstExchangeCard: firstExchangeCard, secondExchangeCard: secondExchangeCard, diff --git a/lib/src/screens/ionia/auth/ionia_welcome_page.dart b/lib/src/screens/ionia/auth/ionia_welcome_page.dart index 91d09c2db..4d0cf69c0 100644 --- a/lib/src/screens/ionia/auth/ionia_welcome_page.dart +++ b/lib/src/screens/ionia/auth/ionia_welcome_page.dart @@ -3,11 +3,14 @@ import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/widgets/primary_button.dart'; import 'package:cake_wallet/typography.dart'; +import 'package:cake_wallet/view_model/ionia/ionia_gift_cards_list_view_model.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/src/widgets/framework.dart'; import 'package:cake_wallet/generated/i18n.dart'; +import 'package:mobx/mobx.dart'; class IoniaWelcomePage extends BasePage { - IoniaWelcomePage(); + IoniaWelcomePage(this._cardsListViewModel); @override Widget middle(BuildContext context) { @@ -22,8 +25,15 @@ class IoniaWelcomePage extends BasePage { ); } + final IoniaGiftCardsListViewModel _cardsListViewModel; + @override Widget body(BuildContext context) { + reaction((_) => _cardsListViewModel.isLoggedIn, (bool state) { + if (state) { + Navigator.pushReplacementNamed(context, Routes.ioniaManageCardsPage); + } + }); return Padding( padding: const EdgeInsets.all(24.0), child: Column( @@ -31,7 +41,7 @@ class IoniaWelcomePage extends BasePage { children: [ Column( children: [ - SizedBox(height: 90), + SizedBox(height: 100), Text( S.of(context).about_cake_pay, style: TextStyle( diff --git a/lib/src/screens/ionia/cards/ionia_manage_cards_page.dart b/lib/src/screens/ionia/cards/ionia_manage_cards_page.dart index 80ebada1f..9baa38f24 100644 --- a/lib/src/screens/ionia/cards/ionia_manage_cards_page.dart +++ b/lib/src/screens/ionia/cards/ionia_manage_cards_page.dart @@ -17,7 +17,7 @@ import 'package:cake_wallet/generated/i18n.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; class IoniaManageCardsPage extends BasePage { - IoniaManageCardsPage(this._cardsListViewModel): searchFocusNode = FocusNode() { + IoniaManageCardsPage(this._cardsListViewModel) { _searchController.addListener(() { if (_searchController.text != _cardsListViewModel.searchString) { _searchDebounce.run(() { @@ -29,7 +29,6 @@ class IoniaManageCardsPage extends BasePage { _cardsListViewModel.getMerchants(); } - final FocusNode searchFocusNode; final IoniaGiftCardsListViewModel _cardsListViewModel; final _searchDebounce = Debounce(Duration(milliseconds: 500)); @@ -87,14 +86,7 @@ class IoniaManageCardsPage extends BasePage { //highlightColor: Colors.transparent, //splashColor: Colors.transparent, //padding: EdgeInsets.all(0), - onPressed: (){ - if (searchFocusNode.hasFocus) { - searchFocusNode.unfocus(); - return; - } - - Navigator.of(context).pop(); - }, + onPressed: () => Navigator.pop(context), child: _backButton), ), ); @@ -157,7 +149,6 @@ class IoniaManageCardsPage extends BasePage { Expanded( child: _SearchWidget( controller: _searchController, - focusNode: searchFocusNode, )), SizedBox(width: 10), filterButton @@ -275,10 +266,9 @@ class _SearchWidget extends StatelessWidget { const _SearchWidget({ Key? key, required this.controller, - required this.focusNode, }) : super(key: key); final TextEditingController controller; - final FocusNode focusNode; + @override Widget build(BuildContext context) { final searchIcon = Padding( @@ -290,7 +280,6 @@ class _SearchWidget extends StatelessWidget { ); return TextField( - focusNode: focusNode, style: TextStyle(color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!), controller: controller, decoration: InputDecoration( diff --git a/lib/src/screens/receive/anonpay_invoice_page.dart b/lib/src/screens/receive/anonpay_invoice_page.dart index f8df3eeb3..199c33e09 100644 --- a/lib/src/screens/receive/anonpay_invoice_page.dart +++ b/lib/src/screens/receive/anonpay_invoice_page.dart @@ -9,7 +9,6 @@ import 'package:cake_wallet/src/screens/receive/widgets/anonpay_input_form.dart' import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; import 'package:cake_wallet/src/widgets/keyboard_done_button.dart'; import 'package:cake_wallet/utils/device_info.dart'; -import 'package:cake_wallet/utils/responsive_layout_util.dart'; import 'package:cake_wallet/view_model/anon_invoice_page_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/receive_option_view_model.dart'; import 'package:flutter/material.dart'; @@ -28,7 +27,8 @@ class AnonPayInvoicePage extends BasePage { AnonPayInvoicePage( this.anonInvoicePageViewModel, this.receiveOptionViewModel, - ) : _amountFocusNode = FocusNode() {} + ) : _amountFocusNode = FocusNode() { + } final _nameController = TextEditingController(); final _emailController = TextEditingController(); @@ -53,11 +53,6 @@ class AnonPayInvoicePage extends BasePage { @override AppBarStyle get appBarStyle => AppBarStyle.transparent; - @override - void onClose(BuildContext context) { - Navigator.popUntil(context, ModalRoute.withName(Routes.dashboard)); - } - @override Widget middle(BuildContext context) => PresentReceiveOptionPicker(receiveOptionViewModel: receiveOptionViewModel); @@ -70,22 +65,15 @@ class AnonPayInvoicePage extends BasePage { anonInvoicePageViewModel.reset(); }); - Future _onNavigateBack(BuildContext context) async { - onClose(context); - return false; - } - @override Widget body(BuildContext context) { WidgetsBinding.instance.addPostFrameCallback((_) => _setReactions(context)); - return WillPopScope( - onWillPop: () => _onNavigateBack(context), - child: KeyboardActions( - disableScroll: true, - config: KeyboardActionsConfig( - keyboardActionsPlatform: KeyboardActionsPlatform.IOS, - keyboardBarColor: Theme.of(context) + return KeyboardActions( + disableScroll: true, + config: KeyboardActionsConfig( + keyboardActionsPlatform: KeyboardActionsPlatform.IOS, + keyboardBarColor: Theme.of(context) .accentTextTheme! .bodyLarge! .backgroundColor!, @@ -101,7 +89,7 @@ class AnonPayInvoicePage extends BasePage { child: ScrollableWithBottomSection( contentPadding: EdgeInsets.only(bottom: 24), content: Container( - decoration: ResponsiveLayoutUtil.instance.isMobile ? BoxDecoration( + decoration: DeviceInfo.instance.isMobile ? BoxDecoration( borderRadius: BorderRadius.only( bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)), gradient: LinearGradient( @@ -112,81 +100,79 @@ class AnonPayInvoicePage extends BasePage { begin: Alignment.topLeft, end: Alignment.bottomRight, ), - ) : null, - child: Observer(builder: (_) { - return Padding( - padding: EdgeInsets.fromLTRB(24, 120, 24, 0), - child: AnonInvoiceForm( - nameController: _nameController, - descriptionController: _descriptionController, - amountController: _amountController, - emailController: _emailController, - depositAmountFocus: _amountFocusNode, - formKey: _formKey, - isInvoice: receiveOptionViewModel.selectedReceiveOption == - ReceivePageOption.anonPayInvoice, - anonInvoicePageViewModel: anonInvoicePageViewModel, - ), - ); - }), - ), - bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24), - bottomSection: Observer(builder: (_) { - final isInvoice = - receiveOptionViewModel.selectedReceiveOption == ReceivePageOption.anonPayInvoice; - return Column( - children: [ - Padding( - padding: EdgeInsets.only(bottom: 15), - child: Center( - child: Text( - isInvoice - ? S.of(context).anonpay_description("an invoice", "pay") - : S.of(context).anonpay_description("a donation link", "donate"), - textAlign: TextAlign.center, - style: TextStyle( - color: Theme.of(context) + ) : null, + child: Observer(builder: (_) { + return Padding( + padding: EdgeInsets.fromLTRB(24, 120, 24, 0), + child: AnonInvoiceForm( + nameController: _nameController, + descriptionController: _descriptionController, + amountController: _amountController, + emailController: _emailController, + depositAmountFocus: _amountFocusNode, + formKey: _formKey, + isInvoice: receiveOptionViewModel.selectedReceiveOption == + ReceivePageOption.anonPayInvoice, + anonInvoicePageViewModel: anonInvoicePageViewModel, + ), + ); + }), + ), + bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24), + bottomSection: Observer(builder: (_) { + final isInvoice = + receiveOptionViewModel.selectedReceiveOption == ReceivePageOption.anonPayInvoice; + return Column( + children: [ + Padding( + padding: EdgeInsets.only(bottom: 15), + child: Center( + child: Text( + isInvoice + ? S.of(context).anonpay_description("an invoice", "pay") + : S.of(context).anonpay_description("a donation link", "donate"), + textAlign: TextAlign.center, + style: TextStyle( + color: Theme.of(context) .primaryTextTheme! .displayLarge! .decorationColor!, fontWeight: FontWeight.w500, fontSize: 12), - ), ), ), - LoadingPrimaryButton( - text: isInvoice - ? S.of(context).create_invoice - : S.of(context).create_donation_link, - onPressed: () { - anonInvoicePageViewModel.setRequestParams( - inputAmount: _amountController.text, - inputName: _nameController.text, - inputEmail: _emailController.text, - inputDescription: _descriptionController.text, - ); - if (anonInvoicePageViewModel.receipientEmail.isNotEmpty && - _formKey.currentState != null && - !_formKey.currentState!.validate()) { - return; - } - if (isInvoice) { - anonInvoicePageViewModel.createInvoice(); - } else { - anonInvoicePageViewModel.generateDonationLink(); - } - }, - color: Theme.of(context) + ), + LoadingPrimaryButton( + text: + isInvoice ? S.of(context).create_invoice : S.of(context).create_donation_link, + onPressed: () { + anonInvoicePageViewModel.setRequestParams( + inputAmount: _amountController.text, + inputName: _nameController.text, + inputEmail: _emailController.text, + inputDescription: _descriptionController.text, + ); + if (anonInvoicePageViewModel.receipientEmail.isNotEmpty && + _formKey.currentState != null && + !_formKey.currentState!.validate()) { + return; + } + if (isInvoice) { + anonInvoicePageViewModel.createInvoice(); + } else { + anonInvoicePageViewModel.generateDonationLink(); + } + }, + color: Theme.of(context) .accentTextTheme! .bodyLarge! .color!, - textColor: Colors.white, - isLoading: anonInvoicePageViewModel.state is IsExecutingState, - ), - ], - ); - }), - ), + textColor: Colors.white, + isLoading: anonInvoicePageViewModel.state is IsExecutingState, + ), + ], + ); + }), ), ), ); diff --git a/lib/src/screens/receive/widgets/currency_input_field.dart b/lib/src/screens/receive/widgets/currency_input_field.dart index 85e2cdbe2..f1ce170f7 100644 --- a/lib/src/screens/receive/widgets/currency_input_field.dart +++ b/lib/src/screens/receive/widgets/currency_input_field.dart @@ -1,5 +1,4 @@ import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; -import 'package:cake_wallet/utils/responsive_layout_util.dart'; import 'package:cw_core/currency.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -10,8 +9,7 @@ class CurrencyInputField extends StatelessWidget { required this.onTapPicker, required this.selectedCurrency, this.focusNode, - required this.controller, - required this.isLight, + required this.controller, required this.isLight, }); final Function() onTapPicker; @@ -24,12 +22,13 @@ class CurrencyInputField extends StatelessWidget { Widget build(BuildContext context) { final arrowBottomPurple = Image.asset( 'assets/images/arrow_bottom_purple_icon.png', - color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!, + color: Theme.of(context) + .accentTextTheme! + .displayMedium! + .backgroundColor!, height: 8, ); - // This magic number for wider screen sets the text input focus at center of the inputfield - final _width = - ResponsiveLayoutUtil.instance.isMobile ? MediaQuery.of(context).size.width : 500; + final _width = MediaQuery.of(context).size.width; return Column( children: [ @@ -43,12 +42,10 @@ class CurrencyInputField extends StatelessWidget { keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true), inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\d+(\.|\,)?\d{0,8}'))], hintText: '0.000', - placeholderTextStyle: isLight - ? null - : TextStyle( - color: Theme.of(context).primaryTextTheme!.headlineSmall!.color!, - fontWeight: FontWeight.w600, - ), + placeholderTextStyle: isLight ? null : TextStyle( + color: Theme.of(context).primaryTextTheme!.headlineSmall!.color!, + fontWeight: FontWeight.w600, + ), borderColor: Theme.of(context).accentTextTheme!.titleLarge!.backgroundColor!, textColor: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!, textStyle: TextStyle( @@ -75,10 +72,7 @@ class CurrencyInputField extends StatelessWidget { style: TextStyle( fontWeight: FontWeight.w600, fontSize: 16, - color: Theme.of(context) - .accentTextTheme! - .displayMedium! - .backgroundColor!, + color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!, ), ), if (selectedCurrency.tag != null) @@ -113,10 +107,8 @@ class CurrencyInputField extends StatelessWidget { style: TextStyle( fontWeight: FontWeight.w600, fontSize: 20, - color: Theme.of(context) - .accentTextTheme! - .displayMedium! - .backgroundColor!, + color: + Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!, ), ), ), diff --git a/lib/src/screens/restore/wallet_restore_page.dart b/lib/src/screens/restore/wallet_restore_page.dart index 2e9033f83..6f1ede0c8 100644 --- a/lib/src/screens/restore/wallet_restore_page.dart +++ b/lib/src/screens/restore/wallet_restore_page.dart @@ -274,8 +274,6 @@ class WalletRestorePage extends BasePage { } void _confirmForm() { - // Dismissing all visible keyboard to provide context for navigation - FocusManager.instance.primaryFocus?.unfocus(); final formContext = walletRestoreViewModel.mode == WalletRestoreMode.seed ? walletRestoreFromSeedFormKey.currentContext : walletRestoreFromKeysFormKey.currentContext; diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart index 4ad1ad8ca..9e648d094 100644 --- a/lib/src/screens/send/send_page.dart +++ b/lib/src/screens/send/send_page.dart @@ -62,7 +62,7 @@ class SendPage extends BasePage { final _closeButton = currentTheme.type == ThemeType.dark ? closeButtonImageDarkTheme : closeButtonImage; - bool isMobileView = ResponsiveLayoutUtil.instance.isMobile; + bool isMobileView = ResponsiveLayoutUtil.instance.isMobile(context); return MergeSemantics( child: SizedBox( @@ -92,7 +92,7 @@ class SendPage extends BasePage { double _sendCardHeight(BuildContext context) { final double initialHeight = sendViewModel.isElectrumWallet ? 490 : 465; - if (!ResponsiveLayoutUtil.instance.isMobile) { + if (!ResponsiveLayoutUtil.instance.isMobile(context)) { return initialHeight - 66; } return initialHeight; @@ -145,247 +145,216 @@ class SendPage extends BasePage { Widget body(BuildContext context) { _setEffects(context); - return GestureDetector( - onLongPress: () => sendViewModel.balanceViewModel.isReversing = - !sendViewModel.balanceViewModel.isReversing, - onLongPressUp: () => sendViewModel.balanceViewModel.isReversing = - !sendViewModel.balanceViewModel.isReversing, - child: Form( - key: _formKey, - child: ScrollableWithBottomSection( - contentPadding: EdgeInsets.only(bottom: 24), - content: FocusTraversalGroup( - policy: OrderedTraversalPolicy(), - child: Column( - children: [ - Container( - height: _sendCardHeight(context), - child: Observer( - builder: (_) { - return PageView.builder( - scrollDirection: Axis.horizontal, - controller: controller, - itemCount: sendViewModel.outputs.length, - itemBuilder: (context, index) { - final output = sendViewModel.outputs[index]; - - return SendCard( - key: output.key, - output: output, - sendViewModel: sendViewModel, - initialPaymentRequest: initialPaymentRequest, - ); - }); - }, - )), - Padding( - padding: EdgeInsets.only( - top: 10, left: 24, right: 24, bottom: 10), - child: Container( - height: 10, - child: Observer( - builder: (_) { - final count = sendViewModel.outputs.length; - - return count > 1 - ? SmoothPageIndicator( - controller: controller, - count: count, - effect: ScrollingDotsEffect( - spacing: 6.0, - radius: 6.0, - dotWidth: 6.0, - dotHeight: 6.0, - dotColor: Theme.of(context) - .primaryTextTheme - !.displaySmall! - .backgroundColor!, - activeDotColor: Theme.of(context) - .primaryTextTheme - !.displayMedium! - .backgroundColor!), - ) - : Offstage(); - }, - ), + return Form( + key: _formKey, + child: ScrollableWithBottomSection( + contentPadding: EdgeInsets.only(bottom: 24), + content: FocusTraversalGroup( + policy: OrderedTraversalPolicy(), + child: Column( + children: [ + Container( + height: _sendCardHeight(context), + child: Observer( + builder: (_) { + return PageView.builder( + scrollDirection: Axis.horizontal, + controller: controller, + itemCount: sendViewModel.outputs.length, + itemBuilder: (context, index) { + final output = sendViewModel.outputs[index]; + + return SendCard( + key: output.key, + output: output, + sendViewModel: sendViewModel, + initialPaymentRequest: initialPaymentRequest, + ); + }); + }, + )), + Padding( + padding: + EdgeInsets.only(top: 10, left: 24, right: 24, bottom: 10), + child: Container( + height: 10, + child: Observer( + builder: (_) { + final count = sendViewModel.outputs.length; + + return count > 1 + ? SmoothPageIndicator( + controller: controller, + count: count, + effect: ScrollingDotsEffect( + spacing: 6.0, + radius: 6.0, + dotWidth: 6.0, + dotHeight: 6.0, + dotColor: Theme.of(context) + .primaryTextTheme!.displaySmall! + .backgroundColor!, + activeDotColor: Theme.of(context) + .primaryTextTheme!.displayMedium! + .backgroundColor!), + ) + : Offstage(); + }, ), ), - if (sendViewModel.hasMultiRecipient) - Container( - height: 40, - width: double.infinity, - padding: EdgeInsets.only(left: 24), - child: SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: Observer( - builder: (_) { - final templates = sendViewModel.templates; - final itemCount = templates.length; - - return Row( - children: [ - AddTemplateButton( - onTap: () => Navigator.of(context) - .pushNamed(Routes.sendTemplate), - currentTemplatesLength: templates.length, - ), - ListView.builder( - scrollDirection: Axis.horizontal, - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - itemCount: itemCount, - itemBuilder: (context, index) { - final template = templates[index]; - return TemplateTile( - key: UniqueKey(), - to: template.name, - amount: template.isCurrencySelected - ? template.amount - : template.amountFiat, - from: template.isCurrencySelected - ? template.cryptoCurrency - : template.fiatCurrency, - onTap: () async { - final fiatFromTemplate = FiatCurrency - .all - .singleWhere((element) => - element.title == - template.fiatCurrency); - final output = _defineCurrentOutput(); - output.address = template.address; - if (template.isCurrencySelected) { - output - .setCryptoAmount(template.amount); - } else { - sendViewModel.setFiatCurrency( - fiatFromTemplate); - output.setFiatAmount( - template.amountFiat); - } - output.resetParsedAddress(); - await output - .fetchParsedAddress(context); - }, - onRemove: () { - showPopUp( - context: context, - builder: (dialogContext) { - return AlertWithTwoActions( - alertTitle: - S.of(context).template, - alertContent: S - .of(context) - .confirm_delete_template, - rightButtonText: - S.of(context).delete, - leftButtonText: - S.of(context).cancel, - actionRightButton: () { - Navigator.of(dialogContext) - .pop(); - sendViewModel - .sendTemplateViewModel - .removeTemplate( - template: template); - }, - actionLeftButton: () => - Navigator.of(dialogContext) - .pop()); - }, - ); + ), + if (sendViewModel.hasMultiRecipient) + Container( + height: 40, + width: double.infinity, + padding: EdgeInsets.only(left: 24), + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Observer( + builder: (_) { + final templates = sendViewModel.templates; + final itemCount = templates.length; + + return Row( + children: [ + AddTemplateButton( + onTap: () => Navigator.of(context).pushNamed(Routes.sendTemplate), + currentTemplatesLength: templates.length, + ), + ListView.builder( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemCount: itemCount, + itemBuilder: (context, index) { + final template = templates[index]; + return TemplateTile( + key: UniqueKey(), + to: template.name, + amount: template.isCurrencySelected ? template.amount : template.amountFiat, + from: template.isCurrencySelected ? template.cryptoCurrency : template.fiatCurrency, + onTap: () async { + final fiatFromTemplate = FiatCurrency.all.singleWhere((element) => element.title == template.fiatCurrency); + final output = _defineCurrentOutput(); + output.address = template.address; + if(template.isCurrencySelected){ + output.setCryptoAmount(template.amount); + }else{ + sendViewModel.setFiatCurrency(fiatFromTemplate); + output.setFiatAmount(template.amountFiat); + } + output.resetParsedAddress(); + await output.fetchParsedAddress(context); + }, + onRemove: () { + showPopUp( + context: context, + builder: (dialogContext) { + return AlertWithTwoActions( + alertTitle: S.of(context).template, + alertContent: S + .of(context) + .confirm_delete_template, + rightButtonText: S.of(context).delete, + leftButtonText: S.of(context).cancel, + actionRightButton: () { + Navigator.of(dialogContext).pop(); + sendViewModel.sendTemplateViewModel + .removeTemplate( + template: template); + }, + actionLeftButton: () => + Navigator.of(dialogContext) + .pop()); }, ); }, - ), - ], - ); - }, - ), - ), - ) - ], - ), - ), - bottomSectionPadding: - EdgeInsets.only(left: 24, right: 24, bottom: 24), - bottomSection: Column( - children: [ - if (sendViewModel.hasCurrecyChanger) - Observer( - builder: (_) => Padding( - padding: EdgeInsets.only(bottom: 12), - child: PrimaryButton( - onPressed: () => presentCurrencyPicker(context), - text: - 'Change your asset (${sendViewModel.selectedCryptoCurrency})', - color: Colors.transparent, - textColor: Theme.of(context) - .accentTextTheme - !.displaySmall! - .decorationColor!, - ))), - if (sendViewModel.hasMultiRecipient) - Padding( - padding: EdgeInsets.only(bottom: 12), - child: PrimaryButton( - onPressed: () { - sendViewModel.addOutput(); - Future.delayed(const Duration(milliseconds: 250), () { - controller - .jumpToPage(sendViewModel.outputs.length - 1); - }); - }, - text: S.of(context).add_receiver, - color: Colors.transparent, - textColor: Theme.of(context) - .accentTextTheme - !.displaySmall! - .decorationColor!, - isDottedBorder: true, - borderColor: Theme.of(context) - .primaryTextTheme - !.displaySmall! - .decorationColor!, - )), - Observer( - builder: (_) { - return LoadingPrimaryButton( - onPressed: () async { - if (_formKey.currentState != null && - !_formKey.currentState!.validate()) { - if (sendViewModel.outputs.length > 1) { - showErrorValidationAlert(context); - } - - return; - } - - final notValidItems = sendViewModel.outputs - .where((item) => - item.address.isEmpty || - item.cryptoAmount.isEmpty) - .toList(); - - if (notValidItems.isNotEmpty ?? false) { - showErrorValidationAlert(context); - return; - } - - await sendViewModel.createTransaction(); + ); + }, + ), + ], + ); }, - text: S.of(context).send, - color: - Theme.of(context).accentTextTheme!.bodyLarge!.color!, - textColor: Colors.white, - isLoading: sendViewModel.state is IsExecutingState || - sendViewModel.state is TransactionCommitting, - isDisabled: !sendViewModel.isReadyForSend, - ); - }, + ), + ), ) ], - )), - ), + ), + ), + bottomSectionPadding: + EdgeInsets.only(left: 24, right: 24, bottom: 24), + bottomSection: Column( + children: [ + if (sendViewModel.hasCurrecyChanger) + Observer(builder: (_) => + Padding( + padding: EdgeInsets.only(bottom: 12), + child: PrimaryButton( + onPressed: () => presentCurrencyPicker(context), + text: 'Change your asset (${sendViewModel.selectedCryptoCurrency})', + color: Colors.transparent, + textColor: Theme.of(context) + .accentTextTheme!.displaySmall! + .decorationColor!, + ) + ) + ), + if (sendViewModel.hasMultiRecipient) + Padding( + padding: EdgeInsets.only(bottom: 12), + child: PrimaryButton( + onPressed: () { + sendViewModel.addOutput(); + Future.delayed(const Duration(milliseconds: 250), () { + controller.jumpToPage(sendViewModel.outputs.length - 1); + }); + }, + text: S.of(context).add_receiver, + color: Colors.transparent, + textColor: Theme.of(context) + .accentTextTheme!.displaySmall! + .decorationColor!, + isDottedBorder: true, + borderColor: Theme.of(context) + .primaryTextTheme!.displaySmall! + .decorationColor!, + )), + Observer( + builder: (_) { + return LoadingPrimaryButton( + onPressed: () async { + if (_formKey.currentState != null && !_formKey.currentState!.validate()) { + if (sendViewModel.outputs.length > 1) { + showErrorValidationAlert(context); + } + + return; + } + + final notValidItems = sendViewModel.outputs + .where((item) => + item.address.isEmpty || item.cryptoAmount.isEmpty) + .toList(); + + if (notValidItems.isNotEmpty ?? false) { + showErrorValidationAlert(context); + return; + } + + await sendViewModel.createTransaction(); + + }, + text: S.of(context).send, + color: Theme.of(context).accentTextTheme!.bodyLarge!.color!, + textColor: Colors.white, + isLoading: sendViewModel.state is IsExecutingState || + sendViewModel.state is TransactionCommitting, + isDisabled: !sendViewModel.isReadyForSend, + ); + }, + ) + ], + )), ); } @@ -413,54 +382,51 @@ class SendPage extends BasePage { WidgetsBinding.instance.addPostFrameCallback((_) { if (context.mounted) { showPopUp( - context: context, - builder: (BuildContext context) { - return ConfirmSendingAlert( - alertTitle: S.of(context).confirm_sending, - amount: S.of(context).send_amount, - amountValue: - sendViewModel.pendingTransaction!.amountFormatted, - fiatAmountValue: - sendViewModel.pendingTransactionFiatAmountFormatted, - fee: S.of(context).send_fee, - feeValue: sendViewModel.pendingTransaction!.feeFormatted, - feeFiatAmount: sendViewModel - .pendingTransactionFeeFiatAmountFormatted, - outputs: sendViewModel.outputs, - rightButtonText: S.of(context).ok, - leftButtonText: S.of(context).cancel, - actionRightButton: () { - Navigator.of(context).pop(); - sendViewModel.commitTransaction(); - showPopUp( - context: context, - builder: (BuildContext context) { - return Observer(builder: (_) { - final state = sendViewModel.state; + context: context, + builder: (BuildContext context) { + return ConfirmSendingAlert( + alertTitle: S.of(context).confirm_sending, + amount: S.of(context).send_amount, + amountValue: + sendViewModel.pendingTransaction!.amountFormatted, + fiatAmountValue: sendViewModel.pendingTransactionFiatAmountFormatted, + fee: S.of(context).send_fee, + feeValue: sendViewModel.pendingTransaction!.feeFormatted, + feeFiatAmount: sendViewModel.pendingTransactionFeeFiatAmountFormatted, + outputs: sendViewModel.outputs, + rightButtonText: S.of(context).ok, + leftButtonText: S.of(context).cancel, + actionRightButton: () { + Navigator.of(context).pop(); + sendViewModel.commitTransaction(); + showPopUp( + context: context, + builder: (BuildContext context) { + return Observer(builder: (_) { + final state = sendViewModel.state; - if (state is FailureState) { - Navigator.of(context).pop(); + if (state is FailureState) { + Navigator.of(context).pop(); + } + + if (state is TransactionCommitted) { + return AlertWithOneAction( + alertTitle: '', + alertContent: S.of(context).send_success( + sendViewModel.selectedCryptoCurrency.toString()), + buttonText: S.of(context).ok, + buttonAction: () { + Navigator.of(context).pop(); + RequestReviewHandler.requestReview(); + }); } - if (state is TransactionCommitted) { - return AlertWithOneAction( - alertTitle: '', - alertContent: S.of(context).send_success( - sendViewModel.selectedCryptoCurrency - .toString()), - buttonText: S.of(context).ok, - buttonAction: () { - Navigator.of(context).pop(); - RequestReviewHandler.requestReview(); - }); - } - - return Offstage(); - }); + return Offstage(); }); - }, - actionLeftButton: () => Navigator.of(context).pop()); - }); + }); + }, + actionLeftButton: () => Navigator.of(context).pop()); + }); } }); } @@ -495,18 +461,16 @@ class SendPage extends BasePage { }); } - void presentCurrencyPicker(BuildContext context) async { + void presentCurrencyPicker(BuildContext context) async { await showPopUp( builder: (_) => Picker( - items: sendViewModel.currencies, - displayItem: (Object item) => item.toString(), - selectedAtIndex: sendViewModel.currencies - .indexOf(sendViewModel.selectedCryptoCurrency), - title: S.of(context).please_select, - mainAxisAlignment: MainAxisAlignment.center, - onItemSelected: (CryptoCurrency cur) => - sendViewModel.selectedCryptoCurrency = cur, - ), + items: sendViewModel.currencies, + displayItem: (Object item) => item.toString(), + selectedAtIndex: sendViewModel.currencies.indexOf(sendViewModel.selectedCryptoCurrency), + title: S.of(context).please_select, + mainAxisAlignment: MainAxisAlignment.center, + onItemSelected: (CryptoCurrency cur) => sendViewModel.selectedCryptoCurrency = cur, + ), context: context); } } diff --git a/lib/src/screens/send/widgets/send_card.dart b/lib/src/screens/send/widgets/send_card.dart index 2b4b40fa3..96045b1bd 100644 --- a/lib/src/screens/send/widgets/send_card.dart +++ b/lib/src/screens/send/widgets/send_card.dart @@ -122,7 +122,7 @@ class SendCardState extends State color: Colors.transparent, )), Container( - decoration: ResponsiveLayoutUtil.instance.isMobile ? BoxDecoration( + decoration: ResponsiveLayoutUtil.instance.isMobile(context) ? BoxDecoration( borderRadius: BorderRadius.only( bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)), @@ -137,9 +137,9 @@ class SendCardState extends State child: Padding( padding: EdgeInsets.fromLTRB( 24, - ResponsiveLayoutUtil.instance.isMobile ? 100 : 55, + ResponsiveLayoutUtil.instance.isMobile(context) ? 100 : 55, 24, - ResponsiveLayoutUtil.instance.isMobile ? 32 : 0, + ResponsiveLayoutUtil.instance.isMobile(context) ? 32 : 0, ), child: SingleChildScrollView( child: Observer(builder: (_) => Column( diff --git a/lib/src/screens/settings/display_settings_page.dart b/lib/src/screens/settings/display_settings_page.dart index 04fd134e6..c7baa9b6a 100644 --- a/lib/src/screens/settings/display_settings_page.dart +++ b/lib/src/screens/settings/display_settings_page.dart @@ -8,7 +8,6 @@ import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell. import 'package:cake_wallet/themes/theme_base.dart'; import 'package:cake_wallet/themes/theme_list.dart'; import 'package:cake_wallet/utils/device_info.dart'; -import 'package:cake_wallet/utils/responsive_layout_util.dart'; import 'package:cake_wallet/view_model/settings/choices_list_item.dart'; import 'package:cake_wallet/view_model/settings/display_settings_view_model.dart'; import 'package:flutter/material.dart'; @@ -30,11 +29,11 @@ class DisplaySettingsPage extends BasePage { child: Column( children: [ SettingsSwitcherCell( - title: S.current.settings_display_balance, - value: _displaySettingsViewModel.shouldDisplayBalance, - onValueChange: (_, bool value) { - _displaySettingsViewModel.setShouldDisplayBalance(value); - }), + title: S.current.settings_display_balance, + value: _displaySettingsViewModel.shouldDisplayBalance, + onValueChange: (_, bool value) { + _displaySettingsViewModel.setShouldDisplayBalance(value); + }), SettingsSwitcherCell( title: S.current.show_market_place, value: _displaySettingsViewModel.shouldShowMarketPlaceInDashboard, @@ -43,17 +42,14 @@ class DisplaySettingsPage extends BasePage { }, ), //if (!isHaven) it does not work correctly - if (!_displaySettingsViewModel.disabledFiatApiMode) + if(!_displaySettingsViewModel.disabledFiatApiMode) SettingsPickerCell( title: S.current.settings_currency, searchHintText: S.current.search_currency, items: FiatCurrency.all, selectedItem: _displaySettingsViewModel.fiatCurrency, - onItemSelected: (FiatCurrency currency) => - _displaySettingsViewModel.setFiatCurrency(currency), - images: FiatCurrency.all - .map((e) => Image.asset("assets/images/flags/${e.countryCode}.png")) - .toList(), + onItemSelected: (FiatCurrency currency) => _displaySettingsViewModel.setFiatCurrency(currency), + images: FiatCurrency.all.map((e) => Image.asset("assets/images/flags/${e.countryCode}.png")).toList(), isGridView: true, matchingCriteria: (FiatCurrency currency, String searchText) { return currency.title.toLowerCase().contains(searchText) || @@ -70,14 +66,13 @@ class DisplaySettingsPage extends BasePage { selectedItem: _displaySettingsViewModel.languageCode, onItemSelected: _displaySettingsViewModel.onLanguageSelected, images: LanguageService.list.keys - .map((e) => Image.asset( - "assets/images/flags/${LanguageService.localeCountryCode[e]}.png")) + .map((e) => Image.asset("assets/images/flags/${LanguageService.localeCountryCode[e]}.png")) .toList(), matchingCriteria: (String code, String searchText) { return LanguageService.list[code]?.toLowerCase().contains(searchText) ?? false; }, ), - if (ResponsiveLayoutUtil.instance.isMobile && DeviceInfo.instance.isMobile) + if (DeviceInfo.instance.isMobile) SettingsChoicesCell( ChoicesListItem( title: S.current.color_theme, diff --git a/lib/src/screens/setup_2fa/setup_2fa_enter_code_page.dart b/lib/src/screens/setup_2fa/setup_2fa_enter_code_page.dart index e88b1090b..49763a797 100644 --- a/lib/src/screens/setup_2fa/setup_2fa_enter_code_page.dart +++ b/lib/src/screens/setup_2fa/setup_2fa_enter_code_page.dart @@ -43,24 +43,26 @@ class TotpAuthCodePageState extends State { @override void initState() { - if(widget.totpArguments.onTotpAuthenticationFinished != null) { - _reaction ??= reaction((_) => widget.setup2FAViewModel.state, (ExecutionState state) { + _reaction ??= reaction((_) => widget.setup2FAViewModel.state, (ExecutionState state) { + if (state is ExecutedSuccessfullyState) { WidgetsBinding.instance.addPostFrameCallback((_) { - if (state is ExecutedSuccessfullyState) { - widget.totpArguments.onTotpAuthenticationFinished!(true, this); - } + widget.totpArguments.onTotpAuthenticationFinished!(true, this); + }); + } - if (state is FailureState) { - print(state.error); - widget.totpArguments.onTotpAuthenticationFinished!(false, this); - } + if (state is FailureState) { + print(state.error); + WidgetsBinding.instance.addPostFrameCallback((_) { + widget.totpArguments.onTotpAuthenticationFinished!(false, this); + }); + } - if (state is AuthenticationBanned) { - widget.totpArguments.onTotpAuthenticationFinished!(false, this); - } - }); + if (state is AuthenticationBanned) { + WidgetsBinding.instance.addPostFrameCallback((_) { + widget.totpArguments.onTotpAuthenticationFinished!(false, this); + }); + } }); - } super.initState(); } diff --git a/lib/src/screens/wallet_list/wallet_list_page.dart b/lib/src/screens/wallet_list/wallet_list_page.dart index 35366455c..8c1e53b55 100644 --- a/lib/src/screens/wallet_list/wallet_list_page.dart +++ b/lib/src/screens/wallet_list/wallet_list_page.dart @@ -2,7 +2,7 @@ import 'package:cake_wallet/main.dart'; import 'package:cake_wallet/src/screens/auth/auth_page.dart'; import 'package:cake_wallet/core/auth_service.dart'; import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; -import 'package:cake_wallet/utils/responsive_layout_util.dart'; +import 'package:cake_wallet/utils/device_info.dart'; import 'package:cake_wallet/utils/show_bar.dart'; import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart'; @@ -217,7 +217,7 @@ class WalletListBodyState extends State { await hideProgressText(); // only pop the wallets route in mobile as it will go back to dashboard page // in desktop platforms the navigation tree is different - if (ResponsiveLayoutUtil.instance.isMobile) { + if (DeviceInfo.instance.isMobile) { WidgetsBinding.instance.addPostFrameCallback((_) { Navigator.of(context).pop(); }); @@ -281,16 +281,16 @@ class WalletListBodyState extends State { } ActionPane _actionPane(WalletListItem wallet) => ActionPane( - motion: const ScrollMotion(), - extentRatio: 0.3, - children: [ - SlidableAction( - onPressed: (_) => _removeWallet(wallet), - backgroundColor: Colors.red, - foregroundColor: Colors.white, - icon: CupertinoIcons.delete, - label: S.of(context).delete, - ), - ], - ); + motion: const ScrollMotion(), + extentRatio: 0.3, + children: [ + SlidableAction( + onPressed: (_) => _removeWallet(wallet), + backgroundColor: Colors.red, + foregroundColor: Colors.white, + icon: CupertinoIcons.delete, + label: S.of(context).delete, + ), + ], + ); } diff --git a/lib/src/widgets/add_template_button.dart b/lib/src/widgets/add_template_button.dart index c88b72e7f..87951e044 100644 --- a/lib/src/widgets/add_template_button.dart +++ b/lib/src/widgets/add_template_button.dart @@ -26,7 +26,7 @@ class AddTemplateButton extends StatelessWidget { child: Container( height: 34, padding: EdgeInsets.symmetric( - horizontal: ResponsiveLayoutUtil.instance.isMobile ? 10 : 30), + horizontal: ResponsiveLayoutUtil.instance.isMobile(context) ? 10 : 30), alignment: Alignment.center, decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(20)), diff --git a/lib/src/widgets/address_text_field.dart b/lib/src/widgets/address_text_field.dart index daa2e0a60..415d40c6d 100644 --- a/lib/src/widgets/address_text_field.dart +++ b/lib/src/widgets/address_text_field.dart @@ -1,6 +1,6 @@ +import 'dart:io'; import 'package:cake_wallet/utils/device_info.dart'; -import 'package:cake_wallet/utils/responsive_layout_util.dart'; import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/routes.dart'; @@ -105,7 +105,7 @@ class AddressTextField extends StatelessWidget { width: prefixIconWidth * options.length + (spaceBetweenPrefixIcons * options.length), child: Row( - mainAxisAlignment: ResponsiveLayoutUtil.instance.isMobile + mainAxisAlignment: DeviceInfo.instance.isMobile ? MainAxisAlignment.spaceBetween : MainAxisAlignment.end, children: [ SizedBox(width: 5), diff --git a/lib/store/app_store.dart b/lib/store/app_store.dart index 639efacb6..196cc48a8 100644 --- a/lib/store/app_store.dart +++ b/lib/store/app_store.dart @@ -1,4 +1,3 @@ -import 'package:cake_wallet/utils/exception_handler.dart'; import 'package:cw_core/transaction_info.dart'; import 'package:mobx/mobx.dart'; import 'package:cw_core/balance.dart'; @@ -39,6 +38,5 @@ abstract class AppStoreBase with Store { wallet) { this.wallet?.close(); this.wallet = wallet; - this.wallet!.setExceptionHandler(ExceptionHandler.onError); } } diff --git a/lib/store/settings_store.dart b/lib/store/settings_store.dart index 6a8c31d2c..bcd2efd9b 100644 --- a/lib/store/settings_store.dart +++ b/lib/store/settings_store.dart @@ -587,6 +587,7 @@ abstract class SettingsStoreBase with Store { if (Platform.isAndroid) { final androidInfo = await deviceInfoPlugin.androidInfo; deviceName = '${androidInfo.brand}%20${androidInfo.manufacturer}%20${androidInfo.model}'; + print(deviceName); } else if (Platform.isIOS) { final iosInfo = await deviceInfoPlugin.iosInfo; deviceName = iosInfo.model; diff --git a/lib/utils/exception_handler.dart b/lib/utils/exception_handler.dart index e4d958444..a5f19cd3e 100644 --- a/lib/utils/exception_handler.dart +++ b/lib/utils/exception_handler.dart @@ -131,16 +131,17 @@ class ExceptionHandler { _ignoredErrors.any((element) => error.contains(element)); static const List _ignoredErrors = const [ - "Bad file descriptor", - "No space left on device", - "Write failed (OS Error: Broken pipe)", - "Can't assign requested address", - "Read failed (OS Error: Socket is not connected)", - "Operation timed out", - "No route to host", - "Software caused connection abort", - "Connection reset by peer", - "Connection timed out", + "errno = 9", // SocketException: Bad file descriptor + "errno = 28", // OS Error: No space left on device + "errno = 32", // SocketException: Write failed (OS Error: Broken pipe) + "errno = 49", // SocketException: Can't assign requested address + "errno = 54", // SocketException: Connection reset by peer + "errno = 57", // SocketException: Read failed (OS Error: Socket is not connected) + "errno = 60", // SocketException: Operation timed out + "errno = 65", // SocketException: No route to host + "errno = 103", // SocketException: Software caused connection abort + "errno = 104", // SocketException: Connection reset by peer + "errno = 110", // SocketException: Connection timed out "Connection reset by peer", "Connection closed before full header was received", "Connection terminated during handshake", diff --git a/lib/utils/responsive_layout_util.dart b/lib/utils/responsive_layout_util.dart index 99c722887..8ae76ca21 100644 --- a/lib/utils/responsive_layout_util.dart +++ b/lib/utils/responsive_layout_util.dart @@ -1,35 +1,33 @@ import 'package:flutter/material.dart'; class ResponsiveLayoutUtil { - static const double _kMobileThreshold = 768; + static const double _kMobileThreshold = 900; static const double kDesktopMaxWidthConstraint = 400; static const double kPopupWidth = 400; static const double kPopupSpaceHeight = 100; - static const _kIpadMaxWidth = 2560.0; + const ResponsiveLayoutUtil._(); static final instance = ResponsiveLayoutUtil._(); - bool get isMobile => - MediaQueryData.fromWindow(WidgetsBinding.instance.window).size.width < _kMobileThreshold; - - bool get isIpad { - final width = MediaQueryData.fromWindow(WidgetsBinding.instance.window).size.width; - return width >= _kMobileThreshold && !(width > _kIpadMaxWidth); + bool isMobile(BuildContext context) { + final MediaQueryData mediaQueryData = MediaQuery.of(context); + return mediaQueryData.size.width < _kMobileThreshold; } /// Returns dynamic size. /// /// If screen size is mobile, it returns 66% ([scale]) of the [originalValue]. double getDynamicSize( + BuildContext context, double originalValue, { double? mobileSize, double? scale, }) { scale ??= 2 / 3; mobileSize ??= originalValue * scale; - final value = isMobile ? mobileSize : originalValue; + final value = isMobile(context) ? mobileSize : originalValue; return value.roundToDouble(); } diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart index ac43c20d9..cfb72cb9e 100644 --- a/lib/view_model/dashboard/dashboard_view_model.dart +++ b/lib/view_model/dashboard/dashboard_view_model.dart @@ -296,7 +296,8 @@ abstract class DashboardViewModelBase with Store { bool get isEnabledSellAction => !settingsStore.disableSell && wallet.type != WalletType.haven && - wallet.type != WalletType.monero; + wallet.type != WalletType.monero && + wallet.type != WalletType.litecoin; @observable bool hasSellAction; diff --git a/lib/view_model/dashboard/market_place_view_model.dart b/lib/view_model/dashboard/market_place_view_model.dart deleted file mode 100644 index 470041127..000000000 --- a/lib/view_model/dashboard/market_place_view_model.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:cake_wallet/ionia/ionia_service.dart'; -import 'package:mobx/mobx.dart'; - -part 'market_place_view_model.g.dart'; - -class MarketPlaceViewModel = MarketPlaceViewModelBase with _$MarketPlaceViewModel; - -abstract class MarketPlaceViewModelBase with Store { - final IoniaService _ioniaService; - - MarketPlaceViewModelBase(this._ioniaService); - - - Future isIoniaUserAuthenticated() async { - return await _ioniaService.isLogined(); - } -} \ No newline at end of file diff --git a/lib/view_model/dashboard/transaction_list_item.dart b/lib/view_model/dashboard/transaction_list_item.dart index c8c6f5175..0f16bdfe8 100644 --- a/lib/view_model/dashboard/transaction_list_item.dart +++ b/lib/view_model/dashboard/transaction_list_item.dart @@ -13,6 +13,7 @@ import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart'; import 'package:cw_core/keyable.dart'; import 'package:cw_core/wallet_type.dart'; + class TransactionListItem extends ActionListItem with Keyable { TransactionListItem( {required this.transaction, @@ -27,7 +28,7 @@ class TransactionListItem extends ActionListItem with Keyable { FiatCurrency get fiatCurrency => settingsStore.fiatCurrency; - BalanceDisplayMode get displayMode => balanceViewModel.displayMode; + BalanceDisplayMode get displayMode => settingsStore.balanceDisplayMode; @override dynamic get keyIndex => transaction.id; diff --git a/lib/view_model/exchange/exchange_trade_view_model.dart b/lib/view_model/exchange/exchange_trade_view_model.dart index d5aeaa4fc..1d9f4f582 100644 --- a/lib/view_model/exchange/exchange_trade_view_model.dart +++ b/lib/view_model/exchange/exchange_trade_view_model.dart @@ -47,7 +47,7 @@ abstract class ExchangeTradeViewModelBase with Store { case ExchangeProviderDescription.simpleSwap: _provider = SimpleSwapExchangeProvider(); break; - case ExchangeProviderDescription.trocador: + case ExchangeProviderDescription.trocador: _provider = TrocadorExchangeProvider(); break; } @@ -114,10 +114,6 @@ abstract class ExchangeTradeViewModelBase with Store { updatedTrade.createdAt = trade.createdAt; } - if (updatedTrade.amount.isEmpty) { - updatedTrade.amount = trade.amount; - } - trade = updatedTrade; _updateItems(); @@ -127,8 +123,7 @@ abstract class ExchangeTradeViewModelBase with Store { } void _updateItems() { - final tagFrom = - tradesStore.trade!.from.tag != null ? '${tradesStore.trade!.from.tag}' + ' ' : ''; + final tagFrom = tradesStore.trade!.from.tag != null ? '${tradesStore.trade!.from.tag}' + ' ' : ''; final tagTo = tradesStore.trade!.to.tag != null ? '${tradesStore.trade!.to.tag}' + ' ' : ''; items.clear(); items.add(ExchangeTradeItem( diff --git a/lib/view_model/exchange/exchange_view_model.dart b/lib/view_model/exchange/exchange_view_model.dart index f823001a4..77fb9a3d4 100644 --- a/lib/view_model/exchange/exchange_view_model.dart +++ b/lib/view_model/exchange/exchange_view_model.dart @@ -443,9 +443,7 @@ abstract class ExchangeViewModelBase with Store { request = SideShiftRequest( depositMethod: depositCurrency, settleMethod: receiveCurrency, - depositAmount: isFixedRateMode - ? receiveAmount.replaceAll(',', '.') - : depositAmount.replaceAll(',', '.'), + depositAmount: depositAmount.replaceAll(',', '.'), settleAddress: receiveAddress, refundAddress: depositAddress, ); diff --git a/lib/view_model/ionia/ionia_gift_cards_list_view_model.dart b/lib/view_model/ionia/ionia_gift_cards_list_view_model.dart index b4974c420..77d8af6c2 100644 --- a/lib/view_model/ionia/ionia_gift_cards_list_view_model.dart +++ b/lib/view_model/ionia/ionia_gift_cards_list_view_model.dart @@ -16,10 +16,12 @@ abstract class IoniaGiftCardsListViewModelBase with Store { ioniaCategories = IoniaCategory.allCategories, selectedIndices = ObservableList.of([IoniaCategory.all]), scrollOffsetFromTop = 0.0, + isLoggedIn = false, merchantState = InitialIoniaMerchantLoadingState(), createCardState = IoniaCreateCardState(), searchString = '', ioniaMerchantList = [] { + _getAuthStatus().then((value) => isLoggedIn = value); } final IoniaService ioniaService; @@ -43,17 +45,24 @@ abstract class IoniaGiftCardsListViewModelBase with Store { @observable List ioniaMerchants; + @observable + bool isLoggedIn; + @observable List ioniaCategories; @observable ObservableList selectedIndices; + Future _getAuthStatus() async { + return await ioniaService.isLogined(); + } + @action Future createCard() async { try { createCardState = IoniaCreateCardLoading(); - await ioniaService.createCard(); + final card = await ioniaService.createCard(); createCardState = IoniaCreateCardSuccess(); } catch (e) { createCardState = IoniaCreateCardFailure(error: e.toString()); diff --git a/lib/view_model/trade_details_view_model.dart b/lib/view_model/trade_details_view_model.dart index 1e8a90c6f..e32e36887 100644 --- a/lib/view_model/trade_details_view_model.dart +++ b/lib/view_model/trade_details_view_model.dart @@ -21,7 +21,6 @@ import 'package:cake_wallet/src/screens/trade_details/track_trade_list_item.dart import 'package:cake_wallet/src/screens/trade_details/trade_details_list_card.dart'; import 'package:cake_wallet/src/screens/trade_details/trade_details_status_item.dart'; import 'package:url_launcher/url_launcher.dart'; -import 'package:collection/collection.dart'; part 'trade_details_view_model.g.dart'; @@ -33,8 +32,7 @@ abstract class TradeDetailsViewModelBase with Store { required this.trades, required this.settingsStore, }) : items = ObservableList(), - trade = trades.values.firstWhereOrNull((element) => element.id == tradeForDetails.id) ?? - tradeForDetails { + trade = tradeForDetails { switch (trade.provider) { case ExchangeProviderDescription.xmrto: _provider = XMRTOExchangeProvider(); @@ -56,6 +54,8 @@ abstract class TradeDetailsViewModelBase with Store { break; } + items = ObservableList(); + _updateItems(); _updateTrade(); @@ -85,12 +85,6 @@ abstract class TradeDetailsViewModelBase with Store { if (updatedTrade.createdAt == null && trade.createdAt != null) { updatedTrade.createdAt = trade.createdAt; } - Trade? foundElement = trades.values.firstWhereOrNull((element) => element.id == trade.id); - if (foundElement != null) { - final editedTrade = trades.get(foundElement.key); - editedTrade?.stateRaw = updatedTrade.stateRaw; - editedTrade?.save(); - } trade = updatedTrade; @@ -160,9 +154,8 @@ abstract class TradeDetailsViewModelBase with Store { } void _launchUrl(String url) { - final uri = Uri.parse(url); try { - launchUrl(uri); + launch(url); } catch (e) {} } } diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index e7e7973dd..c0a406a37 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,7 +5,7 @@ import FlutterMacOS import Foundation -import connectivity_plus_macos +import connectivity_macos import cw_monero import device_info_plus import devicelocale diff --git a/macos/Podfile b/macos/Podfile index fe5678c70..0c76ccf54 100644 --- a/macos/Podfile +++ b/macos/Podfile @@ -36,9 +36,5 @@ end post_install do |installer| installer.pods_project.targets.each do |target| flutter_additional_macos_build_settings(target) - - target.build_configurations.each do |config| - config.build_settings['MACOSX_DEPLOYMENT_TARGET'] = '12.0' - end end end diff --git a/macos/Podfile.lock b/macos/Podfile.lock index 454a59459..19ef7a2a5 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -1,7 +1,7 @@ PODS: - - connectivity_plus_macos (0.0.1): + - connectivity_macos (0.0.1): - FlutterMacOS - - ReachabilitySwift + - Reachability - cw_monero (0.0.1): - cw_monero/Boost (= 0.0.1) - cw_monero/Monero (= 0.0.1) @@ -37,7 +37,7 @@ PODS: - FlutterMacOS - platform_device_id_macos (0.0.1): - FlutterMacOS - - ReachabilitySwift (5.0.0) + - Reachability (3.2) - share_plus_macos (0.0.1): - FlutterMacOS - shared_preferences_foundation (0.0.1): @@ -49,7 +49,7 @@ PODS: - FlutterMacOS DEPENDENCIES: - - connectivity_plus_macos (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus_macos/macos`) + - connectivity_macos (from `Flutter/ephemeral/.symlinks/plugins/connectivity_macos/macos`) - cw_monero (from `Flutter/ephemeral/.symlinks/plugins/cw_monero/macos`) - device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`) - devicelocale (from `Flutter/ephemeral/.symlinks/plugins/devicelocale/macos`) @@ -67,11 +67,11 @@ DEPENDENCIES: SPEC REPOS: trunk: - - ReachabilitySwift + - Reachability EXTERNAL SOURCES: - connectivity_plus_macos: - :path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus_macos/macos + connectivity_macos: + :path: Flutter/ephemeral/.symlinks/plugins/connectivity_macos/macos cw_monero: :path: Flutter/ephemeral/.symlinks/plugins/cw_monero/macos device_info_plus: @@ -102,7 +102,7 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/wakelock_macos/macos SPEC CHECKSUMS: - connectivity_plus_macos: f6e86fd000e971d361e54b5afcadc8c8fa773308 + connectivity_macos: 5dae6ee11d320fac7c05f0d08bd08fc32b5514d9 cw_monero: ec03de55a19c4a2b174ea687e0f4202edc716fa4 device_info_plus: 5401765fde0b8d062a2f8eb65510fb17e77cf07f devicelocale: 9f0f36ac651cabae2c33f32dcff4f32b61c38225 @@ -113,12 +113,12 @@ SPEC CHECKSUMS: path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9 platform_device_id: 3e414428f45df149bbbfb623e2c0ca27c545b763 platform_device_id_macos: f763bb55f088be804d61b96eb4710b8ab6598e94 - ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 + Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 share_plus_macos: 853ee48e7dce06b633998ca0735d482dd671ade4 shared_preferences_foundation: e2dae3258e06f44cc55f49d42024fd8dd03c590c url_launcher_macos: 5335912b679c073563f29d89d33d10d459f95451 wakelock_macos: bc3f2a9bd8d2e6c89fee1e1822e7ddac3bd004a9 -PODFILE CHECKSUM: 5107934592df7813b33d744aebc8ddc6b5a5445f +PODFILE CHECKSUM: 505596d150d38022472859d890f709281982e016 COCOAPODS: 1.11.2 diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 911fa9fcc..a7d9e2807 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -75,6 +75,7 @@ 9646C67C7114830A5ACFF5DF /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; 9F565D5729954F53009A75FB /* secRandom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = secRandom.swift; path = CakeWallet/secRandom.swift; sourceTree = ""; }; + 9F565D5829954F53009A75FB /* decrypt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = decrypt.swift; path = CakeWallet/decrypt.swift; sourceTree = ""; }; B38D1DBC56DBD386923BC063 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -104,6 +105,7 @@ 33CC10E42044A3C60003C045 = { isa = PBXGroup; children = ( + 9F565D5829954F53009A75FB /* decrypt.swift */, 9F565D5729954F53009A75FB /* secRandom.swift */, 33FAB671232836740065AC1E /* Runner */, 33CEB47122A05771004F2AC0 /* Flutter */, diff --git a/pubspec_base.yaml b/pubspec_base.yaml index 1aaf1c6c2..70e46fe91 100644 --- a/pubspec_base.yaml +++ b/pubspec_base.yaml @@ -49,8 +49,8 @@ dependencies: # password: ^1.0.0 basic_utils: ^4.3.0 get_it: ^7.2.0 - # connectivity: ^3.0.3 - connectivity_plus: ^2.3.5 + connectivity: ^3.0.3 + # connectivity_plus: ^2.3.5 keyboard_actions: ^4.0.1 another_flushbar: ^1.12.29 archive: ^3.3.0 diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb index 9e68646d6..e44480c3d 100644 --- a/res/values/strings_ar.arb +++ b/res/values/strings_ar.arb @@ -492,7 +492,7 @@ "submit_request":"تقديم طلب", "buy_alert_content":"لا ندعم حاليًا سوى شراء Bitcoin و Litecoin و Monero. يرجى إنشاء محفظة Bitcoin أو Litecoin أو Monero أو التبديل إليها.", - "sell_alert_content":"نحن ندعم حاليًا فقط بيع Bitcoin و Litecoin. يرجى إنشاء أو التبديل إلى محفظة Bitcoin أو Litecoin الخاصة بك.", + "sell_alert_content":"نحن ندعم حاليًا بيع البيتكوين فقط. لبيع Bitcoin ، يرجى إنشاء أو التبديل إلى محفظة Bitcoin الخاصة بك.", "outdated_electrum_wallet_description":"محافظ Bitcoin الجديدة التي تم إنشاؤها في Cake الآن سييد مكونة من 24 كلمة. من الضروري أن تقوم بإنشاء محفظة Bitcoin جديدة وتحويل جميع أموالك إلى المحفظة الجديدة المكونة من 24 كلمة ، والتوقف عن استخدام محافظ سييد مكونة من 12 كلمة. يرجى القيام بذلك على الفور لتأمين أموالك.", "understand":"لقد فهمت", diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb index 7903be4fb..66ccbbabc 100644 --- a/res/values/strings_bg.arb +++ b/res/values/strings_bg.arb @@ -492,7 +492,7 @@ "submit_request" : "изпращане на заявка", "buy_alert_content" : "Понастоящем поддържаме само закупуване на Bitcoin, Litecoin и Monero. Моля, създайте или преминете към своя портфейл Bitcoin, Litecoin или Monero.", - "sell_alert_content": "В момента поддържаме само продажбата на Bitcoin и Litecoin. Моля, създайте или превключете към своя биткойн или лайткойн портфейл.", + "sell_alert_content": "В момента поддържаме само продажбата на Bitcoin. За да продавате Bitcoin, създайте или изберете своя Bitcoin портфейл.", "outdated_electrum_wallet_description" : "Нови Bitcoin портфейли, създадени в Cake, сега имат seed от 24 думи. Трябва да създадете нов Bitcoin адрес и да прехвърлите всичките си средства в него и веднага да спрете използването на стари портфейли. Моля, напревете това незабавно, за да подсигурите средствата си.", "understand" : "Разбирам", diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb index b10e452fa..a0de3122b 100644 --- a/res/values/strings_cs.arb +++ b/res/values/strings_cs.arb @@ -492,7 +492,7 @@ "submit_request" : "odeslat požadavek", "buy_alert_content" : "V současné době podporujeme pouze nákup Bitcoinů, Litecoinů a Monero. Vytvořte nebo přepněte na svou peněženku Bitcoinů, Litecoinů nebo Monero.", - "sell_alert_content": "V současné době podporujeme pouze prodej bitcoinů a litecoinů. Vytvořte nebo přepněte na svou bitcoinovou nebo litecoinovou peněženku.", + "sell_alert_content": "V současné době podporujeme pouze prodej Bitcoinu. Pro prodej Bitcoinu si prosím vytvořte Bitcoinovou peněženku, nebo se do ní přepněte.", "outdated_electrum_wallet_description" : "Nové Bitcoinové peněženky vytvořené v Cake mají nyní seed se 24 slovy. Je třeba si vytvořit novou Bitcoinovou peněženku se 24 slovy, převést na ni všechny prostředky a přestat používat seed se 12 slovy. Prosím udělejte to hned pro zabezpečení svých prostředků.", "understand" : "Rozumím", diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index ee3faf144..e018616f2 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -492,7 +492,7 @@ "submit_request" : "Eine Anfrage stellen", "buy_alert_content" : "Derzeit unterstützen wir nur den Kauf von Bitcoin, Litecoin und Monero. Bitte erstellen oder wechseln Sie zu Ihrer Bitcoin-, Litecoin- oder Monero-Wallet.", - "sell_alert_content": "Wir unterstützen derzeit nur den Verkauf von Bitcoin und Litecoin. Bitte erstellen Sie Ihr Bitcoin- oder Litecoin-Wallet oder wechseln Sie zu diesem.", + "sell_alert_content": "Wir unterstützen derzeit nur den Verkauf von Bitcoin. Um Bitcoin zu verkaufen, erstellen Sie bitte Ihre Bitcoin-Wallet oder wechseln Sie zu ihr.", "outdated_electrum_wallet_description" : "Neue Bitcoin-Wallets, die in Cake erstellt wurden, haben jetzt einen 24-Wort-Seed. Sie müssen eine neue Bitcoin-Wallet erstellen, Ihr gesamtes Geld in die neue 24-Wort-Wallet überweisen und keine Wallet mit einem 12-Wort-Seed mehr verwenden. Bitte tun Sie dies sofort, um Ihr Geld zu sichern.", "understand" : "Ich verstehe", diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index 2859d3ea6..5992cf270 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -492,7 +492,7 @@ "submit_request" : "submit a request", "buy_alert_content" : "Currently we only support the purchase of Bitcoin, Litecoin, and Monero. Please create or switch to your Bitcoin, Litecoin, or Monero wallet.", - "sell_alert_content": "We currently only support the sale of Bitcoin and Litecoin. Please create or switch to your Bitcoin or Litecoin wallet.", + "sell_alert_content": "We currently only support the sale of Bitcoin. To sell Bitcoin, please create or switch to your Bitcoin wallet.", "outdated_electrum_wallet_description" : "New Bitcoin wallets created in Cake now have a 24-word seed. It is mandatory that you create a new Bitcoin wallet and transfer all of your funds to the new 24-word wallet, and stop using wallets with a 12-word seed. Please do this immediately to secure your funds.", "understand" : "I understand", diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 8c7b74756..69587f133 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -492,7 +492,7 @@ "submit_request" : "presentar una solicitud", "buy_alert_content" : "Actualmente solo admitimos la compra de Bitcoin, Litecoin y Monero. Cree o cambie a su billetera Bitcoin, Litecoin o Monero.", - "sell_alert_content": "Actualmente solo admitimos la venta de Bitcoin y Litecoin. Cree o cambie a su billetera Bitcoin o Litecoin.", + "sell_alert_content": "Actualmente solo admitimos la venta de Bitcoin. Para vender Bitcoin, cree o cambie a su billetera Bitcoin.", "outdated_electrum_wallet_description" : "Las nuevas carteras de Bitcoin creadas en Cake ahora tienen una semilla de 24 palabras. Es obligatorio que cree una nueva billetera de Bitcoin y transfiera todos sus fondos a la nueva billetera de 24 palabras, y deje de usar billeteras con una semilla de 12 palabras. Haga esto de inmediato para asegurar sus fondos.", "understand" : "Entiendo", diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index 73be578a6..da783faee 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -492,7 +492,7 @@ "submit_request" : "soumettre une requête", "buy_alert_content" : "Actuellement, nous ne prenons en charge que l'achat de Bitcoin, Litecoin et Monero. Veuillez créer ou basculer vers votre portefeuille (wallet) Bitcoin, Litecoin ou Monero.", - "sell_alert_content": "Actuellement, nous ne prenons en charge que la vente de Bitcoin et Litecoin. Veuillez créer ou basculer vers votre portefeuille (wallet) Bitcoin ou Litecoin.", + "sell_alert_content": "Pour le moment nous ne supportons que la vente de Bitcoin. Pour vendre du Bitcoin, merci de créer ou de sélectionner votre portefeuille (wallet) Bitcoin.", "outdated_electrum_wallet_description" : "Les nouveaux portefeuilles (wallets) Bitcoin créés dans Cake ont dorénavant une phrase secrète (seed) de 24 mots. Il est impératif que vous créiez un nouveau portefeuille Bitcoin, que vous y transfériez tous vos fonds puis que vous cessiez d'utiliser le portefeuille avec une phrase secrète de 12 mots. Merci de faire cela immédiatement pour assurer la sécurité de vos avoirs.", "understand" : "J'ai compris", @@ -691,14 +691,14 @@ "arrive_in_this_address" : "${currency} ${tag}arrivera à cette adresse", "do_not_send": "Ne pas envoyer", "error_dialog_content": "Oups, nous avons rencontré une erreur.\n\nMerci d'envoyer le rapport d'erreur à notre équipe d'assistance afin de nous permettre d'améliorer l'application.", - "scan_qr_code": "Scannez le QR code", - "cold_or_recover_wallet": "Ajoutez un portefeuille froid (cold wallet) ou récupérez un portefeuille papier (paper wallet)", - "please_wait": "Merci de patienter", - "sweeping_wallet": "Portefeuille (wallet) de consolidation", - "sweeping_wallet_alert": "Cette opération ne devrait pas prendre longtemps. NE QUITTEZ PAS CET ÉCRAN OU LES FONDS CONSOLIDÉS POURRAIENT ÊTRE PERDUS", + "scan_qr_code": "Scannez le code QR", + "cold_or_recover_wallet": "Ajoutez un cold wallet ou récupérez un paper wallet", + "please_wait": "S'il vous plaît, attendez", + "sweeping_wallet": "Portefeuille de balayage", + "sweeping_wallet_alert": "Cela ne devrait pas prendre longtemps. NE QUITTEZ PAS CET ÉCRAN OU LES FONDS BALAYÉS POURRAIENT ÊTRE PERDUS", "decimal_places_error": "Trop de décimales", "edit_node": "Modifier le nœud", - "frozen_balance": "Solde gelé", + "frozen_balance": "Équilibre gelé", "invoice_details": "Détails de la facture", "donation_link_details": "Détails du lien de don", "anonpay_description": "Générez ${type}. Le destinataire peut ${method} avec n'importe quelle crypto-monnaie prise en charge, et vous recevrez des fonds dans ce portefeuille (wallet).", @@ -715,22 +715,22 @@ "error_text_input_above_maximum_limit" : "Le montant est supérieur au maximum", "show_market_place" :"Afficher la place de marché", "prevent_screenshots": "Empêcher les captures d'écran et l'enregistrement d'écran", - "modify_2fa": "Modifier les paramètres Cake 2FA", - "disable_cake_2fa": "Désactiver Cake 2FA", - "question_to_disable_2fa":"Êtes-vous sûr de vouloir désactiver Cake 2FA ? Un code 2FA ne sera plus nécessaire pour accéder au portefeuille (wallet) et à certaines fonctions.", + "modify_2fa": "Modifier le gâteau 2FA", + "disable_cake_2fa": "Désactiver le gâteau 2FA", + "question_to_disable_2fa":"Êtes-vous sûr de vouloir désactiver Cake 2FA ? Un code 2FA ne sera plus nécessaire pour accéder au portefeuille et à certaines fonctions.", "disable": "Désactiver", - "setup_2fa": "Paramétrer Cake 2FA", + "setup_2fa": "Gâteau d'installation 2FA", "verify_with_2fa": "Vérifier avec Cake 2FA", "totp_code": "Code TOTP", - "please_fill_totp": "Veuillez renseigner le code à 8 chiffres affiché sur votre autre appareil", - "totp_2fa_success": "Succès! Cake 2FA est activé pour ce portefeuille. N'oubliez pas de sauvegarder votre phrase secrète (seed) au cas où vous perdriez l'accès au portefeuille (wallet).", + "please_fill_totp": "Veuillez renseigner le code à 8 chiffres présent sur votre autre appareil", + "totp_2fa_success": "Succès! Cake 2FA activé pour ce portefeuille. N'oubliez pas de sauvegarder votre graine mnémonique au cas où vous perdriez l'accès au portefeuille.", "totp_verification_success" :"Vérification réussie !", - "totp_2fa_failure": "Code incorrect. Veuillez essayer un code différent ou générer un nouveau secret TOTP. Utilisez une application 2FA compatible qui prend en charge les codes à 8 chiffres et SHA512.", + "totp_2fa_failure": "Code incorrect. Veuillez essayer un code différent ou générer une nouvelle clé secrète. Utilisez une application 2FA compatible qui prend en charge les codes à 8 chiffres et SHA512.", "enter_totp_code": "Veuillez entrer le code TOTP.", - "add_secret_code":"Configurer un autre appareil à l'aide de ce secret TOTP", - "totp_secret_code":"Secret TOTP", + "add_secret_code":"Ajouter ce code secret à un autre appareil", + "totp_secret_code":"Code secret TOTP", "important_note": "Note importante", - "setup_2fa_text": "Cake 2FA (Authentification à 2 Facteurs) n'est PAS aussi sûr que le stockage à froid. Cake 2FA protège contre les attaques basiques, comme un ami fournissant votre empreinte digitale pendant que vous dormez.\n\n Cake 2FA ne protège PAS contre un appareil compromis par un attaquant sophistiqué.\n\n Si vous perdez l'accès à vos codes 2FA , VOUS PERDREZ L'ACCÈS À CE PORTEFEUILLE (WALLET). Vous devrez restaurer votre portefeuille à partir de sa phrase secrète (seed). VOUS DEVEZ DONC SAUVEGARDER VOTRE PHRASE SECRÈTE ! De plus, quelqu'un ayant accès à votre phrase secrète pourra voler vos fonds, en contournant Cake 2FA.\n\n Le personnel d'assistance de Cake ne pourra pas vous aider si vous perdez l'accès à votre phrase secrète, puisque Cake est un portefeuille non dépositaire (non custodial).", + "setup_2fa_text": "Cake 2FA n'est PAS aussi sûr que le stockage à froid. 2FA protège contre les types d'attaques de base, comme votre ami fournissant votre empreinte digitale pendant que vous dormez.\n\n Cake 2FA ne protège PAS contre un appareil compromis par un attaquant sophistiqué.\n\n Si vous perdez l'accès à vos codes 2FA , VOUS PERDREZ L'ACCÈS À CE PORTEFEUILLE. Vous devrez restaurer votre portefeuille à partir de graines mnémotechniques. VOUS DEVEZ DONC SAUVEGARDER VOS SEMENCES MNEMONIQUES ! De plus, quelqu'un ayant accès à vos graines mnémoniques pourra voler vos fonds, en contournant Cake 2FA.\n\n Le personnel d'assistance de Cake ne pourra pas vous aider si vous perdez l'accès à vos graines mnémoniques, puisque Cake est un portefeuille non dépositaire.", "setup_totp_recommended": "Configurer TOTP (recommandé)", "disable_buy": "Désactiver l'action d'achat", "disable_sell": "Désactiver l'action de vente" diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb index 14493fced..0e2c136ee 100644 --- a/res/values/strings_ha.arb +++ b/res/values/strings_ha.arb @@ -487,7 +487,7 @@ "submit_request": "gabatar da bukata", "buy_alert_content": "A halin yanzu muna tallafawa kawai siyan Bitcoin da Litecoin. Don siyan Bitcoin ko Litecoin, da fatan za a ƙirƙira ko canza zuwa walat ɗin ku na Bitcoin ko Litecoin.", - "sell_alert_content": "A halin yanzu muna tallafawa siyar da Bitcoin da Litecoin kawai. Da fatan za a ƙirƙira ko canza zuwa walat ɗin ku na Bitcoin ko Litecoin.", + "sell_alert_content": "A halin yanzu muna tallafawa siyar da Bitcoin kawai. Don sayar da Bitcoin, da fatan za a ƙirƙira ko canza zuwa walat ɗin ku na Bitcoin.", "outdated_electrum_wallet_description": "Sabbin walat ɗin Bitcoin da aka kirkira a cikin Cake yanzu suna da nau'in kalma 24. Ya zama dole ka ƙirƙiri sabon walat ɗin Bitcoin kuma canza duk kuɗin ku zuwa sabon walat ɗin kalmomi 24, kuma ku daina amfani da walat tare da iri mai kalma 12. Da fatan za a yi haka nan take don samun kuɗin ku.", "understand": "na gane", diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index 042bc149b..575cae485 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -492,7 +492,7 @@ "submit_request" : "एक अनुरोध सबमिट करें", "buy_alert_content" : "वर्तमान में हम केवल बिटकॉइन, लाइटकॉइन और मोनेरो की खरीद का समर्थन करते हैं। कृपया अपना बिटकॉइन, लाइटकॉइन, या मोनेरो वॉलेट बनाएं या स्विच करें।", - "sell_alert_content": "वर्तमान में हम केवल बिटकॉइन और लाइटकॉइन की बिक्री का समर्थन करते हैं। कृपया अपना बिटकॉइन या लाइटकॉइन वॉलेट बनाएं या स्विच करें।", + "sell_alert_content": "हम वर्तमान में केवल बिटकॉइन की बिक्री का समर्थन करते हैं। बिटकॉइन बेचने के लिए, कृपया अपना बिटकॉइन वॉलेट बनाएं या उसमें स्विच करें।", "outdated_electrum_wallet_description" : "केक में बनाए गए नए बिटकॉइन वॉलेट में अब 24-शब्द का बीज है। यह अनिवार्य है कि आप एक नया बिटकॉइन वॉलेट बनाएं और अपने सभी फंड को नए 24-शब्द वाले वॉलेट में स्थानांतरित करें, और 12-शब्द बीज वाले वॉलेट का उपयोग करना बंद करें। कृपया अपने धन को सुरक्षित करने के लिए इसे तुरंत करें।", "understand" : "मुझे समझ", diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index 7f094daa7..9a7e41b5a 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -492,7 +492,7 @@ "submit_request" : "podnesi zahtjev", "buy_alert_content" : "Trenutno podržavamo samo kupnju Bitcoina, Litecoina i Monera. Izradite ili prijeđite na svoj Bitcoin, Litecoin ili Monero novčanik.", - "sell_alert_content": "Trenutno podržavamo samo prodaju Bitcoina i Litecoina. Izradite ili prijeđite na svoj Bitcoin ili Litecoin novčanik.", + "sell_alert_content": "Trenutno podržavamo samo prodaju Bitcoina. Da biste prodali Bitcoin, stvorite ili prijeđite na svoj Bitcoin novčanik.", "outdated_electrum_wallet_description" : "Novi Bitcoin novčanici stvoreni u Cakeu sada imaju sjeme od 24 riječi. Obavezno je stvoriti novi Bitcoin novčanik i prenijeti sva svoja sredstva u novi novčanik od 24 riječi te prestati koristiti novčanike s sjemenkom od 12 riječi. Učinite to odmah kako biste osigurali svoja sredstva.", "understand" : "Razumijem", diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb index be271bbec..fb0d04743 100644 --- a/res/values/strings_id.arb +++ b/res/values/strings_id.arb @@ -479,7 +479,7 @@ "submit_request" : "kirim permintaan", "buy_alert_content" : "Saat ini kami hanya mendukung pembelian Bitcoin, Litecoin, dan Monero. Harap buat atau alihkan ke dompet Bitcoin, Litecoin, atau Monero Anda.", - "sell_alert_content": "Saat ini kami hanya mendukung penjualan Bitcoin dan Litecoin. Harap buat atau alihkan ke dompet Bitcoin atau Litecoin Anda.", + "sell_alert_content": "Saat ini kami hanya mendukung penjualan Bitcoin. Untuk menjual Bitcoin, silakan buat atau beralih ke dompet Bitcoin Anda.", "outdated_electrum_wallet_description" : "Dompet Bitcoin baru yang dibuat di Cake sekarang memiliki biji semai 24 kata. Wajib bagi Anda untuk membuat dompet Bitcoin baru dan mentransfer semua dana Anda ke dompet 24 kata baru, dan berhenti menggunakan dompet dengan biji semai 12 kata. Silakan lakukan ini segera untuk mengamankan dana Anda.", "understand" : "Saya mengerti", diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index b4064898f..d1fc5df11 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -492,7 +492,7 @@ "submit_request" : "invia una richiesta", "buy_alert_content" : "Attualmente supportiamo solo l'acquisto di Bitcoin, Litecoin e Monero. Crea o passa al tuo portafoglio Bitcoin, Litecoin o Monero.", - "sell_alert_content": "Al momento supportiamo solo la vendita di Bitcoin e Litecoin. Crea o passa al tuo portafoglio Bitcoin o Litecoin.", + "sell_alert_content": "Al momento supportiamo solo la vendita di Bitcoin. Per vendere Bitcoin, crea o passa al tuo portafoglio Bitcoin.", "outdated_electrum_wallet_description" : "I nuovi portafogli Bitcoin creati in Cake ora hanno un seme di 24 parole. È obbligatorio creare un nuovo portafoglio Bitcoin e trasferire tutti i fondi nel nuovo portafoglio di 24 parole e smettere di usare portafogli con un seme di 12 parole. Ti preghiamo di farlo immediatamente per proteggere i tuoi fondi.", "understand" : "Capisco", diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index 92eecedb5..e2c4315be 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -492,7 +492,7 @@ "submit_request" : "リクエストを送信する", "buy_alert_content" : "現在、ビットコイン、ライトコイン、モネロの購入のみをサポートしています。 Bitcoin、Litecoin、または Monero ウォレットを作成するか、切り替えてください。", - "sell_alert_content": "現在、ビットコインとライトコインの販売のみをサポートしています。 ビットコインまたはライトコインウォレットを作成するか、ウォレットに切り替えてください。", + "sell_alert_content": "現在、ビットコインの販売のみをサポートしています。ビットコインを販売するには、ビットコインウォレットを作成するか切り替えてください。", "outdated_electrum_wallet_description" : "Cakeで作成された新しいビットコインウォレットには、24ワードのシードがあります。 新しいビットコインウォレットを作成し、すべての資金を新しい24ワードのウォレットに転送し、12ワードのシードを持つウォレットの使用を停止することが必須です。 あなたの資金を確保するためにこれをすぐに行ってください。", "understand" : "わかります", diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index fdb2efb7b..fb0cd46e9 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -492,7 +492,7 @@ "submit_request" : "요청을 제출", "buy_alert_content" : "현재 우리는 Bitcoin, Litecoin 및 Monero 구매만 지원합니다. Bitcoin, Litecoin 또는 Monero 지갑을 생성하거나 전환하십시오.", - "sell_alert_content": "현재 Bitcoin 및 Litecoin 판매만 지원합니다. Bitcoin 또는 Litecoin 지갑을 생성하거나 전환하십시오.", + "sell_alert_content": "현재 비트코인 ​​판매만 지원합니다. 비트코인을 판매하려면 비트코인 ​​지갑을 생성하거나 전환하세요.", "outdated_electrum_wallet_description" : "Cake에서 생성 된 새로운 비트 코인 지갑에는 이제 24 단어 시드가 있습니다. 새로운 비트 코인 지갑을 생성하고 모든 자금을 새로운 24 단어 지갑으로 이체하고 12 단어 시드가있는 지갑 사용을 중지해야합니다. 자금을 확보하려면 즉시이 작업을 수행하십시오.", "understand" : "이해 했어요", diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb index dce50b1d5..a9ac402e6 100644 --- a/res/values/strings_my.arb +++ b/res/values/strings_my.arb @@ -492,7 +492,7 @@ "submit_request" : "တောင်းဆိုချက်တစ်ခုတင်ပြပါ။", "buy_alert_content" : "လောလောဆယ်တွင် ကျွန်ုပ်တို့သည် Bitcoin၊ Litecoin နှင့် Monero တို့ကိုသာ ဝယ်ယူမှုကို ပံ့ပိုးပေးပါသည်။ သင်၏ Bitcoin၊ Litecoin သို့မဟုတ် Monero ပိုက်ဆံအိတ်ကို ဖန်တီးပါ သို့မဟုတ် ပြောင်းပါ။", - "sell_alert_content" : "ကျွန်ုပ်တို့သည် လက်ရှိတွင် Bitcoin နှင့် Litecoin ရောင်းချခြင်းကိုသာ ထောက်ခံပါသည်။ သင်၏ Bitcoin သို့မဟုတ် Litecoin ပိုက်ဆံအိတ်ကို ဖန်တီးပါ သို့မဟုတ် ပြောင်းပါ။", + "sell_alert_content" : "ကျွန်ုပ်တို့သည် လက်ရှိတွင် Bitcoin ရောင်းချခြင်းကိုသာ ပံ့ပိုးပေးပါသည်။ Bitcoin ရောင်းချရန်၊ သင်၏ Bitcoin ပိုက်ဆံအိတ်ကို ဖန်တီးပါ သို့မဟုတ် ပြောင်းပါ။", "outdated_electrum_wallet_description" : "ယခု Cake တွင်ဖန်တီးထားသော Bitcoin ပိုက်ဆံအိတ်အသစ်တွင် စကားလုံး 24 မျိုးရှိသည်။ Bitcoin ပိုက်ဆံအိတ်အသစ်တစ်ခုကို ဖန်တီးပြီး သင့်ငွေအားလုံးကို 24 စကားလုံးပိုက်ဆံအိတ်အသစ်သို့ လွှဲပြောင်းပြီး 12 စကားလုံးမျိုးစေ့ဖြင့် ပိုက်ဆံအိတ်များကို အသုံးပြုခြင်းကို ရပ်တန့်ရန် မဖြစ်မနေလိုအပ်ပါသည်။ သင့်ရန်ပုံငွေများကို လုံခြုံစေရန်အတွက် ၎င်းကိုချက်ချင်းလုပ်ဆောင်ပါ။", "understand" : "ကျွန်တော်နားလည်ပါတယ်", diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index 4f2384004..cf3b94c51 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -492,7 +492,7 @@ "submit_request" : "een verzoek indienen", "buy_alert_content" : "Momenteel ondersteunen we alleen de aankoop van Bitcoin, Litecoin en Monero. Maak of schakel over naar uw Bitcoin-, Litecoin- of Monero-portemonnee.", - "sell_alert_content": "We ondersteunen momenteel alleen de verkoop van Bitcoin en Litecoin. Maak of schakel over naar uw Bitcoin- of Litecoin-portemonnee.", + "sell_alert_content": "We ondersteunen momenteel alleen de verkoop van Bitcoin. Om Bitcoin te verkopen, maakt u uw Bitcoin-portemonnee aan of schakelt u over naar deze.", "outdated_electrum_wallet_description" : "Nieuwe Bitcoin-portefeuilles die in Cake zijn gemaakt, hebben nu een zaadje van 24 woorden. Het is verplicht dat u een nieuwe Bitcoin-portemonnee maakt en al uw geld overmaakt naar de nieuwe portemonnee van 24 woorden, en stopt met het gebruik van wallets met een seed van 12 woorden. Doe dit onmiddellijk om uw geld veilig te stellen.", "understand" : "Ik begrijp het", diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index e59f0e0b6..44f5d10c1 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -492,7 +492,7 @@ "submit_request" : "Złóż wniosek", "buy_alert_content" : "Obecnie obsługujemy tylko zakup Bitcoin, Litecoin i Monero. Utwórz lub przełącz się na swój portfel Bitcoin, Litecoin lub Monero.", - "sell_alert_content": "Obecnie obsługujemy tylko sprzedaż Bitcoin i Litecoin. Utwórz lub przełącz się na swój portfel Bitcoin lub Litecoin.", + "sell_alert_content": "Obecnie obsługujemy tylko sprzedaż Bitcoina. Aby sprzedać Bitcoin, utwórz lub przełącz się na swój portfel Bitcoin.", "outdated_electrum_wallet_description" : "Nowe portfele Bitcoin utworzone w Cake mają teraz fraze seed składające się z 24 słów. Konieczne jest utworzenie nowego portfela Bitcoin i przeniesienie wszystkich środków do nowego portfela na 24 słowa oraz zaprzestanie korzystania z portfeli z frazą seed na 12 słów. Zrób to natychmiast, aby zabezpieczyć swoje fundusze.", "understand" : "Rozumiem", diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index 6ab076310..d1776bc2f 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -492,7 +492,7 @@ "submit_request" : "enviar um pedido", "buy_alert_content" : "Atualmente, oferecemos suporte apenas à compra de Bitcoin, Litecoin e Monero. Crie ou troque para sua carteira Bitcoin, Litecoin ou Monero.", - "sell_alert_content": "Atualmente, oferecemos suporte apenas à venda de Bitcoin e Litecoin. Por favor, crie ou mude para sua carteira Bitcoin ou Litecoin.", + "sell_alert_content": "Atualmente, apoiamos apenas a venda de Bitcoin. Para vender Bitcoin, crie ou mude para sua carteira Bitcoin.", "outdated_electrum_wallet_description" : "As novas carteiras Bitcoin criadas no Cake agora têm uma semente de 24 palavras. É obrigatório que você crie uma nova carteira Bitcoin e transfira todos os seus fundos para a nova carteira de 24 palavras, e pare de usar carteiras com semente de 12 palavras. Faça isso imediatamente para garantir seus fundos.", "understand" : "Entendo", diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index 18ed4dc4e..77e149479 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -492,7 +492,7 @@ "submit_request" : "отправить запрос", "buy_alert_content" : "В настоящее время мы поддерживаем только покупку Bitcoin, Litecoin и Monero. Пожалуйста, создайте или переключитесь на свой кошелек Bitcoin, Litecoin или Monero.", - "sell_alert_content": "В настоящее время мы поддерживаем только продажу биткойнов и лайткойнов. Пожалуйста, создайте или переключитесь на свой биткойн- или лайткойн-кошелек.", + "sell_alert_content": "В настоящее время мы поддерживаем только продажу биткойнов. Чтобы продать биткойны, создайте или переключитесь на свой биткойн-кошелек.", "outdated_electrum_wallet_description" : "Новые биткойн-кошельки, созданные в Cake, теперь содержат мнемоническую фразу из 24 слов. Вы обязательно должны создать новый биткойн-кошелек и перевести все свои средства в новый кошелек из 24 слов, а также прекратить использование кошельков с мнемонической фразой из 12 слов. Пожалуйста, сделайте это немедленно, чтобы обезопасить свои средства.", "understand" : "Понятно", diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb index 265d6b649..6a7937c16 100644 --- a/res/values/strings_th.arb +++ b/res/values/strings_th.arb @@ -490,7 +490,7 @@ "submit_request" : "ส่งคำขอ", "buy_alert_content" : "ขณะนี้เรารองรับการซื้อ Bitcoin, Litecoin และ Monero เท่านั้น โปรดสร้างหรือเปลี่ยนเป็นกระเป๋าเงิน Bitcoin, Litecoin หรือ Monero ของคุณ", - "sell_alert_content" : "ขณะนี้เราสนับสนุนการขาย Bitcoin และ Litecoin เท่านั้น โปรดสร้างหรือเปลี่ยนเป็นกระเป๋าเงิน Bitcoin หรือ Litecoin ของคุณ", + "sell_alert_content" : "ในปัจจุบันเรารองรับการขาย Bitcoin เท่านั้น หากต้องการขาย Bitcoin โปรดสร้างหรือเปลี่ยนเป็นกระเป๋า Bitcoin ของคุณ", "outdated_electrum_wallet_description" : "กระเป๋า Bitcoin ใหม่ที่สร้างใน Cake มี seed ขนาด 24 คำ ซึ่งจำเป็นต้องสร้างกระเป๋า Bitcoin ใหม่และโอนทุกเงินของคุณไปยังกระเป๋าใหม่ขนาด 24 คำ และหยุดใช้กระเป๋าที่มี seed ขนาด 12 คำ กรุณาทำด่วนเพื่อรักษาเงินของคุณ", "understand" : "ฉันเข้าใจ", diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb index 644e7069a..c36f7a3d3 100644 --- a/res/values/strings_tr.arb +++ b/res/values/strings_tr.arb @@ -492,7 +492,7 @@ "submit_request" : "talep gönder", "buy_alert_content" : "Şu anda yalnızca Bitcoin, Litecoin ve Monero satın alımını destekliyoruz. Lütfen Bitcoin, Litecoin veya Monero cüzdanınızı oluşturun veya cüzdanınıza geçiş yapın.", - "sell_alert_content": "Şu anda yalnızca Bitcoin ve Litecoin satışını destekliyoruz. Lütfen Bitcoin veya Litecoin cüzdanınızı oluşturun veya cüzdanınıza geçiş yapın.", + "sell_alert_content": "Şu anda sadece Bitcoin satışını destekliyoruz. Bitcoin satmak için lütfen Bitcoin cüzdanınızı oluşturun veya Bitcoin cüzdanınıza geçiş yapın.", "outdated_electrum_wallet_description" : "Cake'te oluşturulan yeni Bitcoin cüzdanları artık 24 kelimelik bir tohuma sahip. Yeni bir Bitcoin cüzdanı oluşturmanız ve tüm paranızı 24 kelimelik yeni cüzdana aktarmanız ve 12 kelimelik tohuma sahip cüzdanları kullanmayı bırakmanız zorunludur. Lütfen paranızı güvence altına almak için bunu hemen yapın.", "understand" : "Anladım", diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index 624042d8d..2fa0c7cf4 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -491,7 +491,7 @@ "submit_request" : "надіслати запит", "buy_alert_content" : "Наразі ми підтримуємо лише придбання Bitcoin, Litecoin і Monero. Створіть або перейдіть на свій гаманець Bitcoin, Litecoin або Monero.", - "sell_alert_content": "Зараз ми підтримуємо лише продаж біткойнів і лайткоінів. Будь ласка, створіть або перейдіть на свій гаманець Bitcoin або Litecoin.", + "sell_alert_content": "Наразі ми підтримуємо лише продаж біткойнів. Щоб продати біткойн, створіть або перейдіть на свій біткойн-гаманець.", "outdated_electrum_wallet_description" : "Нові біткойн-гаманці, створені в Cake, тепер містять мнемонічну фразу з 24 слів. Обов’язково стовріть новий біткойн-гаманець, переведіть всі кошти на новий гаманець із 24 слів і припиніть використання гаманців із мнемонічною фразою з 12 слів. Зробіть це негайно, щоб убезпечити свої кошти.", "understand" : "Зрозуміло", diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb index a00794e48..7d20c9423 100644 --- a/res/values/strings_ur.arb +++ b/res/values/strings_ur.arb @@ -494,7 +494,7 @@ "submit_request" : "درخواست بھیج دو", "buy_alert_content" : "فی الحال ہم صرف Bitcoin، Litecoin، اور Monero کی خریداری کی حمایت کرتے ہیں۔ براہ کرم اپنا Bitcoin، Litecoin، یا Monero والیٹ بنائیں یا اس پر سوئچ کریں۔", - "sell_alert_content" : "ہم فی الحال صرف Bitcoin اور Litecoin کی فروخت کی حمایت کرتے ہیں۔ براہ کرم اپنا Bitcoin یا Litecoin والیٹ بنائیں یا اس پر سوئچ کریں۔", + "sell_alert_content" : "ہم فی الحال صرف Bitcoin کی فروخت کی حمایت کرتے ہیں۔ Bitcoin فروخت کرنے کے لیے، براہ کرم اپنا Bitcoin والیٹ بنائیں یا اس میں سوئچ کریں۔", "outdated_electrum_wallet_description" : "Cake میں بنائے گئے نئے Bitcoin بٹوے میں اب 24 الفاظ کا بیج ہے۔ یہ لازمی ہے کہ آپ ایک نیا Bitcoin والیٹ بنائیں اور اپنے تمام فنڈز کو نئے 24 الفاظ والے والیٹ میں منتقل کریں، اور 12 الفاظ کے بیج والے بٹوے کا استعمال بند کریں۔ براہ کرم اپنے فنڈز کو محفوظ بنانے کے لیے فوری طور پر ایسا کریں۔", "understand" : "میں سمجھتا ہوں۔", diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb index cb38a09df..57ed51d24 100644 --- a/res/values/strings_yo.arb +++ b/res/values/strings_yo.arb @@ -483,7 +483,7 @@ "submit_request" : "Ṣé ìbéèrè", "buy_alert_content" : "A jẹ́ kí ríra Bitcoin àti Litecoin nìkan. Ẹ jọ̀wọ́ dá tàbí sún àpamọ́wọ́ ti Bitcoin yín tàbí àpamọ́wọ́ ti Litecoin yín mọ́, t'ẹ́ bá fẹ́ ra Bitcoin tàbí Litecoin.", - "sell_alert_content": "Lọwọlọwọ a ṣe atilẹyin tita Bitcoin ati Litecoin nikan. Jọwọ ṣẹda tabi yipada si Bitcoin tabi apamọwọ Litecoin rẹ.", + "sell_alert_content": "A jẹ́ kí títa Bitcoin nìkan. Ẹ jọ̀wọ́ dá tàbí sún àpamọ́wọ́ ti Bitcoin yín mọ́, t'ẹ́ bá fẹ́ ta Bitcoin.", "outdated_electrum_wallet_description" : "Àwọn àpamọ́wọ́ títun Bitcoin ti a ti dá nínú Cake Wallet lọ́wọ́lọ́wọ́. Àwọn àpamọ́wọ́ títun t'á dá nínú Cake Wallet ni hóró tó ní ọ̀rọ̀ mẹ́rinlélógún. Ẹ gbọ́dọ̀ dá àpamọ́wọ́. Ẹ sì sún gbogbo owó yín sí àpamọ́wọ́ títun náà tó dá lórí ọ̀rọ̀ mẹ́rinlélógún. Ẹ sì gbọ́dọ̀ yé lo àwọn àpamọ́wọ́ tó dá lórí hóró tó ní ọ̀rọ̀ méjìlá. Ẹ jọ̀wọ́ ṣe èyí láìpẹ́ kí ẹ ba owó yín.", "understand" : "Ó ye mi", diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index dd0e05fcd..ed5426ade 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -491,7 +491,7 @@ "submit_request" : "提交请求", "buy_alert_content" : "目前我们只支持购买比特币、莱特币和门罗币。 请创建或切换到您的比特币、莱特币或门罗币钱包。", - "sell_alert_content" : "我们目前只支持比特币和莱特币的销售。 请创建或切换到您的比特币或莱特币钱包。", + "sell_alert_content" : "我们目前只支持比特币的销售。 要出售比特币,请创建或切换到您的比特币钱包。", "outdated_electrum_wallet_description" : "在Cake创建的新比特币钱包现在有一个24字的种子。你必须创建一个新的比特币钱包,并将你所有的资金转移到新的24字钱包,并停止使用12字种子的钱包。请立即这样做以保证你的资金安全。", "understand" : "我已知晓", diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh index 8e4a338ab..119ddb56c 100644 --- a/scripts/android/app_env.sh +++ b/scripts/android/app_env.sh @@ -14,14 +14,14 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN) APP_ANDROID_TYPE=$1 MONERO_COM_NAME="Monero.com" -MONERO_COM_VERSION="1.3.8" -MONERO_COM_BUILD_NUMBER=51 +MONERO_COM_VERSION="1.3.7" +MONERO_COM_BUILD_NUMBER=50 MONERO_COM_BUNDLE_ID="com.monero.app" MONERO_COM_PACKAGE="com.monero.app" CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="4.6.7" -CAKEWALLET_BUILD_NUMBER=161 +CAKEWALLET_VERSION="4.6.6" +CAKEWALLET_BUILD_NUMBER=160 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet" CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet" diff --git a/scripts/ios/app_env.sh b/scripts/ios/app_env.sh index 114c9191f..360b64770 100644 --- a/scripts/ios/app_env.sh +++ b/scripts/ios/app_env.sh @@ -13,13 +13,13 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN) APP_IOS_TYPE=$1 MONERO_COM_NAME="Monero.com" -MONERO_COM_VERSION="1.3.8" -MONERO_COM_BUILD_NUMBER=49 +MONERO_COM_VERSION="1.3.7" +MONERO_COM_BUILD_NUMBER=48 MONERO_COM_BUNDLE_ID="com.cakewallet.monero" CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="4.6.7" -CAKEWALLET_BUILD_NUMBER=159 +CAKEWALLET_VERSION="4.6.6" +CAKEWALLET_BUILD_NUMBER=155 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" HAVEN_NAME="Haven" diff --git a/scripts/linux/app_env.sh b/scripts/linux/app_env.sh index ac8c7c9df..5689fc86f 100755 --- a/scripts/linux/app_env.sh +++ b/scripts/linux/app_env.sh @@ -14,8 +14,8 @@ if [ -n "$1" ]; then fi CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="1.0.2" -CAKEWALLET_BUILD_NUMBER=3 +CAKEWALLET_VERSION="1.0.1" +CAKEWALLET_BUILD_NUMBER=2 if ! [[ " ${TYPES[*]} " =~ " ${APP_LINUX_TYPE} " ]]; then echo "Wrong app type." diff --git a/scripts/macos/app_env.sh b/scripts/macos/app_env.sh index e05172bad..8f328465e 100755 --- a/scripts/macos/app_env.sh +++ b/scripts/macos/app_env.sh @@ -15,8 +15,8 @@ if [ -n "$1" ]; then fi CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="1.0.6" -CAKEWALLET_BUILD_NUMBER=25 +CAKEWALLET_VERSION="1.0.5" +CAKEWALLET_BUILD_NUMBER=24 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then diff --git a/tool/utils/secret_key.dart b/tool/utils/secret_key.dart index b5b4de6d6..621ab1cfc 100644 --- a/tool/utils/secret_key.dart +++ b/tool/utils/secret_key.dart @@ -20,6 +20,7 @@ class SecretKey { SecretKey('moonPayApiKey', () => ''), SecretKey('moonPaySecretKey', () => ''), SecretKey('sideShiftAffiliateId', () => ''), + SecretKey('sideShiftApiKey', () => ''), SecretKey('simpleSwapApiKey', () => ''), SecretKey('simpleSwapApiKeyDesktop', () => ''), SecretKey('anypayToken', () => ''), From 7d77a167ac2b161a8a3bf4fd0adea9f93eed4b34 Mon Sep 17 00:00:00 2001 From: Harold Than <62450449+thanvinhbaohoang@users.noreply.github.com> Date: Fri, 7 Jul 2023 07:21:43 -0400 Subject: [PATCH 4/4] Button: Cursor to Pointer on Hover (#982) * Button: Cursor to Pointer on Hover * Updated build-guide-linux.md to Revert Flutter Version --------- Co-authored-by: Harold --- build-guide-linux.md | 37 +++++++- .../desktop_action_button.dart | 87 ++++++++++--------- 2 files changed, 81 insertions(+), 43 deletions(-) diff --git a/build-guide-linux.md b/build-guide-linux.md index 4e04a5e2b..c08d0405b 100644 --- a/build-guide-linux.md +++ b/build-guide-linux.md @@ -37,6 +37,9 @@ CakeWallet requires some packages to be install on your build system. You may ea Need to install flutter. For this please check section [How to install flutter on Linux](https://docs.flutter.dev/get-started/install/linux). + + + ### 3. Verify Installations Verify that the Flutter have been correctly installed on your system with the following command: @@ -46,7 +49,7 @@ Verify that the Flutter have been correctly installed on your system with the fo The output of this command will appear like this, indicating successful installations. If there are problems with your installation, they **must** be corrected before proceeding. ``` Doctor summary (to see all details, run flutter doctor -v): -[✓] Flutter (Channel stable, 3.x.x, on Linux, locale en_US.UTF-8) +[✓] Flutter (Channel stable, 3.7.x, on Linux, locale en_US.UTF-8) ``` ### 4. Acquiring the CakeWallet Source Code @@ -100,6 +103,38 @@ Install Flutter package dependencies with this command: > `$ flutter pub get` +> ### If you get the error like: +> ``` +> The lower bound of "sdk: '>=2.0.0-dev.68.0 <3.0.0'" must be 2.12.0 or higher to enable null safety. +> ``` +> +> #### Downgrade Flutter to version 3.7.x +> Make sure that Flutter is reverted back to version 3.7.x (which would automatically revert Dart to 2.18 or 2.19) +> +> In your Linux terminal, find where your Flutter SDK is installed with: +> +> ``` +> $ which flutter +> ``` +> +> Proceed to the Flutter SDK path: +> +> ``` +> $ cd user/snap/flutter/common/flutter +> ``` +> +> In the Flutter SDK directory, revert to a 3.7.x version (I used 3.7.12): +> +> +> ``` +> $ git checkout 3.7.12 +> ``` +> Then re-configure Cake Wallet's Linux project again. For this open `scripts/linux` (`$cd scripts/linux`) directory and run: +> `$ ./cakewallet.sh` +> and back to project root directory: +> `$ cd ../..` +> and fetch dependecies again +> `$ flutter pub get` Your CakeWallet binary will be built with some specific keys for iterate with 3rd party services. You may generate these secret keys placeholders with the following command: diff --git a/lib/src/screens/dashboard/desktop_widgets/desktop_action_button.dart b/lib/src/screens/dashboard/desktop_widgets/desktop_action_button.dart index 6e6db72cc..a0f9aabfb 100644 --- a/lib/src/screens/dashboard/desktop_widgets/desktop_action_button.dart +++ b/lib/src/screens/dashboard/desktop_widgets/desktop_action_button.dart @@ -21,54 +21,57 @@ class DesktopActionButton extends StatelessWidget { @override Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.fromLTRB(8, 0, 8, 8), - child: GestureDetector( - onTap: onTap, - child: Container( - padding: EdgeInsets.symmetric(vertical: 25), - width: double.infinity, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15.0), - color: Theme.of(context).textTheme!.titleLarge!.backgroundColor!, - ), - child: Center( - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Image.asset( - image, - height: 30, - width: 30, - color: isEnabled - ? Theme.of(context) - .accentTextTheme! - .displayMedium! - .backgroundColor! - : Theme.of(context) - .accentTextTheme! - .displaySmall! - .backgroundColor!, - ), - const SizedBox(width: 10), - AutoSizeText( - title, - style: TextStyle( - fontSize: 24, - fontFamily: 'Lato', - fontWeight: FontWeight.bold, + return MouseRegion( + cursor: SystemMouseCursors.click, + child: Padding( + padding: const EdgeInsets.fromLTRB(8, 0, 8, 8), + child: GestureDetector( + onTap: onTap, + child: Container( + padding: EdgeInsets.symmetric(vertical: 25), + width: double.infinity, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15.0), + color: Theme.of(context).textTheme!.titleLarge!.backgroundColor!, + ), + child: Center( + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Image.asset( + image, + height: 30, + width: 30, color: isEnabled ? Theme.of(context) .accentTextTheme! .displayMedium! .backgroundColor! - : null, - height: 1, + : Theme.of(context) + .accentTextTheme! + .displaySmall! + .backgroundColor!, ), - maxLines: 1, - textAlign: TextAlign.center, - ) - ], + const SizedBox(width: 10), + AutoSizeText( + title, + style: TextStyle( + fontSize: 24, + fontFamily: 'Lato', + fontWeight: FontWeight.bold, + color: isEnabled + ? Theme.of(context) + .accentTextTheme! + .displayMedium! + .backgroundColor! + : null, + height: 1, + ), + maxLines: 1, + textAlign: TextAlign.center, + ) + ], + ), ), ), ),