Detach events

This commit is contained in:
Kyle Spearrin 2017-02-17 21:18:59 -05:00
parent 22f3bd1073
commit 27e996dba0
13 changed files with 344 additions and 165 deletions

View file

@ -154,10 +154,10 @@ namespace Bit.Android
{ {
if(addressNode?.Text != null) if(addressNode?.Text != null)
{ {
uri = browser.GetUriFunction(addressNode.Text); uri = browser.GetUriFunction(addressNode.Text).Trim();
if(uri != null && uri.Contains(".")) if(uri != null && uri.Contains("."))
{ {
if(!uri.Contains("://")) if(!uri.Contains("://") && !uri.Contains(" "))
{ {
uri = string.Concat("http://", uri); uri = string.Concat("http://", uri);
} }

View file

@ -18,13 +18,15 @@ namespace Bit.Android.Controls
{ {
private bool _isPassword; private bool _isPassword;
private bool _toggledPassword; private bool _toggledPassword;
private bool _isDisposed;
private ExtendedEntry _view;
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e) protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{ {
base.OnElementChanged(e); base.OnElementChanged(e);
var view = (ExtendedEntry)Element; _view = (ExtendedEntry)Element;
_isPassword = view.IsPassword; _isPassword = _view.IsPassword;
if(Control != null) if(Control != null)
{ {
@ -36,69 +38,74 @@ namespace Bit.Android.Controls
} }
} }
SetBorder(view); SetBorder(_view);
SetMaxLength(view); SetMaxLength(_view);
SetReturnType(view); SetReturnType(_view);
// Editor Action is called when the return button is pressed // Editor Action is called when the return button is pressed
Control.EditorAction += (object sender, TextView.EditorActionEventArgs args) => Control.EditorAction += Control_EditorAction;
{
if(view.ReturnType != ReturnType.Next)
{
view.Unfocus();
}
// Call all the methods attached to base_entry event handler Completed if(_view.DisableAutocapitalize)
view.InvokeCompleted();
};
if(view.DisableAutocapitalize)
{ {
Control.SetRawInputType(Control.InputType |= InputTypes.TextVariationEmailAddress); Control.SetRawInputType(Control.InputType |= InputTypes.TextVariationEmailAddress);
} }
if(view.Autocorrect.HasValue) if(_view.Autocorrect.HasValue)
{ {
Control.SetRawInputType(Control.InputType |= InputTypes.TextFlagNoSuggestions); Control.SetRawInputType(Control.InputType |= InputTypes.TextFlagNoSuggestions);
} }
view.ToggleIsPassword += (object sender, EventArgs args) => _view.ToggleIsPassword += ToggleIsPassword;
{
var cursorStart = Control.SelectionStart;
var cursorEnd = Control.SelectionEnd;
Control.TransformationMethod = _isPassword ? null : new PasswordTransformationMethod(); if(_view.FontFamily == "monospace")
// set focus
Control.RequestFocus();
if(_toggledPassword)
{
// restore cursor position
Control.SetSelection(cursorStart, cursorEnd);
}
else
{
// set cursor to end
Control.SetSelection(Control.Text.Length);
}
// show keyboard
var app = XLabs.Ioc.Resolver.Resolve<global::Android.App.Application>();
var inputMethodManager =
app.GetSystemService(global::Android.Content.Context.InputMethodService) as InputMethodManager;
inputMethodManager.ShowSoftInput(Control, ShowFlags.Forced);
inputMethodManager.ToggleSoftInput(ShowFlags.Forced, HideSoftInputFlags.ImplicitOnly);
_isPassword = view.IsPasswordFromToggled = !_isPassword;
_toggledPassword = true;
};
if(view.FontFamily == "monospace")
{ {
Control.Typeface = Typeface.Monospace; Control.Typeface = Typeface.Monospace;
} }
} }
private void ToggleIsPassword(object sender, EventArgs e)
{
var cursorStart = Control.SelectionStart;
var cursorEnd = Control.SelectionEnd;
Control.TransformationMethod = _isPassword ? null : new PasswordTransformationMethod();
// set focus
Control.RequestFocus();
if(_toggledPassword)
{
// restore cursor position
Control.SetSelection(cursorStart, cursorEnd);
}
else
{
// set cursor to end
Control.SetSelection(Control.Text.Length);
}
// show keyboard
var app = XLabs.Ioc.Resolver.Resolve<global::Android.App.Application>();
var inputMethodManager =
app.GetSystemService(global::Android.Content.Context.InputMethodService) as InputMethodManager;
inputMethodManager.ShowSoftInput(Control, ShowFlags.Forced);
inputMethodManager.ToggleSoftInput(ShowFlags.Forced, HideSoftInputFlags.ImplicitOnly);
_isPassword = _view.IsPasswordFromToggled = !_isPassword;
_toggledPassword = true;
}
private void Control_EditorAction(object sender, TextView.EditorActionEventArgs e)
{
if(_view.ReturnType != ReturnType.Next)
{
_view.Unfocus();
}
// Call all the methods attached to base_entry event handler Completed
_view.InvokeCompleted();
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{ {
var view = (ExtendedEntry)Element; var view = (ExtendedEntry)Element;
@ -124,6 +131,23 @@ namespace Bit.Android.Controls
} }
} }
protected override void Dispose(bool disposing)
{
if(_isDisposed)
{
return;
}
_isDisposed = true;
if(disposing && Control != null)
{
_view.ToggleIsPassword -= ToggleIsPassword;
Control.EditorAction -= Control_EditorAction;
}
base.Dispose(disposing);
}
private void SetReturnType(ExtendedEntry view) private void SetReturnType(ExtendedEntry view)
{ {
if(view.ReturnType.HasValue) if(view.ReturnType.HasValue)

View file

@ -1,5 +1,4 @@
using System; using System;
using System.ComponentModel;
using Bit.Android.Controls; using Bit.Android.Controls;
using Bit.App.Controls; using Bit.App.Controls;
using Xamarin.Forms; using Xamarin.Forms;

View file

@ -18,6 +18,8 @@ namespace Bit.App.Pages
Init(); Init();
} }
public ExtendedTextCell CreditsCell { get; set; }
public void Init() public void Init()
{ {
var logo = new CachedImage var logo = new CachedImage
@ -43,12 +45,11 @@ namespace Bit.App.Pages
Padding = new Thickness(0, 40, 0, 0) Padding = new Thickness(0, 40, 0, 0)
}; };
var creditsCell = new ExtendedTextCell CreditsCell = new ExtendedTextCell
{ {
Text = AppResources.Credits, Text = AppResources.Credits,
ShowDisclousure = true ShowDisclousure = true
}; };
creditsCell.Tapped += RateCell_Tapped;
var table = new ExtendedTableView var table = new ExtendedTableView
{ {
@ -60,7 +61,7 @@ namespace Bit.App.Pages
{ {
new TableSection new TableSection
{ {
creditsCell CreditsCell
} }
} }
}; };
@ -90,5 +91,17 @@ namespace Bit.App.Pages
{ {
Navigation.PushAsync(new SettingsCreditsPage()); Navigation.PushAsync(new SettingsCreditsPage());
} }
protected override void OnAppearing()
{
base.OnAppearing();
CreditsCell.Tapped += RateCell_Tapped;
}
protected override void OnDisappearing()
{
base.OnDisappearing();
CreditsCell.Tapped -= RateCell_Tapped;
}
} }
} }

View file

@ -25,8 +25,9 @@ namespace Bit.App.Pages
new TableSection(AppResources.Translations) new TableSection(AppResources.Translations)
{ {
new CustomViewCell(@"@felixqu - Chinese new CustomViewCell(@"@felixqu - Chinese
@Primokorn - French @Primokorn, @maxlandry - French
@King-Tut-Tut - Swedish") @King-Tut-Tut - Swedish
@Igetin - Finnish")
}, },
new TableSection(AppResources.Icons) new TableSection(AppResources.Icons)
{ {

View file

@ -18,14 +18,21 @@ namespace Bit.App.Pages
Init(); Init();
} }
public ExtendedTextCell EmailCell { get; set; }
public ExtendedTextCell WebsiteCell { get; set; }
public ExtendedTextCell BugCell { get; set; }
public StackLayout StackLayout { get; set; }
private CustomLabel EmailLabel { get; set; }
private CustomLabel WebsiteLabel { get; set; }
private CustomLabel BugLabel { get; set; }
public void Init() public void Init()
{ {
var emailCell = new ExtendedTextCell EmailCell = new ExtendedTextCell
{ {
Text = AppResources.EmailUs, Text = AppResources.EmailUs,
ShowDisclousure = true ShowDisclousure = true
}; };
emailCell.Tapped += EmailCell_Tapped;
var emailTable = new CustomTableView var emailTable = new CustomTableView
{ {
@ -33,22 +40,21 @@ namespace Bit.App.Pages
{ {
new TableSection new TableSection
{ {
emailCell EmailCell
} }
} }
}; };
var emailLabel = new CustomLabel(this) EmailLabel = new CustomLabel(this)
{ {
Text = AppResources.EmailUsDescription Text = AppResources.EmailUsDescription
}; };
var websiteCell = new ExtendedTextCell WebsiteCell = new ExtendedTextCell
{ {
Text = AppResources.VisitOurWebsite, Text = AppResources.VisitOurWebsite,
ShowDisclousure = true ShowDisclousure = true
}; };
websiteCell.Tapped += WebsiteCell_Tapped;
var websiteTable = new CustomTableView var websiteTable = new CustomTableView
{ {
@ -57,22 +63,21 @@ namespace Bit.App.Pages
{ {
new TableSection new TableSection
{ {
websiteCell WebsiteCell
} }
} }
}; };
var websiteLabel = new CustomLabel(this) WebsiteLabel = new CustomLabel(this)
{ {
Text = AppResources.VisitOurWebsiteDescription Text = AppResources.VisitOurWebsiteDescription
}; };
var bugCell = new ExtendedTextCell BugCell = new ExtendedTextCell
{ {
Text = AppResources.FileBugReport, Text = AppResources.FileBugReport,
ShowDisclousure = true ShowDisclousure = true
}; };
bugCell.Tapped += BugCell_Tapped;
var bugTable = new CustomTableView var bugTable = new CustomTableView
{ {
@ -81,36 +86,54 @@ namespace Bit.App.Pages
{ {
new TableSection new TableSection
{ {
bugCell BugCell
} }
} }
}; };
var bugLabel = new CustomLabel(this) BugLabel = new CustomLabel(this)
{ {
Text = AppResources.FileBugReportDescription Text = AppResources.FileBugReportDescription
}; };
var stackLayout = new StackLayout StackLayout = new StackLayout
{ {
Children = { emailTable, emailLabel, websiteTable, websiteLabel, bugTable, bugLabel }, Children = { emailTable, EmailLabel, websiteTable, WebsiteLabel, bugTable, BugLabel },
Spacing = 0 Spacing = 0
}; };
stackLayout.LayoutChanged += (sender, args) =>
{
websiteLabel.WidthRequest = stackLayout.Bounds.Width - websiteLabel.Bounds.Left * 2;
emailLabel.WidthRequest = stackLayout.Bounds.Width - emailLabel.Bounds.Left * 2;
bugLabel.WidthRequest = stackLayout.Bounds.Width - bugLabel.Bounds.Left * 2;
};
if(Device.OS == TargetPlatform.iOS) if(Device.OS == TargetPlatform.iOS)
{ {
ToolbarItems.Add(new DismissModalToolBarItem(this, AppResources.Cancel)); ToolbarItems.Add(new DismissModalToolBarItem(this, AppResources.Cancel));
} }
Title = AppResources.HelpAndFeedback; Title = AppResources.HelpAndFeedback;
Content = new ScrollView { Content = stackLayout }; Content = new ScrollView { Content = StackLayout };
}
protected override void OnAppearing()
{
base.OnAppearing();
EmailCell.Tapped += EmailCell_Tapped;
WebsiteCell.Tapped += WebsiteCell_Tapped;
BugCell.Tapped += BugCell_Tapped;
StackLayout.LayoutChanged += StackLayout_LayoutChanged;
}
protected override void OnDisappearing()
{
base.OnDisappearing();
EmailCell.Tapped -= EmailCell_Tapped;
WebsiteCell.Tapped -= WebsiteCell_Tapped;
BugCell.Tapped -= BugCell_Tapped;
StackLayout.LayoutChanged -= StackLayout_LayoutChanged;
}
private void StackLayout_LayoutChanged(object sender, EventArgs e)
{
WebsiteLabel.WidthRequest = StackLayout.Bounds.Width - WebsiteLabel.Bounds.Left * 2;
EmailLabel.WidthRequest = StackLayout.Bounds.Width - EmailLabel.Bounds.Left * 2;
BugLabel.WidthRequest = StackLayout.Bounds.Width - BugLabel.Bounds.Left * 2;
} }
private void EmailCell_Tapped(object sender, EventArgs e) private void EmailCell_Tapped(object sender, EventArgs e)

View file

@ -25,18 +25,21 @@ namespace Bit.App.Pages
Init(); Init();
} }
public ExtendedObservableCollection<SettingsFolderPageModel> Folders { get; private set; } = new ExtendedObservableCollection<SettingsFolderPageModel>(); public ExtendedObservableCollection<SettingsFolderPageModel> Folders { get; private set; }
= new ExtendedObservableCollection<SettingsFolderPageModel>();
public ListView ListView { get; set; }
private AddFolderToolBarItem AddItem { get; set; }
private void Init() private void Init()
{ {
ToolbarItems.Add(new AddFolderToolBarItem(this)); AddItem = new AddFolderToolBarItem(this);
ToolbarItems.Add(AddItem);
var listView = new ListView ListView = new ListView
{ {
ItemsSource = Folders ItemsSource = Folders,
ItemTemplate = new DataTemplate(() => new SettingsFolderListViewCell(this))
}; };
listView.ItemSelected += FolderSelected;
listView.ItemTemplate = new DataTemplate(() => new SettingsFolderListViewCell(this));
if(Device.OS == TargetPlatform.iOS) if(Device.OS == TargetPlatform.iOS)
{ {
@ -44,15 +47,24 @@ namespace Bit.App.Pages
} }
Title = AppResources.Folders; Title = AppResources.Folders;
Content = listView; Content = ListView;
} }
protected override void OnAppearing() protected override void OnAppearing()
{ {
base.OnAppearing(); base.OnAppearing();
ListView.ItemSelected += FolderSelected;
AddItem.InitEvents();
LoadFoldersAsync().Wait(); LoadFoldersAsync().Wait();
} }
protected override void OnDisappearing()
{
base.OnDisappearing();
ListView.ItemSelected -= FolderSelected;
AddItem.Dispose();
}
private async Task LoadFoldersAsync() private async Task LoadFoldersAsync()
{ {
var folders = await _folderService.GetAllAsync(); var folders = await _folderService.GetAllAsync();
@ -67,7 +79,7 @@ namespace Bit.App.Pages
await Navigation.PushForDeviceAsync(page); await Navigation.PushForDeviceAsync(page);
} }
private class AddFolderToolBarItem : ToolbarItem private class AddFolderToolBarItem : ExtendedToolbarItem
{ {
private readonly SettingsListFoldersPage _page; private readonly SettingsListFoldersPage _page;
@ -76,10 +88,10 @@ namespace Bit.App.Pages
_page = page; _page = page;
Text = AppResources.Add; Text = AppResources.Add;
Icon = "plus"; Icon = "plus";
Clicked += ClickedItem; ClickAction = () => ClickedItem();
} }
private async void ClickedItem(object sender, EventArgs e) private async void ClickedItem()
{ {
var page = new SettingsAddFolderPage(); var page = new SettingsAddFolderPage();
await _page.Navigation.PushForDeviceAsync(page); await _page.Navigation.PushForDeviceAsync(page);

View file

@ -37,6 +37,17 @@ namespace Bit.App.Pages
private ExtendedSwitchCell PinCell { get; set; } private ExtendedSwitchCell PinCell { get; set; }
private ExtendedSwitchCell FingerprintCell { get; set; } private ExtendedSwitchCell FingerprintCell { get; set; }
private ExtendedTextCell LockOptionsCell { get; set; } private ExtendedTextCell LockOptionsCell { get; set; }
private ExtendedTextCell TwoStepCell { get; set; }
private ExtendedTextCell ChangeMasterPasswordCell { get; set; }
private ExtendedTextCell ChangeEmailCell { get; set; }
private ExtendedTextCell FoldersCell { get; set; }
private ExtendedTextCell SyncCell { get; set; }
private ExtendedTextCell LockCell { get; set; }
private ExtendedTextCell LogOutCell { get; set; }
private ExtendedTextCell AboutCell { get; set; }
private ExtendedTextCell HelpCell { get; set; }
private ExtendedTextCell RateCell { get; set; }
private LongDetailViewCell RateCellLong { get; set; }
private ExtendedTableView Table { get; set; } private ExtendedTableView Table { get; set; }
private void Init() private void Init()
@ -46,7 +57,6 @@ namespace Bit.App.Pages
Text = AppResources.UnlockWithPIN, Text = AppResources.UnlockWithPIN,
On = _settings.GetValueOrDefault(Constants.SettingPinUnlockOn, false) On = _settings.GetValueOrDefault(Constants.SettingPinUnlockOn, false)
}; };
PinCell.OnChanged += PinCell_Changed;
LockOptionsCell = new ExtendedTextCell LockOptionsCell = new ExtendedTextCell
{ {
@ -54,20 +64,18 @@ namespace Bit.App.Pages
Detail = GetLockOptionsDetailsText(), Detail = GetLockOptionsDetailsText(),
ShowDisclousure = true ShowDisclousure = true
}; };
LockOptionsCell.Tapped += LockOptionsCell_Tapped;
var twoStepCell = new ExtendedTextCell TwoStepCell = new ExtendedTextCell
{ {
Text = AppResources.TwoStepLogin, Text = AppResources.TwoStepLogin,
ShowDisclousure = true ShowDisclousure = true
}; };
twoStepCell.Tapped += TwoStepCell_Tapped; ;
var securitySecion = new TableSection(AppResources.Security) var securitySecion = new TableSection(AppResources.Security)
{ {
LockOptionsCell, LockOptionsCell,
PinCell, PinCell,
twoStepCell TwoStepCell
}; };
if(_fingerprint.IsAvailable) if(_fingerprint.IsAvailable)
@ -80,87 +88,76 @@ namespace Bit.App.Pages
On = _settings.GetValueOrDefault(Constants.SettingFingerprintUnlockOn, false), On = _settings.GetValueOrDefault(Constants.SettingFingerprintUnlockOn, false),
IsEnabled = _fingerprint.IsAvailable IsEnabled = _fingerprint.IsAvailable
}; };
FingerprintCell.OnChanged += FingerprintCell_Changed;
securitySecion.Insert(1, FingerprintCell); securitySecion.Insert(1, FingerprintCell);
} }
var changeMasterPasswordCell = new ExtendedTextCell ChangeMasterPasswordCell = new ExtendedTextCell
{ {
Text = AppResources.ChangeMasterPassword, Text = AppResources.ChangeMasterPassword,
ShowDisclousure = true ShowDisclousure = true
}; };
changeMasterPasswordCell.Tapped += ChangeMasterPasswordCell_Tapped;
var changeEmailCell = new ExtendedTextCell ChangeEmailCell = new ExtendedTextCell
{ {
Text = AppResources.ChangeEmail, Text = AppResources.ChangeEmail,
ShowDisclousure = true ShowDisclousure = true
}; };
changeEmailCell.Tapped += ChangeEmailCell_Tapped;
var foldersCell = new ExtendedTextCell FoldersCell = new ExtendedTextCell
{ {
Text = AppResources.Folders, Text = AppResources.Folders,
ShowDisclousure = true ShowDisclousure = true
}; };
foldersCell.Tapped += FoldersCell_Tapped;
var syncCell = new ExtendedTextCell SyncCell = new ExtendedTextCell
{ {
Text = AppResources.Sync, Text = AppResources.Sync,
ShowDisclousure = true ShowDisclousure = true
}; };
syncCell.Tapped += SyncCell_Tapped;
var lockCell = new ExtendedTextCell LockCell = new ExtendedTextCell
{ {
Text = AppResources.Lock Text = AppResources.Lock
}; };
lockCell.Tapped += LockCell_Tapped;
var logOutCell = new ExtendedTextCell LogOutCell = new ExtendedTextCell
{ {
Text = AppResources.LogOut Text = AppResources.LogOut
}; };
logOutCell.Tapped += LogOutCell_Tapped;
var aboutCell = new ExtendedTextCell AboutCell = new ExtendedTextCell
{ {
Text = AppResources.About, Text = AppResources.About,
ShowDisclousure = true ShowDisclousure = true
}; };
aboutCell.Tapped += AboutCell_Tapped;
var helpCell = new ExtendedTextCell HelpCell = new ExtendedTextCell
{ {
Text = AppResources.HelpAndFeedback, Text = AppResources.HelpAndFeedback,
ShowDisclousure = true ShowDisclousure = true
}; };
helpCell.Tapped += HelpCell_Tapped;
var otherSection = new TableSection(AppResources.Other) var otherSection = new TableSection(AppResources.Other)
{ {
aboutCell, AboutCell,
helpCell HelpCell
}; };
if(Device.OS == TargetPlatform.iOS) if(Device.OS == TargetPlatform.iOS)
{ {
var rateCell = new LongDetailViewCell(AppResources.RateTheApp, AppResources.RateTheAppDescriptionAppStore); RateCellLong = new LongDetailViewCell(AppResources.RateTheApp, AppResources.RateTheAppDescriptionAppStore);
rateCell.Tapped += RateCell_Tapped; otherSection.Add(RateCellLong);
otherSection.Add(rateCell);
} }
else else
{ {
var rateCell = new ExtendedTextCell RateCell = new ExtendedTextCell
{ {
Text = AppResources.RateTheApp, Text = AppResources.RateTheApp,
Detail = AppResources.RateTheAppDescription, Detail = AppResources.RateTheAppDescription,
ShowDisclousure = true, ShowDisclousure = true,
DetailLineBreakMode = LineBreakMode.WordWrap DetailLineBreakMode = LineBreakMode.WordWrap
}; };
rateCell.Tapped += RateCell_Tapped; otherSection.Add(RateCell);
otherSection.Add(rateCell);
} }
Table = new CustomTable Table = new CustomTable
@ -170,18 +167,18 @@ namespace Bit.App.Pages
securitySecion, securitySecion,
new TableSection(AppResources.Account) new TableSection(AppResources.Account)
{ {
changeMasterPasswordCell, ChangeMasterPasswordCell,
changeEmailCell ChangeEmailCell
}, },
new TableSection(AppResources.Manage) new TableSection(AppResources.Manage)
{ {
foldersCell, FoldersCell,
syncCell SyncCell
}, },
new TableSection(AppResources.CurrentSession) new TableSection(AppResources.CurrentSession)
{ {
lockCell, LockCell,
logOutCell LogOutCell
}, },
otherSection otherSection
} }
@ -191,6 +188,72 @@ namespace Bit.App.Pages
Content = Table; Content = Table;
} }
protected override void OnAppearing()
{
base.OnAppearing();
PinCell.OnChanged += PinCell_Changed;
LockOptionsCell.Tapped += LockOptionsCell_Tapped;
TwoStepCell.Tapped += TwoStepCell_Tapped;
ChangeMasterPasswordCell.Tapped += ChangeMasterPasswordCell_Tapped;
if(FingerprintCell != null)
{
FingerprintCell.OnChanged += FingerprintCell_Changed;
}
ChangeEmailCell.Tapped += ChangeEmailCell_Tapped;
FoldersCell.Tapped += FoldersCell_Tapped;
SyncCell.Tapped += SyncCell_Tapped;
LockCell.Tapped += LockCell_Tapped;
LogOutCell.Tapped += LogOutCell_Tapped;
AboutCell.Tapped += AboutCell_Tapped;
HelpCell.Tapped += HelpCell_Tapped;
if(RateCellLong != null)
{
RateCellLong.Tapped += RateCell_Tapped;
}
if(RateCell != null)
{
RateCell.Tapped += RateCell_Tapped;
}
}
protected override void OnDisappearing()
{
base.OnDisappearing();
PinCell.OnChanged -= PinCell_Changed;
LockOptionsCell.Tapped -= LockOptionsCell_Tapped;
TwoStepCell.Tapped -= TwoStepCell_Tapped;
ChangeMasterPasswordCell.Tapped -= ChangeMasterPasswordCell_Tapped;
if(FingerprintCell != null)
{
FingerprintCell.OnChanged -= FingerprintCell_Changed;
}
ChangeEmailCell.Tapped -= ChangeEmailCell_Tapped;
FoldersCell.Tapped -= FoldersCell_Tapped;
SyncCell.Tapped -= SyncCell_Tapped;
LockCell.Tapped -= LockCell_Tapped;
LogOutCell.Tapped -= LogOutCell_Tapped;
AboutCell.Tapped -= AboutCell_Tapped;
HelpCell.Tapped -= HelpCell_Tapped;
if(RateCellLong != null)
{
RateCellLong.Tapped -= RateCell_Tapped;
}
if(RateCell != null)
{
RateCell.Tapped -= RateCell_Tapped;
}
}
private async void TwoStepCell_Tapped(object sender, EventArgs e) private async void TwoStepCell_Tapped(object sender, EventArgs e)
{ {
if(!await _userDialogs.ConfirmAsync(AppResources.TwoStepLoginConfirmation, null, AppResources.Yes, if(!await _userDialogs.ConfirmAsync(AppResources.TwoStepLoginConfirmation, null, AppResources.Yes,
@ -340,8 +403,7 @@ namespace Bit.App.Pages
if(cell.On && !_settings.GetValueOrDefault(Constants.SettingPinUnlockOn, false)) if(cell.On && !_settings.GetValueOrDefault(Constants.SettingPinUnlockOn, false))
{ {
cell.On = false; cell.On = false;
var pinPage = new SettingsPinPage(); var pinPage = new SettingsPinPage((page) => PinEntered(page));
pinPage.OnPinEntered += PinEntered;
Navigation.PushModalAsync(new ExtendedNavigationPage(pinPage)); Navigation.PushModalAsync(new ExtendedNavigationPage(pinPage));
} }
else if(!cell.On) else if(!cell.On)
@ -350,9 +412,8 @@ namespace Bit.App.Pages
} }
} }
private void PinEntered(object sender, EventArgs args) private void PinEntered(SettingsPinPage page)
{ {
var page = sender as SettingsPinPage;
page.PinControl.Entry.Unfocus(); page.PinControl.Entry.Unfocus();
page.Navigation.PopModalAsync(); page.Navigation.PopModalAsync();

View file

@ -15,9 +15,11 @@ namespace Bit.App.Pages
{ {
private readonly IUserDialogs _userDialogs; private readonly IUserDialogs _userDialogs;
private readonly ISettings _settings; private readonly ISettings _settings;
private Action<SettingsPinPage> _pinEnteredAction;
public SettingsPinPage() public SettingsPinPage(Action<SettingsPinPage> pinEnteredAction)
{ {
_pinEnteredAction = pinEnteredAction;
_userDialogs = Resolver.Resolve<IUserDialogs>(); _userDialogs = Resolver.Resolve<IUserDialogs>();
_settings = Resolver.Resolve<ISettings>(); _settings = Resolver.Resolve<ISettings>();
@ -26,7 +28,7 @@ namespace Bit.App.Pages
public PinPageModel Model { get; set; } = new PinPageModel(); public PinPageModel Model { get; set; } = new PinPageModel();
public PinControl PinControl { get; set; } public PinControl PinControl { get; set; }
public EventHandler OnPinEntered; public TapGestureRecognizer Tgr { get; set; }
public void Init() public void Init()
{ {
@ -50,10 +52,9 @@ namespace Bit.App.Pages
Children = { PinControl.Label, instructionLabel, PinControl.Entry } Children = { PinControl.Label, instructionLabel, PinControl.Entry }
}; };
var tgr = new TapGestureRecognizer(); Tgr = new TapGestureRecognizer();
tgr.Tapped += Tgr_Tapped; PinControl.Label.GestureRecognizers.Add(Tgr);
PinControl.Label.GestureRecognizers.Add(tgr); instructionLabel.GestureRecognizers.Add(Tgr);
instructionLabel.GestureRecognizers.Add(tgr);
if(Device.OS == TargetPlatform.iOS) if(Device.OS == TargetPlatform.iOS)
{ {
@ -62,18 +63,14 @@ namespace Bit.App.Pages
Title = AppResources.SetPIN; Title = AppResources.SetPIN;
Content = stackLayout; Content = stackLayout;
Content.GestureRecognizers.Add(tgr); Content.GestureRecognizers.Add(Tgr);
BindingContext = Model; BindingContext = Model;
} }
private void Tgr_Tapped(object sender, EventArgs e)
{
PinControl.Entry.Focus();
}
protected override void OnAppearing() protected override void OnAppearing()
{ {
base.OnAppearing(); base.OnAppearing();
Tgr.Tapped += Tgr_Tapped;
PinControl.OnPinEntered += PinEntered; PinControl.OnPinEntered += PinEntered;
PinControl.InitEvents(); PinControl.InitEvents();
PinControl.Entry.FocusWithDelay(); PinControl.Entry.FocusWithDelay();
@ -83,12 +80,18 @@ namespace Bit.App.Pages
{ {
base.OnDisappearing(); base.OnDisappearing();
PinControl.Dispose(); PinControl.Dispose();
Tgr.Tapped -= Tgr_Tapped;
PinControl.OnPinEntered -= PinEntered; PinControl.OnPinEntered -= PinEntered;
} }
protected void PinEntered(object sender, EventArgs args) protected void PinEntered(object sender, EventArgs args)
{ {
OnPinEntered.Invoke(this, null); _pinEnteredAction?.Invoke(this);
}
private void Tgr_Tapped(object sender, EventArgs e)
{
PinControl.Entry.Focus();
} }
} }
} }

View file

@ -82,8 +82,14 @@ namespace Bit.App.Pages
GeneratorCell.Tapped += GeneratorCell_Tapped; GeneratorCell.Tapped += GeneratorCell_Tapped;
WebCell.Tapped += WebCell_Tapped; WebCell.Tapped += WebCell_Tapped;
ImportCell.Tapped += ImportCell_Tapped; ImportCell.Tapped += ImportCell_Tapped;
ExtensionCell.Tapped += ExtensionCell_Tapped; if(ExtensionCell != null)
AutofillCell.Tapped += AutofillCell_Tapped; {
ExtensionCell.Tapped += ExtensionCell_Tapped;
}
if(AutofillCell != null)
{
AutofillCell.Tapped += AutofillCell_Tapped;
}
} }
protected override void OnDisappearing() protected override void OnDisappearing()
@ -92,8 +98,14 @@ namespace Bit.App.Pages
GeneratorCell.Tapped -= GeneratorCell_Tapped; GeneratorCell.Tapped -= GeneratorCell_Tapped;
WebCell.Tapped -= WebCell_Tapped; WebCell.Tapped -= WebCell_Tapped;
ImportCell.Tapped -= ImportCell_Tapped; ImportCell.Tapped -= ImportCell_Tapped;
ExtensionCell.Tapped -= ExtensionCell_Tapped; if(ExtensionCell != null)
AutofillCell.Tapped -= AutofillCell_Tapped; {
ExtensionCell.Tapped -= ExtensionCell_Tapped;
}
if(AutofillCell != null)
{
AutofillCell.Tapped -= AutofillCell_Tapped;
}
} }

View file

@ -36,6 +36,10 @@ namespace Bit.App.Pages
public PasswordGeneratorPageModel Model { get; private set; } = new PasswordGeneratorPageModel(); public PasswordGeneratorPageModel Model { get; private set; } = new PasswordGeneratorPageModel();
public Label Password { get; private set; } public Label Password { get; private set; }
public SliderViewCell SliderCell { get; private set; } public SliderViewCell SliderCell { get; private set; }
public TapGestureRecognizer Tgr { get; set; }
public ExtendedTextCell SettingsCell { get; set; }
public ExtendedTextCell RegenerateCell { get; set; }
public ExtendedTextCell CopyCell { get; set; }
public void Init() public void Init()
{ {
@ -49,20 +53,16 @@ namespace Bit.App.Pages
VerticalOptions = LayoutOptions.Start VerticalOptions = LayoutOptions.Start
}; };
var tgr = new TapGestureRecognizer(); Tgr = new TapGestureRecognizer();
tgr.Tapped += Tgr_Tapped; Password.GestureRecognizers.Add(Tgr);
Password.GestureRecognizers.Add(tgr);
Password.SetBinding<PasswordGeneratorPageModel>(Label.TextProperty, m => m.Password); Password.SetBinding<PasswordGeneratorPageModel>(Label.TextProperty, m => m.Password);
SliderCell = new SliderViewCell(this, _passwordGenerationService, _settings); SliderCell = new SliderViewCell(this, _passwordGenerationService, _settings);
var settingsCell = new ExtendedTextCell { Text = AppResources.MoreSettings, ShowDisclousure = true }; SettingsCell = new ExtendedTextCell { Text = AppResources.MoreSettings, ShowDisclousure = true };
settingsCell.Tapped += SettingsCell_Tapped;
var buttonColor = Color.FromHex("3c8dbc"); var buttonColor = Color.FromHex("3c8dbc");
var regenerateCell = new ExtendedTextCell { Text = AppResources.RegeneratePassword, TextColor = buttonColor }; RegenerateCell = new ExtendedTextCell { Text = AppResources.RegeneratePassword, TextColor = buttonColor };
regenerateCell.Tapped += RegenerateCell_Tapped; ; CopyCell = new ExtendedTextCell { Text = AppResources.CopyPassword, TextColor = buttonColor };
var copyCell = new ExtendedTextCell { Text = AppResources.CopyPassword, TextColor = buttonColor };
copyCell.Tapped += CopyCell_Tapped;
var table = new ExtendedTableView var table = new ExtendedTableView
{ {
@ -75,13 +75,13 @@ namespace Bit.App.Pages
{ {
new TableSection new TableSection
{ {
regenerateCell, RegenerateCell,
copyCell CopyCell
}, },
new TableSection(AppResources.Options) new TableSection(AppResources.Options)
{ {
SliderCell, SliderCell,
settingsCell SettingsCell
} }
} }
}; };
@ -142,6 +142,12 @@ namespace Bit.App.Pages
protected override void OnAppearing() protected override void OnAppearing()
{ {
base.OnAppearing(); base.OnAppearing();
Tgr.Tapped += Tgr_Tapped;
RegenerateCell.Tapped += RegenerateCell_Tapped;
SettingsCell.Tapped += SettingsCell_Tapped;
CopyCell.Tapped += CopyCell_Tapped;
SliderCell.InitEvents();
if(_fromAutofill) if(_fromAutofill)
{ {
_googleAnalyticsService.TrackExtensionEvent("GeneratedPassword"); _googleAnalyticsService.TrackExtensionEvent("GeneratedPassword");
@ -154,6 +160,16 @@ namespace Bit.App.Pages
Model.Length = _settings.GetValueOrDefault(Constants.PasswordGeneratorLength, 10).ToString(); Model.Length = _settings.GetValueOrDefault(Constants.PasswordGeneratorLength, 10).ToString();
} }
protected override void OnDisappearing()
{
base.OnDisappearing();
Tgr.Tapped -= Tgr_Tapped;
RegenerateCell.Tapped -= RegenerateCell_Tapped;
SettingsCell.Tapped -= SettingsCell_Tapped;
CopyCell.Tapped -= CopyCell_Tapped;
SliderCell.Dispose();
}
private void RegenerateCell_Tapped(object sender, EventArgs e) private void RegenerateCell_Tapped(object sender, EventArgs e)
{ {
Model.Password = _passwordGenerationService.GeneratePassword(); Model.Password = _passwordGenerationService.GeneratePassword();
@ -192,7 +208,7 @@ namespace Bit.App.Pages
} }
// TODO: move to standalone reusable control // TODO: move to standalone reusable control
public class SliderViewCell : ExtendedViewCell public class SliderViewCell : ExtendedViewCell, IDisposable
{ {
private readonly ToolsPasswordGeneratorPage _page; private readonly ToolsPasswordGeneratorPage _page;
private readonly IPasswordGenerationService _passwordGenerationService; private readonly IPasswordGenerationService _passwordGenerationService;
@ -234,8 +250,6 @@ namespace Bit.App.Pages
Value.SetBinding<PasswordGeneratorPageModel>(Label.TextProperty, m => m.Length); Value.SetBinding<PasswordGeneratorPageModel>(Label.TextProperty, m => m.Length);
LengthSlider.ValueChanged += Slider_ValueChanged;
var stackLayout = new StackLayout var stackLayout = new StackLayout
{ {
Orientation = StackOrientation.Horizontal, Orientation = StackOrientation.Horizontal,
@ -263,6 +277,16 @@ namespace Bit.App.Pages
_page.Model.Length = length.ToString(); _page.Model.Length = length.ToString();
_page.Model.Password = _passwordGenerationService.GeneratePassword(); _page.Model.Password = _passwordGenerationService.GeneratePassword();
} }
public void InitEvents()
{
LengthSlider.ValueChanged += Slider_ValueChanged;
}
public void Dispose()
{
LengthSlider.ValueChanged -= Slider_ValueChanged;
}
} }
} }
} }

View file

@ -39,14 +39,12 @@ namespace Bit.App.Pages
Text = "A-Z", Text = "A-Z",
On = _settings.GetValueOrDefault(Constants.PasswordGeneratorUppercase, true) On = _settings.GetValueOrDefault(Constants.PasswordGeneratorUppercase, true)
}; };
UppercaseCell.OnChanged += UppercaseCell_OnChanged;
LowercaseCell = new ExtendedSwitchCell LowercaseCell = new ExtendedSwitchCell
{ {
Text = "a-z", Text = "a-z",
On = _settings.GetValueOrDefault(Constants.PasswordGeneratorLowercase, true) On = _settings.GetValueOrDefault(Constants.PasswordGeneratorLowercase, true)
}; };
LowercaseCell.OnChanged += LowercaseCell_OnChanged;
SpecialCell = new ExtendedSwitchCell SpecialCell = new ExtendedSwitchCell
{ {
@ -59,7 +57,6 @@ namespace Bit.App.Pages
Text = "0-9", Text = "0-9",
On = _settings.GetValueOrDefault(Constants.PasswordGeneratorNumbers, true) On = _settings.GetValueOrDefault(Constants.PasswordGeneratorNumbers, true)
}; };
NumbersCell.OnChanged += NumbersCell_OnChanged;
AvoidAmbiguousCell = new ExtendedSwitchCell AvoidAmbiguousCell = new ExtendedSwitchCell
{ {
@ -114,6 +111,11 @@ namespace Bit.App.Pages
base.OnAppearing(); base.OnAppearing();
SpecialCell.OnChanged += SpecialCell_OnChanged; SpecialCell.OnChanged += SpecialCell_OnChanged;
AvoidAmbiguousCell.OnChanged += AvoidAmbiguousCell_OnChanged; AvoidAmbiguousCell.OnChanged += AvoidAmbiguousCell_OnChanged;
UppercaseCell.OnChanged += UppercaseCell_OnChanged;
LowercaseCell.OnChanged += LowercaseCell_OnChanged;
NumbersCell.OnChanged += NumbersCell_OnChanged;
NumbersMinCell.InitEvents();
SpecialMinCell.InitEvents();
} }
protected override void OnDisappearing() protected override void OnDisappearing()
@ -121,6 +123,11 @@ namespace Bit.App.Pages
base.OnDisappearing(); base.OnDisappearing();
SpecialCell.OnChanged -= SpecialCell_OnChanged; SpecialCell.OnChanged -= SpecialCell_OnChanged;
AvoidAmbiguousCell.OnChanged -= AvoidAmbiguousCell_OnChanged; AvoidAmbiguousCell.OnChanged -= AvoidAmbiguousCell_OnChanged;
UppercaseCell.OnChanged -= UppercaseCell_OnChanged;
LowercaseCell.OnChanged -= LowercaseCell_OnChanged;
NumbersCell.OnChanged -= NumbersCell_OnChanged;
NumbersMinCell.Dispose();
SpecialMinCell.Dispose();
_settings.AddOrUpdateValue(Constants.PasswordGeneratorMinNumbers, _settings.AddOrUpdateValue(Constants.PasswordGeneratorMinNumbers,
Convert.ToInt32(NumbersMinCell.Stepper.Value)); Convert.ToInt32(NumbersMinCell.Stepper.Value));

View file

@ -277,7 +277,7 @@ namespace Bit.App.Pages
ListView.ItemSelected -= LoginSelected; ListView.ItemSelected -= LoginSelected;
Search.TextChanged -= SearchBar_TextChanged; Search.TextChanged -= SearchBar_TextChanged;
Search.SearchButtonPressed -= SearchBar_SearchButtonPressed; Search.SearchButtonPressed -= SearchBar_SearchButtonPressed;
AddLoginItem.Dispose(); AddLoginItem?.Dispose();
} }
protected override bool OnBackButtonPressed() protected override bool OnBackButtonPressed()