mirror of
https://github.com/bitwarden/android.git
synced 2024-12-21 00:31:58 +03:00
Added task cancellation to vault list so that search filtering tasks do not stack.
This commit is contained in:
parent
2180fb6728
commit
ee867df0be
1 changed files with 84 additions and 19 deletions
|
@ -14,6 +14,7 @@ using PushNotification.Plugin.Abstractions;
|
||||||
using Plugin.Settings.Abstractions;
|
using Plugin.Settings.Abstractions;
|
||||||
using Plugin.Connectivity.Abstractions;
|
using Plugin.Connectivity.Abstractions;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace Bit.App.Pages
|
namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
|
@ -29,6 +30,7 @@ namespace Bit.App.Pages
|
||||||
private readonly ISettings _settings;
|
private readonly ISettings _settings;
|
||||||
private readonly bool _favorites;
|
private readonly bool _favorites;
|
||||||
private bool _loadExistingData;
|
private bool _loadExistingData;
|
||||||
|
private CancellationTokenSource _filterResultsCancellationTokenSource;
|
||||||
|
|
||||||
public VaultListSitesPage(bool favorites)
|
public VaultListSitesPage(bool favorites)
|
||||||
: base(true)
|
: base(true)
|
||||||
|
@ -62,7 +64,7 @@ namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
if(success)
|
if(success)
|
||||||
{
|
{
|
||||||
FetchAndLoadVault();
|
_filterResultsCancellationTokenSource = FetchAndLoadVault();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -106,7 +108,7 @@ namespace Bit.App.Pages
|
||||||
|
|
||||||
private void SearchBar_SearchButtonPressed(object sender, EventArgs e)
|
private void SearchBar_SearchButtonPressed(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
FilterResultsBackground(((SearchBar)sender).Text);
|
_filterResultsCancellationTokenSource = FilterResultsBackground(((SearchBar)sender).Text, _filterResultsCancellationTokenSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SearchBar_TextChanged(object sender, TextChangedEventArgs e)
|
private void SearchBar_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
@ -118,11 +120,12 @@ namespace Bit.App.Pages
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FilterResultsBackground(e.NewTextValue);
|
_filterResultsCancellationTokenSource = FilterResultsBackground(e.NewTextValue, _filterResultsCancellationTokenSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FilterResultsBackground(string searchFilter)
|
private CancellationTokenSource FilterResultsBackground(string searchFilter, CancellationTokenSource previousCts)
|
||||||
{
|
{
|
||||||
|
var cts = new CancellationTokenSource();
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
if(!string.IsNullOrWhiteSpace(searchFilter))
|
if(!string.IsNullOrWhiteSpace(searchFilter))
|
||||||
|
@ -132,23 +135,47 @@ namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
|
||||||
FilterResults(searchFilter);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void FilterResults(string searchFilter)
|
|
||||||
{
|
{
|
||||||
|
previousCts?.Cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FilterResults(searchFilter, cts.Token);
|
||||||
|
}
|
||||||
|
catch(OperationCanceledException) { }
|
||||||
|
}, cts.Token);
|
||||||
|
|
||||||
|
return cts;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FilterResults(string searchFilter, CancellationToken ct)
|
||||||
|
{
|
||||||
|
if(ct.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
throw new OperationCanceledException(ct);
|
||||||
|
}
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(searchFilter))
|
if(string.IsNullOrWhiteSpace(searchFilter))
|
||||||
{
|
{
|
||||||
LoadFolders(Sites);
|
LoadFolders(Sites, ct);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
searchFilter = searchFilter.ToLower();
|
searchFilter = searchFilter.ToLower();
|
||||||
var filteredSites = Sites.Where(s => s.Name.ToLower().Contains(searchFilter) || s.Username.ToLower().Contains(searchFilter));
|
var filteredSites = Sites
|
||||||
LoadFolders(filteredSites);
|
.Where(s => s.Name.ToLower().Contains(searchFilter) || s.Username.ToLower().Contains(searchFilter))
|
||||||
|
.TakeWhile(s => !ct.IsCancellationRequested)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if(ct.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
throw new OperationCanceledException(ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadFolders(filteredSites, ct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +184,7 @@ namespace Bit.App.Pages
|
||||||
base.OnAppearing();
|
base.OnAppearing();
|
||||||
if(_loadExistingData)
|
if(_loadExistingData)
|
||||||
{
|
{
|
||||||
FetchAndLoadVault();
|
_filterResultsCancellationTokenSource = FetchAndLoadVault();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_connectivity.IsConnected && Device.OS == TargetPlatform.iOS && !_favorites)
|
if(_connectivity.IsConnected && Device.OS == TargetPlatform.iOS && !_favorites)
|
||||||
|
@ -192,14 +219,15 @@ namespace Bit.App.Pages
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FetchAndLoadVault()
|
private CancellationTokenSource FetchAndLoadVault()
|
||||||
{
|
{
|
||||||
|
var cts = new CancellationTokenSource();
|
||||||
_settings.AddOrUpdateValue(Constants.FirstVaultLoad, false);
|
_settings.AddOrUpdateValue(Constants.FirstVaultLoad, false);
|
||||||
_loadExistingData = true;
|
_loadExistingData = true;
|
||||||
|
|
||||||
if(PresentationFolders.Count > 0 && _syncService.SyncInProgress)
|
if(PresentationFolders.Count > 0 && _syncService.SyncInProgress)
|
||||||
{
|
{
|
||||||
return;
|
return cts;
|
||||||
}
|
}
|
||||||
|
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
|
@ -214,11 +242,17 @@ namespace Bit.App.Pages
|
||||||
Folders = folders.Select(f => new VaultListPageModel.Folder(f)).OrderBy(s => s.Name);
|
Folders = folders.Select(f => new VaultListPageModel.Folder(f)).OrderBy(s => s.Name);
|
||||||
Sites = sites.Select(s => new VaultListPageModel.Site(s)).OrderBy(s => s.Name).ThenBy(s => s.Username);
|
Sites = sites.Select(s => new VaultListPageModel.Site(s)).OrderBy(s => s.Name).ThenBy(s => s.Username);
|
||||||
|
|
||||||
FilterResults(Search.Text);
|
try
|
||||||
});
|
{
|
||||||
|
FilterResults(Search.Text, cts.Token);
|
||||||
|
}
|
||||||
|
catch(OperationCanceledException) { }
|
||||||
|
}, cts.Token);
|
||||||
|
|
||||||
|
return cts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadFolders(IEnumerable<VaultListPageModel.Site> sites)
|
private void LoadFolders(IEnumerable<VaultListPageModel.Site> sites, CancellationToken ct)
|
||||||
{
|
{
|
||||||
var folders = new List<VaultListPageModel.Folder>(Folders);
|
var folders = new List<VaultListPageModel.Folder>(Folders);
|
||||||
|
|
||||||
|
@ -228,13 +262,44 @@ namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
folder.Clear();
|
folder.Clear();
|
||||||
}
|
}
|
||||||
folder.AddRange(sites.Where(s => s.FolderId == folder.Id));
|
|
||||||
|
var sitesToAdd = sites
|
||||||
|
.Where(s => s.FolderId == folder.Id)
|
||||||
|
.TakeWhile(s => !ct.IsCancellationRequested)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if(ct.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
throw new OperationCanceledException(ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
var noneFolder = new VaultListPageModel.Folder(sites.Where(s => s.FolderId == null));
|
folder.AddRange(sitesToAdd);
|
||||||
|
}
|
||||||
|
|
||||||
|
var noneToAdd = sites
|
||||||
|
.Where(s => s.FolderId == null)
|
||||||
|
.TakeWhile(s => !ct.IsCancellationRequested)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if(ct.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
throw new OperationCanceledException(ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
var noneFolder = new VaultListPageModel.Folder(noneToAdd);
|
||||||
folders.Add(noneFolder);
|
folders.Add(noneFolder);
|
||||||
|
|
||||||
PresentationFolders.ResetWithRange(folders.Where(f => f.Any()));
|
var foldersToAdd = folders
|
||||||
|
.Where(f => f.Any())
|
||||||
|
.TakeWhile(s => !ct.IsCancellationRequested)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if(ct.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
throw new OperationCanceledException(ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
PresentationFolders.ResetWithRange(foldersToAdd);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SiteSelected(object sender, SelectedItemChangedEventArgs e)
|
private void SiteSelected(object sender, SelectedItemChangedEventArgs e)
|
||||||
|
|
Loading…
Reference in a new issue