mirror of
https://github.com/bitwarden/android.git
synced 2024-12-21 08:42:39 +03:00
Moved add/edit pages to use custom form cells. Moved navigation of vault to modals. Created custom renderer for left modal dismiss button on navigation pages. refresh for edit site UI.
This commit is contained in:
parent
8ec957c39c
commit
83f308cbf0
13 changed files with 340 additions and 103 deletions
|
@ -44,12 +44,17 @@
|
||||||
<Compile Include="Behaviors\EmailValidationBehavior.cs" />
|
<Compile Include="Behaviors\EmailValidationBehavior.cs" />
|
||||||
<Compile Include="Behaviors\ConnectivityBehavior.cs" />
|
<Compile Include="Behaviors\ConnectivityBehavior.cs" />
|
||||||
<Compile Include="Behaviors\RequiredValidationBehavior.cs" />
|
<Compile Include="Behaviors\RequiredValidationBehavior.cs" />
|
||||||
|
<Compile Include="Controls\DismissModalToolBarItem.cs" />
|
||||||
<Compile Include="Controls\EntryLabel.cs" />
|
<Compile Include="Controls\EntryLabel.cs" />
|
||||||
<Compile Include="Controls\ExtendedEditor.cs" />
|
<Compile Include="Controls\ExtendedEditor.cs" />
|
||||||
|
<Compile Include="Controls\ExtendedNavigationPage.cs" />
|
||||||
<Compile Include="Controls\ExtendedTableView.cs" />
|
<Compile Include="Controls\ExtendedTableView.cs" />
|
||||||
<Compile Include="Controls\ExtendedPicker.cs" />
|
<Compile Include="Controls\ExtendedPicker.cs" />
|
||||||
<Compile Include="Controls\ExtendedEntry.cs" />
|
<Compile Include="Controls\ExtendedEntry.cs" />
|
||||||
<Compile Include="Controls\ExtendedTabbedPage.cs" />
|
<Compile Include="Controls\ExtendedTabbedPage.cs" />
|
||||||
|
<Compile Include="Controls\FormEditorCell.cs" />
|
||||||
|
<Compile Include="Controls\FormPickerCell.cs" />
|
||||||
|
<Compile Include="Controls\FormEntryCell.cs" />
|
||||||
<Compile Include="Models\Api\ApiError.cs" />
|
<Compile Include="Models\Api\ApiError.cs" />
|
||||||
<Compile Include="Models\Api\ApiResult.cs" />
|
<Compile Include="Models\Api\ApiResult.cs" />
|
||||||
<Compile Include="Models\Api\Request\FolderRequest.cs" />
|
<Compile Include="Models\Api\Request\FolderRequest.cs" />
|
||||||
|
|
23
src/App/Controls/DismissModalToolBarItem.cs
Normal file
23
src/App/Controls/DismissModalToolBarItem.cs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
using System;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
namespace Bit.App.Controls
|
||||||
|
{
|
||||||
|
public class DismissModalToolBarItem : ToolbarItem
|
||||||
|
{
|
||||||
|
private readonly ContentPage _page;
|
||||||
|
|
||||||
|
public DismissModalToolBarItem(ContentPage page, string text = null)
|
||||||
|
{
|
||||||
|
_page = page;
|
||||||
|
Text = text ?? "Close";
|
||||||
|
Clicked += ClickedItem;
|
||||||
|
Priority = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void ClickedItem(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
await _page.Navigation.PopModalAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
27
src/App/Controls/ExtendedNavigationPage.cs
Normal file
27
src/App/Controls/ExtendedNavigationPage.cs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
using System;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
namespace Bit.App.Controls
|
||||||
|
{
|
||||||
|
public class ExtendedNavigationPage : NavigationPage
|
||||||
|
{
|
||||||
|
public ExtendedNavigationPage()
|
||||||
|
: base()
|
||||||
|
{
|
||||||
|
SetDefaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtendedNavigationPage(Page root)
|
||||||
|
: base(root)
|
||||||
|
{
|
||||||
|
SetDefaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetDefaults()
|
||||||
|
{
|
||||||
|
// default colors for our app
|
||||||
|
BarBackgroundColor = Color.FromHex("3c8dbc");
|
||||||
|
BarTextColor = Color.FromHex("ffffff");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
34
src/App/Controls/FormEditorCell.cs
Normal file
34
src/App/Controls/FormEditorCell.cs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
using System;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
namespace Bit.App.Controls
|
||||||
|
{
|
||||||
|
public class FormEditorCell : ViewCell
|
||||||
|
{
|
||||||
|
public FormEditorCell(Keyboard entryKeyboard = null, double? height = null)
|
||||||
|
{
|
||||||
|
Editor = new ExtendedEditor
|
||||||
|
{
|
||||||
|
Keyboard = entryKeyboard,
|
||||||
|
HasBorder = false
|
||||||
|
};
|
||||||
|
|
||||||
|
if(height.HasValue)
|
||||||
|
{
|
||||||
|
Editor.HeightRequest = height.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
var stackLayout = new StackLayout
|
||||||
|
{
|
||||||
|
Padding = new Thickness(15, 15, 15, 0),
|
||||||
|
BackgroundColor = Color.White
|
||||||
|
};
|
||||||
|
|
||||||
|
stackLayout.Children.Add(Editor);
|
||||||
|
|
||||||
|
View = stackLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtendedEditor Editor { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
38
src/App/Controls/FormEntryCell.cs
Normal file
38
src/App/Controls/FormEntryCell.cs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
using System;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
namespace Bit.App.Controls
|
||||||
|
{
|
||||||
|
public class FormEntryCell : ViewCell
|
||||||
|
{
|
||||||
|
public FormEntryCell(string labelText, Keyboard entryKeyboard = null, bool IsPassword = false)
|
||||||
|
{
|
||||||
|
Label = new Label
|
||||||
|
{
|
||||||
|
Text = labelText,
|
||||||
|
FontSize = 14,
|
||||||
|
TextColor = Color.FromHex("777777")
|
||||||
|
};
|
||||||
|
|
||||||
|
Entry = new ExtendedEntry
|
||||||
|
{
|
||||||
|
Keyboard = entryKeyboard,
|
||||||
|
HasBorder = false
|
||||||
|
};
|
||||||
|
|
||||||
|
var stackLayout = new StackLayout
|
||||||
|
{
|
||||||
|
Padding = new Thickness(15, 15, 15, 0),
|
||||||
|
BackgroundColor = Color.White
|
||||||
|
};
|
||||||
|
|
||||||
|
stackLayout.Children.Add(Label);
|
||||||
|
stackLayout.Children.Add(Entry);
|
||||||
|
|
||||||
|
View = stackLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Label Label { get; private set; }
|
||||||
|
public ExtendedEntry Entry { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
44
src/App/Controls/FormPickerCell.cs
Normal file
44
src/App/Controls/FormPickerCell.cs
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
using System;
|
||||||
|
using Bit.App.Resources;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
namespace Bit.App.Controls
|
||||||
|
{
|
||||||
|
public class FormPickerCell : ViewCell
|
||||||
|
{
|
||||||
|
public FormPickerCell(string labelText, string[] pickerItems)
|
||||||
|
{
|
||||||
|
Label = new Label
|
||||||
|
{
|
||||||
|
Text = labelText,
|
||||||
|
FontSize = 14,
|
||||||
|
TextColor = Color.FromHex("777777")
|
||||||
|
};
|
||||||
|
|
||||||
|
Picker = new ExtendedPicker
|
||||||
|
{
|
||||||
|
HasBorder = false
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach(var item in pickerItems)
|
||||||
|
{
|
||||||
|
Picker.Items.Add(item);
|
||||||
|
}
|
||||||
|
Picker.SelectedIndex = 0;
|
||||||
|
|
||||||
|
var stackLayout = new StackLayout
|
||||||
|
{
|
||||||
|
Padding = new Thickness(15, 15, 15, 0),
|
||||||
|
BackgroundColor = Color.White
|
||||||
|
};
|
||||||
|
|
||||||
|
stackLayout.Children.Add(Label);
|
||||||
|
stackLayout.Children.Add(Picker);
|
||||||
|
|
||||||
|
View = stackLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Label Label { get; private set; }
|
||||||
|
public ExtendedPicker Picker { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,12 +12,9 @@ namespace Bit.App.Pages
|
||||||
BarTintColor = Color.FromHex("222d32");
|
BarTintColor = Color.FromHex("222d32");
|
||||||
TintColor = Color.FromHex("ffffff");
|
TintColor = Color.FromHex("ffffff");
|
||||||
|
|
||||||
var settingsNavigation = new NavigationPage(new SettingsPage());
|
var settingsNavigation = new ExtendedNavigationPage(new SettingsPage());
|
||||||
var vaultNavigation = new NavigationPage(new VaultListPage());
|
var vaultNavigation = new ExtendedNavigationPage(new VaultListPage());
|
||||||
var syncNavigation = new NavigationPage(new SyncPage());
|
var syncNavigation = new ExtendedNavigationPage(new SyncPage());
|
||||||
|
|
||||||
vaultNavigation.BarBackgroundColor = settingsNavigation.BarBackgroundColor = syncNavigation.BarBackgroundColor = Color.FromHex("3c8dbc");
|
|
||||||
vaultNavigation.BarTextColor = settingsNavigation.BarTextColor = syncNavigation.BarTextColor = Color.FromHex("ffffff");
|
|
||||||
|
|
||||||
vaultNavigation.Title = AppResources.MyVault;
|
vaultNavigation.Title = AppResources.MyVault;
|
||||||
vaultNavigation.Icon = "fa-lock";
|
vaultNavigation.Icon = "fa-lock";
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Acr.UserDialogs;
|
using Acr.UserDialogs;
|
||||||
using Bit.App.Abstractions;
|
using Bit.App.Abstractions;
|
||||||
|
@ -30,55 +31,20 @@ namespace Bit.App.Pages
|
||||||
|
|
||||||
private void Init()
|
private void Init()
|
||||||
{
|
{
|
||||||
var folders = _folderService.GetAllAsync().GetAwaiter().GetResult().OrderBy(f => f.Name?.Decrypt());
|
var uriCell = new FormEntryCell(AppResources.URI, Keyboard.Url);
|
||||||
|
var nameCell = new FormEntryCell(AppResources.Name);
|
||||||
|
var usernameCell = new FormEntryCell(AppResources.Username);
|
||||||
|
var passwordCell = new FormEntryCell(AppResources.Password, IsPassword: true);
|
||||||
|
|
||||||
var uriEntry = new ExtendedEntry { Keyboard = Keyboard.Url, HasBorder = false };
|
var folderOptions = new List<string> { AppResources.FolderNone };
|
||||||
var nameEntry = new ExtendedEntry { HasBorder = false };
|
var folders = _folderService.GetAllAsync().GetAwaiter().GetResult().OrderBy(f => f.Name?.Decrypt());
|
||||||
var folderPicker = new ExtendedPicker { Title = AppResources.Folder, HasBorder = false };
|
|
||||||
folderPicker.Items.Add(AppResources.FolderNone);
|
|
||||||
folderPicker.SelectedIndex = 0;
|
|
||||||
foreach(var folder in folders)
|
foreach(var folder in folders)
|
||||||
{
|
{
|
||||||
folderPicker.Items.Add(folder.Name.Decrypt());
|
folderOptions.Add(folder.Name.Decrypt());
|
||||||
}
|
}
|
||||||
var usernameEntry = new ExtendedEntry { HasBorder = false };
|
var folderCell = new FormPickerCell(AppResources.Folder, folderOptions.ToArray());
|
||||||
var passwordEntry = new ExtendedEntry { IsPassword = true, HasBorder = false };
|
|
||||||
var notesEditor = new ExtendedEditor { HeightRequest = 90, HasBorder = false };
|
|
||||||
|
|
||||||
var uriStackLayout = new FormEntryStackLayout();
|
var notesCell = new FormEditorCell(height:90);
|
||||||
uriStackLayout.Children.Add(new EntryLabel { Text = AppResources.URI });
|
|
||||||
uriStackLayout.Children.Add(uriEntry);
|
|
||||||
var uriCell = new ViewCell();
|
|
||||||
uriCell.View = uriStackLayout;
|
|
||||||
|
|
||||||
var nameStackLayout = new FormEntryStackLayout();
|
|
||||||
nameStackLayout.Children.Add(new EntryLabel { Text = AppResources.Name });
|
|
||||||
nameStackLayout.Children.Add(nameEntry);
|
|
||||||
var nameCell = new ViewCell();
|
|
||||||
nameCell.View = nameStackLayout;
|
|
||||||
|
|
||||||
var folderStackLayout = new FormEntryStackLayout();
|
|
||||||
folderStackLayout.Children.Add(new EntryLabel { Text = AppResources.Folder });
|
|
||||||
folderStackLayout.Children.Add(folderPicker);
|
|
||||||
var folderCell = new ViewCell();
|
|
||||||
folderCell.View = folderStackLayout;
|
|
||||||
|
|
||||||
var usernameStackLayout = new FormEntryStackLayout();
|
|
||||||
usernameStackLayout.Children.Add(new EntryLabel { Text = AppResources.Username });
|
|
||||||
usernameStackLayout.Children.Add(usernameEntry);
|
|
||||||
var usernameCell = new ViewCell();
|
|
||||||
usernameCell.View = usernameStackLayout;
|
|
||||||
|
|
||||||
var passwordStackLayout = new FormEntryStackLayout();
|
|
||||||
passwordStackLayout.Children.Add(new EntryLabel { Text = AppResources.Password });
|
|
||||||
passwordStackLayout.Children.Add(passwordEntry);
|
|
||||||
var passwordCell = new ViewCell();
|
|
||||||
passwordCell.View = passwordStackLayout;
|
|
||||||
|
|
||||||
var notesStackLayout = new FormEntryStackLayout();
|
|
||||||
notesStackLayout.Children.Add(notesEditor);
|
|
||||||
var notesCell = new ViewCell();
|
|
||||||
notesCell.View = notesStackLayout;
|
|
||||||
|
|
||||||
var mainTable = new ExtendedTableView
|
var mainTable = new ExtendedTableView
|
||||||
{
|
{
|
||||||
|
@ -88,7 +54,7 @@ namespace Bit.App.Pages
|
||||||
EnableSelection = false,
|
EnableSelection = false,
|
||||||
Root = new TableRoot
|
Root = new TableRoot
|
||||||
{
|
{
|
||||||
new TableSection
|
new TableSection("Site Information")
|
||||||
{
|
{
|
||||||
uriCell,
|
uriCell,
|
||||||
nameCell,
|
nameCell,
|
||||||
|
@ -123,13 +89,13 @@ namespace Bit.App.Pages
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(uriEntry.Text))
|
if(string.IsNullOrWhiteSpace(uriCell.Entry.Text))
|
||||||
{
|
{
|
||||||
await DisplayAlert(AppResources.AnErrorHasOccurred, string.Format(AppResources.ValidationFieldRequired, AppResources.URI), AppResources.Ok);
|
await DisplayAlert(AppResources.AnErrorHasOccurred, string.Format(AppResources.ValidationFieldRequired, AppResources.URI), AppResources.Ok);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(nameEntry.Text))
|
if(string.IsNullOrWhiteSpace(nameCell.Entry.Text))
|
||||||
{
|
{
|
||||||
await DisplayAlert(AppResources.AnErrorHasOccurred, string.Format(AppResources.ValidationFieldRequired, AppResources.Name), AppResources.Ok);
|
await DisplayAlert(AppResources.AnErrorHasOccurred, string.Format(AppResources.ValidationFieldRequired, AppResources.Name), AppResources.Ok);
|
||||||
return;
|
return;
|
||||||
|
@ -137,16 +103,16 @@ namespace Bit.App.Pages
|
||||||
|
|
||||||
var site = new Site
|
var site = new Site
|
||||||
{
|
{
|
||||||
Uri = uriEntry.Text.Encrypt(),
|
Uri = uriCell.Entry.Text.Encrypt(),
|
||||||
Name = nameEntry.Text.Encrypt(),
|
Name = nameCell.Entry.Text.Encrypt(),
|
||||||
Username = usernameEntry.Text?.Encrypt(),
|
Username = usernameCell.Entry.Text?.Encrypt(),
|
||||||
Password = passwordEntry.Text?.Encrypt(),
|
Password = passwordCell.Entry.Text?.Encrypt(),
|
||||||
Notes = notesEditor.Text?.Encrypt(),
|
Notes = notesCell.Editor.Text?.Encrypt(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if(folderPicker.SelectedIndex > 0)
|
if(folderCell.Picker.SelectedIndex > 0)
|
||||||
{
|
{
|
||||||
site.FolderId = folders.ElementAt(folderPicker.SelectedIndex - 1).Id;
|
site.FolderId = folders.ElementAt(folderCell.Picker.SelectedIndex - 1).Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
var saveTask = _siteService.SaveAsync(site);
|
var saveTask = _siteService.SaveAsync(site);
|
||||||
|
@ -155,12 +121,13 @@ namespace Bit.App.Pages
|
||||||
|
|
||||||
_userDialogs.HideLoading();
|
_userDialogs.HideLoading();
|
||||||
await Navigation.PopAsync();
|
await Navigation.PopAsync();
|
||||||
_userDialogs.SuccessToast(nameEntry.Text, "New site created.");
|
_userDialogs.SuccessToast(nameCell.Entry.Text, "New site created.");
|
||||||
}, ToolbarItemOrder.Default, 0);
|
}, ToolbarItemOrder.Default, 0);
|
||||||
|
|
||||||
Title = AppResources.AddSite;
|
Title = AppResources.AddSite;
|
||||||
Content = scrollView;
|
Content = scrollView;
|
||||||
ToolbarItems.Add(saveToolBarItem);
|
ToolbarItems.Add(saveToolBarItem);
|
||||||
|
ToolbarItems.Add(new DismissModalToolBarItem(this, "Cancel"));
|
||||||
|
|
||||||
if(!_connectivity.IsConnected)
|
if(!_connectivity.IsConnected)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection.Emit;
|
|
||||||
using System.Text;
|
|
||||||
using Acr.UserDialogs;
|
using Acr.UserDialogs;
|
||||||
using Bit.App.Abstractions;
|
using Bit.App.Abstractions;
|
||||||
|
using Bit.App.Controls;
|
||||||
using Bit.App.Resources;
|
using Bit.App.Resources;
|
||||||
using Plugin.Connectivity.Abstractions;
|
using Plugin.Connectivity.Abstractions;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
@ -40,12 +39,17 @@ namespace Bit.App.Pages
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var folders = _folderService.GetAllAsync().GetAwaiter().GetResult().OrderBy(f => f.Name?.Decrypt());
|
var uriCell = new FormEntryCell(AppResources.URI, Keyboard.Url);
|
||||||
|
uriCell.Entry.Text = site.Uri?.Decrypt();
|
||||||
|
var nameCell = new FormEntryCell(AppResources.Name);
|
||||||
|
nameCell.Entry.Text = site.Name?.Decrypt();
|
||||||
|
var usernameCell = new FormEntryCell(AppResources.Username);
|
||||||
|
usernameCell.Entry.Text = site.Username?.Decrypt();
|
||||||
|
var passwordCell = new FormEntryCell(AppResources.Password, IsPassword: true);
|
||||||
|
passwordCell.Entry.Text = site.Password?.Decrypt();
|
||||||
|
|
||||||
var uriEntry = new Entry { Keyboard = Keyboard.Url, Text = site.Uri?.Decrypt() };
|
var folderOptions = new List<string> { AppResources.FolderNone };
|
||||||
var nameEntry = new Entry { Text = site.Name?.Decrypt() };
|
var folders = _folderService.GetAllAsync().GetAwaiter().GetResult().OrderBy(f => f.Name?.Decrypt());
|
||||||
var folderPicker = new Picker { Title = AppResources.Folder };
|
|
||||||
folderPicker.Items.Add(AppResources.FolderNone);
|
|
||||||
int selectedIndex = 0;
|
int selectedIndex = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
foreach(var folder in folders)
|
foreach(var folder in folders)
|
||||||
|
@ -56,30 +60,46 @@ namespace Bit.App.Pages
|
||||||
selectedIndex = i;
|
selectedIndex = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
folderPicker.Items.Add(folder.Name.Decrypt());
|
folderOptions.Add(folder.Name.Decrypt());
|
||||||
}
|
}
|
||||||
folderPicker.SelectedIndex = selectedIndex;
|
var folderCell = new FormPickerCell(AppResources.Folder, folderOptions.ToArray());
|
||||||
var usernameEntry = new Entry { Text = site.Username?.Decrypt() };
|
folderCell.Picker.SelectedIndex = selectedIndex;
|
||||||
var passwordEntry = new Entry { IsPassword = true, Text = site.Password?.Decrypt() };
|
|
||||||
var notesEditor = new Editor { Text = site.Notes?.Decrypt() };
|
|
||||||
|
|
||||||
var stackLayout = new StackLayout();
|
var notesCell = new FormEditorCell(height: 90);
|
||||||
stackLayout.Children.Add(new Label { Text = AppResources.URI });
|
notesCell.Editor.Text = site.Notes?.Decrypt();
|
||||||
stackLayout.Children.Add(uriEntry);
|
|
||||||
stackLayout.Children.Add(new Label { Text = AppResources.Name });
|
var table = new ExtendedTableView
|
||||||
stackLayout.Children.Add(nameEntry);
|
{
|
||||||
stackLayout.Children.Add(new Label { Text = AppResources.Folder });
|
Intent = TableIntent.Settings,
|
||||||
stackLayout.Children.Add(folderPicker);
|
EnableScrolling = false,
|
||||||
stackLayout.Children.Add(new Label { Text = AppResources.Username });
|
HasUnevenRows = true,
|
||||||
stackLayout.Children.Add(usernameEntry);
|
EnableSelection = false,
|
||||||
stackLayout.Children.Add(new Label { Text = AppResources.Password });
|
Root = new TableRoot
|
||||||
stackLayout.Children.Add(passwordEntry);
|
{
|
||||||
stackLayout.Children.Add(new Label { Text = AppResources.Notes });
|
new TableSection("Site Information")
|
||||||
stackLayout.Children.Add(notesEditor);
|
{
|
||||||
|
uriCell,
|
||||||
|
nameCell,
|
||||||
|
folderCell,
|
||||||
|
usernameCell,
|
||||||
|
passwordCell
|
||||||
|
},
|
||||||
|
new TableSection(AppResources.Notes)
|
||||||
|
{
|
||||||
|
notesCell
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if(Device.OS == TargetPlatform.iOS)
|
||||||
|
{
|
||||||
|
table.RowHeight = -1;
|
||||||
|
table.EstimatedRowHeight = 70;
|
||||||
|
}
|
||||||
|
|
||||||
var scrollView = new ScrollView
|
var scrollView = new ScrollView
|
||||||
{
|
{
|
||||||
Content = stackLayout,
|
Content = table,
|
||||||
Orientation = ScrollOrientation.Vertical
|
Orientation = ScrollOrientation.Vertical
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -91,27 +111,31 @@ namespace Bit.App.Pages
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(uriEntry.Text))
|
if(string.IsNullOrWhiteSpace(uriCell.Entry.Text))
|
||||||
{
|
{
|
||||||
await DisplayAlert(AppResources.AnErrorHasOccurred, string.Format(AppResources.ValidationFieldRequired, AppResources.URI), AppResources.Ok);
|
await DisplayAlert(AppResources.AnErrorHasOccurred, string.Format(AppResources.ValidationFieldRequired, AppResources.URI), AppResources.Ok);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(nameEntry.Text))
|
if(string.IsNullOrWhiteSpace(nameCell.Entry.Text))
|
||||||
{
|
{
|
||||||
await DisplayAlert(AppResources.AnErrorHasOccurred, string.Format(AppResources.ValidationFieldRequired, AppResources.Name), AppResources.Ok);
|
await DisplayAlert(AppResources.AnErrorHasOccurred, string.Format(AppResources.ValidationFieldRequired, AppResources.Name), AppResources.Ok);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
site.Uri = uriEntry.Text.Encrypt();
|
site.Uri = uriCell.Entry.Text.Encrypt();
|
||||||
site.Name = nameEntry.Text.Encrypt();
|
site.Name = nameCell.Entry.Text.Encrypt();
|
||||||
site.Username = usernameEntry.Text?.Encrypt();
|
site.Username = usernameCell.Entry.Text?.Encrypt();
|
||||||
site.Password = passwordEntry.Text?.Encrypt();
|
site.Password = passwordCell.Entry.Text?.Encrypt();
|
||||||
site.Notes = notesEditor.Text?.Encrypt();
|
site.Notes = notesCell.Editor.Text?.Encrypt();
|
||||||
|
|
||||||
if(folderPicker.SelectedIndex > 0)
|
if(folderCell.Picker.SelectedIndex > 0)
|
||||||
{
|
{
|
||||||
site.FolderId = folders.ElementAt(folderPicker.SelectedIndex - 1).Id;
|
site.FolderId = folders.ElementAt(folderCell.Picker.SelectedIndex - 1).Id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
site.FolderId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var saveTask = _siteService.SaveAsync(site);
|
var saveTask = _siteService.SaveAsync(site);
|
||||||
|
@ -119,13 +143,14 @@ namespace Bit.App.Pages
|
||||||
await saveTask;
|
await saveTask;
|
||||||
|
|
||||||
_userDialogs.HideLoading();
|
_userDialogs.HideLoading();
|
||||||
await Navigation.PopAsync();
|
await Navigation.PopModalAsync();
|
||||||
_userDialogs.SuccessToast(nameEntry.Text, "Site updated.");
|
_userDialogs.SuccessToast(nameCell.Entry.Text, "Site updated.");
|
||||||
}, ToolbarItemOrder.Default, 0);
|
}, ToolbarItemOrder.Default, 0);
|
||||||
|
|
||||||
Title = "Edit Site";
|
Title = "Edit Site";
|
||||||
Content = scrollView;
|
Content = scrollView;
|
||||||
ToolbarItems.Add(saveToolBarItem);
|
ToolbarItems.Add(saveToolBarItem);
|
||||||
|
ToolbarItems.Add(new DismissModalToolBarItem(this, "Cancel"));
|
||||||
|
|
||||||
if(!_connectivity.IsConnected)
|
if(!_connectivity.IsConnected)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Acr.UserDialogs;
|
using Acr.UserDialogs;
|
||||||
using Bit.App.Abstractions;
|
using Bit.App.Abstractions;
|
||||||
|
using Bit.App.Controls;
|
||||||
using Bit.App.Models.Page;
|
using Bit.App.Models.Page;
|
||||||
using Bit.App.Resources;
|
using Bit.App.Resources;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
@ -71,7 +72,8 @@ namespace Bit.App.Pages
|
||||||
private void SiteSelected(object sender, SelectedItemChangedEventArgs e)
|
private void SiteSelected(object sender, SelectedItemChangedEventArgs e)
|
||||||
{
|
{
|
||||||
var site = e.SelectedItem as VaultListPageModel.Site;
|
var site = e.SelectedItem as VaultListPageModel.Site;
|
||||||
Navigation.PushAsync(new VaultViewSitePage(site.Id));
|
var page = new ExtendedNavigationPage(new VaultViewSitePage(site.Id));
|
||||||
|
Navigation.PushModalAsync(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void MoreClickedAsync(object sender, EventArgs e)
|
private async void MoreClickedAsync(object sender, EventArgs e)
|
||||||
|
@ -83,11 +85,13 @@ namespace Bit.App.Pages
|
||||||
|
|
||||||
if(selection == AppResources.View)
|
if(selection == AppResources.View)
|
||||||
{
|
{
|
||||||
await Navigation.PushAsync(new VaultViewSitePage(site.Id));
|
var page = new ExtendedNavigationPage(new VaultViewSitePage(site.Id));
|
||||||
|
await Navigation.PushModalAsync(page);
|
||||||
}
|
}
|
||||||
else if(selection == AppResources.Edit)
|
else if(selection == AppResources.Edit)
|
||||||
{
|
{
|
||||||
// TODO: navigate to edit page
|
var page = new ExtendedNavigationPage(new VaultEditSitePage(site.Id));
|
||||||
|
await Navigation.PushModalAsync(page);
|
||||||
}
|
}
|
||||||
else if(selection == AppResources.CopyPassword)
|
else if(selection == AppResources.CopyPassword)
|
||||||
{
|
{
|
||||||
|
@ -147,7 +151,8 @@ namespace Bit.App.Pages
|
||||||
|
|
||||||
private async void ClickedItem(object sender, EventArgs e)
|
private async void ClickedItem(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
await _page.Navigation.PushAsync(new VaultAddSitePage());
|
var page = new ExtendedNavigationPage(new VaultAddSitePage());
|
||||||
|
await _page.Navigation.PushModalAsync(page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using Acr.UserDialogs;
|
using Acr.UserDialogs;
|
||||||
using Bit.App.Abstractions;
|
using Bit.App.Abstractions;
|
||||||
|
using Bit.App.Controls;
|
||||||
using Bit.App.Models.Page;
|
using Bit.App.Models.Page;
|
||||||
using Bit.App.Resources;
|
using Bit.App.Resources;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
@ -30,6 +31,7 @@ namespace Bit.App.Pages
|
||||||
private void Init()
|
private void Init()
|
||||||
{
|
{
|
||||||
ToolbarItems.Add(new EditSiteToolBarItem(this, _siteId));
|
ToolbarItems.Add(new EditSiteToolBarItem(this, _siteId));
|
||||||
|
ToolbarItems.Add(new DismissModalToolBarItem(this));
|
||||||
var stackLayout = new StackLayout();
|
var stackLayout = new StackLayout();
|
||||||
|
|
||||||
// Username
|
// Username
|
||||||
|
@ -157,7 +159,8 @@ namespace Bit.App.Pages
|
||||||
|
|
||||||
private async void ClickedItem(object sender, EventArgs e)
|
private async void ClickedItem(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
await _page.Navigation.PushAsync(new VaultEditSitePage(_siteId));
|
var page = new ExtendedNavigationPage(new VaultEditSitePage(_siteId));
|
||||||
|
await _page.Navigation.PushModalAsync(page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
68
src/iOS/Controls/ContentPageRenderer.cs
Normal file
68
src/iOS/Controls/ContentPageRenderer.cs
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using Bit.iOS.Controls;
|
||||||
|
using UIKit;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using Xamarin.Forms.Platform.iOS;
|
||||||
|
|
||||||
|
[assembly: ExportRenderer(typeof(ContentPage), typeof(ContentPageRenderer))]
|
||||||
|
namespace Bit.iOS.Controls
|
||||||
|
{
|
||||||
|
public class ContentPageRenderer : PageRenderer
|
||||||
|
{
|
||||||
|
public override void ViewWillAppear(bool animated)
|
||||||
|
{
|
||||||
|
base.ViewWillAppear(animated);
|
||||||
|
|
||||||
|
var contentPage = Element as ContentPage;
|
||||||
|
if(contentPage == null || NavigationController == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var itemsInfo = contentPage.ToolbarItems;
|
||||||
|
|
||||||
|
var navigationItem = NavigationController.TopViewController.NavigationItem;
|
||||||
|
var leftNativeButtons = (navigationItem.LeftBarButtonItems ?? new UIBarButtonItem[] { }).ToList();
|
||||||
|
var rightNativeButtons = (navigationItem.RightBarButtonItems ?? new UIBarButtonItem[] { }).ToList();
|
||||||
|
|
||||||
|
var newLeftButtons = new List<UIBarButtonItem>();
|
||||||
|
var newRightButtons = new List<UIBarButtonItem>();
|
||||||
|
|
||||||
|
rightNativeButtons.ForEach(nativeItem =>
|
||||||
|
{
|
||||||
|
// Use reflection to get Xamarin private field "_item"
|
||||||
|
var field = nativeItem.GetType().GetField("_item", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||||
|
if(field == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var info = field.GetValue(nativeItem) as ToolbarItem;
|
||||||
|
if(info == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(info.Priority < 0)
|
||||||
|
{
|
||||||
|
newLeftButtons.Add(nativeItem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newRightButtons.Add(nativeItem);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
leftNativeButtons.ForEach(nativeItem =>
|
||||||
|
{
|
||||||
|
newLeftButtons.Add(nativeItem);
|
||||||
|
});
|
||||||
|
|
||||||
|
navigationItem.RightBarButtonItems = newRightButtons.ToArray();
|
||||||
|
navigationItem.LeftBarButtonItems = newLeftButtons.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -101,6 +101,7 @@
|
||||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
|
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Controls\ContentPageRenderer.cs" />
|
||||||
<Compile Include="Controls\ExtendedTableViewRenderer.cs" />
|
<Compile Include="Controls\ExtendedTableViewRenderer.cs" />
|
||||||
<Compile Include="Controls\ExtendedPickerRenderer.cs" />
|
<Compile Include="Controls\ExtendedPickerRenderer.cs" />
|
||||||
<Compile Include="Controls\ExtendedEntryRenderer.cs" />
|
<Compile Include="Controls\ExtendedEntryRenderer.cs" />
|
||||||
|
|
Loading…
Reference in a new issue