ensure wallets and tiles get "activated" by navigation manager.
ADD
WalletWasabi.Fluent/ViewModels/ActivatableViewModel.cs
+using System.Reactive.Disposables;
+
+namespace WalletWasabi.Fluent.ViewModels
+{
+ public class ActivatableViewModel : ViewModelBase
+ {
+ protected virtual void OnActivated(CompositeDisposable disposables)
+ {
+
+ }
+
+ public void Activate(CompositeDisposable disposables)
+ {
+ OnActivated(disposables);
+ }
+ }
+}
\ No newline at end of file

MODIFY
WalletWasabi.Fluent/ViewModels/WalletManagerViewModel.cs
WalletWasabi.Fluent/ViewModels/WalletManagerViewModel.cs
@@ -195,8 +195,6 @@ namespace WalletWasabi.Fluent.ViewModels
{
var isLoggedIn = walletViewModel.Wallet.IsLoggedIn;
- walletViewModel.Dispose();
-
_wallets.Remove(walletViewModel);
if (isLoggedIn)

MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Home/History/HistoryViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Home/History/HistoryViewModel.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.ObjectModel;
using System.Reactive;
using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Avalonia.Threading;
@@ -18,42 +19,32 @@ using WalletWasabi.Wallets;
namespace WalletWasabi.Fluent.ViewModels.Wallets.Home.History
{
- [NavigationMetaData(Title = "Transaction History")]
- public partial class HistoryViewModel : RoutableViewModel
+ public partial class HistoryViewModel : ActivatableViewModel
{
private readonly Wallet _wallet;
private readonly BitcoinStore _bitcoinStore;
- private readonly ReadOnlyObservableCollection<HistoryItemViewModel> _transactions;
- private readonly ReadOnlyObservableCollection<HistoryItemViewModel> _unfilteredTransactions;
+ private ObservableCollectionExtended<HistoryItemViewModel> _transactions;
+ private ObservableCollectionExtended<HistoryItemViewModel> _unfilteredTransactions;
private readonly SourceList<HistoryItemViewModel> _transactionSourceList;
+ private readonly IObservable<Unit> _updateTrigger;
[AutoNotify] private bool _showCoinJoin;
[AutoNotify] private HistoryItemViewModel? _selectedItem;
- public HistoryViewModel(Wallet wallet, UiConfig uiConfig, IObservable<Unit> updateTrigger)
+ public HistoryViewModel(INavigationStack<RoutableViewModel> dialogNavigationStack, Wallet wallet, UiConfig uiConfig, IObservable<Unit> updateTrigger)
{
+ _updateTrigger = updateTrigger;
_wallet = wallet;
_bitcoinStore = wallet.BitcoinStore;
_showCoinJoin = uiConfig.ShowCoinJoinInHistory;
_transactionSourceList = new SourceList<HistoryItemViewModel>();
-
- var coinJoinFilter = this.WhenAnyValue(x => x.ShowCoinJoin).Select(CoinJoinFilter);
-
- _transactionSourceList
- .Connect()
- .ObserveOn(RxApp.MainThreadScheduler)
- .Sort(SortExpressionComparer<HistoryItemViewModel>.Descending(x => x.OrderIndex))
- .Bind(out _unfilteredTransactions)
- .Filter(coinJoinFilter)
- .Bind(out _transactions)
- .Subscribe();
+ _transactions = new ObservableCollectionExtended<HistoryItemViewModel>();
+ _unfilteredTransactions = new ObservableCollectionExtended<HistoryItemViewModel>();
this.WhenAnyValue(x => x.ShowCoinJoin)
- .ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(showCoinJoin => uiConfig.ShowCoinJoinInHistory = showCoinJoin);
this.WhenAnyValue(x => x.SelectedItem)
- .ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(async selectedItem =>
{
if (selectedItem is null)
@@ -61,7 +52,7 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Home.History
return;
}
- Navigate(NavigationTarget.DialogScreen).To(new TransactionDetailsViewModel(selectedItem.TransactionSummary, _bitcoinStore, wallet, updateTrigger));
+ dialogNavigationStack.To(new TransactionDetailsViewModel(selectedItem.TransactionSummary, _bitcoinStore, wallet, updateTrigger));
Dispatcher.UIThread.Post(() =>
{
@@ -69,15 +60,36 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Home.History
});
});
- updateTrigger.Subscribe(async _ => await UpdateAsync());
RxApp.MainThreadScheduler.Schedule(async () => await UpdateAsync());
}
- public ReadOnlyObservableCollection<HistoryItemViewModel> UnfilteredTransactions => _unfilteredTransactions;
+ protected override void OnActivated(CompositeDisposable disposables)
+ {
+ base.OnActivated(disposables);
+
+ var coinJoinFilter = this.WhenAnyValue(x => x.ShowCoinJoin)
+ .Select(CoinJoinFilter);
+
+ _transactionSourceList
+ .Connect()
+ .ObserveOn(RxApp.MainThreadScheduler)
+ .Sort(SortExpressionComparer<HistoryItemViewModel>.Descending(x => x.OrderIndex))
+ .Bind(_unfilteredTransactions)
+ .Filter(coinJoinFilter)
+ .Bind(_transactions)
+ .Subscribe()
+ .DisposeWith(disposables);
+
+ _updateTrigger
+ .Subscribe(async _ => await UpdateAsync())
+ .DisposeWith(disposables);
+ }
+
+ public ObservableCollection<HistoryItemViewModel> UnfilteredTransactions => _unfilteredTransactions;
- public ReadOnlyObservableCollection<HistoryItemViewModel> Transactions => _transactions;
+ public ObservableCollection<HistoryItemViewModel> Transactions => _transactions;
- private Func<HistoryItemViewModel, bool> CoinJoinFilter(bool showCoinJoin)
+ private static Func<HistoryItemViewModel, bool> CoinJoinFilter(bool showCoinJoin)
{
return item =>
{
@@ -90,7 +102,7 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Home.History
};
}
- public async Task UpdateAsync()
+ private async Task UpdateAsync()
{
try
{

MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Home/Tiles/TileViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Home/Tiles/TileViewModel.cs
@@ -2,16 +2,7 @@ using System.Reactive.Disposables;
namespace WalletWasabi.Fluent.ViewModels.Wallets.Home.Tiles
{
- public abstract class TileViewModel : ViewModelBase
+ public abstract class TileViewModel : ActivatableViewModel
{
- protected virtual void OnActivated(CompositeDisposable disposables)
- {
-
- }
-
- public void Activate(CompositeDisposable disposables)
- {
- OnActivated(disposables);
- }
}
}
\ No newline at end of file

MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Home/Tiles/WalletBalanceChartTileViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Home/Tiles/WalletBalanceChartTileViewModel.cs
@@ -14,7 +14,7 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Home.Tiles
{
public partial class WalletBalanceChartTileViewModel : TileViewModel
{
- private readonly ReadOnlyObservableCollection<HistoryItemViewModel> _history;
+ private readonly ObservableCollection<HistoryItemViewModel> _history;
[AutoNotify] private ObservableCollection<double> _yValues;
[AutoNotify] private ObservableCollection<double> _xValues;
[AutoNotify] private double? _xMinimum;
@@ -22,7 +22,7 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Home.Tiles
[AutoNotify] private List<string>? _xLabels;
private TimePeriodOption _currentTimePeriod = TimePeriodOption.ThreeMonths;
- public WalletBalanceChartTileViewModel(ReadOnlyObservableCollection<HistoryItemViewModel> history)
+ public WalletBalanceChartTileViewModel(ObservableCollection<HistoryItemViewModel> history)
{
_history = history;
_yValues = new ObservableCollection<double>();

MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/WalletViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/WalletViewModel.cs
@@ -13,7 +13,7 @@ using WalletWasabi.Wallets;
namespace WalletWasabi.Fluent.ViewModels.Wallets
{
- public partial class WalletViewModel : WalletViewModelBase
+ public class WalletViewModel : WalletViewModelBase
{
private readonly List<TileViewModel> _tiles;
@@ -24,14 +24,17 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets
: throw new NotSupportedException($"Cannot open {GetType().Name} before closing it.");
var balanceChanged =
- Observable.FromEventPattern(Wallet.TransactionProcessor, nameof(Wallet.TransactionProcessor.WalletRelevantTransactionProcessed)).Select(_ => Unit.Default)
+ Observable.FromEventPattern(Wallet.TransactionProcessor,
+ nameof(Wallet.TransactionProcessor.WalletRelevantTransactionProcessed))
+ .Select(_ => Unit.Default)
.Throttle(TimeSpan.FromSeconds(0.1))
- .Merge(Observable.FromEventPattern(Wallet, nameof(Wallet.NewFilterProcessed)).Select(_ => Unit.Default))
+ .Merge(Observable.FromEventPattern(Wallet, nameof(Wallet.NewFilterProcessed))
+ .Select(_ => Unit.Default))
.Merge(uiConfig.WhenAnyValue(x => x.PrivacyMode).Select(_ => Unit.Default))
.Merge(Wallet.Synchronizer.WhenAnyValue(x => x.UsdExchangeRate).Select(_ => Unit.Default))
.ObserveOn(RxApp.MainThreadScheduler);
- History = new HistoryViewModel(wallet, uiConfig, balanceChanged);
+ History = new HistoryViewModel(Navigate(NavigationTarget.DialogScreen), wallet, uiConfig, balanceChanged);
BalanceTile = new WalletBalanceTileViewModel(wallet, balanceChanged);
BalanceChartTile = new WalletBalanceChartTileViewModel(History.UnfilteredTransactions);
@@ -57,6 +60,8 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets
{
tile.Activate(disposables);
}
+
+ History.Activate(disposables);
}
private CompositeDisposable Disposables { get; set; }

MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/WalletViewModelBase.cs
WalletWasabi.Fluent/ViewModels/Wallets/WalletViewModelBase.cs
@@ -10,20 +10,19 @@ using WalletWasabi.Wallets;
namespace WalletWasabi.Fluent.ViewModels.Wallets
{
- public abstract partial class WalletViewModelBase : NavBarItemViewModel, IComparable<WalletViewModelBase>, IDisposable
+ public abstract partial class WalletViewModelBase : NavBarItemViewModel, IComparable<WalletViewModelBase>
{
[AutoNotify] private string _titleTip;
- [AutoNotify(SetterModifier = AccessModifier.Private)] private WalletState _walletState;
- private CompositeDisposable? _disposables;
- private bool _disposedValue;
+
+ [AutoNotify(SetterModifier = AccessModifier.Private)]
+ private WalletState _walletState;
+
private string _title;
protected WalletViewModelBase(Wallet wallet)
{
Wallet = Guard.NotNull(nameof(wallet), wallet);
- _disposables = new CompositeDisposable();
-
_title = WalletName;
var isHardware = Wallet.KeyManager.IsHardwareWallet;
var isWatch = Wallet.KeyManager.IsWatchOnly;
@@ -31,12 +30,17 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets
WalletState = wallet.State;
- Observable.FromEventPattern<WalletState>(wallet, nameof(wallet.StateChanged))
+ OpenCommand = ReactiveCommand.Create(() => Navigate().To(this, NavigationMode.Clear));
+ }
+
+ protected override void OnNavigatedTo(bool isInHistory, CompositeDisposable disposables)
+ {
+ base.OnNavigatedTo(isInHistory, disposables);
+
+ Observable.FromEventPattern<WalletState>(Wallet, nameof(Wallet.StateChanged))
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(x => WalletState = x.EventArgs)
- .DisposeWith(_disposables);
-
- OpenCommand = ReactiveCommand.Create(() => Navigate().To(this, NavigationMode.Clear));
+ .DisposeWith(disposables);
}
public override string Title
@@ -65,30 +69,5 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets
}
public override string ToString() => WalletName;
-
- #region IDisposable Support
-
- protected virtual void Dispose(bool disposing)
- {
- if (!_disposedValue)
- {
- if (disposing)
- {
- _disposables?.Dispose();
- _disposables = null;
- }
-
- _disposedValue = true;
- }
- }
-
- // This code added to correctly implement the disposable pattern.
- public void Dispose()
- {
- // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
- Dispose(true);
- }
-
- #endregion IDisposable Support
}
}
\ No newline at end of file

MODIFY
WalletWasabi.Fluent/Views/Wallets/Home/History/HistoryTable.axaml
WalletWasabi.Fluent/Views/Wallets/Home/History/HistoryTable.axaml
</StackPanel>
<!-- Title -->
- <Label Content="{Binding Title}" DockPanel.Dock="Left" FontWeight="Bold" FontSize="16"/>
+ <Label Content="Transaction History" DockPanel.Dock="Left" FontWeight="Bold" FontSize="16"/>
</DockPanel>
<DataGrid Items="{Binding Transactions}"

ensure wallets and tiles get "activated" by navigation manager.