initial attempt to recognise and lock in payjoin.
MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Send/SendViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Send/SendViewModel.cs
using System;
using System.Collections.Generic;
+using System.Reactive.Concurrency;
using System.Reactive.Disposables;
+using System.Reactive.Linq;
using System.Windows.Input;
using Avalonia;
+using Avalonia.Threading;
using NBitcoin;
using NBitcoin.Payment;
using ReactiveUI;
@@ -26,6 +29,7 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
[AutoNotify] private string _to;
[AutoNotify] private decimal _amountBtc;
[AutoNotify] private decimal _exchangeRate;
+ [AutoNotify] private bool _isFixedAmount;
private string? _payJoinEndPoint;
public SendViewModel(WalletViewModel walletVm)
@@ -35,14 +39,45 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
ExchangeRate = walletVm.Wallet.Synchronizer.UsdExchangeRate;
+ this.WhenAnyValue(x => x.To)
+ .ObserveOn(RxApp.MainThreadScheduler)
+ .Subscribe(ParseToField);
+
PasteCommand = ReactiveCommand.CreateFromTask(async () =>
{
var text = await Application.Current.Clipboard.GetTextAsync();
- var wallet = walletVm.Wallet;
+ if (!TryParseUrl(text))
+ {
+ To = text;
+ // todo validation errors.
+ }
+ });
+ }
+
+ private void ParseToField(string s)
+ {
+ Dispatcher.UIThread.Post(() => { TryParseUrl(s); });
+ }
+
+ private bool _parsingUrl;
+
+ private bool TryParseUrl(string text)
+ {
+ if (_parsingUrl)
+ {
+ return false;
+ }
+
+ _parsingUrl = true;
+
+ bool result = false;
+
+ var wallet = _owner.Wallet;
if (AddressStringParser.TryParse(text, wallet.Network, out BitcoinUrlBuilder? url))
{
+ result = true;
SmartLabel label = url.Label;
if (!label.IsEmpty)
@@ -58,6 +93,11 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
if (url.Amount is { })
{
AmountBtc = url.Amount.ToDecimal(MoneyUnit.BTC);
+ IsFixedAmount = true;
+ }
+ else
+ {
+ IsFixedAmount = false;
}
if (url.UnknowParameters.TryGetValue("pj", out var endPoint))
@@ -76,7 +116,14 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
_payJoinEndPoint = null;
}
}
- });
+ else
+ {
+ IsFixedAmount = false;
+ }
+
+ _parsingUrl = false;
+
+ return result;
}
protected override void OnNavigatedTo(bool inStack, CompositeDisposable disposables)
@@ -92,6 +139,7 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
public double XAxisCurrentValue { get; set; } = 36;
+
public double XAxisMinValue { get; set; } = 1;
public double XAxisMaxValue { get; set; } = 1008;

MODIFY
WalletWasabi.Fluent/Views/Wallets/Send/SendView.axaml
WalletWasabi.Fluent/Views/Wallets/Send/SendView.axaml
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:i="using:Avalonia.Xaml.Interactivity"
xmlns:behaviors="using:WalletWasabi.Fluent.Behaviors"
xmlns:c="using:WalletWasabi.Fluent.Controls"
xmlns:vm="using:WalletWasabi.Fluent.ViewModels.Wallets.Send"
</StackPanel.Styles>
<DockPanel>
<Label DockPanel.Dock="Left" Content="_To:" Target="toTb" />
- <TextBox x:Name="toTb" MaxLength="250" Text="{Binding To}"
+ <TextBox x:Name="toTb" MaxLength="250" Text="{Binding To, Mode=TwoWay}"
Watermark="(e.g. Bitcoin address or PayJoin URL)">
<TextBox.InnerRightContent>
<Button Classes="plain"
<PathIcon Data="{StaticResource paste_regular}" Width="13" />
</Button>
</TextBox.InnerRightContent>
- <i:Interaction.Behaviors>
- <behaviors:FocusOnAttachedBehavior />
- </i:Interaction.Behaviors>
</TextBox>
</DockPanel>
<DockPanel>
<Label DockPanel.Dock="Left" Content="_Amount:" Target="amountTb" />
- <c:CurrencyEntryBox x:Name="amountTb" AmountBtc="{Binding AmountBtc}" ConversionRate="{Binding ExchangeRate}" ConversionCurrencyCode="USD" />
+ <c:CurrencyEntryBox x:Name="amountTb" IsReadOnly="{Binding IsFixedAmount}" AmountBtc="{Binding AmountBtc}" ConversionRate="{Binding ExchangeRate}" ConversionCurrencyCode="USD" />
</DockPanel>
<DockPanel>

initial attempt to recognise and lock in payjoin.