separate enter wallet name page
MODIFY
WalletWasabi.Fluent/ViewModels/AddWallet/AddWalletPageViewModel.cs
WalletWasabi.Fluent/ViewModels/AddWallet/AddWalletPageViewModel.cs
@@ -2,19 +2,11 @@ using ReactiveUI;
using System;
using System.IO;
using System.Reactive.Disposables;
-using System.Windows.Input;
using System.Reactive.Linq;
using WalletWasabi.Blockchain.Keys;
-using WalletWasabi.Fluent.ViewModels.Dialogs;
-using System.Threading.Tasks;
-using WalletWasabi.Fluent.Helpers;
-using WalletWasabi.Fluent.ViewModels.AddWallet.Create;
-using WalletWasabi.Fluent.ViewModels.AddWallet.HardwareWallet;
using WalletWasabi.Fluent.Validation;
using WalletWasabi.Models;
using WalletWasabi.Fluent.ViewModels.NavBar;
-using WalletWasabi.Helpers;
-using WalletWasabi.Logging;
namespace WalletWasabi.Fluent.ViewModels.AddWallet
{
@@ -30,7 +22,6 @@ namespace WalletWasabi.Fluent.ViewModels.AddWallet
public partial class AddWalletPageViewModel : NavBarItemViewModel
{
[AutoNotify] private string _walletName = "";
- [AutoNotify] private bool _optionsEnabled;
public AddWalletPageViewModel()
{
@@ -47,22 +38,18 @@ namespace WalletWasabi.Fluent.ViewModels.AddWallet
.Subscribe(y => EnableBack = y);
});
- this.WhenAnyValue(x => x.WalletName)
+ var canExecute = this.WhenAnyValue(x => x.WalletName)
.ObserveOn(RxApp.MainThreadScheduler)
- .Select(x => !string.IsNullOrWhiteSpace(x))
- .Subscribe(x => OptionsEnabled = x && !Validations.Any);
+ .Select(x => !string.IsNullOrWhiteSpace(x) && !Validations.Any);
- RecoverWalletCommand = ReactiveCommand.Create(() => OnRecoverWallet());
-
- ImportWalletCommand = ReactiveCommand.CreateFromTask(async () => await OnImportWalletAsync());
-
- ConnectHardwareWalletCommand = ReactiveCommand.Create(() => OnConnectHardwareWallet());
-
- CreateWalletCommand = ReactiveCommand.CreateFromTask(async () => await OnCreateWalletAsync());
+ NextCommand = ReactiveCommand.Create(OnNext, canExecute);
this.ValidateProperty(x => x.WalletName, errors => ValidateWalletName(errors, WalletName));
+ }
- EnableAutoBusyOn(CreateWalletCommand);
+ private void OnNext()
+ {
+ Navigate().To(new SelectWalletCreationOptionViewModel(WalletName));
}
private static void ValidateWalletName(IValidationErrors errors, string walletName)
@@ -94,70 +81,6 @@ namespace WalletWasabi.Fluent.ViewModels.AddWallet
}
}
- public ICommand CreateWalletCommand { get; }
-
- public ICommand RecoverWalletCommand { get; }
-
- public ICommand ImportWalletCommand { get; }
-
- public ICommand ConnectHardwareWalletCommand { get; }
-
- private void OnRecoverWallet()
- {
- Navigate().To(new RecoverWalletViewModel(WalletName));
- }
-
- private void OnConnectHardwareWallet()
- {
- Navigate().To(new ConnectHardwareWalletViewModel(WalletName));
- }
-
- private async Task OnImportWalletAsync()
- {
- try
- {
- var filePath = await FileDialogHelper.ShowOpenFileDialogAsync("Import wallet file", new[] { "json" });
-
- if (filePath is null)
- {
- return;
- }
-
- var keyManager = await ImportWalletHelper.ImportWalletAsync(Services.WalletManager, WalletName, filePath);
-
- Navigate().To(new AddedWalletPageViewModel(keyManager));
- }
- catch (Exception ex)
- {
- Logger.LogError(ex);
- await ShowErrorAsync(Title, ex.ToUserFriendlyString(),
- "The wallet file was not valid or compatible with Wasabi.");
- }
- }
-
- private async Task OnCreateWalletAsync()
- {
- var dialogResult = await NavigateDialogAsync(
- new CreatePasswordDialogViewModel("Type the password of the wallet and click Continue.", enableEmpty: true, enableCancel: Services.WalletManager.HasWallet()));
-
- if (dialogResult.Result is { } password)
- {
- var (km, mnemonic) = await Task.Run(
- () =>
- {
- var walletGenerator = new WalletGenerator(
- Services.WalletManager.WalletDirectories.WalletsDir,
- Services.WalletManager.Network)
- {
- TipHeight = Services.BitcoinStore.SmartHeaderChain.TipHeight
- };
- return walletGenerator.GenerateWallet(WalletName, password);
- });
-
- Navigate().To(new RecoveryWordsViewModel(km, mnemonic));
- }
- }
-
protected override void OnNavigatedTo(bool isInHistory, CompositeDisposable disposables)
{
base.OnNavigatedTo(isInHistory, disposables);

ADD
WalletWasabi.Fluent/ViewModels/AddWallet/SelectWalletCreationOptionViewModel.cs
+using System;
+using System.Reactive.Disposables;
+using System.Threading.Tasks;
+using System.Windows.Input;
+using ReactiveUI;
+using WalletWasabi.Blockchain.Keys;
+using WalletWasabi.Fluent.Helpers;
+using WalletWasabi.Fluent.ViewModels.AddWallet.Create;
+using WalletWasabi.Fluent.ViewModels.AddWallet.HardwareWallet;
+using WalletWasabi.Fluent.ViewModels.Dialogs;
+using WalletWasabi.Fluent.ViewModels.Navigation;
+using WalletWasabi.Helpers;
+using WalletWasabi.Logging;
+
+namespace WalletWasabi.Fluent.ViewModels.AddWallet
+{
+ [NavigationMetaData(Title = "Select an option")]
+ public partial class SelectWalletCreationOptionViewModel : RoutableViewModel
+ {
+ public SelectWalletCreationOptionViewModel(string walletName)
+ {
+ EnableBack = true;
+
+ RecoverWalletCommand = ReactiveCommand.Create(() => OnRecoverWallet(walletName));
+
+ ImportWalletCommand = ReactiveCommand.CreateFromTask(async () => await OnImportWalletAsync(walletName));
+
+ ConnectHardwareWalletCommand = ReactiveCommand.Create(() => OnConnectHardwareWallet(walletName));
+
+ CreateWalletCommand = ReactiveCommand.CreateFromTask(async () => await OnCreateWalletAsync(walletName));
+
+ EnableAutoBusyOn(CreateWalletCommand);
+ }
+
+ public ICommand CreateWalletCommand { get; }
+
+ public ICommand RecoverWalletCommand { get; }
+
+ public ICommand ImportWalletCommand { get; }
+
+ public ICommand ConnectHardwareWalletCommand { get; }
+
+ private void OnRecoverWallet(string walletName)
+ {
+ Navigate().To(new RecoverWalletViewModel(walletName));
+ }
+
+ private void OnConnectHardwareWallet(string walletName)
+ {
+ Navigate().To(new ConnectHardwareWalletViewModel(walletName));
+ }
+
+ private async Task OnImportWalletAsync(string walletName)
+ {
+ try
+ {
+ var filePath = await FileDialogHelper.ShowOpenFileDialogAsync("Import wallet file", new[] { "json" });
+
+ if (filePath is null)
+ {
+ return;
+ }
+
+ var keyManager = await ImportWalletHelper.ImportWalletAsync(Services.WalletManager, walletName, filePath);
+
+ Navigate().To(new AddedWalletPageViewModel(keyManager));
+ }
+ catch (Exception ex)
+ {
+ Logger.LogError(ex);
+ await ShowErrorAsync(Title, ex.ToUserFriendlyString(),
+ "The wallet file was not valid or compatible with Wasabi.");
+ }
+ }
+
+ private async Task OnCreateWalletAsync(string walletName)
+ {
+ var dialogResult = await NavigateDialogAsync(
+ new CreatePasswordDialogViewModel("Type the password of the wallet and click Continue.", enableEmpty: true, enableCancel: Services.WalletManager.HasWallet()));
+
+ if (dialogResult.Result is { } password)
+ {
+ var (km, mnemonic) = await Task.Run(
+ () =>
+ {
+ var walletGenerator = new WalletGenerator(
+ Services.WalletManager.WalletDirectories.WalletsDir,
+ Services.WalletManager.Network)
+ {
+ TipHeight = Services.BitcoinStore.SmartHeaderChain.TipHeight
+ };
+ return walletGenerator.GenerateWallet(walletName, password);
+ });
+
+ Navigate().To(new RecoveryWordsViewModel(km, mnemonic));
+ }
+ }
+
+ protected override void OnNavigatedTo(bool isInHistory, CompositeDisposable disposables)
+ {
+ base.OnNavigatedTo(isInHistory, disposables);
+
+ var enableCancel = Services.WalletManager.HasWallet();
+ SetupCancel(enableCancel: enableCancel, enableCancelOnEscape: enableCancel, enableCancelOnPressed: enableCancel);
+ }
+ }
+}

MODIFY
WalletWasabi.Fluent/Views/AddWallet/AddWalletPageView.axaml
WalletWasabi.Fluent/Views/AddWallet/AddWalletPageView.axaml
x:DataType="vm:AddWalletPageViewModel"
x:CompileBindings="True"
x:Class="WalletWasabi.Fluent.Views.AddWallet.AddWalletPageView">
- <c:ContentArea Title="{Binding Title}" Caption="Type in your wallet's name and select an option:"
+ <c:ContentArea Title="{Binding Title}" Caption="Type in your wallet's name"
EnableCancel="{Binding EnableCancel}"
EnableBack="{Binding EnableBack}"
- IsBusy="{Binding IsBusy}">
- <DockPanel>
+ IsBusy="{Binding IsBusy}"
+ EnableNext="True" NextContent="Continue">
<StackPanel DockPanel.Dock="Top" Margin="0 0 0 20">
<Label Content="Wallet _Name:" Target="walletNameTb" />
<TextBox x:Name="walletNameTb" MaxLength="250" Text="{Binding WalletName}" Watermark="(e.g. My Wallet)">
</i:Interaction.Behaviors>
</TextBox>
</StackPanel>
- <WrapPanel Orientation="Horizontal" Margin="0 0 0 20" HorizontalAlignment="Center">
- <WrapPanel.Styles>
- <Style Selector="c|TileButton">
- <Setter Property="Margin" Value="4"/>
- <Setter Property="IsEnabled" Value="{Binding OptionsEnabled}"/>
- </Style>
- </WrapPanel.Styles>
- <c:TileButton Text="Create a new wallet"
- Classes="action"
- Icon="{StaticResource add_regular}"
- Command="{Binding CreateWalletCommand}" />
- <c:TileButton Text="Connect to hardware wallet"
- Icon="{StaticResource calculator_regular}"
- Command="{Binding ConnectHardwareWalletCommand}" />
- <c:TileButton Text="Import a wallet"
- Icon="{StaticResource import_regular}"
- Command="{Binding ImportWalletCommand}" />
- <c:TileButton Text="Recover a wallet"
- Icon="{StaticResource recover_arrow_right_regular}"
- Command="{Binding RecoverWalletCommand}" />
- </WrapPanel>
- </DockPanel>
</c:ContentArea>
</UserControl>

ADD
WalletWasabi.Fluent/Views/AddWallet/SelectWalletCreationOptionView.axaml
+<UserControl xmlns="https://github.com/avaloniaui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:vm="using:WalletWasabi.Fluent.ViewModels.AddWallet"
+ xmlns:c="using:WalletWasabi.Fluent.Controls"
+ mc:Ignorable="d" d:DesignWidth="428" d:DesignHeight="371"
+ x:DataType="vm:SelectWalletCreationOptionViewModel"
+ x:CompileBindings="True"
+ x:Class="WalletWasabi.Fluent.Views.AddWallet.SelectWalletCreationOptionView">
+ <UserControl.KeyBindings>
+ <KeyBinding Gesture="Enter" Command="{Binding CreateWalletCommand}" />
+ </UserControl.KeyBindings>
+ <c:ContentArea Title="{Binding Title}" Caption="Select an option:"
+ EnableCancel="{Binding EnableCancel}"
+ EnableBack="{Binding EnableBack}"
+ IsBusy="{Binding IsBusy}">
+ <WrapPanel Orientation="Horizontal" Margin="0 0 0 20" HorizontalAlignment="Center">
+ <WrapPanel.Styles>
+ <Style Selector="c|TileButton">
+ <Setter Property="Margin" Value="4"/>
+ </Style>
+ </WrapPanel.Styles>
+ <c:TileButton Text="Create a new wallet"
+ Classes="action"
+ Icon="{StaticResource add_regular}"
+ Command="{Binding CreateWalletCommand}" />
+ <c:TileButton Text="Connect to hardware wallet"
+ Icon="{StaticResource calculator_regular}"
+ Command="{Binding ConnectHardwareWalletCommand}" />
+ <c:TileButton Text="Import a wallet"
+ Icon="{StaticResource import_regular}"
+ Command="{Binding ImportWalletCommand}" />
+ <c:TileButton Text="Recover a wallet"
+ Icon="{StaticResource recover_arrow_right_regular}"
+ Command="{Binding RecoverWalletCommand}" />
+ </WrapPanel>
+ </c:ContentArea>
+</UserControl>

ADD
WalletWasabi.Fluent/Views/AddWallet/SelectWalletCreationOptionView.axaml.cs
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace WalletWasabi.Fluent.Views.AddWallet
+{
+ public class SelectWalletCreationOptionView : UserControl
+ {
+ public SelectWalletCreationOptionView()
+ {
+ InitializeComponent();
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+ }
+}

separate enter wallet name page