Add suggested labels to send
MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Labels/SuggestionLabelsViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Labels/SuggestionLabelsViewModel.cs
@@ -15,9 +15,9 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Labels
{
private readonly SourceList<SuggestionLabelViewModel> _suggestionLabels;
private readonly ObservableCollectionExtended<SuggestionLabelViewModel> _suggestionLabelResults;
+ private readonly ObservableCollectionExtended<string> _suggestions;
private readonly ObservableCollectionExtended<string> _labels;
private Action<string>? _addTag;
- [AutoNotify] private HashSet<string> _suggestions;
public SuggestionLabelsViewModel()
{
@@ -33,10 +33,9 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Labels
.OrderByDescending(x => x.Count)
.ToList();
- _suggestions = mostUsedLabels.Select(x => x.Label).ToHashSet();
-
_suggestionLabels = new SourceList<SuggestionLabelViewModel>();
_suggestionLabelResults = new ObservableCollectionExtended<SuggestionLabelViewModel>();
+ _suggestions = new ObservableCollectionExtended<string>();
_suggestionLabels.AddRange(
mostUsedLabels.Select(x => new SuggestionLabelViewModel(x.Label, x.Count, label => _addTag?.Invoke(label))));
@@ -54,11 +53,22 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Labels
.Bind(_suggestionLabelResults)
.Subscribe();
+ _suggestionLabels
+ .Connect()
+ .Filter(suggestionLabelsFilter)
+ .Sort(SortExpressionComparer<SuggestionLabelViewModel>.Descending(x => x.Count))
+ .Transform(x => x.Label)
+ .ObserveOn(RxApp.MainThreadScheduler)
+ .Bind(_suggestions)
+ .Subscribe();
+
SetAddTag = (addTag) => _addTag = addTag;
}
public ObservableCollection<SuggestionLabelViewModel> SuggestionLabelResults => _suggestionLabelResults;
+ public ObservableCollection<string> Suggestions => _suggestions;
+
public ObservableCollection<string> Labels => _labels;
public Action<Action<string>>? SetAddTag { get; }

MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Receive/ReceiveViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Receive/ReceiveViewModel.cs
@@ -61,7 +61,7 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Receive
private void OnShowExistingAddresses()
{
- Navigate().To(new ReceiveAddressesViewModel(_wallet, _suggestionLabels.Suggestions));
+ Navigate().To(new ReceiveAddressesViewModel(_wallet, _suggestionLabels.Suggestions.ToHashSet()));
}
protected override void OnNavigatedTo(bool isInHistory, CompositeDisposable disposable)

MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Send/SendViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Send/SendViewModel.cs
@@ -23,6 +23,7 @@ using WalletWasabi.Fluent.ViewModels.Dialogs;
using WalletWasabi.Fluent.ViewModels.Dialogs.Base;
using WalletWasabi.Fluent.ViewModels.NavBar;
using WalletWasabi.Fluent.ViewModels.Navigation;
+using WalletWasabi.Fluent.ViewModels.Wallets.Labels;
using WalletWasabi.Logging;
using WalletWasabi.Models;
using WalletWasabi.Tor.Http;
@@ -51,9 +52,9 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
[AutoNotify] private decimal _exchangeRate;
[AutoNotify] private bool _isFixedAmount;
[AutoNotify] private ObservableCollection<string> _priorLabels;
- [AutoNotify] private ObservableCollection<string> _labels;
[AutoNotify] private bool _isPayJoin;
[AutoNotify] private string? _payJoinEndPoint;
+ [AutoNotify(SetterModifier = AccessModifier.Private)] private SuggestionLabelsViewModel _suggestionLabels;
private bool _parsingUrl;
@@ -62,7 +63,7 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
_to = "";
_wallet = wallet;
_transactionInfo = new TransactionInfo();
- _labels = new ObservableCollection<string>();
+ _suggestionLabels = new SuggestionLabelsViewModel();
ExchangeRate = _wallet.Synchronizer.UsdExchangeRate;
PriorLabels = new();
@@ -94,17 +95,17 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
}
});
- Labels.ToObservableChangeSet().Subscribe(x => _transactionInfo.UserLabels = new SmartLabel(_labels.ToArray()));
+ _suggestionLabels.Labels.ToObservableChangeSet().Subscribe(x => _transactionInfo.UserLabels = new SmartLabel(_suggestionLabels.Labels.ToArray()));
PasteCommand = ReactiveCommand.CreateFromTask(async () => await OnPasteAsync());
AutoPasteCommand = ReactiveCommand.CreateFromTask(async () => await OnAutoPasteAsync());
var nextCommandCanExecute =
- this.WhenAnyValue(x => x.Labels, x => x.AmountBtc, x => x.To).Select(_ => Unit.Default)
- .Merge(Observable.FromEventPattern(Labels, nameof(Labels.CollectionChanged)).Select(_ => Unit.Default))
+ this.WhenAnyValue(x => x.SuggestionLabels.Labels, x => x.AmountBtc, x => x.To).Select(_ => Unit.Default)
+ .Merge(Observable.FromEventPattern(_suggestionLabels.Labels, nameof(_suggestionLabels.Labels.CollectionChanged)).Select(_ => Unit.Default))
.Select(_ =>
{
- var allFilled = !string.IsNullOrEmpty(To) && AmountBtc > 0 && Labels.Any();
+ var allFilled = !string.IsNullOrEmpty(To) && AmountBtc > 0 && _suggestionLabels.Labels.Any();
var hasError = Validations.Any;
return allFilled && !hasError;
@@ -232,11 +233,11 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
if (!label.IsEmpty)
{
- Labels.Clear();
+ _suggestionLabels.Labels.Clear();
foreach (var labelString in label.Labels)
{
- Labels.Add(labelString);
+ _suggestionLabels.Labels.Add(labelString);
}
}
@@ -280,7 +281,7 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
{
To = "";
AmountBtc = 0;
- Labels.Clear();
+ _suggestionLabels.Labels.Clear();
ClearValidations();
}
@@ -289,24 +290,9 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
.Subscribe(x => ExchangeRate = x)
.DisposeWith(disposables);
- _wallet.TransactionProcessor.WhenAnyValue(x => x.Coins).Select(_ => Unit.Default)
- .Merge(this.WhenAnyValue(x => x.Labels.Count).Select(_ => Unit.Default))
- .ObserveOn(RxApp.MainThreadScheduler)
- .Subscribe(_ => UpdateSuggestedLabels())
- .DisposeWith(disposables);
-
RxApp.MainThreadScheduler.Schedule(async () => await OnAutoPasteAsync());
base.OnNavigatedTo(inHistory, disposables);
}
-
- private void UpdateSuggestedLabels()
- {
- var enteredLabels = Labels;
- var allLabels = WalletHelpers.GetLabels();
- var newSuggestedLabels = allLabels.Except(enteredLabels).Distinct();
-
- PriorLabels = new ObservableCollection<string>(newSuggestedLabels);
- }
}
}

MODIFY
WalletWasabi.Fluent/Views/Wallets/Send/SendView.axaml
WalletWasabi.Fluent/Views/Wallets/Send/SendView.axaml
xmlns:behaviors="using:WalletWasabi.Fluent.Behaviors"
xmlns:c="using:WalletWasabi.Fluent.Controls"
xmlns:vm="using:WalletWasabi.Fluent.ViewModels.Wallets.Send"
+ xmlns:labels="clr-namespace:WalletWasabi.Fluent.Views.Wallets.Labels"
mc:Ignorable="d"
x:DataType="vm:SendViewModel"
x:CompileBindings="True"
</DockPanel>
</DockPanel>
<!-- Labels -->
- <DockPanel DockPanel.Dock="Top" Margin="0,0,0,10">
+ <DockPanel DockPanel.Dock="Top"
+ VerticalAlignment="Top"
+ Margin="0,0,0,10">
<Label DockPanel.Dock="Left" Content="_Labels:" Target="LabelTagBox" />
- <c:TagsBox x:Name="LabelTagBox" VerticalAlignment="Top"
+ <labels:SuggestionLabelsView DockPanel.Dock="Bottom"
+ Margin="0,10,0,0"
+ DataContext="{Binding SuggestionLabels}"/>
+ <c:TagsBox x:Name="LabelTagBox"
+ DataContext="{Binding SuggestionLabels}"
+ SetAddTagAction="{Binding SetAddTag}"
+ VerticalAlignment="Top"
Watermark="{StaticResource LabelsWatermarkText}"
TagSeparator=","
SuggestionsAreCaseSensitive="True"
RestrictInputToSuggestions="False"
Items="{Binding Labels}"
- Suggestions="{Binding PriorLabels}" />
+ Suggestions="{Binding Suggestions}" />
</DockPanel>
</DockPanel>
</c:ContentArea>

Add suggested labels to send