diff --git a/src/App/App.csproj b/src/App/App.csproj
index 45c41f270..ab30c1057 100644
--- a/src/App/App.csproj
+++ b/src/App/App.csproj
@@ -53,6 +53,7 @@
+
diff --git a/src/App/Controls/LabeledValueCell.cs b/src/App/Controls/LabeledValueCell.cs
new file mode 100644
index 000000000..5d1fb11a8
--- /dev/null
+++ b/src/App/Controls/LabeledValueCell.cs
@@ -0,0 +1,97 @@
+using Acr.UserDialogs;
+using Bit.App.Abstractions;
+using Bit.App.Resources;
+using System;
+using Xamarin.Forms;
+using XLabs.Ioc;
+
+namespace Bit.App.Controls
+{
+ public class LabeledValueCell : ViewCell
+ {
+ private readonly IUserDialogs _userDialogs;
+ private readonly IClipboardService _clipboardService;
+
+ public LabeledValueCell(
+ string labelText,
+ string valueText = null,
+ bool copyValue = false,
+ bool password = false,
+ bool launch = false)
+ {
+ _userDialogs = Resolver.Resolve();
+ _clipboardService = Resolver.Resolve();
+
+ var stackLayout = new StackLayout
+ {
+ Padding = new Thickness(15, 15, 15, 0),
+ BackgroundColor = Color.White
+ };
+
+ if(labelText != null)
+ {
+ Label = new Label
+ {
+ Text = labelText,
+ FontSize = 14,
+ TextColor = Color.FromHex("777777")
+ };
+
+ stackLayout.Children.Add(Label);
+ }
+
+ Value = new Label
+ {
+ Text = valueText,
+ LineBreakMode = LineBreakMode.TailTruncation,
+ HorizontalOptions = LayoutOptions.StartAndExpand,
+ VerticalOptions = LayoutOptions.Center
+ };
+
+ var valueStackLayout = new StackLayout
+ {
+ Orientation = StackOrientation.Horizontal
+ };
+ valueStackLayout.Children.Add(Value);
+
+ if(copyValue)
+ {
+ var copyButton = new Button
+ {
+ Text = AppResources.Copy,
+ HorizontalOptions = LayoutOptions.End,
+ VerticalOptions = LayoutOptions.Center,
+ Command = new Command(() => Copy())
+ };
+
+ valueStackLayout.Children.Add(copyButton);
+ }
+
+ if(launch)
+ {
+ var launchButton = new Button
+ {
+ Text = AppResources.Launch,
+ HorizontalOptions = LayoutOptions.End,
+ VerticalOptions = LayoutOptions.Center,
+ Command = new Command(() => Device.OpenUri(new Uri(Value.Text)))
+ };
+
+ valueStackLayout.Children.Add(launchButton);
+ }
+
+ stackLayout.Children.Add(valueStackLayout);
+
+ View = stackLayout;
+ }
+
+ public Label Label { get; private set; }
+ public Label Value { get; private set; }
+
+ private void Copy()
+ {
+ _clipboardService.CopyToClipboard(Value.Text);
+ _userDialogs.SuccessToast(string.Format(AppResources.ValueHasBeenCopied, Label.Text));
+ }
+ }
+}
diff --git a/src/App/Pages/VaultListPage.cs b/src/App/Pages/VaultListPage.cs
index 6e2fbd7fd..c976a69b2 100644
--- a/src/App/Pages/VaultListPage.cs
+++ b/src/App/Pages/VaultListPage.cs
@@ -42,7 +42,6 @@ namespace Bit.App.Pages
Title = AppResources.MyVault;
Content = listView;
- NavigationPage.SetBackButtonTitle(this, AppResources.Back);
}
protected override void OnAppearing()
diff --git a/src/App/Pages/VaultViewSitePage.cs b/src/App/Pages/VaultViewSitePage.cs
index 06cec8bb1..f5a5e5f06 100644
--- a/src/App/Pages/VaultViewSitePage.cs
+++ b/src/App/Pages/VaultViewSitePage.cs
@@ -27,101 +27,70 @@ namespace Bit.App.Pages
}
private VaultViewSitePageModel Model { get; set; } = new VaultViewSitePageModel();
+ private ExtendedTableView Table { get; set; }
private void Init()
{
ToolbarItems.Add(new EditSiteToolBarItem(this, _siteId));
ToolbarItems.Add(new DismissModalToolBarItem(this));
- var stackLayout = new StackLayout();
// Username
- var usernameRow = new StackLayout { Orientation = StackOrientation.Horizontal };
- var usernameLabel = new Label
- {
- HorizontalOptions = LayoutOptions.StartAndExpand,
- VerticalOptions = LayoutOptions.Center,
- LineBreakMode = LineBreakMode.TailTruncation
- };
- usernameLabel.SetBinding(Label.TextProperty, s => s.Username);
- usernameRow.Children.Add(usernameLabel);
- usernameRow.Children.Add(new Button
- {
- Text = AppResources.Copy,
- HorizontalOptions = LayoutOptions.End,
- VerticalOptions = LayoutOptions.Center,
- Command = new Command(() => Copy(usernameLabel.Text, AppResources.Username))
- });
- stackLayout.Children.Add(new Label { Text = AppResources.Username });
- stackLayout.Children.Add(usernameRow);
+ var nameCell = new LabeledValueCell(AppResources.Name);
+ nameCell.Value.SetBinding(Label.TextProperty, s => s.Name);
+
+ // Username
+ var usernameCell = new LabeledValueCell(AppResources.Username, copyValue: true);
+ usernameCell.Value.SetBinding(Label.TextProperty, s => s.Username);
// Password
- var passwordRow = new StackLayout { Orientation = StackOrientation.Horizontal };
- var passwordLabel = new Label
- {
- HorizontalOptions = LayoutOptions.StartAndExpand,
- VerticalOptions = LayoutOptions.Center,
- LineBreakMode = LineBreakMode.TailTruncation
- };
- passwordLabel.SetBinding(Label.TextProperty, s => s.MaskedPassword);
- passwordRow.Children.Add(passwordLabel);
- var togglePasswordButton = new Button
- {
- HorizontalOptions = LayoutOptions.End,
- VerticalOptions = LayoutOptions.Center,
- Command = new Command(() => Model.ShowPassword = !Model.ShowPassword)
- };
- togglePasswordButton.CommandParameter = togglePasswordButton;
- togglePasswordButton.SetBinding(Button.TextProperty, s => s.ShowHideText);
- passwordRow.Children.Add(togglePasswordButton);
- passwordRow.Children.Add(new Button
- {
- Text = AppResources.Copy,
- HorizontalOptions = LayoutOptions.End,
- VerticalOptions = LayoutOptions.Center,
- Command = new Command(() => Copy(Model.Password, AppResources.Password))
- });
- stackLayout.Children.Add(new Label { Text = AppResources.Password });
- stackLayout.Children.Add(passwordRow);
+ var passwordCell = new LabeledValueCell(AppResources.Password, copyValue: true);
+ passwordCell.Value.SetBinding(Label.TextProperty, s => s.Password);
// URI
- var uriRow = new StackLayout { Orientation = StackOrientation.Horizontal };
- var uriLabel = new Label
- {
- HorizontalOptions = LayoutOptions.StartAndExpand,
- VerticalOptions = LayoutOptions.Center,
- LineBreakMode = LineBreakMode.TailTruncation
- };
- uriLabel.SetBinding(Label.TextProperty, s => s.Uri);
- uriRow.Children.Add(uriLabel);
- uriRow.Children.Add(new Button
- {
- Text = AppResources.Launch,
- HorizontalOptions = LayoutOptions.End,
- VerticalOptions = LayoutOptions.Center,
- Command = new Command(() => Device.OpenUri(new Uri(uriLabel.Text)))
- });
- stackLayout.Children.Add(new Label { Text = AppResources.Website });
- stackLayout.Children.Add(uriRow);
+ var uriCell = new LabeledValueCell(AppResources.URI, launch: true);
+ uriCell.Value.SetBinding(Label.TextProperty, s => s.Uri);
// Notes
- var notes = new Label { Text = AppResources.Notes };
- notes.SetBinding(Label.IsVisibleProperty, s => s.ShowNotes);
- stackLayout.Children.Add(notes);
- var notesLabel = new Label();
- notesLabel.SetBinding(Label.TextProperty, s => s.Notes);
- notesLabel.SetBinding(Label.IsVisibleProperty, s => s.ShowNotes);
- stackLayout.Children.Add(notesLabel);
+ var notesCell = new LabeledValueCell(AppResources.Notes);
+ notesCell.Value.SetBinding(Label.TextProperty, s => s.Notes);
+
+ Table = new ExtendedTableView
+ {
+ Intent = TableIntent.Settings,
+ EnableScrolling = false,
+ HasUnevenRows = true,
+ EnableSelection = true,
+ Root = new TableRoot
+ {
+ new TableSection("Site Information")
+ {
+ uriCell,
+ nameCell,
+ usernameCell,
+ passwordCell
+ },
+ new TableSection(AppResources.Notes)
+ {
+ notesCell
+ }
+ }
+ };
+
+ if(Device.OS == TargetPlatform.iOS)
+ {
+ Table.RowHeight = -1;
+ Table.EstimatedRowHeight = 70;
+ }
var scrollView = new ScrollView
{
- Content = stackLayout,
+ Content = Table,
Orientation = ScrollOrientation.Vertical
};
SetBinding(Page.TitleProperty, new Binding("PageTitle"));
Content = scrollView;
BindingContext = Model;
- NavigationPage.SetBackButtonTitle(this, AppResources.Back);
}
protected override void OnAppearing()
@@ -136,6 +105,10 @@ namespace Bit.App.Pages
Model.Update(site);
base.OnAppearing();
+
+ // 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);
}
private void Copy(string copyText, string alertLabel)