Single click add wallet UI
MODIFY
WalletWasabi.Fluent/Controls/TileButton.axaml
WalletWasabi.Fluent/Controls/TileButton.axaml
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
- <Panel>
- <PathIcon x:Name="PART_Icon"
- Data="{TemplateBinding Icon}"
- Width="{TemplateBinding IconSize}"
- Height="{TemplateBinding IconSize}"
- Foreground="{TemplateBinding Foreground}"/>
+ <DockPanel>
<TextBlock x:Name="PART_Text"
Text="{TemplateBinding Text}"
Foreground="{TemplateBinding Foreground}"
- DockPanel.Dock="Bottom"/>
- </Panel>
+ DockPanel.Dock="Top" />
+ <PathIcon x:Name="PART_Icon"
+ Data="{TemplateBinding Icon}"
+ Width="{TemplateBinding IconSize}"
+ Height="{TemplateBinding IconSize}" />
+ </DockPanel>
</Border>
</ControlTemplate>
</Setter>
</Style>
<Style Selector="c|TileButton /template/ PathIcon#PART_Icon">
- <Setter Property="Opacity" Value="0.8"/>
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Margin" Value="0 0 0 15" />
+ <Setter Property="Foreground" Value="{StaticResource SystemAccentColor}" />
</Style>
<Style Selector="c|TileButton /template/ TextBlock#PART_Text">
- <Setter Property="Margin" Value="10 0 10 15"/>
+ <Setter Property="Margin" Value="10 10 10 15" />
<Setter Property="TextWrapping" Value="Wrap" />
+ <Setter Property="MinHeight" Value="34" />
<Setter Property="HorizontalAlignment" Value="Center" />
- <Setter Property="VerticalAlignment" Value="Bottom"/>
<Setter Property="TextAlignment" Value="Center" />
</Style>
<Style Selector="c|TileButton /template/ Border#PART_Border">
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
- <Setter Property="BoxShadow" Value="{DynamicResource OptionButtonShadow}" />
+ <Setter Property="BoxShadow" Value="{DynamicResource OptimizePrivacyOptionBoxShadow1}" />
</Style>
<Style Selector="c|TileButton">
<Setter Property="Height" Value="150" />
<Setter Property="ClipToBounds" Value="False" />
<Setter Property="BorderThickness" Value="0" />
- <Setter Property="Background" Value="{DynamicResource TileRegionColor}" />
+ <Setter Property="Background" Value="{DynamicResource OptimizePrivacyOptionSelectedColor}" />
<Setter Property="BorderBrush" Value="{DynamicResource TileBorderColor}" />
</Style>
<!-- Pointerover -->
<Style Selector="c|TileButton:pointerover">
- <Setter Property="Background" Value="{DynamicResource ButtonBackgroundPointerOver}" />
+ <!--<Setter Property="Background" Value="{DynamicResource ButtonBackgroundPointerOver}" />-->
<Setter Property="BorderBrush" Value="{DynamicResource ButtonBorderBrushPointerOver}" />
<Setter Property="Foreground" Value="{DynamicResource ButtonForegroundPointerOver}" />
</Style>
<Setter Property="RenderTransform" Value="scale(0.98)" />
</Style>
+ <Style Selector="c|TileButton:pointerover /template/ Border#PART_Border">
+ <Setter Property="BoxShadow" Value="{DynamicResource OptimizePrivacyOptionBoxShadow2}" />
+ </Style>
+
+ <Style Selector="c|TileButton:pressed /template/ Border#PART_Border">
+ <Setter Property="BoxShadow" Value="0 0 0 #121212" />
+ </Style>
+
<!-- Action style -->
<Style Selector="c|TileButton.action">
- <Setter Property="BorderThickness" Value="0 0 0 2" />
+ <Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="{DynamicResource SystemAccentColor}" />
</Style>
-
</Styles>

MODIFY
WalletWasabi.Fluent/ViewModels/AddWallet/AddWalletPageViewModel.cs
WalletWasabi.Fluent/ViewModels/AddWallet/AddWalletPageViewModel.cs
-using System.Collections.Generic;
using System.IO;
-using System.Linq;
using System.Reactive;
using System.Reactive.Disposables;
using System.Threading.Tasks;
+using System.Windows.Input;
using ReactiveUI;
using WalletWasabi.Fluent.Helpers;
using WalletWasabi.Fluent.Models;
@@ -27,41 +26,17 @@ namespace WalletWasabi.Fluent.ViewModels.AddWallet;
NavBarPosition = NavBarPosition.Bottom)]
public partial class AddWalletPageViewModel : DialogViewModelBase<Unit>
{
- [AutoNotify] private AddWalletPageOption _selectedOption;
-
public AddWalletPageViewModel()
{
SelectionMode = NavBarItemSelectionMode.Button;
- Options = new()
- {
- new AddWalletPageOption
- {
- CreationOption = WalletCreationOption.AddNewWallet,
- Title = "Create a new wallet",
- IconName = "add_regular"
- },
- new AddWalletPageOption
- {
- CreationOption = WalletCreationOption.ConnectToHardwareWallet,
- Title = "Connect to hardware wallet",
- IconName = "calculator_regular"
- },
- new AddWalletPageOption
- {
- CreationOption = WalletCreationOption.ImportWallet,
- Title = "Import a wallet",
- IconName = "import_regular"
- },
- new AddWalletPageOption
- {
- CreationOption = WalletCreationOption.RecoverWallet,
- Title = "Recover a wallet",
- IconName = "recover_arrow_right_regular"
- },
- };
+ CreateWalletCommand = ReactiveCommand.Create(OnCreateWallet);
- _selectedOption = Options.First();
+ ConnectHardwareWalletCommand = ReactiveCommand.Create(OnConnectHardwareWallet);
+
+ ImportWalletCommand = ReactiveCommand.CreateFromTask(async () => await OnImportWalletAsync());
+
+ RecoverWalletCommand = ReactiveCommand.Create(OnRecoverWallet);
OpenCommand = ReactiveCommand.Create(async () =>
{
@@ -69,13 +44,27 @@ public partial class AddWalletPageViewModel : DialogViewModelBase<Unit>
await NavigateDialogAsync(this, NavigationTarget.DialogScreen);
MainViewModel.Instance.IsOobeBackgroundVisible = false;
});
+ }
+
+ public ICommand CreateWalletCommand { get; }
+
+ public ICommand ConnectHardwareWalletCommand { get; }
- NextCommand = ReactiveCommand.CreateFromTask(OnNextAsync);
+ public ICommand ImportWalletCommand { get; }
+
+ public ICommand RecoverWalletCommand { get; }
+
+ private void OnCreateWallet()
+ {
+ Navigate().To(new WalletNamePageViewModel(WalletCreationOption.AddNewWallet));
}
- public List<AddWalletPageOption> Options { get; }
+ private void OnConnectHardwareWallet()
+ {
+ Navigate().To(new WalletNamePageViewModel(WalletCreationOption.ConnectToHardwareWallet));
+ }
- private async Task ImportWalletAsync()
+ private async Task OnImportWalletAsync()
{
try
{
@@ -105,15 +94,38 @@ public partial class AddWalletPageViewModel : DialogViewModelBase<Unit>
}
}
- private async Task OnNextAsync()
+ private void OnRecoverWallet()
+ {
+ Navigate().To(new WalletNamePageViewModel(WalletCreationOption.RecoverWallet));
+ }
+
+ private async Task ImportWalletAsync()
+ {
+ try
+ {
+ var filePath = await FileDialogHelper.ShowOpenFileDialogAsync("Import wallet file", new[] { "json" });
+
+ if (filePath is null)
{
- if (SelectedOption.CreationOption == WalletCreationOption.ImportWallet)
+ return;
+ }
+
+ var walletName = Path.GetFileNameWithoutExtension(filePath);
+
+ var validationError = WalletHelpers.ValidateWalletName(walletName);
+ if (validationError is { })
{
- await ImportWalletAsync();
+ Navigate().To(new WalletNamePageViewModel(WalletCreationOption.ImportWallet, filePath));
+ return;
}
- else
+
+ var keyManager = await ImportWalletHelper.ImportWalletAsync(Services.WalletManager, walletName, filePath);
+ Navigate().To(new AddedWalletPageViewModel(keyManager));
+ }
+ catch (Exception ex)
{
- Navigate().To(new WalletNamePageViewModel(SelectedOption.CreationOption));
+ Logger.LogError(ex);
+ await ShowErrorAsync("Import wallet", ex.ToUserFriendlyString(), "Wasabi was unable to import your wallet.");
}
}
@@ -123,7 +135,5 @@ public partial class AddWalletPageViewModel : DialogViewModelBase<Unit>
var enableCancel = Services.WalletManager.HasWallet();
SetupCancel(enableCancel: enableCancel, enableCancelOnEscape: enableCancel, enableCancelOnPressed: enableCancel);
-
- SelectedOption = Options.First();
}
}

MODIFY
WalletWasabi.Fluent/Views/AddWallet/AddWalletPageView.axaml
WalletWasabi.Fluent/Views/AddWallet/AddWalletPageView.axaml
EnableCancel="{Binding EnableCancel}"
EnableBack="{Binding EnableBack}"
IsBusy="{Binding IsBusy}"
- EnableNext="True"
- NextContent="Continue">
- <ListBox Items="{Binding Options}" SelectedItem="{Binding SelectedOption}" Background="Transparent"
- ScrollViewer.VerticalScrollBarVisibility="Disabled">
- <ListBox.Styles>
- <Style Selector="ListBoxItem">
- <Setter Property="Cursor" Value="Hand" />
- <Setter Property="Padding" Value="0 12 0 12" />
- </Style>
- <Style Selector="ListBoxItem /template/ ContentPresenter#PART_ContentPresenter">
- <Setter Property="Background" Value="Transparent" />
- <Setter Property="VerticalAlignment" Value="Center" />
- </Style>
+ EnableNext="False">
+ <UniformGrid Rows="1" HorizontalAlignment="Center">
+ <c:TileButton Text="Create a new wallet"
+ Classes="action"
+ Icon="{StaticResource add_regular}"
+ Command="{Binding CreateWalletCommand}"
+ IsDefault="{Binding IsActive}"
+ Margin="10" IconSize="50" />
- <Style Selector="ListBoxItem:selected /template/ ContentPresenter#PART_ContentPresenter, ListBoxItem:pointerover /template/ ContentPresenter#PART_ContentPresenter">
- <Setter Property="Background" Value="Transparent" />
- </Style>
- <Style Selector="ListBoxItem:selected Border#PART_DecorationBorderHover, ListBoxItem:selected Border#PART_DecorationBorderUnselected">
- <Setter Property="BorderBrush" Value="{DynamicResource SystemAccentColor}" />
- </Style>
+ <c:TileButton Text="Connect to hardware wallet"
+ Icon="{StaticResource calculator_regular}"
+ Command="{Binding ConnectHardwareWalletCommand}"
+ Margin="10" IconSize="50" />
- <Style Selector="ListBoxItem Border#PART_MainContentBorder">
- <Setter Property="Padding" Value="10 25 10 25" />
- <Setter Property="CornerRadius" Value="4" />
- </Style>
+ <c:TileButton Text="Import a wallet"
+ Icon="{StaticResource import_regular}"
+ Command="{Binding ImportWalletCommand}"
+ Margin="10" IconSize="50" />
- <Style Selector="ListBoxItem Border#PART_DecorationBorderUnselected">
- <Setter Property="Padding" Value="10 25 10 25" />
- <Setter Property="CornerRadius" Value="4" />
- <Setter Property="Margin" Value="5" />
- <Setter Property="BorderBrush" Value="#14FFFFFF" />
- <Setter Property="BorderThickness" Value="1" />
- <Setter Property="Background" Value="{StaticResource OptimizePrivacyOptionSelectedColor}" />
- <Setter Property="BoxShadow" Value="{StaticResource OptimizePrivacyOptionBoxShadow1}" />
- </Style>
-
- <Style Selector="ListBoxItem Border#PART_DecorationBorderHover">
- <Setter Property="Padding" Value="10 25 10 25" />
- <Setter Property="CornerRadius" Value="4" />
- <Setter Property="Margin" Value="5" />
- <Setter Property="BorderBrush" Value="#2AFFFFFF" />
- <Setter Property="BorderThickness" Value="1" />
- <Setter Property="Background" Value="{StaticResource OptimizePrivacyOptionSelectedColor}" />
- <Setter Property="BoxShadow" Value="{StaticResource OptimizePrivacyOptionBoxShadow2}" />
-
- <Setter Property="Opacity" Value="0" />
- </Style>
-
- <Style Selector="ListBoxItem:pointerover Border#PART_DecorationBorderHover">
- <Setter Property="Opacity" Value="1" />
- </Style>
- </ListBox.Styles>
- <ListBox.ItemsPanel>
- <ItemsPanelTemplate>
- <UniformGrid Rows="1" />
- </ItemsPanelTemplate>
- </ListBox.ItemsPanel>
- <ListBox.DataTemplates>
- <DataTemplate>
- <c:SuggestionItem VerticalAlignment="Center">
- <StackPanel Spacing="20" Height="150" MaxWidth="180">
- <TextBlock Text="{Binding Title}" TextWrapping="Wrap" TextAlignment="Center" Height="34" />
- <Viewbox HorizontalAlignment="Center" Height="70">
- <PathIcon Data="{Binding IconName, Converter={x:Static conv:NavBarIconConverter.Instance}}"
- Foreground="{StaticResource SystemAccentColor}" />
- </Viewbox>
- </StackPanel>
- </c:SuggestionItem>
- </DataTemplate>
- </ListBox.DataTemplates>
- </ListBox>
+ <c:TileButton Text="Recover a wallet"
+ Icon="{StaticResource recover_arrow_right_regular}"
+ Command="{Binding RecoverWalletCommand}"
+ Margin="10" IconSize="50" />
+ </UniformGrid>
</c:ContentArea>
</UserControl>

Single click add wallet UI