From 27e996dba0df2a0b1ff3b32d59ccae89e7d14423 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Fri, 17 Feb 2017 21:18:59 -0500 Subject: [PATCH] Detach events --- src/Android/AutofillService.cs | 4 +- src/Android/Controls/ExtendedEntryRenderer.cs | 122 +++++++++------ .../Controls/ExtendedTabbedPageRenderer.cs | 1 - src/App/Pages/Settings/SettingsAboutPage.cs | 19 ++- src/App/Pages/Settings/SettingsCreditsPage.cs | 5 +- src/App/Pages/Settings/SettingsHelpPage.cs | 67 ++++++--- .../Pages/Settings/SettingsListFoldersPage.cs | 32 ++-- src/App/Pages/Settings/SettingsPage.cs | 141 +++++++++++++----- src/App/Pages/Settings/SettingsPinPage.cs | 29 ++-- src/App/Pages/Tools/ToolsPage.cs | 20 ++- .../Pages/Tools/ToolsPasswordGeneratorPage.cs | 54 +++++-- .../ToolsPasswordGeneratorSettingsPage.cs | 13 +- src/App/Pages/Vault/VaultListLoginsPage.cs | 2 +- 13 files changed, 344 insertions(+), 165 deletions(-) diff --git a/src/Android/AutofillService.cs b/src/Android/AutofillService.cs index ca8e28d03..bb7eaa5cf 100644 --- a/src/Android/AutofillService.cs +++ b/src/Android/AutofillService.cs @@ -154,10 +154,10 @@ namespace Bit.Android { if(addressNode?.Text != null) { - uri = browser.GetUriFunction(addressNode.Text); + uri = browser.GetUriFunction(addressNode.Text).Trim(); if(uri != null && uri.Contains(".")) { - if(!uri.Contains("://")) + if(!uri.Contains("://") && !uri.Contains(" ")) { uri = string.Concat("http://", uri); } diff --git a/src/Android/Controls/ExtendedEntryRenderer.cs b/src/Android/Controls/ExtendedEntryRenderer.cs index db447f370..22fe08a8a 100644 --- a/src/Android/Controls/ExtendedEntryRenderer.cs +++ b/src/Android/Controls/ExtendedEntryRenderer.cs @@ -18,13 +18,15 @@ namespace Bit.Android.Controls { private bool _isPassword; private bool _toggledPassword; + private bool _isDisposed; + private ExtendedEntry _view; protected override void OnElementChanged(ElementChangedEventArgs e) { base.OnElementChanged(e); - var view = (ExtendedEntry)Element; - _isPassword = view.IsPassword; + _view = (ExtendedEntry)Element; + _isPassword = _view.IsPassword; if(Control != null) { @@ -36,69 +38,74 @@ namespace Bit.Android.Controls } } - SetBorder(view); - SetMaxLength(view); - SetReturnType(view); + SetBorder(_view); + SetMaxLength(_view); + SetReturnType(_view); // Editor Action is called when the return button is pressed - Control.EditorAction += (object sender, TextView.EditorActionEventArgs args) => - { - if(view.ReturnType != ReturnType.Next) - { - view.Unfocus(); - } + Control.EditorAction += Control_EditorAction; - // Call all the methods attached to base_entry event handler Completed - view.InvokeCompleted(); - }; - - if(view.DisableAutocapitalize) + if(_view.DisableAutocapitalize) { Control.SetRawInputType(Control.InputType |= InputTypes.TextVariationEmailAddress); } - if(view.Autocorrect.HasValue) + if(_view.Autocorrect.HasValue) { Control.SetRawInputType(Control.InputType |= InputTypes.TextFlagNoSuggestions); } - view.ToggleIsPassword += (object sender, EventArgs args) => - { - var cursorStart = Control.SelectionStart; - var cursorEnd = Control.SelectionEnd; + _view.ToggleIsPassword += ToggleIsPassword; - 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(); - 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") + if(_view.FontFamily == "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(); + 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) { 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) { if(view.ReturnType.HasValue) diff --git a/src/Android/Controls/ExtendedTabbedPageRenderer.cs b/src/Android/Controls/ExtendedTabbedPageRenderer.cs index 891471fc9..7c82f97a5 100644 --- a/src/Android/Controls/ExtendedTabbedPageRenderer.cs +++ b/src/Android/Controls/ExtendedTabbedPageRenderer.cs @@ -1,5 +1,4 @@ using System; -using System.ComponentModel; using Bit.Android.Controls; using Bit.App.Controls; using Xamarin.Forms; diff --git a/src/App/Pages/Settings/SettingsAboutPage.cs b/src/App/Pages/Settings/SettingsAboutPage.cs index c01ef86f6..8b54ace52 100644 --- a/src/App/Pages/Settings/SettingsAboutPage.cs +++ b/src/App/Pages/Settings/SettingsAboutPage.cs @@ -18,6 +18,8 @@ namespace Bit.App.Pages Init(); } + public ExtendedTextCell CreditsCell { get; set; } + public void Init() { var logo = new CachedImage @@ -43,12 +45,11 @@ namespace Bit.App.Pages Padding = new Thickness(0, 40, 0, 0) }; - var creditsCell = new ExtendedTextCell + CreditsCell = new ExtendedTextCell { Text = AppResources.Credits, ShowDisclousure = true }; - creditsCell.Tapped += RateCell_Tapped; var table = new ExtendedTableView { @@ -60,7 +61,7 @@ namespace Bit.App.Pages { new TableSection { - creditsCell + CreditsCell } } }; @@ -90,5 +91,17 @@ namespace Bit.App.Pages { Navigation.PushAsync(new SettingsCreditsPage()); } + + protected override void OnAppearing() + { + base.OnAppearing(); + CreditsCell.Tapped += RateCell_Tapped; + } + + protected override void OnDisappearing() + { + base.OnDisappearing(); + CreditsCell.Tapped -= RateCell_Tapped; + } } } diff --git a/src/App/Pages/Settings/SettingsCreditsPage.cs b/src/App/Pages/Settings/SettingsCreditsPage.cs index d82cbd47f..84413c29a 100644 --- a/src/App/Pages/Settings/SettingsCreditsPage.cs +++ b/src/App/Pages/Settings/SettingsCreditsPage.cs @@ -25,8 +25,9 @@ namespace Bit.App.Pages new TableSection(AppResources.Translations) { new CustomViewCell(@"@felixqu - Chinese -@Primokorn - French -@King-Tut-Tut - Swedish") +@Primokorn, @maxlandry - French +@King-Tut-Tut - Swedish +@Igetin - Finnish") }, new TableSection(AppResources.Icons) { diff --git a/src/App/Pages/Settings/SettingsHelpPage.cs b/src/App/Pages/Settings/SettingsHelpPage.cs index de9963516..654d555dc 100644 --- a/src/App/Pages/Settings/SettingsHelpPage.cs +++ b/src/App/Pages/Settings/SettingsHelpPage.cs @@ -18,14 +18,21 @@ namespace Bit.App.Pages 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() { - var emailCell = new ExtendedTextCell + EmailCell = new ExtendedTextCell { Text = AppResources.EmailUs, ShowDisclousure = true }; - emailCell.Tapped += EmailCell_Tapped; var emailTable = new CustomTableView { @@ -33,22 +40,21 @@ namespace Bit.App.Pages { new TableSection { - emailCell + EmailCell } } }; - var emailLabel = new CustomLabel(this) + EmailLabel = new CustomLabel(this) { Text = AppResources.EmailUsDescription }; - var websiteCell = new ExtendedTextCell + WebsiteCell = new ExtendedTextCell { Text = AppResources.VisitOurWebsite, ShowDisclousure = true }; - websiteCell.Tapped += WebsiteCell_Tapped; var websiteTable = new CustomTableView { @@ -57,22 +63,21 @@ namespace Bit.App.Pages { new TableSection { - websiteCell + WebsiteCell } } }; - var websiteLabel = new CustomLabel(this) + WebsiteLabel = new CustomLabel(this) { Text = AppResources.VisitOurWebsiteDescription }; - var bugCell = new ExtendedTextCell + BugCell = new ExtendedTextCell { Text = AppResources.FileBugReport, ShowDisclousure = true }; - bugCell.Tapped += BugCell_Tapped; var bugTable = new CustomTableView { @@ -81,36 +86,54 @@ namespace Bit.App.Pages { new TableSection { - bugCell + BugCell } } }; - var bugLabel = new CustomLabel(this) + BugLabel = new CustomLabel(this) { 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 }; - 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) { ToolbarItems.Add(new DismissModalToolBarItem(this, AppResources.Cancel)); } 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) diff --git a/src/App/Pages/Settings/SettingsListFoldersPage.cs b/src/App/Pages/Settings/SettingsListFoldersPage.cs index 92515697e..7b0ebb422 100644 --- a/src/App/Pages/Settings/SettingsListFoldersPage.cs +++ b/src/App/Pages/Settings/SettingsListFoldersPage.cs @@ -25,18 +25,21 @@ namespace Bit.App.Pages Init(); } - public ExtendedObservableCollection Folders { get; private set; } = new ExtendedObservableCollection(); + public ExtendedObservableCollection Folders { get; private set; } + = new ExtendedObservableCollection(); + public ListView ListView { get; set; } + private AddFolderToolBarItem AddItem { get; set; } 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) { @@ -44,15 +47,24 @@ namespace Bit.App.Pages } Title = AppResources.Folders; - Content = listView; + Content = ListView; } protected override void OnAppearing() { base.OnAppearing(); + ListView.ItemSelected += FolderSelected; + AddItem.InitEvents(); LoadFoldersAsync().Wait(); } + protected override void OnDisappearing() + { + base.OnDisappearing(); + ListView.ItemSelected -= FolderSelected; + AddItem.Dispose(); + } + private async Task LoadFoldersAsync() { var folders = await _folderService.GetAllAsync(); @@ -67,7 +79,7 @@ namespace Bit.App.Pages await Navigation.PushForDeviceAsync(page); } - private class AddFolderToolBarItem : ToolbarItem + private class AddFolderToolBarItem : ExtendedToolbarItem { private readonly SettingsListFoldersPage _page; @@ -76,10 +88,10 @@ namespace Bit.App.Pages _page = page; Text = AppResources.Add; Icon = "plus"; - Clicked += ClickedItem; + ClickAction = () => ClickedItem(); } - private async void ClickedItem(object sender, EventArgs e) + private async void ClickedItem() { var page = new SettingsAddFolderPage(); await _page.Navigation.PushForDeviceAsync(page); diff --git a/src/App/Pages/Settings/SettingsPage.cs b/src/App/Pages/Settings/SettingsPage.cs index 60c371c69..3fff0a54a 100644 --- a/src/App/Pages/Settings/SettingsPage.cs +++ b/src/App/Pages/Settings/SettingsPage.cs @@ -37,6 +37,17 @@ namespace Bit.App.Pages private ExtendedSwitchCell PinCell { get; set; } private ExtendedSwitchCell FingerprintCell { 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 void Init() @@ -46,7 +57,6 @@ namespace Bit.App.Pages Text = AppResources.UnlockWithPIN, On = _settings.GetValueOrDefault(Constants.SettingPinUnlockOn, false) }; - PinCell.OnChanged += PinCell_Changed; LockOptionsCell = new ExtendedTextCell { @@ -54,20 +64,18 @@ namespace Bit.App.Pages Detail = GetLockOptionsDetailsText(), ShowDisclousure = true }; - LockOptionsCell.Tapped += LockOptionsCell_Tapped; - var twoStepCell = new ExtendedTextCell + TwoStepCell = new ExtendedTextCell { Text = AppResources.TwoStepLogin, ShowDisclousure = true }; - twoStepCell.Tapped += TwoStepCell_Tapped; ; var securitySecion = new TableSection(AppResources.Security) { LockOptionsCell, PinCell, - twoStepCell + TwoStepCell }; if(_fingerprint.IsAvailable) @@ -80,87 +88,76 @@ namespace Bit.App.Pages On = _settings.GetValueOrDefault(Constants.SettingFingerprintUnlockOn, false), IsEnabled = _fingerprint.IsAvailable }; - FingerprintCell.OnChanged += FingerprintCell_Changed; securitySecion.Insert(1, FingerprintCell); } - var changeMasterPasswordCell = new ExtendedTextCell + ChangeMasterPasswordCell = new ExtendedTextCell { Text = AppResources.ChangeMasterPassword, ShowDisclousure = true }; - changeMasterPasswordCell.Tapped += ChangeMasterPasswordCell_Tapped; - var changeEmailCell = new ExtendedTextCell + ChangeEmailCell = new ExtendedTextCell { Text = AppResources.ChangeEmail, ShowDisclousure = true }; - changeEmailCell.Tapped += ChangeEmailCell_Tapped; - var foldersCell = new ExtendedTextCell + FoldersCell = new ExtendedTextCell { Text = AppResources.Folders, ShowDisclousure = true }; - foldersCell.Tapped += FoldersCell_Tapped; - var syncCell = new ExtendedTextCell + SyncCell = new ExtendedTextCell { Text = AppResources.Sync, ShowDisclousure = true }; - syncCell.Tapped += SyncCell_Tapped; - var lockCell = new ExtendedTextCell + LockCell = new ExtendedTextCell { Text = AppResources.Lock }; - lockCell.Tapped += LockCell_Tapped; - var logOutCell = new ExtendedTextCell + LogOutCell = new ExtendedTextCell { Text = AppResources.LogOut }; - logOutCell.Tapped += LogOutCell_Tapped; - var aboutCell = new ExtendedTextCell + AboutCell = new ExtendedTextCell { Text = AppResources.About, ShowDisclousure = true }; - aboutCell.Tapped += AboutCell_Tapped; - var helpCell = new ExtendedTextCell + HelpCell = new ExtendedTextCell { Text = AppResources.HelpAndFeedback, ShowDisclousure = true }; - helpCell.Tapped += HelpCell_Tapped; var otherSection = new TableSection(AppResources.Other) { - aboutCell, - helpCell + AboutCell, + HelpCell }; if(Device.OS == TargetPlatform.iOS) { - var rateCell = new LongDetailViewCell(AppResources.RateTheApp, AppResources.RateTheAppDescriptionAppStore); - rateCell.Tapped += RateCell_Tapped; - otherSection.Add(rateCell); + RateCellLong = new LongDetailViewCell(AppResources.RateTheApp, AppResources.RateTheAppDescriptionAppStore); + otherSection.Add(RateCellLong); } else { - var rateCell = new ExtendedTextCell + RateCell = new ExtendedTextCell { Text = AppResources.RateTheApp, Detail = AppResources.RateTheAppDescription, ShowDisclousure = true, DetailLineBreakMode = LineBreakMode.WordWrap }; - rateCell.Tapped += RateCell_Tapped; - otherSection.Add(rateCell); + otherSection.Add(RateCell); } Table = new CustomTable @@ -170,18 +167,18 @@ namespace Bit.App.Pages securitySecion, new TableSection(AppResources.Account) { - changeMasterPasswordCell, - changeEmailCell + ChangeMasterPasswordCell, + ChangeEmailCell }, new TableSection(AppResources.Manage) { - foldersCell, - syncCell + FoldersCell, + SyncCell }, new TableSection(AppResources.CurrentSession) { - lockCell, - logOutCell + LockCell, + LogOutCell }, otherSection } @@ -191,6 +188,72 @@ namespace Bit.App.Pages 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) { 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)) { cell.On = false; - var pinPage = new SettingsPinPage(); - pinPage.OnPinEntered += PinEntered; + var pinPage = new SettingsPinPage((page) => PinEntered(page)); Navigation.PushModalAsync(new ExtendedNavigationPage(pinPage)); } 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.Navigation.PopModalAsync(); diff --git a/src/App/Pages/Settings/SettingsPinPage.cs b/src/App/Pages/Settings/SettingsPinPage.cs index 74968ec73..b117ee5cd 100644 --- a/src/App/Pages/Settings/SettingsPinPage.cs +++ b/src/App/Pages/Settings/SettingsPinPage.cs @@ -15,9 +15,11 @@ namespace Bit.App.Pages { private readonly IUserDialogs _userDialogs; private readonly ISettings _settings; + private Action _pinEnteredAction; - public SettingsPinPage() + public SettingsPinPage(Action pinEnteredAction) { + _pinEnteredAction = pinEnteredAction; _userDialogs = Resolver.Resolve(); _settings = Resolver.Resolve(); @@ -26,7 +28,7 @@ namespace Bit.App.Pages public PinPageModel Model { get; set; } = new PinPageModel(); public PinControl PinControl { get; set; } - public EventHandler OnPinEntered; + public TapGestureRecognizer Tgr { get; set; } public void Init() { @@ -50,10 +52,9 @@ namespace Bit.App.Pages Children = { PinControl.Label, instructionLabel, PinControl.Entry } }; - var tgr = new TapGestureRecognizer(); - tgr.Tapped += Tgr_Tapped; - PinControl.Label.GestureRecognizers.Add(tgr); - instructionLabel.GestureRecognizers.Add(tgr); + Tgr = new TapGestureRecognizer(); + PinControl.Label.GestureRecognizers.Add(Tgr); + instructionLabel.GestureRecognizers.Add(Tgr); if(Device.OS == TargetPlatform.iOS) { @@ -62,18 +63,14 @@ namespace Bit.App.Pages Title = AppResources.SetPIN; Content = stackLayout; - Content.GestureRecognizers.Add(tgr); + Content.GestureRecognizers.Add(Tgr); BindingContext = Model; } - private void Tgr_Tapped(object sender, EventArgs e) - { - PinControl.Entry.Focus(); - } - protected override void OnAppearing() { base.OnAppearing(); + Tgr.Tapped += Tgr_Tapped; PinControl.OnPinEntered += PinEntered; PinControl.InitEvents(); PinControl.Entry.FocusWithDelay(); @@ -83,12 +80,18 @@ namespace Bit.App.Pages { base.OnDisappearing(); PinControl.Dispose(); + Tgr.Tapped -= Tgr_Tapped; PinControl.OnPinEntered -= PinEntered; } 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(); } } } diff --git a/src/App/Pages/Tools/ToolsPage.cs b/src/App/Pages/Tools/ToolsPage.cs index 022f0f9f6..45511925a 100644 --- a/src/App/Pages/Tools/ToolsPage.cs +++ b/src/App/Pages/Tools/ToolsPage.cs @@ -82,8 +82,14 @@ namespace Bit.App.Pages GeneratorCell.Tapped += GeneratorCell_Tapped; WebCell.Tapped += WebCell_Tapped; ImportCell.Tapped += ImportCell_Tapped; - ExtensionCell.Tapped += ExtensionCell_Tapped; - AutofillCell.Tapped += AutofillCell_Tapped; + if(ExtensionCell != null) + { + ExtensionCell.Tapped += ExtensionCell_Tapped; + } + if(AutofillCell != null) + { + AutofillCell.Tapped += AutofillCell_Tapped; + } } protected override void OnDisappearing() @@ -92,8 +98,14 @@ namespace Bit.App.Pages GeneratorCell.Tapped -= GeneratorCell_Tapped; WebCell.Tapped -= WebCell_Tapped; ImportCell.Tapped -= ImportCell_Tapped; - ExtensionCell.Tapped -= ExtensionCell_Tapped; - AutofillCell.Tapped -= AutofillCell_Tapped; + if(ExtensionCell != null) + { + ExtensionCell.Tapped -= ExtensionCell_Tapped; + } + if(AutofillCell != null) + { + AutofillCell.Tapped -= AutofillCell_Tapped; + } } diff --git a/src/App/Pages/Tools/ToolsPasswordGeneratorPage.cs b/src/App/Pages/Tools/ToolsPasswordGeneratorPage.cs index 43346110c..e8a286dc7 100644 --- a/src/App/Pages/Tools/ToolsPasswordGeneratorPage.cs +++ b/src/App/Pages/Tools/ToolsPasswordGeneratorPage.cs @@ -36,6 +36,10 @@ namespace Bit.App.Pages public PasswordGeneratorPageModel Model { get; private set; } = new PasswordGeneratorPageModel(); public Label Password { 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() { @@ -49,20 +53,16 @@ namespace Bit.App.Pages VerticalOptions = LayoutOptions.Start }; - var tgr = new TapGestureRecognizer(); - tgr.Tapped += Tgr_Tapped; - Password.GestureRecognizers.Add(tgr); + Tgr = new TapGestureRecognizer(); + Password.GestureRecognizers.Add(Tgr); Password.SetBinding(Label.TextProperty, m => m.Password); SliderCell = new SliderViewCell(this, _passwordGenerationService, _settings); - var settingsCell = new ExtendedTextCell { Text = AppResources.MoreSettings, ShowDisclousure = true }; - settingsCell.Tapped += SettingsCell_Tapped; + SettingsCell = new ExtendedTextCell { Text = AppResources.MoreSettings, ShowDisclousure = true }; var buttonColor = Color.FromHex("3c8dbc"); - var regenerateCell = new ExtendedTextCell { Text = AppResources.RegeneratePassword, TextColor = buttonColor }; - regenerateCell.Tapped += RegenerateCell_Tapped; ; - var copyCell = new ExtendedTextCell { Text = AppResources.CopyPassword, TextColor = buttonColor }; - copyCell.Tapped += CopyCell_Tapped; + RegenerateCell = new ExtendedTextCell { Text = AppResources.RegeneratePassword, TextColor = buttonColor }; + CopyCell = new ExtendedTextCell { Text = AppResources.CopyPassword, TextColor = buttonColor }; var table = new ExtendedTableView { @@ -75,13 +75,13 @@ namespace Bit.App.Pages { new TableSection { - regenerateCell, - copyCell + RegenerateCell, + CopyCell }, new TableSection(AppResources.Options) { SliderCell, - settingsCell + SettingsCell } } }; @@ -142,6 +142,12 @@ namespace Bit.App.Pages protected override void OnAppearing() { base.OnAppearing(); + Tgr.Tapped += Tgr_Tapped; + RegenerateCell.Tapped += RegenerateCell_Tapped; + SettingsCell.Tapped += SettingsCell_Tapped; + CopyCell.Tapped += CopyCell_Tapped; + SliderCell.InitEvents(); + if(_fromAutofill) { _googleAnalyticsService.TrackExtensionEvent("GeneratedPassword"); @@ -154,6 +160,16 @@ namespace Bit.App.Pages 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) { Model.Password = _passwordGenerationService.GeneratePassword(); @@ -192,7 +208,7 @@ namespace Bit.App.Pages } // TODO: move to standalone reusable control - public class SliderViewCell : ExtendedViewCell + public class SliderViewCell : ExtendedViewCell, IDisposable { private readonly ToolsPasswordGeneratorPage _page; private readonly IPasswordGenerationService _passwordGenerationService; @@ -234,8 +250,6 @@ namespace Bit.App.Pages Value.SetBinding(Label.TextProperty, m => m.Length); - LengthSlider.ValueChanged += Slider_ValueChanged; - var stackLayout = new StackLayout { Orientation = StackOrientation.Horizontal, @@ -263,6 +277,16 @@ namespace Bit.App.Pages _page.Model.Length = length.ToString(); _page.Model.Password = _passwordGenerationService.GeneratePassword(); } + + public void InitEvents() + { + LengthSlider.ValueChanged += Slider_ValueChanged; + } + + public void Dispose() + { + LengthSlider.ValueChanged -= Slider_ValueChanged; + } } } } diff --git a/src/App/Pages/Tools/ToolsPasswordGeneratorSettingsPage.cs b/src/App/Pages/Tools/ToolsPasswordGeneratorSettingsPage.cs index e70896c46..6304bc9b0 100644 --- a/src/App/Pages/Tools/ToolsPasswordGeneratorSettingsPage.cs +++ b/src/App/Pages/Tools/ToolsPasswordGeneratorSettingsPage.cs @@ -39,14 +39,12 @@ namespace Bit.App.Pages Text = "A-Z", On = _settings.GetValueOrDefault(Constants.PasswordGeneratorUppercase, true) }; - UppercaseCell.OnChanged += UppercaseCell_OnChanged; LowercaseCell = new ExtendedSwitchCell { Text = "a-z", On = _settings.GetValueOrDefault(Constants.PasswordGeneratorLowercase, true) }; - LowercaseCell.OnChanged += LowercaseCell_OnChanged; SpecialCell = new ExtendedSwitchCell { @@ -59,7 +57,6 @@ namespace Bit.App.Pages Text = "0-9", On = _settings.GetValueOrDefault(Constants.PasswordGeneratorNumbers, true) }; - NumbersCell.OnChanged += NumbersCell_OnChanged; AvoidAmbiguousCell = new ExtendedSwitchCell { @@ -114,6 +111,11 @@ namespace Bit.App.Pages base.OnAppearing(); SpecialCell.OnChanged += SpecialCell_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() @@ -121,6 +123,11 @@ namespace Bit.App.Pages base.OnDisappearing(); SpecialCell.OnChanged -= SpecialCell_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, Convert.ToInt32(NumbersMinCell.Stepper.Value)); diff --git a/src/App/Pages/Vault/VaultListLoginsPage.cs b/src/App/Pages/Vault/VaultListLoginsPage.cs index d66d42594..4ba377da8 100644 --- a/src/App/Pages/Vault/VaultListLoginsPage.cs +++ b/src/App/Pages/Vault/VaultListLoginsPage.cs @@ -277,7 +277,7 @@ namespace Bit.App.Pages ListView.ItemSelected -= LoginSelected; Search.TextChanged -= SearchBar_TextChanged; Search.SearchButtonPressed -= SearchBar_SearchButtonPressed; - AddLoginItem.Dispose(); + AddLoginItem?.Dispose(); } protected override bool OnBackButtonPressed()