generator UI elements

This commit is contained in:
Kyle Spearrin 2019-05-13 14:43:23 -04:00
parent 28473dd85f
commit 018a7c9f96
3 changed files with 351 additions and 42 deletions

View file

@ -22,35 +22,174 @@
Order="Secondary" />
</ContentPage.ToolbarItems>
<StackLayout Spacing="20">
<StackLayout StyleClass="box">
<controls:MonoLabel
Text="{Binding Password}"
Margin="0, 20"
StyleClass="text-lg"
HorizontalOptions="Center" />
<StackLayout Orientation="Horizontal">
<Button Text="{u:I18n RegeneratePassword}"
HorizontalOptions="FillAndExpand"
Clicked="Regenerate_Clicked"></Button>
<Button Text="{u:I18n CopyPassword}"
HorizontalOptions="FillAndExpand"
Clicked="Copy_Clicked"></Button>
<ContentPage.Resources>
<ResourceDictionary>
<u:InverseBoolConverter x:Key="inverseBool" />
</ResourceDictionary>
</ContentPage.Resources>
<ScrollView>
<StackLayout Spacing="20">
<StackLayout StyleClass="box">
<controls:MonoLabel
Text="{Binding Password}"
Margin="0, 20"
StyleClass="text-lg"
HorizontalOptions="Center" />
<StackLayout Orientation="Horizontal">
<Button Text="{u:I18n RegeneratePassword}"
HorizontalOptions="FillAndExpand"
Clicked="Regenerate_Clicked"></Button>
<Button Text="{u:I18n CopyPassword}"
HorizontalOptions="FillAndExpand"
Clicked="Copy_Clicked"></Button>
</StackLayout>
</StackLayout>
<StackLayout StyleClass="box-row-header">
<Label Text="{u:I18n Options}"
StyleClass="box-header, box-header-platform" />
</StackLayout>
<StackLayout StyleClass="box-row, box-row-input">
<Label
Text="{u:I18n Type}"
StyleClass="box-label" />
<Picker
ItemsSource="{Binding TypeOptions, Mode=OneTime}"
SelectedIndex="{Binding TypeSelectedIndex}"
StyleClass="box-value" />
<StackLayout StyleClass="box">
<StackLayout StyleClass="box-row-header">
<Label Text="{u:I18n Options}"
StyleClass="box-header, box-header-platform" />
</StackLayout>
<StackLayout StyleClass="box-row, box-row-input">
<Label
Text="{u:I18n Type}"
StyleClass="box-label" />
<Picker
ItemsSource="{Binding TypeOptions, Mode=OneTime}"
SelectedIndex="{Binding TypeSelectedIndex}"
StyleClass="box-value" />
</StackLayout>
<StackLayout Spacing="0"
Padding="0"
IsVisible="{Binding IsPassword, Converter={StaticResource inverseBool}}">
<StackLayout StyleClass="box-row, box-row-stepper">
<Label
Text="{u:I18n NumberOfWords}"
StyleClass="box-label, box-label-regular"
VerticalOptions="FillAndExpand"
VerticalTextAlignment="Center" />
<Label
Text="{Binding NumWords}"
StyleClass="box-label, box-sub-label"
HorizontalOptions="FillAndExpand"
HorizontalTextAlignment="End"
VerticalOptions="FillAndExpand"
VerticalTextAlignment="Center" />
<Stepper
Value="{Binding NumWords}"
Minimum="3"
Maximum="20"
Increment="1" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
<StackLayout StyleClass="box-row, box-row-input">
<Label
Text="{u:I18n WordSeparator}"
StyleClass="box-label" />
<Entry
Text="{Binding WordSeparator}"
StyleClass="box-value" />
</StackLayout>
</StackLayout>
<StackLayout Spacing="0" Padding="0" IsVisible="{Binding IsPassword}">
<StackLayout StyleClass="box-row, box-row-switch">
<Label
Text="A-Z"
StyleClass="box-label, box-label-regular"
HorizontalOptions="StartAndExpand" />
<Switch
IsToggled="{Binding Uppercase}"
StyleClass="box-value"
HorizontalOptions="End" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
<StackLayout StyleClass="box-row, box-row-switch">
<Label
Text="a-z"
StyleClass="box-label, box-label-regular"
HorizontalOptions="StartAndExpand" />
<Switch
IsToggled="{Binding Lowercase}"
StyleClass="box-value"
HorizontalOptions="End" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
<StackLayout StyleClass="box-row, box-row-switch">
<Label
Text="0-9"
StyleClass="box-label, box-label-regular"
HorizontalOptions="StartAndExpand" />
<Switch
IsToggled="{Binding Number}"
StyleClass="box-value"
HorizontalOptions="End" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
<StackLayout StyleClass="box-row, box-row-switch">
<Label
Text="!@#$%^&amp;*"
StyleClass="box-label, box-label-regular"
HorizontalOptions="StartAndExpand" />
<Switch
IsToggled="{Binding Special}"
StyleClass="box-value"
HorizontalOptions="End" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
<StackLayout StyleClass="box-row, box-row-stepper">
<Label
Text="{u:I18n MinNumbers}"
StyleClass="box-label, box-label-regular"
VerticalOptions="FillAndExpand"
VerticalTextAlignment="Center" />
<Label
Text="{Binding MinNumber}"
StyleClass="box-label, box-sub-label"
HorizontalOptions="FillAndExpand"
HorizontalTextAlignment="End"
VerticalOptions="FillAndExpand"
VerticalTextAlignment="Center" />
<Stepper
Value="{Binding MinNumber}"
Minimum="0"
Maximum="5"
Increment="1" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
<StackLayout StyleClass="box-row, box-row-stepper">
<Label
Text="{u:I18n MinSpecial}"
StyleClass="box-label, box-label-regular"
VerticalOptions="FillAndExpand"
VerticalTextAlignment="Center" />
<Label
Text="{Binding MinSpecial}"
StyleClass="box-label, box-sub-label"
HorizontalOptions="FillAndExpand"
HorizontalTextAlignment="End"
VerticalOptions="FillAndExpand"
VerticalTextAlignment="Center" />
<Stepper
Value="{Binding MinSpecial}"
Minimum="0"
Maximum="5"
Increment="1" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
<StackLayout StyleClass="box-row, box-row-switch">
<Label
Text="{u:I18n AvoidAmbiguousCharacters}"
StyleClass="box-label, box-label-regular"
HorizontalOptions="StartAndExpand" />
<Switch
IsToggled="{Binding AvoidAmbiguous}"
StyleClass="box-value"
HorizontalOptions="End" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
</StackLayout>
</StackLayout>
</StackLayout>
</StackLayout>
</ScrollView>
</pages:BaseContentPage>

View file

@ -2,9 +2,7 @@
using Bit.Core.Abstractions;
using Bit.Core.Models.Domain;
using Bit.Core.Utilities;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace Bit.App.Pages
@ -17,7 +15,18 @@ namespace Bit.App.Pages
private PasswordGenerationOptions _options;
private string _password;
private bool _isPassword;
private bool _uppercase;
private bool _lowercase;
private bool _number;
private bool _special;
private bool _avoidAmbiguous;
private int _minNumber;
private int _minSpecial;
private int _length;
private int _numWords;
private string _wordSeparator;
private int _typeSelectedIndex;
private bool _doneIniting;
public GeneratorPageViewModel()
{
@ -42,10 +51,134 @@ namespace Bit.App.Pages
set => SetProperty(ref _isPassword, value);
}
public PasswordGenerationOptions Options
public int Length
{
get => _options;
set => SetProperty(ref _options, value);
get => _length;
set
{
if(SetProperty(ref _length, value))
{
_options.Length = value;
var task = SaveOptionsAsync();
}
}
}
public bool Uppercase
{
get => _uppercase;
set
{
if(SetProperty(ref _uppercase, value))
{
_options.Uppercase = value;
var task = SaveOptionsAsync();
}
}
}
public bool Lowercase
{
get => _lowercase;
set
{
if(SetProperty(ref _lowercase, value))
{
_options.Lowercase = value;
var task = SaveOptionsAsync();
}
}
}
public bool Number
{
get => _number;
set
{
if(SetProperty(ref _number, value))
{
_options.Number = value;
var task = SaveOptionsAsync();
}
}
}
public bool Special
{
get => _special;
set
{
if(SetProperty(ref _special, value))
{
_options.Special = value;
var task = SaveOptionsAsync();
}
}
}
public bool AvoidAmbiguous
{
get => _avoidAmbiguous;
set
{
if(SetProperty(ref _avoidAmbiguous, value))
{
_options.Ambiguous = !value;
var task = SaveOptionsAsync();
}
}
}
public int MinNumber
{
get => _minNumber;
set
{
if(SetProperty(ref _minNumber, value))
{
_options.MinNumber = value;
var task = SaveOptionsAsync();
}
}
}
public int MinSpecial
{
get => _minSpecial;
set
{
if(SetProperty(ref _minSpecial, value))
{
_options.MinSpecial = value;
var task = SaveOptionsAsync();
}
}
}
public int NumWords
{
get => _numWords;
set
{
if(SetProperty(ref _numWords, value))
{
_options.NumWords = value;
var task = SaveOptionsAsync();
}
}
}
public string WordSeparator
{
get => _wordSeparator;
set
{
if(SetProperty(ref _wordSeparator, value))
{
_options.WordSeparator = value;
var task = SaveOptionsAsync();
}
}
}
public int TypeSelectedIndex
@ -55,29 +188,37 @@ namespace Bit.App.Pages
{
if(SetProperty(ref _typeSelectedIndex, value))
{
TypeChanged();
IsPassword = value == 0;
var task = SaveOptionsAsync();
}
}
}
public async Task InitAsync()
{
Options = await _passwordGenerationService.GetOptionsAsync();
TypeSelectedIndex = Options.Type == "passphrase" ? 1 : 0;
Password = await _passwordGenerationService.GeneratePasswordAsync(Options);
_options = await _passwordGenerationService.GetOptionsAsync();
LoadFromOptions();
Password = await _passwordGenerationService.GeneratePasswordAsync(_options);
await _passwordGenerationService.AddHistoryAsync(Password);
_doneIniting = true;
}
public async Task RegenerateAsync()
{
Password = await _passwordGenerationService.GeneratePasswordAsync(Options);
Password = await _passwordGenerationService.GeneratePasswordAsync(_options);
await _passwordGenerationService.AddHistoryAsync(Password);
}
public async Task SaveOptionsAsync(bool regenerate = true)
{
_passwordGenerationService.NormalizeOptions(Options);
await _passwordGenerationService.SaveOptionsAsync(Options);
if(!_doneIniting)
{
return;
}
SetOptions();
_passwordGenerationService.NormalizeOptions(_options);
await _passwordGenerationService.SaveOptionsAsync(_options);
LoadFromOptions();
if(regenerate)
{
await RegenerateAsync();
@ -90,11 +231,33 @@ namespace Bit.App.Pages
_platformUtilsService.ShowToast("success", null, AppResources.CopiedPassword);
}
public async void TypeChanged()
private void LoadFromOptions()
{
AvoidAmbiguous = !_options.Ambiguous.GetValueOrDefault();
TypeSelectedIndex = _options.Type == "passphrase" ? 1 : 0;
IsPassword = TypeSelectedIndex == 0;
Options.Type = IsPassword ? "password" : "passphrase";
await SaveOptionsAsync();
MinNumber = _options.MinNumber.GetValueOrDefault();
MinSpecial = _options.MinSpecial.GetValueOrDefault();
Special = _options.Special.GetValueOrDefault();
Number = _options.Number.GetValueOrDefault();
NumWords = _options.NumWords.GetValueOrDefault();
WordSeparator = _options.WordSeparator;
Uppercase = _options.Uppercase.GetValueOrDefault();
Lowercase = _options.Lowercase.GetValueOrDefault();
}
private void SetOptions()
{
_options.Ambiguous = !AvoidAmbiguous;
_options.Type = TypeSelectedIndex == 1 ? "passphrase" : "password";
_options.MinNumber = MinNumber;
_options.MinSpecial = MinSpecial;
_options.Special = Special;
_options.NumWords = NumWords;
_options.Number = Number;
_options.WordSeparator = WordSeparator;
_options.Uppercase = Uppercase;
_options.Lowercase = Lowercase;
}
}
}

View file

@ -257,6 +257,13 @@
<Setter Property="Orientation"
Value="Horizontal" />
</Style>
<Style TargetType="StackLayout"
Class="box-row-stepper">
<Setter Property="Orientation"
Value="Horizontal" />
<Setter Property="Spacing"
Value="10" />
</Style>
<Style TargetType="Button"
ApplyToDerivedTypes="True"
Class="box-row-button">