diff --git a/cw_core/lib/wallet_type.dart b/cw_core/lib/wallet_type.dart index 05ef14175..10a472d60 100644 --- a/cw_core/lib/wallet_type.dart +++ b/cw_core/lib/wallet_type.dart @@ -25,6 +25,21 @@ const walletTypes = [ WalletType.bsc, ]; +const electrumWalletTypes = [ + WalletType.bitcoin, + WalletType.litecoin, + WalletType.bitcoinCash, + WalletType.dogecoin +]; + +const evmWalletTypes = [ + WalletType.ethereum, + WalletType.polygon, + WalletType.base, + WalletType.arbitrum, + WalletType.bsc +]; + @HiveType(typeId: WALLET_TYPE_TYPE_ID) enum WalletType { @HiveField(0) diff --git a/lib/di.dart b/lib/di.dart index 156a36247..715c88660 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -60,6 +60,7 @@ import 'package:cake_wallet/new-ui/pages/lightning_username_page.dart'; import 'package:cake_wallet/new-ui/pages/receive_page.dart'; import 'package:cake_wallet/new-ui/viewmodels/lightning_username/lightning_username_bloc.dart'; import 'package:cake_wallet/new-ui/widgets/addresses_page/address_label_input.dart'; +import 'package:cake_wallet/new-ui/widgets/coins_page/assets_history/transaction_details_modal.dart'; import 'package:cake_wallet/new-ui/widgets/receive_page/receive_label_modal.dart'; import 'package:cake_wallet/new-ui/pages/swap_page.dart'; import 'package:cake_wallet/order/order.dart'; @@ -1419,6 +1420,11 @@ Future setup({ } ); + getIt.registerFactoryParam( + (transactionInfo, _) => TransactionDetailsModal(transactionDetailsViewModel: getIt.get( + param1: [transactionInfo, false])) + ); + getIt.registerFactoryParam( (TransactionInfo transactionInfo, _) => TransactionDetailsPage( transactionDetailsViewModel: getIt.get( diff --git a/lib/entities/new_ui_entities/list_item/list_item_regular_row.dart b/lib/entities/new_ui_entities/list_item/list_item_regular_row.dart index 1f23e2b00..a9ef260d0 100644 --- a/lib/entities/new_ui_entities/list_item/list_item_regular_row.dart +++ b/lib/entities/new_ui_entities/list_item/list_item_regular_row.dart @@ -11,6 +11,8 @@ class ListItemRegularRow extends ListItem { this.onTap, this.trailingIconPath, this.showArrow = true, + this.bottomWidget, + this.trailingWidget, this.truncateTrailingText = false, this.foregroundColor, this.trailingIconSize @@ -22,6 +24,8 @@ class ListItemRegularRow extends ListItem { final String? trailingIconPath; final VoidCallback? onTap; final bool showArrow; + final Widget? bottomWidget; + final Widget? trailingWidget; final bool truncateTrailingText; final Color? foregroundColor; final double? trailingIconSize; diff --git a/lib/new-ui/widgets/coins_page/assets_history/history_section.dart b/lib/new-ui/widgets/coins_page/assets_history/history_section.dart index aa6672fdf..a205ce0e0 100644 --- a/lib/new-ui/widgets/coins_page/assets_history/history_section.dart +++ b/lib/new-ui/widgets/coins_page/assets_history/history_section.dart @@ -1,9 +1,11 @@ +import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/new-ui/widgets/coins_page/assets_history/anonpay_history_tile.dart'; import 'package:cake_wallet/new-ui/widgets/coins_page/assets_history/history_order_tile.dart'; import 'package:cake_wallet/new-ui/widgets/coins_page/assets_history/history_tile.dart'; import 'package:cake_wallet/new-ui/widgets/coins_page/assets_history/history_trade_tile.dart'; import 'package:cake_wallet/new-ui/widgets/coins_page/assets_history/payjoin_history_tile.dart'; +import 'package:cake_wallet/new-ui/widgets/coins_page/assets_history/transaction_details_modal.dart'; import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/utils/date_formatter.dart'; import 'package:cake_wallet/view_model/dashboard/anonpay_transaction_list_item.dart'; @@ -15,7 +17,6 @@ import 'package:cake_wallet/view_model/dashboard/trade_list_item.dart'; import 'package:cake_wallet/view_model/dashboard/transaction_list_item.dart'; import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/sync_status.dart'; -import 'package:cw_core/utils/print_verbose.dart'; import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:intl/intl.dart'; @@ -70,8 +71,10 @@ class HistorySection extends StatelessWidget { asset = CryptoCurrency.btcln; return GestureDetector( - onTap: () => Navigator.of(context) - .pushNamed(Routes.transactionDetails, arguments: transaction), + onTap: () { + final page = getIt.get(param1: transaction); + showModalBottomSheet(isScrollControlled:true,context: context, builder: (context) => page); + }, child: HistoryTile( title: item.formattedTitle + transactionType, date: DateFormat('HH:mm').format(transaction.date), diff --git a/lib/new-ui/widgets/coins_page/assets_history/transaction_details_modal.dart b/lib/new-ui/widgets/coins_page/assets_history/transaction_details_modal.dart new file mode 100644 index 000000000..fe7b15f0f --- /dev/null +++ b/lib/new-ui/widgets/coins_page/assets_history/transaction_details_modal.dart @@ -0,0 +1,226 @@ +import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item.dart'; +import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_regular_row.dart'; +import 'package:cake_wallet/generated/i18n.dart'; +import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart'; +import 'package:cake_wallet/routes.dart'; +import 'package:cake_wallet/src/screens/transaction_details/confirmations_list_item.dart'; +import 'package:cake_wallet/src/screens/transaction_details/transaction_details_list_item.dart'; +import 'package:cake_wallet/src/screens/transaction_details/address_list_item.dart'; +import 'package:cake_wallet/src/widgets/new_list_row/new_list_section.dart'; +import 'package:cake_wallet/utils/address_formatter.dart'; +import 'package:cake_wallet/view_model/transaction_details_view_model.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_mobx/flutter_mobx.dart'; + +class TransactionDetailsModal extends StatefulWidget { + const TransactionDetailsModal({super.key, required this.transactionDetailsViewModel}); + + final TransactionDetailsViewModel transactionDetailsViewModel; + + @override + State createState() => _TransactionDetailsModalState(); +} + +class _TransactionDetailsModalState extends State { + final TextEditingController noteController = TextEditingController(); + final FocusNode noteFocusNode = FocusNode(); + + @override + void initState() { + super.initState(); + noteController.text = widget.transactionDetailsViewModel.note; + + noteFocusNode.addListener(() { + if (!noteFocusNode.hasFocus) { + widget.transactionDetailsViewModel.updateNote(noteController.text); + } + }); + } + + @override + Widget build(BuildContext context) { + return DraggableScrollableSheet( + expand: false, + initialChildSize: 0.6, + minChildSize: 0.25, + maxChildSize: 0.9, + snap: true, + snapSizes: const [0.6, 0.9], + builder: (context, controller) => SafeArea( + bottom: false, + child: Padding( + padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), + child: GestureDetector( + onTap: FocusScope.of(context).unfocus, + child: Container( + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surface, + borderRadius: BorderRadius.vertical(top: Radius.circular(25))), + child: Column( + children: [ + ModalTopBar( + title: S.of(context).transaction, + leadingIcon: Icon(Icons.close), + onLeadingPressed: Navigator.of(context).pop, + ), + Expanded( + child: SingleChildScrollView( + controller: controller, + child: Column( + children: [ + Image.asset( + widget.transactionDetailsViewModel.transactionAsset.iconPath ?? + "", + width: 64, + height: 64), + SizedBox(height: 10), + Text( + widget.transactionDetailsViewModel.formattedTitle + + widget.transactionDetailsViewModel.formattedStatus, + style: TextStyle(fontSize: 20, fontWeight: FontWeight.w500), + ), + Text( + widget.transactionDetailsViewModel.transactionInfo + .amountFormatted(), + style: TextStyle(fontSize: 28), + ), + Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + spacing: 12, + children: [ + NewListSections(sections: { + "": widget.transactionDetailsViewModel.items + .map((item) { + if (item.value.isEmpty) return null; + + final shouldBuildBottomWidget = + item.value.length > 25; + + return ListItemRegularRow( + onTap: () { + Clipboard.setData( + ClipboardData(text: item.value)); + }, + showArrow: false, + keyValue: + ((item.key as ValueKey?)?.value as String?) ?? + item.title, + label: item.title, + trailingWidget: shouldBuildBottomWidget + ? null + : _buildTrailingWIdget(item), + bottomWidget: shouldBuildBottomWidget + ? _buildBottomWidget(item) + : null); + }) + .whereType() + .toList(), + }), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + color: Theme.of(context).colorScheme.surfaceContainer), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + spacing: 8, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(S.of(context).note), + TextField( + focusNode: noteFocusNode, + controller: noteController, + decoration: InputDecoration( + hintText: S.of(context).add_a_note, + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + contentPadding: EdgeInsets.zero, + isDense: true), + ) + ], + ), + ), + ), + Observer( + builder: (_) => NewListSections(sections: { + "view tx": [ + ListItemRegularRow( + keyValue: "view tx on", + label: widget.transactionDetailsViewModel + .explorerDescription, + onTap: widget + .transactionDetailsViewModel.launchExplorer, + foregroundColor: + Theme.of(context).colorScheme.primary, + trailingIconPath: "assets/new-ui/link_arrow.svg", + trailingIconSize: 8) + ], + if (widget.transactionDetailsViewModel.canReplaceByFee) + "rbf": [ + ListItemRegularRow( + keyValue: "replace by fee", + label: S.of(context).bump_fee, + onTap: () { + Navigator.of(context) + .pushNamed(Routes.bumpFeePage, arguments: [ + widget.transactionDetailsViewModel + .transactionInfo, + widget.transactionDetailsViewModel + .rawTransaction + ]); + }) + ] + }), + ) + ], + ), + ), + SizedBox(height: MediaQuery.of(context).viewPadding.bottom) + ], + ), + ), + ) + ], + ), + ), + ), + ), + )); + } + + Widget _buildTrailingWIdget(TransactionDetailsListItem item) { + return switch (item.runtimeType) { + ConfirmationsListItem => Row( + children: [ + Text((item as ConfirmationsListItem).current.toString(), + style: TextStyle(color: Theme.of(context).colorScheme.primary)), + if (item.needed > 0) + Text("/${item.needed}", + style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant)) + ], + ), + _ => Text( + item.value, + style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant), + ) + }; + } + + Widget _buildBottomWidget(TransactionDetailsListItem item) { + return switch (item.runtimeType) { + AddressListItem => AddressFormatter.buildSegmentedAddress( + address: item.value, + evenTextStyle: TextStyle( + fontSize: 12, + fontFamily: "IBM Plex Mono", + color: Theme.of(context).colorScheme.onSurface)), + _ => Text( + item.value, + style: TextStyle(fontSize: 12, color: Theme.of(context).colorScheme.onSurfaceVariant), + ) + }; + } +} diff --git a/lib/src/screens/transaction_details/address_list_item.dart b/lib/src/screens/transaction_details/address_list_item.dart new file mode 100644 index 000000000..1e969f581 --- /dev/null +++ b/lib/src/screens/transaction_details/address_list_item.dart @@ -0,0 +1,5 @@ +import 'package:cake_wallet/src/screens/transaction_details/transaction_details_list_item.dart'; + +class AddressListItem extends TransactionDetailsListItem { + AddressListItem({required super.title, required super.value, super.key}); +} \ No newline at end of file diff --git a/lib/src/screens/transaction_details/confirmations_list_item.dart b/lib/src/screens/transaction_details/confirmations_list_item.dart new file mode 100644 index 000000000..a1c7d4414 --- /dev/null +++ b/lib/src/screens/transaction_details/confirmations_list_item.dart @@ -0,0 +1,12 @@ +import 'package:cake_wallet/src/screens/transaction_details/transaction_details_list_item.dart'; + +class ConfirmationsListItem extends TransactionDetailsListItem { + late final int current; + late final int needed; + + ConfirmationsListItem({required super.title, required super.value, super.key}) { + final parts = value.split("/"); + current = int.tryParse(parts.first)??0; + needed = int.tryParse(parts.last)??0; + } +} \ No newline at end of file diff --git a/lib/src/widgets/new_list_row/list_Item_style_wrapper.dart b/lib/src/widgets/new_list_row/list_Item_style_wrapper.dart index 1e4d5e70f..88ebf59ce 100644 --- a/lib/src/widgets/new_list_row/list_Item_style_wrapper.dart +++ b/lib/src/widgets/new_list_row/list_Item_style_wrapper.dart @@ -7,14 +7,14 @@ class ListItemStyleWrapper extends StatelessWidget { required this.isLastInSection, required this.builder, this.onTap, - this.height = 50, this.iconPath, + this.height, }); final String? iconPath; final bool isFirstInSection; final bool isLastInSection; - final double height; + final double? height; final VoidCallback? onTap; final Widget Function(BuildContext context, TextStyle textStyle, TextStyle labelStyle) builder; @@ -59,7 +59,7 @@ class ListItemStyleWrapper extends StatelessWidget { child: InkWell( onTap: onTap, child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 12), + padding: EdgeInsets.symmetric(horizontal: 12, vertical: height == null ? 12 : 0), child: builder(context, textStyle, labelStyle))))), if(iconPath != null && isLastInSection == false) Container( color: theme.colorScheme.surfaceContainer, diff --git a/lib/src/widgets/new_list_row/list_item_regular_row_widget.dart b/lib/src/widgets/new_list_row/list_item_regular_row_widget.dart index 7705cdcac..e60dcfbaf 100644 --- a/lib/src/widgets/new_list_row/list_item_regular_row_widget.dart +++ b/lib/src/widgets/new_list_row/list_item_regular_row_widget.dart @@ -19,6 +19,8 @@ class ListItemRegularRowWidget extends StatelessWidget { this.truncateTrailingText = false, this.foregroundColor, this.trailingIconSize, + this.bottomWidget, + this.trailingWidget }); final String keyValue; @@ -31,6 +33,8 @@ class ListItemRegularRowWidget extends StatelessWidget { final bool isLastInSection; final bool showArrow; final String? trailingIconPath; + final Widget? bottomWidget; + final Widget? trailingWidget; final bool truncateTrailingText; final Color? foregroundColor; final double? trailingIconSize; @@ -38,74 +42,84 @@ class ListItemRegularRowWidget extends StatelessWidget { @override Widget build(BuildContext context) { final theme = Theme.of(context); - final trailingTextToShow = truncateTrailingText && trailingText != null && trailingText!.length > 20 - ? "${trailingText!.substring(0, 17)}..." - : trailingText; + final trailingTextToShow = + truncateTrailingText && trailingText != null && trailingText!.length > 20 + ? "${trailingText!.substring(0, 17)}..." + : trailingText; return ListItemStyleWrapper( onTap: onTap, iconPath: iconPath, isFirstInSection: isFirstInSection, isLastInSection: isLastInSection, - height: subtitle != null ? 64 : 50, builder: (context, textStyle, labelStyle) { - return Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, children: [ - Expanded( - child: Row( - children: [ - if(iconPath != null) - Padding( - padding: const EdgeInsets.only(right: 12.0), - child: CakeImageWidget(imageUrl: iconPath!, width: 24,height: 24,) - ), - Flexible( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(label, style: foregroundColor == null ? textStyle : textStyle.copyWith(color: foregroundColor)), - if (subtitle != null) - Text( - subtitle!, - style: labelStyle.copyWith(fontSize: 12), - ), - ], - ), - ), - ], - ), - ), - Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - if (trailingTextToShow != null) - Padding( - padding: const EdgeInsets.only(right: 8.0), - child: Text( - trailingTextToShow, - style: labelStyle, - ), + Expanded( + child: Row( + children: [ + if (iconPath != null) + Padding( + padding: const EdgeInsets.only(right: 12.0), + child: CakeImageWidget(imageUrl: iconPath!, width: 24,height: 24,) + ), + Flexible( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(label, + style: foregroundColor == null + ? textStyle + : textStyle.copyWith(color: foregroundColor)), + if (subtitle != null) + Text( + subtitle!, + style: labelStyle.copyWith(fontSize: 12), + ), + ], + ), + ), + ], ), - if(trailingIconPath != null) - CakeImageWidget(imageUrl: - trailingIconPath!, - height: trailingIconSize ?? 18, - width:trailingIconSize ?? 18, - colorFilter: ColorFilter.mode(foregroundColor ?? Theme.of(context).colorScheme.onSurfaceVariant,BlendMode.srcIn), - ) - else if(showArrow) - CakeImageWidget(imageUrl: - "assets/new-ui/arrow_forward.svg", - height: 14, - color: theme.colorScheme.onSurfaceVariant - ) + ), + Row( + children: [ + if (trailingTextToShow != null) + Padding( + padding: const EdgeInsets.only(right: 8.0), + child: Text( + trailingTextToShow, + style: labelStyle, + ), + ), + if (trailingWidget != null) + trailingWidget! + else if (trailingIconPath != null) + CakeImageWidget(imageUrl: + trailingIconPath!, + height: trailingIconSize ?? 18, + width:trailingIconSize ?? 18, + colorFilter: ColorFilter.mode(foregroundColor ?? Theme.of(context).colorScheme.onSurfaceVariant,BlendMode.srcIn), + ) + else if (showArrow) + CakeImageWidget(imageUrl: + "assets/new-ui/arrow_forward.svg", + height: 14, + color: theme.colorScheme.onSurfaceVariant + ) + ], + ), ], ), + if (bottomWidget != null) bottomWidget! ], ); - } - ); + }); } } diff --git a/lib/src/widgets/new_list_row/list_item_text_field_widget.dart b/lib/src/widgets/new_list_row/list_item_text_field_widget.dart index 9b248c2dc..fd66df2c0 100644 --- a/lib/src/widgets/new_list_row/list_item_text_field_widget.dart +++ b/lib/src/widgets/new_list_row/list_item_text_field_widget.dart @@ -36,6 +36,7 @@ class _ListItemTextFieldWidgetState extends State { return ListItemStyleWrapper( isFirstInSection: widget.isFirstInSection, isLastInSection: widget.isLastInSection, + height:50, builder: (context, textStyle, labelStyle) { return Row( children: [ diff --git a/lib/src/widgets/new_list_row/new_list_section.dart b/lib/src/widgets/new_list_row/new_list_section.dart index b36fc5164..21893d81e 100644 --- a/lib/src/widgets/new_list_row/new_list_section.dart +++ b/lib/src/widgets/new_list_row/new_list_section.dart @@ -104,6 +104,8 @@ class NewListSections extends StatelessWidget { truncateTrailingText: item.truncateTrailingText, foregroundColor: item.foregroundColor, trailingIconSize: item.trailingIconSize, + trailingWidget: item.trailingWidget, + bottomWidget: item.bottomWidget, ); } diff --git a/lib/view_model/transaction_details_view_model.dart b/lib/view_model/transaction_details_view_model.dart index dc49babf2..ed2c45e3b 100644 --- a/lib/view_model/transaction_details_view_model.dart +++ b/lib/view_model/transaction_details_view_model.dart @@ -1,8 +1,13 @@ +import 'package:cake_wallet/reactions/wallet_connect.dart'; +import 'package:cake_wallet/solana/solana.dart'; +import 'package:cake_wallet/src/screens/transaction_details/address_list_item.dart'; +import 'package:cake_wallet/src/screens/transaction_details/confirmations_list_item.dart'; import 'package:cake_wallet/store/app_store.dart'; import 'package:cake_wallet/core/address_validator.dart'; import 'package:cake_wallet/tron/tron.dart'; -import 'package:cake_wallet/wownero/wownero.dart'; +import 'package:cake_wallet/zano/zano.dart'; import 'package:cw_core/crypto_currency.dart'; +import 'package:cw_core/currency_for_wallet_type.dart'; import 'package:cw_core/utils/print_verbose.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/transaction_info.dart'; @@ -13,10 +18,8 @@ import 'package:cake_wallet/entities/priority_for_wallet_type.dart'; import 'package:cake_wallet/entities/transaction_description.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/monero/monero.dart'; -import 'package:cake_wallet/src/screens/transaction_details/blockexplorer_list_item.dart'; import 'package:cake_wallet/src/screens/transaction_details/rbf_details_list_fee_picker_item.dart'; import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart'; -import 'package:cake_wallet/src/screens/transaction_details/textfield_list_item.dart'; import 'package:cake_wallet/src/screens/transaction_details/transaction_details_list_item.dart'; import 'package:cake_wallet/src/screens/transaction_details/transaction_expandable_list_item.dart'; import 'package:cake_wallet/utils/date_formatter.dart'; @@ -26,12 +29,181 @@ import 'package:cw_core/transaction_direction.dart'; import 'package:cw_core/transaction_priority.dart'; import 'package:flutter/foundation.dart'; import 'package:hive/hive.dart'; -import 'package:intl/src/intl/date_format.dart'; import 'package:mobx/mobx.dart'; import 'package:url_launcher/url_launcher.dart'; part 'transaction_details_view_model.g.dart'; +bool _trueFunc(_) => true; + +bool isLightning(TransactionInfo tx) { + printV(tx.additionalInfo); + return (tx.additionalInfo["isLightning"] as bool?) ?? false; +} + +class TxDetailRowDefinition { + final String keyString; + final String title; + final String Function(TransactionDetailsViewModelBase) valueGetter; + final bool Function(TransactionDetailsViewModelBase) applicable; + final dynamic Function({ + required String title, + required String value, + required Key key, + }) listItemBuilder; + + TxDetailRowDefinition( + {required this.keyString, + required this.title, + required this.valueGetter, + this.applicable = _trueFunc, + this.listItemBuilder = StandartListItem.new}); + + static final List defs = [ + TxDetailRowDefinition( + keyString: "standard_list_item_transaction_details_date_key", + title: S.current.transaction_details_date, + valueGetter: (vm) => DateFormatter.withCurrentLocal().format(vm.transactionInfo.date)), + + + TxDetailRowDefinition( + keyString: "standard_list_item_transaction_details_height_key", + title: S.current.transaction_details_height, + valueGetter: (vm) => vm.transactionInfo.height.toString(), + applicable: (vm) => !([WalletType.solana, WalletType.tron].contains(vm.wallet.type) && + !isLightning(vm.transactionInfo))), + + + TxDetailRowDefinition( + keyString: "standard_list_item_transaction_details_fee_key", + title: S.current.transaction_details_fee, + valueGetter: (vm) => vm.transactionInfo.feeFormatted()!, + applicable: (vm) => + vm.wallet.type != WalletType.nano && + (vm.transactionInfo.feeFormatted() ?? "").isNotEmpty), + + + TxDetailRowDefinition( + keyString: "standard_list_item_transaction_confirmations_key", + title: S.current.confirmations, + valueGetter: (vm) => "${vm.transactionInfo.confirmations}/${vm.neededConfirmations}", + applicable: (vm) => + [...electrumWalletTypes, ...evmWalletTypes, WalletType.zcash, WalletType.monero] + .contains(vm.wallet.type) && + !isLightning(vm.transactionInfo), + listItemBuilder: ConfirmationsListItem.new), + + + TxDetailRowDefinition( + keyString: "standard_list_item_transaction_details_recipient_address_key", + title: S.current.transaction_details_recipient_address, + valueGetter: (vm) { + vm.isRecipientAddressShown = true; + switch (vm.wallet.type) { + case WalletType.monero: + return monero!.getTransactionAddress( + vm.wallet, + vm.transactionInfo.additionalInfo['accountIndex'] as int, + vm.transactionInfo.additionalInfo['addressIndex'] as int); + case WalletType.bitcoin: + return (bitcoin!.getTransactionAddresses(vm.wallet, vm.transactionInfo) ?? []) + .firstOrNull ?? + ""; + case WalletType.tron: + return tron!.getTronBase58Address(vm.transactionInfo.to!, vm.wallet); + default: + return vm.transactionInfo.to!; + } + }, + applicable: (vm) => + vm.showRecipientAddress && + (vm.transactionInfo.to != null || + [WalletType.monero, WalletType.tron].contains(vm.wallet.type) || + vm.wallet.type == WalletType.bitcoin && + vm.transactionInfo.direction == TransactionDirection.incoming), + listItemBuilder: AddressListItem.new), + + + TxDetailRowDefinition( + keyString: "standard_list_item_transaction_details_source_address_key", + title: S.current.transaction_details_source_address, + valueGetter: (vm) { + switch (vm.wallet.type) { + case WalletType.tron: + return tron!.getTronBase58Address(vm.transactionInfo.from!, vm.wallet); + default: + return vm.transactionInfo.from!; + } + }, + applicable: (vm) => vm.transactionInfo.from != null, + listItemBuilder: AddressListItem.new), + + TxDetailRowDefinition( + keyString: "standard_list_item_address_label_key", + title: S.current.address_label, + valueGetter: (vm) => monero!.getSubaddressLabel( + vm.wallet, + vm.transactionInfo.additionalInfo['accountIndex'] as int, + vm.transactionInfo.additionalInfo['addressIndex'] as int), + applicable: (vm) => vm.wallet.type == WalletType.monero), + + + TxDetailRowDefinition( + keyString: "standard_list_item_transaction_key", + title: S.current.transaction_key, + valueGetter: (vm) { + final descriptionKey = + '${vm.transactionInfo.txHash}_${vm.wallet.walletAddresses.primaryAddress}'; + + final description = vm.transactionDescriptionBox.values.firstWhere( + (val) => val.id == descriptionKey || val.id == vm.transactionInfo.txHash, + orElse: () => TransactionDescription(id: descriptionKey)); + return vm.transactionInfo.additionalInfo['key'] as String? ?? + description.transactionKey ?? + ""; + }, + applicable: (vm) => vm.wallet.type == WalletType.monero), + + + TxDetailRowDefinition( + keyString: "standard_list_item_transaction_confirmed_key", + title: S.current.confirmed_tx, + valueGetter: (vm) => (vm.transactionInfo.confirmations > 0).toString(), + applicable: (vm) => vm.wallet.type == WalletType.nano), + + + TxDetailRowDefinition( + keyString: "standard_list_item_transaction_details_memo_key", + title: S.current.memo, + valueGetter: (vm) => vm.transactionInfo.additionalInfo['memo'] as String, + applicable: (vm) => + vm.wallet.type == WalletType.zcash && + vm.transactionInfo.additionalInfo["memo"] != null), + + + TxDetailRowDefinition( + keyString: "standard_list_item_transaction_details_asset_id_key", + title: "Asset ID", + valueGetter: (vm) => + vm.transactionInfo.additionalInfo["assetId"] as String? ?? "Unknown asset id", + applicable: (vm) => vm.wallet.type == WalletType.zano), + + + TxDetailRowDefinition( + keyString: "standard_list_item_transaction_details_comment_key", + title: S.current.transaction_details_title, + valueGetter: (vm) => vm.transactionInfo.additionalInfo['comment'] as String? ?? "", + applicable: (vm) => vm.wallet.type == WalletType.zano), + + + TxDetailRowDefinition( + keyString: "standard_list_item_transaction_details_id_key", + title: S.current.transaction_details_transaction_id, + valueGetter: (vm) => vm.transactionInfo.txHash, + ), + ]; +} + class TransactionDetailsViewModel = TransactionDetailsViewModelBase with _$TransactionDetailsViewModel; @@ -49,61 +221,19 @@ abstract class TransactionDetailsViewModelBase with Store { isRecipientAddressShown = false, _appStore = appStore, showRecipientAddress = appStore.settingsStore.shouldSaveRecipientAddress { - final dateFormat = DateFormatter.withCurrentLocal(); final tx = transactionInfo; - // TODO: can be cleaned further - switch (wallet.type) { - case WalletType.monero: - _addMoneroListItems(tx, dateFormat); - break; - case WalletType.bitcoin: - _addElectrumListItems(tx, dateFormat, CryptoCurrency.btc); - if (!canReplaceByFee) _checkForRBF(tx); - break; - case WalletType.litecoin: - _addLitecoinListItems(tx, dateFormat); - case WalletType.bitcoinCash: - _addElectrumListItems(tx, dateFormat, CryptoCurrency.bch); - break; - case WalletType.haven: - _addHavenListItems(tx, dateFormat); - break; - case WalletType.ethereum: - case WalletType.polygon: - case WalletType.base: - case WalletType.arbitrum: - case WalletType.bsc: - _addEVMListItems(tx, dateFormat); - break; - case WalletType.nano: - _addNanoListItems(tx, dateFormat); - break; - case WalletType.solana: - _addSolanaListItems(tx, dateFormat); - break; - case WalletType.tron: - _addTronListItems(tx, dateFormat); - break; - case WalletType.wownero: - _addWowneroListItems(tx, dateFormat); - break; - case WalletType.zano: - _addZanoListItems(tx, dateFormat); - break; - case WalletType.decred: - _addDecredListItems(tx, dateFormat); - break; - case WalletType.dogecoin: - _addDogecoinListItems(tx, dateFormat); - break; - case WalletType.zcash: - _addZcashListItems(tx, dateFormat); - case WalletType.none: - case WalletType.banano: - break; + for (final def in TxDetailRowDefinition.defs) { + if (def.applicable(this)) { + items.add(def.listItemBuilder( + title: def.title, + value: def.valueGetter(this), + key: ValueKey(def.keyString)) as TransactionDetailsListItem); + } } + _checkForRBF(tx); + final descriptionKey = '${transactionInfo.txHash}_${wallet.walletAddresses.primaryAddress}'; final description = transactionDescriptionBox.values.firstWhere( (val) => val.id == descriptionKey || val.id == transactionInfo.txHash, @@ -114,7 +244,7 @@ abstract class TransactionDetailsViewModelBase with Store { if (recipientAddress?.isNotEmpty ?? false) { items.add( - StandartListItem( + AddressListItem( title: S.current.transaction_details_recipient_address, value: recipientAddress!, key: ValueKey('standard_list_item_${recipientAddress}_key'), @@ -122,44 +252,28 @@ abstract class TransactionDetailsViewModelBase with Store { ); } } + } - final type = wallet.type; + void updateNote(String note) { + final descriptionKey = '${transactionInfo.txHash}_${wallet.walletAddresses.primaryAddress}'; + final description = transactionDescriptionBox.values.firstWhere( + (val) => val.id == descriptionKey || val.id == transactionInfo.txHash, + orElse: () => TransactionDescription(id: descriptionKey)); - final isLightning = tx.additionalInfo["isLightning"] as bool? ?? false; + description.transactionNote = note; - if (!isLightning) { - items.add( - BlockExplorerListItem( - title: S.current.view_in_block_explorer, - value: _explorerDescription(type, wallet.chainId), - onTap: () async { - try { - final uri = Uri.parse(_explorerUrl(type, tx.txHash, wallet.chainId)); - if (await canLaunchUrl(uri)) await launchUrl( - uri, mode: LaunchMode.externalApplication); - } catch (e) {} - }, - key: ValueKey('block_explorer_list_item_${type.name}_wallet_type_key'), - ), - ); + if (description.isInBox) { + description.save(); + } else { + transactionDescriptionBox.add(description); } + } - items.add( - TextFieldListItem( - title: S.current.note_tap_to_change, - value: description.note, - onSubmitted: (value) { - description.transactionNote = value; - - if (description.isInBox) { - description.save(); - } else { - transactionDescriptionBox.add(description); - } - }, - key: ValueKey('textfield_list_item_note_entry_key'), - ), - ); + String get note { + final descriptionKey = '${transactionInfo.txHash}_${wallet.walletAddresses.primaryAddress}'; + final description = transactionDescriptionBox.values.firstWhereOrNull( + (val) => val.id == descriptionKey || val.id == transactionInfo.txHash); + return description?.transactionNote??""; } final TransactionInfo transactionInfo; @@ -176,22 +290,128 @@ abstract class TransactionDetailsViewModelBase with Store { String? rawTransaction; TransactionPriority? transactionPriority; + CryptoCurrency get transactionAsset { + if (isEVMCompatibleChain(wallet.type)) { + return evm!.assetOfTransaction(wallet, transactionInfo); + } + + return switch (wallet.type) { + WalletType.solana => solana!.assetOfTransaction(wallet, transactionInfo), + WalletType.tron => tron!.assetOfTransaction(wallet, transactionInfo), + WalletType.zano => zano!.assetOfTransaction(wallet, transactionInfo) ?? CryptoCurrency.zano, + _ => walletTypeToCryptoCurrency(wallet.type) + }; + } + + + // TODO integrate these getters with the TransactionInfo object + String get formattedPendingStatus { + switch (wallet.type) { + case WalletType.monero: + case WalletType.haven: + case WalletType.zano: + if (transactionInfo.confirmations >= 0 && transactionInfo.confirmations < 10) { + return ' (${transactionInfo.confirmations}/10)'; + } + break; + case WalletType.wownero: + if (transactionInfo.confirmations >= 0 && transactionInfo.confirmations < 3) { + return ' (${transactionInfo.confirmations}/3)'; + } + break; + case WalletType.litecoin: + bool isPegIn = (transactionInfo.additionalInfo["isPegIn"] as bool?) ?? false; + bool isPegOut = (transactionInfo.additionalInfo["isPegOut"] as bool?) ?? false; + bool fromPegOut = (transactionInfo.additionalInfo["fromPegOut"] as bool?) ?? false; + String str = ''; + if (transactionInfo.confirmations <= 0) { + str = S.current.pending; + } + if ((isPegOut || fromPegOut) && + transactionInfo.confirmations >= 0 && + transactionInfo.confirmations < 6) { + str = " (${transactionInfo.confirmations}/6)"; + } + if (isPegIn) { + str += " (Peg In)"; + } + if (isPegOut) { + str += " (Peg Out)"; + } + return str; + default: + return ''; + } + + return ''; + } + + String get formattedStatus { + if ([ + WalletType.monero, + WalletType.haven, + WalletType.wownero, + WalletType.litecoin, + WalletType.zano, + ].contains(wallet.type)) { + return formattedPendingStatus; + } + + return transactionInfo.isPending ? S.current.pending : ''; + } + + int get neededConfirmations { + switch (wallet.type) { + case WalletType.monero: + case WalletType.haven: + case WalletType.zano: + return 10; + case WalletType.wownero: + return 3; + case WalletType.litecoin: + bool isPegOut = (transactionInfo.additionalInfo["isPegOut"] as bool?) ?? false; + bool fromPegOut = (transactionInfo.additionalInfo["fromPegOut"] as bool?) ?? false; + if(isPegOut || fromPegOut) + return 6; + default: + return 0; + } + return 0; + } + + + + String get formattedTitle { + if (transactionInfo.additionalInfo['autoShield'] == true) { + return "Autoshield"; + } + if (transactionInfo.direction == TransactionDirection.incoming) { + return S.current.received; + } + + return S.current.sent; + } + @observable bool canReplaceByFee; - String _explorerUrl(WalletType type, String txId, int? chainId) { - if (chainId != null) { - final explorerUrl = evm!.getExplorerUrlForChainId(chainId); + String get _explorerUrl { + + final txId = transactionInfo.id; + if (wallet.chainId != null) { + final explorerUrl = evm!.getExplorerUrlForChainId(wallet.chainId!); if (explorerUrl != null) return '$explorerUrl/tx/${txId}'; } - switch (type) { + switch (wallet.type) { case WalletType.monero: return 'https://monero.com/tx/${txId}'; case WalletType.bitcoin: return 'https://mempool.cakewallet.com/${wallet.isTestnet ? "testnet/" : ""}tx/${txId}'; case WalletType.litecoin: - return 'https://blockchair.com/litecoin/transaction/${txId}'; + return bitcoin!.txIsMweb(transactionInfo) + ? "https://www.mwebexplorer.com/blocks/block/${transactionInfo.height}" + : 'https://blockchair.com/litecoin/transaction/${txId}'; case WalletType.bitcoinCash: return 'https://blockchair.com/bitcoin-cash/transaction/${txId}'; case WalletType.haven: @@ -229,390 +449,10 @@ abstract class TransactionDetailsViewModelBase with Store { } } - String _explorerDescription(WalletType type, int? chainId) { - if (chainId != null) { - final explorerUrl = evm!.getExplorerUrlForChainId(chainId, showProtocol: false); - if (explorerUrl != null) { - return S.current.view_transaction_on + explorerUrl; - } - } - switch (type) { - case WalletType.monero: - return S.current.view_transaction_on + 'Monero.com'; - case WalletType.bitcoin: - return S.current.view_transaction_on + 'mempool.space'; - case WalletType.litecoin: - case WalletType.bitcoinCash: - case WalletType.dogecoin: - return S.current.view_transaction_on + 'Blockchair.com'; - case WalletType.haven: - return S.current.view_transaction_on + 'explorer.havenprotocol.org'; - case WalletType.ethereum: - return S.current.view_transaction_on + 'etherscan.io'; - case WalletType.nano: - return S.current.view_transaction_on + 'nanexplorer.com'; - case WalletType.banano: - return S.current.view_transaction_on + 'nanexplorer.com'; - case WalletType.polygon: - return S.current.view_transaction_on + 'polygonscan.com'; - case WalletType.bsc: - return S.current.view_transaction_on + 'bscscan.com'; - case WalletType.solana: - return S.current.view_transaction_on + 'solscan.io'; - case WalletType.tron: - return S.current.view_transaction_on + 'tronscan.org'; - case WalletType.wownero: - return S.current.view_transaction_on + 'Wownero.com'; - case WalletType.zano: - return S.current.view_transaction_on + 'explorer.zano.org'; - case WalletType.decred: - return S.current.view_transaction_on + 'dcrdata.decred.org'; - case WalletType.base: - return S.current.view_transaction_on + 'basescan.org'; - case WalletType.arbitrum: - return S.current.view_transaction_on + 'arbiscan.io'; - case WalletType.zcash: - return S.current.view_transaction_on + 'blockchair.com'; - case WalletType.none: - return ''; - } - } + String get explorerDescription => S.current.view_transaction_on + Uri.parse(_explorerUrl).host; - void _addMoneroListItems(TransactionInfo tx, DateFormat dateFormat) { - final descriptionKey = '${transactionInfo.txHash}_${wallet.walletAddresses.primaryAddress}'; - final description = transactionDescriptionBox.values.firstWhere( - (val) => val.id == descriptionKey || val.id == transactionInfo.txHash, - orElse: () => TransactionDescription(id: descriptionKey)); - - final key = tx.additionalInfo['key'] as String? ?? description.transactionKey; - final accountIndex = tx.additionalInfo['accountIndex'] as int; - final addressIndex = tx.additionalInfo['addressIndex'] as int; - final feeFormatted = tx.feeFormatted(); - final _items = [ - StandartListItem( - title: S.current.transaction_details_transaction_id, - value: tx.txHash, - key: ValueKey('standard_list_item_transaction_details_id_key'), - ), - StandartListItem( - title: S.current.transaction_details_date, - value: dateFormat.format(tx.date), - key: ValueKey('standard_list_item_transaction_details_date_key'), - ), - StandartListItem( - title: S.current.transaction_details_height, - value: '${tx.height}', - key: ValueKey('standard_list_item_transaction_details_height_key'), - ), - StandartListItem( - title: S.current.transaction_details_amount, - value: tx.amountFormatted(), - key: ValueKey('standard_list_item_transaction_details_amount_key'), - ), - if (feeFormatted != null) - StandartListItem( - title: S.current.transaction_details_fee, - value: feeFormatted, - key: ValueKey('standard_list_item_transaction_details_fee_key'), - ), - if (key?.isNotEmpty ?? false) - StandartListItem( - title: S.current.transaction_key, - value: key!, - key: ValueKey('standard_list_item_transaction_key'), - ), - ]; - - if (tx.direction == TransactionDirection.incoming) { - try { - final address = monero!.getTransactionAddress(wallet, accountIndex, addressIndex); - final label = monero!.getSubaddressLabel(wallet, accountIndex, addressIndex); - - if (address.isNotEmpty) { - isRecipientAddressShown = true; - _items.add( - StandartListItem( - title: S.current.transaction_details_recipient_address, - value: address, - key: ValueKey('standard_list_item_transaction_details_recipient_address_key'), - ), - ); - } - - if (label.isNotEmpty) { - _items.add(StandartListItem( - title: S.current.address_label, - value: label, - key: ValueKey('standard_list_item_address_label_key'), - )); - } - } catch (e) { - printV(e.toString()); - } - } - - items.addAll(_items); - } - - void _addElectrumListItems( - TransactionInfo tx, DateFormat dateFormat, CryptoCurrency cryptoCurrency) { - final isLightning = (tx.additionalInfo["isLightning"] as bool?) ?? false; - - final currency = isLightning ? CryptoCurrency.btcln : cryptoCurrency; - final symbol = _appStore.amountParsingProxy.getCryptoSymbol(currency); - final amountFormatted = _appStore.amountParsingProxy.getDisplayCryptoString( - tx.amount, currency); - final feeFormatted = (tx.fee != null) - ? _appStore.amountParsingProxy.getDisplayCryptoString(tx.fee!, currency) - : ""; - - final _items = [ - StandartListItem( - title: S.current.transaction_details_transaction_id, - value: tx.txHash, - key: ValueKey('standard_list_item_transaction_details_id_key'), - ), - StandartListItem( - title: S.current.transaction_details_date, - value: dateFormat.format(tx.date), - key: ValueKey('standard_list_item_transaction_details_date_key'), - ), - if (!isLightning) ...[ - StandartListItem( - title: S.current.confirmations, - value: tx.confirmations.toString(), - key: ValueKey('standard_list_item_transaction_confirmations_key'), - ), - StandartListItem( - title: S.current.transaction_details_height, - value: '${tx.height}', - key: ValueKey('standard_list_item_transaction_details_height_key'), - ), - ], - StandartListItem( - title: S.current.transaction_details_amount, - value: '$amountFormatted $symbol', - key: ValueKey('standard_list_item_transaction_details_amount_key'), - ), - if (tx.feeFormatted()?.isNotEmpty ?? false) - StandartListItem( - title: S.current.transaction_details_fee, - value: '$feeFormatted $symbol', - key: ValueKey('standard_list_item_transaction_details_fee_key'), - ), - ]; - - if (wallet.type == WalletType.bitcoin && tx.direction == TransactionDirection.incoming) { - try { - final addresses = bitcoin!.getTransactionAddresses(wallet, tx); - - if (addresses != null) { - isRecipientAddressShown = true; - for (final address in addresses) { - _items.add( - StandartListItem( - title: S.current.transaction_details_recipient_address, - value: address, - key: ValueKey('standard_list_item_transaction_details_recipient_address_key'), - ), - ); - } - } - } catch (e) { - printV(e.toString()); - } - } - - items.addAll(_items); - } - - void _addLitecoinListItems(TransactionInfo tx, DateFormat dateFormat) { - _addElectrumListItems(tx, dateFormat, CryptoCurrency.ltc); - - bool isMweb = bitcoin!.txIsMweb(tx); - - final _items = [ - if (isMweb) - BlockExplorerListItem( - title: S.current.view_in_block_explorer, - value: S.current.view_transaction_on + 'mwebexplorer.com', - onTap: () async { - try { - final uri = Uri.parse('https://www.mwebexplorer.com/blocks/block/${tx.height}'); - if (await canLaunchUrl(uri)) - await launchUrl(uri, mode: LaunchMode.externalApplication); - } catch (e) {} - }, - key: ValueKey('block_explorer_list_item_mweb_wallet_type_key'), - ), - ]; - - items.addAll(_items); - } - - void _addHavenListItems(TransactionInfo tx, DateFormat dateFormat) { - items.addAll([ - StandartListItem( - title: S.current.transaction_details_transaction_id, - value: tx.txHash, - key: ValueKey('standard_list_item_transaction_details_id_key'), - ), - StandartListItem( - title: S.current.transaction_details_date, - value: dateFormat.format(tx.date), - key: ValueKey('standard_list_item_transaction_details_date_key'), - ), - StandartListItem( - title: S.current.transaction_details_height, - value: '${tx.height}', - key: ValueKey('standard_list_item_transaction_details_height_key'), - ), - StandartListItem( - title: S.current.transaction_details_amount, - value: tx.amountFormatted(), - key: ValueKey('standard_list_item_transaction_details_amount_key'), - ), - if (tx.feeFormatted()?.isNotEmpty ?? false) - StandartListItem( - title: S.current.transaction_details_fee, - value: tx.feeFormatted()!, - key: ValueKey('standard_list_item_transaction_details_fee_key'), - ), - ]); - } - - void _addEVMListItems(TransactionInfo tx, DateFormat dateFormat) { - final _items = [ - StandartListItem( - title: S.current.transaction_details_transaction_id, - value: tx.txHash, - key: ValueKey('standard_list_item_transaction_details_id_key'), - ), - StandartListItem( - title: S.current.transaction_details_date, - value: dateFormat.format(tx.date), - key: ValueKey('standard_list_item_transaction_details_date_key'), - ), - StandartListItem( - title: S.current.confirmations, - value: tx.confirmations.toString(), - key: ValueKey('standard_list_item_transaction_confirmations_key'), - ), - StandartListItem( - title: S.current.transaction_details_height, - value: '${tx.height}', - key: ValueKey('standard_list_item_transaction_details_height_key'), - ), - StandartListItem( - title: S.current.transaction_details_amount, - value: tx.amountFormatted(), - key: ValueKey('standard_list_item_transaction_details_amount_key'), - ), - if (tx.feeFormatted()?.isNotEmpty ?? false) - StandartListItem( - title: S.current.transaction_details_fee, - value: tx.feeFormatted()!, - key: ValueKey('standard_list_item_transaction_details_fee_key'), - ), - if (showRecipientAddress && tx.to != null) - StandartListItem( - title: S.current.transaction_details_recipient_address, - value: tx.to!, - key: ValueKey('standard_list_item_transaction_details_recipient_address_key'), - ), - if (tx.direction == TransactionDirection.incoming && tx.from != null) - StandartListItem( - title: S.current.transaction_details_source_address, - value: tx.from!, - key: ValueKey('standard_list_item_transaction_details_source_address_key'), - ), - ]; - - items.addAll(_items); - } - - void _addNanoListItems(TransactionInfo tx, DateFormat dateFormat) { - final _items = [ - StandartListItem( - title: S.current.transaction_details_transaction_id, - value: tx.txHash, - key: ValueKey('standard_list_item_transaction_details_id_key'), - ), - if (showRecipientAddress && tx.to != null) - StandartListItem( - title: S.current.transaction_details_recipient_address, - value: tx.to!, - key: ValueKey('standard_list_item_transaction_details_recipient_address_key'), - ), - if (showRecipientAddress && tx.from != null) - StandartListItem( - title: S.current.transaction_details_source_address, - value: tx.from!, - key: ValueKey('standard_list_item_transaction_details_source_address_key'), - ), - StandartListItem( - title: S.current.transaction_details_amount, - value: tx.amountFormatted(), - key: ValueKey('standard_list_item_transaction_details_amount_key'), - ), - StandartListItem( - title: S.current.transaction_details_date, - value: dateFormat.format(tx.date), - key: ValueKey('standard_list_item_transaction_details_date_key'), - ), - StandartListItem( - title: S.current.confirmed_tx, - value: (tx.confirmations > 0).toString(), - key: ValueKey('standard_list_item_transaction_confirmed_key'), - ), - StandartListItem( - title: S.current.transaction_details_height, - value: '${tx.height}', - key: ValueKey('standard_list_item_transaction_details_height_key'), - ), - ]; - - items.addAll(_items); - } - - void _addSolanaListItems(TransactionInfo tx, DateFormat dateFormat) { - final _items = [ - StandartListItem( - title: S.current.transaction_details_transaction_id, - value: tx.txHash.replaceAll(RegExp(r'_(incoming|outgoing)$'), ''), - key: ValueKey('standard_list_item_transaction_details_id_key'), - ), - StandartListItem( - title: S.current.transaction_details_date, - value: dateFormat.format(tx.date), - key: ValueKey('standard_list_item_transaction_details_date_key'), - ), - StandartListItem( - title: S.current.transaction_details_amount, - value: tx.amountFormatted(), - key: ValueKey('standard_list_item_transaction_details_amount_key'), - ), - if (tx.feeFormatted()?.isNotEmpty ?? false) - StandartListItem( - title: S.current.transaction_details_fee, - value: tx.feeFormatted()!, - key: ValueKey('standard_list_item_transaction_details_fee_key'), - ), - if (showRecipientAddress && tx.to != null) - StandartListItem( - title: S.current.transaction_details_recipient_address, - value: tx.to!, - key: ValueKey('standard_list_item_transaction_details_recipient_address_key'), - ), - if (tx.from != null) - StandartListItem( - title: S.current.transaction_details_source_address, - value: tx.from!, - key: ValueKey('standard_list_item_transaction_details_source_address_key'), - ), - ]; - - items.addAll(_items); + void launchExplorer() { + launchUrl(Uri.parse(_explorerUrl)); } void addBumpFeesListItems(TransactionInfo tx, String rawTransaction) { @@ -699,186 +539,8 @@ abstract class TransactionDetailsViewModelBase with Store { } } - void _addTronListItems(TransactionInfo tx, DateFormat dateFormat) { - final _items = [ - StandartListItem( - title: S.current.transaction_details_transaction_id, - value: tx.txHash, - key: ValueKey('standard_list_item_transaction_details_id_key'), - ), - StandartListItem( - title: S.current.transaction_details_date, - value: dateFormat.format(tx.date), - key: ValueKey('standard_list_item_transaction_details_date_key'), - ), - StandartListItem( - title: S.current.transaction_details_amount, - value: tx.amountFormatted(), - key: ValueKey('standard_list_item_transaction_details_amount_key'), - ), - if (tx.feeFormatted()?.isNotEmpty ?? false) - StandartListItem( - title: S.current.transaction_details_fee, - value: tx.feeFormatted()!, - key: ValueKey('standard_list_item_transaction_details_fee_key'), - ), - if (showRecipientAddress && tx.to != null) - StandartListItem( - title: S.current.transaction_details_recipient_address, - value: tron!.getTronBase58Address(tx.to!, wallet), - key: ValueKey('standard_list_item_transaction_details_recipient_address_key'), - ), - if (tx.from != null) - StandartListItem( - title: S.current.transaction_details_source_address, - value: tron!.getTronBase58Address(tx.from!, wallet), - key: ValueKey('standard_list_item_transaction_details_source_address_key'), - ), - ]; - items.addAll(_items); - } - void _addDecredListItems(TransactionInfo tx, DateFormat dateFormat) { - final _items = [ - StandartListItem( - title: S.current.transaction_details_transaction_id, - value: tx.txHash, - key: ValueKey('standard_list_item_transaction_details_id_key'), - ), - StandartListItem( - title: S.current.transaction_details_date, - value: dateFormat.format(tx.date), - key: ValueKey('standard_list_item_transaction_details_date_key'), - ), - StandartListItem( - title: S.current.transaction_details_height, - value: '${tx.height}', - key: ValueKey('standard_list_item_transaction_details_height_key'), - ), - StandartListItem( - title: S.current.transaction_details_amount, - value: tx.amountFormatted(), - key: ValueKey('standard_list_item_transaction_details_amount_key'), - ), - if (tx.feeFormatted()?.isNotEmpty ?? false) - StandartListItem( - title: S.current.transaction_details_fee, - value: tx.feeFormatted()!, - key: ValueKey('standard_list_item_transaction_details_fee_key'), - ), - if (showRecipientAddress && tx.to != null) - StandartListItem( - title: S.current.transaction_details_recipient_address, - value: tx.to!, - key: ValueKey('standard_list_item_transaction_details_recipient_address_key'), - ), - if (tx.from != null) - StandartListItem( - title: S.current.transaction_details_source_address, - value: tx.from!, - key: ValueKey('standard_list_item_transaction_details_source_address_key'), - ), - ]; - - items.addAll(_items); - } - - void _addZcashListItems(TransactionInfo tx, DateFormat dateFormat) { - final memo = tx.additionalInfo['memo'] as String?; - - final _items = [ - StandartListItem( - title: S.current.transaction_details_transaction_id, - value: tx.txHash, - key: ValueKey('standard_list_item_transaction_details_id_key'), - ), - if (tx.to != null) - StandartListItem( - title: S.current.transaction_details_recipient_address, - value: tx.to!, - key: ValueKey('standard_list_item_transaction_details_recipient_address_key'), - ), - StandartListItem( - title: S.current.transaction_details_date, - value: dateFormat.format(tx.date), - key: ValueKey('standard_list_item_transaction_details_date_key'), - ), - StandartListItem( - title: S.current.confirmations, - value: tx.confirmations.toString(), - key: ValueKey('standard_list_item_transaction_confirmations_key'), - ), - StandartListItem( - title: S.current.transaction_details_height, - value: '${tx.height ?? 0}', - key: ValueKey('standard_list_item_transaction_details_height_key'), - ), - StandartListItem( - title: S.current.transaction_details_amount, - value: tx.amountFormatted(), - key: ValueKey('standard_list_item_transaction_details_amount_key'), - ), - if (tx.feeFormatted() != null && tx.feeFormatted()!.isNotEmpty) - StandartListItem( - title: S.current.transaction_details_fee, - value: tx.feeFormatted()!, - key: ValueKey('standard_list_item_transaction_details_fee_key'), - ), - if (memo != null && memo.isNotEmpty) - StandartListItem( - title: S.current.memo, - value: memo, - key: ValueKey('standard_list_item_transaction_details_memo_key'), - ), - ]; - items.addAll(_items); - } - - void _addDogecoinListItems(TransactionInfo tx, DateFormat dateFormat) { - final _items = [ - StandartListItem( - title: S.current.transaction_details_transaction_id, - value: tx.txHash, - key: ValueKey('standard_list_item_transaction_details_id_key'), - ), - StandartListItem( - title: S.current.transaction_details_date, - value: dateFormat.format(tx.date), - key: ValueKey('standard_list_item_transaction_details_date_key'), - ), - StandartListItem( - title: S.current.transaction_details_height, - value: '${tx.height}', - key: ValueKey('standard_list_item_transaction_details_height_key'), - ), - StandartListItem( - title: S.current.transaction_details_amount, - value: tx.amountFormatted(), - key: ValueKey('standard_list_item_transaction_details_amount_key'), - ), - if (tx.feeFormatted()?.isNotEmpty ?? false) - StandartListItem( - title: S.current.transaction_details_fee, - value: tx.feeFormatted()!, - key: ValueKey('standard_list_item_transaction_details_fee_key'), - ), - if (showRecipientAddress && tx.to != null) - StandartListItem( - title: S.current.transaction_details_recipient_address, - value: tx.to!, - key: ValueKey('standard_list_item_transaction_details_recipient_address_key'), - ), - if (tx.from != null) - StandartListItem( - title: S.current.transaction_details_source_address, - value: tx.from!, - key: ValueKey('standard_list_item_transaction_details_source_address_key'), - ), - ]; - - items.addAll(_items); - } @action Future _checkForRBF(TransactionInfo tx) async { @@ -929,93 +591,5 @@ abstract class TransactionDetailsViewModelBase with Store { ? '' : sendViewModel.pendingTransactionFeeFiatAmount + ' ' + sendViewModel.fiat.title; - void _addWowneroListItems(TransactionInfo tx, DateFormat dateFormat) { - final key = tx.additionalInfo['key'] as String?; - final accountIndex = tx.additionalInfo['accountIndex'] as int; - final addressIndex = tx.additionalInfo['addressIndex'] as int; - final feeFormatted = tx.feeFormatted(); - final _items = [ - StandartListItem( - title: S.current.transaction_details_transaction_id, - value: tx.txHash, - key: ValueKey('standard_list_item_transaction_details_id_key'), - ), - StandartListItem( - title: S.current.transaction_details_date, - value: dateFormat.format(tx.date), - key: ValueKey('standard_list_item_transaction_details_date_key'), - ), - StandartListItem( - title: S.current.transaction_details_height, - value: '${tx.height}', - key: ValueKey('standard_list_item_transaction_details_height_key'), - ), - StandartListItem( - title: S.current.transaction_details_amount, - value: tx.amountFormatted(), - key: ValueKey('standard_list_item_transaction_details_amount_key'), - ), - if (feeFormatted != null) - StandartListItem( - title: S.current.transaction_details_fee, - value: feeFormatted, - key: ValueKey('standard_list_item_transaction_details_fee_key'), - ), - if (key?.isNotEmpty ?? false) - StandartListItem( - title: S.current.transaction_key, - value: key!, - key: ValueKey('standard_list_item_transaction_key'), - ), - ]; - if (tx.direction == TransactionDirection.incoming) { - try { - final address = wownero!.getTransactionAddress(wallet, accountIndex, addressIndex); - final label = wownero!.getSubaddressLabel(wallet, accountIndex, addressIndex); - - if (address.isNotEmpty) { - isRecipientAddressShown = true; - _items.add( - StandartListItem( - title: S.current.transaction_details_recipient_address, - value: address, - key: ValueKey('standard_list_item_transaction_details_recipient_address_key'), - ), - ); - } - - if (label.isNotEmpty) { - _items.add( - StandartListItem( - title: S.current.address_label, - value: label, - key: ValueKey('standard_list_item_address_label_key'), - ), - ); - } - } catch (e) { - printV(e.toString()); - } - } - - items.addAll(_items); - } - - void _addZanoListItems(TransactionInfo tx, DateFormat dateFormat) { - final comment = tx.additionalInfo['comment'] as String?; - items.addAll([ - StandartListItem(title: S.current.transaction_details_transaction_id, value: tx.id), - StandartListItem( - title: 'Asset ID', value: tx.additionalInfo['assetId'] as String? ?? "Unknown asset id"), - StandartListItem( - title: S.current.transaction_details_date, value: dateFormat.format(tx.date)), - StandartListItem(title: S.current.transaction_details_height, value: '${tx.height}'), - StandartListItem(title: S.current.transaction_details_amount, value: tx.amountFormatted()), - if (tx.feeFormatted()?.isNotEmpty ?? false) - StandartListItem(title: S.current.transaction_details_fee, value: tx.feeFormatted()!), - if (comment != null && comment.isNotEmpty) - StandartListItem(title: S.current.transaction_details_title, value: comment), - ]); - } } diff --git a/res/pictures/link_arrow.svg b/res/pictures/link_arrow.svg index feb8a6079..3cd0ea17f 100644 --- a/res/pictures/link_arrow.svg +++ b/res/pictures/link_arrow.svg @@ -1,3 +1,3 @@ - + diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb index ab480a489..6c0cb29f7 100644 --- a/res/values/strings_ar.arb +++ b/res/values/strings_ar.arb @@ -13,6 +13,7 @@ "active_cards": "البطاقات النشطة", "activeConnectionsPrompt": "ستظهر الاتصالات النشطة هنا", "add": "إضافة", + "add_a_note": "أضف ملاحظة", "add_account": "إضافة حساب", "add_contact": "إضافة جهة اتصال", "add_contact_to_address_book": "هل ترغب في إضافة جهة الاتصال هذه إلى دفتر العناوين الخاص بك؟", @@ -679,6 +680,7 @@ "none_of_selected_providers_can_exchange": "لا يمكن لأيٍّ من المزوّدين المحدّدين إجراء هذه المبادلة", "noNFTYet": "لا توجد رموز NFT بعد", "normal": "عادي", + "note": "ملحوظة", "note_optional": "ملاحظة (اختيارية)", "note_tap_to_change": "ملاحظة (اضغط للتغيير)", "notification_permission_denied": "تم رفض إذن الإشعارات بشكل دائم. يُرجى تمكينه يدويًا من الإعدادات", @@ -1183,6 +1185,7 @@ "trade_state_underpaid": "غير مدفوع بالكامل", "trade_state_unpaid": "غير مدفوع", "trades": "الصفقات", + "transaction": "عملية", "transaction_commited": "تم تأكيد المعاملة", "transaction_cost": "تكلفة المعاملة", "transaction_details_amount": "الكمية", diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb index d50474f43..0b1103e58 100644 --- a/res/values/strings_bg.arb +++ b/res/values/strings_bg.arb @@ -13,6 +13,7 @@ "active_cards": "Активни карти", "activeConnectionsPrompt": "Тук ще се показват активните връзки", "add": "Добави", + "add_a_note": "Добавете бележка", "add_account": "Добавяне на акаунт", "add_contact": "Добавяне на контакт", "add_contact_to_address_book": "Желаете ли да добавите този контакт към адресната си книга?", @@ -679,6 +680,7 @@ "none_of_selected_providers_can_exchange": "Нито един от избраните доставчици не може да извърши този суап", "noNFTYet": "Все още няма NFT", "normal": "Нормален", + "note": "Забележка", "note_optional": "Бележка (незадължително)", "note_tap_to_change": "Бележка (докоснете, за да промените)", "notification_permission_denied": "Разрешението за известия е окончателно отказано. Моля, включете го ръчно в настройките.", @@ -1183,6 +1185,7 @@ "trade_state_underpaid": "Недоплатено", "trade_state_unpaid": "Неплатено", "trades": "Сделки", + "transaction": "Транзакция", "transaction_commited": "Транзакцията е потвърдена", "transaction_cost": "Разход за транзакция", "transaction_details_amount": "Сума", diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb index aebca6a93..2e93f2d8c 100644 --- a/res/values/strings_cs.arb +++ b/res/values/strings_cs.arb @@ -13,6 +13,7 @@ "active_cards": "Aktivní karty", "activeConnectionsPrompt": "Aktivní připojení se zobrazí zde", "add": "Přidat", + "add_a_note": "Přidejte poznámku", "add_account": "Přidat účet", "add_contact": "Přidat kontakt", "add_contact_to_address_book": "Chcete přidat tento kontakt do svého adresáře?", @@ -679,6 +680,7 @@ "none_of_selected_providers_can_exchange": "Žádný z vybraných poskytovatelů nemůže tento swap provést", "noNFTYet": "Zatím žádné NFT", "normal": "Normální", + "note": "Poznámka", "note_optional": "Poznámka (nepovinné)", "note_tap_to_change": "Poznámka (klepnutím změnit)", "notification_permission_denied": "Oprávnění k oznámením bylo trvale zamítnuto, prosím ručně jej povolte v nastavení", @@ -1183,6 +1185,7 @@ "trade_state_underpaid": "Nedoplaceno", "trade_state_unpaid": "Nezaplaceno", "trades": "Obchody", + "transaction": "Transakce", "transaction_commited": "Transakce potvrzena", "transaction_cost": "Náklady transakce", "transaction_details_amount": "Částka", diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index f3b379170..4737c1d5b 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -13,6 +13,7 @@ "active_cards": "Aktive Karten", "activeConnectionsPrompt": "Aktive Verbindungen werden hier angezeigt", "add": "Hinzufügen", + "add_a_note": "Fügen Sie eine Notiz hinzu", "add_account": "Konto hinzufügen", "add_contact": "Kontakt hinzufügen", "add_contact_to_address_book": "Möchten Sie diesen Kontakt zu Ihrem Adressbuch hinzufügen?", @@ -679,6 +680,7 @@ "none_of_selected_providers_can_exchange": "Keiner der ausgewählten Anbieter kann diesen Swap durchführen", "noNFTYet": "Noch keine NFTs", "normal": "Normal", + "note": "Notiz", "note_optional": "Notiz (optional)", "note_tap_to_change": "Notiz (zum Ändern tippen)", "notification_permission_denied": "Die Benachrichtigungsberechtigung wurde dauerhaft verweigert. Bitte aktivieren Sie sie manuell in den Einstellungen.", @@ -1184,6 +1186,7 @@ "trade_state_underpaid": "Unterbezahlt", "trade_state_unpaid": "Unbezahlt", "trades": "Trades", + "transaction": "Transaktion", "transaction_commited": "Transaktion übermittelt", "transaction_cost": "Transaktionskosten", "transaction_details_amount": "Betrag", diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index f55ddf0fa..f3f732c23 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -13,6 +13,7 @@ "active_cards": "Active cards", "activeConnectionsPrompt": "Active connections will appear here", "add": "Add", + "add_a_note": "Add a note", "add_account": "Add Account", "add_contact": "Add contact", "add_contact_to_address_book": "Would you like to add this contact to your address book?", @@ -679,6 +680,7 @@ "none_of_selected_providers_can_exchange": "None of the selected providers can make this swap", "noNFTYet": "No NFTs yet", "normal": "Normal", + "note": "Note", "note_optional": "Note (optional)", "note_tap_to_change": "Note (tap to change)", "notification_permission_denied": "Notification permission got permamently denied, please manually enable it in settings", @@ -1184,6 +1186,7 @@ "trade_state_underpaid": "Underpaid", "trade_state_unpaid": "Unpaid", "trades": "Trades", + "transaction": "Transaction", "transaction_commited": "Transaction commited", "transaction_cost": "Transaction Cost", "transaction_details_amount": "Amount", diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 49ce3fc0c..474a55b10 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -13,6 +13,7 @@ "active_cards": "Tarjetas activas", "activeConnectionsPrompt": "Las conexiones activas aparecerán aquí", "add": "Añadir", + "add_a_note": "Añadir una nota", "add_account": "Añadir cuenta", "add_contact": "Agregar contacto", "add_contact_to_address_book": "¿Te gustaría añadir este contacto a tu libreta de direcciones?", @@ -679,6 +680,7 @@ "none_of_selected_providers_can_exchange": "Ninguno de los proveedores seleccionados puede realizar este swap", "noNFTYet": "Aún no hay NFT", "normal": "Normal", + "note": "Nota", "note_optional": "Nota (opcional)", "note_tap_to_change": "Nota (toca para cambiar)", "notification_permission_denied": "El permiso de notificaciones se ha denegado permanentemente. Por favor, habilítalo manualmente en la configuración.", @@ -1184,6 +1186,7 @@ "trade_state_underpaid": "Pago insuficiente", "trade_state_unpaid": "No pagado", "trades": "Operaciones", + "transaction": "Transacción", "transaction_commited": "Transacción confirmada", "transaction_cost": "Costo de transacción", "transaction_details_amount": "Cantidad", diff --git a/res/values/strings_fa.arb b/res/values/strings_fa.arb index 5e1edfa7d..0c405d4ac 100644 --- a/res/values/strings_fa.arb +++ b/res/values/strings_fa.arb @@ -13,6 +13,7 @@ "active_cards": "کارت‌های فعال", "activeConnectionsPrompt": "اتصال‌های فعال اینجا نمایش داده می‌شوند", "add": "افزودن", + "add_a_note": "یک یادداشت اضافه کنید", "add_account": "افزودن حساب", "add_contact": "افزودن مخاطب", "add_contact_to_address_book": "آیا می‌خواهید این مخاطب را به دفترچه آدرس خود اضافه کنید؟", @@ -677,6 +678,7 @@ "none_of_selected_providers_can_exchange": "هیچ‌یک از ارائه‌دهندگان انتخاب‌شده نمی‌توانند این سواپ را انجام دهند", "noNFTYet": "هنوز هیچ NFT‌ای وجود ندارد", "normal": "عادی", + "note": "توجه داشته باشید", "note_optional": "یادداشت (اختیاری)", "note_tap_to_change": "یادداشت (برای تغییر ضربه بزنید)", "notification_permission_denied": "مجوز اعلان‌ها به‌طور دائمی رد شده است، لطفاً آن را به‌صورت دستی در تنظیمات فعال کنید", @@ -1182,6 +1184,7 @@ "trade_state_underpaid": "کم‌پرداخت", "trade_state_unpaid": "پرداخت‌نشده", "trades": "معاملات", + "transaction": "معامله", "transaction_commited": "تراکنش ثبت شد", "transaction_cost": "هزینه تراکنش", "transaction_details_amount": "مقدار", diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index 625bbde3e..a97b59b1b 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -13,6 +13,7 @@ "active_cards": "Cartes actives", "activeConnectionsPrompt": "Les connexions actives apparaîtront ici", "add": "Ajouter", + "add_a_note": "Ajouter une note", "add_account": "Ajouter un compte", "add_contact": "Ajouter un contact", "add_contact_to_address_book": "Souhaitez-vous ajouter ce contact à votre carnet d'adresses ?", @@ -679,6 +680,7 @@ "none_of_selected_providers_can_exchange": "Aucun des fournisseurs sélectionnés ne peut effectuer ce swap", "noNFTYet": "Aucun NFT pour le moment", "normal": "Normal", + "note": "Note", "note_optional": "Note (facultative)", "note_tap_to_change": "Note (appuyez pour modifier)", "notification_permission_denied": "L'autorisation des notifications a été refusée de manière permanente. Veuillez l'activer manuellement dans les paramètres.", @@ -1183,6 +1185,7 @@ "trade_state_underpaid": "Sous-payé", "trade_state_unpaid": "Impayé", "trades": "Trades", + "transaction": "Transaction", "transaction_commited": "Transaction validée", "transaction_cost": "Coût de transaction", "transaction_details_amount": "Montant", diff --git a/res/values/strings_gn.arb b/res/values/strings_gn.arb index 7c535a745..c63a8c559 100644 --- a/res/values/strings_gn.arb +++ b/res/values/strings_gn.arb @@ -12,6 +12,7 @@ "active_cards": "Tarjeta oĩva hag̃ua", "activeConnectionsPrompt": "Umi jeikeha oĩva ojehechaukáta ko'ápe", "add": "Emoĩve", + "add_a_note": "Emoĩ peteĩ nóta", "add_account": "Embojoapy cuenta", "add_contact": "Emoĩve contacto", "add_contact_to_address_book": "¿Reipotápa remoĩ ko contacto nde kundaharape?", @@ -531,6 +532,7 @@ "none_of_selected_providers_can_exchange": "Ndaipóri umi proveedor ojeiporavóva apytépe ikatúva ojapo ko swap.", "noNFTYet": "Ndaipóri NFT gueteri", "normal": "Normal", + "note": "Haipy", "note_optional": "Jehaipy (opcional)", "note_tap_to_change": "Jehaipy (eikutu emoambue hag̃ua)", "nullURIError": "URI nulo", @@ -951,6 +953,7 @@ "trade_state_underpaid": "Ojehepyme’ẽ mboyve", "trade_state_unpaid": "Noñeme’ẽi", "trades": "Ñemuha", + "transaction": "Transacción rehegua", "transaction_commited": "Transacción ojejapóma.", "transaction_details_amount": "Hetakue", "transaction_details_copied": "${title} ojekopia portapapélpe", diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb index 4d57e1b17..3253c51d5 100644 --- a/res/values/strings_ha.arb +++ b/res/values/strings_ha.arb @@ -13,6 +13,7 @@ "active_cards": "Katunan da ke aiki", "activeConnectionsPrompt": "Haɗe-haɗe masu aiki za su bayyana a nan", "add": "Ƙara", + "add_a_note": "Ƙara bayanin kula", "add_account": "Ƙara Asusun", "add_contact": "Ƙara tuntuɓa", "add_contact_to_address_book": "Kuna so ku ƙara wannan tuntuɓa zuwa littafin adireshinku?", @@ -679,6 +680,7 @@ "none_of_selected_providers_can_exchange": "Babu ɗaya daga cikin masu ba da sabis da aka zaɓa da zai iya yin wannan musayar", "noNFTYet": "Babu NFT tukuna", "normal": "Na al’ada", + "note": "Lura", "note_optional": "Bayani (na zaɓi)", "note_tap_to_change": "Bayanan kula (taɓa don canjawa)", "notification_permission_denied": "An ƙi ba da izinin sanarwa har abada, don Allah ka kunna shi da hannu a cikin saituna", @@ -1185,6 +1187,7 @@ "trade_state_underpaid": "Ba a biya cikakke ba", "trade_state_unpaid": "Ba a biya ba", "trades": "Kasuwanci", + "transaction": "Ma'amala", "transaction_commited": "An tabbatar da ma'amala", "transaction_cost": "Kudin ma'amala", "transaction_details_amount": "Adadi", diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index dc7790521..105aa6c45 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -13,6 +13,7 @@ "active_cards": "सक्रिय कार्ड", "activeConnectionsPrompt": "सक्रिय कनेक्शन यहां दिखाई देंगे", "add": "जोड़ें", + "add_a_note": "एक नोट जोड़े", "add_account": "अकाउंट जोड़ें", "add_contact": "संपर्क जोड़ें", "add_contact_to_address_book": "क्या आप इस संपर्क को अपनी पता पुस्तिका में जोड़ना चाहेंगे?", @@ -679,6 +680,7 @@ "none_of_selected_providers_can_exchange": "चयनित प्रदाताओं में से कोई भी यह स्वैप नहीं कर सकता", "noNFTYet": "अभी तक कोई NFT नहीं", "normal": "सामान्य", + "note": "टिप्पणी", "note_optional": "नोट (वैकल्पिक)", "note_tap_to_change": "नोट (बदलने के लिए टैप करें)", "notification_permission_denied": "अधिसूचना की अनुमति स्थायी रूप से अस्वीकार कर दी गई है, कृपया इसे सेटिंग्स में जाकर मैन्युअल रूप से सक्षम करें", @@ -1185,6 +1187,7 @@ "trade_state_underpaid": "अपर्याप्त भुगतान", "trade_state_unpaid": "अवैतनिक", "trades": "ट्रेड्स", + "transaction": "लेन-देन", "transaction_commited": "लेन-देन कमिट हो गया", "transaction_cost": "लेनदेन लागत", "transaction_details_amount": "राशि", diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index 4ca1ae54a..d893c6952 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -13,6 +13,7 @@ "active_cards": "Aktivne kartice", "activeConnectionsPrompt": "Ovdje će se prikazati aktivne veze", "add": "Dodaj", + "add_a_note": "Dodajte bilješku", "add_account": "Dodaj račun", "add_contact": "Dodaj kontakt", "add_contact_to_address_book": "Želite li dodati ovaj kontakt u svoj adresar?", @@ -679,6 +680,7 @@ "none_of_selected_providers_can_exchange": "Nijedan od odabranih pružatelja ne može izvršiti ovu zamjenu", "noNFTYet": "Još nema NFT-ova", "normal": "Normalno", + "note": "Bilješka", "note_optional": "Napomena (nije obvezno)", "note_tap_to_change": "Napomena (dodirnite za promjenu)", "notification_permission_denied": "Dozvola za obavijesti trajno je odbijena, molimo ručno je omogućite u postavkama", @@ -1183,6 +1185,7 @@ "trade_state_underpaid": "Nedovoljno plaćeno", "trade_state_unpaid": "Neplaćeno", "trades": "Trgovanja", + "transaction": "Transakcija", "transaction_commited": "Transakcija potvrđena", "transaction_cost": "Trošak transakcije", "transaction_details_amount": "Iznos", diff --git a/res/values/strings_hy.arb b/res/values/strings_hy.arb index f884ebddb..1607a382f 100644 --- a/res/values/strings_hy.arb +++ b/res/values/strings_hy.arb @@ -13,6 +13,7 @@ "active_cards": "Ակտիվ քարտեր", "activeConnectionsPrompt": "Ակտիվ կապերը կհայտնվեն այստեղ", "add": "Ավելացնել", + "add_a_note": "Ավելացնել նշում", "add_account": "Ավելացնել հաշիվ", "add_contact": "Ավելացնել կոնտակտ", "add_contact_to_address_book": "Ցանկանո՞ւմ եք այս կոնտակտը ավելացնել Ձեր հասցեագրքում:", @@ -678,6 +679,7 @@ "none_of_selected_providers_can_exchange": "Ընտրված մատակարարներից ոչ մեկը չի կարող կատարել այս սվոփը", "noNFTYet": "Դեռևս NFT-ներ չկան", "normal": "Նորմալ", + "note": "Նշում", "note_optional": "Նշում (ըստ ցանկության)", "note_tap_to_change": "Նշում (հպեք՝ փոխելու համար)", "notification_permission_denied": "Ծանուցումների թույլտվությունը մշտապես մերժվել է, խնդրում ենք այն ձեռքով միացնել կարգավորումներում", @@ -1181,6 +1183,7 @@ "trade_state_underpaid": "Թերվճարված", "trade_state_unpaid": "Չվճարված", "trades": "Գործարքներ", + "transaction": "Գործարք", "transaction_commited": "Գործարքը հաստատվեց", "transaction_cost": "Գործարքի արժեք", "transaction_details_amount": "Գումար", diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb index 99a587392..4276081d8 100644 --- a/res/values/strings_id.arb +++ b/res/values/strings_id.arb @@ -13,6 +13,7 @@ "active_cards": "Kartu aktif", "activeConnectionsPrompt": "Koneksi aktif akan muncul di sini", "add": "Tambah", + "add_a_note": "Tambahkan catatan", "add_account": "Tambahkan Akun", "add_contact": "Tambah kontak", "add_contact_to_address_book": "Apakah Anda ingin menambahkan kontak ini ke buku alamat Anda?", @@ -679,6 +680,7 @@ "none_of_selected_providers_can_exchange": "Tidak ada penyedia yang dipilih yang dapat melakukan swap ini", "noNFTYet": "Belum ada NFT", "normal": "Normal", + "note": "Catatan", "note_optional": "Catatan (opsional)", "note_tap_to_change": "Catatan (ketuk untuk mengubah)", "notification_permission_denied": "Izin notifikasi ditolak secara permanen, mohon aktifkan secara manual di pengaturan", @@ -1186,6 +1188,7 @@ "trade_state_underpaid": "Kurang dibayar", "trade_state_unpaid": "Belum dibayar", "trades": "Perdagangan", + "transaction": "Transaksi", "transaction_commited": "Transaksi dikomit", "transaction_cost": "Biaya Transaksi", "transaction_details_amount": "Jumlah", diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index 72ed9288e..a0675f7ff 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -13,6 +13,7 @@ "active_cards": "Carte attive", "activeConnectionsPrompt": "Le connessioni attive appariranno qui", "add": "Aggiungi", + "add_a_note": "Aggiungi una nota", "add_account": "Aggiungi account", "add_contact": "Aggiungi contatto", "add_contact_to_address_book": "Vuoi aggiungere questo contatto alla tua rubrica?", @@ -679,6 +680,7 @@ "none_of_selected_providers_can_exchange": "Nessuno dei provider selezionati può effettuare questo swap", "noNFTYet": "Nessun NFT ancora", "normal": "Normale", + "note": "Nota", "note_optional": "Nota (opzionale)", "note_tap_to_change": "Nota (tocca per cambiare)", "notification_permission_denied": "L'autorizzazione alle notifiche è stata negata in modo permanente, abilitala manualmente nelle impostazioni", @@ -1183,6 +1185,7 @@ "trade_state_underpaid": "Pagamento insufficiente", "trade_state_unpaid": "Non pagato", "trades": "Operazioni", + "transaction": "Transazione", "transaction_commited": "Transazione confermata", "transaction_cost": "Costo della transazione", "transaction_details_amount": "Importo", diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index 1597fb304..a6f4fd430 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -13,6 +13,7 @@ "active_cards": "有効なカード", "activeConnectionsPrompt": "アクティブな接続はここに表示されます", "add": "追加", + "add_a_note": "メモを追加する", "add_account": "アカウントを追加", "add_contact": "連絡先を追加", "add_contact_to_address_book": "この連絡先をアドレス帳に追加しますか?", @@ -680,6 +681,7 @@ "none_of_selected_providers_can_exchange": "選択したプロバイダーはいずれもこのスワップを実行できません", "noNFTYet": "NFTはまだありません", "normal": "通常", + "note": "注記", "note_optional": "メモ(任意)", "note_tap_to_change": "メモ(タップして変更)", "notification_permission_denied": "通知の権限が永久に拒否されました。設定で手動で有効にしてください", @@ -1183,6 +1185,7 @@ "trade_state_underpaid": "支払い不足", "trade_state_unpaid": "未払い", "trades": "取引", + "transaction": "取引", "transaction_commited": "トランザクションがコミットされました", "transaction_cost": "取引手数料", "transaction_details_amount": "金額", diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index 6df7fd1ba..e4effa006 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -13,6 +13,7 @@ "active_cards": "활성화된 카드", "activeConnectionsPrompt": "활성 연결이 여기에 표시됩니다", "add": "추가", + "add_a_note": "메모 추가", "add_account": "계정 추가", "add_contact": "연락처 추가", "add_contact_to_address_book": "이 연락처를 주소록에 추가하시겠습니까?", @@ -679,6 +680,7 @@ "none_of_selected_providers_can_exchange": "선택한 제공업체 중 이 스왑을 지원하는 곳이 없습니다", "noNFTYet": "아직 NFT가 없습니다", "normal": "일반", + "note": "메모", "note_optional": "메모(선택 사항)", "note_tap_to_change": "메모 (탭하여 변경)", "notification_permission_denied": "알림 권한이 영구적으로 거부되었습니다. 설정에서 수동으로 활성화해 주세요.", @@ -1183,6 +1185,7 @@ "trade_state_underpaid": "지불 부족", "trade_state_unpaid": "미결제", "trades": "거래", + "transaction": "거래", "transaction_commited": "트랜잭션이 커밋되었습니다", "transaction_cost": "거래 수수료", "transaction_details_amount": "금액", diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb index a9785f5be..2a9bb18d1 100644 --- a/res/values/strings_my.arb +++ b/res/values/strings_my.arb @@ -13,6 +13,7 @@ "active_cards": "အသုံးပြုနေသောကတ်များ", "activeConnectionsPrompt": "လက်ရှိ ချိတ်ဆက်မှုများကို ဤနေရာတွင် ပြသပါမည်", "add": "ထည့်ရန်", + "add_a_note": "မှတ်စုတစ်ခုထည့်ပါ။", "add_account": "အကောင့်ထည့်ရန်", "add_contact": "အဆက်အသွယ် ထည့်ရန်", "add_contact_to_address_book": "ဒီအဆက်အသွယ်ကို သင့်လိပ်စာစာအုပ်ထဲ ထည့်ချင်ပါသလား။", @@ -679,6 +680,7 @@ "none_of_selected_providers_can_exchange": "ရွေးချယ်ထားသော ပံ့ပိုးပေးသူများထဲမှ မည်သူမျှ ဒီ swap ကို မလုပ်နိုင်ပါ", "noNFTYet": "NFT မရှိသေးပါ", "normal": "ပုံမှန်", + "note": "မှတ်ချက်", "note_optional": "မှတ်ချက် (မဖြည့်လည်းရသည်)", "note_tap_to_change": "မှတ်ချက် (ပြောင်းလဲရန် နှိပ်ပါ)", "notification_permission_denied": "အသိပေးချက်ခွင့်ပြုချက်ကို အပြီးတိုင် ငြင်းပယ်ထားပါသည်၊ ကျေးဇူးပြု၍ ချိန်ညှိချက်များတွင် လက်ဖြင့် ဖွင့်ပေးပါ", @@ -1182,6 +1184,7 @@ "trade_state_underpaid": "ပေးချေမှုမလုံလောက်ပါ", "trade_state_unpaid": "မပေးချေရသေး", "trades": "အရောင်းအဝယ်များ", + "transaction": "ငွေလွှဲခြင်း။", "transaction_commited": "ငွေလွှဲမှု အတည်ပြုပြီးပါပြီ", "transaction_cost": "ငွေလွှဲခ ကုန်ကျစရိတ်", "transaction_details_amount": "ပမာဏ", diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index 3d85f18fd..a27007d94 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -13,6 +13,7 @@ "active_cards": "Actieve kaarten", "activeConnectionsPrompt": "Actieve verbindingen worden hier weergegeven", "add": "Toevoegen", + "add_a_note": "Voeg een notitie toe", "add_account": "Account toevoegen", "add_contact": "Contactpersoon toevoegen", "add_contact_to_address_book": "Wil je dit contact toevoegen aan je adresboek?", @@ -676,9 +677,10 @@ "none_of_selected_providers_can_exchange": "Geen van de geselecteerde providers kan deze swap maken", "noNFTYet": "Nog geen NFT's", "normal": "Normaal", - "note_optional": "Opmerking (optioneel)", - "note_tap_to_change": "Opmerking (tik om te wijzigen)", - "notification_permission_denied": "Meldingstoestemming is permanent geweigerd, schakel deze handmatig in via de instellingen", + "note": "Opmerking", + "note_optional": "Notitie (optioneel)", + "note_tap_to_change": "Notitie (tik om te wijzigen)", + "notification_permission_denied": "Meldingstoestemming is permanent geweigerd. Schakel deze handmatig in via de instellingen.", "nullURIError": "URI is null", "offer_expires_in": "Aanbieding verloopt over: ", "offline": "Offline", @@ -1178,6 +1180,7 @@ "trade_state_trading": "Handel", "trade_state_underpaid": "Te weinig betaald", "trade_state_unpaid": "Onbetaald", + "transaction": "Transactie", "trades": "Trades", "transaction_commited": "Transactie vastgelegd", "transaction_cost": "Transactiekosten", diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index e80a7d3b3..ba93ddd30 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -13,6 +13,7 @@ "active_cards": "Aktywne karty", "activeConnectionsPrompt": "Aktywne połączenia pojawią się tutaj", "add": "Dodaj", + "add_a_note": "Dodaj notatkę", "add_account": "Dodaj konto", "add_contact": "Dodaj kontakt", "add_contact_to_address_book": "Czy chcesz dodać ten kontakt do swojej książki adresowej?", @@ -678,6 +679,7 @@ "none_of_selected_providers_can_exchange": "Żaden z wybranych dostawców nie może wykonać tej wymiany", "noNFTYet": "Brak NFT", "normal": "Normalny", + "note": "Notatka", "note_optional": "Notatka (opcjonalnie)", "note_tap_to_change": "Notatka (stuknij, aby zmienić)", "notification_permission_denied": "Uprawnienie do powiadomień zostało trwale odrzucone. Włącz je ręcznie w ustawieniach.", @@ -1181,6 +1183,7 @@ "trade_state_underpaid": "Niedopłacone", "trade_state_unpaid": "Nieopłacone", "trades": "Transakcje", + "transaction": "Transakcja", "transaction_commited": "Transakcja zatwierdzona", "transaction_cost": "Koszt transakcji", "transaction_details_amount": "Kwota", diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index d2823434f..981ab9871 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -13,6 +13,7 @@ "active_cards": "Cartões ativos", "activeConnectionsPrompt": "As conexões ativas aparecerão aqui", "add": "Adicionar", + "add_a_note": "Adicione uma nota", "add_account": "Adicionar conta", "add_contact": "Adicionar contato", "add_contact_to_address_book": "Você gostaria de adicionar este contato ao seu catálogo de endereços?", @@ -680,6 +681,7 @@ "none_of_selected_providers_can_exchange": "Nenhum dos provedores selecionados pode realizar esta troca", "noNFTYet": "Ainda não há NFTs", "normal": "Normal", + "note": "Observação", "note_optional": "Nota (opcional)", "note_tap_to_change": "Nota (toque para mudar)", "notification_permission_denied": "A permissão de notificações foi negada permanentemente. Ative-a manualmente nas configurações.", @@ -1184,6 +1186,7 @@ "trade_state_underpaid": "Pago insuficiente", "trade_state_unpaid": "Não pago", "trades": "Negociações", + "transaction": "Transação", "transaction_commited": "Transação confirmada", "transaction_cost": "Custo da transação", "transaction_details_amount": "Valor", diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index 416377e8f..99496d876 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -13,6 +13,7 @@ "active_cards": "Активные карты", "activeConnectionsPrompt": "Здесь будут отображаться активные подключения", "add": "Добавить", + "add_a_note": "Добавить заметку", "add_account": "Добавить аккаунт", "add_contact": "Добавить контакт", "add_contact_to_address_book": "Хотите добавить этот контакт в адресную книгу?", @@ -679,6 +680,7 @@ "none_of_selected_providers_can_exchange": "Ни один из выбранных провайдеров не может выполнить этот обмен", "noNFTYet": "Пока нет NFT", "normal": "Обычный", + "note": "Примечание", "note_optional": "Примечание (необязательно)", "note_tap_to_change": "Примечание (нажмите, чтобы изменить)", "notification_permission_denied": "Разрешение на уведомления было навсегда отклонено, пожалуйста, включите его вручную в настройках", @@ -1183,6 +1185,7 @@ "trade_state_underpaid": "Недоплачено", "trade_state_unpaid": "Не оплачено", "trades": "Сделки", + "transaction": "Сделка", "transaction_commited": "Транзакция подтверждена", "transaction_cost": "Стоимость транзакции", "transaction_details_amount": "Сумма", diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb index fc986ff8b..3c62489d1 100644 --- a/res/values/strings_th.arb +++ b/res/values/strings_th.arb @@ -13,6 +13,7 @@ "active_cards": "บัตรที่ใช้งานอยู่", "activeConnectionsPrompt": "การเชื่อมต่อที่ใช้งานอยู่จะแสดงที่นี่", "add": "เพิ่ม", + "add_a_note": "เพิ่มบันทึก", "add_account": "เพิ่มบัญชี", "add_contact": "เพิ่มผู้ติดต่อ", "add_contact_to_address_book": "คุณต้องการเพิ่มผู้ติดต่อนี้ลงในสมุดที่อยู่ของคุณหรือไม่?", @@ -679,6 +680,7 @@ "none_of_selected_providers_can_exchange": "ไม่มีผู้ให้บริการที่เลือกไว้รายใดสามารถทำการสวอปนี้ได้", "noNFTYet": "ยังไม่มี NFT", "normal": "ปกติ", + "note": "บันทึก", "note_optional": "หมายเหตุ (ไม่จำเป็น)", "note_tap_to_change": "หมายเหตุ (แตะเพื่อเปลี่ยน)", "notification_permission_denied": "สิทธิ์การแจ้งเตือนถูกปฏิเสธอย่างถาวร โปรดเปิดใช้งานด้วยตนเองในการตั้งค่า", @@ -1182,6 +1184,7 @@ "trade_state_underpaid": "ชำระไม่ครบ", "trade_state_unpaid": "ยังไม่ได้ชำระ", "trades": "การเทรด", + "transaction": "ธุรกรรม", "transaction_commited": "ธุรกรรมถูกบันทึกแล้ว", "transaction_cost": "ค่าธรรมเนียมธุรกรรม", "transaction_details_amount": "จำนวน", diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb index 2893fdc42..4e8e97993 100644 --- a/res/values/strings_tl.arb +++ b/res/values/strings_tl.arb @@ -13,6 +13,7 @@ "active_cards": "Mga aktibong card", "activeConnectionsPrompt": "Lalabas dito ang mga aktibong koneksyon", "add": "Magdagdag", + "add_a_note": "Magdagdag ng tala", "add_account": "Magdagdag ng account", "add_contact": "Magdagdag ng kontak", "add_contact_to_address_book": "Gusto mo bang idagdag ang contact na ito sa iyong address book?", @@ -679,6 +680,7 @@ "none_of_selected_providers_can_exchange": "Wala sa mga napiling provider ang makakagawa ng swap na ito", "noNFTYet": "Wala pang mga NFT", "normal": "Normal", + "note": "Tandaan", "note_optional": "Tala (opsyonal)", "note_tap_to_change": "Tala (i-tap para baguhin)", "notification_permission_denied": "Permanenteng tinanggihan ang pahintulot para sa mga abiso. Pakipaganahin ito nang manu-mano sa mga setting.", @@ -1182,6 +1184,7 @@ "trade_state_underpaid": "Kulang ang bayad", "trade_state_unpaid": "Hindi bayad", "trades": "Mga Trade", + "transaction": "Transaksyon", "transaction_commited": "Nakumpirma ang transaksyon", "transaction_cost": "Gastos sa Transaksyon", "transaction_details_amount": "Halaga", diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb index f2753f940..a0ef9832e 100644 --- a/res/values/strings_tr.arb +++ b/res/values/strings_tr.arb @@ -13,6 +13,7 @@ "active_cards": "Aktif kartlar", "activeConnectionsPrompt": "Etkin bağlantılar burada görünecek", "add": "Ekle", + "add_a_note": "Not ekle", "add_account": "Hesap Ekle", "add_contact": "Kişi ekle", "add_contact_to_address_book": "Bu kişiyi adres defterinize eklemek ister misiniz?", @@ -679,6 +680,7 @@ "none_of_selected_providers_can_exchange": "Seçilen sağlayıcıların hiçbiri bu takası gerçekleştiremez", "noNFTYet": "Henüz NFT yok", "normal": "Normal", + "note": "Not", "note_optional": "Not (isteğe bağlı)", "note_tap_to_change": "Not (değiştirmek için dokunun)", "notification_permission_denied": "Bildirim izni kalıcı olarak reddedildi, lütfen ayarlardan manuel olarak etkinleştirin", @@ -1182,6 +1184,7 @@ "trade_state_underpaid": "Eksik ödendi", "trade_state_unpaid": "Ödenmedi", "trades": "Alım satımlar", + "transaction": "İşlem", "transaction_commited": "İşlem onaylandı", "transaction_cost": "İşlem maliyeti", "transaction_details_amount": "Miktar", diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index fc280695c..7b48fc386 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -13,6 +13,7 @@ "active_cards": "Активні картки", "activeConnectionsPrompt": "Активні підключення з’являться тут", "add": "Додати", + "add_a_note": "Додайте примітку", "add_account": "Додати акаунт", "add_contact": "Додати контакт", "add_contact_to_address_book": "Бажаєте додати цей контакт до своєї адресної книги?", @@ -679,6 +680,7 @@ "none_of_selected_providers_can_exchange": "Жоден із вибраних провайдерів не може виконати цей своп", "noNFTYet": "NFT ще немає", "normal": "Звичайний", + "note": "Примітка", "note_optional": "Примітка (необов’язково)", "note_tap_to_change": "Примітка (натисніть, щоб змінити)", "notification_permission_denied": "Дозвіл на сповіщення було назавжди відхилено, будь ласка, увімкніть його вручну в налаштуваннях", @@ -1183,6 +1185,7 @@ "trade_state_underpaid": "Недоплачено", "trade_state_unpaid": "Не оплачено", "trades": "Угоди", + "transaction": "Транзакція", "transaction_commited": "Транзакцію підтверджено", "transaction_cost": "Вартість транзакції", "transaction_details_amount": "Сума", diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb index e8de667ac..e7dec9234 100644 --- a/res/values/strings_ur.arb +++ b/res/values/strings_ur.arb @@ -13,6 +13,7 @@ "active_cards": "فعال کارڈز", "activeConnectionsPrompt": "فعال کنکشنز یہاں ظاہر ہوں گے", "add": "شامل کریں", + "add_a_note": "ایک نوٹ شامل کریں۔", "add_account": "اکاؤنٹ شامل کریں", "add_contact": "رابطہ شامل کریں", "add_contact_to_address_book": "کیا آپ اس رابطے کو اپنی ایڈریس بک میں شامل کرنا چاہیں گے؟", @@ -679,6 +680,7 @@ "none_of_selected_providers_can_exchange": "منتخب کردہ فراہم کنندگان میں سے کوئی بھی یہ سواپ نہیں کر سکتا", "noNFTYet": "ابھی تک کوئی NFTs نہیں", "normal": "معمول", + "note": "نوٹ", "note_optional": "نوٹ (اختیاری)", "note_tap_to_change": "نوٹ (تبدیل کرنے کے لیے ٹیپ کریں)", "notification_permission_denied": "نوٹیفکیشن کی اجازت مستقل طور پر مسترد کر دی گئی ہے، براہِ کرم اسے سیٹنگز میں دستی طور پر فعال کریں", @@ -1184,6 +1186,7 @@ "trade_state_underpaid": "کم ادائیگی", "trade_state_unpaid": "غیر ادا شدہ", "trades": "تبادلے", + "transaction": "لین دین", "transaction_commited": "ٹرانزیکشن مکمل ہو گئی", "transaction_cost": "لین دین کی لاگت", "transaction_details_amount": "رقم", diff --git a/res/values/strings_vi.arb b/res/values/strings_vi.arb index 63efd82e7..f51cde326 100644 --- a/res/values/strings_vi.arb +++ b/res/values/strings_vi.arb @@ -13,6 +13,7 @@ "active_cards": "Thẻ đang hoạt động", "activeConnectionsPrompt": "Các kết nối đang hoạt động sẽ hiển thị ở đây", "add": "Thêm", + "add_a_note": "Thêm ghi chú", "add_account": "Thêm tài khoản", "add_contact": "Thêm liên hệ", "add_contact_to_address_book": "Bạn có muốn thêm liên hệ này vào sổ địa chỉ không?", @@ -677,6 +678,7 @@ "none_of_selected_providers_can_exchange": "Không có nhà cung cấp nào trong số các nhà cung cấp đã chọn có thể thực hiện hoán đổi này", "noNFTYet": "Chưa có NFT nào", "normal": "Bình thường", + "note": "Ghi chú", "note_optional": "Ghi chú (tùy chọn)", "note_tap_to_change": "Ghi chú (chạm để thay đổi)", "notification_permission_denied": "Quyền thông báo đã bị từ chối vĩnh viễn, vui lòng bật thủ công trong cài đặt", @@ -1179,6 +1181,7 @@ "trade_state_underpaid": "Trả thiếu", "trade_state_unpaid": "Chưa thanh toán", "trades": "Giao dịch", + "transaction": "Giao dịch", "transaction_commited": "Giao dịch đã được xác nhận", "transaction_cost": "Chi phí giao dịch", "transaction_details_amount": "Số lượng", diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb index 177a2422c..a544aa8e9 100644 --- a/res/values/strings_yo.arb +++ b/res/values/strings_yo.arb @@ -13,6 +13,7 @@ "active_cards": "Àwọn káàdì tó ń ṣiṣẹ́", "activeConnectionsPrompt": "Awọn asopọ tó ń ṣiṣẹ yóò hàn níbí", "add": "Fi kún", + "add_a_note": "Fi akọsilẹ kun", "add_account": "Ṣàfikún Àkántì", "add_contact": "Ṣàfikún olubasọrọ", "add_contact_to_address_book": "Ṣe o fẹ́ fi olubasọrọ yìí kún ìwé àdírẹ́sì rẹ?", @@ -680,6 +681,7 @@ "none_of_selected_providers_can_exchange": "Ko si ọkan ninu awọn olupese tí a yàn tó lè ṣe paṣipaarọ yìí", "noNFTYet": "Ko si NFT sibẹsibẹ", "normal": "Deede", + "note": "Akiyesi", "note_optional": "Àkọsílẹ̀ (àṣàyàn)", "note_tap_to_change": "Akọsilẹ (tẹ lati yí padà)", "notification_permission_denied": "A ti kọ igbanilaaye iwifunni patapata, jọwọ mu un ṣiṣẹ lọ́wọ́ rẹ nínú àwọn eto", @@ -1183,6 +1185,7 @@ "trade_state_underpaid": "A san iye tó kéré ju", "trade_state_unpaid": "A kò tíì san", "trades": "Àwọn ìṣòwò", + "transaction": "Idunadura", "transaction_commited": "Idunadura ti fọwọsi", "transaction_cost": "Iye Iṣowo", "transaction_details_amount": "Iye", diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index e8fc8f72e..6a3a19fdb 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -13,6 +13,7 @@ "active_cards": "已激活的卡", "activeConnectionsPrompt": "活跃连接将显示在此处", "add": "添加", + "add_a_note": "添加注释", "add_account": "添加账户", "add_contact": "添加联系人", "add_contact_to_address_book": "您想将此联系人添加到地址簿吗?", @@ -679,6 +680,7 @@ "none_of_selected_providers_can_exchange": "所选的提供商均无法完成此兑换", "noNFTYet": "暂无 NFT", "normal": "普通", + "note": "笔记", "note_optional": "备注(可选)", "note_tap_to_change": "备注(轻触以更改)", "notification_permission_denied": "通知权限已被永久拒绝,请在设置中手动启用", @@ -1182,6 +1184,7 @@ "trade_state_underpaid": "支付不足", "trade_state_unpaid": "未付款", "trades": "交易", + "transaction": "交易", "transaction_commited": "交易已提交", "transaction_cost": "交易费用", "transaction_details_amount": "金额",