From c8a9bcba39f50f4557d3a1aa50e6d3cebedbfb5c Mon Sep 17 00:00:00 2001 From: knightforce Date: Wed, 5 Feb 2025 03:02:29 +0500 Subject: [PATCH 1/2] TonConfirmTransaction Elementary --- lib/app/router/routs/wallet/wallet.dart | 3 +- lib/data/models/approval_request.freezed.dart | 31 +- .../ton_confirm_transaction/bloc/bloc.dart | 1 - .../bloc/ton_confirm_transaction_bloc.dart | 235 ------ .../bloc/ton_confirm_transaction_event.dart | 18 - .../ton_confirm_transaction_state.dart | 5 +- ...on_confirm_transaction_state.freezed.dart} | 679 +----------------- .../ton_confirm_transaction.dart | 2 - .../ton_confirm_transaction_screen.dart | 116 +++ .../ton_confirm_transaction_screen_model.dart | 107 +++ .../ton_confirm_transaction_screen_wm.dart | 191 +++++ .../view/ton_confirm_transaction_page.dart | 139 ---- .../ton_confirm_transaction/view/view.dart | 1 - .../confirm_view.dart} | 12 +- .../transaction_prepare.dart} | 12 +- lib/feature/wallet/wallet.dart | 1 - 16 files changed, 444 insertions(+), 1109 deletions(-) delete mode 100644 lib/feature/wallet/ton_confirm_transaction/bloc/bloc.dart delete mode 100644 lib/feature/wallet/ton_confirm_transaction/bloc/ton_confirm_transaction_bloc.dart delete mode 100644 lib/feature/wallet/ton_confirm_transaction/bloc/ton_confirm_transaction_event.dart rename lib/feature/wallet/ton_confirm_transaction/{bloc => data}/ton_confirm_transaction_state.dart (86%) rename lib/feature/wallet/ton_confirm_transaction/{bloc/ton_confirm_transaction_bloc.freezed.dart => data/ton_confirm_transaction_state.freezed.dart} (70%) delete mode 100644 lib/feature/wallet/ton_confirm_transaction/ton_confirm_transaction.dart create mode 100644 lib/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen.dart create mode 100644 lib/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen_model.dart create mode 100644 lib/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen_wm.dart delete mode 100644 lib/feature/wallet/ton_confirm_transaction/view/ton_confirm_transaction_page.dart delete mode 100644 lib/feature/wallet/ton_confirm_transaction/view/view.dart rename lib/feature/wallet/ton_confirm_transaction/{view/ton_confirm_transaction_confirm_view.dart => widgets/confirm_view.dart} (88%) rename lib/feature/wallet/ton_confirm_transaction/{view/ton_confirm_transaction_prepare.dart => widgets/transaction_prepare.dart} (88%) diff --git a/lib/app/router/routs/wallet/wallet.dart b/lib/app/router/routs/wallet/wallet.dart index f03c7282c..e13e6ee67 100644 --- a/lib/app/router/routs/wallet/wallet.dart +++ b/lib/app/router/routs/wallet/wallet.dart @@ -13,6 +13,7 @@ import 'package:app/feature/wallet/new_account/add_account.dart'; import 'package:app/feature/wallet/new_account/add_account_page.dart'; import 'package:app/feature/wallet/new_account/add_external_account/add_external_account_page.dart'; import 'package:app/feature/wallet/new_account/select_seed/select_seed_page.dart'; +import 'package:app/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen.dart'; import 'package:app/feature/wallet/wallet.dart'; import 'package:app/feature/wallet/widgets/account_asset_tab/select_new_asset/select_new_asset.dart'; import 'package:app/utils/url_utils.dart'; @@ -348,7 +349,7 @@ GoRoute get tonConfirmTranscationRoute { ) as List) .cast(); - return TonConfirmTransactionPage( + return TonConfirmTransactionScreen( walletAddress: Address( address: state.uri.queryParameters[ tonWalletConfirmTransactionWalletAddressQueryParam]!, diff --git a/lib/data/models/approval_request.freezed.dart b/lib/data/models/approval_request.freezed.dart index d624b2c7e..c7be2cc2a 100644 --- a/lib/data/models/approval_request.freezed.dart +++ b/lib/data/models/approval_request.freezed.dart @@ -2930,7 +2930,6 @@ abstract class _$$SendMessageImplCopyWith<$Res> $AddressCopyWith<$Res> get sender; $AddressCopyWith<$Res> get recipient; $FunctionCallCopyWith<$Res>? get payload; - $KnownPayloadCopyWith<$Res>? get knownPayload; } /// @nodoc @@ -3024,20 +3023,6 @@ class __$$SendMessageImplCopyWithImpl<$Res> return _then(_value.copyWith(payload: value)); }); } - - /// Create a copy of ApprovalRequest - /// with the given fields replaced by the non-null parameter values. - @override - @pragma('vm:prefer-inline') - $KnownPayloadCopyWith<$Res>? get knownPayload { - if (_value.knownPayload == null) { - return null; - } - - return $KnownPayloadCopyWith<$Res>(_value.knownPayload!, (value) { - return _then(_value.copyWith(knownPayload: value)); - }); - } } /// @nodoc @@ -3088,15 +3073,23 @@ class _$SendMessageImpl implements _SendMessage { (identical(other.amount, amount) || other.amount == amount) && (identical(other.bounce, bounce) || other.bounce == bounce) && (identical(other.payload, payload) || other.payload == payload) && - (identical(other.knownPayload, knownPayload) || - other.knownPayload == knownPayload) && + const DeepCollectionEquality() + .equals(other.knownPayload, knownPayload) && (identical(other.completer, completer) || other.completer == completer)); } @override - int get hashCode => Object.hash(runtimeType, origin, sender, recipient, - amount, bounce, payload, knownPayload, completer); + int get hashCode => Object.hash( + runtimeType, + origin, + sender, + recipient, + amount, + bounce, + payload, + const DeepCollectionEquality().hash(knownPayload), + completer); /// Create a copy of ApprovalRequest /// with the given fields replaced by the non-null parameter values. diff --git a/lib/feature/wallet/ton_confirm_transaction/bloc/bloc.dart b/lib/feature/wallet/ton_confirm_transaction/bloc/bloc.dart deleted file mode 100644 index 102de224d..000000000 --- a/lib/feature/wallet/ton_confirm_transaction/bloc/bloc.dart +++ /dev/null @@ -1 +0,0 @@ -export 'ton_confirm_transaction_bloc.dart'; diff --git a/lib/feature/wallet/ton_confirm_transaction/bloc/ton_confirm_transaction_bloc.dart b/lib/feature/wallet/ton_confirm_transaction/bloc/ton_confirm_transaction_bloc.dart deleted file mode 100644 index 8ad94fb1f..000000000 --- a/lib/feature/wallet/ton_confirm_transaction/bloc/ton_confirm_transaction_bloc.dart +++ /dev/null @@ -1,235 +0,0 @@ -// ignore_for_file: use_build_context_synchronously - -import 'package:app/app/service/service.dart'; -import 'package:app/core/bloc/bloc_mixin.dart'; -import 'package:app/di/di.dart'; -import 'package:app/generated/generated.dart'; -import 'package:app/utils/constants.dart'; -import 'package:bloc/bloc.dart'; -import 'package:flutter/material.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:logging/logging.dart'; -import 'package:nekoton_repository/nekoton_repository.dart' hide Message; - -part 'ton_confirm_transaction_bloc.freezed.dart'; - -part 'ton_confirm_transaction_event.dart'; - -part 'ton_confirm_transaction_state.dart'; - -/// Bloc that allows prepare transaction confirmation for multisig wallet. -/// If [localCustodians] more than 1, then user will prepare transaction by -/// selecting custodian for confirmation, else it will calculate transaction. -// TODO(knightforce): use Elementary instead Bloc -class TonConfirmTransactionBloc - extends Bloc - with BlocBaseMixin { - TonConfirmTransactionBloc({ - required this.context, - required this.nekotonRepository, - required this.walletAddress, - required this.localCustodians, - required this.transactionId, - required this.amount, - required this.destination, - required this.comment, - }) : super( - localCustodians.length > 1 - ? const TonConfirmTransactionState.prepare() - : TonConfirmTransactionState.loading(localCustodians.first), - ) { - account ??= nekotonRepository.seedList.findAccountByAddress(walletAddress); - - final currentTransport = nekotonRepository.currentTransport; - - final currency = Currencies()[currentTransport.nativeTokenTicker]; - - if (currency != null) { - money = Money.fromBigIntWithCurrency( - amount, - currency, - ); - } - - _registerHandlers(); - if (localCustodians.length == 1) { - add(TonConfirmTransactionEvent.prepare(localCustodians.first)); - } - } - - final _logger = Logger('TonConfirmTransactionBloc'); - final BuildContext context; - final NekotonRepository nekotonRepository; - - /// Address of wallet which will be used to confirm transaction - final Address walletAddress; - - /// Local custodians that CAN CONFIRM transaction (not all) - final List localCustodians; - - /// Transaction that should be confirmed - final String transactionId; - - /// Amount of transaction - final BigInt amount; - - /// Destination where funds should be sent (this page won't displayed for - /// incoming transaction) - final Address destination; - - /// Comment of transaction - final String? comment; - - KeyAccount? account; - - Money? money; - - /// Fee for transaction after calculating it in [_handlePrepare] - BigInt? fees; - - late PublicKey selectedCustodian; - - void _registerHandlers() { - on<_Prepare>((event, emit) => _handlePrepare(emit, event.custodian)); - on<_Send>((event, emit) => _handleSend(emit, event.password)); - on<_CompleteSend>( - (event, emit) => emitSafe( - TonConfirmTransactionState.sent( - fees!, - event.transaction, - selectedCustodian, - ), - ), - ); - on<_AllowCloseSend>( - (event, emit) => - emitSafe(const TonConfirmTransactionState.sending(canClose: true)), - ); - } - - // ignore: long-method - Future _handlePrepare( - Emitter emit, - PublicKey custodian, - ) async { - UnsignedMessage? unsignedMessage; - try { - selectedCustodian = custodian; - unsignedMessage = await _prepareConfirmTransaction(); - fees = await nekotonRepository.estimateFees( - address: walletAddress, - message: unsignedMessage, - ); - - final walletState = await nekotonRepository.walletsStream - .expand((e) => e) - .firstWhere((wallets) => wallets.address == walletAddress); - - if (walletState.hasError) { - emitSafe(TonConfirmTransactionState.subscribeError(walletState.error!)); - - return; - } - - final wallet = walletState.wallet!; - - final balance = wallet.contractState.balance; - - final isPossibleToSendMessage = balance > (fees! + amount); - - if (!isPossibleToSendMessage) { - emitSafe( - TonConfirmTransactionState.calculatingError( - LocaleKeys.insufficientFunds.tr(), - selectedCustodian, - fees, - ), - ); - - return; - } - - emitSafe( - TonConfirmTransactionState.readyToSend( - fees!, - selectedCustodian, - ), - ); - } on Exception catch (e, t) { - _logger.severe('_handlePrepare', e, t); - emitSafe( - TonConfirmTransactionState.calculatingError( - e.toString(), - selectedCustodian, - ), - ); - } finally { - unsignedMessage?.dispose(); - } - } - - Future _handleSend( - Emitter emit, - String password, - ) async { - UnsignedMessage? unsignedMessage; - try { - emitSafe(const TonConfirmTransactionState.sending(canClose: false)); - // await unsignedMessage.refreshTimeout(); - // TODO(komarov): fix refresh_timeout in nekoton - unsignedMessage = await _prepareConfirmTransaction(); - - final hash = unsignedMessage.hash; - final transport = nekotonRepository.currentTransport.transport; - - final signature = await nekotonRepository.seedList.sign( - data: hash, - publicKey: selectedCustodian, - password: password, - signatureId: await transport.getSignatureId(), - ); - - final signedMessage = await unsignedMessage.sign(signature: signature); - - emitSafe(const TonConfirmTransactionState.sending(canClose: true)); - - final transaction = await nekotonRepository.send( - address: walletAddress, - signedMessage: signedMessage, - amount: amount, - destination: destination, - ); - - inject().show( - Message.successful( - context: context, - message: LocaleKeys.transactionSentSuccessfully.tr(), - ), - ); - if (!isClosed) { - add(TonConfirmTransactionEvent.completeSend(transaction)); - } - } on OperationCanceledException catch (_) { - } on Exception catch (e, t) { - _logger.severe('_handleSend', e, t); - inject() - .show(Message.error(context: context, message: e.toString())); - emitSafe( - TonConfirmTransactionState.readyToSend( - fees!, - selectedCustodian, - ), - ); - } finally { - unsignedMessage?.dispose(); - } - } - - Future _prepareConfirmTransaction() => - nekotonRepository.prepareConfirmTransaction( - address: walletAddress, - publicKey: selectedCustodian, - transactionId: transactionId, - expiration: defaultSendTimeout, - ); -} diff --git a/lib/feature/wallet/ton_confirm_transaction/bloc/ton_confirm_transaction_event.dart b/lib/feature/wallet/ton_confirm_transaction/bloc/ton_confirm_transaction_event.dart deleted file mode 100644 index 1a00445dd..000000000 --- a/lib/feature/wallet/ton_confirm_transaction/bloc/ton_confirm_transaction_event.dart +++ /dev/null @@ -1,18 +0,0 @@ -part of 'ton_confirm_transaction_bloc.dart'; - -@freezed -class TonConfirmTransactionEvent with _$TonConfirmTransactionEvent { - const factory TonConfirmTransactionEvent.prepare(PublicKey custodian) = - _Prepare; - - /// Password entered, when ready to send - const factory TonConfirmTransactionEvent.send(String password) = _Send; - - /// Allow user to close send page - const factory TonConfirmTransactionEvent.allowCloseSend() = _AllowCloseSend; - - /// Complete sending transaction with result. - const factory TonConfirmTransactionEvent.completeSend( - Transaction transaction, - ) = _CompleteSend; -} diff --git a/lib/feature/wallet/ton_confirm_transaction/bloc/ton_confirm_transaction_state.dart b/lib/feature/wallet/ton_confirm_transaction/data/ton_confirm_transaction_state.dart similarity index 86% rename from lib/feature/wallet/ton_confirm_transaction/bloc/ton_confirm_transaction_state.dart rename to lib/feature/wallet/ton_confirm_transaction/data/ton_confirm_transaction_state.dart index 21fe6dc27..16ff67000 100644 --- a/lib/feature/wallet/ton_confirm_transaction/bloc/ton_confirm_transaction_state.dart +++ b/lib/feature/wallet/ton_confirm_transaction/data/ton_confirm_transaction_state.dart @@ -1,4 +1,7 @@ -part of 'ton_confirm_transaction_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:nekoton_repository/nekoton_repository.dart'; + +part 'ton_confirm_transaction_state.freezed.dart'; @freezed class TonConfirmTransactionState with _$TonConfirmTransactionState { diff --git a/lib/feature/wallet/ton_confirm_transaction/bloc/ton_confirm_transaction_bloc.freezed.dart b/lib/feature/wallet/ton_confirm_transaction/data/ton_confirm_transaction_state.freezed.dart similarity index 70% rename from lib/feature/wallet/ton_confirm_transaction/bloc/ton_confirm_transaction_bloc.freezed.dart rename to lib/feature/wallet/ton_confirm_transaction/data/ton_confirm_transaction_state.freezed.dart index 3bc21da3c..18d1b0dbe 100644 --- a/lib/feature/wallet/ton_confirm_transaction/bloc/ton_confirm_transaction_bloc.freezed.dart +++ b/lib/feature/wallet/ton_confirm_transaction/data/ton_confirm_transaction_state.freezed.dart @@ -3,7 +3,7 @@ // ignore_for_file: type=lint // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark -part of 'ton_confirm_transaction_bloc.dart'; +part of 'ton_confirm_transaction_state.dart'; // ************************************************************************** // FreezedGenerator @@ -14,683 +14,6 @@ T _$identity(T value) => value; final _privateConstructorUsedError = UnsupportedError( 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); -/// @nodoc -mixin _$TonConfirmTransactionEvent { - @optionalTypeArgs - TResult when({ - required TResult Function(PublicKey custodian) prepare, - required TResult Function(String password) send, - required TResult Function() allowCloseSend, - required TResult Function(Transaction transaction) completeSend, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function(PublicKey custodian)? prepare, - TResult? Function(String password)? send, - TResult? Function()? allowCloseSend, - TResult? Function(Transaction transaction)? completeSend, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeWhen({ - TResult Function(PublicKey custodian)? prepare, - TResult Function(String password)? send, - TResult Function()? allowCloseSend, - TResult Function(Transaction transaction)? completeSend, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult map({ - required TResult Function(_Prepare value) prepare, - required TResult Function(_Send value) send, - required TResult Function(_AllowCloseSend value) allowCloseSend, - required TResult Function(_CompleteSend value) completeSend, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(_Prepare value)? prepare, - TResult? Function(_Send value)? send, - TResult? Function(_AllowCloseSend value)? allowCloseSend, - TResult? Function(_CompleteSend value)? completeSend, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeMap({ - TResult Function(_Prepare value)? prepare, - TResult Function(_Send value)? send, - TResult Function(_AllowCloseSend value)? allowCloseSend, - TResult Function(_CompleteSend value)? completeSend, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $TonConfirmTransactionEventCopyWith<$Res> { - factory $TonConfirmTransactionEventCopyWith(TonConfirmTransactionEvent value, - $Res Function(TonConfirmTransactionEvent) then) = - _$TonConfirmTransactionEventCopyWithImpl<$Res, - TonConfirmTransactionEvent>; -} - -/// @nodoc -class _$TonConfirmTransactionEventCopyWithImpl<$Res, - $Val extends TonConfirmTransactionEvent> - implements $TonConfirmTransactionEventCopyWith<$Res> { - _$TonConfirmTransactionEventCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - /// Create a copy of TonConfirmTransactionEvent - /// with the given fields replaced by the non-null parameter values. -} - -/// @nodoc -abstract class _$$PrepareImplCopyWith<$Res> { - factory _$$PrepareImplCopyWith( - _$PrepareImpl value, $Res Function(_$PrepareImpl) then) = - __$$PrepareImplCopyWithImpl<$Res>; - @useResult - $Res call({PublicKey custodian}); - - $PublicKeyCopyWith<$Res> get custodian; -} - -/// @nodoc -class __$$PrepareImplCopyWithImpl<$Res> - extends _$TonConfirmTransactionEventCopyWithImpl<$Res, _$PrepareImpl> - implements _$$PrepareImplCopyWith<$Res> { - __$$PrepareImplCopyWithImpl( - _$PrepareImpl _value, $Res Function(_$PrepareImpl) _then) - : super(_value, _then); - - /// Create a copy of TonConfirmTransactionEvent - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? custodian = null, - }) { - return _then(_$PrepareImpl( - null == custodian - ? _value.custodian - : custodian // ignore: cast_nullable_to_non_nullable - as PublicKey, - )); - } - - /// Create a copy of TonConfirmTransactionEvent - /// with the given fields replaced by the non-null parameter values. - @override - @pragma('vm:prefer-inline') - $PublicKeyCopyWith<$Res> get custodian { - return $PublicKeyCopyWith<$Res>(_value.custodian, (value) { - return _then(_value.copyWith(custodian: value)); - }); - } -} - -/// @nodoc - -class _$PrepareImpl implements _Prepare { - const _$PrepareImpl(this.custodian); - - @override - final PublicKey custodian; - - @override - String toString() { - return 'TonConfirmTransactionEvent.prepare(custodian: $custodian)'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$PrepareImpl && - (identical(other.custodian, custodian) || - other.custodian == custodian)); - } - - @override - int get hashCode => Object.hash(runtimeType, custodian); - - /// Create a copy of TonConfirmTransactionEvent - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - @override - @pragma('vm:prefer-inline') - _$$PrepareImplCopyWith<_$PrepareImpl> get copyWith => - __$$PrepareImplCopyWithImpl<_$PrepareImpl>(this, _$identity); - - @override - @optionalTypeArgs - TResult when({ - required TResult Function(PublicKey custodian) prepare, - required TResult Function(String password) send, - required TResult Function() allowCloseSend, - required TResult Function(Transaction transaction) completeSend, - }) { - return prepare(custodian); - } - - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function(PublicKey custodian)? prepare, - TResult? Function(String password)? send, - TResult? Function()? allowCloseSend, - TResult? Function(Transaction transaction)? completeSend, - }) { - return prepare?.call(custodian); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function(PublicKey custodian)? prepare, - TResult Function(String password)? send, - TResult Function()? allowCloseSend, - TResult Function(Transaction transaction)? completeSend, - required TResult orElse(), - }) { - if (prepare != null) { - return prepare(custodian); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(_Prepare value) prepare, - required TResult Function(_Send value) send, - required TResult Function(_AllowCloseSend value) allowCloseSend, - required TResult Function(_CompleteSend value) completeSend, - }) { - return prepare(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(_Prepare value)? prepare, - TResult? Function(_Send value)? send, - TResult? Function(_AllowCloseSend value)? allowCloseSend, - TResult? Function(_CompleteSend value)? completeSend, - }) { - return prepare?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(_Prepare value)? prepare, - TResult Function(_Send value)? send, - TResult Function(_AllowCloseSend value)? allowCloseSend, - TResult Function(_CompleteSend value)? completeSend, - required TResult orElse(), - }) { - if (prepare != null) { - return prepare(this); - } - return orElse(); - } -} - -abstract class _Prepare implements TonConfirmTransactionEvent { - const factory _Prepare(final PublicKey custodian) = _$PrepareImpl; - - PublicKey get custodian; - - /// Create a copy of TonConfirmTransactionEvent - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - _$$PrepareImplCopyWith<_$PrepareImpl> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class _$$SendImplCopyWith<$Res> { - factory _$$SendImplCopyWith( - _$SendImpl value, $Res Function(_$SendImpl) then) = - __$$SendImplCopyWithImpl<$Res>; - @useResult - $Res call({String password}); -} - -/// @nodoc -class __$$SendImplCopyWithImpl<$Res> - extends _$TonConfirmTransactionEventCopyWithImpl<$Res, _$SendImpl> - implements _$$SendImplCopyWith<$Res> { - __$$SendImplCopyWithImpl(_$SendImpl _value, $Res Function(_$SendImpl) _then) - : super(_value, _then); - - /// Create a copy of TonConfirmTransactionEvent - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? password = null, - }) { - return _then(_$SendImpl( - null == password - ? _value.password - : password // ignore: cast_nullable_to_non_nullable - as String, - )); - } -} - -/// @nodoc - -class _$SendImpl implements _Send { - const _$SendImpl(this.password); - - @override - final String password; - - @override - String toString() { - return 'TonConfirmTransactionEvent.send(password: $password)'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$SendImpl && - (identical(other.password, password) || - other.password == password)); - } - - @override - int get hashCode => Object.hash(runtimeType, password); - - /// Create a copy of TonConfirmTransactionEvent - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - @override - @pragma('vm:prefer-inline') - _$$SendImplCopyWith<_$SendImpl> get copyWith => - __$$SendImplCopyWithImpl<_$SendImpl>(this, _$identity); - - @override - @optionalTypeArgs - TResult when({ - required TResult Function(PublicKey custodian) prepare, - required TResult Function(String password) send, - required TResult Function() allowCloseSend, - required TResult Function(Transaction transaction) completeSend, - }) { - return send(password); - } - - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function(PublicKey custodian)? prepare, - TResult? Function(String password)? send, - TResult? Function()? allowCloseSend, - TResult? Function(Transaction transaction)? completeSend, - }) { - return send?.call(password); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function(PublicKey custodian)? prepare, - TResult Function(String password)? send, - TResult Function()? allowCloseSend, - TResult Function(Transaction transaction)? completeSend, - required TResult orElse(), - }) { - if (send != null) { - return send(password); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(_Prepare value) prepare, - required TResult Function(_Send value) send, - required TResult Function(_AllowCloseSend value) allowCloseSend, - required TResult Function(_CompleteSend value) completeSend, - }) { - return send(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(_Prepare value)? prepare, - TResult? Function(_Send value)? send, - TResult? Function(_AllowCloseSend value)? allowCloseSend, - TResult? Function(_CompleteSend value)? completeSend, - }) { - return send?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(_Prepare value)? prepare, - TResult Function(_Send value)? send, - TResult Function(_AllowCloseSend value)? allowCloseSend, - TResult Function(_CompleteSend value)? completeSend, - required TResult orElse(), - }) { - if (send != null) { - return send(this); - } - return orElse(); - } -} - -abstract class _Send implements TonConfirmTransactionEvent { - const factory _Send(final String password) = _$SendImpl; - - String get password; - - /// Create a copy of TonConfirmTransactionEvent - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - _$$SendImplCopyWith<_$SendImpl> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class _$$AllowCloseSendImplCopyWith<$Res> { - factory _$$AllowCloseSendImplCopyWith(_$AllowCloseSendImpl value, - $Res Function(_$AllowCloseSendImpl) then) = - __$$AllowCloseSendImplCopyWithImpl<$Res>; -} - -/// @nodoc -class __$$AllowCloseSendImplCopyWithImpl<$Res> - extends _$TonConfirmTransactionEventCopyWithImpl<$Res, _$AllowCloseSendImpl> - implements _$$AllowCloseSendImplCopyWith<$Res> { - __$$AllowCloseSendImplCopyWithImpl( - _$AllowCloseSendImpl _value, $Res Function(_$AllowCloseSendImpl) _then) - : super(_value, _then); - - /// Create a copy of TonConfirmTransactionEvent - /// with the given fields replaced by the non-null parameter values. -} - -/// @nodoc - -class _$AllowCloseSendImpl implements _AllowCloseSend { - const _$AllowCloseSendImpl(); - - @override - String toString() { - return 'TonConfirmTransactionEvent.allowCloseSend()'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && other is _$AllowCloseSendImpl); - } - - @override - int get hashCode => runtimeType.hashCode; - - @override - @optionalTypeArgs - TResult when({ - required TResult Function(PublicKey custodian) prepare, - required TResult Function(String password) send, - required TResult Function() allowCloseSend, - required TResult Function(Transaction transaction) completeSend, - }) { - return allowCloseSend(); - } - - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function(PublicKey custodian)? prepare, - TResult? Function(String password)? send, - TResult? Function()? allowCloseSend, - TResult? Function(Transaction transaction)? completeSend, - }) { - return allowCloseSend?.call(); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function(PublicKey custodian)? prepare, - TResult Function(String password)? send, - TResult Function()? allowCloseSend, - TResult Function(Transaction transaction)? completeSend, - required TResult orElse(), - }) { - if (allowCloseSend != null) { - return allowCloseSend(); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(_Prepare value) prepare, - required TResult Function(_Send value) send, - required TResult Function(_AllowCloseSend value) allowCloseSend, - required TResult Function(_CompleteSend value) completeSend, - }) { - return allowCloseSend(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(_Prepare value)? prepare, - TResult? Function(_Send value)? send, - TResult? Function(_AllowCloseSend value)? allowCloseSend, - TResult? Function(_CompleteSend value)? completeSend, - }) { - return allowCloseSend?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(_Prepare value)? prepare, - TResult Function(_Send value)? send, - TResult Function(_AllowCloseSend value)? allowCloseSend, - TResult Function(_CompleteSend value)? completeSend, - required TResult orElse(), - }) { - if (allowCloseSend != null) { - return allowCloseSend(this); - } - return orElse(); - } -} - -abstract class _AllowCloseSend implements TonConfirmTransactionEvent { - const factory _AllowCloseSend() = _$AllowCloseSendImpl; -} - -/// @nodoc -abstract class _$$CompleteSendImplCopyWith<$Res> { - factory _$$CompleteSendImplCopyWith( - _$CompleteSendImpl value, $Res Function(_$CompleteSendImpl) then) = - __$$CompleteSendImplCopyWithImpl<$Res>; - @useResult - $Res call({Transaction transaction}); - - $TransactionCopyWith<$Res> get transaction; -} - -/// @nodoc -class __$$CompleteSendImplCopyWithImpl<$Res> - extends _$TonConfirmTransactionEventCopyWithImpl<$Res, _$CompleteSendImpl> - implements _$$CompleteSendImplCopyWith<$Res> { - __$$CompleteSendImplCopyWithImpl( - _$CompleteSendImpl _value, $Res Function(_$CompleteSendImpl) _then) - : super(_value, _then); - - /// Create a copy of TonConfirmTransactionEvent - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? transaction = null, - }) { - return _then(_$CompleteSendImpl( - null == transaction - ? _value.transaction - : transaction // ignore: cast_nullable_to_non_nullable - as Transaction, - )); - } - - /// Create a copy of TonConfirmTransactionEvent - /// with the given fields replaced by the non-null parameter values. - @override - @pragma('vm:prefer-inline') - $TransactionCopyWith<$Res> get transaction { - return $TransactionCopyWith<$Res>(_value.transaction, (value) { - return _then(_value.copyWith(transaction: value)); - }); - } -} - -/// @nodoc - -class _$CompleteSendImpl implements _CompleteSend { - const _$CompleteSendImpl(this.transaction); - - @override - final Transaction transaction; - - @override - String toString() { - return 'TonConfirmTransactionEvent.completeSend(transaction: $transaction)'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$CompleteSendImpl && - (identical(other.transaction, transaction) || - other.transaction == transaction)); - } - - @override - int get hashCode => Object.hash(runtimeType, transaction); - - /// Create a copy of TonConfirmTransactionEvent - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - @override - @pragma('vm:prefer-inline') - _$$CompleteSendImplCopyWith<_$CompleteSendImpl> get copyWith => - __$$CompleteSendImplCopyWithImpl<_$CompleteSendImpl>(this, _$identity); - - @override - @optionalTypeArgs - TResult when({ - required TResult Function(PublicKey custodian) prepare, - required TResult Function(String password) send, - required TResult Function() allowCloseSend, - required TResult Function(Transaction transaction) completeSend, - }) { - return completeSend(transaction); - } - - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function(PublicKey custodian)? prepare, - TResult? Function(String password)? send, - TResult? Function()? allowCloseSend, - TResult? Function(Transaction transaction)? completeSend, - }) { - return completeSend?.call(transaction); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function(PublicKey custodian)? prepare, - TResult Function(String password)? send, - TResult Function()? allowCloseSend, - TResult Function(Transaction transaction)? completeSend, - required TResult orElse(), - }) { - if (completeSend != null) { - return completeSend(transaction); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(_Prepare value) prepare, - required TResult Function(_Send value) send, - required TResult Function(_AllowCloseSend value) allowCloseSend, - required TResult Function(_CompleteSend value) completeSend, - }) { - return completeSend(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(_Prepare value)? prepare, - TResult? Function(_Send value)? send, - TResult? Function(_AllowCloseSend value)? allowCloseSend, - TResult? Function(_CompleteSend value)? completeSend, - }) { - return completeSend?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(_Prepare value)? prepare, - TResult Function(_Send value)? send, - TResult Function(_AllowCloseSend value)? allowCloseSend, - TResult Function(_CompleteSend value)? completeSend, - required TResult orElse(), - }) { - if (completeSend != null) { - return completeSend(this); - } - return orElse(); - } -} - -abstract class _CompleteSend implements TonConfirmTransactionEvent { - const factory _CompleteSend(final Transaction transaction) = - _$CompleteSendImpl; - - Transaction get transaction; - - /// Create a copy of TonConfirmTransactionEvent - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - _$$CompleteSendImplCopyWith<_$CompleteSendImpl> get copyWith => - throw _privateConstructorUsedError; -} - /// @nodoc mixin _$TonConfirmTransactionState { @optionalTypeArgs diff --git a/lib/feature/wallet/ton_confirm_transaction/ton_confirm_transaction.dart b/lib/feature/wallet/ton_confirm_transaction/ton_confirm_transaction.dart deleted file mode 100644 index 3348f34d8..000000000 --- a/lib/feature/wallet/ton_confirm_transaction/ton_confirm_transaction.dart +++ /dev/null @@ -1,2 +0,0 @@ -export 'bloc/bloc.dart'; -export 'view/view.dart'; diff --git a/lib/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen.dart b/lib/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen.dart new file mode 100644 index 000000000..ed03bcd41 --- /dev/null +++ b/lib/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen.dart @@ -0,0 +1,116 @@ +import 'package:app/feature/wallet/ton_confirm_transaction/data/ton_confirm_transaction_state.dart'; +import 'package:app/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen_wm.dart'; +import 'package:app/feature/wallet/ton_confirm_transaction/widgets/confirm_view.dart'; +import 'package:app/feature/wallet/ton_confirm_transaction/widgets/transaction_prepare.dart'; +import 'package:app/feature/wallet/ton_wallet_send/widgets/transaction_sending_widget.dart'; +import 'package:app/feature/wallet/widgets/wallet_subscribe_error_widget.dart'; +import 'package:app/generated/generated.dart'; +import 'package:elementary/elementary.dart'; +import 'package:elementary_helper/elementary_helper.dart'; +import 'package:flutter/material.dart'; +import 'package:nekoton_repository/nekoton_repository.dart'; +import 'package:ui_components_lib/ui_components_lib.dart'; + +class TonConfirmTransactionScreen + extends ElementaryWidget { + TonConfirmTransactionScreen({ + /// Address of wallet which will be used to confirm transaction + required Address walletAddress, + required BigInt amount, + required String transactionId, + required this.localCustodians, + required this.destination, + required this.comment, + this.transactionIdHash, + super.key, + WidgetModelFactory? wmFactory, + }) : super( + wmFactory ?? + (ctx) => defaultTonConfirmTransactionScreenWidgetModelFactory( + ctx, + walletAddress: walletAddress, + amount: amount, + transactionId: transactionId, + ), + ); + + /// Local custodians that CAN CONFIRM transaction (not all local) + final List localCustodians; + + final String? transactionIdHash; + + /// Destination where funds should be sent (this page won't displayed for + /// incoming transaction) + final Address destination; + + /// Comment of transaction + final String? comment; + + @override + Widget build(TonConfirmTransactionScreenWidgetModel wm) { + return StateNotifierBuilder( + listenableState: wm.screenState, + builder: (context, state) { + if (state == null) { + return const SizedBox.shrink(); + } + return state.when( + prepare: () => Scaffold( + appBar: DefaultAppBar( + titleText: LocaleKeys.confirmTransaction.tr(), + ), + body: TonWalletConfirmTransactionPrepare( + localCustodians: localCustodians, + onPressed: wm.onPressedPrepare, + ), + ), + subscribeError: (error) => Scaffold( + appBar: DefaultAppBar( + titleText: LocaleKeys.confirmTransaction.tr(), + ), + body: Center(child: WalletSubscribeErrorWidget(error: error)), + ), + loading: (custodian) => _confirmPage(wm, custodian: custodian), + calculatingError: (error, custodian, fee) => + _confirmPage(wm, fee: fee, error: error, custodian: custodian), + readyToSend: (fee, custodian) => + _confirmPage(wm, fee: fee, custodian: custodian), + sending: (canClose) => Scaffold( + body: Padding( + padding: const EdgeInsets.all(DimensSize.d16), + child: TransactionSendingWidget(canClose: canClose), + ), + ), + sent: (fee, transaction, custodian) => + _confirmPage(wm, fee: fee, custodian: custodian), + ); + }, + ); + } + + Widget _confirmPage( + TonConfirmTransactionScreenWidgetModel wm, { + required PublicKey custodian, + BigInt? fee, + String? error, + }) { + // Получаем account и money из Widget Model + final account = wm.account; + final money = wm.money; + return Scaffold( + appBar: DefaultAppBar(titleText: LocaleKeys.confirmTransaction.tr()), + body: TonWalletConfirmTransactionConfirmView( + account: account, + transactionIdHash: transactionIdHash, + money: money, + recipient: destination, + amount: wm.amount, + comment: comment, + publicKey: custodian, + fee: fee, + feeError: error, + onPasswordEntered: wm.onPasswordEntered, + ), + ); + } +} diff --git a/lib/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen_model.dart b/lib/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen_model.dart new file mode 100644 index 000000000..e72e2bf4a --- /dev/null +++ b/lib/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen_model.dart @@ -0,0 +1,107 @@ +import 'package:app/app/service/messenger/message.dart'; +import 'package:app/app/service/messenger/service/messenger_service.dart'; +import 'package:app/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen.dart'; +import 'package:app/generated/generated.dart'; +import 'package:app/utils/constants.dart'; +import 'package:elementary/elementary.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:nekoton_repository/nekoton_repository.dart' hide Message; + +/// [ElementaryModel] for [TonConfirmTransactionScreen] +class TonConfirmTransactionScreenModel extends ElementaryModel { + TonConfirmTransactionScreenModel( + ErrorHandler errorHandler, + this._nekotonRepository, + this._messengerService, + this._walletAddress, + this.amount, + this._transactionId, + ) : super(errorHandler: errorHandler); + + final NekotonRepository _nekotonRepository; + final MessengerService _messengerService; + final Address _walletAddress; + final BigInt amount; + final String _transactionId; + + late final account = + _nekotonRepository.seedList.findAccountByAddress(_walletAddress); + + late final currency = + Currencies()[_nekotonRepository.currentTransport.nativeTokenTicker]; + + late final money = currency == null + ? null + : Money.fromBigIntWithCurrency( + amount, + currency!, + ); + + Future prepareConfirmTransaction( + PublicKey selectedCustodian, + ) => + _nekotonRepository.prepareConfirmTransaction( + address: _walletAddress, + publicKey: selectedCustodian, + transactionId: _transactionId, + expiration: defaultSendTimeout, + ); + + Future estimateFees(UnsignedMessage unsignedMessage) => + _nekotonRepository.estimateFees( + address: _walletAddress, + message: unsignedMessage, + ); + + // Получаем состояние кошелька и проверяем баланс + Future get walletState => _nekotonRepository.walletsStream + .expand((e) => e) + .firstWhere((wallets) => wallets.address == _walletAddress); + + Future createSignedMessage({ + required String hash, + required PublicKey selectedCustodian, + required String password, + required UnsignedMessage unsignedMessage, + }) async { + final transport = _nekotonRepository.currentTransport.transport; + + final signature = await _nekotonRepository.seedList.sign( + data: hash, + publicKey: selectedCustodian, + password: password, + signatureId: await transport.getSignatureId(), + ); + + return unsignedMessage.sign(signature: signature); + } + + Future send({ + required SignedMessage signedMessage, + required Address destination, + }) => + _nekotonRepository.send( + address: _walletAddress, + signedMessage: signedMessage, + amount: amount, + destination: destination, + ); + + void showSuccessful(BuildContext? context) { + _messengerService.show( + Message.successful( + context: context, + message: LocaleKeys.transactionSentSuccessfully.tr(), + ), + ); + } + + void showError(BuildContext? context, Object e) { + _messengerService.show( + Message.error( + context: context, + message: e.toString(), + ), + ); + } +} diff --git a/lib/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen_wm.dart b/lib/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen_wm.dart new file mode 100644 index 000000000..eb478ccaf --- /dev/null +++ b/lib/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen_wm.dart @@ -0,0 +1,191 @@ +import 'package:app/app/router/router.dart'; +import 'package:app/core/error_handler_factory.dart'; +import 'package:app/core/wm/custom_wm.dart'; +import 'package:app/di/di.dart'; +import 'package:app/feature/wallet/ton_confirm_transaction/data/ton_confirm_transaction_state.dart'; +import 'package:app/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen.dart'; +import 'package:app/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen_model.dart'; +import 'package:app/generated/generated.dart'; +import 'package:elementary/elementary.dart'; +import 'package:flutter/widgets.dart'; +import 'package:go_router/go_router.dart'; +import 'package:logging/logging.dart'; +import 'package:nekoton_repository/nekoton_repository.dart'; + +/// Factory method for creating [TonConfirmTransactionScreenWidgetModel] +TonConfirmTransactionScreenWidgetModel + defaultTonConfirmTransactionScreenWidgetModelFactory( + BuildContext context, { + required Address walletAddress, + required BigInt amount, + required String transactionId, +}) { + return TonConfirmTransactionScreenWidgetModel( + TonConfirmTransactionScreenModel( + createPrimaryErrorHandler(context), + inject(), + inject(), + walletAddress, + amount, + transactionId, + ), + ); +} + +/// [WidgetModel] для [TonConfirmTransactionScreen] +class TonConfirmTransactionScreenWidgetModel extends CustomWidgetModel< + TonConfirmTransactionScreen, TonConfirmTransactionScreenModel> { + TonConfirmTransactionScreenWidgetModel( + super.model, + ); + + late final screenState = createNotifier( + _localCustodians.length > 1 + ? const TonConfirmTransactionState.prepare() + : TonConfirmTransactionState.loading(_localCustodians.first), + ); + + late PublicKey selectedCustodian; + + /// Fee for transaction after calculating it in [_handlePrepare] + BigInt? _fees; + + final _logger = Logger('TonConfirmTransaction'); + + KeyAccount? get account => model.account; + + Money? get money => model.money; + + BigInt get amount => model.amount; + + List get _localCustodians => widget.localCustodians; + + @override + void initWidgetModel() { + super.initWidgetModel(); + _init(); + } + + void onPasswordEntered(String value) { + _handleSend(value); + } + + void onPressedPrepare(PublicKey key) { + _handlePrepare(key); + } + + void _init() { + if (widget.localCustodians.length == 1) { + _handlePrepare(widget.localCustodians.first); + } + } + + Future _handlePrepare(PublicKey custodian) async { + UnsignedMessage? unsignedMessage; + try { + selectedCustodian = custodian; + unsignedMessage = await model.prepareConfirmTransaction( + selectedCustodian, + ); + _fees = await model.estimateFees(unsignedMessage); + + final walletState = await model.walletState; + + if (walletState.hasError) { + screenState.accept( + TonConfirmTransactionState.subscribeError(walletState.error!), + ); + return; + } + + final wallet = walletState.wallet!; + + final balance = wallet.contractState.balance; + + final isPossibleToSendMessage = balance > (_fees! + model.amount); + + if (!isPossibleToSendMessage) { + screenState.accept( + TonConfirmTransactionState.calculatingError( + LocaleKeys.insufficientFunds.tr(), + selectedCustodian, + _fees, + ), + ); + return; + } + + screenState.accept( + TonConfirmTransactionState.readyToSend(_fees!, selectedCustodian), + ); + } catch (e, t) { + _logger.severe('_handlePrepare:', e, t); + screenState.accept( + TonConfirmTransactionState.calculatingError( + e.toString(), + selectedCustodian, + ), + ); + } finally { + unsignedMessage?.dispose(); + } + } + + Future _handleSend(String password) async { + UnsignedMessage? unsignedMessage; + + if (_fees == null) { + return; + } + + try { + screenState.accept( + const TonConfirmTransactionState.sending(canClose: false), + ); + unsignedMessage = await model.prepareConfirmTransaction( + selectedCustodian, + ); + + final signedMessage = await model.createSignedMessage( + hash: unsignedMessage.hash, + selectedCustodian: selectedCustodian, + password: password, + unsignedMessage: unsignedMessage, + ); + + screenState.accept( + const TonConfirmTransactionState.sending(canClose: true), + ); + + final transaction = await model.send( + signedMessage: signedMessage, + destination: widget.destination, + ); + + model.showSuccessful(contextSafe); + + screenState.accept( + TonConfirmTransactionState.sent( + _fees!, + transaction, + selectedCustodian, + ), + ); + + _goToWallet(); + } on OperationCanceledException catch (_) { + } catch (e, t) { + _logger.severe('_handleSend', e, t); + model.showError(contextSafe, e.toString()); + screenState.accept( + TonConfirmTransactionState.readyToSend(_fees!, selectedCustodian), + ); + } finally { + unsignedMessage?.dispose(); + } + } + + void _goToWallet() { + context.goNamed(AppRoute.wallet.name); + } +} diff --git a/lib/feature/wallet/ton_confirm_transaction/view/ton_confirm_transaction_page.dart b/lib/feature/wallet/ton_confirm_transaction/view/ton_confirm_transaction_page.dart deleted file mode 100644 index 6a2189fb3..000000000 --- a/lib/feature/wallet/ton_confirm_transaction/view/ton_confirm_transaction_page.dart +++ /dev/null @@ -1,139 +0,0 @@ -import 'package:app/app/router/router.dart'; -import 'package:app/di/di.dart'; -import 'package:app/feature/wallet/ton_confirm_transaction/view/ton_confirm_transaction_confirm_view.dart'; -import 'package:app/feature/wallet/ton_confirm_transaction/view/ton_confirm_transaction_prepare.dart'; -import 'package:app/feature/wallet/wallet.dart'; -import 'package:app/generated/generated.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:go_router/go_router.dart'; -import 'package:nekoton_repository/nekoton_repository.dart'; -import 'package:ui_components_lib/ui_components_lib.dart'; - -/// Page that allows confirm multisig transaction for [TonWallet]. -/// This pages displays only for outgoing transaction. -// TODO(knightforce): rename to Multisig or Custodian -class TonConfirmTransactionPage extends StatelessWidget { - const TonConfirmTransactionPage({ - required this.walletAddress, - required this.localCustodians, - required this.transactionId, - required this.amount, - required this.destination, - required this.comment, - this.transactionIdHash, - super.key, - }); - - /// Address of wallet which will be used to confirm transaction - final Address walletAddress; - - /// Local custodians that CAN CONFIRM transaction (not all local) - final List localCustodians; - - /// Transaction that should be confirmed - final String transactionId; - - final String? transactionIdHash; - - /// Amount of transaction - final BigInt amount; - - /// Destination where funds should be sent (this page won't displayed for - /// incoming transaction) - final Address destination; - - /// Comment of transaction - final String? comment; - - @override - Widget build(BuildContext context) { - return BlocProvider( - create: (_) => TonConfirmTransactionBloc( - context: context, - nekotonRepository: inject(), - walletAddress: walletAddress, - amount: amount, - destination: destination, - localCustodians: localCustodians, - transactionId: transactionId, - comment: comment, - ), - child: - BlocConsumer( - listener: (context, state) { - state.whenOrNull( - sent: (_, __, ___) => context.goNamed(AppRoute.wallet.name), - ); - }, - builder: (context, state) { - final bloc = context.read(); - - return state.when( - prepare: () => Scaffold( - appBar: DefaultAppBar( - titleText: LocaleKeys.confirmTransaction.tr(), - ), - body: TonWalletConfirmTransactionPrepare( - localCustodians: localCustodians, - ), - ), - subscribeError: (error) => Scaffold( - appBar: DefaultAppBar( - titleText: LocaleKeys.confirmTransaction.tr(), - ), - body: Center(child: WalletSubscribeErrorWidget(error: error)), - ), - loading: (c) => _confirmPage(bloc, custodian: c), - calculatingError: ( - error, - custodian, - fee, - ) => - _confirmPage( - bloc, - fee: fee, - error: error, - custodian: custodian, - ), - readyToSend: (fee, custodian) => - _confirmPage(bloc, fee: fee, custodian: custodian), - sending: (canClose) => Scaffold( - body: Padding( - padding: const EdgeInsets.all(DimensSize.d16), - child: TransactionSendingWidget(canClose: canClose), - ), - ), - sent: (fee, _, custodian) => _confirmPage( - bloc, - fee: fee, - custodian: custodian, - ), - ); - }, - ), - ); - } - - Widget _confirmPage( - TonConfirmTransactionBloc bloc, { - required PublicKey custodian, - BigInt? fee, - String? error, - }) { - return Scaffold( - appBar: DefaultAppBar(titleText: LocaleKeys.confirmTransaction.tr()), - body: TonWalletConfirmTransactionConfirmView( - account: bloc.account, - transactionIdHash: transactionIdHash, - money: bloc.money, - recipient: destination, - amount: amount, - comment: comment, - publicKey: custodian, - fee: fee, - feeError: error, - ), - ); - } -} diff --git a/lib/feature/wallet/ton_confirm_transaction/view/view.dart b/lib/feature/wallet/ton_confirm_transaction/view/view.dart deleted file mode 100644 index 48df0ee06..000000000 --- a/lib/feature/wallet/ton_confirm_transaction/view/view.dart +++ /dev/null @@ -1 +0,0 @@ -export 'ton_confirm_transaction_page.dart'; diff --git a/lib/feature/wallet/ton_confirm_transaction/view/ton_confirm_transaction_confirm_view.dart b/lib/feature/wallet/ton_confirm_transaction/widgets/confirm_view.dart similarity index 88% rename from lib/feature/wallet/ton_confirm_transaction/view/ton_confirm_transaction_confirm_view.dart rename to lib/feature/wallet/ton_confirm_transaction/widgets/confirm_view.dart index 74c9ca2d8..2001e0999 100644 --- a/lib/feature/wallet/ton_confirm_transaction/view/ton_confirm_transaction_confirm_view.dart +++ b/lib/feature/wallet/ton_confirm_transaction/widgets/confirm_view.dart @@ -1,10 +1,8 @@ import 'package:app/feature/profile/profile.dart'; -import 'package:app/feature/wallet/ton_confirm_transaction/bloc/bloc.dart'; import 'package:app/feature/wallet/widgets/account_info.dart'; import 'package:app/feature/wallet/widgets/token_transfer_info/token_transfer_info_widget.dart'; import 'package:app/generated/generated.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:nekoton_repository/nekoton_repository.dart'; import 'package:ui_components_lib/ui_components_lib.dart'; import 'package:ui_components_lib/v2/widgets/adaptive_footer_single_child_scroll_view.dart'; @@ -17,6 +15,7 @@ class TonWalletConfirmTransactionConfirmView extends StatelessWidget { required this.amount, required this.comment, required this.publicKey, + required this.onPasswordEntered, this.transactionIdHash, this.account, this.money, @@ -37,6 +36,8 @@ class TonWalletConfirmTransactionConfirmView extends StatelessWidget { final PublicKey publicKey; + final ValueChanged onPasswordEntered; + @override Widget build(BuildContext context) { final isLoading = fee == null && feeError == null; @@ -56,12 +57,7 @@ class TonWalletConfirmTransactionConfirmView extends StatelessWidget { title: LocaleKeys.confirm.tr(), isLoading: isLoading, isDisabled: feeError != null || fee == null, - onPasswordEntered: (value) { - Navigator.of(context).pop(); - context - .read() - .add(TonConfirmTransactionEvent.send(value)); - }, + onPasswordEntered: onPasswordEntered, ), ), const SizedBox(height: DimensSize.d16), diff --git a/lib/feature/wallet/ton_confirm_transaction/view/ton_confirm_transaction_prepare.dart b/lib/feature/wallet/ton_confirm_transaction/widgets/transaction_prepare.dart similarity index 88% rename from lib/feature/wallet/ton_confirm_transaction/view/ton_confirm_transaction_prepare.dart rename to lib/feature/wallet/ton_confirm_transaction/widgets/transaction_prepare.dart index febf95ea5..1b08e65f9 100644 --- a/lib/feature/wallet/ton_confirm_transaction/view/ton_confirm_transaction_prepare.dart +++ b/lib/feature/wallet/ton_confirm_transaction/widgets/transaction_prepare.dart @@ -1,8 +1,6 @@ import 'package:app/di/di.dart'; -import 'package:app/feature/wallet/ton_confirm_transaction/ton_confirm_transaction.dart'; import 'package:app/generated/generated.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:nekoton_repository/nekoton_repository.dart'; import 'package:ui_components_lib/ui_components_lib.dart'; import 'package:ui_components_lib/v2/widgets/buttons/accent_button.dart'; @@ -12,10 +10,12 @@ import 'package:ui_components_lib/v2/widgets/buttons/button_shape.dart'; class TonWalletConfirmTransactionPrepare extends StatefulWidget { const TonWalletConfirmTransactionPrepare({ required this.localCustodians, + required this.onPressed, super.key, }); final List localCustodians; + final ValueChanged onPressed; @override State createState() => @@ -65,12 +65,14 @@ class _TonWalletConfirmTransactionPrepareState AccentButton( buttonShape: ButtonShape.pill, title: LocaleKeys.nextWord.tr(), - onPressed: () => context.read().add( - TonConfirmTransactionEvent.prepare(custodianNotifier.value), - ), + onPressed: _onPressed, ), ], ), ); } + + void _onPressed() { + widget.onPressed(custodianNotifier.value); + } } diff --git a/lib/feature/wallet/wallet.dart b/lib/feature/wallet/wallet.dart index 0416d3a29..86ae570fd 100644 --- a/lib/feature/wallet/wallet.dart +++ b/lib/feature/wallet/wallet.dart @@ -1,7 +1,6 @@ export 'staking/staking.dart'; export 'token_wallet_details/token_wallet_details.dart'; export 'token_wallet_send/token_wallet_send.dart'; -export 'ton_confirm_transaction/ton_confirm_transaction.dart'; export 'ton_wallet_details/ton_wallet_details.dart'; export 'ton_wallet_send/ton_wallet_send.dart'; export 'view/view.dart'; From 78f9a0a46117e8830998ca185671a50f9a26b8bf Mon Sep 17 00:00:00 2001 From: knightforce Date: Wed, 5 Feb 2025 04:00:29 +0500 Subject: [PATCH 2/2] TonConfirmTransaction ui refactoring --- lib/data/models/approval_request.freezed.dart | 31 +- .../data/ton_confirm_transaction_state.dart | 14 +- ...ton_confirm_transaction_state.freezed.dart | 378 +++++++++--------- .../ton_confirm_transaction_screen.dart | 173 +++++--- .../ton_confirm_transaction_screen_wm.dart | 55 ++- .../components/common/default_app_bar.dart | 4 +- 6 files changed, 370 insertions(+), 285 deletions(-) diff --git a/lib/data/models/approval_request.freezed.dart b/lib/data/models/approval_request.freezed.dart index c7be2cc2a..d624b2c7e 100644 --- a/lib/data/models/approval_request.freezed.dart +++ b/lib/data/models/approval_request.freezed.dart @@ -2930,6 +2930,7 @@ abstract class _$$SendMessageImplCopyWith<$Res> $AddressCopyWith<$Res> get sender; $AddressCopyWith<$Res> get recipient; $FunctionCallCopyWith<$Res>? get payload; + $KnownPayloadCopyWith<$Res>? get knownPayload; } /// @nodoc @@ -3023,6 +3024,20 @@ class __$$SendMessageImplCopyWithImpl<$Res> return _then(_value.copyWith(payload: value)); }); } + + /// Create a copy of ApprovalRequest + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $KnownPayloadCopyWith<$Res>? get knownPayload { + if (_value.knownPayload == null) { + return null; + } + + return $KnownPayloadCopyWith<$Res>(_value.knownPayload!, (value) { + return _then(_value.copyWith(knownPayload: value)); + }); + } } /// @nodoc @@ -3073,23 +3088,15 @@ class _$SendMessageImpl implements _SendMessage { (identical(other.amount, amount) || other.amount == amount) && (identical(other.bounce, bounce) || other.bounce == bounce) && (identical(other.payload, payload) || other.payload == payload) && - const DeepCollectionEquality() - .equals(other.knownPayload, knownPayload) && + (identical(other.knownPayload, knownPayload) || + other.knownPayload == knownPayload) && (identical(other.completer, completer) || other.completer == completer)); } @override - int get hashCode => Object.hash( - runtimeType, - origin, - sender, - recipient, - amount, - bounce, - payload, - const DeepCollectionEquality().hash(knownPayload), - completer); + int get hashCode => Object.hash(runtimeType, origin, sender, recipient, + amount, bounce, payload, knownPayload, completer); /// Create a copy of ApprovalRequest /// with the given fields replaced by the non-null parameter values. diff --git a/lib/feature/wallet/ton_confirm_transaction/data/ton_confirm_transaction_state.dart b/lib/feature/wallet/ton_confirm_transaction/data/ton_confirm_transaction_state.dart index 16ff67000..c56b0473a 100644 --- a/lib/feature/wallet/ton_confirm_transaction/data/ton_confirm_transaction_state.dart +++ b/lib/feature/wallet/ton_confirm_transaction/data/ton_confirm_transaction_state.dart @@ -5,38 +5,38 @@ part 'ton_confirm_transaction_state.freezed.dart'; @freezed class TonConfirmTransactionState with _$TonConfirmTransactionState { - const factory TonConfirmTransactionState.prepare() = _PrepareState; + const factory TonConfirmTransactionState.prepare() = PrepareState; const factory TonConfirmTransactionState.loading( PublicKey custodian, - ) = _LoadingState; + ) = LoadingState; const factory TonConfirmTransactionState.subscribeError(Object error) = - _SubscribeError; + SubscribeError; /// Error during prepare process const factory TonConfirmTransactionState.calculatingError( String error, PublicKey custodian, [ BigInt? fee, - ]) = _CalculatingError; + ]) = CalculatingError; /// Blockchain fee loaded, allow user send transaction const factory TonConfirmTransactionState.readyToSend( BigInt fee, PublicKey custodian, - ) = _Ready; + ) = Ready; /// Transaction is sending. /// [canClose] needs to allow user close transaction right after it was sent /// to blockchain but not completed. const factory TonConfirmTransactionState.sending({required bool canClose}) = - _Sending; + Sending; /// Transaction sent successfully const factory TonConfirmTransactionState.sent( BigInt fee, Transaction transaction, PublicKey custodian, - ) = _Sent; + ) = Sent; } diff --git a/lib/feature/wallet/ton_confirm_transaction/data/ton_confirm_transaction_state.freezed.dart b/lib/feature/wallet/ton_confirm_transaction/data/ton_confirm_transaction_state.freezed.dart index 18d1b0dbe..7d38fe3c3 100644 --- a/lib/feature/wallet/ton_confirm_transaction/data/ton_confirm_transaction_state.freezed.dart +++ b/lib/feature/wallet/ton_confirm_transaction/data/ton_confirm_transaction_state.freezed.dart @@ -59,35 +59,35 @@ mixin _$TonConfirmTransactionState { throw _privateConstructorUsedError; @optionalTypeArgs TResult map({ - required TResult Function(_PrepareState value) prepare, - required TResult Function(_LoadingState value) loading, - required TResult Function(_SubscribeError value) subscribeError, - required TResult Function(_CalculatingError value) calculatingError, - required TResult Function(_Ready value) readyToSend, - required TResult Function(_Sending value) sending, - required TResult Function(_Sent value) sent, + required TResult Function(PrepareState value) prepare, + required TResult Function(LoadingState value) loading, + required TResult Function(SubscribeError value) subscribeError, + required TResult Function(CalculatingError value) calculatingError, + required TResult Function(Ready value) readyToSend, + required TResult Function(Sending value) sending, + required TResult Function(Sent value) sent, }) => throw _privateConstructorUsedError; @optionalTypeArgs TResult? mapOrNull({ - TResult? Function(_PrepareState value)? prepare, - TResult? Function(_LoadingState value)? loading, - TResult? Function(_SubscribeError value)? subscribeError, - TResult? Function(_CalculatingError value)? calculatingError, - TResult? Function(_Ready value)? readyToSend, - TResult? Function(_Sending value)? sending, - TResult? Function(_Sent value)? sent, + TResult? Function(PrepareState value)? prepare, + TResult? Function(LoadingState value)? loading, + TResult? Function(SubscribeError value)? subscribeError, + TResult? Function(CalculatingError value)? calculatingError, + TResult? Function(Ready value)? readyToSend, + TResult? Function(Sending value)? sending, + TResult? Function(Sent value)? sent, }) => throw _privateConstructorUsedError; @optionalTypeArgs TResult maybeMap({ - TResult Function(_PrepareState value)? prepare, - TResult Function(_LoadingState value)? loading, - TResult Function(_SubscribeError value)? subscribeError, - TResult Function(_CalculatingError value)? calculatingError, - TResult Function(_Ready value)? readyToSend, - TResult Function(_Sending value)? sending, - TResult Function(_Sent value)? sent, + TResult Function(PrepareState value)? prepare, + TResult Function(LoadingState value)? loading, + TResult Function(SubscribeError value)? subscribeError, + TResult Function(CalculatingError value)? calculatingError, + TResult Function(Ready value)? readyToSend, + TResult Function(Sending value)? sending, + TResult Function(Sent value)? sent, required TResult orElse(), }) => throw _privateConstructorUsedError; @@ -137,7 +137,7 @@ class __$$PrepareStateImplCopyWithImpl<$Res> /// @nodoc -class _$PrepareStateImpl implements _PrepareState { +class _$PrepareStateImpl implements PrepareState { const _$PrepareStateImpl(); @override @@ -210,13 +210,13 @@ class _$PrepareStateImpl implements _PrepareState { @override @optionalTypeArgs TResult map({ - required TResult Function(_PrepareState value) prepare, - required TResult Function(_LoadingState value) loading, - required TResult Function(_SubscribeError value) subscribeError, - required TResult Function(_CalculatingError value) calculatingError, - required TResult Function(_Ready value) readyToSend, - required TResult Function(_Sending value) sending, - required TResult Function(_Sent value) sent, + required TResult Function(PrepareState value) prepare, + required TResult Function(LoadingState value) loading, + required TResult Function(SubscribeError value) subscribeError, + required TResult Function(CalculatingError value) calculatingError, + required TResult Function(Ready value) readyToSend, + required TResult Function(Sending value) sending, + required TResult Function(Sent value) sent, }) { return prepare(this); } @@ -224,13 +224,13 @@ class _$PrepareStateImpl implements _PrepareState { @override @optionalTypeArgs TResult? mapOrNull({ - TResult? Function(_PrepareState value)? prepare, - TResult? Function(_LoadingState value)? loading, - TResult? Function(_SubscribeError value)? subscribeError, - TResult? Function(_CalculatingError value)? calculatingError, - TResult? Function(_Ready value)? readyToSend, - TResult? Function(_Sending value)? sending, - TResult? Function(_Sent value)? sent, + TResult? Function(PrepareState value)? prepare, + TResult? Function(LoadingState value)? loading, + TResult? Function(SubscribeError value)? subscribeError, + TResult? Function(CalculatingError value)? calculatingError, + TResult? Function(Ready value)? readyToSend, + TResult? Function(Sending value)? sending, + TResult? Function(Sent value)? sent, }) { return prepare?.call(this); } @@ -238,13 +238,13 @@ class _$PrepareStateImpl implements _PrepareState { @override @optionalTypeArgs TResult maybeMap({ - TResult Function(_PrepareState value)? prepare, - TResult Function(_LoadingState value)? loading, - TResult Function(_SubscribeError value)? subscribeError, - TResult Function(_CalculatingError value)? calculatingError, - TResult Function(_Ready value)? readyToSend, - TResult Function(_Sending value)? sending, - TResult Function(_Sent value)? sent, + TResult Function(PrepareState value)? prepare, + TResult Function(LoadingState value)? loading, + TResult Function(SubscribeError value)? subscribeError, + TResult Function(CalculatingError value)? calculatingError, + TResult Function(Ready value)? readyToSend, + TResult Function(Sending value)? sending, + TResult Function(Sent value)? sent, required TResult orElse(), }) { if (prepare != null) { @@ -254,8 +254,8 @@ class _$PrepareStateImpl implements _PrepareState { } } -abstract class _PrepareState implements TonConfirmTransactionState { - const factory _PrepareState() = _$PrepareStateImpl; +abstract class PrepareState implements TonConfirmTransactionState { + const factory PrepareState() = _$PrepareStateImpl; } /// @nodoc @@ -305,7 +305,7 @@ class __$$LoadingStateImplCopyWithImpl<$Res> /// @nodoc -class _$LoadingStateImpl implements _LoadingState { +class _$LoadingStateImpl implements LoadingState { const _$LoadingStateImpl(this.custodian); @override @@ -392,13 +392,13 @@ class _$LoadingStateImpl implements _LoadingState { @override @optionalTypeArgs TResult map({ - required TResult Function(_PrepareState value) prepare, - required TResult Function(_LoadingState value) loading, - required TResult Function(_SubscribeError value) subscribeError, - required TResult Function(_CalculatingError value) calculatingError, - required TResult Function(_Ready value) readyToSend, - required TResult Function(_Sending value) sending, - required TResult Function(_Sent value) sent, + required TResult Function(PrepareState value) prepare, + required TResult Function(LoadingState value) loading, + required TResult Function(SubscribeError value) subscribeError, + required TResult Function(CalculatingError value) calculatingError, + required TResult Function(Ready value) readyToSend, + required TResult Function(Sending value) sending, + required TResult Function(Sent value) sent, }) { return loading(this); } @@ -406,13 +406,13 @@ class _$LoadingStateImpl implements _LoadingState { @override @optionalTypeArgs TResult? mapOrNull({ - TResult? Function(_PrepareState value)? prepare, - TResult? Function(_LoadingState value)? loading, - TResult? Function(_SubscribeError value)? subscribeError, - TResult? Function(_CalculatingError value)? calculatingError, - TResult? Function(_Ready value)? readyToSend, - TResult? Function(_Sending value)? sending, - TResult? Function(_Sent value)? sent, + TResult? Function(PrepareState value)? prepare, + TResult? Function(LoadingState value)? loading, + TResult? Function(SubscribeError value)? subscribeError, + TResult? Function(CalculatingError value)? calculatingError, + TResult? Function(Ready value)? readyToSend, + TResult? Function(Sending value)? sending, + TResult? Function(Sent value)? sent, }) { return loading?.call(this); } @@ -420,13 +420,13 @@ class _$LoadingStateImpl implements _LoadingState { @override @optionalTypeArgs TResult maybeMap({ - TResult Function(_PrepareState value)? prepare, - TResult Function(_LoadingState value)? loading, - TResult Function(_SubscribeError value)? subscribeError, - TResult Function(_CalculatingError value)? calculatingError, - TResult Function(_Ready value)? readyToSend, - TResult Function(_Sending value)? sending, - TResult Function(_Sent value)? sent, + TResult Function(PrepareState value)? prepare, + TResult Function(LoadingState value)? loading, + TResult Function(SubscribeError value)? subscribeError, + TResult Function(CalculatingError value)? calculatingError, + TResult Function(Ready value)? readyToSend, + TResult Function(Sending value)? sending, + TResult Function(Sent value)? sent, required TResult orElse(), }) { if (loading != null) { @@ -436,8 +436,8 @@ class _$LoadingStateImpl implements _LoadingState { } } -abstract class _LoadingState implements TonConfirmTransactionState { - const factory _LoadingState(final PublicKey custodian) = _$LoadingStateImpl; +abstract class LoadingState implements TonConfirmTransactionState { + const factory LoadingState(final PublicKey custodian) = _$LoadingStateImpl; PublicKey get custodian; @@ -480,7 +480,7 @@ class __$$SubscribeErrorImplCopyWithImpl<$Res> /// @nodoc -class _$SubscribeErrorImpl implements _SubscribeError { +class _$SubscribeErrorImpl implements SubscribeError { const _$SubscribeErrorImpl(this.error); @override @@ -568,13 +568,13 @@ class _$SubscribeErrorImpl implements _SubscribeError { @override @optionalTypeArgs TResult map({ - required TResult Function(_PrepareState value) prepare, - required TResult Function(_LoadingState value) loading, - required TResult Function(_SubscribeError value) subscribeError, - required TResult Function(_CalculatingError value) calculatingError, - required TResult Function(_Ready value) readyToSend, - required TResult Function(_Sending value) sending, - required TResult Function(_Sent value) sent, + required TResult Function(PrepareState value) prepare, + required TResult Function(LoadingState value) loading, + required TResult Function(SubscribeError value) subscribeError, + required TResult Function(CalculatingError value) calculatingError, + required TResult Function(Ready value) readyToSend, + required TResult Function(Sending value) sending, + required TResult Function(Sent value) sent, }) { return subscribeError(this); } @@ -582,13 +582,13 @@ class _$SubscribeErrorImpl implements _SubscribeError { @override @optionalTypeArgs TResult? mapOrNull({ - TResult? Function(_PrepareState value)? prepare, - TResult? Function(_LoadingState value)? loading, - TResult? Function(_SubscribeError value)? subscribeError, - TResult? Function(_CalculatingError value)? calculatingError, - TResult? Function(_Ready value)? readyToSend, - TResult? Function(_Sending value)? sending, - TResult? Function(_Sent value)? sent, + TResult? Function(PrepareState value)? prepare, + TResult? Function(LoadingState value)? loading, + TResult? Function(SubscribeError value)? subscribeError, + TResult? Function(CalculatingError value)? calculatingError, + TResult? Function(Ready value)? readyToSend, + TResult? Function(Sending value)? sending, + TResult? Function(Sent value)? sent, }) { return subscribeError?.call(this); } @@ -596,13 +596,13 @@ class _$SubscribeErrorImpl implements _SubscribeError { @override @optionalTypeArgs TResult maybeMap({ - TResult Function(_PrepareState value)? prepare, - TResult Function(_LoadingState value)? loading, - TResult Function(_SubscribeError value)? subscribeError, - TResult Function(_CalculatingError value)? calculatingError, - TResult Function(_Ready value)? readyToSend, - TResult Function(_Sending value)? sending, - TResult Function(_Sent value)? sent, + TResult Function(PrepareState value)? prepare, + TResult Function(LoadingState value)? loading, + TResult Function(SubscribeError value)? subscribeError, + TResult Function(CalculatingError value)? calculatingError, + TResult Function(Ready value)? readyToSend, + TResult Function(Sending value)? sending, + TResult Function(Sent value)? sent, required TResult orElse(), }) { if (subscribeError != null) { @@ -612,8 +612,8 @@ class _$SubscribeErrorImpl implements _SubscribeError { } } -abstract class _SubscribeError implements TonConfirmTransactionState { - const factory _SubscribeError(final Object error) = _$SubscribeErrorImpl; +abstract class SubscribeError implements TonConfirmTransactionState { + const factory SubscribeError(final Object error) = _$SubscribeErrorImpl; Object get error; @@ -682,7 +682,7 @@ class __$$CalculatingErrorImplCopyWithImpl<$Res> /// @nodoc -class _$CalculatingErrorImpl implements _CalculatingError { +class _$CalculatingErrorImpl implements CalculatingError { const _$CalculatingErrorImpl(this.error, this.custodian, [this.fee]); @override @@ -776,13 +776,13 @@ class _$CalculatingErrorImpl implements _CalculatingError { @override @optionalTypeArgs TResult map({ - required TResult Function(_PrepareState value) prepare, - required TResult Function(_LoadingState value) loading, - required TResult Function(_SubscribeError value) subscribeError, - required TResult Function(_CalculatingError value) calculatingError, - required TResult Function(_Ready value) readyToSend, - required TResult Function(_Sending value) sending, - required TResult Function(_Sent value) sent, + required TResult Function(PrepareState value) prepare, + required TResult Function(LoadingState value) loading, + required TResult Function(SubscribeError value) subscribeError, + required TResult Function(CalculatingError value) calculatingError, + required TResult Function(Ready value) readyToSend, + required TResult Function(Sending value) sending, + required TResult Function(Sent value) sent, }) { return calculatingError(this); } @@ -790,13 +790,13 @@ class _$CalculatingErrorImpl implements _CalculatingError { @override @optionalTypeArgs TResult? mapOrNull({ - TResult? Function(_PrepareState value)? prepare, - TResult? Function(_LoadingState value)? loading, - TResult? Function(_SubscribeError value)? subscribeError, - TResult? Function(_CalculatingError value)? calculatingError, - TResult? Function(_Ready value)? readyToSend, - TResult? Function(_Sending value)? sending, - TResult? Function(_Sent value)? sent, + TResult? Function(PrepareState value)? prepare, + TResult? Function(LoadingState value)? loading, + TResult? Function(SubscribeError value)? subscribeError, + TResult? Function(CalculatingError value)? calculatingError, + TResult? Function(Ready value)? readyToSend, + TResult? Function(Sending value)? sending, + TResult? Function(Sent value)? sent, }) { return calculatingError?.call(this); } @@ -804,13 +804,13 @@ class _$CalculatingErrorImpl implements _CalculatingError { @override @optionalTypeArgs TResult maybeMap({ - TResult Function(_PrepareState value)? prepare, - TResult Function(_LoadingState value)? loading, - TResult Function(_SubscribeError value)? subscribeError, - TResult Function(_CalculatingError value)? calculatingError, - TResult Function(_Ready value)? readyToSend, - TResult Function(_Sending value)? sending, - TResult Function(_Sent value)? sent, + TResult Function(PrepareState value)? prepare, + TResult Function(LoadingState value)? loading, + TResult Function(SubscribeError value)? subscribeError, + TResult Function(CalculatingError value)? calculatingError, + TResult Function(Ready value)? readyToSend, + TResult Function(Sending value)? sending, + TResult Function(Sent value)? sent, required TResult orElse(), }) { if (calculatingError != null) { @@ -820,8 +820,8 @@ class _$CalculatingErrorImpl implements _CalculatingError { } } -abstract class _CalculatingError implements TonConfirmTransactionState { - const factory _CalculatingError(final String error, final PublicKey custodian, +abstract class CalculatingError implements TonConfirmTransactionState { + const factory CalculatingError(final String error, final PublicKey custodian, [final BigInt? fee]) = _$CalculatingErrorImpl; String get error; @@ -887,7 +887,7 @@ class __$$ReadyImplCopyWithImpl<$Res> /// @nodoc -class _$ReadyImpl implements _Ready { +class _$ReadyImpl implements Ready { const _$ReadyImpl(this.fee, this.custodian); @override @@ -977,13 +977,13 @@ class _$ReadyImpl implements _Ready { @override @optionalTypeArgs TResult map({ - required TResult Function(_PrepareState value) prepare, - required TResult Function(_LoadingState value) loading, - required TResult Function(_SubscribeError value) subscribeError, - required TResult Function(_CalculatingError value) calculatingError, - required TResult Function(_Ready value) readyToSend, - required TResult Function(_Sending value) sending, - required TResult Function(_Sent value) sent, + required TResult Function(PrepareState value) prepare, + required TResult Function(LoadingState value) loading, + required TResult Function(SubscribeError value) subscribeError, + required TResult Function(CalculatingError value) calculatingError, + required TResult Function(Ready value) readyToSend, + required TResult Function(Sending value) sending, + required TResult Function(Sent value) sent, }) { return readyToSend(this); } @@ -991,13 +991,13 @@ class _$ReadyImpl implements _Ready { @override @optionalTypeArgs TResult? mapOrNull({ - TResult? Function(_PrepareState value)? prepare, - TResult? Function(_LoadingState value)? loading, - TResult? Function(_SubscribeError value)? subscribeError, - TResult? Function(_CalculatingError value)? calculatingError, - TResult? Function(_Ready value)? readyToSend, - TResult? Function(_Sending value)? sending, - TResult? Function(_Sent value)? sent, + TResult? Function(PrepareState value)? prepare, + TResult? Function(LoadingState value)? loading, + TResult? Function(SubscribeError value)? subscribeError, + TResult? Function(CalculatingError value)? calculatingError, + TResult? Function(Ready value)? readyToSend, + TResult? Function(Sending value)? sending, + TResult? Function(Sent value)? sent, }) { return readyToSend?.call(this); } @@ -1005,13 +1005,13 @@ class _$ReadyImpl implements _Ready { @override @optionalTypeArgs TResult maybeMap({ - TResult Function(_PrepareState value)? prepare, - TResult Function(_LoadingState value)? loading, - TResult Function(_SubscribeError value)? subscribeError, - TResult Function(_CalculatingError value)? calculatingError, - TResult Function(_Ready value)? readyToSend, - TResult Function(_Sending value)? sending, - TResult Function(_Sent value)? sent, + TResult Function(PrepareState value)? prepare, + TResult Function(LoadingState value)? loading, + TResult Function(SubscribeError value)? subscribeError, + TResult Function(CalculatingError value)? calculatingError, + TResult Function(Ready value)? readyToSend, + TResult Function(Sending value)? sending, + TResult Function(Sent value)? sent, required TResult orElse(), }) { if (readyToSend != null) { @@ -1021,8 +1021,8 @@ class _$ReadyImpl implements _Ready { } } -abstract class _Ready implements TonConfirmTransactionState { - const factory _Ready(final BigInt fee, final PublicKey custodian) = +abstract class Ready implements TonConfirmTransactionState { + const factory Ready(final BigInt fee, final PublicKey custodian) = _$ReadyImpl; BigInt get fee; @@ -1070,7 +1070,7 @@ class __$$SendingImplCopyWithImpl<$Res> /// @nodoc -class _$SendingImpl implements _Sending { +class _$SendingImpl implements Sending { const _$SendingImpl({required this.canClose}); @override @@ -1157,13 +1157,13 @@ class _$SendingImpl implements _Sending { @override @optionalTypeArgs TResult map({ - required TResult Function(_PrepareState value) prepare, - required TResult Function(_LoadingState value) loading, - required TResult Function(_SubscribeError value) subscribeError, - required TResult Function(_CalculatingError value) calculatingError, - required TResult Function(_Ready value) readyToSend, - required TResult Function(_Sending value) sending, - required TResult Function(_Sent value) sent, + required TResult Function(PrepareState value) prepare, + required TResult Function(LoadingState value) loading, + required TResult Function(SubscribeError value) subscribeError, + required TResult Function(CalculatingError value) calculatingError, + required TResult Function(Ready value) readyToSend, + required TResult Function(Sending value) sending, + required TResult Function(Sent value) sent, }) { return sending(this); } @@ -1171,13 +1171,13 @@ class _$SendingImpl implements _Sending { @override @optionalTypeArgs TResult? mapOrNull({ - TResult? Function(_PrepareState value)? prepare, - TResult? Function(_LoadingState value)? loading, - TResult? Function(_SubscribeError value)? subscribeError, - TResult? Function(_CalculatingError value)? calculatingError, - TResult? Function(_Ready value)? readyToSend, - TResult? Function(_Sending value)? sending, - TResult? Function(_Sent value)? sent, + TResult? Function(PrepareState value)? prepare, + TResult? Function(LoadingState value)? loading, + TResult? Function(SubscribeError value)? subscribeError, + TResult? Function(CalculatingError value)? calculatingError, + TResult? Function(Ready value)? readyToSend, + TResult? Function(Sending value)? sending, + TResult? Function(Sent value)? sent, }) { return sending?.call(this); } @@ -1185,13 +1185,13 @@ class _$SendingImpl implements _Sending { @override @optionalTypeArgs TResult maybeMap({ - TResult Function(_PrepareState value)? prepare, - TResult Function(_LoadingState value)? loading, - TResult Function(_SubscribeError value)? subscribeError, - TResult Function(_CalculatingError value)? calculatingError, - TResult Function(_Ready value)? readyToSend, - TResult Function(_Sending value)? sending, - TResult Function(_Sent value)? sent, + TResult Function(PrepareState value)? prepare, + TResult Function(LoadingState value)? loading, + TResult Function(SubscribeError value)? subscribeError, + TResult Function(CalculatingError value)? calculatingError, + TResult Function(Ready value)? readyToSend, + TResult Function(Sending value)? sending, + TResult Function(Sent value)? sent, required TResult orElse(), }) { if (sending != null) { @@ -1201,8 +1201,8 @@ class _$SendingImpl implements _Sending { } } -abstract class _Sending implements TonConfirmTransactionState { - const factory _Sending({required final bool canClose}) = _$SendingImpl; +abstract class Sending implements TonConfirmTransactionState { + const factory Sending({required final bool canClose}) = _$SendingImpl; bool get canClose; @@ -1280,7 +1280,7 @@ class __$$SentImplCopyWithImpl<$Res> /// @nodoc -class _$SentImpl implements _Sent { +class _$SentImpl implements Sent { const _$SentImpl(this.fee, this.transaction, this.custodian); @override @@ -1374,13 +1374,13 @@ class _$SentImpl implements _Sent { @override @optionalTypeArgs TResult map({ - required TResult Function(_PrepareState value) prepare, - required TResult Function(_LoadingState value) loading, - required TResult Function(_SubscribeError value) subscribeError, - required TResult Function(_CalculatingError value) calculatingError, - required TResult Function(_Ready value) readyToSend, - required TResult Function(_Sending value) sending, - required TResult Function(_Sent value) sent, + required TResult Function(PrepareState value) prepare, + required TResult Function(LoadingState value) loading, + required TResult Function(SubscribeError value) subscribeError, + required TResult Function(CalculatingError value) calculatingError, + required TResult Function(Ready value) readyToSend, + required TResult Function(Sending value) sending, + required TResult Function(Sent value) sent, }) { return sent(this); } @@ -1388,13 +1388,13 @@ class _$SentImpl implements _Sent { @override @optionalTypeArgs TResult? mapOrNull({ - TResult? Function(_PrepareState value)? prepare, - TResult? Function(_LoadingState value)? loading, - TResult? Function(_SubscribeError value)? subscribeError, - TResult? Function(_CalculatingError value)? calculatingError, - TResult? Function(_Ready value)? readyToSend, - TResult? Function(_Sending value)? sending, - TResult? Function(_Sent value)? sent, + TResult? Function(PrepareState value)? prepare, + TResult? Function(LoadingState value)? loading, + TResult? Function(SubscribeError value)? subscribeError, + TResult? Function(CalculatingError value)? calculatingError, + TResult? Function(Ready value)? readyToSend, + TResult? Function(Sending value)? sending, + TResult? Function(Sent value)? sent, }) { return sent?.call(this); } @@ -1402,13 +1402,13 @@ class _$SentImpl implements _Sent { @override @optionalTypeArgs TResult maybeMap({ - TResult Function(_PrepareState value)? prepare, - TResult Function(_LoadingState value)? loading, - TResult Function(_SubscribeError value)? subscribeError, - TResult Function(_CalculatingError value)? calculatingError, - TResult Function(_Ready value)? readyToSend, - TResult Function(_Sending value)? sending, - TResult Function(_Sent value)? sent, + TResult Function(PrepareState value)? prepare, + TResult Function(LoadingState value)? loading, + TResult Function(SubscribeError value)? subscribeError, + TResult Function(CalculatingError value)? calculatingError, + TResult Function(Ready value)? readyToSend, + TResult Function(Sending value)? sending, + TResult Function(Sent value)? sent, required TResult orElse(), }) { if (sent != null) { @@ -1418,8 +1418,8 @@ class _$SentImpl implements _Sent { } } -abstract class _Sent implements TonConfirmTransactionState { - const factory _Sent(final BigInt fee, final Transaction transaction, +abstract class Sent implements TonConfirmTransactionState { + const factory Sent(final BigInt fee, final Transaction transaction, final PublicKey custodian) = _$SentImpl; BigInt get fee; diff --git a/lib/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen.dart b/lib/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen.dart index ed03bcd41..9603153e1 100644 --- a/lib/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen.dart +++ b/lib/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen.dart @@ -4,7 +4,6 @@ import 'package:app/feature/wallet/ton_confirm_transaction/widgets/confirm_view. import 'package:app/feature/wallet/ton_confirm_transaction/widgets/transaction_prepare.dart'; import 'package:app/feature/wallet/ton_wallet_send/widgets/transaction_sending_widget.dart'; import 'package:app/feature/wallet/widgets/wallet_subscribe_error_widget.dart'; -import 'package:app/generated/generated.dart'; import 'package:elementary/elementary.dart'; import 'package:elementary_helper/elementary_helper.dart'; import 'package:flutter/material.dart'; @@ -48,69 +47,129 @@ class TonConfirmTransactionScreen @override Widget build(TonConfirmTransactionScreenWidgetModel wm) { - return StateNotifierBuilder( - listenableState: wm.screenState, - builder: (context, state) { - if (state == null) { + return Scaffold( + appBar: _AppBar(appbarState: wm.appbarState), + body: StateNotifierBuilder( + listenableState: wm.screenState, + builder: (_, TonConfirmTransactionState? state) { + if (state == null) { + return const SizedBox.shrink(); + } + + return switch (state) { + PrepareState() => TonWalletConfirmTransactionPrepare( + localCustodians: localCustodians, + onPressed: wm.onPressedPrepare, + ), + SubscribeError(:final error) => Center( + child: WalletSubscribeErrorWidget(error: error), + ), + Sending(:final canClose) => Padding( + padding: const EdgeInsets.all(DimensSize.d16), + child: TransactionSendingWidget(canClose: canClose), + ), + _ => _ConfirmPage( + account: wm.account, + amount: wm.amount, + money: wm.money, + comment: comment, + transactionIdHash: transactionIdHash, + destination: destination, + custodian: switch (state) { + LoadingState(:final custodian) || + CalculatingError(:final custodian) || + Ready(:final custodian) || + Sent(:final custodian) => + custodian, + _ => null, + }, + fee: switch (state) { + CalculatingError(:final fee) => fee, + Ready(:final fee) || Sent(:final fee) => fee, + _ => null, + }, + error: switch (state) { + CalculatingError(:final error) => error, + _ => null, + }, + onPasswordEntered: wm.onPasswordEntered, + ), + }; + }, + ), + ); + } +} + +class _AppBar extends StatelessWidget implements PreferredSizeWidget { + const _AppBar({ + required this.appbarState, + }); + + final ListenableState appbarState; + + @override + Size get preferredSize => DefaultAppBar.size; + + @override + Widget build(BuildContext context) { + return StateNotifierBuilder( + listenableState: appbarState, + builder: (_, String? title) { + if (title == null) { return const SizedBox.shrink(); } - return state.when( - prepare: () => Scaffold( - appBar: DefaultAppBar( - titleText: LocaleKeys.confirmTransaction.tr(), - ), - body: TonWalletConfirmTransactionPrepare( - localCustodians: localCustodians, - onPressed: wm.onPressedPrepare, - ), - ), - subscribeError: (error) => Scaffold( - appBar: DefaultAppBar( - titleText: LocaleKeys.confirmTransaction.tr(), - ), - body: Center(child: WalletSubscribeErrorWidget(error: error)), - ), - loading: (custodian) => _confirmPage(wm, custodian: custodian), - calculatingError: (error, custodian, fee) => - _confirmPage(wm, fee: fee, error: error, custodian: custodian), - readyToSend: (fee, custodian) => - _confirmPage(wm, fee: fee, custodian: custodian), - sending: (canClose) => Scaffold( - body: Padding( - padding: const EdgeInsets.all(DimensSize.d16), - child: TransactionSendingWidget(canClose: canClose), - ), - ), - sent: (fee, transaction, custodian) => - _confirmPage(wm, fee: fee, custodian: custodian), + + return DefaultAppBar( + titleText: title, ); }, ); } +} - Widget _confirmPage( - TonConfirmTransactionScreenWidgetModel wm, { - required PublicKey custodian, - BigInt? fee, - String? error, - }) { - // Получаем account и money из Widget Model - final account = wm.account; - final money = wm.money; - return Scaffold( - appBar: DefaultAppBar(titleText: LocaleKeys.confirmTransaction.tr()), - body: TonWalletConfirmTransactionConfirmView( - account: account, - transactionIdHash: transactionIdHash, - money: money, - recipient: destination, - amount: wm.amount, - comment: comment, - publicKey: custodian, - fee: fee, - feeError: error, - onPasswordEntered: wm.onPasswordEntered, - ), +class _ConfirmPage extends StatelessWidget { + const _ConfirmPage({ + required this.amount, + required this.destination, + required this.onPasswordEntered, + this.account, + this.money, + this.transactionIdHash, + this.comment, + this.custodian, + this.fee, + this.error, + }); + + final KeyAccount? account; + final BigInt amount; + final Money? money; + final String? transactionIdHash; + final String? comment; + final Address destination; + final PublicKey? custodian; + final BigInt? fee; + final String? error; + final ValueChanged onPasswordEntered; + + @override + Widget build(BuildContext context) { + if (custodian == null) { + return const SizedBox.shrink(); + } + + return TonWalletConfirmTransactionConfirmView( + account: account, + transactionIdHash: transactionIdHash, + money: money, + recipient: destination, + amount: amount, + comment: comment, + publicKey: custodian!, + fee: fee, + feeError: error, + onPasswordEntered: onPasswordEntered, ); } } diff --git a/lib/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen_wm.dart b/lib/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen_wm.dart index eb478ccaf..b125d8c27 100644 --- a/lib/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen_wm.dart +++ b/lib/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen_wm.dart @@ -7,6 +7,7 @@ import 'package:app/feature/wallet/ton_confirm_transaction/ton_confirm_transacti import 'package:app/feature/wallet/ton_confirm_transaction/ton_confirm_transaction_screen_model.dart'; import 'package:app/generated/generated.dart'; import 'package:elementary/elementary.dart'; +import 'package:elementary_helper/elementary_helper.dart'; import 'package:flutter/widgets.dart'; import 'package:go_router/go_router.dart'; import 'package:logging/logging.dart'; @@ -39,19 +40,25 @@ class TonConfirmTransactionScreenWidgetModel extends CustomWidgetModel< super.model, ); - late final screenState = createNotifier( + late final _screenState = createNotifier( _localCustodians.length > 1 ? const TonConfirmTransactionState.prepare() : TonConfirmTransactionState.loading(_localCustodians.first), ); - late PublicKey selectedCustodian; + late final _appbarState = createNotifier(); + + late PublicKey _selectedCustodian; /// Fee for transaction after calculating it in [_handlePrepare] BigInt? _fees; final _logger = Logger('TonConfirmTransaction'); + ListenableState get screenState => _screenState; + + ListenableState get appbarState => _appbarState; + KeyAccount? get account => model.account; Money? get money => model.money; @@ -64,6 +71,16 @@ class TonConfirmTransactionScreenWidgetModel extends CustomWidgetModel< void initWidgetModel() { super.initWidgetModel(); _init(); + _screenState.addListener( + () { + _appbarState.accept( + _screenState.value?.maybeWhen( + sending: (_) => null, + orElse: () => LocaleKeys.confirmTransaction.tr(), + ), + ); + }, + ); } void onPasswordEntered(String value) { @@ -83,16 +100,16 @@ class TonConfirmTransactionScreenWidgetModel extends CustomWidgetModel< Future _handlePrepare(PublicKey custodian) async { UnsignedMessage? unsignedMessage; try { - selectedCustodian = custodian; + _selectedCustodian = custodian; unsignedMessage = await model.prepareConfirmTransaction( - selectedCustodian, + _selectedCustodian, ); _fees = await model.estimateFees(unsignedMessage); final walletState = await model.walletState; if (walletState.hasError) { - screenState.accept( + _screenState.accept( TonConfirmTransactionState.subscribeError(walletState.error!), ); return; @@ -105,25 +122,25 @@ class TonConfirmTransactionScreenWidgetModel extends CustomWidgetModel< final isPossibleToSendMessage = balance > (_fees! + model.amount); if (!isPossibleToSendMessage) { - screenState.accept( + _screenState.accept( TonConfirmTransactionState.calculatingError( LocaleKeys.insufficientFunds.tr(), - selectedCustodian, + _selectedCustodian, _fees, ), ); return; } - screenState.accept( - TonConfirmTransactionState.readyToSend(_fees!, selectedCustodian), + _screenState.accept( + TonConfirmTransactionState.readyToSend(_fees!, _selectedCustodian), ); } catch (e, t) { _logger.severe('_handlePrepare:', e, t); - screenState.accept( + _screenState.accept( TonConfirmTransactionState.calculatingError( e.toString(), - selectedCustodian, + _selectedCustodian, ), ); } finally { @@ -139,21 +156,21 @@ class TonConfirmTransactionScreenWidgetModel extends CustomWidgetModel< } try { - screenState.accept( + _screenState.accept( const TonConfirmTransactionState.sending(canClose: false), ); unsignedMessage = await model.prepareConfirmTransaction( - selectedCustodian, + _selectedCustodian, ); final signedMessage = await model.createSignedMessage( hash: unsignedMessage.hash, - selectedCustodian: selectedCustodian, + selectedCustodian: _selectedCustodian, password: password, unsignedMessage: unsignedMessage, ); - screenState.accept( + _screenState.accept( const TonConfirmTransactionState.sending(canClose: true), ); @@ -164,11 +181,11 @@ class TonConfirmTransactionScreenWidgetModel extends CustomWidgetModel< model.showSuccessful(contextSafe); - screenState.accept( + _screenState.accept( TonConfirmTransactionState.sent( _fees!, transaction, - selectedCustodian, + _selectedCustodian, ), ); @@ -177,8 +194,8 @@ class TonConfirmTransactionScreenWidgetModel extends CustomWidgetModel< } catch (e, t) { _logger.severe('_handleSend', e, t); model.showError(contextSafe, e.toString()); - screenState.accept( - TonConfirmTransactionState.readyToSend(_fees!, selectedCustodian), + _screenState.accept( + TonConfirmTransactionState.readyToSend(_fees!, _selectedCustodian), ); } finally { unsignedMessage?.dispose(); diff --git a/packages/ui_components_lib/lib/components/common/default_app_bar.dart b/packages/ui_components_lib/lib/components/common/default_app_bar.dart index cea6790a4..aef23ac6a 100644 --- a/packages/ui_components_lib/lib/components/common/default_app_bar.dart +++ b/packages/ui_components_lib/lib/components/common/default_app_bar.dart @@ -56,6 +56,8 @@ class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget { this.systemOverlayStyle, }); + static const size = Size.fromHeight(defaultAppBarHeight); + /// This is a default action of [DefaultAppBar] that is used with leading /// or action buttons. /// This field exists because of difference of navigation between story book @@ -83,7 +85,7 @@ class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget { }; @override - Size get preferredSize => const Size.fromHeight(defaultAppBarHeight); + Size get preferredSize => size; /// Color of the appbar. /// Default is transparent