diff --git a/lib/new-ui/pages/send_page.dart b/lib/new-ui/pages/send_page.dart index 0a6ea20d6a..82b139db19 100644 --- a/lib/new-ui/pages/send_page.dart +++ b/lib/new-ui/pages/send_page.dart @@ -969,7 +969,7 @@ class _NewSendPageState extends State { final balanceByAsset = { for (final r in widget.sendViewModel.balanceViewModel.formattedBalances) r.asset: CurrencyPickerBalance( - amount: "${r.availableBalance} ${r.asset.title}", + amount: "${r.availableBalance} ${r.formattedAssetTitle}", fiat: isFiatDisabled ? null : "${r.fiatAvailableBalanceRaw} ${r.fiatCurrency?.symbol}", fiatValue: isFiatDisabled ? null : double.tryParse(r.fiatAvailableBalanceRaw), ), diff --git a/lib/new-ui/pages/swap_page.dart b/lib/new-ui/pages/swap_page.dart index b59ef80e03..870f0b6104 100644 --- a/lib/new-ui/pages/swap_page.dart +++ b/lib/new-ui/pages/swap_page.dart @@ -28,7 +28,6 @@ import "package:cake_wallet/src/widgets/primary_button.dart"; import "package:cake_wallet/utils/debounce.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/balance_view_model.dart"; import "package:cake_wallet/view_model/exchange/exchange_trade_view_model.dart"; import "package:cake_wallet/view_model/exchange/exchange_view_model.dart"; import "package:cake_wallet/view_model/wallet_switcher_view_model.dart"; @@ -53,7 +52,6 @@ class NewSwapPage extends StatefulWidget { required this.walletSwitcherViewModel, CryptoCurrency? initialCurrency, this.fromSend, - this.balanceViewModel, }) { depositWalletName = exchangeViewModel.depositCurrency == CryptoCurrency.xmr ? exchangeViewModel.wallet.name @@ -72,7 +70,6 @@ class NewSwapPage extends StatefulWidget { final AddressResolverService adrResService; final PaymentRequest? initialPaymentRequest; final SwapFromSendArgs? fromSend; - final BalanceViewModel? balanceViewModel; late final String? depositWalletName; late final String? receiveWalletName; @@ -97,16 +94,12 @@ class _NewSwapPageState extends State { .contains(widget.exchangeViewModel.depositCurrency) && !(widget.exchangeViewModel.status is SyncedSyncStatus); - Map? _depositBalanceByAsset() { - final balanceViewModel = widget.balanceViewModel; - if (balanceViewModel == null) { - return null; - } - + Map _depositBalanceByAsset() { + final balanceViewModel = widget.exchangeViewModel.feesViewModel.balanceViewModel; return { for (final r in balanceViewModel.formattedBalances) r.asset: CurrencyPickerBalance( - amount: "${r.availableBalance} ${r.asset.title}", + amount: "${r.availableBalance} ${r.formattedAssetTitle}", fiat: balanceViewModel.isFiatDisabled ? null : "${r.fiatAvailableBalanceRaw} ${r.fiatCurrency?.symbol}", @@ -653,15 +646,10 @@ class _NewSwapPageState extends State { key: depositKey, title: fromSend != null ? "" : S.of(context).send, sourceSelectorMode: fromSend != null, - walletName: fromSend != null - ? widget.exchangeViewModel.wallet.name - : null, - balanceByAsset: - fromSend != null ? _depositBalanceByAsset() : null, - useSingleNetworkLayout: fromSend != null, - filteredNetwork: fromSend != null - ? widget.exchangeViewModel.wallet.type - : null, + walletName: widget.exchangeViewModel.wallet.name, + balanceByAsset: _depositBalanceByAsset(), + useSingleNetworkLayout: true, + filteredNetwork: widget.exchangeViewModel.wallet.type, currency: widget.exchangeViewModel.depositCurrency, useBaseUnit: widget.exchangeViewModel.useDepositBaseUnit, hasRefundAddress: true, @@ -758,6 +746,7 @@ class _NewSwapPageState extends State { svgPath: "assets/new-ui/swap_amounts.svg", onPressed: widget.exchangeViewModel.reverseSwapDirection, + semanticLabel: S.of(context).swap_reverse_direction, ), ], ), diff --git a/lib/new-ui/widgets/anypay/anypay_flow.dart b/lib/new-ui/widgets/anypay/anypay_flow.dart index 0a6077b2fa..c3c6cfee64 100644 --- a/lib/new-ui/widgets/anypay/anypay_flow.dart +++ b/lib/new-ui/widgets/anypay/anypay_flow.dart @@ -351,7 +351,6 @@ class AnyPayFlow { null, walletSwitcherViewModel: walletSwitcherViewModel, fromSend: SwapFromSendArgs.fromIntent(intent), - balanceViewModel: sendViewModel.balanceViewModel, ); await Navigator.of(presentContext).push( CupertinoPageRoute( diff --git a/lib/new-ui/widgets/currency_picker/chain_chip_strip.dart b/lib/new-ui/widgets/currency_picker/chain_chip_strip.dart index 17910a4c5e..55b2f0b546 100644 --- a/lib/new-ui/widgets/currency_picker/chain_chip_strip.dart +++ b/lib/new-ui/widgets/currency_picker/chain_chip_strip.dart @@ -55,7 +55,7 @@ class _ChainChip extends StatelessWidget { Widget build(BuildContext context) { final colors = Theme.of(context).colorScheme; return Padding( - padding: const EdgeInsetsDirectional.only(end: 8), + padding: const EdgeInsetsDirectional.only(end: 4), child: MergeSemantics( child: Semantics( button: true, @@ -65,10 +65,10 @@ class _ChainChip extends StatelessWidget { onTap: onTap, borderRadius: BorderRadius.circular(80), child: Container( - padding: const EdgeInsets.symmetric(horizontal: 10), + padding: EdgeInsets.symmetric(horizontal: isSelected ? 12 : 10), decoration: BoxDecoration( color: isSelected ? colors.primary : colors.surfaceContainer, - borderRadius: BorderRadius.circular(20), + borderRadius: BorderRadius.circular(80), ), child: Center( child: Text( @@ -76,7 +76,7 @@ class _ChainChip extends StatelessWidget { style: Theme.of(context).textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w500, fontSize: isSelected ? 14 : 12, - letterSpacing: -0.07, + letterSpacing: isSelected ? -0.07 : -0.06, color: isSelected ? colors.onPrimary : colors.primary, ), ), diff --git a/lib/new-ui/widgets/currency_picker/currency_picker_args.dart b/lib/new-ui/widgets/currency_picker/currency_picker_args.dart index 13a06523a9..05882eb4ce 100644 --- a/lib/new-ui/widgets/currency_picker/currency_picker_args.dart +++ b/lib/new-ui/widgets/currency_picker/currency_picker_args.dart @@ -15,6 +15,10 @@ String chainNameForCurrency(CryptoCurrency c) { return wt != null ? walletTypeToString(wt) : (c.tag ?? ""); } +String assetNameForCurrency(CryptoCurrency c) => c == CryptoCurrency.btcln + ? (CryptoCurrency.btc.fullName ?? CryptoCurrency.btc.title) + : (c.fullName ?? c.title); + final Set _stablecoinSymbols = { for (final c in CryptoCurrency.all) if (c.groups.contains(CurrencyGroups.stablecoin)) c.title.toUpperCase(), @@ -100,9 +104,10 @@ CurrencyPickerBalance? balanceForAsset( } final title = asset.title.toUpperCase(); + final tag = asset.tag?.toUpperCase(); CurrencyPickerBalance? byTitle; for (final entry in balances.entries) { - if (entry.key.title.toUpperCase() == title) { + if (entry.key.title.toUpperCase() == title && entry.key.tag?.toUpperCase() == tag) { if (byTitle != null) { return null; } @@ -124,6 +129,8 @@ class CurrencyPickerArgs { required this.symbolResolver, this.recentsSource = RecentsSource.none, this.useSingleNetworkLayout = false, + this.walletName, + this.otherAssets, }); final CryptoCurrency? selected; @@ -134,4 +141,6 @@ class CurrencyPickerArgs { final Map? balanceByAsset; final RecentsSource recentsSource; final bool useSingleNetworkLayout; + final String? walletName; + final CurrencyPickerArgs? otherAssets; } diff --git a/lib/new-ui/widgets/currency_picker/currency_picker_footer.dart b/lib/new-ui/widgets/currency_picker/currency_picker_footer.dart new file mode 100644 index 0000000000..49ad78bc5e --- /dev/null +++ b/lib/new-ui/widgets/currency_picker/currency_picker_footer.dart @@ -0,0 +1,74 @@ +import "package:cake_wallet/generated/i18n.dart"; +import "package:cake_wallet/new-ui/widgets/currency_picker/currency_picker_search_field.dart"; +import "package:flutter/material.dart"; + +class CurrencyPickerFooter extends StatelessWidget { + const CurrencyPickerFooter({ + required this.searchController, + this.action, + super.key, + }); + + final TextEditingController searchController; + final Widget? action; + + static const double _actionHeight = 55; + static const double _actionGap = 16; + + static const double _searchHeight = 60; + static const double _bottomMargin = 24; + + static const double _fadeHeightWithAction = 200; + static const double _fadeHeight = 125; + + static double heightFor({required bool hasAction}) => + (hasAction ? _actionHeight + _actionGap : 0) + _searchHeight + _bottomMargin; + + @override + Widget build(BuildContext context) { + final action = this.action; + return Positioned( + left: 0, + right: 0, + bottom: 0, + child: Stack( + alignment: Alignment.bottomCenter, + children: [ + IgnorePointer( + child: Container( + height: action == null ? _fadeHeight : _fadeHeightWithAction, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Theme.of(context).colorScheme.surface.withAlpha(0), + Theme.of(context).colorScheme.surface, + ], + ), + ), + ), + ), + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (action != null) ...[ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: SizedBox(height: _actionHeight, child: action), + ), + const SizedBox(height: _actionGap), + ], + CurrencyPickerSearchField( + controller: searchController, + hintText: S.of(context).search, + ), + const SizedBox(height: _bottomMargin), + ], + ), + ], + ), + ); + } +} diff --git a/lib/new-ui/widgets/currency_picker/currency_picker_list_container.dart b/lib/new-ui/widgets/currency_picker/currency_picker_list_container.dart index fa05f55f08..99d7a6d49e 100644 --- a/lib/new-ui/widgets/currency_picker/currency_picker_list_container.dart +++ b/lib/new-ui/widgets/currency_picker/currency_picker_list_container.dart @@ -16,8 +16,8 @@ class CurrencyPickerListContainer extends StatelessWidget { height: 1, thickness: 1, color: colors.surfaceContainerHigh, - indent: 56, - endIndent: 24, + indent: 52, + endIndent: 12, )); } } diff --git a/lib/new-ui/widgets/currency_picker/currency_picker_row.dart b/lib/new-ui/widgets/currency_picker/currency_picker_row.dart index 52ac4c0656..4655943a3d 100644 --- a/lib/new-ui/widgets/currency_picker/currency_picker_row.dart +++ b/lib/new-ui/widgets/currency_picker/currency_picker_row.dart @@ -1,4 +1,5 @@ import 'package:cake_wallet/new-ui/widgets/coins_page/token_image_widget.dart'; +import "package:cake_wallet/new-ui/widgets/currency_picker/currency_picker_args.dart"; import 'package:cake_wallet/src/widgets/cake_image_widget.dart'; import 'package:cw_core/crypto_currency.dart'; import 'package:flutter/material.dart'; @@ -10,6 +11,7 @@ class CurrencyPickerRow extends StatelessWidget { required this.isSelected, required this.trailing, required this.onTap, + this.subtitle, this.chainPillLabel, this.chainBadgePath, }); @@ -18,6 +20,7 @@ class CurrencyPickerRow extends StatelessWidget { final bool isSelected; final Widget trailing; final VoidCallback onTap; + final String? subtitle; final String? chainPillLabel; final String? chainBadgePath; @@ -30,8 +33,9 @@ class CurrencyPickerRow extends StatelessWidget { selected: isSelected, child: InkWell( onTap: onTap, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12), + child: Container( + height: subtitle == null ? 48 : 56, + padding: const EdgeInsets.symmetric(horizontal: 12), child: Row( children: [ ExcludeSemantics( @@ -39,32 +43,50 @@ class CurrencyPickerRow extends StatelessWidget { ), const SizedBox(width: 12), Expanded( - child: Row( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Flexible( - child: Text( - currency.fullName ?? currency.title, - overflow: TextOverflow.ellipsis, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontWeight: FontWeight.w500, + Row( + children: [ + Flexible( + child: Text( + assetNameForCurrency(currency), + overflow: TextOverflow.ellipsis, + style: Theme.of(context) + .textTheme + .bodyMedium + ?.copyWith(letterSpacing: -0.07), + ), + ), + if (chainPillLabel != null) ...[ + const SizedBox(width: 6), + Container( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), + decoration: BoxDecoration( + color: colors.surfaceContainerHigh, + borderRadius: BorderRadius.circular(20), ), - ), + child: Text( + chainPillLabel!, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + fontWeight: FontWeight.w500, + letterSpacing: -0.06, + color: colors.primary, + ), + ), + ), + ], + ], ), - if (chainPillLabel != null) ...[ - const SizedBox(width: 8), - Container( - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), - decoration: BoxDecoration( - color: colors.surfaceContainerHigh, - borderRadius: BorderRadius.circular(10), - ), - child: Text( - chainPillLabel!, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - fontWeight: FontWeight.w500, - color: colors.onSecondaryContainer, - ), - ), + if (subtitle != null) ...[ + const SizedBox(height: 4), + Text( + subtitle!, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + letterSpacing: -0.06, + color: colors.onSurfaceVariant, + ), ), ], ], @@ -72,12 +94,22 @@ class CurrencyPickerRow extends StatelessWidget { ), const SizedBox(width: 8), trailing, - const SizedBox(width: 8), + const SizedBox(width: 4), ExcludeSemantics( - child: Icon( - Icons.chevron_right, - size: 20, - color: isSelected ? colors.primary : colors.onSurfaceVariant, + child: SizedBox( + width: 16, + height: 16, + child: Center( + child: CakeImageWidget( + imageUrl: "assets/new-ui/arrow_right.svg", + width: 7, + height: 12, + colorFilter: ColorFilter.mode( + isSelected ? colors.primary : colors.onSurfaceVariant, + BlendMode.srcIn, + ), + ), + ), ), ), ], @@ -99,10 +131,10 @@ class _IconWithBadge extends StatelessWidget { Widget build(BuildContext context) { final icon = TokenImageWidget( imageUrl: currency.iconPath ?? '', - size: 32, - errorWidget: Container( - width: 32, - height: 32, + size: 28, + errorWidget: SizedBox( + width: 28, + height: 28, child: Center( child: Text( currency.title.length >= 2 ? currency.title.substring(0, 2) : currency.title, @@ -110,34 +142,31 @@ class _IconWithBadge extends StatelessWidget { ), ), ); - if (badgePath == null) return icon; + if (badgePath == null) { + return icon; + } return SizedBox( - width: 36, - height: 36, + width: 28, + height: 28, child: Stack( - clipBehavior: Clip.none, children: [ icon, Positioned( - right: -2, - bottom: -2, + right: 0, + bottom: 0, child: Container( - width: 18, - height: 18, + width: 12, + height: 12, + padding: const EdgeInsets.all(3), decoration: BoxDecoration( - borderRadius: BorderRadius.circular(6), - border: Border.all( - color: Theme.of(context).colorScheme.surfaceContainerHigh, - width: 2, - ), + borderRadius: BorderRadius.circular(4), color: Theme.of(context).colorScheme.onSurface, ), - padding: const EdgeInsets.all(2), child: CakeImageWidget( imageUrl: badgePath, color: Theme.of(context).colorScheme.surface, - width: 13, - height: 13, + width: 6, + height: 6, fit: BoxFit.cover, ), ), diff --git a/lib/new-ui/widgets/currency_picker/currency_picker_search_field.dart b/lib/new-ui/widgets/currency_picker/currency_picker_search_field.dart index 25876f0f12..be02749cae 100644 --- a/lib/new-ui/widgets/currency_picker/currency_picker_search_field.dart +++ b/lib/new-ui/widgets/currency_picker/currency_picker_search_field.dart @@ -16,11 +16,12 @@ class CurrencyPickerSearchField extends StatelessWidget { @override Widget build(BuildContext context) { final colors = Theme.of(context).colorScheme; + return Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: Container( - height: 48, - padding: const EdgeInsets.symmetric(horizontal: 14), + height: 44, + padding: const EdgeInsets.only(right: 16), decoration: BoxDecoration( color: colors.surfaceContainer, border: Border.all(color: colors.surfaceContainer, width: 1), @@ -28,8 +29,12 @@ class CurrencyPickerSearchField extends StatelessWidget { ), child: Row( children: [ - ExcludeSemantics(child: Icon(Icons.search, size: 20, color: colors.primary)), - const SizedBox(width: 10), + ExcludeSemantics( + child: SizedBox( + width: 44, + child: Center(child: Icon(Icons.search, size: 20, color: colors.primary)), + ), + ), Expanded( // The hint names the field only while it is empty, so the label is // supplied once there is text to keep exactly one announcement. @@ -38,13 +43,14 @@ class CurrencyPickerSearchField extends StatelessWidget { label: controller.text.isEmpty ? null : hintText, child: TextFormField( controller: controller, - style: Theme.of(context).textTheme.bodyMedium, + style: Theme.of(context).textTheme.bodySmall?.copyWith(fontSize: 12.8), decoration: InputDecoration( isCollapsed: true, border: InputBorder.none, focusedBorder: InputBorder.none, hintText: hintText, - hintStyle: Theme.of(context).textTheme.bodyMedium?.copyWith( + hintStyle: Theme.of(context).textTheme.bodySmall?.copyWith( + fontSize: 12.8, color: colors.onSurfaceVariant, ), ), diff --git a/lib/new-ui/widgets/currency_picker/currency_picker_sheet.dart b/lib/new-ui/widgets/currency_picker/currency_picker_sheet.dart index 43577eef95..3832626abf 100644 --- a/lib/new-ui/widgets/currency_picker/currency_picker_sheet.dart +++ b/lib/new-ui/widgets/currency_picker/currency_picker_sheet.dart @@ -5,7 +5,7 @@ import 'package:cake_wallet/new-ui/widgets/currency_picker/single_network_curren import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart'; import 'package:flutter/material.dart'; -class CurrencyPickerSheet extends StatelessWidget { +class CurrencyPickerSheet extends StatefulWidget { const CurrencyPickerSheet({super.key, required this.args}); final CurrencyPickerArgs args; @@ -13,8 +13,7 @@ class CurrencyPickerSheet extends StatelessWidget { static Future show({ required BuildContext context, required CurrencyPickerArgs args, - }) { - return showModalBottomSheet( + }) => showModalBottomSheet( context: context, isScrollControlled: true, useSafeArea: true, @@ -23,35 +22,75 @@ class CurrencyPickerSheet extends StatelessWidget { backgroundColor: Colors.transparent, builder: (_) => CurrencyPickerSheet(args: args), ); + + @override + State createState() => _CurrencyPickerSheetState(); +} + +class _CurrencyPickerSheetState extends State { + bool _showingOtherAssets = false; + + void _showOtherAssets(bool show) { + FocusManager.instance.primaryFocus?.unfocus(); + setState(() => _showingOtherAssets = show); } @override Widget build(BuildContext context) { final colors = Theme.of(context).colorScheme; - return Padding( - padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), - child: Container( - decoration: BoxDecoration( - borderRadius: const BorderRadius.vertical(top: Radius.circular(24)), - color: colors.surface, - ), - child: SafeArea( - top: false, - child: Column( - mainAxisSize: MainAxisSize.max, - children: [ - ModalTopBar( - title: S.of(context).select_asset, - leadingIcon: const Icon(Icons.close), - leadingSemanticLabel: S.of(context).close, - onLeadingPressed: () => Navigator.of(context).maybePop(), - ), - Expanded( - child: args.useSingleNetworkLayout - ? SingleNetworkCurrencyPicker(args: args) - : MultiNetworkCurrencyPicker(args: args), - ), - ], + final args = widget.args; + final otherAssets = args.otherAssets; + final showingOtherAssets = otherAssets != null && _showingOtherAssets; + + final primaryPicker = args.useSingleNetworkLayout + ? SingleNetworkCurrencyPicker( + args: args, + onSendAnotherAsset: otherAssets == null ? null : () => _showOtherAssets(true), + ) + : MultiNetworkCurrencyPicker(args: args); + + return PopScope( + canPop: !showingOtherAssets, + onPopInvokedWithResult: (didPop, _) { + if (!didPop) { + _showOtherAssets(false); + } + }, + child: Padding( + padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), + child: Container( + decoration: BoxDecoration( + borderRadius: const BorderRadius.vertical(top: Radius.circular(24)), + color: colors.surface, + ), + child: SafeArea( + top: false, + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + ModalTopBar( + title: S.of(context).select_asset, + leadingIcon: Icon(showingOtherAssets ? Icons.arrow_back_ios_new : Icons.close), + leadingSemanticLabel: + showingOtherAssets ? S.of(context).seed_alert_back : S.of(context).close, + onLeadingPressed: showingOtherAssets + ? () => _showOtherAssets(false) + : () => Navigator.of(context).maybePop(), + ), + Expanded( + child: otherAssets == null + ? primaryPicker + : IndexedStack( + index: showingOtherAssets ? 1 : 0, + sizing: StackFit.expand, + children: [ + primaryPicker, + MultiNetworkCurrencyPicker(args: otherAssets), + ], + ), + ), + ], + ), ), ), ), diff --git a/lib/new-ui/widgets/currency_picker/multi_network_currency_picker.dart b/lib/new-ui/widgets/currency_picker/multi_network_currency_picker.dart index ffea261d23..c4af80bfd0 100644 --- a/lib/new-ui/widgets/currency_picker/multi_network_currency_picker.dart +++ b/lib/new-ui/widgets/currency_picker/multi_network_currency_picker.dart @@ -2,6 +2,7 @@ import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/new-ui/widgets/coins_page/token_image_widget.dart'; import 'package:cake_wallet/new-ui/widgets/currency_picker/chain_chip_strip.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_footer.dart"; import 'package:cake_wallet/new-ui/widgets/currency_picker/picker_recents_loader.dart'; import 'package:cake_wallet/new-ui/widgets/currency_picker/currency_picker_list_container.dart'; import 'package:cake_wallet/new-ui/widgets/currency_picker/currency_picker_row.dart'; @@ -100,7 +101,7 @@ class _MultiNetworkCurrencyPickerState extends State void _selectCurrency(CryptoCurrency currency) { widget.args.onSelected(currency); - Navigator.of(context).maybePop(); + Navigator.of(context).pop(); } void _onStablecoinPillTapped(CryptoCurrency tapped) { @@ -148,6 +149,7 @@ class _MultiNetworkCurrencyPickerState extends State @override Widget build(BuildContext context) { + final footerHeight = CurrencyPickerFooter.heightFor(hasAction: false); return Column( mainAxisSize: MainAxisSize.max, children: [ @@ -158,22 +160,24 @@ class _MultiNetworkCurrencyPickerState extends State onSelected: (network) => setState(() => _selectedNetwork = network), ), Expanded( - child: _MultiNetworkPickerBody( - items: _visibleItems, - isSearching: _isSearching, - recents: _recents, - recentsLoaded: _recentsLoaded, - natives: _natives, - selected: widget.args.selected, - symbolResolver: widget.args.symbolResolver, - onSelect: _selectCurrency, - onStablecoinTap: _onStablecoinPillTapped, + child: Stack( + children: [ + _MultiNetworkPickerBody( + items: _visibleItems, + isSearching: _isSearching, + recents: _recents, + recentsLoaded: _recentsLoaded, + natives: _natives, + selected: widget.args.selected, + symbolResolver: widget.args.symbolResolver, + onSelect: _selectCurrency, + onStablecoinTap: _onStablecoinPillTapped, + footerHeight: footerHeight, + ), + CurrencyPickerFooter(searchController: _searchController), + ], ), ), - CurrencyPickerSearchField( - controller: _searchController, - hintText: S.of(context).search, - ), ], ); } @@ -190,10 +194,12 @@ class _MultiNetworkPickerBody extends StatefulWidget { required this.symbolResolver, required this.onSelect, required this.onStablecoinTap, + required this.footerHeight, }); final bool isSearching; final bool recentsLoaded; + final double footerHeight; final CryptoCurrency? selected; final List items; final List recents; @@ -275,7 +281,7 @@ class _MultiNetworkPickerBodyState extends State<_MultiNetworkPickerBody> { if (items.isEmpty) { return Center( child: Padding( - padding: const EdgeInsets.all(24), + padding: EdgeInsets.fromLTRB(24, 24, 24, widget.footerHeight), child: Text( S.of(context).picker_no_matches, textAlign: TextAlign.center, @@ -294,7 +300,7 @@ class _MultiNetworkPickerBodyState extends State<_MultiNetworkPickerBody> { controller: _scrollController, primary: false, physics: const ClampingScrollPhysics(), - padding: const EdgeInsets.fromLTRB(16, 8, 16, 16), + padding: EdgeInsets.fromLTRB(16, 8, 16, widget.footerHeight), children: [ CurrencyPickerListContainer( rows: [ @@ -351,7 +357,7 @@ class _MultiNetworkPickerBodyState extends State<_MultiNetworkPickerBody> { controller: _scrollController, primary: false, physics: const ClampingScrollPhysics(), - padding: const EdgeInsets.fromLTRB(16, 8, 16, 16), + padding: EdgeInsets.fromLTRB(16, 8, 16, widget.footerHeight), children: [ if (recentsLoaded && visibleRecents.isNotEmpty) _PickerSection( @@ -525,7 +531,7 @@ class _PickerSection extends StatelessWidget { children: [ PickerSectionHeader(title: title), child, - const SizedBox(height: 16), + const SizedBox(height: 20), ], ); } @@ -541,15 +547,13 @@ class _SymbolTrailing extends StatelessWidget { final String Function(CryptoCurrency) symbolResolver; @override - Widget build(BuildContext context) { - return Text( + Widget build(BuildContext context) => Text( symbolResolver(currency), style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontWeight: FontWeight.w500, + letterSpacing: -0.07, color: Theme.of(context).colorScheme.onSurfaceVariant, ), ); - } } class _SeeAllRow extends StatelessWidget { @@ -601,13 +605,12 @@ class _RecentsRow extends StatelessWidget { final void Function(CryptoCurrency) onTap; @override - Widget build(BuildContext context) { - return SizedBox( - height: 44, + Widget build(BuildContext context) => SizedBox( + height: 36, child: ListView.separated( scrollDirection: Axis.horizontal, itemCount: items.length, - separatorBuilder: (_, __) => const SizedBox(width: 8), + separatorBuilder: (_, __) => const SizedBox(width: 4), itemBuilder: (_, i) { final item = items[i]; return _RecentPill( @@ -619,7 +622,6 @@ class _RecentsRow extends StatelessWidget { }, ), ); - } } class _RecentPill extends StatelessWidget { @@ -642,7 +644,8 @@ class _RecentPill extends StatelessWidget { onTap: onTap, borderRadius: BorderRadius.circular(80), child: Container( - padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6), + height: 36, + padding: const EdgeInsets.only(left: 6, right: 10), decoration: BoxDecoration( color: colors.surfaceContainer, borderRadius: BorderRadius.circular(80), @@ -658,8 +661,9 @@ class _RecentPill extends StatelessWidget { const SizedBox(width: 8), Text( label, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontWeight: FontWeight.w600, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + fontWeight: FontWeight.w500, + letterSpacing: -0.06, ), ), ], diff --git a/lib/new-ui/widgets/currency_picker/picker_section_header.dart b/lib/new-ui/widgets/currency_picker/picker_section_header.dart index 1f75f8b34d..64b41198b9 100644 --- a/lib/new-ui/widgets/currency_picker/picker_section_header.dart +++ b/lib/new-ui/widgets/currency_picker/picker_section_header.dart @@ -6,16 +6,14 @@ class PickerSectionHeader extends StatelessWidget { final String title; @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.fromLTRB(4, 12, 4, 8), + Widget build(BuildContext context) => Padding( + padding: const EdgeInsets.only(bottom: 12), child: Text( title, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontWeight: FontWeight.w500, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + letterSpacing: -0.06, color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), ); - } } diff --git a/lib/new-ui/widgets/currency_picker/pill_grid.dart b/lib/new-ui/widgets/currency_picker/pill_grid.dart index fdcd5777a5..e5d5cae466 100644 --- a/lib/new-ui/widgets/currency_picker/pill_grid.dart +++ b/lib/new-ui/widgets/currency_picker/pill_grid.dart @@ -18,8 +18,7 @@ class PillGrid extends StatelessWidget { final String Function(CryptoCurrency c) symbolResolver; @override - Widget build(BuildContext context) { - return LayoutBuilder( + Widget build(BuildContext context) => LayoutBuilder( builder: (context, constraints) { const gap = 8.0; final cardWidth = (constraints.maxWidth - gap) / 2; @@ -41,7 +40,6 @@ class PillGrid extends StatelessWidget { ); }, ); - } } class _PillCard extends StatelessWidget { @@ -62,12 +60,13 @@ class _PillCard extends StatelessWidget { final colors = Theme.of(context).colorScheme; return InkWell( onTap: onTap, - borderRadius: BorderRadius.circular(80), + borderRadius: BorderRadius.circular(20), child: Container( - padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10), + height: 36, + padding: const EdgeInsets.only(left: 6, right: 8), decoration: BoxDecoration( color: colors.surfaceContainer, - borderRadius: BorderRadius.circular(80), + borderRadius: BorderRadius.circular(20), border: isSelected ? Border.all(color: colors.primary, width: 1.5) : null, ), child: Row( @@ -81,15 +80,23 @@ class _PillCard extends StatelessWidget { child: Text( label, overflow: TextOverflow.ellipsis, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontWeight: FontWeight.w600, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + fontWeight: FontWeight.w500, + letterSpacing: -0.06, ), ), ), - Icon( - Icons.chevron_right, - size: 18, - color: colors.onSurfaceVariant, + SizedBox( + width: 12, + height: 12, + child: Center( + child: CakeImageWidget( + imageUrl: "assets/new-ui/arrow_right.svg", + width: 5, + height: 9, + colorFilter: ColorFilter.mode(colors.onSurfaceVariant, BlendMode.srcIn), + ), + ), ), ], ), diff --git a/lib/new-ui/widgets/currency_picker/single_network_currency_picker.dart b/lib/new-ui/widgets/currency_picker/single_network_currency_picker.dart index a6fd378d6f..2b3bcea261 100644 --- a/lib/new-ui/widgets/currency_picker/single_network_currency_picker.dart +++ b/lib/new-ui/widgets/currency_picker/single_network_currency_picker.dart @@ -1,10 +1,12 @@ import "package:cake_wallet/generated/i18n.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_footer.dart"; import "package:cake_wallet/new-ui/widgets/currency_picker/currency_picker_list_container.dart"; import "package:cake_wallet/new-ui/widgets/currency_picker/currency_picker_row.dart"; import "package:cake_wallet/new-ui/widgets/currency_picker/currency_picker_search_field.dart"; import "package:cake_wallet/new-ui/widgets/currency_picker/picker_section_header.dart"; import "package:cake_wallet/reactions/wallet_utils.dart"; +import "package:cake_wallet/src/widgets/cake_image_widget.dart"; import "package:cw_core/crypto_currency.dart"; import "package:cw_core/currency_for_wallet_type.dart"; import "package:cw_core/wallet_type.dart"; @@ -13,10 +15,12 @@ import "package:flutter/material.dart"; class SingleNetworkCurrencyPicker extends StatefulWidget { const SingleNetworkCurrencyPicker({ required this.args, + this.onSendAnotherAsset, super.key, }); final CurrencyPickerArgs args; + final VoidCallback? onSendAnotherAsset; @override State createState() => _SingleNetworkCurrencyPickerState(); @@ -44,9 +48,8 @@ class _SingleNetworkCurrencyPickerState extends State balanceForAsset(_args.balanceByAsset, c); - - double _fiatValueFor(CryptoCurrency c) => _balanceFor(c)?.fiatValue ?? 0; + double _fiatValueFor(CryptoCurrency c) => + balanceForAsset(_args.balanceByAsset, c)?.fiatValue ?? 0; @override Widget build(BuildContext context) { @@ -72,93 +75,144 @@ class _SingleNetworkCurrencyPickerState extends State _selectCurrency(native), - ), - ], - ), - const SizedBox(height: 16), - ], - if (tokens.isNotEmpty) ...[ - PickerSectionHeader( - title: S - .of(context) - .picker_section_tokens_standard(tokenStandardFor(_network)), - ), - CurrencyPickerListContainer( - rows: [ - for (final t in tokens) - CurrencyPickerRow( - currency: t, - isSelected: _args.selected == t, - trailing: _BalanceTrailing(balance: _balanceFor(t)), - onTap: () => _selectCurrency(t), - ), - ], - ), - ], - ] - : [ - CurrencyPickerListContainer( - rows: [ - if (nativeMatches) - CurrencyPickerRow( - currency: native, - isSelected: _args.selected == native, - trailing: _BalanceTrailing(balance: _balanceFor(native)), - onTap: () => _selectCurrency(native), - ), - for (final t in tokens) - CurrencyPickerRow( - currency: t, - isSelected: _args.selected == t, - trailing: _BalanceTrailing(balance: _balanceFor(t)), - onTap: () => _selectCurrency(t), - ), - ], - ), + (nativeMatches || tokens.isNotEmpty) + ? ListView( + padding: EdgeInsets.fromLTRB(16, 8, 16, footerHeight), + children: [ + if (walletName != null) ...[ + _FromWalletHeader(walletName: walletName), + const SizedBox(height: 24), + ], + if (hasTokens(_network)) ...[ + if (nativeMatches) ...[ + PickerSectionHeader(title: S.of(context).picker_section_gas_token), + CurrencyPickerListContainer( + rows: [ + _WalletAssetRow(args: _args, currency: native, onTap: _selectCurrency), + ], + ), + const SizedBox(height: 24), + ], + if (tokens.isNotEmpty) ...[ + PickerSectionHeader( + title: S + .of(context) + .picker_section_tokens_standard(tokenStandardFor(_network)), + ), + CurrencyPickerListContainer( + rows: [ + for (final t in tokens) + _WalletAssetRow(args: _args, currency: t, onTap: _selectCurrency), ], - ) - : Center( - child: Padding( - padding: const EdgeInsets.all(24), - child: Text( - S.of(context).picker_no_matches, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), + ), + ], + ] else + CurrencyPickerListContainer( + rows: [ + if (nativeMatches) + _WalletAssetRow(args: _args, currency: native, onTap: _selectCurrency), + for (final t in tokens) + _WalletAssetRow(args: _args, currency: t, onTap: _selectCurrency), + ], ), + ], + ) + : Padding( + padding: EdgeInsets.fromLTRB(24, 24, 24, footerHeight), + child: Center( + child: Text( + S.of(context).picker_no_matches, + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.bodyMedium?.copyWith( + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), ), ), - ), - CurrencyPickerSearchField( - controller: _searchController, - hintText: S.of(context).search, + ), + CurrencyPickerFooter( + searchController: _searchController, + action: onSendAnotherAsset == null + ? null + : _SendAnotherAssetButton(onTap: onSendAnotherAsset), ), ], ); } } +class _FromWalletHeader extends StatelessWidget { + const _FromWalletHeader({required this.walletName}); + + final String walletName; + + @override + Widget build(BuildContext context) => MergeSemantics( + child: Row( + children: [ + Text( + S.of(context).from, + style: Theme.of(context).textTheme.bodySmall?.copyWith(letterSpacing: -0.06), + ), + const SizedBox(width: 8), + ExcludeSemantics( + child: CakeImageWidget( + imageUrl: "assets/new-ui/wallet_filled.svg", + width: 16, + height: 16, + colorFilter: ColorFilter.mode( + Theme.of(context).colorScheme.onSurfaceVariant, BlendMode.srcIn), + ), + ), + const SizedBox(width: 8), + Flexible( + child: Text( + walletName, + overflow: TextOverflow.ellipsis, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + fontWeight: FontWeight.w500, + letterSpacing: -0.06, + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + ), + ), + ], + ), + ); +} + +class _WalletAssetRow extends StatelessWidget { + const _WalletAssetRow({ + required this.args, + required this.currency, + required this.onTap, + }); + + final CurrencyPickerArgs args; + final CryptoCurrency currency; + final void Function(CryptoCurrency) onTap; + + @override + Widget build(BuildContext context) { + final network = args.filterByNetwork!; + final chainName = chainNameForCurrency(currency); + return CurrencyPickerRow( + currency: currency, + isSelected: args.selected == currency, + subtitle: args.symbolResolver(currency), + chainPillLabel: chainName == walletTypeToString(network) ? null : chainName, + chainBadgePath: currency.chainIconPath ?? walletTypeToCryptoCurrency(network).chainIconPath, + trailing: _BalanceTrailing(balance: balanceForAsset(args.balanceByAsset, currency)), + onTap: () => onTap(currency), + ); + } +} + class _BalanceTrailing extends StatelessWidget { const _BalanceTrailing({required this.balance}); @@ -167,30 +221,69 @@ class _BalanceTrailing extends StatelessWidget { @override Widget build(BuildContext context) { final colors = Theme.of(context).colorScheme; - final amount = balance?.amount ?? "—"; final fiat = balance?.fiat; return Column( crossAxisAlignment: CrossAxisAlignment.end, mainAxisSize: MainAxisSize.min, children: [ Text( - amount, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontWeight: FontWeight.w500, - ), + balance?.amount ?? "—", + style: Theme.of(context).textTheme.bodySmall?.copyWith(letterSpacing: -0.06), ), - if (fiat != null && fiat.isNotEmpty) - Padding( - padding: const EdgeInsets.only(top: 2), - child: Text( - fiat, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - fontWeight: FontWeight.w400, - color: colors.onSurfaceVariant, - ), - ), + if (fiat != null && fiat.isNotEmpty) ...[ + const SizedBox(height: 4), + Text( + fiat, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + letterSpacing: -0.06, + color: colors.onSurfaceVariant, + ), ), + ], ], ); } } + +class _SendAnotherAssetButton extends StatelessWidget { + const _SendAnotherAssetButton({required this.onTap}); + + final VoidCallback onTap; + + @override + Widget build(BuildContext context) => MergeSemantics( + child: Semantics( + button: true, + child: Material( + color: Theme.of(context).colorScheme.surfaceContainer, + borderRadius: BorderRadius.circular(16), + child: InkWell( + onTap: onTap, + borderRadius: BorderRadius.circular(16), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ExcludeSemantics( + child: CakeImageWidget( + imageUrl: "assets/new-ui/send_another_asset.svg", + width: 24, + height: 24, + colorFilter: + ColorFilter.mode(Theme.of(context).colorScheme.primary, BlendMode.srcIn), + ), + ), + const SizedBox(width: 10), + Text( + S.of(context).send_another_asset, + style: Theme.of(context).textTheme.bodyMedium?.copyWith( + letterSpacing: -0.07, + color: Theme.of(context).colorScheme.primary, + ), + ), + ], + ), + ), + ), + ), + ); +} diff --git a/lib/new-ui/widgets/send_page/l2_action_wallet_selector.dart b/lib/new-ui/widgets/send_page/l2_action_wallet_selector.dart index e9aac029df..6d5b105a56 100644 --- a/lib/new-ui/widgets/send_page/l2_action_wallet_selector.dart +++ b/lib/new-ui/widgets/send_page/l2_action_wallet_selector.dart @@ -354,8 +354,7 @@ class WalletRow extends StatelessWidget { final bool? isSelected; @override - Widget build(BuildContext context) { - return Container( + Widget build(BuildContext context) => Container( height: isCurrent ? 64 : 48, decoration: BoxDecoration( color: Theme.of(context).colorScheme.surfaceContainer, @@ -397,9 +396,20 @@ class WalletRow extends StatelessWidget { ), isSelected != null ? NewSimpleCheckbox(value: isSelected!, onChanged: (val) {}) - : Icon( - Icons.chevron_right, - color: Theme.of(context).colorScheme.onSurfaceVariant, + : SizedBox( + width: 16, + height: 16, + child: Center( + child: CakeImageWidget( + imageUrl: "assets/new-ui/arrow_right.svg", + width: 7, + height: 12, + colorFilter: ColorFilter.mode( + Theme.of(context).colorScheme.onSurfaceVariant, + BlendMode.srcIn, + ), + ), + ), ) ], ), @@ -407,5 +417,4 @@ class WalletRow extends StatelessWidget { ), ), ); - } } diff --git a/lib/new-ui/widgets/swap_page/swap_address_selection_modal.dart b/lib/new-ui/widgets/swap_page/swap_address_selection_modal.dart index 8c6d83498b..22a8b0abdc 100644 --- a/lib/new-ui/widgets/swap_page/swap_address_selection_modal.dart +++ b/lib/new-ui/widgets/swap_page/swap_address_selection_modal.dart @@ -1,5 +1,6 @@ import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart'; +import "package:cake_wallet/new-ui/widgets/send_page/l2_action_wallet_selector.dart"; import 'package:cake_wallet/new-ui/widgets/send_page/send_address_input.dart'; import 'package:cake_wallet/src/widgets/cake_image_widget.dart'; import 'package:cake_wallet/src/widgets/new_list_row/new_simple_checkbox.dart'; @@ -70,155 +71,185 @@ class _SwapAddressSelectionModalState extends State { if (!_itemsLoaded) return SizedBox.shrink(); return Container( - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.surface, - borderRadius: BorderRadius.vertical(top: Radius.circular(16))), - child: SafeArea( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - ModalTopBar( - title: widget.isSelectingReceiver - ? "${S.of(context).receive_to}..." - : "${S.of(context).send_from}...", - leadingIcon: Icon(Icons.close), - leadingSemanticLabel: S.of(context).close, - onLeadingPressed: Navigator.of(context).pop, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surface, + borderRadius: BorderRadius.vertical(top: Radius.circular(24))), + child: SafeArea( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + ModalTopBar( + title: widget.isSelectingReceiver + ? "${S.of(context).receive_to}..." + : "${S.of(context).send_from}...", + leadingIcon: Icon(Icons.close), + leadingSemanticLabel: S.of(context).close, + onLeadingPressed: Navigator.of(context).pop, + ), + if (!widget.isSelectingReceiver && items.isNotEmpty) + Padding( + padding: const EdgeInsets.fromLTRB(18, 0, 18, 6), + child: Align( + alignment: AlignmentDirectional.centerStart, + child: Text( + S.of(context).available_wallets, + style: Theme.of(context).textTheme.bodyMedium?.copyWith( + letterSpacing: -0.07, + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + ), + ), ), - Flexible( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 18.0), - child: items.isEmpty - ? Center( - child: Text( - "${S.of(context).no_wallets_for} ${widget.isSelectingReceiver ? currency.fullName : currency.fullName}.", - style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant), - )) - : ListView.builder( - padding: EdgeInsets.only(bottom: 12), - shrinkWrap: true, - controller: ModalScrollController.of(context), - itemCount: items.length, - itemBuilder: (context, index) { - final item = items[index]; + Flexible( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 18.0), + child: items.isEmpty + ? Center( + child: Text( + "${S.of(context).no_wallets_for} ${currency.fullName}.", + style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant), + )) + : ListView.builder( + padding: EdgeInsets.only(bottom: 12), + shrinkWrap: true, + controller: ModalScrollController.of(context), + itemCount: items.length, + itemBuilder: (context, index) { + final item = items[index]; - late final bool selected; - if (widget.isSelectingReceiver) { - selected = widget.exchangeViewModel.receiveAddress == item.address; - } else { - selected = widget.exchangeViewModel.wallet.name == item.name && - !widget.exchangeViewModel.isSendFromExternal; - } - - final String currencyIconPath = - getCryptoCurrencyIconForWalletListItem(item.type); - - final bool hasAccounts = - item.type == WalletType.monero && widget.isSelectingReceiver; - - List? accounts = - hasAccounts ? this.accounts[item.id] : null; + final String currencyIconPath = + getCryptoCurrencyIconForWalletListItem(item.type); + if (!widget.isSelectingReceiver) { return Padding( padding: const EdgeInsets.symmetric(vertical: 6.0), - child: SwapAddressSelectionModalRow( - wallet: item, - iconPath: currencyIconPath, - isSelected: selected, - accounts: accounts, - onAddressChosen: (address, accountName) { - Navigator.of(context).pop(SwapAddressSelectionResult( - address: address, + child: WalletRow( + currencyIconPath: currencyIconPath, + walletName: item.name, + onTap: () { + Navigator.of(context).pop( + SwapAddressSelectionResult( + address: item.address, walletInfo: item, - accountName: accountName)); + accountName: null, + ), + ); }, ), ); - }, - ), - ), - ), - Container( - height: 1, - color: Theme.of(context).colorScheme.surfaceContainerHigh, - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 18), - child: !widget.isSelectingReceiver - ? GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - Navigator.of(context).pop(SwapAddressSelectionResult()); + } + + final bool hasAccounts = item.type == WalletType.monero; + + List? accounts = + hasAccounts ? this.accounts[item.id] : null; + + return Padding( + padding: const EdgeInsets.symmetric(vertical: 6), + child: SwapAddressSelectionModalRow( + wallet: item, + iconPath: currencyIconPath, + isSelected: widget.exchangeViewModel.receiveAddress == item.address, + accounts: accounts, + onAddressChosen: (address, accountName) { + Navigator.of(context).pop( + SwapAddressSelectionResult( + address: address, + walletInfo: item, + accountName: accountName, + ), + ); + }, + ), + ); }, - child: Container( - height: 64, - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.surfaceContainer, - borderRadius: BorderRadius.circular(16)), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - spacing: 10, - children: [ - CakeImageWidget( - imageUrl: "assets/new-ui/send_from_external.svg", - colorFilter: ColorFilter.mode( - Theme.of(context).colorScheme.primary, BlendMode.srcIn)), - Text(S.of(context).send_from_external, - style: TextStyle( - fontSize: 15, - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.primary)) - ], - ), + ), + ), + ), + Container( + height: 1, + color: Theme.of(context).colorScheme.surfaceContainerHigh, + ), + Padding( + padding: !widget.isSelectingReceiver + ? const EdgeInsets.fromLTRB(18, 24, 18, 32) + : const EdgeInsets.symmetric(horizontal: 24.0, vertical: 18), + child: !widget.isSelectingReceiver + ? GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () { + Navigator.of(context).pop(SwapAddressSelectionResult()); + }, + child: Container( + height: 55, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surfaceContainer, + borderRadius: BorderRadius.circular(16)), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 10, + children: [ + CakeImageWidget( + imageUrl: "assets/new-ui/send_from_external.svg", + colorFilter: ColorFilter.mode( + Theme.of(context).colorScheme.primary, BlendMode.srcIn)), + Text(S.of(context).send_from_external, + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.w500, + color: Theme.of(context).colorScheme.primary)) + ], ), - ) - : Row( - children: [ - Flexible( - child: NewSendAddressInput( - addressController: addressController, - selectedCurrency: widget.exchangeViewModel.receiveCurrency, - onEditingComplete: () {}, - bottomPadding: true, - ), + ), + ) + : Row( + children: [ + Flexible( + child: NewSendAddressInput( + addressController: addressController, + selectedCurrency: widget.exchangeViewModel.receiveCurrency, + onEditingComplete: () {}, + bottomPadding: true, ), - AnimatedScale( - alignment: Alignment.centerLeft, - scale: textEntered ? 1.0 : 0.0, - duration: const Duration(milliseconds: 200), - curve: Curves.easeOutCubic, - child: Row( - children: [ - SizedBox(width: textEntered ? 8 : 0), - GestureDetector( - onTap: () { - Navigator.of(context).pop(SwapAddressSelectionResult( - address: addressController.text)); - }, - child: AnimatedContainer( - duration: const Duration(milliseconds: 200), - curve: Curves.easeOutCubic, - width: textEntered ? 48 : 0, - height: 48, - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.primary, - shape: BoxShape.circle, - ), - child: Icon( - Icons.arrow_forward_ios, - color: Theme.of(context).colorScheme.onPrimary, - ), + ), + AnimatedScale( + alignment: Alignment.centerLeft, + scale: textEntered ? 1.0 : 0.0, + duration: const Duration(milliseconds: 200), + curve: Curves.easeOutCubic, + child: Row( + children: [ + SizedBox(width: textEntered ? 8 : 0), + GestureDetector( + onTap: () { + Navigator.of(context).pop( + SwapAddressSelectionResult(address: addressController.text)); + }, + child: AnimatedContainer( + duration: const Duration(milliseconds: 200), + curve: Curves.easeOutCubic, + width: textEntered ? 48 : 0, + height: 48, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.primary, + shape: BoxShape.circle, + ), + child: Icon( + Icons.arrow_forward_ios, + color: Theme.of(context).colorScheme.onPrimary, ), ), - ], - ), - ) - ], - ), - ) - ], - ), - )); + ), + ], + ), + ) + ], + ), + ) + ], + ), + ), + ); } } diff --git a/lib/new-ui/widgets/swap_page/swap_amount_box.dart b/lib/new-ui/widgets/swap_page/swap_amount_box.dart index 784dbd4ef8..ba70325cde 100644 --- a/lib/new-ui/widgets/swap_page/swap_amount_box.dart +++ b/lib/new-ui/widgets/swap_page/swap_amount_box.dart @@ -147,8 +147,6 @@ class SwapAmountBoxState extends State { ? _getCurrencyChainIconPath(widget.currency as CryptoCurrency) : null; - final colors = Theme.of(context).colorScheme; - if (widget.sourceSelectorMode) { return SwapSourceSelector( currencyIconPath: widget.currency.iconPath ?? "", @@ -553,28 +551,15 @@ class SwapAmountBoxState extends State { return address; } - void _presentCurrencyPicker() { - final rawCurrencies = widget.isReceiverCard - ? widget.exchangeViewModel.receiveCurrencies - : widget.exchangeViewModel.depositCurrencies; - final currencies = rawCurrencies.whereType().toList(); + Future _presentCurrencyPicker() async { + final currencies = _pickableAssets( + widget.isReceiverCard + ? widget.exchangeViewModel.receiveCurrencies + : widget.exchangeViewModel.depositCurrencies, + ); final restrictToCurrentBalances = !widget.isReceiverCard && widget.balanceByAsset != null && widget.balanceByAsset!.isNotEmpty; - if (!restrictToCurrentBalances) { - appendEvmDefaultTokens(currencies); - } - if (widget.exchangeViewModel.wallet.type == WalletType.bitcoin) { - currencies.sort((a, b) { - if (a == CryptoCurrency.btcln) { - return -1; - } - if (b == CryptoCurrency.btcln) { - return 1; - } - return 0; - }); - } List items = currencies; if (restrictToCurrentBalances) { @@ -589,15 +574,29 @@ class SwapAmountBoxState extends State { items = items.where((c) => cryptoCurrencyOrTokenToWalletType(c) == network).toList(); } - if (items.length <= 1) { - return; - } - final selected = widget.isReceiverCard ? widget.exchangeViewModel.receiveCurrency : widget.exchangeViewModel.depositCurrency; - CurrencyPickerSheet.show( + CryptoCurrency? otherAsset; + final otherAssets = _canSendFromOtherSource + ? CurrencyPickerArgs( + items: _pickableAssets(widget.exchangeViewModel.depositCurrencies), + selected: selected, + recentsSource: RecentsSource.trades, + onSelected: (currency) { + widget.onCurrencySelected(currency); + otherAsset = currency; + }, + symbolResolver: widget.exchangeViewModel.amountParsingProxy.getCryptoSymbol, + ) + : null; + + if (items.length <= 1 && otherAssets == null) { + return; + } + + await CurrencyPickerSheet.show( context: context, args: CurrencyPickerArgs( items: items, @@ -608,8 +607,42 @@ class SwapAmountBoxState extends State { recentsSource: RecentsSource.trades, onSelected: widget.onCurrencySelected, symbolResolver: widget.exchangeViewModel.amountParsingProxy.getCryptoSymbol, + walletName: widget.walletName, + otherAssets: otherAssets, ), ); + + if (otherAsset == null || !mounted) { + return; + } + await _promptSourceWallet(); + } + + bool get _canSendFromOtherSource => !widget.isReceiverCard && !widget.sourceSelectorMode; + + List _pickableAssets(List currencies) { + final assets = currencies.whereType().toList(); + appendEvmDefaultTokens(assets); + if (widget.exchangeViewModel.wallet.type == WalletType.bitcoin) { + assets.sort((a, b) { + if (a == CryptoCurrency.btcln) { + return -1; + } + if (b == CryptoCurrency.btcln) { + return 1; + } + return 0; + }); + } + return assets; + } + + Future _promptSourceWallet() async { + final wallets = await widget.exchangeViewModel.depositWallets; + if (!mounted || wallets.isEmpty) { + return; + } + await _presentWalletPicker(); } Future _presentQRScanner(BuildContext context) async { @@ -632,7 +665,7 @@ class SwapAmountBoxState extends State { } catch (_) {} } - void _presentWalletPicker() async { + Future _presentWalletPicker() async { final res = await showMaterialModalBottomSheet( context: context, backgroundColor: Colors.transparent, @@ -677,8 +710,16 @@ class SwapAmountBoxState extends State { if (wallet == null) { return; } - widget.exchangeViewModel.depositAddress = wallet.address; - addressController.text = _normalizeAddressFormat(wallet.address); + final isLoadedWallet = wallet.name == widget.exchangeViewModel.wallet.name && + wallet.type == widget.exchangeViewModel.wallet.type; + final address = isLoadedWallet + ? widget.exchangeViewModel.wallet.walletAddresses.addressForExchange + : wallet.address; + widget.exchangeViewModel.depositAddress = address; + addressController.text = _normalizeAddressFormat(address); + if (isLoadedWallet) { + return; + } widget.walletSwitcherViewModel.selectWallet(wallet); await widget.walletSwitcherViewModel.switchToSelectedWallet(); } diff --git a/lib/view_model/exchange/exchange_view_model.dart b/lib/view_model/exchange/exchange_view_model.dart index 5b6ee9e102..e5a8160ecf 100644 --- a/lib/view_model/exchange/exchange_view_model.dart +++ b/lib/view_model/exchange/exchange_view_model.dart @@ -472,11 +472,11 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with } catch (_) {} } - if (type != null) { - return await WalletInfo.selectList("type = ?", [type.index]); + if (type == null) { + return []; } - return await WalletInfo.getAll(); + return WalletInfo.selectList("type = ?", [type.index]); } @action diff --git a/res/pictures/send_another_asset.svg b/res/pictures/send_another_asset.svg new file mode 100644 index 0000000000..b6709fd87a --- /dev/null +++ b/res/pictures/send_another_asset.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb index 81497576e3..8760f348f2 100644 --- a/res/values/strings_ar.arb +++ b/res/values/strings_ar.arb @@ -95,6 +95,7 @@ "available_balance": "الرصيد المتاح", "available_balance_description": "يشير “Available Balance” أو “Confirmed Balance” إلى الأموال التي يمكن إنفاقها فورًا. إذا ظهرت الأموال في الرصيد السفلي ولكن ليس في الرصيد العلوي، فعليك الانتظار بضع دقائق حتى تحصل الأموال الواردة على المزيد من تأكيدات الشبكة. بعد حصولها على المزيد من التأكيدات، ستصبح قابلة للإنفاق.", "available_balance_short": "المبلغ الإجمالي: ${amount}", + "available_wallets": "المحافظ المتاحة", "avg_savings": "متوسط التوفير", "avl": "AVL", "awaitDAppProcessing": "يرجى الانتظار حتى ينتهي الـ dApp من المعالجة.", @@ -1009,6 +1010,7 @@ "send": "إرسال", "send_address": "عنوان ${cryptoCurrency}", "send_amount": "المبلغ:", + "send_another_asset": "إرسال أصل آخر", "send_change_to_you": "الفكة، إليك:", "send_creating_transaction": "جارٍ إنشاء المعاملة", "send_error_currency": "لا يمكن أن تحتوي العملة إلا على أرقام", diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb index 9c5ba5e18a..7b8549386f 100644 --- a/res/values/strings_bg.arb +++ b/res/values/strings_bg.arb @@ -95,6 +95,7 @@ "available_balance": "Наличен баланс", "available_balance_description": "„Наличният баланс“ или „Потвърденият баланс“ са средства, които могат да бъдат изразходвани веднага. Ако средствата се появяват в долния баланс, но не и в горния, трябва да изчакате няколко минути, докато входящите средства получат повече мрежови потвърждения. След като получат повече потвърждения, те ще могат да бъдат изразходвани.", "available_balance_short": "Ср.: ${amount}", + "available_wallets": "Налични портфейли", "avg_savings": "Средни спестявания", "avl": "Avl", "awaitDAppProcessing": "Моля, изчакайте dApp да завърши обработката.", @@ -1009,6 +1010,7 @@ "send": "Изпрати", "send_address": "${cryptoCurrency} адрес", "send_amount": "Сума:", + "send_another_asset": "Изпратете друг актив", "send_change_to_you": "Ресто, към вас:", "send_creating_transaction": "Създаване на транзакция", "send_error_currency": "Валутата може да съдържа само цифри", diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb index eba7717453..1cfcc56aba 100644 --- a/res/values/strings_cs.arb +++ b/res/values/strings_cs.arb @@ -95,6 +95,7 @@ "available_balance": "Dostupný zůstatek", "available_balance_description": "„Dostupný zůstatek“ nebo „Potvrzený zůstatek“ jsou prostředky, které lze okamžitě utratit. Pokud se prostředky zobrazují ve spodním zůstatku, ale ne v horním, musíte několik minut počkat, než příchozí prostředky získají více síťových potvrzení. Jakmile získají více potvrzení, bude možné je utratit.", "available_balance_short": "Avl: ${amount}", + "available_wallets": "Dostupné peněženky", "avg_savings": "Prům. úspora", "avl": "Avl", "awaitDAppProcessing": "Počkejte prosím, až dApp dokončí zpracování.", @@ -1009,6 +1010,7 @@ "send": "Odeslat", "send_address": "${cryptoCurrency} adresa", "send_amount": "Částka:", + "send_another_asset": "Pošlete další aktivum", "send_change_to_you": "Drobné, vám:", "send_creating_transaction": "Vytváření transakce", "send_error_currency": "Měna může obsahovat pouze číslice", diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index a50caead6d..fc216affb5 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -98,6 +98,7 @@ "available_balance": "Verfügbares Guthaben", "available_balance_description": "Der „Verfügbare Kontostand“ bzw. „Bestätigter Kontostand“ sind Guthaben, die sofort ausgegeben werden können. Wenn Guthaben im unteren Kontostand angezeigt wird, aber nicht im oberen, müssen Sie ein paar Minuten warten, bis die eingehenden Gelder weitere Netzwerkbestätigungen erhalten. Sobald sie mehr Bestätigungen haben, können sie ausgegeben werden.", "available_balance_short": "Durchschnitt: ${amount}", + "available_wallets": "Verfügbare Geldbörsen", "avg_savings": "Durchschn. Ersparnis", "avl": "Verf.", "awaitDAppProcessing": "Bitte warten Sie, bis die dApp die Verarbeitung abgeschlossen hat.", @@ -1036,6 +1037,7 @@ "send": "Senden", "send_address": "${cryptoCurrency}-Adresse", "send_amount": "Betrag:", + "send_another_asset": "Senden Sie ein weiteres Asset", "send_change_to_you": "Wechselgeld, an Sie:", "send_creating_transaction": "Transaktion wird erstellt", "send_error_currency": "Die Währung darf nur Zahlen enthalten", diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index 1ea0cf8a20..ea46ae9a5b 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -98,6 +98,7 @@ "available_balance": "Available Balance", "available_balance_description": "The “Available Balance” or “Confirmed Balance” are funds that can be spent immediately. If funds appear in the lower balance but not the top balance, then you must wait a few minutes for the incoming funds to get more network confirmations. After they get more confirmations, they will be spendable.", "available_balance_short": "Avl: ${amount}", + "available_wallets": "Available Wallets", "avg_savings": "Avg. Savings", "avl": "Avl", "awaitDAppProcessing": "Kindly wait for the dApp to finish processing.", @@ -1039,6 +1040,7 @@ "send": "Send", "send_address": "${cryptoCurrency} address", "send_amount": "Amount:", + "send_another_asset": "Send another asset", "send_change_to_you": "Change, to you:", "send_creating_transaction": "Creating transaction", "send_error_currency": "Currency can only contain numbers", diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 444fd55faa..9274c38d44 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -95,6 +95,7 @@ "available_balance": "Saldo disponible", "available_balance_description": "El “Saldo Disponible” o “Saldo Confirmado” son fondos que pueden gastarse de inmediato. Si los fondos aparecen en el saldo inferior pero no en el saldo superior, deberás esperar unos minutos a que los fondos entrantes obtengan más confirmaciones de la red. Una vez que tengan más confirmaciones, podrás gastarlos.", "available_balance_short": "Valor medio: ${amount}", + "available_wallets": "Carteras disponibles", "avg_savings": "Ahorro prom.", "avl": "Avl", "awaitDAppProcessing": "Espere a que la dApp termine de procesar.", @@ -1011,6 +1012,7 @@ "send": "Enviar", "send_address": "Dirección de ${cryptoCurrency}", "send_amount": "Cantidad:", + "send_another_asset": "Enviar otro activo", "send_change_to_you": "Cambio, para ti:", "send_creating_transaction": "Creando transacción", "send_error_currency": "La moneda solo puede contener números", diff --git a/res/values/strings_fa.arb b/res/values/strings_fa.arb index 5cf611d28d..94ba380c99 100644 --- a/res/values/strings_fa.arb +++ b/res/values/strings_fa.arb @@ -95,6 +95,7 @@ "available_balance": "موجودی در دسترس", "available_balance_description": "«موجودی قابل‌دسترس» یا «موجودی تأییدشده» وجوهی هستند که می‌توان بلافاصله خرج کرد.\nاگر وجوه در موجودی پایین‌تر ظاهر شوند اما در موجودی بالا نباشند، باید چند دقیقه صبر کنید تا وجوه ورودی تأییدهای شبکه بیشتری دریافت کنند.\nپس از دریافت تأییدهای بیشتر، قابل خرج کردن خواهند بود.", "available_balance_short": "Avl: ${amount}", + "available_wallets": "کیف پول های موجود", "avg_savings": "میانگین صرفه‌جویی", "avl": "Avl", "awaitDAppProcessing": "لطفاً منتظر بمانید تا پردازش dApp به پایان برسد.", @@ -1009,6 +1010,7 @@ "send": "ارسال", "send_address": "آدرس ${cryptoCurrency}", "send_amount": "مقدار:", + "send_another_asset": "یک دارایی دیگر ارسال کنید", "send_change_to_you": "باقی‌مانده، به شما:", "send_creating_transaction": "در حال ایجاد تراکنش", "send_error_currency": "واحد پول فقط می‌تواند شامل اعداد باشد", diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index f213e9751a..87070a7e91 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -95,6 +95,7 @@ "available_balance": "Solde disponible", "available_balance_description": "Le « Solde disponible » ou le « Solde confirmé » correspond aux fonds que vous pouvez dépenser immédiatement. Si des fonds apparaissent dans le solde inférieur mais pas dans le solde supérieur, vous devez attendre quelques minutes pour que les fonds entrants obtiennent davantage de confirmations sur le réseau. Une fois qu’ils auront reçu plus de confirmations, ils pourront être dépensés.", "available_balance_short": "Valeur moyenne : ${amount}", + "available_wallets": "Portefeuilles disponibles", "avg_savings": "Économies moy.", "avl": "Avl", "awaitDAppProcessing": "Veuillez patienter pendant que la dApp termine le traitement.", @@ -1009,6 +1010,7 @@ "send": "Envoyer", "send_address": "Adresse ${cryptoCurrency}", "send_amount": "Montant :", + "send_another_asset": "Envoyer un autre élément", "send_change_to_you": "Monnaie rendue, pour vous :", "send_creating_transaction": "Création de la transaction", "send_error_currency": "Le montant ne peut contenir que des chiffres", diff --git a/res/values/strings_gn.arb b/res/values/strings_gn.arb index 41ae92d9bf..3acd9d13cd 100644 --- a/res/values/strings_gn.arb +++ b/res/values/strings_gn.arb @@ -95,6 +95,7 @@ "available_balance": "Saldo ojepurukuaáva", "available_balance_description": "Pe “Available Balance” térã “Confirmed Balance” ha'e umi fondo ikatúva reipuru pya'e. Umi fondo ojehecháramo pe saldo yvýpe ha ndaha'éi pe saldo yvate gotyo, upéicharõ eha'arõ sapy'ami hag̃ua umi fondo og̃uahẽva ohupytyve hag̃ua confirmación de red. Oguerekóvo hetave confirmación, ikatúta reipuru.", "available_balance_short": "Avl: ${amount}.", + "available_wallets": "Carteras ojeguerekóva", "avg_savings": "Ñongatu mbytegua", "avl": "Avl", "awaitDAppProcessing": "Eha'arõmi pe dApp omohu'ã hag̃ua hembiapo.", @@ -1015,6 +1016,7 @@ "send": "Emondo", "send_address": "Dirección ${cryptoCurrency} rehegua", "send_amount": "Hetakue:", + "send_another_asset": "Omondo ambue bien", "send_change_to_you": "Ñemoambue, ndéve:", "send_creating_transaction": "Ojejapo hag̃ua ñembohasa", "send_error_currency": "Pe moneda ikatu oguereko papapy añoite.", diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb index 9656357c19..6cb5e14c6c 100644 --- a/res/values/strings_ha.arb +++ b/res/values/strings_ha.arb @@ -95,6 +95,7 @@ "available_balance": "Ma’aunin da ake da shi", "available_balance_description": "“Ma'aunin da ake da shi” ko “Tabbataccen Ma'auni” su ne kuɗaɗen da za a iya kashewa nan take. Idan kuɗaɗe sun bayyana a ƙananan ma'auni amma ba a babban ma'auni ba, to dole ne ku jira 'yan mintoci kaɗan domin kuɗaɗen da ke shigowa su sami ƙarin tabbaci daga hanyar sadarwa. Bayan sun sami ƙarin tabbaci, za a iya kashe su.", "available_balance_short": "Avl: ${amount}", + "available_wallets": "Akwai Wallets", "avg_savings": "Matsakaitan Ajiya", "avl": "Avl", "awaitDAppProcessing": "Da fatan za a jira dApp ya kammala sarrafawa.", @@ -1011,6 +1012,7 @@ "send": "Aika", "send_address": "Adireshin ${cryptoCurrency}", "send_amount": "Adadi:", + "send_another_asset": "Aika wani kadari", "send_change_to_you": "Ragowa, zuwa gare ku:", "send_creating_transaction": "Ana ƙirƙirar ma'amala", "send_error_currency": "Kuɗi na iya ƙunsar lambobi kawai", diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index 4e5e873710..899c928608 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -95,6 +95,7 @@ "available_balance": "उपलब्ध शेष राशि", "available_balance_description": "“Available Balance” या “Confirmed Balance” वे धनराशि हैं जिन्हें तुरंत खर्च किया जा सकता है। यदि फंड नीचे वाले बैलेंस में दिखाई देते हैं, लेकिन ऊपर वाले बैलेंस में नहीं, तो आने वाले फंड को नेटवर्क पर और अधिक पुष्टिकरण मिलने के लिए आपको कुछ मिनट इंतज़ार करना होगा। अधिक पुष्टिकरण मिलने के बाद, वे खर्च करने योग्य हो जाएंगे।", "available_balance_short": "एवीएल: ${amount}", + "available_wallets": "उपलब्ध वॉलेट", "avg_savings": "औसत बचत", "avl": "अवल", "awaitDAppProcessing": "कृपया dApp की प्रोसेसिंग पूरी होने तक प्रतीक्षा करें।", @@ -1011,6 +1012,7 @@ "send": "भेजें", "send_address": "${cryptoCurrency} पता", "send_amount": "राशि:", + "send_another_asset": "दूसरी संपत्ति भेजें", "send_change_to_you": "चेंज, आपको:", "send_creating_transaction": "लेनदेन बनाया जा रहा है", "send_error_currency": "मुद्रा में केवल संख्याएँ हो सकती हैं", diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index 5bce2b9694..4a551678aa 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -95,6 +95,7 @@ "available_balance": "Raspoloživo stanje", "available_balance_description": "“Dostupno stanje” ili “Potvrđeno stanje” su sredstva koja možete odmah potrošiti. Ako se sredstva prikazuju u donjem stanju, ali ne i u gornjem, morate pričekati nekoliko minuta da dolazna sredstva dobiju više mrežnih potvrda. Nakon što dobiju više potvrda, moći ćete ih potrošiti.", "available_balance_short": "Prosjek: ${amount}", + "available_wallets": "Dostupni novčanici", "avg_savings": "Prosj. ušteda", "avl": "Avl", "awaitDAppProcessing": "Molimo pričekajte da dApp završi s obradom.", @@ -1009,6 +1010,7 @@ "send": "Pošalji", "send_address": "${cryptoCurrency} adresa", "send_amount": "Iznos:", + "send_another_asset": "Pošalji drugo sredstvo", "send_change_to_you": "Kusur, vama:", "send_creating_transaction": "Stvaranje transakcije", "send_error_currency": "Valuta može sadržavati samo brojeve", diff --git a/res/values/strings_hy.arb b/res/values/strings_hy.arb index d9bef69ad9..38b6747ef4 100644 --- a/res/values/strings_hy.arb +++ b/res/values/strings_hy.arb @@ -95,6 +95,7 @@ "available_balance": "Հասանելի մնացորդ", "available_balance_description": "«Հասանելի մնացորդը» կամ «Հաստատված մնացորդը» միջոցներ են, որոնք կարելի է անմիջապես ծախսել։ Եթե միջոցները երևում են ստորին մնացորդում, բայց ոչ վերևի մնացորդում, ապա պետք է մի քանի րոպե սպասեք, մինչև մուտքագրվող միջոցները ստանան ավելի շատ ցանցային հաստատումներ։ Ավելի շատ հաստատումներ ստանալուց հետո դրանք հնարավոր կլինի ծախսել։", "available_balance_short": "Ավլ՝ ${amount}", + "available_wallets": "Հասանելի դրամապանակներ", "avg_savings": "Միջին խնայողություն", "avl": "Ավլ", "awaitDAppProcessing": "Խնդրում ենք սպասել, մինչև dApp-ը ավարտի մշակումը։", @@ -1009,6 +1010,7 @@ "send": "Ուղարկել", "send_address": "${cryptoCurrency} հասցե", "send_amount": "Գումար՝", + "send_another_asset": "Ուղարկեք մեկ այլ ակտիվ", "send_change_to_you": "Մանրադրամ, ձեզ:", "send_creating_transaction": "Գործարքի ստեղծում", "send_error_currency": "Արժույթը կարող է պարունակել միայն թվեր", diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb index 6186f8e891..3235e2fd25 100644 --- a/res/values/strings_id.arb +++ b/res/values/strings_id.arb @@ -95,6 +95,7 @@ "available_balance": "Saldo Tersedia", "available_balance_description": "“Saldo Tersedia” atau “Saldo Terkonfirmasi” adalah dana yang dapat langsung dibelanjakan. Jika dana muncul di saldo bawah tetapi tidak di saldo atas, maka Anda harus menunggu beberapa menit agar dana masuk mendapatkan konfirmasi jaringan tambahan. Setelah mendapatkan lebih banyak konfirmasi, dana tersebut akan dapat dibelanjakan.", "available_balance_short": "Rata-rata: ${amount}", + "available_wallets": "Dompet yang Tersedia", "avg_savings": "Rata-rata Penghematan", "avl": "Rata-rata", "awaitDAppProcessing": "Mohon tunggu hingga dApp selesai memproses.", @@ -1012,6 +1013,7 @@ "send": "Kirim", "send_address": "Alamat ${cryptoCurrency}", "send_amount": "Jumlah:", + "send_another_asset": "Kirim aset lain", "send_change_to_you": "Kembalian, untuk Anda:", "send_creating_transaction": "Membuat transaksi", "send_error_currency": "Mata uang hanya boleh berisi angka", diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index b9b5a5cb69..49837ba4eb 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -95,6 +95,7 @@ "available_balance": "Saldo disponibile", "available_balance_description": "Il “Saldo disponibile” o “Saldo confermato” sono fondi che possono essere spesi immediatamente. Se i fondi compaiono nel saldo in basso ma non in quello in alto, devi attendere qualche minuto affinché i fondi in arrivo ottengano ulteriori conferme di rete. Dopo aver ricevuto più conferme, saranno spendibili.", "available_balance_short": "Avl: ${amount}", + "available_wallets": "Portafogli disponibili", "avg_savings": "Risparmio medio", "avl": "Avl", "awaitDAppProcessing": "Attendi che la dApp completi l'elaborazione.", @@ -1010,6 +1011,7 @@ "send": "Invia", "send_address": "Indirizzo ${cryptoCurrency}", "send_amount": "Importo:", + "send_another_asset": "Invia un'altra risorsa", "send_change_to_you": "Resto, a te:", "send_creating_transaction": "Creazione della transazione", "send_error_currency": "La valuta può contenere solo numeri", diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index 3b7a4fd636..7f50e75267 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -95,6 +95,7 @@ "available_balance": "利用可能残高", "available_balance_description": "「利用可能な残高」または「承認済み残高」は、すぐに使用できる資金です。下の残高には表示されているのに上の残高に表示されない場合は、受信した資金がネットワークでさらに承認(確認)されるまで数分待つ必要があります。承認数が増えると、使用できるようになります。", "available_balance_short": "平均: ${amount}", + "available_wallets": "利用可能なウォレット", "avg_savings": "平均節約額", "avl": "アヴル", "awaitDAppProcessing": "dAppの処理が完了するまでお待ちください。", @@ -1010,6 +1011,7 @@ "send": "送信", "send_address": "${cryptoCurrency} アドレス", "send_amount": "金額:", + "send_another_asset": "別のアセットを送信する", "send_change_to_you": "お釣り(自分宛て):", "send_creating_transaction": "トランザクションを作成しています", "send_error_currency": "通貨には数字のみを含めることができます", diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index 8533a9a11f..ad5feb7347 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -95,6 +95,7 @@ "available_balance": "사용 가능 잔액", "available_balance_description": "“사용 가능 잔액” 또는 “확정 잔액”은 즉시 사용할 수 있는 자금입니다. 자금이 아래 잔액에는 표시되지만 위 잔액에는 표시되지 않는 경우, 입금된 자금이 네트워크에서 더 많은 컨펌(확인)을 받을 때까지 몇 분 정도 기다려야 합니다. 더 많은 컨펌을 받은 후에는 사용할 수 있습니다.", "available_balance_short": "평균: ${amount}", + "available_wallets": "사용 가능한 지갑", "avg_savings": "평균 절감액", "avl": "Avl", "awaitDAppProcessing": "dApp의 처리가 완료될 때까지 잠시 기다려 주세요.", @@ -1009,6 +1010,7 @@ "send": "보내기", "send_address": "${cryptoCurrency} 주소", "send_amount": "수량:", + "send_another_asset": "다른 자산 보내기", "send_change_to_you": "거스름돈, 나에게:", "send_creating_transaction": "트랜잭션 생성 중", "send_error_currency": "통화는 숫자만 포함할 수 있습니다", diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb index 4cdccba42d..0ebc6c5010 100644 --- a/res/values/strings_my.arb +++ b/res/values/strings_my.arb @@ -95,6 +95,7 @@ "available_balance": "ရရှိနိုင်သော လက်ကျန်", "available_balance_description": "“Available Balance” သို့မဟုတ် “Confirmed Balance” သည် ချက်ချင်းသုံးစွဲနိုင်သော လက်ကျန်ငွေဖြစ်သည်။ လက်ကျန်အောက်ပိုင်းတွင်သာ ဝင်လာသော်လည်း အပေါ်ပိုင်းလက်ကျန်တွင် မပေါ်သေးပါက ကွန်ယက်အတည်ပြုချက် (network confirmations) ပိုမိုရရှိရန် မိနစ်အနည်းငယ် စောင့်ရပါမည်။ အတည်ပြုချက်များ ပိုမိုရရှိပြီးနောက် ထိုငွေများကို သုံးစွဲနိုင်ပါလိမ့်မည်။", "available_balance_short": "Avl- ${amount}", + "available_wallets": "ရနိုင်သော ပိုက်ဆံအိတ်များ", "avg_savings": "ပျမ်းမျှ ချွေတာမှု", "avl": "Avl", "awaitDAppProcessing": "ကျေးဇူးပြု၍ dApp ၏ စီမံဆောင်ရွက်မှု ပြီးဆုံးသည်အထိ စောင့်ပါ။", @@ -1009,6 +1010,7 @@ "send": "ပို့ရန်", "send_address": "${cryptoCurrency} လိပ်စာ", "send_amount": "ပမာဏ:", + "send_another_asset": "အခြားပစ္စည်းကို ပို့ပါ။", "send_change_to_you": "အပြန်ငွေ (Change), သင့်ထံသို့:", "send_creating_transaction": "ငွေလွှဲလုပ်ငန်းစဉ်ကို ဖန်တီးနေသည်", "send_error_currency": "ငွေကြေးပမာဏတွင် နံပါတ်များသာ ထည့်နိုင်သည်။", diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index 2e804baec1..68e0cdb20f 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -95,6 +95,7 @@ "available_balance": "Beschikbaar saldo", "available_balance_description": "Het “Beschikbare saldo” of “Bevestigde saldo” zijn fondsen die direct kunnen worden uitgegeven. Als fondsen in het lagere saldo verschijnen maar niet in het bovenste saldo, dan moet je een paar minuten wachten tot de inkomende fondsen meer netwerkbevestigingen krijgen. Daarna kan het worden uitgegeven.", "available_balance_short": "Gem.: ${amount}", + "available_wallets": "Beschikbare portemonnees", "avg_savings": "Gem. besparingen", "avl": "Gem", "awaitDAppProcessing": "Wacht tot de dApp klaar is met verwerken.", @@ -1009,6 +1010,7 @@ "send": "Verzenden", "send_address": "${cryptoCurrency}-adres", "send_amount": "Bedrag:", + "send_another_asset": "Stuur nog een item", "send_change_to_you": "Wisselgeld, aan jou:", "send_creating_transaction": "Transactie maken", "send_error_currency": "Valuta kan alleen cijfers bevatten", diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index 082138e3d1..15ac22ec56 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -95,6 +95,7 @@ "available_balance": "Dostępne saldo", "available_balance_description": "„Dostępne saldo” lub „Potwierdzone saldo” to środki, które można wydać od razu. Jeśli środki pojawiają się w dolnym saldzie, ale nie w górnym, musisz poczekać kilka minut, aż przychodzące środki uzyskają więcej potwierdzeń sieci. Gdy uzyskają więcej potwierdzeń, będzie można je wydać.", "available_balance_short": "Średnia: ${amount}", + "available_wallets": "Dostępne portfele", "avg_savings": "Śr. oszczędności", "avl": "Avl", "awaitDAppProcessing": "Proszę poczekać, aż dApp zakończy przetwarzanie.", @@ -1009,6 +1010,7 @@ "send": "Wyślij", "send_address": "Adres ${cryptoCurrency}", "send_amount": "Kwota:", + "send_another_asset": "Wyślij kolejny zasób", "send_change_to_you": "Reszta, do Ciebie:", "send_creating_transaction": "Tworzenie transakcji", "send_error_currency": "Waluta może zawierać tylko liczby", diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index b3e100be26..3b3e04548f 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -95,6 +95,7 @@ "available_balance": "Saldo disponível", "available_balance_description": "O “Saldo Disponível” ou “Saldo Confirmado” são fundos que podem ser gastos imediatamente. Se os fundos aparecerem no saldo inferior, mas não no saldo superior, você deve aguardar alguns minutos para que os fundos recebidos obtenham mais confirmações na rede. Depois que tiverem mais confirmações, eles poderão ser gastos.", "available_balance_short": "Avl: ${amount}", + "available_wallets": "Carteiras disponíveis", "avg_savings": "Poupança média", "avl": "Avl", "awaitDAppProcessing": "Por favor, aguarde o dApp concluir o processamento.", @@ -1011,6 +1012,7 @@ "send": "Enviar", "send_address": "Endereço de ${cryptoCurrency}", "send_amount": "Valor:", + "send_another_asset": "Enviar outro ativo", "send_change_to_you": "Troco, para você:", "send_creating_transaction": "Criando transação", "send_error_currency": "A moeda só pode conter números", diff --git a/res/values/strings_pt_BR.arb b/res/values/strings_pt_BR.arb index b91f6b0ccd..d1ef0ac5c3 100644 --- a/res/values/strings_pt_BR.arb +++ b/res/values/strings_pt_BR.arb @@ -90,6 +90,7 @@ "available_balance": "Saldo disponível", "available_balance_description": "O “Saldo disponível” ou “Saldo confirmado” são fundos que podem ser gastos imediatamente. Se os fundos aparecerem no saldo inferior, mas não no saldo superior, você deve aguardar alguns minutos para que os fundos recebidos obtenham mais confirmações na rede. Depois que tiverem mais confirmações, eles poderão ser gastos.", "available_balance_short": "Avl: ${amount}", + "available_wallets": "Carteiras disponíveis", "avg_savings": "Economia média", "awaitDAppProcessing": "Aguarde até que o dApp termine de processar.", "awaiting_payment_confirmation": "Aguardando confirmação do pagamento", @@ -961,6 +962,7 @@ "send": "Enviar", "send_address": "Endereço ${cryptoCurrency}", "send_amount": "Valor:", + "send_another_asset": "Enviar outro ativo", "send_change_to_you": "Troco, para você:", "send_creating_transaction": "Criando transação", "send_error_currency": "A moeda só pode conter números", diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index 696eb803b6..7bc5c825c2 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -95,6 +95,7 @@ "available_balance": "Доступный баланс", "available_balance_description": "«Доступный баланс» или «Подтверждённый баланс» — это средства, которые можно потратить сразу. Если средства отображаются в нижнем балансе, но не в верхнем, значит, нужно подождать несколько минут, пока входящие средства получат больше подтверждений сети. После получения дополнительных подтверждений их можно будет потратить.", "available_balance_short": "Avl: ${amount}", + "available_wallets": "Доступные кошельки", "avg_savings": "Средняя экономия", "avl": "Авл", "awaitDAppProcessing": "Пожалуйста, подождите, пока dApp завершит обработку.", @@ -1010,6 +1011,7 @@ "send": "Отправить", "send_address": "${cryptoCurrency} адрес", "send_amount": "Сумма:", + "send_another_asset": "Отправить еще один актив", "send_change_to_you": "Сдача вам:", "send_creating_transaction": "Создание транзакции", "send_error_currency": "Валюта может содержать только цифры", diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb index b979ea9d52..bd6c59e853 100644 --- a/res/values/strings_th.arb +++ b/res/values/strings_th.arb @@ -95,6 +95,7 @@ "available_balance": "ยอดคงเหลือที่ใช้ได้", "available_balance_description": "“ยอดคงเหลือที่ใช้ได้” หรือ “ยอดคงเหลือที่ยืนยันแล้ว” คือเงินที่สามารถใช้จ่ายได้ทันที หากเงินปรากฏในยอดคงเหลือด้านล่างแต่ไม่ปรากฏในยอดคงเหลือด้านบน คุณต้องรอสักครู่เพื่อให้เงินที่เข้ามาได้รับการยืนยันจากเครือข่ายเพิ่มขึ้น เมื่อได้รับการยืนยันมากขึ้นแล้ว เงินนั้นจะสามารถใช้จ่ายได้", "available_balance_short": "จำนวน: ${amount}", + "available_wallets": "กระเป๋าเงินที่มีจำหน่าย", "avg_savings": "การประหยัดเฉลี่ย", "avl": "เฉลี่ย", "awaitDAppProcessing": "โปรดรอให้ dApp ประมวลผลให้เสร็จสิ้น", @@ -1009,6 +1010,7 @@ "send": "ส่ง", "send_address": "ที่อยู่ ${cryptoCurrency}", "send_amount": "จำนวน:", + "send_another_asset": "ส่งทรัพย์สินอีก", "send_change_to_you": "เงินทอน ส่งกลับให้คุณ:", "send_creating_transaction": "กำลังสร้างธุรกรรม", "send_error_currency": "สกุลเงินต้องมีเฉพาะตัวเลขเท่านั้น", diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb index 7582cbe83d..60d5719b0f 100644 --- a/res/values/strings_tl.arb +++ b/res/values/strings_tl.arb @@ -95,6 +95,7 @@ "available_balance": "Magagamit na Balanse", "available_balance_description": "Ang “Magagamit na Balanse” o “Nakumpirmang Balanse” ay mga pondong maaari nang gastusin kaagad. Kung lumalabas ang mga pondo sa mas mababang balanse ngunit wala sa itaas na balanse, kailangan mong maghintay ng ilang minuto para makakuha ng mas maraming kumpirmasyon sa network ang mga papasok na pondo. Kapag nakakuha na sila ng mas maraming kumpirmasyon, maaari na silang gastusin.", "available_balance_short": "Avl: ${amount}", + "available_wallets": "Magagamit na mga Wallet", "avg_savings": "Avg. Matitipid", "avl": "Avl", "awaitDAppProcessing": "Mangyaring maghintay hanggang matapos ang pagproseso ng dApp.", @@ -1009,6 +1010,7 @@ "send": "Ipadala", "send_address": "${cryptoCurrency} address", "send_amount": "Halaga:", + "send_another_asset": "Magpadala ng isa pang asset", "send_change_to_you": "Sukli, sa iyo:", "send_creating_transaction": "Ginagawa ang transaksyon", "send_error_currency": "Ang currency ay maaari lamang maglaman ng mga numero", diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb index b4ecc86dea..b1499dd8eb 100644 --- a/res/values/strings_tr.arb +++ b/res/values/strings_tr.arb @@ -95,6 +95,7 @@ "available_balance": "Kullanılabilir Bakiye", "available_balance_description": "“Kullanılabilir Bakiye” veya “Onaylanmış Bakiye”, hemen harcanabilen fonlardır. Fonlar alt bakiyede görünüp üst bakiyede görünmüyorsa, gelen fonların ağda daha fazla onay alması için birkaç dakika beklemeniz gerekir. Daha fazla onay aldıktan sonra harcanabilir olacaktır.", "available_balance_short": "Ortalama: ${amount}", + "available_wallets": "Mevcut Cüzdanlar", "avg_savings": "Ort. Tasarruf", "avl": "Avl", "awaitDAppProcessing": "Lütfen dApp'in işlemi tamamlamasını bekleyin.", @@ -1009,6 +1010,7 @@ "send": "Gönder", "send_address": "${cryptoCurrency} adresi", "send_amount": "Miktar:", + "send_another_asset": "Başka bir varlık gönder", "send_change_to_you": "Para üstü, size:", "send_creating_transaction": "İşlem oluşturuluyor", "send_error_currency": "Para birimi yalnızca sayılardan oluşabilir", diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index 3c75634556..37ea1637c2 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -95,6 +95,7 @@ "available_balance": "Доступний баланс", "available_balance_description": "«Доступний баланс» або «Підтверджений баланс» — це кошти, які можна витратити негайно. Якщо кошти відображаються в нижньому балансі, але не у верхньому, потрібно зачекати кілька хвилин, доки вхідні кошти отримають більше підтверджень мережі. Після отримання додаткових підтверджень їх можна буде витратити.", "available_balance_short": "Середня сума: ${amount}", + "available_wallets": "Доступні гаманці", "avg_savings": "Сер. заощадження", "avl": "Avl", "awaitDAppProcessing": "Будь ласка, зачекайте, доки dApp завершить обробку.", @@ -1010,6 +1011,7 @@ "send": "Надіслати", "send_address": "${cryptoCurrency} адреса", "send_amount": "Сума:", + "send_another_asset": "Надіслати інший актив", "send_change_to_you": "Решта, вам:", "send_creating_transaction": "Створення транзакції", "send_error_currency": "Валюта може містити лише цифри", diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb index ec60f8ce13..cc52dcad9d 100644 --- a/res/values/strings_ur.arb +++ b/res/values/strings_ur.arb @@ -95,6 +95,7 @@ "available_balance": "دستیاب بیلنس", "available_balance_description": "”دستیاب بیلنس” یا ”تصدیق شدہ بیلنس” وہ فنڈز ہیں جنہیں فوراً خرچ کیا جا سکتا ہے۔ اگر فنڈز نیچے والے بیلنس میں نظر آئیں لیکن اوپر والے بیلنس میں نہیں، تو آپ کو آنے والے فنڈز کے مزید نیٹ ورک کنفرمیشنز حاصل ہونے کے لیے چند منٹ انتظار کرنا ہوگا۔ جب انہیں مزید کنفرمیشنز مل جائیں گی تو وہ خرچ کے قابل ہو جائیں گے۔", "available_balance_short": "Avl: ${amount}", + "available_wallets": "دستیاب بٹوے", "avg_savings": "اوسط بچت", "avl": "Avl", "awaitDAppProcessing": "براہِ کرم dApp کی پروسیسنگ مکمل ہونے تک انتظار کریں۔", @@ -1011,6 +1012,7 @@ "send": "بھیجیں", "send_address": "${cryptoCurrency} ایڈریس", "send_amount": "رقم:", + "send_another_asset": "دوسرا اثاثہ بھیجیں۔", "send_change_to_you": "بقایا، آپ کو:", "send_creating_transaction": "ٹرانزیکشن بنائی جا رہی ہے", "send_error_currency": "کرنسی میں صرف اعداد شامل ہو سکتے ہیں۔", diff --git a/res/values/strings_vi.arb b/res/values/strings_vi.arb index d6506bbd1b..9080c4e74e 100644 --- a/res/values/strings_vi.arb +++ b/res/values/strings_vi.arb @@ -95,6 +95,7 @@ "available_balance": "Số dư khả dụng", "available_balance_description": "“Số dư khả dụng” hoặc “Số dư đã xác nhận” là số tiền có thể chi tiêu ngay lập tức. Nếu tiền xuất hiện ở số dư phía dưới nhưng không xuất hiện ở số dư phía trên, thì bạn phải đợi vài phút để khoản tiền đến có thêm xác nhận từ mạng. Sau khi có thêm xác nhận, chúng sẽ có thể chi tiêu.", "available_balance_short": "Trung bình: ${amount}", + "available_wallets": "Ví có sẵn", "avg_savings": "Tiết kiệm TB", "avl": "trung bình", "awaitDAppProcessing": "Vui lòng đợi dApp xử lý xong.", @@ -1010,6 +1011,7 @@ "send": "Gửi", "send_address": "Địa chỉ ${cryptoCurrency}", "send_amount": "Số lượng:", + "send_another_asset": "Gửi nội dung khác", "send_change_to_you": "Tiền thừa, gửi về bạn:", "send_creating_transaction": "Đang tạo giao dịch", "send_error_currency": "Trường tiền tệ chỉ được chứa số", diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb index f0758d0ed7..893182247d 100644 --- a/res/values/strings_yo.arb +++ b/res/values/strings_yo.arb @@ -95,6 +95,7 @@ "available_balance": "Ìwọ̀ntúnwọ̀nsì tó wà", "available_balance_description": "“Iwọntunwọnsi Wa” tabi “Iwọntunwọnsi Ti a Jẹ́rìí” jẹ́ àwọn owó tí o lè na lẹ́sẹ̀kẹsẹ. Bí àwọn owó bá hàn ní iwọntunwọnsi ìsàlẹ̀ ṣùgbọ́n kì í hàn ní iwọntunwọnsi òkè, nígbà náà o gbọdọ̀ dúró fún ìṣẹ́jú díẹ̀ kí àwọn owó tí ń wọlé lè gba ìjẹ́rìí nẹ́tíwọ́ọ̀kì púpọ̀ síi. Lẹ́yìn tí wọ́n bá ti gba ìjẹ́rìí púpọ̀ síi, o lè na wọ́n.", "available_balance_short": "Avl: ${amount}", + "available_wallets": "Awọn Woleti ti o wa", "avg_savings": "Ìpamọ́ àpapọ̀", "avl": "Avl", "awaitDAppProcessing": "Jọ̀wọ́, dúró kí dApp parí ìṣiṣẹ́.", @@ -1010,6 +1011,7 @@ "send": "Fìránṣẹ́", "send_address": "Àdírẹ́sì ${cryptoCurrency}", "send_amount": "Iye:", + "send_another_asset": "Fi ohun-ini miiran ranṣẹ", "send_change_to_you": "Iyokù, sí ọ:", "send_creating_transaction": "Ń dá ìdúnàdúrà sílẹ̀", "send_error_currency": "Owo gbọdọ̀ ní àwọn nọ́mbà nìkan", diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index 9d4a11e75c..57afcb07e2 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -95,6 +95,7 @@ "available_balance": "可用余额", "available_balance_description": "“可用余额”或“确认余额”是指可立即花费的资金。如果资金显示在下方余额中但未显示在上方余额中,则需要等待几分钟,让转入资金获得更多网络确认。获得更多确认后,这些资金即可花费。", "available_balance_short": "平均价值:${amount}", + "available_wallets": "可用钱包", "avg_savings": "平均节省", "avl": "平均", "awaitDAppProcessing": "请稍候,等待 dApp 完成处理。", @@ -1010,6 +1011,7 @@ "send": "发送", "send_address": "${cryptoCurrency} 地址", "send_amount": "数量:", + "send_another_asset": "发送另一个资产", "send_change_to_you": "找零(返回给您):", "send_creating_transaction": "正在创建交易", "send_error_currency": "币种只能包含数字",