save length and history when value done changing

This commit is contained in:
Kyle Spearrin 2019-05-31 09:09:32 -04:00
parent ac6f3a6bb6
commit 8df940447d
5 changed files with 55 additions and 5 deletions

View file

@ -105,6 +105,7 @@
VerticalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"
HorizontalTextAlignment="End" /> HorizontalTextAlignment="End" />
<controls:ExtendedSlider <controls:ExtendedSlider
ValueChanged="LengthSlider_ValueChanged"
Value="{Binding Length}" Value="{Binding Length}"
StyleClass="box-value" StyleClass="box-value"
VerticalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"

View file

@ -23,6 +23,8 @@ namespace Bit.App.Pages
} }
} }
public DateTime LastLengthSliderChange { get; set; } = DateTime.MinValue;
public async Task InitAsync() public async Task InitAsync()
{ {
await _vm.InitAsync(); await _vm.InitAsync();
@ -57,5 +59,13 @@ namespace Bit.App.Pages
var page = new GeneratorHistoryPage(); var page = new GeneratorHistoryPage();
await Navigation.PushModalAsync(new NavigationPage(page)); await Navigation.PushModalAsync(new NavigationPage(page));
} }
private void LengthSlider_ValueChanged(object sender, ValueChangedEventArgs e)
{
if(e.NewValue != e.OldValue)
{
LastLengthSliderChange = DateTime.UtcNow;
}
}
} }
} }

View file

@ -3,7 +3,9 @@ using Bit.App.Utilities;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Models.Domain; using Bit.Core.Models.Domain;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Xamarin.Forms; using Xamarin.Forms;
@ -29,6 +31,7 @@ namespace Bit.App.Pages
private string _wordSeparator; private string _wordSeparator;
private int _typeSelectedIndex; private int _typeSelectedIndex;
private bool _doneIniting; private bool _doneIniting;
private CancellationTokenSource _sliderCancellationTokenSource;
public GeneratorPageViewModel() public GeneratorPageViewModel()
{ {
@ -67,7 +70,7 @@ namespace Bit.App.Pages
if(SetProperty(ref _length, value)) if(SetProperty(ref _length, value))
{ {
_options.Length = value; _options.Length = value;
var task = SaveOptionsAsync(); var task = SaveOptionsSliderAsync();
} }
} }
} }
@ -207,8 +210,7 @@ namespace Bit.App.Pages
{ {
_options = await _passwordGenerationService.GetOptionsAsync(); _options = await _passwordGenerationService.GetOptionsAsync();
LoadFromOptions(); LoadFromOptions();
Password = await _passwordGenerationService.GeneratePasswordAsync(_options); await RegenerateAsync();
await _passwordGenerationService.AddHistoryAsync(Password);
_doneIniting = true; _doneIniting = true;
} }
@ -234,6 +236,39 @@ namespace Bit.App.Pages
} }
} }
public async Task SaveOptionsSliderAsync()
{
if(!_doneIniting)
{
return;
}
SetOptions();
_passwordGenerationService.NormalizeOptions(_options);
LoadFromOptions();
Password = await _passwordGenerationService.GeneratePasswordAsync(_options);
var page = Page as GeneratorPage;
var previousCts = _sliderCancellationTokenSource;
var cts = new CancellationTokenSource();
var task = Task.Run(async () =>
{
await Task.Delay(500);
if(DateTime.UtcNow - page.LastLengthSliderChange < TimeSpan.FromMilliseconds(450))
{
return;
}
else
{
previousCts?.Cancel();
}
cts.Token.ThrowIfCancellationRequested();
await _passwordGenerationService.SaveOptionsAsync(_options);
cts.Token.ThrowIfCancellationRequested();
await _passwordGenerationService.AddHistoryAsync(Password, cts.Token);
}, cts.Token);
_sliderCancellationTokenSource = cts;
}
public async Task CopyAsync() public async Task CopyAsync()
{ {
await _platformUtilsService.CopyToClipboardAsync(Password); await _platformUtilsService.CopyToClipboardAsync(Password);

View file

@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.Core.Models.Domain; using Bit.Core.Models.Domain;
@ -6,7 +7,7 @@ namespace Bit.Core.Abstractions
{ {
public interface IPasswordGenerationService public interface IPasswordGenerationService
{ {
Task AddHistoryAsync(string password); Task AddHistoryAsync(string password, CancellationToken token = default(CancellationToken));
Task ClearAsync(); Task ClearAsync();
Task<string> GeneratePassphraseAsync(PasswordGenerationOptions options); Task<string> GeneratePassphraseAsync(PasswordGenerationOptions options);
Task<string> GeneratePasswordAsync(PasswordGenerationOptions options); Task<string> GeneratePasswordAsync(PasswordGenerationOptions options);

View file

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Bit.Core.Services namespace Bit.Core.Services
@ -240,7 +241,7 @@ namespace Bit.Core.Services
return _history ?? new List<GeneratedPasswordHistory>(); return _history ?? new List<GeneratedPasswordHistory>();
} }
public async Task AddHistoryAsync(string password) public async Task AddHistoryAsync(string password, CancellationToken token = default(CancellationToken))
{ {
var hasKey = await _cryptoService.HasKeyAsync(); var hasKey = await _cryptoService.HasKeyAsync();
if(!hasKey) if(!hasKey)
@ -253,6 +254,7 @@ namespace Bit.Core.Services
{ {
return; return;
} }
token.ThrowIfCancellationRequested();
currentHistory.Insert(0, new GeneratedPasswordHistory { Password = password, Date = DateTime.UtcNow }); currentHistory.Insert(0, new GeneratedPasswordHistory { Password = password, Date = DateTime.UtcNow });
// Remove old items. // Remove old items.
if(currentHistory.Count > MaxPasswordsInHistory) if(currentHistory.Count > MaxPasswordsInHistory)
@ -260,6 +262,7 @@ namespace Bit.Core.Services
currentHistory.RemoveAt(currentHistory.Count - 1); currentHistory.RemoveAt(currentHistory.Count - 1);
} }
var newHistory = await EncryptHistoryAsync(currentHistory); var newHistory = await EncryptHistoryAsync(currentHistory);
token.ThrowIfCancellationRequested();
await _storageService.SaveAsync(Keys_History, newHistory); await _storageService.SaveAsync(Keys_History, newHistory);
} }