mirror of
https://github.com/bitwarden/android.git
synced 2024-12-25 02:18:27 +03:00
consolidating section header models
This commit is contained in:
parent
362ddd0339
commit
2f2d85576f
4 changed files with 48 additions and 63 deletions
|
@ -183,28 +183,23 @@ namespace Bit.App.Models.Page
|
||||||
public string Name { get; set; } = AppResources.FolderNone;
|
public string Name { get; set; } = AppResources.FolderNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NameGroup : List<Cipher>
|
public class Section<T> : List<T>
|
||||||
{
|
{
|
||||||
public NameGroup(string nameGroup, List<Cipher> ciphers)
|
public Section(List<T> groupItems, string name, bool doUpper = true)
|
||||||
{
|
{
|
||||||
Name = nameGroup.ToUpperInvariant();
|
AddRange(groupItems);
|
||||||
AddRange(ciphers);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name { get; set; }
|
if(doUpper)
|
||||||
}
|
|
||||||
|
|
||||||
public class Section : List<Grouping>
|
|
||||||
{
|
{
|
||||||
public Section(List<Grouping> groupings, string name)
|
|
||||||
{
|
|
||||||
AddRange(groupings);
|
|
||||||
Name = name.ToUpperInvariant();
|
Name = name.ToUpperInvariant();
|
||||||
ItemCount = groupings.Count;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public int ItemCount { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Grouping
|
public class Grouping
|
||||||
|
@ -239,16 +234,5 @@ namespace Bit.App.Models.Page
|
||||||
public bool Folder { get; set; }
|
public bool Folder { get; set; }
|
||||||
public bool Collection { get; set; }
|
public bool Collection { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AutofillGrouping : List<AutofillCipher>
|
|
||||||
{
|
|
||||||
public AutofillGrouping(List<AutofillCipher> logins, string name)
|
|
||||||
{
|
|
||||||
AddRange(logins);
|
|
||||||
Name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name { get; set; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ using System.Threading;
|
||||||
using Bit.App.Models;
|
using Bit.App.Models;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Bit.App.Enums;
|
using Bit.App.Enums;
|
||||||
|
using static Bit.App.Models.Page.VaultListPageModel;
|
||||||
|
|
||||||
namespace Bit.App.Pages
|
namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
|
@ -53,8 +54,8 @@ namespace Bit.App.Pages
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExtendedObservableCollection<VaultListPageModel.AutofillGrouping> PresentationCiphersGroup { get; private set; }
|
public ExtendedObservableCollection<Section<AutofillCipher>> PresentationCiphersGroup { get; private set; }
|
||||||
= new ExtendedObservableCollection<VaultListPageModel.AutofillGrouping>();
|
= new ExtendedObservableCollection<Section<AutofillCipher>>();
|
||||||
public StackLayout NoDataStackLayout { get; set; }
|
public StackLayout NoDataStackLayout { get; set; }
|
||||||
public ListView ListView { get; set; }
|
public ListView ListView { get; set; }
|
||||||
public ActivityIndicator LoadingIndicator { get; set; }
|
public ActivityIndicator LoadingIndicator { get; set; }
|
||||||
|
@ -100,7 +101,7 @@ namespace Bit.App.Pages
|
||||||
ItemsSource = PresentationCiphersGroup,
|
ItemsSource = PresentationCiphersGroup,
|
||||||
HasUnevenRows = true,
|
HasUnevenRows = true,
|
||||||
GroupHeaderTemplate = new DataTemplate(() => new SectionHeaderViewCell(
|
GroupHeaderTemplate = new DataTemplate(() => new SectionHeaderViewCell(
|
||||||
nameof(VaultListPageModel.AutofillGrouping.Name))),
|
nameof(Section<AutofillCipher>.Name))),
|
||||||
ItemTemplate = new DataTemplate(() => new VaultListViewCell(
|
ItemTemplate = new DataTemplate(() => new VaultListViewCell(
|
||||||
(VaultListPageModel.Cipher c) => Helpers.CipherMoreClickedAsync(this, c, true)))
|
(VaultListPageModel.Cipher c) => Helpers.CipherMoreClickedAsync(this, c, true)))
|
||||||
};
|
};
|
||||||
|
@ -165,42 +166,42 @@ namespace Bit.App.Pages
|
||||||
|
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
var autofillGroupings = new List<VaultListPageModel.AutofillGrouping>();
|
var autofillGroupings = new List<Section<AutofillCipher>>();
|
||||||
var ciphers = await _cipherService.GetAllAsync(Uri);
|
var ciphers = await _cipherService.GetAllAsync(Uri);
|
||||||
|
|
||||||
if(_appOptions.FillType.HasValue && _appOptions.FillType.Value != CipherType.Login)
|
if(_appOptions.FillType.HasValue && _appOptions.FillType.Value != CipherType.Login)
|
||||||
{
|
{
|
||||||
var others = ciphers?.Item3.Where(c => c.Type == _appOptions.FillType.Value)
|
var others = ciphers?.Item3.Where(c => c.Type == _appOptions.FillType.Value)
|
||||||
.Select(c => new VaultListPageModel.AutofillCipher(c, _appSettingsService, false))
|
.Select(c => new AutofillCipher(c, _appSettingsService, false))
|
||||||
.OrderBy(s => s.Name)
|
.OrderBy(s => s.Name)
|
||||||
.ThenBy(s => s.Subtitle)
|
.ThenBy(s => s.Subtitle)
|
||||||
.ToList();
|
.ToList();
|
||||||
if(others?.Any() ?? false)
|
if(others?.Any() ?? false)
|
||||||
{
|
{
|
||||||
autofillGroupings.Add(new VaultListPageModel.AutofillGrouping(others, AppResources.Items));
|
autofillGroupings.Add(new Section<AutofillCipher>(others, AppResources.Items));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var normalLogins = ciphers?.Item1
|
var normalLogins = ciphers?.Item1
|
||||||
.Select(l => new VaultListPageModel.AutofillCipher(l, _appSettingsService, false))
|
.Select(l => new AutofillCipher(l, _appSettingsService, false))
|
||||||
.OrderBy(s => s.Name)
|
.OrderBy(s => s.Name)
|
||||||
.ThenBy(s => s.Subtitle)
|
.ThenBy(s => s.Subtitle)
|
||||||
.ToList();
|
.ToList();
|
||||||
if(normalLogins?.Any() ?? false)
|
if(normalLogins?.Any() ?? false)
|
||||||
{
|
{
|
||||||
autofillGroupings.Add(new VaultListPageModel.AutofillGrouping(normalLogins,
|
autofillGroupings.Add(new Section<AutofillCipher>(normalLogins,
|
||||||
AppResources.MatchingItems));
|
AppResources.MatchingItems));
|
||||||
}
|
}
|
||||||
|
|
||||||
var fuzzyLogins = ciphers?.Item2
|
var fuzzyLogins = ciphers?.Item2
|
||||||
.Select(l => new VaultListPageModel.AutofillCipher(l, _appSettingsService, true))
|
.Select(l => new AutofillCipher(l, _appSettingsService, true))
|
||||||
.OrderBy(s => s.Name)
|
.OrderBy(s => s.Name)
|
||||||
.ThenBy(s => s.Subtitle)
|
.ThenBy(s => s.Subtitle)
|
||||||
.ToList();
|
.ToList();
|
||||||
if(fuzzyLogins?.Any() ?? false)
|
if(fuzzyLogins?.Any() ?? false)
|
||||||
{
|
{
|
||||||
autofillGroupings.Add(new VaultListPageModel.AutofillGrouping(fuzzyLogins,
|
autofillGroupings.Add(new Section<AutofillCipher>(fuzzyLogins,
|
||||||
AppResources.PossibleMatchingItems));
|
AppResources.PossibleMatchingItems));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,7 +222,7 @@ namespace Bit.App.Pages
|
||||||
|
|
||||||
private async void CipherSelected(object sender, SelectedItemChangedEventArgs e)
|
private async void CipherSelected(object sender, SelectedItemChangedEventArgs e)
|
||||||
{
|
{
|
||||||
var cipher = e.SelectedItem as VaultListPageModel.AutofillCipher;
|
var cipher = e.SelectedItem as AutofillCipher;
|
||||||
if(cipher == null)
|
if(cipher == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -4,7 +4,6 @@ using System.Threading.Tasks;
|
||||||
using Acr.UserDialogs;
|
using Acr.UserDialogs;
|
||||||
using Bit.App.Abstractions;
|
using Bit.App.Abstractions;
|
||||||
using Bit.App.Controls;
|
using Bit.App.Controls;
|
||||||
using Bit.App.Models.Page;
|
|
||||||
using Bit.App.Resources;
|
using Bit.App.Resources;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using XLabs.Ioc;
|
using XLabs.Ioc;
|
||||||
|
@ -14,6 +13,7 @@ using Plugin.Connectivity.Abstractions;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Bit.App.Enums;
|
using Bit.App.Enums;
|
||||||
|
using static Bit.App.Models.Page.VaultListPageModel;
|
||||||
|
|
||||||
namespace Bit.App.Pages
|
namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
|
@ -52,8 +52,8 @@ namespace Bit.App.Pages
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExtendedObservableCollection<VaultListPageModel.Section> PresentationSections { get; private set; }
|
public ExtendedObservableCollection<Section<Grouping>> PresentationSections { get; private set; }
|
||||||
= new ExtendedObservableCollection<VaultListPageModel.Section>();
|
= new ExtendedObservableCollection<Section<Grouping>>();
|
||||||
public ListView ListView { get; set; }
|
public ListView ListView { get; set; }
|
||||||
public StackLayout NoDataStackLayout { get; set; }
|
public StackLayout NoDataStackLayout { get; set; }
|
||||||
public ActivityIndicator LoadingIndicator { get; set; }
|
public ActivityIndicator LoadingIndicator { get; set; }
|
||||||
|
@ -73,7 +73,7 @@ namespace Bit.App.Pages
|
||||||
ItemsSource = PresentationSections,
|
ItemsSource = PresentationSections,
|
||||||
HasUnevenRows = true,
|
HasUnevenRows = true,
|
||||||
GroupHeaderTemplate = new DataTemplate(() => new SectionHeaderViewCell(
|
GroupHeaderTemplate = new DataTemplate(() => new SectionHeaderViewCell(
|
||||||
nameof(VaultListPageModel.Section.Name), nameof(VaultListPageModel.Section.ItemCount),
|
nameof(Section<Grouping>.Name), nameof(Section<Grouping>.Count),
|
||||||
new Thickness(16, Helpers.OnPlatform(20, 12, 12), 16, 12))),
|
new Thickness(16, Helpers.OnPlatform(20, 12, 12), 16, 12))),
|
||||||
ItemTemplate = new DataTemplate(() => new VaultGroupingViewCell())
|
ItemTemplate = new DataTemplate(() => new VaultGroupingViewCell())
|
||||||
};
|
};
|
||||||
|
@ -154,7 +154,7 @@ namespace Bit.App.Pages
|
||||||
|
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
var sections = new List<VaultListPageModel.Section>();
|
var sections = new List<Section<Grouping>>();
|
||||||
var ciphers = await _cipherService.GetAllAsync();
|
var ciphers = await _cipherService.GetAllAsync();
|
||||||
var collectionsDict = (await _collectionService.GetAllCipherAssociationsAsync())
|
var collectionsDict = (await _collectionService.GetAllCipherAssociationsAsync())
|
||||||
.GroupBy(c => c.Item2).ToDictionary(g => g.Key, v => v.ToList());
|
.GroupBy(c => c.Item2).ToDictionary(g => g.Key, v => v.ToList());
|
||||||
|
@ -178,19 +178,19 @@ namespace Bit.App.Pages
|
||||||
|
|
||||||
var folders = await _folderService.GetAllAsync();
|
var folders = await _folderService.GetAllAsync();
|
||||||
var folderGroupings = folders?
|
var folderGroupings = folders?
|
||||||
.Select(f => new VaultListPageModel.Grouping(f, folderCounts.ContainsKey(f.Id) ? folderCounts[f.Id] : 0))
|
.Select(f => new Grouping(f, folderCounts.ContainsKey(f.Id) ? folderCounts[f.Id] : 0))
|
||||||
.OrderBy(g => g.Name).ToList();
|
.OrderBy(g => g.Name).ToList();
|
||||||
folderGroupings.Add(new VaultListPageModel.Grouping(AppResources.FolderNone, folderCounts["none"]));
|
folderGroupings.Add(new Grouping(AppResources.FolderNone, folderCounts["none"]));
|
||||||
sections.Add(new VaultListPageModel.Section(folderGroupings, AppResources.Folders));
|
sections.Add(new Section<Grouping>(folderGroupings, AppResources.Folders));
|
||||||
|
|
||||||
var collections = await _collectionService.GetAllAsync();
|
var collections = await _collectionService.GetAllAsync();
|
||||||
var collectionGroupings = collections?
|
var collectionGroupings = collections?
|
||||||
.Select(c => new VaultListPageModel.Grouping(c,
|
.Select(c => new Grouping(c,
|
||||||
collectionsDict.ContainsKey(c.Id) ? collectionsDict[c.Id].Count() : 0))
|
collectionsDict.ContainsKey(c.Id) ? collectionsDict[c.Id].Count() : 0))
|
||||||
.OrderBy(g => g.Name).ToList();
|
.OrderBy(g => g.Name).ToList();
|
||||||
if(collectionGroupings?.Any() ?? false)
|
if(collectionGroupings?.Any() ?? false)
|
||||||
{
|
{
|
||||||
sections.Add(new VaultListPageModel.Section(collectionGroupings, AppResources.Collections));
|
sections.Add(new Section<Grouping>(collectionGroupings, AppResources.Collections));
|
||||||
}
|
}
|
||||||
|
|
||||||
Device.BeginInvokeOnMainThread(() =>
|
Device.BeginInvokeOnMainThread(() =>
|
||||||
|
@ -216,7 +216,7 @@ namespace Bit.App.Pages
|
||||||
|
|
||||||
private void GroupingSelected(object sender, SelectedItemChangedEventArgs e)
|
private void GroupingSelected(object sender, SelectedItemChangedEventArgs e)
|
||||||
{
|
{
|
||||||
var grouping = e.SelectedItem as VaultListPageModel.Grouping;
|
var grouping = e.SelectedItem as Grouping;
|
||||||
if(grouping == null)
|
if(grouping == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -3,7 +3,6 @@ using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.App.Abstractions;
|
using Bit.App.Abstractions;
|
||||||
using Bit.App.Controls;
|
using Bit.App.Controls;
|
||||||
using Bit.App.Models.Page;
|
|
||||||
using Bit.App.Resources;
|
using Bit.App.Resources;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using XLabs.Ioc;
|
using XLabs.Ioc;
|
||||||
|
@ -11,6 +10,7 @@ using Bit.App.Utilities;
|
||||||
using Plugin.Settings.Abstractions;
|
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;
|
||||||
|
|
||||||
namespace Bit.App.Pages
|
namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
|
@ -39,9 +39,9 @@ namespace Bit.App.Pages
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExtendedObservableCollection<VaultListPageModel.NameGroup> PresentationLetters { get; private set; }
|
public ExtendedObservableCollection<Section<Cipher>> PresentationLetters { get; private set; }
|
||||||
= new ExtendedObservableCollection<VaultListPageModel.NameGroup>();
|
= new ExtendedObservableCollection<Section<Cipher>>();
|
||||||
public VaultListPageModel.Cipher[] Ciphers { get; set; } = new VaultListPageModel.Cipher[] { };
|
public Cipher[] Ciphers { get; set; } = new Cipher[] { };
|
||||||
public ListView ListView { get; set; }
|
public ListView ListView { get; set; }
|
||||||
public SearchBar Search { get; set; }
|
public SearchBar Search { get; set; }
|
||||||
public StackLayout ResultsStackLayout { get; set; }
|
public StackLayout ResultsStackLayout { get; set; }
|
||||||
|
@ -53,10 +53,11 @@ namespace Bit.App.Pages
|
||||||
IsGroupingEnabled = true,
|
IsGroupingEnabled = true,
|
||||||
ItemsSource = PresentationLetters,
|
ItemsSource = PresentationLetters,
|
||||||
HasUnevenRows = true,
|
HasUnevenRows = true,
|
||||||
GroupHeaderTemplate = new DataTemplate(() => new SectionHeaderViewCell(
|
GroupHeaderTemplate = new DataTemplate(() => new SectionHeaderViewCell(nameof(Section<Cipher>.Name),
|
||||||
nameof(VaultListPageModel.NameGroup.Name), nameof(VaultListPageModel.NameGroup.Count))),
|
nameof(Section<Cipher>.Count))),
|
||||||
|
GroupShortNameBinding = new Binding(nameof(Section<Cipher>.Name)),
|
||||||
ItemTemplate = new DataTemplate(() => new VaultListViewCell(
|
ItemTemplate = new DataTemplate(() => new VaultListViewCell(
|
||||||
(VaultListPageModel.Cipher c) => Helpers.CipherMoreClickedAsync(this, c, false)))
|
(Cipher c) => Helpers.CipherMoreClickedAsync(this, c, false)))
|
||||||
};
|
};
|
||||||
|
|
||||||
if(Device.RuntimePlatform == Device.iOS)
|
if(Device.RuntimePlatform == Device.iOS)
|
||||||
|
@ -204,7 +205,7 @@ namespace Bit.App.Pages
|
||||||
var ciphers = await _cipherService.GetAllAsync();
|
var ciphers = await _cipherService.GetAllAsync();
|
||||||
|
|
||||||
Ciphers = ciphers
|
Ciphers = ciphers
|
||||||
.Select(s => new VaultListPageModel.Cipher(s, _appSettingsService))
|
.Select(s => new Cipher(s, _appSettingsService))
|
||||||
.OrderBy(s =>
|
.OrderBy(s =>
|
||||||
{
|
{
|
||||||
// Sort numbers and letters before special characters
|
// Sort numbers and letters before special characters
|
||||||
|
@ -225,11 +226,10 @@ namespace Bit.App.Pages
|
||||||
return cts;
|
return cts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadLetters(VaultListPageModel.Cipher[] ciphers, CancellationToken ct)
|
private void LoadLetters(Cipher[] ciphers, CancellationToken ct)
|
||||||
{
|
{
|
||||||
ct.ThrowIfCancellationRequested();
|
ct.ThrowIfCancellationRequested();
|
||||||
var letterGroups = ciphers.GroupBy(c => c.NameGroup)
|
var letterGroups = ciphers.GroupBy(c => c.NameGroup).Select(g => new Section<Cipher>(g.ToList(), g.Key));
|
||||||
.Select(g => new VaultListPageModel.NameGroup(g.Key, g.ToList()));
|
|
||||||
ct.ThrowIfCancellationRequested();
|
ct.ThrowIfCancellationRequested();
|
||||||
Device.BeginInvokeOnMainThread(() =>
|
Device.BeginInvokeOnMainThread(() =>
|
||||||
{
|
{
|
||||||
|
@ -240,7 +240,7 @@ namespace Bit.App.Pages
|
||||||
|
|
||||||
private async void CipherSelected(object sender, SelectedItemChangedEventArgs e)
|
private async void CipherSelected(object sender, SelectedItemChangedEventArgs e)
|
||||||
{
|
{
|
||||||
var cipher = e.SelectedItem as VaultListPageModel.Cipher;
|
var cipher = e.SelectedItem as Cipher;
|
||||||
if(cipher == null)
|
if(cipher == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in a new issue