From 92b7b1d6039633d22b9bfa367baad2e84948c252 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Mon, 27 Nov 2017 15:05:12 -0500 Subject: [PATCH] handle conditions when no data --- src/App/Pages/Vault/VaultListCiphersPage.cs | 63 ++++++++++++++++--- src/App/Pages/Vault/VaultListGroupingsPage.cs | 23 +++---- src/App/Resources/AppResources.Designer.cs | 18 ++++++ src/App/Resources/AppResources.resx | 6 ++ 4 files changed, 86 insertions(+), 24 deletions(-) diff --git a/src/App/Pages/Vault/VaultListCiphersPage.cs b/src/App/Pages/Vault/VaultListCiphersPage.cs index 66e8ff197..ca0508b49 100644 --- a/src/App/Pages/Vault/VaultListCiphersPage.cs +++ b/src/App/Pages/Vault/VaultListCiphersPage.cs @@ -56,11 +56,12 @@ namespace Bit.App.Pages Init(); } - public ExtendedObservableCollection> PresentationLetters { get; private set; } + public ExtendedObservableCollection> PresentationSections { get; private set; } = new ExtendedObservableCollection>(); public Cipher[] Ciphers { get; set; } = new Cipher[] { }; public ListView ListView { get; set; } public SearchBar Search { get; set; } + public StackLayout NoDataStackLayout { get; set; } public StackLayout ResultsStackLayout { get; set; } private AddCipherToolBarItem AddCipherItem { get; set; } @@ -75,7 +76,7 @@ namespace Bit.App.Pages ListView = new ListView(ListViewCachingStrategy.RecycleElement) { IsGroupingEnabled = true, - ItemsSource = PresentationLetters, + ItemsSource = PresentationSections, HasUnevenRows = true, GroupHeaderTemplate = new DataTemplate(() => new SectionHeaderViewCell(nameof(Section.Name), nameof(Section.Count))), @@ -101,6 +102,41 @@ namespace Bit.App.Pages Search.HeightRequest = 50; } + var noDataLabel = new Label + { + Text = _favorites ? AppResources.NoFavorites : AppResources.NoItems, + HorizontalTextAlignment = TextAlignment.Center, + FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)), + Style = (Style)Application.Current.Resources["text-muted"] + }; + + if(_folder || !string.IsNullOrWhiteSpace(_folderId)) + { + noDataLabel.Text = AppResources.NoItemsFolder; + } + else if(!string.IsNullOrWhiteSpace(_collectionId)) + { + noDataLabel.Text = AppResources.NoItemsCollection; + } + + NoDataStackLayout = new StackLayout + { + Children = { noDataLabel }, + VerticalOptions = LayoutOptions.CenterAndExpand, + Padding = new Thickness(20, 0), + Spacing = 20 + }; + + if(string.IsNullOrWhiteSpace(_collectionId) && !_favorites) + { + NoDataStackLayout.Children.Add(new ExtendedButton + { + Text = AppResources.AddAnItem, + Command = new Command(() => Helpers.AddCipher(this, _folderId)), + Style = (Style)Application.Current.Resources["btn-primaryAccent"] + }); + } + ResultsStackLayout = new StackLayout { Children = { Search, ListView }, @@ -182,7 +218,7 @@ namespace Bit.App.Pages if(string.IsNullOrWhiteSpace(searchFilter)) { - LoadLetters(Ciphers, ct); + LoadSections(Ciphers, ct); } else { @@ -194,7 +230,7 @@ namespace Bit.App.Pages .ToArray(); ct.ThrowIfCancellationRequested(); - LoadLetters(filteredCiphers, ct); + LoadSections(filteredCiphers, ct); } } @@ -248,7 +284,7 @@ namespace Bit.App.Pages private CancellationTokenSource FetchAndLoadVault() { var cts = new CancellationTokenSource(); - if(PresentationLetters.Count > 0 && _syncService.SyncInProgress) + if(PresentationSections.Count > 0 && _syncService.SyncInProgress) { return cts; } @@ -281,7 +317,7 @@ namespace Bit.App.Pages { // Sort numbers and letters before special characters return !string.IsNullOrWhiteSpace(s.Name) && s.Name.Length > 0 && - Char.IsLetterOrDigit(s.Name[0]) ? 0 : 1; + Char.IsDigit(s.Name[0]) ? 0 : Char.IsLetter(s.Name[0]) ? 1 : 2; }) .ThenBy(s => s.Name) .ThenBy(s => s.Subtitle) @@ -297,15 +333,22 @@ namespace Bit.App.Pages return cts; } - private void LoadLetters(Cipher[] ciphers, CancellationToken ct) + private void LoadSections(Cipher[] ciphers, CancellationToken ct) { ct.ThrowIfCancellationRequested(); - var letterGroups = ciphers.GroupBy(c => c.NameGroup).Select(g => new Section(g.ToList(), g.Key)); + var sections = ciphers.GroupBy(c => c.NameGroup).Select(g => new Section(g.ToList(), g.Key)); ct.ThrowIfCancellationRequested(); Device.BeginInvokeOnMainThread(() => { - PresentationLetters.ResetWithRange(letterGroups); - Content = ResultsStackLayout; + PresentationSections.ResetWithRange(sections); + if(PresentationSections.Count > 0 || !string.IsNullOrWhiteSpace(Search.Text)) + { + Content = ResultsStackLayout; + } + else + { + Content = NoDataStackLayout; + } }); } diff --git a/src/App/Pages/Vault/VaultListGroupingsPage.cs b/src/App/Pages/Vault/VaultListGroupingsPage.cs index 7772808f0..1fb03f904 100644 --- a/src/App/Pages/Vault/VaultListGroupingsPage.cs +++ b/src/App/Pages/Vault/VaultListGroupingsPage.cs @@ -90,14 +90,6 @@ namespace Bit.App.Pages Style = (Style)Application.Current.Resources["text-muted"] }; - NoDataStackLayout = new StackLayout - { - Children = { noDataLabel }, - VerticalOptions = LayoutOptions.CenterAndExpand, - Padding = new Thickness(20, 0), - Spacing = 20 - }; - var addCipherButton = new ExtendedButton { Text = AppResources.AddAnItem, @@ -105,7 +97,13 @@ namespace Bit.App.Pages Style = (Style)Application.Current.Resources["btn-primaryAccent"] }; - NoDataStackLayout.Children.Add(addCipherButton); + NoDataStackLayout = new StackLayout + { + Children = { noDataLabel, addCipherButton }, + VerticalOptions = LayoutOptions.CenterAndExpand, + Padding = new Thickness(20, 0), + Spacing = 20 + }; LoadingIndicator = new ActivityIndicator { @@ -225,12 +223,9 @@ namespace Bit.App.Pages Device.BeginInvokeOnMainThread(() => { - if(sections.Any()) - { - PresentationSections.ResetWithRange(sections); - } + PresentationSections.ResetWithRange(sections); - if(PresentationSections.Count > 0) + if(ciphers.Any() || folders.Any()) { Content = ListView; } diff --git a/src/App/Resources/AppResources.Designer.cs b/src/App/Resources/AppResources.Designer.cs index 05d1527cc..ef57dd515 100644 --- a/src/App/Resources/AppResources.Designer.cs +++ b/src/App/Resources/AppResources.Designer.cs @@ -2113,6 +2113,24 @@ namespace Bit.App.Resources { } } + /// + /// Looks up a localized string similar to There are no items in this collection.. + /// + public static string NoItemsCollection { + get { + return ResourceManager.GetString("NoItemsCollection", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to There are no items in this folder.. + /// + public static string NoItemsFolder { + get { + return ResourceManager.GetString("NoItemsFolder", resourceCulture); + } + } + /// /// Looks up a localized string similar to There are no items in your vault for {0}.. /// diff --git a/src/App/Resources/AppResources.resx b/src/App/Resources/AppResources.resx index 9b89bef8a..5ca64ef2f 100644 --- a/src/App/Resources/AppResources.resx +++ b/src/App/Resources/AppResources.resx @@ -1203,4 +1203,10 @@ Default to the "My Vault" page instead of "Favorites" whenever I open the app. + + There are no items in this collection. + + + There are no items in this folder. + \ No newline at end of file