mirror of
https://github.com/bitwarden/android.git
synced 2024-12-27 11:28:28 +03:00
PM-3350 Fixed iOS Extensions navigation to several pages and improved avoiding duplicate calls to OnNavigatedTo
This commit is contained in:
parent
5f12bb9747
commit
df4d89cd52
13 changed files with 145 additions and 179 deletions
|
@ -1,10 +1,6 @@
|
||||||
using System;
|
using Bit.Core.Abstractions;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Bit.Core.Resources.Localization;
|
using Bit.Core.Resources.Localization;
|
||||||
using Bit.Core.Abstractions;
|
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Microsoft.Maui.Controls;
|
|
||||||
using Microsoft.Maui;
|
|
||||||
|
|
||||||
namespace Bit.App.Pages
|
namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
|
@ -19,11 +15,10 @@ namespace Bit.App.Pages
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
_vm = BindingContext as EnvironmentPageViewModel;
|
_vm = BindingContext as EnvironmentPageViewModel;
|
||||||
_vm.Page = this;
|
_vm.Page = this;
|
||||||
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
|
||||||
if (Device.RuntimePlatform == Device.Android)
|
#if ANDROID
|
||||||
{
|
ToolbarItems.RemoveAt(0);
|
||||||
ToolbarItems.RemoveAt(0);
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
_webVaultEntry.ReturnType = ReturnType.Next;
|
_webVaultEntry.ReturnType = ReturnType.Next;
|
||||||
_webVaultEntry.ReturnCommand = new Command(() => _apiEntry.Focus());
|
_webVaultEntry.ReturnCommand = new Command(() => _apiEntry.Focus());
|
||||||
|
@ -31,7 +26,7 @@ namespace Bit.App.Pages
|
||||||
_apiEntry.ReturnCommand = new Command(() => _identityEntry.Focus());
|
_apiEntry.ReturnCommand = new Command(() => _identityEntry.Focus());
|
||||||
_identityEntry.ReturnType = ReturnType.Next;
|
_identityEntry.ReturnType = ReturnType.Next;
|
||||||
_identityEntry.ReturnCommand = new Command(() => _iconsEntry.Focus());
|
_identityEntry.ReturnCommand = new Command(() => _iconsEntry.Focus());
|
||||||
_vm.SubmitSuccessAction = () => Device.BeginInvokeOnMainThread(async () => await SubmitSuccessAsync());
|
_vm.SubmitSuccessAction = () => MainThread.BeginInvokeOnMainThread(async () => await SubmitSuccessAsync());
|
||||||
_vm.CloseAction = async () =>
|
_vm.CloseAction = async () =>
|
||||||
{
|
{
|
||||||
await Navigation.PopModalAsync();
|
await Navigation.PopModalAsync();
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
using System;
|
using Bit.App.Models;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Bit.App.Models;
|
|
||||||
using Bit.App.Utilities;
|
using Bit.App.Utilities;
|
||||||
using Bit.Core.Abstractions;
|
using Bit.Core.Abstractions;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Microsoft.Maui.Controls;
|
|
||||||
using Microsoft.Maui;
|
|
||||||
|
|
||||||
namespace Bit.App.Pages
|
namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
|
@ -20,16 +16,16 @@ namespace Bit.App.Pages
|
||||||
|
|
||||||
public HomePage(AppOptions appOptions = null)
|
public HomePage(AppOptions appOptions = null)
|
||||||
{
|
{
|
||||||
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
|
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>();
|
||||||
_appOptions = appOptions;
|
_appOptions = appOptions;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
_vm = BindingContext as HomeViewModel;
|
_vm = BindingContext as HomeViewModel;
|
||||||
_vm.Page = this;
|
_vm.Page = this;
|
||||||
_vm.ShowCancelButton = _appOptions?.IosExtension ?? false;
|
_vm.ShowCancelButton = _appOptions?.IosExtension ?? false;
|
||||||
_vm.StartLoginAction = async () => await StartLoginAsync();
|
_vm.StartLoginAction = async () => await StartLoginAsync();
|
||||||
_vm.StartRegisterAction = () => Device.BeginInvokeOnMainThread(async () => await StartRegisterAsync());
|
_vm.StartRegisterAction = () => MainThread.BeginInvokeOnMainThread(async () => await StartRegisterAsync());
|
||||||
_vm.StartSsoLoginAction = () => Device.BeginInvokeOnMainThread(async () => await StartSsoLoginAsync());
|
_vm.StartSsoLoginAction = () => MainThread.BeginInvokeOnMainThread(async () => await StartSsoLoginAsync());
|
||||||
_vm.StartEnvironmentAction = () => Device.BeginInvokeOnMainThread(async () => await StartEnvironmentAsync());
|
_vm.StartEnvironmentAction = () => MainThread.BeginInvokeOnMainThread(async () => await StartEnvironmentAsync());
|
||||||
_vm.CloseAction = async () =>
|
_vm.CloseAction = async () =>
|
||||||
{
|
{
|
||||||
await _accountListOverlay.HideAsync();
|
await _accountListOverlay.HideAsync();
|
||||||
|
@ -53,28 +49,28 @@ namespace Bit.App.Pages
|
||||||
await Navigation.PushModalAsync(new NavigationPage(new LoginPage(email, _appOptions)));
|
await Navigation.PushModalAsync(new NavigationPage(new LoginPage(email, _appOptions)));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async void OnAppearing()
|
protected override async void OnNavigatedTo(NavigatedToEventArgs args)
|
||||||
{
|
{
|
||||||
base.OnAppearing();
|
base.OnNavigatedTo(args);
|
||||||
_mainContent.Content = _mainLayout;
|
|
||||||
_accountAvatar?.OnAppearing();
|
await MainThread.InvokeOnMainThreadAsync(() => _mainContent.Content = _mainLayout);
|
||||||
|
|
||||||
if (!_appOptions?.HideAccountSwitcher ?? false)
|
|
||||||
{
|
|
||||||
_vm.AvatarImageSource = await GetAvatarImageSourceAsync(false);
|
|
||||||
}
|
|
||||||
_broadcasterService.Subscribe(nameof(HomePage), (message) =>
|
|
||||||
{
|
|
||||||
if (message.Command is ThemeManager.UPDATED_THEME_MESSAGE_KEY)
|
|
||||||
{
|
|
||||||
Device.BeginInvokeOnMainThread(() =>
|
|
||||||
{
|
|
||||||
UpdateLogo();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
_accountAvatar?.OnAppearing();
|
||||||
|
|
||||||
|
if (!_appOptions?.HideAccountSwitcher ?? false)
|
||||||
|
{
|
||||||
|
await MainThread.InvokeOnMainThreadAsync(async () => _vm.AvatarImageSource = await GetAvatarImageSourceAsync(false));
|
||||||
|
}
|
||||||
|
_broadcasterService.Subscribe(nameof(HomePage), (message) =>
|
||||||
|
{
|
||||||
|
if (message.Command is ThemeManager.UPDATED_THEME_MESSAGE_KEY)
|
||||||
|
{
|
||||||
|
MainThread.BeginInvokeOnMainThread(UpdateLogo);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
await _vm.UpdateEnvironment();
|
await _vm.UpdateEnvironment();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -83,6 +79,14 @@ namespace Bit.App.Pages
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnNavigatingFrom(NavigatingFromEventArgs args)
|
||||||
|
{
|
||||||
|
base.OnNavigatingFrom(args);
|
||||||
|
|
||||||
|
_broadcasterService?.Unsubscribe(nameof(HomePage));
|
||||||
|
_accountAvatar?.OnDisappearing();
|
||||||
|
}
|
||||||
|
|
||||||
protected override bool OnBackButtonPressed()
|
protected override bool OnBackButtonPressed()
|
||||||
{
|
{
|
||||||
if (_accountListOverlay.IsVisible)
|
if (_accountListOverlay.IsVisible)
|
||||||
|
@ -93,13 +97,6 @@ namespace Bit.App.Pages
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnDisappearing()
|
|
||||||
{
|
|
||||||
base.OnDisappearing();
|
|
||||||
_broadcasterService.Unsubscribe(nameof(HomePage));
|
|
||||||
_accountAvatar?.OnDisappearing();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateLogo()
|
private void UpdateLogo()
|
||||||
{
|
{
|
||||||
_logo.Source = !ThemeManager.UsingLightTheme ? "logo_white.png" : "logo.png";
|
_logo.Source = !ThemeManager.UsingLightTheme ? "logo_white.png" : "logo.png";
|
||||||
|
|
|
@ -1,18 +1,12 @@
|
||||||
using System;
|
using Bit.App.Models;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Bit.App.Models;
|
|
||||||
using Bit.App.Utilities;
|
using Bit.App.Utilities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Microsoft.Maui.Controls;
|
|
||||||
using Microsoft.Maui;
|
|
||||||
|
|
||||||
namespace Bit.App.Pages
|
namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
public partial class LoginApproveDevicePage : BaseContentPage
|
public partial class LoginApproveDevicePage : BaseContentPage
|
||||||
{
|
{
|
||||||
|
|
||||||
private readonly LoginApproveDeviceViewModel _vm;
|
private readonly LoginApproveDeviceViewModel _vm;
|
||||||
private readonly AppOptions _appOptions;
|
private readonly AppOptions _appOptions;
|
||||||
|
|
||||||
|
@ -28,9 +22,11 @@ namespace Bit.App.Pages
|
||||||
_appOptions = appOptions;
|
_appOptions = appOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnAppearing()
|
protected override bool ShouldCheckToPreventOnNavigatedToCalledTwice => true;
|
||||||
|
|
||||||
|
protected override async Task InitOnNavigatedToAsync()
|
||||||
{
|
{
|
||||||
_vm.InitAsync();
|
await _vm.InitAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ContinueToVaultAsync()
|
private async Task ContinueToVaultAsync()
|
||||||
|
@ -62,4 +58,3 @@ namespace Bit.App.Pages
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,16 +64,12 @@ namespace Bit.App.Pages
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override bool ShouldCheckToPreventOnNavigatedToCalledTwice => true;
|
||||||
|
|
||||||
public Entry MasterPasswordEntry { get; set; }
|
public Entry MasterPasswordEntry { get; set; }
|
||||||
|
|
||||||
protected override async void OnNavigatedTo(NavigatedToEventArgs args)
|
protected override async Task InitOnNavigatedToAsync()
|
||||||
{
|
{
|
||||||
base.OnNavigatedTo(args);
|
|
||||||
|
|
||||||
//IsInitialized is used as a workaround to avoid duplicate initialization issues because of OnNavigatedTo being called twice.
|
|
||||||
if (HasInitialized) { return; }
|
|
||||||
HasInitialized = true;
|
|
||||||
|
|
||||||
_broadcasterService.Subscribe(nameof(LoginPage), message =>
|
_broadcasterService.Subscribe(nameof(LoginPage), message =>
|
||||||
{
|
{
|
||||||
if (message.Command == Constants.ClearSensitiveFields)
|
if (message.Command == Constants.ClearSensitiveFields)
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
using System;
|
using Bit.App.Models;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Bit.App.Models;
|
|
||||||
using Bit.App.Utilities;
|
using Bit.App.Utilities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Microsoft.Maui.Controls;
|
|
||||||
using Microsoft.Maui;
|
|
||||||
|
|
||||||
namespace Bit.App.Pages
|
namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
|
@ -23,23 +18,25 @@ namespace Bit.App.Pages
|
||||||
_vm.Email = email;
|
_vm.Email = email;
|
||||||
_vm.AuthRequestType = authRequestType;
|
_vm.AuthRequestType = authRequestType;
|
||||||
_vm.AuthingWithSso = authingWithSso;
|
_vm.AuthingWithSso = authingWithSso;
|
||||||
_vm.StartTwoFactorAction = () => Device.BeginInvokeOnMainThread(async () => await StartTwoFactorAsync());
|
_vm.StartTwoFactorAction = () => MainThread.BeginInvokeOnMainThread(async () => await StartTwoFactorAsync());
|
||||||
_vm.LogInSuccessAction = () => Device.BeginInvokeOnMainThread(async () => await LogInSuccessAsync());
|
_vm.LogInSuccessAction = () => MainThread.BeginInvokeOnMainThread(async () => await LogInSuccessAsync());
|
||||||
_vm.UpdateTempPasswordAction = () => Device.BeginInvokeOnMainThread(async () => await UpdateTempPasswordAsync());
|
_vm.UpdateTempPasswordAction = () => MainThread.BeginInvokeOnMainThread(async () => await UpdateTempPasswordAsync());
|
||||||
_vm.CloseAction = () => { Navigation.PopModalAsync(); };
|
_vm.CloseAction = () => { Navigation.PopModalAsync(); };
|
||||||
|
|
||||||
_vm.CreatePasswordlessLoginCommand.Execute(null);
|
_vm.CreatePasswordlessLoginCommand.Execute(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnAppearing()
|
protected override bool ShouldCheckToPreventOnNavigatedToCalledTwice => true;
|
||||||
|
|
||||||
|
protected override Task InitOnNavigatedToAsync()
|
||||||
{
|
{
|
||||||
base.OnAppearing();
|
|
||||||
_vm.StartCheckLoginRequestStatus();
|
_vm.StartCheckLoginRequestStatus();
|
||||||
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnDisappearing()
|
protected override void OnNavigatedFrom(NavigatedFromEventArgs args)
|
||||||
{
|
{
|
||||||
base.OnDisappearing();
|
base.OnNavigatedFrom(args);
|
||||||
_vm.StopCheckLoginRequestStatus();
|
_vm.StopCheckLoginRequestStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,4 +63,3 @@ namespace Bit.App.Pages
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,26 +1,14 @@
|
||||||
using System;
|
using System.Windows.Input;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows.Input;
|
|
||||||
using Bit.App.Abstractions;
|
using Bit.App.Abstractions;
|
||||||
using Bit.Core.Resources.Localization;
|
|
||||||
using Bit.App.Utilities;
|
using Bit.App.Utilities;
|
||||||
using Bit.Core;
|
|
||||||
using Bit.Core.Abstractions;
|
using Bit.Core.Abstractions;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Exceptions;
|
using Bit.Core.Exceptions;
|
||||||
using Bit.Core.Models.Domain;
|
using Bit.Core.Models.Domain;
|
||||||
using Bit.Core.Models.Response;
|
using Bit.Core.Models.Response;
|
||||||
using Bit.Core.Services;
|
using Bit.Core.Resources.Localization;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
|
|
||||||
using Microsoft.Maui.Controls;
|
|
||||||
using Microsoft.Maui;
|
|
||||||
|
|
||||||
namespace Bit.App.Pages
|
namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
public class LoginPasswordlessRequestViewModel : CaptchaProtectedViewModel
|
public class LoginPasswordlessRequestViewModel : CaptchaProtectedViewModel
|
||||||
|
@ -72,7 +60,7 @@ namespace Bit.App.Pages
|
||||||
onException: ex => HandleException(ex),
|
onException: ex => HandleException(ex),
|
||||||
allowsMultipleExecutions: false);
|
allowsMultipleExecutions: false);
|
||||||
|
|
||||||
CloseCommand = new AsyncCommand(() => Device.InvokeOnMainThreadAsync(CloseAction),
|
CloseCommand = new AsyncCommand(() => MainThread.InvokeOnMainThreadAsync(CloseAction),
|
||||||
onException: _logger.Exception,
|
onException: _logger.Exception,
|
||||||
allowsMultipleExecutions: false);
|
allowsMultipleExecutions: false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,25 +39,10 @@ namespace Bit.App.Pages
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async void OnNavigatedTo(NavigatedToEventArgs args)
|
protected override bool ShouldCheckToPreventOnNavigatedToCalledTwice => true;
|
||||||
|
|
||||||
|
protected override async Task InitOnNavigatedToAsync()
|
||||||
{
|
{
|
||||||
base.OnNavigatedTo(args);
|
|
||||||
|
|
||||||
//IsInitialized is used as a workaround to avoid duplicate initialization issues because of OnNavigatedTo being called twice.
|
|
||||||
if (HasInitialized) { return; }
|
|
||||||
HasInitialized = true;
|
|
||||||
|
|
||||||
await _vm.InitAsync();
|
|
||||||
if (string.IsNullOrWhiteSpace(_vm.OrgIdentifier))
|
|
||||||
{
|
|
||||||
RequestFocus(_orgIdentifier);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override async void OnNavigatedFrom(NavigatedFromEventArgs args)
|
|
||||||
{
|
|
||||||
base.OnNavigatedFrom(args);
|
|
||||||
|
|
||||||
await _vm.InitAsync();
|
await _vm.InitAsync();
|
||||||
if (string.IsNullOrWhiteSpace(_vm.OrgIdentifier))
|
if (string.IsNullOrWhiteSpace(_vm.OrgIdentifier))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
using System;
|
namespace Bit.App.Pages
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.Maui.Controls;
|
|
||||||
using Microsoft.Maui;
|
|
||||||
|
|
||||||
namespace Bit.App.Pages
|
|
||||||
{
|
{
|
||||||
public partial class RegisterPage : BaseContentPage
|
public partial class RegisterPage : BaseContentPage
|
||||||
{
|
{
|
||||||
|
@ -16,18 +11,17 @@ namespace Bit.App.Pages
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
_vm = BindingContext as RegisterPageViewModel;
|
_vm = BindingContext as RegisterPageViewModel;
|
||||||
_vm.Page = this;
|
_vm.Page = this;
|
||||||
_vm.RegistrationSuccess = () => Device.BeginInvokeOnMainThread(async () => await RegistrationSuccessAsync(homePage));
|
_vm.RegistrationSuccess = () => MainThread.BeginInvokeOnMainThread(async () => await RegistrationSuccessAsync(homePage));
|
||||||
_vm.CloseAction = async () =>
|
_vm.CloseAction = async () =>
|
||||||
{
|
{
|
||||||
await Navigation.PopModalAsync();
|
await Navigation.PopModalAsync();
|
||||||
};
|
};
|
||||||
MasterPasswordEntry = _masterPassword;
|
MasterPasswordEntry = _masterPassword;
|
||||||
ConfirmMasterPasswordEntry = _confirmMasterPassword;
|
ConfirmMasterPasswordEntry = _confirmMasterPassword;
|
||||||
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
|
||||||
if (Device.RuntimePlatform == Device.Android)
|
#if ANDROID
|
||||||
{
|
ToolbarItems.RemoveAt(0);
|
||||||
ToolbarItems.RemoveAt(0);
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
_email.ReturnType = ReturnType.Next;
|
_email.ReturnType = ReturnType.Next;
|
||||||
_email.ReturnCommand = new Command(() => _masterPassword.Focus());
|
_email.ReturnCommand = new Command(() => _masterPassword.Focus());
|
||||||
|
@ -40,14 +34,17 @@ namespace Bit.App.Pages
|
||||||
public Entry MasterPasswordEntry { get; set; }
|
public Entry MasterPasswordEntry { get; set; }
|
||||||
public Entry ConfirmMasterPasswordEntry { get; set; }
|
public Entry ConfirmMasterPasswordEntry { get; set; }
|
||||||
|
|
||||||
protected override void OnAppearing()
|
protected override bool ShouldCheckToPreventOnNavigatedToCalledTwice => true;
|
||||||
|
|
||||||
|
protected override Task InitOnNavigatedToAsync()
|
||||||
{
|
{
|
||||||
base.OnAppearing();
|
|
||||||
if (!_inputFocused)
|
if (!_inputFocused)
|
||||||
{
|
{
|
||||||
RequestFocus(_email);
|
RequestFocus(_email);
|
||||||
_inputFocused = true;
|
_inputFocused = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void Submit_Clicked(object sender, EventArgs e)
|
private async void Submit_Clicked(object sender, EventArgs e)
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
using System;
|
using Bit.App.Models;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Bit.App.Models;
|
|
||||||
using Bit.App.Utilities;
|
using Bit.App.Utilities;
|
||||||
using Microsoft.Maui.Controls;
|
|
||||||
using Microsoft.Maui;
|
|
||||||
|
|
||||||
namespace Bit.App.Pages
|
namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
|
@ -19,17 +15,16 @@ namespace Bit.App.Pages
|
||||||
_vm = BindingContext as SetPasswordPageViewModel;
|
_vm = BindingContext as SetPasswordPageViewModel;
|
||||||
_vm.Page = this;
|
_vm.Page = this;
|
||||||
_vm.SetPasswordSuccessAction =
|
_vm.SetPasswordSuccessAction =
|
||||||
() => Device.BeginInvokeOnMainThread(async () => await SetPasswordSuccessAsync());
|
() => MainThread.BeginInvokeOnMainThread(async () => await SetPasswordSuccessAsync());
|
||||||
_vm.CloseAction = async () =>
|
_vm.CloseAction = async () =>
|
||||||
{
|
{
|
||||||
await Navigation.PopModalAsync();
|
await Navigation.PopModalAsync();
|
||||||
};
|
};
|
||||||
_vm.OrgIdentifier = orgIdentifier;
|
_vm.OrgIdentifier = orgIdentifier;
|
||||||
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
|
||||||
if (Device.RuntimePlatform == Device.Android)
|
#if ANDROID
|
||||||
{
|
ToolbarItems.RemoveAt(0);
|
||||||
ToolbarItems.RemoveAt(0);
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
MasterPasswordEntry = _masterPassword;
|
MasterPasswordEntry = _masterPassword;
|
||||||
ConfirmMasterPasswordEntry = _confirmMasterPassword;
|
ConfirmMasterPasswordEntry = _confirmMasterPassword;
|
||||||
|
@ -43,9 +38,10 @@ namespace Bit.App.Pages
|
||||||
public Entry MasterPasswordEntry { get; set; }
|
public Entry MasterPasswordEntry { get; set; }
|
||||||
public Entry ConfirmMasterPasswordEntry { get; set; }
|
public Entry ConfirmMasterPasswordEntry { get; set; }
|
||||||
|
|
||||||
protected override async void OnAppearing()
|
protected override bool ShouldCheckToPreventOnNavigatedToCalledTwice => true;
|
||||||
|
|
||||||
|
protected override async Task InitOnNavigatedToAsync()
|
||||||
{
|
{
|
||||||
base.OnAppearing();
|
|
||||||
await _vm.InitAsync();
|
await _vm.InitAsync();
|
||||||
RequestFocus(_masterPassword);
|
RequestFocus(_masterPassword);
|
||||||
}
|
}
|
||||||
|
@ -58,7 +54,7 @@ namespace Bit.App.Pages
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void Close_Clicked(object sender, EventArgs e)
|
private void Close_Clicked(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (DoOnce())
|
if (DoOnce())
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,8 +22,8 @@ namespace Bit.App.Pages
|
||||||
SetActivityIndicator();
|
SetActivityIndicator();
|
||||||
_appOptions = appOptions;
|
_appOptions = appOptions;
|
||||||
_orgIdentifier = orgIdentifier;
|
_orgIdentifier = orgIdentifier;
|
||||||
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
|
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>();
|
||||||
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
_messagingService = ServiceContainer.Resolve<IMessagingService>();
|
||||||
_vm = BindingContext as TwoFactorPageViewModel;
|
_vm = BindingContext as TwoFactorPageViewModel;
|
||||||
_vm.Page = this;
|
_vm.Page = this;
|
||||||
_vm.AuthingWithSso = authingWithSso ?? false;
|
_vm.AuthingWithSso = authingWithSso ?? false;
|
||||||
|
@ -40,25 +40,21 @@ namespace Bit.App.Pages
|
||||||
_vm.CloseAction = async () => await Navigation.PopModalAsync();
|
_vm.CloseAction = async () => await Navigation.PopModalAsync();
|
||||||
DuoWebView = _duoWebView;
|
DuoWebView = _duoWebView;
|
||||||
|
|
||||||
if (DeviceInfo.Platform == DevicePlatform.Android)
|
#if ANDROID
|
||||||
{
|
ToolbarItems.Remove(_cancelItem);
|
||||||
ToolbarItems.Remove(_cancelItem);
|
ToolbarItems.Add(_useAnotherTwoStepMethod);
|
||||||
}
|
#else
|
||||||
if (DeviceInfo.Platform == DevicePlatform.iOS)
|
|
||||||
{
|
ToolbarItems.Add(_moreItem);
|
||||||
ToolbarItems.Add(_moreItem);
|
#endif
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ToolbarItems.Add(_useAnotherTwoStepMethod);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public HybridWebView DuoWebView { get; set; }
|
public HybridWebView DuoWebView { get; set; }
|
||||||
|
|
||||||
protected override async void OnAppearing()
|
protected override bool ShouldCheckToPreventOnNavigatedToCalledTwice => true;
|
||||||
|
|
||||||
|
protected override async Task InitOnNavigatedToAsync()
|
||||||
{
|
{
|
||||||
base.OnAppearing();
|
|
||||||
_broadcasterService.Subscribe(nameof(TwoFactorPage), (message) =>
|
_broadcasterService.Subscribe(nameof(TwoFactorPage), (message) =>
|
||||||
{
|
{
|
||||||
if (message.Command == "gotYubiKeyOTP")
|
if (message.Command == "gotYubiKeyOTP")
|
||||||
|
@ -101,10 +97,11 @@ namespace Bit.App.Pages
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnDisappearing()
|
protected override void OnNavigatedFrom(NavigatedFromEventArgs args)
|
||||||
{
|
{
|
||||||
base.OnDisappearing();
|
base.OnNavigatedFrom(args);
|
||||||
|
|
||||||
if (!_vm.YubikeyMethod)
|
if (!_vm.YubikeyMethod)
|
||||||
{
|
{
|
||||||
_messagingService.Send("listenYubiKeyOTP", false);
|
_messagingService.Send("listenYubiKeyOTP", false);
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
using System;
|
using Bit.Core.Abstractions;
|
||||||
using Bit.Core.Resources.Localization;
|
using Bit.Core.Resources.Localization;
|
||||||
using Bit.Core.Abstractions;
|
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Microsoft.Maui.Controls;
|
|
||||||
using Microsoft.Maui;
|
|
||||||
|
|
||||||
namespace Bit.App.Pages
|
namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
|
@ -17,8 +14,8 @@ namespace Bit.App.Pages
|
||||||
public UpdateTempPasswordPage()
|
public UpdateTempPasswordPage()
|
||||||
{
|
{
|
||||||
// Service Init
|
// Service Init
|
||||||
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
_messagingService = ServiceContainer.Resolve<IMessagingService>();
|
||||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>();
|
||||||
|
|
||||||
// Binding
|
// Binding
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
@ -30,9 +27,9 @@ namespace Bit.App.Pages
|
||||||
// Actions Declaration
|
// Actions Declaration
|
||||||
_vm.LogOutAction = () =>
|
_vm.LogOutAction = () =>
|
||||||
{
|
{
|
||||||
_messagingService.Send("logout");
|
_messagingService.Send(AccountsManagerMessageCommands.LOGOUT);
|
||||||
};
|
};
|
||||||
_vm.UpdateTempPasswordSuccessAction = () => Device.BeginInvokeOnMainThread(UpdateTempPasswordSuccess);
|
_vm.UpdateTempPasswordSuccessAction = () => MainThread.BeginInvokeOnMainThread(UpdateTempPasswordSuccess);
|
||||||
|
|
||||||
// Link fields that will be referenced in codebehind
|
// Link fields that will be referenced in codebehind
|
||||||
MasterPasswordEntry = _masterPassword;
|
MasterPasswordEntry = _masterPassword;
|
||||||
|
@ -48,9 +45,10 @@ namespace Bit.App.Pages
|
||||||
public Entry MasterPasswordEntry { get; set; }
|
public Entry MasterPasswordEntry { get; set; }
|
||||||
public Entry ConfirmMasterPasswordEntry { get; set; }
|
public Entry ConfirmMasterPasswordEntry { get; set; }
|
||||||
|
|
||||||
protected override async void OnAppearing()
|
protected override bool ShouldCheckToPreventOnNavigatedToCalledTwice => true;
|
||||||
|
|
||||||
|
protected override async Task InitOnNavigatedToAsync()
|
||||||
{
|
{
|
||||||
base.OnAppearing();
|
|
||||||
await LoadOnAppearedAsync(_mainLayout, true, async () =>
|
await LoadOnAppearedAsync(_mainLayout, true, async () =>
|
||||||
{
|
{
|
||||||
await _vm.InitAsync(true);
|
await _vm.InitAsync(true);
|
||||||
|
@ -81,7 +79,7 @@ namespace Bit.App.Pages
|
||||||
|
|
||||||
private void UpdateTempPasswordSuccess()
|
private void UpdateTempPasswordSuccess()
|
||||||
{
|
{
|
||||||
_messagingService.Send("logout");
|
_messagingService.Send(AccountsManagerMessageCommands.LOGOUT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,10 @@ using Bit.App.Controls;
|
||||||
using Bit.App.Utilities;
|
using Bit.App.Utilities;
|
||||||
using Bit.Core.Abstractions;
|
using Bit.Core.Abstractions;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
|
#if IOS
|
||||||
using Microsoft.Maui.Controls.PlatformConfiguration;
|
using Microsoft.Maui.Controls.PlatformConfiguration;
|
||||||
using Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;
|
using Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Bit.App.Pages
|
namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
|
@ -16,22 +18,34 @@ namespace Bit.App.Pages
|
||||||
protected int ShowModalAnimationDelay = 400;
|
protected int ShowModalAnimationDelay = 400;
|
||||||
protected int ShowPageAnimationDelay = 100;
|
protected int ShowPageAnimationDelay = 100;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used as a workaround to avoid duplicate initialization issues for some pages where OnNavigatedTo is called twice.
|
||||||
|
/// </summary>
|
||||||
|
private bool _hasInitedOnNavigatedTo;
|
||||||
|
|
||||||
public BaseContentPage()
|
public BaseContentPage()
|
||||||
{
|
{
|
||||||
if (DeviceInfo.Platform == DevicePlatform.iOS)
|
#if IOS
|
||||||
{
|
On<iOS>().SetUseSafeArea(true);
|
||||||
On<iOS>().SetUseSafeArea(true);
|
On<iOS>().SetModalPresentationStyle(UIModalPresentationStyle.FullScreen);
|
||||||
On<iOS>().SetModalPresentationStyle(UIModalPresentationStyle.FullScreen);
|
#endif
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//IsInitialized is used as a workaround to avoid duplicate initialization issues for some pages where OnNavigatedTo is called twice.
|
|
||||||
protected bool HasInitialized { get; set; }
|
|
||||||
|
|
||||||
public DateTime? LastPageAction { get; set; }
|
public DateTime? LastPageAction { get; set; }
|
||||||
|
|
||||||
public bool IsThemeDirty { get; set; }
|
public bool IsThemeDirty { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This flag is used to see if check is needed to avoid duplicate calls of <see cref="OnNavigatedTo(NavigatedToEventArgs)"/>
|
||||||
|
/// Usually on modal navigation to the current page this flag should be <c>true</c>
|
||||||
|
/// Also this flag is added instead of directly checking for all pages to avoid potential issues on the app
|
||||||
|
/// and focusing only on the places where it's actually needed.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This should be removed once MAUI fixes the issue of duplicate call to the method.
|
||||||
|
/// </remarks>
|
||||||
|
protected virtual bool ShouldCheckToPreventOnNavigatedToCalledTwice => false;
|
||||||
|
|
||||||
protected override async void OnNavigatedTo(NavigatedToEventArgs args)
|
protected override async void OnNavigatedTo(NavigatedToEventArgs args)
|
||||||
{
|
{
|
||||||
base.OnNavigatedTo(args);
|
base.OnNavigatedTo(args);
|
||||||
|
@ -42,6 +56,22 @@ namespace Bit.App.Pages
|
||||||
}
|
}
|
||||||
|
|
||||||
await SaveActivityAsync();
|
await SaveActivityAsync();
|
||||||
|
|
||||||
|
if (ShouldCheckToPreventOnNavigatedToCalledTwice && _hasInitedOnNavigatedTo)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_hasInitedOnNavigatedTo = true;
|
||||||
|
|
||||||
|
await InitOnNavigatedToAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual Task InitOnNavigatedToAsync() => Task.CompletedTask;
|
||||||
|
|
||||||
|
protected override void OnNavigatedFrom(NavigatedFromEventArgs args)
|
||||||
|
{
|
||||||
|
base.OnNavigatedFrom(args);
|
||||||
|
_hasInitedOnNavigatedTo = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DoOnce(Action action = null, int milliseconds = 1000)
|
public bool DoOnce(Action action = null, int milliseconds = 1000)
|
||||||
|
|
|
@ -73,10 +73,6 @@
|
||||||
</Compile>
|
</Compile>
|
||||||
<BundleResource Include="Resources\MaterialIcons_Regular.ttf" />
|
<BundleResource Include="Resources\MaterialIcons_Regular.ttf" />
|
||||||
<BundleResource Include="Resources\bwi-font.ttf" />
|
<BundleResource Include="Resources\bwi-font.ttf" />
|
||||||
<Compile Include="TestViewController.cs" />
|
|
||||||
<Compile Include="TestViewController.designer.cs">
|
|
||||||
<DependentUpon>TestViewController.cs</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Core\Core.csproj" />
|
<ProjectReference Include="..\Core\Core.csproj" />
|
||||||
|
|
Loading…
Reference in a new issue