Use ICoinsView instead of CoinsRegistry
MODIFY
WalletWasabi.Gui/Controls/WalletExplorer/CoinListViewModel.cs
WalletWasabi.Gui/Controls/WalletExplorer/CoinListViewModel.cs
@@ -398,50 +398,26 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(x => IsAnyCoinSelected = x is null ? false : x > Money.Zero);
- Observable.FromEventPattern<NotifyCollectionChangedEventArgs>(Global.WalletService.Coins, nameof(Global.WalletService.Coins.CollectionChanged))
+ Observable.FromEventPattern<SmartCoin>(Global.WalletService.TransactionProcessor, nameof(Global.WalletService.TransactionProcessor.CoinReceived))
.ObserveOn(RxApp.MainThreadScheduler)
- .Subscribe(x =>
- {
- var e = x.EventArgs;
- try
- {
- switch (e.Action)
- {
- case NotifyCollectionChangedAction.Add:
- var added = new CoinsView(e.NewItems.Cast<SmartCoin>());
- foreach (SmartCoin c in added.UnSpent())
+ .Subscribe(coin =>
{
- var newCoinVm = new CoinViewModel(this, c);
+ var newCoinVm = new CoinViewModel(this, coin.EventArgs);
newCoinVm.SubscribeEvents();
RootList.Add(newCoinVm);
- }
- break;
+ }).DisposeWith(Disposables);
- case NotifyCollectionChangedAction.Remove:
- var removed = new CoinsView(e.OldItems.Cast<SmartCoin>());
- foreach (var c in removed)
+ Observable.FromEventPattern<SmartCoin>(Global.WalletService.TransactionProcessor, nameof(Global.WalletService.TransactionProcessor.CoinSpent))
+ .ObserveOn(RxApp.MainThreadScheduler)
+ .Subscribe(coin =>
{
- CoinViewModel toRemove = RootList.Items.FirstOrDefault(cvm => cvm.Model == c);
+ CoinViewModel toRemove = RootList.Items.FirstOrDefault(cvm => cvm.Model == coin.EventArgs);
if (toRemove != default)
{
toRemove.IsSelected = false;
RootList.Remove(toRemove);
toRemove.UnsubscribeEvents();
}
- }
- break;
-
- case NotifyCollectionChangedAction.Reset:
- {
- ClearRootList();
- }
- break;
- }
- }
- catch (Exception ex)
- {
- Logger.LogDebug(ex);
- }
}).DisposeWith(Disposables);
SetSelections();

MODIFY
WalletWasabi.Gui/Controls/WalletExplorer/HistoryTabViewModel.cs
WalletWasabi.Gui/Controls/WalletExplorer/HistoryTabViewModel.cs
@@ -63,8 +63,7 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
Disposables = Disposables is null ? new CompositeDisposable() : throw new NotSupportedException($"Cannot open {GetType().Name} before closing it.");
- Observable.FromEventPattern(Global.WalletService.Coins, nameof(Global.WalletService.Coins.CollectionChanged))
- .Merge(Observable.FromEventPattern(Global.WalletService, nameof(Global.WalletService.NewBlockProcessed)))
+ Observable.FromEventPattern(Global.WalletService, nameof(Global.WalletService.NewBlockProcessed))
.Merge(Observable.FromEventPattern(Global.WalletService.TransactionProcessor, nameof(Global.WalletService.TransactionProcessor.CoinSpent)))
.Merge(Observable.FromEventPattern(Global.WalletService.TransactionProcessor, nameof(Global.WalletService.TransactionProcessor.SpenderConfirmed)))
.Throttle(TimeSpan.FromSeconds(5))

MODIFY
WalletWasabi.Gui/Controls/WalletExplorer/ReceiveTabViewModel.cs
WalletWasabi.Gui/Controls/WalletExplorer/ReceiveTabViewModel.cs
@@ -162,8 +162,8 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
Disposables = Disposables is null ? new CompositeDisposable() : throw new NotSupportedException($"Cannot open {GetType().Name} before closing it.");
- Observable.FromEventPattern(Global.WalletService.Coins,
- nameof(Global.WalletService.Coins.CollectionChanged))
+ Observable.FromEventPattern(Global.WalletService.TransactionProcessor,
+ nameof(Global.WalletService.TransactionProcessor.CoinReceived))
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(_ => InitializeAddresses())
.DisposeWith(Disposables);

MODIFY
WalletWasabi.Gui/Controls/WalletExplorer/WalletViewModel.cs
WalletWasabi.Gui/Controls/WalletExplorer/WalletViewModel.cs
@@ -95,7 +95,7 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
var observed = Observable.Merge(
Global.UiConfig.WhenAnyValue(x => x.LurkingWifeMode).Select(_ => Unit.Default),
- Observable.FromEventPattern(Global.WalletService.Coins, nameof(Global.WalletService.Coins.CollectionChanged)).Select(_ => Unit.Default),
+ Observable.FromEventPattern(Global.WalletService.TransactionProcessor, nameof(Global.WalletService.TransactionProcessor.CoinReceived)).Select(_ => Unit.Default),
Observable.FromEventPattern(Global.WalletService.TransactionProcessor, nameof(Global.WalletService.TransactionProcessor.CoinSpent)).Select(_ => Unit.Default))
.Throttle(TimeSpan.FromSeconds(1))
.ObserveOn(RxApp.MainThreadScheduler);

MODIFY
WalletWasabi.Gui/Global.cs
WalletWasabi.Gui/Global.cs
@@ -421,7 +421,7 @@ namespace WalletWasabi.Gui
Logger.LogInfo($"{nameof(WalletService)} started.");
token.ThrowIfCancellationRequested();
- WalletService.Coins.CollectionChanged += Coins_CollectionChanged;
+ WalletService.TransactionProcessor.CoinReceived += CoinReceived;
}
_cancelWalletServiceInitialization = null; // Must make it null explicitly, because dispose won't make it null.
}
@@ -488,28 +488,20 @@ namespace WalletWasabi.Gui
return keyManager;
}
- private void Coins_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
+ private void CoinReceived(object sender, SmartCoin coin)
{
try
{
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || UiConfig?.LurkingWifeMode is true)
+ if (coin.HdPubKey.IsInternal)
{
return;
}
- if (e.Action == NotifyCollectionChangedAction.Add)
- {
- foreach (SmartCoin coin in e.NewItems)
- {
- //if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && RuntimeInformation.OSDescription.StartsWith("Microsoft Windows 10"))
- //{
- // // It's harder than you'd think. Maybe the best would be to wait for .NET Core 3 for WPF things on Windows?
- //}
- // else
- if (coin.HdPubKey.IsInternal)
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || UiConfig?.LurkingWifeMode is true)
{
- continue;
+ return;
}
+
string amountString = coin.Amount.ToString(false, true);
using var process = Process.Start(new ProcessStartInfo
{
@@ -520,8 +512,6 @@ namespace WalletWasabi.Gui
CreateNoWindow = true
});
}
- }
- }
catch (Exception ex)
{
Logger.LogWarning(ex);
@@ -532,7 +522,7 @@ namespace WalletWasabi.Gui
{
if (WalletService != null)
{
- WalletService.Coins.CollectionChanged -= Coins_CollectionChanged;
+ WalletService.TransactionProcessor.CoinReceived -= CoinReceived;
}
try
{

MODIFY
WalletWasabi/Services/WalletService.cs
WalletWasabi/Services/WalletService.cs
@@ -71,7 +71,7 @@ namespace WalletWasabi.Services
public ConcurrentDictionary<uint256, (Height height, DateTimeOffset dateTime)> ProcessedBlocks { get; }
- public CoinsRegistry Coins { get; }
+ public ICoinsView Coins { get; }
public event EventHandler<FilterModel> NewFilterProcessed;
@@ -140,6 +140,7 @@ namespace WalletWasabi.Services
private void TransactionProcessor_CoinSpent(object sender, SmartCoin spentCoin)
{
ChaumianClient.ExposedLinks.TryRemove(spentCoin.GetTxoRef(), out _);
+ RefreshCoinHistories();
}
private async void TransactionProcessor_CoinReceivedAsync(object sender, SmartCoin newCoin)
@@ -158,10 +159,6 @@ namespace WalletWasabi.Services
Logger.LogError(ex);
}
}
- }
-
- private void Coins_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
- {
RefreshCoinHistories();
}
@@ -260,7 +257,6 @@ namespace WalletWasabi.Services
await LoadWalletStateAsync(cancel);
await LoadDummyMempoolAsync();
}
- Coins.CollectionChanged += Coins_CollectionChanged;
RefreshCoinHistories();
}
@@ -1077,7 +1073,6 @@ namespace WalletWasabi.Services
BitcoinStore.IndexStore.NewFilter -= IndexDownloader_NewFilterAsync;
BitcoinStore.IndexStore.Reorged -= IndexDownloader_ReorgedAsync;
BitcoinStore.MempoolService.TransactionReceived -= Mempool_TransactionReceived;
- Coins.CollectionChanged -= Coins_CollectionChanged;
TransactionProcessor.CoinSpent -= TransactionProcessor_CoinSpent;
TransactionProcessor.CoinReceived -= TransactionProcessor_CoinReceivedAsync;

Use ICoinsView instead of CoinsRegistry