diff --git a/src/App/Pages/Accounts/LockPage.xaml.cs b/src/App/Pages/Accounts/LockPage.xaml.cs index 354c45230..22f6416ef 100644 --- a/src/App/Pages/Accounts/LockPage.xaml.cs +++ b/src/App/Pages/Accounts/LockPage.xaml.cs @@ -25,8 +25,6 @@ namespace Bit.App.Pages _vm = BindingContext as LockPageViewModel; _vm.Page = this; _vm.UnlockedAction = () => Device.BeginInvokeOnMainThread(async () => await UnlockedAsync()); - MasterPasswordEntry = _masterPassword; - PinEntry = _pin; if (Device.RuntimePlatform == Device.iOS) { @@ -38,8 +36,17 @@ namespace Bit.App.Pages } } - public Entry MasterPasswordEntry { get; set; } - public Entry PinEntry { get; set; } + public Entry SecretEntry + { + get + { + if (_vm?.PinLock ?? false) + { + return _pin; + } + return _masterPassword; + } + } public async Task PromptBiometricAfterResumeAsync() { @@ -70,16 +77,12 @@ namespace Bit.App.Pages _vm.AvatarImageSource = await GetAvatarImageSourceAsync(); await _vm.InitAsync(); + + _vm.FocusSecretEntry += PerformFocusSecretEntry; + if (!_vm.BiometricLock) { - if (_vm.PinLock) - { - RequestFocus(PinEntry); - } - else - { - RequestFocus(MasterPasswordEntry); - } + RequestFocus(SecretEntry); } else { @@ -99,6 +102,18 @@ namespace Bit.App.Pages } } + private void PerformFocusSecretEntry(int? cursorPosition) + { + Device.BeginInvokeOnMainThread(() => + { + SecretEntry.Focus(); + if (cursorPosition.HasValue) + { + SecretEntry.CursorPosition = cursorPosition.Value; + } + }); + } + protected override bool OnBackButtonPressed() { if (_accountListOverlay.IsVisible) diff --git a/src/App/Pages/Accounts/LockPageViewModel.cs b/src/App/Pages/Accounts/LockPageViewModel.cs index 5b007be38..0b771ae1e 100644 --- a/src/App/Pages/Accounts/LockPageViewModel.cs +++ b/src/App/Pages/Accounts/LockPageViewModel.cs @@ -10,6 +10,7 @@ using Bit.Core.Enums; using Bit.Core.Models.Domain; using Bit.Core.Models.Request; using Bit.Core.Utilities; +using Xamarin.CommunityToolkit.Helpers; using Xamarin.Forms; namespace Bit.App.Pages @@ -27,6 +28,7 @@ namespace Bit.App.Pages private readonly IBiometricService _biometricService; private readonly IKeyConnectorService _keyConnectorService; private readonly ILogger _logger; + private readonly WeakEventManager _secretEntryFocusWeakEventManager = new WeakEventManager(); private string _email; private bool _showPassword; @@ -133,6 +135,11 @@ namespace Bit.App.Pages public string MasterPassword { get; set; } public string Pin { get; set; } public Action UnlockedAction { get; set; } + public event Action FocusSecretEntry + { + add => _secretEntryFocusWeakEventManager.AddEventHandler(value); + remove => _secretEntryFocusWeakEventManager.RemoveEventHandler(value); + } public async Task InitAsync() { @@ -342,15 +349,12 @@ namespace Bit.App.Pages _messagingService.Send("logout"); } } - + public void TogglePassword() { ShowPassword = !ShowPassword; - var page = (Page as LockPage); - var entry = PinLock ? page.PinEntry : page.MasterPasswordEntry; - var str = PinLock ? Pin : MasterPassword; - entry.Focus(); - entry.CursorPosition = String.IsNullOrEmpty(str) ? 0 : str.Length; + var secret = PinLock ? Pin : MasterPassword; + _secretEntryFocusWeakEventManager.RaiseEvent(string.IsNullOrEmpty(secret) ? 0 : secret.Length, nameof(FocusSecretEntry)); } public async Task PromptBiometricAsync() @@ -361,18 +365,8 @@ namespace Bit.App.Pages return; } var success = await _platformUtilsService.AuthenticateBiometricAsync(null, - PinLock ? AppResources.PIN : AppResources.MasterPassword, () => - { - var page = Page as LockPage; - if (PinLock) - { - page.PinEntry.Focus(); - } - else - { - page.MasterPasswordEntry.Focus(); - } - }); + PinLock ? AppResources.PIN : AppResources.MasterPassword, + () => _secretEntryFocusWeakEventManager.RaiseEvent((int?)null, nameof(FocusSecretEntry))); await _stateService.SetBiometricLockedAsync(!success); if (success) {