What changed, and why it matters
This is a large cleanup commit that removes the old user interface code from the Cake Wallet app and switches the app to use only the new UI. It deletes many old screens, view models, fonts, and related dependency-injection registrations. There is no direct security fix here; it is ordinary maintenance that reduces code size and removes unused/commented-out functionality such as the Yat emoji-id integration and old buy/sell/exchange pages. Because so much code is removed, there is a small risk that something useful was accidentally deleted or that a route now points to a missing page, but the diff itself does not show an exploitable vulnerability.
Treat this as a routine refactor. Reviewers should verify that no live routes still reference deleted pages, that the new UI pages cover all required user flows (especially buy/sell, exchange, receive, and address management), and that removal of the YatStore and old webviews does not break any currently enabled feature. Regression testing on navigation and deep links is appropriate, but no immediate security response is indicated.
Security signals we found
Large-scale deletion of legacy UI code and unreachable routes
Removal of disabled/unused Yat emoji-id integration code (commented-out network calls and empty URL constants)
Removal of old buy/sell webview pages that handled external payment flows
Route table simplified to point only to new UI pages
No new cryptographic, authentication, or input-validation logic added
Evidence from the diff
Commit d38c748 is a UI refactor titled ‘remove old ui’. It deletes ~18,900 lines across 155 files, removing legacy screens under lib/src/screens (dashboard, send, receive, exchange, buy/sell, settings, etc.), legacy view models and stores, the Lato font assets, and the disabled YatStore. The remaining code is updated to always use the new UI pages (NewDashboard, NewSendPage, NewReceivePage, NewSwapPage, NewAddressesPage, etc.) and to remove FeatureFlag.hasNewUi / hasNewUiExtraPages branches. Dependency injection in lib/di.dart is pruned accordingly. The change is structural cleanup, not a security patch.
Changed components
Cake Wallet Flutter UI layerlib/di.dart dependency injectionlib/router.dart route tablelib/src/screens/* legacy screenslib/new-ui/* new UI pagescw_core/lib/receive_page_option.dartassets/fonts/Lato-*.ttfInspect captured patch +74 / −18935
### assets/fonts/Lato-Bold.ttf
[binary or diff unavailable]
### assets/fonts/Lato-Medium.ttf
[binary or diff unavailable]
### assets/fonts/Lato-Regular.ttf
[binary or diff unavailable]
### assets/fonts/Lato-Semibold.ttf
[binary or diff unavailable]
### 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
];
### 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)),
);
}
### lib/cake_pay/src/cards/cake_pay_cards_page.dart
@@ -168,12 +168,10 @@ class _CakePayCardsPageBodyState extends State<CakePayCardsPageBody> {
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,
### lib/cake_pay/src/widgets/three_checkbox_alert_content_widget.dart
@@ -172,7 +172,6 @@ class _ThreeCheckboxAlertContentState extends State<ThreeCheckboxAlertContent> {
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<ThreeCheckboxAlertContent> {
style: TextStyle(
color: Colors.red,
fontSize: 14,
- fontFamily: 'Lato',
fontWeight: FontWeight.w400,
decoration: TextDecoration.none,
),
### lib/core/address_resolver/yat/yat_store.dart
@@ -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 = <String, List<String>>{
- "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<List<String>> 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 = <String>[];
- //final currency = ticker.toUpperCase();
- //final responseJSON = json.decode(response.body) as Map<String, dynamic>;
- //final result = responseJSON['result'] as Map<dynamic, dynamic>;
- //result.forEach((dynamic key, dynamic value) {
- // final tag = key as String ?? '';
- // final record = value as Map<String, dynamic>;
-
- // if (YatLink.tags[currency]?.contains(tag) ?? false) {
- // final address = record['address'] as String;
- // if (address?.isNotEmpty ?? false) {
- // addresses.add(address);
- // }
- // }
- //});
-
- //return addresses;
- return [];
-}
-
-Future<String> 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: <String, String>{
- // '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<String, dynamic>;
- // return responseJSON['access_token'] as String;
- //}catch(_) {
- // return '';
- //}
- return '';
-}
-
-Future<String> 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: <String, String>{
- // '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<String, dynamic>;
- // return responseJSON['api_key'] as String;
- //}catch(_) {
- // return '';
- //}
- return '';
-}
-
-Future<void> 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: <String, String>{
- // 'x-api-key': apiKey,
- // 'Content-Type': 'application/json',
- // 'Accept': '*/*'
- // },
- // body: bodyJson);
-
- //if (response.statusCode != 200) {
- // throw YatException(text: response.body.toString());
- //}
-}
-
-Future<String> 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<String, dynamic>;
- //final data = responseJSON['data'] as Map<String, dynamic>;
- //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<String>.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<String> emojiIncommingSC;
-
- Stream<String> get emojiIncommingStream => emojiIncommingSC.stream;
-
- @observable
- WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>? _wallet;
-
- Future<void> 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<Balance, TransactionHistoryBase<TransactionInfo>, 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<void> _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 = <String, String>{};
- //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 '';
- }
-}
### 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,42 +97,24 @@ 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';
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_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,23 +126,20 @@ 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';
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';
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,34 +167,28 @@ 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';
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';
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';
import 'package:cake_wallet/view_model/cake_pay/cake_pay_cards_list_view_model.dart';
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<void> setup({
getIt.registerSingleton<OrderFilterStore>(OrderFilterStore());
getIt.registerSingleton<TransactionFilterStore>(TransactionFilterStore(getIt.get<AppStore>()));
getIt.registerSingleton<FiatConversionStore>(FiatConversionStore());
- getIt.registerSingleton<SendTemplateStore>(SendTemplateStore(templateSource: _templates));
- getIt.registerSingleton<ExchangeTemplateStore>(
- ExchangeTemplateStore(templateSource: _exchangeTemplates));
- getIt.registerSingleton<YatStore>(
- YatStore(appStore: getIt.get<AppStore>(), secureStorage: getIt.get<SecureStorage>())..init());
getIt.registerSingleton<AnonpayTransactionsStore>(
AnonpayTransactionsStore(anonpayInvoiceInfoSource: _anonpayInvoiceInfoSource));
getIt.registerSingleton<SeedSettingsStore>(SeedSettingsStore());
@@ -546,7 +500,6 @@ Future<void> setup({
getIt.registerFactory<WalletAddressListViewModel>(() => WalletAddressListViewModel(
appStore: getIt.get<AppStore>(),
- yatStore: getIt.get<YatStore>(),
fiatConversionStore: getIt.get<FiatConversionStore>()));
getIt.registerFactory(() => BalanceViewModel(
@@ -557,7 +510,6 @@ Future<void> setup({
getIt.registerFactory(
() => ExchangeViewModel(
getIt.get<AppStore>(),
- getIt.get<ExchangeTemplateStore>(),
getIt.get<TradesStore>(),
getIt.get<SharedPreferences>(),
getIt.get<ContactListViewModel>(),
@@ -585,7 +537,6 @@ Future<void> setup({
orderFilterStore: getIt.get<OrderFilterStore>(),
transactionFilterStore: getIt.get<TransactionFilterStore>(),
settingsStore: settingsStore,
- yatStore: getIt.get<YatStore>(),
anonpayTransactionsStore: getIt.get<AnonpayTransactionsStore>(),
payjoinTransactionsStore: getIt.get<PayjoinTransactionsStore>(),
sharedPreferences: getIt.get<SharedPreferences>(),
@@ -775,17 +726,6 @@ Future<void> setup({
return walletKitService;
});
- getIt.registerFactory(() => BalancePage(
- nftViewModel: getIt.get<NFTViewModel>(),
- dashboardViewModel: getIt.get<DashboardViewModel>(),
- settingsStore: getIt.get<SettingsStore>()));
-
- getIt.registerFactory<DashboardPage>(() => DashboardPage(
- bottomSheetService: getIt.get<BottomSheetService>(),
- balancePage: getIt.get<BalancePage>(),
- dashboardViewModel: getIt.get<DashboardViewModel>(),
- addressListViewModel: getIt.get<WalletAddressListViewModel>(),
- ));
getIt.registerFactory<NewDashboard>(() => NewDashboard(
dashboardViewModel: getIt.get<DashboardViewModel>(),
@@ -797,27 +737,6 @@ Future<void> setup({
nftViewModel: getIt.get<NFTViewModel>(),
));
- getIt.registerFactory<DesktopSidebarWrapper>(() {
- final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();
- return DesktopSidebarWrapper(
- bottomSheetService: getIt.get<BottomSheetService>(),
- dashboardViewModel: getIt.get<DashboardViewModel>(),
- desktopSidebarViewModel: getIt.get<DesktopSidebarViewModel>(),
- child: getIt.get<DesktopDashboardPage>(param1: _navigatorKey),
- desktopNavigatorKey: _navigatorKey,
- );
- });
- getIt.registerFactoryParam<DesktopDashboardPage, GlobalKey<NavigatorState>, void>(
- (desktopKey, _) => DesktopDashboardPage(
- balancePage: getIt.get<BalancePage>(),
- dashboardViewModel: getIt.get<DashboardViewModel>(),
- addressListViewModel: getIt.get<WalletAddressListViewModel>(),
- desktopKey: desktopKey,
- ));
-
- getIt.registerFactory<TransactionsPage>(
- () => TransactionsPage(dashboardViewModel: getIt.get<DashboardViewModel>()));
-
getIt.registerFactory<Setup2FAInfoPage>(() => Setup2FAInfoPage());
getIt.registerFactory<Setup2FAPage>(
@@ -829,43 +748,9 @@ Future<void> setup({
getIt.registerFactory<Modify2FAPage>(
() => Modify2FAPage(setup2FAViewModel: getIt.get<Setup2FAViewModel>()));
- getIt.registerFactory<DesktopSettingsPage>(
- () => DesktopSettingsPage(getIt.get<DashboardViewModel>()));
-
getIt.registerFactoryParam<ReceiveOptionViewModel, ReceivePageOption?, void>(
(pageOption, _) => ReceiveOptionViewModel(getIt.get<AppStore>().wallet!, pageOption));
- getIt.registerFactoryParam<AnonInvoicePageViewModel, List<dynamic>, void>((args, _) {
- final address = args.first as String;
- final pageOption = args.last as ReceivePageOption;
- return AnonInvoicePageViewModel(
- getIt.get<AnonPayApi>(),
- address,
- getIt.get<SettingsStore>(),
- getIt.get<AppStore>().wallet!,
- _anonpayInvoiceInfoSource,
- getIt.get<SharedPreferences>(),
- pageOption,
- );
- });
-
- getIt.registerFactoryParam<AnonPayInvoicePage, List<dynamic>, void>((List<dynamic> args, _) {
- final pageOption = args.last as ReceivePageOption;
- return AnonPayInvoicePage(getIt.get<AnonInvoicePageViewModel>(param1: args),
- getIt.get<ReceiveOptionViewModel>(param1: pageOption));
- });
-
- getIt.registerFactory<ReceivePage>(
- () => ReceivePage(addressListViewModel: getIt.get<WalletAddressListViewModel>()));
-
- getIt.registerFactory<AddressPage>(
- () => AddressPage(
- addressListViewModel: getIt<WalletAddressListViewModel>(),
- dashboardViewModel: getIt<DashboardViewModel>(),
- receiveOptionViewModel: getIt<ReceiveOptionViewModel>(),
- ),
- );
-
getIt.registerFactoryParam<NewReceivePage, bool?, CryptoCurrency?>((param1, param2) =>
NewReceivePage(
addressListViewModel: getIt.get<WalletAddressListViewModel>(),
@@ -878,10 +763,6 @@ Future<void> setup({
(WalletAddressListItem? item, _) =>
WalletAddressEditOrCreateViewModel(wallet: getIt.get<AppStore>().wallet!, item: item));
- getIt.registerFactoryParam<AddressEditOrCreatePage, dynamic, void>((dynamic item, _) =>
- AddressEditOrCreatePage(
- addressEditOrCreateViewModel:
- getIt.get<WalletAddressEditOrCreateViewModel>(param1: item)));
getIt.registerFactoryParam<AddressLabelInputPopup, dynamic, void>((dynamic item, _) =>
AddressLabelInputPopup(
@@ -897,16 +778,10 @@ Future<void> setup({
walletAddressEditOrCreateViewModel:
getIt.get<WalletAddressEditOrCreateViewModel>(param1: item)));
- getIt.registerFactory<SendTemplateViewModel>(() => SendTemplateViewModel(
- getIt.get<AppStore>().wallet!,
- getIt.get<AppStore>(),
- getIt.get<SendTemplateStore>(),
- getIt.get<FiatConversionStore>()));
getIt.registerFactoryParam<SendViewModel, UnspentCoinType?, void>(
(coinTypeToSpendFrom, _) => SendViewModel(
getIt.get<AppStore>(),
- getIt.get<SendTemplateViewModel>(),
getIt.get<FiatConversionStore>(),
getIt.get<AddressResolverService>(),
getIt.get<BalanceViewModel>(),
@@ -921,14 +796,7 @@ Future<void> setup({
getIt.get<FeesViewModel>()),
);
- getIt.registerFactoryParam<SendPage, PaymentRequest?, UnspentCoinType?>(
- (PaymentRequest? initialPaymentRequest, coinTypeToSpendFrom) => SendPage(
- sendViewModel: getIt.get<SendViewModel>(param1: coinTypeToSpendFrom),
- authService: getIt.get<AuthService>(),
- initialPaymentRequest: initialPaymentRequest,
- paymentViewModel: getIt.get<PaymentViewModel>(),
- walletSwitcherViewModel: getIt.get<WalletSwitcherViewModel>(),
- ));
+
getIt.registerFactoryParam<NewSendPage, SendPageParams?, void>((params, _) {
params ??= SendPageParams();
@@ -943,8 +811,7 @@ Future<void> setup({
);
});
- getIt.registerFactory(
- () => SendTemplatePage(sendTemplateViewModel: getIt.get<SendTemplateViewModel>()));
+
if (DeviceInfo.instance.isMobile) {
getIt.registerFactory(
@@ -1017,51 +884,20 @@ Future<void> setup({
'Unexpected wallet type: ${wallet.type} for generate Monero AccountListViewModel');
});
- getIt.registerFactory(
- () => MoneroAccountListPage(accountListViewModel: getIt.get<MoneroAccountListViewModel>()));
-
- getIt.registerFactory(
- () => NanoAccountListPage(accountListViewModel: getIt.get<NanoAccountListViewModel>()));
-
- /*getIt.registerFactory(() {
- final wallet = getIt.get<AppStore>().wallet;
-
- if (wallet is MoneroWallet) {
- return MoneroAccountEditOrCreateViewModel(wallet.accountList);
- }
-
- // FIXME: throw exception.
- return null;
- });
-
- getIt.registerFactory(() => MoneroAccountEditOrCreatePage(
- moneroAccountCreationViewModel:
- getIt.get<MoneroAccountEditOrCreateViewModel>()));*/
-
getIt.registerFactoryParam<MoneroAccountEditOrCreateViewModel, AccountListItem?, void>(
(AccountListItem? account, _) => MoneroAccountEditOrCreateViewModel(
monero!.getAccountList(getIt.get<AppStore>().wallet!),
wownero?.getAccountList(getIt.get<AppStore>().wallet!),
wallet: getIt.get<AppStore>().wallet!,
accountListItem: account));
- getIt.registerFactoryParam<MoneroAccountEditOrCreatePage, AccountListItem?, void>(
- (AccountListItem? account, _) => MoneroAccountEditOrCreatePage(
- moneroAccountCreationViewModel:
- getIt.get<MoneroAccountEditOrCreateViewModel>(param1: account)));
-
getIt.registerFactoryParam<NanoAccountEditOrCreateViewModel, NanoAccount?, void>(
(NanoAccount? account, _) =>
NanoAccountEditOrCreateViewModel(nano!.getAccountList(getIt.get<AppStore>().wallet!),
// banano?.getAccountList(getIt.get<AppStore>().wallet!),
wallet: getIt.get<AppStore>().wallet!,
accountListItem: account));
- getIt.registerFactoryParam<NanoAccountEditOrCreatePage, NanoAccount?, void>(
- (NanoAccount? account, _) => NanoAccountEditOrCreatePage(
- nanoAccountCreationViewModel:
- getIt.get<NanoAccountEditOrCreateViewModel>(param1: account)));
-
getIt.registerFactory(
() => DisplaySettingsViewModel(getIt.get<AppStore>(), getIt.get<ThemeStore>()));
@@ -1129,16 +965,16 @@ Future<void> setup({
getIt.registerFactoryParam<ContactPage, ContactRecord?, void>(
(ContactRecord? contact, _) => ContactPage(getIt.get<ContactViewModel>(param1: contact)));
- getIt.registerFactory(() => AddressListPage(getIt.get<WalletAddressListViewModel>()));
getIt.registerFactoryParam<NodeListViewModel, bool, void>((isPow, _) {
final appStore = getIt.get<AppStore>();
return NodeListViewModel(appStore, isPow);
});
- getIt.registerFactoryParam<NewAddressesPage, bool, void>(
- (showHidden, _) => NewAddressesPage(
- showHidden: showHidden,
+ getIt.registerFactoryParam<NewAddressesPage, AddressesPageArgs, void>(
+ (args, _) => NewAddressesPage(
+ showHidden: args.showHidden,
+ popOnSelection: args.popOnSelection,
addressListViewModel: getIt<WalletAddressListViewModel>(),
dashboardViewModel: getIt<DashboardViewModel>(),
),
@@ -1154,7 +990,6 @@ Future<void> setup({
getIt.registerFactory(() => PrivacyPage(getIt.get<PrivacySettingsViewModel>()));
- getIt.registerFactory(() => TrocadorProvidersPage(getIt.get<TrocadorProvidersViewModel>()));
getIt.registerFactory(() => DomainLookupsPage(getIt.get<ConnectionSyncViewModel>()));
@@ -1239,8 +1074,6 @@ Future<void> setup({
wallet: getIt.get<AppStore>().wallet!,
));
- getIt.registerFactoryParam<WebViewPage, String, Uri>((title, uri) => WebViewPage(title, uri));
-
getIt.registerFactory<FeesViewModel>(
() => FeesViewModel(
getIt.get<AppStore>(),
@@ -1258,11 +1091,6 @@ Future<void> setup({
),
);
- getIt.registerFactoryParam<ExchangePage, PaymentRequest?, void>(
- (PaymentRequest? paymentRequest, __) {
- return ExchangePage(getIt.get<ExchangeViewModel>(), getIt.get<AuthService>(),
- getIt.get<AddressResolverService>(), paymentRequest);
- });
getIt.registerFactoryParam<NewSwapPage, PaymentRequest?, CryptoCurrency?>(
(PaymentRequest? paymentRequest, CryptoCurrency? initialCurrency) {
@@ -1276,17 +1104,9 @@ Future<void> setup({
);
});
- getIt.registerFactory(() => ExchangeConfirmPage(tradesStore: getIt.get<TradesStore>()));
-
- getIt.registerFactory(
- () => ExchangeTradePage(exchangeTradeViewModel: getIt.get<ExchangeTradeViewModel>()));
-
- getIt.registerFactory(() =>
- ExchangeTradeExternalSendPage(exchangeTradeViewModel: getIt.get<ExchangeTradeViewModel>()));
getIt.registerFactory(() => BackgroundSyncPage(getIt.get<DashboardViewModel>()));
- getIt.registerFactory(() => ExchangeTemplatePage(getIt.get<ExchangeViewModel>()));
getIt.registerFactoryParam<SwapConfirmationBottomSheet, PaymentFlowResult, void>(
(paymentFlowResult, _) => SwapConfirmationBottomSheet(
@@ -1394,8 +1214,6 @@ Future<void> setup({
getIt.registerFactory(() => RescanPage(getIt.get<RescanViewModel>()));
- getIt.registerFactory(() => FaqPage(getIt.get<SettingsStore>()));
-
getIt.registerFactoryParam<WalletRestoreViewModel, WalletType, Map<String, dynamic>?>(
(type, additionalParams) {
final restoredWallet = additionalParams?['restoredWallet'] as RestoredWallet?;
@@ -1470,17 +1288,12 @@ Future<void> setup({
getIt.registerFactory<PreSeedPage>(() => PreSeedPage(getIt.get<AppStore>().wallet!));
- getIt.registerFactoryParam<TransactionSuccessPage, String, void>(
- (content, _) => TransactionSuccessPage(content: content));
-
getIt.registerFactoryParam<TradeDetailsViewModel, Trade, void>(
(trade, _) => TradeDetailsViewModel(tradeForDetails: trade, appStore: getIt.get<AppStore>()));
- getIt.registerFactory(() => CakeFeaturesViewModel(getIt.get<CakePayService>()));
getIt.registerFactory(() => CakeFeaturesPage(
- dashboardViewModel: getIt.get<DashboardViewModel>(),
- cakeFeaturesViewModel: getIt.get<CakeFeaturesViewModel>()));
+ dashboardViewModel: getIt.get<DashboardViewModel>(),));
getIt.registerFactory(() => BackupServiceV3(getIt.get<SecureStorage>(),
_transactionDescriptionBox, getIt.get<KeyService>(), getIt.get<SharedPreferences>()));
@@ -1514,39 +1327,6 @@ Future<void> setup({
getIt.registerFactoryParam<NewBuySellAmountPage, BuySellPageMode, void>((mode, _) =>
NewBuySellAmountPage(buySellViewModel: getIt.get<BuySellViewModel>(param1: mode)));
- getIt.registerFactory(
- () => BuySellPage(getIt.get<BuySellViewModel>(), getIt.get<AddressResolverService>()));
-
- getIt.registerFactoryParam<BuyOptionsPage, List<dynamic>, void>((List<dynamic> args, _) {
- final items = args.first as List<SelectableItem>;
- 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<PaymentMethodOptionsPage, List<dynamic>, void>((List<dynamic> args, _) {
- final items = args.first as List<SelectableOption>;
- final pickAnOption = args[1] as void Function(SelectableOption option)?;
-
- return PaymentMethodOptionsPage(items: items, pickAnOption: pickAnOption);
- });
-
- getIt.registerFactory(() {
- final wallet = getIt.get<AppStore>().wallet;
-
- return BuyViewModel(_ordersSource, getIt.get<OrdersStore>(), getIt.get<SettingsStore>(),
- getIt.get<BuyAmountViewModel>(),
- wallet: wallet!);
- });
-
- getIt.registerFactoryParam<BuyWebViewPage, List<dynamic>, void>((List<dynamic> args, _) {
- final url = args.first as String;
- final buyViewModel = args[1] as BuyViewModel;
-
- return BuyWebViewPage(
- buyViewModel: buyViewModel, ordersStore: getIt.get<OrdersStore>(), url: url);
- });
getIt.registerFactoryParam<OrderDetailsViewModel, Order, void>((order, _) {
final wallet = getIt.get<AppStore>().wallet;
@@ -1584,11 +1364,6 @@ Future<void> setup({
);
});
- getIt.registerFactoryParam<UnspentCoinsListPage, UnspentCoinType?, void>(
- (coinTypeToSpendFrom, _) => UnspentCoinsListPage(
- unspentCoinsListViewModel:
- getIt.get<UnspentCoinsListViewModel>(param1: coinTypeToSpendFrom)));
-
getIt.registerFactoryParam<NewCoinControlPage, UnspentCoinType?, bool?>(
(coinTypeToSpendFrom, canEdit) => NewCoinControlPage(
unspentCoinsListViewModel:
@@ -1665,11 +1440,6 @@ Future<void> setup({
useTorOnly: getIt.get<SettingsStore>().exchangeStatus == ExchangeApiMode.torOnly,
wallet: getIt.get<AppStore>().wallet!));
- getIt.registerFactory(() =>
- DesktopWalletSelectionDropDown(getIt.get<WalletListViewModel>(), getIt.get<AuthService>()));
-
- getIt.registerFactory(() => DesktopSidebarViewModel());
-
getIt.registerFactoryParam<AnonpayDetailsViewModel, AnonpayInvoiceInfo, void>(
(AnonpayInvoiceInfo anonpayInvoiceInfo, _) => AnonpayDetailsViewModel(
anonPayApi: getIt.get<AnonPayApi>(),
@@ -1685,10 +1455,6 @@ Future<void> setup({
themeStore: getIt.get<ThemeStore>(),
));
- getIt.registerFactoryParam<AnonPayReceivePage, AnonPayReceivePageArgs, void>(
- (AnonPayReceivePageArgs anonpayReceivePageArgs, _) =>
- AnonPayReceivePage(args: anonpayReceivePageArgs));
-
getIt.registerFactoryParam<AnonpayDetailsPage, AnonpayInvoiceInfo, void>(
(AnonpayInvoiceInfo anonpayInvoiceInfo, _) => AnonpayDetailsPage(
anonpayDetailsViewModel: getIt.get<AnonpayDetailsViewModel>(param1: anonpayInvoiceInfo)));
### 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<NewAddressesPage> createState() => _NewAddressesPageState();
@@ -133,6 +143,7 @@ class _NewAddressesPageState extends State<NewAddressesPage> {
fontSize: 10,
color: Theme.of(context).colorScheme.onSurfaceVariant),
),
+ if(!widget.popOnSelection)
ShowHiddenButton()
],
),
@@ -148,11 +159,15 @@ class _NewAddressesPageState extends State<NewAddressesPage> {
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 {
### 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<NewReceivePage> {
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<SharedPreferences>();
- 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));
}
});
}
### 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<NewSendPage>(
param1: SendPageParams(
unspentCoinType:
@@ -74,11 +73,6 @@ class CoinActionRow extends StatelessWidget {
);
},
);
- } else {
- Map<String, dynamic>? 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<NewReceivePage>(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<WalletAddressListViewModel>().setAddressType(
- bitcoin!.getOptionToType(bitcoin!.getBitcoinLightningReceivePageOption()));
- } else {
- await getIt<WalletAddressListViewModel>().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<NewSwapPage>(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(
### lib/new-ui/widgets/coins_page/cards/cards_view.dart
@@ -349,7 +349,7 @@ class _CardsViewState extends State<CardsView> {
}
}
- if (FeatureFlag.hasNewUiExtraPages && widget.dashboardViewModel.type == WalletType.bitcoin) {
+ if (widget.dashboardViewModel.type == WalletType.bitcoin) {
final page = getIt.get<NewSendPage>(
param1: SendPageParams(
initialPaymentRequest: paymentRequest,
@@ -396,7 +396,7 @@ class _CardsViewState extends State<CardsView> {
unspentCoinType = UnspentCoinType.lightning;
}
- if (FeatureFlag.hasNewUiExtraPages && widget.dashboardViewModel.type == WalletType.bitcoin) {
+ if (widget.dashboardViewModel.type == WalletType.bitcoin) {
final page = getIt.get<NewSendPage>(
param1: SendPageParams(
initialPaymentRequest: paymentRequest,
### 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,15 +94,13 @@ 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';
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<dynamic> createRoute(RouteSettings settings) {
case Routes.receiveAddresses:
return handleRouteWithPlatformAwareness(
- (context) => getIt.get<NewAddressesPage>(param1: settings.arguments as bool));
+ (context) => getIt.get<NewAddressesPage>(param1: AddressesPageArgs(showHidden:settings.arguments as bool)));
case Routes.seed:
return handleRouteWithPlatformAwareness(
@@ -445,14 +419,11 @@ Route<dynamic> createRoute(RouteSettings settings) {
builder: (_) => getIt.get<WalletRestoreChooseDerivationPage>(
param1: settings.arguments as List<DerivationInfo>));
- case Routes.sweepingWalletPage:
- return CupertinoPageRoute<void>(builder: (_) => getIt.get<SweepingWalletPage>());
case Routes.dashboard:
return CupertinoPageRoute<void>(
settings: settings,
- builder: (_) =>
- FeatureFlag.hasNewUi ? getIt.get<NewDashboard>() : getIt.get<DashboardPage>());
+ builder: (_) => getIt.get<NewDashboard>());
case Routes.send:
final args = settings.arguments as Map<String, dynamic>?;
@@ -472,27 +443,12 @@ Route<dynamic> createRoute(RouteSettings settings) {
settings: settings,
);
- case Routes.sendTemplate:
- return CupertinoPageRoute<void>(
- fullscreenDialog: true, builder: (_) => getIt.get<SendTemplatePage>());
-
- case Routes.receive:
- return CupertinoPageRoute<void>(
- builder: (context) => getIt.get<ReceivePage>(), settings: settings);
-
- case Routes.addressPage:
- return handleRouteWithPlatformAwareness((context) => getIt.get<AddressPage>(),
- settings: settings);
case Routes.newReceivePage:
- if (FeatureFlag.hasNewUi) {
return handleRouteWithPlatformAwareness(
(context) => Material(child: getIt.get<NewReceivePage>(param1: false, param2: null)),
settings: settings,
);
- }
- return handleRouteWithPlatformAwareness((context) => getIt.get<AddressPage>(),
- settings: settings);
case Routes.transactionDetails:
return CupertinoPageRoute<void>(
@@ -505,9 +461,6 @@ Route<dynamic> createRoute(RouteSettings settings) {
fullscreenDialog: true,
builder: (_) => getIt.get<RBFDetailsPage>(param1: settings.arguments as List<dynamic>));
- case Routes.newSubaddress:
- return CupertinoPageRoute<void>(
- builder: (_) => getIt.get<AddressEditOrCreatePage>(param1: settings.arguments));
case Routes.disclaimer:
return CupertinoPageRoute<void>(builder: (_) => DisclaimerPage());
@@ -625,9 +578,6 @@ Route<dynamic> createRoute(RouteSettings settings) {
(context) => getIt.get<PrivacyPage>(),
);
- case Routes.trocadorProvidersPage:
- return CupertinoPageRoute<void>(
- fullscreenDialog: true, builder: (_) => getIt.get<TrocadorProvidersPage>());
case Routes.domainLookupsPage:
return CupertinoPageRoute<void>(
@@ -667,23 +617,13 @@ Route<dynamic> createRoute(RouteSettings settings) {
param1: args?['editingNode'] as Node?, param2: args?['isSelected'] as bool?);
return CupertinoPageRoute<void>(builder: (_) => page);
- case Routes.accountCreation:
- return CupertinoPageRoute<String>(
- builder: (_) => getIt.get<MoneroAccountEditOrCreatePage>(
- param1: settings.arguments as AccountListItem?));
-
case Routes.accountCustomizer:
return handleRouteWithPlatformAwareness(
(_) => getIt.get<AccountCustomizer>(
param1: settings.arguments! as DashboardViewModel,
),
);
- case Routes.nanoAccountCreation:
- return CupertinoPageRoute<String>(
- builder: (_) =>
- getIt.get<NanoAccountEditOrCreatePage>(param1: settings.arguments as NanoAccount?));
-
case Routes.addressBook:
return handleRouteWithPlatformAwareness(
(context) => getIt.get<ContactListPage>(),
@@ -695,7 +635,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
builder: (_) => getIt.get<ContactListPage>(param1: args[0], param2: args[1]));
case Routes.pickerWalletAddress:
- return MaterialPageRoute<void>(builder: (_) => getIt.get<AddressListPage>());
+ return MaterialPageRoute<void>(builder: (_) => getIt.get<NewAddressesPage>(param1: AddressesPageArgs(showHidden: false, popOnSelection: true)));
case Routes.addressBookAddContact:
return handleRouteWithPlatformAwareness(
@@ -712,12 +652,6 @@ Route<dynamic> createRoute(RouteSettings settings) {
(context) => getIt.get<ShowKeysDisclaimerPage>(),
);
- case Routes.exchangeTrade:
- return CupertinoPageRoute<void>(builder: (_) => getIt.get<ExchangeTradePage>());
-
- case Routes.exchangeConfirm:
- return MaterialPageRoute<void>(builder: (_) => getIt.get<ExchangeConfirmPage>());
-
case Routes.tradeDetails:
return CupertinoPageRoute<void>(
fullscreenDialog: true,
@@ -732,46 +666,26 @@ Route<dynamic> createRoute(RouteSettings settings) {
(context) => Material(child: getIt.get<NewBuySellAmountPage>(param1: BuySellPageMode.buy)),
);
- case Routes.buyOptionsPage:
- final args = settings.arguments as List;
- return MaterialPageRoute<void>(builder: (_) => getIt.get<BuyOptionsPage>(param1: args));
-
- case Routes.paymentMethodOptionsPage:
- final args = settings.arguments as List;
- return MaterialPageRoute<void>(
- builder: (_) => getIt.get<PaymentMethodOptionsPage>(param1: args));
-
- case Routes.buyWebView:
- final args = settings.arguments as List;
- return MaterialPageRoute<void>(
- fullscreenDialog: true, builder: (_) => getIt.get<BuyWebViewPage>(param1: args));
case Routes.exchange:
return handleRouteWithPlatformAwareness(
- (context) => getIt.get<ExchangePage>(param1: settings.arguments as PaymentRequest?),
+ (context) => Material(
+ child: getIt.get<NewSwapPage>(param1: settings.arguments as PaymentRequest?)),
+ settings: settings,
);
- case Routes.exchangeTemplate:
- return CupertinoPageRoute<void>(builder: (_) => getIt.get<ExchangeTemplatePage>());
-
case Routes.rescan:
final page = getIt.get<RescanPage>();
return MaterialPageRoute<void>(builder: (_) => page);
- case Routes.faq:
- return MaterialPageRoute<void>(builder: (_) => getIt.get<FaqPage>());
case Routes.preSeedPage:
return MaterialPageRoute<void>(builder: (_) => getIt.get<PreSeedPage>());
case Routes.walletGroupExistingSeedDescriptionPage:
return MaterialPageRoute<void>(builder: (_) => WalletGroupExistingSeedDescriptionPage());
- case Routes.transactionSuccessPage:
- return MaterialPageRoute<void>(
- builder: (_) => getIt.get<TransactionSuccessPage>(param1: settings.arguments as String));
-
case Routes.backup:
return handleRouteWithPlatformAwareness(
(context) => getIt.get<BackupPage>(),
@@ -845,13 +759,6 @@ Route<dynamic> createRoute(RouteSettings settings) {
(context) => getIt.get<CakePayAccountPage>(),
);
- case Routes.webViewPage:
- final args = settings.arguments as List;
- final title = args.first as String;
- final url = args[1] as Uri;
- return CupertinoPageRoute<void>(
- builder: (_) => getIt.get<WebViewPage>(param1: title, param2: url));
-
case Routes.advancedPrivacySettings:
final args = settings.arguments as Map<String, dynamic>;
final type = args['type'] as WalletType;
@@ -879,15 +786,6 @@ Route<dynamic> createRoute(RouteSettings settings) {
),
);
- case Routes.anonPayInvoicePage:
- final args = settings.arguments as List;
- return CupertinoPageRoute<void>(builder: (_) => getIt.get<AnonPayInvoicePage>(param1: args));
-
- case Routes.anonPayReceivePage:
- final anonReceivePageArgs = settings.arguments as AnonPayReceivePageArgs;
- return CupertinoPageRoute<void>(
- builder: (_) => getIt.get<AnonPayReceivePage>(param1: anonReceivePageArgs));
-
case Routes.anonPayDetailsPage:
final anonInvoiceViewData = settings.arguments as AnonpayInvoiceInfo;
return CupertinoPageRoute<void>(
@@ -901,24 +799,9 @@ Route<dynamic> createRoute(RouteSettings settings) {
builder: (_) =>
getIt.get<PayjoinDetailsPage>(param1: sessionId, param2: transactionInfo));
- case Routes.desktop_actions:
- return PageRouteBuilder(
- opaque: false,
- pageBuilder: (_, __, ___) => DesktopDashboardActions(getIt<DashboardViewModel>()),
- );
-
- case Routes.desktop_settings_page:
- return CupertinoPageRoute<void>(builder: (_) => getIt.get<DesktopSettingsPage>());
-
case Routes.empty_no_route:
return MaterialPageRoute<void>(builder: (_) => SizedBox.shrink());
- case Routes.transactionsPage:
- return CupertinoPageRoute<void>(
- settings: settings,
- fullscreenDialog: true,
- builder: (_) => getIt.get<TransactionsPage>());
-
case Routes.setup_2faPage:
return MaterialPageRoute<void>(builder: (_) => getIt.get<Setup2FAPage>());
@@ -1032,11 +915,6 @@ Route<dynamic> createRoute(RouteSettings settings) {
builder: (_) => getIt.get<SeedVerificationPage>(param1: settings.arguments as bool),
);
- case Routes.exchangeTradeExternalSendPage:
- return MaterialPageRoute<void>(
- builder: (_) => getIt.get<ExchangeTradeExternalSendPage>(),
- );
-
case Routes.backgroundSync:
return handleRouteWithPlatformAwareness(
(context) => getIt.get<BackgroundSyncPage>(),
### lib/src/screens/buy/buy_sell_options_page.dart
@@ -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<SelectableItem> 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;
-}
### lib/src/screens/buy/buy_sell_page.dart
@@ -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<ExchangeCardState>();
- final fiatCurrencyKey = GlobalKey<ExchangeCardState>();
- final _formKey = GlobalKey<FormState>();
- 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<ExchangeCardState> 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<ExchangeCardState> 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<String> 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] ?? ''
- : '';
- }
-}
### lib/src/screens/buy/buy_webview_page.dart
@@ -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<BuyWebViewPageBody> {
- 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);
- }
- });
- }
-}
### lib/src/screens/buy/payment_method_options_page.dart
@@ -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<SelectableItem> 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;
-}
### lib/src/screens/buy/webview_page.dart
@@ -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<WebViewPageBody> {
- 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<SharedPreferences>();
-
- if (sharedPrefs.getBool(PreferencesKey.showCameraConsent) ?? true) {
- final bool userConsent = await showPopUp<bool>(
- 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,
- );
- },
- );
- }
-}
### lib/src/screens/connect_device/debug_device_page.dart
@@ -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<DebugDevicePageBody> {
-// 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<Permission, PermissionStatus> 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 = <LedgerDevice>[];
-// 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<void> reconnectCurrentDevice() async {
-// // await ledger.disconnect(selectedDevice!);
-// // await ledger.connect(selectedDevice!);
-// }
-//
-// Future<void> 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<String> 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<dynamic> 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),
-// );
-// }
-// }
### lib/src/screens/connect_device/widgets/device_tile.dart
@@ -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: <Widget>[
- 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,
- ),
- )
- ],
- ),
- ),
- );
- }
-}
### lib/src/screens/contact/contact_list_page.dart
@@ -459,7 +459,7 @@ class _ContactListBodyState extends State<ContactListBody> {
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,
### lib/src/screens/dashboard/dashboard_page.dart
@@ -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<DashboardPage> createState() => _DashboardPageState();
-}
-
-class _DashboardPageState extends State<DashboardPage> {
- @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<DesktopSidebarWrapper>();
- } else {
- dashboardChild = dashboardPageView;
- }
- } else if (responsiveLayoutUtil.shouldRenderMobileUI) {
- dashboardChild = dashboardPageView;
- } else {
- dashboardChild = getIt.get<DesktopSidebarWrapper>();
- }
-
- 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<Widget> pages = ObservableList<Widget>();
- 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: <Widget>[
- 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: <Widget>[
- IgnorePointer(
- child: Container(
- alignment: Alignment.bottomCenter,
- height: 220,
- decoration: BoxDecoration(
- gradient: LinearGradient(
- begin: Alignment.topCenter,
- end: Alignment.bottomCenter,
- colors: <Color>[
- 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<CakeFeaturesViewModel>(),
- ),
- ),
- );
- }
- 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<void>.delayed(Duration(milliseconds: 500)).then(
- (_) {
- showPopUp<void>(
- 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<void>.delayed(
- Duration(seconds: 1),
- () {
- showPopUp<void>(
- 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<String> affectedWalletNames = await dashboardViewModel.checkAffectedWallets();
-
- if (affectedWalletNames.isNotEmpty) {
- Future<void>.delayed(
- Duration(seconds: 1),
- () {
- showPopUp<void>(
- context: context,
- builder: (BuildContext context) {
- return VulnerableSeedsPopup(affectedWalletNames);
- },
- );
- },
- );
- }
- }
-
- void _showHavenPopup(BuildContext context) async {
- final List<String> havenWalletList = await dashboardViewModel.checkForHavenWallets();
-
- if (havenWalletList.isNotEmpty) {
- Future<void>.delayed(
- Duration(seconds: 1),
- () {
- showPopUp<void>(
- context: context,
- builder: (BuildContext context) {
- return HavenWalletRemovalPopup(havenWalletList);
- },
- );
- },
- );
- }
- }
-}
### lib/src/screens/dashboard/desktop_dashboard_page.dart
@@ -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<NavigatorState> desktopKey;
-
- bool _isEffectsInstalled = false;
- StreamSubscription<bool>? _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<void>.delayed(Duration(milliseconds: 500)).then((_) {
- showPopUp<void>(
- 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<void>.delayed(Duration(seconds: 1));
- await showPopUp<void>(
- 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<String> affectedWalletNames = await dashboardViewModel.checkAffectedWallets();
-
- if (affectedWalletNames.isNotEmpty) {
- Future<void>.delayed(
- Duration(seconds: 1),
- () {
- showPopUp<void>(
- context: context,
- builder: (BuildContext context) {
- return VulnerableSeedsPopup(affectedWalletNames);
- },
- );
- },
- );
- }
- }
-}
### lib/src/screens/dashboard/desktop_widgets/desktop_action_button.dart
@@ -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,
- )
- ],
- ),
- ),
- ),
- ),
- ),
- );
- }
-}
### lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart
@@ -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<CakeFeaturesViewModel>(),
- ),
- ),
- ],
- );
- }),
- );
- }
-}
### lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_navbar.dart
@@ -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<ThemeStore>().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;
-}
### lib/src/screens/dashboard/desktop_widgets/desktop_sidebar/side_menu.dart
@@ -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<SideMenuItem> topItems;
- final List<SideMenuItem> 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),
- ],
- ),
- );
- }
-}
### lib/src/screens/dashboard/desktop_widgets/desktop_sidebar/side_menu_item.dart
@@ -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),
- );
- }
-}
### lib/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart
@@ -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<NavigatorState> 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<DesktopWalletSelectionDropDown>(),
- ),
- 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<SidebarItem>((_) => desktopSidebarViewModel.currentPage, (page) {
- if (page == SidebarItem.dashboard) {
- pageController.jumpToPage(0);
- return;
- }
- pageController.jumpToPage(page.index - 1);
- });
- }
-}
### lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart
@@ -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<DesktopWalletSelectionDropDown> createState() => _DesktopWalletSelectionDropDownState();
-}
-
-class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionDropDown> {
- 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<void>? _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<DesktopDropdownItem>(
- items: dropDownItems
- .map(
- (wallet) => DropdownMenuItem<DesktopDropdownItem>(
- 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<bool>(
- 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<void> _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<void>(text, context, duration: null)..show(context);
- }
-
- void hideProgressText() {
- _progressBar?.dismiss();
- _progressBar = null;
- }
-}
### lib/src/screens/dashboard/desktop_widgets/dropdown_item_widget.dart
@@ -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: <Widget>[
- image,
- SizedBox(width: 10),
- Flexible(
- child: Text(
- title,
- style: Theme.of(context).textTheme.bodyMedium,
- overflow: TextOverflow.ellipsis,
- maxLines: 1,
- ),
- )
- ],
- ),
- );
- }
-}
### lib/src/screens/dashboard/pages/address_page.dart
@@ -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<FormState>(),
- _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<FormState> _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: <Widget>[
- 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<SharedPreferences>();
- 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;
- }
-}
### lib/src/screens/dashboard/pages/balance/balance_page.dart
@@ -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<bool>(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)
- ],
- ),
- ),
- ],
- ),
- );
- },
- );
- }
-}
### lib/src/screens/dashboard/pages/balance/balance_row_widget.dart
@@ -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<void> 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<void> 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<void>(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 (_) {}
- }
-}
### lib/src/screens/dashboard/pages/balance/crypto_balance_widget.dart
@@ -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<void> _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<void>(
- 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<void>(
- 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<void> _enableMweb(BuildContext context) async {
- if (!dashboardViewModel.hasEnabledMwebBefore) {
- await showPopUp<void>(
- 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<void> _dismissMweb(BuildContext context) async {
- await showPopUp<void>(
- 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();
- }
-}
### 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(
### lib/src/screens/dashboard/pages/navigation_dock.dart
@@ -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(),
- ),
- ),
- ),
- ),
- ),
- ),
- );
- },
- ),
- );
- }
-}
### lib/src/screens/dashboard/pages/transactions_page.dart
@@ -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: <Widget>[
- 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<CsvExportService>().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<String> 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,
- ),
- ),
- );
- },
- ),
- ),
- ],
- ),
- ),
- );
- }
-}
### lib/src/screens/dashboard/widgets/action_button.dart
@@ -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: <Widget>[
- 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,
- ),
- ),
- ),
- ],
- ),
- ),
- ),
- );
- }
-}
### lib/src/screens/dashboard/widgets/home_screen_account_widget.dart
@@ -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<void>(context: context, builder: (_) => getIt.get<MoneroAccountListPage>());
- },
- 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,
- ),
- ),
- ],
- ),
- ],
- ),
- ],
- ),
- ),
- );
- }
-}
### lib/src/screens/dashboard/widgets/info_card.dart
@@ -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,
- ),
- ),
- );
- }
-}
### lib/src/screens/dashboard/widgets/page_indicator.dart
@@ -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<PageIndicator> createState() => _PageIndicatorState();
-}
-
-class _PageIndicatorState extends State<PageIndicator> {
- 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<double> 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<Color?>(
- 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<Color?>(
- 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,
- ),
- );
- }
-}
### lib/src/screens/dashboard/widgets/present_receive_option_picker.dart
@@ -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: <Widget>[
- Column(
- crossAxisAlignment: CrossAxisAlignment.center,
- mainAxisSize: MainAxisSize.min,
- children: <Widget>[
- 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<void>(
- 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,
- );
- }
-}
### lib/src/screens/dashboard/widgets/sync_indicator.dart
@@ -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: <Widget>[
- 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: <Widget>[
- 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,
- ),
- ),
- )
- ],
- ),
- )
- ],
- ),
- ),
- ));
- });
- }
-}
### lib/src/screens/exchange/exchange_page.dart
@@ -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<ExchangeCardState>();
- final receiveKey = GlobalKey<ExchangeCardState>();
- final _formKey = GlobalKey<FormState>();
- 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: <Widget>[
- _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: <Widget>[
- 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<void>(
- 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: <Widget>[
- 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<void>(
- 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<void>(
- 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<ExchangeCardState> 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<ExchangeCardState> 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<String> 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<void>.delayed(Duration(seconds: 1));
- final confirmed = await showPopUp<bool>(
- 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,
- );
- }
-}
### lib/src/screens/exchange/exchange_template_page.dart
@@ -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<ExchangeCardState>();
- final receiveKey = GlobalKey<ExchangeCardState>();
- final _formKey = GlobalKey<FormState>();
- 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: <Widget>[
- 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: <Widget>[
- 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<ExchangeCardState> 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<ExchangeCardState> 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 = '';
- }
- }
-}
### lib/src/screens/exchange/widgets/currency_picker_item_widget.dart
@@ -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,
- ),
- ],
- ),
- ),
- ),
- );
- }
-}
### lib/src/screens/exchange/widgets/currency_picker_widget.dart
@@ -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<Currency> 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,
- );
- }),
- ),
- );
- }
-}
### lib/src/screens/exchange_trade/exchange_confirm_page.dart
@@ -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: <Widget>[
- Expanded(
- child: Column(
- children: <Widget>[
- 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: <Widget>[
- Expanded(
- child: Padding(
- padding: EdgeInsets.all(24),
- child: Column(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- crossAxisAlignment: CrossAxisAlignment.center,
- children: <Widget>[
- 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<void>(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,
- )
- ],
- ),
- );
- }
-}
### lib/src/screens/exchange_trade/exchange_trade_external_send_page.dart
@@ -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: <Widget>[
- 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: <Widget>[
- Row(
- children: <Widget>[
- 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();
- },
- ),
- ),
- );
- }
-}
### lib/src/screens/exchange_trade/exchange_trade_page.dart
@@ -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<void>(
- 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<ExchangeTradeForm> {
- 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: <Widget>[
- trade.expiredAt != null
- ? Row(
- mainAxisSize: MainAxisSize.max,
- mainAxisAlignment: MainAxisAlignment.center,
- children: <Widget>[
- 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<void> _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<void>(
- 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<void>(
- 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<bool>(
- 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<void>(
- 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,
- );
- }
-}
### lib/src/screens/exchange_trade/information_page.dart
@@ -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: <Widget>[
- 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,
- ),
- )
- ],
- ),
- ),
- ));
- }
-}
### lib/src/screens/exchange_trade/widgets/exchange_trade_card_item_widget.dart
@@ -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: <Widget>[
- 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<void> 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<void>(
- 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<bool>(
- 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<void>(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: <Widget>[
- 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: <Widget>[
- 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,
- ),
- ],
- ),
- ),
- );
- }
-}
### lib/src/screens/exchange_trade/widgets/timer_widget.dart
@@ -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<TimerWidget> {
- 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;
- }
-}
### lib/src/screens/faq/faq_page.dart
@@ -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: <Widget>[
- 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),
- ),
- );
- }
-}
### lib/src/screens/monero_accounts/monero_account_edit_or_create_page.dart
@@ -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<FormState>(),
- _textController = TextEditingController() {
- _textController.addListener(() => moneroAccountCreationViewModel.label = _textController.text);
- _textController.text = moneroAccountCreationViewModel.label;
- }
-
- final MoneroAccountEditOrCreateViewModel moneroAccountCreationViewModel;
-
- @override
- String get title => S.current.account;
-
- final GlobalKey<FormState> _formKey;
- final TextEditingController _textController;
-
- @override
- Widget body(BuildContext context) => Form(
- key: _formKey,
- child: Container(
- padding: EdgeInsets.all(24.0),
- child: Column(
- children: <Widget>[
- 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,
- ),
- )
- ],
- ),
- ),
- );
-}
### lib/src/screens/monero_accounts/monero_account_list_page.dart
@@ -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: <Widget>[
- 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,
- ),
- ),
- )
- ],
- ),
- ),
- ),
- )
- ],
- );
- });
- }
-}
### lib/src/screens/monero_accounts/widgets/account_tile.dart
@@ -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,
- ),
- ],
- );
-}
### lib/src/screens/nano_accounts/nano_account_edit_or_create_page.dart
@@ -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<FormState>(),
- _textController = TextEditingController() {
- _textController.addListener(() => nanoAccountCreationViewModel.label = _textController.text);
- _textController.text = nanoAccountCreationViewModel.label;
- }
-
- final NanoAccountEditOrCreateViewModel nanoAccountCreationViewModel;
-
- @override
- String get title => S.current.account;
-
- final GlobalKey<FormState> _formKey;
- final TextEditingController _textController;
-
- @override
- Widget body(BuildContext context) => Form(
- key: _formKey,
- child: Container(
- padding: EdgeInsets.all(24.0),
- child: Column(
- children: <Widget>[
- 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,
- ),
- ),
- ],
- ),
- ),
- );
-}
### lib/src/screens/nano_accounts/nano_account_list_page.dart
@@ -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: <Widget>[
- 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,
- ),
- ),
- )
- ],
- ),
- ),
- ),
- )
- ],
- );
- });
- }
-}
### lib/src/screens/nano_accounts/widgets/account_tile.dart
@@ -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,
- ),
- ],
- );
-}
### lib/src/screens/nodes/widgets/node_indicator.dart
@@ -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,
- ),
- );
- }
-}
### lib/src/screens/receive/address_list_page.dart
@@ -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: <Widget>[
- AddressList(
- addressListViewModel: addressListViewModel,
- onSelect: (String address) async {
- Navigator.of(context).pop(address);
- },
- ),
- ],
- ),
- ),
- ),
- ],
- );
- }
-}
### lib/src/screens/receive/anonpay_invoice_page.dart
@@ -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<FormState>();
-
- 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<bool> _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: <Widget>[
- 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<SharedPreferences>();
- 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<void>(
- 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;
- }
-}
### lib/src/screens/receive/anonpay_receive_page.dart
@@ -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: <Widget>[
- 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),
- ],
- ),
- );
- }
-}
### lib/src/screens/receive/receive_page.dart
@@ -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<FormState>() {
- _amountController.addListener(() {
- if (_formKey.currentState!.validate()) {
- addressListViewModel.changeAmount(_amountController.text);
- }
- });
- }
-
- final WalletAddressListViewModel addressListViewModel;
- final TextEditingController _amountController;
- final GlobalKey<FormState> _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: <Widget>[
- 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,
- ),
- ),
- ),
- ],
- ),
- ),
- );
-}
### lib/src/screens/receive/widgets/address_cell.dart
@@ -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,
- ),
- ],
- );
-}
### lib/src/screens/receive/widgets/address_list.dart
@@ -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<AddressList> createState() => _AddressListState();
-}
-
-class _AddressListState extends State<AddressList> {
- bool showHiddenAddresses = false;
-
- void _toggleHiddenAddresses() {
- setState(() {
- showHiddenAddresses = !showHiddenAddresses;
- });
- updateItems();
- }
-
- List<ListItem> getItems(List<ListItem> 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<ListItem> 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<void>(
- context: context,
- builder: (_) => getIt.get<MoneroAccountListPage>(),
- );
- updateItems();
- } else {
- await showPopUp<void>(
- context: context,
- builder: (_) => getIt.get<NanoAccountListPage>(),
- );
- 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();
- }
-}
### lib/src/screens/receive/widgets/anonpay_currency_input_field.dart
@@ -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: <Widget>[
- 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: <Widget>[
- 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,
- ),
- ),
- ],
- ),
- ),
- ],
- );
- }
-}
### lib/src/screens/receive/widgets/anonpay_input_form.dart
@@ -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<FormState> formKey;
- final bool isInvoice;
-
- @override
- Widget build(BuildContext context) {
- return Form(
- key: formKey,
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: <Widget>[
- 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<void>(
- builder: (_) => CurrencyPicker(
- selectedAtIndex: anonInvoicePageViewModel.selectedCurrencyIndex,
- items: anonInvoicePageViewModel.currencies,
- hintText: S.of(context).search_currency,
- onItemSelected: anonInvoicePageViewModel.selectCurrency,
- ),
- context: context,
- );
- }
-}
### lib/src/screens/receive/widgets/anonpay_status_section.dart
@@ -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,
- ),
- ),
- ],
- ),
- ],
- ),
- );
- }
-}
### lib/src/screens/receive/widgets/copy_link_item.dart
@@ -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<void>(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,
- ),
- )
- ],
- )
- ],
- );
- }
-}
### lib/src/screens/receive/widgets/header_tile.dart
@@ -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<HeaderTile> {
- 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: <Widget>[
- _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,
- ),
- ),
- ],
- ),
- ],
- ),
- );
- }
-}
### lib/src/screens/receive/widgets/qr_widget.dart
@@ -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<FormState> 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: <Widget>[
- Column(
- children: [
- Row(
- children: <Widget>[
- 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: <Widget>[
- 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<void>(context, S.of(context).copied_to_clipboard);
- },
- child: Row(
- mainAxisSize: MainAxisSize.max,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: <Widget>[
- 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<void>(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<void>(
- 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(),
- ),
- );
- }
-}
### lib/src/screens/release_notes/release_notes_screen.dart
@@ -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<List<String>> _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: <Widget>[
- ConstrainedBox(
- constraints: BoxConstraints(
- maxHeight: MediaQuery.of(context).size.height * 0.7,
- ),
- child: _getNotesWidget(),
- )
- ],
- ),
- ),
- ),
- ),
- ],
- ),
- ),
- ),
- ),
- ),
- AlertCloseButton(
- bottom: 30,
- )
- ],
- );
- }
-
- Widget _getNotesWidget() {
- return FutureBuilder<List<String>>(
- future: _loadStrings(),
- builder: (BuildContext context, AsyncSnapshot<List<String>> 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,
- )
- ],
- );
- }
-}
### lib/src/screens/restore/sweeping_wallet_page.dart
@@ -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<SweepingWalletWidget> createState() => _SweepingWalletWidgetState();
-}
-
-class _SweepingWalletWidgetState extends State<SweepingWalletWidget> {
- @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: <Widget>[
- 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: <Widget>[
- Column(
- children: <Widget>[
- 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,
- ),
- ),
- ],
- ),
- ],
- ))
- ],
- )));
- }
-}
### lib/src/screens/send/send_page.dart
@@ -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<FormState>();
-
- final SendViewModel sendViewModel;
- final PaymentViewModel paymentViewModel;
- final WalletSwitcherViewModel walletSwitcherViewModel;
- final AuthService authService;
- final GlobalKey<FormState> _formKey;
- final controller = PageController(initialPage: 0);
- final PaymentRequest? initialPaymentRequest;
- final FocusNode _cryptoAmountFocus = FocusNode();
- final FocusNode _fiatAmountFocus = FocusNode();
-
- final currentPage = ValueNotifier<int>(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<Widget> sendCards = [];
- List<KeyboardActionsItem> 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: <Widget>[
- 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: <Widget>[
- 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<void>(
- 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<void>(
- 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<void>(
- 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<bool>(
- 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<void>(
- 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<void>(
- 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<void>(
- 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<void> _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<void>(
- 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;
- }
-}
### lib/src/screens/send/send_template_page.dart
@@ -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<FormState>();
- 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];
- }
-}
### lib/src/screens/send/transaction_success_info_page.dart
@@ -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();
- };
-}
### lib/src/screens/send/widgets/choose_yat_address_alert.dart
@@ -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<String> 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<String> addresses;
-
- @override
- ChooseYatAddressButtonsState createState() => ChooseYatAddressButtonsState(addresses);
-}
-
-class ChooseYatAddressButtonsState extends State<ChooseYatAddressButtons> {
- ChooseYatAddressButtonsState(this.addresses) : itemCount = addresses?.length ?? 0;
-
- final List<String> 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<String>(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,
- )
- ],
- );
- }
-}
### lib/src/screens/send/widgets/send_card.dart
@@ -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<SendCard> with AutomaticKeepAliveClientMixin<SendCard> {
- 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<void> _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<void> _showPaymentConfirmation(
- PaymentViewModel paymentViewModel,
- WalletSwitcherViewModel walletSwitcherViewModel,
- PaymentRequest paymentRequest,
- PaymentFlowResult result,
- ) async {
- if (!context.mounted) {
- return;
- }
-
- await showModalBottomSheet<void>(
- 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<void> _showTokenSelectionFlow(
- PaymentViewModel paymentViewModel,
- WalletSwitcherViewModel walletSwitcherViewModel,
- PaymentRequest paymentRequest, {
- WalletType? fixedNetwork,
- }) async {
- if (!context.mounted) {
- return;
- }
-
- await showModalBottomSheet<void>(
- 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<void> _handleSelectWallet(
- PaymentViewModel paymentViewModel,
- WalletSwitcherViewModel walletSwitcherViewModel,
- PaymentRequest paymentRequest,
- PaymentFlowResult result,
- ) async {
- Navigator.of(context).pop();
-
- await showModalBottomSheet<WalletInfo>(
- 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<AppStore>();
- 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<void> _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<void>(
- 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<AppStore>();
- 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<void>(
- 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<AppStore>();
- 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<void> _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<void>(
- 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<void> _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<SwapConfirmationBottomSheet>(param1: result);
- await showModalBottomSheet<Trade?>(
- 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<KeyboardTheme>()!.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: <Widget>[
- 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: <Widget>[
- 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<String>(
- 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: <Widget>[
- Text(
- S.of(context).send_estimated_fee,
- style: Theme.of(context).textTheme.bodySmall!.copyWith(
- fontWeight: FontWeight.w700,
- ),
- ),
- Container(
- child: Row(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: <Widget>[
- 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<void> 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<void>(
- 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<void>(
- 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;
-}
### lib/src/screens/send/widgets/send_template_card.dart
@@ -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: <Widget>[
- Padding(
- padding: EdgeInsets.fromLTRB(24, 90, 24, 32),
- child: Column(
- children: <Widget>[
- 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<void>(
- 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),
- ),
- );
- }
-}
### lib/src/screens/settings/attributes.dart
@@ -1 +0,0 @@
-enum Attributes { arrow, header, link, switcher, widget, rawWidget }
### lib/src/screens/settings/desktop_settings/desktop_settings_page.dart
@@ -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<NavigatorState>();
-
-class DesktopSettingsPage extends StatefulWidget {
- const DesktopSettingsPage(this.dashboardViewModel, {super.key});
-
- final DashboardViewModel dashboardViewModel;
-
- @override
- State<DesktopSettingsPage> createState() => _DesktopSettingsPageState();
-}
-
-class _DesktopSettingsPageState extends State<DesktopSettingsPage> {
- 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))!
- ];
- },
- ),
- ),
- )
- ],
- ),
- ),
- );
- }
-}
### lib/src/screens/settings/items/item_headers.dart
@@ -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';
-}
### lib/src/screens/settings/items/settings_item.dart
@@ -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;
-}
### 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,
### lib/src/screens/settings/trocador_providers_page.dart
@@ -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,
- ),
- ),
- ],
- ),
- ),
- ),
- ),
- );
- }
-}
### lib/src/screens/settings/widgets/setting_priority_picker_cell.dart
@@ -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<ItemType> 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<void>(
- 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<ItemType> items;
- final void Function(ItemType item, double customValue)? onItemSelected;
- final String Function(ItemType item, int value)? displayItem;
- final List<Image>? 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,
- ),
- );
- }
-}
### lib/src/screens/settings/widgets/settings_picker_row.dart
@@ -1,9 +0,0 @@
-import 'package:flutter/cupertino.dart';
-
-class SettingsPickerRaw extends StatelessWidget {
- @override
- Widget build(BuildContext context) {
- // TODO: implement build
- throw UnimplementedError();
- }
-}
### lib/src/screens/settings/widgets/settings_version_cell.dart
@@ -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: <Widget>[
- Text(
- title,
- style: Theme.of(context).textTheme.bodySmall!.copyWith(
- fontWeight: FontWeight.normal,
- color: Theme.of(context).colorScheme.onSurfaceVariant,
- ),
- )
- ],
- ),
- );
- }
-}
### lib/src/screens/settings/widgets/wallet_connect_button.dart
@@ -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: <Widget>[
- 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,
- )
- ],
- ),
- ),
- );
- }
-}
### lib/src/screens/splash/splash_page.dart
@@ -1,8 +0,0 @@
-import 'package:flutter/material.dart';
-
-class SplashPage extends StatelessWidget {
- @override
- Widget build(BuildContext context) {
- return Scaffold(body: Container());
- }
-}
### lib/src/screens/subaddress/address_edit_or_create_page.dart
@@ -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<FormState>(),
- _labelController = TextEditingController(),
- super() {
- _labelController.addListener(() => addressEditOrCreateViewModel.label = _labelController.text);
- _labelController.text = addressEditOrCreateViewModel.label;
- }
-
- final WalletAddressEditOrCreateViewModel addressEditOrCreateViewModel;
- final GlobalKey<FormState> _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: <Widget>[
- 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;
- }
-}
### 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;
### lib/src/screens/unspent_coins/unspent_coins_list_page.dart
@@ -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<void> 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<void> Function(BuildContext context) handleOnPopInvoked;
-
- @override
- UnspentCoinsListFormState createState() => UnspentCoinsListFormState(unspentCoinsListViewModel);
-}
-
-class UnspentCoinsListFormState extends State<UnspentCoinsListForm> {
- UnspentCoinsListFormState(this.unspentCoinsListViewModel);
-
- final UnspentCoinsListViewModel unspentCoinsListViewModel;
-
- late Future<void> _initialization;
- ReactionDisposer? _disposer;
-
- @override
- void initState() {
- super.initState();
- _initialization = unspentCoinsListViewModel.initialSetup();
- _setupReactions();
- }
-
- void _setupReactions() {
- _disposer = reaction<bool>(
- (_) => unspentCoinsListViewModel.isDisposing,
- (isDisposing) {
- if (isDisposing) {
- _showSavingDataAlert();
- }
- },
- );
- }
-
- void _showSavingDataAlert() {
- showDialog<void>(
- 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<void>(
- 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);
- },
- ),
- );
- });
- },
- ),
- ),
- ],
- ),
- ),
- );
- },
- ),
- );
- }
-}
### lib/src/screens/unspent_coins/widgets/unspent_coins_list_item.dart
@@ -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,
- ),
- ),
- ),
- ],
- ),
- ],
- ),
- ),
- ],
- ),
- ),
- ],
- ),
- );
- }
-}
### lib/src/screens/wallet_list/wallet_list_page.dart
@@ -339,45 +339,26 @@ class WalletListBodyState extends State<WalletListBody> {
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: <Color>[
- 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: <Color>[
- 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: <Color>[
+ 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<WalletListBody> {
color: Theme.of(context).colorScheme.primary,
textColor: Theme.of(context).colorScheme.onPrimary,
),
- if (FeatureFlag.hasNewUi) SizedBox(height: 52.0)
+ SizedBox(height: 52.0)
],
),
),
### lib/src/screens/yat/widgets/first_introduction.dart
@@ -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))
- ]),
- ));
- }
-}
### lib/src/screens/yat/widgets/second_introduction.dart
@@ -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))
- ]),
- ));
- }
-}
### lib/src/screens/yat/widgets/third_introduction.dart
@@ -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),
- )
- ],
- ),
- ),
- );
- }
-}
### lib/src/screens/yat/widgets/yat_bar.dart
@@ -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)
- ]);
- }
-}
### lib/src/screens/yat/widgets/yat_close_button.dart
@@ -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,
- ),
- ),
- );
- }
-}
### lib/src/screens/yat/widgets/yat_page_indicator.dart
@@ -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)));
- })));
- }
-}
### lib/src/screens/yat/yat_popup.dart
@@ -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())
- ],
- );
- }
-}
### lib/src/screens/yat_emoji_id.dart
@@ -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())
- ],
- ))),
- )
- ],
- );
- }
-}
### lib/src/widgets/adaptable_page_view.dart
@@ -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<Widget> children;
-
- @override
- State<PageViewHeightAdaptable> createState() => _PageViewHeightAdaptableState();
-}
-
-class _PageViewHeightAdaptableState extends State<PageViewHeightAdaptable> {
- final _sizes = <int, Size>{};
-
- @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<int, Size> 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<int, Size> sizes,
- required double page,
- }) : _sizes = sizes,
- _page = page,
- super(child);
-
- Map<int, Size> _sizes;
- Map<int, Size> get sizes => _sizes;
- set sizes(Map<int, Size> 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),
- ),
- );
- }
-}
### lib/src/widgets/add_template_button.dart
@@ -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,
- ),
- ),
- ),
- ),
- ),
- );
- }
-}
### lib/src/widgets/alert_with_no_action.dart.dart
@@ -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();
-}
### lib/src/widgets/alert_with_picker_option.dart
@@ -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<Map<String, String>> options;
- final ValueChanged<Map<String, String>>? 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,
- ),
- ],
- ),
- ],
- ),
- ),
- );
- },
- ),
- ),
- ],
- );
- }
-}
### 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))),
### lib/src/widgets/bottom_sheet/payment_confirmation_bottom_sheet.dart
@@ -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),
- ],
- ],
- ),
- );
- },
- );
- }
-}
### lib/src/widgets/bottom_sheet/token_selection_bottom_sheet.dart
@@ -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<CryptoCurrency> 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<void> _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<void>(
- 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<void>(
- 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<void>(
- context: context,
- builder: (BuildContext context) {
- return CurrencyPicker(
- selectedAtIndex: selectedIndex >= 0 ? selectedIndex : 0,
- items: availableTokens.cast<Currency>(),
- 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<void> _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,
- ),
- ],
- ),
- ),
- ),
- );
- }
-}
### lib/src/widgets/bottom_sheet/wallet_switcher_bottom_sheet.dart
@@ -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<WalletInfo> 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,
- ),
- ],
- ),
- ),
- );
- },
- ),
- ),
- ],
- ),
- );
- },
- ),
- );
- }
-}
### lib/src/widgets/cake_scrollbar.dart
@@ -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: <Widget>[
- 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))),
- ),
- )
- ],
- ),
- ));
- }
-}
### lib/src/widgets/discount_badge.dart
@@ -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'),
- ),
- ),
- );
- }
-}
### lib/src/widgets/evm_switcher.dart
@@ -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<ChainInfo> chains;
- final ChainInfo? currentChain;
- final Future<void> Function(int chainId) onChainSelected;
- final Set<int> hiddenChainIds;
- final void Function(Set<int> hiddenChainIds) onHiddenChanged;
-
- static const editModeAnimDuration = Duration(milliseconds: 200);
-
- @override
- State<EvmSwitcher> createState() => _EvmSwitcherState();
-}
-
-class _EvmSwitcherState extends State<EvmSwitcher> {
- bool _editMode = false;
- var optionsEnabled = <bool>[];
-
- @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<int> a, Set<int> 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<int> _currentHiddenChainIds() {
- final hidden = <int>{};
- 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,
- )),
- ],
- ),
- ),
- );
- }
-}
### lib/src/widgets/evm_switcher_row.dart
@@ -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)
- ],
- ),
- ),
- ),
- );
- }
-}
### lib/src/widgets/haven_wallet_removal_popup.dart
@@ -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<String> 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: <Widget>[
- 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)
- ],
- );
- }
-}
### lib/src/widgets/introducing_card.dart
@@ -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,
- ),
- ),
- ),
- ),
- ),
- )
- ],
- ),
- ),
- );
- }
-}
### lib/src/widgets/picker_inner_wrapper_widget.dart
@@ -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<Widget> 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: <Widget>[
- 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: <Widget>[
- 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,
- ),
- ),
- ),
- ),
- )
- ],
- );
- }
-}
### lib/src/widgets/service_status_tile.dart
@@ -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);
- }
-}
### lib/src/widgets/services_updates_widget.dart
@@ -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> servicesResponse;
- final bool enabled;
-
- const ServicesUpdatesWidget(this.servicesResponse, {super.key, required this.enabled});
-
- @override
- State<ServicesUpdatesWidget> createState() => _ServicesUpdatesWidgetState();
-}
-
-class _ServicesUpdatesWidgetState extends State<ServicesUpdatesWidget> {
- bool wasOpened = false;
-
- @override
- Widget build(BuildContext context) {
- if (!widget.enabled) {
- return InkWell(
- onTap: () async {
- await showPopUp<void>(
- 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<ServicesResponse>(
- future: widget.servicesResponse,
- builder: (context, state) {
- return InkWell(
- onTap: state.hasData
- ? () {
- // save currentSha when the user see the status
- getIt
- .get<SharedPreferences>()
- .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,
- ),
- ),
- ],
- ),
- );
- },
- ),
- );
- }
-}
### lib/src/widgets/simple_checkbox.dart
@@ -1,34 +0,0 @@
-import 'package:flutter/material.dart';
-
-class SimpleCheckbox extends StatefulWidget {
- SimpleCheckbox({this.onChanged});
-
- final Function(bool)? onChanged;
-
- @override
- State<SimpleCheckbox> createState() => _SimpleCheckboxState();
-}
-
-class _SimpleCheckboxState extends State<SimpleCheckbox> {
- 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)),
- ),
- );
- }
-}
### lib/src/widgets/tab_view_wrapper_widget.dart
@@ -41,7 +41,6 @@ class _TabViewWrapperState extends State<TabViewWrapper> with SingleTickerProvid
Widget build(BuildContext context) {
final textStyle = TextStyle(
fontSize: 18,
- fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: Theme.of(context).colorScheme.onSurface);
### lib/src/widgets/template_tile.dart
@@ -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<TemplateTile> {
- 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: <Widget>[
- 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;
- }
-}
### lib/store/templates/exchange_template_store.dart
@@ -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<ExchangeTemplate>() {
- templates = ObservableList<ExchangeTemplate>();
- update();
- }
-
- @observable
- ObservableList<ExchangeTemplate> templates;
-
- Box<ExchangeTemplate> templateSource;
-
- @action
- void update() => templates.replaceRange(0, templates.length, templateSource.values.toList());
-
- @action
- Future<void> 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<void> remove({required ExchangeTemplate template}) async => await template.delete();
-}
### lib/store/templates/send_template_store.dart
@@ -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<Template>() {
- update();
- }
-
- @observable
- ObservableList<Template> templates;
-
- Box<Template> templateSource;
-
- @action
- void update() => templates.replaceRange(0, templates.length, templateSource.values.toList());
-
- @action
- Future<void> addTemplate(
- {required String name,
- required bool isCurrencySelected,
- required String address,
- required String cryptoCurrency,
- required String fiatCurrency,
- required String amount,
- required String amountFiat,
- required List<Template> additionalRecipients}) async {
- final template = Template(
- nameRaw: name,
- isCurrencySelectedRaw: isCurrencySelected,
- addressRaw: address,
- cryptoCurrencyRaw: cryptoCurrency,
- fiatCurrencyRaw: fiatCurrency,
- amountRaw: amount,
- amountFiatRaw: amountFiat,
- additionalRecipientsRaw: additionalRecipients);
- await templateSource.add(template);
- }
-
- @action
- Future<void> remove({required Template template}) async => await template.delete();
-}
### lib/typography.dart
@@ -1,7 +1,6 @@
import 'package:cake_wallet/utils/feature_flag.dart';
import 'package:flutter/material.dart';
-const latoFont = "Lato";
const wixFont = "Wix Madefor Text";
TextStyle textXxSmall({Color? color}) => _cakeRegular(10, color);
@@ -56,7 +55,7 @@ TextStyle _textStyle({
Color? color,
}) =>
TextStyle(
- fontFamily: FeatureFlag.hasNewUi ? wixFont : latoFont,
+ fontFamily: wixFont,
fontSize: size,
fontWeight: fontWeight,
color: color ?? Colors.white,
### lib/utils/feature_flag.dart
@@ -17,6 +17,4 @@ class FeatureFlag {
static const bool duressPinEnabled = true;
static const bool isEVMChainSwitcherEnabled = false;
static const bool isAutomaticNodeSwitchingEnabled = false;
- static const bool hasNewUi = true;
- static const bool hasNewUiExtraPages = true;
}
### lib/utils/item_cell.dart
@@ -1,18 +0,0 @@
-import 'package:flutter/foundation.dart';
-import 'package:mobx/mobx.dart';
-import 'package:cake_wallet/utils/mobx.dart';
-import 'package:cw_core/keyable.dart';
-// part 'node_list_view_model.g.dart';
-//
-// class NodeListViewModel = NodeListViewModelBase with _$NodeListViewModel;
-
-class ItemCell<Item> with Keyable {
- ItemCell(this.value, {required this.isSelectedBuilder, required dynamic key}) {
- keyIndex = key;
- }
-
- final Item value;
-
- bool get isSelected => isSelectedBuilder(value);
- bool Function(Item item) isSelectedBuilder;
-}
### lib/utils/list_section.dart
@@ -1,5 +0,0 @@
-class ListSection<Item> {
- const ListSection({required this.items});
-
- final List<Item> items;
-}
### lib/utils/mobx.dart
@@ -3,72 +3,14 @@ import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
import 'package:cw_core/keyable.dart';
-void connectMapToListWithTransform<T extends Keyable, Y extends Keyable>(
- ObservableMap<dynamic, T> source, ObservableList<Y> dest, Y Function(T?) transform,
- {bool Function(T?)? filter}) {
- source.observe((MapChange<dynamic, T> change) {
- if (change.type == null) {
- return;
- }
-
- switch (change.type) {
- case OperationType.add:
- if (filter?.call(change.newValue) ?? true) {
- dest.add(transform(change.newValue));
- }
- break;
- case OperationType.remove:
- // Hive could has equal index and key
- dest.removeWhere((elem) => elem.keyIndex == (change.key ?? change.newValue?.keyIndex));
- break;
- case OperationType.update:
- for (var i = 0; i < dest.length; i++) {
- final item = dest[i];
-
- if (item.keyIndex == change.key) {
- dest[i] = transform(change.newValue);
- }
- }
- break;
- default:
- break;
- }
- });
-}
typedef Filter<T> = bool Function(T);
typedef Transform<T, Y> = Y Function(T);
-enum ChangeType { update, delete, add }
-class EntityChange<T extends Keyable> {
- EntityChange(this.value, this.type, {dynamic key}) : _key = key;
- dynamic get key => _key ?? value.keyIndex;
- final T value;
- final ChangeType type;
- final dynamic _key;
-}
extension MobxBindable<T extends Keyable> on Box<T> {
- StreamSubscription<BoxEvent> bindToList(
- ObservableList<T> dest, {
- bool initialFire = false,
- Filter<T>? filter,
- }) {
- if (initialFire) {
- final res = filter != null ? values.where(filter) : values;
- dest.addAll(res);
- }
-
- return watch().listen((event) {
- if (filter != null && event.value != null && !filter(event.value as T)) {
- return;
- }
-
- dest.acceptBoxChange(event);
- });
- }
StreamSubscription<BoxEvent> bindToListWithTransform<Y extends Keyable>(
ObservableList<Y> dest,
@@ -91,37 +33,7 @@ extension MobxBindable<T extends Keyable> on Box<T> {
}
extension HiveBindable<T extends Keyable> on ObservableList<T> {
- Stream<EntityChange<T>> listen() {
- // ignore: close_sinks
- final controller = StreamController<EntityChange<T>>();
-
- observe((ListChange<T> change) {
- change.elementChanges?.forEach((change) {
- ChangeType type;
-
- switch (change.type) {
- case OperationType.add:
- type = ChangeType.add;
- break;
- case OperationType.remove:
- type = ChangeType.delete;
- break;
- case OperationType.update:
- type = ChangeType.update;
- break;
- }
-
- final value = change.newValue as T;
- controller.add(EntityChange(value, type,
- key: type == ChangeType.delete ? change.index : value.keyIndex));
- });
- });
- return controller.stream;
- }
-
- StreamSubscription<EntityChange<T>> bindToList(ObservableList<T> dest) =>
- listen().listen((event) => dest.acceptEntityChange(event));
void acceptBoxChange(BoxEvent event, {T? transformed}) {
if (event.deleted) {
@@ -145,22 +57,4 @@ extension HiveBindable<T extends Keyable> on ObservableList<T> {
}
}
- void acceptEntityChange(EntityChange<T> event) {
- if (event.type == ChangeType.delete) {
- removeWhere((el) => el.keyIndex == event.key);
- return;
- }
-
- final dynamic value = event.value;
-
- if (value is T) {
- final index = indexWhere((el) => el.keyIndex == value.keyIndex);
-
- if (index > -1) {
- this.setAll(index, [value]); // FIXME: fixme
- } else {
- add(value);
- }
- }
- }
}
### lib/view_model/anon_invoice_page_view_model.dart
@@ -1,208 +0,0 @@
-import 'package:cake_wallet/anonpay/anonpay_api.dart';
-import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart';
-import 'package:cake_wallet/anonpay/anonpay_request.dart';
-import 'package:cake_wallet/core/execution_state.dart';
-import 'package:cake_wallet/entities/fiat_currency.dart';
-import 'package:cake_wallet/entities/preferences_key.dart';
-import 'package:cake_wallet/utils/qr_util.dart';
-import 'package:cw_core/receive_page_option.dart';
-import 'package:cake_wallet/store/settings_store.dart';
-import 'package:cw_core/crypto_currency.dart';
-import 'package:cw_core/currency.dart';
-import 'package:cw_core/wallet_base.dart';
-import 'package:hive/hive.dart';
-import 'package:mobx/mobx.dart';
-import 'package:shared_preferences/shared_preferences.dart';
-
-part 'anon_invoice_page_view_model.g.dart';
-
-class AnonInvoicePageViewModel = AnonInvoicePageViewModelBase with _$AnonInvoicePageViewModel;
-
-abstract class AnonInvoicePageViewModelBase with Store {
- AnonInvoicePageViewModelBase(
- this.anonPayApi,
- this.address,
- this.settingsStore,
- this._wallet,
- this._anonpayInvoiceInfoSource,
- this.sharedPreferences,
- this.pageOption,
- ) : receipientEmail = '',
- receipientName = '',
- description = '',
- amount = '',
- state = InitialExecutionState(),
- selectedCurrency = _wallet.currency,
- cryptoCurrency = _wallet.currency {
- _getPreviousDonationLink();
- _fetchLimits();
- }
-
- List<Currency> get currencies => [_wallet.currency, ...FiatCurrency.all];
- final AnonPayApi anonPayApi;
- final String address;
- final SettingsStore settingsStore;
- final WalletBase _wallet;
- final Box<AnonpayInvoiceInfo> _anonpayInvoiceInfoSource;
- final SharedPreferences sharedPreferences;
- final ReceivePageOption pageOption;
-
- @observable
- Currency selectedCurrency;
-
- CryptoCurrency cryptoCurrency;
-
- @observable
- String receipientEmail;
-
- @observable
- String receipientName;
-
- @observable
- String description;
-
- @observable
- String amount;
-
- @observable
- ExecutionState state;
-
- @computed
- int get selectedCurrencyIndex => currencies.indexOf(selectedCurrency);
-
- @observable
- double? minimum;
-
- @observable
- double? maximum;
-
- @action
- void selectCurrency(Currency currency) {
- selectedCurrency = currency;
- maximum = minimum = null;
- if (currency is CryptoCurrency) {
- cryptoCurrency = currency;
- } else {
- cryptoCurrency = _wallet.currency;
- }
-
- _fetchLimits();
- }
-
- @action
- Future<void> createInvoice() async {
- state = IsExecutingState();
- if (amount.isNotEmpty) {
- final amountInCrypto = double.tryParse(amount);
- if (amountInCrypto == null) {
- state = FailureState('Amount is invalid');
- return;
- }
- if (minimum != null && amountInCrypto < minimum!) {
- state = FailureState('Amount is too small');
- return;
- }
- if (maximum != null && amountInCrypto > maximum!) {
- state = FailureState('Amount is too big');
- return;
- }
- }
- try {
- final result = await anonPayApi.createInvoice(AnonPayRequest(
- cryptoCurrency: cryptoCurrency,
- address: address,
- amount: amount.isEmpty ? null : amount,
- description: description,
- email: receipientEmail,
- name: receipientName,
- fiatEquivalent:
- selectedCurrency is FiatCurrency ? (selectedCurrency as FiatCurrency).raw : null,
- ));
-
- _anonpayInvoiceInfoSource.add(result);
-
- state = ExecutedSuccessfullyState(payload: result);
- } catch (e) {
- state = FailureState(e.toString());
- }
- }
-
- @action
- void setRequestParams({
- required String inputAmount,
- required String inputName,
- required String inputEmail,
- required String inputDescription,
- }) {
- receipientName = inputName;
- receipientEmail = inputEmail;
- description = inputDescription;
- amount = inputAmount;
- }
-
- @action
- Future<void> generateDonationLink() async {
- state = IsExecutingState();
-
- final result = await anonPayApi.generateDonationLink(AnonPayRequest(
- cryptoCurrency: cryptoCurrency,
- address: address,
- description: description,
- email: receipientEmail,
- name: receipientName,
- ));
-
- await sharedPreferences.setString(PreferencesKey.clearnetDonationLink, result.clearnetUrl);
- await sharedPreferences.setString(PreferencesKey.onionDonationLink, result.onionUrl);
- await sharedPreferences.setString(PreferencesKey.donationLinkWalletName, _wallet.name);
-
- state = ExecutedSuccessfullyState(payload: result);
- }
-
- Future<void> _fetchLimits() async {
- try {
- final limit = await anonPayApi.fetchLimits(
- cryptoCurrency: cryptoCurrency,
- fiatCurrency: selectedCurrency is FiatCurrency ? selectedCurrency as FiatCurrency : null,
- );
- minimum = limit.min;
- maximum = limit.max != null ? limit.max! / 4 : null;
- } catch (e) {
- state = FailureState(e.toString());
- }
- }
-
- @computed
- String get currentWalletName => _wallet.name;
-
- @computed
- String get qrImage => getQrImage(_wallet.type);
-
- @action
- void reset() {
- selectedCurrency = _wallet.currency;
- cryptoCurrency = _wallet.currency;
- receipientEmail = '';
- receipientName = '';
- description = '';
- amount = '';
- _fetchLimits();
- }
-
- Future<void> _getPreviousDonationLink() async {
- if (pageOption == ReceivePageOption.anonPayDonationLink) {
- final donationLink = sharedPreferences.getString(PreferencesKey.clearnetDonationLink);
- final donationLinkWalletName =
- sharedPreferences.getString(PreferencesKey.donationLinkWalletName);
-
- if (donationLink != null && currentWalletName == donationLinkWalletName) {
- final url = Uri.parse(donationLink);
- url.queryParameters.forEach((key, value) {
- if (key == 'name') receipientName = value;
- if (key == 'email') receipientEmail = value;
- if (key == 'description') description = Uri.decodeComponent(value);
- });
- }
- }
- }
-}
### lib/view_model/buy/buy_item.dart
@@ -1,29 +0,0 @@
-import 'package:cake_wallet/buy/buy_amount.dart';
-import 'package:cake_wallet/buy/buy_provider.dart';
-import 'package:cake_wallet/entities/fiat_currency.dart';
-import 'package:cake_wallet/view_model/buy/buy_amount_view_model.dart';
-import 'package:cw_core/utils/print_verbose.dart';
-
-class BuyItem {
- BuyItem({required this.provider, required this.buyAmountViewModel});
-
- final BuyProvider provider;
- final BuyAmountViewModel buyAmountViewModel;
-
- double get amount => buyAmountViewModel.doubleAmount;
-
- FiatCurrency get fiatCurrency => buyAmountViewModel.fiatCurrency;
-
- Future<BuyAmount> get buyAmount async {
- BuyAmount _buyAmount;
-
- try {
- _buyAmount = await provider.calculateAmount(amount?.toString() ?? '', fiatCurrency.title);
- } catch (e) {
- _buyAmount = BuyAmount(sourceAmount: 0.0, destAmount: 0.0);
- printV(e.toString());
- }
-
- return _buyAmount;
- }
-}
### lib/view_model/buy/buy_sell_view_model.dart
@@ -396,63 +396,6 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S
}
}
- void onTapChoseProvider(BuildContext context) async {
- skipIsReadyToTradeReaction = true;
- final initialQuotes = List<Quote>.from(sortedRecommendedQuotes + sortedQuotes);
- await calculateBestRate();
- final newQuotes = (sortedRecommendedQuotes + sortedQuotes);
-
- for (var quote in newQuotes) quote.limits = null;
-
- final newQuoteProviders = newQuotes
- .map((quote) => quote.provider.isAggregator ? quote.rampName : quote.provider.title)
- .toSet();
-
- final outOfLimitQuotes = initialQuotes.where((initialQuote) {
- return !newQuoteProviders.contains(
- initialQuote.provider.isAggregator ? initialQuote.rampName : initialQuote.provider.title);
- }).map((missingQuote) {
- final quote = Quote(
- rate: missingQuote.rate,
- feeAmount: missingQuote.feeAmount,
- networkFee: missingQuote.networkFee,
- transactionFee: missingQuote.transactionFee,
- payout: missingQuote.payout,
- rampId: missingQuote.rampId,
- rampName: missingQuote.rampName,
- rampIconPath: missingQuote.rampIconPath,
- paymentType: missingQuote.paymentType,
- quoteId: missingQuote.quoteId,
- recommendations: missingQuote.recommendations,
- provider: missingQuote.provider,
- isBuyAction: missingQuote.isBuyAction,
- limits: missingQuote.limits,
- );
- quote.setFiatCurrency = missingQuote.fiatCurrency;
- quote.setCryptoCurrency = missingQuote.cryptoCurrency;
- return quote;
- }).toList();
-
- final updatedQuoteOptions = List<SelectableItem>.from([
- OptionTitle(title: 'Recommended'),
- ...sortedRecommendedQuotes,
- if (sortedQuotes.isNotEmpty) OptionTitle(title: 'All Providers'),
- ...sortedQuotes,
- if (outOfLimitQuotes.isNotEmpty) OptionTitle(title: 'Out of Limits'),
- ...outOfLimitQuotes,
- ]);
-
- if (context.mounted) {
- await Navigator.of(context).pushNamed(
- Routes.buyOptionsPage,
- arguments: [
- updatedQuoteOptions,
- changeOption,
- launchTrade,
- ],
- ).then((value) => calculateBestRate());
- }
- }
void _onPairChange() {
_initialize();
### lib/view_model/buy/buy_view_model.dart
@@ -1,100 +0,0 @@
-import 'package:cake_wallet/buy/buy_provider.dart';
-import 'package:cake_wallet/buy/wyre/wyre_buy_provider.dart';
-import 'package:cw_core/crypto_currency.dart';
-import 'package:cake_wallet/entities/fiat_currency.dart';
-import 'package:cw_core/utils/print_verbose.dart';
-import 'package:cw_core/wallet_type.dart';
-import 'package:cake_wallet/store/settings_store.dart';
-import 'package:cake_wallet/view_model/buy/buy_item.dart';
-import 'package:hive/hive.dart';
-import 'package:cake_wallet/order/order.dart';
-import 'package:cake_wallet/store/dashboard/orders_store.dart';
-import 'package:mobx/mobx.dart';
-import 'package:cw_core/wallet_base.dart';
-import 'buy_amount_view_model.dart';
-
-part 'buy_view_model.g.dart';
-
-class BuyViewModel = BuyViewModelBase with _$BuyViewModel;
-
-abstract class BuyViewModelBase with Store {
- BuyViewModelBase(this.ordersSource, this.ordersStore, this.settingsStore, this.buyAmountViewModel,
- {required this.wallet})
- : isRunning = false,
- isDisabled = true,
- isShowProviderButtons = false,
- items = <BuyItem>[] {
- _fetchBuyItems();
- }
-
- final Box<Order> ordersSource;
- final OrdersStore ordersStore;
- final SettingsStore settingsStore;
- final BuyAmountViewModel buyAmountViewModel;
- final WalletBase wallet;
-
- @observable
- BuyProvider? selectedProvider;
-
- @observable
- List<BuyItem> items;
-
- @observable
- bool isRunning;
-
- @observable
- bool isDisabled;
-
- @observable
- bool isShowProviderButtons;
-
- WalletType get type => wallet.type;
-
- double get doubleAmount => buyAmountViewModel.doubleAmount;
-
- @computed
- FiatCurrency get fiatCurrency => buyAmountViewModel.fiatCurrency;
-
- CryptoCurrency get cryptoCurrency => wallet.currency;
-
- Future<String> fetchUrl() async {
- String _url = '';
-
- try {
- _url = await selectedProvider!.requestUrl(doubleAmount.toString(), fiatCurrency.title);
- } catch (e) {
- printV(e.toString());
- }
-
- return _url;
- }
-
- Future<void> saveOrder(String orderId) async {
- try {
- final order = await selectedProvider!.findOrderById(orderId);
- order.from = fiatCurrency.title;
- order.to = cryptoCurrency.title;
- await ordersSource.add(order);
- ordersStore.setOrder(order);
- } catch (e) {
- printV(e.toString());
- }
- }
-
- void reset() {
- buyAmountViewModel.amount = '';
- selectedProvider = null;
- }
-
- Future<void> _fetchBuyItems() async {
- final List<BuyProvider> _providerList = [];
-
- if (wallet.type == WalletType.bitcoin) {
- _providerList.add(WyreBuyProvider(wallet: wallet));
- }
-
- items = _providerList
- .map((provider) => BuyItem(provider: provider, buyAmountViewModel: buyAmountViewModel))
- .toList();
- }
-}
### lib/view_model/dashboard/action_list_display_mode.dart
@@ -1,32 +0,0 @@
-enum ActionListDisplayMode { transactions, trades }
-
-int serializeActionlistDisplayModes(List<ActionListDisplayMode> modes) {
- var i = 0;
-
- for (final mode in modes) {
- switch (mode) {
- case ActionListDisplayMode.trades:
- i += 1;
- break;
- case ActionListDisplayMode.transactions:
- i += 10;
- break;
- }
- }
-
- return i;
-}
-
-List<ActionListDisplayMode> deserializeActionlistDisplayModes(int raw) {
- final modes = <ActionListDisplayMode>[];
-
- if (raw == 1 || raw - 10 == 1) {
- modes.add(ActionListDisplayMode.trades);
- }
-
- if (raw >= 10) {
- modes.add(ActionListDisplayMode.transactions);
- }
-
- return modes;
-}
### lib/view_model/dashboard/cake_features_view_model.dart
@@ -1,16 +0,0 @@
-import 'package:cake_wallet/cake_pay/src/services/cake_pay_service.dart';
-import 'package:mobx/mobx.dart';
-
-part 'cake_features_view_model.g.dart';
-
-class CakeFeaturesViewModel = CakeFeaturesViewModelBase with _$CakeFeaturesViewModel;
-
-abstract class CakeFeaturesViewModelBase with Store {
- final CakePayService _cakePayService;
-
- CakeFeaturesViewModelBase(this._cakePayService);
-
- Future<bool> isIoniaUserAuthenticated() async {
- return await _cakePayService.isLogged();
- }
-}
### lib/view_model/dashboard/dashboard_view_model.dart
@@ -4,7 +4,6 @@ import 'dart:io' show Platform;
import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/bitcoin/bitcoin.dart';
-import 'package:cake_wallet/core/address_resolver/yat/yat_store.dart';
import 'package:cake_wallet/core/key_service.dart';
import 'package:cake_wallet/view_model/dashboard/date_section_item.dart';
import "package:cw_core/balance_card_style_settings.dart";
@@ -85,7 +84,6 @@ abstract class DashboardViewModelBase with Store {
required this.orderFilterStore,
required this.transactionFilterStore,
required this.settingsStore,
- required this.yatStore,
required this.ordersStore,
required this.anonpayTransactionsStore,
required this.payjoinTransactionsStore,
@@ -1171,7 +1169,6 @@ abstract class DashboardViewModelBase with Store {
SettingsStore settingsStore;
- YatStore yatStore;
TradesStore tradesStore;
### lib/view_model/dashboard/desktop_sidebar_view_model.dart
@@ -1,35 +0,0 @@
-import 'package:mobx/mobx.dart';
-
-part 'desktop_sidebar_view_model.g.dart';
-
-enum SidebarItem {
- dashboard,
- transactions,
- status,
- support,
- settings,
-}
-
-class DesktopSidebarViewModel = DesktopSidebarViewModelBase with _$DesktopSidebarViewModel;
-
-abstract class DesktopSidebarViewModelBase with Store {
- DesktopSidebarViewModelBase();
-
- @observable
- SidebarItem currentPage = SidebarItem.dashboard;
-
- @action
- void onPageChange(SidebarItem item) {
- if (currentPage == item) {
- resetSidebar();
-
- return;
- }
- currentPage = item;
- }
-
- @action
- void resetSidebar() {
- currentPage = SidebarItem.dashboard;
- }
-}
### lib/view_model/dashboard/dropdown_filter_item.dart
@@ -1,19 +0,0 @@
-import 'package:cake_wallet/view_model/dashboard/filter_item.dart';
-
-class DropdownFilterItem extends FilterItem {
- DropdownFilterItem({
- required this.items,
- required this.caption,
- required this.selectedItem,
- required this.onItemSelected,
- }) : super(
- value: () => false,
- caption: caption,
- onChanged: (_) {},
- );
-
- final List<String> items;
- final String caption;
- final String selectedItem;
- final Function(String) onItemSelected;
-}
### lib/view_model/dashboard/wallet_balance.dart
@@ -1,6 +0,0 @@
-class WalletBalance {
- WalletBalance({required this.unlockedBalance, required this.totalBalance});
-
- String unlockedBalance;
- String totalBalance;
-}
### lib/view_model/exchange/exchange_trade_view_model.dart
@@ -51,8 +51,7 @@ abstract class ExchangeTradeViewModelBase with Store {
required this.fiatConversionStore,
}) : trade = tradesStore.trade!,
isSwapsXYZCanSendFromExternal =
- _checkIfSwapsXYZCanSendFromExternal(tradesStore.trade!, wallet),
- items = ObservableList<ExchangeTradeItem>() {
+ _checkIfSwapsXYZCanSendFromExternal(tradesStore.trade!, wallet) {
setUpOutput();
switch (trade.provider) {
case ExchangeProviderDescription.changeNow:
@@ -97,7 +96,6 @@ abstract class ExchangeTradeViewModelBase with Store {
break;
}
- _updateItems();
if (_provider != null) {
_updateTrade();
@@ -151,8 +149,6 @@ abstract class ExchangeTradeViewModelBase with Store {
? ""
: "${sendViewModel.pendingTransactionFeeFiatAmount} ${sendViewModel.fiat.title}";
- @observable
- ObservableList<ExchangeTradeItem> items;
ExchangeProvider? _provider;
@@ -252,107 +248,11 @@ abstract class ExchangeTradeViewModelBase with Store {
await trade.save();
tradesStore.setTrade(trade);
- _updateItems();
} catch (e) {
printV(e.toString());
}
}
- void _updateItems() {
- final tradeFrom = trade.from;
- final tradeTo = trade.to;
-
- final tagFrom = tradeFrom?.tag != null ? "${tradeFrom!.tag} " : "";
- final tagTo = tradeTo?.tag != null ? "${tradeTo!.tag} " : "";
-
- items.clear();
-
- if (trade.provider != ExchangeProviderDescription.thorChain)
- items.add(
- ExchangeTradeItem(
- title: "${trade.provider.title} ${S.current.id}",
- data: "${trade.id}",
- isCopied: true,
- isReceiveDetail: true,
- isExternalSendDetail: false,
- ),
- );
-
- if (tradeFrom != null && tradeTo != null) {
- items.addAll([
- ExchangeTradeItem(
- title: S.current.amount,
- data:
- "${_amountParsingProxy.getDisplayCryptoAmount(trade.amount, tradeFrom)} ${_amountParsingProxy.getCryptoSymbol(tradeFrom)}",
- isCopied: false,
- isReceiveDetail: false,
- isExternalSendDetail: true,
- ),
- ExchangeTradeItem(
- title: "${S.current.you_will_receive_estimated_amount}:",
- data:
- "${_amountParsingProxy.getDisplayCryptoAmount(trade.receiveAmount ?? "0", tradeTo)} ${_amountParsingProxy.getCryptoSymbol(tradeTo)}",
- isCopied: true,
- isReceiveDetail: true,
- isExternalSendDetail: false,
- ),
- ExchangeTradeItem(
- title: "${S.current.send_to_this_address("$tradeFrom", tagFrom)}:",
- data: trade.inputAddress ?? '',
- isCopied: false,
- isReceiveDetail: false,
- isExternalSendDetail: true,
- ),
- ]);
-
- items.add(
- isSwapsXYZCanSendFromExternal
- ? ExchangeTradeItem(
- title: S.current.send_to_this_address('${tradeFrom}', tagFrom) + ':',
- data: trade.inputAddress ?? '',
- isCopied: false,
- isReceiveDetail: false,
- isExternalSendDetail: true)
- : ExchangeTradeItem(
- title: 'Smart contract call (no address required)',
- data: 'Wallet will execute a contract call. On-chain transaction',
- isCopied: false,
- isReceiveDetail: false,
- isExternalSendDetail: true),
- );
- }
-
- final isExtraIdExist = trade.extraId != null && trade.extraId!.isNotEmpty;
-
- if (isExtraIdExist) {
- final title = tradeFrom == CryptoCurrency.xrp
- ? S.current.destination_tag
- : [CryptoCurrency.xlm, CryptoCurrency.ton].contains(tradeFrom)
- ? S.current.memo
- : S.current.extra_id;
-
- items.add(
- ExchangeTradeItem(
- title: title,
- data: trade.extraId ?? "",
- isCopied: true,
- isReceiveDetail: !isExtraIdExist,
- isExternalSendDetail: isExtraIdExist,
- ),
- );
- }
-
- items.add(
- ExchangeTradeItem(
- title: "${S.current.arrive_in_this_address("${tradeTo}", tagTo)}:",
- data: trade.payoutAddress ?? "",
- isCopied: true,
- isReceiveDetail: true,
- isExternalSendDetail: false,
- ),
- );
- }
-
String? checkIfCanSend(Trade? trade, WalletBase wallet) {
if (trade == null) return 'Trade is null';
### lib/view_model/exchange/exchange_view_model.dart
@@ -48,7 +48,6 @@ import "package:cw_core/wallet_info.dart";
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
import 'package:cake_wallet/store/dashboard/trades_store.dart';
import 'package:cake_wallet/store/settings_store.dart';
-import 'package:cake_wallet/store/templates/exchange_template_store.dart';
import 'package:cake_wallet/evm/evm.dart';
import 'package:cake_wallet/reactions/wallet_connect.dart';
import 'package:cake_wallet/utils/feature_flag.dart';
@@ -96,7 +95,6 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
ExchangeViewModelBase(
this._appStore,
- this._exchangeTemplateStore,
this.tradesStore,
this.sharedPreferences,
this.contactListViewModel,
@@ -296,7 +294,6 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
isElectrumWallet;
bool _useTorOnly;
- final ExchangeTemplateStore _exchangeTemplateStore;
final TradesStore tradesStore;
final SharedPreferences sharedPreferences;
@@ -422,8 +419,6 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
@computed
SyncStatus get status => wallet.syncStatus;
- @computed
- ObservableList<ExchangeTemplate> get templates => _exchangeTemplateStore.templates;
@computed
List<WalletContact> get walletContactsToShow => contactListViewModel.walletContacts
@@ -1469,30 +1464,6 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
_depositAmount = tmpAmount;
}
- void updateTemplate() => _exchangeTemplateStore.update();
-
- void 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}) =>
- _exchangeTemplateStore.addTemplate(
- amount: amount,
- depositCurrency: depositCurrency,
- receiveCurrency: receiveCurrency,
- provider: provider,
- depositAddress: depositAddress,
- receiveAddress: receiveAddress,
- depositCurrencyTitle: depositCurrencyTitle,
- receiveCurrencyTitle: receiveCurrencyTitle);
-
- void removeTemplate({required ExchangeTemplate template}) =>
- _exchangeTemplateStore.remove(template: template);
-
void _onPairChange({bool clearBoth = false}) {
if (clearBoth) {
_depositAmount = null;
### lib/view_model/send/send_template_view_model.dart
@@ -1,114 +0,0 @@
-import 'package:cake_wallet/evm/evm.dart';
-import 'package:cake_wallet/reactions/wallet_connect.dart';
-import 'package:cake_wallet/store/app_store.dart';
-import 'package:cake_wallet/view_model/send/template_view_model.dart';
-import 'package:cw_core/crypto_currency.dart';
-import 'package:cw_core/currency_for_wallet_type.dart';
-import 'package:cw_core/wallet_type.dart';
-import 'package:mobx/mobx.dart';
-import 'package:cake_wallet/entities/template.dart';
-import 'package:cake_wallet/store/templates/send_template_store.dart';
-import 'package:cake_wallet/core/template_validator.dart';
-import 'package:cake_wallet/core/address_validator.dart';
-import 'package:cake_wallet/core/amount_validator.dart';
-import 'package:cw_core/wallet_base.dart';
-import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
-
-part 'send_template_view_model.g.dart';
-
-class SendTemplateViewModel = SendTemplateViewModelBase with _$SendTemplateViewModel;
-
-abstract class SendTemplateViewModelBase with Store {
- final WalletBase _wallet;
- final AppStore _appStore;
- final SendTemplateStore _sendTemplateStore;
- final FiatConversionStore _fiatConversationStore;
-
- SendTemplateViewModelBase(
- this._wallet, this._appStore, this._sendTemplateStore, this._fiatConversationStore)
- : recipients = ObservableList<TemplateViewModel>() {
- addRecipient();
- }
-
- ObservableList<TemplateViewModel> recipients;
-
- @action
- void addRecipient() {
- recipients.add(TemplateViewModel(
- wallet: _wallet, appStore: _appStore, fiatConversationStore: _fiatConversationStore));
- }
-
- @action
- void removeRecipient(TemplateViewModel recipient) {
- recipients.remove(recipient);
- }
-
- AmountValidator get amountValidator => AmountValidator(
- currency: walletTypeToCryptoCurrency(_wallet.type, chainId: _wallet.chainId),
- amountParsingProxy: _appStore.amountParsingProxy,
- );
-
- AddressValidator get addressValidator => AddressValidator(
- type: _wallet.currency,
- isTestnet: _wallet.isTestnet,
- network: _wallet.walletInfo.network,
- );
-
- TemplateValidator get templateValidator => TemplateValidator();
-
- bool get hasMultiRecipient =>
- _wallet.type != WalletType.haven &&
- _wallet.type != WalletType.solana &&
- _wallet.type != WalletType.tron &&
- !isEVMCompatibleChain(_wallet.type);
-
- @computed
- CryptoCurrency get cryptoCurrency => _wallet.currency;
-
- @computed
- String get fiatCurrency => _appStore.settingsStore.fiatCurrency.title;
-
- @computed
- int get fiatCurrencyDecimals => _appStore.settingsStore.fiatCurrency.decimals;
-
- @computed
- ObservableList<Template> get templates => _sendTemplateStore.templates;
-
- @action
- void updateTemplate() => _sendTemplateStore.update();
-
- @action
- void addTemplate(
- {required String name,
- required bool isCurrencySelected,
- required String cryptoCurrency,
- required String address,
- required String amount,
- required String amountFiat,
- required List<Template> additionalRecipients}) {
- _sendTemplateStore.addTemplate(
- name: name,
- isCurrencySelected: isCurrencySelected,
- address: address,
- cryptoCurrency: cryptoCurrency,
- fiatCurrency: fiatCurrency,
- amount: amount,
- amountFiat: amountFiat,
- additionalRecipients: additionalRecipients);
- updateTemplate();
- }
-
- @action
- void removeTemplate({required Template template}) {
- _sendTemplateStore.remove(template: template);
- updateTemplate();
- }
-
- @computed
- List<CryptoCurrency> get walletCurrencies => _wallet.balance.keys.toList();
-
- bool get hasMultipleTokens =>
- isEVMCompatibleChain(_wallet.type) ||
- _wallet.type == WalletType.solana ||
- _wallet.type == WalletType.tron;
-}
### lib/view_model/send/send_view_model.dart
@@ -48,7 +48,6 @@ import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart';
import 'package:cake_wallet/view_model/hardware_wallet/hardware_wallet_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:cake_wallet/view_model/send/send_template_view_model.dart';
import 'package:cake_wallet/view_model/send/send_view_model_state.dart';
import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_list_view_model.dart';
import 'package:cake_wallet/wownero/wownero.dart';
@@ -103,7 +102,6 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
SendViewModelBase(
this._appStore,
- this.sendTemplateViewModel,
this._fiatConversationStore,
this._adrResService,
this.balanceViewModel,
@@ -436,10 +434,6 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
return sp.hasMatch(address);
}
- @computed
- List<Template> get templates => sendTemplateViewModel.templates
- .where((template) => _isEqualCurrency(template.cryptoCurrency))
- .toList();
@computed
bool get hasCoinControl =>
@@ -492,7 +486,6 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
final AppStore _appStore;
SettingsStore get _settingsStore => _appStore.settingsStore;
- final SendTemplateViewModel sendTemplateViewModel;
final BalanceViewModel balanceViewModel;
final ContactListViewModel contactListViewModel;
final HardwareWalletViewModel? hardwareWalletViewModel;
@@ -504,9 +497,12 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
@computed
AmountParsingProxy get amountParsingProxy => _appStore.amountParsingProxy;
- @computed
bool get hasMultiRecipient =>
- sendTemplateViewModel.hasMultiRecipient && coinTypeToSpendFrom != UnspentCoinType.lightning;
+ wallet.type != WalletType.haven &&
+ wallet.type != WalletType.solana &&
+ wallet.type != WalletType.tron &&
+ !isEVMCompatibleChain(wallet.type) &&
+ coinTypeToSpendFrom != UnspentCoinType.lightning;
@computed
String get languageCode => _appStore.settingsStore.languageCode;
### lib/view_model/send/template_view_model.dart
[binary or diff unavailable]
### lib/view_model/settings/regular_list_item.dart
[binary or diff unavailable]
### lib/view_model/settings/switcher_list_item.dart
[binary or diff unavailable]
### lib/view_model/wallet_address_list/wallet_address_list_view_model.dart
[binary or diff unavailable]
### pubspec.lock
[binary or diff unavailable]
### pubspec_base.yaml
[binary or diff unavailable]Why this scored 18/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.