prototyping stuff
MODIFY
WalletWasabi.Fluent/App.xaml
WalletWasabi.Fluent/App.xaml
<StyleInclude Source="avares://WalletWasabi.Fluent/Icons/Icons.xaml" />
<StyleInclude Source="avares://WalletWasabi.Fluent/Styles/Styles.xaml" />
<StyleInclude Source="avares://WalletWasabi.Fluent/Controls/Dialog.xaml" />
+ <StyleInclude Source="avares://WalletWasabi.Fluent/Controls/TagBox.xaml" />
<StyleInclude Source="avares://WalletWasabi.Fluent/Controls/NavBarItem.xaml" />
<StyleInclude Source="avares://WalletWasabi.Fluent/Controls/NavBarTreeItem.xaml" />
</Application.Styles>

ADD
WalletWasabi.Fluent/Controls/TagBox.xaml
+<Styles xmlns="https://github.com/avaloniaui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:c="clr-namespace:WalletWasabi.Fluent.Controls">
+
+ <Style Selector="c|TagBox">
+ <Setter Property="Template">
+ <ControlTemplate>
+ <Panel>
+ <WrapPanel Name="PART_Container">
+ <AutoCompleteBox Name="PART_InputBox" MinimumPrefixLength="{TemplateBinding MinimumPrefixLength}"
+ Items="{TemplateBinding Suggestions}"/>
+ </WrapPanel>
+ </Panel>
+ </ControlTemplate>
+ </Setter>
+ </Style>
+
+ <Style Selector="c|TagBox /template/ TextBox#PART_InputBox">
+ <Setter Property="Opacity" Value="1"/>
+ </Style>
+
+</Styles>

ADD
WalletWasabi.Fluent/Controls/TagBox.xaml.cs
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.Primitives;
+using Avalonia.Input;
+using Avalonia.Threading;
+
+namespace WalletWasabi.Fluent.Controls
+{
+ /// <summary>
+ /// </summary>
+ public class TagBox : ContentControl
+ {
+ public static readonly StyledProperty<bool> IsDialogOpenProperty =
+ AvaloniaProperty.Register<TagBox, bool>(nameof(IsDialogOpen));
+
+ public bool IsDialogOpen
+ {
+ get => GetValue(IsDialogOpenProperty);
+ set => SetValue(IsDialogOpenProperty, value);
+ }
+
+ public static readonly StyledProperty<int> MinimumPrefixLengthProperty =
+ AvaloniaProperty.Register<TagBox, int>(nameof(MinimumPrefixLength));
+
+ public int MinimumPrefixLength
+ {
+ get => GetValue(MinimumPrefixLengthProperty);
+ set => SetValue(MinimumPrefixLengthProperty, value);
+ }
+
+ public static readonly StyledProperty<IEnumerable> SuggestionsProperty =
+ AvaloniaProperty.Register<TagBox, IEnumerable>(nameof(Suggestions));
+
+ public IEnumerable Suggestions
+ {
+ get => GetValue(SuggestionsProperty);
+ set => SetValue(SuggestionsProperty, value);
+ }
+
+
+ private WrapPanel _wp;
+ private AutoCompleteBox _tb;
+
+ protected override void OnPropertyChanged<T>(AvaloniaPropertyChangedEventArgs<T> change)
+ {
+ base.OnPropertyChanged(change);
+
+ if (change.Property == IsDialogOpenProperty)
+ {
+ PseudoClasses.Set(":open", change.NewValue.GetValueOrDefault<bool>());
+ }
+ }
+
+ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
+ {
+ _wp = e.NameScope.Find<WrapPanel>("PART_Container"); ;
+ _tb = e.NameScope.Find<AutoCompleteBox>("PART_InputBox"); ;
+ _tb.KeyUp += OnKeyPress;
+ _tb.GetObservable<string>(TextBox.TextProperty).Subscribe(TextChanged);
+ }
+
+ private void TextChanged(string obj)
+ {
+ if (obj.Length > 1 && !string.IsNullOrEmpty(obj.Trim()) && obj.EndsWith(' '))
+ {
+ var index = _wp.Children.Count - 1;
+
+ _wp.Children.Insert(index, new TextBlock() { Text = obj.Trim(), Margin = new Thickness(5) });
+
+ Dispatcher.UIThread.InvokeAsync(() => { _tb.Text = string.Empty; });
+ }
+ }
+
+ private void OnKeyPress(object? sender, KeyEventArgs e)
+ {
+ if (e.Key == Key.Back && string.IsNullOrEmpty(_tb.Text.Trim()) && _wp.Children.Count > 1)
+ {
+ _wp.Children.RemoveAt(_wp.Children.Count - 2);
+ }
+ else if (e.Key == Key.Enter && !string.IsNullOrEmpty(_tb.Text.Trim()))
+ {
+ var index = _wp.Children.Count - 1;
+
+ _wp.Children.Insert(index, new TextBlock() { Text = _tb.Text.Trim(), Margin = new Thickness(5) });
+
+ Dispatcher.UIThread.InvokeAsync(() => { _tb.Text = string.Empty; });
+ }
+ }
+ }
+}

MODIFY
WalletWasabi.Fluent/ViewModels/NavBarViewModel.cs
WalletWasabi.Fluent/ViewModels/NavBarViewModel.cs
@@ -43,6 +43,7 @@ namespace WalletWasabi.Fluent.ViewModels
SelectedItem = new HomePageViewModel(screen);
_topItems.Add(_selectedItem);
+ _topItems.Add(new RecoveryPageViewModel(screen));
_bottomItems.Add(new AddWalletPageViewModel(screen));
_bottomItems.Add(new SettingsPageViewModel(screen));

ADD
WalletWasabi.Fluent/ViewModels/RecoverWalletPageViewModel.cs
+using System.Collections;
+using System.Collections.Generic;
+using NBitcoin;
+using ReactiveUI;
+
+namespace WalletWasabi.Fluent.ViewModels
+{
+ public class RecoveryPageViewModel : NavBarItemViewModel
+ {
+ public RecoveryPageViewModel(IScreen screen) : base(screen)
+ {
+ Title = "Recovery";
+ }
+
+ public override string IconName => "home_regular";
+
+ public IEnumerable MnemonicSuggestions => Wordlist.English.GetWords();
+ }
+}

ADD
WalletWasabi.Fluent/Views/RecoveryPageView.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:c="clr-namespace:WalletWasabi.Fluent.Controls"
+ mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
+ x:Class="WalletWasabi.Fluent.Views.RecoveryPageView">
+ <Panel>
+ <c:TagBox Suggestions="{Binding MnemonicSuggestions}"/>
+ </Panel>
+</UserControl>

ADD
WalletWasabi.Fluent/Views/RecoveryPageView.axaml.cs
+using Avalonia.Markup.Xaml;
+using Avalonia.ReactiveUI;
+using WalletWasabi.Fluent.ViewModels;
+
+namespace WalletWasabi.Fluent.Views
+{
+ public class RecoveryPageView : ReactiveUserControl<RecoveryPageViewModel>
+ {
+ public RecoveryPageView()
+ {
+ InitializeComponent();
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+ }
+}

prototyping stuff