Privacy Bar - Pocket segments
MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Home/Tiles/PrivacyRing/PrivacyBarItemViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Home/Tiles/PrivacyRing/PrivacyBarItemViewModel.cs
using Avalonia;
using Avalonia.Media;
+using System.Linq;
using WalletWasabi.Blockchain.TransactionOutputs;
using WalletWasabi.Fluent.Helpers;
+using WalletWasabi.Fluent.Models;
using WalletWasabi.Fluent.ViewModels.Wallets.Advanced.WalletCoins;
+using WalletWasabi.Wallets;
namespace WalletWasabi.Fluent.ViewModels.Wallets.Home.Tiles.PrivacyRing;
@@ -24,11 +27,11 @@ public class PrivacyBarItemViewModel : ViewModelBase, IDisposable
};
}
- public PrivacyBarItemViewModel(bool isPrivate, bool isSemiPrivate, bool isNonPrivate, double start, double width)
+ public PrivacyBarItemViewModel(Pocket pocket, Wallet wallet, double start, double width)
{
- IsPrivate = isPrivate;
- IsSemiPrivate = isSemiPrivate;
- IsNonPrivate = isNonPrivate;
+ IsPrivate = pocket.Coins.First().IsPrivate(wallet.KeyManager.AnonScoreTarget);
+ IsSemiPrivate = !IsPrivate && pocket.Coins.First().IsSemiPrivate();
+ IsNonPrivate = !IsPrivate && !IsSemiPrivate;
Data = new RectangleGeometry
{

MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Home/Tiles/PrivacyRing/PrivacyBarViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Home/Tiles/PrivacyRing/PrivacyBarViewModel.cs
using Avalonia;
-using Avalonia.Media;
using DynamicData;
using DynamicData.Binding;
using ReactiveUI;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reactive;
using System.Reactive.Linq;
@@ -16,6 +16,7 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Home.Tiles.PrivacyRing;
public partial class PrivacyBarViewModel : ViewModelBase
{
+ private const int MaximumCoinCount = 100;
private readonly SourceList<PrivacyBarItemViewModel> _itemsSourceList = new();
private IObservable<Unit> _coinsUpdated;
@@ -51,7 +52,11 @@ public partial class PrivacyBarViewModel : ViewModelBase
private void RefreshCoinsList(IEnumerable<Pocket> pockets)
{
- _itemsSourceList.Edit(list =>
+ _itemsSourceList.Edit(list => CreateSegments(list, pockets));
+ }
+
+ [SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "items are disposed of together with _itemsSourceList.")]
+ private void CreateSegments(IExtendedList<PrivacyBarItemViewModel> list, IEnumerable<Pocket> pockets)
{
list.Clear();
@@ -60,10 +65,31 @@ public partial class PrivacyBarViewModel : ViewModelBase
return;
}
+ var coinCount = pockets.SelectMany(x => x.Coins).Count();
+
+ var result = Enumerable.Empty<PrivacyBarItemViewModel>();
+
+ if (coinCount < MaximumCoinCount)
+ {
+ result = CreateCoinSegments(pockets, coinCount);
+ }
+ else
+ {
+ result = CreatePocketSegments(pockets);
+ }
+
+ foreach (var item in result)
+ {
+ list.Add(item);
+ }
+ }
+
+ private IEnumerable<PrivacyBarItemViewModel> CreateCoinSegments(IEnumerable<Pocket> pockets, int coinCount)
+ {
var total = pockets.Sum(x => Math.Abs(x.Amount.ToDecimal(NBitcoin.MoneyUnit.BTC)));
var start = 0.0m;
- var usableWidth = Width - (pockets.SelectMany(x => x.Coins).Count() * 2);
+ var usableWidth = Width - (coinCount * 2);
foreach (var pocket in pockets.OrderByDescending(x => x.Coins.First().HdPubKey.AnonymitySet))
{
@@ -75,21 +101,45 @@ public partial class PrivacyBarViewModel : ViewModelBase
var amount = coin.Amount.ToDecimal(NBitcoin.MoneyUnit.BTC);
var width = Math.Abs((decimal)usableWidth * amount / total);
- // Artificially enlarge UTXOs smaller than 2 px in order to make them visible.
+ // Artificially enlarge segments smaller than 2 px in order to make them visible.
if (width < 2)
{
width++;
margin--;
}
- var item = new PrivacyBarItemViewModel(this, coin, (double)start, (double)width);
-
- list.Add(item);
+ yield return new PrivacyBarItemViewModel(this, coin, (double)start, (double)width);
start += width + margin;
}
}
- });
+ }
+
+ private IEnumerable<PrivacyBarItemViewModel> CreatePocketSegments(IEnumerable<Pocket> pockets)
+ {
+ var total = pockets.Sum(x => Math.Abs(x.Amount.ToDecimal(NBitcoin.MoneyUnit.BTC)));
+ var start = 0.0m;
+
+ var usableWidth = Width - (pockets.Count() * 2);
+
+ foreach (var pocket in pockets.OrderByDescending(x => x.Coins.First().HdPubKey.AnonymitySet))
+ {
+ var margin = 2;
+ var amount = pocket.Amount.ToDecimal(NBitcoin.MoneyUnit.BTC);
+
+ var width = Math.Abs((decimal)usableWidth * amount / total);
+
+ // Artificially enlarge segments smaller than 2 px in order to make them visible.
+ if (width < 2)
+ {
+ width++;
+ margin--;
+ }
+
+ yield return new PrivacyBarItemViewModel(pocket, Wallet, (double)start, (double)width);
+
+ start += width + margin;
+ }
}
public void Dispose()

Privacy Bar - Pocket segments