mirror of
https://github.com/bitwarden/android.git
synced 2024-12-24 18:08:26 +03:00
filtered results for groupings and favorites
This commit is contained in:
parent
09412f0b78
commit
4879d906d9
7 changed files with 91 additions and 12 deletions
|
@ -7,6 +7,7 @@ namespace Bit.App.Abstractions
|
||||||
public interface ICipherCollectionRepository
|
public interface ICipherCollectionRepository
|
||||||
{
|
{
|
||||||
Task<IEnumerable<CipherCollectionData>> GetAllByUserIdAsync(string userId);
|
Task<IEnumerable<CipherCollectionData>> GetAllByUserIdAsync(string userId);
|
||||||
|
Task<IEnumerable<CipherCollectionData>> GetAllByUserIdCollectionAsync(string userId, string collectionId);
|
||||||
Task InsertAsync(CipherCollectionData obj);
|
Task InsertAsync(CipherCollectionData obj);
|
||||||
Task DeleteAsync(CipherCollectionData obj);
|
Task DeleteAsync(CipherCollectionData obj);
|
||||||
Task DeleteByUserIdAsync(string userId);
|
Task DeleteByUserIdAsync(string userId);
|
||||||
|
|
|
@ -12,6 +12,8 @@ namespace Bit.App.Abstractions
|
||||||
Task<Cipher> GetByIdAsync(string id);
|
Task<Cipher> GetByIdAsync(string id);
|
||||||
Task<IEnumerable<Cipher>> GetAllAsync();
|
Task<IEnumerable<Cipher>> GetAllAsync();
|
||||||
Task<IEnumerable<Cipher>> GetAllAsync(bool favorites);
|
Task<IEnumerable<Cipher>> GetAllAsync(bool favorites);
|
||||||
|
Task<IEnumerable<Cipher>> GetAllByFolderAsync(string folderId);
|
||||||
|
Task<IEnumerable<Cipher>> GetAllByCollectionAsync(string collectionId);
|
||||||
Task<Tuple<IEnumerable<Cipher>, IEnumerable<Cipher>, IEnumerable<Cipher>>> GetAllAsync(string uriString);
|
Task<Tuple<IEnumerable<Cipher>, IEnumerable<Cipher>, IEnumerable<Cipher>>> GetAllAsync(string uriString);
|
||||||
Task<ApiResult<CipherResponse>> SaveAsync(Cipher cipher);
|
Task<ApiResult<CipherResponse>> SaveAsync(Cipher cipher);
|
||||||
Task UpsertDataAsync(CipherData cipher);
|
Task UpsertDataAsync(CipherData cipher);
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using Bit.App.Controls;
|
using Bit.App.Controls;
|
||||||
using Bit.App.Resources;
|
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Bit.App.Pages
|
namespace Bit.App.Pages
|
||||||
|
@ -12,7 +11,7 @@ namespace Bit.App.Pages
|
||||||
TintColor = Color.FromHex("3c8dbc");
|
TintColor = Color.FromHex("3c8dbc");
|
||||||
|
|
||||||
var settingsNavigation = new ExtendedNavigationPage(new SettingsPage());
|
var settingsNavigation = new ExtendedNavigationPage(new SettingsPage());
|
||||||
var favoritesNavigation = new ExtendedNavigationPage(new VaultListCiphersPage(true));
|
var favoritesNavigation = new ExtendedNavigationPage(new VaultSearchCiphersPage(favorites: true));
|
||||||
var vaultNavigation = new ExtendedNavigationPage(new VaultListGroupingsPage());
|
var vaultNavigation = new ExtendedNavigationPage(new VaultListGroupingsPage());
|
||||||
var toolsNavigation = new ExtendedNavigationPage(new ToolsPage());
|
var toolsNavigation = new ExtendedNavigationPage(new ToolsPage());
|
||||||
|
|
||||||
|
|
|
@ -214,7 +214,7 @@ namespace Bit.App.Pages
|
||||||
return cts;
|
return cts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GroupingSelected(object sender, SelectedItemChangedEventArgs e)
|
private async void GroupingSelected(object sender, SelectedItemChangedEventArgs e)
|
||||||
{
|
{
|
||||||
var grouping = e.SelectedItem as Grouping;
|
var grouping = e.SelectedItem as Grouping;
|
||||||
if(grouping == null)
|
if(grouping == null)
|
||||||
|
@ -222,6 +222,17 @@ namespace Bit.App.Pages
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Page page;
|
||||||
|
if(grouping.Folder)
|
||||||
|
{
|
||||||
|
page = new VaultSearchCiphersPage(folder: true, folderId: grouping.Id, groupingName: grouping.Name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
page = new VaultSearchCiphersPage(collectionId: grouping.Id, groupingName: grouping.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
await Navigation.PushAsync(page);
|
||||||
((ListView)sender).SelectedItem = null;
|
((ListView)sender).SelectedItem = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ using Plugin.Settings.Abstractions;
|
||||||
using Plugin.Connectivity.Abstractions;
|
using Plugin.Connectivity.Abstractions;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using static Bit.App.Models.Page.VaultListPageModel;
|
using static Bit.App.Models.Page.VaultListPageModel;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Bit.App.Pages
|
namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
|
@ -24,10 +25,22 @@ namespace Bit.App.Pages
|
||||||
private readonly IAppSettingsService _appSettingsService;
|
private readonly IAppSettingsService _appSettingsService;
|
||||||
private readonly IGoogleAnalyticsService _googleAnalyticsService;
|
private readonly IGoogleAnalyticsService _googleAnalyticsService;
|
||||||
private CancellationTokenSource _filterResultsCancellationTokenSource;
|
private CancellationTokenSource _filterResultsCancellationTokenSource;
|
||||||
|
private readonly bool _favorites = false;
|
||||||
|
private readonly bool _folder = false;
|
||||||
|
private readonly string _folderId = null;
|
||||||
|
private readonly string _collectionId = null;
|
||||||
|
private readonly string _groupingName = null;
|
||||||
|
|
||||||
public VaultSearchCiphersPage()
|
public VaultSearchCiphersPage(bool folder = false, string folderId = null,
|
||||||
|
string collectionId = null, string groupingName = null, bool favorites = false)
|
||||||
: base(true)
|
: base(true)
|
||||||
{
|
{
|
||||||
|
_folder = folder;
|
||||||
|
_folderId = folderId;
|
||||||
|
_collectionId = collectionId;
|
||||||
|
_favorites = favorites;
|
||||||
|
_groupingName = groupingName;
|
||||||
|
|
||||||
_cipherService = Resolver.Resolve<ICipherService>();
|
_cipherService = Resolver.Resolve<ICipherService>();
|
||||||
_connectivity = Resolver.Resolve<IConnectivity>();
|
_connectivity = Resolver.Resolve<IConnectivity>();
|
||||||
_syncService = Resolver.Resolve<ISyncService>();
|
_syncService = Resolver.Resolve<ISyncService>();
|
||||||
|
@ -83,7 +96,19 @@ namespace Bit.App.Pages
|
||||||
Spacing = 0
|
Spacing = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
Title = AppResources.SearchVault;
|
if(!string.IsNullOrWhiteSpace(_groupingName))
|
||||||
|
{
|
||||||
|
Title = _groupingName;
|
||||||
|
}
|
||||||
|
else if(_favorites)
|
||||||
|
{
|
||||||
|
Title = AppResources.Favorites;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Title = AppResources.SearchVault;
|
||||||
|
}
|
||||||
|
|
||||||
Content = new ActivityIndicator
|
Content = new ActivityIndicator
|
||||||
{
|
{
|
||||||
IsRunning = true,
|
IsRunning = true,
|
||||||
|
@ -177,7 +202,11 @@ namespace Bit.App.Pages
|
||||||
Search.TextChanged += SearchBar_TextChanged;
|
Search.TextChanged += SearchBar_TextChanged;
|
||||||
Search.SearchButtonPressed += SearchBar_SearchButtonPressed;
|
Search.SearchButtonPressed += SearchBar_SearchButtonPressed;
|
||||||
_filterResultsCancellationTokenSource = FetchAndLoadVault();
|
_filterResultsCancellationTokenSource = FetchAndLoadVault();
|
||||||
Search.FocusWithDelay();
|
|
||||||
|
if(!_folder && string.IsNullOrWhiteSpace(_folderId) && string.IsNullOrWhiteSpace(_collectionId) && !_favorites)
|
||||||
|
{
|
||||||
|
Search.FocusWithDelay();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnDisappearing()
|
protected override void OnDisappearing()
|
||||||
|
@ -202,7 +231,23 @@ namespace Bit.App.Pages
|
||||||
|
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
var ciphers = await _cipherService.GetAllAsync();
|
IEnumerable<Models.Cipher> ciphers;
|
||||||
|
if(_folder || !string.IsNullOrWhiteSpace(_folderId))
|
||||||
|
{
|
||||||
|
ciphers = await _cipherService.GetAllByFolderAsync(_folderId);
|
||||||
|
}
|
||||||
|
else if(!string.IsNullOrWhiteSpace(_collectionId))
|
||||||
|
{
|
||||||
|
ciphers = await _cipherService.GetAllByCollectionAsync(_collectionId);
|
||||||
|
}
|
||||||
|
else if(_favorites)
|
||||||
|
{
|
||||||
|
ciphers = await _cipherService.GetAllAsync(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ciphers = await _cipherService.GetAllAsync();
|
||||||
|
}
|
||||||
|
|
||||||
Ciphers = ciphers
|
Ciphers = ciphers
|
||||||
.Select(s => new Cipher(s, _appSettingsService))
|
.Select(s => new Cipher(s, _appSettingsService))
|
||||||
|
|
|
@ -19,6 +19,13 @@ namespace Bit.App.Repositories
|
||||||
return Task.FromResult(cipherCollections);
|
return Task.FromResult(cipherCollections);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task<IEnumerable<CipherCollectionData>> GetAllByUserIdCollectionAsync(string userId, string collectionId)
|
||||||
|
{
|
||||||
|
var cipherCollections = Connection.Table<CipherCollectionData>().Where(
|
||||||
|
f => f.UserId == userId && f.CollectionId == collectionId).Cast<CipherCollectionData>();
|
||||||
|
return Task.FromResult(cipherCollections);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual Task InsertAsync(CipherCollectionData obj)
|
public virtual Task InsertAsync(CipherCollectionData obj)
|
||||||
{
|
{
|
||||||
Connection.Insert(obj);
|
Connection.Insert(obj);
|
||||||
|
|
|
@ -16,6 +16,7 @@ namespace Bit.App.Services
|
||||||
private readonly string[] _ignoredSearchTerms = new string[] { "com", "net", "org", "android",
|
private readonly string[] _ignoredSearchTerms = new string[] { "com", "net", "org", "android",
|
||||||
"io", "co", "uk", "au", "nz", "fr", "de", "tv", "info", "app", "apps", "eu", "me", "dev", "jp", "mobile" };
|
"io", "co", "uk", "au", "nz", "fr", "de", "tv", "info", "app", "apps", "eu", "me", "dev", "jp", "mobile" };
|
||||||
private readonly ICipherRepository _cipherRepository;
|
private readonly ICipherRepository _cipherRepository;
|
||||||
|
private readonly ICipherCollectionRepository _cipherCollectionRepository;
|
||||||
private readonly IAttachmentRepository _attachmentRepository;
|
private readonly IAttachmentRepository _attachmentRepository;
|
||||||
private readonly IAuthService _authService;
|
private readonly IAuthService _authService;
|
||||||
private readonly ICipherApiRepository _cipherApiRepository;
|
private readonly ICipherApiRepository _cipherApiRepository;
|
||||||
|
@ -26,6 +27,7 @@ namespace Bit.App.Services
|
||||||
|
|
||||||
public CipherService(
|
public CipherService(
|
||||||
ICipherRepository cipherRepository,
|
ICipherRepository cipherRepository,
|
||||||
|
ICipherCollectionRepository cipherCollectionRepository,
|
||||||
IAttachmentRepository attachmentRepository,
|
IAttachmentRepository attachmentRepository,
|
||||||
IAuthService authService,
|
IAuthService authService,
|
||||||
ICipherApiRepository cipherApiRepository,
|
ICipherApiRepository cipherApiRepository,
|
||||||
|
@ -33,6 +35,7 @@ namespace Bit.App.Services
|
||||||
ICryptoService cryptoService)
|
ICryptoService cryptoService)
|
||||||
{
|
{
|
||||||
_cipherRepository = cipherRepository;
|
_cipherRepository = cipherRepository;
|
||||||
|
_cipherCollectionRepository = cipherCollectionRepository;
|
||||||
_attachmentRepository = attachmentRepository;
|
_attachmentRepository = attachmentRepository;
|
||||||
_authService = authService;
|
_authService = authService;
|
||||||
_cipherApiRepository = cipherApiRepository;
|
_cipherApiRepository = cipherApiRepository;
|
||||||
|
@ -71,11 +74,22 @@ namespace Bit.App.Services
|
||||||
|
|
||||||
public async Task<IEnumerable<Cipher>> GetAllAsync(bool favorites)
|
public async Task<IEnumerable<Cipher>> GetAllAsync(bool favorites)
|
||||||
{
|
{
|
||||||
var attachmentData = await _attachmentRepository.GetAllByUserIdAsync(_authService.UserId);
|
var ciphers = await GetAllAsync();
|
||||||
var attachmentDict = attachmentData.GroupBy(a => a.LoginId).ToDictionary(g => g.Key, g => g.ToList());
|
return ciphers.Where(c => c.Favorite == favorites);
|
||||||
var data = await _cipherRepository.GetAllByUserIdAsync(_authService.UserId, favorites);
|
}
|
||||||
var cipher = data.Select(f => new Cipher(f, attachmentDict.ContainsKey(f.Id) ? attachmentDict[f.Id] : null));
|
|
||||||
return cipher;
|
public async Task<IEnumerable<Cipher>> GetAllByFolderAsync(string folderId)
|
||||||
|
{
|
||||||
|
var ciphers = await GetAllAsync();
|
||||||
|
return ciphers.Where(c => c.FolderId == folderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<Cipher>> GetAllByCollectionAsync(string collectionId)
|
||||||
|
{
|
||||||
|
var assoc = await _cipherCollectionRepository.GetAllByUserIdCollectionAsync(_authService.UserId, collectionId);
|
||||||
|
var cipherIds = new HashSet<string>(assoc.Select(c => c.CipherId));
|
||||||
|
var ciphers = await GetAllAsync();
|
||||||
|
return ciphers.Where(c => cipherIds.Contains(c.Id));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Tuple<IEnumerable<Cipher>, IEnumerable<Cipher>, IEnumerable<Cipher>>> GetAllAsync(string uriString)
|
public async Task<Tuple<IEnumerable<Cipher>, IEnumerable<Cipher>, IEnumerable<Cipher>>> GetAllAsync(string uriString)
|
||||||
|
|
Loading…
Reference in a new issue