mirror of
https://github.com/bitwarden/android.git
synced 2024-12-24 09:58:27 +03:00
Vault add/edit/view site updates to table section/cell display.
This commit is contained in:
parent
baeee00a8d
commit
8108f4023a
9 changed files with 101 additions and 49 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue