Make login navigation explicit.
MODIFY
WalletWasabi.Fluent/ViewModels/Login/LoginViewModel.cs
WalletWasabi.Fluent/ViewModels/Login/LoginViewModel.cs
@@ -14,14 +14,17 @@ namespace WalletWasabi.Fluent.ViewModels.Login
[NavigationMetaData(Title = "Login")]
public partial class LoginViewModel : RoutableViewModel
{
+ private readonly WalletManagerViewModel _walletManagerViewModel;
private readonly ClosedWalletViewModel _closedWalletVm;
+
[AutoNotify] private string _password;
[AutoNotify] private bool _isPasswordIncorrect;
[AutoNotify] private bool _isPasswordNeeded;
[AutoNotify] private string _walletName;
- public LoginViewModel(ClosedWalletViewModel closedWalletVm, LegalChecker legalChecker)
+ public LoginViewModel(WalletManagerViewModel walletManagerViewModel, ClosedWalletViewModel closedWalletVm, LegalChecker legalChecker)
{
+ _walletManagerViewModel = walletManagerViewModel;
_closedWalletVm = closedWalletVm;
var wallet = _closedWalletVm.Wallet;
@@ -65,12 +68,12 @@ namespace WalletWasabi.Fluent.ViewModels.Login
if (dialogResult.Result)
{
await legalChecker.AgreeAsync();
- LoginWallet();
+ await LoginWallet();
}
}
else
{
- LoginWallet();
+ await LoginWallet();
}
}
});
@@ -93,11 +96,24 @@ namespace WalletWasabi.Fluent.ViewModels.Login
public KeyManager KeyManager { get; }
- private void LoginWallet()
+ private async Task LoginWallet()
{
+ IsBusy = true;
_closedWalletVm.Wallet.Login();
_closedWalletVm.RaisePropertyChanged(nameof(WalletViewModelBase.IsLoggedIn));
- Navigate().To(_closedWalletVm, NavigationMode.Clear);
+
+ var destination = await _walletManagerViewModel.LoginWalletAsync(_closedWalletVm);
+
+ if (destination is { })
+ {
+ Navigate().To(destination, NavigationMode.Clear);
+ }
+ else
+ {
+ await ShowErrorAsync("Error", "Wasabi was unable to login and load your wallet.");
+ }
+
+ IsBusy = false;
}
}
}

MODIFY
WalletWasabi.Fluent/ViewModels/WalletManagerViewModel.cs
WalletWasabi.Fluent/ViewModels/WalletManagerViewModel.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Linq;
+using System.Threading.Tasks;
using Avalonia.Threading;
using DynamicData;
using DynamicData.Binding;
@@ -13,6 +14,7 @@ using WalletWasabi.Fluent.ViewModels.Wallets.Actions;
using WalletWasabi.Fluent.ViewModels.Wallets.Receive;
using WalletWasabi.Fluent.ViewModels.Wallets.Send;
using WalletWasabi.Gui;
+using WalletWasabi.Logging;
using WalletWasabi.Services;
using WalletWasabi.Stores;
using WalletWasabi.Wallets;
@@ -89,7 +91,7 @@ namespace WalletWasabi.Fluent.ViewModels
wallet =>
{
WalletViewModelBase vm = (wallet.State <= WalletState.Starting)
- ? ClosedWalletViewModel.Create(walletManager, wallet, legalChecker)
+ ? ClosedWalletViewModel.Create(this, wallet, legalChecker)
: WalletViewModel.Create(uiConfig, wallet);
InsertWallet(vm);
@@ -104,6 +106,36 @@ namespace WalletWasabi.Fluent.ViewModels
public BitcoinStore BitcoinStore { get; }
+ public async Task<WalletViewModelBase?> LoginWalletAsync(ClosedWalletViewModel closedWalletViewModel)
+ {
+ var wallet = closedWalletViewModel.Wallet;
+
+ if (wallet.State != WalletState.Uninitialized)
+ {
+ throw new Exception("Wallet is already being logged in.");
+ }
+
+ try
+ {
+ await Task.Run(async () => await Model.StartWalletAsync(wallet));
+ }
+ catch (OperationCanceledException ex)
+ {
+ Logger.LogTrace(ex);
+ }
+ catch (Exception ex)
+ {
+ Logger.LogError(ex);
+ }
+
+ if (_walletDictionary.ContainsKey(wallet))
+ {
+ return _walletDictionary[wallet];
+ }
+
+ return null;
+ }
+
private void OpenClosedWallet(WalletManager walletManager, UiConfig uiConfig, ClosedWalletViewModel closedWalletViewModel)
{
IsLoadingWallet = true;
@@ -177,7 +209,7 @@ namespace WalletWasabi.Fluent.ViewModels
{
foreach (var wallet in walletManager.GetWallets())
{
- InsertWallet(ClosedWalletViewModel.Create(walletManager, wallet, legalChecker));
+ InsertWallet(ClosedWalletViewModel.Create(this, wallet, legalChecker));
}
}

MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/ClosedWalletViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/ClosedWalletViewModel.cs
@@ -16,62 +16,25 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets
{
public partial class ClosedWalletViewModel : WalletViewModelBase
{
- private readonly WalletManager _walletManager;
[AutoNotify] private ObservableCollection<NavBarItemViewModel> _items;
- protected ClosedWalletViewModel(WalletManager walletManager, Wallet wallet, LegalChecker legalChecker)
+ protected ClosedWalletViewModel(WalletManagerViewModel walletManagerViewModel, Wallet wallet, LegalChecker legalChecker)
: base(wallet)
{
- _walletManager = walletManager;
_items = new ObservableCollection<NavBarItemViewModel>();
OpenCommand = ReactiveCommand.Create(() =>
{
if (!Wallet.IsLoggedIn)
{
- Navigate().To(new LoginViewModel(this, legalChecker));
+ Navigate().To(new LoginViewModel(walletManagerViewModel, this, legalChecker));
}
});
}
- protected override void OnNavigatedTo(bool inStack, CompositeDisposable disposable)
- {
- base.OnNavigatedTo(inStack, disposable);
-
- if (Wallet.State == WalletState.Uninitialized)
- {
- RxApp.MainThreadScheduler.Schedule(async () =>
- {
- await LoadWallet();
- });
- }
- }
-
public override string IconName => "web_asset_regular";
- public async Task LoadWallet()
- {
- if (Wallet.State != WalletState.Uninitialized)
- {
- return;
- }
-
- try
- {
- await Task.Run(async () => await _walletManager.StartWalletAsync(Wallet));
- }
- catch (OperationCanceledException ex)
- {
- Logger.LogTrace(ex);
- }
- catch (Exception ex)
- {
- await ShowErrorAsync(ex.ToUserFriendlyString(), "Wasabi was unable to load your wallet");
- Logger.LogError(ex);
- }
- }
-
- public static WalletViewModelBase Create(WalletManager walletManager, Wallet wallet, LegalChecker legalChecker)
+ public static WalletViewModelBase Create(WalletManagerViewModel walletManager, Wallet wallet, LegalChecker legalChecker)
{
return wallet.KeyManager.IsHardwareWallet
? new ClosedHardwareWalletViewModel(walletManager, wallet, legalChecker)

MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/HardwareWallet/ClosedHardwareWalletViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/HardwareWallet/ClosedHardwareWalletViewModel.cs
@@ -5,7 +5,7 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.HardwareWallet
{
public class ClosedHardwareWalletViewModel : ClosedWalletViewModel
{
- internal ClosedHardwareWalletViewModel(WalletManager walletManager, Wallet wallet, LegalChecker legalChecker) : base(walletManager, wallet, legalChecker)
+ internal ClosedHardwareWalletViewModel(WalletManagerViewModel walletManager, Wallet wallet, LegalChecker legalChecker) : base(walletManager, wallet, legalChecker)
{
}
}

MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/WatchOnlyWallet/ClosedWatchOnlyWalletViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/WatchOnlyWallet/ClosedWatchOnlyWalletViewModel.cs
@@ -5,7 +5,7 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.WatchOnlyWallet
{
public class ClosedWatchOnlyWalletViewModel : ClosedWalletViewModel
{
- internal ClosedWatchOnlyWalletViewModel(WalletManager walletManager, Wallet wallet, LegalChecker legalChecker) : base(walletManager, wallet, legalChecker)
+ internal ClosedWatchOnlyWalletViewModel(WalletManagerViewModel walletManager, Wallet wallet, LegalChecker legalChecker) : base(walletManager, wallet, legalChecker)
{
}
}

Make login navigation explicit.