[WIP] label suggestion
RENAME
WalletWasabi.Gui/Behaviors/MnemonicSuggestionBehavior.cs
WalletWasabi.Gui/Behaviors/SuggestionBehavior.cs
@@ -10,14 +10,14 @@ using WalletWasabi.Gui.Tabs.WalletManager;
namespace WalletWasabi.Gui.Behaviors
{
- internal class MnemonicSuggestionBehavior : Behavior<TextBox>
+ internal class SuggestionBehavior : Behavior<TextBox>
{
private CompositeDisposable _disposables;
- private static readonly AvaloniaProperty<IEnumerable<MnemonicViewModel>> SuggestionItemsProperty =
- AvaloniaProperty.Register<MnemonicSuggestionBehavior, IEnumerable<MnemonicViewModel>>(nameof(SuggestionItems), defaultBindingMode: Avalonia.Data.BindingMode.TwoWay);
+ private static readonly AvaloniaProperty<IEnumerable<SuggestionViewModel>> SuggestionItemsProperty =
+ AvaloniaProperty.Register<SuggestionBehavior, IEnumerable<SuggestionViewModel>>(nameof(SuggestionItems), defaultBindingMode: Avalonia.Data.BindingMode.TwoWay);
- public IEnumerable<MnemonicViewModel> SuggestionItems
+ public IEnumerable<SuggestionViewModel> SuggestionItems
{
get => GetValue(SuggestionItemsProperty);
set => SetValue(SuggestionItemsProperty, value);

MODIFY
WalletWasabi.Gui/Controls/WalletExplorer/ReceiveTabView.xaml
WalletWasabi.Gui/Controls/WalletExplorer/ReceiveTabView.xaml
<Grid ColumnDefinitions="*,300" DockPanel.Dock="Top" Margin="0 0 0 10">
<controls:ExtendedTextBox Text="{Binding Label, Mode=TwoWay}" Watermark="Label (Required)" UseFloatingWatermark="True" Grid.Column="0" Margin="0 0 10 0">
<i:Interaction.Behaviors>
+ <behaviors:SuggestionBehavior SuggestionItems="{Binding Suggestions}" />
<behaviors:CommandOnEnterBehavior Command="{Binding GenerateCommand}" />
<behaviors:FocusBehavior IsFocused="{Binding IsSelected}" />
<iac:FocusOnAttachedToVisualTreeBehavior />

MODIFY
WalletWasabi.Gui/Controls/WalletExplorer/ReceiveTabViewModel.cs
WalletWasabi.Gui/Controls/WalletExplorer/ReceiveTabViewModel.cs
@@ -8,6 +8,7 @@ using System.Linq;
using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;
+using WalletWasabi.Gui.Tabs.WalletManager;
using WalletWasabi.Gui.ViewModels;
using WalletWasabi.KeyManagement;
@@ -22,8 +23,10 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
private bool _labelRequiredNotificationVisible;
private double _clipboardNotificationOpacity;
private bool _clipboardNotificationVisible;
+ private int _caretIndex;
+ private ObservableCollection<SuggestionViewModel> _suggestions;
- public ReceiveTabViewModel(WalletViewModel walletViewModel)
+ private ReceiveTabViewModel(WalletViewModel walletViewModel)
: base("Receive", walletViewModel)
{
_addresses = new ObservableCollection<AddressViewModel>();
@@ -72,7 +75,7 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
Label = string.Empty;
});
});
-
+ this.WhenAnyValue(x => x.Label).Subscribe(x => UpdateSuggestions(x));
this.WhenAnyValue(x => x.SelectedAddress).Subscribe(address =>
{
if (!(address is null))
@@ -88,6 +91,7 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
});
}
});
+ _suggestions = new ObservableCollection<SuggestionViewModel>();
}
private void InitializeAddresses()
@@ -144,6 +148,62 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
set { this.RaiseAndSetIfChanged(ref _clipboardNotificationVisible, value); }
}
+ public int CaretIndex
+ {
+ get { return _caretIndex; }
+ set { this.RaiseAndSetIfChanged(ref _caretIndex, value); }
+ }
+
+ public ObservableCollection<SuggestionViewModel> Suggestions
+ {
+ get { return _suggestions; }
+ set { this.RaiseAndSetIfChanged(ref _suggestions, value); }
+ }
+
+ private void UpdateSuggestions(string words)
+ {
+ if (string.IsNullOrWhiteSpace(words))
+ {
+ Suggestions?.Clear();
+ return;
+ }
+
+ string[] enteredWordList = words.Split(' ', StringSplitOptions.RemoveEmptyEntries);
+ var lastWorld = enteredWordList.LastOrDefault().Replace("\t", "");
+
+ if (lastWorld.Length < 1)
+ {
+ _suggestions.Clear();
+ return;
+ }
+
+ var suggestedWords = Global.WalletService.GetNonSpecialLabels().Where(w => w.StartsWith(lastWorld, StringComparison.InvariantCultureIgnoreCase)).Take(7);
+
+ _suggestions.Clear();
+ foreach (var suggestion in suggestedWords)
+ {
+ _suggestions.Add(new SuggestionViewModel(suggestion, OnAddWord));
+ }
+ }
+
+ public void OnAddWord(string word)
+ {
+ string[] words = Label.Split(' ', StringSplitOptions.RemoveEmptyEntries);
+ if (words.Length == 0)
+ {
+ Label = word + " ";
+ }
+ else
+ {
+ words[words.Length - 1] = word;
+ Label = string.Join(' ', words) + " ";
+ }
+
+ CaretIndex = Label.Length;
+
+ Suggestions.Clear();
+ }
+
public ReactiveCommand GenerateCommand { get; }
}
}

MODIFY
WalletWasabi.Gui/Tabs/WalletManager/MnemonicViewModel.cs
WalletWasabi.Gui/Tabs/WalletManager/MnemonicViewModel.cs
@@ -5,12 +5,12 @@ using System.Linq;
namespace WalletWasabi.Gui.Tabs.WalletManager
{
- internal class MnemonicViewModel
+ public class SuggestionViewModel
{
public string Word { get; }
public Action<string> OnSelection { get; }
- public MnemonicViewModel(string word, Action<string> onSeleted)
+ public SuggestionViewModel(string word, Action<string> onSeleted)
{
Word = word;
OnSelection = onSeleted;

MODIFY
WalletWasabi.Gui/Tabs/WalletManager/RecoverWalletView.xaml
WalletWasabi.Gui/Tabs/WalletManager/RecoverWalletView.xaml
<TextBox Text="{Binding Password}" Watermark="Password" PasswordChar="*" UseFloatingWatermark="True" />
<controls:ExtendedTextBox Text="{Binding MnemonicWords}" Watermark="MnemonicWords" UseFloatingWatermark="True" CaretIndex="{Binding CaretIndex, Mode=TwoWay}">
<i:Interaction.Behaviors>
- <behaviors:MnemonicSuggestionBehavior SuggestionItems="{Binding Suggestions}" />
+ <behaviors:SuggestionBehavior SuggestionItems="{Binding Suggestions}" />
</i:Interaction.Behaviors>
</controls:ExtendedTextBox>
<ItemsControl Items="{Binding Suggestions}">

MODIFY
WalletWasabi.Gui/Tabs/WalletManager/RecoverWalletViewModel.cs
WalletWasabi.Gui/Tabs/WalletManager/RecoverWalletViewModel.cs
@@ -25,7 +25,7 @@ namespace WalletWasabi.Gui.Tabs.WalletManager
private string _walletName;
private bool _termsAccepted;
private string _validationMessage;
- private ObservableCollection<MnemonicViewModel> _suggestions;
+ private ObservableCollection<SuggestionViewModel> _suggestions;
public RecoverWalletViewModel(WalletManagerViewModel owner) : base("Recover Wallet")
{
@@ -93,7 +93,7 @@ namespace WalletWasabi.Gui.Tabs.WalletManager
}
});
- _suggestions = new ObservableCollection<MnemonicViewModel>();
+ _suggestions = new ObservableCollection<SuggestionViewModel>();
}
public string Password
@@ -108,7 +108,7 @@ namespace WalletWasabi.Gui.Tabs.WalletManager
set { this.RaiseAndSetIfChanged(ref _mnemonicWords, value); }
}
- public ObservableCollection<MnemonicViewModel> Suggestions
+ public ObservableCollection<SuggestionViewModel> Suggestions
{
get { return _suggestions; }
set { this.RaiseAndSetIfChanged(ref _suggestions, value); }
@@ -188,7 +188,7 @@ namespace WalletWasabi.Gui.Tabs.WalletManager
_suggestions.Clear();
foreach (var suggestion in suggestedWords)
{
- _suggestions.Add(new MnemonicViewModel(suggestion, OnAddWord));
+ _suggestions.Add(new SuggestionViewModel(suggestion, OnAddWord));
}
}

MODIFY
WalletWasabi.Gui/WalletWasabi.Gui.csproj
WalletWasabi.Gui/WalletWasabi.Gui.csproj
</ItemGroup>
<ItemGroup>
- <EmbeddedResource Update="Assets\IndexMain.dat">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </EmbeddedResource>
<EmbeddedResource Include="Extensions\DummyHack.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>

[WIP] label suggestion