Permalink
Browse files

Merge branch 'words'

  • Loading branch information...
nopara73 committed Nov 8, 2018
2 parents 79fb38b + a31eeab commit 8b5273e90249303fb0e23e05723d72e1890d99ea
@@ -2,20 +2,22 @@
using Avalonia.Controls;
using Avalonia.Xaml.Interactivity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using WalletWasabi.Gui.Tabs.WalletManager;
namespace WalletWasabi.Gui.Behaviors
{
internal class MnemonicSuggestionBehavior : Behavior<TextBox>
{
private CompositeDisposable _disposables;
private static readonly AvaloniaProperty<string> SuggestionItemsProperty =
AvaloniaProperty.Register<MnemonicSuggestionBehavior, string>(nameof(SuggestionItems), defaultBindingMode: Avalonia.Data.BindingMode.TwoWay);
private static readonly AvaloniaProperty<IEnumerable<MnemonicViewModel>> SuggestionItemsProperty =
AvaloniaProperty.Register<MnemonicSuggestionBehavior, IEnumerable<MnemonicViewModel>>(nameof(SuggestionItems), defaultBindingMode: Avalonia.Data.BindingMode.TwoWay);
public string SuggestionItems
public IEnumerable<MnemonicViewModel> SuggestionItems
{
get => GetValue(SuggestionItemsProperty);
set => SetValue(SuggestionItemsProperty, value);
@@ -46,16 +48,7 @@ protected override void OnDetaching()
private void HandleAutoUpdate()
{
var textBox = AssociatedObject;
var text = textBox.Text;
var enteredWordList = text.Split(' ', StringSplitOptions.RemoveEmptyEntries);
var lastWorld = enteredWordList.LastOrDefault();
var suggestions = SuggestionItems.Split(" ", StringSplitOptions.RemoveEmptyEntries);
if(suggestions.Length == 1)
{
textBox.Text = text.Substring(0, text.Length - lastWorld.Length) + suggestions[0] + " ";
textBox.CaretIndex = textBox.Text.Length;
}
SuggestionItems.FirstOrDefault()?.OnSelected();
}
}
}
@@ -0,0 +1,24 @@
using ReactiveUI;
using System;
using System.Collections.Generic;
using System.Linq;
namespace WalletWasabi.Gui.Tabs.WalletManager
{
internal class MnemonicViewModel
{
public string Word { get; }
public Action<string> OnSelection { get; }
public MnemonicViewModel(string word, Action<string> onSeleted)
{
Word = word;
OnSelection = onSeleted;
}
public void OnSelected()
{
OnSelection(Word);
}
}
}
@@ -12,12 +12,23 @@
</StackPanel>
<controls:ExtendedTextBox Text="{Binding WalletName}" Watermark="Wallet Name" UseFloatingWatermark="True" />
<TextBox Text="{Binding Password}" Watermark="Password" PasswordChar="*" UseFloatingWatermark="True" />
<controls:ExtendedTextBox Text="{Binding MnemonicWords}" Watermark="MnemonicWords" UseFloatingWatermark="True" >
<controls:ExtendedTextBox Text="{Binding MnemonicWords}" Watermark="MnemonicWords" UseFloatingWatermark="True" CaretIndex="{Binding CaretIndex, Mode=TwoWay}">
<i:Interaction.Behaviors>
<behaviors:MnemonicSuggestionBehavior SuggestionItems="{Binding Suggestions}" />
</i:Interaction.Behaviors>
</controls:ExtendedTextBox>
<TextBlock Text="{Binding Suggestions}" FontWeight="Bold" />
<ItemsControl Items="{Binding Suggestions}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation ="Horizontal" Spacing="2"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Focusable="False" Content="{Binding Word}" Command="{Binding OnSelected}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
</controls:GroupBox>
@@ -1,11 +1,15 @@
using AvalonStudio.Extensibility;
using Avalonia.Threading;
using AvalonStudio.Extensibility;
using AvalonStudio.Shell;
using NBitcoin;
using ReactiveUI;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using WalletWasabi.Gui.ViewModels;
using WalletWasabi.Helpers;
using WalletWasabi.KeyManagement;
@@ -15,15 +19,18 @@ namespace WalletWasabi.Gui.Tabs.WalletManager
{
internal class RecoverWalletViewModel : CategoryViewModel
{
private int _caretIndex;
private string _password;
private string _mnemonicWords;
private string _walletName;
private bool _termsAccepted;
private string _validationMessage;
private string _suggestions;
private ObservableCollection<MnemonicViewModel> _suggestions;
public RecoverWalletViewModel(WalletManagerViewModel owner) : base("Recover Wallet")
{
MnemonicWords = "";
RecoverCommand = ReactiveCommand.Create(() =>
{
WalletName = Guard.Correct(WalletName);
@@ -77,6 +84,16 @@ public RecoverWalletViewModel(WalletManagerViewModel owner) : base("Recover Wall
}
}
});
this.WhenAnyValue(x => x.CaretIndex).Subscribe(_ =>
{
if (CaretIndex != MnemonicWords.Length)
{
CaretIndex = MnemonicWords.Length;
}
});
_suggestions = new ObservableCollection<MnemonicViewModel>();
}
public string Password
@@ -91,7 +108,7 @@ public string MnemonicWords
set { this.RaiseAndSetIfChanged(ref _mnemonicWords, value); }
}
public string Suggestions
public ObservableCollection<MnemonicViewModel> Suggestions
{
get { return _suggestions; }
set { this.RaiseAndSetIfChanged(ref _suggestions, value); }
@@ -115,6 +132,12 @@ public string ValidationMessage
set { this.RaiseAndSetIfChanged(ref _validationMessage, value); }
}
public int CaretIndex
{
get { return _caretIndex; }
set { this.RaiseAndSetIfChanged(ref _caretIndex, value); }
}
public ReactiveCommand RecoverCommand { get; }
public void OnTermsClicked()
@@ -137,28 +160,54 @@ public override void OnCategorySelected()
base.OnCategorySelected();
Password = null;
MnemonicWords = null;
MnemonicWords = "";
WalletName = Utils.GetNextWalletName();
TermsAccepted = false;
ValidationMessage = null;
}
private void UpdateSuggestions(string words)
{
if (string.IsNullOrEmpty(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 = string.Empty;
_suggestions.Clear();
return;
}
var suggestedWords = EnglishWords.Where(w => w.StartsWith(lastWorld));
Suggestions = string.Join(" ", suggestedWords.ToArray());
var suggestedWords = EnglishWords.Where(w => w.StartsWith(lastWorld)).Take(7);
_suggestions.Clear();
foreach (var suggestion in suggestedWords)
{
_suggestions.Add(new MnemonicViewModel(suggestion, OnAddWord));
}
}
public void OnAddWord(string word)
{
string[] words = MnemonicWords.Split(' ', StringSplitOptions.RemoveEmptyEntries);
if (words.Length == 0)
{
MnemonicWords = word + " ";
}
else
{
words[words.Length - 1] = word;
MnemonicWords = string.Join(' ', words) + " ";
}
CaretIndex = MnemonicWords.Length;
Suggestions.Clear();
}
private static IEnumerable<string> EnglishWords = Wordlist.English.GetWords();

0 comments on commit 8b5273e

Please sign in to comment.