dont use a dialog for fee slider page.
MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Send/FeeSliderViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Send/FeeSliderViewModel.cs
@@ -3,12 +3,19 @@ using System.Collections.Generic;
using System.Linq;
using System.Reactive.Disposables;
using System.Reactive.Linq;
+using System.Threading.Tasks;
using NBitcoin;
using ReactiveUI;
using WalletWasabi.Blockchain.Analysis.FeesEstimation;
+using WalletWasabi.Exceptions;
+using WalletWasabi.Fluent.Helpers;
using WalletWasabi.Fluent.MathNet;
+using WalletWasabi.Fluent.Models;
+using WalletWasabi.Fluent.ViewModels.Dialogs;
using WalletWasabi.Fluent.ViewModels.Dialogs.Base;
+using WalletWasabi.Fluent.ViewModels.Navigation;
using WalletWasabi.Gui.Converters;
+using WalletWasabi.Logging;
using WalletWasabi.Wallets;
namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
@@ -20,9 +27,10 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
NavBarPosition = NavBarPosition.None,
Searchable = false,
NavigationTarget = NavigationTarget.DialogScreen)]
- public partial class FeeSliderViewModel : DialogViewModelBase<(FeeRate feeRate, TimeSpan confirmationTime)>
+ public partial class FeeSliderViewModel : RoutableViewModel
{
private readonly Wallet _wallet;
+ private readonly TransactionInfo _transactionInfo;
[AutoNotify] private double[] _xAxisValues;
[AutoNotify] private double[] _yAxisValues;
@@ -40,9 +48,11 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
private FeeRate _feeRate;
private double _lastXAxisCurrentValue;
- public FeeSliderViewModel(Wallet wallet)
+ public FeeSliderViewModel(Wallet wallet, TransactionInfo transactionInfo)
{
_wallet = wallet;
+ _transactionInfo = transactionInfo;
+
_lastXAxisCurrentValue = _xAxisCurrentValue;
this.WhenAnyValue(x => x.XAxisCurrentValue)
@@ -58,15 +68,50 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
this.WhenAnyValue(x => x.XAxisCurrentValueIndex)
.Subscribe(SetXAxisCurrentValue);
- NextCommand = ReactiveCommand.Create(() =>
+ NextCommand = ReactiveCommand.CreateFromTask(async () =>
{
_lastXAxisCurrentValue = XAxisCurrentValue;
- var confirmationTime = CalculateConfirmationTime(_lastXAxisCurrentValue);
+ _transactionInfo.ConfirmationTimeSpan = CalculateConfirmationTime(_lastXAxisCurrentValue);
- Close(DialogResultKind.Normal, (_feeRate, confirmationTime));
+ await OnNextAsync();
});
}
+ private async Task OnNextAsync()
+ {
+ var transactionInfo = _transactionInfo;
+ var targetAnonymitySet = _wallet.ServiceConfiguration.GetMixUntilAnonymitySetValue();
+ var mixedCoins = _wallet.Coins.Where(x => x.HdPubKey.AnonymitySet >= targetAnonymitySet).ToList();
+ var totalMixedCoinsAmount = Money.FromUnit(mixedCoins.Sum(coin => coin.Amount), MoneyUnit.Satoshi);
+ transactionInfo.Coins = mixedCoins;
+
+ transactionInfo.FeeRate = _feeRate;
+
+ if (transactionInfo.Amount > totalMixedCoinsAmount)
+ {
+ Navigate().To(new PrivacyControlViewModel(_wallet, transactionInfo));
+ return;
+ }
+
+ try
+ {
+ if (_transactionInfo.PayJoinClient is { })
+ {
+ await BuildTransactionAsPayJoinAsync(transactionInfo);
+ }
+ else
+ {
+ await BuildTransactionAsNormalAsync(transactionInfo, totalMixedCoinsAmount);
+ }
+ }
+ catch (Exception ex)
+ {
+ Logger.LogError(ex);
+ await ShowErrorAsync("Transaction Building", ex.ToUserFriendlyString(),
+ "Wasabi was unable to create your transaction.");
+ }
+ }
+
protected override void OnNavigatedTo(bool isInHistory, CompositeDisposable disposables)
{
base.OnNavigatedTo(isInHistory, disposables);
@@ -85,6 +130,50 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
}
}
+ private async Task BuildTransactionAsNormalAsync(TransactionInfo transactionInfo, Money totalMixedCoinsAmount)
+ {
+ try
+ {
+ var txRes = await Task.Run(() => TransactionHelpers.BuildTransaction(_wallet, transactionInfo));
+ Navigate().To(new OptimisePrivacyViewModel(_wallet, transactionInfo, txRes));
+ }
+ catch (InsufficientBalanceException)
+ {
+ var txRes = await Task.Run(() => TransactionHelpers.BuildTransaction(_wallet, transactionInfo.Address,
+ totalMixedCoinsAmount, transactionInfo.Labels, transactionInfo.FeeRate, transactionInfo.Coins,
+ subtractFee: true));
+ var dialog = new InsufficientBalanceDialogViewModel(BalanceType.Private, txRes,
+ _wallet.Synchronizer.UsdExchangeRate);
+ var result = await NavigateDialogAsync(dialog, NavigationTarget.DialogScreen);
+
+ if (result.Result)
+ {
+ Navigate().To(new OptimisePrivacyViewModel(_wallet, transactionInfo, txRes));
+ }
+ else
+ {
+ Navigate().To(new PrivacyControlViewModel(_wallet, transactionInfo));
+ }
+ }
+ }
+
+ private async Task BuildTransactionAsPayJoinAsync(TransactionInfo transactionInfo)
+ {
+ try
+ {
+ // Do not add the PayJoin client yet, it will be added before broadcasting.
+ var txRes = await Task.Run(() => TransactionHelpers.BuildTransaction(_wallet, transactionInfo));
+ Navigate().To(new TransactionPreviewViewModel(_wallet, transactionInfo, txRes));
+ }
+ catch (InsufficientBalanceException)
+ {
+ await ShowErrorAsync("Transaction Building",
+ "There are not enough private funds to cover the transaction fee",
+ "Wasabi was unable to create your transaction.");
+ Navigate().To(new PrivacyControlViewModel(_wallet, transactionInfo));
+ }
+ }
+
private TimeSpan CalculateConfirmationTime(double targetBlock)
{
var timeInMinutes = Math.Ceiling(targetBlock) * 10;

MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Send/SendViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Send/SendViewModel.cs
@@ -108,7 +108,10 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
return allFilled && !hasError;
});
- NextCommand = ReactiveCommand.CreateFromTask(async () => await OnNextAsync(), nextCommandCanExecute);
+ NextCommand = ReactiveCommand.Create(() =>
+ {
+ Navigate().To(new FeeSliderViewModel(_wallet, _transactionInfo));
+ }, nextCommandCanExecute);
EnableAutoBusyOn(NextCommand);
}
@@ -141,89 +144,6 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
_parsingUrl = false;
}
- private async Task OnNextAsync()
- {
- var result = await NavigateDialogAsync(new FeeSliderViewModel(_wallet));
-
- if (result.Kind == DialogResultKind.Normal && result.Result is { })
- {
- _transactionInfo.FeeRate = result.Result.feeRate;
- _transactionInfo.ConfirmationTimeSpan = result.Result.confirmationTime;
- }
- else
- {
- return;
- }
-
- var transactionInfo = _transactionInfo;
- var targetAnonymitySet = _wallet.ServiceConfiguration.GetMixUntilAnonymitySetValue();
- var mixedCoins = _wallet.Coins.Where(x => x.HdPubKey.AnonymitySet >= targetAnonymitySet).ToList();
- var totalMixedCoinsAmount = Money.FromUnit(mixedCoins.Sum(coin => coin.Amount), MoneyUnit.Satoshi);
- transactionInfo.Coins = mixedCoins;
-
- if (transactionInfo.Amount > totalMixedCoinsAmount)
- {
- Navigate().To(new PrivacyControlViewModel(_wallet, transactionInfo));
- return;
- }
-
- try
- {
- if (IsPayJoin)
- {
- await BuildTransactionAsPayJoinAsync(transactionInfo);
- }
- else
- {
- await BuildTransactionAsNormalAsync(transactionInfo, totalMixedCoinsAmount);
- }
- }
- catch (Exception ex)
- {
- Logger.LogError(ex);
- await ShowErrorAsync("Transaction Building", ex.ToUserFriendlyString(), "Wasabi was unable to create your transaction.");
- }
- }
-
- private async Task BuildTransactionAsNormalAsync(TransactionInfo transactionInfo, Money totalMixedCoinsAmount)
- {
- try
- {
- var txRes = await Task.Run(() => TransactionHelpers.BuildTransaction(_wallet, transactionInfo));
- Navigate().To(new OptimisePrivacyViewModel(_wallet, transactionInfo, txRes));
- }
- catch (InsufficientBalanceException)
- {
- var txRes = await Task.Run(() => TransactionHelpers.BuildTransaction(_wallet, transactionInfo.Address, totalMixedCoinsAmount, transactionInfo.Labels, transactionInfo.FeeRate, transactionInfo.Coins, subtractFee: true));
- var dialog = new InsufficientBalanceDialogViewModel(BalanceType.Private, txRes, _wallet.Synchronizer.UsdExchangeRate);
- var result = await NavigateDialogAsync(dialog, NavigationTarget.DialogScreen);
-
- if (result.Result)
- {
- Navigate().To(new OptimisePrivacyViewModel(_wallet, transactionInfo, txRes));
- }
- else
- {
- Navigate().To(new PrivacyControlViewModel(_wallet, transactionInfo));
- }
- }
- }
-
- private async Task BuildTransactionAsPayJoinAsync(TransactionInfo transactionInfo)
- {
- try
- {
- // Do not add the PayJoin client yet, it will be added before broadcasting.
- var txRes = await Task.Run(() => TransactionHelpers.BuildTransaction(_wallet, transactionInfo));
- Navigate().To(new TransactionPreviewViewModel(_wallet, transactionInfo, txRes));
- }
- catch (InsufficientBalanceException)
- {
- await ShowErrorAsync("Transaction Building", "There are not enough private funds to cover the transaction fee", "Wasabi was unable to create your transaction.");
- Navigate().To(new PrivacyControlViewModel(_wallet, transactionInfo));
- }
- }
-
private IPayjoinClient? GetPayjoinClient(string endPoint)
{
if (!string.IsNullOrWhiteSpace(endPoint) &&

dont use a dialog for fee slider page.