Vault add/edit/view site updates to table section/cell display.

This commit is contained in:
Kyle Spearrin 2016-06-13 20:03:16 -04:00
parent baeee00a8d
commit 8108f4023a
9 changed files with 101 additions and 49 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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)
{

View file

@ -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);

View file

@ -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);

View file

@ -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<VaultViewSitePageModel>(Label.TextProperty, s => s.Name);
// Username
var usernameCell = new LabeledValueCell(AppResources.Username, button1Text: AppResources.Copy);
usernameCell.Value.SetBinding<VaultViewSitePageModel>(Label.TextProperty, s => s.Username);
usernameCell.Button1.Command = new Command(() => Copy(Model.Username, AppResources.Username));
usernameCell.View.SetBinding<VaultViewSitePageModel>(IsVisibleProperty, s => s.ShowUsername);
UsernameCell = new LabeledValueCell(AppResources.Username, button1Text: AppResources.Copy);
UsernameCell.Value.SetBinding<VaultViewSitePageModel>(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<VaultViewSitePageModel>(Label.TextProperty, s => s.MaskedPassword);
passwordCell.Button1.SetBinding<VaultViewSitePageModel>(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<VaultViewSitePageModel>(Label.TextProperty, s => s.MaskedPassword);
PasswordCell.Button1.SetBinding<VaultViewSitePageModel>(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<VaultViewSitePageModel>(Label.TextProperty, s => s.UriHost);
uriCell.Button1.Command = new Command(() => Device.OpenUri(new Uri(Model.Uri)));
uriCell.View.SetBinding<VaultViewSitePageModel>(IsVisibleProperty, s => s.ShowUri);
UriCell = new LabeledValueCell(AppResources.Website, button1Text: AppResources.Launch);
UriCell.Value.SetBinding<VaultViewSitePageModel>(Label.TextProperty, s => s.UriHost);
UriCell.Button1.Command = new Command(() => Device.OpenUri(new Uri(Model.Uri)));
// Notes
var notesCell = new LabeledValueCell();
notesCell.Value.SetBinding<VaultViewSitePageModel>(Label.TextProperty, s => s.Notes);
notesCell.View.SetBinding<VaultViewSitePageModel>(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)

View file

@ -26,11 +26,13 @@ namespace Bit.App.Repositories
public async Task<ApiResult<T>> HandleErrorAsync<T>(HttpResponseMessage response)
{
try
{
var errors = new List<ApiError>();
if(response.StatusCode == System.Net.HttpStatusCode.BadRequest)
{
var responseContent = await response.Content.ReadAsStringAsync();
var errorResponseModel = JsonConvert.DeserializeObject<ErrorResponse>(responseContent);
var errors = new List<ApiError>();
foreach(var valError in errorResponseModel.ValidationErrors)
{
foreach(var errorMessage in valError.Value)
@ -38,6 +40,7 @@ namespace Bit.App.Repositories
errors.Add(new ApiError { Message = errorMessage });
}
}
}
return ApiResult<T>.Failed(response.StatusCode, errors.ToArray());
}