diff --git a/assets/fonts/Lato-Bold.ttf b/assets/fonts/Lato-Bold.ttf deleted file mode 100644 index 59c48434c..000000000 Binary files a/assets/fonts/Lato-Bold.ttf and /dev/null differ diff --git a/assets/fonts/Lato-Medium.ttf b/assets/fonts/Lato-Medium.ttf deleted file mode 100644 index a208b9912..000000000 Binary files a/assets/fonts/Lato-Medium.ttf and /dev/null differ diff --git a/assets/fonts/Lato-Regular.ttf b/assets/fonts/Lato-Regular.ttf deleted file mode 100644 index f01f55892..000000000 Binary files a/assets/fonts/Lato-Regular.ttf and /dev/null differ diff --git a/assets/fonts/Lato-Semibold.ttf b/assets/fonts/Lato-Semibold.ttf deleted file mode 100644 index 0b95c6430..000000000 Binary files a/assets/fonts/Lato-Semibold.ttf and /dev/null differ diff --git a/cw_core/lib/receive_page_option.dart b/cw_core/lib/receive_page_option.dart index aacbe4918..5a560575c 100644 --- a/cw_core/lib/receive_page_option.dart +++ b/cw_core/lib/receive_page_option.dart @@ -3,8 +3,6 @@ import 'package:cw_core/enumerate.dart'; class ReceivePageOption implements Enumerate { static const mainnet = ReceivePageOption._('mainnet'); static const testnet = ReceivePageOption._('testnet'); - static const anonPayInvoice = ReceivePageOption._('anonPayInvoice'); - static const anonPayDonationLink = ReceivePageOption._('anonPayDonationLink'); const ReceivePageOption._(this.value, {this.iconPath, this.description, this.isCommon = false, this.addAddressWord = false}); @@ -22,7 +20,4 @@ class ReceivePageOption implements Enumerate { const ReceivePageOptions = [ ReceivePageOption.mainnet, - // FIXME anonpay disabed for new ui beta. restore after screens are ready - // ReceivePageOption.anonPayInvoice, - // ReceivePageOption.anonPayDonationLink ]; diff --git a/lib/cake_pay/src/cards/cake_pay_buy_card_page.dart b/lib/cake_pay/src/cards/cake_pay_buy_card_page.dart index 64551ca65..3864b042c 100644 --- a/lib/cake_pay/src/cards/cake_pay_buy_card_page.dart +++ b/lib/cake_pay/src/cards/cake_pay_buy_card_page.dart @@ -90,7 +90,6 @@ class CakePayBuyCardPage extends BasePage { style: TextStyle( fontSize: 18.0, fontWeight: FontWeight.bold, - fontFamily: 'Lato', color: titleColor(context)), ); } diff --git a/lib/cake_pay/src/cards/cake_pay_cards_page.dart b/lib/cake_pay/src/cards/cake_pay_cards_page.dart index 9caee90ee..d6e88d377 100644 --- a/lib/cake_pay/src/cards/cake_pay_cards_page.dart +++ b/lib/cake_pay/src/cards/cake_pay_cards_page.dart @@ -168,12 +168,10 @@ class _CakePayCardsPageBodyState extends State { child: TabViewWrapper( labelStyle: TextStyle( color: titleColor, - fontFamily: 'Lato', fontSize: 20, fontWeight: FontWeight.w600), unselectedLabelStyle: TextStyle( color: titleColor?.withAlpha(150) ?? Colors.white70, - fontFamily: 'Lato', fontSize: 20, fontWeight: FontWeight.w400), indicatorColor: titleColor, diff --git a/lib/cake_pay/src/widgets/three_checkbox_alert_content_widget.dart b/lib/cake_pay/src/widgets/three_checkbox_alert_content_widget.dart index 9e8029ff7..60c7b784a 100644 --- a/lib/cake_pay/src/widgets/three_checkbox_alert_content_widget.dart +++ b/lib/cake_pay/src/widgets/three_checkbox_alert_content_widget.dart @@ -172,7 +172,6 @@ class _ThreeCheckboxAlertContentState extends State { S.of(context).settings_terms_and_conditions, style: TextStyle( fontSize: 16, - fontFamily: 'Lato', fontWeight: FontWeight.w400, color: Colors.blueAccent, decoration: TextDecoration.none, @@ -190,7 +189,6 @@ class _ThreeCheckboxAlertContentState extends State { style: TextStyle( color: Colors.red, fontSize: 14, - fontFamily: 'Lato', fontWeight: FontWeight.w400, decoration: TextDecoration.none, ), diff --git a/lib/core/address_resolver/yat/yat_store.dart b/lib/core/address_resolver/yat/yat_store.dart deleted file mode 100644 index bcae5331b..000000000 --- a/lib/core/address_resolver/yat/yat_store.dart +++ /dev/null @@ -1,280 +0,0 @@ -import 'package:cake_wallet/core/secure_storage.dart'; -import 'package:cw_core/transaction_history.dart'; -import 'package:cw_core/utils/print_verbose.dart'; -import 'package:cw_core/wallet_base.dart'; -import 'package:cw_core/balance.dart'; -import 'package:cw_core/transaction_info.dart'; -import 'package:cake_wallet/store/app_store.dart'; -import 'package:mobx/mobx.dart'; -import 'package:cw_core/wallet_type.dart'; -import 'dart:async'; - -part 'yat_store.g.dart'; - -class YatLink { - static const partnerId = ''; // 'CW'; - static const baseDevUrl = ''; // 'https://yat.fyi'; - static const baseReleaseUrl = ''; // 'https://y.at'; - static const signInSuffix = ''; // '/partner/$partnerId/link-email'; - static const createSuffix = ''; // '/create'; - static const managePath = ''; // '/partner/$partnerId/manage'; - static const queryParameter = ''; // '?address_json='; - static const apiDevUrl = ''; // 'https://a.yat.fyi'; - static const apiReleaseUrl = ''; // 'https://a.y.at'; - static const requestDevUrl = ''; // 'https://a.yat.fyi/emoji_id/'; - static const requestReleaseUrl = ''; //'https://a.y.at/emoji_id/'; - static const startFlowUrl = ''; // 'https://www.y03btrk.com/4RQSJ/6JHXF/'; - static const isDevMode = true; - static const tags = >{ - "XMR": ['0x1001', '0x1002'], - "BTC": ['0x1003'], - "LTC": ['0x1019'] - }; - - static String get apiUrl => YatLink.isDevMode ? YatLink.apiDevUrl : YatLink.apiReleaseUrl; - - static String get emojiIdUrl => apiUrl + '/emoji_id/'; - - static String get baseUrl => YatLink.isDevMode ? YatLink.baseDevUrl : YatLink.baseReleaseUrl; -} - -Future> fetchYatAddress(String emojiId, String ticker) async { - throw Exception(); - //final url = YatLink.emojiIdUrl + emojiId + '/payment'; - //final response = await get(url); - - //if (response.statusCode != 200) { - // throw YatException(text: response.body.toString()); - //} - - //final addresses = []; - //final currency = ticker.toUpperCase(); - //final responseJSON = json.decode(response.body) as Map; - //final result = responseJSON['result'] as Map; - //result.forEach((dynamic key, dynamic value) { - // final tag = key as String ?? ''; - // final record = value as Map; - - // if (YatLink.tags[currency]?.contains(tag) ?? false) { - // final address = record['address'] as String; - // if (address?.isNotEmpty ?? false) { - // addresses.add(address); - // } - // } - //}); - - //return addresses; - return []; -} - -Future fetchYatAccessToken(String refreshToken) async { - throw Exception(); - //try { - // final url = YatLink.apiUrl + '/auth/token/refresh'; - // final bodyJson = json.encode({'refresh_token': refreshToken}); - // final response = await post( - // url, - // headers: { - // 'Content-Type': 'application/json', - // 'Accept': '*/*' - // }, - // body: bodyJson); - - // if (response.statusCode != 200) { - // throw YatException(text: response.body.toString()); - // } - - // final responseJSON = json.decode(response.body) as Map; - // return responseJSON['access_token'] as String; - //}catch(_) { - // return ''; - //} - return ''; -} - -Future fetchYatApiKey(String accessKey) async { - throw Exception(); - //try { - // final url = YatLink.apiUrl + '/api_keys'; - // final bodyJson = json.encode({'name': 'CW'}); - // final response = await post( - // url, - // headers: { - // 'Authorization': 'Bearer $accessKey', - // 'Content-Type': 'application/json', - // 'Accept': '*/*' - // }, - // body: bodyJson); - - // if (response.statusCode != 200) { - // throw YatException(text: response.body.toString()); - // } - - // final responseJSON = json.decode(response.body) as Map; - // return responseJSON['api_key'] as String; - //}catch(_) { - // return ''; - //} - return ''; -} - -Future updateEmojiIdAddress( - String emojiId, String address, String apiKey, WalletType type) async { - throw Exception(); - //final url = YatLink.emojiIdUrl + emojiId; - //final cur = walletTypeToCryptoCurrency(type); - //final curFormatted = cur.toString().toUpperCase(); - //var tag = ''; - - //if (type == WalletType.monero && !address.startsWith('4')) { - // tag = YatLink.tags[curFormatted].last; - //} else { - // tag = YatLink.tags[curFormatted].first; - //} - - //final bodyJson = json.encode({ - // 'insert': [{ - // 'data': address, - // 'tag': tag - // }] - //}); - //final response = await patch( - // url, - // headers: { - // 'x-api-key': apiKey, - // 'Content-Type': 'application/json', - // 'Accept': '*/*' - // }, - // body: bodyJson); - - //if (response.statusCode != 200) { - // throw YatException(text: response.body.toString()); - //} -} - -Future visualisationForEmojiId(String emojiId) async { - throw Exception(); - //final url = YatLink.emojiIdUrl + emojiId + '/json/VisualizerFileLocations'; - //final response = await get(url); - //final responseJSON = json.decode(response.body) as Map; - //final data = responseJSON['data'] as Map; - //final result = data['gif'] as String ?? ''; - //return result; - return ''; -} - -class YatStore = YatStoreBase with _$YatStore; - -abstract class YatStoreBase with Store { - YatStoreBase({required this.appStore, required this.secureStorage}) - : _wallet = appStore.wallet, - emoji = appStore.wallet?.walletInfo?.yatEmojiId ?? '', - refreshToken = '', - accessToken = '', - apiKey = '', - emojiIncommingSC = StreamController.broadcast() { - //reaction((_) => appStore.wallet, _onWalletChange); - //reaction((_) => emoji, (String _) => _onEmojiChange()); - //reaction((_) => refreshToken, (String _) => _onRefreshTokenChange()); - } - - static const yatRefreshTokenKeyBase = 'yat_refresh_token'; - static const yatAccessTokenKeyBase = 'yat_access_token'; - static const yatApiKeyBase = 'yat_api_key'; - - static String yatRefreshTokenKey(String name) => '${yatRefreshTokenKeyBase}_$name'; - static String yatAccessTokenKey(String name) => '${yatAccessTokenKeyBase}_$name'; - static String yatApiKey(String name) => '${yatApiKeyBase}_$name'; - - AppStore appStore; - - SecureStorage secureStorage; - - @observable - String emoji; - - @observable - String refreshToken; - - @observable - String accessToken; - - @observable - String apiKey; - - StreamController emojiIncommingSC; - - Stream get emojiIncommingStream => emojiIncommingSC.stream; - - @observable - WalletBase, TransactionInfo>? _wallet; - - Future init() async { - if (_wallet == null) { - return; - } - - refreshToken = - await secureStorage.read(key: yatRefreshTokenKey(_wallet!.walletInfo.name)) ?? ''; - accessToken = await secureStorage.read(key: yatAccessTokenKey(_wallet!.walletInfo.name)) ?? ''; - apiKey = await secureStorage.read(key: yatApiKey(_wallet!.walletInfo.name)) ?? ''; - } - - @action - void _onWalletChange( - WalletBase, TransactionInfo> wallet) { - this._wallet = wallet; - emoji = wallet?.walletInfo?.yatEmojiId ?? ''; - init(); - } - - @action - void _onEmojiChange() { - try { - final walletInfo = _wallet?.walletInfo; - - if (walletInfo == null) { - return; - } - - walletInfo!.yatEid = emoji; - - walletInfo!.save(); - } catch (e) { - printV(e.toString()); - } - } - - @action - Future _onRefreshTokenChange() async { - throw Exception(); - - //try { - // await secureStorage.write(key: yatRefreshTokenKey(_wallet.walletInfo.name), value: refreshToken); - // accessToken = await fetchYatAccessToken(refreshToken); - // await secureStorage.write(key: yatAccessTokenKey(_wallet.walletInfo.name), value: accessToken); - // apiKey = await fetchYatApiKey(accessToken); - // await secureStorage.write(key: yatApiKey(_wallet.walletInfo.name), value: accessToken); - //} catch (e) { - // printV(e.toString()); - //} - } - - String defineQueryParameters() { - throw Exception(); - //final result = {}; - //final tags = YatLink.tags[_wallet.currency.toString().toUpperCase()]; - //String tag = tags.first; - - //if (_wallet.type == WalletType.monero - // && _wallet.walletAddresses.address.startsWith('4')) { - // tag = tags.last; - //} - //result[tag] = '${_wallet.walletAddresses.address}|${_wallet.name}'; - //final addressJson = json.encode([result]); - //final addressJsonBytes = utf8.encode(addressJson); - - //return base64.encode(addressJsonBytes); - return ''; - } -} diff --git a/lib/di.dart b/lib/di.dart index 160709171..34c9b2336 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -9,7 +9,6 @@ import 'package:cake_wallet/bitcoin_cash/bitcoin_cash.dart'; import 'package:cake_wallet/core/address_resolver/address_resolver_service.dart'; import 'package:cake_wallet/core/anypay/anypay_service.dart'; import 'package:cake_wallet/core/address_resolver/yat/yat_service.dart'; -import 'package:cake_wallet/core/address_resolver/yat/yat_store.dart'; import 'package:cake_wallet/entities/bitcoin_amount_display_mode.dart'; import 'package:cake_wallet/evm/evm.dart'; import 'package:cake_wallet/buy/dfx/dfx_buy_provider.dart'; @@ -83,22 +82,11 @@ import 'package:cake_wallet/src/screens/anonpay_details/anonpay_details_page.dar import 'package:cake_wallet/src/screens/auth/auth_page.dart'; 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_sell_options_page.dart'; -import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart'; -import 'package:cake_wallet/src/screens/buy/payment_method_options_page.dart'; -import 'package:cake_wallet/src/screens/buy/webview_page.dart'; import 'package:cake_wallet/src/screens/contact/contact_list_page.dart'; import 'package:cake_wallet/src/screens/contact/contact_page.dart'; -import 'package:cake_wallet/src/screens/dashboard/dashboard_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'; import 'package:cake_wallet/src/screens/dashboard/edit_token_page.dart'; import 'package:cake_wallet/src/screens/dashboard/home_settings_page.dart'; -import 'package:cake_wallet/src/screens/dashboard/pages/address_page.dart'; -import 'package:cake_wallet/src/screens/dashboard/pages/balance/balance_page.dart'; import 'package:cake_wallet/src/screens/dashboard/pages/cake_features_page.dart'; -import 'package:cake_wallet/src/screens/dashboard/pages/transactions_page.dart'; import 'package:cake_wallet/src/screens/dev/background_sync_logs_page.dart'; import 'package:cake_wallet/src/screens/dev/exchange_provider_logs_page.dart'; import 'package:cake_wallet/src/screens/dev/monero_background_sync.dart'; @@ -109,29 +97,15 @@ import 'package:cake_wallet/src/screens/dev/qr_tools_page.dart'; import 'package:cake_wallet/src/screens/dev/secure_preferences_page.dart'; import 'package:cake_wallet/src/screens/dev/shared_preferences_page.dart'; import 'package:cake_wallet/src/screens/dev/socket_health_logs_page.dart'; -import 'package:cake_wallet/src/screens/exchange/exchange_page.dart'; -import 'package:cake_wallet/src/screens/exchange/exchange_template_page.dart'; -import 'package:cake_wallet/src/screens/exchange_trade/exchange_confirm_page.dart'; -import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_external_send_page.dart'; -import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_page.dart'; -import 'package:cake_wallet/src/screens/faq/faq_page.dart'; import 'package:cake_wallet/src/screens/integrations/deuro/savings_page.dart'; -import 'package:cake_wallet/src/screens/monero_accounts/monero_account_edit_or_create_page.dart'; -import 'package:cake_wallet/src/screens/monero_accounts/monero_account_list_page.dart'; import 'package:cake_wallet/src/screens/nano/nano_change_rep_page.dart'; -import 'package:cake_wallet/src/screens/nano_accounts/nano_account_edit_or_create_page.dart'; -import 'package:cake_wallet/src/screens/nano_accounts/nano_account_list_page.dart'; import 'package:cake_wallet/src/screens/new_wallet/new_wallet_type_page.dart'; import 'package:cake_wallet/src/screens/nodes/node_create_or_edit_page.dart'; import 'package:cake_wallet/src/screens/nodes/pow_node_create_or_edit_page.dart'; import 'package:cake_wallet/src/screens/order_details/order_details_page.dart'; import 'package:cake_wallet/src/screens/payjoin_details/payjoin_details_page.dart'; import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart'; -import 'package:cake_wallet/src/screens/receive/address_list_page.dart'; -import 'package:cake_wallet/src/screens/receive/anonpay_invoice_page.dart'; -import 'package:cake_wallet/src/screens/receive/anonpay_receive_page.dart'; import 'package:cake_wallet/src/screens/receive/fullscreen_qr_page.dart'; -import 'package:cake_wallet/src/screens/receive/receive_page.dart'; import 'package:cake_wallet/src/screens/rescan/rescan_page.dart'; import 'package:cake_wallet/src/screens/restore/restore_from_backup_page.dart'; import 'package:cake_wallet/src/screens/restore/restore_options_page.dart'; @@ -139,12 +113,8 @@ import 'package:cake_wallet/src/screens/restore/wallet_restore_choose_derivation import 'package:cake_wallet/src/screens/restore/wallet_restore_page.dart'; import 'package:cake_wallet/src/screens/seed/seed_verification/seed_verification_page.dart'; import 'package:cake_wallet/src/screens/seed/wallet_seed_page.dart'; -import 'package:cake_wallet/src/screens/send/send_page.dart'; -import 'package:cake_wallet/src/screens/send/send_template_page.dart'; -import 'package:cake_wallet/src/screens/send/transaction_success_info_page.dart'; import 'package:cake_wallet/src/screens/settings/background_sync_page.dart'; import 'package:cake_wallet/src/screens/settings/connection_sync_page.dart'; -import 'package:cake_wallet/src/screens/settings/desktop_settings/desktop_settings_page.dart'; import 'package:cake_wallet/src/screens/settings/display_settings_page.dart'; import 'package:cake_wallet/src/screens/settings/domain_lookups_page.dart'; import 'package:cake_wallet/src/screens/settings/manage_nodes_page.dart'; @@ -156,7 +126,6 @@ import 'package:cake_wallet/src/screens/settings/privacy_page.dart'; import 'package:cake_wallet/src/screens/settings/security_backup_page.dart'; import 'package:cake_wallet/src/screens/settings/silent_payments_logs_page.dart'; import 'package:cake_wallet/src/screens/settings/silent_payments_settings.dart'; -import 'package:cake_wallet/src/screens/settings/trocador_providers_page.dart'; import 'package:cake_wallet/src/screens/setup_2fa/modify_2fa_page.dart'; import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa.dart'; import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_enter_code_page.dart'; @@ -164,7 +133,6 @@ import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_info_page.dart'; import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_qr_page.dart'; import 'package:cake_wallet/src/screens/setup_pin_code/setup_pin_code.dart'; import 'package:cake_wallet/src/screens/start_tor/start_tor_page.dart'; -import 'package:cake_wallet/src/screens/subaddress/address_edit_or_create_page.dart'; import 'package:cake_wallet/src/screens/support/support_page.dart'; import 'package:cake_wallet/src/screens/support_chat/support_chat_page.dart'; import 'package:cake_wallet/src/screens/support_other_links/support_other_links_page.dart'; @@ -172,7 +140,6 @@ import 'package:cake_wallet/src/screens/trade_details/trade_details_page.dart'; import 'package:cake_wallet/src/screens/transaction_details/rbf_details_page.dart'; import 'package:cake_wallet/src/screens/transaction_details/transaction_details_page.dart'; import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_details_page.dart'; -import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_list_page.dart'; import 'package:cake_wallet/src/screens/ur/animated_ur_page.dart'; import 'package:cake_wallet/new-ui/pages/bridge/bridge_detail_page.dart'; import 'package:cake_wallet/src/screens/wallet/wallet_edit_page.dart'; @@ -200,8 +167,6 @@ import 'package:cake_wallet/store/dashboard/trades_store.dart'; import 'package:cake_wallet/store/dashboard/transaction_filter_store.dart'; import 'package:cake_wallet/store/seed_settings_store.dart'; import 'package:cake_wallet/store/settings_store.dart'; -import 'package:cake_wallet/store/templates/exchange_template_store.dart'; -import 'package:cake_wallet/store/templates/send_template_store.dart'; import 'package:cake_wallet/store/wallet_list_store.dart'; import 'package:cake_wallet/themes/core/theme_store.dart'; import 'package:cake_wallet/tron/tron.dart'; @@ -209,7 +174,6 @@ import 'package:cake_wallet/utils/device_info.dart'; import 'package:cake_wallet/utils/payment_request.dart'; import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart'; import 'package:cake_wallet/view_model/animated_ur_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/auth_view_model.dart'; import 'package:cake_wallet/view_model/backup_view_model.dart'; @@ -217,7 +181,6 @@ import 'package:cake_wallet/view_model/bridge/bridge_details_view_model.dart'; import 'package:cake_wallet/view_model/bridge/bridge_history_view_model.dart'; import 'package:cake_wallet/view_model/buy/buy_amount_view_model.dart'; import 'package:cake_wallet/view_model/buy/buy_sell_view_model.dart'; -import 'package:cake_wallet/view_model/buy/buy_view_model.dart'; import 'package:cake_wallet/view_model/cake_pay/cake_pay_account_view_model.dart'; import 'package:cake_wallet/view_model/cake_pay/cake_pay_auth_view_model.dart'; import 'package:cake_wallet/view_model/cake_pay/cake_pay_buy_card_view_model.dart'; @@ -225,9 +188,7 @@ import 'package:cake_wallet/view_model/cake_pay/cake_pay_cards_list_view_model.d import 'package:cake_wallet/view_model/contact_list/contact_list_view_model.dart'; import 'package:cake_wallet/view_model/contact_list/contact_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart'; -import 'package:cake_wallet/view_model/dashboard/cake_features_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; -import 'package:cake_wallet/view_model/dashboard/desktop_sidebar_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/home_settings_view_model.dart'; import "package:cake_wallet/view_model/dashboard/nft_send_view_model.dart"; import 'package:cake_wallet/view_model/dashboard/nft_view_model.dart'; @@ -263,7 +224,6 @@ import 'package:cake_wallet/view_model/restore/restore_wallet.dart'; import 'package:cake_wallet/view_model/restore_from_backup_view_model.dart'; import 'package:cake_wallet/view_model/seed_settings_view_model.dart'; import 'package:cake_wallet/view_model/send/fees_view_model.dart'; -import 'package:cake_wallet/view_model/send/send_template_view_model.dart'; import 'package:cake_wallet/view_model/send/send_view_model.dart'; import 'package:cake_wallet/view_model/set_up_2fa_viewmodel.dart'; import 'package:cake_wallet/view_model/settings/connection_sync_view_model.dart'; @@ -325,7 +285,6 @@ import 'buy/meld/meld_buy_provider.dart'; import 'dogecoin/dogecoin.dart'; import 'new-ui/viewmodels/card_customizer/card_customizer_bloc.dart'; import 'new-ui/widgets/addresses_page/address_info.dart'; -import 'src/screens/buy/buy_sell_page.dart'; final getIt = GetIt.instance; @@ -403,11 +362,6 @@ Future setup({ getIt.registerSingleton(OrderFilterStore()); getIt.registerSingleton(TransactionFilterStore(getIt.get())); getIt.registerSingleton(FiatConversionStore()); - getIt.registerSingleton(SendTemplateStore(templateSource: _templates)); - getIt.registerSingleton( - ExchangeTemplateStore(templateSource: _exchangeTemplates)); - getIt.registerSingleton( - YatStore(appStore: getIt.get(), secureStorage: getIt.get())..init()); getIt.registerSingleton( AnonpayTransactionsStore(anonpayInvoiceInfoSource: _anonpayInvoiceInfoSource)); getIt.registerSingleton(SeedSettingsStore()); @@ -546,7 +500,6 @@ Future setup({ getIt.registerFactory(() => WalletAddressListViewModel( appStore: getIt.get(), - yatStore: getIt.get(), fiatConversionStore: getIt.get())); getIt.registerFactory(() => BalanceViewModel( @@ -557,7 +510,6 @@ Future setup({ getIt.registerFactory( () => ExchangeViewModel( getIt.get(), - getIt.get(), getIt.get(), getIt.get(), getIt.get(), @@ -585,7 +537,6 @@ Future setup({ orderFilterStore: getIt.get(), transactionFilterStore: getIt.get(), settingsStore: settingsStore, - yatStore: getIt.get(), anonpayTransactionsStore: getIt.get(), payjoinTransactionsStore: getIt.get(), sharedPreferences: getIt.get(), @@ -775,17 +726,6 @@ Future setup({ return walletKitService; }); - getIt.registerFactory(() => BalancePage( - nftViewModel: getIt.get(), - dashboardViewModel: getIt.get(), - settingsStore: getIt.get())); - - getIt.registerFactory(() => DashboardPage( - bottomSheetService: getIt.get(), - balancePage: getIt.get(), - dashboardViewModel: getIt.get(), - addressListViewModel: getIt.get(), - )); getIt.registerFactory(() => NewDashboard( dashboardViewModel: getIt.get(), @@ -797,27 +737,6 @@ Future setup({ nftViewModel: getIt.get(), )); - getIt.registerFactory(() { - final GlobalKey _navigatorKey = GlobalKey(); - return DesktopSidebarWrapper( - bottomSheetService: getIt.get(), - dashboardViewModel: getIt.get(), - desktopSidebarViewModel: getIt.get(), - child: getIt.get(param1: _navigatorKey), - desktopNavigatorKey: _navigatorKey, - ); - }); - getIt.registerFactoryParam, void>( - (desktopKey, _) => DesktopDashboardPage( - balancePage: getIt.get(), - dashboardViewModel: getIt.get(), - addressListViewModel: getIt.get(), - desktopKey: desktopKey, - )); - - getIt.registerFactory( - () => TransactionsPage(dashboardViewModel: getIt.get())); - getIt.registerFactory(() => Setup2FAInfoPage()); getIt.registerFactory( @@ -829,43 +748,9 @@ Future setup({ getIt.registerFactory( () => Modify2FAPage(setup2FAViewModel: getIt.get())); - getIt.registerFactory( - () => DesktopSettingsPage(getIt.get())); - getIt.registerFactoryParam( (pageOption, _) => ReceiveOptionViewModel(getIt.get().wallet!, pageOption)); - getIt.registerFactoryParam, void>((args, _) { - final address = args.first as String; - final pageOption = args.last as ReceivePageOption; - return AnonInvoicePageViewModel( - getIt.get(), - address, - getIt.get(), - getIt.get().wallet!, - _anonpayInvoiceInfoSource, - getIt.get(), - pageOption, - ); - }); - - getIt.registerFactoryParam, void>((List args, _) { - final pageOption = args.last as ReceivePageOption; - return AnonPayInvoicePage(getIt.get(param1: args), - getIt.get(param1: pageOption)); - }); - - getIt.registerFactory( - () => ReceivePage(addressListViewModel: getIt.get())); - - getIt.registerFactory( - () => AddressPage( - addressListViewModel: getIt(), - dashboardViewModel: getIt(), - receiveOptionViewModel: getIt(), - ), - ); - getIt.registerFactoryParam((param1, param2) => NewReceivePage( addressListViewModel: getIt.get(), @@ -878,10 +763,6 @@ Future setup({ (WalletAddressListItem? item, _) => WalletAddressEditOrCreateViewModel(wallet: getIt.get().wallet!, item: item)); - getIt.registerFactoryParam((dynamic item, _) => - AddressEditOrCreatePage( - addressEditOrCreateViewModel: - getIt.get(param1: item))); getIt.registerFactoryParam((dynamic item, _) => AddressLabelInputPopup( @@ -897,16 +778,10 @@ Future setup({ walletAddressEditOrCreateViewModel: getIt.get(param1: item))); - getIt.registerFactory(() => SendTemplateViewModel( - getIt.get().wallet!, - getIt.get(), - getIt.get(), - getIt.get())); getIt.registerFactoryParam( (coinTypeToSpendFrom, _) => SendViewModel( getIt.get(), - getIt.get(), getIt.get(), getIt.get(), getIt.get(), @@ -921,14 +796,7 @@ Future setup({ getIt.get()), ); - getIt.registerFactoryParam( - (PaymentRequest? initialPaymentRequest, coinTypeToSpendFrom) => SendPage( - sendViewModel: getIt.get(param1: coinTypeToSpendFrom), - authService: getIt.get(), - initialPaymentRequest: initialPaymentRequest, - paymentViewModel: getIt.get(), - walletSwitcherViewModel: getIt.get(), - )); + getIt.registerFactoryParam((params, _) { params ??= SendPageParams(); @@ -943,8 +811,7 @@ Future setup({ ); }); - getIt.registerFactory( - () => SendTemplatePage(sendTemplateViewModel: getIt.get())); + if (DeviceInfo.instance.isMobile) { getIt.registerFactory( @@ -1017,27 +884,6 @@ Future setup({ 'Unexpected wallet type: ${wallet.type} for generate Monero AccountListViewModel'); }); - getIt.registerFactory( - () => MoneroAccountListPage(accountListViewModel: getIt.get())); - - getIt.registerFactory( - () => NanoAccountListPage(accountListViewModel: getIt.get())); - - /*getIt.registerFactory(() { - final wallet = getIt.get().wallet; - - if (wallet is MoneroWallet) { - return MoneroAccountEditOrCreateViewModel(wallet.accountList); - } - - // FIXME: throw exception. - return null; - }); - - getIt.registerFactory(() => MoneroAccountEditOrCreatePage( - moneroAccountCreationViewModel: - getIt.get()));*/ - getIt.registerFactoryParam( (AccountListItem? account, _) => MoneroAccountEditOrCreateViewModel( monero!.getAccountList(getIt.get().wallet!), @@ -1045,11 +891,6 @@ Future setup({ wallet: getIt.get().wallet!, accountListItem: account)); - getIt.registerFactoryParam( - (AccountListItem? account, _) => MoneroAccountEditOrCreatePage( - moneroAccountCreationViewModel: - getIt.get(param1: account))); - getIt.registerFactoryParam( (NanoAccount? account, _) => NanoAccountEditOrCreateViewModel(nano!.getAccountList(getIt.get().wallet!), @@ -1057,11 +898,6 @@ Future setup({ wallet: getIt.get().wallet!, accountListItem: account)); - getIt.registerFactoryParam( - (NanoAccount? account, _) => NanoAccountEditOrCreatePage( - nanoAccountCreationViewModel: - getIt.get(param1: account))); - getIt.registerFactory( () => DisplaySettingsViewModel(getIt.get(), getIt.get())); @@ -1129,16 +965,16 @@ Future setup({ getIt.registerFactoryParam( (ContactRecord? contact, _) => ContactPage(getIt.get(param1: contact))); - getIt.registerFactory(() => AddressListPage(getIt.get())); getIt.registerFactoryParam((isPow, _) { final appStore = getIt.get(); return NodeListViewModel(appStore, isPow); }); - getIt.registerFactoryParam( - (showHidden, _) => NewAddressesPage( - showHidden: showHidden, + getIt.registerFactoryParam( + (args, _) => NewAddressesPage( + showHidden: args.showHidden, + popOnSelection: args.popOnSelection, addressListViewModel: getIt(), dashboardViewModel: getIt(), ), @@ -1154,7 +990,6 @@ Future setup({ getIt.registerFactory(() => PrivacyPage(getIt.get())); - getIt.registerFactory(() => TrocadorProvidersPage(getIt.get())); getIt.registerFactory(() => DomainLookupsPage(getIt.get())); @@ -1239,8 +1074,6 @@ Future setup({ wallet: getIt.get().wallet!, )); - getIt.registerFactoryParam((title, uri) => WebViewPage(title, uri)); - getIt.registerFactory( () => FeesViewModel( getIt.get(), @@ -1258,11 +1091,6 @@ Future setup({ ), ); - getIt.registerFactoryParam( - (PaymentRequest? paymentRequest, __) { - return ExchangePage(getIt.get(), getIt.get(), - getIt.get(), paymentRequest); - }); getIt.registerFactoryParam( (PaymentRequest? paymentRequest, CryptoCurrency? initialCurrency) { @@ -1276,17 +1104,9 @@ Future setup({ ); }); - getIt.registerFactory(() => ExchangeConfirmPage(tradesStore: getIt.get())); - - getIt.registerFactory( - () => ExchangeTradePage(exchangeTradeViewModel: getIt.get())); - - getIt.registerFactory(() => - ExchangeTradeExternalSendPage(exchangeTradeViewModel: getIt.get())); getIt.registerFactory(() => BackgroundSyncPage(getIt.get())); - getIt.registerFactory(() => ExchangeTemplatePage(getIt.get())); getIt.registerFactoryParam( (paymentFlowResult, _) => SwapConfirmationBottomSheet( @@ -1394,8 +1214,6 @@ Future setup({ getIt.registerFactory(() => RescanPage(getIt.get())); - getIt.registerFactory(() => FaqPage(getIt.get())); - getIt.registerFactoryParam?>( (type, additionalParams) { final restoredWallet = additionalParams?['restoredWallet'] as RestoredWallet?; @@ -1470,17 +1288,12 @@ Future setup({ getIt.registerFactory(() => PreSeedPage(getIt.get().wallet!)); - getIt.registerFactoryParam( - (content, _) => TransactionSuccessPage(content: content)); - getIt.registerFactoryParam( (trade, _) => TradeDetailsViewModel(tradeForDetails: trade, appStore: getIt.get())); - getIt.registerFactory(() => CakeFeaturesViewModel(getIt.get())); getIt.registerFactory(() => CakeFeaturesPage( - dashboardViewModel: getIt.get(), - cakeFeaturesViewModel: getIt.get())); + dashboardViewModel: getIt.get(),)); getIt.registerFactory(() => BackupServiceV3(getIt.get(), _transactionDescriptionBox, getIt.get(), getIt.get())); @@ -1514,39 +1327,6 @@ Future setup({ getIt.registerFactoryParam((mode, _) => NewBuySellAmountPage(buySellViewModel: getIt.get(param1: mode))); - getIt.registerFactory( - () => BuySellPage(getIt.get(), getIt.get())); - - getIt.registerFactoryParam, void>((List args, _) { - final items = args.first as List; - final pickAnOption = args[1] as void Function(SelectableOption option)?; - final confirmOption = args[2] as void Function(BuildContext contex)?; - return BuyOptionsPage(items: items, pickAnOption: pickAnOption, confirmOption: confirmOption); - }); - - getIt - .registerFactoryParam, void>((List args, _) { - final items = args.first as List; - final pickAnOption = args[1] as void Function(SelectableOption option)?; - - return PaymentMethodOptionsPage(items: items, pickAnOption: pickAnOption); - }); - - getIt.registerFactory(() { - final wallet = getIt.get().wallet; - - return BuyViewModel(_ordersSource, getIt.get(), getIt.get(), - getIt.get(), - wallet: wallet!); - }); - - getIt.registerFactoryParam, void>((List args, _) { - final url = args.first as String; - final buyViewModel = args[1] as BuyViewModel; - - return BuyWebViewPage( - buyViewModel: buyViewModel, ordersStore: getIt.get(), url: url); - }); getIt.registerFactoryParam((order, _) { final wallet = getIt.get().wallet; @@ -1584,11 +1364,6 @@ Future setup({ ); }); - getIt.registerFactoryParam( - (coinTypeToSpendFrom, _) => UnspentCoinsListPage( - unspentCoinsListViewModel: - getIt.get(param1: coinTypeToSpendFrom))); - getIt.registerFactoryParam( (coinTypeToSpendFrom, canEdit) => NewCoinControlPage( unspentCoinsListViewModel: @@ -1665,11 +1440,6 @@ Future setup({ useTorOnly: getIt.get().exchangeStatus == ExchangeApiMode.torOnly, wallet: getIt.get().wallet!)); - getIt.registerFactory(() => - DesktopWalletSelectionDropDown(getIt.get(), getIt.get())); - - getIt.registerFactory(() => DesktopSidebarViewModel()); - getIt.registerFactoryParam( (AnonpayInvoiceInfo anonpayInvoiceInfo, _) => AnonpayDetailsViewModel( anonPayApi: getIt.get(), @@ -1685,10 +1455,6 @@ Future setup({ themeStore: getIt.get(), )); - getIt.registerFactoryParam( - (AnonPayReceivePageArgs anonpayReceivePageArgs, _) => - AnonPayReceivePage(args: anonpayReceivePageArgs)); - getIt.registerFactoryParam( (AnonpayInvoiceInfo anonpayInvoiceInfo, _) => AnonpayDetailsPage( anonpayDetailsViewModel: getIt.get(param1: anonpayInvoiceInfo))); diff --git a/lib/new-ui/pages/addresses_page.dart b/lib/new-ui/pages/addresses_page.dart index ee02aa88f..8944f3feb 100644 --- a/lib/new-ui/pages/addresses_page.dart +++ b/lib/new-ui/pages/addresses_page.dart @@ -27,16 +27,26 @@ import 'package:cake_wallet/utils/list_item.dart'; import 'package:mobx/mobx.dart'; import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; + +class AddressesPageArgs { + AddressesPageArgs({required this.showHidden, this.popOnSelection = false}); + + final bool showHidden; + final bool popOnSelection; +} + + class NewAddressesPage extends StatefulWidget { const NewAddressesPage( {super.key, required this.addressListViewModel, required this.dashboardViewModel, - required this.showHidden}); + required this.showHidden, required this.popOnSelection}); final WalletAddressListViewModel addressListViewModel; final DashboardViewModel dashboardViewModel; final bool showHidden; + final bool popOnSelection; @override State createState() => _NewAddressesPageState(); @@ -133,6 +143,7 @@ class _NewAddressesPageState extends State { fontSize: 10, color: Theme.of(context).colorScheme.onSurfaceVariant), ), + if(!widget.popOnSelection) ShowHiddenButton() ], ), @@ -148,11 +159,15 @@ class _NewAddressesPageState extends State { builder: (_) => AddressRow( selected: item.address == widget.addressListViewModel.address.address, - first: widget.showHidden && index == 0, + first: (widget.showHidden || widget.popOnSelection) && index == 0, last: index == filteredItems.length - 1, item: item, onSelect: () { - widget.addressListViewModel.setAddress(item); + if(widget.popOnSelection) { + Navigator.of(context).pop(item.address); + } else { + widget.addressListViewModel.setAddress(item); + } }, onLabelChanged: updateItems, onAddressHidden: () async { diff --git a/lib/new-ui/pages/receive_page.dart b/lib/new-ui/pages/receive_page.dart index 2948f9a93..c63d83cd7 100644 --- a/lib/new-ui/pages/receive_page.dart +++ b/lib/new-ui/pages/receive_page.dart @@ -20,7 +20,6 @@ import "package:cake_wallet/new-ui/widgets/receive_page/receive_qr_code.dart"; import "package:cake_wallet/new-ui/widgets/receive_page/receive_token_display.dart"; import "package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart"; import "package:cake_wallet/routes.dart"; -import "package:cake_wallet/src/screens/receive/anonpay_receive_page.dart"; import "package:cake_wallet/utils/share_util.dart"; import "package:cake_wallet/view_model/dashboard/dashboard_view_model.dart"; import "package:cake_wallet/view_model/dashboard/receive_option_view_model.dart"; @@ -116,53 +115,13 @@ class _NewReceivePageState extends State { return; } - switch (option) { - case ReceivePageOption.anonPayInvoice: - Navigator.pushNamed( - context, - Routes.anonPayInvoicePage, - arguments: [widget.addressListViewModel.address.address, option], - ); - break; - case ReceivePageOption.anonPayDonationLink: - final sharedPreferences = getIt.get(); - final clearnetUrl = sharedPreferences.getString(PreferencesKey.clearnetDonationLink); - final onionUrl = sharedPreferences.getString(PreferencesKey.onionDonationLink); - final donationWalletName = - sharedPreferences.getString(PreferencesKey.donationLinkWalletName); - - if (clearnetUrl != null && - onionUrl != null && - widget.addressListViewModel.wallet.name == donationWalletName) { - Navigator.pushNamed( - context, - Routes.anonPayReceivePage, - arguments: AnonPayReceivePageArgs( - invoiceInfo: AnonpayDonationLinkInfo( - clearnetUrl: clearnetUrl, - onionUrl: onionUrl, - address: widget.addressListViewModel.address.address, - ), - qrImage: widget.addressListViewModel.qrImage, - ), - ); - } else { - Navigator.pushNamed( - context, - Routes.anonPayInvoicePage, - arguments: [widget.addressListViewModel.address.address, option], - ); - } - break; - default: - if ([WalletType.bitcoin, WalletType.litecoin] - .contains(widget.addressListViewModel.type)) { - widget.addressListViewModel.setAddressType(bitcoin!.getBitcoinAddressType(option)); - } - if (widget.addressListViewModel.type == WalletType.zcash) { - printV("help me i'll kms if that wont work: ${zcash!.getZcashAddressType(option)}"); - widget.addressListViewModel.setAddressType(zcash!.getZcashAddressType(option)); - } + if ([WalletType.bitcoin, WalletType.litecoin] + .contains(widget.addressListViewModel.type)) { + widget.addressListViewModel.setAddressType(bitcoin!.getBitcoinAddressType(option)); + } + if (widget.addressListViewModel.type == WalletType.zcash) { + printV("help me i'll kms if that wont work: ${zcash!.getZcashAddressType(option)}"); + widget.addressListViewModel.setAddressType(zcash!.getZcashAddressType(option)); } }); } diff --git a/lib/new-ui/widgets/coins_page/action_row/coin_action_row.dart b/lib/new-ui/widgets/coins_page/action_row/coin_action_row.dart index f085a2d38..52082f0e9 100644 --- a/lib/new-ui/widgets/coins_page/action_row/coin_action_row.dart +++ b/lib/new-ui/widgets/coins_page/action_row/coin_action_row.dart @@ -53,7 +53,6 @@ class CoinActionRow extends StatelessWidget { ), label: S.of(context).send, action: () { - if (FeatureFlag.hasNewUiExtraPages) { final sendPage = getIt.get( param1: SendPageParams( unspentCoinType: @@ -74,11 +73,6 @@ class CoinActionRow extends StatelessWidget { ); }, ); - } else { - Map? args; - if (lightningMode) args = {'coinTypeToSpendFrom': UnspentCoinType.lightning}; - Navigator.of(context).pushNamed(Routes.send, arguments: args); - } }, ), CoinActionButton( @@ -91,7 +85,6 @@ class CoinActionRow extends StatelessWidget { ), label: S.of(context).receive, action: () async { - if (FeatureFlag.hasNewUiExtraPages) { final page = getIt.get(param1: lightningMode); CupertinoScaffold.showCupertinoModalBottomSheet( context: context, @@ -100,17 +93,6 @@ class CoinActionRow extends StatelessWidget { return Material(child: ModalNavigator(parentContext: context, rootPage: page)); }, ); - } else { - // ToDo: (Konsti) refactor as part of the derivation PR (I hate myself for it) - if (lightningMode) { - await getIt().setAddressType( - bitcoin!.getOptionToType(bitcoin!.getBitcoinLightningReceivePageOption())); - } else { - await getIt().setAddressType( - bitcoin!.getOptionToType(bitcoin!.getBitcoinSegwitPageOption())); - } - Navigator.of(context).pushNamed(Routes.addressPage); - } }, ), if (showSwap) @@ -126,7 +108,6 @@ class CoinActionRow extends StatelessWidget { action: () { final page = getIt.get(param2: lightningMode ? CryptoCurrency.btcln : null); - if (FeatureFlag.hasNewUiExtraPages) { CupertinoScaffold.showCupertinoModalBottomSheet( context: context, barrierColor: Colors.black.withAlpha(85), @@ -136,9 +117,6 @@ class CoinActionRow extends StatelessWidget { parentContext: context, )), ); - } else { - Navigator.of(context).pushNamed(Routes.exchange); - } }, ), CoinActionButton( diff --git a/lib/new-ui/widgets/coins_page/cards/cards_view.dart b/lib/new-ui/widgets/coins_page/cards/cards_view.dart index 1aec566a7..2dbbfac7d 100644 --- a/lib/new-ui/widgets/coins_page/cards/cards_view.dart +++ b/lib/new-ui/widgets/coins_page/cards/cards_view.dart @@ -349,7 +349,7 @@ class _CardsViewState extends State { } } - if (FeatureFlag.hasNewUiExtraPages && widget.dashboardViewModel.type == WalletType.bitcoin) { + if (widget.dashboardViewModel.type == WalletType.bitcoin) { final page = getIt.get( param1: SendPageParams( initialPaymentRequest: paymentRequest, @@ -396,7 +396,7 @@ class _CardsViewState extends State { unspentCoinType = UnspentCoinType.lightning; } - if (FeatureFlag.hasNewUiExtraPages && widget.dashboardViewModel.type == WalletType.bitcoin) { + if (widget.dashboardViewModel.type == WalletType.bitcoin) { final page = getIt.get( param1: SendPageParams( initialPaymentRequest: paymentRequest, diff --git a/lib/router.dart b/lib/router.dart index b30d37824..8f6325ca8 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -17,6 +17,7 @@ import "package:cake_wallet/new-ui/pages/seed/pre_seed_page.dart"; import "package:cake_wallet/new-ui/pages/seed/show_keys_disclaimer_page.dart"; import "package:cake_wallet/new-ui/pages/receive_page.dart"; import 'package:cake_wallet/new-ui/pages/send_page.dart'; +import "package:cake_wallet/new-ui/pages/swap_page.dart"; import "package:cake_wallet/new-ui/widgets/buy_sell/buy_sell_selector_modal.dart"; import 'package:cake_wallet/new-ui/widgets/hardware_wallet/sync_key_images_sheet.dart'; import 'package:cake_wallet/order/order.dart'; @@ -33,25 +34,17 @@ import 'package:cake_wallet/src/screens/anonpay_details/anonpay_details_page.dar import 'package:cake_wallet/src/screens/auth/auth_page.dart'; 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_sell_options_page.dart'; -import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart'; -import 'package:cake_wallet/src/screens/buy/payment_method_options_page.dart'; -import 'package:cake_wallet/src/screens/buy/webview_page.dart'; import 'package:cake_wallet/cake_pay/cake_pay.dart'; import 'package:cake_wallet/src/screens/connect_device/connect_device_page.dart'; -import 'package:cake_wallet/src/screens/connect_device/monero_hardware_wallet_options_page.dart'; +import "package:cake_wallet/src/screens/connect_device/monero_hardware_wallet_options_page.dart"; import 'package:cake_wallet/src/screens/connect_device/select_device_manufacturer_page.dart'; -import 'package:cake_wallet/src/screens/connect_device/select_hardware_wallet_account_page.dart'; +import "package:cake_wallet/src/screens/connect_device/select_hardware_wallet_account_page.dart"; import 'package:cake_wallet/src/screens/contact/contact_list_page.dart'; import 'package:cake_wallet/src/screens/contact/contact_page.dart'; -import 'package:cake_wallet/src/screens/dashboard/dashboard_page.dart'; -import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart'; import 'package:cake_wallet/src/screens/dashboard/edit_token_page.dart'; import 'package:cake_wallet/src/screens/dashboard/home_settings_page.dart'; -import 'package:cake_wallet/src/screens/dashboard/pages/address_page.dart'; import 'package:cake_wallet/src/screens/dashboard/pages/nft_details_page.dart'; import "package:cake_wallet/src/screens/dashboard/pages/nft_send_page.dart"; -import 'package:cake_wallet/src/screens/dashboard/pages/transactions_page.dart'; import 'package:cake_wallet/src/screens/dashboard/sign_page.dart'; import 'package:cake_wallet/src/screens/dev/exchange_provider_logs_page.dart'; import 'package:cake_wallet/src/screens/dev/monero_background_sync.dart'; @@ -67,16 +60,8 @@ import 'package:cake_wallet/src/screens/dev/background_sync_logs_page.dart'; import 'package:cake_wallet/src/screens/dev/socket_health_logs_page.dart'; import 'package:cake_wallet/src/screens/disclaimer/disclaimer_page.dart'; import 'package:cake_wallet/src/screens/disclaimer/third_party_disclaimer_page.dart'; -import 'package:cake_wallet/src/screens/exchange/exchange_page.dart'; -import 'package:cake_wallet/src/screens/exchange/exchange_template_page.dart'; -import 'package:cake_wallet/src/screens/exchange_trade/exchange_confirm_page.dart'; -import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_external_send_page.dart'; -import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_page.dart'; -import 'package:cake_wallet/src/screens/faq/faq_page.dart'; import 'package:cake_wallet/src/screens/integrations/deuro/savings_page.dart'; -import 'package:cake_wallet/src/screens/monero_accounts/monero_account_edit_or_create_page.dart'; import 'package:cake_wallet/src/screens/nano/nano_change_rep_page.dart'; -import 'package:cake_wallet/src/screens/nano_accounts/nano_account_edit_or_create_page.dart'; import 'package:cake_wallet/src/screens/new_wallet/wallet_group_display_page.dart'; import 'package:cake_wallet/src/screens/new_wallet/advanced_privacy_settings_page.dart'; import 'package:cake_wallet/src/screens/new_wallet/new_wallet_page.dart'; @@ -88,24 +73,16 @@ import 'package:cake_wallet/src/screens/nodes/pow_node_create_or_edit_page.dart' import 'package:cake_wallet/src/screens/order_details/order_details_page.dart'; import 'package:cake_wallet/src/screens/payjoin_details/payjoin_details_page.dart'; import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart'; -import 'package:cake_wallet/src/screens/receive/address_list_page.dart'; -import 'package:cake_wallet/src/screens/receive/anonpay_invoice_page.dart'; -import 'package:cake_wallet/src/screens/receive/anonpay_receive_page.dart'; import 'package:cake_wallet/src/screens/receive/fullscreen_qr_page.dart'; -import 'package:cake_wallet/src/screens/receive/receive_page.dart'; import 'package:cake_wallet/src/screens/rescan/rescan_page.dart'; import 'package:cake_wallet/src/screens/restore/restore_from_backup_page.dart'; import 'package:cake_wallet/src/screens/restore/restore_options_page.dart'; -import 'package:cake_wallet/src/screens/restore/sweeping_wallet_page.dart'; import 'package:cake_wallet/src/screens/restore/wallet_restore_choose_derivation.dart'; import 'package:cake_wallet/src/screens/restore/wallet_restore_page.dart'; import 'package:cake_wallet/src/screens/seed/seed_verification/seed_verification_page.dart'; import 'package:cake_wallet/src/screens/seed/wallet_seed_page.dart'; -import 'package:cake_wallet/src/screens/send/send_template_page.dart'; -import 'package:cake_wallet/src/screens/send/transaction_success_info_page.dart'; import 'package:cake_wallet/src/screens/settings/background_sync_page.dart'; import 'package:cake_wallet/src/screens/settings/connection_sync_page.dart'; -import 'package:cake_wallet/src/screens/settings/desktop_settings/desktop_settings_page.dart'; import 'package:cake_wallet/src/screens/settings/display_settings_page.dart'; import 'package:cake_wallet/src/screens/settings/domain_lookups_page.dart'; import 'package:cake_wallet/src/screens/settings/manage_nodes_page.dart'; @@ -117,7 +94,6 @@ import 'package:cake_wallet/src/screens/settings/privacy_page.dart'; import 'package:cake_wallet/src/screens/settings/security_backup_page.dart'; import 'package:cake_wallet/src/screens/settings/silent_payments_settings.dart'; import 'package:cake_wallet/src/screens/settings/silent_payments_logs_page.dart'; -import 'package:cake_wallet/src/screens/settings/trocador_providers_page.dart'; import 'package:cake_wallet/src/screens/setup_2fa/modify_2fa_page.dart'; import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa.dart'; import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_enter_code_page.dart'; @@ -125,7 +101,6 @@ import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_info_page.dart'; import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_qr_page.dart'; import 'package:cake_wallet/src/screens/setup_pin_code/setup_pin_code.dart'; import 'package:cake_wallet/src/screens/start_tor/start_tor_page.dart'; -import 'package:cake_wallet/src/screens/subaddress/address_edit_or_create_page.dart'; import 'package:cake_wallet/src/screens/support/support_page.dart'; import 'package:cake_wallet/src/screens/support_chat/support_chat_page.dart'; import 'package:cake_wallet/src/screens/support_other_links/support_other_links_page.dart'; @@ -174,7 +149,6 @@ import 'package:cake_wallet/zcash/zcash_network_type.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'src/screens/buy/buy_sell_page.dart'; import 'src/screens/dashboard/pages/nft_import_page.dart'; late RouteSettings currentRouteSettings; @@ -427,7 +401,7 @@ Route createRoute(RouteSettings settings) { case Routes.receiveAddresses: return handleRouteWithPlatformAwareness( - (context) => getIt.get(param1: settings.arguments as bool)); + (context) => getIt.get(param1: AddressesPageArgs(showHidden:settings.arguments as bool))); case Routes.seed: return handleRouteWithPlatformAwareness( @@ -445,14 +419,11 @@ Route createRoute(RouteSettings settings) { builder: (_) => getIt.get( param1: settings.arguments as List)); - case Routes.sweepingWalletPage: - return CupertinoPageRoute(builder: (_) => getIt.get()); case Routes.dashboard: return CupertinoPageRoute( settings: settings, - builder: (_) => - FeatureFlag.hasNewUi ? getIt.get() : getIt.get()); + builder: (_) => getIt.get()); case Routes.send: final args = settings.arguments as Map?; @@ -472,27 +443,12 @@ Route createRoute(RouteSettings settings) { settings: settings, ); - case Routes.sendTemplate: - return CupertinoPageRoute( - fullscreenDialog: true, builder: (_) => getIt.get()); - - case Routes.receive: - return CupertinoPageRoute( - builder: (context) => getIt.get(), settings: settings); - - case Routes.addressPage: - return handleRouteWithPlatformAwareness((context) => getIt.get(), - settings: settings); case Routes.newReceivePage: - if (FeatureFlag.hasNewUi) { return handleRouteWithPlatformAwareness( (context) => Material(child: getIt.get(param1: false, param2: null)), settings: settings, ); - } - return handleRouteWithPlatformAwareness((context) => getIt.get(), - settings: settings); case Routes.transactionDetails: return CupertinoPageRoute( @@ -505,9 +461,6 @@ Route createRoute(RouteSettings settings) { fullscreenDialog: true, builder: (_) => getIt.get(param1: settings.arguments as List)); - case Routes.newSubaddress: - return CupertinoPageRoute( - builder: (_) => getIt.get(param1: settings.arguments)); case Routes.disclaimer: return CupertinoPageRoute(builder: (_) => DisclaimerPage()); @@ -625,9 +578,6 @@ Route createRoute(RouteSettings settings) { (context) => getIt.get(), ); - case Routes.trocadorProvidersPage: - return CupertinoPageRoute( - fullscreenDialog: true, builder: (_) => getIt.get()); case Routes.domainLookupsPage: return CupertinoPageRoute( @@ -667,11 +617,6 @@ Route createRoute(RouteSettings settings) { param1: args?['editingNode'] as Node?, param2: args?['isSelected'] as bool?); return CupertinoPageRoute(builder: (_) => page); - case Routes.accountCreation: - return CupertinoPageRoute( - builder: (_) => getIt.get( - param1: settings.arguments as AccountListItem?)); - case Routes.accountCustomizer: return handleRouteWithPlatformAwareness( (_) => getIt.get( @@ -679,11 +624,6 @@ Route createRoute(RouteSettings settings) { ), ); - case Routes.nanoAccountCreation: - return CupertinoPageRoute( - builder: (_) => - getIt.get(param1: settings.arguments as NanoAccount?)); - case Routes.addressBook: return handleRouteWithPlatformAwareness( (context) => getIt.get(), @@ -695,7 +635,7 @@ Route createRoute(RouteSettings settings) { builder: (_) => getIt.get(param1: args[0], param2: args[1])); case Routes.pickerWalletAddress: - return MaterialPageRoute(builder: (_) => getIt.get()); + return MaterialPageRoute(builder: (_) => getIt.get(param1: AddressesPageArgs(showHidden: false, popOnSelection: true))); case Routes.addressBookAddContact: return handleRouteWithPlatformAwareness( @@ -712,12 +652,6 @@ Route createRoute(RouteSettings settings) { (context) => getIt.get(), ); - case Routes.exchangeTrade: - return CupertinoPageRoute(builder: (_) => getIt.get()); - - case Routes.exchangeConfirm: - return MaterialPageRoute(builder: (_) => getIt.get()); - case Routes.tradeDetails: return CupertinoPageRoute( fullscreenDialog: true, @@ -732,35 +666,19 @@ Route createRoute(RouteSettings settings) { (context) => Material(child: getIt.get(param1: BuySellPageMode.buy)), ); - case Routes.buyOptionsPage: - final args = settings.arguments as List; - return MaterialPageRoute(builder: (_) => getIt.get(param1: args)); - case Routes.paymentMethodOptionsPage: - final args = settings.arguments as List; - return MaterialPageRoute( - builder: (_) => getIt.get(param1: args)); - - case Routes.buyWebView: - final args = settings.arguments as List; - - return MaterialPageRoute( - fullscreenDialog: true, builder: (_) => getIt.get(param1: args)); case Routes.exchange: return handleRouteWithPlatformAwareness( - (context) => getIt.get(param1: settings.arguments as PaymentRequest?), + (context) => Material( + child: getIt.get(param1: settings.arguments as PaymentRequest?)), + settings: settings, ); - case Routes.exchangeTemplate: - return CupertinoPageRoute(builder: (_) => getIt.get()); - case Routes.rescan: final page = getIt.get(); return MaterialPageRoute(builder: (_) => page); - case Routes.faq: - return MaterialPageRoute(builder: (_) => getIt.get()); case Routes.preSeedPage: return MaterialPageRoute(builder: (_) => getIt.get()); @@ -768,10 +686,6 @@ Route createRoute(RouteSettings settings) { case Routes.walletGroupExistingSeedDescriptionPage: return MaterialPageRoute(builder: (_) => WalletGroupExistingSeedDescriptionPage()); - case Routes.transactionSuccessPage: - return MaterialPageRoute( - builder: (_) => getIt.get(param1: settings.arguments as String)); - case Routes.backup: return handleRouteWithPlatformAwareness( (context) => getIt.get(), @@ -845,13 +759,6 @@ Route createRoute(RouteSettings settings) { (context) => getIt.get(), ); - 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.advancedPrivacySettings: final args = settings.arguments as Map; final type = args['type'] as WalletType; @@ -879,15 +786,6 @@ Route createRoute(RouteSettings settings) { ), ); - case Routes.anonPayInvoicePage: - final args = settings.arguments as List; - return CupertinoPageRoute(builder: (_) => getIt.get(param1: args)); - - case Routes.anonPayReceivePage: - final anonReceivePageArgs = settings.arguments as AnonPayReceivePageArgs; - return CupertinoPageRoute( - builder: (_) => getIt.get(param1: anonReceivePageArgs)); - case Routes.anonPayDetailsPage: final anonInvoiceViewData = settings.arguments as AnonpayInvoiceInfo; return CupertinoPageRoute( @@ -901,24 +799,9 @@ Route createRoute(RouteSettings settings) { builder: (_) => getIt.get(param1: sessionId, param2: transactionInfo)); - case Routes.desktop_actions: - return PageRouteBuilder( - opaque: false, - pageBuilder: (_, __, ___) => DesktopDashboardActions(getIt()), - ); - - case Routes.desktop_settings_page: - return CupertinoPageRoute(builder: (_) => getIt.get()); - case Routes.empty_no_route: return MaterialPageRoute(builder: (_) => SizedBox.shrink()); - case Routes.transactionsPage: - return CupertinoPageRoute( - settings: settings, - fullscreenDialog: true, - builder: (_) => getIt.get()); - case Routes.setup_2faPage: return MaterialPageRoute(builder: (_) => getIt.get()); @@ -1032,11 +915,6 @@ Route createRoute(RouteSettings settings) { builder: (_) => getIt.get(param1: settings.arguments as bool), ); - case Routes.exchangeTradeExternalSendPage: - return MaterialPageRoute( - builder: (_) => getIt.get(), - ); - case Routes.backgroundSync: return handleRouteWithPlatformAwareness( (context) => getIt.get(), diff --git a/lib/src/screens/buy/buy_sell_options_page.dart b/lib/src/screens/buy/buy_sell_options_page.dart deleted file mode 100644 index 900810f68..000000000 --- a/lib/src/screens/buy/buy_sell_options_page.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'package:cake_wallet/core/selectable_option.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/screens/select_options_page.dart'; -import 'package:flutter/cupertino.dart'; - -class BuyOptionsPage extends SelectOptionsPage { - BuyOptionsPage({required this.items, this.pickAnOption, this.confirmOption}); - - final List items; - final Function(SelectableOption option)? pickAnOption; - final Function(BuildContext context)? confirmOption; - - @override - String get pageTitle => S.current.choose_a_provider; - - @override - EdgeInsets? get contentPadding => null; - - @override - EdgeInsets? get tilePadding => EdgeInsets.only(top: 8); - - @override - EdgeInsets? get innerPadding => EdgeInsets.symmetric(horizontal: 24, vertical: 8); - - @override - double? get imageHeight => 40; - - @override - double? get imageWidth => 40; - - @override - Color? get selectedBackgroundColor => null; - - @override - double? get tileBorderRadius => 30; - - @override - String get bottomSectionText => ''; - - @override - void Function(SelectableOption option)? get onOptionTap => pickAnOption; - - @override - String get primaryButtonText => S.current.confirm; - - @override - void Function(BuildContext context)? get primaryButtonAction => confirmOption; -} diff --git a/lib/src/screens/buy/buy_sell_page.dart b/lib/src/screens/buy/buy_sell_page.dart deleted file mode 100644 index a157e6c98..000000000 --- a/lib/src/screens/buy/buy_sell_page.dart +++ /dev/null @@ -1,511 +0,0 @@ -import 'package:cake_wallet/buy/sell_buy_states.dart'; -import 'package:cake_wallet/core/address_resolver/address_resolver_service.dart'; -import 'package:cake_wallet/core/address_validator.dart'; -import 'package:cake_wallet/di.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/new-ui/widgets/buy_sell/buy_sell_selector_modal.dart'; -import 'package:cake_wallet/new-ui/widgets/currency_picker/currency_picker_args.dart'; -import 'package:cake_wallet/new-ui/widgets/currency_picker/currency_picker_sheet.dart'; -import 'package:cake_wallet/new-ui/widgets/currency_picker/fiat_currency_picker_sheet.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/src/screens/exchange/widgets/desktop_exchange_cards_section.dart'; -import 'package:cake_wallet/src/screens/exchange/widgets/exchange_card.dart'; -import 'package:cake_wallet/src/screens/exchange/widgets/mobile_exchange_cards_section.dart'; -import 'package:cake_wallet/src/widgets/keyboard_done_button.dart'; -import 'package:cake_wallet/src/widgets/primary_button.dart'; -import 'package:cake_wallet/src/widgets/provider_optoin_tile.dart'; -import 'package:cake_wallet/src/widgets/scrollable_with_bottom_section.dart'; -import 'package:cake_wallet/src/widgets/trail_button.dart'; -import 'package:cake_wallet/utils/responsive_layout_util.dart'; -import 'package:cake_wallet/view_model/buy/buy_sell_view_model.dart'; -import 'package:cw_core/crypto_currency.dart'; -import 'package:cw_core/currency.dart'; -import 'package:cw_core/wallet_type.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:keyboard_actions/keyboard_actions.dart'; -import 'package:mobx/mobx.dart'; - -class BuySellPage extends BasePage { - BuySellPage(this.buySellViewModel, this._resolver); - - final BuySellViewModel buySellViewModel; - final AddressResolverService _resolver; - final cryptoCurrencyKey = GlobalKey(); - final fiatCurrencyKey = GlobalKey(); - final _formKey = GlobalKey(); - final _fiatAmountFocus = FocusNode(); - final _cryptoAmountFocus = FocusNode(); - final _cryptoAddressFocus = FocusNode(); - var _isReactionsSet = false; - - late final String? depositWalletName; - late final String? receiveWalletName; - - @override - String get title => S.current.buy + '/' + S.current.sell; - - @override - bool get gradientBackground => true; - - @override - bool get gradientAll => true; - - @override - bool get resizeToAvoidBottomInset => false; - - @override - bool get extendBodyBehindAppBar => true; - - @override - AppBarStyle get appBarStyle => AppBarStyle.completelyTransparent; - - @override - Function(BuildContext)? get pushToNextWidget => (context) { - FocusScopeNode currentFocus = FocusScope.of(context); - if (!currentFocus.hasPrimaryFocus) { - currentFocus.focusedChild?.unfocus(); - } - }; - - @override - Widget trailing(BuildContext context) => TrailButton( - caption: S.of(context).clear, - onPressed: () { - _formKey.currentState?.reset(); - buySellViewModel.reset(); - }); - - @override - Widget? leading(BuildContext context) { - final _backButton = Icon( - Icons.arrow_back_ios, - color: Theme.of(context).colorScheme.primary, - size: 16, - ); - final _closeButton = currentTheme.isDark ? closeButtonImageDarkTheme : closeButtonImage; - - bool isMobileView = responsiveLayoutUtil.shouldRenderMobileUI; - - return MergeSemantics( - child: SizedBox( - height: isMobileView ? 37 : 45, - width: isMobileView ? 37 : 45, - child: ButtonTheme( - minWidth: double.minPositive, - child: Semantics( - label: !isMobileView ? S.of(context).close : S.of(context).seed_alert_back, - child: TextButton( - style: ButtonStyle( - overlayColor: WidgetStateColor.resolveWith((states) => Colors.transparent), - ), - onPressed: () => onClose(context), - child: !isMobileView ? _closeButton : _backButton, - ), - ), - ), - ), - ); - } - - @override - Widget body(BuildContext context) { - WidgetsBinding.instance.addPostFrameCallback((_) => _setReactions(context, buySellViewModel)); - - return KeyboardActions( - disableScroll: true, - config: KeyboardActionsConfig( - keyboardActionsPlatform: KeyboardActionsPlatform.IOS, - keyboardBarColor: Theme.of(context).colorScheme.surface, - nextFocus: false, - actions: [ - KeyboardActionsItem( - focusNode: _fiatAmountFocus, toolbarButtons: [(_) => KeyboardDoneButton()]), - KeyboardActionsItem( - focusNode: _cryptoAmountFocus, toolbarButtons: [(_) => KeyboardDoneButton()]) - ]), - child: Container( - color: Theme.of(context).colorScheme.surface, - child: Form( - key: _formKey, - child: ScrollableWithBottomSection( - contentPadding: EdgeInsets.only(bottom: 24), - content: Observer( - builder: (_) => Column( - children: [ - _exchangeCardsSection(context), - Padding( - padding: EdgeInsets.symmetric(horizontal: 24), - child: Column( - children: [ - SizedBox(height: 12), - _buildPaymentMethodTile(context), - ], - ), - ), - ], - ), - ), - bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24), - bottomSection: Observer( - builder: (_) => Column( - children: [ - if (buySellViewModel.isBuySellQuoteFailed) - Padding( - padding: EdgeInsets.only(bottom: 15), - child: Row( - children: [ - Expanded( - child: Container( - alignment: Alignment.centerRight, - child: Icon( - Icons.warning_amber_rounded, - color: Theme.of(context).colorScheme.error, - size: 26, - ), - ), - ), - Expanded( - flex: 8, - child: Text( - buySellViewModel.buySellQuoteFailedError ?? - S.of(context).buy_sell_pair_is_not_supported_warning, - textAlign: TextAlign.center, - softWrap: true, - overflow: TextOverflow.ellipsis, - maxLines: 3, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - color: Theme.of(context).colorScheme.error, - fontWeight: FontWeight.w500, - ), - ), - ), - ], - ), - ), - LoadingPrimaryButton( - text: S.current.choose_a_provider, - onPressed: () async { - if (!_formKey.currentState!.validate()) return; - buySellViewModel.onTapChoseProvider(context); - }, - color: Theme.of(context).colorScheme.primary, - textColor: Theme.of(context).colorScheme.onPrimary, - isDisabled: buySellViewModel.isBuySellQuoteFailed, - isLoading: - !buySellViewModel.isReadyToTrade && !buySellViewModel.isBuySellQuoteFailed, - ), - ], - ), - ), - ), - ), - ), - ); - } - - Widget _buildPaymentMethodTile(BuildContext context) { - if (buySellViewModel.paymentMethodState is PaymentMethodLoading || - buySellViewModel.paymentMethodState is InitialPaymentMethod) { - return OptionTilePlaceholder( - withBadge: false, - withSubtitle: false, - borderRadius: 30, - padding: EdgeInsets.symmetric(horizontal: 24, vertical: 8), - leadingIcon: Icons.arrow_forward_ios, - isDarkTheme: currentTheme.isDark); - } - if (buySellViewModel.paymentMethodState is PaymentMethodFailed) { - return OptionTilePlaceholder(errorText: 'No payment methods available', borderRadius: 30); - } - if (buySellViewModel.paymentMethodState is PaymentMethodLoaded && - buySellViewModel.selectedPaymentMethod != null) { - final selectedPaymentMethod = buySellViewModel.selectedPaymentMethod!; - return ProviderOptionTile( - lightImagePath: selectedPaymentMethod.lightIconPath, - darkImagePath: selectedPaymentMethod.darkIconPath, - title: selectedPaymentMethod.title, - onPressed: () => _pickPaymentMethod(context), - leadingIcon: Icons.arrow_forward_ios, - isLightMode: !currentTheme.isDark, - borderRadius: 30, - padding: EdgeInsets.symmetric(horizontal: 24, vertical: 8), - titleTextStyle: Theme.of(context).textTheme.titleMedium?.copyWith( - color: Theme.of(context).colorScheme.onSurface, - fontWeight: FontWeight.w600, - ), - ); - } - return OptionTilePlaceholder(errorText: 'No payment methods available', borderRadius: 30); - } - - void _pickPaymentMethod(BuildContext context) async { - final currentOption = buySellViewModel.selectedPaymentMethod; - await Navigator.of(context).pushNamed( - Routes.paymentMethodOptionsPage, - arguments: [ - buySellViewModel.paymentMethods, - buySellViewModel.changeOption, - ], - ); - - buySellViewModel.selectedPaymentMethod; - if (currentOption != null && - currentOption.paymentMethodType != - buySellViewModel.selectedPaymentMethod?.paymentMethodType) { - await buySellViewModel.calculateBestRate(); - } - } - - void _setReactions(BuildContext context, BuySellViewModel buySellViewModel) { - if (_isReactionsSet) return; - - final fiatAmountController = fiatCurrencyKey.currentState!.amountController; - final cryptoAmountController = cryptoCurrencyKey.currentState!.amountController; - final cryptoAddressController = cryptoCurrencyKey.currentState!.addressController; - - cryptoAddressController.addListener(() { - buySellViewModel.changeCryptoCurrencyAddress(cryptoAddressController.text); - }); - - _onCurrencyChange(buySellViewModel.cryptoCurrency, buySellViewModel, cryptoCurrencyKey); - _onCurrencyChange(buySellViewModel.fiatCurrency, buySellViewModel, fiatCurrencyKey); - - reaction( - (_) => buySellViewModel.wallet.name, - (_) => _onWalletNameChange( - buySellViewModel, buySellViewModel.cryptoCurrency, cryptoCurrencyKey)); - - reaction((_) => buySellViewModel.cryptoCurrency, - (currency) => _onCurrencyChange(currency, buySellViewModel, cryptoCurrencyKey)); - - reaction((_) => buySellViewModel.fiatCurrency, - (currency) => _onCurrencyChange(currency, buySellViewModel, fiatCurrencyKey)); - - reaction((_) => buySellViewModel.fiatAmount, (amount) { - if (fiatCurrencyKey.currentState!.amountController.text != amount) { - fiatCurrencyKey.currentState!.amountController.text = amount; - } - }); - - reaction((_) => buySellViewModel.isCryptoCurrencyAddressEnabled, (isEnabled) { - cryptoCurrencyKey.currentState!.isAddressEditable(isEditable: isEnabled); - }); - - reaction((_) => buySellViewModel.cryptoAmount, (amount) { - if (cryptoCurrencyKey.currentState!.amountController.text != amount) { - cryptoCurrencyKey.currentState!.amountController.text = amount; - } - }); - - reaction((_) => buySellViewModel.cryptoCurrencyAddress, (String address) { - if (cryptoAddressController.text != address) { - cryptoCurrencyKey.currentState!.addressController.text = address; - } - }); - - fiatAmountController.addListener(() { - if (fiatAmountController.text != buySellViewModel.fiatAmount) { - buySellViewModel.changeFiatAmount(amount: fiatAmountController.text); - } - }); - - cryptoAmountController.addListener(() { - if (cryptoAmountController.text != buySellViewModel.cryptoAmount) { - buySellViewModel.changeCryptoAmount(amount: cryptoAmountController.text); - } - }); - - _cryptoAddressFocus.addListener(() async { - if (!_cryptoAddressFocus.hasFocus && cryptoAddressController.text.isNotEmpty) { - final domain = cryptoAddressController.text; - final parsed = await fetchParsedAddress(context, domain, buySellViewModel.cryptoCurrency); - if (parsed.isNotEmpty) { - buySellViewModel.cryptoCurrencyAddress = parsed; - } - } - }); - - reaction((_) => buySellViewModel.wallet.walletAddresses.addressForBuy, (String address) { - if (buySellViewModel.cryptoCurrency == CryptoCurrency.xmr) { - cryptoCurrencyKey.currentState!.changeAddress(address: address); - } - }); - - reaction((_) => buySellViewModel.isReadyToTrade, (bool isReady) { - if (isReady) { - if (buySellViewModel.skipIsReadyToTradeReaction) { - buySellViewModel.skipIsReadyToTradeReaction = false; - return; - } - if (cryptoAmountController.text.isNotEmpty && - cryptoAmountController.text != S.current.fetching) { - buySellViewModel.changeCryptoAmount(amount: cryptoAmountController.text); - } else if (fiatAmountController.text.isNotEmpty && - fiatAmountController.text != S.current.fetching) { - buySellViewModel.changeFiatAmount(amount: fiatAmountController.text); - } - } - }); - - _isReactionsSet = true; - } - - void _onCurrencyChange( - Currency currency, BuySellViewModel buySellViewModel, GlobalKey key) { - final isCurrentTypeWallet = currency == buySellViewModel.wallet.currency; - - key.currentState!.changeSelectedCurrency(currency); - key.currentState!.changeWalletName(isCurrentTypeWallet ? buySellViewModel.wallet.name : ''); - - key.currentState!.changeAddress( - address: isCurrentTypeWallet ? buySellViewModel.wallet.walletAddresses.addressForBuy : ''); - - key.currentState!.changeAmount(amount: ''); - } - - void _onWalletNameChange(BuySellViewModel buySellViewModel, CryptoCurrency currency, - GlobalKey key) { - final isCurrentTypeWallet = currency == buySellViewModel.wallet.currency; - - if (isCurrentTypeWallet) { - key.currentState!.changeWalletName(buySellViewModel.wallet.name); - key.currentState!.addressController.text = - buySellViewModel.wallet.walletAddresses.addressForBuy; - } else if (key.currentState!.addressController.text == - buySellViewModel.wallet.walletAddresses.addressForBuy) { - key.currentState!.changeWalletName(''); - key.currentState!.addressController.text = ''; - } - } - - void disposeBestRateSync() => {}; - - Widget _exchangeCardsSection(BuildContext context) { - final fiatExchangeCard = Observer( - builder: (_) => ExchangeCard( - cardInstanceName: 'fiat_currency_trade_card', - onDispose: disposeBestRateSync, - amountFocusNode: _fiatAmountFocus, - key: fiatCurrencyKey, - title: 'FIAT ${S.of(context).amount}', - initialCurrency: buySellViewModel.fiatCurrency, - initialWalletName: '', - initialAddress: '', - initialIsAmountEditable: true, - isAmountEstimated: false, - currencyRowPadding: EdgeInsets.zero, - addressRowPadding: EdgeInsets.zero, - isMoneroWallet: buySellViewModel.wallet == WalletType.monero, - showAddressField: false, - showLimitsField: false, - currencies: buySellViewModel.fiatCurrencies, - onCurrencySelected: (currency) => buySellViewModel.changeFiatCurrency(currency: currency), - onTapCurrencyPicker: _presentFiatPicker, - imageArrow: Image.asset( - 'assets/images/arrow_bottom_purple_icon.png', - color: Theme.of(context).colorScheme.primary, - height: 8, - ), - currencyButtonColor: Colors.transparent, - addressButtonsColor: Theme.of(context).colorScheme.surfaceContainerHighest, - borderColor: Theme.of(context).colorScheme.outlineVariant, - onPushPasteButton: (context) async {}, - onPushAddressBookButton: (context) async {}, - fillColor: buySellViewModel.mode == BuySellPageMode.buy - ? Theme.of(context).colorScheme.surfaceContainer - : Theme.of(context).colorScheme.surfaceContainerLow, - ), - ); - - final cryptoExchangeCard = Observer( - builder: (_) => ExchangeCard( - cardInstanceName: 'crypto_currency_trade_card', - onDispose: disposeBestRateSync, - amountFocusNode: _cryptoAmountFocus, - addressFocusNode: _cryptoAddressFocus, - key: cryptoCurrencyKey, - title: 'Crypto ${S.of(context).amount}', - initialCurrency: buySellViewModel.cryptoCurrency, - initialWalletName: '', - initialAddress: buySellViewModel.cryptoCurrency == buySellViewModel.wallet.currency - ? buySellViewModel.wallet.walletAddresses.addressForBuy - : buySellViewModel.cryptoCurrencyAddress, - initialIsAmountEditable: true, - isAmountEstimated: true, - showLimitsField: false, - currencyRowPadding: EdgeInsets.zero, - addressRowPadding: EdgeInsets.zero, - isMoneroWallet: buySellViewModel.wallet == WalletType.monero, - currencies: buySellViewModel.cryptoCurrencies, - onCurrencySelected: (currency) => buySellViewModel.changeCryptoCurrency(currency: currency), - onTapCurrencyPicker: _presentCryptoPicker, - imageArrow: Image.asset( - 'assets/images/arrow_bottom_cake_green.png', - color: Theme.of(context).colorScheme.primary, - height: 8, - ), - currencyButtonColor: Colors.transparent, - addressButtonsColor: Theme.of(context).colorScheme.surfaceContainerHighest, - borderColor: Theme.of(context).colorScheme.outlineVariant, - addressTextFieldValidator: AddressValidator(type: buySellViewModel.cryptoCurrency), - onPushPasteButton: (context) async {}, - onPushAddressBookButton: (context) async {}, - fillColor: buySellViewModel.mode == BuySellPageMode.buy - ? Theme.of(context).colorScheme.surfaceContainerLow - : Theme.of(context).colorScheme.surfaceContainer, - useSatoshis: buySellViewModel.useSatoshi, - ), - ); - - if (responsiveLayoutUtil.shouldRenderMobileUI) { - return Observer( - builder: (_) { - return Placeholder(); - }, - ); - } - - return Observer( - builder: (_) { - return Placeholder(); - }, - ); - } - - void _presentFiatPicker(BuildContext context) { - FiatCurrencyPickerSheet.show( - context: context, - selected: buySellViewModel.fiatCurrency, - onSelected: (currency) => buySellViewModel.changeFiatCurrency(currency: currency), - ); - } - - void _presentCryptoPicker(BuildContext context) { - final items = [...buySellViewModel.cryptoCurrencies]; - appendEvmDefaultTokens(items); - CurrencyPickerSheet.show( - context: context, - args: CurrencyPickerArgs( - items: items, - selected: buySellViewModel.cryptoCurrency, - recentsSource: RecentsSource.orders, - onSelected: (currency) => buySellViewModel.changeCryptoCurrency(currency: currency), - symbolResolver: buySellViewModel.amountParsingProxy.getCryptoSymbol, - ), - ); - } - - Future fetchParsedAddress( - BuildContext context, - String domain, - CryptoCurrency currency, - ) async { - final parsedAddresses = - await _resolver.resolve(query: domain, wallet: buySellViewModel.wallet, currency: currency); - return parsedAddresses.isNotEmpty - ? parsedAddresses.first.parsedAddressByCurrencyMap[currency] ?? '' - : ''; - } -} diff --git a/lib/src/screens/buy/buy_webview_page.dart b/lib/src/screens/buy/buy_webview_page.dart deleted file mode 100644 index 488408d5c..000000000 --- a/lib/src/screens/buy/buy_webview_page.dart +++ /dev/null @@ -1,108 +0,0 @@ -import 'dart:async'; -import 'package:cake_wallet/buy/moonpay/moonpay_provider.dart'; -import 'package:cake_wallet/buy/wyre/wyre_buy_provider.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/store/dashboard/orders_store.dart'; -import 'package:cake_wallet/view_model/buy/buy_view_model.dart'; -import 'package:cw_core/utils/print_verbose.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_inappwebview/flutter_inappwebview.dart'; - -class BuyWebViewPage extends BasePage { - BuyWebViewPage({required this.buyViewModel, required this.ordersStore, required this.url}); - - final OrdersStore ordersStore; - final String url; - final BuyViewModel buyViewModel; - - @override - String get title => S.current.buy; - - @override - Widget body(BuildContext context) => - BuyWebViewPageBody(buyViewModel, ordersStore: ordersStore, url: url); -} - -class BuyWebViewPageBody extends StatefulWidget { - BuyWebViewPageBody(this.buyViewModel, {required this.ordersStore, this.url}); - - final OrdersStore ordersStore; - final String? url; - final BuyViewModel buyViewModel; - - @override - BuyWebViewPageBodyState createState() => BuyWebViewPageBodyState(); -} - -class BuyWebViewPageBodyState extends State { - BuyWebViewPageBodyState() - : _webViewkey = GlobalKey(), - _isSaving = false, - orderId = ''; - - String orderId; - InAppWebViewController? _webViewController; - GlobalKey _webViewkey; - Timer? _timer; - bool _isSaving; - - @override - void initState() { - super.initState(); - _webViewkey = GlobalKey(); - _isSaving = false; - widget.ordersStore.orderId = ''; - - if (widget.buyViewModel.selectedProvider is WyreBuyProvider) { - _saveOrder(keyword: 'completed', splitSymbol: '/'); - } - - if (widget.buyViewModel.selectedProvider is MoonPayProvider) { - _saveOrder(keyword: 'transactionId', splitSymbol: '='); - } - } - - @override - Widget build(BuildContext context) { - return InAppWebView( - key: _webViewkey, - initialSettings: InAppWebViewSettings( - transparentBackground: true, - ), - initialUrlRequest: URLRequest(url: WebUri(widget.url ?? '')), - onWebViewCreated: (InAppWebViewController controller) => - setState(() => _webViewController = controller)); - } - - void _saveOrder({required String keyword, required String splitSymbol}) { - _timer?.cancel(); - _timer = Timer.periodic(Duration(seconds: 1), (timer) async { - try { - if (_webViewController == null || _isSaving) { - return; - } - - final url = (await _webViewController!.getUrl())?.toString(); - if (url == null) { - throw Exception('_saveOrder: Url is null'); - } - - if (url.contains(keyword)) { - final urlParts = url.split(splitSymbol); - orderId = urlParts.last; - widget.ordersStore.orderId = orderId; - - if (orderId.isNotEmpty) { - _isSaving = true; - await widget.buyViewModel.saveOrder(orderId); - timer.cancel(); - } - } - } catch (e) { - _isSaving = false; - printV(e); - } - }); - } -} diff --git a/lib/src/screens/buy/payment_method_options_page.dart b/lib/src/screens/buy/payment_method_options_page.dart deleted file mode 100644 index 541f91ab4..000000000 --- a/lib/src/screens/buy/payment_method_options_page.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'package:cake_wallet/core/selectable_option.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/screens/select_options_page.dart'; -import 'package:flutter/cupertino.dart'; - -class PaymentMethodOptionsPage extends SelectOptionsPage { - PaymentMethodOptionsPage({required this.items, this.pickAnOption}); - - final List items; - final Function(SelectableOption option)? pickAnOption; - - @override - String get pageTitle => S.current.choose_a_payment_method; - - @override - EdgeInsets? get contentPadding => null; - - @override - EdgeInsets? get tilePadding => EdgeInsets.only(top: 12); - - @override - EdgeInsets? get innerPadding => EdgeInsets.symmetric(horizontal: 24, vertical: 12); - - @override - double? get imageHeight => null; - - @override - double? get imageWidth => null; - - @override - Color? get selectedBackgroundColor => null; - - @override - double? get tileBorderRadius => 30; - - @override - String get bottomSectionText => ''; - - @override - void Function(SelectableOption option)? get onOptionTap => pickAnOption; - - @override - String get primaryButtonText => S.current.confirm; - - @override - void Function(BuildContext context)? get primaryButtonAction => null; -} diff --git a/lib/src/screens/buy/webview_page.dart b/lib/src/screens/buy/webview_page.dart deleted file mode 100644 index b1c61a2cd..000000000 --- a/lib/src/screens/buy/webview_page.dart +++ /dev/null @@ -1,87 +0,0 @@ -import 'package:cake_wallet/di.dart'; -import 'package:cake_wallet/entities/preferences_key.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; -import 'package:cake_wallet/utils/permission_handler.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_inappwebview/flutter_inappwebview.dart'; -import 'package:permission_handler/permission_handler.dart'; -import 'package:shared_preferences/shared_preferences.dart'; - -class WebViewPage extends BasePage { - WebViewPage(this._title, this._url); - - final String _title; - final Uri _url; - - @override - String get title => _title; - - @override - Widget body(BuildContext context) { - return WebViewPageBody(_title, _url); - } -} - -class WebViewPageBody extends StatefulWidget { - WebViewPageBody(this.title, this.uri); - - final String title; - final Uri uri; - - @override - WebViewPageBodyState createState() => WebViewPageBodyState(); -} - -class WebViewPageBodyState extends State { - WebViewPageBodyState(); - - @override - Widget build(BuildContext context) { - return InAppWebView( - initialSettings: InAppWebViewSettings( - transparentBackground: true, - ), - initialUrlRequest: URLRequest(url: WebUri.uri(widget.uri)), - onPermissionRequest: (controller, request) async { - final sharedPrefs = getIt.get(); - - if (sharedPrefs.getBool(PreferencesKey.showCameraConsent) ?? true) { - final bool userConsent = await showPopUp( - context: context, - builder: (BuildContext context) { - return AlertWithTwoActions( - alertTitle: S.of(context).privacy, - alertContent: S.of(context).camera_consent(widget.title), - rightButtonText: S.of(context).agree, - leftButtonText: S.of(context).cancel, - actionRightButton: () => Navigator.of(context).pop(true), - actionLeftButton: () => Navigator.of(context).pop(false)); - }) ?? - false; - - /// if user did NOT give the consent then return permission denied - if (!userConsent) { - return PermissionResponse( - resources: request.resources, - action: PermissionResponseAction.DENY, - ); - } - - sharedPrefs.setBool(PreferencesKey.showCameraConsent, false); - } - - bool permissionGranted = - await PermissionHandler.checkPermission(Permission.camera, context); - - return PermissionResponse( - resources: request.resources, - action: - permissionGranted ? PermissionResponseAction.GRANT : PermissionResponseAction.DENY, - ); - }, - ); - } -} diff --git a/lib/src/screens/connect_device/debug_device_page.dart b/lib/src/screens/connect_device/debug_device_page.dart deleted file mode 100644 index bad20a96c..000000000 --- a/lib/src/screens/connect_device/debug_device_page.dart +++ /dev/null @@ -1,236 +0,0 @@ -// import 'dart:typed_data'; -// -// import 'package:basic_utils/basic_utils.dart'; -// import 'package:bitcoin_base/bitcoin_base.dart'; -// import 'package:cake_wallet/src/screens/base_page.dart'; -// import 'package:cake_wallet/src/screens/connect_device/widgets/device_tile.dart'; -// import 'package:cake_wallet/src/widgets/primary_button.dart'; -// import 'package:cake_wallet/utils/responsive_layout_util.dart'; -// import 'package:flutter/material.dart'; -// import 'package:ledger_flutter_plus/ledger_flutter_plus.dart'; -// import 'package:ledger_litecoin/ledger_litecoin.dart'; -// import 'package:permission_handler/permission_handler.dart'; -// -// class DebugDevicePage extends BasePage { -// @override -// String get title => "Connect Ledger"; -// -// @override -// Widget body(BuildContext context) => DebugDevicePageBody(); -// } -// -// class DebugDevicePageBody extends StatefulWidget { -// @override -// DebugDevicePageBodyState createState() => DebugDevicePageBodyState(); -// } -// -// class DebugDevicePageBodyState extends State { -// final imageLedger = Image.asset( -// 'assets/images/ledger_icon_black.png', -// width: 40, -// ); -// final ledger = Ledger( -// options: LedgerOptions( -// scanMode: ScanMode.balanced, -// maxScanDuration: const Duration(milliseconds: 5000), -// ), -// onPermissionRequest: (status) async { -// Map statuses = await [ -// // Permission.location, -// Permission.bluetoothScan, -// Permission.bluetoothConnect, -// Permission.bluetoothAdvertise, -// ].request(); -// -// if (status != BleStatus.ready) { -// return false; -// } -// -// return statuses.values.where((status) => status.isDenied).isEmpty; -// }, -// ); -// -// // late BitcoinLedgerApp btc; -// late LitecoinLedgerApp ltc; -// -// var devices = []; -// var status = ""; -// var counter = 0; -// LedgerDevice? selectedDevice = null; -// -// @override -// void initState() { -// super.initState(); -// // btc = BitcoinLedgerApp(ledger); -// ltc = LitecoinLedgerApp(ledger); -// } -// -// @override -// void dispose() { -// super.dispose(); -// ledger.close(ConnectionType.ble); -// ledger.close(ConnectionType.usb); -// } -// -// Future reconnectCurrentDevice() async { -// // await ledger.disconnect(selectedDevice!); -// // await ledger.connect(selectedDevice!); -// } -// -// Future disconnectCurrentDevice() async { -// await ledger.disconnect(selectedDevice!); -// setState(() => selectedDevice = null); -// } -// -// @override -// Widget build(BuildContext context) { -// final imageLedger = 'assets/images/hardware_wallet/ledger_nano_x.png'; -// -// return Center( -// child: Container( -// width: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint, -// height: double.infinity, -// padding: EdgeInsets.symmetric(vertical: 24, horizontal: 24), -// child: SingleChildScrollView( -// child: Column( -// children: [ -// Padding( -// padding: EdgeInsets.only(top: 20), -// child: Text(status), -// ), -// if (selectedDevice != null) ...[ -// DebugButton( -// title: "Get Version", -// method: "Version", -// // func: () async => await btc.getVersion(selectedDevice!), -// func: () async => await ltc.getVersion(selectedDevice!), -// ), -// DebugButton( -// title: "Get Wallet Address", -// method: "Wallet Address", -// func: () async { -// setState(() => counter++); -// final derivationPath = "m/84'/2'/0'/0/0"; -// return await ltc.getAccounts(selectedDevice!, -// accountsDerivationPath: derivationPath); -// // return await btc.getAccounts(selectedDevice!, accountsDerivationPath: derivationPath); -// // return await ethereum!.getHardwareWalletAccounts(selectedDevice!); -// }, -// ), -// DebugButton( -// title: "Send Money", -// method: "Raw Tx", -// func: sendMoney -// ), -// Padding( -// padding: EdgeInsets.only(top: 20), -// child: PrimaryButton( -// text: "Disconnect", -// onPressed: () => disconnectCurrentDevice(), -// color: Theme.of(context).colorScheme.primary, -// textColor: Theme.of(context).colorScheme.onPrimary), -// ), -// ], -// if (selectedDevice == null) ...[ -// ...devices -// .map( -// (device) => Padding( -// padding: EdgeInsets.only(bottom: 20), -// child: DeviceTile( -// onPressed: () { -// setState(() => selectedDevice = device); -// ledger.connect(device); -// }, -// title: device.name, -// leading: imageLedger, -// connectionType: device.connectionType, -// ), -// ), -// ) -// .toList(), -// PrimaryButton( -// text: "Refresh BLE", -// onPressed: () async { -// setState(() => devices = []); -// ledger.scan().listen((device) => setState(() { -// devices.add(device); -// })); -// }, -// color: Theme.of(context).colorScheme.primary, -// textColor: Theme.of(context).colorScheme.onPrimary), -// Padding( -// padding: EdgeInsets.only(top: 20), -// child: PrimaryButton( -// text: "Use USB", -// onPressed: () async { -// final dev = await ledger.listUsbDevices(); -// setState(() => devices = dev); -// }, -// color: Theme.of(context).colorScheme.primary, -// textColor: Theme.of(context).colorScheme.onPrimary), -// ), -// ], -// ], -// ), -// )), -// ); -// } -// -// Future sendMoney() async { -// final readyInputs = [ -// LedgerTransaction( -// rawTx: "010000000001018c055c85c3724c98842d27712771dd0de139711f5940bba2df4615c5522184740000000017160014faf7f6dfb4e70798b92c93f33b4c51024491829df0ffffff022b05c70000000000160014f489f947fd13a1fb44ac168427081d3f30b6ce0cde9dd82e0000000017a914d5eca376cb49d65031220ff9093b7d407073ed0d8702483045022100f648c9f6a9b8f35b6ec29bbfae312c95ed3d56ce6a3f177d994efe90562ec4bd02205b82ce2c94bc0c9d152c3afc668b200bd82f48d6a14e83c66ba0f154cd5f69190121038f1dca119420d4aa7ad04af1c0d65304723789cccc56d335b18692390437f35900000000", -// outputIndex: 0, -// ownerPublicKey: -// HexUtils.decode("03b2e67958ed3356e329e05cf94c3bee6b20c17175ac3b2a1278e073bf44f5d6ec"), -// ownerDerivationPath: "m/84'/2'/0'/0/0", -// sequence: 0xffffffff, -// ) -// ]; -// -// final outputs = [ -// BitcoinOutput( -// address: P2wpkhAddress.fromAddress( -// address: "ltc1qn0g5e36xaj07lqj6w9xn52ng07hud42g3jf5ps", -// network: LitecoinNetwork.mainnet), -// value: BigInt.from(1000000)), -// BitcoinOutput( -// address: P2wpkhAddress.fromAddress( -// address: "ltc1qrx29qz4ghu4j0xk37ptgk7034cwpmjyxhrcnk9", -// network: LitecoinNetwork.mainnet), -// value: BigInt.from(12042705)), -// ]; -// return await ltc.createTransaction(selectedDevice!, -// inputs: readyInputs, -// outputs: outputs -// .map((e) => TransactionOutput.fromBigInt( -// e.value, Uint8List.fromList(e.address.toScriptPubKey().toBytes()))) -// .toList(), -// sigHashType: 0x01, -// additionals: ["bech32"], -// isSegWit: true, -// useTrustedInputForSegwit: true); -// } -// -// Widget DebugButton( -// {required String title, required String method, required Future Function() func}) { -// return Padding( -// padding: EdgeInsets.only(top: 20), -// child: PrimaryButton( -// text: title, -// onPressed: () async { -// try { -// setState(() => status = "Sending..."); -// final acc = await func(); -// setState(() => status = "$method: $acc"); -// printV("$method: $acc"); -// } on LedgerException catch (ex) { -// setState(() => status = "${ex.errorCode.toRadixString(16)} ${ex.message}"); -// printV("${ex.errorCode.toRadixString(16)} ${ex.message}"); -// } -// }, -// color: Theme.of(context).colorScheme.primary, -// textColor: Theme.of(context).colorScheme.onPrimary), -// ); -// } -// } diff --git a/lib/src/screens/connect_device/widgets/device_tile.dart b/lib/src/screens/connect_device/widgets/device_tile.dart deleted file mode 100644 index 7880dada9..000000000 --- a/lib/src/screens/connect_device/widgets/device_tile.dart +++ /dev/null @@ -1,78 +0,0 @@ -import 'package:cake_wallet/entities/hardware_wallet/hardware_wallet_device.dart'; -import 'package:cake_wallet/src/widgets/cake_image_widget.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; - -class DeviceTile extends StatelessWidget { - const DeviceTile({ - required this.onPressed, - required this.title, - this.leading, - this.connectionType, - }); - - final VoidCallback onPressed; - final String title; - final String? leading; - final HardwareWalletConnectionType? connectionType; - - String? get connectionTypeIcon { - switch (connectionType) { - case HardwareWalletConnectionType.ble: - return 'assets/images/bluetooth.png'; - case HardwareWalletConnectionType.usb: - return 'assets/images/usb.png'; - default: - return null; - } - } - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onPressed, - child: Container( - width: double.infinity, - padding: EdgeInsets.all(24), - alignment: Alignment.center, - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(12)), - color: Theme.of(context).colorScheme.surfaceContainer, - ), - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - CakeImageWidget( - height: 30, - imageUrl: leading, - colorFilter: - ColorFilter.mode(Theme.of(context).colorScheme.onSurface, BlendMode.srcIn), - ), - Expanded( - child: Padding( - padding: EdgeInsets.only(left: 16), - child: Text( - title, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 20, - fontWeight: FontWeight.w500, - ), - ), - ), - ), - if (connectionTypeIcon != null) - Center( - child: Image.asset( - connectionTypeIcon!, - height: 25, - color: Theme.of(context).colorScheme.onSurface, - ), - ) - ], - ), - ), - ); - } -} diff --git a/lib/src/screens/contact/contact_list_page.dart b/lib/src/screens/contact/contact_list_page.dart index e8a336fa8..6e988384e 100644 --- a/lib/src/screens/contact/contact_list_page.dart +++ b/lib/src/screens/contact/contact_list_page.dart @@ -459,7 +459,7 @@ class _ContactListBodyState extends State { color: Theme.of(context).colorScheme.onSurface, ); return Padding( - padding: const EdgeInsets.only(bottom: FeatureFlag.hasNewUi ? 48 : 0), + padding: const EdgeInsets.only(bottom: 48), child: MergeSemantics( child: SizedBox( height: 58, diff --git a/lib/src/screens/dashboard/dashboard_page.dart b/lib/src/screens/dashboard/dashboard_page.dart deleted file mode 100644 index f4f151735..000000000 --- a/lib/src/screens/dashboard/dashboard_page.dart +++ /dev/null @@ -1,446 +0,0 @@ -import 'dart:async'; -import 'package:cake_wallet/entities/preferences_key.dart'; -import 'package:cake_wallet/di.dart'; -import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart'; -import 'package:cake_wallet/src/screens/dashboard/pages/cake_features_page.dart'; -import 'package:cake_wallet/src/screens/dashboard/widgets/page_indicator.dart'; -import 'package:cake_wallet/src/screens/dashboard/widgets/new_main_navbar_widget.dart'; -import 'package:cake_wallet/src/screens/wallet_connect/widgets/bottom_sheet/bottom_sheet_listener_widget.dart'; -import 'package:cake_wallet/src/screens/wallet_connect/services/bottom_sheet_service.dart'; -import 'package:cake_wallet/src/widgets/evm_switcher.dart'; -import 'package:cake_wallet/src/widgets/gradient_background.dart'; -import 'package:cake_wallet/src/widgets/haven_wallet_removal_popup.dart'; -import 'package:cake_wallet/src/widgets/services_updates_widget.dart'; -import 'package:cake_wallet/src/widgets/vulnerable_seeds_popup.dart'; -import 'package:cake_wallet/utils/device_info.dart'; -import 'package:cake_wallet/utils/feature_flag.dart'; -import 'package:cake_wallet/utils/version_comparator.dart'; -import 'package:cake_wallet/view_model/dashboard/cake_features_view_model.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/src/screens/yat_emoji_id.dart'; -import 'package:cake_wallet/utils/responsive_layout_util.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; -import 'package:flutter/material.dart'; -import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/src/screens/dashboard/widgets/menu_widget.dart'; -import 'package:cake_wallet/src/screens/dashboard/pages/balance/balance_page.dart'; -import 'package:cake_wallet/src/screens/dashboard/pages/transactions_page.dart'; -import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator.dart'; -import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:mobx/mobx.dart'; -import 'package:shared_preferences/shared_preferences.dart'; -import 'package:cake_wallet/main.dart'; -import 'package:cake_wallet/src/screens/release_notes/release_notes_screen.dart'; -import 'package:cake_wallet/themes/core/theme_extension.dart'; - -class DashboardPage extends StatefulWidget { - DashboardPage({ - required this.bottomSheetService, - required this.balancePage, - required this.dashboardViewModel, - required this.addressListViewModel, - }); - - final BalancePage balancePage; - final BottomSheetService bottomSheetService; - final DashboardViewModel dashboardViewModel; - final WalletAddressListViewModel addressListViewModel; - - @override - State createState() => _DashboardPageState(); -} - -class _DashboardPageState extends State { - @override - void initState() { - super.initState(); - - bool isMobileLayout = - responsiveLayoutUtil.screenWidth < ResponsiveLayoutUtilBase.kMobileThreshold; - - reaction((_) => responsiveLayoutUtil.screenWidth, (screenWidth) { - // Check if it was previously in mobile layout, and now changing to desktop - if (isMobileLayout && - screenWidth > ResponsiveLayoutUtilBase.kDesktopMaxDashBoardWidthConstraint) { - setState(() { - isMobileLayout = false; - }); - } - - // Check if it was previously in desktop layout, and now changing to mobile - if (!isMobileLayout && - screenWidth <= ResponsiveLayoutUtilBase.kDesktopMaxDashBoardWidthConstraint) { - setState(() { - isMobileLayout = true; - }); - } - }); - } - - @override - Widget build(BuildContext context) { - Widget dashboardChild; - - final dashboardPageView = RefreshIndicator( - displacement: responsiveLayoutUtil.screenHeight * 0.1, - onRefresh: () async { - unawaited(widget.balancePage.nftViewModel.getNFTAssetByWallet()); - - await widget.dashboardViewModel.refreshDashboard(); - }, - child: SingleChildScrollView( - physics: AlwaysScrollableScrollPhysics(), - child: Container( - height: responsiveLayoutUtil.screenHeight, - child: _DashboardPageView( - balancePage: widget.balancePage, - bottomSheetService: widget.bottomSheetService, - dashboardViewModel: widget.dashboardViewModel, - addressListViewModel: widget.addressListViewModel, - ), - ), - ), - ); - - if (DeviceInfo.instance.isDesktop) { - if (responsiveLayoutUtil.screenWidth > - ResponsiveLayoutUtilBase.kDesktopMaxDashBoardWidthConstraint) { - dashboardChild = getIt.get(); - } else { - dashboardChild = dashboardPageView; - } - } else if (responsiveLayoutUtil.shouldRenderMobileUI) { - dashboardChild = dashboardPageView; - } else { - dashboardChild = getIt.get(); - } - - return Scaffold(body: dashboardChild); - } -} - -class _DashboardPageView extends BasePage { - _DashboardPageView({ - required this.bottomSheetService, - required this.balancePage, - required this.dashboardViewModel, - required this.addressListViewModel, - }); - - final BalancePage balancePage; - - @override - bool get gradientBackground => true; - - @override - Widget Function(BuildContext, Widget) get rootWrapper => - (BuildContext context, Widget scaffold) => GradientBackground(scaffold: scaffold); - - @override - bool get resizeToAvoidBottomInset => false; - - @override - Widget get endDrawer => - MenuWidget(dashboardViewModel, ValueKey('dashboard_page_drawer_menu_widget_key')); - - @override - Widget leading(BuildContext context) { - if (FeatureFlag.isEVMChainSwitcherEnabled && - dashboardViewModel.isEVMWallet && - dashboardViewModel.availableChains.isNotEmpty) { - return TextButton( - style: TextButton.styleFrom( - minimumSize: Size(50, 30), - tapTargetSize: MaterialTapTargetSize.shrinkWrap, - alignment: Alignment.centerLeft, - ), - onPressed: () => showDialog( - context: context, - builder: (context) => EvmSwitcher( - chains: dashboardViewModel.availableChains, - currentChain: dashboardViewModel.currentChain, - onChainSelected: (chainId) => dashboardViewModel.selectChain(chainId), - hiddenChainIds: dashboardViewModel.settingsStore.evmHiddenChainIds, - onHiddenChanged: (hidden) => - dashboardViewModel.settingsStore.setEvmHiddenChainIds(hidden), - ), - ), - child: Container( - child: SvgPicture.asset( - 'assets/images/evm_switcher.svg', - color: Theme.of(context).colorScheme.onSurfaceVariant, - height: 30, - ), - ), - ); - } - - return Observer( - builder: (context) { - return ServicesUpdatesWidget( - key: ValueKey('dashboard_page_services_update_button_key'), - dashboardViewModel.getServicesStatus(), - enabled: dashboardViewModel.isEnabledBulletinAction, - ); - }, - ); - } - - @override - Widget middle(BuildContext context) { - return SyncIndicator( - key: ValueKey('dashboard_page_sync_indicator_button_key'), - dashboardViewModel: dashboardViewModel, - onTap: () => Navigator.of(context, rootNavigator: true).pushNamed(Routes.connectionSync), - ); - } - - @override - Widget trailing(BuildContext context) { - return Container( - alignment: Alignment.centerRight, - width: 42, - child: TextButton( - key: ValueKey('dashboard_page_wallet_menu_button_key'), - onPressed: () => onOpenEndDrawer(), - child: Semantics( - label: S.of(context).wallet_menu, - child: SvgPicture.asset( - 'assets/images/menu.svg', - color: Theme.of(context).colorScheme.primary, - ), - ), - ), - ); - } - - final DashboardViewModel dashboardViewModel; - final BottomSheetService bottomSheetService; - final WalletAddressListViewModel addressListViewModel; - - int get initialPage => dashboardViewModel.shouldShowMarketPlaceInDashboard ? 1 : 0; - ObservableList pages = ObservableList(); - bool _isEffectsInstalled = false; - - @override - Widget body(BuildContext context) { - final controller = PageController(initialPage: initialPage); - - reaction( - (_) => dashboardViewModel.shouldShowMarketPlaceInDashboard, - (bool value) { - if (!dashboardViewModel.shouldShowMarketPlaceInDashboard) { - controller.jumpToPage(0); - } - pages.clear(); - _isEffectsInstalled = false; - _setEffects(context); - - if (value) { - controller.jumpToPage(1); - } else { - controller.jumpToPage(0); - } - }, - ); - _setEffects(context); - - return SafeArea( - minimum: EdgeInsets.only(bottom: 0), - child: BottomSheetListener( - bottomSheetService: bottomSheetService, - child: Container( - child: Stack( - alignment: Alignment.bottomCenter, - children: [ - Observer( - builder: (context) { - return PageView.builder( - key: const ValueKey('dashboard_page_view_key'), - controller: controller, - physics: const BouncingScrollPhysics(), - itemCount: pages.length, - itemBuilder: (context, index) => pages[index], - ); - }, - ), - Stack( - alignment: Alignment.bottomCenter, - children: [ - IgnorePointer( - child: Container( - alignment: Alignment.bottomCenter, - height: 220, - decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - context.customColors.backgroundGradientColor.withAlpha(5), - context.customColors.backgroundGradientColor.withAlpha(50), - context.customColors.backgroundGradientColor.withAlpha(125), - context.customColors.backgroundGradientColor.withAlpha(150), - context.customColors.backgroundGradientColor.withAlpha(200), - context.customColors.backgroundGradientColor, - context.customColors.backgroundGradientColor, - ], - ), - ), - ), - ), - Container( - margin: EdgeInsets.only(bottom: 110), - child: Semantics( - container: true, - label: 'Page indicator', - hint: - 'Swipe left or right to change page, or double tap buttons below to navigate directly.', - child: ExcludeSemantics( - excluding: false, - child: PageIndicator( - controller: controller, - dashboardViewModel: dashboardViewModel, - ), - ), - ), - ), - NewMainNavBar( - dashboardViewModel: dashboardViewModel, - selectedIndex: 0, - onItemTap: (index) {}), - ], - ), - ], - ), - ), - ), - ); - } - - void _setEffects(BuildContext context) async { - if (_isEffectsInstalled || !context.mounted) { - return; - } - if (dashboardViewModel.shouldShowMarketPlaceInDashboard) { - pages.add( - Semantics( - label: S.of(context).apps, - child: CakeFeaturesPage( - dashboardViewModel: dashboardViewModel, - cakeFeaturesViewModel: getIt.get(), - ), - ), - ); - } - pages.add(Semantics(label: S.of(context).balance_page, child: balancePage)); - pages.add( - Semantics( - label: S.of(context).history, - child: TransactionsPage(dashboardViewModel: dashboardViewModel), - ), - ); - _isEffectsInstalled = true; - - _showReleaseNotesPopup(context); - - _showVulnerableSeedsPopup(context); - - _showHavenPopup(context); - - var needToPresentYat = false; - - rootKey.currentState?.isInactive.listen( - (inactive) { - if (needToPresentYat) { - Future.delayed(Duration(milliseconds: 500)).then( - (_) { - showPopUp( - context: navigatorKey.currentContext!, - builder: (_) => YatEmojiId(dashboardViewModel.yatStore.emoji), - ); - needToPresentYat = false; - }, - ); - } - }, - ); - - dashboardViewModel.yatStore.emojiIncommingStream.listen( - (String emoji) { - if (!_isEffectsInstalled || emoji.isEmpty) { - return; - } - - needToPresentYat = true; - }, - ); - } - - void _showReleaseNotesPopup(BuildContext context) async { - final sharedPrefs = await SharedPreferences.getInstance(); - final currentAppVersion = - VersionComparator.getExtendedVersionNumber(dashboardViewModel.settingsStore.appVersion); - final lastSeenAppVersion = sharedPrefs.getInt(PreferencesKey.lastSeenAppVersion); - final isNewInstall = sharedPrefs.getBool(PreferencesKey.isNewInstall); - - if (currentAppVersion != lastSeenAppVersion && !isNewInstall!) { - Future.delayed( - Duration(seconds: 1), - () { - showPopUp( - context: context, - builder: (BuildContext context) { - return ReleaseNotesScreen( - title: 'Version ${dashboardViewModel.settingsStore.appVersion}', - ); - }, - ); - }, - ); - - sharedPrefs.setInt(PreferencesKey.lastSeenAppVersion, currentAppVersion); - } else if (isNewInstall!) { - sharedPrefs.setInt(PreferencesKey.lastSeenAppVersion, currentAppVersion); - } - } - - void _showVulnerableSeedsPopup(BuildContext context) async { - final List affectedWalletNames = await dashboardViewModel.checkAffectedWallets(); - - if (affectedWalletNames.isNotEmpty) { - Future.delayed( - Duration(seconds: 1), - () { - showPopUp( - context: context, - builder: (BuildContext context) { - return VulnerableSeedsPopup(affectedWalletNames); - }, - ); - }, - ); - } - } - - void _showHavenPopup(BuildContext context) async { - final List havenWalletList = await dashboardViewModel.checkForHavenWallets(); - - if (havenWalletList.isNotEmpty) { - Future.delayed( - Duration(seconds: 1), - () { - showPopUp( - context: context, - builder: (BuildContext context) { - return HavenWalletRemovalPopup(havenWalletList); - }, - ); - }, - ); - } - } -} diff --git a/lib/src/screens/dashboard/desktop_dashboard_page.dart b/lib/src/screens/dashboard/desktop_dashboard_page.dart deleted file mode 100644 index 4769b1efd..000000000 --- a/lib/src/screens/dashboard/desktop_dashboard_page.dart +++ /dev/null @@ -1,135 +0,0 @@ -import 'dart:async'; -import 'package:cake_wallet/entities/preferences_key.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/src/screens/release_notes/release_notes_screen.dart'; -import 'package:cake_wallet/src/screens/yat_emoji_id.dart'; -import 'package:cake_wallet/src/widgets/vulnerable_seeds_popup.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; -import 'package:cake_wallet/utils/version_comparator.dart'; -import 'package:flutter/material.dart'; -import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; -import 'package:cake_wallet/src/screens/dashboard/pages/balance/balance_page.dart'; -import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart'; -import 'package:cake_wallet/main.dart'; -import 'package:cake_wallet/router.dart' as Router; -import 'package:shared_preferences/shared_preferences.dart'; - -class DesktopDashboardPage extends StatelessWidget { - DesktopDashboardPage({ - required this.balancePage, - required this.dashboardViewModel, - required this.addressListViewModel, - required this.desktopKey, - }); - - final BalancePage balancePage; - final DashboardViewModel dashboardViewModel; - final WalletAddressListViewModel addressListViewModel; - final GlobalKey desktopKey; - - bool _isEffectsInstalled = false; - StreamSubscription? _onInactiveSub; - - @override - Widget build(BuildContext context) { - _setEffects(context); - - return Container( - color: Theme.of(context).colorScheme.surface, - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - width: 400, - child: balancePage, - ), - Flexible( - child: ConstrainedBox( - constraints: BoxConstraints(maxWidth: 500), - child: Navigator( - key: desktopKey, - initialRoute: Routes.desktop_actions, - onGenerateRoute: (settings) => Router.createRoute(settings), - onGenerateInitialRoutes: (NavigatorState navigator, String initialRouteName) { - return [ - navigator.widget.onGenerateRoute!(RouteSettings(name: initialRouteName))! - ]; - }, - ), - ), - ), - ], - ), - ); - } - - void _setEffects(BuildContext context) async { - if (_isEffectsInstalled) { - return; - } - _isEffectsInstalled = true; - - var needToPresentYat = false; - var isInactive = false; - - _onInactiveSub = rootKey.currentState!.isInactive.listen((inactive) { - isInactive = inactive; - - if (needToPresentYat) { - Future.delayed(Duration(milliseconds: 500)).then((_) { - showPopUp( - context: navigatorKey.currentContext!, - builder: (_) => YatEmojiId(dashboardViewModel.yatStore.emoji)); - needToPresentYat = false; - }); - } - }); - - dashboardViewModel.yatStore.emojiIncommingStream.listen((String emoji) { - if (!_isEffectsInstalled || emoji.isEmpty) { - return; - } - - needToPresentYat = true; - }); - - final sharedPrefs = await SharedPreferences.getInstance(); - final currentAppVersion = - VersionComparator.getExtendedVersionNumber(dashboardViewModel.settingsStore.appVersion); - final lastSeenAppVersion = sharedPrefs.getInt(PreferencesKey.lastSeenAppVersion); - final isNewInstall = sharedPrefs.getBool(PreferencesKey.isNewInstall); - - if (currentAppVersion != lastSeenAppVersion && !isNewInstall!) { - await Future.delayed(Duration(seconds: 1)); - await showPopUp( - context: context, - builder: (BuildContext context) { - return ReleaseNotesScreen( - title: 'Version ${dashboardViewModel.settingsStore.appVersion}'); - }); - sharedPrefs.setInt(PreferencesKey.lastSeenAppVersion, currentAppVersion); - } else if (isNewInstall!) { - sharedPrefs.setInt(PreferencesKey.lastSeenAppVersion, currentAppVersion); - } - - _showVulnerableSeedsPopup(context); - } - - void _showVulnerableSeedsPopup(BuildContext context) async { - final List affectedWalletNames = await dashboardViewModel.checkAffectedWallets(); - - if (affectedWalletNames.isNotEmpty) { - Future.delayed( - Duration(seconds: 1), - () { - showPopUp( - context: context, - builder: (BuildContext context) { - return VulnerableSeedsPopup(affectedWalletNames); - }, - ); - }, - ); - } - } -} diff --git a/lib/src/screens/dashboard/desktop_widgets/desktop_action_button.dart b/lib/src/screens/dashboard/desktop_widgets/desktop_action_button.dart deleted file mode 100644 index ebc502483..000000000 --- a/lib/src/screens/dashboard/desktop_widgets/desktop_action_button.dart +++ /dev/null @@ -1,71 +0,0 @@ -import 'package:auto_size_text/auto_size_text.dart'; -import 'package:flutter/material.dart'; - -class DesktopActionButton extends StatelessWidget { - final String image; - final String title; - final bool canShow; - final bool isEnabled; - final Function() onTap; - - const DesktopActionButton({ - Key? key, - required this.title, - required this.image, - required this.onTap, - bool? canShow, - bool? isEnabled, - }) : this.isEnabled = isEnabled ?? true, - this.canShow = canShow ?? true, - super(key: key); - - @override - Widget build(BuildContext context) { - 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).colorScheme.surfaceContainer, - ), - child: Center( - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Image.asset( - image, - height: 30, - width: 30, - color: isEnabled - ? Theme.of(context).colorScheme.onPrimaryContainer - : Theme.of(context).colorScheme.onSurfaceVariant, - ), - const SizedBox(width: 10), - AutoSizeText( - title, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 24, - fontWeight: FontWeight.bold, - color: isEnabled - ? Theme.of(context).colorScheme.onPrimaryContainer - : Theme.of(context).colorScheme.onSurfaceVariant, - height: 1, - ), - maxLines: 1, - textAlign: TextAlign.center, - ) - ], - ), - ), - ), - ), - ), - ); - } -} diff --git a/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart b/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart deleted file mode 100644 index 1a063a220..000000000 --- a/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart +++ /dev/null @@ -1,87 +0,0 @@ -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/pages/cake_features_page.dart'; -import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; -import 'package:cake_wallet/view_model/dashboard/cake_features_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; - -class DesktopDashboardActions extends StatelessWidget { - final DashboardViewModel dashboardViewModel; - - const DesktopDashboardActions(this.dashboardViewModel, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - color: Theme.of(context).colorScheme.surface, - child: Observer(builder: (_) { - return Column( - children: [ - const SizedBox(height: 16), - DesktopActionButton( - title: MainActions.showWalletsAction.name(context), - image: MainActions.showWalletsAction.image, - canShow: MainActions.showWalletsAction.canShow?.call(dashboardViewModel), - isEnabled: MainActions.showWalletsAction.isEnabled?.call(dashboardViewModel), - onTap: () async => - await MainActions.showWalletsAction.onTap(context, dashboardViewModel), - ), - DesktopActionButton( - title: MainActions.swapAction.name(context), - image: MainActions.swapAction.image, - canShow: MainActions.swapAction.canShow?.call(dashboardViewModel), - isEnabled: MainActions.swapAction.isEnabled?.call(dashboardViewModel), - onTap: () async => await MainActions.swapAction.onTap(context, dashboardViewModel), - ), - Row( - children: [ - Expanded( - child: DesktopActionButton( - title: MainActions.receiveAction.name(context), - image: MainActions.receiveAction.image, - canShow: MainActions.receiveAction.canShow?.call(dashboardViewModel), - isEnabled: MainActions.receiveAction.isEnabled?.call(dashboardViewModel), - onTap: () async => - await MainActions.receiveAction.onTap(context, dashboardViewModel), - ), - ), - Expanded( - child: DesktopActionButton( - title: MainActions.sendAction.name(context), - image: MainActions.sendAction.image, - canShow: MainActions.sendAction.canShow?.call(dashboardViewModel), - isEnabled: MainActions.sendAction.isEnabled?.call(dashboardViewModel), - onTap: () async => - await MainActions.sendAction.onTap(context, dashboardViewModel), - ), - ), - ], - ), - Row( - children: [ - Expanded( - child: DesktopActionButton( - title: MainActions.tradeAction.name(context), - image: MainActions.tradeAction.image, - canShow: MainActions.tradeAction.canShow?.call(dashboardViewModel), - isEnabled: MainActions.tradeAction.isEnabled?.call(dashboardViewModel), - onTap: () async => - await MainActions.tradeAction.onTap(context, dashboardViewModel), - ), - ), - ], - ), - Expanded( - child: CakeFeaturesPage( - dashboardViewModel: dashboardViewModel, - cakeFeaturesViewModel: getIt.get(), - ), - ), - ], - ); - }), - ); - } -} diff --git a/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_navbar.dart b/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_navbar.dart deleted file mode 100644 index 31caa08da..000000000 --- a/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_navbar.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:cake_wallet/di.dart'; -import 'package:cake_wallet/themes/core/material_base_theme.dart'; -import 'package:cake_wallet/themes/core/theme_store.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; - -class DesktopDashboardNavbar extends StatelessWidget implements ObstructingPreferredSizeWidget { - final Widget leading; - final Widget middle; - final Widget trailing; - - DesktopDashboardNavbar({ - super.key, - required this.leading, - required this.middle, - required this.trailing, - }); - - MaterialThemeBase get currentTheme => getIt.get().currentTheme; - - @override - Widget build(BuildContext context) { - return Container( - padding: const EdgeInsetsDirectional.only(end: 24), - color: Theme.of(context).colorScheme.surfaceContainerLowest.withOpacity(0.1), - child: Center( - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Flexible(child: leading), - middle, - trailing, - ], - ), - ), - ); - } - - @override - Size get preferredSize => Size.fromHeight(60); - - @override - bool shouldFullyObstruct(BuildContext context) => false; -} diff --git a/lib/src/screens/dashboard/desktop_widgets/desktop_sidebar/side_menu.dart b/lib/src/screens/dashboard/desktop_widgets/desktop_sidebar/side_menu.dart deleted file mode 100644 index 69fa14114..000000000 --- a/lib/src/screens/dashboard/desktop_widgets/desktop_sidebar/side_menu.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar/side_menu_item.dart'; -import 'package:flutter/material.dart'; - -class SideMenu extends StatelessWidget { - const SideMenu({ - super.key, - required this.topItems, - required this.bottomItems, - required this.width, - }); - - final List topItems; - final List bottomItems; - final double width; - - @override - Widget build(BuildContext context) { - return Container( - color: Theme.of(context).colorScheme.surfaceContainerLowest.withOpacity(0.1), - width: width, - height: MediaQuery.of(context).size.height, - child: Column( - children: [ - ...topItems, - Spacer(), - ...bottomItems, - SizedBox(height: 30), - ], - ), - ); - } -} diff --git a/lib/src/screens/dashboard/desktop_widgets/desktop_sidebar/side_menu_item.dart b/lib/src/screens/dashboard/desktop_widgets/desktop_sidebar/side_menu_item.dart deleted file mode 100644 index 1f169d202..000000000 --- a/lib/src/screens/dashboard/desktop_widgets/desktop_sidebar/side_menu_item.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:cake_wallet/src/widgets/cake_image_widget.dart'; -import 'package:flutter/material.dart'; - -class SideMenuItem extends StatelessWidget { - const SideMenuItem({ - Key? key, - required this.onTap, - this.imagePath, - this.icon, - this.widget, - this.isSelected = false, - }) : assert(widget != null || icon != null || imagePath != null); - - final void Function() onTap; - final String? imagePath; - final IconData? icon; - final bool isSelected; - final Widget? widget; - - Color _setColor(BuildContext context) { - if (isSelected) { - return Theme.of(context).colorScheme.primary; - } else { - return Theme.of(context).colorScheme.onSurfaceVariant; - } - } - - @override - Widget build(BuildContext context) { - return InkWell( - child: Padding( - padding: EdgeInsets.all(20), - child: widget ?? _getIcon(context), - ), - onTap: () => onTap.call(), - highlightColor: Colors.transparent, - focusColor: Colors.transparent, - hoverColor: Colors.transparent, - splashColor: Colors.transparent, - ); - } - - Widget _getIcon(BuildContext context) { - return icon != null - ? Icon( - icon, - color: _setColor(context), - size: 30, - ) - : CakeImageWidget( - imageUrl: imagePath ?? '', - fit: BoxFit.cover, - height: 30, - width: 30, - color: _setColor(context), - ); - } -} diff --git a/lib/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart b/lib/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart deleted file mode 100644 index a26f48928..000000000 --- a/lib/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart +++ /dev/null @@ -1,173 +0,0 @@ -import 'package:cake_wallet/di.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/src/screens/auth/auth_page.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_dashboard_navbar.dart'; -import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar/side_menu.dart'; -import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar/side_menu_item.dart'; -import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart'; -import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator.dart'; -import 'package:cake_wallet/src/screens/wallet_connect/widgets/bottom_sheet/bottom_sheet_listener_widget.dart'; -import 'package:cake_wallet/src/screens/wallet_connect/services/bottom_sheet_service.dart'; -import 'package:cake_wallet/src/widgets/services_updates_widget.dart'; -import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; -import 'package:cake_wallet/view_model/dashboard/desktop_sidebar_view_model.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:cake_wallet/router.dart' as Router; -import 'package:mobx/mobx.dart'; - -class DesktopSidebarWrapper extends BasePage { - final BottomSheetService bottomSheetService; - final Widget child; - final DesktopSidebarViewModel desktopSidebarViewModel; - final DashboardViewModel dashboardViewModel; - final GlobalKey desktopNavigatorKey; - - DesktopSidebarWrapper({ - required this.child, - required this.bottomSheetService, - required this.desktopSidebarViewModel, - required this.dashboardViewModel, - required this.desktopNavigatorKey, - }); - - @override - ObstructingPreferredSizeWidget appBar(BuildContext context) => DesktopDashboardNavbar( - leading: Padding( - padding: EdgeInsets.only(left: sideMenuWidth), - child: getIt(), - ), - middle: SyncIndicator( - dashboardViewModel: dashboardViewModel, - onTap: () => Navigator.of(context, rootNavigator: true).pushNamed(Routes.connectionSync), - ), - trailing: InkWell( - onTap: () { - Navigator.of(context).pushNamed( - Routes.unlock, - arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) { - if (isAuthenticatedSuccessfully) { - auth.close(); - } - }, - ); - }, - child: Icon(Icons.lock_outline), - ), - ); - - @override - bool get resizeToAvoidBottomInset => false; - - final pageController = PageController(); - - double get sideMenuWidth => 76.0; - - @override - Widget body(BuildContext context) { - _setEffects(); - - return BottomSheetListener( - bottomSheetService: bottomSheetService, - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Observer(builder: (_) { - return SideMenu( - width: sideMenuWidth, - topItems: [ - SideMenuItem( - // imagePath: 'assets/images/wallet_outline.png', - icon: Icons.home, - isSelected: desktopSidebarViewModel.currentPage == SidebarItem.dashboard, - onTap: () { - desktopSidebarViewModel.onPageChange(SidebarItem.dashboard); - desktopNavigatorKey.currentState - ?.pushNamedAndRemoveUntil(Routes.desktop_actions, (route) => false); - }, - ), - SideMenuItem( - onTap: () { - if (desktopSidebarViewModel.currentPage == SidebarItem.transactions) { - desktopNavigatorKey.currentState - ?.pushNamedAndRemoveUntil(Routes.desktop_actions, (route) => false); - desktopSidebarViewModel.resetSidebar(); - } else { - desktopSidebarViewModel.onPageChange(SidebarItem.transactions); - desktopNavigatorKey.currentState?.pushNamed(Routes.transactionsPage); - } - }, - isSelected: desktopSidebarViewModel.currentPage == SidebarItem.transactions, - imagePath: 'assets/images/history.svg', - ), - SideMenuItem( - widget: ServicesUpdatesWidget( - dashboardViewModel.getServicesStatus(), - enabled: dashboardViewModel.isEnabledBulletinAction, - ), - isSelected: desktopSidebarViewModel.currentPage == SidebarItem.status, - onTap: () {}, - ), - ], - bottomItems: [ - SideMenuItem( - imagePath: 'assets/images/support_icon.png', - isSelected: desktopSidebarViewModel.currentPage == SidebarItem.support, - onTap: () => desktopSidebarViewModel.onPageChange(SidebarItem.support), - ), - SideMenuItem( - imagePath: 'assets/images/settings_outline.png', - isSelected: desktopSidebarViewModel.currentPage == SidebarItem.settings, - onTap: () => desktopSidebarViewModel.onPageChange(SidebarItem.settings), - ), - ], - ); - }), - Expanded( - child: PageView( - controller: pageController, - physics: NeverScrollableScrollPhysics(), - children: [ - child, - Container( - color: Theme.of(context).colorScheme.surface, - padding: EdgeInsets.all(20), - child: Navigator( - initialRoute: Routes.support, - onGenerateRoute: (settings) => Router.createRoute(settings), - onGenerateInitialRoutes: (NavigatorState navigator, String initialRouteName) { - return [ - navigator.widget.onGenerateRoute!(RouteSettings(name: initialRouteName))! - ]; - }, - ), - ), - Navigator( - initialRoute: Routes.desktop_settings_page, - onGenerateRoute: (settings) => Router.createRoute(settings), - onGenerateInitialRoutes: (NavigatorState navigator, String initialRouteName) { - return [ - navigator.widget.onGenerateRoute!(RouteSettings(name: initialRouteName))! - ]; - }, - ), - ], - ), - ), - ], - ), - ); - } - - void _setEffects() async { - reaction((_) => desktopSidebarViewModel.currentPage, (page) { - if (page == SidebarItem.dashboard) { - pageController.jumpToPage(0); - return; - } - pageController.jumpToPage(page.index - 1); - }); - } -} diff --git a/lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart b/lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart deleted file mode 100644 index ed85dc81c..000000000 --- a/lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart +++ /dev/null @@ -1,285 +0,0 @@ -import 'package:another_flushbar/flushbar.dart'; -import 'package:cake_wallet/core/new_wallet_arguments.dart'; -import 'package:cake_wallet/core/auth_service.dart'; -import 'package:cake_wallet/entities/desktop_dropdown_item.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/src/screens/auth/auth_page.dart'; -import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/dropdown_item_widget.dart'; -import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.dart'; -import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; -import 'package:cake_wallet/store/settings_store.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'; -import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart'; -import 'package:cake_wallet/wallet_type_utils.dart'; -import 'package:cw_core/wallet_type.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:flutter_svg/svg.dart'; - -class DesktopWalletSelectionDropDown extends StatefulWidget { - final WalletListViewModel walletListViewModel; - final AuthService _authService; - - DesktopWalletSelectionDropDown(this.walletListViewModel, this._authService, {Key? key}) - : super(key: key); - - @override - State createState() => _DesktopWalletSelectionDropDownState(); -} - -class _DesktopWalletSelectionDropDownState extends State { - final moneroIcon = - Image.asset('assets/new-ui/crypto_full_icons/monero.svg', height: 24, width: 24); - final bitcoinIcon = - Image.asset('assets/new-ui/crypto_full_icons/bitcoin.svg', height: 24, width: 24); - final tBitcoinIcon = Image.asset('assets/images/tbtc.png', height: 24, width: 24); - final litecoinIcon = - Image.asset('assets/new-ui/crypto_full_icons/litecoin.svg', height: 24, width: 24); - final havenIcon = Image.asset('assets/images/haven_logo.webp', height: 24, width: 24); - final ethereumIcon = - Image.asset('assets/new-ui/crypto_full_icons/ethereum.svg', height: 24, width: 24); - final polygonIcon = - Image.asset('assets/new-ui/crypto_full_icons/polygon.svg', height: 24, width: 24); - final bitcoinCashIcon = - Image.asset('assets/new-ui/crypto_full_icons/bitcoin-cash.svg', height: 24, width: 24); - final baseIcon = Image.asset('assets/new-ui/crypto_full_icons/base.svg', height: 24, width: 24); - final arbitrumIcon = - Image.asset('assets/new-ui/crypto_full_icons/arbitrum.svg', height: 24, width: 24); - final bscIcon = Image.asset('assets/new-ui/crypto_full_icons/bnb.svg', height: 24, width: 24); - final nanoIcon = Image.asset('assets/new-ui/crypto_full_icons/nano.svg', height: 24, width: 24); - final bananoIcon = Image.asset('assets/new-ui/crypto_full_icons/nano.svg', height: 24, width: 24); - final solanaIcon = - Image.asset('assets/new-ui/crypto_full_icons/solana.svg', height: 24, width: 24); - final tronIcon = Image.asset('assets/new-ui/crypto_full_icons/tron.svg', height: 24, width: 24); - final wowneroIcon = - Image.asset('assets/new-ui/crypto_full_icons/wownero.svg', height: 24, width: 24); - final zanoIcon = Image.asset('assets/new-ui/crypto_full_icons/zano.svg', height: 24, width: 24); - final decredIcon = - Image.asset('assets/new-ui/crypto_full_icons/decred.svg', height: 24, width: 24); - final dogeIcon = - Image.asset('assets/new-ui/crypto_full_icons/dogecoin.svg', height: 24, width: 24); - final zcashIcon = Image.asset('assets/new-ui/crypto_full_icons/zcash.svg', height: 24, width: 24); - final nonWalletTypeIcon = Image.asset('assets/images/close.png', height: 24, width: 24); - - Image _newWalletImage(BuildContext context) => Image.asset( - 'assets/images/new_wallet.png', - height: 12, - width: 12, - color: Theme.of(context).colorScheme.onSurface, - ); - - Image _restoreWalletImage(BuildContext context) => Image.asset( - 'assets/images/restore_wallet.png', - height: 12, - width: 12, - color: Theme.of(context).colorScheme.onSurface, - ); - - Flushbar? _progressBar; - - @override - Widget build(BuildContext context) { - final themeData = Theme.of(context); - return Observer(builder: (context) { - final dropDownItems = [ - ...widget.walletListViewModel.wallets - .map((wallet) => DesktopDropdownItem( - isSelected: wallet.isCurrent, - child: ConstrainedBox( - constraints: BoxConstraints(maxWidth: 500), - child: DropDownItemWidget( - title: wallet.name, - image: wallet.isEnabled - ? _imageFor(type: wallet.type, isTestnet: wallet.isTestnet) - : nonWalletTypeIcon, - ), - ), - onSelected: () => _onSelectedWallet(wallet), - )) - .toList(), - DesktopDropdownItem( - onSelected: () => _navigateToCreateWallet(), - child: DropDownItemWidget( - title: S.of(context).create_new, - image: _newWalletImage(context), - ), - ), - DesktopDropdownItem( - onSelected: () => _navigateToRestoreWallet(), - child: DropDownItemWidget( - title: S.of(context).restore_wallet, - image: _restoreWalletImage(context), - ), - ), - ]; - - final selectedItem = dropDownItems.firstWhere( - (element) => element.isSelected, - orElse: () => dropDownItems.first, - ); - - return DropdownButton( - items: dropDownItems - .map( - (wallet) => DropdownMenuItem( - child: wallet.child, - value: wallet, - ), - ) - .toList(), - onChanged: (item) { - item?.onSelected(); - }, - dropdownColor: themeData.colorScheme.surface, - style: themeData.textTheme.bodyMedium, - selectedItemBuilder: (context) => dropDownItems.map((item) => item.child).toList(), - value: selectedItem, - underline: const SizedBox(), - focusColor: Colors.transparent, - borderRadius: BorderRadius.circular(15.0), - ); - }); - } - - void _onSelectedWallet(WalletListItem selectedWallet) async { - if (selectedWallet.isCurrent || !selectedWallet.isEnabled) return; - - WidgetsBinding.instance.addPostFrameCallback((_) async { - final confirmed = await showPopUp( - context: context, - builder: (dialogContext) { - return AlertWithTwoActions( - alertTitle: S.of(context).change_wallet_alert_title, - alertContent: S.of(context).change_wallet_alert_content(selectedWallet.name), - leftButtonText: S.of(context).cancel, - rightButtonText: S.of(context).change, - actionLeftButton: () => Navigator.of(dialogContext).pop(false), - actionRightButton: () => Navigator.of(dialogContext).pop(true)); - }) ?? - false; - - if (confirmed) { - await _loadWallet(selectedWallet); - } - }); - } - - Widget _imageFor({required WalletType type, bool? isTestnet}) { - switch (type) { - case WalletType.bitcoin: - if (isTestnet == true) return tBitcoinIcon; - return bitcoinIcon; - case WalletType.monero: - return moneroIcon; - case WalletType.wownero: - return wowneroIcon; - case WalletType.litecoin: - return litecoinIcon; - case WalletType.haven: - return havenIcon; - case WalletType.ethereum: - return ethereumIcon; - case WalletType.bitcoinCash: - return bitcoinCashIcon; - case WalletType.nano: - return nanoIcon; - case WalletType.banano: - return bananoIcon; - case WalletType.polygon: - return polygonIcon; - case WalletType.solana: - return solanaIcon; - case WalletType.tron: - return tronIcon; - case WalletType.zano: - return zanoIcon; - case WalletType.decred: - return decredIcon; - case WalletType.dogecoin: - return dogeIcon; - case WalletType.base: - return baseIcon; - case WalletType.arbitrum: - return arbitrumIcon; - case WalletType.bsc: - return bscIcon; - case WalletType.zcash: - return zcashIcon; - case WalletType.none: - return nonWalletTypeIcon; - } - } - - Future _loadWallet(WalletListItem wallet) async { - if (SettingsStoreBase.walletPasswordDirectInput) { - Navigator.of(context).pushNamed(Routes.walletUnlockLoadable, - arguments: WalletUnlockArguments( - callback: (bool isAuthenticatedSuccessfully, AuthPageState auth) async { - if (isAuthenticatedSuccessfully) { - auth.close(); - setState(() {}); - } - }, - walletName: wallet.name, - walletType: wallet.type)); - return; - } - - widget._authService.authenticateAction( - context, - onAuthSuccess: (isAuthenticatedSuccessfully) async { - if (!isAuthenticatedSuccessfully) return; - - try { - if (mounted) { - changeProcessText(S.of(context).wallet_list_loading_wallet(wallet.name)); - } - await widget.walletListViewModel.loadWallet(wallet); - hideProgressText(); - setState(() {}); - } catch (e) { - if (mounted) { - changeProcessText(S.of(context).wallet_list_failed_to_load(wallet.name, e.toString())); - } - } - }, - conditionToDetermineIfToUse2FA: - widget.walletListViewModel.shouldRequireTOTP2FAForAccessingWallet, - ); - } - - void _navigateToCreateWallet() { - if (isSingleCoin) { - widget._authService.authenticateAction( - context, - route: Routes.newWallet, - arguments: NewWalletArguments(type: widget.walletListViewModel.currentWalletType), - conditionToDetermineIfToUse2FA: - widget.walletListViewModel.shouldRequireTOTP2FAForCreatingNewWallets, - ); - } else { - widget._authService.authenticateAction( - context, - route: Routes.newWalletType, - conditionToDetermineIfToUse2FA: - widget.walletListViewModel.shouldRequireTOTP2FAForCreatingNewWallets, - ); - } - } - - void _navigateToRestoreWallet() { - Navigator.of(context).pushNamed(Routes.restoreOptions, arguments: false); - } - - void changeProcessText(String text) { - _progressBar = createBar(text, context, duration: null)..show(context); - } - - void hideProgressText() { - _progressBar?.dismiss(); - _progressBar = null; - } -} diff --git a/lib/src/screens/dashboard/desktop_widgets/dropdown_item_widget.dart b/lib/src/screens/dashboard/desktop_widgets/dropdown_item_widget.dart deleted file mode 100644 index 17839195e..000000000 --- a/lib/src/screens/dashboard/desktop_widgets/dropdown_item_widget.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:flutter/material.dart'; - -class DropDownItemWidget extends StatelessWidget { - const DropDownItemWidget({super.key, required this.title, required this.image}); - final double tileHeight = 60; - final Widget image; - final String title; - - @override - Widget build(BuildContext context) { - return Container( - height: tileHeight, - padding: EdgeInsets.symmetric(horizontal: 20), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - image, - SizedBox(width: 10), - Flexible( - child: Text( - title, - style: Theme.of(context).textTheme.bodyMedium, - overflow: TextOverflow.ellipsis, - maxLines: 1, - ), - ) - ], - ), - ); - } -} diff --git a/lib/src/screens/dashboard/pages/address_page.dart b/lib/src/screens/dashboard/pages/address_page.dart deleted file mode 100644 index a055ffcf4..000000000 --- a/lib/src/screens/dashboard/pages/address_page.dart +++ /dev/null @@ -1,330 +0,0 @@ -import 'package:cake_wallet/bitcoin/bitcoin.dart'; -import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart'; -import 'package:cake_wallet/di.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/anonpay/anonpay_donation_link_info.dart'; -import 'package:cake_wallet/entities/preferences_key.dart'; -import 'package:cake_wallet/src/screens/receive/anonpay_receive_page.dart'; -import 'package:cake_wallet/src/widgets/cake_image_widget.dart'; -import 'package:cake_wallet/zcash/zcash.dart'; -import 'package:cw_core/receive_page_option.dart'; -import 'package:cake_wallet/src/screens/dashboard/widgets/present_receive_option_picker.dart'; -import 'package:cake_wallet/src/widgets/gradient_background.dart'; -import 'package:cake_wallet/src/widgets/keyboard_done_button.dart'; -import 'package:cake_wallet/utils/responsive_layout_util.dart'; -import 'package:cake_wallet/utils/share_util.dart'; -import 'package:cake_wallet/view_model/dashboard/receive_option_view_model.dart'; -import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; -import 'package:cw_core/utils/print_verbose.dart'; -import 'package:cw_core/wallet_type.dart'; -import 'package:flutter/material.dart'; -import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart'; -import 'package:cake_wallet/src/screens/receive/widgets/qr_widget.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:keyboard_actions/keyboard_actions.dart'; -import 'package:mobx/mobx.dart'; -import 'package:shared_preferences/shared_preferences.dart'; - -class AddressPage extends BasePage { - AddressPage({ - required this.addressListViewModel, - required this.dashboardViewModel, - required this.receiveOptionViewModel, - }) : _cryptoAmountFocus = FocusNode(), - _formKey = GlobalKey(), - _amountController = TextEditingController() { - _amountController.addListener(() { - if (_formKey.currentState!.validate()) { - addressListViewModel.changeAmount(_amountController.text); - } - }); - } - - final WalletAddressListViewModel addressListViewModel; - final DashboardViewModel dashboardViewModel; - final ReceiveOptionViewModel receiveOptionViewModel; - final TextEditingController _amountController; - final GlobalKey _formKey; - - final FocusNode _cryptoAmountFocus; - - @override - bool get gradientBackground => true; - - @override - bool get resizeToAvoidBottomInset => false; - - bool effectsInstalled = false; - - @override - Widget? leading(BuildContext context) { - final _backButton = Icon( - Icons.arrow_back_ios, - color: Theme.of(context).colorScheme.primary, - size: 16, - ); - final _closeButton = currentTheme.isDark ? closeButtonImageDarkTheme : closeButtonImage; - - bool isMobileView = responsiveLayoutUtil.shouldRenderMobileUI; - - return MergeSemantics( - child: SizedBox( - height: isMobileView ? 37 : 45, - width: isMobileView ? 37 : 45, - child: ButtonTheme( - minWidth: double.minPositive, - child: Semantics( - label: !isMobileView ? S.of(context).close : S.of(context).seed_alert_back, - child: TextButton( - style: ButtonStyle( - overlayColor: WidgetStateColor.resolveWith((states) => Colors.transparent), - ), - onPressed: () => onClose(context), - child: !isMobileView ? _closeButton : _backButton, - ), - ), - ), - ), - ); - } - - @override - Widget middle(BuildContext context) => PresentReceiveOptionPicker( - color: titleColor(context), receiveOptionViewModel: receiveOptionViewModel); - - @override - Widget Function(BuildContext, Widget) get rootWrapper => - (BuildContext context, Widget scaffold) => GradientBackground(scaffold: scaffold); - - @override - Widget? trailing(BuildContext context) { - return Material( - color: Colors.transparent, - child: Semantics( - label: S.of(context).share, - child: IconButton( - padding: EdgeInsets.zero, - constraints: BoxConstraints(), - highlightColor: Colors.transparent, - splashColor: Colors.transparent, - iconSize: 25, - onPressed: () { - ShareUtil.share( - text: addressListViewModel.uri.toString(), - context: context, - ); - }, - icon: Icon(Icons.share, size: 20, color: Theme.of(context).colorScheme.primary), - ), - ), - ); - } - - @override - Widget body(BuildContext context) { - _setEffects(context); - - return KeyboardActions( - autoScroll: false, - disableScroll: true, - tapOutsideBehavior: TapOutsideBehavior.translucentDismiss, - config: KeyboardActionsConfig( - keyboardActionsPlatform: KeyboardActionsPlatform.IOS, - keyboardBarColor: Theme.of(context).colorScheme.surface, - nextFocus: false, - actions: [ - KeyboardActionsItem( - focusNode: _cryptoAmountFocus, - toolbarButtons: [(_) => KeyboardDoneButton()], - ) - ], - ), - child: Container( - padding: EdgeInsets.fromLTRB(24, 0, 24, 32), - child: Column( - children: [ - Expanded( - child: QRWidget( - formKey: _formKey, - addressListViewModel: addressListViewModel, - amountTextFieldFocusNode: _cryptoAmountFocus, - amountController: _amountController, - ), - ), - SizedBox(height: 16), - Observer( - builder: (_) { - if (addressListViewModel.hasAddressList) { - return SelectButton( - text: addressListViewModel.buttonTitle, - onTap: () => Navigator.of(context).pushNamed(Routes.receive), - textColor: Theme.of(context).colorScheme.onSecondaryContainer, - color: Theme.of(context).colorScheme.surfaceContainer, - arrowColor: Theme.of(context).colorScheme.onSurfaceVariant, - textSize: 14, - height: 50, - ); - } else { - return const SizedBox(); - } - }, - ), - if (addressListViewModel.hasTokensList) ...[ - Container( - padding: EdgeInsets.all(20), - decoration: BoxDecoration( - border: Border.all(color: Theme.of(context).colorScheme.surfaceContainer), - color: Theme.of(context).colorScheme.surfaceContainer, - borderRadius: BorderRadius.circular(18), - ), - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - CakeImageWidget( - imageUrl: addressListViewModel.monoImage, - height: 16, - width: 16, - color: Theme.of(context).colorScheme.onSurface, - ), - SizedBox(width: 10), - Text( - '${S.current.your} ${addressListViewModel.walletTypeName} ${S.current.address}', - style: Theme.of(context).textTheme.titleMedium?.copyWith( - fontWeight: FontWeight.w500, - ), - ), - ], - ), - SizedBox(height: 10), - Text( - '${S.current.qr_instruction} ${addressListViewModel.walletTypeName}', - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant, - fontWeight: FontWeight.w500, - ), - ), - SizedBox(height: 20), - Observer( - builder: (_) { - final walletImages = addressListViewModel - .getWalletImages(addressListViewModel.selectedChainId); - return Center( - child: SizedBox( - height: 40, - width: walletImages.length * 32.0, - child: Stack( - children: [ - for (int i = walletImages.length - 1; i >= 0; i--) - Positioned( - left: i * 25.0, - child: Container( - decoration: BoxDecoration( - border: Border.all( - color: Theme.of(context).colorScheme.surfaceContainer, - width: 3, - ), - color: Theme.of(context).colorScheme.surfaceContainer, - borderRadius: BorderRadius.circular(24), - ), - child: ClipOval( - child: CakeImageWidget( - height: 35, - width: 35, - imageUrl: walletImages[i], - color: walletImages.last == walletImages[i] - ? Theme.of(context).colorScheme.onSurfaceVariant - : null, - ), - ), - ), - ), - ], - ), - ), - ); - }, - ), - ], - ), - ), - SizedBox(height: 48), - ], - ], - ), - ), - ); - } - - void _setEffects(BuildContext context) { - if (effectsInstalled) { - return; - } - - reaction((_) => receiveOptionViewModel.selectedReceiveOption, (ReceivePageOption option) { - if (dashboardViewModel.type == WalletType.bitcoin && - bitcoin!.isBitcoinReceivePageOption(option)) { - addressListViewModel.setAddressType(bitcoin!.getOptionToType(option)); - return; - } - if (dashboardViewModel.type == WalletType.zcash) { - addressListViewModel.setAddressType(zcash!.getOptionToType(option)); - return; - } - - switch (option) { - case ReceivePageOption.anonPayInvoice: - Navigator.pushNamed( - context, - Routes.anonPayInvoicePage, - arguments: [addressListViewModel.address.address, option], - ); - break; - case ReceivePageOption.anonPayDonationLink: - final sharedPreferences = getIt.get(); - final clearnetUrl = sharedPreferences.getString(PreferencesKey.clearnetDonationLink); - final onionUrl = sharedPreferences.getString(PreferencesKey.onionDonationLink); - final donationWalletName = - sharedPreferences.getString(PreferencesKey.donationLinkWalletName); - - if (clearnetUrl != null && - onionUrl != null && - addressListViewModel.wallet.name == donationWalletName) { - Navigator.pushNamed( - context, - Routes.anonPayReceivePage, - arguments: AnonPayReceivePageArgs( - invoiceInfo: AnonpayDonationLinkInfo( - clearnetUrl: clearnetUrl, - onionUrl: onionUrl, - address: addressListViewModel.address.address, - ), - qrImage: addressListViewModel.qrImage, - ), - ); - } else { - Navigator.pushNamed( - context, - Routes.anonPayInvoicePage, - arguments: [addressListViewModel.address.address, option], - ); - } - break; - default: - if ([WalletType.bitcoin, WalletType.litecoin].contains(addressListViewModel.type)) { - addressListViewModel.setAddressType(bitcoin!.getBitcoinAddressType(option)); - } - if (addressListViewModel.type == WalletType.zcash) { - printV("help me i'll kms if that wont work: ${zcash!.getZcashAddressType(option)}"); - addressListViewModel.setAddressType(zcash!.getZcashAddressType(option)); - } - } - }); - - effectsInstalled = true; - } -} diff --git a/lib/src/screens/dashboard/pages/balance/balance_page.dart b/lib/src/screens/dashboard/pages/balance/balance_page.dart deleted file mode 100644 index 3718568dc..000000000 --- a/lib/src/screens/dashboard/pages/balance/balance_page.dart +++ /dev/null @@ -1,81 +0,0 @@ -import 'package:cake_wallet/reactions/wallet_connect.dart'; -import 'package:cake_wallet/src/screens/dashboard/pages/balance/crypto_balance_widget.dart'; -import 'package:cake_wallet/src/screens/dashboard/pages/nft_listing_page.dart'; -import 'package:cake_wallet/store/settings_store.dart'; -import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; -import 'package:cake_wallet/view_model/dashboard/nft_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; - -class BalancePage extends StatelessWidget { - BalancePage({ - required this.dashboardViewModel, - required this.settingsStore, - required this.nftViewModel, - }); - - final DashboardViewModel dashboardViewModel; - final NFTViewModel nftViewModel; - final SettingsStore settingsStore; - - @override - Widget build(BuildContext context) { - return Observer( - builder: (context) { - final isNFTActivated = isNFTACtivatedChain(dashboardViewModel.type, - chainId: dashboardViewModel.wallet.chainId); - return DefaultTabController( - key: ValueKey(isNFTActivated), - length: isNFTActivated ? 2 : 1, - child: Column( - children: [ - if (isNFTActivated) - Align( - alignment: Alignment.centerLeft, - child: Padding( - padding: const EdgeInsets.only(left: 8), - child: TabBar( - indicatorSize: TabBarIndicatorSize.label, - isScrollable: true, - physics: const NeverScrollableScrollPhysics(), - labelStyle: Theme.of(context).textTheme.titleMedium?.copyWith( - fontWeight: FontWeight.w600, - fontSize: 18, - height: 1, - color: Theme.of(context).colorScheme.primary, - ), - unselectedLabelStyle: Theme.of(context).textTheme.titleMedium?.copyWith( - fontWeight: FontWeight.w600, - fontSize: 18, - height: 1, - color: Theme.of(context).colorScheme.primary, - ), - labelColor: Theme.of(context).colorScheme.primary, - dividerColor: Colors.transparent, - indicatorColor: Theme.of(context).colorScheme.primary, - unselectedLabelColor: - Theme.of(context).colorScheme.secondary.withOpacity(0.7), - tabAlignment: TabAlignment.start, - tabs: const [ - Tab(text: 'My Crypto'), - Tab(text: 'My NFTs'), - ], - ), - ), - ), - Expanded( - child: TabBarView( - physics: const NeverScrollableScrollPhysics(), - children: [ - CryptoBalanceWidget(dashboardViewModel: dashboardViewModel), - if (isNFTActivated) NFTListingPage(nftViewModel: nftViewModel) - ], - ), - ), - ], - ), - ); - }, - ); - } -} diff --git a/lib/src/screens/dashboard/pages/balance/balance_row_widget.dart b/lib/src/screens/dashboard/pages/balance/balance_row_widget.dart deleted file mode 100644 index ce05dad05..000000000 --- a/lib/src/screens/dashboard/pages/balance/balance_row_widget.dart +++ /dev/null @@ -1,693 +0,0 @@ -import 'dart:math'; - -import 'package:auto_size_text/auto_size_text.dart'; -import 'package:cake_wallet/bitcoin/bitcoin.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/src/screens/exchange_trade/information_page.dart'; -import 'package:cake_wallet/src/widgets/cake_image_widget.dart'; -import 'package:cake_wallet/themes/core/theme_extension.dart'; -import 'package:cake_wallet/utils/payment_request.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; -import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; -import 'package:cw_core/crypto_currency.dart'; -import 'package:cw_core/unspent_coin_type.dart'; -import 'package:cw_core/wallet_type.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:fluttertoast/fluttertoast.dart'; -import 'package:url_launcher/url_launcher.dart'; - -class BalanceRowWidget extends StatelessWidget { - BalanceRowWidget({ - required this.availableBalanceLabel, - required this.availableBalance, - required this.availableFiatBalance, - required this.additionalBalanceLabel, - required this.additionalBalance, - required this.additionalFiatBalance, - required this.secondAvailableBalanceLabel, - required this.secondAvailableBalance, - required this.secondAvailableFiatBalance, - required this.secondAdditionalBalanceLabel, - required this.secondAdditionalBalance, - required this.secondAdditionalFiatBalance, - required this.frozenBalance, - required this.frozenFiatBalance, - required this.currency, - required this.hasAdditionalBalance, - required this.hasSecondAvailableBalance, - required this.hasSecondAdditionalBalance, - required this.isTestnet, - required this.dashboardViewModel, - super.key, - }); - - final String availableBalanceLabel; - final String availableBalance; - final String availableFiatBalance; - final String additionalBalanceLabel; - final String additionalBalance; - final String additionalFiatBalance; - final String secondAvailableBalanceLabel; - final String secondAvailableBalance; - final String secondAvailableFiatBalance; - final String secondAdditionalBalanceLabel; - final String secondAdditionalBalance; - final String secondAdditionalFiatBalance; - final String frozenBalance; - final String frozenFiatBalance; - final CryptoCurrency currency; - final bool hasAdditionalBalance; - final bool hasSecondAvailableBalance; - final bool hasSecondAdditionalBalance; - final bool isTestnet; - final DashboardViewModel dashboardViewModel; - - @override - Widget build(BuildContext context) { - return Column( - children: [ - Container( - margin: const EdgeInsets.only(left: 16, right: 16), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15.0), - gradient: LinearGradient( - colors: [ - context.customColors.cardGradientColorPrimary, - context.customColors.cardGradientColorSecondary, - ], - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - ), - ), - child: TextButton( - onPressed: _showToast, - onLongPress: () => dashboardViewModel.balanceViewModel.switchBalanceValue(), - style: TextButton.styleFrom( - side: BorderSide( - width: 1.25, color: Theme.of(context).colorScheme.surfaceContainerHigh), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), - ), - child: Container( - margin: const EdgeInsets.only( - top: 10, - left: 12, - right: 12, - bottom: 10, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: hasAdditionalBalance - ? () => _showBalanceDescription( - context, S.of(context).available_balance_description) - : null, - child: Row( - children: [ - Semantics( - hint: 'Double tap to see more information', - container: true, - child: Text( - '${availableBalanceLabel}', - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant, - height: 1, - ), - ), - ), - if (hasAdditionalBalance) - Padding( - padding: const EdgeInsets.symmetric(horizontal: 4), - child: Icon( - Icons.help_outline, - size: 16, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - ], - ), - ), - SizedBox(height: 6), - AutoSizeText( - availableBalance, - minFontSize: 16, - overflow: TextOverflow.ellipsis, - style: Theme.of(context).textTheme.titleLarge?.copyWith( - color: Theme.of(context).colorScheme.onSurface, - fontWeight: FontWeight.w900, - fontSize: 24, - height: 1, - ), - maxLines: 1, - textAlign: TextAlign.start, - ), - SizedBox(height: 6), - if (isTestnet) - Text( - S.of(context).testnet_coins_no_value, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - height: 1, - ), - ), - if (!isTestnet) - Text( - '${availableFiatBalance}', - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.onSurfaceVariant, - height: 1, - ), - ), - ], - ), - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - CakeImageWidget( - imageUrl: currency.iconPath, - height: 40, - width: 40, - errorWidget: Container( - height: 30.0, - width: 30.0, - child: Center( - child: Text( - currency.title.substring(0, min(currency.title.length, 2)), - style: Theme.of(context).textTheme.bodySmall?.copyWith( - fontSize: 11, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - ), - decoration: BoxDecoration( - shape: BoxShape.circle, - color: Theme.of(context).colorScheme.surfaceContainer, - ), - ), - ), - const SizedBox(height: 10), - Text( - currency.title, - overflow: TextOverflow.ellipsis, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontSize: 16, - fontWeight: FontWeight.w700, - color: Theme.of(context).colorScheme.onSurface, - height: 1, - ), - ), - ], - ), - ), - ], - ), - if (currency.isPotentialScam) - Container( - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), - margin: const EdgeInsets.only(top: 4), - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.errorContainer, - borderRadius: BorderRadius.circular(8), - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Icon( - Icons.warning_amber_outlined, - size: 16, - color: Theme.of(context).colorScheme.onErrorContainer, - ), - const SizedBox(width: 4), - Text( - S.of(context).potential_scam, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of(context).colorScheme.onErrorContainer, - fontWeight: FontWeight.w700, - ), - ), - ], - ), - ), - if (frozenBalance.isNotEmpty) - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox(height: 26), - Row( - children: [ - Text( - S.of(context).frozen_balance, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant, - height: 1, - ), - ), - ], - ), - const SizedBox(height: 8), - AutoSizeText( - frozenBalance, - style: Theme.of(context).textTheme.bodyLarge!.copyWith( - fontSize: 20, - color: Theme.of(context).colorScheme.primary, - height: 1, - ), - maxLines: 1, - textAlign: TextAlign.center, - ), - const SizedBox(height: 4), - if (!isTestnet) - Text( - frozenFiatBalance, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodySmall!.copyWith(height: 1), - ), - ], - ), - if (hasAdditionalBalance) - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox(height: 24), - Text( - '${additionalBalanceLabel}', - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant, - height: 1, - ), - ), - const SizedBox(height: 8), - AutoSizeText( - additionalBalance, - style: Theme.of(context).textTheme.bodyLarge!.copyWith( - fontSize: 20, - color: Theme.of(context).colorScheme.secondary, - height: 1, - ), - maxLines: 1, - textAlign: TextAlign.center, - ), - const SizedBox(height: 4), - if (!isTestnet) - Text( - '${additionalFiatBalance}', - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodySmall!.copyWith(height: 1), - ), - ], - ), - ], - ), - ), - ), - ), - if (hasSecondAdditionalBalance || hasSecondAvailableBalance) ...[ - SizedBox(height: 10), - Container( - margin: const EdgeInsets.only(left: 16, right: 16), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), - gradient: LinearGradient( - colors: [ - context.customColors.cardGradientColorPrimary, - context.customColors.cardGradientColorSecondary, - ], - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - ), - ), - child: TextButton( - onPressed: _showToast, - onLongPress: () => dashboardViewModel.balanceViewModel.switchBalanceValue(), - style: TextButton.styleFrom( - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - margin: const EdgeInsets.only(top: 10, left: 12, right: 8, bottom: 10), - child: Stack( - children: [ - if (currency == CryptoCurrency.ltc) - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Column( - children: [ - ImageIcon( - AssetImage('assets/images/mweb_logo.png'), - size: 40, - ), - const SizedBox(height: 10), - Text( - 'MWEB', - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontSize: 16, - fontWeight: FontWeight.w700, - color: Theme.of(context).colorScheme.onSurface, - height: 1, - ), - ), - ], - ), - ], - ), - if (currency == CryptoCurrency.btc) - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Column( - children: [ - SvgPicture.asset( - 'assets/images/lightning-icon.svg', - width: 40, - height: 40, - ), - const SizedBox(height: 10), - Text( - 'Lightning', - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontSize: 16, - fontWeight: FontWeight.w700, - color: Theme.of(context).colorScheme.onSurface, - height: 1, - ), - ), - ], - ), - ], - ), - if (hasSecondAvailableBalance) - Row( - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: onPressedHelp, - child: Row( - children: [ - Text( - secondAvailableBalanceLabel, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: - Theme.of(context).colorScheme.onSurfaceVariant, - height: 1, - ), - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 4), - child: Icon( - Icons.help_outline, - size: 16, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ) - ], - ), - ), - SizedBox(height: 8), - AutoSizeText( - secondAvailableBalance, - style: Theme.of(context).textTheme.bodyLarge?.copyWith( - fontSize: 24, - fontWeight: FontWeight.w800, - color: Theme.of(context).colorScheme.onSurface, - height: 1, - ), - maxLines: 1, - textAlign: TextAlign.center, - ), - SizedBox(height: 6), - if (!isTestnet) - Text( - secondAvailableFiatBalance, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.onSurfaceVariant, - height: 1, - ), - ), - ], - ), - ], - ), - ], - ), - ), - Container( - margin: const EdgeInsets.only(top: 0, left: 24, right: 8, bottom: 16), - child: Stack( - children: [ - if (hasSecondAdditionalBalance) - Row( - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox(height: 24), - Text( - secondAdditionalBalanceLabel, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant, - height: 1, - ), - ), - SizedBox(height: 8), - AutoSizeText( - secondAdditionalBalance, - style: Theme.of(context).textTheme.bodyLarge?.copyWith( - fontSize: 20, - color: Theme.of(context).colorScheme.secondary, - height: 1, - ), - maxLines: 1, - textAlign: TextAlign.center, - ), - SizedBox(height: 4), - if (!isTestnet) - Text( - '${secondAdditionalFiatBalance}', - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - height: 1, - ), - ), - ], - ), - ], - ), - ], - ), - ), - IntrinsicHeight( - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 12), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Semantics( - label: depositToL2Label, - child: OutlinedButton( - onPressed: () => depositToL2(context), - style: OutlinedButton.styleFrom( - backgroundColor: Theme.of(context).colorScheme.primary, - side: BorderSide( - color: - Theme.of(context).colorScheme.outlineVariant.withAlpha(0), - width: 0, - ), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - ), - child: Container( - padding: const EdgeInsets.symmetric(vertical: 12), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Image.asset( - height: 30, - width: 30, - 'assets/images/received.png', - color: Theme.of(context).colorScheme.onPrimary, - ), - const SizedBox(width: 8), - Text( - depositToL2Label, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - color: Theme.of(context).colorScheme.onPrimary, - fontWeight: FontWeight.w700, - ), - ), - ], - ), - ), - ), - ), - ), - SizedBox(width: 16), - Expanded( - child: Semantics( - label: withdrawFromL2Label, - child: OutlinedButton( - onPressed: () => withdrawFromL2(context), - style: OutlinedButton.styleFrom( - backgroundColor: Theme.of(context).colorScheme.surface, - side: BorderSide( - color: - Theme.of(context).colorScheme.outlineVariant.withAlpha(0), - width: 0, - ), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - ), - child: Container( - padding: EdgeInsets.symmetric(vertical: 12), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Image.asset( - height: 30, - width: 30, - 'assets/images/upload.png', - color: Theme.of(context).colorScheme.onSecondaryContainer, - ), - const SizedBox(width: 8), - Text( - withdrawFromL2Label, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - color: Theme.of(context) - .colorScheme - .onSecondaryContainer, - fontWeight: FontWeight.w700, - ), - ), - ], - ), - ), - ), - ), - ), - ], - ), - ), - ), - const SizedBox(height: 16), - ], - ), - ), - ), - ], - ], - ); - } - - String get depositToL2Label => dashboardViewModel.type == WalletType.litecoin - ? S.current.litecoin_mweb_pegin - : S.current.bitcoin_lightning_deposit; - - String get withdrawFromL2Label => dashboardViewModel.type == WalletType.litecoin - ? S.current.litecoin_mweb_pegout - : S.current.bitcoin_lightning_withdraw; - - Future depositToL2(BuildContext context) async { - PaymentRequest? paymentRequest = null; - - if (dashboardViewModel.type == WalletType.litecoin) { - final depositAddress = bitcoin!.getUnusedMwebAddress(dashboardViewModel.wallet); - if ((depositAddress?.isNotEmpty ?? false)) { - paymentRequest = PaymentRequest.fromUri(Uri.parse("litecoin:$depositAddress")); - } - } else if (dashboardViewModel.type == WalletType.bitcoin) { - final depositAddress = await bitcoin!.getUnusedSpakDepositAddress(dashboardViewModel.wallet); - if ((depositAddress?.isNotEmpty ?? false)) { - paymentRequest = PaymentRequest.fromUri(Uri.parse("bitcoin:$depositAddress")); - } - } - - Navigator.pushNamed( - context, - Routes.send, - arguments: { - 'paymentRequest': paymentRequest, - 'coinTypeToSpendFrom': UnspentCoinType.nonMweb, - }, - ); - } - - Future withdrawFromL2(BuildContext context) async { - PaymentRequest? paymentRequest = null; - UnspentCoinType unspentCoinType = UnspentCoinType.any; - final withdrawAddress = bitcoin!.getUnusedSegwitAddress(dashboardViewModel.wallet); - - if (dashboardViewModel.type == WalletType.litecoin) { - if ((withdrawAddress?.isNotEmpty ?? false)) { - paymentRequest = PaymentRequest.fromUri(Uri.parse("litecoin:$withdrawAddress")); - } - unspentCoinType = UnspentCoinType.mweb; - } else if (dashboardViewModel.type == WalletType.bitcoin) { - if ((withdrawAddress?.isNotEmpty ?? false)) { - paymentRequest = PaymentRequest.fromUri(Uri.parse("bitcoin:$withdrawAddress")); - } - unspentCoinType = UnspentCoinType.lightning; - } - - Navigator.pushNamed( - context, - Routes.send, - arguments: { - 'paymentRequest': paymentRequest, - 'coinTypeToSpendFrom': unspentCoinType, - }, - ); - } - - void onPressedHelp() { - var helpUri = Uri.parse("https://docs.cakewallet.com/cryptos/bitcoin#lightning"); - if (dashboardViewModel.type == WalletType.litecoin) { - helpUri = Uri.parse("https://docs.cakewallet.com/cryptos/litecoin#mweb"); - } - - launchUrl(helpUri, mode: LaunchMode.externalApplication); - } - - void _showBalanceDescription(BuildContext context, String content) { - showPopUp(context: context, builder: (_) => InformationPage(information: content)); - } - - void _showToast() async { - try { - await Fluttertoast.showToast( - msg: S.current.show_balance_toast, - backgroundColor: Color.fromRGBO(0, 0, 0, 0.85), - ); - } catch (_) {} - } -} diff --git a/lib/src/screens/dashboard/pages/balance/crypto_balance_widget.dart b/lib/src/screens/dashboard/pages/balance/crypto_balance_widget.dart deleted file mode 100644 index 932a220bd..000000000 --- a/lib/src/screens/dashboard/pages/balance/crypto_balance_widget.dart +++ /dev/null @@ -1,479 +0,0 @@ -import 'package:cake_wallet/bitcoin/bitcoin.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/src/screens/dashboard/pages/balance/balance_row_widget.dart'; -import 'package:cake_wallet/src/screens/dashboard/widgets/home_screen_account_widget.dart'; -import 'package:cake_wallet/src/screens/dashboard/widgets/info_card.dart'; -import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; -import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; -import 'package:cake_wallet/src/widgets/dashboard_card_widget.dart'; -import 'package:cake_wallet/src/widgets/introducing_card.dart'; -import 'package:cake_wallet/src/widgets/standard_switch.dart'; -import 'package:cake_wallet/themes/core/theme_extension.dart'; -import 'package:cake_wallet/utils/feature_flag.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; -import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; -import 'package:cw_core/wallet_info.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:url_launcher/url_launcher.dart'; - -class CryptoBalanceWidget extends StatelessWidget { - const CryptoBalanceWidget({ - super.key, - required this.dashboardViewModel, - }); - - final DashboardViewModel dashboardViewModel; - final btcLockLight = 'assets/images/btc_lock_light.png'; - final btcLockDark = 'assets/images/btc_lock_dark.png'; - - String? get hardwareWalletIcon { - switch (dashboardViewModel.wallet.hardwareWalletType) { - case null: - return null; - case HardwareWalletType.bitbox: - return "assets/new-ui/hardware_wallets/device_bitbox.svg"; - case HardwareWalletType.ledger: - return "assets/new-ui/hardware_wallets/device_ledger_nano_x.svg"; - case HardwareWalletType.trezor: - return "assets/new-ui/hardware_wallets/device_trezor_safe_5.svg"; - case HardwareWalletType.cupcake: - return "assets/images/cupcake.svg"; - case HardwareWalletType.coldcard: - case HardwareWalletType.seedsigner: - case HardwareWalletType.keystone: - return "assets/images/hardware_wallet/device_qr.svg"; - } - } - - @override - Widget build(BuildContext context) { - return SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Observer( - builder: (_) { - if (dashboardViewModel.getMoneroError != null) { - return Padding( - padding: const EdgeInsets.fromLTRB(16, 0, 16, 16), - child: DashBoardRoundedCardWidget( - title: "Invalid monero bindings", - subTitle: dashboardViewModel.getMoneroError.toString(), - ), - ); - } - return Container(); - }, - ), - Observer( - builder: (_) { - if (dashboardViewModel.getWowneroError != null) { - return Padding( - padding: const EdgeInsets.fromLTRB(16, 0, 16, 16), - child: DashBoardRoundedCardWidget( - title: "Invalid wownero bindings", - subTitle: dashboardViewModel.getWowneroError.toString(), - ), - ); - } - return Container(); - }, - ), - Observer( - builder: (_) => dashboardViewModel.balanceViewModel.hasAccounts - ? HomeScreenAccountWidget( - walletName: dashboardViewModel.name, accountName: dashboardViewModel.subname) - : Column( - children: [ - SizedBox(height: 16), - Container( - margin: const EdgeInsets.only(left: 24, bottom: 16), - child: Observer( - builder: (_) { - return Row( - children: [ - Text( - dashboardViewModel.balanceViewModel.asset, - style: Theme.of(context).textTheme.headlineSmall?.copyWith( - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.onSurface, - height: 1, - ), - maxLines: 1, - textAlign: TextAlign.center, - ), - if (hardwareWalletIcon != null) - Container( - child: SvgPicture.asset( - hardwareWalletIcon!, - width: 24, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - if (dashboardViewModel - .balanceViewModel.isHomeScreenSettingsEnabled) - TextButton( - style: TextButton.styleFrom( - minimumSize: Size(50, 30), - tapTargetSize: MaterialTapTargetSize.shrinkWrap, - alignment: Alignment.centerLeft), - onPressed: () => Navigator.pushNamed( - context, - Routes.homeSettings, - arguments: dashboardViewModel.balanceViewModel, - ), - child: Container( - child: SvgPicture.asset( - 'assets/images/home_screen_setting_icon.svg', - color: Theme.of(context).colorScheme.onSurfaceVariant, - height: 30), - ), - ), - ], - ); - }, - ), - ), - ], - )), - Observer( - builder: (_) { - if (dashboardViewModel.balanceViewModel.isShowCard && FeatureFlag.isCakePayEnabled) { - return IntroducingCard( - title: S.of(context).introducing_cake_pay, - subTitle: S.of(context).cake_pay_learn_more, - borderColor: Theme.of(context).colorScheme.outline, - closeCard: dashboardViewModel.balanceViewModel.disableIntroCakePayCard); - } - return Container(); - }, - ), - Observer(builder: (_) { - if (!dashboardViewModel.showRepWarning) { - return const SizedBox(); - } - return Padding( - padding: const EdgeInsets.fromLTRB(16, 0, 16, 8), - child: DashBoardRoundedCardWidget( - title: S.of(context).rep_warning, - subTitle: S.of(context).rep_warning_sub, - onTap: () => Navigator.of(context).pushNamed(Routes.changeRep), - onClose: () { - dashboardViewModel.settingsStore.shouldShowRepWarning = false; - }, - ), - ); - }), - Observer( - builder: (_) { - if (dashboardViewModel.balanceViewModel.formattedBalances.isEmpty) { - return Center( - child: Container( - child: Text( - 'Loading balances...', - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant, - height: 1, - ), - textAlign: TextAlign.center, - ), - ), - ); - } - - return ListView.separated( - physics: NeverScrollableScrollPhysics(), - shrinkWrap: true, - separatorBuilder: (_, __) => Container(padding: EdgeInsets.only(bottom: 10)), - itemCount: dashboardViewModel.balanceViewModel.formattedBalances.length, - itemBuilder: (__, index) { - final balance = - dashboardViewModel.balanceViewModel.formattedBalances.elementAt(index); - return Observer(builder: (_) { - return BalanceRowWidget( - dashboardViewModel: dashboardViewModel, - availableBalanceLabel: - '${dashboardViewModel.balanceViewModel.availableBalanceLabel}', - availableBalance: balance.availableBalance, - availableFiatBalance: balance.fiatAvailableBalance, - additionalBalanceLabel: - '${dashboardViewModel.balanceViewModel.additionalBalanceLabel}', - additionalBalance: balance.additionalBalance, - additionalFiatBalance: balance.fiatAdditionalBalance, - frozenBalance: balance.frozenBalance, - frozenFiatBalance: balance.fiatFrozenBalance, - currency: balance.asset, - hasAdditionalBalance: - dashboardViewModel.balanceViewModel.hasAdditionalBalance(balance.asset), - hasSecondAdditionalBalance: - dashboardViewModel.balanceViewModel.hasSecondAdditionalBalance, - hasSecondAvailableBalance: - dashboardViewModel.balanceViewModel.hasSecondAvailableBalance, - secondAdditionalBalance: balance.secondAdditionalBalance, - secondAdditionalFiatBalance: balance.fiatSecondAdditionalBalance, - secondAvailableBalance: balance.secondAvailableBalance, - secondAvailableFiatBalance: balance.fiatSecondAvailableBalance, - secondAdditionalBalanceLabel: - '${dashboardViewModel.balanceViewModel.secondAdditionalBalanceLabel}', - secondAvailableBalanceLabel: - '${dashboardViewModel.balanceViewModel.secondAvailableBalanceLabel}', - isTestnet: dashboardViewModel.isTestnet, - ); - }); - }, - ); - }, - ), - Observer(builder: (context) { - return Column( - children: [ - if (dashboardViewModel.isMoneroWalletBrokenReasons.isNotEmpty) ...[ - SizedBox(height: 10), - Padding( - padding: const EdgeInsets.fromLTRB(16, 0, 16, 8), - child: DashBoardRoundedCardWidget( - customBorder: 30, - title: "This wallet has encountered an issue", - subTitle: "Here are the things that you should note:\n - " + - dashboardViewModel.isMoneroWalletBrokenReasons.join("\n - ") + - "\n\nPlease restart your wallet and if it doesn't help contact our support.", - )) - ], - if (dashboardViewModel.showSilentPaymentsCard) ...[ - SizedBox(height: 10), - Padding( - padding: const EdgeInsets.fromLTRB(16, 0, 16, 0), - child: DashBoardRoundedCardWidget( - shadowBlur: dashboardViewModel.getShadowBlur(), - shadowSpread: dashboardViewModel.getShadowSpread(), - marginV: 0, - marginH: 0, - customBorder: 30, - title: S.of(context).silent_payments, - subTitle: S.of(context).enable_silent_payments_scanning, - hint: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () => launchUrl( - Uri.parse( - "https://docs.cakewallet.com/cryptos/bitcoin#silent-payments"), - mode: LaunchMode.externalApplication, - ), - child: Row( - children: [ - Text( - S.of(context).what_is_silent_payments, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant, - height: 1, - ), - softWrap: true, - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 4), - child: Icon( - Icons.help_outline, - size: 16, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ) - ], - ), - ), - Observer( - builder: (_) => StandardSwitch( - value: dashboardViewModel.silentPaymentsScanningActive, - onTapped: () => _toggleSilentPaymentsScanning(context), - ), - ) - ], - ), - ], - ), - onTap: () => _toggleSilentPaymentsScanning(context), - image: !context.currentTheme.isDark - ? Image.asset(btcLockLight, height: 48) - : Image.asset(btcLockDark, height: 48), - ), - ), - ], - if (dashboardViewModel.showMwebCard) ...[ - SizedBox(height: 10), - Padding( - padding: const EdgeInsets.fromLTRB(16, 0, 16, 8), - child: InfoCard( - title: S.of(context).litecoin_mweb, - description: S.of(context).litecoin_mweb_description, - leftButtonTitle: S.of(context).litecoin_mweb_dismiss, - rightButtonTitle: S.of(context).enable, - image: 'assets/images/mweb_logo.png', - leftButtonAction: () => _dismissMweb(context), - rightButtonAction: () => _enableMweb(context), - hintWidget: GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () => launchUrl( - Uri.parse("https://docs.cakewallet.com/cryptos/litecoin/#mweb"), - mode: LaunchMode.externalApplication, - ), - child: Text( - S.of(context).learn_more, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant, - height: 1, - ), - softWrap: true, - ), - ), - ), - ), - ], - if (dashboardViewModel.showDecredInfoCard) ...[ - SizedBox(height: 10), - Padding( - padding: const EdgeInsets.fromLTRB(16, 0, 16, 8), - child: InfoCard( - title: S.of(context).synchronizing, - description: S.of(context).decred_info_card_details, - image: 'assets/new-ui/crypto_full_icons/decred.svg', - leftButtonTitle: S.of(context).litecoin_mweb_dismiss, - rightButtonTitle: S.of(context).learn_more, - leftButtonAction: () => dashboardViewModel.dismissDecredInfoCard(), - rightButtonAction: () => launchUrl( - Uri.parse("https://docs.cakewallet.com/cryptos/decred/#spv-sync")), - ), - ), - ], - if (dashboardViewModel.showPayjoinCard) ...[ - SizedBox(height: 10), - Padding( - padding: const EdgeInsets.fromLTRB(16, 0, 16, 8), - child: InfoCard( - title: "Payjoin", - description: S.of(context).payjoin_card_content, - hintWidget: GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () => launchUrl( - Uri.parse("https://docs.cakewallet.com/cryptos/bitcoin/#payjoin"), - mode: LaunchMode.externalApplication, - ), - child: Row( - children: [ - Text( - S.of(context).what_is_payjoin, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant, - height: 1, - ), - softWrap: true, - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 4), - child: Icon( - Icons.help_outline, - size: 16, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ) - ], - ), - ), - image: 'assets/images/payjoin.png', - leftButtonTitle: S.of(context).litecoin_mweb_dismiss, - rightButtonTitle: S.of(context).enable, - leftButtonAction: () => dashboardViewModel.dismissPayjoin(), - rightButtonAction: () => _enablePayjoin(context), - ), - ), - ], - ], - ); - }), - SizedBox(height: 130), - ], - ), - ); - } - - Future _toggleSilentPaymentsScanning(BuildContext context) async { - final isSilentPaymentsScanningActive = dashboardViewModel.silentPaymentsScanningActive; - final newValue = !isSilentPaymentsScanningActive; - - dashboardViewModel.silentPaymentsScanningActive = newValue; - - final needsToSwitch = !isSilentPaymentsScanningActive && - await bitcoin!.getNodeIsElectrsSPEnabled(dashboardViewModel.wallet) == false; - - if (needsToSwitch) { - return showPopUp( - context: context, - builder: (BuildContext context) => AlertWithTwoActions( - alertTitle: S.of(context).change_current_node_title, - alertContent: S.of(context).confirm_silent_payments_switch_node, - rightButtonText: S.of(context).confirm, - leftButtonText: S.of(context).cancel, - actionRightButton: () { - dashboardViewModel.setSilentPaymentsScanning(newValue); - Navigator.of(context).pop(); - }, - actionLeftButton: () { - dashboardViewModel.silentPaymentsScanningActive = isSilentPaymentsScanningActive; - Navigator.of(context).pop(); - }, - )); - } - - return dashboardViewModel.setSilentPaymentsScanning(newValue); - } - - void _enablePayjoin(BuildContext context) { - showPopUp( - context: context, - builder: (BuildContext context) => AlertWithOneAction( - alertTitle: S.of(context).payjoin_enabling_popup_title, - alertContent: S.of(context).payjoin_enabling_popup_content, - buttonText: S.of(context).ok, - buttonAction: () { - Navigator.of(context).pop(); - }, - )); - - dashboardViewModel.enablePayjoin(); - } - - Future _enableMweb(BuildContext context) async { - if (!dashboardViewModel.hasEnabledMwebBefore) { - await showPopUp( - context: context, - builder: (BuildContext context) => AlertWithOneAction( - alertTitle: S.of(context).alert_notice, - alertContent: S.of(context).litecoin_mweb_warning, - buttonText: S.of(context).understand, - buttonAction: () { - Navigator.of(context).pop(); - }, - )); - } - dashboardViewModel.setMwebEnabled(); - } - - Future _dismissMweb(BuildContext context) async { - await showPopUp( - context: context, - builder: (BuildContext context) => AlertWithOneAction( - alertTitle: S.of(context).alert_notice, - alertContent: S.of(context).litecoin_mweb_enable_later, - buttonText: S.of(context).understand, - buttonAction: () { - Navigator.of(context).pop(); - }, - )); - dashboardViewModel.dismissMweb(); - } -} diff --git a/lib/src/screens/dashboard/pages/cake_features_page.dart b/lib/src/screens/dashboard/pages/cake_features_page.dart index 08d5dbd57..7cff07a89 100644 --- a/lib/src/screens/dashboard/pages/cake_features_page.dart +++ b/lib/src/screens/dashboard/pages/cake_features_page.dart @@ -8,7 +8,6 @@ import 'package:cake_wallet/src/widgets/cake_image_widget.dart'; import 'package:cake_wallet/src/widgets/dashboard_card_widget.dart'; import 'package:cake_wallet/utils/feature_flag.dart'; import 'package:cake_wallet/utils/show_pop_up.dart'; -import 'package:cake_wallet/view_model/dashboard/cake_features_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; import 'package:cw_core/utils/print_verbose.dart'; import 'package:cw_core/wallet_type.dart'; @@ -18,10 +17,9 @@ import 'package:url_launcher/url_launcher.dart'; import 'package:cake_wallet/src/widgets/gradient_background.dart'; class CakeFeaturesPage extends StatelessWidget { - CakeFeaturesPage({required this.dashboardViewModel, required this.cakeFeaturesViewModel}); + CakeFeaturesPage({required this.dashboardViewModel}); final DashboardViewModel dashboardViewModel; - final CakeFeaturesViewModel cakeFeaturesViewModel; @override Widget build(BuildContext context) { @@ -38,7 +36,7 @@ class CakeFeaturesPage extends StatelessWidget { child: ConstrainedBox( constraints: BoxConstraints(minHeight: constraints.maxHeight), child: IntrinsicHeight( - child: !FeatureFlag.hasNewUi ? _buildOldUi(context) : _buildNewUi(context), + child: _buildNewUi(context), ), ), ); @@ -52,19 +50,6 @@ class CakeFeaturesPage extends StatelessWidget { } Widget _buildHeader(BuildContext context) { - if (!FeatureFlag.hasNewUi) { - return Padding( - padding: const EdgeInsets.only(left: 24, top: 16, bottom: 16), - child: Text( - S.of(context).apps, - style: Theme.of(context).textTheme.headlineLarge?.copyWith( - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - ); - } - return Align( alignment: Alignment.center, child: Padding( @@ -81,45 +66,6 @@ class CakeFeaturesPage extends StatelessWidget { ); } - Widget _buildOldUi(BuildContext context) { - return Column( - children: [ - const SizedBox(height: 2), - DashBoardRoundedCardWidget( - shadowBlur: dashboardViewModel.getShadowBlur(), - shadowSpread: dashboardViewModel.getShadowSpread(), - onTap: () => _onCakePayTap(context), - title: 'Cake Pay', - subTitle: S.of(context).cake_pay_subtitle, - image: Image.asset('assets/images/cakepay.png', height: 74, width: 70, fit: BoxFit.cover), - ), - Observer(builder: (_) { - if (dashboardViewModel.type == WalletType.ethereum) { - return DashBoardRoundedCardWidget( - shadowBlur: dashboardViewModel.getShadowBlur(), - shadowSpread: dashboardViewModel.getShadowSpread(), - onTap: () => Navigator.of(context).pushNamed(Routes.dEuroSavings), - title: S.of(context).deuro_savings, - subTitle: S.of(context).deuro_savings_subtitle, - image: Image.asset('assets/images/deuro_icon.png', - height: 80, width: 80, fit: BoxFit.cover), - ); - } - return const SizedBox(); - }), - DashBoardRoundedCardWidget( - shadowBlur: dashboardViewModel.getShadowBlur(), - shadowSpread: dashboardViewModel.getShadowSpread(), - onTap: () => _launchUrl("cake.nano-gpt.com"), - title: "NanoGPT", - subTitle: S.of(context).nanogpt_subtitle, - image: Image.asset('assets/images/nanogpt.png', height: 80, width: 80, fit: BoxFit.cover), - ), - const Spacer(), - const SizedBox(height: 125), - ], - ); - } Widget _buildNewUi(BuildContext context) { return Column( diff --git a/lib/src/screens/dashboard/pages/navigation_dock.dart b/lib/src/screens/dashboard/pages/navigation_dock.dart deleted file mode 100644 index a5e1e32b2..000000000 --- a/lib/src/screens/dashboard/pages/navigation_dock.dart +++ /dev/null @@ -1,83 +0,0 @@ -import 'dart:ui'; -import 'package:cake_wallet/entities/main_actions.dart'; -import 'package:cake_wallet/themes/core/theme_extension.dart'; -import 'package:flutter/material.dart'; -import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; -import 'package:cake_wallet/src/screens/dashboard/widgets/action_button.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; - -class NavigationDock extends StatelessWidget { - const NavigationDock({ - required this.dashboardViewModel, - }); - - final DashboardViewModel dashboardViewModel; - - @override - Widget build(BuildContext context) { - return Positioned( - child: Observer( - builder: (_) { - return Container( - height: 84, - alignment: Alignment.bottomCenter, - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(50), - ), - margin: const EdgeInsets.only(left: 8, right: 8, bottom: 16), - child: ClipRRect( - borderRadius: BorderRadius.circular(50), - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 50, sigmaY: 50), - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(50.0), - color: Theme.of(context).colorScheme.surfaceContainer, - ), - padding: const EdgeInsets.symmetric(horizontal: 8), - child: ClipRect( - child: Row( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: MainActions.all - .where((element) => element.canShow?.call(dashboardViewModel) ?? true) - .map( - (action) => Expanded( - child: Semantics( - button: true, - enabled: (action.isEnabled?.call(dashboardViewModel) ?? true), - child: ActionButton( - key: action.key, - image: Image.asset( - action.image, - height: 24, - width: 24, - color: Theme.of(context).colorScheme.primary, - ), - title: action.name(context), - onClick: (action.isEnabled?.call(dashboardViewModel) ?? true) - ? () async => - await action.onTap(context, dashboardViewModel) - : null, - textColor: action.isEnabled?.call(dashboardViewModel) ?? true - ? null - : Theme.of(context).colorScheme.onSurface, - ), - ), - ), - ) - .toList(), - ), - ), - ), - ), - ), - ), - ); - }, - ), - ); - } -} diff --git a/lib/src/screens/dashboard/pages/transactions_page.dart b/lib/src/screens/dashboard/pages/transactions_page.dart deleted file mode 100644 index c699fb0f9..000000000 --- a/lib/src/screens/dashboard/pages/transactions_page.dart +++ /dev/null @@ -1,250 +0,0 @@ -import 'package:cake_wallet/bitcoin/bitcoin.dart'; -import 'package:cake_wallet/core/csv_export_service.dart'; -import 'package:cake_wallet/di.dart'; -import 'package:cake_wallet/entities/balance_display_mode.dart'; -import 'package:cake_wallet/order/order_source_description.dart'; -import 'package:cake_wallet/src/screens/dashboard/widgets/anonpay_transaction_row.dart'; -import 'package:cake_wallet/src/screens/dashboard/widgets/order_row.dart'; -import 'package:cake_wallet/src/screens/dashboard/widgets/payjoin_transaction_row.dart'; -import 'package:cake_wallet/src/screens/dashboard/widgets/trade_row.dart'; -import 'package:cake_wallet/src/widgets/dashboard_card_widget.dart'; -import 'package:cake_wallet/utils/responsive_layout_util.dart'; -import 'package:cake_wallet/view_model/dashboard/anonpay_transaction_list_item.dart'; -import 'package:cake_wallet/view_model/dashboard/order_list_item.dart'; -import 'package:cake_wallet/view_model/dashboard/payjoin_transaction_list_item.dart'; -import 'package:cake_wallet/view_model/dashboard/trade_list_item.dart'; -import 'package:cw_core/crypto_currency.dart'; -import 'package:cw_core/sync_status.dart'; -import 'package:cw_core/wallet_type.dart'; -import 'package:flutter/material.dart'; -import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:cake_wallet/src/screens/dashboard/widgets/header_row.dart'; -import 'package:cake_wallet/src/screens/dashboard/widgets/date_section_raw.dart'; -import 'package:cake_wallet/src/screens/dashboard/widgets/transaction_raw.dart'; -import 'package:cake_wallet/view_model/dashboard/transaction_list_item.dart'; -import 'package:cake_wallet/view_model/dashboard/date_section_item.dart'; -import 'package:intl/intl.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:url_launcher/url_launcher.dart'; - -class TransactionsPage extends StatelessWidget { - TransactionsPage({required this.dashboardViewModel}); - - final DashboardViewModel dashboardViewModel; - - @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.shouldRenderMobileUI - ? null - : Theme.of(context).colorScheme.surface, - child: Column( - children: [ - Observer(builder: (_) { - final status = dashboardViewModel.status; - if (status is SyncingSyncStatus) { - return DashBoardRoundedCardWidget( - key: ValueKey('transactions_page_syncing_alert_card_key'), - onTap: () { - try { - final uri = Uri.parse("https://docs.cakewallet.com/faq/funds-not-appearing"); - launchUrl(uri, mode: LaunchMode.externalApplication); - } catch (_) {} - }, - title: S.of(context).syncing_wallet_alert_title, - subTitle: S.of(context).syncing_wallet_alert_content, - ); - } else { - return Container(); - } - }), - HeaderRow( - dashboardViewModel: dashboardViewModel, - onExportCsv: () => - getIt.get().exportToCsv(dashboardViewModel.items, context), - key: ValueKey('transactions_page_header_row_key'), - ), - Expanded( - child: Observer( - builder: (_) { - final items = dashboardViewModel.items; - return items.isNotEmpty - ? ListView.builder( - key: ValueKey('transactions_page_list_view_builder_key'), - itemCount: items.length + 1, - itemBuilder: (context, index) { - if (index == items.length) return SizedBox(height: 150); - - final item = items[index]; - - if (item is DateSectionItem) { - return DateSectionRaw(date: item.date, key: item.key); - } - - if (item is TransactionListItem) { - if (item.hasTokens && item.assetOfTransaction == null) { - return Container(); - } - - final transaction = item.transaction; - final transactionType = - dashboardViewModel.getTransactionType(transaction); - - List tags = []; - if (dashboardViewModel.type == WalletType.bitcoin) { - if (bitcoin!.txIsReceivedSilentPayment(transaction)) { - tags.add(S.of(context).silent_payment); - } - } - if (dashboardViewModel.type == WalletType.litecoin) { - if (bitcoin!.txIsMweb(transaction)) { - tags.add("MWEB"); - } - } - return Observer( - builder: (_) => TransactionRow( - key: item.key, - onTap: () => Navigator.of(context) - .pushNamed(Routes.transactionDetails, arguments: transaction), - isShield: transaction.additionalInfo['isAutoShield'] == true, - direction: transaction.direction, - formattedDate: DateFormat('HH:mm').format(transaction.date), - formattedAmount: item.formattedCryptoAmount, - formattedFiatAmount: - dashboardViewModel.balanceViewModel.isFiatDisabled - ? '' - : item.formattedFiatAmount, - title: - item.formattedTitle + item.formattedStatus + transactionType, - tags: tags, - ), - ); - } - - if (item is AnonpayTransactionListItem) { - final transactionInfo = item.transaction; - - return AnonpayTransactionRow( - key: item.key, - 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 PayjoinTransactionListItem) { - final session = item.session; - - return PayjoinTransactionRow( - key: item.key, - onTap: () => Navigator.of(context).pushNamed( - Routes.payjoinDetails, - arguments: [item.sessionId, item.transaction], - ), - currency: "BTC", - state: item.status, - amount: dashboardViewModel.appStore.amountParsingProxy - .getDisplayCryptoString( - session.amount.toInt(), CryptoCurrency.btc), - createdAt: DateFormat('HH:mm').format(session.inProgressSince!), - isSending: session.isSenderSession, - ); - } - - if (item is TradeListItem) { - final trade = item.trade; - - final tradeFrom = trade.from; - - final tradeTo = trade.to; - - return tradeFrom != null && tradeTo != null - ? Observer( - builder: (_) => TradeRow( - key: item.key, - onTap: () => Navigator.of(context) - .pushNamed(Routes.tradeDetails, arguments: trade), - swapState: trade.state, - provider: trade.provider, - title: "$tradeFrom → $tradeTo", - fromSymbol: dashboardViewModel.appStore.amountParsingProxy - .getCryptoSymbol(tradeFrom), - toSymbol: dashboardViewModel.appStore.amountParsingProxy - .getCryptoSymbol(tradeTo), - createdAtFormattedDate: trade.createdAt != null - ? DateFormat("HH:mm").format(trade.createdAt!) - : null, - formattedAmount: item.tradeFormattedAmount, - formattedReceiveAmount: item.tradeFormattedReceiveAmount, - ), - ) - : Container(); - } - if (item is OrderListItem) { - final order = item.order; - return Observer( - builder: (_) { - // TODO: Refactor Amount Hiding Logic it is not working properly for Orders and Trades - final hide = dashboardViewModel.balanceViewModel.displayMode == - BalanceDisplayMode.hiddenBalance; - - final formattedAmount = hide ? '---' : order.amountFormatted(); - final formattedReceiveAmount = hide ? '---' : order.receiveAmount; - - return OrderRow( - key: item.key, - onTap: () => Navigator.of(context) - .pushNamed(Routes.orderDetails, arguments: order), - providerTitle: order.providerTitle, - providerIconPath: order.providerIcon, - from: order.from ?? '', - to: order.to ?? '', - createdAtFormattedDate: - DateFormat('HH:mm').format(order.createdAt), - formattedAmount: formattedAmount, - formattedReceiveAmount: - dashboardViewModel.balanceViewModel.isFiatDisabled && - order.source == OrderSourceDescription.order - ? '' - : formattedReceiveAmount, - ); - }, - ); - } - return Container(color: Colors.transparent, height: 1); - }, - ) - : Center( - child: Text( - key: ValueKey('transactions_page_placeholder_transactions_text_key'), - S.of(context).placeholder_transactions, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - ); - }, - ), - ), - ], - ), - ), - ); - } -} diff --git a/lib/src/screens/dashboard/widgets/action_button.dart b/lib/src/screens/dashboard/widgets/action_button.dart deleted file mode 100644 index f2a3d5b09..000000000 --- a/lib/src/screens/dashboard/widgets/action_button.dart +++ /dev/null @@ -1,66 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -class ActionButton extends StatelessWidget { - ActionButton({ - required this.image, - required this.title, - this.route, - this.onClick, - this.alignment = Alignment.center, - this.textColor, - super.key, - }); - - final Image image; - final String title; - final String? route; - final Alignment alignment; - final VoidCallback? onClick; - final Color? textColor; - - @override - Widget build(BuildContext context) { - return TextButton( - style: TextButton.styleFrom( - padding: EdgeInsets.zero, - minimumSize: Size.zero, - tapTargetSize: MaterialTapTargetSize.shrinkWrap, - ), - onPressed: () { - if (route?.isNotEmpty ?? false) { - Navigator.of(context, rootNavigator: true).pushNamed(route!); - } else { - onClick?.call(); - } - }, - child: SizedBox.expand( - child: Container( - color: Colors.transparent, - alignment: alignment, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - image, - const SizedBox(height: 4), - Flexible( - child: Text( - title, - maxLines: 1, - overflow: TextOverflow.fade, - softWrap: false, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.labelSmall?.copyWith( - color: textColor ?? Theme.of(context).colorScheme.onSurface, - ), - ), - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/src/screens/dashboard/widgets/home_screen_account_widget.dart b/lib/src/screens/dashboard/widgets/home_screen_account_widget.dart deleted file mode 100644 index 55572d568..000000000 --- a/lib/src/screens/dashboard/widgets/home_screen_account_widget.dart +++ /dev/null @@ -1,68 +0,0 @@ -import 'package:cake_wallet/di.dart'; -import 'package:cake_wallet/src/screens/monero_accounts/monero_account_list_page.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; -import 'package:flutter/material.dart'; - -class HomeScreenAccountWidget extends StatelessWidget { - HomeScreenAccountWidget({this.walletName, this.accountName}); - - final String? walletName; - final String? accountName; - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: () async { - await showPopUp(context: context, builder: (_) => getIt.get()); - }, - behavior: HitTestBehavior.opaque, - child: Padding( - padding: EdgeInsets.all(25.0), - child: Row( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - child: Text( - walletName ?? '', - style: Theme.of(context).textTheme.headlineSmall?.copyWith( - fontWeight: FontWeight.bold, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - ), - SizedBox( - height: 5.0, - ), - Row( - children: [ - Padding(padding: EdgeInsets.only(left: 20)), - Container( - child: Text( - accountName ?? '', - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontWeight: FontWeight.bold, - color: Theme.of(context).colorScheme.primary, - ), - ), - ), - Container( - child: Icon( - Icons.keyboard_arrow_down, - color: Theme.of(context).colorScheme.primary, - ), - ), - ], - ), - ], - ), - ], - ), - ), - ); - } -} diff --git a/lib/src/screens/dashboard/widgets/info_card.dart b/lib/src/screens/dashboard/widgets/info_card.dart deleted file mode 100644 index 42552aa09..000000000 --- a/lib/src/screens/dashboard/widgets/info_card.dart +++ /dev/null @@ -1,97 +0,0 @@ -import 'package:cake_wallet/src/widgets/cake_image_widget.dart'; -import 'package:cake_wallet/src/widgets/dashboard_card_widget.dart'; -import 'package:flutter/material.dart'; - -class InfoCard extends StatelessWidget { - final String leftButtonTitle; - final String rightButtonTitle; - final String title; - final String description; - final String image; - final Function() leftButtonAction; - final Function() rightButtonAction; - - final Widget? hintWidget; - - const InfoCard({ - super.key, - required this.title, - required this.description, - required this.leftButtonTitle, - required this.rightButtonTitle, - required this.leftButtonAction, - required this.rightButtonAction, - required this.image, - this.hintWidget, - }); - - @override - Widget build(BuildContext context) { - return DashBoardRoundedCardWidget( - marginH: 0, - marginV: 0, - customBorder: 30, - title: title, - subTitle: description, - hint: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (hintWidget != null) hintWidget!, - if (hintWidget != null) SizedBox(height: 8), - Row( - children: [ - Expanded( - child: ElevatedButton( - onPressed: leftButtonAction, - style: ElevatedButton.styleFrom( - backgroundColor: Theme.of(context).colorScheme.surface, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - ), - child: Text( - leftButtonTitle, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - color: Theme.of(context).colorScheme.onSecondaryContainer, - ), - ), - ), - ), - const SizedBox(width: 8), - Expanded( - child: ElevatedButton( - onPressed: rightButtonAction, - style: ElevatedButton.styleFrom( - backgroundColor: Theme.of(context).colorScheme.primary, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - ), - child: Text( - rightButtonTitle, - maxLines: 1, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - color: Theme.of(context).colorScheme.onPrimary, - ), - ), - ), - ), - ], - ), - ], - ), - onTap: () => {}, - icon: Container( - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.surfaceContainer, - shape: BoxShape.circle, - ), - child: CakeImageWidget( - imageUrl: image, - height: 40, - width: 40, - ), - ), - ); - } -} diff --git a/lib/src/screens/dashboard/widgets/page_indicator.dart b/lib/src/screens/dashboard/widgets/page_indicator.dart deleted file mode 100644 index 05b03a1be..000000000 --- a/lib/src/screens/dashboard/widgets/page_indicator.dart +++ /dev/null @@ -1,302 +0,0 @@ -import 'dart:math' as math; -import 'dart:ui'; -import 'package:cake_wallet/entities/page_indicator_actions.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; - -class PageIndicator extends StatefulWidget { - const PageIndicator({ - super.key, - required this.controller, - required this.dashboardViewModel, - }); - - final PageController controller; - final DashboardViewModel dashboardViewModel; - - @override - State createState() => _PageIndicatorState(); -} - -class _PageIndicatorState extends State { - static const barHeight = 37.0; - static const iconWidth = 16.0; - static const iconHeight = 16.0; - static const iconSpacing = 5.0; - static const barHorizontalPadding = 4.0; - static const pillHorizontalPadding = 8.0; - static const edgePadding = 5.0; - static const barBorderRadius = 50.0; - static const pillBorderRadius = 50.0; - static const pageSwitchDuration = Duration(milliseconds: 300); - static const pillMoveDuration = Duration(milliseconds: 300); - static const pillResizeDuration = Duration(milliseconds: 200); - static const textStyle = TextStyle( - fontSize: 12, - fontWeight: FontWeight.w400, - ); - - late int selectedIndex; - late final VoidCallback _pageListener; - - @override - void initState() { - super.initState(); - - selectedIndex = widget.controller.initialPage; - - _pageListener = () { - final page = widget.controller.page; - if (page == null) return; - - final rounded = page.round(); - if (rounded != selectedIndex && mounted) { - setState(() { - selectedIndex = rounded; - }); - } - }; - - widget.controller.addListener(_pageListener); - } - - @override - void dispose() { - widget.controller.removeListener(_pageListener); - super.dispose(); - } - - void _onItemTap(int index) { - if (index == selectedIndex) return; - widget.controller.animateToPage( - index, - duration: pageSwitchDuration, - curve: Curves.easeOutCubic, - ); - } - - double _estimateItemWidthForAction(BuildContext context, PageIndicatorActions action, - {Color? color}) { - final text = action.name(context); - final textPainter = TextPainter( - text: TextSpan(text: text, style: textStyle.copyWith(color: color)), - maxLines: 1, - textDirection: Directionality.of(context), - textScaler: MediaQuery.of(context).textScaler, - )..layout(); - return iconWidth + iconSpacing + textPainter.width + pillHorizontalPadding * 2; - } - - @override - Widget build(BuildContext context) { - final visibleActions = PageIndicatorActions.all.where((action) { - return action.isEnabled?.call(widget.dashboardViewModel) ?? true; - }).toList(); - - // Don't show indicator if less than 2 actions - if (visibleActions.length < 2) return const SizedBox.shrink(); - - selectedIndex = selectedIndex.clamp(0, visibleActions.length - 1); - - // Theme setup - final theme = Theme.of(context); - final backgroundColor = theme.colorScheme.surfaceContainer.withAlpha(122); - final pillColor = theme.colorScheme.onSurface.withAlpha(30); - final activeColor = theme.colorScheme.onSurface; - final inactiveColor = theme.colorScheme.primary; - - // Size calculations - final screenWidth = MediaQuery.of(context).size.width; - final isRTL = Directionality.of(context) == TextDirection.rtl; - - final pillWidth = _estimateItemWidthForAction( - context, - visibleActions[selectedIndex], - color: activeColor, - ); - - final actionWidths = [ - for (final action in visibleActions) - _estimateItemWidthForAction(context, action, color: inactiveColor) - ]; - - final totalItemsWidth = - actionWidths.fold(0.0, (sum, width) => sum + width) + barHorizontalPadding * 2; - - final barWidth = math.min(totalItemsWidth, screenWidth * 0.95); - - final count = visibleActions.length; - final firstLeft = edgePadding; - final secondLeft = barWidth - (isRTL ? actionWidths.first : actionWidths[1]) - edgePadding; - - final List positions; - - if (count == 2) { - positions = [firstLeft, secondLeft]; - } else { - final lastLeft = barWidth - (isRTL ? actionWidths.first : actionWidths.last) - edgePadding; - - final centerLeft = - (isRTL ? actionWidths.last + edgePadding : actionWidths.first + edgePadding); - - positions = [firstLeft, centerLeft, lastLeft]; - } - - final left = (isRTL ? positions.reversed.toList() : positions)[selectedIndex]; - final currentAction = visibleActions[selectedIndex]; - - return Align( - alignment: Alignment.bottomCenter, - child: Padding( - padding: EdgeInsets.only(top: 10), - child: Container( - width: barWidth, - child: ClipRRect( - borderRadius: BorderRadius.circular(barBorderRadius), - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 30, sigmaY: 30), - child: Container( - height: barHeight, - decoration: BoxDecoration( - color: backgroundColor, - borderRadius: BorderRadius.circular(barBorderRadius), - ), - child: Stack( - alignment: Alignment.center, - children: [ - AnimatedPill( - left: left, - pillColor: pillColor, - currentAction: currentAction, - pillIconHeight: iconHeight, - pillIconWidth: iconWidth, - pillIconSpacing: iconSpacing, - pillBorderRadius: pillBorderRadius, - contentColor: activeColor, - estimateWidthForAction: pillWidth, - pillTextStyle: textStyle, - pillMoveDuration: pillMoveDuration, - pillResizeDuration: pillResizeDuration, - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: barHorizontalPadding), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - for (int i = 0; i < visibleActions.length; i++) - Semantics( - button: true, - label: visibleActions[i].name(context), - value: i == selectedIndex ? 'Selected' : null, - hint: 'Double tap to open ${visibleActions[i].name(context)} page', - onTap: () => _onItemTap(i), - child: GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () => _onItemTap(i), - child: Container( - height: barHeight, - width: i == selectedIndex - ? pillWidth - : _estimateItemWidthForAction(context, visibleActions[i]), - alignment: Alignment.center, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - TweenAnimationBuilder( - duration: const Duration(milliseconds: 300), - curve: Curves.easeOutCubic, - tween: ColorTween( - begin: inactiveColor, - end: i == selectedIndex ? activeColor : inactiveColor, - ), - builder: (context, color, _) => SvgPicture.asset( - visibleActions[i].image, - width: iconWidth, - height: iconHeight, - colorFilter: ColorFilter.mode(color!, BlendMode.srcIn), - ), - ), - SizedBox(width: iconSpacing), - TweenAnimationBuilder( - duration: const Duration(milliseconds: 300), - curve: Curves.easeOutCubic, - tween: ColorTween( - begin: inactiveColor, - end: i == selectedIndex ? activeColor : inactiveColor, - ), - builder: (context, color, _) => Text( - visibleActions[i].name(context), - style: textStyle.copyWith(color: color), - overflow: TextOverflow.fade, - softWrap: false, - ), - ), - ], - ), - ), - ), - ), - ], - ), - ) - ], - )), - ), - ), - ), - ), - ); - } -} - -class AnimatedPill extends StatelessWidget { - const AnimatedPill({ - super.key, - required this.left, - required this.pillColor, - required this.contentColor, - required this.pillIconHeight, - required this.pillIconWidth, - required this.pillBorderRadius, - required this.currentAction, - required this.estimateWidthForAction, - required this.pillIconSpacing, - required this.pillTextStyle, - required this.pillMoveDuration, - required this.pillResizeDuration, - }); - - final double left; - final Color pillColor; - final Color contentColor; - final double pillIconHeight; - final double pillIconWidth; - final double pillBorderRadius; - final PageIndicatorActions currentAction; - final double estimateWidthForAction; - final double pillIconSpacing; - final TextStyle pillTextStyle; - final Duration pillMoveDuration; - final Duration pillResizeDuration; - - @override - Widget build(BuildContext context) { - return AnimatedPositioned( - duration: pillMoveDuration, - curve: Curves.easeOutCubic, - left: left, - top: 4, - bottom: 4, - child: AnimatedContainer( - duration: pillResizeDuration, - curve: Curves.easeOutCubic, - width: estimateWidthForAction, - decoration: - BoxDecoration(color: pillColor, borderRadius: BorderRadius.circular(pillBorderRadius)), - clipBehavior: Clip.hardEdge, - alignment: Alignment.center, - ), - ); - } -} diff --git a/lib/src/screens/dashboard/widgets/present_receive_option_picker.dart b/lib/src/screens/dashboard/widgets/present_receive_option_picker.dart deleted file mode 100644 index 8d4ea99cd..000000000 --- a/lib/src/screens/dashboard/widgets/present_receive_option_picker.dart +++ /dev/null @@ -1,163 +0,0 @@ -import 'package:cake_wallet/src/widgets/alert_close_button.dart'; -import 'package:cake_wallet/src/widgets/rounded_checkbox.dart'; -import 'package:cake_wallet/src/widgets/alert_background.dart'; -import 'package:cake_wallet/typography.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; -import 'package:cake_wallet/view_model/dashboard/receive_option_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:cake_wallet/generated/i18n.dart'; - -class PresentReceiveOptionPicker extends StatelessWidget { - PresentReceiveOptionPicker({required this.receiveOptionViewModel, required this.color}); - - final ReceiveOptionViewModel receiveOptionViewModel; - final Color color; - - @override - Widget build(BuildContext context) { - final arrowBottom = Image.asset( - 'assets/images/arrow_bottom_purple_icon.png', - color: Theme.of(context).colorScheme.primary, - height: 6, - ); - - return Padding( - padding: EdgeInsets.only(left: 6), - child: TextButton( - onPressed: () => _showPicker(context), - style: ButtonStyle( - padding: WidgetStateProperty.all(EdgeInsets.zero), - splashFactory: NoSplash.splashFactory, - foregroundColor: WidgetStateProperty.all(Colors.transparent), - overlayColor: WidgetStateProperty.all(Colors.transparent), - ), - child: Row( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - Text( - S.current.receive, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 17.0, - fontWeight: FontWeight.bold, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - Row( - children: [ - Observer( - builder: (_) => Text( - receiveOptionViewModel.selectedReceiveOption - .toString() - .replaceAll(RegExp(r'silent payments', caseSensitive: false), - S.current.silent_payments) - .replaceAll(RegExp(r'default', caseSensitive: false), - S.current.string_default), - style: Theme.of(context).textTheme.bodySmall!.copyWith( - fontSize: 10.0, - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - ), - ], - ), - ], - ), - SizedBox(width: 5), - Padding( - padding: EdgeInsets.only(top: 12), - child: arrowBottom, - ) - ], - ), - )); - } - - void _showPicker(BuildContext context) async { - await showPopUp( - builder: (BuildContext popUpContext) => Scaffold( - resizeToAvoidBottomInset: false, - backgroundColor: Colors.transparent, - body: Stack( - alignment: AlignmentDirectional.center, - children: [ - AlertBackground( - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Spacer(), - Container( - margin: EdgeInsets.symmetric(horizontal: 24), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(30), - color: Theme.of(context).colorScheme.surface, - ), - child: Padding( - padding: const EdgeInsets.only(top: 24, bottom: 24), - child: (ListView.separated( - padding: EdgeInsets.zero, - shrinkWrap: true, - itemCount: receiveOptionViewModel.options.length, - itemBuilder: (_, index) { - final option = receiveOptionViewModel.options[index]; - return InkWell( - onTap: () { - Navigator.pop(popUpContext); - - receiveOptionViewModel.selectReceiveOption(option); - }, - child: Padding( - padding: const EdgeInsets.only(left: 24, right: 24), - child: Observer(builder: (_) { - final value = receiveOptionViewModel.selectedReceiveOption; - - return Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - option - .toString() - .replaceAll( - RegExp(r'silent payments', caseSensitive: false), - S.current.silent_payments) - .replaceAll(RegExp(r'default', caseSensitive: false), - S.current.string_default), - textAlign: TextAlign.left, - style: textSmall( - color: Theme.of(context).colorScheme.onSurface, - ).copyWith( - fontWeight: - value == option ? FontWeight.w800 : FontWeight.w500, - )), - RoundedCheckbox( - value: value == option, - ) - ], - ); - }), - ), - ); - }, - separatorBuilder: (_, index) => SizedBox(height: 30), - )), - ), - ), - Spacer() - ], - ), - ), - AlertCloseButton(onTap: () => Navigator.of(popUpContext).pop(), bottom: 40) - ], - ), - ), - context: context, - ); - } -} diff --git a/lib/src/screens/dashboard/widgets/sync_indicator.dart b/lib/src/screens/dashboard/widgets/sync_indicator.dart deleted file mode 100644 index 3c6dd6ade..000000000 --- a/lib/src/screens/dashboard/widgets/sync_indicator.dart +++ /dev/null @@ -1,87 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; -import 'package:cake_wallet/core/sync_status_title.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:cw_core/sync_status.dart'; -import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator_icon.dart'; - -class SyncIndicator extends StatelessWidget { - SyncIndicator({ - required this.dashboardViewModel, - required this.onTap, - super.key, - }); - - final DashboardViewModel dashboardViewModel; - final Function() onTap; - - @override - Widget build(BuildContext context) { - return Observer(builder: (_) { - final syncIndicatorWidth = 237.0; - final status = dashboardViewModel.status; - final statusText = - syncStatusTitle(status, dashboardViewModel.settingsStore.syncStatusDisplayMode); - final progress = status.progress(); - final indicatorOffset = progress * syncIndicatorWidth; - final indicatorWidth = progress < 1 - ? indicatorOffset > 0 - ? indicatorOffset - : 0.0 - : syncIndicatorWidth; - - return ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(15)), - child: GestureDetector( - onTap: onTap, - onLongPress: dashboardViewModel.toggleSwitchStatusDisplayMode, - child: Container( - height: 30, - width: syncIndicatorWidth, - color: Theme.of(context).colorScheme.surfaceContainerLow, - child: Stack( - alignment: Alignment.center, - children: [ - progress <= 1 - ? Positioned( - left: 0, - top: 0, - bottom: 0, - child: Container( - width: indicatorWidth, - height: 30, - color: Theme.of(context).colorScheme.surfaceContainer, - )) - : Offstage(), - Padding( - padding: EdgeInsets.only(left: 24, right: 24), - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SyncIndicatorIcon( - isSynced: status is SyncedSyncStatus, - showTorIcon: dashboardViewModel.builtinTor, - size: dashboardViewModel.builtinTor ? 16 : 6, - ), - Padding( - padding: EdgeInsets.only(left: 6), - child: Text( - statusText, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - ) - ], - ), - ) - ], - ), - ), - )); - }); - } -} diff --git a/lib/src/screens/exchange/exchange_page.dart b/lib/src/screens/exchange/exchange_page.dart deleted file mode 100644 index 713d316d7..000000000 --- a/lib/src/screens/exchange/exchange_page.dart +++ /dev/null @@ -1,803 +0,0 @@ -import 'package:cake_wallet/core/address_resolver/address_resolver_service.dart'; -import 'package:cake_wallet/exchange/exchange_provider_description.dart'; -import 'package:cake_wallet/exchange/provider/chainflip_exchange_provider.dart'; -import 'package:cake_wallet/exchange/provider/thorchain_exchange.provider.dart'; -import 'package:cake_wallet/core/auth_service.dart'; -import 'package:cake_wallet/di.dart'; -import 'package:cake_wallet/src/screens/exchange/widgets/desktop_exchange_cards_section.dart'; -import 'package:cake_wallet/src/screens/exchange/widgets/mobile_exchange_cards_section.dart'; -import 'package:cake_wallet/src/widgets/add_template_button.dart'; -import 'package:cake_wallet/utils/debounce.dart'; -import 'package:cake_wallet/utils/payment_request.dart'; -import 'package:cake_wallet/utils/responsive_layout_util.dart'; -import 'package:cw_core/sync_status.dart'; -import 'package:cw_core/utils/print_verbose.dart'; -import 'package:cake_wallet/src/widgets/standard_checkbox.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:keyboard_actions/keyboard_actions.dart'; -import 'package:mobx/mobx.dart'; -import 'package:cake_wallet/exchange/exchange_template.dart'; -import 'package:cake_wallet/exchange/exchange_trade_state.dart'; -import 'package:cake_wallet/exchange/limits_state.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; -import 'package:cake_wallet/src/widgets/keyboard_done_button.dart'; -import 'package:cake_wallet/src/widgets/template_tile.dart'; -import 'package:cake_wallet/src/widgets/trail_button.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cw_core/crypto_currency.dart'; -import 'package:cake_wallet/src/screens/exchange/widgets/exchange_card.dart'; -import 'package:cake_wallet/src/widgets/primary_button.dart'; -import 'package:cake_wallet/src/widgets/scrollable_with_bottom_section.dart'; -import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; -import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart'; -import 'package:cake_wallet/core/address_validator.dart'; -import 'package:cake_wallet/core/amount_validator.dart'; -import 'package:cake_wallet/src/screens/exchange/widgets/present_provider_picker.dart'; -import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator_icon.dart'; - -class ExchangePage extends BasePage { - ExchangePage( - this.exchangeViewModel, this.authService, this.adrResService, this.initialPaymentRequest) { - depositWalletName = exchangeViewModel.depositCurrency == CryptoCurrency.xmr - ? exchangeViewModel.wallet.name - : null; - receiveWalletName = exchangeViewModel.receiveCurrency == CryptoCurrency.xmr - ? exchangeViewModel.wallet.name - : null; - } - - final ExchangeViewModel exchangeViewModel; - final AuthService authService; - final AddressResolverService adrResService; - final PaymentRequest? initialPaymentRequest; - final depositKey = GlobalKey(); - final receiveKey = GlobalKey(); - final _formKey = GlobalKey(); - final _depositAmountFocus = FocusNode(); - final _depositAddressFocus = FocusNode(); - final _receiveAmountFocus = FocusNode(); - final _receiveAddressFocus = FocusNode(); - final _receiveAmountDebounce = Debounce(Duration(milliseconds: 500)); - Debounce _depositAmountDebounce = Debounce(Duration(milliseconds: 500)); - var _isReactionsSet = false; - - late final String? depositWalletName; - late final String? receiveWalletName; - - @override - String get title => S.current.exchange; - - @override - bool get gradientBackground => true; - - @override - bool get gradientAll => true; - - @override - bool get resizeToAvoidBottomInset => false; - - @override - bool get extendBodyBehindAppBar => true; - - @override - AppBarStyle get appBarStyle => AppBarStyle.transparent; - - @override - Function(BuildContext)? get pushToNextWidget => (context) { - FocusScopeNode currentFocus = FocusScope.of(context); - if (!currentFocus.hasPrimaryFocus) { - currentFocus.focusedChild?.unfocus(); - } - }; - - bool get _shouldWaitTillSynced => - [CryptoCurrency.xmr, CryptoCurrency.btc, CryptoCurrency.ltc] - .contains(exchangeViewModel.depositCurrency) && - !(exchangeViewModel.status is SyncedSyncStatus); - - @override - Widget middle(BuildContext context) => Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.only(right: 6.0), - child: Observer( - builder: (_) => - SyncIndicatorIcon(isSynced: exchangeViewModel.status is SyncedSyncStatus), - ), - ), - PresentProviderPicker(exchangeViewModel: exchangeViewModel) - ], - ); - - @override - Widget trailing(BuildContext context) => TrailButton( - caption: S.of(context).reset, - onPressed: () { - _formKey.currentState?.reset(); - exchangeViewModel.reset(); - }, - ); - - @override - Widget? leading(BuildContext context) { - final _backButton = Icon( - Icons.arrow_back_ios, - color: Theme.of(context).colorScheme.primary, - size: 16, - ); - final _closeButton = currentTheme.isDark ? closeButtonImageDarkTheme : closeButtonImage; - - bool isMobileView = responsiveLayoutUtil.shouldRenderMobileUI; - - return MergeSemantics( - child: SizedBox( - height: isMobileView ? 37 : 45, - width: isMobileView ? 37 : 45, - child: ButtonTheme( - minWidth: double.minPositive, - child: Semantics( - label: !isMobileView ? S.of(context).close : S.of(context).seed_alert_back, - child: TextButton( - style: ButtonStyle( - overlayColor: WidgetStateColor.resolveWith((states) => Colors.transparent), - ), - onPressed: () => onClose(context), - child: !isMobileView ? _closeButton : _backButton, - ), - ), - ), - ), - ); - } - - @override - Widget body(BuildContext context) { - WidgetsBinding.instance.addPostFrameCallback((_) => _setReactions(context, exchangeViewModel)); - - return KeyboardActions( - disableScroll: true, - config: KeyboardActionsConfig( - keyboardActionsPlatform: KeyboardActionsPlatform.IOS, - keyboardBarColor: Theme.of(context).colorScheme.surfaceContainerHighest, - nextFocus: false, - actions: [ - KeyboardActionsItem( - focusNode: _depositAmountFocus, toolbarButtons: [(_) => KeyboardDoneButton()]), - KeyboardActionsItem( - focusNode: _receiveAmountFocus, toolbarButtons: [(_) => KeyboardDoneButton()]) - ], - ), - child: Container( - color: Theme.of(context).colorScheme.surface, - child: Form( - key: _formKey, - child: ScrollableWithBottomSection( - contentPadding: EdgeInsets.only(bottom: 24), - content: Observer( - builder: (_) => Column( - children: [ - _exchangeCardsSection(context), - Padding( - padding: EdgeInsets.only(top: 12, left: 24), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - StandardCheckbox( - value: exchangeViewModel.isFixedRateMode, - caption: S.of(context).fixed_rate, - onChanged: (value) { - if (value) { - exchangeViewModel.enableFixedRateMode(); - } else { - exchangeViewModel.isFixedRateMode = false; - } - }, - ), - ], - ), - ), - SizedBox(height: 30), - _buildTemplateSection(context) - ], - ), - ), - bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24), - bottomSection: Column( - children: [ - Padding( - padding: EdgeInsets.only(bottom: 15), - child: Observer( - builder: (_) { - final description = exchangeViewModel.isFixedRateMode - ? exchangeViewModel.isAvailableInSelected - ? S.of(context).amount_is_guaranteed - : S.of(context).fixed_pair_not_supported - : exchangeViewModel.isAvailableInSelected - ? S.of(context).amount_is_estimate - : S.of(context).this_pair_is_not_supported_warning; - return Row( - children: [ - if (description == S.of(context).this_pair_is_not_supported_warning) - Expanded( - child: Container( - alignment: Alignment.centerRight, - child: Icon(Icons.warning_amber_rounded, - color: Theme.of(context).colorScheme.error, size: 26), - ), - ), - Expanded( - flex: 8, - child: Text( - description, - textAlign: TextAlign.center, - softWrap: true, - overflow: TextOverflow.ellipsis, - maxLines: 3, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant, - fontWeight: FontWeight.w500, - ), - ), - ), - ], - ); - }, - ), - ), - Observer( - builder: (_) => LoadingPrimaryButton( - key: ValueKey('exchange_page_exchange_button_key'), - text: exchangeViewModel.isAvailableInSelected - ? S.of(context).swap - : S.of(context).change_selected_exchanges, - onPressed: exchangeViewModel.isAvailableInSelected - ? () { - FocusScope.of(context).unfocus(); - - if (_formKey.currentState != null && - _formKey.currentState!.validate()) { - if (_shouldWaitTillSynced) { - showPopUp( - context: context, - builder: (BuildContext context) { - return AlertWithOneAction( - alertTitle: S.of(context).exchange, - alertContent: S.of(context).exchange_sync_alert_content, - buttonText: S.of(context).ok, - buttonAction: () => Navigator.of(context).pop(), - ); - }, - ); - } else { - final check = exchangeViewModel.shouldDisplayTOTP(); - authService.authenticateAction( - context, - conditionToDetermineIfToUse2FA: check, - onAuthSuccess: (value) { - if (value) { - exchangeViewModel.createTrade(); - } - }, - ); - } - } - } - : () => PresentProviderPicker(exchangeViewModel: exchangeViewModel) - .presentProviderPicker(context), - color: Theme.of(context).colorScheme.primary, - textColor: Theme.of(context).colorScheme.onPrimary, - isDisabled: exchangeViewModel.selectedProviders.isEmpty, - isLoading: exchangeViewModel.tradeState is TradeIsCreating, - ), - ), - ], - ), - ), - ), - ), - ); - } - - Widget _buildTemplateSection(BuildContext context) { - return Container( - height: 40, - width: double.infinity, - padding: EdgeInsets.only(left: 24), - child: SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: Observer( - builder: (_) { - final templates = exchangeViewModel.templates; - - return Row( - children: [ - AddTemplateButton( - onTap: () => Navigator.of(context).pushNamed(Routes.exchangeTemplate), - currentTemplatesLength: templates.length, - ), - ListView.builder( - scrollDirection: Axis.horizontal, - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - itemCount: templates.length, - itemBuilder: (context, index) { - final template = templates[index]; - - return TemplateTile( - key: UniqueKey(), - amount: template.amount, - from: template.depositCurrencyTitle, - to: template.receiveCurrencyTitle, - onTap: () { - applyTemplate(context, exchangeViewModel, template); - }, - 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(); - exchangeViewModel.removeTemplate(template: template); - exchangeViewModel.updateTemplate(); - }, - actionLeftButton: () => Navigator.of(dialogContext).pop(), - ); - }, - ); - }, - ); - }, - ), - ], - ); - }, - ), - ), - ); - } - - void applyTemplate( - BuildContext context, ExchangeViewModel exchangeViewModel, ExchangeTemplate template) async { - final depositCryptoCurrency = - CryptoCurrency.safeParseCurrencyFromString(template.depositCurrency); - final receiveCryptoCurrency = - CryptoCurrency.safeParseCurrencyFromString(template.receiveCurrency); - - if (depositCryptoCurrency == null || receiveCryptoCurrency == null) { - ///TO DO: add support for user tokens - return; - } - - exchangeViewModel.changeDepositCurrency(currency: depositCryptoCurrency); - exchangeViewModel.changeReceiveCurrency(currency: receiveCryptoCurrency); - - exchangeViewModel.changeDepositAmount(amount: template.amount); - exchangeViewModel.depositAddress = template.depositAddress; - exchangeViewModel.receiveAddress = template.receiveAddress; - exchangeViewModel.isReceiveAmountEntered = false; - exchangeViewModel.isFixedRateMode = false; - - var domain = template.depositAddress; - exchangeViewModel.depositAddress = - await fetchParsedAddress(context, domain, depositCryptoCurrency); - - domain = template.receiveAddress; - exchangeViewModel.receiveAddress = - await fetchParsedAddress(context, domain, receiveCryptoCurrency); - } - - void _setReactions(BuildContext context, ExchangeViewModel exchangeViewModel) { - if (_isReactionsSet) { - return; - } - - if (exchangeViewModel.feesViewModel.isLowFee) { - _showFeeAlert(context); - } - - final depositAddressController = depositKey.currentState!.addressController; - final depositAmountController = depositKey.currentState!.amountController; - final receiveAddressController = receiveKey.currentState!.addressController; - final receiveAmountController = receiveKey.currentState!.amountController; - final limitsState = exchangeViewModel.limitsState; - - if (limitsState is LimitsLoadedSuccessfully) { - final min = limitsState.limits.min != null ? limitsState.limits.min.toString() : null; - final max = limitsState.limits.max != null ? limitsState.limits.max.toString() : null; - final key = exchangeViewModel.isFixedRateMode ? receiveKey : depositKey; - key.currentState!.changeLimits(min: min, max: max); - } - - _onCurrencyChange(exchangeViewModel.receiveCurrency, exchangeViewModel, receiveKey); - _onCurrencyChange(exchangeViewModel.depositCurrency, exchangeViewModel, depositKey); - - reaction( - (_) => exchangeViewModel.wallet.name, - (_) => - _onWalletNameChange(exchangeViewModel, exchangeViewModel.receiveCurrency, receiveKey)); - - reaction( - (_) => exchangeViewModel.wallet.name, - (_) => - _onWalletNameChange(exchangeViewModel, exchangeViewModel.depositCurrency, depositKey)); - - reaction((_) => exchangeViewModel.receiveCurrency, - (CryptoCurrency currency) => _onCurrencyChange(currency, exchangeViewModel, receiveKey)); - - reaction((_) => exchangeViewModel.depositCurrency, - (CryptoCurrency currency) => _onCurrencyChange(currency, exchangeViewModel, depositKey)); - - reaction((_) => exchangeViewModel.depositAmount, (String amount) { - if (exchangeViewModel.isSendAllEnabled) { - depositAmountController.text = S.of(context).all; - } else if (depositAmountController.text != amount && amount != S.of(context).all) { - depositAmountController.text = amount; - } - }); - - reaction((_) => exchangeViewModel.depositAddress, (String address) { - if (depositKey.currentState!.addressController.text != address) { - depositKey.currentState!.addressController.text = address; - } - }); - - reaction((_) => exchangeViewModel.isDepositAddressEnabled, (bool isEnabled) { - depositKey.currentState!.isAddressEditable(isEditable: isEnabled); - }); - - reaction((_) => exchangeViewModel.receiveAmount, (String amount) { - if (receiveKey.currentState!.amountController.text != amount) { - receiveKey.currentState!.amountController.text = amount; - } - }); - - reaction((_) => exchangeViewModel.receiveAddress, (String address) { - if (receiveKey.currentState!.addressController.text != address) { - receiveKey.currentState!.addressController.text = address; - } - }); - - reaction((_) => exchangeViewModel.isReceiveAmountEditable, (bool isReceiveAmountEditable) { - receiveKey.currentState!.isAmountEditable(isEditable: isReceiveAmountEditable); - }); - - reaction((_) => exchangeViewModel.tradeState, (ExchangeTradeState state) { - if (state is TradeIsCreatedFailure) { - WidgetsBinding.instance.addPostFrameCallback((_) { - showPopUp( - context: context, - builder: (BuildContext context) { - return AlertWithOneAction( - key: ValueKey('exchange_page_trade_creation_failure_dialog_key'), - buttonKey: ValueKey('exchange_page_trade_creation_failure_dialog_button_key'), - alertTitle: S.of(context).provider_error(state.title), - alertContent: state.error, - buttonText: S.of(context).ok, - buttonAction: () => Navigator.of(context).pop()); - }); - }); - } - if (state is TradeIsCreatedSuccessfully) { - exchangeViewModel.reset(); - (exchangeViewModel.tradesStore.trade?.provider == ExchangeProviderDescription.thorChain || - exchangeViewModel.tradesStore.trade?.provider == - ExchangeProviderDescription.chainflip) - ? Navigator.of(context).pushReplacementNamed(Routes.exchangeTrade) - : Navigator.of(context).pushReplacementNamed(Routes.exchangeConfirm); - } - }); - - reaction((_) => exchangeViewModel.limitsState, (LimitsState state) { - String? min; - String? max; - - if (state is LimitsLoadedSuccessfully) { - min = state.limits.min != null ? state.limits.min.toString() : null; - max = state.limits.max != null ? state.limits.max.toString() : null; - } - - if (state is LimitsLoadedFailure) { - min = '0'; - max = '0'; - } - - if (state is LimitsIsLoading) { - min = '...'; - max = '...'; - } - - if (exchangeViewModel.isFixedRateMode) { - depositKey.currentState!.changeLimits(min: null, max: null); - receiveKey.currentState!.changeLimits(min: min, max: max); - } else { - depositKey.currentState!.changeLimits(min: min, max: max); - receiveKey.currentState!.changeLimits(min: null, max: null); - } - }); - - reaction((_) => exchangeViewModel.bestRate, (double rate) { - if (exchangeViewModel.isFixedRateMode) { - exchangeViewModel.changeReceiveAmount(amount: receiveAmountController.text); - } else { - if (depositAmountController.text == S.current.all) - exchangeViewModel.changeDepositAmount(amount: exchangeViewModel.depositAmount); - else - exchangeViewModel.changeDepositAmount(amount: depositAmountController.text); - } - }); - - depositAddressController - .addListener(() => exchangeViewModel.depositAddress = depositAddressController.text); - - depositAmountController.addListener(() { - if (depositAmountController.text != exchangeViewModel.depositAmount && - depositAmountController.text != S.of(context).all) { - exchangeViewModel.isSendAllEnabled = false; - final isThorChain = exchangeViewModel.selectedProviders - .any((provider) => provider is ThorChainExchangeProvider); - final isChainflip = exchangeViewModel.selectedProviders - .any((provider) => provider is ChainflipExchangeProvider); - - _depositAmountDebounce = isThorChain || isChainflip - ? Debounce(Duration(milliseconds: 1000)) - : Debounce(Duration(milliseconds: 500)); - - _depositAmountDebounce.run(() { - exchangeViewModel.calculateBestRate(); - exchangeViewModel.changeDepositAmount(amount: depositAmountController.text); - exchangeViewModel.isReceiveAmountEntered = false; - }); - } - }); - - receiveAddressController - .addListener(() => exchangeViewModel.receiveAddress = receiveAddressController.text); - - receiveAmountController.addListener(() { - if (receiveAmountController.text != exchangeViewModel.receiveAmount) { - _receiveAmountDebounce.run(() { - exchangeViewModel.calculateBestRate(); - exchangeViewModel.changeReceiveAmount(amount: receiveAmountController.text); - exchangeViewModel.isReceiveAmountEntered = true; - }); - } - }); - - reaction((_) => exchangeViewModel.wallet.walletAddresses.addressForExchange, (String address) { - if (exchangeViewModel.depositCurrency == CryptoCurrency.xmr) { - depositKey.currentState!.changeAddress(address: address); - } - - if (exchangeViewModel.receiveCurrency == CryptoCurrency.xmr) { - receiveKey.currentState!.changeAddress(address: address); - } - }); - - _depositAddressFocus.addListener(() async { - if (!_depositAddressFocus.hasFocus && depositAddressController.text.isNotEmpty) { - final domain = depositAddressController.text; - exchangeViewModel.depositAddress = - await fetchParsedAddress(context, domain, exchangeViewModel.depositCurrency); - } - }); - - _receiveAddressFocus.addListener(() async { - if (!_receiveAddressFocus.hasFocus && receiveAddressController.text.isNotEmpty) { - final domain = receiveAddressController.text; - exchangeViewModel.receiveAddress = - await fetchParsedAddress(context, domain, exchangeViewModel.receiveCurrency); - } - }); - - _receiveAmountFocus.addListener(() { - if (_receiveAmountFocus.hasFocus) { - exchangeViewModel.enableFixedRateMode(); - } - // exchangeViewModel.changeReceiveAmount(amount: receiveAmountController.text); - }); - - _depositAmountFocus.addListener(() { - exchangeViewModel.isFixedRateMode = false; - // exchangeViewModel.changeDepositAmount( - // amount: depositAmountController.text); - }); - - if (initialPaymentRequest != null) { - try { - exchangeViewModel.receiveCurrency = - CryptoCurrency.fromString(initialPaymentRequest!.scheme); - exchangeViewModel.setCanonicalReceiveAmount(initialPaymentRequest!.amount); - exchangeViewModel.receiveAddress = initialPaymentRequest!.address; - } catch (e) { - printV('error: ${e.toString()}'); - // TODO - } - } - - _isReactionsSet = true; - } - - void _onCurrencyChange(CryptoCurrency currency, ExchangeViewModel exchangeViewModel, - GlobalKey key) { - final isCurrentTypeWallet = exchangeViewModel.useSameWalletAddress(currency); - - key.currentState!.changeSelectedCurrency(currency); - key.currentState!.changeWalletName(isCurrentTypeWallet ? exchangeViewModel.wallet.name : ''); - - key.currentState!.changeAddress( - address: - isCurrentTypeWallet ? exchangeViewModel.wallet.walletAddresses.addressForExchange : ''); - } - - void _onWalletNameChange(ExchangeViewModel exchangeViewModel, CryptoCurrency currency, - GlobalKey key) { - final isCurrentTypeWallet = currency == exchangeViewModel.wallet.currency; - - if (isCurrentTypeWallet) { - key.currentState!.changeWalletName(exchangeViewModel.wallet.name); - key.currentState!.addressController.text = - exchangeViewModel.wallet.walletAddresses.addressForExchange; - } else if (key.currentState!.addressController.text == - exchangeViewModel.wallet.walletAddresses.addressForExchange) { - key.currentState!.changeWalletName(''); - key.currentState!.addressController.text = ''; - } - } - - Future fetchParsedAddress( - BuildContext context, String domain, CryptoCurrency currency) async { - final parsedAddresses = await adrResService.resolve( - query: domain, wallet: exchangeViewModel.wallet, currency: currency); - return parsedAddresses.isNotEmpty - ? (parsedAddresses.first.parsedAddressByCurrencyMap[currency] ?? domain) - : domain; - } - - void _showFeeAlert(BuildContext context) async { - await Future.delayed(Duration(seconds: 1)); - final confirmed = await showPopUp( - context: context, - builder: (dialogContext) { - return AlertWithTwoActions( - alertTitle: S.of(context).low_fee, - 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)); - }) ?? - false; - if (confirmed) { - exchangeViewModel.feesViewModel.setDefaultTransactionPriority(); - } - } - - void disposeBestRateSync() => exchangeViewModel.bestRateSync.cancel(); - - Widget _exchangeCardsSection(BuildContext context) { - final firstExchangeCard = Observer( - builder: (_) => ExchangeCard( - cardInstanceName: 'deposit_exchange_card', - onDispose: disposeBestRateSync, - hasAllAmount: exchangeViewModel.hasAllAmount, - allAmount: - exchangeViewModel.hasAllAmount ? () => exchangeViewModel.enableSendAllAmount() : null, - isAllAmountEnabled: exchangeViewModel.isSendAllEnabled, - amountFocusNode: _depositAmountFocus, - addressFocusNode: _depositAddressFocus, - key: depositKey, - title: S.of(context).you_will_send, - initialCurrency: exchangeViewModel.depositCurrency, - initialWalletName: depositWalletName ?? '', - initialAddress: exchangeViewModel.depositCurrency == exchangeViewModel.wallet.currency - ? exchangeViewModel.wallet.walletAddresses.addressForExchange - : exchangeViewModel.depositAddress, - initialIsAmountEditable: true, - initialIsAddressEditable: exchangeViewModel.isDepositAddressEnabled, - isAmountEstimated: false, - hasRefundAddress: true, - isMoneroWallet: exchangeViewModel.isMoneroWallet, - currencies: exchangeViewModel.depositCurrencies, - onCurrencySelected: (currency) { - exchangeViewModel.changeDepositCurrency(currency: currency); - }, - currencyButtonColor: Colors.transparent, - addressButtonsColor: Colors.transparent, - borderColor: Theme.of(context).colorScheme.outlineVariant, - fillColor: Theme.of(context).colorScheme.surfaceContainer, - currencyValueValidator: (value) { - return !exchangeViewModel.isFixedRateMode && value != S.of(context).all - ? AmountValidator( - isAutovalidate: true, - currency: exchangeViewModel.depositCurrency, - amountParsingProxy: exchangeViewModel.amountParsingProxy, - minValue: exchangeViewModel.limits.min.toString(), - maxValue: exchangeViewModel.limits.max.toString(), - ).call(value) - : null; - }, - addressTextFieldValidator: AddressValidator(type: exchangeViewModel.depositCurrency), - onPushPasteButton: (context) async { - final domain = exchangeViewModel.depositAddress; - exchangeViewModel.depositAddress = - await fetchParsedAddress(context, domain, exchangeViewModel.depositCurrency); - }, - onPushAddressBookButton: (context) async { - final domain = exchangeViewModel.depositAddress; - exchangeViewModel.depositAddress = - await fetchParsedAddress(context, domain, exchangeViewModel.depositCurrency); - }, - useSatoshis: exchangeViewModel.useDepositBaseUnit, - ), - ); - - final secondExchangeCard = Observer( - builder: (_) => ExchangeCard( - cardInstanceName: 'receive_exchange_card', - onDispose: disposeBestRateSync, - amountFocusNode: _receiveAmountFocus, - addressFocusNode: _receiveAddressFocus, - key: receiveKey, - title: S.of(context).you_will_get, - initialCurrency: exchangeViewModel.receiveCurrency, - initialWalletName: receiveWalletName ?? '', - initialAddress: exchangeViewModel.receiveCurrency == exchangeViewModel.wallet.currency - ? exchangeViewModel.wallet.walletAddresses.addressForExchange - : exchangeViewModel.receiveAddress, - initialIsAmountEditable: exchangeViewModel.isReceiveAmountEditable, - isAmountEstimated: true, - isMoneroWallet: exchangeViewModel.isMoneroWallet, - currencies: exchangeViewModel.receiveCurrencies, - onCurrencySelected: (currency) => - exchangeViewModel.changeReceiveCurrency(currency: currency), - currencyButtonColor: Colors.transparent, - addressButtonsColor: Colors.transparent, - borderColor: Theme.of(context).colorScheme.outlineVariant, - fillColor: Theme.of(context).colorScheme.surfaceContainerLow, - currencyValueValidator: (value) { - return exchangeViewModel.isFixedRateMode - ? AmountValidator( - isAutovalidate: true, - currency: exchangeViewModel.receiveCurrency, - amountParsingProxy: exchangeViewModel.amountParsingProxy, - minValue: exchangeViewModel.limits.min.toString(), - maxValue: exchangeViewModel.limits.max.toString(), - ).call(value) - : null; - }, - addressTextFieldValidator: AddressValidator(type: exchangeViewModel.receiveCurrency), - onPushPasteButton: (context) async { - final domain = exchangeViewModel.receiveAddress; - exchangeViewModel.receiveAddress = - await fetchParsedAddress(context, domain, exchangeViewModel.receiveCurrency); - }, - onPushAddressBookButton: (context) async { - final domain = exchangeViewModel.receiveAddress; - exchangeViewModel.receiveAddress = - await fetchParsedAddress(context, domain, exchangeViewModel.receiveCurrency); - }, - useSatoshis: exchangeViewModel.useReceiveBaseUnit, - ), - ); - - return responsiveLayoutUtil.shouldRenderMobileUI - ? MobileExchangeCardsSection( - firstExchangeCard: firstExchangeCard, - secondExchangeCard: secondExchangeCard, - ) - : DesktopExchangeCardsSection( - firstExchangeCard: firstExchangeCard, - secondExchangeCard: secondExchangeCard, - ); - } -} diff --git a/lib/src/screens/exchange/exchange_template_page.dart b/lib/src/screens/exchange/exchange_template_page.dart deleted file mode 100644 index 893238455..000000000 --- a/lib/src/screens/exchange/exchange_template_page.dart +++ /dev/null @@ -1,378 +0,0 @@ -import 'package:cake_wallet/exchange/provider/exchange_provider.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/src/widgets/keyboard_done_button.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:keyboard_actions/keyboard_actions.dart'; -import 'package:mobx/mobx.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cw_core/crypto_currency.dart'; -import 'package:cake_wallet/src/screens/exchange/widgets/exchange_card.dart'; -import 'package:cake_wallet/src/widgets/primary_button.dart'; -import 'package:cake_wallet/src/widgets/scrollable_with_bottom_section.dart'; -import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart'; -import 'package:cake_wallet/core/amount_validator.dart'; -import 'package:cake_wallet/src/screens/exchange/widgets/present_provider_picker.dart'; - -class ExchangeTemplatePage extends BasePage { - ExchangeTemplatePage(this.exchangeViewModel); - - final ExchangeViewModel exchangeViewModel; - final depositKey = GlobalKey(); - final receiveKey = GlobalKey(); - final _formKey = GlobalKey(); - final _depositAmountFocus = FocusNode(); - final _receiveAmountFocus = FocusNode(); - var _isReactionsSet = false; - - @override - bool get gradientAll => true; - - @override - String get title => S.current.exchange_new_template; - - @override - bool get extendBodyBehindAppBar => true; - - @override - AppBarStyle get appBarStyle => AppBarStyle.transparent; - - @override - Widget trailing(BuildContext context) => - PresentProviderPicker(exchangeViewModel: exchangeViewModel); - - @override - Widget body(BuildContext context) { - final arrowBottomPurple = Image.asset( - 'assets/images/arrow_bottom_purple_icon.png', - color: Theme.of(context).colorScheme.primary, - height: 8, - ); - final arrowBottomCakeGreen = Image.asset( - 'assets/images/arrow_bottom_cake_green.png', - color: Theme.of(context).colorScheme.primary, - height: 8, - ); - - final depositWalletName = exchangeViewModel.depositCurrency == CryptoCurrency.xmr - ? exchangeViewModel.wallet.name - : null; - final receiveWalletName = exchangeViewModel.receiveCurrency == CryptoCurrency.xmr - ? exchangeViewModel.wallet.name - : null; - - WidgetsBinding.instance.addPostFrameCallback((_) => _setReactions(context, exchangeViewModel)); - - return KeyboardActions( - disableScroll: true, - config: KeyboardActionsConfig( - keyboardActionsPlatform: KeyboardActionsPlatform.IOS, - keyboardBarColor: Theme.of(context).colorScheme.surfaceVariant, - nextFocus: false, - actions: [ - KeyboardActionsItem( - focusNode: _depositAmountFocus, toolbarButtons: [(_) => KeyboardDoneButton()]), - KeyboardActionsItem( - focusNode: _receiveAmountFocus, toolbarButtons: [(_) => KeyboardDoneButton()]) - ], - ), - child: Container( - color: Theme.of(context).colorScheme.surface, - child: Form( - key: _formKey, - child: ScrollableWithBottomSection( - contentPadding: EdgeInsets.only(bottom: 24), - content: Container( - padding: EdgeInsets.only(bottom: 32), - decoration: BoxDecoration( - borderRadius: BorderRadius.only( - bottomLeft: Radius.circular(24), - bottomRight: Radius.circular(24), - ), - color: Theme.of(context).colorScheme.surfaceContainer, - ), - child: FocusTraversalGroup( - policy: OrderedTraversalPolicy(), - child: Column( - children: [ - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.only( - bottomLeft: Radius.circular(24), - bottomRight: Radius.circular(24)), - color: Theme.of(context).colorScheme.surfaceContainerLow, - ), - padding: EdgeInsets.fromLTRB(24, 100, 24, 32), - child: Observer( - builder: (_) => ExchangeCard( - cardInstanceName: 'deposit_exchange_template_card', - amountFocusNode: _depositAmountFocus, - key: depositKey, - title: S.of(context).you_will_send, - initialCurrency: exchangeViewModel.depositCurrency, - initialWalletName: depositWalletName ?? '', - initialAddress: exchangeViewModel.depositCurrency == - exchangeViewModel.wallet.currency - ? exchangeViewModel.wallet.walletAddresses.addressForExchange - : exchangeViewModel.depositAddress, - initialIsAmountEditable: true, - initialIsAddressEditable: exchangeViewModel.isDepositAddressEnabled, - isAmountEstimated: false, - hasRefundAddress: true, - isMoneroWallet: exchangeViewModel.isMoneroWallet, - currencies: CryptoCurrency.all, - onCurrencySelected: (currency) => - exchangeViewModel.changeDepositCurrency(currency: currency), - imageArrow: arrowBottomPurple, - currencyButtonColor: Colors.transparent, - addressButtonsColor: - Theme.of(context).colorScheme.surfaceContainerHighest, - borderColor: Theme.of(context).colorScheme.outlineVariant, - fillColor: Theme.of(context).colorScheme.surfaceContainer, - currencyValueValidator: AmountValidator( - currency: exchangeViewModel.depositCurrency, - amountParsingProxy: exchangeViewModel.amountParsingProxy, - ), - ), - ), - ), - Padding( - padding: EdgeInsets.only(top: 29, left: 24, right: 24), - child: Observer( - builder: (_) => ExchangeCard( - cardInstanceName: 'receive_exchange_template_card', - amountFocusNode: _receiveAmountFocus, - key: receiveKey, - title: S.of(context).you_will_get, - initialCurrency: exchangeViewModel.receiveCurrency, - initialWalletName: receiveWalletName ?? '', - initialAddress: exchangeViewModel.receiveCurrency == - exchangeViewModel.wallet.currency - ? exchangeViewModel.wallet.walletAddresses.addressForExchange - : exchangeViewModel.receiveAddress, - initialIsAmountEditable: false, - isAmountEstimated: true, - isMoneroWallet: exchangeViewModel.isMoneroWallet, - currencies: exchangeViewModel.receiveCurrencies, - onCurrencySelected: (currency) => - exchangeViewModel.changeReceiveCurrency(currency: currency), - imageArrow: arrowBottomCakeGreen, - currencyButtonColor: Colors.transparent, - addressButtonsColor: - Theme.of(context).colorScheme.surfaceContainerHighest, - borderColor: Theme.of(context).colorScheme.outlineVariant, - fillColor: Theme.of(context).colorScheme.surfaceContainerLow, - currencyValueValidator: AmountValidator( - currency: exchangeViewModel.receiveCurrency, - amountParsingProxy: exchangeViewModel.amountParsingProxy, - ), - ), - ), - ) - ], - ), - ), - ), - bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24), - bottomSection: Column(children: [ - Padding( - padding: EdgeInsets.only(bottom: 15), - child: Observer( - builder: (_) => Center( - child: Text( - S.of(context).amount_is_estimate, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant, - fontWeight: FontWeight.w500, - ), - ), - ), - ), - ), - PrimaryButton( - onPressed: () { - if (_formKey.currentState != null && _formKey.currentState!.validate()) { - exchangeViewModel.addTemplate( - amount: exchangeViewModel.depositAmount, - depositCurrency: exchangeViewModel.depositCurrency.name, - depositCurrencyTitle: exchangeViewModel.depositCurrency.title + - ' ${exchangeViewModel.depositCurrency.tag ?? ''}', - receiveCurrency: exchangeViewModel.receiveCurrency.name, - receiveCurrencyTitle: exchangeViewModel.receiveCurrency.title + - ' ${exchangeViewModel.receiveCurrency.tag ?? ''}', - provider: exchangeViewModel.provider.toString(), - depositAddress: exchangeViewModel.depositAddress, - receiveAddress: exchangeViewModel.receiveAddress); - exchangeViewModel.updateTemplate(); - Navigator.of(context).pop(); - } - }, - text: S.of(context).save, - color: Theme.of(context).colorScheme.primary, - textColor: Theme.of(context).colorScheme.onPrimary), - ]), - )))); - } - - void _setReactions(BuildContext context, ExchangeViewModel exchangeViewModel) { - if (_isReactionsSet) { - return; - } - - final depositAddressController = depositKey.currentState!.addressController; - final depositAmountController = depositKey.currentState!.amountController; - final receiveAddressController = receiveKey.currentState!.addressController; - final receiveAmountController = receiveKey.currentState!.amountController; - final limitsState = exchangeViewModel.limitsState; - - // FIXME: FIXME - - // final limitsState = exchangeViewModel.limitsState; - // - // if (limitsState is LimitsLoadedSuccessfully) { - // final min = limitsState.limits.min != null - // ? limitsState.limits.min.toString() - // : null; - // final max = limitsState.limits.max != null - // ? limitsState.limits.max.toString() - // : null; - // final key = depositKey; - // key.currentState.changeLimits(min: min, max: max); - // } - - _onCurrencyChange(exchangeViewModel.receiveCurrency, exchangeViewModel, receiveKey); - _onCurrencyChange(exchangeViewModel.depositCurrency, exchangeViewModel, depositKey); - - reaction( - (_) => exchangeViewModel.wallet.name, - (String _) => - _onWalletNameChange(exchangeViewModel, exchangeViewModel.receiveCurrency, receiveKey)); - - reaction( - (_) => exchangeViewModel.wallet.name, - (String _) => - _onWalletNameChange(exchangeViewModel, exchangeViewModel.depositCurrency, depositKey)); - - reaction((_) => exchangeViewModel.receiveCurrency, - (CryptoCurrency currency) => _onCurrencyChange(currency, exchangeViewModel, receiveKey)); - - reaction((_) => exchangeViewModel.depositCurrency, - (CryptoCurrency currency) => _onCurrencyChange(currency, exchangeViewModel, depositKey)); - - reaction((_) => exchangeViewModel.depositAmount, (String amount) { - if (depositKey.currentState!.amountController.text != amount && amount != S.of(context).all) { - depositKey.currentState!.amountController.text = amount; - } - }); - - reaction((_) => exchangeViewModel.depositAddress, (String address) { - if (depositKey.currentState!.addressController.text != address) { - depositKey.currentState!.addressController.text = address; - } - }); - - reaction((_) => exchangeViewModel.isDepositAddressEnabled, (bool isEnabled) { - depositKey.currentState!.isAddressEditable(isEditable: isEnabled); - }); - - reaction((_) => exchangeViewModel.receiveAmount, (String amount) { - if (receiveKey.currentState!.amountController.text != amount) { - receiveKey.currentState!.amountController.text = amount; - } - }); - - reaction((_) => exchangeViewModel.receiveAddress, (String address) { - if (receiveKey.currentState!.addressController.text != address) { - receiveKey.currentState!.addressController.text = address; - } - }); - - reaction((_) => exchangeViewModel.provider, (ExchangeProvider? provider) { - receiveKey.currentState!.isAmountEditable(isEditable: false); - }); - - /*reaction((_) => exchangeViewModel.limitsState, (LimitsState state) { - String min; - String max; - - if (state is LimitsLoadedSuccessfully) { - min = state.limits.min != null ? state.limits.min.toString() : null; - max = state.limits.max != null ? state.limits.max.toString() : null; - } - - if (state is LimitsLoadedFailure) { - min = '0'; - max = '0'; - } - - if (state is LimitsIsLoading) { - min = '...'; - max = '...'; - } - - depositKey.currentState.changeLimits(min: min, max: max); - receiveKey.currentState.changeLimits(min: null, max: null); - });*/ - - depositAddressController - .addListener(() => exchangeViewModel.depositAddress = depositAddressController.text); - - depositAmountController.addListener(() { - if (depositAmountController.text != exchangeViewModel.depositAmount && - exchangeViewModel.depositAmount != S.of(context).all) { - exchangeViewModel.changeDepositAmount(amount: depositAmountController.text); - exchangeViewModel.isReceiveAmountEntered = false; - } - }); - - receiveAddressController - .addListener(() => exchangeViewModel.receiveAddress = receiveAddressController.text); - - receiveAmountController.addListener(() { - if (receiveAmountController.text != exchangeViewModel.receiveAmount) { - exchangeViewModel.changeReceiveAmount(amount: receiveAmountController.text); - exchangeViewModel.isReceiveAmountEntered = true; - } - }); - - reaction((_) => exchangeViewModel.wallet.walletAddresses.address, (String address) { - if (exchangeViewModel.depositCurrency == CryptoCurrency.xmr) { - depositKey.currentState!.changeAddress(address: address); - } - - if (exchangeViewModel.receiveCurrency == CryptoCurrency.xmr) { - receiveKey.currentState!.changeAddress(address: address); - } - }); - - _isReactionsSet = true; - } - - void _onCurrencyChange(CryptoCurrency currency, ExchangeViewModel exchangeViewModel, - GlobalKey key) { - final isCurrentTypeWallet = currency == exchangeViewModel.wallet.currency; - - key.currentState!.changeSelectedCurrency(currency); - key.currentState!.changeWalletName(isCurrentTypeWallet ? exchangeViewModel.wallet.name : ''); - - key.currentState!.changeAddress( - address: isCurrentTypeWallet ? exchangeViewModel.wallet.walletAddresses.address : ''); - - key.currentState!.changeAmount(amount: ''); - } - - void _onWalletNameChange(ExchangeViewModel exchangeViewModel, CryptoCurrency currency, - GlobalKey key) { - final isCurrentTypeWallet = currency == exchangeViewModel.wallet.currency; - - if (isCurrentTypeWallet) { - key.currentState!.changeWalletName(exchangeViewModel.wallet.name); - key.currentState!.addressController.text = exchangeViewModel.wallet.walletAddresses.address; - } else if (key.currentState!.addressController.text == - exchangeViewModel.wallet.walletAddresses.address) { - key.currentState!.changeWalletName(''); - key.currentState!.addressController.text = ''; - } - } -} diff --git a/lib/src/screens/exchange/widgets/currency_picker_item_widget.dart b/lib/src/screens/exchange/widgets/currency_picker_item_widget.dart deleted file mode 100644 index 6a0bb7405..000000000 --- a/lib/src/screens/exchange/widgets/currency_picker_item_widget.dart +++ /dev/null @@ -1,78 +0,0 @@ -import 'package:flutter/material.dart'; - -class PickerItemWidget extends StatelessWidget { - const PickerItemWidget( - {required this.title, this.iconPath, this.isSelected = false, this.tag, this.onTap}); - - final String? iconPath; - final String title; - final bool isSelected; - final String? tag; - final VoidCallback? onTap; - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onTap, - child: Container( - color: Theme.of(context).colorScheme.surface, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 24), - child: Row( - children: [ - Container( - child: Image.asset( - iconPath ?? '', - height: 20.0, - width: 20.0, - ), - ), - const SizedBox(width: 12), - Expanded( - child: Row( - children: [ - Text( - title.toUpperCase(), - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: isSelected - ? Theme.of(context).colorScheme.primary - : Theme.of(context).colorScheme.onSurface, - fontSize: isSelected ? 16 : 14.0, - fontWeight: FontWeight.w600, - ), - ), - if (tag != null) - Align( - alignment: Alignment.topCenter, - child: Container( - width: 35.0, - height: 18.0, - child: Center( - child: Text( - tag!, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 7.0, color: Theme.of(context).colorScheme.primary), - ), - ), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(6.0), - //border: Border.all(color: ), - color: Theme.of(context).colorScheme.surfaceContainerHighest, - ), - ), - ), - ], - ), - ), - if (isSelected) - Icon( - Icons.check, - color: Theme.of(context).colorScheme.primary, - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/src/screens/exchange/widgets/currency_picker_widget.dart b/lib/src/screens/exchange/widgets/currency_picker_widget.dart deleted file mode 100644 index f3b157fa5..000000000 --- a/lib/src/screens/exchange/widgets/currency_picker_widget.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:cw_core/currency.dart'; -import 'package:flutter/material.dart'; -import 'currency_picker_item_widget.dart'; - -class CurrencyPickerWidget extends StatelessWidget { - CurrencyPickerWidget({ - required this.crossAxisCount, - required this.selectedAtIndex, - required this.pickerItemsList, - required this.pickListItem, - }); - - final int crossAxisCount; - final int selectedAtIndex; - final Function pickListItem; - final List pickerItemsList; - - final ScrollController _scrollController = ScrollController(); - - @override - Widget build(BuildContext context) { - return Container( - color: Theme.of(context).colorScheme.outlineVariant, - child: Scrollbar( - controller: _scrollController, - child: GridView.builder( - controller: _scrollController, - padding: EdgeInsets.zero, - shrinkWrap: true, - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: crossAxisCount, - crossAxisSpacing: 2, - childAspectRatio: 3, - ), - itemCount: pickerItemsList.length, - itemBuilder: (BuildContext ctx, index) { - return PickerItemWidget( - onTap: () { - pickListItem(index); - }, - title: pickerItemsList[index].name, - iconPath: pickerItemsList[index].iconPath, - tag: pickerItemsList[index].tag, - ); - }), - ), - ); - } -} diff --git a/lib/src/screens/exchange_trade/exchange_confirm_page.dart b/lib/src/screens/exchange_trade/exchange_confirm_page.dart deleted file mode 100644 index dbb99fc12..000000000 --- a/lib/src/screens/exchange_trade/exchange_confirm_page.dart +++ /dev/null @@ -1,151 +0,0 @@ -import 'package:cake_wallet/exchange/exchange_provider_description.dart'; -import 'package:cake_wallet/store/dashboard/trades_store.dart'; -import 'package:cake_wallet/utils/image_utill.dart'; -import 'package:cake_wallet/utils/show_bar.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/widgets/primary_button.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/exchange/trade.dart'; - -class ExchangeConfirmPage extends BasePage { - ExchangeConfirmPage({required this.tradesStore}) : trade = tradesStore.trade!; - - final TradesStore tradesStore; - final Trade trade; - - @override - String get title => S.current.swap; - - @override - Widget body(BuildContext context) { - return Container( - padding: EdgeInsets.fromLTRB(24, 0, 24, 24), - child: Column( - children: [ - Expanded( - child: Column( - children: [ - Flexible( - child: Center( - child: Text( - S.of(context).exchange_result_write_down_trade_id, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyLarge?.copyWith( - fontSize: 18.0, - fontWeight: FontWeight.w500, - ), - ), - ), - ), - Container( - height: 178, - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(30)), - border: Border.all( - width: 0.0, - color: Theme.of(context).colorScheme.outlineVariant, - ), - color: Theme.of(context).colorScheme.surfaceContainer, - ), - child: Column( - children: [ - Expanded( - child: Padding( - padding: EdgeInsets.all(24), - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text( - "${trade.provider.title} ${S.of(context).trade_id}", - style: Theme.of(context).textTheme.bodySmall?.copyWith( - fontWeight: FontWeight.w500, - ), - ), - Expanded( - child: Text( - trade.id, - overflow: TextOverflow.visible, - style: Theme.of(context).textTheme.titleLarge?.copyWith( - fontSize: 20, - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - ), - ], - ), - ), - ), - Padding( - padding: EdgeInsets.fromLTRB(10, 0, 10, 10), - child: Builder( - builder: (context) => PrimaryButton( - key: ValueKey('exchange_confirm_page_copy_to_clipboard_button_key'), - onPressed: () { - Clipboard.setData(ClipboardData(text: trade.id)); - showBar(context, S.of(context).copied_to_clipboard); - }, - text: S.of(context).copy_id, - color: Theme.of(context).colorScheme.surfaceContainerLow, - textColor: Theme.of(context).colorScheme.onSurface, - borderRadius: BorderRadius.circular(30.0), - ), - ), - ) - ], - ), - ), - Expanded( - child: Column( - children: [ - if (trade.provider == ExchangeProviderDescription.trocador) - Padding( - padding: const EdgeInsets.only(top: 8.0), - child: Text( - S.of(context).selected_trocador_provider + ':${trade.providerName}', - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - fontWeight: FontWeight.w500, - ), - ), - ), - Flexible( - child: Center( - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - (trade.provider.image.isNotEmpty) - ? ImageUtil.getImageFromPath( - imagePath: trade.provider.image, height: 50, width: 50) - : const SizedBox(), - if (!trade.provider.horizontalLogo) - Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: Text(trade.provider.title), - ), - ], - ), - ), - ), - ], - ), - ), - ], - ), - ), - PrimaryButton( - key: ValueKey('exchange_confirm_page_saved_id_button_key'), - onPressed: () => Navigator.of(context).pushReplacementNamed(Routes.exchangeTrade), - text: S.of(context).saved_the_trade_id, - color: Theme.of(context).colorScheme.primary, - textColor: Theme.of(context).colorScheme.onPrimary, - ) - ], - ), - ); - } -} diff --git a/lib/src/screens/exchange_trade/exchange_trade_external_send_page.dart b/lib/src/screens/exchange_trade/exchange_trade_external_send_page.dart deleted file mode 100644 index 6788aedad..000000000 --- a/lib/src/screens/exchange_trade/exchange_trade_external_send_page.dart +++ /dev/null @@ -1,156 +0,0 @@ -import 'package:cake_wallet/entities/qr_view_data.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/src/screens/exchange_trade/widgets/exchange_trade_card_item_widget.dart'; -import 'package:cake_wallet/src/screens/receive/widgets/qr_image.dart'; -import 'package:cake_wallet/utils/brightness_util.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:flutter/material.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/core/execution_state.dart'; -import 'package:cake_wallet/view_model/exchange/exchange_trade_view_model.dart'; -import 'package:cake_wallet/view_model/send/send_view_model_state.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/src/widgets/primary_button.dart'; -import 'package:cake_wallet/src/widgets/scrollable_with_bottom_section.dart'; - -class ExchangeTradeExternalSendPage extends BasePage { - ExchangeTradeExternalSendPage({required this.exchangeTradeViewModel}); - - final ExchangeTradeViewModel exchangeTradeViewModel; - @override - String get title => S.current.swap; - - @override - bool get gradientAll => true; - - @override - bool get resizeToAvoidBottomInset => false; - - @override - bool get extendBodyBehindAppBar => true; - - @override - AppBarStyle get appBarStyle => AppBarStyle.transparent; - - final fetchingLabel = S.current.fetching; - - @override - Widget body(BuildContext context) { - final copyImage = Image.asset( - 'assets/images/copy_content.png', - height: 16, - width: 16, - color: Theme.of(context).colorScheme.primary, - ); - return Container( - child: ScrollableWithBottomSection( - contentPadding: EdgeInsets.only(bottom: 24), - content: Observer( - builder: (_) { - return Column( - children: [ - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.only( - bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)), - color: Theme.of(context).colorScheme.surfaceContainerLow, - ), - padding: EdgeInsets.fromLTRB(24, 110, 24, 32), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Spacer(flex: 3), - Flexible( - flex: 6, - child: GestureDetector( - onTap: () { - BrightnessUtil.changeBrightnessForFunction( - () async { - await Navigator.pushNamed( - context, - Routes.fullscreenQR, - arguments: QrViewData( - embeddedImagePath: - exchangeTradeViewModel.trade.from?.iconPath, - data: exchangeTradeViewModel.paymentUri?.toString() ?? - exchangeTradeViewModel.trade.inputAddress ?? - fetchingLabel, - ), - ); - }, - ); - }, - child: Center( - child: AspectRatio( - aspectRatio: 1.0, - child: Container( - padding: EdgeInsets.all(5), - decoration: BoxDecoration( - border: Border.all( - width: 3, - color: Theme.of(context).colorScheme.primary, - ), - ), - child: QrImage( - data: exchangeTradeViewModel.paymentUri?.toString() ?? - exchangeTradeViewModel.trade.inputAddress ?? - fetchingLabel, - embeddedImagePath: - exchangeTradeViewModel.trade.from?.iconPath, - size: 230, - ), - ), - ), - ), - ), - ), - Spacer(flex: 3) - ], - ), - SizedBox(height: 24), - ...exchangeTradeViewModel.items - .where((item) => item.isExternalSendDetail) - .map( - (item) => TradeItemRowWidget( - key: ValueKey( - 'exchange_trade_external_send_page_send_item_${item.title}_key'), - title: item.title, - value: item.data, - isCopied: true, - copyImage: copyImage, - ), - ) - .toList(), - ], - ), - ), - ], - ); - }, - ), - bottomSection: Observer( - builder: (_) { - final trade = exchangeTradeViewModel.trade; - final sendingState = exchangeTradeViewModel.sendViewModel.state; - - return exchangeTradeViewModel.isSendable && !(sendingState is TransactionCommitted) - ? LoadingPrimaryButton( - key: ValueKey('exchange_trade_external_send_page_continue_button_key'), - isDisabled: trade.inputAddress == null || trade.inputAddress!.isEmpty, - isLoading: sendingState is IsExecutingState, - onPressed: () { - Navigator.of(context).popUntil((route) => route.isFirst); - }, - text: S.current.continue_text, - color: Theme.of(context).colorScheme.primary, - textColor: Theme.of(context).colorScheme.onPrimary, - ) - : Offstage(); - }, - ), - ), - ); - } -} diff --git a/lib/src/screens/exchange_trade/exchange_trade_page.dart b/lib/src/screens/exchange_trade/exchange_trade_page.dart deleted file mode 100644 index 87bbc39f7..000000000 --- a/lib/src/screens/exchange_trade/exchange_trade_page.dart +++ /dev/null @@ -1,423 +0,0 @@ -import 'package:cake_wallet/exchange/exchange_provider_description.dart'; -import 'package:cake_wallet/reactions/wallet_connect.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/src/screens/connect_device/connect_device_page.dart'; -import 'package:cake_wallet/src/screens/exchange/widgets/desktop_exchange_cards_section.dart'; -import 'package:cake_wallet/src/screens/exchange/widgets/mobile_exchange_cards_section.dart'; -import 'package:cake_wallet/src/screens/exchange_trade/widgets/exchange_trade_card_item_widget.dart'; -import 'package:cake_wallet/src/widgets/bottom_sheet/base_bottom_sheet_widget.dart'; -import 'package:cake_wallet/src/widgets/bottom_sheet/confirm_sending_bottom_sheet_widget.dart'; -import 'package:cake_wallet/src/widgets/bottom_sheet/info_bottom_sheet_widget.dart'; -import 'package:cake_wallet/utils/request_review_handler.dart'; -import 'package:cake_wallet/utils/responsive_layout_util.dart'; -import 'package:mobx/mobx.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:flutter/material.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/core/execution_state.dart'; -import 'package:cake_wallet/src/screens/exchange_trade/information_page.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; -import 'package:cake_wallet/view_model/exchange/exchange_trade_view_model.dart'; -import 'package:cake_wallet/view_model/send/send_view_model_state.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/src/screens/exchange_trade/widgets/timer_widget.dart'; -import 'package:cake_wallet/src/widgets/primary_button.dart'; -import 'package:cake_wallet/src/widgets/scrollable_with_bottom_section.dart'; -import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; - -void showInformation(ExchangeTradeViewModel exchangeTradeViewModel, BuildContext context) { - final trade = exchangeTradeViewModel.trade; - final walletName = exchangeTradeViewModel.wallet.name; - - final from = trade.from?.toString() ?? ''; - - final information = exchangeTradeViewModel.isSendable - ? S.current.exchange_trade_result_confirm(trade.amount, from, walletName) + - exchangeTradeViewModel.extraInfo - : S.current.exchange_result_description(trade.amount, from) + - exchangeTradeViewModel.extraInfo; - - showPopUp( - context: context, - builder: (_) => InformationPage( - key: ValueKey('information_page_dialog_key'), - information: information, - ), - ); -} - -class ExchangeTradePage extends BasePage { - ExchangeTradePage({required this.exchangeTradeViewModel}); - - final ExchangeTradeViewModel exchangeTradeViewModel; - - @override - String get title => S.current.swap; - - @override - bool get gradientAll => true; - - @override - bool get resizeToAvoidBottomInset => false; - - @override - bool get extendBodyBehindAppBar => true; - - @override - AppBarStyle get appBarStyle => AppBarStyle.transparent; - - @override - Widget trailing(BuildContext context) { - final questionImage = Image.asset('assets/images/question_mark.png', - color: Theme.of(context).colorScheme.onSurface); - - return SizedBox( - height: 20.0, - width: 20.0, - child: ButtonTheme( - minWidth: double.minPositive, - child: TextButton( - // FIX-ME: Style - //highlightColor: Colors.transparent, - //splashColor: Colors.transparent, - //padding: EdgeInsets.all(0), - onPressed: () => showInformation(exchangeTradeViewModel, context), - child: questionImage), - ), - ); - } - - @override - Widget body(BuildContext context) => ExchangeTradeForm(exchangeTradeViewModel); -} - -class ExchangeTradeForm extends StatefulWidget { - ExchangeTradeForm(this.exchangeTradeViewModel); - - final ExchangeTradeViewModel exchangeTradeViewModel; - - @override - ExchangeTradeState createState() => ExchangeTradeState(); -} - -class ExchangeTradeState extends State { - final fetchingLabel = S.current.fetching; - - String get title => S.current.exchange; - - bool _effectsInstalled = false; - - ReactionDisposer? _exchangeStateReaction; - - @override - void initState() { - super.initState(); - WidgetsBinding.instance.addPostFrameCallback(afterLayout); - } - - void afterLayout(dynamic _) { - showInformation(widget.exchangeTradeViewModel, context); - } - - @override - void dispose() { - widget.exchangeTradeViewModel.timer?.cancel(); - _exchangeStateReaction?.reaction.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - _setEffects(); - - return Container( - child: ScrollableWithBottomSection( - contentPadding: EdgeInsets.only(bottom: 16), - content: Observer(builder: (_) { - final trade = widget.exchangeTradeViewModel.trade; - - return Column( - children: [ - trade.expiredAt != null - ? Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - S.of(context).offer_expires_in, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontWeight: FontWeight.w500, - ), - ), - if (trade.expiredAt != null) - TimerWidget(trade.expiredAt!, - color: Theme.of(context).colorScheme.onSurface) - ]) - : Offstage(), - _ExchangeTradeItemsCardSection( - viewModel: widget.exchangeTradeViewModel, - ), - ], - ); - }), - bottomSectionPadding: EdgeInsets.fromLTRB(24, 0, 24, 24), - bottomSection: Column( - children: [ - if (!widget.exchangeTradeViewModel.shouldHideExternalSendButton) - PrimaryButton( - key: ValueKey('exchange_trade_page_send_from_external_button_key'), - text: S.current.send_from_external_wallet, - onPressed: () async { - Navigator.of(context).pushNamed(Routes.exchangeTradeExternalSendPage); - }, - color: widget.exchangeTradeViewModel.isSendable - ? Theme.of(context).colorScheme.surfaceContainer - : Theme.of(context).colorScheme.primary, - textColor: widget.exchangeTradeViewModel.isSendable - ? Theme.of(context).colorScheme.onSecondaryContainer - : Theme.of(context).colorScheme.onPrimary, - ), - SizedBox(height: 16), - Observer( - builder: (_) { - final trade = widget.exchangeTradeViewModel.trade; - final sendingState = widget.exchangeTradeViewModel.sendViewModel.state; - - return Offstage( - offstage: !(widget.exchangeTradeViewModel.isSendable && - !(sendingState is TransactionCommitted)), - child: LoadingPrimaryButton( - key: ValueKey('exchange_trade_page_send_from_cake_button_key'), - isDisabled: trade.inputAddress == null || - trade.inputAddress!.isEmpty || - sendingState is ExecutedSuccessfullyState, - isLoading: sendingState is IsExecutingState, - onPressed: _onPressedSendFromCakeWallet, - text: S.current.send_from_cake_wallet, - color: Theme.of(context).colorScheme.primary, - textColor: Theme.of(context).colorScheme.onPrimary, - ), - ); - }, - ), - ], - ), - ), - ); - } - - Future _onPressedSendFromCakeWallet() async { - final sendVM = widget.exchangeTradeViewModel.sendViewModel; - - if (sendVM.wallet.isHardwareWallet) { - if (!sendVM.hardwareWalletViewModel!.isConnected(sendVM.walletType)) { - await Navigator.of(context).pushNamed(Routes.connectDevices, - arguments: ConnectDevicePageParams( - walletType: sendVM.walletType, - hardwareWalletType: sendVM.wallet.walletInfo.hardwareWalletType!, - onConnectDevice: (context, _) { - sendVM.hardwareWalletViewModel!.initWallet(sendVM.wallet); - Navigator.of(context).pop(); - }, - )); - } else { - sendVM.hardwareWalletViewModel!.initWallet(sendVM.wallet); - } - } - - widget.exchangeTradeViewModel.confirmSending(); - } - - BuildContext? dialogContext; - BuildContext? loadingBottomSheetContext; - - void _setEffects() { - if (_effectsInstalled) { - return; - } - - _exchangeStateReaction = reaction( - (_) => this.widget.exchangeTradeViewModel.sendViewModel.state, - (ExecutionState state) async { - if (dialogContext != null && dialogContext?.mounted == true) { - Navigator.of(dialogContext!).pop(); - } - - if (state is! IsExecutingState && - loadingBottomSheetContext != null && - loadingBottomSheetContext!.mounted) { - Navigator.of(loadingBottomSheetContext!).pop(); - } - - if (state is FailureState) { - WidgetsBinding.instance.addPostFrameCallback((_) { - showPopUp( - context: context, - builder: (BuildContext popupContext) { - return AlertWithOneAction( - key: ValueKey('exchange_trade_page_send_failure_dialog_key'), - buttonKey: ValueKey('exchange_trade_page_send_failure_dialog_button_key'), - alertTitle: S.of(popupContext).error, - alertContent: state.error, - buttonText: S.of(popupContext).ok, - buttonAction: () => Navigator.of(popupContext).pop()); - }); - }); - } - - if (state is IsExecutingState) { - // wait a bit to avoid showing the loading dialog if transaction is failed - await Future.delayed(const Duration(milliseconds: 300)); - final currentState = widget.exchangeTradeViewModel.sendViewModel.state; - if (currentState is ExecutedSuccessfullyState || currentState is FailureState) { - return; - } - - WidgetsBinding.instance.addPostFrameCallback((_) { - if (context.mounted) { - showModalBottomSheet( - context: context, - isDismissible: false, - builder: (BuildContext context) { - loadingBottomSheetContext = context; - return LoadingBottomSheet( - titleText: S.of(context).generating_transaction, - ); - }, - ); - } - }); - } - - if (state is ExecutedSuccessfullyState) { - WidgetsBinding.instance.addPostFrameCallback((_) async { - final trade = widget.exchangeTradeViewModel.trade; - - final isSwapsXyz = trade.provider == ExchangeProviderDescription.swapsXyz; - final isEVMWallet = widget.exchangeTradeViewModel.sendViewModel.isEVMWallet; - - final amountValue = isSwapsXyz && - isEVMWallet && - !widget.exchangeTradeViewModel.isSwapsXYZCanSendFromExternal - ? trade.amount - : widget.exchangeTradeViewModel.sendViewModel.pendingTransaction!.amountFormatted; - - final fiatAmountValue = isSwapsXyz && - isEVMWallet && - !widget.exchangeTradeViewModel.isSwapsXYZCanSendFromExternal - ? widget.exchangeTradeViewModel.sendViewModel - .calculateTransactionFiatAmount(amountValue) - : widget.exchangeTradeViewModel.sendViewModel.pendingTransactionFiatAmountFormatted; - - if (context.mounted) { - final result = await showModalBottomSheet( - context: context, - isDismissible: false, - isScrollControlled: true, - builder: (bottomSheetContext) { - final sendVM = widget.exchangeTradeViewModel.sendViewModel; - - return ConfirmSendingBottomSheet( - key: ValueKey('exchange_trade_page_confirm_sending_bottom_sheet_key'), - footerType: FooterType.slideActionButton, - isSlideActionEnabled: sendVM.isReadyForSend, - walletType: sendVM.walletType, - titleText: S.of(bottomSheetContext).confirm_transaction, - titleIconPath: sendVM.selectedCryptoCurrency.iconPath, - currency: widget.exchangeTradeViewModel.sendViewModel.selectedCryptoCurrency, - amount: S.of(bottomSheetContext).send_amount, - amountValue: sendVM.amountParsingProxy - .getDisplayCryptoAmount(amountValue, sendVM.selectedCryptoCurrency), - explanation: sendVM.pendingTransactionAdditionalCostNotice, - fiatAmountValue: fiatAmountValue, - fee: isEVMCompatibleChain(sendVM.walletType) - ? S.of(bottomSheetContext).send_estimated_fee - : S.of(bottomSheetContext).send_fee, - feeValue: sendVM.amountParsingProxy - .asDisplayStringWithSymbol(sendVM.pendingTransaction!.fee), - feeFiatAmount: sendVM.pendingTransactionFeeFiatAmountFormatted, - outputs: sendVM.outputs, - onSlideActionComplete: () async { - if (bottomSheetContext.mounted && Navigator.canPop(bottomSheetContext)) - Navigator.of(bottomSheetContext).pop(true); - - sendVM.commitTransaction(context); - }, - amountParsingProxy: sendVM.amountParsingProxy, - ); - }, - ); - - if (result == null) widget.exchangeTradeViewModel.sendViewModel.dismissTransaction(); - } - }); - } - - if (state is TransactionCommitted) { - WidgetsBinding.instance.addPostFrameCallback( - (_) async { - if (!mounted) return; - - await showModalBottomSheet( - context: context, - isScrollControlled: true, - builder: (BuildContext bottomSheetContext) { - return InfoBottomSheet( - footerType: FooterType.singleActionButton, - titleText: S.of(bottomSheetContext).transaction_sent, - contentImage: 'assets/images/birthday_cake.png', - singleActionButtonText: S.of(bottomSheetContext).close, - singleActionButtonKey: ValueKey('send_page_sent_dialog_ok_button_key'), - onSingleActionButtonPressed: () { - Navigator.of(bottomSheetContext).pop(); - if (mounted) { - Navigator.of(context).pushNamedAndRemoveUntil( - Routes.dashboard, - (route) => false, - ); - } - RequestReviewHandler.requestReview(); - }, - ); - }, - ); - }, - ); - } - }, - ); - - _effectsInstalled = true; - } -} - -class _ExchangeTradeItemsCardSection extends StatelessWidget { - const _ExchangeTradeItemsCardSection({required this.viewModel}); - - final ExchangeTradeViewModel viewModel; - - @override - Widget build(BuildContext context) { - final firstExchangeCard = ExchangeTradeCardItemWidget( - isReceiveDetailsCard: true, - exchangeTradeViewModel: viewModel, - ); - - final secondExchangeCard = ExchangeTradeCardItemWidget( - isReceiveDetailsCard: false, - exchangeTradeViewModel: viewModel, - ); - - if (responsiveLayoutUtil.shouldRenderMobileUI) { - return MobileExchangeCardsSection( - firstExchangeCard: firstExchangeCard, - secondExchangeCard: secondExchangeCard, - ); - } - - return DesktopExchangeCardsSection( - firstExchangeCard: firstExchangeCard, - secondExchangeCard: secondExchangeCard, - ); - } -} diff --git a/lib/src/screens/exchange_trade/information_page.dart b/lib/src/screens/exchange_trade/information_page.dart deleted file mode 100644 index ebd2b3379..000000000 --- a/lib/src/screens/exchange_trade/information_page.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/widgets/primary_button.dart'; -import 'package:flutter/material.dart'; -import 'package:cake_wallet/src/widgets/alert_background.dart'; - -class InformationPage extends StatelessWidget { - InformationPage({required this.information, super.key}); - - final String information; - - @override - Widget build(BuildContext context) { - return AlertBackground( - child: Center( - child: Container( - margin: EdgeInsets.only(left: 24, right: 24), - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(30)), - color: Theme.of(context).colorScheme.surface, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Container( - padding: EdgeInsets.fromLTRB(24, 28, 24, 24), - child: Text( - information, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium, - ), - ), - Padding( - padding: EdgeInsets.fromLTRB(10, 0, 10, 10), - child: PrimaryButton( - key: ValueKey('information_page_got_it_button_key'), - onPressed: () => Navigator.of(context).pop(), - text: S.of(context).got_it, - color: Theme.of(context).colorScheme.surfaceContainer, - textColor: Theme.of(context).colorScheme.onSurface, - ), - ) - ], - ), - ), - )); - } -} diff --git a/lib/src/screens/exchange_trade/widgets/exchange_trade_card_item_widget.dart b/lib/src/screens/exchange_trade/widgets/exchange_trade_card_item_widget.dart deleted file mode 100644 index 347498ca7..000000000 --- a/lib/src/screens/exchange_trade/widgets/exchange_trade_card_item_widget.dart +++ /dev/null @@ -1,290 +0,0 @@ -import 'package:cake_wallet/entities/priority_for_wallet_type.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; -import 'package:cake_wallet/src/widgets/list_row.dart'; -import 'package:cake_wallet/src/widgets/picker.dart'; -import 'package:cake_wallet/utils/show_bar.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; -import 'package:cake_wallet/view_model/exchange/exchange_trade_view_model.dart'; -import 'package:cake_wallet/view_model/send/fees_view_model.dart'; -import 'package:cake_wallet/view_model/send/output.dart'; -import 'package:cw_core/transaction_priority.dart'; -import 'package:cw_core/wallet_type.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; - -class ExchangeTradeCardItemWidget extends StatelessWidget { - ExchangeTradeCardItemWidget({ - required this.isReceiveDetailsCard, - required this.exchangeTradeViewModel, - Key? key, - }) : feesViewModel = exchangeTradeViewModel.feesViewModel, - output = exchangeTradeViewModel.output; - - final Output output; - final bool isReceiveDetailsCard; - final FeesViewModel feesViewModel; - final ExchangeTradeViewModel exchangeTradeViewModel; - - @override - Widget build(BuildContext context) { - final copyImage = Image.asset( - 'assets/images/copy_content.png', - height: 16, - width: 16, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ); - - return Container( - width: double.infinity, - color: Colors.transparent, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox(height: 10), - ...exchangeTradeViewModel.items - .where((item) => item.isReceiveDetail == isReceiveDetailsCard) - .map( - (item) => TradeItemRowWidget( - title: item.title, - value: item.data, - isCopied: item.isCopied, - copyImage: copyImage, - ), - ) - .toList(), - if (!isReceiveDetailsCard && exchangeTradeViewModel.isSendable) ...[ - if (feesViewModel.hasFees) - FeeSelectionWidget( - feesViewModel: feesViewModel, - output: output, - onTap: () => pickTransactionPriority(context, output), - ), - if (exchangeTradeViewModel.sendViewModel.hasCoinControl) - CoinControlWidget( - onTap: () => Navigator.of(context).pushNamed( - Routes.unspentCoinsList, - arguments: exchangeTradeViewModel.sendViewModel.coinTypeToSpendFrom, - ), - ), - ], - ], - ), - ); - } - - Future pickTransactionPriority(BuildContext context, Output output) async { - final items = priorityForWalletType(feesViewModel.walletType); - final selectedItem = items.indexOf(feesViewModel.transactionPriority); - final customItemIndex = feesViewModel.getCustomPriorityIndex(items); - final isBitcoinWallet = feesViewModel.walletType == WalletType.bitcoin; - final maxCustomFeeRate = feesViewModel.maxCustomFeeRate?.toDouble(); - double? customFeeRate = isBitcoinWallet ? feesViewModel.customBitcoinFeeRate.toDouble() : null; - - await showPopUp( - context: context, - builder: (BuildContext context) { - int selectedIdx = selectedItem; - return StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return Picker( - items: items, - displayItem: (TransactionPriority priority) => - feesViewModel.displayFeeRate(priority, customFeeRate?.round()), - selectedAtIndex: selectedIdx, - customItemIndex: customItemIndex, - maxValue: maxCustomFeeRate, - title: S.of(context).please_select, - headerEnabled: !isBitcoinWallet, - closeOnItemSelected: !isBitcoinWallet, - mainAxisAlignment: MainAxisAlignment.center, - sliderValue: customFeeRate, - onSliderChanged: (double newValue) => setState(() => customFeeRate = newValue), - onItemSelected: (TransactionPriority priority) async { - feesViewModel.setTransactionPriority(priority); - setState(() => selectedIdx = items.indexOf(priority)); - await output.calculateEstimatedFee(); - if (feesViewModel.isLowFee) { - _showFeeAlert(context); - } - }, - ); - }, - ); - }, - ); - if (isBitcoinWallet) { - feesViewModel.customBitcoinFeeRate = customFeeRate!.round(); - if (feesViewModel.showAlertForCustomFeeRate()) { - _showFeeAlert(context); - } - } - } - - void _showFeeAlert(BuildContext context) async { - final confirmed = await showPopUp( - context: context, - builder: (dialogContext) { - return AlertWithTwoActions( - alertTitle: S.of(context).low_fee, - 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)); - }) ?? - false; - if (confirmed) { - feesViewModel.setDefaultTransactionPriority(); - } - } -} - -class TradeItemRowWidget extends StatelessWidget { - final String title; - final String value; - final bool isCopied; - final Image copyImage; - - const TradeItemRowWidget({ - required this.title, - required this.value, - required this.isCopied, - required this.copyImage, - super.key, - }); - - @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: GestureDetector( - onTap: () { - if (!isCopied) return; - Clipboard.setData(ClipboardData(text: value)); - showBar(context, S.of(context).transaction_details_copied(title)); - }, - child: ListRow( - padding: EdgeInsets.zero, - title: title, - value: value, - image: isCopied ? copyImage : null, - color: Colors.transparent, - hintTextColor: Theme.of(context).colorScheme.onSurfaceVariant, - mainTextColor: Theme.of(context).colorScheme.onSurface, - ), - ), - ); - } -} - -class FeeSelectionWidget extends StatelessWidget { - final FeesViewModel feesViewModel; - final Output output; - final VoidCallback onTap; - - const FeeSelectionWidget({ - required this.feesViewModel, - required this.output, - required this.onTap, - }); - - @override - Widget build(BuildContext context) { - return Observer( - builder: (_) => GestureDetector( - key: ValueKey('exchange_trade_card_item_widget_select_fee_priority_button_key'), - onTap: feesViewModel.hasFeesPriority ? onTap : () {}, - child: Container( - padding: EdgeInsets.only(top: 24), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - S.of(context).send_estimated_fee, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Text( - '${output.estimatedFee} ${feesViewModel.amountParsingProxy.getCryptoSymbol(feesViewModel.currency)}', - style: Theme.of(context).textTheme.bodySmall?.copyWith( - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - if (!feesViewModel.isFiatDisabled) - Padding( - padding: EdgeInsets.only(top: 5), - child: Text( - '${output.estimatedFeeFiatAmount} ${feesViewModel.fiat.title}', - style: Theme.of(context).textTheme.bodySmall?.copyWith( - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - ), - ], - ), - Padding( - padding: EdgeInsets.only(top: 2, left: 5), - child: Icon( - Icons.arrow_forward_ios, - size: 12, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - ], - ), - ], - ), - ), - ), - ); - } -} - -class CoinControlWidget extends StatelessWidget { - final VoidCallback onTap; - - const CoinControlWidget({required this.onTap}); - - @override - Widget build(BuildContext context) { - return GestureDetector( - key: ValueKey('exchange_trade_card_item_widget_unspent_coin_button_key'), - onTap: onTap, - child: Container( - color: Colors.transparent, - padding: EdgeInsets.only(top: 6), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - S.of(context).coin_control, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - Icon( - Icons.arrow_forward_ios, - size: 12, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ], - ), - ), - ); - } -} diff --git a/lib/src/screens/exchange_trade/widgets/timer_widget.dart b/lib/src/screens/exchange_trade/widgets/timer_widget.dart deleted file mode 100644 index 563cfdead..000000000 --- a/lib/src/screens/exchange_trade/widgets/timer_widget.dart +++ /dev/null @@ -1,79 +0,0 @@ -import 'package:flutter/material.dart'; -import 'dart:async'; -import 'package:cake_wallet/generated/i18n.dart'; - -class TimerWidget extends StatefulWidget { - TimerWidget(this.expiratedAt, {this.color = Colors.black}); - - final DateTime expiratedAt; - final Color color; - - @override - TimerWidgetState createState() => TimerWidgetState(); -} - -class TimerWidgetState extends State { - TimerWidgetState() - : _leftSeconds = 0, - _minutes = 0, - _seconds = 0, - _isExpired = false; - - int _leftSeconds; - int _minutes; - int _seconds; - bool _isExpired; - Timer? _timer; - - @override - void initState() { - super.initState(); - final start = DateTime.now(); - _isExpired = false; - _leftSeconds = widget.expiratedAt.difference(start).inSeconds; - _recalculate(); - - WidgetsBinding.instance.addPostFrameCallback((_) { - _timer = Timer.periodic(Duration(seconds: 1), (timer) { - if (_isExpired) { - timer.cancel(); - } - - _leftSeconds--; - _isExpired = _leftSeconds <= 0; - _recalculate(); - setState(() {}); - }); - }); - } - - @override - void dispose() { - _timer?.cancel(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return _isExpired - ? Text( - S.of(context).expired, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.errorContainer, - ), - ) - : Text( - S.of(context).time(_minutes.toString(), _seconds.toString()), - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontWeight: FontWeight.w500, - color: widget.color, - ), - ); - } - - void _recalculate() { - _minutes = _leftSeconds ~/ 60; - _seconds = _leftSeconds % 60; - } -} diff --git a/lib/src/screens/faq/faq_page.dart b/lib/src/screens/faq/faq_page.dart deleted file mode 100644 index 467431e18..000000000 --- a/lib/src/screens/faq/faq_page.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'dart:convert'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/screens/faq/faq_item.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/src/widgets/standard_list.dart'; -import 'package:cake_wallet/store/settings_store.dart'; - -class FaqPage extends BasePage { - FaqPage(this.settingsStore); - - final SettingsStore settingsStore; - - @override - String get title => S.current.faq; - - String get path => 'assets/faq/faq_' + settingsStore.languageCode + '.json'; - - @override - Widget body(BuildContext context) { - return Container( - padding: EdgeInsets.only(top: 12, left: 24), - child: FutureBuilder( - builder: (context, snapshot) { - final faqItems = jsonDecode(snapshot.data.toString()) as List; - - return SingleChildScrollView( - child: Column( - children: [ - StandardListSeparator(), - ListView.separated( - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - itemBuilder: (BuildContext context, int index) { - final title = faqItems[index]["question"].toString(); - final text = faqItems[index]["answer"].toString(); - - return FAQItem(title, text); - }, - separatorBuilder: (_, __) => StandardListSeparator(), - itemCount: faqItems?.length ?? 0, - ) - ], - ), - ); - }, - future: rootBundle.loadString(path), - ), - ); - } -} diff --git a/lib/src/screens/monero_accounts/monero_account_edit_or_create_page.dart b/lib/src/screens/monero_accounts/monero_account_edit_or_create_page.dart deleted file mode 100644 index c046a6dfb..000000000 --- a/lib/src/screens/monero_accounts/monero_account_edit_or_create_page.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:cake_wallet/core/execution_state.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/core/monero_account_label_validator.dart'; -import 'package:cake_wallet/view_model/monero_account_list/monero_account_edit_or_create_view_model.dart'; -import 'package:cake_wallet/src/widgets/primary_button.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; - -class MoneroAccountEditOrCreatePage extends BasePage { - MoneroAccountEditOrCreatePage({required this.moneroAccountCreationViewModel}) - : _formKey = GlobalKey(), - _textController = TextEditingController() { - _textController.addListener(() => moneroAccountCreationViewModel.label = _textController.text); - _textController.text = moneroAccountCreationViewModel.label; - } - - final MoneroAccountEditOrCreateViewModel moneroAccountCreationViewModel; - - @override - String get title => S.current.account; - - final GlobalKey _formKey; - final TextEditingController _textController; - - @override - Widget body(BuildContext context) => Form( - key: _formKey, - child: Container( - padding: EdgeInsets.all(24.0), - child: Column( - children: [ - Expanded( - child: Center( - child: BaseTextFormField( - controller: _textController, - hintText: S.of(context).account, - validator: MoneroLabelValidator(), - ), - ), - ), - Observer( - builder: (_) => LoadingPrimaryButton( - onPressed: () async { - if (_formKey.currentState != null && !_formKey.currentState!.validate()) { - return; - } - - await moneroAccountCreationViewModel.save(); - - if (context.mounted && Navigator.of(context).canPop()) { - Navigator.of(context).pop(_textController.text); - } - }, - text: moneroAccountCreationViewModel.isEdit - ? S.of(context).rename - : S.of(context).add, - color: Theme.of(context).colorScheme.primary, - textColor: Theme.of(context).colorScheme.onPrimary, - isLoading: moneroAccountCreationViewModel.state is IsExecutingState, - isDisabled: moneroAccountCreationViewModel.label?.isEmpty ?? true, - ), - ) - ], - ), - ), - ); -} diff --git a/lib/src/screens/monero_accounts/monero_account_list_page.dart b/lib/src/screens/monero_accounts/monero_account_list_page.dart deleted file mode 100644 index 85e00b369..000000000 --- a/lib/src/screens/monero_accounts/monero_account_list_page.dart +++ /dev/null @@ -1,95 +0,0 @@ -import 'package:cake_wallet/src/widgets/picker_inner_wrapper_widget.dart'; -import 'package:cake_wallet/src/widgets/section_divider.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/view_model/monero_account_list/monero_account_list_view_model.dart'; -import 'package:cake_wallet/src/screens/monero_accounts/widgets/account_tile.dart'; - -class MoneroAccountListPage extends StatelessWidget { - MoneroAccountListPage({required this.accountListViewModel}); - - final MoneroAccountListViewModel accountListViewModel; - final ScrollController controller = ScrollController(); - - @override - Widget build(BuildContext context) { - double itemHeight = 65; - double buttonHeight = 62; - - return Observer(builder: (_) { - final accounts = accountListViewModel.accounts; - - return PickerInnerWrapperWidget( - title: S.of(context).choose_account, - itemsHeight: (itemHeight * accounts.length) + buttonHeight, - children: [ - Expanded( - child: Scrollbar( - controller: controller, - child: ListView.separated( - padding: EdgeInsets.zero, - controller: controller, - separatorBuilder: (context, index) => const HorizontalSectionDivider(), - itemCount: accounts.length, - itemBuilder: (context, index) { - final account = accounts[index]; - - return AccountTile( - isCurrent: account.isSelected, - accountName: account.label, - accountBalance: account.balance ?? '0.00', - currency: accountListViewModel.currency.toString(), - onTap: () { - if (account.isSelected) { - return; - } - - accountListViewModel.select(account); - Navigator.of(context).pop(); - }, - onEdit: () async => await Navigator.of(context).pushNamed( - Routes.accountCreation, - arguments: account, - ), - ); - }, - ), - )), - GestureDetector( - onTap: () async => await Navigator.of(context).pushNamed(Routes.accountCreation), - child: Container( - height: buttonHeight, - color: Theme.of(context).colorScheme.primary, - padding: EdgeInsets.symmetric(horizontal: 24), - child: Center( - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Icon( - Icons.add, - color: Theme.of(context).colorScheme.onPrimary, - ), - Padding( - padding: EdgeInsets.only(left: 5), - child: Text( - S.of(context).create_new_account, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 15, - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onPrimary, - decoration: TextDecoration.none, - ), - ), - ) - ], - ), - ), - ), - ) - ], - ); - }); - } -} diff --git a/lib/src/screens/monero_accounts/widgets/account_tile.dart b/lib/src/screens/monero_accounts/widgets/account_tile.dart deleted file mode 100644 index 7a46a0f7c..000000000 --- a/lib/src/screens/monero_accounts/widgets/account_tile.dart +++ /dev/null @@ -1,96 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_slidable/flutter_slidable.dart'; -import 'package:cake_wallet/generated/i18n.dart'; - -class AccountTile extends StatelessWidget { - AccountTile({ - required this.isCurrent, - required this.accountName, - this.accountBalance, - required this.currency, - required this.onTap, - required this.onEdit, - }); - - final bool isCurrent; - final String accountName; - final String? accountBalance; - final String currency; - final Function() onTap; - final Function() onEdit; - - @override - Widget build(BuildContext context) { - final color = isCurrent - ? Theme.of(context).colorScheme.surfaceContainer - : Theme.of(context).colorScheme.surfaceContainerHighest; - final textColor = isCurrent - ? Theme.of(context).colorScheme.onSurface - : Theme.of(context).colorScheme.onSurfaceVariant; - - final Widget cell = GestureDetector( - onTap: onTap, - child: Container( - height: 60, - width: double.infinity, - padding: EdgeInsets.only(left: 24, right: 24), - color: color, - child: Wrap( - direction: Axis.horizontal, - alignment: WrapAlignment.spaceBetween, - runAlignment: WrapAlignment.center, - crossAxisAlignment: WrapCrossAlignment.center, - children: [ - Container( - child: Text( - accountName, - style: Theme.of(context).textTheme.titleMedium!.copyWith( - fontSize: 18, - fontWeight: FontWeight.w600, - color: textColor, - decoration: TextDecoration.none, - ), - ), - ), - if (accountBalance != null) - Container( - child: Text( - '${accountBalance.toString()} $currency', - textAlign: TextAlign.end, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 15, - fontWeight: FontWeight.w600, - color: isCurrent - ? Theme.of(context).colorScheme.onSurface - : Theme.of(context).colorScheme.onSurfaceVariant, - decoration: TextDecoration.none, - ), - ), - ), - ], - ), - ), - ); - - // return cell; - return Slidable( - key: Key(accountName), - child: cell, - endActionPane: _actionPane(context), - ); - } - - ActionPane _actionPane(BuildContext context) => ActionPane( - motion: const ScrollMotion(), - extentRatio: 0.3, - children: [ - SlidableAction( - onPressed: (_) => onEdit.call(), - backgroundColor: Theme.of(context).colorScheme.primaryContainer, - foregroundColor: Theme.of(context).colorScheme.onPrimaryContainer, - icon: Icons.edit, - label: S.of(context).edit, - ), - ], - ); -} diff --git a/lib/src/screens/nano_accounts/nano_account_edit_or_create_page.dart b/lib/src/screens/nano_accounts/nano_account_edit_or_create_page.dart deleted file mode 100644 index ad5ff3cc8..000000000 --- a/lib/src/screens/nano_accounts/nano_account_edit_or_create_page.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:cake_wallet/core/execution_state.dart'; -import 'package:cake_wallet/view_model/nano_account_list/nano_account_edit_or_create_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/core/monero_account_label_validator.dart'; -import 'package:cake_wallet/view_model/monero_account_list/monero_account_edit_or_create_view_model.dart'; -import 'package:cake_wallet/src/widgets/primary_button.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; - -class NanoAccountEditOrCreatePage extends BasePage { - NanoAccountEditOrCreatePage({required this.nanoAccountCreationViewModel}) - : _formKey = GlobalKey(), - _textController = TextEditingController() { - _textController.addListener(() => nanoAccountCreationViewModel.label = _textController.text); - _textController.text = nanoAccountCreationViewModel.label; - } - - final NanoAccountEditOrCreateViewModel nanoAccountCreationViewModel; - - @override - String get title => S.current.account; - - final GlobalKey _formKey; - final TextEditingController _textController; - - @override - Widget body(BuildContext context) => Form( - key: _formKey, - child: Container( - padding: EdgeInsets.all(24.0), - child: Column( - children: [ - Expanded( - child: Center( - child: BaseTextFormField( - controller: _textController, - hintText: S.of(context).account, - validator: MoneroLabelValidator(), - ), - ), - ), - Observer( - builder: (_) => LoadingPrimaryButton( - onPressed: () async { - if (_formKey.currentState != null && !_formKey.currentState!.validate()) { - return; - } - - await nanoAccountCreationViewModel.save(); - - Navigator.of(context).pop(_textController.text); - }, - text: nanoAccountCreationViewModel.isEdit - ? S.of(context).rename - : S.of(context).add, - color: Theme.of(context).colorScheme.primary, - textColor: Theme.of(context).colorScheme.onPrimary, - isLoading: nanoAccountCreationViewModel.state is IsExecutingState, - isDisabled: nanoAccountCreationViewModel.label?.isEmpty ?? true, - ), - ), - ], - ), - ), - ); -} diff --git a/lib/src/screens/nano_accounts/nano_account_list_page.dart b/lib/src/screens/nano_accounts/nano_account_list_page.dart deleted file mode 100644 index c70dc89dd..000000000 --- a/lib/src/screens/nano_accounts/nano_account_list_page.dart +++ /dev/null @@ -1,92 +0,0 @@ -import 'package:cake_wallet/src/widgets/picker_inner_wrapper_widget.dart'; -import 'package:cake_wallet/src/widgets/section_divider.dart'; -import 'package:cake_wallet/view_model/nano_account_list/nano_account_list_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/screens/monero_accounts/widgets/account_tile.dart'; - -class NanoAccountListPage extends StatelessWidget { - NanoAccountListPage({required this.accountListViewModel}); - - final NanoAccountListViewModel accountListViewModel; - final ScrollController controller = ScrollController(); - - @override - Widget build(BuildContext context) { - double itemHeight = 80; - double buttonHeight = 62; - - return Observer(builder: (_) { - final accounts = accountListViewModel.accounts; - return PickerInnerWrapperWidget( - title: S.of(context).choose_account, - itemsHeight: (itemHeight * accounts.length) + buttonHeight, - children: [ - Expanded( - child: Scrollbar( - controller: controller, - child: ListView.separated( - padding: EdgeInsets.zero, - controller: controller, - separatorBuilder: (context, index) => const VerticalSectionDivider(), - itemCount: accounts.length, - itemBuilder: (context, index) { - final account = accounts[index]; - - return AccountTile( - isCurrent: account.isSelected, - accountName: account.label, - accountBalance: account.balance ?? '0.00', - currency: accountListViewModel.currency.toString(), - onTap: () { - if (account.isSelected) { - return; - } - - accountListViewModel.select(account); - Navigator.of(context).pop(); - }, - onEdit: () async => await Navigator.of(context) - .pushNamed(Routes.nanoAccountCreation, arguments: account), - ); - }, - ), - )), - GestureDetector( - onTap: () async => await Navigator.of(context).pushNamed(Routes.nanoAccountCreation), - child: Container( - height: buttonHeight, - color: Theme.of(context).colorScheme.primary, - padding: EdgeInsets.symmetric(horizontal: 24), - child: Center( - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Icon( - Icons.add, - color: Theme.of(context).colorScheme.onPrimary, - ), - Padding( - padding: EdgeInsets.only(left: 5), - child: Text( - S.of(context).create_new_account, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: Theme.of(context).colorScheme.onPrimary, - fontSize: 15, - fontWeight: FontWeight.w600, - decoration: TextDecoration.none, - ), - ), - ) - ], - ), - ), - ), - ) - ], - ); - }); - } -} diff --git a/lib/src/screens/nano_accounts/widgets/account_tile.dart b/lib/src/screens/nano_accounts/widgets/account_tile.dart deleted file mode 100644 index da8080e70..000000000 --- a/lib/src/screens/nano_accounts/widgets/account_tile.dart +++ /dev/null @@ -1,89 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_slidable/flutter_slidable.dart'; -import 'package:cake_wallet/generated/i18n.dart'; - -class AccountTile extends StatelessWidget { - AccountTile( - {required this.isCurrent, - required this.accountName, - this.accountBalance, - required this.currency, - required this.onTap, - required this.onEdit}); - - final bool isCurrent; - final String accountName; - final String? accountBalance; - final String currency; - final Function() onTap; - final Function() onEdit; - - @override - Widget build(BuildContext context) { - final color = isCurrent - ? Theme.of(context).colorScheme.primaryContainer - : Theme.of(context).colorScheme.surfaceContainerHighest; - final textColor = isCurrent - ? Theme.of(context).colorScheme.onPrimaryContainer - : Theme.of(context).colorScheme.onSurfaceVariant; - - final Widget cell = GestureDetector( - onTap: onTap, - child: Container( - height: 77, - width: double.infinity, - padding: EdgeInsets.only(left: 24, right: 24), - color: color, - child: Wrap( - direction: Axis.horizontal, - alignment: WrapAlignment.spaceBetween, - runAlignment: WrapAlignment.center, - crossAxisAlignment: WrapCrossAlignment.center, - children: [ - Container( - child: Text( - accountName, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 18, - fontWeight: FontWeight.w600, - color: textColor, - decoration: TextDecoration.none, - ), - ), - ), - if (accountBalance != null) - Container( - child: Text( - '${accountBalance.toString()} $currency', - textAlign: TextAlign.end, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 15, - fontWeight: FontWeight.w600, - color: Theme.of(context).textTheme.headlineMedium!.color!, - decoration: TextDecoration.none, - ), - ), - ), - ], - ), - ), - ); - - // return cell; - return Slidable(key: Key(accountName), child: cell, endActionPane: _actionPane(context)); - } - - ActionPane _actionPane(BuildContext context) => ActionPane( - motion: const ScrollMotion(), - extentRatio: 0.3, - children: [ - SlidableAction( - onPressed: (_) => onEdit.call(), - backgroundColor: Theme.of(context).colorScheme.primaryContainer, - foregroundColor: Theme.of(context).colorScheme.onPrimaryContainer, - icon: Icons.edit, - label: S.of(context).edit, - ), - ], - ); -} diff --git a/lib/src/screens/nodes/widgets/node_indicator.dart b/lib/src/screens/nodes/widgets/node_indicator.dart deleted file mode 100644 index 0b6677e37..000000000 --- a/lib/src/screens/nodes/widgets/node_indicator.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:cake_wallet/themes/core/custom_theme_colors.dart'; -import 'package:flutter/material.dart'; - -class NodeIndicator extends StatelessWidget { - const NodeIndicator({this.isLive = false}); - - final bool isLive; - - @override - Widget build(BuildContext context) { - return Container( - width: 12.0, - height: 12.0, - decoration: BoxDecoration( - shape: BoxShape.circle, - color: isLive ? CustomThemeColors.syncGreen : Theme.of(context).colorScheme.errorContainer, - ), - ); - } -} diff --git a/lib/src/screens/receive/address_list_page.dart b/lib/src/screens/receive/address_list_page.dart deleted file mode 100644 index f310a5546..000000000 --- a/lib/src/screens/receive/address_list_page.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart'; -import 'package:cake_wallet/src/screens/receive/widgets/address_list.dart'; -import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; - -class AddressListPage extends StatelessWidget { - AddressListPage(this.addressListViewModel); - - final WalletAddressListViewModel addressListViewModel; - - @override - String get title => S.current.accounts_subaddresses; - - @override - Widget build(BuildContext context) { - return Column( - children: [ - ModalTopBar( - title: S.of(context).accounts_subaddresses, - leadingIcon: Icon(Icons.arrow_back_ios_new), - leadingSemanticLabel: S.of(context).seed_alert_back, - onLeadingPressed: Navigator.of(context).pop, - ), - Expanded( - child: SingleChildScrollView( - controller: ModalScrollController.of(context), - child: Column( - children: [ - AddressList( - addressListViewModel: addressListViewModel, - onSelect: (String address) async { - Navigator.of(context).pop(address); - }, - ), - ], - ), - ), - ), - ], - ); - } -} diff --git a/lib/src/screens/receive/anonpay_invoice_page.dart b/lib/src/screens/receive/anonpay_invoice_page.dart deleted file mode 100644 index f71488b4d..000000000 --- a/lib/src/screens/receive/anonpay_invoice_page.dart +++ /dev/null @@ -1,253 +0,0 @@ -import 'package:cake_wallet/anonpay/anonpay_donation_link_info.dart'; -import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart'; -import 'package:cake_wallet/core/execution_state.dart'; -import 'package:cake_wallet/di.dart'; -import 'package:cake_wallet/entities/preferences_key.dart'; -import 'package:cake_wallet/src/screens/receive/anonpay_receive_page.dart'; -import 'package:cake_wallet/utils/feature_flag.dart'; -import 'package:cw_core/receive_page_option.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/src/screens/dashboard/widgets/present_receive_option_picker.dart'; -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/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'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:keyboard_actions/keyboard_actions.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/src/widgets/trail_button.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/widgets/primary_button.dart'; -import 'package:cake_wallet/src/widgets/scrollable_with_bottom_section.dart'; -import 'package:mobx/mobx.dart'; -import 'package:shared_preferences/shared_preferences.dart'; - -class AnonPayInvoicePage extends BasePage { - AnonPayInvoicePage( - this.anonInvoicePageViewModel, - this.receiveOptionViewModel, - ) : _amountFocusNode = FocusNode() {} - - final _nameController = TextEditingController(); - final _emailController = TextEditingController(); - final _descriptionController = TextEditingController(); - final _amountController = TextEditingController(); - final FocusNode _amountFocusNode; - - final AnonInvoicePageViewModel anonInvoicePageViewModel; - final ReceiveOptionViewModel receiveOptionViewModel; - final _formKey = GlobalKey(); - - bool effectsInstalled = false; - - @override - bool get gradientAll => true; - - @override - bool get resizeToAvoidBottomInset => false; - - @override - bool get extendBodyBehindAppBar => true; - - @override - AppBarStyle get appBarStyle => - FeatureFlag.hasNewUiExtraPages ? AppBarStyle.completelyTransparent : AppBarStyle.transparent; - - @override - void onClose(BuildContext context) => FeatureFlag.hasNewUiExtraPages - ? Navigator.of(context, rootNavigator: true).pop() - : Navigator.popUntil(context, (route) => route.isFirst); - - @override - Widget middle(BuildContext context) => PresentReceiveOptionPicker( - receiveOptionViewModel: receiveOptionViewModel, color: titleColor(context)); - - @override - Widget trailing(BuildContext context) => TrailButton( - caption: S.of(context).clear, - onPressed: () { - _formKey.currentState?.reset(); - 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).colorScheme.surfaceVariant, - nextFocus: false, - actions: [ - KeyboardActionsItem( - focusNode: _amountFocusNode, - toolbarButtons: [(_) => KeyboardDoneButton()], - ), - ], - ), - child: Container( - color: Theme.of(context).colorScheme.surface, - child: ScrollableWithBottomSection( - contentPadding: EdgeInsets.only(bottom: 24), - content: Container( - decoration: responsiveLayoutUtil.shouldRenderMobileUI - ? BoxDecoration( - borderRadius: BorderRadius.only( - bottomLeft: Radius.circular(24), - bottomRight: Radius.circular(24), - ), - color: Theme.of(context).colorScheme.surfaceContainerLow, - ) - : 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: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant, - fontWeight: FontWeight.w500, - ), - ), - ), - ), - LoadingPrimaryButton( - text: isInvoice - ? S.of(context).create_invoice - : S.of(context).create_donation_link, - onPressed: () { - FocusScope.of(context).unfocus(); - 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).colorScheme.primary, - textColor: Theme.of(context).colorScheme.onPrimary, - isLoading: anonInvoicePageViewModel.state is IsExecutingState, - ), - ], - ); - }), - ), - ), - ), - ); - } - - void _setReactions(BuildContext context) { - if (effectsInstalled) { - return; - } - - reaction((_) => receiveOptionViewModel.selectedReceiveOption, (ReceivePageOption option) { - switch (option) { - case ReceivePageOption.mainnet: - Navigator.popAndPushNamed(context, Routes.addressPage); - break; - case ReceivePageOption.anonPayDonationLink: - final sharedPreferences = getIt.get(); - final clearnetUrl = sharedPreferences.getString(PreferencesKey.clearnetDonationLink); - final onionUrl = sharedPreferences.getString(PreferencesKey.onionDonationLink); - final donationWalletName = - sharedPreferences.getString(PreferencesKey.donationLinkWalletName); - - if (clearnetUrl != null && - onionUrl != null && - anonInvoicePageViewModel.currentWalletName == donationWalletName) { - Navigator.pushReplacementNamed( - context, - Routes.anonPayReceivePage, - arguments: AnonPayReceivePageArgs( - invoiceInfo: AnonpayDonationLinkInfo( - clearnetUrl: clearnetUrl, - onionUrl: onionUrl, - address: anonInvoicePageViewModel.address, - ), - qrImage: anonInvoicePageViewModel.qrImage, - ), - ); - } - break; - default: - } - }); - - reaction((_) => anonInvoicePageViewModel.state, (ExecutionState state) { - if (state is ExecutedSuccessfullyState) { - Navigator.pushNamed( - context, - Routes.anonPayReceivePage, - arguments: AnonPayReceivePageArgs( - invoiceInfo: state.payload as AnonpayInvoiceInfo, - qrImage: anonInvoicePageViewModel.qrImage, - ), - ); - } - if (state is FailureState) { - showPopUp( - context: context, - builder: (BuildContext context) { - return AlertWithOneAction( - alertTitle: S.of(context).error, - alertContent: state.error.toString(), - buttonText: S.of(context).ok, - buttonAction: () => Navigator.of(context).pop()); - }); - } - }); - - effectsInstalled = true; - } -} diff --git a/lib/src/screens/receive/anonpay_receive_page.dart b/lib/src/screens/receive/anonpay_receive_page.dart deleted file mode 100644 index 5b6ecc843..000000000 --- a/lib/src/screens/receive/anonpay_receive_page.dart +++ /dev/null @@ -1,158 +0,0 @@ -import 'package:cake_wallet/anonpay/anonpay_info_base.dart'; -import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart'; -import 'package:cake_wallet/entities/qr_view_data.dart'; -import 'package:cw_core/receive_page_option.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/src/widgets/gradient_background.dart'; -import 'package:cake_wallet/src/screens/receive/widgets/anonpay_status_section.dart'; -import 'package:cake_wallet/src/screens/receive/widgets/qr_image.dart'; -import 'package:cake_wallet/src/screens/receive/widgets/copy_link_item.dart'; -import 'package:cake_wallet/utils/brightness_util.dart'; -import 'package:flutter/material.dart'; -import 'package:qr_flutter/qr_flutter.dart' as qr; - -class AnonPayReceivePageArgs { - final AnonpayInfoBase invoiceInfo; - final String? qrImage; - - AnonPayReceivePageArgs({required this.invoiceInfo, this.qrImage}); -} - -class AnonPayReceivePage extends BasePage { - AnonPayReceivePage({required this.args}) : invoiceInfo = args.invoiceInfo; - - final AnonPayReceivePageArgs args; - final AnonpayInfoBase invoiceInfo; - - @override - String get title => S.current.receive; - - @override - bool get gradientBackground => true; - - @override - bool get resizeToAvoidBottomInset => false; - - @override - void onClose(BuildContext context) => Navigator.popUntil(context, (route) => route.isFirst); - - @override - Widget middle(BuildContext context) { - return Column( - children: [ - Text( - title, - style: Theme.of(context).textTheme.bodyLarge!.copyWith( - fontSize: 18.0, - fontWeight: FontWeight.bold, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - Text( - invoiceInfo is AnonpayInvoiceInfo - ? ReceivePageOption.anonPayInvoice.toString() - : ReceivePageOption.anonPayDonationLink.toString(), - style: Theme.of(context).textTheme.bodySmall!.copyWith( - fontSize: 10.0, - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ) - ], - ); - } - - @override - Widget? trailing(BuildContext context) { - if (invoiceInfo is AnonpayInvoiceInfo) { - return null; - } - - return Material( - color: Colors.transparent, - child: IconButton( - onPressed: () => Navigator.popAndPushNamed( - context, - Routes.anonPayInvoicePage, - arguments: [invoiceInfo.address, ReceivePageOption.anonPayDonationLink], - ), - icon: Icon( - Icons.edit, - color: pageIconColor(context), - size: 22.0, - ), - ), - ); - } - - @override - Widget Function(BuildContext, Widget) get rootWrapper => - (BuildContext context, Widget scaffold) => GradientBackground(scaffold: scaffold); - - @override - Widget body(BuildContext context) { - return SingleChildScrollView( - child: Column( - children: [ - SizedBox(height: 24), - if (invoiceInfo is AnonpayInvoiceInfo) - AnonInvoiceStatusSection(invoiceInfo: invoiceInfo as AnonpayInvoiceInfo), - Padding( - padding: EdgeInsets.fromLTRB(24, 50, 24, 24), - child: ConstrainedBox( - constraints: BoxConstraints( - maxWidth: MediaQuery.of(context).size.width * 0.5, - ), - child: GestureDetector( - onTap: () async { - BrightnessUtil.changeBrightnessForFunction(() async { - await Navigator.pushNamed(context, Routes.fullscreenQR, - arguments: QrViewData( - data: invoiceInfo.clearnetUrl, - version: qr.QrVersions.auto, - embeddedImagePath: args.qrImage, - )); - }); - }, - child: Hero( - tag: Key(invoiceInfo.clearnetUrl), - child: Center( - child: AspectRatio( - aspectRatio: 1.0, - child: Container( - padding: EdgeInsets.all(5), - decoration: BoxDecoration( - border: Border.all( - width: 3, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - child: QrImage( - data: invoiceInfo.clearnetUrl, - version: qr.QrVersions.auto, - embeddedImagePath: args.qrImage, - size: 230, - ), - ), - ), - ), - ), - ), - ), - ), - SizedBox(height: 24), - Column( - children: [ - CopyLinkItem(url: invoiceInfo.clearnetUrl, title: S.of(context).clearnet_link), - SizedBox(height: 16), - CopyLinkItem(url: invoiceInfo.onionUrl, title: S.of(context).onion_link), - ], - ), - SizedBox(height: 100), - ], - ), - ); - } -} diff --git a/lib/src/screens/receive/receive_page.dart b/lib/src/screens/receive/receive_page.dart deleted file mode 100644 index 030c10a7f..000000000 --- a/lib/src/screens/receive/receive_page.dart +++ /dev/null @@ -1,125 +0,0 @@ -import 'package:cake_wallet/src/screens/receive/widgets/address_list.dart'; -import 'package:cake_wallet/src/widgets/gradient_background.dart'; -import 'package:cake_wallet/src/widgets/keyboard_done_button.dart'; -import 'package:cake_wallet/utils/share_util.dart'; -import 'package:flutter/material.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/src/screens/receive/widgets/qr_widget.dart'; -import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart'; -import 'package:keyboard_actions/keyboard_actions.dart'; - -class ReceivePage extends BasePage { - ReceivePage({required this.addressListViewModel}) - : _cryptoAmountFocus = FocusNode(), - _amountController = TextEditingController(), - _formKey = GlobalKey() { - _amountController.addListener(() { - if (_formKey.currentState!.validate()) { - addressListViewModel.changeAmount(_amountController.text); - } - }); - } - - final WalletAddressListViewModel addressListViewModel; - final TextEditingController _amountController; - final GlobalKey _formKey; - static const _heroTag = 'receive_page'; - - @override - String get title => S.current.receive; - - @override - bool get gradientBackground => true; - - @override - bool get resizeToAvoidBottomInset => true; - - final FocusNode _cryptoAmountFocus; - - @override - Widget middle(BuildContext context) { - return Text( - title, - style: Theme.of(context).textTheme.titleMedium?.copyWith( - fontSize: 18.0, - fontWeight: FontWeight.bold, - color: pageIconColor(context), - ), - ); - } - - @override - Widget Function(BuildContext, Widget) get rootWrapper => - (BuildContext context, Widget scaffold) => GradientBackground(scaffold: scaffold); - - @override - Widget trailing(BuildContext context) { - return Material( - color: Colors.transparent, - child: Semantics( - label: S.of(context).share, - child: IconButton( - padding: EdgeInsets.zero, - constraints: BoxConstraints(), - highlightColor: Colors.transparent, - splashColor: Colors.transparent, - iconSize: 25, - onPressed: () => ShareUtil.share( - text: addressListViewModel.uri.toString(), - context: context, - ), - icon: Icon( - Icons.share, - size: 20, - color: pageIconColor(context), - ), - ), - ), - ); - } - - @override - Widget body(BuildContext context) => KeyboardActions( - config: KeyboardActionsConfig( - keyboardActionsPlatform: KeyboardActionsPlatform.IOS, - keyboardBarColor: Theme.of(context).colorScheme.surface, - nextFocus: false, - actions: [ - KeyboardActionsItem( - focusNode: _cryptoAmountFocus, - toolbarButtons: [(_) => KeyboardDoneButton()], - ) - ]), - child: SingleChildScrollView( - child: Column( - children: [ - Padding( - padding: EdgeInsets.fromLTRB(24, 50, 24, 24), - child: QRWidget( - addressListViewModel: addressListViewModel, - formKey: _formKey, - heroTag: _heroTag, - amountTextFieldFocusNode: _cryptoAmountFocus, - amountController: _amountController, - ), - ), - AddressList(addressListViewModel: addressListViewModel), - Padding( - padding: EdgeInsets.fromLTRB(24, 24, 24, 32), - child: Text( - addressListViewModel.isSilentPayments - ? S.of(context).silent_payments_disclaimer - : S.of(context).electrum_address_disclaimer, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 15, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - ), - ], - ), - ), - ); -} diff --git a/lib/src/screens/receive/widgets/address_cell.dart b/lib/src/screens/receive/widgets/address_cell.dart deleted file mode 100644 index fe26d87f0..000000000 --- a/lib/src/screens/receive/widgets/address_cell.dart +++ /dev/null @@ -1,231 +0,0 @@ -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/utils/address_formatter.dart'; -import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_item.dart'; -import 'package:cw_core/wallet_type.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_slidable/flutter_slidable.dart'; - -class AddressCell extends StatelessWidget { - AddressCell({ - required this.address, - required this.name, - required this.isCurrent, - required this.isPrimary, - required this.backgroundColor, - required this.textColor, - required this.walletType, - this.onTap, - this.onEdit, - this.onHide, - this.isHidden = false, - this.onDelete, - this.txCount, - this.balance, - this.isChange = false, - this.hasBalance = false, - this.hasReceived = false, - }); - - factory AddressCell.fromItem( - WalletAddressListItem item, { - required bool isCurrent, - required Color backgroundColor, - required Color textColor, - required WalletType walletType, - Function(String)? onTap, - bool hasBalance = false, - bool hasReceived = false, - Function()? onEdit, - Function()? onHide, - bool isHidden = false, - Function()? onDelete, - }) => - AddressCell( - address: item.address, - name: item.name ?? '', - isCurrent: isCurrent, - isPrimary: item.isPrimary, - backgroundColor: backgroundColor, - textColor: textColor, - walletType: walletType, - onTap: onTap, - onEdit: onEdit, - onHide: onHide, - isHidden: isHidden, - onDelete: onDelete, - txCount: item.txCount, - balance: item.balance, - isChange: item.isChange, - hasBalance: hasBalance, - hasReceived: hasReceived, - ); - - final String address; - final String name; - final bool isCurrent; - final bool isPrimary; - final Color backgroundColor; - final Color textColor; - final WalletType walletType; - final Function(String)? onTap; - final Function()? onEdit; - final Function()? onHide; - final bool isHidden; - final Function()? onDelete; - final int? txCount; - final String? balance; - final bool isChange; - final bool hasBalance; - final bool hasReceived; - - @override - Widget build(BuildContext context) { - final Widget cell = InkWell( - onTap: () => onTap?.call(address), - child: Container( - width: double.infinity, - color: backgroundColor, - padding: EdgeInsets.only(left: 24, right: 24, top: 20, bottom: 20), - child: Row( - children: [ - Expanded( - child: Column( - children: [ - Row( - mainAxisAlignment: name.isNotEmpty - ? MainAxisAlignment.spaceBetween - : MainAxisAlignment.center, - mainAxisSize: MainAxisSize.max, - children: [ - Row( - children: [ - if (isChange) - Padding( - padding: const EdgeInsets.only(right: 8.0), - child: Container( - height: 20, - padding: EdgeInsets.all(4), - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(8.5)), - color: textColor, - ), - alignment: Alignment.center, - child: Text( - S.of(context).unspent_change, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: backgroundColor, - fontSize: 10, - fontWeight: FontWeight.w600, - ), - ), - ), - ), - if (name.isNotEmpty) - Text( - '$name', - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontWeight: FontWeight.w600, - color: textColor, - ), - ), - ], - ), - Flexible( - child: AddressFormatter.buildSegmentedAddress( - address: address, - walletType: walletType, - shouldTruncate: name.isNotEmpty || address.length > 43, - evenTextStyle: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: isChange ? 10 : 14, - color: textColor, - ), - ), - ), - ], - ), - if (hasBalance || hasReceived) - Padding( - padding: const EdgeInsets.only(top: 8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - mainAxisSize: MainAxisSize.max, - children: [ - Text( - '${hasReceived ? S.of(context).received : S.of(context).balance}: $balance', - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 16, - fontWeight: FontWeight.w600, - color: textColor, - ), - ), - Text( - '${S.of(context).transactions.toLowerCase()}: $txCount', - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 16, - fontWeight: FontWeight.w600, - color: textColor, - ), - ), - ], - ), - ), - ], - ), - ), - ], - ), - )); - return onEdit == null - ? cell - : Semantics( - label: S.of(context).slidable, - selected: isCurrent, - enabled: !isCurrent, - child: Slidable( - key: Key(address), - startActionPane: _actionPaneStart(context), - endActionPane: _actionPaneEnd(context), - child: cell, - ), - ); - } - - ActionPane _actionPaneEnd(BuildContext context) => ActionPane( - motion: const ScrollMotion(), - extentRatio: onDelete != null ? 0.4 : 0.3, - children: [ - SlidableAction( - onPressed: (_) => onHide?.call(), - backgroundColor: isHidden - ? Theme.of(context).colorScheme.primaryContainer - : Theme.of(context).colorScheme.errorContainer, - foregroundColor: Theme.of(context).colorScheme.onPrimaryContainer, - icon: isHidden ? CupertinoIcons.arrow_left : CupertinoIcons.arrow_right, - label: isHidden ? S.of(context).show : S.of(context).hide, - ), - ], - ); - - ActionPane _actionPaneStart(BuildContext context) => ActionPane( - motion: const ScrollMotion(), - extentRatio: onDelete != null ? 0.4 : 0.3, - children: [ - SlidableAction( - onPressed: (_) => onEdit?.call(), - backgroundColor: Theme.of(context).colorScheme.primaryContainer, - foregroundColor: Theme.of(context).colorScheme.onPrimaryContainer, - icon: Icons.edit, - label: S.of(context).edit, - ), - if (onDelete != null) - SlidableAction( - onPressed: (_) => onDelete!.call(), - backgroundColor: Theme.of(context).colorScheme.errorContainer, - foregroundColor: Theme.of(context).colorScheme.onErrorContainer, - icon: Icons.delete, - label: S.of(context).delete, - ), - ], - ); -} diff --git a/lib/src/screens/receive/widgets/address_list.dart b/lib/src/screens/receive/widgets/address_list.dart deleted file mode 100644 index 2f44b9a47..000000000 --- a/lib/src/screens/receive/widgets/address_list.dart +++ /dev/null @@ -1,209 +0,0 @@ -import 'package:cake_wallet/di.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/src/screens/monero_accounts/monero_account_list_page.dart'; -import 'package:cake_wallet/src/screens/nano_accounts/nano_account_list_page.dart'; -import 'package:cake_wallet/src/screens/receive/widgets/address_cell.dart'; -import 'package:cake_wallet/src/screens/receive/widgets/header_tile.dart'; -import 'package:cake_wallet/src/widgets/section_divider.dart'; -import 'package:cake_wallet/themes/core/material_base_theme.dart'; -import 'package:cake_wallet/utils/list_item.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; -import 'package:cake_wallet/view_model/wallet_address_list/wallet_account_list_header.dart'; -import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_hidden_list_header.dart'; -import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_header.dart'; -import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_item.dart'; -import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart'; -import 'package:cw_core/wallet_type.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; - -class AddressList extends StatefulWidget { - const AddressList({super.key, required this.addressListViewModel, this.onSelect}); - - final WalletAddressListViewModel addressListViewModel; - final Function(String)? onSelect; - - @override - State createState() => _AddressListState(); -} - -class _AddressListState extends State { - bool showHiddenAddresses = false; - - void _toggleHiddenAddresses() { - setState(() { - showHiddenAddresses = !showHiddenAddresses; - }); - updateItems(); - } - - List getItems(List list, bool showHidden) { - return list.where((element) { - if (element is WalletAddressListItem) { - if (showHidden && element.isHidden) return true; - if (!showHidden && !element.isHidden) return true; - return false; - } - return true; - }).toList(); - } - - List items = []; - - void updateItems() { - setState(() { - items = getItems(widget.addressListViewModel.forceRecomputeItems, showHiddenAddresses); - }); - } - - @override - void initState() { - super.initState(); - - items = getItems(widget.addressListViewModel.items, showHiddenAddresses); - } - - @override - Widget build(BuildContext context) { - bool editable = widget.onSelect == null; - return ListView.separated( - padding: EdgeInsets.all(0), - separatorBuilder: (context, _) => const HorizontalSectionDivider(), - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - itemCount: items.length, - itemBuilder: (context, index) { - final item = items[index]; - Widget cell = Container(); - - if (item is WalletAccountListHeader) { - cell = HeaderTile( - showTrailingButton: true, - walletAddressListViewModel: widget.addressListViewModel, - trailingButtonTap: () async { - if (widget.addressListViewModel.type == WalletType.monero || - widget.addressListViewModel.type == WalletType.wownero || - widget.addressListViewModel.type == WalletType.haven) { - await showPopUp( - context: context, - builder: (_) => getIt.get(), - ); - updateItems(); - } else { - await showPopUp( - context: context, - builder: (_) => getIt.get(), - ); - updateItems(); - } - }, - title: S.of(context).accounts, - trailingIcon: Icon( - Icons.arrow_forward_ios, - size: 14, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ); - } - - if (item is WalletAddressHiddenListHeader) { - cell = HeaderTile( - title: S.of(context).hidden_addresses, - walletAddressListViewModel: widget.addressListViewModel, - showTrailingButton: true, - showSearchButton: false, - trailingButtonTap: _toggleHiddenAddresses, - trailingIcon: Icon( - showHiddenAddresses ? Icons.toggle_on : Icons.toggle_off, - size: 20, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ); - } - - if (item is WalletAddressListHeader) { - cell = HeaderTile( - title: S.of(context).addresses, - walletAddressListViewModel: widget.addressListViewModel, - showTrailingButton: widget.addressListViewModel.showAddManualAddresses, - showSearchButton: true, - onSearchCallback: updateItems, - trailingButtonTap: () => - Navigator.of(context).pushNamed(Routes.newSubaddress).then((value) { - updateItems(); // refresh the new address - }), - trailingIcon: Icon( - Icons.add, - size: 20, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ); - } - - if (item is WalletAddressListItem) { - if (item.isHidden && !showHiddenAddresses) { - cell = Container(); - } else if (!item.isHidden && showHiddenAddresses) { - cell = Container(); - } else { - cell = Observer( - builder: (_) { - final isCurrent = - item.address == widget.addressListViewModel.address.address && editable; - final backgroundColor = isCurrent - ? Theme.of(context).colorScheme.primary - : Theme.of(context).colorScheme.surface; - final textColor = isCurrent - ? Theme.of(context).colorScheme.onPrimary - : Theme.of(context).colorScheme.onSurface; - - return AddressCell.fromItem( - item, - isCurrent: isCurrent, - walletType: widget.addressListViewModel.type, - hasBalance: widget.addressListViewModel.isBalanceAvailable, - hasReceived: widget.addressListViewModel.isReceivedAvailable, - // hasReceived: - backgroundColor: backgroundColor, - textColor: textColor, - onTap: (_) { - if (widget.onSelect != null) { - widget.onSelect!(item.address); - return; - } - widget.addressListViewModel.setAddress(item); - }, - onEdit: editable - ? () => Navigator.of(context) - .pushNamed(Routes.newSubaddress, arguments: item) - .then((value) { - updateItems(); // refresh the new address - }) - : null, - isHidden: item.isHidden, - onHide: () => _hideAddress(item), - ); - }, - ); - } - } - - return index != 0 - ? cell - : ClipRRect( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(30), - topRight: Radius.circular(30), - ), - child: cell, - ); - }, - ); - } - - void _hideAddress(WalletAddressListItem item) async { - await widget.addressListViewModel.toggleHideAddress(item); - updateItems(); - } -} diff --git a/lib/src/screens/receive/widgets/anonpay_currency_input_field.dart b/lib/src/screens/receive/widgets/anonpay_currency_input_field.dart deleted file mode 100644 index d4840c2b6..000000000 --- a/lib/src/screens/receive/widgets/anonpay_currency_input_field.dart +++ /dev/null @@ -1,157 +0,0 @@ -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; -import 'package:cw_core/currency.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -class AnonpayCurrencyInputField extends StatelessWidget { - const AnonpayCurrencyInputField( - {super.key, - required this.onTapPicker, - required this.selectedCurrency, - required this.focusNode, - required this.controller, - required this.minAmount, - required this.maxAmount}); - final Function() onTapPicker; - final Currency selectedCurrency; - final FocusNode focusNode; - final TextEditingController controller; - final String minAmount; - final String maxAmount; - - @override - Widget build(BuildContext context) { - final arrowBottomPurple = Image.asset( - 'assets/images/arrow_bottom_purple_icon.png', - color: Theme.of(context).colorScheme.primary, - height: 8, - ); - - return Column( - children: [ - Container( - child: Padding( - padding: EdgeInsets.only(top: 20), - child: Row( - children: [ - Container( - padding: EdgeInsets.only(right: 8), - height: 32, - child: InkWell( - onTap: onTapPicker, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: EdgeInsets.only(right: 5), - child: arrowBottomPurple, - ), - Text( - selectedCurrency.name.toUpperCase(), - style: Theme.of(context).textTheme.bodyLarge?.copyWith( - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - ], - ), - ), - ), - if (selectedCurrency.tag != null) - Padding( - padding: const EdgeInsets.only(right: 3.0), - child: Container( - height: 32, - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.secondaryContainer, - borderRadius: BorderRadius.all(Radius.circular(6)), - ), - child: Center( - child: Padding( - padding: const EdgeInsets.all(6.0), - child: Text( - selectedCurrency.tag!, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - fontWeight: FontWeight.bold, - color: Theme.of(context).colorScheme.onSecondaryContainer, - ), - ), - ), - ), - ), - ), - Padding( - padding: const EdgeInsets.only(right: 4.0), - child: Text( - ':', - style: Theme.of(context).textTheme.bodyLarge?.copyWith( - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - ), - Expanded( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Flexible( - child: BaseTextFormField( - hasUnderlineBorder: true, - borderWidth: 0.0, - focusNode: focusNode, - controller: controller, - textInputAction: TextInputAction.next, - enabled: true, - textAlign: TextAlign.left, - keyboardType: - TextInputType.numberWithOptions(signed: false, decimal: true), - inputFormatters: [FilteringTextInputFormatter.deny(RegExp('[\\-|\\ ]'))], - hintText: '0.0000', - textStyle: Theme.of(context).textTheme.bodyLarge?.copyWith( - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurface, - ), - placeholderTextStyle: Theme.of(context).textTheme.bodyLarge?.copyWith( - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - validator: null, - ), - ), - ], - ), - ), - ], - ), - ), - ), - Divider(height: 1, color: Theme.of(context).colorScheme.outlineVariant), - Container( - height: 15, - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text( - S.of(context).min_value(minAmount, selectedCurrency.toString()), - style: Theme.of(context).textTheme.bodySmall?.copyWith( - height: 1.2, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - SizedBox(width: 10), - Text( - S.of(context).max_value(maxAmount, selectedCurrency.toString()), - style: Theme.of(context).textTheme.bodySmall?.copyWith( - height: 1.2, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - ], - ), - ), - ], - ); - } -} diff --git a/lib/src/screens/receive/widgets/anonpay_input_form.dart b/lib/src/screens/receive/widgets/anonpay_input_form.dart deleted file mode 100644 index 9e0ba76f9..000000000 --- a/lib/src/screens/receive/widgets/anonpay_input_form.dart +++ /dev/null @@ -1,141 +0,0 @@ -import 'package:cake_wallet/core/email_validator.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart'; -import 'package:cake_wallet/src/screens/receive/widgets/anonpay_currency_input_field.dart'; -import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; -import 'package:cake_wallet/view_model/anon_invoice_page_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; - -class AnonInvoiceForm extends StatelessWidget { - AnonInvoiceForm({ - super.key, - required this.formKey, - required this.anonInvoicePageViewModel, - required this.isInvoice, - required this.amountController, - required this.nameController, - required this.emailController, - required this.descriptionController, - required this.depositAmountFocus, - }) : _nameFocusNode = FocusNode(), - _emailFocusNode = FocusNode(), - _descriptionFocusNode = FocusNode() { - amountController.text = anonInvoicePageViewModel.amount; - nameController.text = anonInvoicePageViewModel.receipientName; - descriptionController.text = anonInvoicePageViewModel.description; - emailController.text = anonInvoicePageViewModel.receipientEmail; - } - - final TextEditingController amountController; - final TextEditingController nameController; - final TextEditingController emailController; - final TextEditingController descriptionController; - final AnonInvoicePageViewModel anonInvoicePageViewModel; - final FocusNode depositAmountFocus; - final FocusNode _nameFocusNode; - final FocusNode _emailFocusNode; - final FocusNode _descriptionFocusNode; - final GlobalKey formKey; - final bool isInvoice; - - @override - Widget build(BuildContext context) { - return Form( - key: formKey, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - isInvoice ? S.of(context).invoice_details : S.of(context).donation_link_details, - style: Theme.of(context).textTheme.titleMedium?.copyWith( - fontWeight: FontWeight.w600, - ), - ), - if (isInvoice) - Observer( - builder: (_) { - return AnonpayCurrencyInputField( - onTapPicker: () => _presentPicker(context), - controller: amountController, - focusNode: depositAmountFocus, - maxAmount: anonInvoicePageViewModel.maximum?.toString() ?? '...', - minAmount: anonInvoicePageViewModel.minimum?.toString() ?? '...', - selectedCurrency: anonInvoicePageViewModel.selectedCurrency, - ); - }, - ), - SizedBox(height: 24), - BaseTextFormField( - hasUnderlineBorder: true, - controller: nameController, - focusNode: _nameFocusNode, - suffixIcon: SizedBox(width: 36), - hintText: S.of(context).optional_name, - textInputAction: TextInputAction.next, - placeholderTextStyle: Theme.of(context).textTheme.bodyLarge?.copyWith( - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - textStyle: Theme.of(context).textTheme.bodyLarge?.copyWith( - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurface, - ), - validator: null, - ), - SizedBox(height: 24), - BaseTextFormField( - hasUnderlineBorder: true, - controller: descriptionController, - focusNode: _descriptionFocusNode, - textInputAction: TextInputAction.next, - suffixIcon: SizedBox(width: 36), - hintText: S.of(context).optional_description, - placeholderTextStyle: Theme.of(context).textTheme.bodyLarge?.copyWith( - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - textStyle: Theme.of(context).textTheme.bodyLarge?.copyWith( - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurface, - ), - validator: null, - ), - SizedBox(height: 24), - BaseTextFormField( - hasUnderlineBorder: true, - controller: emailController, - textInputAction: TextInputAction.next, - focusNode: _emailFocusNode, - suffixIcon: SizedBox(width: 36), - keyboardType: TextInputType.emailAddress, - hintText: S.of(context).optional_email_hint, - placeholderTextStyle: Theme.of(context).textTheme.bodyLarge?.copyWith( - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - textStyle: Theme.of(context).textTheme.bodyLarge?.copyWith( - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurface, - ), - validator: EmailValidator(), - ), - SizedBox(height: 52), - ], - ), - ); - } - - void _presentPicker(BuildContext context) { - showPopUp( - builder: (_) => CurrencyPicker( - selectedAtIndex: anonInvoicePageViewModel.selectedCurrencyIndex, - items: anonInvoicePageViewModel.currencies, - hintText: S.of(context).search_currency, - onItemSelected: anonInvoicePageViewModel.selectCurrency, - ), - context: context, - ); - } -} diff --git a/lib/src/screens/receive/widgets/anonpay_status_section.dart b/lib/src/screens/receive/widgets/anonpay_status_section.dart deleted file mode 100644 index c431be1a9..000000000 --- a/lib/src/screens/receive/widgets/anonpay_status_section.dart +++ /dev/null @@ -1,86 +0,0 @@ -import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator_icon.dart'; -import 'package:flutter/material.dart'; - -class AnonInvoiceStatusSection extends StatelessWidget { - const AnonInvoiceStatusSection({ - super.key, - required this.invoiceInfo, - }); - - final AnonpayInvoiceInfo invoiceInfo; - - @override - Widget build(BuildContext context) { - return Container( - width: 200, - padding: EdgeInsets.all(19), - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.surface, - borderRadius: BorderRadius.circular(30), - ), - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - S.current.status, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - Container( - padding: EdgeInsets.symmetric(horizontal: 10, vertical: 5), - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.secondaryContainer, - borderRadius: BorderRadius.circular(10), - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - SyncIndicatorIcon( - boolMode: false, - value: invoiceInfo.status, - size: 6, - ), - SizedBox(width: 5), - Text( - invoiceInfo.status, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSecondaryContainer, - ), - ), - ], - ), - ), - ], - ), - SizedBox(height: 27), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - 'ID', - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - Text( - invoiceInfo.invoiceId, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - ], - ), - ], - ), - ); - } -} diff --git a/lib/src/screens/receive/widgets/copy_link_item.dart b/lib/src/screens/receive/widgets/copy_link_item.dart deleted file mode 100644 index 11d17d20b..000000000 --- a/lib/src/screens/receive/widgets/copy_link_item.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/utils/share_util.dart'; -import 'package:cake_wallet/utils/show_bar.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -class CopyLinkItem extends StatelessWidget { - const CopyLinkItem({super.key, required this.url, required this.title}); - final String url; - final String title; - - @override - Widget build(BuildContext context) { - final copyImage = Image.asset('assets/images/copy_address.png', - color: Theme.of(context).colorScheme.onSurface); - - return Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - title, - style: Theme.of(context).textTheme.bodyLarge?.copyWith( - color: Theme.of(context).colorScheme.onSurface, - ), - ), - SizedBox(width: 50), - Row( - children: [ - InkWell( - onTap: () { - Clipboard.setData(ClipboardData(text: url)); - showBar(context, S.of(context).copied_to_clipboard); - }, - child: copyImage, - ), - SizedBox(width: 20), - IconButton( - padding: EdgeInsets.zero, - constraints: BoxConstraints(), - highlightColor: Colors.transparent, - splashColor: Colors.transparent, - iconSize: 25, - onPressed: () => ShareUtil.share(text: url, context: context), - icon: Icon( - Icons.share, - color: Theme.of(context).colorScheme.primary, - ), - ) - ], - ) - ], - ); - } -} diff --git a/lib/src/screens/receive/widgets/header_tile.dart b/lib/src/screens/receive/widgets/header_tile.dart deleted file mode 100644 index 24918ad50..000000000 --- a/lib/src/screens/receive/widgets/header_tile.dart +++ /dev/null @@ -1,108 +0,0 @@ -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; -import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart'; -import 'package:flutter/material.dart'; - -class HeaderTile extends StatefulWidget { - HeaderTile({ - required this.title, - required this.walletAddressListViewModel, - this.showSearchButton = false, - this.showTrailingButton = false, - this.trailingButtonTap, - this.onSearchCallback, - this.trailingIcon, - }); - - final String title; - final WalletAddressListViewModel walletAddressListViewModel; - final bool showSearchButton; - final bool showTrailingButton; - final VoidCallback? trailingButtonTap; - final VoidCallback? onSearchCallback; - final Icon? trailingIcon; - - @override - _HeaderTileState createState() => _HeaderTileState(); -} - -class _HeaderTileState extends State { - bool _isSearchActive = false; - - @override - Widget build(BuildContext context) { - final searchIcon = Icon(Icons.search, color: Theme.of(context).colorScheme.primary); - - return Container( - padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12), - color: Theme.of(context).colorScheme.surface, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - _isSearchActive - ? Expanded( - child: BaseTextFormField( - onChanged: (value) { - widget.walletAddressListViewModel.updateSearchText(value); - widget.onSearchCallback?.call(); - }, - cursorColor: Theme.of(context).colorScheme.onSurface, - cursorWidth: 0.5, - isDense: true, - hintText: '${S.of(context).search}...', - contentPadding: EdgeInsets.all(4), - placeholderTextStyle: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - autofocus: true, - ), - ) - : Text( - widget.title, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - Row( - children: [ - if (widget.showSearchButton) - GestureDetector( - onTap: () { - setState(() { - _isSearchActive = !_isSearchActive; - widget.walletAddressListViewModel.updateSearchText(''); - }); - }, - child: Container( - height: 32, - width: 32, - decoration: BoxDecoration( - shape: BoxShape.circle, - color: Theme.of(context).colorScheme.secondaryContainer, - ), - child: searchIcon, - ), - ), - const SizedBox(width: 8), - if (widget.showTrailingButton) - GestureDetector( - onTap: widget.trailingButtonTap, - child: Container( - height: 32, - width: 32, - decoration: BoxDecoration( - shape: BoxShape.circle, - color: Theme.of(context).colorScheme.secondaryContainer, - ), - child: widget.trailingIcon, - ), - ), - ], - ), - ], - ), - ); - } -} diff --git a/lib/src/screens/receive/widgets/qr_widget.dart b/lib/src/screens/receive/widgets/qr_widget.dart deleted file mode 100644 index 5c2868c69..000000000 --- a/lib/src/screens/receive/widgets/qr_widget.dart +++ /dev/null @@ -1,321 +0,0 @@ -import 'package:cake_wallet/entities/qr_view_data.dart'; -import 'package:cake_wallet/src/widgets/primary_button.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart'; -import 'package:cake_wallet/src/screens/receive/widgets/currency_input_field.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/screens/receive/widgets/qr_image.dart'; -import 'package:cake_wallet/src/widgets/bottom_sheet/base_bottom_sheet_widget.dart'; -import 'package:cake_wallet/src/widgets/bottom_sheet/info_bottom_sheet_widget.dart'; -import 'package:cake_wallet/utils/address_formatter.dart'; -import 'package:cake_wallet/utils/brightness_util.dart'; -import 'package:cake_wallet/utils/responsive_layout_util.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_address_list/wallet_address_list_view_model.dart'; -import 'package:cw_core/crypto_currency.dart'; -import 'package:cw_core/payment_uris.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:url_launcher/url_launcher.dart'; - -class QRWidget extends StatelessWidget { - QRWidget({ - required this.addressListViewModel, - this.qrVersion, - this.heroTag, - required this.amountController, - required this.formKey, - this.amountTextFieldFocusNode, - }); - - final WalletAddressListViewModel addressListViewModel; - final TextEditingController amountController; - final FocusNode? amountTextFieldFocusNode; - final GlobalKey formKey; - final int? qrVersion; - final String? heroTag; - - PaymentURI get addressUri { - return addressListViewModel.uri; - } - - @override - Widget build(BuildContext context) { - final copyImage = Image.asset( - 'assets/images/copy_address.png', - color: Theme.of(context).colorScheme.onSurfaceVariant, - ); - - // This magic number for wider screen sets the text input focus at center of the inputfield - final _width = - responsiveLayoutUtil.shouldRenderMobileUI ? MediaQuery.of(context).size.width : 500; - - return Center( - child: SingleChildScrollView( - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Column( - children: [ - Row( - children: [ - Spacer(flex: 3), - Observer( - builder: (_) => Flexible( - flex: 9, - child: GestureDetector( - onTap: () { - BrightnessUtil.changeBrightnessForFunction( - () async { - await Navigator.pushNamed( - context, - Routes.fullscreenQR, - arguments: QrViewData( - embeddedImagePath: addressListViewModel.qrImage, - data: addressUri.toString(), - heroTag: heroTag, - ), - ); - }, - ); - }, - child: Hero( - tag: Key(heroTag ?? addressUri.toString()), - child: Center( - child: Container( - padding: EdgeInsets.zero, - decoration: BoxDecoration( - border: Border(top: BorderSide.none), - borderRadius: BorderRadius.all(Radius.circular(5)), - color: Theme.of(context).colorScheme.surface, - ), - child: Column( - children: [ - ClipRRect( - borderRadius: BorderRadius.circular(12.5), - child: AspectRatio( - aspectRatio: 1.0, - child: QrImage( - embeddedImagePath: addressListViewModel.qrImage, - data: addressUri.toString(), - size: 230, - ), - ), - ), - if (addressListViewModel.isPayjoinUnavailable && - !addressListViewModel.isSilentPayments && - !addressListViewModel.isLightning && - !addressListViewModel.isBitcoinViewOnly) ...[ - GestureDetector( - onTap: () => _onPayjoinInactivePressed(context), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: EdgeInsets.only( - top: 4, - bottom: 4, - right: 4, - ), - child: Image.asset( - 'assets/images/payjoin.png', - width: 20, - ), - ), - Text( - S.of(context).payjoin_unavailable, - style: - Theme.of(context).textTheme.bodySmall?.copyWith( - fontWeight: FontWeight.w600, - color: Theme.of(context) - .colorScheme - .onSurfaceVariant, - ), - ), - Padding( - padding: EdgeInsets.only( - top: 4, - bottom: 4, - left: 4, - ), - child: CircleAvatar( - radius: 7, - backgroundColor: Colors.black, - child: Icon( - Icons.question_mark, - size: 10, - color: Colors.white, - ), - ), - ), - ], - ), - ), - ], - if (addressListViewModel.isPayjoinAvailable) ...[ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: EdgeInsets.only( - top: 4, - bottom: 4, - right: 4, - ), - child: Image.asset( - 'assets/images/payjoin.png', - width: 20, - ), - ), - Text( - S.of(context).payjoin_enabled, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - fontWeight: FontWeight.w600, - ), - ), - ], - ), - ] - ], - ), - ), - ), - ), - ), - ), - ), - Spacer(flex: 3) - ], - ), - ], - ), - Observer( - builder: (_) => Row( - children: [ - Expanded( - child: Form( - key: formKey, - child: CurrencyAmountTextField( - hasUnderlineBorder: true, - borderWidth: 0.0, - selectedCurrency: _currencyName, - selectedCurrencyDecimals: - addressListViewModel.selectedCurrencyDecimals, - amountFocusNode: amountTextFieldFocusNode, - amountController: amountController, - padding: EdgeInsets.only(top: 20, left: _width / 4), - isAmountEditable: true, - tag: addressListViewModel.selectedCurrency.tag, - onTapPicker: () => _presentPicker(context), - isPickerEnable: true, - ), - ), - ), - ], - )), - Divider(height: 1, color: Theme.of(context).colorScheme.outlineVariant), - Padding( - padding: EdgeInsets.only(top: 12, bottom: 8), - child: Builder( - builder: (context) => Observer( - builder: (context) => GestureDetector( - onTap: () { - Clipboard.setData(ClipboardData(text: addressUri.address)); - showBar(context, S.of(context).copied_to_clipboard); - }, - child: Row( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: AddressFormatter.buildSegmentedAddress( - address: addressUri.address, - walletType: addressListViewModel.type, - textAlign: TextAlign.center, - evenTextStyle: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 15, - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - ), - Padding( - padding: EdgeInsets.only(left: 12), - child: copyImage, - ) - ], - ), - ), - ), - ), - ), - Observer( - builder: (_) => Offstage( - offstage: !addressListViewModel.isPayjoinAvailable, - child: Padding( - padding: EdgeInsets.only(top: 12), - child: PrimaryImageButton( - onPressed: () { - Clipboard.setData(ClipboardData(text: addressUri.toString())); - showBar(context, S.of(context).copied_to_clipboard); - }, - image: Image.asset( - 'assets/images/payjoin.png', - width: 25, - ), - text: S.of(context).copy_payjoin_address, - color: Theme.of(context).colorScheme.surfaceContainer, - textColor: Theme.of(context).colorScheme.onSurface, - ), - ), - ), - ), - ], - ), - ), - ); - } - - String get _currencyName { - if (addressListViewModel.selectedCurrency is CryptoCurrency) { - if (addressListViewModel.useSatoshi) return "SATS"; - return (addressListViewModel.selectedCurrency as CryptoCurrency).title.toUpperCase(); - } - return addressListViewModel.selectedCurrency.name.toUpperCase(); - } - - void _presentPicker(BuildContext context) async { - await showPopUp( - builder: (_) => CurrencyPicker( - selectedAtIndex: addressListViewModel.selectedCurrencyIndex, - items: addressListViewModel.currencies, - hintText: S.of(context).search_currency, - onItemSelected: addressListViewModel.selectCurrency, - ), - context: context, - ); - // update amount if currency changed - addressListViewModel.changeAmount(amountController.text); - } - - void _onPayjoinInactivePressed(BuildContext context) { - showModalBottomSheet( - context: context, - builder: (context) => InfoBottomSheet( - titleText: S.of(context).payjoin_unavailable_sheet_title, - content: S.of(context).payjoin_unavailable_sheet_content, - footerType: FooterType.doubleActionButton, - doubleActionLeftButtonText: S.of(context).learn_more, - onLeftActionButtonPressed: () => launchUrl( - Uri.parse("https://docs.cakewallet.com/cryptos/bitcoin/#payjoin"), - mode: LaunchMode.externalApplication), - doubleActionRightButtonText: S.of(context).ok, - onRightActionButtonPressed: () => Navigator.of(context).pop(), - ), - ); - } -} diff --git a/lib/src/screens/release_notes/release_notes_screen.dart b/lib/src/screens/release_notes/release_notes_screen.dart deleted file mode 100644 index 72b6755cd..000000000 --- a/lib/src/screens/release_notes/release_notes_screen.dart +++ /dev/null @@ -1,139 +0,0 @@ -import 'dart:convert'; -import 'package:cake_wallet/src/widgets/alert_background.dart'; -import 'package:cake_wallet/src/widgets/alert_close_button.dart'; -import 'package:cake_wallet/wallet_type_utils.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -class ReleaseNotesScreen extends StatelessWidget { - const ReleaseNotesScreen({ - required this.title, - }); - - final String title; - - Future> _loadStrings() async { - String notesContent = await rootBundle.loadString( - isMoneroOnly ? 'assets/text/Monerocom_Release_Notes.txt' : 'assets/text/Release_Notes.txt'); - return LineSplitter().convert(notesContent); - } - - @override - Widget build(BuildContext context) { - return Stack( - alignment: Alignment.center, - children: [ - AlertBackground( - child: AlertDialog( - insetPadding: EdgeInsets.only(left: 16, right: 16, bottom: 48), - elevation: 0.0, - contentPadding: EdgeInsets.zero, - shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(30))), - content: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(30.0), - gradient: LinearGradient(colors: [ - Theme.of(context).colorScheme.surface, - Theme.of(context).colorScheme.surfaceContainer, - ], begin: Alignment.topLeft, end: Alignment.bottomRight)), - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 24.0), - child: Stack( - children: [ - SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.only(top: 16.0), - child: Container( - alignment: Alignment.bottomCenter, - child: DefaultTextStyle( - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - decoration: TextDecoration.none, - fontSize: 24.0, - fontWeight: FontWeight.bold, - color: Theme.of(context).colorScheme.onSurface, - ), - child: Text(title), - ), - ), - ), - ), - SingleChildScrollView( - child: Padding( - padding: EdgeInsets.only(top: 48, bottom: 16), - child: Container( - width: double.maxFinite, - child: Column( - children: [ - ConstrainedBox( - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context).size.height * 0.7, - ), - child: _getNotesWidget(), - ) - ], - ), - ), - ), - ), - ], - ), - ), - ), - ), - ), - AlertCloseButton( - bottom: 30, - ) - ], - ); - } - - Widget _getNotesWidget() { - return FutureBuilder>( - future: _loadStrings(), - builder: (BuildContext context, AsyncSnapshot> snapshot) { - if (snapshot.hasData) { - return ListView.builder( - shrinkWrap: true, - itemCount: snapshot.data!.length, - itemBuilder: (BuildContext context, int index) { - return _getNoteItemWidget(snapshot.data![index], context); - }, - ); - } else if (snapshot.hasError) { - return Text('Error: ${snapshot.error}'); - } else { - return Center(child: CircularProgressIndicator()); - } - }, - ); - } - - Widget _getNoteItemWidget(String myString, BuildContext context) { - return Column( - children: [ - DefaultTextStyle( - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - decoration: TextDecoration.none, - fontSize: 16.0, - color: Theme.of(context).colorScheme.onSurface, - ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(right: 8.0), - child: Text('•'), - ), - Expanded( - child: Text(myString), - ), - ], - )), - SizedBox( - height: 16.0, - ) - ], - ); - } -} diff --git a/lib/src/screens/restore/sweeping_wallet_page.dart b/lib/src/screens/restore/sweeping_wallet_page.dart deleted file mode 100644 index 56a383dec..000000000 --- a/lib/src/screens/restore/sweeping_wallet_page.dart +++ /dev/null @@ -1,116 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:flutter/scheduler.dart'; - -class SweepingWalletPage extends BasePage { - SweepingWalletPage(); - - static const aspectRatioImage = 1.25; - final welcomeImageLight = Image.asset('assets/images/welcome_light.png'); - final welcomeImageDark = Image.asset('assets/images/welcome.png'); - - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: Theme.of(context).colorScheme.surface, - resizeToAvoidBottomInset: false, - body: body(context)); - } - - @override - Widget body(BuildContext context) { - final welcomeImage = currentTheme.isDark ? welcomeImageDark : welcomeImageLight; - - return SweepingWalletWidget( - aspectRatioImage: aspectRatioImage, - welcomeImage: welcomeImage, - ); - } -} - -class SweepingWalletWidget extends StatefulWidget { - const SweepingWalletWidget({ - required this.aspectRatioImage, - required this.welcomeImage, - }); - - final double aspectRatioImage; - final Image welcomeImage; - - @override - State createState() => _SweepingWalletWidgetState(); -} - -class _SweepingWalletWidgetState extends State { - @override - void initState() { - SchedulerBinding.instance.addPostFrameCallback((_) async {}); - super.initState(); - } - - @override - Widget build(BuildContext context) { - return WillPopScope( - onWillPop: () async => false, - child: Container( - padding: EdgeInsets.only(top: 64, bottom: 24, left: 24, right: 24), - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Flexible( - flex: 2, - child: AspectRatio( - aspectRatio: widget.aspectRatioImage, - child: FittedBox(child: widget.welcomeImage, fit: BoxFit.fill))), - Flexible( - flex: 3, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - children: [ - Padding( - padding: EdgeInsets.only(top: 24), - child: Text( - S.of(context).please_wait, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 18, - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - textAlign: TextAlign.center, - ), - ), - Padding( - padding: EdgeInsets.only(top: 5), - child: Text( - S.of(context).sweeping_wallet, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 36, - fontWeight: FontWeight.bold, - color: Theme.of(context).colorScheme.primary, - ), - textAlign: TextAlign.center, - ), - ), - Padding( - padding: EdgeInsets.only(top: 5), - child: Text( - S.of(context).sweeping_wallet_alert, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - textAlign: TextAlign.center, - ), - ), - ], - ), - ], - )) - ], - ))); - } -} diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart deleted file mode 100644 index 954796d50..000000000 --- a/lib/src/screens/send/send_page.dart +++ /dev/null @@ -1,845 +0,0 @@ -import 'package:cake_wallet/bitcoin/bitcoin.dart'; -import 'package:cake_wallet/core/address_validator.dart'; -import 'package:cake_wallet/core/auth_service.dart'; -import 'package:cake_wallet/core/execution_state.dart'; -import 'package:cake_wallet/entities/contact_record.dart'; -import 'package:cake_wallet/entities/fiat_currency.dart'; -import 'package:cake_wallet/entities/template.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/monero/monero.dart'; -import 'package:cake_wallet/reactions/wallet_connect.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/src/screens/connect_device/connect_device_page.dart'; -import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator_icon.dart'; -import 'package:cake_wallet/src/screens/send/widgets/send_card.dart'; -import 'package:cake_wallet/src/widgets/adaptable_page_view.dart'; -import 'package:cake_wallet/src/widgets/add_template_button.dart'; -import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; -import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; -import 'package:cake_wallet/src/widgets/bottom_sheet/base_bottom_sheet_widget.dart'; -import 'package:cake_wallet/src/widgets/bottom_sheet/confirm_sending_bottom_sheet_widget.dart'; -import 'package:cake_wallet/src/widgets/bottom_sheet/info_bottom_sheet_widget.dart'; -import 'package:cake_wallet/src/widgets/keyboard_done_button.dart'; -import 'package:cake_wallet/src/widgets/primary_button.dart'; -import 'package:cake_wallet/src/widgets/scrollable_with_bottom_section.dart'; -import 'package:cake_wallet/src/widgets/simple_checkbox.dart'; -import 'package:cake_wallet/src/widgets/template_tile.dart'; -import 'package:cake_wallet/src/widgets/trail_button.dart'; -import 'package:cake_wallet/utils/payment_request.dart'; -import 'package:cake_wallet/utils/request_review_handler.dart'; -import 'package:cake_wallet/utils/responsive_layout_util.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; -import 'package:cake_wallet/view_model/payment/payment_view_model.dart'; -import 'package:cake_wallet/view_model/send/output.dart'; -import 'package:cake_wallet/view_model/send/send_view_model.dart'; -import 'package:cake_wallet/view_model/send/send_view_model_state.dart'; -import 'package:cake_wallet/view_model/wallet_switcher_view_model.dart'; -import 'package:cw_core/amount/money.dart'; -import 'package:cw_core/crypto_currency.dart'; -import 'package:cw_core/utils/print_verbose.dart'; -import 'package:cw_core/wallet_type.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:keyboard_actions/keyboard_actions.dart'; -import 'package:mobx/mobx.dart'; -import 'package:smooth_page_indicator/smooth_page_indicator.dart'; -import 'package:url_launcher/url_launcher.dart'; - -class SendPage extends BasePage { - SendPage({ - required this.sendViewModel, - required this.authService, - required this.paymentViewModel, - required this.walletSwitcherViewModel, - this.initialPaymentRequest, - }) : _formKey = GlobalKey(); - - final SendViewModel sendViewModel; - final PaymentViewModel paymentViewModel; - final WalletSwitcherViewModel walletSwitcherViewModel; - final AuthService authService; - final GlobalKey _formKey; - final controller = PageController(initialPage: 0); - final PaymentRequest? initialPaymentRequest; - final FocusNode _cryptoAmountFocus = FocusNode(); - final FocusNode _fiatAmountFocus = FocusNode(); - - final currentPage = ValueNotifier(0); - - bool _effectsInstalled = false; - ContactRecord? newContactAddress; - - @override - String get title => S.current.send; - - @override - bool get gradientAll => true; - - @override - bool get resizeToAvoidBottomInset => false; - - @override - bool get extendBodyBehindAppBar => true; - - @override - Function(BuildContext)? get pushToNextWidget => (context) { - FocusScopeNode currentFocus = FocusScope.of(context); - if (!currentFocus.hasPrimaryFocus) { - currentFocus.focusedChild?.unfocus(); - } - }; - - @override - Widget? leading(BuildContext context) { - final _backButton = Icon( - Icons.arrow_back_ios, - color: Theme.of(context).colorScheme.primary, - size: 16, - ); - final _closeButton = currentTheme.isDark ? closeButtonImageDarkTheme : closeButtonImage; - final isMobileView = responsiveLayoutUtil.shouldRenderMobileUI; - - return MergeSemantics( - child: SizedBox( - height: isMobileView ? 37 : 45, - width: isMobileView ? 47 : 45, - child: ButtonTheme( - minWidth: double.minPositive, - child: Semantics( - label: !isMobileView ? S.of(context).close : S.of(context).seed_alert_back, - child: TextButton( - style: ButtonStyle( - overlayColor: WidgetStateColor.resolveWith((states) => Colors.transparent), - ), - onPressed: () => onClose(context), - child: !isMobileView ? _closeButton : _backButton, - ), - ), - ), - ), - ); - } - - @override - AppBarStyle get appBarStyle => AppBarStyle.transparent; - - @override - void onClose(BuildContext context) { - sendViewModel.onClose(); - Navigator.of(context).pop(); - } - - @override - Widget? middle(BuildContext context) { - final supMiddle = super.middle(context); - return Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.only(right: 8.0), - child: Observer( - builder: (_) => SyncIndicatorIcon(isSynced: sendViewModel.isReadyForSend), - ), - ), - if (supMiddle != null) supMiddle - ], - ); - } - - @override - Widget trailing(context) => Observer( - builder: (_) => sendViewModel.isBatchSending - ? TrailButton( - caption: S.of(context).remove, - onPressed: () { - var pageToJump = (controller.page?.round() ?? 0) - 1; - pageToJump = pageToJump > 0 ? pageToJump : 0; - final output = _defineCurrentOutput(); - sendViewModel.removeOutput(output); - controller.jumpToPage(pageToJump); - }, - ) - : TrailButton( - caption: S.of(context).clear, - onPressed: () { - final output = _defineCurrentOutput(); - _formKey.currentState?.reset(); - output.reset(); - }, - ), - ); - - @override - Widget body(BuildContext context) { - _setEffects(context); - - return ValueListenableBuilder( - valueListenable: currentPage, - builder: (context, value, child) { - return Observer(builder: (_) { - List sendCards = []; - List keyboardActions = []; - for (final output in sendViewModel.outputs) { - final isCurrent = sendViewModel.outputs.indexOf(output) == value; - sendCards.add( - SendCard( - currentTheme: currentTheme, - key: output.key, - output: output, - sendViewModel: sendViewModel, - paymentViewModel: paymentViewModel, - walletSwitcherViewModel: walletSwitcherViewModel, - initialPaymentRequest: initialPaymentRequest, - cryptoAmountFocus: isCurrent ? _cryptoAmountFocus : null, - fiatAmountFocus: isCurrent ? _fiatAmountFocus : null, - ), - ); - keyboardActions.add( - KeyboardActionsItem( - focusNode: _cryptoAmountFocus, - toolbarButtons: [(_) => KeyboardDoneButton()], - ), - ); - keyboardActions.add( - KeyboardActionsItem( - focusNode: _fiatAmountFocus, - toolbarButtons: [(_) => KeyboardDoneButton()], - ), - ); - } - return Stack( - children: [ - KeyboardActions( - config: KeyboardActionsConfig( - keyboardActionsPlatform: KeyboardActionsPlatform.ALL, - keyboardBarColor: Theme.of(context).colorScheme.surface, - nextFocus: false, - actions: keyboardActions, - ), - child: Container( - height: 0, - color: Colors.transparent, - ), - ), - GestureDetector( - onLongPress: () => sendViewModel.balanceViewModel.isReversing = - !sendViewModel.balanceViewModel.isReversing, - onLongPressUp: () => sendViewModel.balanceViewModel.isReversing = - !sendViewModel.balanceViewModel.isReversing, - child: RepaintBoundary( - child: Form( - key: _formKey, - child: ScrollableWithBottomSection( - contentPadding: EdgeInsets.only(bottom: 24), - content: FocusTraversalGroup( - policy: OrderedTraversalPolicy(), - child: Column( - children: [ - PageViewHeightAdaptable( - controller: controller, - children: sendCards, - ), - SizedBox(height: 10), - Padding( - padding: EdgeInsets.only(left: 24, right: 24, bottom: 10), - child: Container( - height: 10, - child: Observer( - builder: (_) { - final count = sendViewModel.outputs.length; - - return count > 1 - ? Semantics( - label: 'Page Indicator', - hint: 'Swipe to change receiver', - excludeSemantics: true, - child: SmoothPageIndicator( - controller: controller, - count: count, - effect: ScrollingDotsEffect( - spacing: 6.0, - radius: 6.0, - dotWidth: 6.0, - dotHeight: 6.0, - dotColor: Theme.of(context) - .colorScheme - .primary - .withAlpha(100), - activeDotColor: - Theme.of(context).colorScheme.primary, - ), - ), - ) - : Offstage(); - }, - ), - ), - ), - 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( - key: ValueKey('send_page_add_template_button_key'), - 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, - hasMultipleRecipients: - template.additionalRecipients != null && - template.additionalRecipients!.length > 1, - amount: template.isCurrencySelected - ? template.amount - : template.amountFiat, - from: template.isCurrencySelected - ? template.cryptoCurrency - : template.fiatCurrency, - onTap: () async { - sendViewModel.state = - LoadingTemplateExecutingState(); - if (template.additionalRecipients?.isNotEmpty ?? - false) { - sendViewModel.clearOutputs(); - - for (int i = 0; - i < template.additionalRecipients!.length; - i++) { - Output output; - try { - output = sendViewModel.outputs[i]; - } catch (e) { - sendViewModel.addOutput(); - output = sendViewModel.outputs[i]; - } - - await _setInputsFromTemplate( - context, - output: output, - template: - template.additionalRecipients![i], - ); - } - } else { - final output = _defineCurrentOutput(); - await _setInputsFromTemplate( - context, - output: output, - template: template, - ); - } - sendViewModel.state = InitialExecutionState(); - }, - 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.sendTemplateViewModel.hasMultiRecipient) - Padding( - padding: EdgeInsets.only(bottom: 12), - child: PrimaryButton( - key: ValueKey('send_page_add_receiver_button_key'), - 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).colorScheme.onSurfaceVariant, - isDottedBorder: true, - borderColor: Theme.of(context).colorScheme.outline, - )), - Observer( - builder: (_) { - return LoadingPrimaryButton( - key: ValueKey('send_page_send_button_key'), - onPressed: () async { - //Request dummy node to get the focus out of the text fields - FocusScope.of(context).requestFocus(FocusNode()); - - if (sendViewModel.state is IsExecutingState) return; - if (_formKey.currentState != null && - !_formKey.currentState!.validate()) { - if (sendViewModel.outputs.length > 1) { - showErrorValidationAlert(context); - } - - return; - } - - final hasInvalidItems = sendViewModel.outputs.any((item) => - item.address.isEmpty || - (item.cryptoAmount.isEmpty && !item.sendAll)); - - if (hasInvalidItems) { - showErrorValidationAlert(context); - return; - } - - if (sendViewModel.wallet.isHardwareWallet) { - if (!sendViewModel.hardwareWalletViewModel! - .isConnected(sendViewModel.walletType)) { - await Navigator.of(context) - .pushNamed(Routes.connectDevices, - arguments: ConnectDevicePageParams( - walletType: sendViewModel.walletType, - hardwareWalletType: sendViewModel - .wallet.walletInfo.hardwareWalletType!, - onConnectDevice: (BuildContext context, _) { - sendViewModel.hardwareWalletViewModel! - .initWallet(sendViewModel.wallet); - Navigator.of(context).pop(); - }, - )); - } else { - sendViewModel.hardwareWalletViewModel! - .initWallet(sendViewModel.wallet); - } - } - - if (sendViewModel.wallet.type == WalletType.monero) { - var amount = Money.zero(sendViewModel.wallet.currency); - for (var item in sendViewModel.outputs) { - amount += item.cryptoAmountMoney; - } - if (monero! - .needExportOutputs(sendViewModel.wallet, amount)) { - await Navigator.of(context).pushNamed( - Routes.urqrAnimatedPage, - arguments: - monero!.exportOutputsUR(sendViewModel.wallet)); - await Future.delayed(Duration( - seconds: 1)); // wait for monero to refresh the state - } - if (monero! - .needExportOutputs(sendViewModel.wallet, amount)) { - return; - } - } - - final check = sendViewModel.shouldDisplayTotp(); - authService.authenticateAction( - context, - conditionToDetermineIfToUse2FA: check, - onAuthSuccess: (value) async { - if (value) { - await sendViewModel.createTransaction(); - } - }, - ); - }, - text: _sendButtonText(context), - color: Theme.of(context).colorScheme.primary, - textColor: Theme.of(context).colorScheme.onPrimary, - isLoading: sendViewModel.state is IsExecutingState || - sendViewModel.state is TransactionCommitting || - sendViewModel.state is IsAwaitingDeviceResponseState || - sendViewModel.state is LoadingTemplateExecutingState, - isDisabled: !sendViewModel.isReadyForSend || - sendViewModel.state is ExecutedSuccessfullyState, - ); - }, - ) - ], - )), - ), - ), - ), - ], - ); - }); - }); - } - - BuildContext? dialogContext; - BuildContext? loadingBottomSheetContext; - - void _setEffects(BuildContext context) { - if (_effectsInstalled) return; - - if (sendViewModel.isElectrumWallet) { - bitcoin!.updateFeeRates(sendViewModel.wallet); - } - - controller.addListener(() { - if (!controller.hasClients) return; - currentPage.value = controller.page!.round(); - }); - - reaction((_) => sendViewModel.state, (ExecutionState state) async { - if (dialogContext != null && dialogContext?.mounted == true) { - Navigator.of(dialogContext!).pop(); - } - - if (state is! IsExecutingState && - loadingBottomSheetContext != null && - loadingBottomSheetContext!.mounted) { - Navigator.of(loadingBottomSheetContext!).pop(); - } - - if (state is FailureState) { - WidgetsBinding.instance.addPostFrameCallback( - (_) { - showPopUp( - context: context, - builder: (context) => AlertWithOneAction( - key: ValueKey('send_page_send_failure_dialog_key'), - buttonKey: ValueKey('send_page_send_failure_dialog_button_key'), - alertTitle: S.of(context).error, - alertContent: state.error, - buttonText: S.of(context).ok, - buttonAction: () => Navigator.of(context).pop(), - ), - ); - }, - ); - } - - if (state is IsExecutingState) { - // wait a bit to avoid showing the loading dialog if transaction is failed - await Future.delayed(const Duration(milliseconds: 300)); - final currentState = sendViewModel.state; - if (currentState is ExecutedSuccessfullyState || currentState is FailureState) { - return; - } - - WidgetsBinding.instance.addPostFrameCallback((_) { - if (context.mounted) { - showModalBottomSheet( - context: context, - isDismissible: false, - builder: (context) { - loadingBottomSheetContext = context; - return LoadingBottomSheet( - titleText: S.of(context).generating_transaction, - ); - }, - ); - } - }); - } - - if (state is ExecutedSuccessfullyState) { - WidgetsBinding.instance.addPostFrameCallback((_) async { - if (context.mounted) { - final result = await showModalBottomSheet( - context: context, - isDismissible: false, - isScrollControlled: true, - builder: (BuildContext bottomSheetContext) { - return Observer( - builder: (_) => ConfirmSendingBottomSheet( - key: ValueKey('send_page_confirm_sending_bottom_sheet_key'), - titleText: S.of(bottomSheetContext).confirm_transaction, - accessibleNavigationModeSlideActionButtonText: S.of(bottomSheetContext).send, - footerType: FooterType.slideActionButton, - isSlideActionEnabled: sendViewModel.isReadyForSend, - walletType: sendViewModel.walletType, - titleIconPath: sendViewModel.selectedCryptoCurrency.iconPath, - currency: sendViewModel.selectedCryptoCurrency, - amount: S.of(bottomSheetContext).send_amount, - amountValue: sendViewModel.amountParsingProxy.getDisplayCryptoAmount( - sendViewModel.pendingTransaction!.amountFormatted, - sendViewModel.selectedCryptoCurrency), - fiatAmountValue: sendViewModel.pendingTransactionFiatAmountFormatted, - fee: isEVMCompatibleChain(sendViewModel.walletType) - ? S.of(bottomSheetContext).send_estimated_fee - : S.of(bottomSheetContext).send_fee, - feeValue: - "${sendViewModel.amountParsingProxy.getDisplayCryptoAmount(sendViewModel.pendingTransaction!.feeFormattedValue, sendViewModel.selectedCryptoCurrency)} ${sendViewModel.amountParsingProxy.getCryptoSymbol(sendViewModel.wallet.currency)}", - feeFiatAmount: sendViewModel.pendingTransactionFeeFiatAmountFormatted, - outputs: sendViewModel.outputs, - onSlideActionComplete: () async { - Navigator.of(bottomSheetContext).pop(true); - sendViewModel.commitTransaction(context); - }, - change: sendViewModel.pendingTransaction!.change, - isOpenCryptoPay: sendViewModel.ocpRequest != null, - amountParsingProxy: sendViewModel.amountParsingProxy, - ), - ); - }, - ); - - if (result == null) sendViewModel.dismissTransaction(); - } - }); - } - - if (state is TransactionCommitted) { - WidgetsBinding.instance.addPostFrameCallback((_) async { - if (!context.mounted) return; - - newContactAddress = newContactAddress ?? sendViewModel.newContactAddress(); - - if (newContactAddress?.address != null && - isRegularElectrumAddress(newContactAddress!.address)) { - newContactAddress = null; - } - - bool showContactSheet = (newContactAddress != null && sendViewModel.showAddressBookPopup); - - await showModalBottomSheet( - context: context, - isDismissible: false, - builder: (BuildContext bottomSheetContext) { - return showContactSheet && sendViewModel.ocpRequest == null - ? InfoBottomSheet( - footerType: FooterType.doubleActionButton, - titleText: S.of(bottomSheetContext).transaction_sent, - contentImage: 'assets/images/contact.png', - contentImageColor: Theme.of(context).colorScheme.onSurface, - content: S.of(bottomSheetContext).add_contact_to_address_book, - leftActionButtonKey: - ValueKey('send_page_add_contact_bottom_sheet_no_button_key'), - rightActionButtonKey: - ValueKey('send_page_add_contact_bottom_sheet_yes_button_key'), - bottomActionPanel: Padding( - padding: const EdgeInsets.only(left: 34.0), - child: Row( - children: [ - SimpleCheckbox( - onChanged: (value) => - sendViewModel.setShowAddressBookPopup(!value)), - const SizedBox(width: 8), - Text( - 'Don’t ask me next time', - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 14, - fontFamily: 'Lato', - fontWeight: FontWeight.w500, - color: Theme.of(context).textTheme.titleLarge!.color, - decoration: TextDecoration.none, - ), - ), - ], - ), - ), - doubleActionLeftButtonText: 'No', - doubleActionRightButtonText: 'Yes', - onLeftActionButtonPressed: () { - Navigator.of(bottomSheetContext).pop(); - if (context.mounted) { - Navigator.of(context) - .pushNamedAndRemoveUntil(Routes.dashboard, (route) => false); - } - RequestReviewHandler.requestReview(); - newContactAddress = null; - }, - onRightActionButtonPressed: () { - Navigator.of(bottomSheetContext).pop(); - RequestReviewHandler.requestReview(); - if (context.mounted) { - Navigator.of(context).pushNamed(Routes.addressBookAddContact, - arguments: newContactAddress); - } - newContactAddress = null; - }, - ) - : InfoBottomSheet( - footerType: FooterType.singleActionButton, - titleText: S.of(bottomSheetContext).transaction_sent, - contentImage: 'assets/images/birthday_cake.png', - singleActionButtonText: S.of(bottomSheetContext).close, - singleActionButtonKey: ValueKey('send_page_transaction_sent_button_key'), - onSingleActionButtonPressed: () { - Navigator.of(bottomSheetContext).pop(); - Future.delayed(Duration.zero, () { - if (context.mounted) { - Navigator.of(context) - .pushNamedAndRemoveUntil(Routes.dashboard, (route) => false); - } - RequestReviewHandler.requestReview(); - newContactAddress = null; - }); - }, - ); - }, - ); - - if (initialPaymentRequest?.callbackUrl?.isNotEmpty ?? false) { - // wait a second so it's not as jarring: - await Future.delayed(Duration(seconds: 1)); - try { - launchUrl( - Uri.parse(initialPaymentRequest!.callbackUrl!), - mode: LaunchMode.externalApplication, - ); - } catch (e) { - printV(e); - } - } - - sendViewModel.clearOutputs(); - }); - } - - if (state is IsDeviceSigningResponseState) { - WidgetsBinding.instance.addPostFrameCallback((_) { - if (!context.mounted) return; - - showModalBottomSheet( - context: context, - isDismissible: false, - builder: (context) { - dialogContext = context; - return LoadingBottomSheet(titleText: S.of(context).processing_signed_tx); - }, - ); - }); - } - - if (state is IsAwaitingDeviceResponseState) { - WidgetsBinding.instance.addPostFrameCallback((_) { - if (!context.mounted) return; - - showModalBottomSheet( - context: context, - isDismissible: false, - builder: (context) { - dialogContext = context; - return InfoBottomSheet( - footerType: FooterType.singleActionButton, - titleText: S.of(context).proceed_on_device, - contentImage: 'assets/images/hardware_wallet/ledger_nano_x.png', - contentImageColor: Theme.of(context).colorScheme.onSurface, - content: S.of(context).proceed_on_device_description, - singleActionButtonText: S.of(context).cancel, - onSingleActionButtonPressed: () { - sendViewModel.state = InitialExecutionState(); - Navigator.of(context).pop(); - }, - ); - }); - }); - } - }); - - _effectsInstalled = true; - } - - Future _setInputsFromTemplate(BuildContext context, - {required Output output, required Template template}) async { - output.address = template.address; - - if (template.isCurrencySelected) { - sendViewModel.setSelectedCryptoCurrency(template.cryptoCurrency); - output.setCryptoAmount(template.amount); - } else { - final fiatFromTemplate = - FiatCurrency.all.singleWhere((element) => element.title == template.fiatCurrency); - - sendViewModel.setFiatCurrency(fiatFromTemplate); - output.setFiatAmount(template.amountFiat); - } - - output.resetParsedAddress(); - } - - Output _defineCurrentOutput() { - if (controller.page == null) throw Exception('Controller page is null'); - final itemCount = controller.page!.round(); - return sendViewModel.outputs[itemCount]; - } - - void showErrorValidationAlert(BuildContext context) => showPopUp( - context: context, - builder: (context) => AlertWithOneAction( - alertTitle: S.of(context).error, - alertContent: 'Please, check receiver forms', - buttonText: S.of(context).ok, - buttonAction: () => Navigator.of(context).pop(), - ), - ); - - bool isRegularElectrumAddress(String address) { - final supportedTypes = [CryptoCurrency.btc, CryptoCurrency.ltc, CryptoCurrency.bch]; - final excludedPatterns = [ - RegExp(AddressValidator.silentPaymentAddressPatternMainnet), - RegExp(AddressValidator.silentPaymentAddressPatternTestnet), - RegExp(AddressValidator.mWebAddressPattern), - RegExp(AddressValidator.bolt11InvoiceMatcher), - ]; - - final trimmed = address.trim(); - - bool isValid = false; - for (final type in supportedTypes) { - final addressPattern = AddressValidator.getAddressFromStringPattern(type); - if (addressPattern != null) { - final regex = RegExp('^$addressPattern\$'); - if (regex.hasMatch(trimmed)) { - isValid = true; - break; - } - } - } - - for (final pattern in excludedPatterns) { - if (pattern.hasMatch(trimmed)) return false; - } - - return isValid; - } - - String _sendButtonText(BuildContext context) { - if (!sendViewModel.isReadyForSend) return S.of(context).synchronizing; - if (sendViewModel.payjoinUri != null) return S.of(context).send_payjoin; - return S.of(context).send; - } -} diff --git a/lib/src/screens/send/send_template_page.dart b/lib/src/screens/send/send_template_page.dart deleted file mode 100644 index 20605c211..000000000 --- a/lib/src/screens/send/send_template_page.dart +++ /dev/null @@ -1,189 +0,0 @@ -import 'package:cake_wallet/src/widgets/trail_button.dart'; -import 'package:cake_wallet/view_model/send/template_view_model.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:flutter/material.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/view_model/send/send_template_view_model.dart'; -import 'package:cake_wallet/src/widgets/primary_button.dart'; -import 'package:cake_wallet/src/widgets/scrollable_with_bottom_section.dart'; -import 'package:cake_wallet/src/screens/send/widgets/send_template_card.dart'; -import 'package:smooth_page_indicator/smooth_page_indicator.dart'; - -class SendTemplatePage extends BasePage { - SendTemplatePage({required this.sendTemplateViewModel}); - - final SendTemplateViewModel sendTemplateViewModel; - final _formKey = GlobalKey(); - final controller = PageController(initialPage: 0); - - @override - String get title => S.current.exchange_new_template; - - @override - bool get extendBodyBehindAppBar => true; - - @override - bool get gradientAll => true; - - @override - AppBarStyle get appBarStyle => AppBarStyle.transparent; - - @override - Function(BuildContext)? get pushToNextWidget => (context) { - FocusScopeNode currentFocus = FocusScope.of(context); - if (!currentFocus.hasPrimaryFocus) { - currentFocus.focusedChild?.unfocus(); - } - }; - - @override - Widget trailing(context) => Observer( - builder: (_) { - return sendTemplateViewModel.recipients.length > 1 - ? TrailButton( - caption: S.of(context).remove, - onPressed: () { - int pageToJump = (controller.page?.round() ?? 0) - 1; - pageToJump = pageToJump > 0 ? pageToJump : 0; - final recipient = _defineCurrentRecipient(); - sendTemplateViewModel.removeRecipient(recipient); - controller.jumpToPage(pageToJump); - }, - ) - : TrailButton( - caption: S.of(context).clear, - onPressed: () { - final recipient = _defineCurrentRecipient(); - _formKey.currentState?.reset(); - recipient.reset(); - }, - ); - }, - ); - - @override - Widget body(BuildContext context) { - return Form( - key: _formKey, - child: ScrollableWithBottomSection( - contentPadding: EdgeInsets.only(bottom: 24), - content: FocusTraversalGroup( - policy: OrderedTraversalPolicy(), - child: Column( - children: [ - Container( - height: 460, - child: Observer( - builder: (_) { - return PageView.builder( - scrollDirection: Axis.horizontal, - controller: controller, - itemCount: sendTemplateViewModel.recipients.length, - itemBuilder: (_, index) { - final template = sendTemplateViewModel.recipients[index]; - return SendTemplateCard( - template: template, - index: index, - sendTemplateViewModel: sendTemplateViewModel, - ); - }, - ); - }, - ), - ), - Padding( - padding: EdgeInsets.only(top: 10, left: 24, right: 24, bottom: 10), - child: Container( - height: 10, - child: Observer( - builder: (_) { - final count = sendTemplateViewModel.recipients.length; - - return count > 1 - ? Semantics( - button: false, - label: 'Page Indicator', - hint: 'Swipe to change receiver', - excludeSemantics: true, - child: SmoothPageIndicator( - controller: controller, - count: count, - effect: ScrollingDotsEffect( - spacing: 6.0, - radius: 6.0, - dotWidth: 6.0, - dotHeight: 6.0, - dotColor: Theme.of(context).colorScheme.outlineVariant, - activeDotColor: Theme.of(context).colorScheme.primary, - ), - ), - ) - : Offstage(); - }, - ), - ), - ), - ], - ), - ), - bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24), - bottomSection: Column( - children: [ - if (sendTemplateViewModel.hasMultiRecipient) - Padding( - padding: EdgeInsets.only(bottom: 12), - child: PrimaryButton( - onPressed: () { - sendTemplateViewModel.addRecipient(); - Future.delayed(const Duration(milliseconds: 250), () { - controller.jumpToPage(sendTemplateViewModel.recipients.length - 1); - }); - }, - text: S.of(context).add_receiver, - color: Colors.transparent, - textColor: Theme.of(context).colorScheme.onSurfaceVariant, - isDottedBorder: true, - borderColor: Theme.of(context).colorScheme.surfaceContainerHighest, - ), - ), - PrimaryButton( - onPressed: () { - if (_formKey.currentState != null && _formKey.currentState!.validate()) { - final mainTemplate = sendTemplateViewModel.recipients[0]; - final additionalRecipients = sendTemplateViewModel.recipients - .map((element) => element.toTemplate( - cryptoCurrency: element.selectedCurrency.title, - fiatCurrency: sendTemplateViewModel.fiatCurrency)) - .toList(); - - sendTemplateViewModel.addTemplate( - isCurrencySelected: mainTemplate.isCryptoSelected, - name: mainTemplate.name, - address: mainTemplate.address, - cryptoCurrency: mainTemplate.selectedCurrency.title, - amount: mainTemplate.output.cryptoAmount, - amountFiat: mainTemplate.output.fiatAmount, - additionalRecipients: additionalRecipients, - ); - Navigator.of(context).pop(); - } - }, - text: S.of(context).save, - color: Theme.of(context).colorScheme.primary, - textColor: Theme.of(context).colorScheme.onPrimary, - ) - ], - ), - ), - ); - } - - TemplateViewModel _defineCurrentRecipient() { - if (controller.page == null) { - throw Exception('Controller page is null'); - } - final itemCount = controller.page!.round(); - return sendTemplateViewModel.recipients[itemCount]; - } -} diff --git a/lib/src/screens/send/transaction_success_info_page.dart b/lib/src/screens/send/transaction_success_info_page.dart deleted file mode 100644 index bd4f5cc05..000000000 --- a/lib/src/screens/send/transaction_success_info_page.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/screens/Info_page.dart'; -import 'package:flutter/cupertino.dart'; - -class TransactionSuccessPage extends InfoPage { - TransactionSuccessPage({required this.content}) - : super( - imageLightPath: 'assets/images/birthday_cake.png', - imageDarkPath: 'assets/images/birthday_cake.png', - ); - - final String content; - - @override - bool get onWillPop => false; - - @override - String get pageTitle => 'Transaction Sent Successfully'; - - @override - String get pageDescription => content; - - @override - String get buttonText => S.current.ok; - - @override - Key? get buttonKey => ValueKey('transaction_success_info_page_button_key'); - - @override - void Function(BuildContext) get onPressed => (BuildContext context) { - if (context.mounted) Navigator.of(context).pop(); - }; -} diff --git a/lib/src/screens/send/widgets/choose_yat_address_alert.dart b/lib/src/screens/send/widgets/choose_yat_address_alert.dart deleted file mode 100644 index 5b5d551bb..000000000 --- a/lib/src/screens/send/widgets/choose_yat_address_alert.dart +++ /dev/null @@ -1,116 +0,0 @@ -import 'package:cake_wallet/src/widgets/cake_scrollbar.dart'; -import 'package:cake_wallet/src/widgets/section_divider.dart'; -import 'package:flutter/material.dart'; -import 'package:cake_wallet/src/widgets/base_alert_dialog.dart'; - -class ChooseYatAddressAlert extends BaseAlertDialog { - ChooseYatAddressAlert({ - required this.alertTitle, - required this.alertContent, - required this.addresses, - }); - - final String alertTitle; - final String alertContent; - final List addresses; - - @override - String get titleText => alertTitle; - - @override - String get contentText => alertContent; - - @override - bool get barrierDismissible => false; - - @override - Widget actionButtons(BuildContext context) => ChooseYatAddressButtons(addresses); -} - -class ChooseYatAddressButtons extends StatefulWidget { - ChooseYatAddressButtons(this.addresses); - - final List addresses; - - @override - ChooseYatAddressButtonsState createState() => ChooseYatAddressButtonsState(addresses); -} - -class ChooseYatAddressButtonsState extends State { - ChooseYatAddressButtonsState(this.addresses) : itemCount = addresses?.length ?? 0; - - final List addresses; - final int itemCount; - final double backgroundHeight = 118; - final double thumbHeight = 72; - ScrollController controller = ScrollController(); - double fromTop = 0; - - @override - Widget build(BuildContext context) { - controller.addListener(() { - fromTop = controller.hasClients - ? (controller.offset / - controller.position.maxScrollExtent * - (backgroundHeight - thumbHeight)) - : 0; - setState(() {}); - }); - - return Stack( - alignment: Alignment.center, - clipBehavior: Clip.none, - children: [ - Container( - width: 300, - height: 158, - color: Theme.of(context).colorScheme.surface, - child: ListView.separated( - controller: controller, - padding: EdgeInsets.all(0), - itemCount: itemCount, - separatorBuilder: (_, __) => const HorizontalSectionDivider(), - itemBuilder: (context, index) { - final address = addresses[index]; - - return GestureDetector( - onTap: () => Navigator.of(context).pop(address), - child: Container( - width: 300, - height: 52, - padding: EdgeInsets.only(left: 24, right: 24), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Expanded( - child: Text( - address, - textAlign: TextAlign.center, - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 15, - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurfaceVariant, - decoration: TextDecoration.none, - ), - ), - ) - ], - ), - ), - ); - }, - ), - ), - if (itemCount > 3) - CakeScrollbar( - backgroundHeight: backgroundHeight, - thumbHeight: thumbHeight, - fromTop: fromTop, - ) - ], - ); - } -} diff --git a/lib/src/screens/send/widgets/send_card.dart b/lib/src/screens/send/widgets/send_card.dart deleted file mode 100644 index 3f1682b11..000000000 --- a/lib/src/screens/send/widgets/send_card.dart +++ /dev/null @@ -1,1147 +0,0 @@ -import 'dart:async'; - -import 'package:cake_wallet/core/open_crypto_pay/open_cryptopay_service.dart'; -import 'package:cake_wallet/entities/balance_display_mode.dart'; -import 'package:cake_wallet/entities/priority_for_wallet_type.dart'; -import 'package:cake_wallet/src/screens/receive/widgets/currency_input_field.dart'; -import 'package:cake_wallet/src/widgets/bottom_sheet/payment_confirmation_bottom_sheet.dart'; -import 'package:cake_wallet/src/widgets/bottom_sheet/wallet_switcher_bottom_sheet.dart'; -import 'package:cake_wallet/src/widgets/bottom_sheet/swap_confirmation_bottom_sheet.dart'; -import 'package:cake_wallet/src/widgets/bottom_sheet/token_selection_bottom_sheet.dart'; -import 'package:cake_wallet/src/widgets/bottom_sheet/info_bottom_sheet_widget.dart'; -import 'package:cake_wallet/src/widgets/picker.dart'; -import 'package:cake_wallet/src/widgets/standard_checkbox.dart'; -import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart'; - -import 'package:cake_wallet/themes/core/material_base_theme.dart'; -import 'package:cake_wallet/utils/payment_request.dart'; -import 'package:cake_wallet/utils/responsive_layout_util.dart'; -import 'package:cake_wallet/view_model/payment/payment_view_model.dart'; -import 'package:cake_wallet/view_model/wallet_switcher_view_model.dart'; -import 'package:cake_wallet/exchange/trade.dart'; -import 'package:cw_core/crypto_currency.dart'; -import 'package:cw_core/currency.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/view_model/send/output.dart'; -import 'package:cw_core/transaction_priority.dart'; -import 'package:cw_core/unspent_coin_type.dart'; -import 'package:cw_core/utils/print_verbose.dart'; -import 'package:cw_core/wallet_info.dart'; -import 'package:cw_core/wallet_type.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:mobx/mobx.dart'; -import 'package:cake_wallet/view_model/send/send_view_model.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; -import 'package:cake_wallet/src/widgets/address_text_field.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; -import 'package:cake_wallet/di.dart'; -import 'package:cake_wallet/evm/evm.dart'; -import 'package:cake_wallet/reactions/wallet_connect.dart'; -import 'package:cake_wallet/store/app_store.dart'; - -class SendCard extends StatefulWidget { - SendCard({ - Key? key, - required this.output, - required this.sendViewModel, - required this.paymentViewModel, - required this.walletSwitcherViewModel, - required this.currentTheme, - this.initialPaymentRequest, - this.cryptoAmountFocus, - this.fiatAmountFocus, - }) : super(key: key); - - final Output output; - final SendViewModel sendViewModel; - final PaymentViewModel paymentViewModel; - final WalletSwitcherViewModel walletSwitcherViewModel; - final PaymentRequest? initialPaymentRequest; - final FocusNode? cryptoAmountFocus; - final FocusNode? fiatAmountFocus; - final MaterialThemeBase currentTheme; - - @override - SendCardState createState() => SendCardState( - output: output, - sendViewModel: sendViewModel, - paymentViewModel: paymentViewModel, - walletSwitcherViewModel: walletSwitcherViewModel, - initialPaymentRequest: initialPaymentRequest, - currentTheme: currentTheme, - // cryptoAmountFocus: cryptoAmountFocus ?? FocusNode(), - // fiatAmountFocus: fiatAmountFocus ?? FocusNode(), - // cryptoAmountFocus: FocusNode(), - // fiatAmountFocus: FocusNode(), - ); -} - -class SendCardState extends State with AutomaticKeepAliveClientMixin { - SendCardState({ - required this.output, - required this.sendViewModel, - required this.paymentViewModel, - required this.walletSwitcherViewModel, - this.initialPaymentRequest, - required this.currentTheme, - }) : addressController = TextEditingController(), - cryptoAmountController = TextEditingController(), - fiatAmountController = TextEditingController(), - noteController = TextEditingController(), - extractedAddressController = TextEditingController(), - addressFocusNode = FocusNode(); - - static const prefixIconWidth = 34.0; - static const prefixIconHeight = 34.0; - - final MaterialThemeBase currentTheme; - final Output output; - final SendViewModel sendViewModel; - final PaymentViewModel paymentViewModel; - final WalletSwitcherViewModel walletSwitcherViewModel; - final PaymentRequest? initialPaymentRequest; - - final TextEditingController addressController; - final TextEditingController cryptoAmountController; - final TextEditingController fiatAmountController; - final TextEditingController noteController; - final TextEditingController extractedAddressController; - final FocusNode addressFocusNode; - - bool _effectsInstalled = false; - BuildContext? loadingBottomSheetContext; - bool _justHandledPasteButton = false; - String _lastHandledAddress = ''; - - @override - void initState() { - super.initState(); - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - sendViewModel.updateSendingBalance(); - }); - - /// if the current wallet doesn't match the one in the qr code - if (initialPaymentRequest != null && - sendViewModel.walletCurrencyName != initialPaymentRequest!.scheme.toLowerCase()) { - WidgetsBinding.instance.addPostFrameCallback( - (timeStamp) { - if (mounted) { - final prefix = - initialPaymentRequest!.scheme.isNotEmpty ? "${initialPaymentRequest!.scheme}:" : ""; - final amount = initialPaymentRequest!.amount.isNotEmpty - ? "?amount=${initialPaymentRequest!.amount}" - : ""; - final uri = prefix + initialPaymentRequest!.address + amount; - _handlePaymentFlow(uri, initialPaymentRequest!); - } - }, - ); - } - } - - @override - void dispose() { - addressController.dispose(); - cryptoAmountController.dispose(); - fiatAmountController.dispose(); - noteController.dispose(); - extractedAddressController.dispose(); - addressFocusNode.dispose(); - super.dispose(); - } - - Future _handlePaymentFlow(String uri, PaymentRequest paymentRequest) async { - if (uri.contains('@') || paymentRequest.address.contains('@')) return; - - if (OpenCryptoPayService.isOpenCryptoPayQR(uri)) { - sendViewModel.createOpenCryptoPayTransaction(uri); - return; - } - - try { - final result = await paymentViewModel.processAddress(uri); - - if (paymentRequest.contractAddress != null) { - await sendViewModel.fetchTokenForContractAddress(paymentRequest.contractAddress!); - } - - switch (result.type) { - case PaymentFlowType.singleWallet: - case PaymentFlowType.multipleWallets: - case PaymentFlowType.noWallets: - await _showPaymentConfirmation( - paymentViewModel, - walletSwitcherViewModel, - paymentRequest, - result, - ); - break; - case PaymentFlowType.evmNetworkSelection: - await _showTokenSelectionFlow( - paymentViewModel, - walletSwitcherViewModel, - paymentRequest, - fixedNetwork: result.walletType, - ); - break; - case PaymentFlowType.solanaTokenSelection: - await _showTokenSelectionFlow( - paymentViewModel, - walletSwitcherViewModel, - paymentRequest, - fixedNetwork: WalletType.solana, - ); - break; - case PaymentFlowType.tronTokenSelection: - await _showTokenSelectionFlow( - paymentViewModel, - walletSwitcherViewModel, - paymentRequest, - fixedNetwork: WalletType.tron, - ); - - break; - case PaymentFlowType.currentWalletCompatible: - case PaymentFlowType.error: - case PaymentFlowType.incompatible: - _applyPaymentRequest(paymentRequest); - break; - } - } catch (e) { - printV('Payment flow error: $e'); - _applyPaymentRequest(paymentRequest); - } - } - - Future _showPaymentConfirmation( - PaymentViewModel paymentViewModel, - WalletSwitcherViewModel walletSwitcherViewModel, - PaymentRequest paymentRequest, - PaymentFlowResult result, - ) async { - if (!context.mounted) { - return; - } - - await showModalBottomSheet( - context: context, - isDismissible: true, - isScrollControlled: true, - builder: (BuildContext context) { - return PaymentConfirmationBottomSheet( - paymentFlowResult: result, - paymentViewModel: paymentViewModel, - walletSwitcherViewModel: walletSwitcherViewModel, - paymentRequest: paymentRequest, - onSelectWallet: () => _handleSelectWallet( - paymentViewModel, - walletSwitcherViewModel, - paymentRequest, - result, - ), - onChangeWallet: () => _handleChangeWallet( - paymentViewModel, - walletSwitcherViewModel, - paymentRequest, - result, - ), - onSwap: (bottomSheetContext) => - _handleSwapFlow(paymentViewModel, result, bottomSheetContext), - onSwitchNetwork: () => _handleSwitchNetwork( - paymentViewModel, - walletSwitcherViewModel, - paymentRequest, - result, - ), - ); - }, - ); - } - - Future _showTokenSelectionFlow( - PaymentViewModel paymentViewModel, - WalletSwitcherViewModel walletSwitcherViewModel, - PaymentRequest paymentRequest, { - WalletType? fixedNetwork, - }) async { - if (!context.mounted) { - return; - } - - await showModalBottomSheet( - context: context, - isDismissible: true, - isScrollControlled: true, - builder: (BuildContext context) { - return TokenSelectionBottomSheet( - paymentViewModel: paymentViewModel, - paymentRequest: paymentRequest, - fixedNetwork: fixedNetwork, - onNext: (PaymentFlowResult newResult) { - final canCheckCompatibility = evm != null && - isEVMCompatibleChain(sendViewModel.wallet.type) && - newResult.chainId != null; - - if (canCheckCompatibility) { - final selectedChainId = newResult.chainId!; - final isCompatible = selectedChainId == evm!.getSelectedChainId(sendViewModel.wallet); - - if (isCompatible) { - sendViewModel.setSelectedCryptoCurrency( - newResult.addressDetectionResult!.detectedCurrency!.title, - ); - _applyPaymentRequest(paymentRequest); - return; - } - } - - _showPaymentConfirmation( - paymentViewModel, - walletSwitcherViewModel, - paymentRequest, - newResult, - ); - }, - ); - }, - ); - } - - Future _handleSelectWallet( - PaymentViewModel paymentViewModel, - WalletSwitcherViewModel walletSwitcherViewModel, - PaymentRequest paymentRequest, - PaymentFlowResult result, - ) async { - Navigator.of(context).pop(); - - await showModalBottomSheet( - context: context, - isDismissible: true, - isScrollControlled: true, - builder: (BuildContext dialogContext) { - return WalletSwitcherBottomSheet( - viewModel: walletSwitcherViewModel, - filterWalletType: paymentViewModel.detectedWalletType, - ); - }, - ); - - final success = await walletSwitcherViewModel.switchToSelectedWallet(); - - if (success) { - if (isEVMCompatibleChain(sendViewModel.wallet.type) && result.chainId != null) { - final appStore = getIt.get(); - final node = appStore.settingsStore.getCurrentNode( - sendViewModel.wallet.type, - chainId: result.chainId, - ); - await evm!.selectChain(sendViewModel.wallet, result.chainId!, node: node); - } - - await sendViewModel.wallet.updateBalance(); - - final detectedCurrency = result.addressDetectionResult!.detectedCurrency; - if (detectedCurrency != null) { - sendViewModel.setSelectedCryptoCurrency(detectedCurrency.title); - } - - _applyPaymentRequest(paymentRequest); - } - } - - Future _handleChangeWallet( - PaymentViewModel paymentViewModel, - WalletSwitcherViewModel walletSwitcherViewModel, - PaymentRequest paymentRequest, - PaymentFlowResult result, - ) async { - if (mounted && Navigator.of(context).canPop()) { - Navigator.of(context).pop(); - } - - if (result.type == PaymentFlowType.singleWallet && result.wallet != null) { - walletSwitcherViewModel.selectWallet(result.wallet!); - final success = await walletSwitcherViewModel.switchToSelectedWallet(); - if (success) { - WidgetsBinding.instance.addPostFrameCallback((_) { - if (mounted) { - showModalBottomSheet( - context: context, - isDismissible: false, - builder: (BuildContext context) { - loadingBottomSheetContext = context; - return LoadingBottomSheet( - titleText: S.of(context).loading_your_wallet, - ); - }, - ); - } - }); - - // If EVM wallet and chainId is specified, switch to that chain - if (isEVMCompatibleChain(sendViewModel.wallet.type) && result.chainId != null) { - final appStore = getIt.get(); - final node = appStore.settingsStore.getCurrentNode( - sendViewModel.wallet.type, - chainId: result.chainId, - ); - await evm!.selectChain(sendViewModel.wallet, result.chainId!, node: node); - } - - await Future.delayed(const Duration(seconds: 2)); - if (loadingBottomSheetContext != null && - loadingBottomSheetContext!.mounted && - Navigator.canPop(loadingBottomSheetContext!)) { - Navigator.of(loadingBottomSheetContext!).pop(); - } - - await sendViewModel.wallet.updateBalance(); - sendViewModel - .setSelectedCryptoCurrency(result.addressDetectionResult!.detectedCurrency!.title); - _applyPaymentRequest(paymentRequest); - } - } else if (result.wallets.isNotEmpty && result.wallets.length == 1) { - walletSwitcherViewModel.selectWallet(result.wallets.first); - final success = await walletSwitcherViewModel.switchToSelectedWallet(); - if (success) { - WidgetsBinding.instance.addPostFrameCallback((_) { - if (context.mounted) { - showModalBottomSheet( - context: context, - isDismissible: false, - builder: (BuildContext context) { - loadingBottomSheetContext = context; - return LoadingBottomSheet( - titleText: S.of(context).loading_your_wallet, - ); - }, - ); - } - }); - - // If EVM wallet and chainId is specified, switch to that chain - if (isEVMCompatibleChain(sendViewModel.wallet.type) && result.chainId != null) { - final appStore = getIt.get(); - final node = appStore.settingsStore.getCurrentNode( - sendViewModel.wallet.type, - chainId: result.chainId, - ); - await evm!.selectChain(sendViewModel.wallet, result.chainId!, node: node); - } - - await Future.delayed(const Duration(seconds: 2)); - if (loadingBottomSheetContext != null && loadingBottomSheetContext!.mounted) { - Navigator.of(loadingBottomSheetContext!).pop(); - } - - await sendViewModel.wallet.updateBalance(); - sendViewModel - .setSelectedCryptoCurrency(result.addressDetectionResult!.detectedCurrency!.title); - _applyPaymentRequest(paymentRequest); - } - } - } - - Future _handleSwitchNetwork( - PaymentViewModel paymentViewModel, - WalletSwitcherViewModel walletSwitcherViewModel, - PaymentRequest paymentRequest, - PaymentFlowResult result, - ) async { - if (result.type != PaymentFlowType.evmNetworkSelection || result.wallet == null) return; - - if (context.mounted && Navigator.of(context).canPop()) { - Navigator.of(context).pop(); - } - - try { - WidgetsBinding.instance.addPostFrameCallback((_) { - if (context.mounted) { - showModalBottomSheet( - context: context, - isDismissible: false, - builder: (BuildContext context) { - loadingBottomSheetContext = context; - return LoadingBottomSheet( - titleText: S.of(context).loading_your_wallet, - ); - }, - ); - } - }); - - await paymentViewModel.selectChain(); - - await Future.delayed(const Duration(seconds: 2)); - if (loadingBottomSheetContext != null && loadingBottomSheetContext!.mounted) { - Navigator.of(loadingBottomSheetContext!).pop(); - } - - await sendViewModel.wallet.updateBalance(); - final detectedCurrency = result.addressDetectionResult?.detectedCurrency; - if (detectedCurrency != null) { - sendViewModel.setSelectedCryptoCurrency(detectedCurrency.title); - } - _applyPaymentRequest(paymentRequest); - } catch (e) { - if (loadingBottomSheetContext != null && loadingBottomSheetContext!.mounted) { - Navigator.of(loadingBottomSheetContext!).pop(); - } - printV('Switch network error: $e'); - } - } - - /// Apply payment request to current form - void _applyPaymentRequest(PaymentRequest paymentRequest) { - if (sendViewModel.usePayjoin) { - sendViewModel.payjoinUri = paymentRequest.pjUri; - } - addressController.text = paymentRequest.address; - if (paymentRequest.amount.isNotEmpty) { - cryptoAmountController.text = paymentRequest.amount; - } - noteController.text = paymentRequest.note; - } - - Future _handleSwapFlow( - PaymentViewModel paymentViewModel, - PaymentFlowResult result, - BuildContext bottomSheetContext, - ) async { - Navigator.of(bottomSheetContext).pop(); - - await Future.delayed(const Duration(milliseconds: 100)); - - if (!mounted) return; - - final bottomSheet = getIt.get(param1: result); - await showModalBottomSheet( - context: context, - isDismissible: true, - isScrollControlled: true, - builder: (BuildContext context) => bottomSheet, - ); - } - - @override - Widget build(BuildContext context) { - super.build(context); - _setEffects(context); - - // return Stack( - // children: [ - // return KeyboardActions( - // config: KeyboardActionsConfig( - // keyboardActionsPlatform: KeyboardActionsPlatform.IOS, - // keyboardBarColor: Theme.of(context).extension()!.keyboardBarColor, - // nextFocus: false, - // actions: [ - // KeyboardActionsItem( - // focusNode: cryptoAmountFocus, - // toolbarButtons: [(_) => KeyboardDoneButton()], - // ), - // KeyboardActionsItem( - // focusNode: fiatAmountFocus, - // toolbarButtons: [(_) => KeyboardDoneButton()], - // ) - // ], - // ), - // // child: Container( - // // height: 0, - // // color: Colors.transparent, - // // ), child: - // child: SizedBox( - // height: 100, - // width: 100, - // child: Text('Send Card'), - // ), - // ); - return Container( - decoration: responsiveLayoutUtil.shouldRenderMobileUI - ? BoxDecoration( - borderRadius: BorderRadius.only( - bottomLeft: Radius.circular(24), - bottomRight: Radius.circular(24), - ), - color: Theme.of(context).colorScheme.surfaceContainer, - ) - : null, - child: Padding( - padding: EdgeInsets.fromLTRB( - 24, - responsiveLayoutUtil.shouldRenderMobileUI ? 110 : 55, - 24, - responsiveLayoutUtil.shouldRenderMobileUI ? 32 : 0, - ), - child: Observer( - builder: (_) => Column( - mainAxisSize: MainAxisSize.min, - children: [ - Observer(builder: (_) { - final validator = output.isParsedAddress - ? sendViewModel.textValidator - : sendViewModel.addressValidator; - - return AddressTextField( - contentPadding: EdgeInsets.symmetric(vertical: 8), - hasUnderlineBorder: true, - fillColor: Theme.of(context).colorScheme.surfaceContainerHighest, - addressKey: ValueKey('send_page_address_textfield_key'), - focusNode: addressFocusNode, - controller: addressController, - onURIScanned: (uri) async { - output.resetParsedAddress(); - - // Process the payment through the new flow - await _handlePaymentFlow( - uri.toString(), - PaymentRequest.fromUri(uri), - ); - }, - options: [ - AddressTextFieldOption.paste, - AddressTextFieldOption.qrCode, - AddressTextFieldOption.addressBook - ], - textStyle: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 16, - fontWeight: FontWeight.w500, - ), - hintStyle: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - onPushPasteButton: (context) async { - _justHandledPasteButton = true; - try { - output.resetParsedAddress(); - - final address = - output.isParsedAddress ? output.extractedAddress : output.address; - - await _handlePaymentFlow( - address, - PaymentRequest( - address, - cryptoAmountController.text, - noteController.text, - "", - null, - ), - ); - } finally { - _justHandledPasteButton = false; - } - }, - onPushAddressBookButton: (context) async { - output.resetParsedAddress(); - }, - onSelectedContact: (contact) {}, - validator: validator, - selectedCurrency: sendViewModel.selectedCryptoCurrency, - ); - }), - if (output.isParsedAddress) - Padding( - padding: const EdgeInsets.only(top: 20), - child: BaseTextFormField( - fillColor: Theme.of(context).colorScheme.surfaceContainerHighest, - controller: extractedAddressController, - readOnly: true, - enableInteractiveSelection: false, - textStyle: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.onSurface, - ), - validator: sendViewModel.addressValidator, - ), - ), - CurrencyAmountTextField( - borderWidth: 0.0, - hasUnderlineBorder: true, - fillColor: Theme.of(context).colorScheme.surfaceContainerHighest, - currencyPickerButtonKey: ValueKey('send_page_currency_picker_button_key'), - amountTextfieldKey: ValueKey('send_page_amount_textfield_key'), - sendAllButtonKey: ValueKey('send_page_send_all_button_key'), - currencyAmountTextFieldWidgetKey: - ValueKey('send_page_crypto_currency_amount_textfield_widget_key'), - selectedCurrency: - output.useSatoshi ? "SATS" : sendViewModel.selectedCryptoCurrency.title, - selectedCurrencyDecimals: - output.useSatoshi ? 0 : sendViewModel.selectedCryptoCurrency.decimals, - amountFocusNode: widget.cryptoAmountFocus, - amountController: cryptoAmountController, - isAmountEditable: true, - onTapPicker: () => _presentPicker(context), - isPickerEnable: sendViewModel.hasMultipleTokens, - tag: sendViewModel.selectedCryptoCurrency.tag, - allAmountButton: - !sendViewModel.isBatchSending && sendViewModel.shouldDisplaySendALL, - currencyValueValidator: output.sendAll - ? sendViewModel.allAmountValidator - : sendViewModel.amountValidator(output), - allAmountCallback: () async => - output.setSendAll(await sendViewModel.sendingBalance), - ), - Divider(height: 1, color: Theme.of(context).colorScheme.outlineVariant), - Observer( - builder: (_) { - // force rebuild on mobx - final _ = sendViewModel.coinTypeToSpendFrom; - return Padding( - padding: EdgeInsets.only(top: 10), - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - S.of(context).available_balance + ':', - style: Theme.of(context).textTheme.bodySmall!.copyWith( - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - ), - FutureBuilder( - future: sendViewModel.sendingBalance, - builder: (context, snapshot) { - return GestureDetector( - onTap: () { - sendViewModel.balanceViewModel.switchBalanceValue(); - }, - child: Observer(builder: (_) { - final hidden = sendViewModel.balanceViewModel.displayMode == - BalanceDisplayMode.hiddenBalance; - return Text( - hidden - ? S.of(context).show_balance_send_page - : (snapshot.data ?? sendViewModel.balance), - // default to balance while loading - style: Theme.of(context).textTheme.bodySmall!.copyWith( - fontWeight: FontWeight.w600, - color: hidden - ? Theme.of(context).colorScheme.primary - : Theme.of(context).colorScheme.onSurfaceVariant, - ), - ); - }), - ); - }, - ) - ], - ), - ); - }, - ), - if (!sendViewModel.isFiatDisabled) - CurrencyAmountTextField( - borderWidth: 0.0, - hasUnderlineBorder: true, - fillColor: Theme.of(context).colorScheme.surfaceContainerHighest, - amountTextfieldKey: ValueKey('send_page_fiat_amount_textfield_key'), - currencyAmountTextFieldWidgetKey: - ValueKey('send_page_fiat_currency_amount_textfield_widget_key'), - selectedCurrency: sendViewModel.fiat.title, - selectedCurrencyDecimals: sendViewModel.fiat.decimals, - amountFocusNode: widget.fiatAmountFocus, - amountController: fiatAmountController, - hintText: '0.00', - isAmountEditable: true, - allAmountButton: false, - ), - Divider(height: 1, color: Theme.of(context).colorScheme.outlineVariant), - Padding( - padding: EdgeInsets.only(top: 20), - child: BaseTextFormField( - hasUnderlineBorder: true, - contentPadding: EdgeInsets.symmetric(vertical: 8), - fillColor: Theme.of(context).colorScheme.surfaceContainerHighest, - key: ValueKey('send_page_note_textfield_key'), - controller: noteController, - keyboardType: TextInputType.multiline, - maxLines: null, - textStyle: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontWeight: FontWeight.w500, - ), - hintText: S.of(context).note_optional, - placeholderTextStyle: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - ), - if (sendViewModel.hasFees) - Observer( - builder: (_) => GestureDetector( - key: ValueKey('send_page_select_fee_priority_button_key'), - onTap: sendViewModel.feesViewModel.hasFeesPriority - ? () => pickTransactionPriority(context, output) - : () {}, - child: Container( - padding: EdgeInsets.only(top: 24), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - S.of(context).send_estimated_fee, - style: Theme.of(context).textTheme.bodySmall!.copyWith( - fontWeight: FontWeight.w700, - ), - ), - Container( - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Text( - '${output.estimatedFee} ${sendViewModel.currencySymbol}', - style: Theme.of(context).textTheme.bodySmall!.copyWith( - fontWeight: FontWeight.w600, - ), - ), - Padding( - padding: EdgeInsets.only(top: 5), - child: sendViewModel.isFiatDisabled - ? const SizedBox(height: 14) - : Text( - '${output.estimatedFeeFiatAmount} ${sendViewModel.fiat.title}', - style: - Theme.of(context).textTheme.bodySmall!.copyWith( - fontWeight: FontWeight.w600, - color: Theme.of(context) - .colorScheme - .onSurfaceVariant, - ), - ), - ), - ], - ), - Padding( - padding: EdgeInsets.only(top: 2, left: 5), - child: Icon( - Icons.arrow_forward_ios, - size: 12, - color: Theme.of(context).colorScheme.onSurface, - ), - ) - ], - ), - ) - ], - ), - ), - ), - ), - if (sendViewModel.hasCoinControl) - Padding( - padding: EdgeInsets.only(top: 6), - child: GestureDetector( - key: ValueKey('send_page_unspent_coin_button_key'), - onTap: () async { - await Navigator.of(context).pushNamed( - Routes.unspentCoinsList, - arguments: widget.sendViewModel.coinTypeToSpendFrom, - ); - if (mounted) { - // we just got back from the unspent coins list screen, so we need to recompute the sending balance: - sendViewModel.updateSendingBalance(); - } - }, - child: Container( - color: Colors.transparent, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - S.of(context).coin_control, - style: Theme.of(context).textTheme.bodySmall!.copyWith( - fontWeight: FontWeight.w700, - ), - ), - Icon( - Icons.arrow_forward_ios, - size: 12, - color: Theme.of(context).colorScheme.onSurface, - ), - ], - ), - ), - ), - ), - if (sendViewModel.isMwebAvailable) - Observer( - builder: (_) => Padding( - padding: EdgeInsets.only(top: 14), - child: GestureDetector( - key: ValueKey('send_page_unspent_coin_button_key'), - onTap: () { - bool value = - widget.sendViewModel.coinTypeToSpendFrom == UnspentCoinType.any; - sendViewModel.setAllowMwebCoins(!value); - }, - child: Container( - color: Colors.transparent, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - StandardCheckbox( - caption: S.of(context).litecoin_mweb_allow_coins, - captionColor: Theme.of(context).colorScheme.onSurfaceVariant, - borderColor: Theme.of(context).colorScheme.primary, - iconColor: Theme.of(context).colorScheme.primary, - value: - widget.sendViewModel.coinTypeToSpendFrom == UnspentCoinType.any, - onChanged: (bool? value) { - sendViewModel.setAllowMwebCoins(value ?? false); - }, - ), - ], - ), - ), - ), - ), - ), - ], - ), - ), - ), - ); - } - - void _setEffects(BuildContext context) { - if (_effectsInstalled) { - return; - } - - if (output.address.isNotEmpty) { - addressController.text = output.address; - } - if (output.cryptoAmount.isNotEmpty) { - cryptoAmountController.text = output.cryptoAmount; - } - fiatAmountController.text = output.fiatAmount; - noteController.text = output.note; - extractedAddressController.text = output.extractedAddress; - - cryptoAmountController.addListener(() { - final amount = cryptoAmountController.text; - - if (output.sendAll && amount != S.current.all) { - output.sendAll = false; - } - - if (S.current.all.contains(amount)) return; - - final cAmount = sendViewModel.amountParsingProxy - .getDisplayCryptoAmount(output.cryptoAmount, sendViewModel.selectedCryptoCurrency); - if (amount != cAmount) { - final newAmount = sendViewModel.amountParsingProxy - .getCanonicalCryptoAmount(amount, sendViewModel.selectedCryptoCurrency); - output.setCryptoAmount(newAmount); - } - }); - - fiatAmountController.addListener(() { - final amount = fiatAmountController.text; - - if (amount != output.fiatAmount) { - output.sendAll = false; - output.setFiatAmount(amount); - } - }); - - noteController.addListener(() { - final note = noteController.text; - - if (note != output.note) { - output.note = note; - } - }); - - reaction((_) => output.sendAll, (bool all) { - if (all) cryptoAmountController.text = S.current.all; - }); - - reaction((_) => sendViewModel.selectedCryptoCurrency, (Currency currency) async { - if (output.sendAll) { - output.setSendAll(await sendViewModel.sendingBalance); - } - - output.setCryptoAmount(sendViewModel.amountParsingProxy.getCanonicalCryptoAmount( - cryptoAmountController.text, sendViewModel.selectedCryptoCurrency)); - }); - - reaction((_) => output.fiatAmount, (String amount) { - if (amount != fiatAmountController.text) { - fiatAmountController.text = amount; - } - }); - - reaction((_) => output.cryptoAmount, (String amount) { - if (output.sendAll && amount != S.current.all) { - output.sendAll = false; - } - - final cryptoAmount = sendViewModel.amountParsingProxy.getCanonicalCryptoAmount( - cryptoAmountController.text, sendViewModel.selectedCryptoCurrency); - if (amount != cryptoAmount) { - cryptoAmountController.text = sendViewModel.amountParsingProxy - .getDisplayCryptoAmount(amount, sendViewModel.selectedCryptoCurrency); - } - }); - - reaction((_) => output.address, (String address) { - if (address != addressController.text) { - addressController.text = address; - } - }); - - addressController.addListener(() { - final address = addressController.text; - - if (output.address != address) { - output.resetParsedAddress(); - output.address = address; - - if (SendViewModelBase.isNonZeroAmountLightningInvoice(address)) { - sendViewModel.createTransaction(); - } - } - }); - - reaction((_) => output.note, (String note) { - if (note != noteController.text) { - noteController.text = note; - } - }); - - addressFocusNode.addListener(() async { - if (!addressFocusNode.hasFocus && addressController.text.isNotEmpty) { - final current = addressController.text.trim(); - if (current.isEmpty) return; - if (_justHandledPasteButton || _lastHandledAddress == current) return; - - // If it's a URI with params, go through URI flow - if (current.contains('=')) { - try { - final uri = Uri.parse(current); - _lastHandledAddress = current; - await _handlePaymentFlow( - uri.toString(), - PaymentRequest.fromUri(uri), - ); - return; - } catch (_) { - // fall through to plain address - } - } - - final parsedAddress = output.isParsedAddress ? output.extractedAddress : output.address; - - _lastHandledAddress = current; - await _handlePaymentFlow( - parsedAddress, - PaymentRequest( - parsedAddress, - cryptoAmountController.text, - noteController.text, - "", - null, - ), - ); - } - }); - - reaction((_) => output.extractedAddress, (String extractedAddress) { - extractedAddressController.text = extractedAddress; - }); - - if (initialPaymentRequest != null && - sendViewModel.walletCurrencyName == initialPaymentRequest!.scheme.toLowerCase()) { - addressController.text = initialPaymentRequest!.address; - cryptoAmountController.text = initialPaymentRequest!.amount; - noteController.text = initialPaymentRequest!.note; - } - - reaction((_) => sendViewModel.isReadyForSend, (bool isReadyForSend) { - if (isReadyForSend) { - sendViewModel.updateSendingBalance(); - } - }); - - _effectsInstalled = true; - } - - Future pickTransactionPriority(BuildContext context, Output output) async { - final items = priorityForWalletType(sendViewModel.walletType); - final selectedItem = items.indexOf(sendViewModel.feesViewModel.transactionPriority); - final customItemIndex = sendViewModel.feesViewModel.getCustomPriorityIndex(items); - final isBitcoinWallet = sendViewModel.walletType == WalletType.bitcoin; - final maxCustomFeeRate = sendViewModel.feesViewModel.maxCustomFeeRate?.toDouble(); - double? customFeeRate = - isBitcoinWallet ? sendViewModel.feesViewModel.customBitcoinFeeRate.toDouble() : null; - - FocusManager.instance.primaryFocus?.unfocus(); - - await showPopUp( - context: context, - builder: (BuildContext context) { - int selectedIdx = selectedItem; - return StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return Picker( - items: items, - displayItem: (TransactionPriority priority) => - sendViewModel.feesViewModel.displayFeeRate(priority, customFeeRate?.round()), - selectedAtIndex: selectedIdx, - customItemIndex: customItemIndex, - maxValue: maxCustomFeeRate, - title: S.of(context).please_select, - headerEnabled: !isBitcoinWallet, - closeOnItemSelected: !isBitcoinWallet, - mainAxisAlignment: MainAxisAlignment.center, - sliderValue: customFeeRate, - onSliderChanged: (double newValue) => setState(() => customFeeRate = newValue), - onItemSelected: (TransactionPriority priority) async { - sendViewModel.feesViewModel.setTransactionPriority(priority); - setState(() => selectedIdx = items.indexOf(priority)); - await output.calculateEstimatedFee(); - }, - ); - }, - ); - }, - ); - if (isBitcoinWallet) sendViewModel.feesViewModel.customBitcoinFeeRate = customFeeRate!.round(); - } - - void _presentPicker(BuildContext context) { - showPopUp( - context: context, - builder: (_) => CurrencyPicker( - key: ValueKey('send_page_currency_picker_dialog_button_key'), - selectedAtIndex: sendViewModel.currencies.indexOf(sendViewModel.selectedCryptoCurrency), - items: sendViewModel.currencies, - hintText: S.of(context).search_currency, - onItemSelected: (Currency cur) async { - final selectedCurrency = sendViewModel.selectedCryptoCurrency = (cur as CryptoCurrency); - await output.calculateEstimatedFee(); - return selectedCurrency; - }, - ), - ); - } - - @override - bool get wantKeepAlive => true; -} diff --git a/lib/src/screens/send/widgets/send_template_card.dart b/lib/src/screens/send/widgets/send_template_card.dart deleted file mode 100644 index 81ff5398d..000000000 --- a/lib/src/screens/send/widgets/send_template_card.dart +++ /dev/null @@ -1,256 +0,0 @@ -import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart'; -import 'package:cake_wallet/src/screens/receive/widgets/currency_input_field.dart'; -import 'package:cake_wallet/utils/payment_request.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; -import 'package:cake_wallet/view_model/send/template_view_model.dart'; -import 'package:cw_core/crypto_currency.dart'; -import 'package:cw_core/currency.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:flutter/material.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/view_model/send/send_template_view_model.dart'; -import 'package:cake_wallet/src/widgets/address_text_field.dart'; -import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; -import 'package:mobx/mobx.dart'; - -class SendTemplateCard extends StatelessWidget { - SendTemplateCard({ - super.key, - required this.template, - required this.index, - required this.sendTemplateViewModel, - }); - - final TemplateViewModel template; - final int index; - final SendTemplateViewModel sendTemplateViewModel; - - final _addressController = TextEditingController(); - final _cryptoAmountController = TextEditingController(); - final _fiatAmountController = TextEditingController(); - final _nameController = TextEditingController(); - final FocusNode _cryptoAmountFocus = FocusNode(); - final FocusNode _fiatAmountFocus = FocusNode(); - - bool _effectsInstalled = false; - - @override - Widget build(BuildContext context) { - _setEffects(context); - - return Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.only( - bottomLeft: Radius.circular(24), - bottomRight: Radius.circular(24), - ), - color: Theme.of(context).colorScheme.surfaceContainer, - ), - child: Column( - children: [ - Padding( - padding: EdgeInsets.fromLTRB(24, 90, 24, 32), - child: Column( - children: [ - SizedBox(height: 32), - if (index == 0) - BaseTextFormField( - contentPadding: EdgeInsets.symmetric(vertical: 8), - hasUnderlineBorder: true, - controller: _nameController, - hintText: sendTemplateViewModel.recipients.length > 1 - ? S.of(context).template_name - : S.of(context).send_name, - textStyle: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontWeight: FontWeight.w500, - ), - placeholderTextStyle: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant, - fontWeight: FontWeight.w500, - ), - validator: sendTemplateViewModel.templateValidator, - fillColor: Theme.of(context).colorScheme.surfaceContainerHighest, - ), - Padding( - padding: EdgeInsets.only(top: 20), - child: Observer( - builder: (context) { - return AddressTextField( - hasUnderlineBorder: true, - contentPadding: EdgeInsets.symmetric(vertical: 8), - selectedCurrency: template.selectedCurrency, - controller: _addressController, - onURIScanned: (uri) { - final paymentRequest = PaymentRequest.fromUri(uri); - _addressController.text = paymentRequest.address; - _cryptoAmountController.text = paymentRequest.amount; - }, - options: [ - AddressTextFieldOption.paste, - AddressTextFieldOption.qrCode, - AddressTextFieldOption.addressBook - ], - onPushPasteButton: (context) async { - template.output.resetParsedAddress(); - }, - onPushAddressBookButton: (context) async { - template.output.resetParsedAddress(); - }, - buttonColor: Theme.of(context).colorScheme.surfaceContainerHighest, - textStyle: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontWeight: FontWeight.w500, - ), - hintStyle: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - validator: sendTemplateViewModel.addressValidator, - fillColor: Theme.of(context).colorScheme.surfaceContainerHighest, - ); - }, - ), - ), - Focus( - onFocusChange: (hasFocus) { - if (hasFocus) template.setCryptoCurrency(true); - }, - child: Column( - children: [ - Observer( - builder: (context) => CurrencyAmountTextField( - hasUnderlineBorder: true, - borderWidth: 0.0, - selectedCurrency: template.selectedCurrency.title, - selectedCurrencyDecimals: template.selectedCurrency.decimals, - amountFocusNode: _cryptoAmountFocus, - amountController: _cryptoAmountController, - isSelected: template.isCryptoSelected, - tag: template.selectedCurrency.tag, - isPickerEnable: sendTemplateViewModel.hasMultipleTokens, - onTapPicker: () => _presentPicker(context), - currencyValueValidator: sendTemplateViewModel.amountValidator, - isAmountEditable: true, - fillColor: Theme.of(context).colorScheme.surfaceContainerHighest, - ), - ), - Divider(height: 1, color: Theme.of(context).colorScheme.outlineVariant), - ], - ), - ), - Focus( - onFocusChange: (hasFocus) { - if (hasFocus) template.setCryptoCurrency(false); - }, - child: Column( - children: [ - Observer( - builder: (context) => CurrencyAmountTextField( - hasUnderlineBorder: true, - borderWidth: 0.0, - selectedCurrency: sendTemplateViewModel.fiatCurrency, - selectedCurrencyDecimals: sendTemplateViewModel.fiatCurrencyDecimals, - amountFocusNode: _fiatAmountFocus, - amountController: _fiatAmountController, - isSelected: !template.isCryptoSelected, - hintText: '0.00', - isAmountEditable: true, - fillColor: Theme.of(context).colorScheme.surfaceContainerHighest, - ), - ), - Divider(height: 1, color: Theme.of(context).colorScheme.outlineVariant), - ], - ), - ), - ], - ), - ) - ], - ), - ); - } - - void _setEffects(BuildContext context) { - if (_effectsInstalled) { - return; - } - - final output = template.output; - - if (template.address.isNotEmpty) { - _addressController.text = template.address; - } - if (template.name.isNotEmpty) { - _nameController.text = template.name; - } - if (template.output.cryptoAmount.isNotEmpty) { - _cryptoAmountController.text = template.output.cryptoAmount; - } - if (template.output.fiatAmount.isNotEmpty) { - _fiatAmountController.text = template.output.fiatAmount; - } - - _addressController.addListener(() { - final address = _addressController.text; - - if (template.address != address) { - template.address = address; - } - }); - _cryptoAmountController.addListener(() { - final amount = _cryptoAmountController.text; - - if (amount != output.cryptoAmount) { - output.setCryptoAmount(amount); - } - }); - _fiatAmountController.addListener(() { - final amount = _fiatAmountController.text; - - if (amount != output.fiatAmount) { - output.setFiatAmount(amount); - } - }); - _nameController.addListener(() { - final name = _nameController.text; - - if (name != template.name) { - template.name = name; - } - }); - - reaction((_) => template.address, (String address) { - if (address != _addressController.text) { - _addressController.text = address; - } - }); - reaction((_) => output.cryptoAmount, (String amount) { - if (amount != _cryptoAmountController.text) { - _cryptoAmountController.text = amount; - } - }); - reaction((_) => output.fiatAmount, (String amount) { - if (amount != _fiatAmountController.text) { - _fiatAmountController.text = amount; - } - }); - reaction((_) => template.name, (String name) { - if (name != _nameController.text) { - _nameController.text = name; - } - }); - - _effectsInstalled = true; - } - - void _presentPicker(BuildContext context) { - showPopUp( - context: context, - builder: (_) => CurrencyPicker( - selectedAtIndex: sendTemplateViewModel.walletCurrencies.indexOf(template.selectedCurrency), - items: sendTemplateViewModel.walletCurrencies, - hintText: S.of(context).search_currency, - onItemSelected: (Currency cur) => template.changeSelectedCurrency(cur as CryptoCurrency), - ), - ); - } -} diff --git a/lib/src/screens/settings/attributes.dart b/lib/src/screens/settings/attributes.dart deleted file mode 100644 index fb6ebf4ac..000000000 --- a/lib/src/screens/settings/attributes.dart +++ /dev/null @@ -1 +0,0 @@ -enum Attributes { arrow, header, link, switcher, widget, rawWidget } diff --git a/lib/src/screens/settings/desktop_settings/desktop_settings_page.dart b/lib/src/screens/settings/desktop_settings/desktop_settings_page.dart deleted file mode 100644 index a792560a1..000000000 --- a/lib/src/screens/settings/desktop_settings/desktop_settings_page.dart +++ /dev/null @@ -1,119 +0,0 @@ -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/src/widgets/setting_action_button.dart'; -import 'package:cake_wallet/src/widgets/setting_actions.dart'; -import 'package:cake_wallet/typography.dart'; -import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:cake_wallet/router.dart' as Router; - -final _settingsNavigatorKey = GlobalKey(); - -class DesktopSettingsPage extends StatefulWidget { - const DesktopSettingsPage(this.dashboardViewModel, {super.key}); - - final DashboardViewModel dashboardViewModel; - - @override - State createState() => _DesktopSettingsPageState(); -} - -class _DesktopSettingsPageState extends State { - final int itemCount = SettingActions.all.length; - - int? currentPage; - - void _onItemChange(int index) { - setState(() { - currentPage = index; - }); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Container( - color: Theme.of(context).colorScheme.surface, - height: MediaQuery.of(context).size.height, - child: Row( - children: [ - Expanded( - flex: 1, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.fromLTRB(24, 24, 24, 4), - child: Text( - S.current.settings, - style: textXLarge(), - ), - ), - Expanded( - child: ListView.separated( - padding: EdgeInsets.only(top: 0), - itemBuilder: (_, index) { - final item = SettingActions.all[index]; - - if (!widget.dashboardViewModel.hasSilentPayments && - item.name(context) == S.of(context).silent_payments_settings) { - return Container(); - } - - if ((!widget.dashboardViewModel.isMoneroViewOnly && - item.name(context) == S.of(context).export_outputs) || - (!widget.dashboardViewModel.hasMweb && - item.name(context) == S.of(context).litecoin_mweb_settings)) { - return Container(); - } - - final isLastTile = index == itemCount - 1; - return SettingActionButton( - isLastTile: isLastTile, - selectionActive: currentPage != null, - isSelected: currentPage == index, - isArrowVisible: true, - onTap: () { - if (currentPage != index) { - final settingContext = - _settingsNavigatorKey.currentState?.context ?? context; - item.onTap.call(settingContext); - _onItemChange(index); - } - }, - image: item.image, - title: item.name.call(context), - ); - }, - separatorBuilder: (_, index) => Container( - height: 0.0, - color: Theme.of(context).colorScheme.outlineVariant, - ), - itemCount: itemCount, - ), - ), - ], - ), - ), - Flexible( - flex: 2, - child: ConstrainedBox( - constraints: BoxConstraints(maxWidth: 500), - child: Navigator( - key: _settingsNavigatorKey, - initialRoute: Routes.empty_no_route, - onGenerateRoute: (settings) => Router.createRoute(settings), - onGenerateInitialRoutes: (NavigatorState navigator, String initialRouteName) { - return [ - navigator.widget.onGenerateRoute!(RouteSettings(name: initialRouteName))! - ]; - }, - ), - ), - ) - ], - ), - ), - ); - } -} diff --git a/lib/src/screens/settings/items/item_headers.dart b/lib/src/screens/settings/items/item_headers.dart deleted file mode 100644 index eca0576f4..000000000 --- a/lib/src/screens/settings/items/item_headers.dart +++ /dev/null @@ -1,18 +0,0 @@ -class ItemHeaders { - static const nodes = 'Nodes'; - static const currentNode = 'Current node'; - static const wallets = 'Wallets'; - static const displayBalanceAs = 'Display balance as'; - static const currency = 'Currency'; - static const feePriority = 'Fee priority'; - static const saveRecipientAddress = 'Save recipient address'; - static const personal = 'Personal'; - static const changePIN = 'Change PIN'; - static const changeLanguage = 'Change language'; - static const allowBiometricalAuthentication = 'Allow biometrical authentication'; - static const darkMode = 'Dark mode'; - static const support = 'Support'; - static const termsAndConditions = 'Terms and conditions'; - static const faq = 'FAQ'; - static const version = 'Version'; -} diff --git a/lib/src/screens/settings/items/settings_item.dart b/lib/src/screens/settings/items/settings_item.dart deleted file mode 100644 index 787133a80..000000000 --- a/lib/src/screens/settings/items/settings_item.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:cake_wallet/src/screens/settings/attributes.dart'; - -class SettingsItem { - SettingsItem( - {required this.onTaped, - required this.title, - required this.link, - required this.image, - required this.widget, - required this.attribute, - required this.widgetBuilder}); - - final VoidCallback onTaped; - final String title; - final String link; - final Image image; - final Widget widget; - final Attributes attribute; - final WidgetBuilder widgetBuilder; -} diff --git a/lib/src/screens/settings/silent_payments_settings.dart b/lib/src/screens/settings/silent_payments_settings.dart index 4505a4e17..fdb0455d9 100644 --- a/lib/src/screens/settings/silent_payments_settings.dart +++ b/lib/src/screens/settings/silent_payments_settings.dart @@ -32,14 +32,6 @@ class SilentPaymentsSettingsPage extends StatelessWidget { padding: EdgeInsets.only(top: 10), child: Column( children: [ - if (!FeatureFlag.hasNewUi) - SettingsSwitcherCell( - title: S.current.silent_payments_display_card, - value: _silentPaymentsSettingsViewModel.silentPaymentsCardDisplay, - onValueChange: (_, bool value) { - _silentPaymentsSettingsViewModel.setSilentPaymentsCardDisplay(value); - }, - ), SettingsSwitcherCell( title: S.current.silent_payments_always_scan, value: _silentPaymentsSettingsViewModel.silentPaymentsAlwaysScan, diff --git a/lib/src/screens/settings/trocador_providers_page.dart b/lib/src/screens/settings/trocador_providers_page.dart deleted file mode 100644 index e7f89ba51..000000000 --- a/lib/src/screens/settings/trocador_providers_page.dart +++ /dev/null @@ -1,109 +0,0 @@ -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart'; -import 'package:cake_wallet/view_model/settings/trocador_providers_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; - -class TrocadorProvidersPage extends BasePage { - TrocadorProvidersPage(this.trocadorProvidersViewModel); - - @override - String get title => 'Trocador Providers'; - - final TrocadorProvidersViewModel trocadorProvidersViewModel; - - @override - Widget body(BuildContext context) { - return Container( - padding: EdgeInsets.only(top: 10), - child: Observer( - builder: (_) { - if (trocadorProvidersViewModel.isLoading) { - return Center(child: CircularProgressIndicator()); - } - var providerStates = trocadorProvidersViewModel.providerStates; - final providerRatings = trocadorProvidersViewModel.providerRatings; - if (providerStates.isEmpty) { - return Center(child: Text(S.of(context).no_providers_available)); - } - return ListView.builder( - itemCount: providerStates.length, - itemBuilder: (_, index) { - final providerName = providerStates.keys.elementAt(index); - final providerEnabled = providerStates[providerName] ?? true; - return SettingsSwitcherCell( - title: providerName, - value: providerEnabled, - leading: Badge( - title: 'KYC \nRATING', - subTitle: providerRatings[providerName] ?? 'N/A', - textColor: Theme.of(context).colorScheme.onPrimary, - backgroundColor: Theme.of(context).colorScheme.primary, - ), - onValueChange: (BuildContext _, value) => - trocadorProvidersViewModel.toggleProviderState(providerName), - ); - }, - ); - }, - ), - ); - } -} - -class Badge extends StatelessWidget { - Badge( - {required this.textColor, - required this.backgroundColor, - required this.title, - required this.subTitle}); - - final String title; - final String subTitle; - final Color textColor; - final Color backgroundColor; - - @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.only(right: 8), - child: FittedBox( - fit: BoxFit.fitHeight, - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4), - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(24)), color: backgroundColor), - alignment: Alignment.center, - child: IntrinsicHeight( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Text( - title, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: textColor, - fontSize: 7, - fontWeight: FontWeight.w600, - ), - ), - VerticalDivider( - color: textColor, - thickness: 1, - ), - Text( - subTitle, - style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: textColor, - fontWeight: FontWeight.w600, - ), - ), - ], - ), - ), - ), - ), - ); - } -} diff --git a/lib/src/screens/settings/widgets/setting_priority_picker_cell.dart b/lib/src/screens/settings/widgets/setting_priority_picker_cell.dart deleted file mode 100644 index a15c4369e..000000000 --- a/lib/src/screens/settings/widgets/setting_priority_picker_cell.dart +++ /dev/null @@ -1,79 +0,0 @@ -import 'package:cake_wallet/utils/show_pop_up.dart'; -import 'package:flutter/material.dart'; -import 'package:cake_wallet/src/widgets/picker.dart'; -import 'package:cake_wallet/src/widgets/standard_list.dart'; - -class SettingsPriorityPickerCell extends StandardListRow { - SettingsPriorityPickerCell({ - required String title, - required this.selectedItem, - required this.items, - this.displayItem, - this.images, - this.searchHintText, - this.isGridView = false, - this.matchingCriteria, - this.customValue, - this.maxValue, - this.customItemIndex, - this.onItemSelected, - }) : super( - title: title, - isSelected: false, - onTap: (BuildContext context) async { - var selectedAtIndex = items.indexOf(selectedItem); - double sliderValue = customValue ?? 0.0; - - await showPopUp( - context: context, - builder: (BuildContext context) { - return StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return Picker( - items: items, - displayItem: (ItemType item) => displayItem!(item, sliderValue.round()), - selectedAtIndex: selectedAtIndex, - customItemIndex: customItemIndex, - maxValue: maxValue, - headerEnabled: false, - closeOnItemSelected: false, - mainAxisAlignment: MainAxisAlignment.center, - sliderValue: sliderValue, - onSliderChanged: (double newValue) => - setState(() => sliderValue = newValue), - onItemSelected: (ItemType priority) { - setState(() => selectedAtIndex = items.indexOf(priority)); - onItemSelected?.call(priority, sliderValue); - }, - ); - }, - ); - }, - ); - onItemSelected?.call(items[selectedAtIndex], sliderValue); - }); - - final ItemType selectedItem; - final List items; - final void Function(ItemType item, double customValue)? onItemSelected; - final String Function(ItemType item, int value)? displayItem; - final List? images; - final String? searchHintText; - final bool isGridView; - final bool Function(ItemType, String)? matchingCriteria; - double? customValue; - double? maxValue; - int? customItemIndex; - - @override - Widget buildTrailing(BuildContext context) { - return Text( - displayItem?.call(selectedItem, customValue?.round() ?? 0) ?? selectedItem.toString(), - textAlign: TextAlign.right, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ); - } -} diff --git a/lib/src/screens/settings/widgets/settings_picker_row.dart b/lib/src/screens/settings/widgets/settings_picker_row.dart deleted file mode 100644 index 9115c19c8..000000000 --- a/lib/src/screens/settings/widgets/settings_picker_row.dart +++ /dev/null @@ -1,9 +0,0 @@ -import 'package:flutter/cupertino.dart'; - -class SettingsPickerRaw extends StatelessWidget { - @override - Widget build(BuildContext context) { - // TODO: implement build - throw UnimplementedError(); - } -} diff --git a/lib/src/screens/settings/widgets/settings_version_cell.dart b/lib/src/screens/settings/widgets/settings_version_cell.dart deleted file mode 100644 index 27af50607..000000000 --- a/lib/src/screens/settings/widgets/settings_version_cell.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; - -class SettingsVersionCell extends StatelessWidget { - SettingsVersionCell({required this.title}); - - final String title; - - @override - Widget build(BuildContext context) { - return Padding( - padding: EdgeInsets.only(bottom: 24), - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - title, - style: Theme.of(context).textTheme.bodySmall!.copyWith( - fontWeight: FontWeight.normal, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ) - ], - ), - ); - } -} diff --git a/lib/src/screens/settings/widgets/wallet_connect_button.dart b/lib/src/screens/settings/widgets/wallet_connect_button.dart deleted file mode 100644 index 66b2072cf..000000000 --- a/lib/src/screens/settings/widgets/wallet_connect_button.dart +++ /dev/null @@ -1,42 +0,0 @@ -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:flutter/material.dart'; - -class WalletConnectTile extends StatelessWidget { - const WalletConnectTile({required this.onTap}); - - final VoidCallback onTap; - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onTap, - child: Padding( - padding: EdgeInsets.all(24), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Image.asset( - 'assets/images/walletconnect_logo.png', - height: 24, - width: 24, - ), - SizedBox(width: 16), - Expanded( - child: Text( - S.current.walletConnect, - style: Theme.of(context).textTheme.bodyLarge?.copyWith( - color: Theme.of(context).colorScheme.onSurface, - ), - ), - ), - Image.asset( - 'assets/images/select_arrow.png', - color: Theme.of(context).colorScheme.onSurfaceVariant, - ) - ], - ), - ), - ); - } -} diff --git a/lib/src/screens/splash/splash_page.dart b/lib/src/screens/splash/splash_page.dart deleted file mode 100644 index daaaaa915..000000000 --- a/lib/src/screens/splash/splash_page.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:flutter/material.dart'; - -class SplashPage extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold(body: Container()); - } -} diff --git a/lib/src/screens/subaddress/address_edit_or_create_page.dart b/lib/src/screens/subaddress/address_edit_or_create_page.dart deleted file mode 100644 index a622a9724..000000000 --- a/lib/src/screens/subaddress/address_edit_or_create_page.dart +++ /dev/null @@ -1,82 +0,0 @@ -import 'package:mobx/mobx.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart'; -import 'package:cake_wallet/core/address_label_validator.dart'; -import 'package:cake_wallet/src/widgets/primary_button.dart'; -import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; - -class AddressEditOrCreatePage extends BasePage { - AddressEditOrCreatePage({required this.addressEditOrCreateViewModel}) - : _formKey = GlobalKey(), - _labelController = TextEditingController(), - super() { - _labelController.addListener(() => addressEditOrCreateViewModel.label = _labelController.text); - _labelController.text = addressEditOrCreateViewModel.label; - } - - final WalletAddressEditOrCreateViewModel addressEditOrCreateViewModel; - final GlobalKey _formKey; - final TextEditingController _labelController; - - bool _isEffectsInstalled = false; - - @override - String get title => S.current.new_subaddress_title; - - @override - Widget body(BuildContext context) { - _setEffects(context); - - return Form( - key: _formKey, - child: Container( - padding: EdgeInsets.all(24.0), - child: Column( - children: [ - Expanded( - child: Center( - child: BaseTextFormField( - controller: _labelController, - hintText: S.of(context).new_subaddress_label_name, - validator: AddressLabelValidator(), - ), - )), - Observer( - builder: (_) => LoadingPrimaryButton( - onPressed: () async { - if (_formKey.currentState?.validate() ?? false) { - await addressEditOrCreateViewModel.save(); - } - }, - text: addressEditOrCreateViewModel.isEdit - ? S.of(context).rename - : S.of(context).new_subaddress_create, - color: Theme.of(context).colorScheme.primary, - textColor: Theme.of(context).colorScheme.onPrimary, - isLoading: addressEditOrCreateViewModel.state is AddressIsSaving, - isDisabled: addressEditOrCreateViewModel.label.isEmpty, - ), - ) - ], - ), - )); - } - - void _setEffects(BuildContext context) { - if (_isEffectsInstalled) { - return; - } - reaction((_) => addressEditOrCreateViewModel.state, (AddressEditOrCreateState state) { - if (state is AddressSavedSuccessfully) { - WidgetsBinding.instance.addPostFrameCallback((_) { - if (context.mounted) Navigator.of(context).pop(); - }); - } - }); - - _isEffectsInstalled = true; - } -} diff --git a/lib/src/screens/support_other_links/support_other_links_page.dart b/lib/src/screens/support_other_links/support_other_links_page.dart index 7c82d2ed5..4fc348b62 100644 --- a/lib/src/screens/support_other_links/support_other_links_page.dart +++ b/lib/src/screens/support_other_links/support_other_links_page.dart @@ -2,7 +2,6 @@ import 'package:cake_wallet/src/screens/settings/widgets/settings_cell_with_arro import 'package:cake_wallet/src/screens/settings/widgets/settings_link_provider_cell.dart'; import 'package:cake_wallet/src/widgets/standard_list.dart'; import 'package:cake_wallet/view_model/settings/link_list_item.dart'; -import 'package:cake_wallet/view_model/settings/regular_list_item.dart'; import 'package:cake_wallet/view_model/support_view_model.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/src/screens/base_page.dart'; @@ -36,9 +35,6 @@ class SupportOtherLinksPage extends BasePage { itemCounter: (int _) => supportViewModel.items.length, itemBuilder: (_, index) { final item = supportViewModel.items[index]; - if (item is RegularListItem) { - return SettingsCellWithArrow(title: item.title, handler: item.handler); - } if (item is LinkListItem) { bool hasLightIcon = false; if (item.lightIcon != null) hasLightIcon = true; diff --git a/lib/src/screens/unspent_coins/unspent_coins_list_page.dart b/lib/src/screens/unspent_coins/unspent_coins_list_page.dart deleted file mode 100644 index d162a593d..000000000 --- a/lib/src/screens/unspent_coins/unspent_coins_list_page.dart +++ /dev/null @@ -1,217 +0,0 @@ -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/src/screens/unspent_coins/widgets/unspent_coins_list_item.dart'; -import 'package:cake_wallet/src/widgets/alert_with_no_action.dart.dart'; -import 'package:cake_wallet/src/widgets/standard_checkbox.dart'; -import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_list_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:mobx/mobx.dart'; - -class UnspentCoinsListPage extends BasePage { - UnspentCoinsListPage({required this.unspentCoinsListViewModel}); - - @override - String get title => S.current.unspent_coins_title; - - @override - Widget leading(BuildContext context) { - return MergeSemantics( - child: SizedBox( - height: 37, - width: 37, - child: ButtonTheme( - minWidth: double.minPositive, - child: Semantics( - label: S.of(context).seed_alert_back, - child: TextButton( - style: ButtonStyle( - overlayColor: WidgetStateProperty.all(Colors.transparent), - ), - onPressed: () async => await handleOnPopInvoked(context), - child: backButton(context), - ), - ), - ), - ), - ); - } - - final UnspentCoinsListViewModel unspentCoinsListViewModel; - - Future handleOnPopInvoked(BuildContext context) async { - final navigator = Navigator.of(context); - final hasChanged = unspentCoinsListViewModel.hasAdjustableFieldChanged; - if (unspentCoinsListViewModel.items.isEmpty || !hasChanged) { - if (navigator.canPop()) navigator.pop(); - return; - } - - unspentCoinsListViewModel.setIsDisposing(true); - await unspentCoinsListViewModel.dispose(); - - if (navigator.canPop()) navigator.pop(); - if (navigator.canPop()) navigator.pop(); - } - - @override - Widget body(BuildContext context) => - UnspentCoinsListForm(unspentCoinsListViewModel, handleOnPopInvoked); -} - -class UnspentCoinsListForm extends StatefulWidget { - UnspentCoinsListForm(this.unspentCoinsListViewModel, this.handleOnPopInvoked); - - final UnspentCoinsListViewModel unspentCoinsListViewModel; - final Future Function(BuildContext context) handleOnPopInvoked; - - @override - UnspentCoinsListFormState createState() => UnspentCoinsListFormState(unspentCoinsListViewModel); -} - -class UnspentCoinsListFormState extends State { - UnspentCoinsListFormState(this.unspentCoinsListViewModel); - - final UnspentCoinsListViewModel unspentCoinsListViewModel; - - late Future _initialization; - ReactionDisposer? _disposer; - - @override - void initState() { - super.initState(); - _initialization = unspentCoinsListViewModel.initialSetup(); - _setupReactions(); - } - - void _setupReactions() { - _disposer = reaction( - (_) => unspentCoinsListViewModel.isDisposing, - (isDisposing) { - if (isDisposing) { - _showSavingDataAlert(); - } - }, - ); - } - - void _showSavingDataAlert() { - showDialog( - context: context, - useRootNavigator: false, - builder: (BuildContext context) { - return AlertWithNoAction( - alertContent: 'Updating, please wait…', - alertBarrierDismissible: false, - ); - }, - ); - } - - @override - void dispose() { - _disposer?.call(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return PopScope( - canPop: false, - onPopInvokedWithResult: (bool didPop, Object? result) async { - if (didPop) return; - if (mounted) await widget.handleOnPopInvoked(context); - }, - child: FutureBuilder( - future: _initialization, - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.waiting) { - return Center( - child: CircularProgressIndicator( - color: Theme.of(context).colorScheme.primary, - )); - } - - if (snapshot.hasError) return Center(child: Text('Failed to load unspent coins')); - - return Container( - padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12), - child: Observer( - builder: (_) => Column( - children: [ - if (unspentCoinsListViewModel.items.isNotEmpty) - Row( - children: [ - SizedBox(width: 12), - StandardCheckbox( - iconColor: Theme.of(context).colorScheme.onSurfaceVariant, - value: unspentCoinsListViewModel.isAllSelected, - onChanged: (value) => unspentCoinsListViewModel.toggleSelectAll(value), - ), - SizedBox(width: 12), - Text( - S.current.all_coins, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 16, - fontWeight: FontWeight.bold, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - ], - ), - SizedBox(height: 15), - Expanded( - child: unspentCoinsListViewModel.items.isEmpty - ? Center( - child: Text( - 'No unspent coins available', - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - )) - : ListView.separated( - itemCount: unspentCoinsListViewModel.items.length, - separatorBuilder: (_, __) => SizedBox(height: 15), - itemBuilder: (_, int index) { - final item = unspentCoinsListViewModel.items[index]; - return Observer(builder: (_) { - final fiatAmount = - unspentCoinsListViewModel.fiatAmounts[item.amount] ?? ''; - return GestureDetector( - onTap: () => Navigator.of(context).pushNamed( - Routes.unspentCoinsDetails, - arguments: [item, unspentCoinsListViewModel], - ), - child: UnspentCoinsListItem( - note: item.note, - amount: item.amount, - fiatAmount: fiatAmount, - address: item.address, - isSending: item.isSending, - isFrozen: item.isFrozen, - isChange: item.isChange, - isSilentPayment: item.isSilentPayment, - onCheckBoxTap: item.isFrozen - ? null - : () async { - item.isSending = !item.isSending; - await unspentCoinsListViewModel - .saveUnspentCoinInfo(item); - }, - ), - ); - }); - }, - ), - ), - ], - ), - ), - ); - }, - ), - ); - } -} diff --git a/lib/src/screens/unspent_coins/widgets/unspent_coins_list_item.dart b/lib/src/screens/unspent_coins/widgets/unspent_coins_list_item.dart deleted file mode 100644 index 72d3ad432..000000000 --- a/lib/src/screens/unspent_coins/widgets/unspent_coins_list_item.dart +++ /dev/null @@ -1,213 +0,0 @@ -import 'package:auto_size_text/auto_size_text.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/widgets/standard_checkbox.dart'; -import 'package:flutter/material.dart'; - -class UnspentCoinsListItem extends StatelessWidget { - UnspentCoinsListItem({ - required this.note, - required this.amount, - required this.fiatAmount, - required this.address, - required this.isSending, - required this.isFrozen, - required this.isChange, - required this.isSilentPayment, - this.onCheckBoxTap, - }); - - final String note; - final String amount; - final String fiatAmount; - final String address; - final bool isSending; - final bool isFrozen; - final bool isChange; - final bool isSilentPayment; - final Function()? onCheckBoxTap; - - @override - Widget build(BuildContext context) { - final unselectedItemColor = Theme.of(context).colorScheme.surfaceContainer; - final selectedItemColor = Theme.of(context).colorScheme.primary; - final itemColor = isSending ? selectedItemColor : unselectedItemColor; - final amountColor = isSending - ? Theme.of(context).colorScheme.onPrimary - : Theme.of(context).colorScheme.onSurface; - final addressColor = isSending - ? Theme.of(context).colorScheme.onPrimary - : Theme.of(context).colorScheme.onSurface; - - return Container( - height: 70, - padding: EdgeInsets.symmetric(vertical: 6, horizontal: 12), - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(12)), - color: itemColor, - ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Padding( - padding: EdgeInsets.only(right: 12), - child: StandardCheckbox( - iconColor: amountColor, - borderColor: addressColor, - value: isSending, - onChanged: (value) => onCheckBoxTap?.call(), - ), - ), - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (note.isNotEmpty) - AutoSizeText( - note, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: amountColor, - fontSize: 15, - fontWeight: FontWeight.w600, - ), - maxLines: 1, - ), - AutoSizeText( - amount, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: amountColor, - fontSize: 15, - fontWeight: FontWeight.w600, - ), - maxLines: 1, - ) - ], - ), - if (isFrozen) - Container( - height: 17, - padding: EdgeInsets.only(left: 6, right: 6), - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(8.5)), - color: Theme.of(context).colorScheme.primary, - ), - alignment: Alignment.center, - child: Text( - S.of(context).frozen, - style: Theme.of(context).textTheme.bodySmall!.copyWith( - fontWeight: FontWeight.w600, - color: itemColor, - fontSize: 8, - ), - ), - ), - ], - ), - if (fiatAmount.isNotEmpty) - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AutoSizeText( - fiatAmount, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: amountColor, - fontSize: 1, - fontWeight: FontWeight.w600, - ), - maxLines: 1, - ), - ], - ), - Expanded( - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AutoSizeText( - '${address.substring(0, 5)}...${address.substring(address.length - 5)}', // ToDo: Maybe use address label - style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: addressColor, - ), - maxLines: 1, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - if (isChange) - Container( - height: 17, - padding: EdgeInsets.only(left: 6, right: 6), - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(8.5)), - color: Theme.of(context).colorScheme.primaryContainer, - ), - alignment: Alignment.center, - child: Text( - S.of(context).unspent_change, - style: Theme.of(context).textTheme.bodySmall!.copyWith( - fontWeight: FontWeight.w600, - fontSize: 8, - color: Theme.of(context).colorScheme.onPrimaryContainer, - ), - ), - ), - if (address.toLowerCase().contains("mweb")) - Container( - height: 17, - padding: EdgeInsets.only(left: 6, right: 6), - margin: EdgeInsets.only(left: 6), - decoration: BoxDecoration( - borderRadius: BorderRadius.all( - Radius.circular(8.5), - ), - color: Theme.of(context).colorScheme.primaryContainer, - ), - alignment: Alignment.center, - child: Text( - "MWEB", - style: Theme.of(context).textTheme.bodySmall!.copyWith( - fontWeight: FontWeight.w600, - fontSize: 8, - color: Theme.of(context).colorScheme.onPrimaryContainer, - ), - ), - ), - if (isSilentPayment) - Container( - height: 17, - padding: EdgeInsets.only(left: 6, right: 6), - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(8.5)), - color: Theme.of(context).colorScheme.primaryContainer, - ), - alignment: Alignment.center, - child: Text( - S.of(context).silent_payments, - style: Theme.of(context).textTheme.bodySmall!.copyWith( - fontWeight: FontWeight.w600, - fontSize: 8, - color: Theme.of(context).colorScheme.onPrimaryContainer, - ), - ), - ), - ], - ), - ], - ), - ), - ], - ), - ), - ], - ), - ); - } -} diff --git a/lib/src/screens/wallet_list/wallet_list_page.dart b/lib/src/screens/wallet_list/wallet_list_page.dart index f227af07c..f9ad4b180 100644 --- a/lib/src/screens/wallet_list/wallet_list_page.dart +++ b/lib/src/screens/wallet_list/wallet_list_page.dart @@ -339,45 +339,26 @@ class WalletListBodyState extends State { Stack( alignment: Alignment.bottomCenter, children: [ - !FeatureFlag.hasNewUi - ? IgnorePointer( - child: Container( - alignment: Alignment.bottomCenter, - height: 185, - decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - Theme.of(context).colorScheme.surface.withAlpha(10), - Theme.of(context).colorScheme.surface, - Theme.of(context).colorScheme.surface, - Theme.of(context).colorScheme.surface - ], - ), - ), - ), - ) - : IgnorePointer( - child: Container( - height: 275, - decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - Theme.of(context).colorScheme.surfaceDim.withAlpha(10), - Theme.of(context).colorScheme.surfaceDim.withAlpha(150), - Theme.of(context).colorScheme.surfaceDim.withAlpha(255), - Theme.of(context).colorScheme.surfaceDim.withAlpha(255), - Theme.of(context).colorScheme.surfaceDim.withAlpha(255), - Theme.of(context).colorScheme.surfaceDim.withAlpha(255), - Theme.of(context).colorScheme.surfaceDim.withAlpha(255) - ], - ), - ), - ), + IgnorePointer( + child: Container( + height: 275, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Theme.of(context).colorScheme.surfaceDim.withAlpha(10), + Theme.of(context).colorScheme.surfaceDim.withAlpha(150), + Theme.of(context).colorScheme.surfaceDim.withAlpha(255), + Theme.of(context).colorScheme.surfaceDim.withAlpha(255), + Theme.of(context).colorScheme.surfaceDim.withAlpha(255), + Theme.of(context).colorScheme.surfaceDim.withAlpha(255), + Theme.of(context).colorScheme.surfaceDim.withAlpha(255) + ], ), + ), + ), + ), Container( height: 240, width: MediaQuery.of(context).size.width, @@ -464,7 +445,7 @@ class WalletListBodyState extends State { color: Theme.of(context).colorScheme.primary, textColor: Theme.of(context).colorScheme.onPrimary, ), - if (FeatureFlag.hasNewUi) SizedBox(height: 52.0) + SizedBox(height: 52.0) ], ), ), diff --git a/lib/src/screens/yat/widgets/first_introduction.dart b/lib/src/screens/yat/widgets/first_introduction.dart deleted file mode 100644 index be7606376..000000000 --- a/lib/src/screens/yat/widgets/first_introduction.dart +++ /dev/null @@ -1,68 +0,0 @@ -import 'package:cake_wallet/src/screens/yat/widgets/yat_bar.dart'; -import 'package:cake_wallet/src/screens/yat/widgets/yat_page_indicator.dart'; -import 'package:cake_wallet/src/widgets/primary_button.dart'; -import 'package:cake_wallet/src/widgets/scrollable_with_bottom_section.dart'; -import 'package:flutter/material.dart'; -import 'package:lottie/lottie.dart'; -import 'package:cake_wallet/generated/i18n.dart'; - -class FirstIntroduction extends StatelessWidget { - FirstIntroduction({required this.onNext, this.onClose}); - - static const aspectRatioImage = 1.133; - final VoidCallback? onClose; - final VoidCallback onNext; - final animation = Lottie.asset('assets/animation/anim1.json'); - - @override - Widget build(BuildContext context) { - final screenHeight = MediaQuery.of(context).size.height; - final screenWidth = MediaQuery.of(context).size.width; - - return Container( - height: screenHeight, - width: screenWidth, - color: Theme.of(context).colorScheme.surfaceContainer, - child: ScrollableWithBottomSection( - contentPadding: EdgeInsets.only(top: 40, bottom: 40), - content: Column(children: [ - Container( - height: 45, - padding: EdgeInsets.only(left: 24, right: 24), - child: YatBar(onClose: () => Navigator.of(context).pop())), - animation, - Container( - padding: EdgeInsets.only(left: 30, right: 30), - child: Column(children: [ - Text(S.of(context).yat_alert_title, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 24, - fontWeight: FontWeight.bold, - color: Theme.of(context).colorScheme.onSurface, - decoration: TextDecoration.none, - )), - Padding( - padding: EdgeInsets.only(top: 20), - child: Text(S.of(context).yat_alert_content, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 16, - fontWeight: FontWeight.normal, - color: Theme.of(context).colorScheme.onSurface, - decoration: TextDecoration.none, - ))) - ])) - ]), - bottomSectionPadding: EdgeInsets.fromLTRB(24, 0, 24, 24), - bottomSection: Column(crossAxisAlignment: CrossAxisAlignment.center, children: [ - PrimaryButton( - text: S.of(context).restore_next, - textColor: Theme.of(context).colorScheme.onPrimary, - color: Theme.of(context).colorScheme.primary, - onPressed: onNext), - Padding(padding: EdgeInsets.only(top: 24), child: YatPageIndicator(filled: 0)) - ]), - )); - } -} diff --git a/lib/src/screens/yat/widgets/second_introduction.dart b/lib/src/screens/yat/widgets/second_introduction.dart deleted file mode 100644 index 2d1fe3e08..000000000 --- a/lib/src/screens/yat/widgets/second_introduction.dart +++ /dev/null @@ -1,70 +0,0 @@ -import 'package:cake_wallet/src/screens/yat/widgets/yat_bar.dart'; -import 'package:cake_wallet/src/screens/yat/widgets/yat_page_indicator.dart'; -import 'package:cake_wallet/src/widgets/primary_button.dart'; -import 'package:cake_wallet/src/widgets/scrollable_with_bottom_section.dart'; -import 'package:flutter/material.dart'; -import 'package:lottie/lottie.dart'; -import 'package:cake_wallet/generated/i18n.dart'; - -class SecondIntroduction extends StatelessWidget { - SecondIntroduction({required this.onNext, this.onClose}); - - final VoidCallback? onClose; - final VoidCallback onNext; - final animation = Lottie.asset('assets/animation/anim2.json'); - - @override - Widget build(BuildContext context) { - final screenHeight = MediaQuery.of(context).size.height; - final screenWidth = MediaQuery.of(context).size.width; - - return Container( - height: screenHeight, - width: screenWidth, - color: Theme.of(context).colorScheme.surfaceContainer, - child: ScrollableWithBottomSection( - contentPadding: EdgeInsets.only(top: 40, bottom: 40), - content: Column( - children: [ - Container( - height: 45, - padding: EdgeInsets.only(left: 24, right: 24), - child: YatBar(onClose: onClose)), - animation, - Padding( - padding: EdgeInsets.only(top: 40, left: 30, right: 30), - child: Column(children: [ - Text(S.of(context).second_intro_title, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 24, - fontWeight: FontWeight.bold, - color: Theme.of(context).colorScheme.onSurface, - decoration: TextDecoration.none, - )), - Padding( - padding: EdgeInsets.only(top: 20), - child: Text(S.of(context).second_intro_content, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 16, - fontWeight: FontWeight.normal, - color: Theme.of(context).colorScheme.onSurface, - decoration: TextDecoration.none, - ))) - ]), - ), - ], - ), - bottomSectionPadding: EdgeInsets.fromLTRB(24, 0, 24, 24), - bottomSection: Column(crossAxisAlignment: CrossAxisAlignment.center, children: [ - PrimaryButton( - text: S.of(context).restore_next, - textColor: Theme.of(context).colorScheme.onPrimary, - color: Theme.of(context).colorScheme.primary, - onPressed: onNext), - Padding(padding: EdgeInsets.only(top: 24), child: YatPageIndicator(filled: 1)) - ]), - )); - } -} diff --git a/lib/src/screens/yat/widgets/third_introduction.dart b/lib/src/screens/yat/widgets/third_introduction.dart deleted file mode 100644 index 43fb37efa..000000000 --- a/lib/src/screens/yat/widgets/third_introduction.dart +++ /dev/null @@ -1,98 +0,0 @@ -import 'package:cake_wallet/src/screens/yat/widgets/yat_bar.dart'; -import 'package:cake_wallet/src/screens/yat/widgets/yat_page_indicator.dart'; -import 'package:cake_wallet/src/widgets/primary_button.dart'; -import 'package:cake_wallet/src/widgets/scrollable_with_bottom_section.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:lottie/lottie.dart'; -import 'package:cake_wallet/generated/i18n.dart'; - -class ThirdIntroduction extends StatelessWidget { - ThirdIntroduction({required this.onGet, required this.onConnect, this.onClose}); - - final VoidCallback? onClose; - final VoidCallback onGet; - final VoidCallback onConnect; - final animation = Lottie.asset('assets/animation/anim3.json'); - - @override - Widget build(BuildContext context) { - final screenHeight = MediaQuery.of(context).size.height; - final screenWidth = MediaQuery.of(context).size.width; - - return Container( - height: screenHeight, - width: screenWidth, - color: Theme.of(context).colorScheme.surfaceContainer, - child: ScrollableWithBottomSection( - contentPadding: EdgeInsets.only(top: 40, bottom: 40), - content: Column( - children: [ - Container( - height: 90, - padding: EdgeInsets.only(left: 24, right: 24), - child: YatBar(onClose: onClose)), - animation, - Padding( - padding: EdgeInsets.only(top: 40, left: 30, right: 30), - child: Column(children: [ - Text(S.of(context).third_intro_title, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 24, - fontWeight: FontWeight.bold, - color: Theme.of(context).colorScheme.onSurface, - decoration: TextDecoration.none, - )), - Padding( - padding: EdgeInsets.only(top: 20), - child: Text(S.of(context).third_intro_content, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 16, - fontWeight: FontWeight.normal, - color: Theme.of(context).colorScheme.onSurface, - decoration: TextDecoration.none, - ))) - ])), - ], - ), - bottomSectionPadding: EdgeInsets.fromLTRB(24, 0, 24, 24), - bottomSection: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - PrimaryIconButton( - text: S.of(context).get_your_yat, - textColor: Theme.of(context).colorScheme.onPrimary, - color: Theme.of(context).colorScheme.primary, - borderColor: Theme.of(context).colorScheme.primary, - iconColor: Theme.of(context).colorScheme.onPrimary, - iconBackgroundColor: Colors.transparent, - iconData: CupertinoIcons.arrow_up_right_square, - mainAxisAlignment: MainAxisAlignment.end, - onPressed: onGet, - ), - Padding( - padding: EdgeInsets.only(top: 12), - child: PrimaryIconButton( - text: S.of(context).connect_an_existing_yat, - textColor: Theme.of(context).colorScheme.onPrimary, - color: Theme.of(context).colorScheme.primary, - borderColor: Theme.of(context).colorScheme.primary, - iconColor: Theme.of(context).colorScheme.onPrimary, - iconBackgroundColor: Colors.transparent, - iconData: CupertinoIcons.arrow_up_right_square, - mainAxisAlignment: MainAxisAlignment.end, - onPressed: onConnect, - ), - ), - Padding( - padding: EdgeInsets.only(top: 24), - child: YatPageIndicator(filled: 2), - ) - ], - ), - ), - ); - } -} diff --git a/lib/src/screens/yat/widgets/yat_bar.dart b/lib/src/screens/yat/widgets/yat_bar.dart deleted file mode 100644 index a605e360c..000000000 --- a/lib/src/screens/yat/widgets/yat_bar.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:cake_wallet/src/screens/yat/widgets/yat_close_button.dart'; -import 'package:flutter/material.dart'; - -class YatBar extends StatelessWidget { - YatBar({this.onClose}); - - final VoidCallback? onClose; - final image = Image.asset('assets/images/yat_logo.png', width: 81, height: 28); - - @override - Widget build(BuildContext context) { - return Stack(alignment: Alignment.bottomCenter, children: [ - Positioned(top: 0, right: 0, child: YatCloseButton(onClose: onClose)), - Positioned(top: 16, child: image) - ]); - } -} diff --git a/lib/src/screens/yat/widgets/yat_close_button.dart b/lib/src/screens/yat/widgets/yat_close_button.dart deleted file mode 100644 index 4e3ff0aeb..000000000 --- a/lib/src/screens/yat/widgets/yat_close_button.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:flutter/material.dart'; - -class YatCloseButton extends StatelessWidget { - YatCloseButton({this.onClose}); - - final VoidCallback? onClose; - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onClose, - child: Container( - height: 28, - width: 28, - alignment: Alignment.center, - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.surfaceContainerHighest, - shape: BoxShape.circle, - ), - child: Icon( - Icons.clear, - color: Theme.of(context).colorScheme.onSecondaryContainer, - size: 20, - ), - ), - ); - } -} diff --git a/lib/src/screens/yat/widgets/yat_page_indicator.dart b/lib/src/screens/yat/widgets/yat_page_indicator.dart deleted file mode 100644 index a5fd2d08e..000000000 --- a/lib/src/screens/yat/widgets/yat_page_indicator.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:flutter/material.dart'; - -class YatPageIndicator extends StatelessWidget { - YatPageIndicator({required this.filled}); - - final int filled; - - @override - Widget build(BuildContext context) { - return Container( - width: 44, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: List.generate(3, (index) { - final size = 8.0; - final isFilled = index == filled; - - return Container( - height: size, - width: size, - decoration: BoxDecoration( - shape: BoxShape.circle, - color: isFilled - ? Theme.of(context).colorScheme.primary - : Theme.of(context).colorScheme.onSurfaceVariant.withOpacity(0.1))); - }))); - } -} diff --git a/lib/src/screens/yat/yat_popup.dart b/lib/src/screens/yat/yat_popup.dart deleted file mode 100644 index bcf17a4f1..000000000 --- a/lib/src/screens/yat/yat_popup.dart +++ /dev/null @@ -1,154 +0,0 @@ -import 'package:cake_wallet/core/address_resolver/yat/yat_store.dart'; -import 'package:cake_wallet/src/screens/yat/widgets/first_introduction.dart'; -import 'package:cake_wallet/src/screens/yat/widgets/second_introduction.dart'; -import 'package:cake_wallet/src/screens/yat/widgets/third_introduction.dart'; -import 'package:cake_wallet/src/screens/yat/widgets/yat_close_button.dart'; -import 'package:cake_wallet/src/widgets/alert_background.dart'; -import 'package:cake_wallet/src/widgets/primary_button.dart'; -import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:animate_do/animate_do.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:url_launcher/url_launcher.dart'; -import 'package:cake_wallet/generated/i18n.dart'; - -class YatPopup extends StatelessWidget { - YatPopup({required this.dashboardViewModel, required this.onClose}) - : baseUrl = YatLink.isDevMode ? YatLink.baseDevUrl : YatLink.baseReleaseUrl; - - static const durationInMilliseconds = 250; - - final DashboardViewModel dashboardViewModel; - final VoidCallback onClose; - final String baseUrl; - final image = Image.asset('assets/images/emoji_popup.png'); - - @override - Widget build(BuildContext context) { - final screenWidth = MediaQuery.of(context).size.width; - - return Stack( - clipBehavior: Clip.none, - alignment: Alignment.bottomCenter, - children: [ - AlertBackground(child: Container()), - SlideInUp( - from: 420, - duration: Duration(milliseconds: durationInMilliseconds), - child: ClipRRect( - borderRadius: - BorderRadius.only(topLeft: Radius.circular(24), topRight: Radius.circular(24)), - child: Container( - height: 420, - color: Theme.of(context).colorScheme.surfaceContainer, - padding: EdgeInsets.fromLTRB(24, 15, 24, 24), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column(children: [ - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [YatCloseButton(onClose: onClose)]), - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - height: 64, - width: 165, - alignment: Alignment.center, - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.surfaceContainer, - borderRadius: BorderRadius.all(Radius.circular(32)), - boxShadow: [ - BoxShadow( - color: Theme.of(context) - .colorScheme - .onSurface - .withOpacity(0.05), - blurRadius: 15, - offset: Offset(0, 5)) - ]), - child: image) - ]) - ]), - Container( - padding: EdgeInsets.only(left: 6, right: 6), - child: Column(children: [ - Text(S.of(context).yat_popup_title, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyLarge?.copyWith( - fontSize: 24, - fontWeight: FontWeight.bold, - decoration: TextDecoration.none, - )), - Padding( - padding: EdgeInsets.only(top: 20), - child: Text(S.of(context).yat_popup_content, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontSize: 16, - decoration: TextDecoration.none, - ))) - ])), - PrimaryButton( - text: S.of(context).learn_more, - textColor: Theme.of(context).colorScheme.onPrimary, - color: Theme.of(context).colorScheme.primary, - onPressed: () => dashboardViewModel.isShowFirstYatIntroduction = true) - ], - ))), - ), - Observer( - builder: (_) => dashboardViewModel.isShowFirstYatIntroduction - ? SlideInRight( - from: screenWidth, - duration: Duration(milliseconds: durationInMilliseconds), - child: FirstIntroduction( - onClose: onClose, - onNext: () => dashboardViewModel.isShowSecondYatIntroduction = true)) - : Container()), - Observer( - builder: (_) => dashboardViewModel.isShowSecondYatIntroduction - ? SlideInRight( - from: screenWidth, - duration: Duration(milliseconds: durationInMilliseconds), - child: SecondIntroduction( - onClose: onClose, - onNext: () => dashboardViewModel.isShowThirdYatIntroduction = true)) - : Container()), - Observer( - builder: (_) => dashboardViewModel.isShowThirdYatIntroduction - ? SlideInRight( - from: screenWidth, - duration: Duration(milliseconds: durationInMilliseconds), - child: ThirdIntroduction( - onClose: onClose, - onGet: () { - var createNewYatUrl = YatLink.startFlowUrl; - final createNewYatUrlParameters = - dashboardViewModel.yatStore.defineQueryParameters(); - - if (createNewYatUrlParameters.isNotEmpty) { - createNewYatUrl += '?sub1=' + createNewYatUrlParameters; - } - - final uri = Uri.parse(createNewYatUrl); - launchUrl(uri, mode: LaunchMode.externalApplication); - }, - onConnect: () { - String url = baseUrl + YatLink.signInSuffix; - final parameters = dashboardViewModel.yatStore.defineQueryParameters(); - if (parameters.isNotEmpty) { - url += YatLink.queryParameter + parameters; - } - final uri = Uri.parse(url); - launchUrl(uri, mode: LaunchMode.externalApplication); - })) - : Container()) - ], - ); - } -} diff --git a/lib/src/screens/yat_emoji_id.dart b/lib/src/screens/yat_emoji_id.dart deleted file mode 100644 index c433aa57d..000000000 --- a/lib/src/screens/yat_emoji_id.dart +++ /dev/null @@ -1,93 +0,0 @@ -import 'package:cake_wallet/src/screens/yat/widgets/yat_close_button.dart'; -import 'package:cake_wallet/src/widgets/alert_background.dart'; -import 'package:cake_wallet/src/widgets/primary_button.dart'; -import 'package:flutter/material.dart'; -import 'package:animate_do/animate_do.dart'; - -class YatEmojiId extends StatelessWidget { - YatEmojiId(this.emojiId); - static const durationInMilliseconds = 250; - - final String emojiId; - final image = Image.asset('assets/images/emoji_popup.png'); - - @override - Widget build(BuildContext context) { - final screenWidth = MediaQuery.of(context).size.width; - - return Stack( - clipBehavior: Clip.none, - alignment: Alignment.bottomCenter, - children: [ - AlertBackground(child: Container()), - SlideInUp( - from: 420, - duration: Duration(milliseconds: durationInMilliseconds), - child: ClipRRect( - borderRadius: - BorderRadius.only(topLeft: Radius.circular(24), topRight: Radius.circular(24)), - child: Container( - height: 420, - color: Theme.of(context).colorScheme.primaryContainer, - padding: EdgeInsets.fromLTRB(24, 15, 24, 24), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column(children: [ - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [YatCloseButton(onClose: () => Navigator.of(context).pop())]), - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - padding: EdgeInsets.fromLTRB(10, 5, 10, 5), - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.surfaceContainer, - border: Border.all( - color: Theme.of(context).colorScheme.outlineVariant), - borderRadius: BorderRadius.all(Radius.circular(50))), - child: Text(emojiId, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyLarge?.copyWith( - fontSize: 46, - decoration: TextDecoration.none, - ))) - ]) - ]), - Container( - padding: EdgeInsets.only(left: 6, right: 6), - child: Column(children: [ - Text("That's one nice Yat!", - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyLarge?.copyWith( - fontSize: 32, - fontWeight: FontWeight.bold, - decoration: TextDecoration.none, - )), - Padding( - padding: EdgeInsets.only(top: 20), - child: Text( - 'You can manage your Yat or purchase additional Yats in your account settings', - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontSize: 18, - color: Theme.of(context).colorScheme.onSurfaceVariant, - decoration: TextDecoration.none, - ))) - ])), - PrimaryButton( - text: 'Got it', - textColor: Theme.of(context).colorScheme.onPrimary, - color: Theme.of(context).colorScheme.primary, - onPressed: () => Navigator.of(context).pop()) - ], - ))), - ) - ], - ); - } -} diff --git a/lib/src/widgets/adaptable_page_view.dart b/lib/src/widgets/adaptable_page_view.dart deleted file mode 100644 index 8ef9a2068..000000000 --- a/lib/src/widgets/adaptable_page_view.dart +++ /dev/null @@ -1,216 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart'; - -const _firstLayoutMaxHeight = 10000.0; - -class PageViewHeightAdaptable extends StatefulWidget { - const PageViewHeightAdaptable({ - super.key, - required this.controller, - required this.children, - }) : assert(children.length > 0, 'children must not be empty'); - - final PageController controller; - final List children; - - @override - State createState() => _PageViewHeightAdaptableState(); -} - -class _PageViewHeightAdaptableState extends State { - final _sizes = {}; - - @override - void didUpdateWidget(PageViewHeightAdaptable oldWidget) { - super.didUpdateWidget(oldWidget); - - _sizes.clear(); - } - - @override - Widget build(BuildContext context) { - return ListenableBuilder( - listenable: widget.controller, - builder: (context, child) => _SizingContainer( - sizes: _sizes, - page: widget.controller.hasClients ? widget.controller.page ?? 0 : 0, - child: child!, - ), - child: LayoutBuilder( - builder: (context, constraints) => PageView( - controller: widget.controller, - children: [ - for (final (i, child) in widget.children.indexed) - Stack( - alignment: Alignment.topCenter, - clipBehavior: Clip.hardEdge, - children: [ - SizedBox.fromSize(size: _sizes[i]), - Positioned( - left: 0, - top: 0, - right: 0, - child: _SizeAware( - child: child, - // don't setState, we'll use it in the layout phase - onSizeLaidOut: (size) { - _sizes[i] = size; - }, - ), - ), - ], - ), - ], - ), - ), - ); - } -} - -typedef _OnSizeLaidOutCallback = void Function(Size); - -class _SizingContainer extends SingleChildRenderObjectWidget { - const _SizingContainer({ - super.child, - required this.sizes, - required this.page, - }); - - final Map sizes; - final double page; - - @override - _RenderSizingContainer createRenderObject(BuildContext context) { - return _RenderSizingContainer( - sizes: sizes, - page: page, - ); - } - - @override - void updateRenderObject( - BuildContext context, - _RenderSizingContainer renderObject, - ) { - renderObject - ..sizes = sizes - ..page = page; - } -} - -class _RenderSizingContainer extends RenderProxyBox { - _RenderSizingContainer({ - RenderBox? child, - required Map sizes, - required double page, - }) : _sizes = sizes, - _page = page, - super(child); - - Map _sizes; - Map get sizes => _sizes; - set sizes(Map value) { - if (_sizes == value) return; - _sizes = value; - markNeedsLayout(); - } - - double _page; - double get page => _page; - set page(double value) { - if (_page == value) return; - _page = value; - markNeedsLayout(); - } - - @override - void performLayout() { - if (child case final child?) { - child.layout( - constraints.copyWith( - minWidth: constraints.maxWidth, - minHeight: 0, - maxHeight: constraints.hasBoundedHeight ? null : _firstLayoutMaxHeight, - ), - parentUsesSize: true, - ); - - final int floorPage = page.floor(); - final int ceilPage = page.ceil(); - - Size? a = sizes[floorPage]; - Size? b = sizes[ceilPage]; - - if (a == null && sizes.isNotEmpty) { - a = sizes.values.first; - } - if (b == null && sizes.isNotEmpty) { - b = sizes.values.first; - } - - a ??= child.getDryLayout(constraints); - b ??= a; - - final double t = (page - floorPage).clamp(0.0, 1.0); - final double height = lerpDouble(a.height, b.height, t) ?? a.height; - - child.layout( - constraints.copyWith(minHeight: height, maxHeight: height), - parentUsesSize: true, - ); - size = child.size; - } else { - size = computeSizeForNoChild(constraints); - } - } -} - -class _SizeAware extends SingleChildRenderObjectWidget { - const _SizeAware({ - required Widget child, - required this.onSizeLaidOut, - }) : super(child: child); - - final _OnSizeLaidOutCallback onSizeLaidOut; - - @override - _RenderSizeAware createRenderObject(BuildContext context) { - return _RenderSizeAware( - onSizeLaidOut: onSizeLaidOut, - ); - } - - @override - void updateRenderObject(BuildContext context, _RenderSizeAware renderObject) { - renderObject.onSizeLaidOut = onSizeLaidOut; - } -} - -class _RenderSizeAware extends RenderProxyBox { - _RenderSizeAware({ - RenderBox? child, - required _OnSizeLaidOutCallback onSizeLaidOut, - }) : _onSizeLaidOut = onSizeLaidOut, - super(child); - - _OnSizeLaidOutCallback? _onSizeLaidOut; - _OnSizeLaidOutCallback get onSizeLaidOut => _onSizeLaidOut!; - set onSizeLaidOut(_OnSizeLaidOutCallback value) { - if (_onSizeLaidOut == value) return; - _onSizeLaidOut = value; - markNeedsLayout(); - } - - @override - void performLayout() { - super.performLayout(); - - onSizeLaidOut( - getDryLayout( - constraints.copyWith(maxHeight: double.infinity), - ), - ); - } -} diff --git a/lib/src/widgets/add_template_button.dart b/lib/src/widgets/add_template_button.dart deleted file mode 100644 index f9935ebc3..000000000 --- a/lib/src/widgets/add_template_button.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/utils/responsive_layout_util.dart'; -import 'package:dotted_border/dotted_border.dart'; -import 'package:flutter/material.dart'; - -class AddTemplateButton extends StatelessWidget { - final Function() onTap; - final int currentTemplatesLength; - - const AddTemplateButton({Key? key, required this.onTap, required this.currentTemplatesLength}) - : super(key: key); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onTap, - child: Container( - padding: EdgeInsets.only(left: 1, right: 10), - child: DottedBorder( - borderType: BorderType.RRect, - dashPattern: [6, 4], - color: Theme.of(context).colorScheme.outline, - strokeWidth: 2, - radius: Radius.circular(12), - child: Container( - height: 34, - padding: EdgeInsets.symmetric( - horizontal: responsiveLayoutUtil.shouldRenderMobileUI ? 10 : 30, - ), - alignment: Alignment.center, - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(12)), - color: Colors.transparent, - ), - child: currentTemplatesLength >= 1 - ? Icon( - Icons.add, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ) - : Text( - S.of(context).new_template, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - ), - ), - ), - ); - } -} diff --git a/lib/src/widgets/alert_with_no_action.dart.dart b/lib/src/widgets/alert_with_no_action.dart.dart deleted file mode 100644 index 75c1785cd..000000000 --- a/lib/src/widgets/alert_with_no_action.dart.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:cake_wallet/src/widgets/base_alert_dialog.dart'; - -class AlertWithNoAction extends BaseAlertDialog { - AlertWithNoAction({ - this.alertTitle, - required this.alertContent, - this.alertBarrierDismissible = true, - Key? key, - }); - - final String? alertTitle; - final String alertContent; - final bool alertBarrierDismissible; - - @override - String? get titleText => alertTitle; - - @override - String get contentText => alertContent; - - @override - bool get barrierDismissible => alertBarrierDismissible; - - @override - bool get isBottomDividerExists => false; - - @override - Widget actionButtons(BuildContext context) => Container(); -} diff --git a/lib/src/widgets/alert_with_picker_option.dart b/lib/src/widgets/alert_with_picker_option.dart deleted file mode 100644 index 79a7b204b..000000000 --- a/lib/src/widgets/alert_with_picker_option.dart +++ /dev/null @@ -1,113 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:cake_wallet/src/widgets/base_alert_dialog.dart'; - -class AlertWithPickerOption extends BaseAlertDialog { - AlertWithPickerOption( - {required this.alertTitle, - required this.alertTitleTextSize, - required this.alertSubtitle, - required this.options, - this.onOptionSelected, - this.alertBarrierDismissible = true, - Key? key}); - - final String alertTitle; - final double alertTitleTextSize; - final String alertSubtitle; - final List> options; - final ValueChanged>? onOptionSelected; - final bool alertBarrierDismissible; - - @override - String get titleText => alertTitle; - - @override - double? get titleTextSize => alertTitleTextSize; - - @override - String get contentText => alertSubtitle; - - @override - bool get barrierDismissible => alertBarrierDismissible; - - @override - Widget actionButtons(BuildContext context) => Container(); - - @override - bool get isBottomDividerExists => false; - - @override - Widget content(BuildContext context) { - return Column( - mainAxisSize: MainAxisSize.min, - children: [ - const SizedBox(height: 16), - Text( - contentText, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 10, - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.onSurface, - decoration: TextDecoration.none, - ), - ), - const SizedBox(height: 4), - Container( - constraints: const BoxConstraints(maxHeight: 200), - child: ListView.separated( - shrinkWrap: true, - padding: EdgeInsets.zero, - separatorBuilder: (context, index) => const SizedBox(height: 8), - itemCount: options.length, - itemBuilder: (context, index) { - final item = options[index]; - final displayKey = item['displayKey'] ?? ''; - final displayValue = item['displayValue'] ?? ''; - return GestureDetector( - onTap: () { - onOptionSelected?.call(item); - Navigator.of(context).pop(); - }, - child: Container( - width: double.infinity, - padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(30), - color: Theme.of(context).colorScheme.surface), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - displayKey, - style: Theme.of(context).textTheme.bodySmall!.copyWith( - decoration: TextDecoration.none, - ), - ), - Row( - children: [ - Text( - displayValue, - style: Theme.of(context).textTheme.bodySmall!.copyWith( - decoration: TextDecoration.none, - ), - ), - const SizedBox(width: 4), - Icon( - Icons.arrow_forward_ios, - size: 18, - color: Theme.of(context).colorScheme.onSurface, - ), - ], - ), - ], - ), - ), - ); - }, - ), - ), - ], - ); - } -} diff --git a/lib/src/widgets/bottom_sheet/cake_pay_card_info_bottom_sheet_widget.dart b/lib/src/widgets/bottom_sheet/cake_pay_card_info_bottom_sheet_widget.dart index 21d6863b0..8183981cd 100644 --- a/lib/src/widgets/bottom_sheet/cake_pay_card_info_bottom_sheet_widget.dart +++ b/lib/src/widgets/bottom_sheet/cake_pay_card_info_bottom_sheet_widget.dart @@ -299,14 +299,12 @@ Widget _buildBarcodeSide(BuildContext context, {required String cardNumber, requ children: [ Text('Gift Card Number', style: TextStyle( - fontFamily: 'Lato', fontSize: 10, fontWeight: FontWeight.w500, color: Color.fromRGBO(207, 207, 207, 1))), const SizedBox(height: 4), Text(cardNumber, style: TextStyle( - fontFamily: 'Lato', fontSize: 12, fontWeight: FontWeight.w900, color: Color.fromRGBO(146, 146, 146, 1))), @@ -317,14 +315,12 @@ Widget _buildBarcodeSide(BuildContext context, {required String cardNumber, requ children: [ Text('PIN Number', style: TextStyle( - fontFamily: 'Lato', fontSize: 10, fontWeight: FontWeight.w500, color: Color.fromRGBO(207, 207, 207, 1))), const SizedBox(height: 4), Text(pin, style: TextStyle( - fontFamily: 'Lato', fontSize: 12, fontWeight: FontWeight.w900, color: Color.fromRGBO(146, 146, 146, 1))), diff --git a/lib/src/widgets/bottom_sheet/payment_confirmation_bottom_sheet.dart b/lib/src/widgets/bottom_sheet/payment_confirmation_bottom_sheet.dart deleted file mode 100644 index 3c1dfde4f..000000000 --- a/lib/src/widgets/bottom_sheet/payment_confirmation_bottom_sheet.dart +++ /dev/null @@ -1,305 +0,0 @@ -import 'package:cake_wallet/evm/evm.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/utils/payment_request.dart'; -import 'package:cw_core/currency_for_wallet_type.dart'; -import 'package:cw_core/generate_name.dart'; -import 'package:flutter/material.dart'; -import 'package:cake_wallet/src/widgets/bottom_sheet/base_bottom_sheet_widget.dart'; -import 'package:cake_wallet/src/widgets/primary_button.dart'; -import 'package:cw_core/wallet_type.dart'; -import 'package:cake_wallet/view_model/payment/payment_view_model.dart'; -import 'package:cake_wallet/view_model/wallet_switcher_view_model.dart'; -import 'package:cake_wallet/reactions/wallet_connect.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; - -class PaymentConfirmationBottomSheet extends BaseBottomSheet { - PaymentConfirmationBottomSheet({ - Key? key, - required this.paymentFlowResult, - required this.paymentViewModel, - required this.walletSwitcherViewModel, - required this.paymentRequest, - required this.onSelectWallet, - required this.onChangeWallet, - required this.onSwap, - this.onSwitchNetwork, - }) : super( - titleText: '', - footerType: FooterType.none, - maxHeight: 900, - ); - - final PaymentFlowResult paymentFlowResult; - final PaymentViewModel paymentViewModel; - final WalletSwitcherViewModel walletSwitcherViewModel; - final PaymentRequest paymentRequest; - final VoidCallback onSelectWallet; - final VoidCallback onChangeWallet; - final void Function(BuildContext) onSwap; - final VoidCallback? onSwitchNetwork; - - @override - Widget contentWidget(BuildContext context) { - return _PaymentConfirmationContent( - paymentFlowResult: paymentFlowResult, - paymentViewModel: paymentViewModel, - walletSwitcherViewModel: walletSwitcherViewModel, - paymentRequest: paymentRequest, - onSelectWallet: onSelectWallet, - onChangeWallet: onChangeWallet, - onSwap: onSwap, - onSwitchNetwork: onSwitchNetwork, - ); - } -} - -class _PaymentConfirmationContent extends StatelessWidget { - const _PaymentConfirmationContent({ - required this.paymentFlowResult, - required this.paymentViewModel, - required this.walletSwitcherViewModel, - required this.paymentRequest, - required this.onSelectWallet, - required this.onChangeWallet, - required this.onSwap, - this.onSwitchNetwork, - }); - - final PaymentFlowResult paymentFlowResult; - final PaymentViewModel paymentViewModel; - final WalletSwitcherViewModel walletSwitcherViewModel; - final PaymentRequest paymentRequest; - final VoidCallback onSelectWallet; - final VoidCallback onChangeWallet; - final void Function(BuildContext) onSwap; - final VoidCallback? onSwitchNetwork; - - /// Checks if the given address is a MWEB or SP (Silent Payment) address - bool _isMwebOrSpAddress(String address) { - if (address.isEmpty) return false; - - final lowerAddress = address.toLowerCase(); - - // Check for MWEB addresses (Litecoin MWEB addresses start with "ltcmweb1") - if (lowerAddress.startsWith('ltcmweb1')) return true; - - // Check for Silent Payment addresses (Bitcoin SP addresses start with "sp1", "tsp1") - if (lowerAddress.startsWith('sp1') || lowerAddress.startsWith('tsp1')) return true; - - return false; - } - - /// Checks if flow type is token selection (EVM, Solana, or Tron) - bool _isTokenSelectionFlow(PaymentFlowType type) { - return type == PaymentFlowType.evmNetworkSelection || - type == PaymentFlowType.solanaTokenSelection || - type == PaymentFlowType.tronTokenSelection; - } - - @override - Widget build(BuildContext context) { - return Observer( - builder: (_) { - final currencyName = walletTypeToString(paymentViewModel.detectedWalletType!); - final currentWalletName = isEVMCompatibleChain(paymentViewModel.currentWalletType) - ? evm!.getChainNameByChainId(paymentViewModel.currentChainId!) - : walletTypeToString(paymentViewModel.currentWalletType); - - final hasSingleWallet = paymentFlowResult.type == PaymentFlowType.singleWallet || - paymentFlowResult.wallets.length == 1; - - final hasMultipleWallets = paymentFlowResult.type == PaymentFlowType.multipleWallets || - paymentFlowResult.wallets.length > 1; - - final noAvailableWallets = paymentFlowResult.type == PaymentFlowType.noWallets || - paymentFlowResult.wallets.isEmpty; - - final hasAtLeastOneWallet = hasSingleWallet || hasMultipleWallets; - - final isMwebOrSpAddress = - _isMwebOrSpAddress(paymentFlowResult.addressDetectionResult?.address ?? ''); - - /// If the wallet is EVM but the detected chainId is different from the currently selected chainId - final isEVMWalletButDifferentChainId = - paymentFlowResult.type == PaymentFlowType.evmNetworkSelection && - paymentFlowResult.wallet != null && - isEVMCompatibleChain(paymentViewModel.currentWalletType); - - final otherWalletsCount = paymentFlowResult.wallets.length; - final hasMultipleOtherWallets = otherWalletsCount > 1; - - return Container( - padding: const EdgeInsets.fromLTRB(24, 0, 24, 24), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - if (_isTokenSelectionFlow(paymentFlowResult.type)) ...[ - Stack( - clipBehavior: Clip.none, - children: [ - Image.asset( - paymentFlowResult.addressDetectionResult?.detectedCurrency?.iconPath ?? '', - width: 70, - height: 70, - errorBuilder: (context, error, stackTrace) => Icon( - Icons.currency_bitcoin, - size: 70, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - Positioned( - bottom: 0, - right: 0, - child: Image.asset( - getCryptoCurrencyIconForWalletListItem( - paymentViewModel.detectedWalletType!, - chainId: paymentViewModel.detectedChainId, - ), - width: 32, - height: 32, - errorBuilder: (context, error, stackTrace) => Icon( - Icons.account_balance_wallet, - size: 32, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - ), - ], - ), - const SizedBox(height: 20), - Text( - '${paymentFlowResult.addressDetectionResult?.detectedCurrency} (${walletTypeToString(paymentFlowResult.walletType!)})', - style: Theme.of(context).textTheme.titleMedium!.copyWith( - fontSize: 20, - fontWeight: FontWeight.w900, - color: Theme.of(context).colorScheme.onSurface, - letterSpacing: 0.0, - ), - textAlign: TextAlign.center, - ), - const SizedBox(height: 24), - Text( - '''Would you like to ${!noAvailableWallets ? 'switch to a $currencyName wallet or' : ''} swap ${currentWalletName.capitalized()} for ${paymentFlowResult.addressDetectionResult?.detectedCurrency} (${walletTypeToString(paymentFlowResult.walletType!)}) for this payment?''', - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 16, - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurfaceVariant, - letterSpacing: 0.0, - ), - ), - ] else ...[ - Image.asset( - getCryptoCurrencyIconForWalletListItem( - paymentViewModel.detectedWalletType!, - chainId: paymentViewModel.detectedChainId, - ), - width: 118, - height: 118, - ), - const SizedBox(height: 20), - Text( - '$currencyName ${S.current.address_detected.toLowerCase()}', - style: Theme.of(context).textTheme.titleMedium!.copyWith( - fontSize: 20, - fontWeight: FontWeight.w900, - color: Theme.of(context).colorScheme.onSurface, - letterSpacing: 0.0, - ), - textAlign: TextAlign.center, - ), - const SizedBox(height: 24), - Text( - '''Looks like you scanned a $currencyName address.\n\n''' - '''Would you like to ${!noAvailableWallets ? 'switch to a $currencyName wallet or' : ''} swap ${currentWalletName.capitalized()} for $currencyName for this payment?''', - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 16, - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurfaceVariant, - letterSpacing: 0.0, - ), - ), - ], - const SizedBox(height: 72), - if (isEVMWalletButDifferentChainId) ...[ - if (!isMwebOrSpAddress) ...[ - PrimaryButton( - onPressed: () => onSwap(context), - text: 'Create In App Swap', - color: hasAtLeastOneWallet - ? Theme.of(context).colorScheme.surfaceContainer - : Theme.of(context).colorScheme.primary, - textColor: hasAtLeastOneWallet - ? Theme.of(context).colorScheme.onSecondaryContainer - : Theme.of(context).colorScheme.onPrimary, - ), - const SizedBox(height: 10), - ], - if (onSwitchNetwork != null) ...[ - PrimaryButton( - onPressed: onSwitchNetwork, - text: - 'Switch to ${evm!.getChainNameByChainId(paymentViewModel.detectedChainId!).toUpperCase()} Network', - color: Theme.of(context).colorScheme.surfaceContainer, - textColor: Theme.of(context).colorScheme.onSecondaryContainer, - ), - const SizedBox(height: 10), - ], - if (hasAtLeastOneWallet) ...[ - PrimaryButton( - onPressed: hasMultipleOtherWallets ? onSelectWallet : onChangeWallet, - text: S.current.change_wallet_alert_title, - color: Theme.of(context).colorScheme.primary, - textColor: Theme.of(context).colorScheme.onPrimary, - ), - const SizedBox(height: 10), - ], - ] else if (hasAtLeastOneWallet) ...[ - if (!isMwebOrSpAddress) ...[ - PrimaryButton( - onPressed: () => onSwap(context), - text: '${S.current.swap} ${currentWalletName.capitalized()}', - color: Theme.of(context).colorScheme.surfaceContainer, - textColor: Theme.of(context).colorScheme.onSecondaryContainer, - ), - const SizedBox(height: 10), - ], - PrimaryButton( - onPressed: hasMultipleWallets ? onSelectWallet : onChangeWallet, - text: S.current.switch_wallet, - color: Theme.of(context).colorScheme.primary, - textColor: Theme.of(context).colorScheme.onPrimary, - ), - const SizedBox(height: 10), - ] else ...[ - PrimaryButton( - onPressed: () => Navigator.of(context).pop(), - text: S.current.cancel, - color: Theme.of(context).colorScheme.surfaceContainer, - textColor: Theme.of(context).colorScheme.onSecondaryContainer, - ), - const SizedBox(height: 10), - if (!isMwebOrSpAddress) ...[ - PrimaryButton( - onPressed: () => onSwap(context), - text: '${S.current.swap} ${currentWalletName.capitalized()}', - color: hasAtLeastOneWallet - ? Theme.of(context).colorScheme.surfaceContainer - : Theme.of(context).colorScheme.primary, - textColor: hasAtLeastOneWallet - ? Theme.of(context).colorScheme.onSecondaryContainer - : Theme.of(context).colorScheme.onPrimary, - ), - const SizedBox(height: 10), - ], - const SizedBox(height: 32), - ], - ], - ), - ); - }, - ); - } -} diff --git a/lib/src/widgets/bottom_sheet/token_selection_bottom_sheet.dart b/lib/src/widgets/bottom_sheet/token_selection_bottom_sheet.dart deleted file mode 100644 index 55aafd516..000000000 --- a/lib/src/widgets/bottom_sheet/token_selection_bottom_sheet.dart +++ /dev/null @@ -1,497 +0,0 @@ -import 'package:cake_wallet/core/universal_address_detector.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/reactions/wallet_connect.dart'; -import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart'; -import 'package:cake_wallet/src/widgets/bottom_sheet/base_bottom_sheet_widget.dart'; -import 'package:cake_wallet/src/widgets/cake_image_widget.dart'; -import 'package:cake_wallet/src/widgets/picker.dart'; -import 'package:cake_wallet/src/widgets/primary_button.dart'; -import 'package:cake_wallet/utils/payment_request.dart'; -import 'package:cake_wallet/utils/qr_util.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; -import 'package:cake_wallet/utils/token_utilities.dart'; -import 'package:cake_wallet/view_model/payment/payment_view_model.dart'; -import 'package:cake_wallet/wallet_types.g.dart'; -import 'package:cw_core/crypto_currency.dart'; -import 'package:cw_core/currency.dart'; -import 'package:cw_core/currency_for_wallet_type.dart'; -import 'package:cw_core/erc20_token.dart'; -import 'package:cw_core/spl_token.dart'; -import 'package:cw_core/tron_token.dart'; -import 'package:cw_core/utils/print_verbose.dart'; -import 'package:cw_core/wallet_type.dart'; -import 'package:flutter/material.dart'; - -class TokenSelectionBottomSheet extends BaseBottomSheet { - TokenSelectionBottomSheet({ - Key? key, - required this.paymentViewModel, - required this.paymentRequest, - required this.onNext, - this.fixedNetwork, - }) : super( - titleText: '', - footerType: FooterType.none, - maxHeight: 900, - ); - - final PaymentViewModel paymentViewModel; - final PaymentRequest paymentRequest; - final Function(PaymentFlowResult) onNext; - final WalletType? fixedNetwork; - - @override - Widget contentWidget(BuildContext context) { - return _TokenSelectionContent( - paymentViewModel: paymentViewModel, - paymentRequest: paymentRequest, - onNext: onNext, - fixedNetwork: fixedNetwork, - ); - } -} - -class _TokenSelectionContent extends StatefulWidget { - const _TokenSelectionContent({ - required this.paymentViewModel, - required this.paymentRequest, - required this.onNext, - this.fixedNetwork, - }); - - final PaymentViewModel paymentViewModel; - final PaymentRequest paymentRequest; - final Function(PaymentFlowResult) onNext; - final WalletType? fixedNetwork; - - @override - State<_TokenSelectionContent> createState() => _TokenSelectionContentState(); -} - -class _TokenSelectionContentState extends State<_TokenSelectionContent> { - WalletType? selectedNetwork; - CryptoCurrency? selectedToken; - bool isLoadingTokens = false; - String? tokenLoadError; - - @override - void initState() { - super.initState(); - final baseNetwork = widget.fixedNetwork ?? WalletType.ethereum; - selectedNetwork = _resolveGenericETHDetectionResultToSpecificChain( - baseNetwork, widget.paymentRequest.scheme.isNotEmpty); - _autoSelectToken(); - } - - bool get _isNetworkSelectable => - widget.fixedNetwork == null || isEVMCompatibleChain(widget.fixedNetwork!); - - CryptoCurrency? _tokenMatchingContract(List tokens, String? rawContract) { - final trimmed = rawContract?.trim(); - if (trimmed == null || trimmed.isEmpty) return null; - - for (final token in tokens) { - if (token is Erc20Token && token.contractAddress.toLowerCase() == trimmed.toLowerCase()) { - return token; - } else if (token is SPLToken && token.mintAddress == trimmed) { - return token; - } else if (token is TronToken && token.contractAddress == trimmed) { - return token; - } - } - return null; - } - - WalletType _resolveGenericETHDetectionResultToSpecificChain( - WalletType network, bool hasURIScheme) { - if (hasURIScheme || network != WalletType.ethereum) return network; - - final current = widget.paymentViewModel.currentWalletType; - if (isEVMCompatibleChain(current)) return current; - return network; - } - - Future _autoSelectToken() async { - final initialNetwork = selectedNetwork; - if (initialNetwork == null || !mounted) return; - - final network = _resolveGenericETHDetectionResultToSpecificChain( - initialNetwork, widget.paymentRequest.scheme.isNotEmpty); - - setState(() { - selectedNetwork = network; - isLoadingTokens = true; - tokenLoadError = null; - }); - - try { - final tokens = await TokenUtilities.getAvailableTokensForNetwork(network); - if (!mounted) return; - - if (tokens.isEmpty) { - setState(() { - tokenLoadError = 'No tokens available'; - isLoadingTokens = false; - selectedToken = null; - }); - return; - } - - final matchedToken = - _tokenMatchingContract(tokens, widget.paymentRequest.contractAddress) ?? tokens.first; - - setState(() { - selectedToken = matchedToken; - isLoadingTokens = false; - tokenLoadError = null; - }); - } catch (e) { - printV('Auto-select token error: $e'); - if (!mounted) return; - setState(() { - tokenLoadError = 'Failed to load tokens'; - isLoadingTokens = false; - selectedToken = walletTypeToCryptoCurrency(network); - }); - } - } - - String _getNetworkTitle() { - if (selectedNetwork == null) return S.current.select_network; - return walletTypeToString(selectedNetwork!); - } - - String _getEcosystemTitle() { - if (selectedNetwork == WalletType.solana) { - return 'Solana\n${S.current.address_detected.toLowerCase()}'; - } - if (selectedNetwork == WalletType.tron) { - return 'Tron\n${S.current.address_detected.toLowerCase()}'; - } - return '${S.current.ethereum_ecosystem}\n${S.current.address_detected.toLowerCase()}'; - } - - String _getEcosystemDescription() { - if (selectedNetwork == WalletType.solana) { - return 'Select a token to send on Solana network'; - } - if (selectedNetwork == WalletType.tron) { - return 'Select a token to send on Tron network'; - } - return S.current.evm_ecosystem_description; - } - - String _getNetworkIcon() { - if (selectedNetwork == null) return 'assets/images/eth_chain_mono.svg'; - return getChainMonoImage(selectedNetwork!); - } - - @override - Widget build(BuildContext context) { - return Container( - padding: const EdgeInsets.fromLTRB(24, 0, 24, 24), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CakeImageWidget( - imageUrl: _getNetworkIcon(), - width: 50, - height: 50, - color: Theme.of(context).colorScheme.onSurface, - ), - const SizedBox(height: 24), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 24), - child: Text( - _getEcosystemTitle(), - style: Theme.of(context).textTheme.titleMedium!.copyWith( - fontSize: 20, - fontWeight: FontWeight.w900, - color: Theme.of(context).colorScheme.onSurface, - ), - textAlign: TextAlign.center, - ), - ), - const SizedBox(height: 36), - Text( - _getEcosystemDescription(), - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 16, - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurfaceVariant, - letterSpacing: 0.0, - ), - ), - const SizedBox(height: 32), - TokenSelectionTileWidget( - value: _getNetworkTitle(), - imagePath: selectedNetwork != null ? getChainMonoImage(selectedNetwork!) : null, - color: selectedNetwork != null ? Theme.of(context).colorScheme.primary : null, - enabled: _isNetworkSelectable, - onTap: _isNetworkSelectable ? () => _showNetworkSelection(context) : null, - ), - const SizedBox(height: 16), - TokenSelectionTileWidget( - imagePath: selectedToken?.iconPath, - value: selectedToken != null ? selectedToken!.title : S.current.select_token, - enabled: selectedNetwork != null && !isLoadingTokens, - onTap: isLoadingTokens ? null : () => _showTokenSelection(context), - color: selectedToken == null ? Theme.of(context).colorScheme.primary : null, - ), - if (isLoadingTokens) ...[ - const SizedBox(height: 16), - const CircularProgressIndicator(), - ], - if (tokenLoadError != null) ...[ - const SizedBox(height: 16), - Text( - tokenLoadError!, - style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: Theme.of(context).colorScheme.error, - ), - ), - ], - const SizedBox(height: 32), - PrimaryButton( - text: S.current.restore_next, - color: Theme.of(context).colorScheme.primary, - textColor: Theme.of(context).colorScheme.onPrimary, - onPressed: selectedNetwork != null && selectedToken != null && !isLoadingTokens - ? () async => await _handleNext(context) - : null, - ), - const SizedBox(height: 48), - ], - ), - ); - } - - void _showNetworkSelection(BuildContext context) async { - if (!_isNetworkSelectable) return; - - final evmNetworks = - availableWalletTypes.where((walletType) => isEVMCompatibleChain(walletType)).toList(); - final selectedIndex = evmNetworks.indexOf(selectedNetwork ?? WalletType.ethereum); - - await showPopUp( - context: context, - builder: (BuildContext context) { - return Picker( - items: evmNetworks, - displayItem: (WalletType network) => walletTypeToString(network), - selectedAtIndex: selectedIndex, - title: S.current.select_network, - closeOnItemSelected: true, - hasTitleSpacing: true, - images: evmNetworks - .map((network) => CakeImageWidget( - imageUrl: getChainMonoImage(network), - width: 20, - height: 20, - color: Theme.of(context).colorScheme.primary)) - .toList(), - onItemSelected: (WalletType network) { - setState(() { - selectedNetwork = network; - selectedToken = null; - }); - _autoSelectToken(); - }, - ); - }, - ); - } - - void _showTokenSelection(BuildContext context) async { - if (selectedNetwork == null || isLoadingTokens) return; - - setState(() { - isLoadingTokens = true; - }); - - try { - final availableTokens = await TokenUtilities.getAvailableTokensForNetwork( - selectedNetwork!, - ); - - if (availableTokens.isEmpty) { - setState(() { - isLoadingTokens = false; - }); - await showPopUp( - context: context, - builder: (context) => AlertDialog( - title: Text(S.current.error), - content: const Text('No tokens available for this network'), - actions: [ - TextButton( - onPressed: () => Navigator.of(context).pop(), - child: Text(S.current.ok), - ), - ], - ), - ); - return; - } - - final selectedIndex = selectedToken != null ? availableTokens.indexOf(selectedToken!) : 0; - - setState(() { - isLoadingTokens = false; - }); - - await showPopUp( - context: context, - builder: (BuildContext context) { - return CurrencyPicker( - selectedAtIndex: selectedIndex >= 0 ? selectedIndex : 0, - items: availableTokens.cast(), - hintText: S.current.add_token, - onItemSelected: (Currency currency) { - setState(() { - selectedToken = currency as CryptoCurrency; - }); - }, - ); - }, - ); - } catch (e) { - printV('Error showing token selection: $e'); - setState(() { - isLoadingTokens = false; - tokenLoadError = 'Failed to load tokens'; - }); - } - } - - Future _handleNext(BuildContext context) async { - if (selectedNetwork == null || selectedToken == null) return; - - Navigator.of(context).pop(); - - final compatibleWallets = await widget.paymentViewModel.getWalletsByType(selectedNetwork!); - - PaymentFlowResult newResult; - - if (selectedNetwork == WalletType.solana) { - newResult = PaymentFlowResult.solanaTokenSelection( - AddressDetectionResult( - address: widget.paymentRequest.address, - detectedWalletType: WalletType.solana, - detectedCurrency: selectedToken!, - isValid: true, - amount: widget.paymentRequest.resolveTokenAmount(selectedToken!), - note: widget.paymentRequest.note, - scheme: widget.paymentRequest.scheme, - pjUri: widget.paymentRequest.pjUri, - callbackUrl: widget.paymentRequest.callbackUrl, - callbackMessage: widget.paymentRequest.callbackMessage, - ), - compatibleWallets: compatibleWallets, - wallet: compatibleWallets.isNotEmpty ? compatibleWallets.first : null, - ); - } else if (selectedNetwork == WalletType.tron) { - newResult = PaymentFlowResult.tronTokenSelection( - AddressDetectionResult( - address: widget.paymentRequest.address, - detectedWalletType: WalletType.tron, - detectedCurrency: selectedToken!, - isValid: true, - amount: widget.paymentRequest.resolveTokenAmount(selectedToken!), - note: widget.paymentRequest.note, - scheme: widget.paymentRequest.scheme, - pjUri: widget.paymentRequest.pjUri, - callbackUrl: widget.paymentRequest.callbackUrl, - callbackMessage: widget.paymentRequest.callbackMessage, - ), - compatibleWallets: compatibleWallets, - wallet: compatibleWallets.isNotEmpty ? compatibleWallets.first : null, - ); - } else { - newResult = PaymentFlowResult.evmNetworkSelection( - AddressDetectionResult( - address: widget.paymentRequest.address, - detectedWalletType: selectedNetwork!, - detectedCurrency: selectedToken!, - isValid: true, - amount: widget.paymentRequest.resolveTokenAmount(selectedToken!), - note: widget.paymentRequest.note, - scheme: widget.paymentRequest.scheme, - pjUri: widget.paymentRequest.pjUri, - callbackUrl: widget.paymentRequest.callbackUrl, - callbackMessage: widget.paymentRequest.callbackMessage, - ), - compatibleWallets: compatibleWallets, - wallet: compatibleWallets.isNotEmpty ? compatibleWallets.first : null, - ); - } - - widget.paymentViewModel.detectedWalletType = selectedNetwork!; - widget.onNext(newResult); - } -} - -class TokenSelectionTileWidget extends StatelessWidget { - const TokenSelectionTileWidget({ - super.key, - required this.value, - required this.enabled, - required this.onTap, - this.imagePath, - this.color, - }); - - final String value; - final bool enabled; - final VoidCallback? onTap; - final String? imagePath; - final Color? color; - - @override - Widget build(BuildContext context) { - return InkWell( - onTap: enabled ? onTap : null, - borderRadius: BorderRadius.circular(12), - child: Opacity( - opacity: enabled ? 1.0 : 0.6, - child: Container( - padding: const EdgeInsets.all(16), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Theme.of(context).colorScheme.surfaceContainer, - ), - child: Row( - children: [ - if (imagePath != null) ...[ - CakeImageWidget( - imageUrl: imagePath!, - color: color, - width: 20, - height: 20, - ), - const SizedBox(width: 16), - ], - Expanded( - child: Text( - value, - style: Theme.of(context).textTheme.titleMedium!.copyWith( - fontSize: 14, - fontWeight: FontWeight.w400, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - ), - if (enabled) - Icon( - Icons.keyboard_arrow_down, - size: 24, - color: Theme.of(context).colorScheme.primary, - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/src/widgets/bottom_sheet/wallet_switcher_bottom_sheet.dart b/lib/src/widgets/bottom_sheet/wallet_switcher_bottom_sheet.dart deleted file mode 100644 index f017ae67d..000000000 --- a/lib/src/widgets/bottom_sheet/wallet_switcher_bottom_sheet.dart +++ /dev/null @@ -1,132 +0,0 @@ -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cw_core/currency_for_wallet_type.dart'; -import 'package:flutter/material.dart'; -import 'package:cake_wallet/src/widgets/bottom_sheet/base_bottom_sheet_widget.dart'; -import 'package:cake_wallet/src/widgets/standard_list.dart'; -import 'package:cw_core/wallet_info.dart'; -import 'package:cw_core/wallet_type.dart'; -import 'package:cake_wallet/view_model/wallet_switcher_view_model.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; - -class WalletSwitcherBottomSheet extends BaseBottomSheet { - WalletSwitcherBottomSheet({ - Key? key, - required this.viewModel, - this.filterWalletType, - this.subtitle, - this.onWalletSelected, - }) : super( - titleText: S.current.select_a_wallet, - footerType: FooterType.none, - maxHeight: 900, - ); - - final WalletSwitcherViewModel viewModel; - final WalletType? filterWalletType; - final String? subtitle; - final Function(WalletInfo)? onWalletSelected; - - @override - Widget contentWidget(BuildContext context) { - return _WalletSwitcherContent( - viewModel: viewModel, - filterWalletType: filterWalletType, - subtitle: subtitle, - onWalletSelected: onWalletSelected, - ); - } -} - -class _WalletSwitcherContent extends StatelessWidget { - const _WalletSwitcherContent({ - required this.viewModel, - this.filterWalletType, - this.subtitle, - this.onWalletSelected, - }); - - final WalletSwitcherViewModel viewModel; - final WalletType? filterWalletType; - final String? subtitle; - final Function(WalletInfo)? onWalletSelected; - - @override - Widget build(BuildContext context) { - return FutureBuilder( - future: viewModel.getWallets(filterWalletType), - builder: (context, snapshot) => Observer( - builder: (_) { - final List wallets = (snapshot.data ?? []); - - if (viewModel.isProcessing) { - return Container( - height: 200, - child: Center( - child: CircularProgressIndicator( - color: Theme.of(context).colorScheme.primary, - ), - ), - ); - } - - return Container( - height: 400, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: StandardList( - itemCount: wallets.length, - itemBuilder: (context, index) { - final wallet = wallets[index]; - - return InkWell( - onTap: () { - viewModel.selectWallet(wallet); - Navigator.of(context).pop(); - }, - borderRadius: BorderRadius.circular(12), - child: Container( - margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.surfaceContainer, - borderRadius: BorderRadius.circular(16), - ), - height: 60, - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), - child: Row( - children: [ - Image.asset( - getCryptoCurrencyIconForWalletListItem( - wallet.type, - ), - width: 32, - height: 32, - ), - const SizedBox(width: 16), - Text( - wallet.name, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 18, - fontWeight: FontWeight.w700, - color: Theme.of(context).colorScheme.onSurface, - letterSpacing: 0.0, - ), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - ], - ), - ), - ); - }, - ), - ), - ], - ), - ); - }, - ), - ); - } -} diff --git a/lib/src/widgets/cake_scrollbar.dart b/lib/src/widgets/cake_scrollbar.dart deleted file mode 100644 index 4ce7f0085..000000000 --- a/lib/src/widgets/cake_scrollbar.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:flutter/material.dart'; - -class CakeScrollbar extends StatelessWidget { - CakeScrollbar({ - required this.backgroundHeight, - required this.thumbHeight, - required this.fromTop, - this.rightOffset = 6, - this.backgroundColor, - this.thumbColor, - this.width = 6, - }); - - final double backgroundHeight; - final double thumbHeight; - final double fromTop; - final double width; - final double rightOffset; - final Color? backgroundColor; - final Color? thumbColor; - - @override - Widget build(BuildContext context) { - return Positioned( - right: rightOffset, - child: Container( - height: backgroundHeight, - width: width, - decoration: BoxDecoration( - color: backgroundColor ?? Theme.of(context).colorScheme.surfaceContainerHighest, - borderRadius: BorderRadius.all(Radius.circular(3))), - child: Stack( - children: [ - AnimatedPositioned( - duration: Duration(milliseconds: 0), - top: fromTop, - child: Container( - height: thumbHeight, - width: width, - decoration: BoxDecoration( - color: thumbColor ?? Theme.of(context).colorScheme.primary, - borderRadius: BorderRadius.all(Radius.circular(3))), - ), - ) - ], - ), - )); - } -} diff --git a/lib/src/widgets/discount_badge.dart b/lib/src/widgets/discount_badge.dart deleted file mode 100644 index 9d5a26db2..000000000 --- a/lib/src/widgets/discount_badge.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:cake_wallet/generated/i18n.dart'; - -class DiscountBadge extends StatelessWidget { - const DiscountBadge({ - Key? key, - required this.percentage, - this.discountBackground, - this.isAmount = false, - }) : super(key: key); - - final double percentage; - final bool isAmount; - final AssetImage? discountBackground; - - @override - Widget build(BuildContext context) { - return Container( - padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4), - child: Text( - isAmount - ? '\$${percentage.toStringAsFixed(2)}' - : S.of(context).discount(percentage.toStringAsFixed(2)), - style: Theme.of(context).textTheme.bodySmall?.copyWith( - fontWeight: FontWeight.w500, - ), - ), - decoration: BoxDecoration( - image: DecorationImage( - fit: BoxFit.fill, - image: discountBackground ?? AssetImage('assets/images/badge_discount.png'), - ), - ), - ); - } -} diff --git a/lib/src/widgets/evm_switcher.dart b/lib/src/widgets/evm_switcher.dart deleted file mode 100644 index 0e9799af5..000000000 --- a/lib/src/widgets/evm_switcher.dart +++ /dev/null @@ -1,349 +0,0 @@ -import 'package:cake_wallet/evm/evm.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; - -import 'evm_switcher_row.dart'; - -class EvmSwitcherDataItem { - final String name; - final String svgPath; - final int chainId; - - const EvmSwitcherDataItem({ - required this.name, - required this.svgPath, - required this.chainId, - }); -} - -String _getSvgPathForChain(String chainName) { - final name = chainName.toLowerCase(); - - switch (name) { - case 'ethereum': - return 'assets/new-ui/crypto_full_icons/ethereum.svg'; - case 'polygon': - return 'assets/new-ui/crypto_full_icons/polygon.svg'; - case 'arbitrum': - return 'assets/new-ui/crypto_full_icons/arbitrum.svg'; - case 'base': - return 'assets/new-ui/crypto_full_icons/base.svg'; - case 'bnb': - case 'bsc': - return 'assets/new-ui/crypto_full_icons/bnb.svg'; - default: - return 'assets/new-ui/crypto_full_icons/ethereum.svg'; - } -} - -class EvmSwitcher extends StatefulWidget { - const EvmSwitcher({ - super.key, - required this.chains, - required this.currentChain, - required this.onChainSelected, - required this.hiddenChainIds, - required this.onHiddenChanged, - }); - - final List chains; - final ChainInfo? currentChain; - final Future Function(int chainId) onChainSelected; - final Set hiddenChainIds; - final void Function(Set hiddenChainIds) onHiddenChanged; - - static const editModeAnimDuration = Duration(milliseconds: 200); - - @override - State createState() => _EvmSwitcherState(); -} - -class _EvmSwitcherState extends State { - bool _editMode = false; - var optionsEnabled = []; - - @override - void initState() { - super.initState(); - _syncOptionsEnabled(); - } - - @override - void didUpdateWidget(covariant EvmSwitcher oldWidget) { - super.didUpdateWidget(oldWidget); - if (oldWidget.chains != widget.chains || - !_hiddenSetsEqual(oldWidget.hiddenChainIds, widget.hiddenChainIds)) { - _syncOptionsEnabled(); - } - } - - void _syncOptionsEnabled() { - optionsEnabled = widget.chains - .map((chain) => !widget.hiddenChainIds.contains(chain.chainId)) - .toList(growable: false); - } - - bool _hiddenSetsEqual(Set a, Set b) => a.length == b.length && a.containsAll(b); - - int get _selectedIndex { - if (widget.currentChain == null) return -1; - return widget.chains.indexWhere( - (chain) => chain.chainId == widget.currentChain!.chainId, - ); - } - - bool shouldBuildSeparator(int index) { - final nextEnabled = optionsEnabled.indexWhere( - (e) => e, - index + 1, - ); - - return index != _selectedIndex && - optionsEnabled[index] && - nextEnabled != _selectedIndex && - nextEnabled != -1; - } - - Set _currentHiddenChainIds() { - final hidden = {}; - for (var i = 0; i < widget.chains.length; i++) { - if (i < optionsEnabled.length && !optionsEnabled[i]) { - hidden.add(widget.chains[i].chainId); - } - } - return hidden; - } - - @override - Widget build(BuildContext context) { - final double popupWidth = MediaQuery.of(context).size.width * 0.9; - return Center( - child: Column( - spacing: 25.0, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - _editMode ? "Customize options" : "Select Network", - style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500), - ), - ClipRRect( - borderRadius: BorderRadius.circular(20), - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), - color: Theme.of(context).colorScheme.surfaceContainer, - ), - child: AnimatedContainer( - duration: EvmSwitcher.editModeAnimDuration, - width: popupWidth, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AnimatedSize( - curve: Curves.easeOutCubic, - duration: EvmSwitcher.editModeAnimDuration, - child: Container( - width: _editMode ? 0 : popupWidth, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - ListView.separated( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (context, index) { - if (optionsEnabled[index]) { - final chain = widget.chains[index]; - final data = EvmSwitcherDataItem( - name: chain.name, - svgPath: _getSvgPathForChain(chain.name), - chainId: chain.chainId, - ); - return EvmSwitcherRow( - key: ValueKey(chain.chainId), - data: data, - editMode: false, - selected: index == _selectedIndex, - onTap: () { - widget.onChainSelected(chain.chainId); - if (mounted) { - Navigator.of(context).pop(); - } - }, - editSwitchValue: true, - animDuration: EvmSwitcher.editModeAnimDuration, - ); - } else { - return Container(); - } - }, - separatorBuilder: (context, index) { - if (shouldBuildSeparator(index)) - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 18), - child: Container( - height: 1, - width: double.infinity, - color: - Theme.of(context).colorScheme.surfaceContainerHigh, - )); - else - return Container(height: 1); - }, - itemCount: widget.chains.length), - EvmSwitcherAdditionalOption( - title: "Customize options", - svgPath: "assets/images/evm_switcher_arrow_right.svg", - animDuration: EvmSwitcher.editModeAnimDuration, - topSeparator: true, - bottomSeparator: false, - visible: true, - onTap: () { - setState(() { - _editMode = true; - }); - }, - iconOnRight: true) - ], - ), - ), - ), - AnimatedSize( - curve: Curves.easeOutCubic, - duration: EvmSwitcher.editModeAnimDuration, - child: Container( - width: _editMode ? popupWidth : 0, - height: _editMode ? null : 0, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - EvmSwitcherAdditionalOption( - title: "Back", - svgPath: "assets/images/evm_switcher_arrow_left.svg", - animDuration: EvmSwitcher.editModeAnimDuration, - topSeparator: false, - bottomSeparator: true, - visible: true, - onTap: () { - setState(() { - _editMode = false; - }); - }, - iconOnRight: false), - ListView.separated( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (context, index) { - final chain = widget.chains[index]; - final data = EvmSwitcherDataItem( - name: chain.name, - svgPath: _getSvgPathForChain(chain.name), - chainId: chain.chainId, - ); - return EvmSwitcherRow( - key: ValueKey(chain.chainId), - data: data, - editMode: _editMode, - selected: index == _selectedIndex, - onTap: () { - setState(() { - optionsEnabled[index] = !optionsEnabled[index]; - }); - widget.onHiddenChanged( - _currentHiddenChainIds(), - ); - }, - editSwitchValue: optionsEnabled[index], - animDuration: EvmSwitcher.editModeAnimDuration, - ); - }, - separatorBuilder: (context, index) { - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 18), - child: Container( - height: 1, - width: double.infinity, - color: Theme.of(context).colorScheme.surfaceContainerHigh, - )); - }, - itemCount: widget.chains.length), - ], - ), - ), - ), - ], - )), - ), - ), - ], - ), - ); - } -} - -class EvmSwitcherAdditionalOption extends StatelessWidget { - const EvmSwitcherAdditionalOption( - {super.key, - required this.title, - required this.svgPath, - required this.animDuration, - required this.topSeparator, - required this.bottomSeparator, - required this.visible, - required this.onTap, - required this.iconOnRight}); - - final String title; - final String svgPath; - final Duration animDuration; - final bool topSeparator; - final bool bottomSeparator; - final bool visible; - final VoidCallback onTap; - final bool iconOnRight; - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onTap, - behavior: HitTestBehavior.translucent, - child: Container( - child: Column( - mainAxisSize: MainAxisSize.max, - children: [ - if (topSeparator) - Padding( - padding: const EdgeInsets.symmetric(horizontal: 18), - child: Container( - height: 1, - width: double.infinity, - color: Theme.of(context).colorScheme.surfaceContainerHigh, - )), - Padding( - padding: const EdgeInsets.all(18), - child: Row( - mainAxisSize: MainAxisSize.max, - spacing: 8.0, - children: [ - if (!iconOnRight) SvgPicture.asset(svgPath, width: 16, height: 16), - Text( - title, - style: TextStyle(color: Theme.of(context).colorScheme.primary), - ), - if (iconOnRight) SvgPicture.asset(svgPath, width: 16, height: 16), - ], - ), - ), - if (bottomSeparator) - Padding( - padding: const EdgeInsets.symmetric(horizontal: 18), - child: Container( - height: 1, - width: double.infinity, - color: Theme.of(context).colorScheme.surfaceContainerHigh, - )), - ], - ), - ), - ); - } -} diff --git a/lib/src/widgets/evm_switcher_row.dart b/lib/src/widgets/evm_switcher_row.dart deleted file mode 100644 index d1c269be4..000000000 --- a/lib/src/widgets/evm_switcher_row.dart +++ /dev/null @@ -1,72 +0,0 @@ -import 'package:cake_wallet/src/widgets/cake_image_widget.dart'; -import 'package:cake_wallet/src/widgets/evm_switcher.dart'; -import 'package:cake_wallet/src/widgets/standard_switch.dart'; -import 'package:flutter/material.dart'; - -class EvmSwitcherRow extends StatelessWidget { - const EvmSwitcherRow({ - super.key, - required this.editMode, - required this.selected, - required this.data, - required this.onTap, - required this.animDuration, - required this.editSwitchValue, - }); - - final bool editMode; - final bool selected; - final EvmSwitcherDataItem data; - final VoidCallback onTap; - final Duration animDuration; - final bool editSwitchValue; - - @override - Widget build(BuildContext context) { - final Color resolvedForegroundColor = editMode || selected - ? Theme.of(context).colorScheme.onSurface - : Theme.of(context).colorScheme.primary; - - final Color resolvedBackgroundColor = !editMode && selected - ? Theme.of(context).colorScheme.surfaceContainerHighest - : Theme.of(context).colorScheme.surfaceContainerHighest.withAlpha(0); - - return GestureDetector( - onTap: onTap, - child: AnimatedContainer( - duration: animDuration, - color: resolvedBackgroundColor, - child: Padding( - padding: const EdgeInsets.all(18.0), - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - spacing: 8.0, - children: [ - CakeImageWidget( - imageUrl: data.svgPath, - width: 16, - height: 16, - ), - Text( - data.name, - style: TextStyle(color: resolvedForegroundColor, fontSize: 14), - ), - if (selected && !editMode) - CakeImageWidget( - imageUrl: "assets/images/evm_switcher_checkmark.svg", - width: 18, - height: 18, - ), - ], - ), - if (editMode) StandardSwitch(value: editSwitchValue, onTapped: onTap) - ], - ), - ), - ), - ); - } -} diff --git a/lib/src/widgets/haven_wallet_removal_popup.dart b/lib/src/widgets/haven_wallet_removal_popup.dart deleted file mode 100644 index 4e3793aba..000000000 --- a/lib/src/widgets/haven_wallet_removal_popup.dart +++ /dev/null @@ -1,84 +0,0 @@ -import 'package:cake_wallet/src/widgets/alert_background.dart'; -import 'package:cake_wallet/src/widgets/alert_close_button.dart'; -import 'package:flutter/material.dart'; - -class HavenWalletRemovalPopup extends StatelessWidget { - final List affectedWalletNames; - - const HavenWalletRemovalPopup(this.affectedWalletNames, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Stack( - alignment: Alignment.center, - children: [ - AlertBackground( - child: AlertDialog( - insetPadding: EdgeInsets.only(left: 16, right: 16, bottom: 48), - elevation: 0.0, - contentPadding: EdgeInsets.zero, - shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(30))), - content: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(30.0), - gradient: LinearGradient(colors: [ - Theme.of(context).colorScheme.primaryContainer, - Theme.of(context).colorScheme.secondaryContainer, - ], begin: Alignment.centerLeft, end: Alignment.centerRight)), - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 24.0), - child: Stack( - children: [ - SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.only(top: 16.0), - child: Container( - alignment: Alignment.bottomCenter, - child: DefaultTextStyle( - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - decoration: TextDecoration.none, - fontSize: 24.0, - fontWeight: FontWeight.bold, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - child: Text("Emergency Notice"), - ), - ), - ), - ), - SingleChildScrollView( - child: Padding( - padding: EdgeInsets.only(top: 48, bottom: 16), - child: Container( - width: double.maxFinite, - child: Column( - children: [ - ConstrainedBox( - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context).size.height * 0.7, - ), - child: Text( - "It looks like you have Haven wallets in your list. Haven is getting removed in next release of Cake Wallet, and you currently have Haven in the following wallets:\n\n[${affectedWalletNames.join(", ")}]\n\nPlease move your funds to other wallet, as you will lose access to your Haven funds in next update.\n\nFor assistance, please use the in-app support or email support@cakewallet.com", - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - decoration: TextDecoration.none, - fontSize: 16.0, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - ) - ], - ), - ), - ), - ), - ], - ), - ), - ), - ), - ), - AlertCloseButton(bottom: 30) - ], - ); - } -} diff --git a/lib/src/widgets/introducing_card.dart b/lib/src/widgets/introducing_card.dart deleted file mode 100644 index a03e77053..000000000 --- a/lib/src/widgets/introducing_card.dart +++ /dev/null @@ -1,93 +0,0 @@ -import 'package:auto_size_text/auto_size_text.dart'; -import 'package:flutter/material.dart'; -import 'package:cake_wallet/generated/i18n.dart'; - -class IntroducingCard extends StatelessWidget { - IntroducingCard( - {required this.borderColor, - required this.closeCard, - required this.title, - required this.subTitle}); - - final String title; - final String subTitle; - final Color borderColor; - final Function() closeCard; - - @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.fromLTRB(16, 0, 16, 16), - child: Container( - width: double.infinity, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(30.0), - border: Border.all( - color: borderColor, - width: 1, - ), - color: Theme.of(context).colorScheme.surfaceContainer, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - flex: 1, - child: MergeSemantics( - child: Padding( - padding: const EdgeInsets.all(24), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AutoSizeText( - title, - style: Theme.of(context).textTheme.headlineSmall?.copyWith( - fontWeight: FontWeight.bold, - height: 1, - ), - maxLines: 1, - textAlign: TextAlign.center, - ), - SizedBox(height: 14), - Text( - subTitle, - textAlign: TextAlign.left, - style: Theme.of(context).textTheme.bodySmall, - ), - ], - ), - ), - ), - ), - Padding( - padding: const EdgeInsets.fromLTRB(0, 16, 16, 0), - child: Semantics( - label: S.of(context).close, - child: GestureDetector( - onTap: closeCard, - child: Container( - height: 23, - width: 23, - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.surfaceContainer, - shape: BoxShape.circle, - ), - child: Center( - child: Image.asset( - 'assets/images/x.png', - color: Theme.of(context).colorScheme.onSurface, - height: 15, - width: 15, - ), - ), - ), - ), - ), - ) - ], - ), - ), - ); - } -} diff --git a/lib/src/widgets/picker_inner_wrapper_widget.dart b/lib/src/widgets/picker_inner_wrapper_widget.dart deleted file mode 100644 index 5714719f4..000000000 --- a/lib/src/widgets/picker_inner_wrapper_widget.dart +++ /dev/null @@ -1,90 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:cake_wallet/src/widgets/picker_wrapper_widget.dart'; -import 'package:cake_wallet/utils/responsive_layout_util.dart'; - -class PickerInnerWrapperWidget extends StatelessWidget { - PickerInnerWrapperWidget({required this.children, this.title, this.itemsHeight}); - - final List children; - final String? title; - final double? itemsHeight; - - @override - Widget build(BuildContext context) { - final mq = MediaQuery.of(context); - final bottom = mq.viewInsets.bottom; - final height = mq.size.height - bottom; - - double containerHeight = height * 0.65; - if (bottom > 0) { - // increase a bit or it gets too squished in the top - containerHeight = height * 0.75; - } - - if (title != null) { - return PickerWrapperWidget( - hasTitle: true, - children: [ - Container( - padding: EdgeInsets.symmetric(horizontal: 24), - child: Text( - title!, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.titleMedium?.copyWith( - fontWeight: FontWeight.bold, - fontSize: 18, - decoration: TextDecoration.none, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - ), - SizedBox(height: 8), - Padding( - padding: EdgeInsets.symmetric(horizontal: 24), - child: ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(14)), - child: Container( - color: Theme.of(context).colorScheme.surfaceContainerHighest, - child: ConstrainedBox( - constraints: BoxConstraints( - maxHeight: itemsHeight != null && itemsHeight! <= containerHeight - ? itemsHeight! - : containerHeight, - maxWidth: ResponsiveLayoutUtilBase.kPopupWidth, - ), - child: Column( - children: children, - ), - ), - ), - ), - ) - ], - ); - } - - return PickerWrapperWidget( - hasTitle: false, - children: [ - Padding( - padding: EdgeInsets.symmetric(horizontal: 24), - child: ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(14)), - child: Container( - color: Theme.of(context).colorScheme.surfaceContainerHighest, - child: ConstrainedBox( - constraints: BoxConstraints( - maxHeight: containerHeight, - maxWidth: ResponsiveLayoutUtilBase.kPopupWidth, - ), - child: Column( - children: children, - ), - ), - ), - ), - ) - ], - ); - } -} diff --git a/lib/src/widgets/service_status_tile.dart b/lib/src/widgets/service_status_tile.dart deleted file mode 100644 index 1b7b320a4..000000000 --- a/lib/src/widgets/service_status_tile.dart +++ /dev/null @@ -1,73 +0,0 @@ -import 'package:auto_size_text/auto_size_text.dart'; -import 'package:cake_wallet/entities/service_status.dart'; -import 'package:cake_wallet/themes/core/custom_theme_colors.dart'; -import 'package:flutter/material.dart'; -import 'package:intl/intl.dart'; - -class ServiceStatusTile extends StatelessWidget { - final ServiceStatus status; - - const ServiceStatusTile(this.status, {super.key}); - - @override - Widget build(BuildContext context) { - return ListTile( - contentPadding: const EdgeInsets.all(8), - title: Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Expanded( - child: AutoSizeText( - "${status.title}${status.status != null ? " - ${status.status}" : ""}", - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 16, - fontWeight: FontWeight.w800, - height: 1, - ), - maxLines: 1, - textAlign: TextAlign.start, - ), - ), - Text( - _getTimeString(status.date), - style: Theme.of(context).textTheme.bodySmall, - ), - ], - ), - ), - leading: RotatedBox( - child: Icon( - Icons.info, - color: status.status == "resolved" - ? CustomThemeColors.syncGreen - : Theme.of(context).colorScheme.errorContainer, - ), - quarterTurns: 2, - ), - subtitle: Row( - children: [ - Expanded(child: Text(status.description)), - if (status.image != null) - SizedBox( - height: 50, - width: 50, - child: Image.network(status.image!), - ), - ], - ), - ); - } - - String _getTimeString(DateTime date) { - int difference = DateTime.now().difference(date).inHours; - if (difference == 0) { - return "few minutes ago"; - } - if (difference < 24) { - return DateFormat('h:mm a').format(date); - } - return DateFormat('d-MM-yyyy').format(date); - } -} diff --git a/lib/src/widgets/services_updates_widget.dart b/lib/src/widgets/services_updates_widget.dart deleted file mode 100644 index 19f167467..000000000 --- a/lib/src/widgets/services_updates_widget.dart +++ /dev/null @@ -1,158 +0,0 @@ -import 'package:cake_wallet/di.dart'; -import 'package:cake_wallet/entities/preferences_key.dart'; -import 'package:cake_wallet/entities/service_status.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; -import 'package:cake_wallet/src/widgets/cake_image_widget.dart'; -import 'package:cake_wallet/src/widgets/primary_button.dart'; -import 'package:cake_wallet/src/widgets/service_status_tile.dart'; -import 'package:cake_wallet/utils/device_info.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; -import 'package:flutter/material.dart'; -import 'package:shared_preferences/shared_preferences.dart'; -import 'package:url_launcher/url_launcher.dart'; - -class ServicesUpdatesWidget extends StatefulWidget { - final Future servicesResponse; - final bool enabled; - - const ServicesUpdatesWidget(this.servicesResponse, {super.key, required this.enabled}); - - @override - State createState() => _ServicesUpdatesWidgetState(); -} - -class _ServicesUpdatesWidgetState extends State { - bool wasOpened = false; - - @override - Widget build(BuildContext context) { - if (!widget.enabled) { - return InkWell( - onTap: () async { - await showPopUp( - context: context, - builder: (BuildContext context) { - return AlertWithOneAction( - alertTitle: S.current.service_health_disabled, - alertContent: S.current.service_health_disabled_message, - buttonText: S.current.ok, - buttonAction: () => Navigator.of(context).pop(), - ); - }); - }, - child: CakeImageWidget( - imageUrl: "assets/images/notif.svg", - color: Theme.of(context).colorScheme.primary, - width: DeviceInfo.instance.isDesktop ? 30 : 20, - ), - ); - } - return Padding( - padding: DeviceInfo.instance.isDesktop - ? EdgeInsets.zero - : EdgeInsets.only(left: 16, top: 12, right: 8, bottom: 8), - child: FutureBuilder( - future: widget.servicesResponse, - builder: (context, state) { - return InkWell( - onTap: state.hasData - ? () { - // save currentSha when the user see the status - getIt - .get() - .setString(PreferencesKey.serviceStatusShaKey, state.data!.currentSha); - - setState(() => wasOpened = true); - - showModalBottomSheet( - backgroundColor: Theme.of(context).colorScheme.surface, - context: context, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(50), - topRight: Radius.circular(50), - ), - ), - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context).size.height / 2, - minHeight: MediaQuery.of(context).size.height / 4, - ), - builder: (context) { - Widget body; - if (state.data!.servicesStatus.isEmpty) { - body = Center( - child: Text( - "Everything is up and running as expected", - style: Theme.of(context).textTheme.bodyMedium, - ), - ); - } else { - body = SingleChildScrollView( - child: Column( - children: state.data!.servicesStatus - .map((status) => ServiceStatusTile(status)) - .toList(), - ), - ); - } - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 12), - child: Column( - children: [ - Expanded(child: body), - Align( - alignment: Alignment.bottomCenter, - child: Padding( - padding: EdgeInsets.symmetric( - horizontal: 24, - vertical: 20, - ), - child: PrimaryButton( - onPressed: () { - try { - launchUrl( - Uri.parse( - "https://status.cakewallet.com/", - ), - mode: LaunchMode.externalApplication); - } catch (_) {} - }, - text: "Status Website", - color: Theme.of(context).colorScheme.primary, - textColor: Theme.of(context).colorScheme.onPrimary, - ), - ), - ) - ], - ), - ); - }, - ); - } - : null, - child: Stack( - children: [ - CakeImageWidget( - imageUrl: "assets/images/notif.svg", - color: Theme.of(context).colorScheme.primary, - width: DeviceInfo.instance.isDesktop ? 30 : 20, - ), - if (state.hasData && state.data!.hasUpdates && !wasOpened) - Container( - height: 7, - width: 7, - margin: EdgeInsetsDirectional.only(start: 15), - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.errorContainer, - shape: BoxShape.circle, - ), - ), - ], - ), - ); - }, - ), - ); - } -} diff --git a/lib/src/widgets/simple_checkbox.dart b/lib/src/widgets/simple_checkbox.dart deleted file mode 100644 index 93d7b8abc..000000000 --- a/lib/src/widgets/simple_checkbox.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:flutter/material.dart'; - -class SimpleCheckbox extends StatefulWidget { - SimpleCheckbox({this.onChanged}); - - final Function(bool)? onChanged; - - @override - State createState() => _SimpleCheckboxState(); -} - -class _SimpleCheckboxState extends State { - bool initialValue = false; - - @override - Widget build(BuildContext context) { - return SizedBox( - height: 24.0, - width: 24.0, - child: Checkbox( - value: initialValue, - onChanged: (value) => setState(() { - initialValue = value!; - widget.onChanged?.call(value); - }), - checkColor: Theme.of(context).textTheme.titleLarge!.color, - activeColor: Colors.transparent, - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - side: WidgetStateBorderSide.resolveWith((states) => - BorderSide(color: Theme.of(context).textTheme.titleLarge!.color!, width: 1.0)), - ), - ); - } -} diff --git a/lib/src/widgets/tab_view_wrapper_widget.dart b/lib/src/widgets/tab_view_wrapper_widget.dart index 4fbf2a31d..eb5f669da 100644 --- a/lib/src/widgets/tab_view_wrapper_widget.dart +++ b/lib/src/widgets/tab_view_wrapper_widget.dart @@ -41,7 +41,6 @@ class _TabViewWrapperState extends State with SingleTickerProvid Widget build(BuildContext context) { final textStyle = TextStyle( fontSize: 18, - fontFamily: 'Lato', fontWeight: FontWeight.w600, color: Theme.of(context).colorScheme.onSurface); diff --git a/lib/src/widgets/template_tile.dart b/lib/src/widgets/template_tile.dart deleted file mode 100644 index 3fda11b7c..000000000 --- a/lib/src/widgets/template_tile.dart +++ /dev/null @@ -1,159 +0,0 @@ -import 'package:cake_wallet/themes/core/custom_theme_colors.dart'; -import 'package:flutter/material.dart'; - -class TemplateTile extends StatefulWidget { - TemplateTile({ - Key? key, - required this.to, - required this.amount, - required this.from, - required this.onTap, - required this.onRemove, - this.hasMultipleRecipients, - }) : super(key: key); - - final String to; - final String amount; - final String from; - final VoidCallback onTap; - final VoidCallback onRemove; - final bool? hasMultipleRecipients; - - @override - TemplateTileState createState() => TemplateTileState(to, amount, from, onTap, onRemove); -} - -class TemplateTileState extends State { - TemplateTileState(this.to, this.amount, this.from, this.onTap, this.onRemove); - - final String to; - final String amount; - final String from; - final VoidCallback onTap; - final VoidCallback onRemove; - - bool isRemovable = false; - - @override - Widget build(BuildContext context) { - final toIcon = Image.asset( - 'assets/images/to_icon.png', - color: Theme.of(context).colorScheme.onSurface, - ); - - final content = Row( - mainAxisAlignment: MainAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: widget.hasMultipleRecipients ?? false - ? [ - Text( - to, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontSize: 16, - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - ] - : [ - Text( - amount, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontSize: 16, - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - Padding( - padding: EdgeInsets.only(left: 5), - child: Text( - from, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontSize: 16, - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - ), - Padding( - padding: EdgeInsets.only(left: 5), - child: toIcon, - ), - Padding( - padding: EdgeInsets.only(left: 5), - child: Text( - to, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontSize: 16, - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - ), - ], - ); - - final tile = Container( - padding: EdgeInsets.only(right: 10), - child: ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(12)), - child: GestureDetector( - onTap: onTap, - onLongPress: () { - setState(() { - isRemovable = true; - }); - }, - child: Container( - height: 40, - padding: EdgeInsets.only(left: 24, right: 24), - color: Theme.of(context).colorScheme.surfaceContainerHighest, - child: content, - ), - ), - )); - - final removableTile = Container( - padding: EdgeInsets.only(right: 10), - child: ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(12)), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - GestureDetector( - onTap: () { - setState(() { - isRemovable = false; - }); - }, - child: Container( - height: 40, - padding: EdgeInsets.only(left: 24, right: 10), - color: CustomThemeColors.syncYellow, - child: content, - ), - ), - GestureDetector( - onTap: onRemove, - child: Container( - height: 40, - width: 44, - color: Theme.of(context).colorScheme.errorContainer, - child: Center( - child: Image.asset( - 'assets/images/trash.png', - height: 16, - width: 16, - color: Theme.of(context).colorScheme.onErrorContainer, - ), - ), - ), - ) - ], - ), - ), - ); - - return isRemovable ? removableTile : tile; - } -} diff --git a/lib/store/templates/exchange_template_store.dart b/lib/store/templates/exchange_template_store.dart deleted file mode 100644 index 97e1f41dc..000000000 --- a/lib/store/templates/exchange_template_store.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'dart:async'; -import 'package:mobx/mobx.dart'; -import 'package:hive/hive.dart'; -import 'package:cake_wallet/exchange/exchange_template.dart'; - -part 'exchange_template_store.g.dart'; - -class ExchangeTemplateStore = ExchangeTemplateBase with _$ExchangeTemplateStore; - -abstract class ExchangeTemplateBase with Store { - ExchangeTemplateBase({required this.templateSource}) - : templates = ObservableList() { - templates = ObservableList(); - update(); - } - - @observable - ObservableList templates; - - Box templateSource; - - @action - void update() => templates.replaceRange(0, templates.length, templateSource.values.toList()); - - @action - Future addTemplate({ - required String amount, - required String depositCurrency, - required String receiveCurrency, - required String provider, - required String depositAddress, - required String receiveAddress, - required String depositCurrencyTitle, - required String receiveCurrencyTitle, - }) async { - final template = ExchangeTemplate( - amountRaw: amount, - depositCurrencyRaw: depositCurrency, - receiveCurrencyRaw: receiveCurrency, - providerRaw: provider, - depositAddressRaw: depositAddress, - receiveAddressRaw: receiveAddress, - depositCurrencyTitleRaw: depositCurrencyTitle, - receiveCurrencyTitleRaw: receiveCurrencyTitle); - await templateSource.add(template); - } - - @action - Future remove({required ExchangeTemplate template}) async => await template.delete(); -} diff --git a/lib/store/templates/send_template_store.dart b/lib/store/templates/send_template_store.dart deleted file mode 100644 index a1fff698e..000000000 --- a/lib/store/templates/send_template_store.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'dart:async'; -import 'package:mobx/mobx.dart'; -import 'package:hive/hive.dart'; -import 'package:cake_wallet/entities/template.dart'; - -part 'send_template_store.g.dart'; - -class SendTemplateStore = SendTemplateBase with _$SendTemplateStore; - -abstract class SendTemplateBase with Store { - SendTemplateBase({required this.templateSource}) : templates = ObservableList