Relative layout on register page to show help text under password and hint.

This commit is contained in:
Kyle Spearrin 2016-07-04 02:45:32 -04:00
parent b9c823b0aa
commit f74273999c
4 changed files with 97 additions and 38 deletions

View file

@ -10,12 +10,6 @@ namespace Bit.App.Controls
{ {
public class ExtendedTableView : TableView public class ExtendedTableView : TableView
{ {
public ExtendedTableView()
: base()
{
VerticalOptions = LayoutOptions.Start;
}
public static readonly BindableProperty EnableScrollingProperty = public static readonly BindableProperty EnableScrollingProperty =
BindableProperty.Create(nameof(EnableScrolling), typeof(bool), typeof(ExtendedTableView), true); BindableProperty.Create(nameof(EnableScrolling), typeof(bool), typeof(ExtendedTableView), true);
@ -47,7 +41,7 @@ namespace Bit.App.Controls
protected override SizeRequest OnSizeRequest(double widthConstraint, double heightConstraint) protected override SizeRequest OnSizeRequest(double widthConstraint, double heightConstraint)
{ {
if(Device.OS == TargetPlatform.iOS && VerticalOptions.Alignment != LayoutAlignment.Fill) if(Device.OS == TargetPlatform.iOS && !VerticalOptions.Expands)
{ {
var reflectionService = Resolver.Resolve<IReflectionService>(); var reflectionService = Resolver.Resolve<IReflectionService>();
var baseBaseOnSizeRequest = reflectionService.GetVisualElementOnSizeRequest(this); var baseBaseOnSizeRequest = reflectionService.GetVisualElementOnSizeRequest(this);

View file

@ -26,7 +26,6 @@ namespace Bit.App.Pages
Init(); Init();
} }
public FormEntryCell NameCell { get; set; }
public FormEntryCell EmailCell { get; set; } public FormEntryCell EmailCell { get; set; }
public FormEntryCell PasswordCell { get; set; } public FormEntryCell PasswordCell { get; set; }
public FormEntryCell ConfirmPasswordCell { get; set; } public FormEntryCell ConfirmPasswordCell { get; set; }
@ -42,36 +41,89 @@ namespace Bit.App.Pages
nextElement: PasswordHintCell.Entry, useLabelAsPlaceholder: true, imageSource: "lock", containerPadding: padding); nextElement: PasswordHintCell.Entry, useLabelAsPlaceholder: true, imageSource: "lock", containerPadding: padding);
PasswordCell = new FormEntryCell(AppResources.MasterPassword, IsPassword: true, PasswordCell = new FormEntryCell(AppResources.MasterPassword, IsPassword: true,
nextElement: ConfirmPasswordCell.Entry, useLabelAsPlaceholder: true, imageSource: "lock", containerPadding: padding); nextElement: ConfirmPasswordCell.Entry, useLabelAsPlaceholder: true, imageSource: "lock", containerPadding: padding);
NameCell = new FormEntryCell("Your Name", nextElement: PasswordCell.Entry, EmailCell = new FormEntryCell(AppResources.EmailAddress, nextElement: PasswordCell.Entry,
useLabelAsPlaceholder: true, imageSource: "user", containerPadding: padding);
EmailCell = new FormEntryCell(AppResources.EmailAddress, nextElement: NameCell.Entry,
entryKeyboard: Keyboard.Email, useLabelAsPlaceholder: true, imageSource: "envelope", containerPadding: padding); entryKeyboard: Keyboard.Email, useLabelAsPlaceholder: true, imageSource: "envelope", containerPadding: padding);
PasswordHintCell.Entry.ReturnType = Enums.ReturnType.Done; PasswordHintCell.Entry.ReturnType = Enums.ReturnType.Done;
PasswordHintCell.Entry.Completed += Entry_Completed; PasswordHintCell.Entry.Completed += Entry_Completed;
var table = new ExtendedTableView var table = new FormTableView
{ {
Intent = TableIntent.Settings,
EnableScrolling = true,
HasUnevenRows = true,
EnableSelection = false,
Root = new TableRoot Root = new TableRoot
{ {
new TableSection() new TableSection
{ {
EmailCell, EmailCell,
NameCell PasswordCell
}, }
new TableSection() }
};
var passwordLabel = new Label
{
Text = "The master password is the password you use to access your vault. It is very important that you do not forget your master password. There is no way to recover the password in the event that you forget it.",
LineBreakMode = LineBreakMode.WordWrap,
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
Style = (Style)Application.Current.Resources["text-muted"]
};
var table2 = new FormTableView
{
Root = new TableRoot
{
new TableSection
{ {
PasswordCell,
ConfirmPasswordCell, ConfirmPasswordCell,
PasswordHintCell PasswordHintCell
} }
} }
}; };
var hintLabel = new Label
{
Text = "A master password hint can help you remember your password if you forget it.",
LineBreakMode = LineBreakMode.WordWrap,
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
Style = (Style)Application.Current.Resources["text-muted"]
};
var layout = new RelativeLayout
{
Padding = new Thickness(0, 0, 0, 35)
};
layout.Children.Add(
table,
Constraint.Constant(0),
Constraint.Constant(0),
Constraint.RelativeToParent((parent) => { return parent.Width; })
);
layout.Children.Add(
passwordLabel,
Constraint.Constant(15),
Constraint.RelativeToView(table, (parent, sibling) => { return sibling.Y + sibling.Height - (this.IsPortrait() ? 45 : 25); }),
Constraint.RelativeToParent((parent) => { return parent.Width - 30; })
);
layout.Children.Add(
table2,
Constraint.Constant(0),
Constraint.RelativeToView(passwordLabel, (parent, sibling) => { return sibling.Y + sibling.Height - (this.IsPortrait() ? 15 : 10); }),
Constraint.RelativeToParent((parent) => { return parent.Width; })
);
layout.Children.Add(
hintLabel,
Constraint.Constant(15),
Constraint.RelativeToView(table2, (parent, sibling) => { return sibling.Y + sibling.Height - (this.IsPortrait() ? 45 : 25); }),
Constraint.RelativeToParent((parent) => { return parent.Width - 30; })
);
layout.LowerChild(table2);
layout.LowerChild(table);
var scrollView = new ScrollView
{
Content = layout
};
var loginToolbarItem = new ToolbarItem("Submit", null, async () => var loginToolbarItem = new ToolbarItem("Submit", null, async () =>
{ {
await Register(); await Register();
@ -79,14 +131,14 @@ namespace Bit.App.Pages
if(Device.OS == TargetPlatform.iOS) if(Device.OS == TargetPlatform.iOS)
{ {
table.RowHeight = -1; table.RowHeight = table2.RowHeight = table2.RowHeight = -1;
table.EstimatedRowHeight = 70; table.EstimatedRowHeight = table2.EstimatedRowHeight = table2.EstimatedRowHeight = 70;
ToolbarItems.Add(new DismissModalToolBarItem(this, "Cancel")); ToolbarItems.Add(new DismissModalToolBarItem(this, "Cancel"));
} }
ToolbarItems.Add(loginToolbarItem); ToolbarItems.Add(loginToolbarItem);
Title = "Create Account"; Title = "Create Account";
Content = table; Content = scrollView;
} }
protected override void OnAppearing() protected override void OnAppearing()
@ -108,12 +160,6 @@ namespace Bit.App.Pages
return; return;
} }
if(string.IsNullOrWhiteSpace(NameCell.Entry.Text))
{
await DisplayAlert(AppResources.AnErrorHasOccurred, string.Format(AppResources.ValidationFieldRequired, "Your Name"), AppResources.Ok);
return;
}
if(string.IsNullOrWhiteSpace(PasswordCell.Entry.Text)) if(string.IsNullOrWhiteSpace(PasswordCell.Entry.Text))
{ {
await DisplayAlert(AppResources.AnErrorHasOccurred, string.Format(AppResources.ValidationFieldRequired, "Your Name"), AppResources.Ok); await DisplayAlert(AppResources.AnErrorHasOccurred, string.Format(AppResources.ValidationFieldRequired, "Your Name"), AppResources.Ok);
@ -129,7 +175,6 @@ namespace Bit.App.Pages
var key = _cryptoService.MakeKeyFromPassword(PasswordCell.Entry.Text, EmailCell.Entry.Text); var key = _cryptoService.MakeKeyFromPassword(PasswordCell.Entry.Text, EmailCell.Entry.Text);
var request = new RegisterRequest var request = new RegisterRequest
{ {
Name = NameCell.Entry.Text,
Email = EmailCell.Entry.Text, Email = EmailCell.Entry.Text,
MasterPasswordHash = _cryptoService.HashPasswordBase64(key, PasswordCell.Entry.Text), MasterPasswordHash = _cryptoService.HashPasswordBase64(key, PasswordCell.Entry.Text),
MasterPasswordHint = !string.IsNullOrWhiteSpace(PasswordHintCell.Entry.Text) ? PasswordHintCell.Entry.Text : null MasterPasswordHint = !string.IsNullOrWhiteSpace(PasswordHintCell.Entry.Text) ? PasswordHintCell.Entry.Text : null
@ -148,5 +193,17 @@ namespace Bit.App.Pages
_userDialogs.SuccessToast("Account Created", "Your new account has been created! You may now log in."); _userDialogs.SuccessToast("Account Created", "Your new account has been created! You may now log in.");
await Navigation.PopModalAsync(); await Navigation.PopModalAsync();
} }
private class FormTableView : ExtendedTableView
{
public FormTableView()
{
Intent = TableIntent.Settings;
EnableScrolling = false;
HasUnevenRows = true;
EnableSelection = false;
VerticalOptions = LayoutOptions.Start;
}
}
} }
} }

View file

@ -1,6 +1,7 @@
using System; using System;
using Bit.App.Abstractions; using Bit.App.Abstractions;
using Bit.App.Models; using Bit.App.Models;
using Xamarin.Forms;
using XLabs.Ioc; using XLabs.Ioc;
namespace Bit.App namespace Bit.App
@ -17,5 +18,15 @@ namespace Bit.App
var cryptoService = Resolver.Resolve<ICryptoService>(); var cryptoService = Resolver.Resolve<ICryptoService>();
return cryptoService.Encrypt(s); return cryptoService.Encrypt(s);
} }
public static bool IsPortrait(this Page page)
{
return page.Width < page.Height;
}
public static bool IsLandscape(this Page page)
{
return !page.IsPortrait();
}
} }
} }

View file

@ -2,6 +2,7 @@
using System.ComponentModel; using System.ComponentModel;
using Bit.App.Controls; using Bit.App.Controls;
using Bit.iOS.Controls; using Bit.iOS.Controls;
using CoreGraphics;
using UIKit; using UIKit;
using Xamarin.Forms; using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS; using Xamarin.Forms.Platform.iOS;
@ -23,10 +24,6 @@ namespace Bit.iOS.Controls
UpdateRowHeight(view); UpdateRowHeight(view);
UpdateEstimatedRowHeight(view); UpdateEstimatedRowHeight(view);
UpdateSeparatorColor(view); UpdateSeparatorColor(view);
Control.SectionFooterHeight = 0.01f;
Control.EstimatedSectionFooterHeight = 1f;
Control.ContentInset = new UIEdgeInsets(0, 0, -35, 0);
} }
} }
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)