add behavior to fade pockets
ADD
WalletWasabi.Fluent/Behaviors/FadePocketLabelsBehavior.cs
+using System.Collections.Generic;
+using System.Linq;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+using System.Threading.Tasks;
+using Avalonia;
+using Avalonia.VisualTree;
+using ReactiveUI;
+using WalletWasabi.Blockchain.Analysis.Clustering;
+using WalletWasabi.Fluent.Controls;
+using WalletWasabi.Fluent.ViewModels.Wallets.Send;
+
+namespace WalletWasabi.Fluent.Behaviors;
+
+public class FadePocketLabelsBehavior : AttachedToVisualTreeBehavior<TagsBox>
+{
+ private TagControl[] _currentTags = Array.Empty<TagControl>();
+ private CompositeDisposable? _disposable;
+ private bool _isRunning = true;
+
+ public static readonly StyledProperty<List<PocketViewModel>> PocketsProperty =
+ AvaloniaProperty.Register<FadePocketLabelsBehavior, List<PocketViewModel>>(nameof(Pockets));
+
+ public List<PocketViewModel> Pockets
+ {
+ get => GetValue(PocketsProperty);
+ set => SetValue(PocketsProperty, value);
+ }
+
+ protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
+ {
+ if (AssociatedObject is null)
+ {
+ return;
+ }
+
+ RxApp.MainThreadScheduler.Schedule(async () =>
+ {
+ while (_isRunning)
+ {
+ var tagItems = AssociatedObject.GetVisualDescendants().OfType<TagControl>().ToArray();
+
+ if (tagItems.Any() && tagItems.Length != _currentTags.Length)
+ {
+ _currentTags = tagItems;
+ _disposable?.Dispose();
+ _disposable = new CompositeDisposable();
+
+ foreach (var tagControl in _currentTags)
+ {
+ tagControl
+ .WhenAnyValue(x => x.IsPointerOver)
+ .Subscribe(x =>
+ {
+ var tagControlLabel = tagControl.DataContext;
+ var affectedPockets = Pockets.Where(x => x.Labels.Contains(tagControlLabel));
+ var labelsToFade = SmartLabel.Merge(affectedPockets.Select(x => x.Labels));
+ var tagsToFade = _currentTags.Where(x => labelsToFade.Contains(x.DataContext));
+
+ foreach (var control in tagsToFade)
+ {
+ control.Opacity = x ? 0.3 : 1;
+ }
+ })
+ .DisposeWith(_disposable);
+ }
+ }
+
+ await Task.Delay(500);
+ }
+ });
+ }
+
+ protected override void OnDetaching()
+ {
+ base.OnDetaching();
+
+ _isRunning = false;
+ }
+}

MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Send/PrivacyControlViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Send/PrivacyControlViewModel.cs
@@ -18,10 +18,11 @@ public partial class PrivacyControlViewModel : DialogViewModelBase<IEnumerable<S
{
private readonly Wallet _wallet;
private readonly TransactionInfo _transactionInfo;
-
private readonly bool _isSilent;
- private List<PocketViewModel> _usedPockets;
+ [AutoNotify] private List<PocketViewModel> _usedPockets;
+
+ // private List<PocketViewModel> _usedPockets;
private bool _isUpdating;
public PrivacyControlViewModel(Wallet wallet, TransactionInfo transactionInfo, bool isSilent)
@@ -50,7 +51,7 @@ public partial class PrivacyControlViewModel : DialogViewModelBase<IEnumerable<S
return;
}
- var pocketsToRemove = _usedPockets
+ var pocketsToRemove = UsedPockets
.Where(x => x.Labels.Any(y => !Labels.Contains(y) && x.Labels.Any(y => !MustHaveLabels.Contains(y))))
.ToArray();
@@ -58,7 +59,7 @@ public partial class PrivacyControlViewModel : DialogViewModelBase<IEnumerable<S
{
_isUpdating = true;
- _usedPockets = _usedPockets.Except(pocketsToRemove).ToList();
+ UsedPockets = UsedPockets.Except(pocketsToRemove).ToList();
Labels.Clear();
UpdateLabels();
@@ -73,16 +74,16 @@ public partial class PrivacyControlViewModel : DialogViewModelBase<IEnumerable<S
private void Complete()
{
- Close(DialogResultKind.Normal, _usedPockets.SelectMany(x => x.Coins).ToArray());
+ Close(DialogResultKind.Normal, UsedPockets.SelectMany(x => x.Coins).ToArray());
}
private void UpdateLabels()
{
- foreach (var label in SmartLabel.Merge(_usedPockets.Select(x => x.Labels)))
+ foreach (var label in SmartLabel.Merge(UsedPockets.Select(x => x.Labels)))
{
- var coinsWithSameLabel = _usedPockets.Where(x => x.Labels.Contains(label));
+ var coinsWithSameLabel = UsedPockets.Where(x => x.Labels.Contains(label));
- if (_usedPockets.Sum(x => x.Coins.TotalAmount()) - coinsWithSameLabel.Sum(x => x.Coins.TotalAmount()) >= _transactionInfo.Amount)
+ if (UsedPockets.Sum(x => x.Coins.TotalAmount()) - coinsWithSameLabel.Sum(x => x.Coins.TotalAmount()) >= _transactionInfo.Amount)
{
Labels.Add(label);
}
@@ -104,15 +105,15 @@ public partial class PrivacyControlViewModel : DialogViewModelBase<IEnumerable<S
_isUpdating = false;
}
- if (_usedPockets.Count == 1)
+ if (UsedPockets.Count == 1)
{
Complete();
}
else if (_isSilent &&
- _usedPockets.FirstOrDefault(x => x.Labels == CoinPocketHelper.PrivateFundsText) is { } privatePocket &&
+ UsedPockets.FirstOrDefault(x => x.Labels == CoinPocketHelper.PrivateFundsText) is { } privatePocket &&
privatePocket.Coins.TotalAmount() >= _transactionInfo.Amount)
{
- _usedPockets = _usedPockets.Where(x => x.Labels == CoinPocketHelper.PrivateFundsText).ToList();
+ UsedPockets = UsedPockets.Where(x => x.Labels == CoinPocketHelper.PrivateFundsText).ToList();
Complete();
}
}

MODIFY
WalletWasabi.Fluent/Views/Wallets/Send/PrivacyControlView.axaml
WalletWasabi.Fluent/Views/Wallets/Send/PrivacyControlView.axaml
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:c="using:WalletWasabi.Fluent.Controls"
xmlns:vm="using:WalletWasabi.Fluent.ViewModels.Wallets.Send"
+ xmlns:behaviors="clr-namespace:WalletWasabi.Fluent.Behaviors"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:DataType="vm:PrivacyControlViewModel"
x:CompileBindings="True"
<DockPanel>
<c:TagsBox Items="{Binding MustHaveLabels}" IsReadOnly="True" DockPanel.Dock="Bottom" />
<TextBlock Text="Must have:" DockPanel.Dock="Bottom" />
- <c:TagsBox Items="{Binding Labels}" EnableDelete="True" />
+ <c:TagsBox Items="{Binding Labels}" EnableDelete="True">
+ <Interaction.Behaviors>
+ <behaviors:FadePocketLabelsBehavior Pockets="{Binding UsedPockets}" />
+ </Interaction.Behaviors>
+ </c:TagsBox>
</DockPanel>
</c:ContentArea>
</UserControl>

add behavior to fade pockets