diff --git a/src/App/Controls/FormEditorCell.cs b/src/App/Controls/FormEditorCell.cs index 52eb890f1..7deb902a4 100644 --- a/src/App/Controls/FormEditorCell.cs +++ b/src/App/Controls/FormEditorCell.cs @@ -20,7 +20,7 @@ namespace Bit.App.Controls var stackLayout = new StackLayout { - Padding = new Thickness(15) + Padding = new Thickness(15, 10) }; stackLayout.Children.Add(Editor); diff --git a/src/App/Controls/FormEntryCell.cs b/src/App/Controls/FormEntryCell.cs index 04c23457c..5c17ad8c5 100644 --- a/src/App/Controls/FormEntryCell.cs +++ b/src/App/Controls/FormEntryCell.cs @@ -32,7 +32,7 @@ namespace Bit.App.Controls var stackLayout = new StackLayout { - Padding = new Thickness(15) + Padding = new Thickness(15, 10) }; stackLayout.Children.Add(Label); diff --git a/src/App/Controls/FormPickerCell.cs b/src/App/Controls/FormPickerCell.cs index b6574681b..759d23d62 100644 --- a/src/App/Controls/FormPickerCell.cs +++ b/src/App/Controls/FormPickerCell.cs @@ -30,7 +30,7 @@ namespace Bit.App.Controls var stackLayout = new StackLayout { - Padding = new Thickness(15) + Padding = new Thickness(15, 10) }; stackLayout.Children.Add(Label); diff --git a/src/App/Controls/LabeledValueCell.cs b/src/App/Controls/LabeledValueCell.cs index 45e2df161..96ca450a5 100644 --- a/src/App/Controls/LabeledValueCell.cs +++ b/src/App/Controls/LabeledValueCell.cs @@ -12,7 +12,7 @@ namespace Bit.App.Controls { var containerStackLayout = new StackLayout { - Padding = new Thickness(15), + Padding = new Thickness(15, 10), Orientation = StackOrientation.Horizontal }; @@ -58,7 +58,8 @@ namespace Bit.App.Controls { Text = button1Text, HorizontalOptions = LayoutOptions.End, - VerticalOptions = LayoutOptions.Center + VerticalOptions = LayoutOptions.Center, + Margin = new Thickness(0) }; buttonStackLayout.Children.Add(Button1); @@ -70,7 +71,8 @@ namespace Bit.App.Controls { Text = button2Text, HorizontalOptions = LayoutOptions.End, - VerticalOptions = LayoutOptions.Center + VerticalOptions = LayoutOptions.Center, + Margin = new Thickness(0) }; buttonStackLayout.Children.Add(Button2); diff --git a/src/App/Models/Page/VaultViewSitePageModel.cs b/src/App/Models/Page/VaultViewSitePageModel.cs index 6329f9841..93a8097fb 100644 --- a/src/App/Models/Page/VaultViewSitePageModel.cs +++ b/src/App/Models/Page/VaultViewSitePageModel.cs @@ -11,7 +11,7 @@ namespace Bit.App.Models.Page private string _password; private string _uri; private string _notes; - private bool _showPassword; + private bool _revealPassword; public VaultViewSitePageModel() { } @@ -37,6 +37,7 @@ namespace Bit.App.Models.Page } } public bool ShowUsername => !string.IsNullOrWhiteSpace(Username); + public string Password { get { return _password; } @@ -47,6 +48,8 @@ namespace Bit.App.Models.Page PropertyChanged(this, new PropertyChangedEventArgs(nameof(MaskedPassword))); } } + public bool ShowPassword => !string.IsNullOrWhiteSpace(Password); + public string Uri { get { return _uri; } @@ -58,6 +61,8 @@ namespace Bit.App.Models.Page PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowUri))); } } + public bool ShowUri => !string.IsNullOrWhiteSpace(Uri); + public string UriHost { get @@ -78,7 +83,6 @@ namespace Bit.App.Models.Page } } - public bool ShowUri => !string.IsNullOrWhiteSpace(Uri); public string Notes { get { return _notes; } @@ -90,19 +94,19 @@ namespace Bit.App.Models.Page } } public bool ShowNotes => !string.IsNullOrWhiteSpace(Notes); - public bool ShowPassword + public bool RevealPassword { - get { return _showPassword; } + get { return _revealPassword; } set { - _showPassword = value; - PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowPassword))); + _revealPassword = value; + PropertyChanged(this, new PropertyChangedEventArgs(nameof(RevealPassword))); PropertyChanged(this, new PropertyChangedEventArgs(nameof(MaskedPassword))); PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowHideText))); } } - public string MaskedPassword => ShowPassword ? Password : Password == null ? null : new string('●', Password.Length); - public string ShowHideText => ShowPassword ? AppResources.Hide : AppResources.Show; + public string MaskedPassword => RevealPassword ? Password : Password == null ? null : new string('●', Password.Length); + public string ShowHideText => RevealPassword ? AppResources.Hide : AppResources.Show; public void Update(Site site) { diff --git a/src/App/Pages/VaultAddSitePage.cs b/src/App/Pages/VaultAddSitePage.cs index a292a7600..131880cd5 100644 --- a/src/App/Pages/VaultAddSitePage.cs +++ b/src/App/Pages/VaultAddSitePage.cs @@ -36,6 +36,9 @@ namespace Bit.App.Pages var usernameCell = new FormEntryCell(AppResources.Username, nextElement: passwordCell.Entry); usernameCell.Entry.DisableAutocapitalize = true; usernameCell.Entry.Autocorrect = false; + + usernameCell.Entry.FontFamily = passwordCell.Entry.FontFamily = "Courier"; + var uriCell = new FormEntryCell(AppResources.URI, Keyboard.Url, nextElement: usernameCell.Entry); var nameCell = new FormEntryCell(AppResources.Name, nextElement: uriCell.Entry); diff --git a/src/App/Pages/VaultEditSitePage.cs b/src/App/Pages/VaultEditSitePage.cs index 189ef0e5b..e3844be2b 100644 --- a/src/App/Pages/VaultEditSitePage.cs +++ b/src/App/Pages/VaultEditSitePage.cs @@ -47,6 +47,9 @@ namespace Bit.App.Pages usernameCell.Entry.Text = site.Username?.Decrypt(); usernameCell.Entry.DisableAutocapitalize = true; usernameCell.Entry.Autocorrect = false; + + usernameCell.Entry.FontFamily = passwordCell.Entry.FontFamily = "Courier"; + var uriCell = new FormEntryCell(AppResources.URI, Keyboard.Url, nextElement: usernameCell.Entry); uriCell.Entry.Text = site.Uri?.Decrypt(); var nameCell = new FormEntryCell(AppResources.Name, nextElement: uriCell.Entry); diff --git a/src/App/Pages/VaultViewSitePage.cs b/src/App/Pages/VaultViewSitePage.cs index 20198934c..923cf05be 100644 --- a/src/App/Pages/VaultViewSitePage.cs +++ b/src/App/Pages/VaultViewSitePage.cs @@ -28,6 +28,11 @@ namespace Bit.App.Pages private VaultViewSitePageModel Model { get; set; } = new VaultViewSitePageModel(); private ExtendedTableView Table { get; set; } + private TableSection SiteInformationSection { get; set; } + private TableSection NotesSection { get; set; } + public LabeledValueCell UsernameCell { get; set; } + public LabeledValueCell PasswordCell { get; set; } + public LabeledValueCell UriCell { get; set; } private void Init() { @@ -42,30 +47,39 @@ namespace Bit.App.Pages nameCell.Value.SetBinding(Label.TextProperty, s => s.Name); // Username - var usernameCell = new LabeledValueCell(AppResources.Username, button1Text: AppResources.Copy); - usernameCell.Value.SetBinding(Label.TextProperty, s => s.Username); - usernameCell.Button1.Command = new Command(() => Copy(Model.Username, AppResources.Username)); - usernameCell.View.SetBinding(IsVisibleProperty, s => s.ShowUsername); + UsernameCell = new LabeledValueCell(AppResources.Username, button1Text: AppResources.Copy); + UsernameCell.Value.SetBinding(Label.TextProperty, s => s.Username); + UsernameCell.Button1.Command = new Command(() => Copy(Model.Username, AppResources.Username)); // Password - var passwordCell = new LabeledValueCell(AppResources.Password, button1Text: AppResources.Show, button2Text: AppResources.Copy); - passwordCell.Value.SetBinding(Label.TextProperty, s => s.MaskedPassword); - passwordCell.Button1.SetBinding(Button.TextProperty, s => s.ShowHideText); - passwordCell.Button1.Command = new Command(() => Model.ShowPassword = !Model.ShowPassword); - passwordCell.Button2.Command = new Command(() => Copy(Model.Password, AppResources.Password)); + PasswordCell = new LabeledValueCell(AppResources.Password, button1Text: AppResources.Show, button2Text: AppResources.Copy); + PasswordCell.Value.SetBinding(Label.TextProperty, s => s.MaskedPassword); + PasswordCell.Button1.SetBinding(Button.TextProperty, s => s.ShowHideText); + PasswordCell.Button1.Command = new Command(() => Model.RevealPassword = !Model.RevealPassword); + PasswordCell.Button2.Command = new Command(() => Copy(Model.Password, AppResources.Password)); + + UsernameCell.Value.FontFamily = PasswordCell.Value.FontFamily = "Courier"; // URI - var uriCell = new LabeledValueCell(AppResources.Website, button1Text: AppResources.Launch); - uriCell.Value.SetBinding(Label.TextProperty, s => s.UriHost); - uriCell.Button1.Command = new Command(() => Device.OpenUri(new Uri(Model.Uri))); - uriCell.View.SetBinding(IsVisibleProperty, s => s.ShowUri); + UriCell = new LabeledValueCell(AppResources.Website, button1Text: AppResources.Launch); + UriCell.Value.SetBinding(Label.TextProperty, s => s.UriHost); + UriCell.Button1.Command = new Command(() => Device.OpenUri(new Uri(Model.Uri))); // Notes var notesCell = new LabeledValueCell(); notesCell.Value.SetBinding(Label.TextProperty, s => s.Notes); - notesCell.View.SetBinding(IsVisibleProperty, s => s.ShowNotes); notesCell.Value.LineBreakMode = LineBreakMode.WordWrap; + SiteInformationSection = new TableSection("Site Information") + { + nameCell + }; + + NotesSection = new TableSection(AppResources.Notes) + { + notesCell + }; + Table = new ExtendedTableView { Intent = TableIntent.Settings, @@ -74,17 +88,8 @@ namespace Bit.App.Pages EnableSelection = false, Root = new TableRoot { - new TableSection("Site Information") - { - nameCell, - uriCell, - usernameCell, - passwordCell - }, - new TableSection(AppResources.Notes) - { - notesCell - } + SiteInformationSection, + NotesSection } }; @@ -110,11 +115,43 @@ namespace Bit.App.Pages Model.Update(site); - base.OnAppearing(); + if(!Model.ShowUri) + { + SiteInformationSection.Remove(UriCell); + } + else if(!SiteInformationSection.Contains(UriCell)) + { + SiteInformationSection.Add(UriCell); + } - // Hack to get table row height binding to update. Better way to do this probably? - Table.Root.Add(new TableSection { new TextCell() }); - Table.Root.RemoveAt(Table.Root.Count - 1); + if(!Model.ShowUsername) + { + SiteInformationSection.Remove(UsernameCell); + } + else if(!SiteInformationSection.Contains(UsernameCell)) + { + SiteInformationSection.Add(UsernameCell); + } + + if(!Model.ShowPassword) + { + SiteInformationSection.Remove(PasswordCell); + } + else if(!SiteInformationSection.Contains(PasswordCell)) + { + SiteInformationSection.Add(PasswordCell); + } + + if(!Model.ShowNotes) + { + Table.Root.Remove(NotesSection); + } + else if(!Table.Root.Contains(NotesSection)) + { + Table.Root.Add(NotesSection); + } + + base.OnAppearing(); } private void Copy(string copyText, string alertLabel) diff --git a/src/App/Repositories/BaseApiRepository.cs b/src/App/Repositories/BaseApiRepository.cs index e8fe811d4..4c0af6524 100644 --- a/src/App/Repositories/BaseApiRepository.cs +++ b/src/App/Repositories/BaseApiRepository.cs @@ -27,15 +27,18 @@ namespace Bit.App.Repositories { try { - var responseContent = await response.Content.ReadAsStringAsync(); - var errorResponseModel = JsonConvert.DeserializeObject(responseContent); - var errors = new List(); - foreach(var valError in errorResponseModel.ValidationErrors) + if(response.StatusCode == System.Net.HttpStatusCode.BadRequest) { - foreach(var errorMessage in valError.Value) + var responseContent = await response.Content.ReadAsStringAsync(); + var errorResponseModel = JsonConvert.DeserializeObject(responseContent); + + foreach(var valError in errorResponseModel.ValidationErrors) { - errors.Add(new ApiError { Message = errorMessage }); + foreach(var errorMessage in valError.Value) + { + errors.Add(new ApiError { Message = errorMessage }); + } } }