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..e42d9faa32 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,27 +574,77 @@ 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, - selected: selected, - filterByNetwork: widget.filteredNetwork, - balanceByAsset: widget.balanceByAsset, - useSingleNetworkLayout: widget.useSingleNetworkLayout, - recentsSource: RecentsSource.trades, - onSelected: widget.onCurrencySelected, - symbolResolver: widget.exchangeViewModel.amountParsingProxy.getCryptoSymbol, - ), + args: otherAssets != null && widget.exchangeViewModel.isSendFromExternal + ? otherAssets + : CurrencyPickerArgs( + items: items, + selected: selected, + filterByNetwork: widget.filteredNetwork, + balanceByAsset: widget.balanceByAsset, + useSingleNetworkLayout: widget.useSingleNetworkLayout, + 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 +667,7 @@ class SwapAmountBoxState extends State { } catch (_) {} } - void _presentWalletPicker() async { + Future _presentWalletPicker() async { final res = await showMaterialModalBottomSheet( context: context, backgroundColor: Colors.transparent, @@ -677,8 +712,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 f9129293a2..8fe5db2586 100644 --- a/res/values/strings_ar.arb +++ b/res/values/strings_ar.arb @@ -99,6 +99,7 @@ "available_balance_description": "يشير “Available Balance” أو “Confirmed Balance” إلى الأموال التي يمكن إنفاقها فورًا. إذا ظهرت الأموال في الرصيد السفلي ولكن ليس في الرصيد العلوي، فعليك الانتظار بضع دقائق حتى تحصل الأموال الواردة على المزيد من تأكيدات الشبكة. بعد حصولها على المزيد من التأكيدات، ستصبح قابلة للإنفاق.", "available_balance_short": "المبلغ الإجمالي: ${amount}", "available_providers": "مقدمي الخدمة المتاحين", + "available_wallets": "المحافظ المتاحة", "avg_savings": "متوسط التوفير", "avl": "AVL", "awaitDAppProcessing": "يرجى الانتظار حتى ينتهي الـ dApp من المعالجة.", @@ -1073,6 +1074,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 b36c284bfc..4b6c12f11d 100644 --- a/res/values/strings_bg.arb +++ b/res/values/strings_bg.arb @@ -99,6 +99,7 @@ "available_balance_description": "„Наличният баланс“ или „Потвърденият баланс“ са средства, които могат да бъдат изразходвани веднага. Ако средствата се появяват в долния баланс, но не и в горния, трябва да изчакате няколко минути, докато входящите средства получат повече мрежови потвърждения. След като получат повече потвърждения, те ще могат да бъдат изразходвани.", "available_balance_short": "Ср.: ${amount}", "available_providers": "Налични доставчици", + "available_wallets": "Налични портфейли", "avg_savings": "Средни спестявания", "avl": "Avl", "awaitDAppProcessing": "Моля, изчакайте dApp да завърши обработката.", @@ -1073,6 +1074,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 175e8ac3d1..44b39ba12d 100644 --- a/res/values/strings_cs.arb +++ b/res/values/strings_cs.arb @@ -99,6 +99,7 @@ "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_providers": "Dostupní poskytovatelé", + "available_wallets": "Dostupné peněženky", "avg_savings": "Prům. úspora", "avl": "Avl", "awaitDAppProcessing": "Počkejte prosím, až dApp dokončí zpracování.", @@ -1073,6 +1074,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 0630e9474b..9dc9c2c47c 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -99,6 +99,7 @@ "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_providers": "Verfügbare Anbieter", + "available_wallets": "Verfügbare Geldbörsen", "avg_savings": "Durchschn. Ersparnis", "avl": "Verf.", "awaitDAppProcessing": "Bitte warten Sie, bis die dApp die Verarbeitung abgeschlossen hat.", @@ -1073,6 +1074,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 574340b1e6..e16333cb63 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -99,6 +99,7 @@ "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_providers": "Available Providers", + "available_wallets": "Available Wallets", "avg_savings": "Avg. Savings", "avl": "Avl", "awaitDAppProcessing": "Kindly wait for the dApp to finish processing.", @@ -1074,6 +1075,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 42404fddcd..e81e5a429f 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -99,6 +99,7 @@ "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_providers": "Proveedores disponibles", + "available_wallets": "Carteras disponibles", "avg_savings": "Ahorro prom.", "avl": "Avl", "awaitDAppProcessing": "Espere a que la dApp termine de procesar.", @@ -1074,6 +1075,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 dfc82648d4..df53881da7 100644 --- a/res/values/strings_fa.arb +++ b/res/values/strings_fa.arb @@ -99,6 +99,7 @@ "available_balance_description": "«موجودی قابل‌دسترس» یا «موجودی تأییدشده» وجوهی هستند که می‌توان بلافاصله خرج کرد.\nاگر وجوه در موجودی پایین‌تر ظاهر شوند اما در موجودی بالا نباشند، باید چند دقیقه صبر کنید تا وجوه ورودی تأییدهای شبکه بیشتری دریافت کنند.\nپس از دریافت تأییدهای بیشتر، قابل خرج کردن خواهند بود.", "available_balance_short": "Avl: ${amount}", "available_providers": "ارائه دهندگان در دسترس", + "available_wallets": "کیف پول های موجود", "avg_savings": "میانگین صرفه‌جویی", "avl": "Avl", "awaitDAppProcessing": "لطفاً منتظر بمانید تا پردازش dApp به پایان برسد.", @@ -1073,6 +1074,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 209e7fa32c..b52492334a 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -99,6 +99,7 @@ "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_providers": "Fournisseurs disponibles", + "available_wallets": "Portefeuilles disponibles", "avg_savings": "Économies moy.", "avl": "Avl", "awaitDAppProcessing": "Veuillez patienter pendant que la dApp termine le traitement.", @@ -1073,6 +1074,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 a3b5ceef6a..71ce0558e1 100644 --- a/res/values/strings_gn.arb +++ b/res/values/strings_gn.arb @@ -99,6 +99,7 @@ "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_providers": "Umi Proveedor ojeguerekóva", + "available_wallets": "Carteras ojeguerekóva", "avg_savings": "Ñongatu mbytegua", "avl": "Avl", "awaitDAppProcessing": "Eha'arõmi pe dApp omohu'ã hag̃ua hembiapo.", @@ -1078,6 +1079,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 852f3f582a..6d3cac4599 100644 --- a/res/values/strings_ha.arb +++ b/res/values/strings_ha.arb @@ -99,6 +99,7 @@ "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_providers": "Akwai Masu Bayarwa", + "available_wallets": "Akwai Wallets", "avg_savings": "Matsakaitan Ajiya", "avl": "Avl", "awaitDAppProcessing": "Da fatan za a jira dApp ya kammala sarrafawa.", @@ -1075,6 +1076,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 f07826a1a0..d6db3e521d 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -99,6 +99,7 @@ "available_balance_description": "“Available Balance” या “Confirmed Balance” वे धनराशि हैं जिन्हें तुरंत खर्च किया जा सकता है। यदि फंड नीचे वाले बैलेंस में दिखाई देते हैं, लेकिन ऊपर वाले बैलेंस में नहीं, तो आने वाले फंड को नेटवर्क पर और अधिक पुष्टिकरण मिलने के लिए आपको कुछ मिनट इंतज़ार करना होगा। अधिक पुष्टिकरण मिलने के बाद, वे खर्च करने योग्य हो जाएंगे।", "available_balance_short": "एवीएल: ${amount}", "available_providers": "उपलब्ध प्रदाता", + "available_wallets": "उपलब्ध वॉलेट", "avg_savings": "औसत बचत", "avl": "अवल", "awaitDAppProcessing": "कृपया dApp की प्रोसेसिंग पूरी होने तक प्रतीक्षा करें।", @@ -1075,6 +1076,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 7d2dc9aca7..0db2e4846e 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -99,6 +99,7 @@ "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_providers": "Dostupni pružatelji usluga", + "available_wallets": "Dostupni novčanici", "avg_savings": "Prosj. ušteda", "avl": "Avl", "awaitDAppProcessing": "Molimo pričekajte da dApp završi s obradom.", @@ -1073,6 +1074,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 8b5a807c72..5eb9c2dbc4 100644 --- a/res/values/strings_hy.arb +++ b/res/values/strings_hy.arb @@ -99,6 +99,7 @@ "available_balance_description": "«Հասանելի մնացորդը» կամ «Հաստատված մնացորդը» միջոցներ են, որոնք կարելի է անմիջապես ծախսել։ Եթե միջոցները երևում են ստորին մնացորդում, բայց ոչ վերևի մնացորդում, ապա պետք է մի քանի րոպե սպասեք, մինչև մուտքագրվող միջոցները ստանան ավելի շատ ցանցային հաստատումներ։ Ավելի շատ հաստատումներ ստանալուց հետո դրանք հնարավոր կլինի ծախսել։", "available_balance_short": "Ավլ՝ ${amount}", "available_providers": "Հասանելի մատակարարներ", + "available_wallets": "Հասանելի դրամապանակներ", "avg_savings": "Միջին խնայողություն", "avl": "Ավլ", "awaitDAppProcessing": "Խնդրում ենք սպասել, մինչև dApp-ը ավարտի մշակումը։", @@ -1073,6 +1074,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 ee11f975a1..e6b1473a2e 100644 --- a/res/values/strings_id.arb +++ b/res/values/strings_id.arb @@ -99,6 +99,7 @@ "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_providers": "Penyedia yang Tersedia", + "available_wallets": "Dompet yang Tersedia", "avg_savings": "Rata-rata Penghematan", "avl": "Rata-rata", "awaitDAppProcessing": "Mohon tunggu hingga dApp selesai memproses.", @@ -1076,6 +1077,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 43c1b2094a..69a13c117a 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -99,6 +99,7 @@ "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_providers": "Fornitori disponibili", + "available_wallets": "Portafogli disponibili", "avg_savings": "Risparmio medio", "avl": "Avl", "awaitDAppProcessing": "Attendi che la dApp completi l'elaborazione.", @@ -1074,6 +1075,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 93a8dddd38..187fd0a0fd 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -99,6 +99,7 @@ "available_balance_description": "「利用可能な残高」または「承認済み残高」は、すぐに使用できる資金です。下の残高には表示されているのに上の残高に表示されない場合は、受信した資金がネットワークでさらに承認(確認)されるまで数分待つ必要があります。承認数が増えると、使用できるようになります。", "available_balance_short": "平均: ${amount}", "available_providers": "利用可能なプロバイダー", + "available_wallets": "利用可能なウォレット", "avg_savings": "平均節約額", "avl": "アヴル", "awaitDAppProcessing": "dAppの処理が完了するまでお待ちください。", @@ -1074,6 +1075,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 35e7b53df1..0ca8170d23 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -99,6 +99,7 @@ "available_balance_description": "“사용 가능 잔액” 또는 “확정 잔액”은 즉시 사용할 수 있는 자금입니다. 자금이 아래 잔액에는 표시되지만 위 잔액에는 표시되지 않는 경우, 입금된 자금이 네트워크에서 더 많은 컨펌(확인)을 받을 때까지 몇 분 정도 기다려야 합니다. 더 많은 컨펌을 받은 후에는 사용할 수 있습니다.", "available_balance_short": "평균: ${amount}", "available_providers": "이용 가능한 제공업체", + "available_wallets": "사용 가능한 지갑", "avg_savings": "평균 절감액", "avl": "Avl", "awaitDAppProcessing": "dApp의 처리가 완료될 때까지 잠시 기다려 주세요.", @@ -1073,6 +1074,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 63a76b8bce..bffe51623c 100644 --- a/res/values/strings_my.arb +++ b/res/values/strings_my.arb @@ -99,6 +99,7 @@ "available_balance_description": "“Available Balance” သို့မဟုတ် “Confirmed Balance” သည် ချက်ချင်းသုံးစွဲနိုင်သော လက်ကျန်ငွေဖြစ်သည်။ လက်ကျန်အောက်ပိုင်းတွင်သာ ဝင်လာသော်လည်း အပေါ်ပိုင်းလက်ကျန်တွင် မပေါ်သေးပါက ကွန်ယက်အတည်ပြုချက် (network confirmations) ပိုမိုရရှိရန် မိနစ်အနည်းငယ် စောင့်ရပါမည်။ အတည်ပြုချက်များ ပိုမိုရရှိပြီးနောက် ထိုငွေများကို သုံးစွဲနိုင်ပါလိမ့်မည်။", "available_balance_short": "Avl- ${amount}", "available_providers": "ရရှိနိုင်သော ဝန်ဆောင်မှုပေးသူများ", + "available_wallets": "ရနိုင်သော ပိုက်ဆံအိတ်များ", "avg_savings": "ပျမ်းမျှ ချွေတာမှု", "avl": "Avl", "awaitDAppProcessing": "ကျေးဇူးပြု၍ dApp ၏ စီမံဆောင်ရွက်မှု ပြီးဆုံးသည်အထိ စောင့်ပါ။", @@ -1073,6 +1074,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 6a3513826b..12ba32351d 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -99,6 +99,7 @@ "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_providers": "Beschikbare aanbieders", + "available_wallets": "Beschikbare portemonnees", "avg_savings": "Gem. besparingen", "avl": "Gem", "awaitDAppProcessing": "Wacht tot de dApp klaar is met verwerken.", @@ -1073,6 +1074,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 506cee2ce0..e987f9566b 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -99,6 +99,7 @@ "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_providers": "Dostępni dostawcy", + "available_wallets": "Dostępne portfele", "avg_savings": "Śr. oszczędności", "avl": "Avl", "awaitDAppProcessing": "Proszę poczekać, aż dApp zakończy przetwarzanie.", @@ -1073,6 +1074,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 f500db792f..6c7d5799c0 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -99,6 +99,7 @@ "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_providers": "Provedores disponíveis", + "available_wallets": "Carteiras disponíveis", "avg_savings": "Poupança média", "avl": "Avl", "awaitDAppProcessing": "Por favor, aguarde o dApp concluir o processamento.", @@ -1075,6 +1076,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 897d42329d..285b6a1e29 100644 --- a/res/values/strings_pt_BR.arb +++ b/res/values/strings_pt_BR.arb @@ -99,6 +99,7 @@ "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_providers": "Provedores disponíveis", + "available_wallets": "Carteiras disponíveis", "avg_savings": "Economia média", "avl": "Avl", "awaitDAppProcessing": "Aguarde até que o dApp termine de processar.", @@ -1081,6 +1082,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 fa4ea106bc..96f5c2c3b9 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -99,6 +99,7 @@ "available_balance_description": "«Доступный баланс» или «Подтверждённый баланс» — это средства, которые можно потратить сразу. Если средства отображаются в нижнем балансе, но не в верхнем, значит, нужно подождать несколько минут, пока входящие средства получат больше подтверждений сети. После получения дополнительных подтверждений их можно будет потратить.", "available_balance_short": "Avl: ${amount}", "available_providers": "Доступные провайдеры", + "available_wallets": "Доступные кошельки", "avg_savings": "Средняя экономия", "avl": "Авл", "awaitDAppProcessing": "Пожалуйста, подождите, пока dApp завершит обработку.", @@ -1074,6 +1075,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 205456165c..f90ac34f36 100644 --- a/res/values/strings_th.arb +++ b/res/values/strings_th.arb @@ -99,6 +99,7 @@ "available_balance_description": "“ยอดคงเหลือที่ใช้ได้” หรือ “ยอดคงเหลือที่ยืนยันแล้ว” คือเงินที่สามารถใช้จ่ายได้ทันที หากเงินปรากฏในยอดคงเหลือด้านล่างแต่ไม่ปรากฏในยอดคงเหลือด้านบน คุณต้องรอสักครู่เพื่อให้เงินที่เข้ามาได้รับการยืนยันจากเครือข่ายเพิ่มขึ้น เมื่อได้รับการยืนยันมากขึ้นแล้ว เงินนั้นจะสามารถใช้จ่ายได้", "available_balance_short": "จำนวน: ${amount}", "available_providers": "ผู้ให้บริการที่มีอยู่", + "available_wallets": "กระเป๋าเงินที่มีจำหน่าย", "avg_savings": "การประหยัดเฉลี่ย", "avl": "เฉลี่ย", "awaitDAppProcessing": "โปรดรอให้ dApp ประมวลผลให้เสร็จสิ้น", @@ -1073,6 +1074,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 88a32c8a3b..32def35d0e 100644 --- a/res/values/strings_tl.arb +++ b/res/values/strings_tl.arb @@ -99,6 +99,7 @@ "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_providers": "Mga Available na Provider", + "available_wallets": "Magagamit na mga Wallet", "avg_savings": "Avg. Matitipid", "avl": "Avl", "awaitDAppProcessing": "Mangyaring maghintay hanggang matapos ang pagproseso ng dApp.", @@ -1073,6 +1074,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 6771e15b20..ce4bc0cfce 100644 --- a/res/values/strings_tr.arb +++ b/res/values/strings_tr.arb @@ -99,6 +99,7 @@ "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_providers": "Mevcut Sağlayıcılar", + "available_wallets": "Mevcut Cüzdanlar", "avg_savings": "Ort. Tasarruf", "avl": "Avl", "awaitDAppProcessing": "Lütfen dApp'in işlemi tamamlamasını bekleyin.", @@ -1073,6 +1074,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 de0148d779..7aa0231c0d 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -99,6 +99,7 @@ "available_balance_description": "«Доступний баланс» або «Підтверджений баланс» — це кошти, які можна витратити негайно. Якщо кошти відображаються в нижньому балансі, але не у верхньому, потрібно зачекати кілька хвилин, доки вхідні кошти отримають більше підтверджень мережі. Після отримання додаткових підтверджень їх можна буде витратити.", "available_balance_short": "Середня сума: ${amount}", "available_providers": "Доступні постачальники", + "available_wallets": "Доступні гаманці", "avg_savings": "Сер. заощадження", "avl": "Avl", "awaitDAppProcessing": "Будь ласка, зачекайте, доки dApp завершить обробку.", @@ -1074,6 +1075,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 1bd36f3ad0..2458fa420b 100644 --- a/res/values/strings_ur.arb +++ b/res/values/strings_ur.arb @@ -99,6 +99,7 @@ "available_balance_description": "”دستیاب بیلنس” یا ”تصدیق شدہ بیلنس” وہ فنڈز ہیں جنہیں فوراً خرچ کیا جا سکتا ہے۔ اگر فنڈز نیچے والے بیلنس میں نظر آئیں لیکن اوپر والے بیلنس میں نہیں، تو آپ کو آنے والے فنڈز کے مزید نیٹ ورک کنفرمیشنز حاصل ہونے کے لیے چند منٹ انتظار کرنا ہوگا۔ جب انہیں مزید کنفرمیشنز مل جائیں گی تو وہ خرچ کے قابل ہو جائیں گے۔", "available_balance_short": "Avl: ${amount}", "available_providers": "دستیاب فراہم کنندگان", + "available_wallets": "دستیاب بٹوے", "avg_savings": "اوسط بچت", "avl": "Avl", "awaitDAppProcessing": "براہِ کرم dApp کی پروسیسنگ مکمل ہونے تک انتظار کریں۔", @@ -1075,6 +1076,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 b86ca15de6..b1bf11fe2e 100644 --- a/res/values/strings_vi.arb +++ b/res/values/strings_vi.arb @@ -99,6 +99,7 @@ "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_providers": "Nhà cung cấp có sẵn", + "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.", @@ -1074,6 +1075,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 5b581022b6..22bc234f18 100644 --- a/res/values/strings_yo.arb +++ b/res/values/strings_yo.arb @@ -99,6 +99,7 @@ "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_providers": "Awọn olupese ti o wa", + "available_wallets": "Awọn Woleti ti o wa", "avg_savings": "Ìpamọ́ àpapọ̀", "avl": "Avl", "awaitDAppProcessing": "Jọ̀wọ́, dúró kí dApp parí ìṣiṣẹ́.", @@ -1074,6 +1075,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 64bff69a7c..421079b9d2 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -99,6 +99,7 @@ "available_balance_description": "“可用余额”或“确认余额”是指可立即花费的资金。如果资金显示在下方余额中但未显示在上方余额中,则需要等待几分钟,让转入资金获得更多网络确认。获得更多确认后,这些资金即可花费。", "available_balance_short": "平均价值:${amount}", "available_providers": "可用的提供商", + "available_wallets": "可用钱包", "avg_savings": "平均节省", "avl": "平均", "awaitDAppProcessing": "请稍候,等待 dApp 完成处理。", @@ -1073,6 +1074,7 @@ "send": "发送", "send_address": "${cryptoCurrency} 地址", "send_amount": "数量:", + "send_another_asset": "发送另一个资产", "send_change_to_you": "找零(返回给您):", "send_creating_transaction": "正在创建交易", "send_error_currency": "币种只能包含数字",