mirror of
https://github.com/bitwarden/mobile
synced 2026-01-10 04:23:21 +00:00
Organizated pages into folders based on app "section"
This commit is contained in:
100
src/App/Pages/Settings/SettingsAddFolderPage.cs
Normal file
100
src/App/Pages/Settings/SettingsAddFolderPage.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
using System;
|
||||
using Acr.UserDialogs;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Controls;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Resources;
|
||||
using Plugin.Connectivity.Abstractions;
|
||||
using Xamarin.Forms;
|
||||
using XLabs.Ioc;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class SettingsAddFolderPage : ExtendedContentPage
|
||||
{
|
||||
private readonly IFolderService _folderService;
|
||||
private readonly IUserDialogs _userDialogs;
|
||||
private readonly IConnectivity _connectivity;
|
||||
|
||||
public SettingsAddFolderPage()
|
||||
{
|
||||
_folderService = Resolver.Resolve<IFolderService>();
|
||||
_userDialogs = Resolver.Resolve<IUserDialogs>();
|
||||
_connectivity = Resolver.Resolve<IConnectivity>();
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
private void Init()
|
||||
{
|
||||
var nameCell = new FormEntryCell(AppResources.Name);
|
||||
|
||||
var table = new ExtendedTableView
|
||||
{
|
||||
Intent = TableIntent.Settings,
|
||||
EnableScrolling = false,
|
||||
HasUnevenRows = true,
|
||||
EnableSelection = false,
|
||||
Root = new TableRoot
|
||||
{
|
||||
new TableSection()
|
||||
{
|
||||
nameCell
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if(Device.OS == TargetPlatform.iOS)
|
||||
{
|
||||
table.RowHeight = -1;
|
||||
table.EstimatedRowHeight = 70;
|
||||
}
|
||||
|
||||
var saveToolBarItem = new ToolbarItem(AppResources.Save, null, async () =>
|
||||
{
|
||||
if(!_connectivity.IsConnected)
|
||||
{
|
||||
AlertNoConnection();
|
||||
return;
|
||||
}
|
||||
|
||||
if(string.IsNullOrWhiteSpace(nameCell.Entry.Text))
|
||||
{
|
||||
await DisplayAlert(AppResources.AnErrorHasOccurred, string.Format(AppResources.ValidationFieldRequired, AppResources.Name), AppResources.Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
var folder = new Folder
|
||||
{
|
||||
Name = nameCell.Entry.Text.Encrypt()
|
||||
};
|
||||
|
||||
var saveTask = _folderService.SaveAsync(folder);
|
||||
_userDialogs.ShowLoading("Saving...", MaskType.Black);
|
||||
await saveTask;
|
||||
|
||||
_userDialogs.HideLoading();
|
||||
await Navigation.PopModalAsync();
|
||||
_userDialogs.SuccessToast(nameCell.Entry.Text, "New folder created.");
|
||||
}, ToolbarItemOrder.Default, 0);
|
||||
|
||||
Title = "Add Folder";
|
||||
Content = table;
|
||||
ToolbarItems.Add(saveToolBarItem);
|
||||
if(Device.OS == TargetPlatform.iOS)
|
||||
{
|
||||
ToolbarItems.Add(new DismissModalToolBarItem(this, "Cancel"));
|
||||
}
|
||||
|
||||
if(!_connectivity.IsConnected)
|
||||
{
|
||||
AlertNoConnection();
|
||||
}
|
||||
}
|
||||
|
||||
private void AlertNoConnection()
|
||||
{
|
||||
DisplayAlert(AppResources.InternetConnectionRequiredTitle, AppResources.InternetConnectionRequiredMessage, AppResources.Ok);
|
||||
}
|
||||
}
|
||||
}
|
||||
144
src/App/Pages/Settings/SettingsEditFolderPage.cs
Normal file
144
src/App/Pages/Settings/SettingsEditFolderPage.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using Acr.UserDialogs;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Controls;
|
||||
using Bit.App.Resources;
|
||||
using Plugin.Connectivity.Abstractions;
|
||||
using Xamarin.Forms;
|
||||
using XLabs.Ioc;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class SettingsEditFolderPage : ExtendedContentPage
|
||||
{
|
||||
private readonly string _folderId;
|
||||
private readonly IFolderService _folderService;
|
||||
private readonly IUserDialogs _userDialogs;
|
||||
private readonly IConnectivity _connectivity;
|
||||
|
||||
public SettingsEditFolderPage(string folderId)
|
||||
{
|
||||
_folderId = folderId;
|
||||
_folderService = Resolver.Resolve<IFolderService>();
|
||||
_userDialogs = Resolver.Resolve<IUserDialogs>();
|
||||
_connectivity = Resolver.Resolve<IConnectivity>();
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
private void Init()
|
||||
{
|
||||
var folder = _folderService.GetByIdAsync(_folderId).GetAwaiter().GetResult();
|
||||
if(folder == null)
|
||||
{
|
||||
// TODO: handle error. navigate back? should never happen...
|
||||
return;
|
||||
}
|
||||
|
||||
var nameCell = new FormEntryCell(AppResources.Name);
|
||||
nameCell.Entry.Text = folder.Name.Decrypt();
|
||||
|
||||
var deleteCell = new ExtendedTextCell { Text = AppResources.Delete, TextColor = Color.Red };
|
||||
deleteCell.Tapped += DeleteCell_Tapped;
|
||||
|
||||
var mainTable = new ExtendedTableView
|
||||
{
|
||||
Intent = TableIntent.Settings,
|
||||
EnableScrolling = false,
|
||||
EnableSelection = false,
|
||||
HasUnevenRows = true,
|
||||
Root = new TableRoot
|
||||
{
|
||||
new TableSection()
|
||||
{
|
||||
nameCell
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if(Device.OS == TargetPlatform.iOS)
|
||||
{
|
||||
mainTable.RowHeight = -1;
|
||||
mainTable.EstimatedRowHeight = 70;
|
||||
}
|
||||
|
||||
var deleteTable = new ExtendedTableView
|
||||
{
|
||||
Intent = TableIntent.Settings,
|
||||
EnableScrolling = false,
|
||||
EnableSelection = true,
|
||||
Root = new TableRoot
|
||||
{
|
||||
new TableSection()
|
||||
{
|
||||
deleteCell
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var saveToolBarItem = new ToolbarItem(AppResources.Save, null, async () =>
|
||||
{
|
||||
if(!_connectivity.IsConnected)
|
||||
{
|
||||
AlertNoConnection();
|
||||
return;
|
||||
}
|
||||
|
||||
if(string.IsNullOrWhiteSpace(nameCell.Entry.Text))
|
||||
{
|
||||
await DisplayAlert(AppResources.AnErrorHasOccurred, string.Format(AppResources.ValidationFieldRequired, AppResources.Name), AppResources.Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
folder.Name = nameCell.Entry.Text.Encrypt();
|
||||
|
||||
var saveTask = _folderService.SaveAsync(folder);
|
||||
_userDialogs.ShowLoading("Saving...", MaskType.Black);
|
||||
await saveTask;
|
||||
|
||||
_userDialogs.HideLoading();
|
||||
await Navigation.PopModalAsync();
|
||||
_userDialogs.SuccessToast(nameCell.Entry.Text, "Folder updated.");
|
||||
}, ToolbarItemOrder.Default, 0);
|
||||
|
||||
Title = "Edit Folder";
|
||||
Content = new StackLayout { Children = { mainTable, deleteTable } };
|
||||
ToolbarItems.Add(saveToolBarItem);
|
||||
if(Device.OS == TargetPlatform.iOS)
|
||||
{
|
||||
ToolbarItems.Add(new DismissModalToolBarItem(this, "Cancel"));
|
||||
}
|
||||
|
||||
if(!_connectivity.IsConnected)
|
||||
{
|
||||
AlertNoConnection();
|
||||
}
|
||||
}
|
||||
|
||||
private async void DeleteCell_Tapped(object sender, EventArgs e)
|
||||
{
|
||||
// TODO: Validate the delete operation. ex. Cannot delete a folder that has sites in it?
|
||||
|
||||
if(!await _userDialogs.ConfirmAsync(AppResources.DoYouReallyWantToDelete, null, AppResources.Yes, AppResources.No))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var deleteTask = _folderService.DeleteAsync(_folderId);
|
||||
_userDialogs.ShowLoading("Deleting...", MaskType.Black);
|
||||
await deleteTask;
|
||||
_userDialogs.HideLoading();
|
||||
|
||||
if((await deleteTask).Succeeded)
|
||||
{
|
||||
await Navigation.PopModalAsync();
|
||||
_userDialogs.SuccessToast("Folder deleted.");
|
||||
}
|
||||
}
|
||||
|
||||
private void AlertNoConnection()
|
||||
{
|
||||
DisplayAlert(AppResources.InternetConnectionRequiredTitle, AppResources.InternetConnectionRequiredMessage, AppResources.Ok);
|
||||
}
|
||||
}
|
||||
}
|
||||
92
src/App/Pages/Settings/SettingsListFoldersPage.cs
Normal file
92
src/App/Pages/Settings/SettingsListFoldersPage.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Acr.UserDialogs;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Controls;
|
||||
using Bit.App.Models.Page;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities;
|
||||
using Xamarin.Forms;
|
||||
using XLabs.Ioc;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class SettingsListFoldersPage : ExtendedContentPage
|
||||
{
|
||||
private readonly IFolderService _folderService;
|
||||
private readonly IUserDialogs _userDialogs;
|
||||
public SettingsListFoldersPage()
|
||||
{
|
||||
_folderService = Resolver.Resolve<IFolderService>();
|
||||
_userDialogs = Resolver.Resolve<IUserDialogs>();
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
public ExtendedObservableCollection<SettingsFolderPageModel> Folders { get; private set; } = new ExtendedObservableCollection<SettingsFolderPageModel>();
|
||||
|
||||
private void Init()
|
||||
{
|
||||
ToolbarItems.Add(new AddFolderToolBarItem(this));
|
||||
|
||||
var listView = new ListView
|
||||
{
|
||||
ItemsSource = Folders
|
||||
};
|
||||
listView.ItemSelected += FolderSelected;
|
||||
listView.ItemTemplate = new DataTemplate(() => new SettingsFolderListViewCell(this));
|
||||
|
||||
Title = "Folders";
|
||||
Content = listView;
|
||||
}
|
||||
|
||||
protected override void OnAppearing()
|
||||
{
|
||||
base.OnAppearing();
|
||||
LoadFoldersAsync().Wait();
|
||||
}
|
||||
|
||||
private async Task LoadFoldersAsync()
|
||||
{
|
||||
var folders = await _folderService.GetAllAsync();
|
||||
var pageFolders = folders.Select(f => new SettingsFolderPageModel(f));
|
||||
Folders.ResetWithRange(pageFolders);
|
||||
}
|
||||
|
||||
private void FolderSelected(object sender, SelectedItemChangedEventArgs e)
|
||||
{
|
||||
var folder = e.SelectedItem as SettingsFolderPageModel;
|
||||
var page = new ExtendedNavigationPage(new SettingsEditFolderPage(folder.Id));
|
||||
Navigation.PushModalAsync(page);
|
||||
}
|
||||
|
||||
private class AddFolderToolBarItem : ToolbarItem
|
||||
{
|
||||
private readonly SettingsListFoldersPage _page;
|
||||
|
||||
public AddFolderToolBarItem(SettingsListFoldersPage page)
|
||||
{
|
||||
_page = page;
|
||||
Text = AppResources.Add;
|
||||
Icon = "plus";
|
||||
Clicked += ClickedItem;
|
||||
}
|
||||
|
||||
private async void ClickedItem(object sender, EventArgs e)
|
||||
{
|
||||
var page = new ExtendedNavigationPage(new SettingsAddFolderPage());
|
||||
await _page.Navigation.PushModalAsync(page);
|
||||
}
|
||||
}
|
||||
|
||||
private class SettingsFolderListViewCell : ExtendedTextCell
|
||||
{
|
||||
public SettingsFolderListViewCell(SettingsListFoldersPage page)
|
||||
{
|
||||
this.SetBinding<SettingsFolderPageModel>(TextProperty, s => s.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
296
src/App/Pages/Settings/SettingsPage.cs
Normal file
296
src/App/Pages/Settings/SettingsPage.cs
Normal file
@@ -0,0 +1,296 @@
|
||||
using System;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Xamarin.Forms;
|
||||
using XLabs.Ioc;
|
||||
using Bit.App.Controls;
|
||||
using Acr.UserDialogs;
|
||||
using Plugin.Settings.Abstractions;
|
||||
using Plugin.Fingerprint.Abstractions;
|
||||
using PushNotification.Plugin.Abstractions;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class SettingsPage : ExtendedContentPage
|
||||
{
|
||||
private readonly IAuthService _authService;
|
||||
private readonly IUserDialogs _userDialogs;
|
||||
private readonly ISettings _settings;
|
||||
private readonly IFingerprint _fingerprint;
|
||||
private readonly IPushNotification _pushNotification;
|
||||
|
||||
// TODO: Model binding context?
|
||||
|
||||
public SettingsPage()
|
||||
{
|
||||
_authService = Resolver.Resolve<IAuthService>();
|
||||
_userDialogs = Resolver.Resolve<IUserDialogs>();
|
||||
_settings = Resolver.Resolve<ISettings>();
|
||||
_fingerprint = Resolver.Resolve<IFingerprint>();
|
||||
_pushNotification = Resolver.Resolve<IPushNotification>();
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
private ExtendedSwitchCell PinCell { get; set; }
|
||||
private ExtendedSwitchCell FingerprintCell { get; set; }
|
||||
private ExtendedTextCell LockOptionsCell { get; set; }
|
||||
|
||||
private void Init()
|
||||
{
|
||||
FingerprintCell = new ExtendedSwitchCell
|
||||
{
|
||||
Text = "Use Touch ID" + (!_fingerprint.IsAvailable ? " (Unavilable)" : null),
|
||||
On = _settings.GetValueOrDefault<bool>(Constants.SettingFingerprintUnlockOn),
|
||||
IsEnabled = _fingerprint.IsAvailable
|
||||
};
|
||||
FingerprintCell.OnChanged += FingerprintCell_Changed;
|
||||
|
||||
PinCell = new ExtendedSwitchCell
|
||||
{
|
||||
Text = "Use PIN Code",
|
||||
On = _settings.GetValueOrDefault<bool>(Constants.SettingPinUnlockOn)
|
||||
};
|
||||
PinCell.OnChanged += PinCell_Changed;
|
||||
|
||||
LockOptionsCell = new ExtendedTextCell
|
||||
{
|
||||
Text = "Lock Options",
|
||||
Detail = GetLockOptionsDetailsText(),
|
||||
ShowDisclousure = true
|
||||
};
|
||||
LockOptionsCell.Tapped += LockOptionsCell_Tapped;
|
||||
|
||||
var changeMasterPasswordCell = new ExtendedTextCell
|
||||
{
|
||||
Text = "Change Master Password",
|
||||
ShowDisclousure = true
|
||||
};
|
||||
changeMasterPasswordCell.Tapped += ChangeMasterPasswordCell_Tapped;
|
||||
|
||||
var foldersCell = new ExtendedTextCell
|
||||
{
|
||||
Text = "Folders",
|
||||
ShowDisclousure = true
|
||||
};
|
||||
foldersCell.Tapped += FoldersCell_Tapped;
|
||||
|
||||
var syncCell = new ExtendedTextCell
|
||||
{
|
||||
Text = "Sync",
|
||||
ShowDisclousure = true
|
||||
};
|
||||
syncCell.Tapped += SyncCell_Tapped;
|
||||
|
||||
var lockCell = new ExtendedTextCell
|
||||
{
|
||||
Text = "Lock"
|
||||
};
|
||||
lockCell.Tapped += LockCell_Tapped;
|
||||
|
||||
var logOutCell = new ExtendedTextCell
|
||||
{
|
||||
Text = "Log Out"
|
||||
};
|
||||
logOutCell.Tapped += LogOutCell_Tapped;
|
||||
|
||||
var table = new ExtendedTableView
|
||||
{
|
||||
EnableScrolling = true,
|
||||
Intent = TableIntent.Menu,
|
||||
HasUnevenRows = true,
|
||||
Root = new TableRoot
|
||||
{
|
||||
new TableSection("Security")
|
||||
{
|
||||
LockOptionsCell,
|
||||
FingerprintCell,
|
||||
PinCell,
|
||||
changeMasterPasswordCell
|
||||
},
|
||||
new TableSection("Manage")
|
||||
{
|
||||
foldersCell,
|
||||
syncCell
|
||||
},
|
||||
new TableSection("Current Session")
|
||||
{
|
||||
lockCell,
|
||||
logOutCell
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if( Device.OS == TargetPlatform.iOS )
|
||||
{
|
||||
table.RowHeight = -1;
|
||||
table.EstimatedRowHeight = 44;
|
||||
}
|
||||
|
||||
Title = AppResources.Settings;
|
||||
Content = table;
|
||||
}
|
||||
|
||||
private async void LockOptionsCell_Tapped(object sender, EventArgs e)
|
||||
{
|
||||
var selection = await DisplayActionSheet("Lock Options", AppResources.Cancel, null,
|
||||
"Immediately", "1 minute", "15 minutes", "1 hour", "4 hours", "Never");
|
||||
|
||||
if(selection == AppResources.Cancel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(selection == "Immediately")
|
||||
{
|
||||
_settings.AddOrUpdateValue(Constants.SettingLockSeconds, 0);
|
||||
}
|
||||
else if(selection == "1 minute")
|
||||
{
|
||||
_settings.AddOrUpdateValue(Constants.SettingLockSeconds, 60);
|
||||
}
|
||||
else if(selection == "5 minutes")
|
||||
{
|
||||
_settings.AddOrUpdateValue(Constants.SettingLockSeconds, 60 * 5);
|
||||
}
|
||||
else if(selection == "15 minutes")
|
||||
{
|
||||
_settings.AddOrUpdateValue(Constants.SettingLockSeconds, 60 * 15);
|
||||
}
|
||||
else if(selection == "1 hour")
|
||||
{
|
||||
_settings.AddOrUpdateValue(Constants.SettingLockSeconds, 60 * 60);
|
||||
}
|
||||
else if(selection == "4 hours")
|
||||
{
|
||||
_settings.AddOrUpdateValue(Constants.SettingLockSeconds, 60 * 60 * 4);
|
||||
}
|
||||
else if(selection == "Never")
|
||||
{
|
||||
_settings.Remove(Constants.SettingLockSeconds);
|
||||
}
|
||||
|
||||
LockOptionsCell.Detail = selection;
|
||||
}
|
||||
|
||||
private void SyncCell_Tapped(object sender, EventArgs e)
|
||||
{
|
||||
Navigation.PushAsync(new SettingsSyncPage());
|
||||
}
|
||||
|
||||
private void LockCell_Tapped(object sender, EventArgs e)
|
||||
{
|
||||
MessagingCenter.Send(Application.Current, "Lock", true);
|
||||
}
|
||||
|
||||
private async void LogOutCell_Tapped(object sender, EventArgs e)
|
||||
{
|
||||
if(!await _userDialogs.ConfirmAsync("Are you sure you want to log out?", null, AppResources.Yes, AppResources.Cancel))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_authService.LogOut();
|
||||
_pushNotification.Unregister();
|
||||
Application.Current.MainPage = new HomePage();
|
||||
}
|
||||
|
||||
private async void ChangeMasterPasswordCell_Tapped(object sender, EventArgs e)
|
||||
{
|
||||
if(!await _userDialogs.ConfirmAsync("You can change your master password on the bitwarden.com web vault. Do you want to visit the website now?", null, AppResources.Yes, AppResources.Cancel))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Device.OpenUri(new Uri("https://vault.bitwarden.com"));
|
||||
}
|
||||
|
||||
private void FingerprintCell_Changed(object sender, EventArgs e)
|
||||
{
|
||||
var cell = sender as ExtendedSwitchCell;
|
||||
if(cell == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_settings.AddOrUpdateValue(Constants.SettingFingerprintUnlockOn, cell.On);
|
||||
|
||||
if(cell.On)
|
||||
{
|
||||
_settings.AddOrUpdateValue(Constants.SettingPinUnlockOn, false);
|
||||
PinCell.On = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void PinCell_Changed(object sender, EventArgs e)
|
||||
{
|
||||
var cell = sender as ExtendedSwitchCell;
|
||||
if(cell == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(cell.On)
|
||||
{
|
||||
var pinPage = new SettingsPinPage();
|
||||
pinPage.OnPinEntered += PinEntered;
|
||||
Navigation.PushAsync(pinPage);
|
||||
}
|
||||
else
|
||||
{
|
||||
_settings.AddOrUpdateValue(Constants.SettingPinUnlockOn, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void PinEntered(object sender, EventArgs args)
|
||||
{
|
||||
var page = sender as SettingsPinPage;
|
||||
page.Navigation.PopAsync();
|
||||
|
||||
_authService.PIN = page.Model.PIN;
|
||||
|
||||
_settings.AddOrUpdateValue(Constants.SettingPinUnlockOn, true);
|
||||
_settings.AddOrUpdateValue(Constants.SettingFingerprintUnlockOn, false);
|
||||
FingerprintCell.On = false;
|
||||
}
|
||||
|
||||
private void FoldersCell_Tapped(object sender, EventArgs e)
|
||||
{
|
||||
Navigation.PushAsync(new SettingsListFoldersPage());
|
||||
}
|
||||
|
||||
private string GetLockOptionsDetailsText()
|
||||
{
|
||||
var lockSeconds = _settings.GetValueOrDefault<int?>(Constants.SettingLockSeconds);
|
||||
if(!lockSeconds.HasValue)
|
||||
{
|
||||
return "Never";
|
||||
}
|
||||
|
||||
if(lockSeconds.Value == 60)
|
||||
{
|
||||
return "1 minute";
|
||||
}
|
||||
else if(lockSeconds.Value == 60 * 5)
|
||||
{
|
||||
return "5 minutes";
|
||||
}
|
||||
else if(lockSeconds.Value == 60 * 15)
|
||||
{
|
||||
return "15 minutes";
|
||||
}
|
||||
else if(lockSeconds.Value == 60 * 60)
|
||||
{
|
||||
return "1 hour";
|
||||
}
|
||||
else if(lockSeconds.Value == 60 * 60 * 4)
|
||||
{
|
||||
return "4 hours";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Immediately";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
71
src/App/Pages/Settings/SettingsPinPage.cs
Normal file
71
src/App/Pages/Settings/SettingsPinPage.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Acr.UserDialogs;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Xamarin.Forms;
|
||||
using XLabs.Ioc;
|
||||
using Plugin.Settings.Abstractions;
|
||||
using Bit.App.Models.Page;
|
||||
using Bit.App.Controls;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class SettingsPinPage : ExtendedContentPage
|
||||
{
|
||||
private readonly IUserDialogs _userDialogs;
|
||||
private readonly ISettings _settings;
|
||||
|
||||
public SettingsPinPage()
|
||||
{
|
||||
_userDialogs = Resolver.Resolve<IUserDialogs>();
|
||||
_settings = Resolver.Resolve<ISettings>();
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
public PinPageModel Model { get; set; } = new PinPageModel();
|
||||
public PinControl PinControl { get; set; }
|
||||
public EventHandler OnPinEntered;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
PinControl = new PinControl();
|
||||
PinControl.OnPinEntered += PinEntered;
|
||||
PinControl.Label.SetBinding<PinPageModel>(Label.TextProperty, s => s.LabelText);
|
||||
PinControl.Entry.SetBinding<PinPageModel>(Entry.TextProperty, s => s.PIN);
|
||||
|
||||
var stackLayout = new StackLayout
|
||||
{
|
||||
Padding = new Thickness(30, 40),
|
||||
Spacing = 10,
|
||||
Children = { PinControl.Label, PinControl.Entry }
|
||||
};
|
||||
|
||||
var tgr = new TapGestureRecognizer();
|
||||
tgr.Tapped += Tgr_Tapped;
|
||||
PinControl.Label.GestureRecognizers.Add(tgr);
|
||||
|
||||
Title = "Set PIN";
|
||||
Content = stackLayout;
|
||||
Content.GestureRecognizers.Add(tgr);
|
||||
BindingContext = Model;
|
||||
}
|
||||
|
||||
private void Tgr_Tapped(object sender, EventArgs e)
|
||||
{
|
||||
PinControl.Entry.Focus();
|
||||
}
|
||||
|
||||
protected override void OnAppearing()
|
||||
{
|
||||
base.OnAppearing();
|
||||
PinControl.Entry.Focus();
|
||||
}
|
||||
|
||||
protected void PinEntered(object sender, EventArgs args)
|
||||
{
|
||||
OnPinEntered.Invoke(this, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
75
src/App/Pages/Settings/SettingsSyncPage.cs
Normal file
75
src/App/Pages/Settings/SettingsSyncPage.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Acr.UserDialogs;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Controls;
|
||||
using Bit.App.Resources;
|
||||
using Plugin.Connectivity.Abstractions;
|
||||
using Xamarin.Forms;
|
||||
using XLabs.Ioc;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class SettingsSyncPage : ExtendedContentPage
|
||||
{
|
||||
private readonly ISyncService _syncService;
|
||||
private readonly IUserDialogs _userDialogs;
|
||||
private readonly IConnectivity _connectivity;
|
||||
|
||||
public SettingsSyncPage()
|
||||
{
|
||||
_syncService = Resolver.Resolve<ISyncService>();
|
||||
_userDialogs = Resolver.Resolve<IUserDialogs>();
|
||||
_connectivity = Resolver.Resolve<IConnectivity>();
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
var syncButton = new Button
|
||||
{
|
||||
Text = "Sync Vault",
|
||||
Command = new Command(async () => await SyncAsync())
|
||||
};
|
||||
|
||||
var stackLayout = new StackLayout { };
|
||||
stackLayout.Children.Add(syncButton);
|
||||
|
||||
Title = "Sync";
|
||||
Content = stackLayout;
|
||||
Icon = "fa-refresh";
|
||||
|
||||
if(!_connectivity.IsConnected)
|
||||
{
|
||||
AlertNoConnection();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SyncAsync()
|
||||
{
|
||||
if(!_connectivity.IsConnected)
|
||||
{
|
||||
AlertNoConnection();
|
||||
return;
|
||||
}
|
||||
|
||||
_userDialogs.ShowLoading("Syncing...", MaskType.Black);
|
||||
var succeeded = await _syncService.FullSyncAsync();
|
||||
_userDialogs.HideLoading();
|
||||
if(succeeded)
|
||||
{
|
||||
_userDialogs.SuccessToast("Syncing complete.");
|
||||
}
|
||||
else
|
||||
{
|
||||
_userDialogs.ErrorToast("Syncing failed.");
|
||||
}
|
||||
}
|
||||
|
||||
public void AlertNoConnection()
|
||||
{
|
||||
DisplayAlert(AppResources.InternetConnectionRequiredTitle, AppResources.InternetConnectionRequiredMessage, AppResources.Ok);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user