diff --git a/lib/new-ui/pages/home_page.dart b/lib/new-ui/pages/home_page.dart index e93bcd0975..f201cb2f0a 100644 --- a/lib/new-ui/pages/home_page.dart +++ b/lib/new-ui/pages/home_page.dart @@ -8,6 +8,7 @@ import 'package:cake_wallet/new-ui/viewmodels/card_customizer/card_customizer_bl import 'package:cake_wallet/new-ui/widgets/coins_page/action_row/coin_action_row.dart'; import 'package:cake_wallet/new-ui/widgets/coins_page/assets_history/assets_history_section.dart'; import 'package:cake_wallet/new-ui/widgets/coins_page/cards/cards_view.dart'; +import 'package:cake_wallet/new-ui/widgets/coins_page/compact_wallet_header.dart'; import 'package:cake_wallet/new-ui/widgets/coins_page/mweb_ad.dart'; import 'package:cake_wallet/new-ui/widgets/coins_page/top_bar_widget/top_bar.dart'; import 'package:cake_wallet/new-ui/widgets/coins_page/unconfirmed_balance_widget.dart'; @@ -16,6 +17,7 @@ import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/nft_view_model.dart'; import 'package:cake_wallet/view_model/monero_account_list/monero_account_edit_or_create_view_model.dart'; import 'package:cake_wallet/view_model/monero_account_list/monero_account_list_view_model.dart'; +import 'package:cw_core/wallet_type.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -36,17 +38,43 @@ class NewHomePage extends StatefulWidget { class _NewHomePageState extends State { MoneroAccountListViewModel? accountListViewModel; bool _lightningMode = false; + final GlobalKey _cardsViewKey = GlobalKey(); + final ScrollController _scrollController = ScrollController(); + double _triggerOffset = double.infinity; + bool _showHeader = false; @override void initState() { super.initState(); _setAccountViewModel(); + _scrollController.addListener(_onScroll); reaction((_)=>widget.dashboardViewModel.wallet, (_) { _setAccountViewModel(); setState(() { _lightningMode = false; }); }); + + WidgetsBinding.instance.addPostFrameCallback((_) { + _calculateTriggerOffset(); + }); + } + + void _calculateTriggerOffset() { + final RenderBox? renderBox = _cardsViewKey.currentContext?.findRenderObject() as RenderBox?; + if (renderBox != null) { + setState(() { + _triggerOffset = renderBox.size.height; + }); + } + } + + void _onScroll() { + if (_scrollController.offset >= _triggerOffset && !_showHeader) { + setState(() => _showHeader = true); + } else if (_scrollController.offset < _triggerOffset && _showHeader) { + setState(() => _showHeader = false); + } } void _setAccountViewModel() { @@ -58,121 +86,166 @@ class _NewHomePageState extends State { @override Widget build(BuildContext context) { return Container( - height: MediaQuery.of(context).size.height, - decoration: BoxDecoration( - gradient: LinearGradient( - colors: [ - Theme.of(context).colorScheme.surface, - Theme.of(context).colorScheme.surfaceDim, - ], - begin: Alignment.topCenter, - end: Alignment.bottomCenter, + height: MediaQuery.of(context).size.height, + decoration: BoxDecoration( + gradient: LinearGradient( + colors: [ + Theme.of(context).colorScheme.surface, + Theme.of(context).colorScheme.surfaceDim, + ], + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ), ), - ), - child: Stack( - children: [ - CustomScrollView( - physics: BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()), - slivers:[ - SliverPadding( - padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top), - sliver: CupertinoSliverRefreshControl( - refreshTriggerPullDistance: 160, - refreshIndicatorExtent: 90, - onRefresh: () => widget.dashboardViewModel.refreshDashboard(), + child: Stack( + children: [ + CustomScrollView( + controller: _scrollController, + physics: BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()), + slivers: [ + SliverPadding( + padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top), + sliver: CupertinoSliverRefreshControl( + refreshTriggerPullDistance: 160, + refreshIndicatorExtent: 90, + onRefresh: () => widget.dashboardViewModel.refreshDashboard(), + ), ), - ), - SliverToBoxAdapter( - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.start, - spacing: 24.0, - children: [ - TopBar( - dashboardViewModel: widget.dashboardViewModel, - lightningMode: _lightningMode, - onLightningSwitchPress: () { - setState(() { - _lightningMode = !_lightningMode; - }); - }, - onSettingsButtonPress: () { - CupertinoScaffold.showCupertinoModalBottomSheet( - context: context, - barrierColor: Colors.black.withAlpha(85), - builder: (context) => FractionallySizedBox( - child: Material( + SliverToBoxAdapter( + child: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + TopBar( + dashboardViewModel: widget.dashboardViewModel, + lightningMode: _lightningMode, + onLightningSwitchPress: () { + setState(() { + _lightningMode = !_lightningMode; + }); + }, + onSettingsButtonPress: () { + CupertinoScaffold.showCupertinoModalBottomSheet( + context: context, + barrierColor: Colors.black.withAlpha(85), + builder: (context) => FractionallySizedBox( + child: Material( child: NewSettingsPage( dashboardViewModel: widget.dashboardViewModel, - authService: getIt.get(), + authService: getIt.get(), ))), - ); - }, + ); + }, + ), + SizedBox(height: 24), + Observer( + builder: (_) => WalletInfoBar( + lightningMode: _lightningMode, + hardwareWalletType: widget.dashboardViewModel.wallet.hardwareWalletType, + name: widget.dashboardViewModel.wallet.name, + onCustomizeButtonTap: openCustomizer), + ), + SizedBox(height: 24), + ], ), - Observer( - builder: (_)=>WalletInfoBar( - lightningMode: _lightningMode, - hardwareWalletType: widget.dashboardViewModel.wallet.hardwareWalletType, - name: widget.dashboardViewModel.wallet.name, - onCustomizeButtonTap: openCustomizer - ), + ), + SliverToBoxAdapter( + child: CardsView( + key: _cardsViewKey, + showContent: true, + dashboardViewModel: widget.dashboardViewModel, + accountListViewModel: accountListViewModel, + onCompactModeBackgroundCardsTapped: openCustomizer, + lightningMode: _lightningMode, ), - Column( + ), + SliverToBoxAdapter( + child: Column( children: [ - CardsView( - key: ValueKey(widget.dashboardViewModel.wallet.name), + SizedBox(height: 10), + UnconfirmedBalanceWidget( dashboardViewModel: widget.dashboardViewModel, - accountListViewModel: accountListViewModel, - onCompactModeBackgroundCardsTapped: openCustomizer, - lightningMode: _lightningMode, ), - UnconfirmedBalanceWidget(dashboardViewModel: widget.dashboardViewModel,), + SizedBox(height: 24), + Observer( + builder: (_) { + return Column( + children: [ + CoinActionRow( + lightningMode: _lightningMode, + showSwap: widget.dashboardViewModel.isEnabledSwapAction, + ), + MwebAd( + dashboardViewModel: widget.dashboardViewModel, + ), + ], + ); + }, + ), + SizedBox(height: 24), + Observer( + builder: (_) => AssetsHistorySection( + nftViewModel: widget.nftViewModel, + dashboardViewModel: widget.dashboardViewModel, + ), + ), + SizedBox(height: 80.0) ], ), - Observer( - builder: (_) { - return Column( - children: [ - CoinActionRow( - lightningMode: _lightningMode, - showSwap: widget.dashboardViewModel.isEnabledSwapAction,), - MwebAd(dashboardViewModel: widget.dashboardViewModel,), - ], - ); - }, - ), - Observer( - builder: (_) => AssetsHistorySection( - nftViewModel: widget.nftViewModel, + ), + ], + ), + Container( + height: (MediaQuery.of(context).padding.top), + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.bottomCenter, + end: Alignment.topCenter, + colors: [ + Theme.of(context).colorScheme.surface.withAlpha(5), + Theme.of(context).colorScheme.surface.withAlpha(25), + Theme.of(context).colorScheme.surface.withAlpha(50), + Theme.of(context).colorScheme.surface.withAlpha(100), + Theme.of(context).colorScheme.surface.withAlpha(150), + Theme.of(context).colorScheme.surface.withAlpha(175), + Theme.of(context).colorScheme.surface.withAlpha(200), + ], + ), + ), + ), + Align( + alignment: Alignment.topCenter, + child: IgnorePointer( + ignoring: !_showHeader, + child: AnimatedOpacity( + duration: const Duration(milliseconds: 200), + opacity: _showHeader ? 1 : 0, + child: Observer( + builder: (_) => CompactWalletHeader( + onHeaderTapped: () => _scrollController.animateTo(0, + duration: Duration(milliseconds: 300), curve: Curves.easeOutCubic), dashboardViewModel: widget.dashboardViewModel, + accountListViewModel: accountListViewModel, + lightningMode: _lightningMode, + showSwap: widget.dashboardViewModel.isEnabledSwapAction, ), ), - SizedBox(height: 80.0) - ], - ), - ),] - ), - Container( - height: (MediaQuery.of(context).padding.top), - decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.bottomCenter, - end: Alignment.topCenter, - colors: [ - Theme.of(context).colorScheme.surface.withAlpha(5), - Theme.of(context).colorScheme.surface.withAlpha(25), - Theme.of(context).colorScheme.surface.withAlpha(50), - Theme.of(context).colorScheme.surface.withAlpha(100), - Theme.of(context).colorScheme.surface.withAlpha(150), - Theme.of(context).colorScheme.surface.withAlpha(175), - Theme.of(context).colorScheme.surface.withAlpha(200), - ], + ), ), - ), - ), - ], - ), - ); + ) + ], + ), + ); + } + + double getCardBoxHeight() { + final numCards = widget.dashboardViewModel.wallet.type == WalletType.bitcoin + ? 1 + : widget.dashboardViewModel.cardDesigns.length; + final maxCardHeight = MediaQuery.of(context).size.width * 0.878 * (2/3.2); + final overlapAmount = numCards > 3 ? 5.0 : 60.0; + + return maxCardHeight + (numCards-1)*overlapAmount; } void openCustomizer() async { @@ -215,4 +288,4 @@ class _NewHomePageState extends State { } widget.dashboardViewModel.loadCardDesigns(); } -} +} \ No newline at end of file diff --git a/lib/new-ui/widgets/coins_page/action_row/coin_action_row.dart b/lib/new-ui/widgets/coins_page/action_row/coin_action_row.dart index 6e5c128107..56e6bf133f 100644 --- a/lib/new-ui/widgets/coins_page/action_row/coin_action_row.dart +++ b/lib/new-ui/widgets/coins_page/action_row/coin_action_row.dart @@ -6,6 +6,7 @@ import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/new-ui/modal_navigator.dart'; import 'package:cake_wallet/new-ui/pages/send_page.dart'; import 'package:cake_wallet/new-ui/pages/swap_page.dart'; +import 'package:cake_wallet/new-ui/widgets/modern_button.dart'; import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/utils/feature_flag.dart'; import 'package:cake_wallet/utils/payment_request.dart'; @@ -21,6 +22,142 @@ import '../../../pages/receive_page.dart'; import '../../../pages/scan_page.dart'; import 'coin_action_button.dart'; +class CoinAction { + final String name; + final String iconPath; + final Function(BuildContext, bool) action; + + CoinAction({required this.name, required this.iconPath, required this.action}); + + static final send = CoinAction( + name: S.current.send, + iconPath: "assets/new-ui/send.svg", + action: (context, lightningMode) { + if (FeatureFlag.hasNewUiExtraPages) { + final sendPage = getIt.get( + param1: SendPageParams( + unspentCoinType: lightningMode ? UnspentCoinType.lightning : UnspentCoinType.any, + ), + ); + + CupertinoScaffold.showCupertinoModalBottomSheet( + context: context, + barrierColor: Colors.black.withAlpha(60), + builder: (context) { + return Material( + child: ModalNavigator( + rootPage: sendPage, + parentContext: context, + ), + ); + }, + ); + } else { + Map? args; + if (lightningMode) args = {'coinTypeToSpendFrom': UnspentCoinType.lightning}; + Navigator.of(context).pushNamed(Routes.send, arguments: args); + } + }); + + static final receive = CoinAction( + name: S.current.receive, + iconPath: "assets/new-ui/receive.svg", + action: (context, lightningMode) async { + if (FeatureFlag.hasNewUiExtraPages) { + final page = getIt.get(param1: lightningMode); + CupertinoScaffold.showCupertinoModalBottomSheet( + context: context, + barrierColor: Colors.black.withAlpha(60), + builder: (context) { + return Material(child: ModalNavigator(parentContext:context,rootPage: page)); + }, + ); + } else { + // ToDo: (Konsti) refactor as part of the derivation PR (I hate myself for it) + if (lightningMode) { + await getIt().setAddressType( + bitcoin!.getOptionToType(bitcoin!.getBitcoinLightningReceivePageOption())); + } else { + await getIt().setAddressType( + bitcoin!.getOptionToType(bitcoin!.getBitcoinSegwitPageOption())); + } + Navigator.of(context).pushNamed(Routes.addressPage); + } + ; + }); + + static final swap = CoinAction( + name: S.current.swap, + iconPath: "assets/new-ui/exchange.svg", + action: (context, lightningMode) { + final page = getIt.get(param2: lightningMode ? CryptoCurrency.btcln : null); + if (FeatureFlag.hasNewUiExtraPages) { + CupertinoScaffold.showCupertinoModalBottomSheet( + context: context, + barrierColor: Colors.black.withAlpha(85), + builder: (context) => Material( + child: ModalNavigator( + rootPage: page, + parentContext: context, + )), + ); + } else { + Navigator.of(context).pushNamed(Routes.exchange); + } + }); + + static final scan = CoinAction( + name: S.current.scan, + iconPath: "assets/new-ui/scan.svg", + action: (context, lightningMode) async { + if (false && FeatureFlag.hasNewUiExtraPages) { + showModalBottomSheet( + context: context, + isScrollControlled: true, + builder: (context) => FractionallySizedBox( + heightFactor: 0.9, + child: ScanPage(), + ), + ); + } else { + final code = await presentQRScanner(context); + + if (code == null || code.isEmpty) return; + + late final PaymentRequest req; + if (SendViewModelBase.isNonZeroAmountLightningInvoice(code) || + OpenCryptoPayService.isOpenCryptoPayQR(code)) { + req = PaymentRequest(code, "", "", "", ""); + } else { + final uri = Uri.tryParse(code); + if (uri == null) return; + req = PaymentRequest.fromUri(uri); + } + + final sendPage = getIt.get( + param1: SendPageParams(initialPaymentRequest: req), + ); + + CupertinoScaffold.showCupertinoModalBottomSheet( + context: context, + barrierColor: Colors.black.withAlpha(60), + builder: (context) { + return Material( + child: ModalNavigator( + rootPage: sendPage, + parentContext: context, + ), + ); + }, + ); + } + ; + } + ); + + static final all = [send, receive, swap, scan]; +} + class CoinActionRow extends StatelessWidget { const CoinActionRow({super.key, this.lightningMode = false, this.showSwap = true}); @@ -32,164 +169,46 @@ class CoinActionRow extends StatelessWidget { return Padding( padding: const EdgeInsets.symmetric(horizontal: 18.0), child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - spacing: MediaQuery.of(context).size.width * 0.05, - children: [ - CoinActionButton( - icon: SvgPicture.asset( - "assets/new-ui/send.svg", - colorFilter: ColorFilter.mode( - Theme.of(context).colorScheme.primary, - BlendMode.srcIn, - ), - ), - label: S.of(context).send, - action: () { - if (FeatureFlag.hasNewUiExtraPages) { - final sendPage = getIt.get( - param1: SendPageParams( - unspentCoinType: - lightningMode ? UnspentCoinType.lightning : UnspentCoinType.nonMweb, + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.center, + spacing: MediaQuery.of(context).size.width * 0.05, + children: CoinAction.all.where((item) => item != CoinAction.swap || showSwap) + .map((item) => CoinActionButton( + icon: SvgPicture.asset( + item.iconPath, + colorFilter: + ColorFilter.mode(Theme.of(context).colorScheme.primary, BlendMode.srcIn), ), - ); - - CupertinoScaffold.showCupertinoModalBottomSheet( - context: context, - barrierColor: Colors.black.withAlpha(60), - builder: (context) { - return Material( - child: ModalNavigator( - rootPage: sendPage, - parentContext: context, - ), - ); - }, - ); - } else { - Map? args; - if (lightningMode) args = {'coinTypeToSpendFrom' : UnspentCoinType.lightning}; - Navigator.of(context).pushNamed(Routes.send, arguments: args); - } - }, - ), - CoinActionButton( - icon: SvgPicture.asset( - "assets/new-ui/receive.svg", - colorFilter: ColorFilter.mode( - Theme.of(context).colorScheme.primary, - BlendMode.srcIn, - ), - ), - label: S.of(context).receive, - action: () async { - if (FeatureFlag.hasNewUiExtraPages) { - final page = getIt.get(param1: lightningMode); - CupertinoScaffold.showCupertinoModalBottomSheet( - context: context, - barrierColor: Colors.black.withAlpha(60), - builder: (context) { - return Material(child: ModalNavigator(parentContext:context,rootPage: page)); - }, - ); - } else { - // ToDo: (Konsti) refactor as part of the derivation PR (I hate myself for it) - if (lightningMode) { - await getIt().setAddressType( - bitcoin!.getOptionToType(bitcoin!.getBitcoinLightningReceivePageOption())); - } else { - await getIt().setAddressType( - bitcoin!.getOptionToType(bitcoin!.getBitcoinSegwitPageOption())); - } - Navigator.of(context).pushNamed(Routes.addressPage); - } - }, - ), - if (showSwap) - CoinActionButton( - icon: SvgPicture.asset( - "assets/new-ui/exchange.svg", - colorFilter: ColorFilter.mode( - Theme.of(context).colorScheme.primary, - BlendMode.srcIn, - ), - ), - label: S.of(context).swap, - action: () { - final page = getIt.get(param2: lightningMode ? CryptoCurrency.btcln : null); - if (FeatureFlag.hasNewUiExtraPages) { - CupertinoScaffold.showCupertinoModalBottomSheet( - context: context, - barrierColor: Colors.black.withAlpha(85), - builder: (context) => Material( - child: ModalNavigator( - rootPage: page, - parentContext: context, - )), - ); - } else { - Navigator.of(context).pushNamed(Routes.exchange); - } - }, - ), - CoinActionButton( - icon: SvgPicture.asset( - "assets/new-ui/scan.svg", - colorFilter: ColorFilter.mode( - Theme.of(context).colorScheme.primary, - BlendMode.srcIn, - ), - ), - label: "Scan", - action: () => _onPressedScan(context), - ), - ], - ), + label: item.name, + action: () => item.action(context, lightningMode))) + .toList()), ); } +} - Future _onPressedScan(BuildContext context) async { - if (false && FeatureFlag.hasNewUiExtraPages) { - showModalBottomSheet( - context: context, - isScrollControlled: true, - builder: (context) => FractionallySizedBox( - heightFactor: 0.9, - child: ScanPage(), - ), - ); - } else { - final code = await presentQRScanner(context); - - if (code == null || code.isEmpty) return; - - late final PaymentRequest req; - if (SendViewModelBase.isNonZeroAmountLightningInvoice(code) || - OpenCryptoPayService.isOpenCryptoPayQR(code)) { - req = PaymentRequest(code, "", "", "", ""); - } else { - final uri = Uri.tryParse(code); - if (uri == null) return; - req = PaymentRequest.fromUri(uri); - } +class CompactCoinActionRow extends StatelessWidget { + const CompactCoinActionRow({super.key, this.lightningMode = false, this.showSwap = true}); - final sendPage = getIt.get( - param1: SendPageParams(initialPaymentRequest: req), - ); - - CupertinoScaffold.showCupertinoModalBottomSheet( - context: context, - barrierColor: Colors.black.withAlpha(60), - builder: (context) { - return Material( - child: ModalNavigator( - rootPage: sendPage, - parentContext: context, - ), - ); - }, - ); - } - ; + final bool lightningMode; + final bool showSwap; + + + @override + Widget build(BuildContext context) { + return Row( + spacing: 20, + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.center, + children: CoinAction.all.where((item) => item != CoinAction.swap || showSwap) + .map((item) => ModernButton.svg( + svgPath: item.iconPath, + size: 36, + iconSize: 20, + onPressed: () => item.action(context, lightningMode), + backgroundColor: Theme.of(context).colorScheme.primary, + iconColor: Theme.of(context).colorScheme.onPrimary, + )) + .toList(), + ); } } diff --git a/lib/new-ui/widgets/coins_page/cards/balance_card.dart b/lib/new-ui/widgets/coins_page/cards/balance_card.dart index c6a6381715..5812a2b072 100644 --- a/lib/new-ui/widgets/coins_page/cards/balance_card.dart +++ b/lib/new-ui/widgets/coins_page/cards/balance_card.dart @@ -24,7 +24,7 @@ class BalanceCard extends StatelessWidget { this.fiatBalance = "", this.assetName = "", this.designSwitchDuration = const Duration(), - this.actions = const [], + this.actions = const [], this.showForeground = true, this.capitalizeAssetName = true, }); @@ -38,6 +38,7 @@ class BalanceCard extends StatelessWidget { final bool capitalizeAssetName; final String assetName; final bool selected; + final bool showForeground; final CardDesign design; final List actions; final Duration designSwitchDuration; @@ -87,150 +88,154 @@ class BalanceCard extends StatelessWidget { key: ValueKey('svgFullOff'), ), ), - Padding( - padding: EdgeInsets.all(width * 0.05), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - mainAxisSize: MainAxisSize.max, - children: [ - if (showText) - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - if(accountName.isNotEmpty || accountBalance.isNotEmpty) - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AnimatedDefaultTextStyle( + AnimatedOpacity( + duration: designSwitchDuration, + opacity: showForeground ? 1 : 0, + child: Padding( + padding: EdgeInsets.all(width * 0.05), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.max, + children: [ + if (showText) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + if(accountName.isNotEmpty || accountBalance.isNotEmpty) + Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + AnimatedDefaultTextStyle( + duration: designSwitchDuration, + style: Theme.of(context).textTheme.titleMedium!.copyWith( + fontWeight: FontWeight.w500, + color: design.colors.textColor), + child: Text(accountName), + ), + AnimatedOpacity( + opacity: selected ? 0 : 1, + duration: textFadeDuration, + child: Text( + accountBalance, + style: TextStyle(color: design.colors.textColor, fontSize: 14), + ), + ), + ], + ), + AnimatedOpacity( + opacity: selected ? 1 : 0, + duration: textFadeDuration, + child: AnimatedSwitcher( duration: designSwitchDuration, - style: Theme.of(context).textTheme.titleMedium!.copyWith( - fontWeight: FontWeight.w500, - color: design.colors.textColor), - child: Text(accountName), + layoutBuilder: (currentChild, previousChildren) { + return Stack( + alignment: Alignment.centerLeft, + children: [ + ...previousChildren, + if (currentChild != null) currentChild, + ], + ); + }, + child: Row( + key: ValueKey("$balance ${assetName.toUpperCase()}"), + spacing: 8.0, + children: [ + AnimatedDefaultTextStyle( + duration: designSwitchDuration, + style: DefaultTextStyle.of(context) + .style + .copyWith(color: design.colors.textColor, fontSize: 28, fontWeight: FontWeight.w500, letterSpacing: -0.4), + child: Text(balance), + ), + AnimatedDefaultTextStyle( + duration: designSwitchDuration, + style: DefaultTextStyle.of(context) + .style + .copyWith(color: design.colors.textColorSecondary, fontSize: 28, fontWeight: FontWeight.w400, letterSpacing: -0.4), + child: Text(capitalizeAssetName ? assetName.toUpperCase() : assetName.toLowerCase()), + ), + ], + ), ), - AnimatedOpacity( - opacity: selected ? 0 : 1, - duration: textFadeDuration, + ), + AnimatedDefaultTextStyle( + duration: designSwitchDuration, + style: DefaultTextStyle.of(context).style.copyWith( + fontSize: 15, + fontWeight: FontWeight.w400, + color: design.colors.textColorSecondary), + child: AnimatedSwitcher( + duration: designSwitchDuration, + layoutBuilder: (currentChild, previousChildren) { + return Stack( + alignment: Alignment.centerLeft, + children: [ + ...previousChildren, + if (currentChild != null) currentChild, + ], + ); + }, child: Text( - accountBalance, - style: TextStyle(color: design.colors.textColor, fontSize: 14), + key: ValueKey(fiatBalance), + fiatBalance, ), ), - ], - ), - AnimatedOpacity( - opacity: selected ? 1 : 0, - duration: textFadeDuration, - child: AnimatedSwitcher( - duration: designSwitchDuration, - layoutBuilder: (currentChild, previousChildren) { - return Stack( - alignment: Alignment.centerLeft, - children: [ - ...previousChildren, - if (currentChild != null) currentChild, - ], - ); - }, - child: Row( - key: ValueKey("$balance ${assetName.toUpperCase()}"), - spacing: 8.0, - children: [ - AnimatedDefaultTextStyle( - duration: designSwitchDuration, - style: DefaultTextStyle.of(context) - .style - .copyWith(color: design.colors.textColor, fontSize: 28, fontWeight: FontWeight.w500, letterSpacing: -0.4), - child: Text(balance), - ), - AnimatedDefaultTextStyle( - duration: designSwitchDuration, - style: DefaultTextStyle.of(context) - .style - .copyWith(color: design.colors.textColorSecondary, fontSize: 28, fontWeight: FontWeight.w400, letterSpacing: -0.4), - child: Text(capitalizeAssetName ? assetName.toUpperCase() : assetName.toLowerCase()), - ), + ), + ], + ) + else + Container(), + Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + AnimatedSwitcher( + duration: designSwitchDuration, + switchInCurve: Curves.easeInOut, + switchOutCurve: Curves.easeInOut, + layoutBuilder: (currentChild, previousChildren) { + return Stack( + alignment: Alignment.centerLeft, + children: [ + ...previousChildren, + if (currentChild != null) currentChild, ], - ), + ); + }, + child: Row( + key: ValueKey(actions.toString()), + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.start, + children: actions.map(getBalanceCardActionButton).toList(), ), ), - AnimatedDefaultTextStyle( + AnimatedSwitcher( duration: designSwitchDuration, - style: DefaultTextStyle.of(context).style.copyWith( - fontSize: 15, - fontWeight: FontWeight.w400, - color: design.colors.textColorSecondary), - child: AnimatedSwitcher( - duration: designSwitchDuration, - layoutBuilder: (currentChild, previousChildren) { - return Stack( - alignment: Alignment.centerLeft, - children: [ - ...previousChildren, - if (currentChild != null) currentChild, - ], - ); - }, - child: Text( - key: ValueKey(fiatBalance), - fiatBalance, - ), - ), + switchInCurve: Curves.easeInOut, + switchOutCurve: Curves.easeInOut, + child: design.backgroundType == CardDesignBackgroundTypes.svgIcon + ? SvgPicture.asset( + design.imagePath, + key: const ValueKey('svgIcon'), + height: iconWidth, + width: iconWidth, + colorFilter: ColorFilter.mode( + design.colors.backgroundImageColor.withAlpha(80), + BlendMode.srcIn, + ), + ) + : const SizedBox.shrink( + key: ValueKey('svgIconOff'), + ), ), ], - ) - else - Container(), - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - AnimatedSwitcher( - duration: designSwitchDuration, - switchInCurve: Curves.easeInOut, - switchOutCurve: Curves.easeInOut, - layoutBuilder: (currentChild, previousChildren) { - return Stack( - alignment: Alignment.centerLeft, - children: [ - ...previousChildren, - if (currentChild != null) currentChild, - ], - ); - }, - child: Row( - key: ValueKey(actions.toString()), - crossAxisAlignment: CrossAxisAlignment.end, - mainAxisAlignment: MainAxisAlignment.start, - children: actions.map(getBalanceCardActionButton).toList(), - ), - ), - AnimatedSwitcher( - duration: designSwitchDuration, - switchInCurve: Curves.easeInOut, - switchOutCurve: Curves.easeInOut, - child: design.backgroundType == CardDesignBackgroundTypes.svgIcon - ? SvgPicture.asset( - design.imagePath, - key: const ValueKey('svgIcon'), - height: iconWidth, - width: iconWidth, - colorFilter: ColorFilter.mode( - design.colors.backgroundImageColor.withAlpha(80), - BlendMode.srcIn, - ), - ) - : const SizedBox.shrink( - key: ValueKey('svgIconOff'), - ), - ), - ], - ), - ], + ), + ], + ), ), ), ], diff --git a/lib/new-ui/widgets/coins_page/cards/cards_view.dart b/lib/new-ui/widgets/coins_page/cards/cards_view.dart index 37f0476ce3..f011f4569c 100644 --- a/lib/new-ui/widgets/coins_page/cards/cards_view.dart +++ b/lib/new-ui/widgets/coins_page/cards/cards_view.dart @@ -16,7 +16,6 @@ import 'package:cw_core/card_design.dart'; import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/unspent_coin_type.dart'; import 'package:cw_core/wallet_type.dart'; -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; @@ -31,18 +30,23 @@ class CardsView extends StatefulWidget { required this.dashboardViewModel, required this.accountListViewModel, required this.lightningMode, - required this.onCompactModeBackgroundCardsTapped}); + required this.onCompactModeBackgroundCardsTapped, + required this.showContent}); final DashboardViewModel dashboardViewModel; final MoneroAccountListViewModel? accountListViewModel; final VoidCallback onCompactModeBackgroundCardsTapped; final bool lightningMode; + final bool showContent; + @override _CardsViewState createState() => _CardsViewState(); } class _CardsViewState extends State { + late final cardWidth = MediaQuery.of(context).size.width*0.878; + late int _selectedIndex; @override @@ -59,7 +63,6 @@ class _CardsViewState extends State { static const Duration animDuration = Duration(milliseconds: 200); static const int compactModeTreshold = 4; static const int maxCards = 5; - late final double cardWidth = MediaQuery.of(context).size.width * 0.878; Widget _buildCard(int visualIndex, int realIndex, int numCards, double parentWidth, Map order, bool compactMode, double overlapAmount) { @@ -71,14 +74,12 @@ class _CardsViewState extends State { final top = baseTop - (howFarBehind * overlapAmount); - final left = (parentWidth - cardWidth) / 2.0; return AnimatedPositioned( key: ValueKey("$visualIndex $realIndex"), duration: animDuration, curve: Curves.easeOut, top: top, - left: left, child: AnimatedScale( duration: animDuration, curve: Curves.easeOut, @@ -171,6 +172,10 @@ class _CardsViewState extends State { ] : []; + final double maxWidth = MediaQuery.of(context).size.width * 0.878; + final double widthFactor = (cardWidth / maxWidth).clamp(0.0, 1.0); + final double radius = 10.0 + (10.0 * widthFactor); + return BalanceCard( width: cardWidth, accountName: accountName, @@ -179,6 +184,8 @@ class _CardsViewState extends State { assetName: walletBalanceRecord?.formattedAssetTitle ?? assetTitleFallback, capitalizeAssetName: _shouldCapitalizeAssetName(), balance: walletBalance, + borderRadius: radius, + showForeground: widget.showContent, fiatBalance: walletFiatBalance, selected: _selectedIndex == visualIndex, design: cardDesign, @@ -223,10 +230,11 @@ class _CardsViewState extends State { @override Widget build(BuildContext context) { return Observer(builder: (_) { - final parentWidth = MediaQuery.of(context).size.width; + final parentWidth = cardWidth; + final children = []; - int numCards = widget.dashboardViewModel.wallet.type == WalletType.bitcoin + int numCards = widget.dashboardViewModel.wallet.type == WalletType.bitcoin || !widget.showContent ? 1 : widget.dashboardViewModel.cardDesigns.length; if(numCards == 0) numCards = 1; @@ -255,27 +263,19 @@ class _CardsViewState extends State { final double overlapAmount = compactMode ? 5.0 : 46.0; for (int i = min(numCards - 1, maxCards); i >= 0; i--) { int visualIndex = (_selectedIndex - i + numCards) % numCards; - int realIndex = order[visualIndex]!; - children.add(_buildCard( visualIndex, realIndex, numCards, parentWidth, order, compactMode, overlapAmount)); } - return AnimatedContainer( - duration: Duration(milliseconds: 200), - curve: Curves.easeOut, - width: double.infinity, + return Container( height: _getBoxHeight(numCards, overlapAmount), - child: AnimatedSwitcher( - duration: Duration(milliseconds: 200), - transitionBuilder: (child, animation) => FadeTransition(opacity: animation, child: child), - child: SizedBox( - key: ValueKey(_getBoxHeight(numCards, overlapAmount)), - width: double.infinity, - height: _getBoxHeight(numCards, overlapAmount), - child: Stack(alignment: Alignment.center, children: children), - ), + width: cardWidth, + child: SizedBox( + key: ValueKey(_getBoxHeight(numCards, overlapAmount)), + // height: _getBoxHeight(numCards, overlapAmount), + width: cardWidth, + child: Stack(alignment: Alignment.center, children: children), ), ); }); diff --git a/lib/new-ui/widgets/coins_page/compact_wallet_header.dart b/lib/new-ui/widgets/coins_page/compact_wallet_header.dart new file mode 100644 index 0000000000..930d9e7c20 --- /dev/null +++ b/lib/new-ui/widgets/coins_page/compact_wallet_header.dart @@ -0,0 +1,150 @@ +import 'package:cake_wallet/new-ui/widgets/coins_page/action_row/coin_action_row.dart'; +import 'package:cake_wallet/new-ui/widgets/coins_page/cards/balance_card.dart'; +import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart'; +import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; +import 'package:cake_wallet/view_model/monero_account_list/monero_account_list_view_model.dart'; +import 'package:cw_core/card_design.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_mobx/flutter_mobx.dart'; + +class CompactWalletHeader extends StatelessWidget { + const CompactWalletHeader( + {super.key, + required this.dashboardViewModel, + this.accountListViewModel, + required this.lightningMode, + required this.onHeaderTapped, + required this.showSwap}); + + final DashboardViewModel dashboardViewModel; + final bool lightningMode; + final bool showSwap; + final VoidCallback onHeaderTapped; + final MoneroAccountListViewModel? accountListViewModel; + + @override + Widget build(BuildContext context) { + return AbsorbPointer( + absorbing: false, + child: Stack( + children: [ + Positioned.fill( + child: AbsorbPointer( + absorbing: true, + child: Container( + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.bottomCenter, + end: Alignment.topCenter, + colors: [ + Theme.of(context).colorScheme.surface.withAlpha(5), + Theme.of(context).colorScheme.surface.withAlpha(25), + Theme.of(context).colorScheme.surface.withAlpha(50), + Theme.of(context).colorScheme.surface.withAlpha(100), + Theme.of(context).colorScheme.surface.withAlpha(150), + Theme.of(context).colorScheme.surface.withAlpha(175), + Theme.of(context).colorScheme.surface.withAlpha(200), + ], + ), + )), + ), + ), + SafeArea( + child: Observer(builder: (context) { + final account = + accountListViewModel?.accounts.where((item) => item.isSelected).firstOrNull; + + final String accountName = account == null ? "" : account.label; + + final walletName = dashboardViewModel.wallet.name; + + final BalanceRecord? record = + dashboardViewModel.balanceViewModel.formattedBalances.firstOrNull; + final String balance = record?.availableBalance ?? "0.00"; + final String currency = record?.asset.title ?? ""; + + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.all(12.0), + child: GestureDetector( + onTap: onHeaderTapped, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(16), + color: Theme.of(context).colorScheme.surfaceContainer), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + spacing: 8, + children: [ + BalanceCard( + width: 80, + design: dashboardViewModel.cardDesigns + .elementAtOrNull(account?.id ?? 0) ?? + CardDesign.genericDefault, + borderRadius: 7, + ), + Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (accountName.isNotEmpty) + Text( + accountName, + style: TextStyle( + fontWeight: FontWeight.w500, + color: Theme.of(context).colorScheme.primary), + ), + Text( + walletName, + style: TextStyle( + fontWeight: accountName.isEmpty + ? FontWeight.w500 + : FontWeight.w400, + color: accountName.isEmpty + ? Theme.of(context).colorScheme.primary + : Theme.of(context).colorScheme.onSurfaceVariant), + ) + ], + ), + ], + ), + Row( + spacing: 12, + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Container( + width: 1, + height: 36, + color: Theme.of(context).colorScheme.surfaceContainerHigh, + ), + Text("$balance $currency") + ], + ), + ], + ), + ), + ), + ), + ), + CompactCoinActionRow( + lightningMode: lightningMode, + showSwap: showSwap, + ) + ], + ); + }), + ) + ], + ), + ); + } +} diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb index 1fa1923037..205470e0cc 100644 --- a/res/values/strings_ar.arb +++ b/res/values/strings_ar.arb @@ -859,6 +859,7 @@ "save_to_downloads": "ﺕﻼﻳﺰﻨﺘﻟﺍ ﻲﻓ ﻆﻔﺣ", "saved_the_trade_id": "لقد تم حفظ معرف العملية", "savings": "الادخار", + "scan": "مسح", "scan_one_block": "مسح كتلة واحدة", "scan_qr_code": "امسح رمز QR ضوئيًا", "scan_qr_code_to_get_address": "امسح ال QR للحصول على العنوان", diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb index 98a6b16cf0..0eb63a524c 100644 --- a/res/values/strings_bg.arb +++ b/res/values/strings_bg.arb @@ -859,6 +859,7 @@ "save_to_downloads": "Запазване в Изтегляния", "saved_the_trade_id": "Запазих trade ID-то", "savings": "Спестявания", + "scan": "Сканиране", "scan_one_block": "Сканирайте един блок", "scan_qr_code": "Сканирайте QR кода, за да получите адреса", "scan_qr_code_to_get_address": "Сканирайте QR кода, за да получите адреса", diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb index 463b9f7d83..dbc891c679 100644 --- a/res/values/strings_cs.arb +++ b/res/values/strings_cs.arb @@ -859,6 +859,7 @@ "save_to_downloads": "Uložit do Stažených souborů", "saved_the_trade_id": "Uložil jsem si ID transakce (trade ID)", "savings": "Úspory", + "scan": "Skenovat", "scan_one_block": "Prohledejte jeden blok", "scan_qr_code": "Naskenujte QR kód pro získání adresy", "scan_qr_code_to_get_address": "Prohledejte QR kód a získejte adresu", diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index b39009aba9..82d0d42340 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -860,6 +860,7 @@ "save_to_downloads": "Unter „Downloads“ speichern", "saved_the_trade_id": "Ich habe die Handels-ID gespeichert", "savings": "Ersparnisse", + "scan": "Scan", "scan_one_block": "Einen Block scannen", "scan_qr_code": "QR-Code scannen", "scan_qr_code_to_get_address": "Scannen Sie den QR-Code, um die Adresse zu erhalten", diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index 1f8183239c..1b51c82543 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -860,6 +860,7 @@ "save_to_downloads": "Save to Downloads", "saved_the_trade_id": "I've saved the trade ID", "savings": "Savings", + "scan": "Scan", "scan_one_block": "Scan one block", "scan_qr_code": "Scan QR code", "scan_qr_code_to_get_address": "Scan the QR code to get the address", diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index beba9a30fd..1152ac41ce 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -860,6 +860,7 @@ "save_to_downloads": "Guardar en Descargas", "saved_the_trade_id": "He guardado el ID de la operación", "savings": "Ahorros", + "scan": "Escanear", "scan_one_block": "Escanear un bloque", "scan_qr_code": "Escanear código QR", "scan_qr_code_to_get_address": "Escanea el código QR para obtener la dirección", diff --git a/res/values/strings_fa.arb b/res/values/strings_fa.arb index 5d558a2051..f5559aba74 100644 --- a/res/values/strings_fa.arb +++ b/res/values/strings_fa.arb @@ -858,6 +858,7 @@ "save_to_downloads": "ذخیره در دانلودها", "saved_the_trade_id": "من شناسه معامله را ذخیره کردم", "savings": "پس انداز", + "scan": "اسکن کنید", "scan_one_block": "اسکن یک بلاک", "scan_qr_code": "اسکن کد QR", "scan_qr_code_to_get_address": "کد QR را برای دریافت آدرس اسکن کنید", diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index d64db3951b..899b56caa2 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -859,6 +859,7 @@ "save_to_downloads": "Enregistrer dans les téléchargements", "saved_the_trade_id": "J'ai sauvegardé l'ID d'échange", "savings": "Économies", + "scan": "Balayage", "scan_one_block": "Scanner un bloc", "scan_qr_code": "Scannez le QR code", "scan_qr_code_to_get_address": "Scannez le QR code pour obtenir l'adresse", diff --git a/res/values/strings_gn.arb b/res/values/strings_gn.arb index 590cb2f164..aeadcf0940 100644 --- a/res/values/strings_gn.arb +++ b/res/values/strings_gn.arb @@ -678,6 +678,7 @@ "save_to_downloads": "Ñongatu mboguejýpyre-pe", "saved_the_trade_id": "Añongatu ID ñemuha rehegua", "savings": "Ahorro rehegua .", + "scan": "Escaneo rehegua", "scan_one_block": "escanea peteĩ bloque", "scan_qr_code": "Re-escanea papapy QR", "scan_qr_code_to_get_address": "Escanea pe código QR reikuaa hag̃ua pe dirección", diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb index 95e053fa22..3b18ed9957 100644 --- a/res/values/strings_ha.arb +++ b/res/values/strings_ha.arb @@ -861,6 +861,7 @@ "save_to_downloads": "Ajiye zuwa Zazzagewa", "saved_the_trade_id": "Na ajiye ID na ciniki", "savings": "Adana", + "scan": "Duba", "scan_one_block": "Duba toshe daya", "scan_qr_code": "Gani QR kodin", "scan_qr_code_to_get_address": "Duba lambar QR don samun adireshin", diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index 0c129a3be7..8d93aba17f 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -861,6 +861,7 @@ "save_to_downloads": "डाउनलोड में सहेजें", "saved_the_trade_id": "मैंने व्यापार बचा लिया है ID", "savings": "बचत", + "scan": "स्कैन", "scan_one_block": "एक ब्लॉक को स्कैन करना", "scan_qr_code": "स्कैन क्यू आर कोड", "scan_qr_code_to_get_address": "पता प्राप्त करने के लिए QR कोड स्कैन करें", diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index 1ed4ace6e1..ea69d074d7 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -859,6 +859,7 @@ "save_to_downloads": "Spremi u Preuzimanja", "saved_the_trade_id": "Spremio/la sam transakcijski ID", "savings": "Štednja", + "scan": "Skenirati", "scan_one_block": "Skenirajte jedan blok", "scan_qr_code": "Skenirajte QR kod", "scan_qr_code_to_get_address": "Skeniraj QR kod za dobivanje adrese", diff --git a/res/values/strings_hy.arb b/res/values/strings_hy.arb index 5efc5fc547..ae4d33bbe7 100644 --- a/res/values/strings_hy.arb +++ b/res/values/strings_hy.arb @@ -858,6 +858,7 @@ "save_to_downloads": "Պահպանել ներբեռնումներում", "saved_the_trade_id": "Ես պահպանել եմ առևտրի ID-ն", "savings": "Խնայողություններ", + "scan": "Սկանավորել", "scan_one_block": "Սկանավորել մեկ բլոկ", "scan_qr_code": "Սկանավորել QR կոդ", "scan_qr_code_to_get_address": "Սկանավորել QR կոդը հասցեն ստանալու համար", diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb index ff239d07cd..7c6c2db9b3 100644 --- a/res/values/strings_id.arb +++ b/res/values/strings_id.arb @@ -862,6 +862,7 @@ "save_to_downloads": "Simpan ke Unduhan", "saved_the_trade_id": "Saya telah menyimpan ID perdagangan", "savings": "Tabungan", + "scan": "Pindai", "scan_one_block": "Pindai satu blok", "scan_qr_code": "Scan kode QR untuk mendapatkan alamat", "scan_qr_code_to_get_address": "Pindai kode QR untuk mendapatkan alamat", diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index f92629c605..a335a74cee 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -860,6 +860,7 @@ "save_to_downloads": "Salva in Download", "saved_the_trade_id": "Ho salvato l'ID dello scambio", "savings": "Risparmio", + "scan": "Scansione", "scan_one_block": "Scansionare un blocco", "scan_qr_code": "Scansiona il codice QR", "scan_qr_code_to_get_address": "Scansiona il codice QR per ottenere l'indirizzo", diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index 9a7d3ac2f7..8e69be5feb 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -860,6 +860,7 @@ "save_to_downloads": "ダウンロードに保存", "saved_the_trade_id": "取引IDを保存しました", "savings": "貯蓄", + "scan": "スキャン", "scan_one_block": "1つのブロックをスキャンします", "scan_qr_code": "QRコードをスキャン", "scan_qr_code_to_get_address": "QRコードをスキャンして住所を取得します", diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index d8ef1f2d95..f49a8da7fe 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -860,6 +860,7 @@ "save_to_downloads": "다운로드에 저장", "saved_the_trade_id": "거래 ID를 저장했습니다", "savings": "저금", + "scan": "주사", "scan_one_block": "블록 하나 스캔", "scan_qr_code": "QR 코드 스캔", "scan_qr_code_to_get_address": "주소를 얻으려면 QR 코드를 스캔하세요", diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb index c40ca3f3a6..2e4ba12140 100644 --- a/res/values/strings_my.arb +++ b/res/values/strings_my.arb @@ -859,6 +859,7 @@ "save_to_downloads": "ဒေါင်းလုဒ်များထံ သိမ်းဆည်းပါ။", "saved_the_trade_id": "ကုန်သွယ်မှု ID ကို သိမ်းဆည်းပြီးပါပြီ။", "savings": "စုဆောင်းငွေ", + "scan": "စကင်န်", "scan_one_block": "တစ်ကွက်ကိုစကင်ဖတ်စစ်ဆေးပါ", "scan_qr_code": "QR ကုဒ်ကို စကင်န်ဖတ်ပါ။", "scan_qr_code_to_get_address": "လိပ်စာရယူရန် QR ကုဒ်ကို စကင်န်ဖတ်ပါ။", diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index 24e1544c1a..99bbfae5c9 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -859,6 +859,7 @@ "save_to_downloads": "Opslaan in downloads", "saved_the_trade_id": "Ik heb de ruil-ID opgeslagen", "savings": "Besparingen", + "scan": "Scannen", "scan_one_block": "Scan een blok", "scan_qr_code": "Scan QR-code", "scan_qr_code_to_get_address": "Scan de QR-code om het adres te krijgen", diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index d09bc03e5a..1887820f26 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -858,6 +858,7 @@ "save_to_downloads": "Zapisz w folderze Pobrane", "saved_the_trade_id": "Zapisałem ID transakcji", "savings": "Oszczędności", + "scan": "Skandować", "scan_one_block": "Zeskanuj jeden blok", "scan_qr_code": "Zeskanuj kod QR", "scan_qr_code_to_get_address": "Zeskanuj kod QR, aby uzyskać adres", diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index f5100e5ce4..298813c182 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -861,6 +861,7 @@ "save_to_downloads": "Salvar em Downloads", "saved_the_trade_id": "ID da troca salvo", "savings": "Poupança", + "scan": "Digitalizar", "scan_one_block": "Escanear um bloco", "scan_qr_code": "Escanear código QR", "scan_qr_code_to_get_address": "Digitalize o código QR para obter o endereço", diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index d4424b5df2..247b8c6c4f 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -860,6 +860,7 @@ "save_to_downloads": "Сохранить в загрузках", "saved_the_trade_id": "Я сохранил ID сделки", "savings": "Экономия", + "scan": "Сканировать", "scan_one_block": "Сканируйте один блок", "scan_qr_code": "Сканировать QR-код", "scan_qr_code_to_get_address": "Отсканируйте QR-код для получения адреса", diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb index 43a049f69c..bad91f2139 100644 --- a/res/values/strings_th.arb +++ b/res/values/strings_th.arb @@ -859,6 +859,7 @@ "save_to_downloads": "บันทึกลงดาวน์โหลด", "saved_the_trade_id": "ฉันได้บันทึก ID ของการซื้อขายแล้ว", "savings": "ออมทรัพย์", + "scan": "สแกน", "scan_one_block": "สแกนหนึ่งบล็อก", "scan_qr_code": "สแกนรหัส QR", "scan_qr_code_to_get_address": "สแกน QR code เพื่อรับที่อยู่", diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb index 3b54d76770..e6cb5ca867 100644 --- a/res/values/strings_tl.arb +++ b/res/values/strings_tl.arb @@ -859,6 +859,7 @@ "save_to_downloads": "I-save sa mga Pag-download", "saved_the_trade_id": "Nai-save ko na ang trade ID", "savings": "Savings", + "scan": "I-scan", "scan_one_block": "I-scan ang isang bloke", "scan_qr_code": "I-scan ang QR code", "scan_qr_code_to_get_address": "I-scan ang QR code upang makuha ang address", diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb index 251e1f094b..8b1c75cbe1 100644 --- a/res/values/strings_tr.arb +++ b/res/values/strings_tr.arb @@ -859,6 +859,7 @@ "save_to_downloads": "İndirilenlere Kaydet", "saved_the_trade_id": "Takas ID'imi kaydettim", "savings": "Tasarruf", + "scan": "Tara", "scan_one_block": "Bir bloğu tara", "scan_qr_code": "QR kodunu tarayın", "scan_qr_code_to_get_address": "Adresi getirmek için QR kodunu tara", diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index 9c4e5f5e47..bb535e1883 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -860,6 +860,7 @@ "save_to_downloads": "Зберегти до завантажень", "saved_the_trade_id": "Я зберіг ID операції", "savings": "Економія", + "scan": "Сканувати", "scan_one_block": "Сканувати один блок", "scan_qr_code": "Відскануйте QR-код", "scan_qr_code_to_get_address": "Скануйте QR-код для одержання адреси", diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb index b67f857b52..5ded1c7487 100644 --- a/res/values/strings_ur.arb +++ b/res/values/strings_ur.arb @@ -861,6 +861,7 @@ "save_to_downloads": "۔ﮟﯾﺮﮐ ﻅﻮﻔﺤﻣ ﮟﯿﻣ ﺯﮈﻮﻟ ﻥﺅﺍﮈ", "saved_the_trade_id": "میں نے تجارتی ID محفوظ کر لی ہے۔", "savings": "بچت", + "scan": "اسکین کریں۔", "scan_one_block": "ایک بلاک اسکین کریں", "scan_qr_code": "پتہ حاصل کرنے کے لیے QR کوڈ اسکین کریں۔", "scan_qr_code_to_get_address": "پتہ حاصل کرنے کے لئے QR کوڈ کو اسکین کریں", diff --git a/res/values/strings_vi.arb b/res/values/strings_vi.arb index a3c30406af..459c3678ac 100644 --- a/res/values/strings_vi.arb +++ b/res/values/strings_vi.arb @@ -857,6 +857,7 @@ "save_to_downloads": "Lưu vào Tải xuống", "saved_the_trade_id": "Tôi đã lưu ID giao dịch", "savings": "Tiết kiệm", + "scan": "Quét", "scan_one_block": "Quét một khối", "scan_qr_code": "Quét mã QR", "scan_qr_code_to_get_address": "Quét mã QR để nhận địa chỉ", diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb index de4a255af5..3da5f3c3c5 100644 --- a/res/values/strings_yo.arb +++ b/res/values/strings_yo.arb @@ -860,6 +860,7 @@ "save_to_downloads": "Fipamọ si Awọn igbasilẹ", "saved_the_trade_id": "Mo ti pamọ́ àmì ìdánimọ̀ pàṣípààrọ̀", "savings": "Ifowopamọ", + "scan": "Ṣayẹwo", "scan_one_block": "Ọlọjẹ ọkan bulọki", "scan_qr_code": "Yan QR koodu", "scan_qr_code_to_get_address": "Ṣayẹwo koodu QR naa lati gba adirẹsi naa", diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index 008aa79145..2e9797fbe1 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -859,6 +859,7 @@ "save_to_downloads": "保存到下载", "saved_the_trade_id": "我已经保存了交易编号", "savings": "储蓄", + "scan": "扫描", "scan_one_block": "扫描一个街区", "scan_qr_code": "扫描二维码", "scan_qr_code_to_get_address": "扫描二维码获取地址",