mirror of
https://github.com/bitwarden/mobile
synced 2025-12-12 06:13:21 +00:00
PM-3349 PM-3350 MAUI Migration Initial
This commit is contained in:
550
src/Core/App.xaml.cs
Normal file
550
src/Core/App.xaml.cs
Normal file
@@ -0,0 +1,550 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Pages;
|
||||
using Bit.Core.Resources.Localization;
|
||||
using Bit.App.Services;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.App.Utilities.AccountManagement;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Response;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.Maui.Controls.Xaml;
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
|
||||
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
namespace Bit.App
|
||||
{
|
||||
public partial class App : Application, IAccountsManagerHost
|
||||
{
|
||||
public const string POP_ALL_AND_GO_TO_TAB_GENERATOR_MESSAGE = "popAllAndGoToTabGenerator";
|
||||
public const string POP_ALL_AND_GO_TO_TAB_MYVAULT_MESSAGE = "popAllAndGoToTabMyVault";
|
||||
public const string POP_ALL_AND_GO_TO_TAB_SEND_MESSAGE = "popAllAndGoToTabSend";
|
||||
public const string POP_ALL_AND_GO_TO_AUTOFILL_CIPHERS_MESSAGE = "popAllAndGoToAutofillCiphers";
|
||||
|
||||
private readonly IBroadcasterService _broadcasterService;
|
||||
private readonly IMessagingService _messagingService;
|
||||
private readonly IStateService _stateService;
|
||||
private readonly IVaultTimeoutService _vaultTimeoutService;
|
||||
private readonly ISyncService _syncService;
|
||||
private readonly IAuthService _authService;
|
||||
private readonly IDeviceActionService _deviceActionService;
|
||||
private readonly IFileService _fileService;
|
||||
private readonly IAccountsManager _accountsManager;
|
||||
private readonly IPushNotificationService _pushNotificationService;
|
||||
private readonly IConfigService _configService;
|
||||
private static bool _isResumed;
|
||||
// these variables are static because the app is launching new activities on notification click, creating new instances of App.
|
||||
private static bool _pendingCheckPasswordlessLoginRequests;
|
||||
private static object _processingLoginRequestLock = new object();
|
||||
|
||||
public App() : this(null)
|
||||
{
|
||||
}
|
||||
|
||||
public App(AppOptions appOptions)
|
||||
{
|
||||
Options = appOptions ?? new AppOptions();
|
||||
if (Options.IosExtension)
|
||||
{
|
||||
Current = this;
|
||||
return;
|
||||
}
|
||||
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
|
||||
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
||||
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||
_vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService");
|
||||
_syncService = ServiceContainer.Resolve<ISyncService>("syncService");
|
||||
_authService = ServiceContainer.Resolve<IAuthService>("authService");
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
_fileService = ServiceContainer.Resolve<IFileService>();
|
||||
_accountsManager = ServiceContainer.Resolve<IAccountsManager>("accountsManager");
|
||||
_pushNotificationService = ServiceContainer.Resolve<IPushNotificationService>();
|
||||
_configService = ServiceContainer.Resolve<IConfigService>();
|
||||
|
||||
_accountsManager.Init(() => Options, this);
|
||||
|
||||
Bootstrap();
|
||||
_broadcasterService.Subscribe(nameof(App), async (message) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (message.Command == "showDialog")
|
||||
{
|
||||
var details = message.Data as DialogDetails;
|
||||
var confirmed = true;
|
||||
var confirmText = string.IsNullOrWhiteSpace(details.ConfirmText) ?
|
||||
AppResources.Ok : details.ConfirmText;
|
||||
Device.BeginInvokeOnMainThread(async () =>
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(details.CancelText))
|
||||
{
|
||||
confirmed = await Current.MainPage.DisplayAlert(details.Title, details.Text, confirmText,
|
||||
details.CancelText);
|
||||
}
|
||||
else
|
||||
{
|
||||
await Current.MainPage.DisplayAlert(details.Title, details.Text, confirmText);
|
||||
}
|
||||
_messagingService.Send("showDialogResolve", new Tuple<int, bool>(details.DialogId, confirmed));
|
||||
});
|
||||
}
|
||||
else if (message.Command == AppHelpers.RESUMED_MESSAGE_COMMAND)
|
||||
{
|
||||
// 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.iOS)
|
||||
{
|
||||
ResumedAsync().FireAndForget();
|
||||
}
|
||||
}
|
||||
else if (message.Command == "slept")
|
||||
{
|
||||
// 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.iOS)
|
||||
{
|
||||
await SleptAsync();
|
||||
}
|
||||
}
|
||||
else if (message.Command == "migrated")
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
await _accountsManager.NavigateOnAccountChangeAsync();
|
||||
}
|
||||
else if (message.Command == POP_ALL_AND_GO_TO_TAB_GENERATOR_MESSAGE ||
|
||||
message.Command == POP_ALL_AND_GO_TO_TAB_MYVAULT_MESSAGE ||
|
||||
message.Command == POP_ALL_AND_GO_TO_TAB_SEND_MESSAGE ||
|
||||
message.Command == POP_ALL_AND_GO_TO_AUTOFILL_CIPHERS_MESSAGE ||
|
||||
message.Command == DeepLinkContext.NEW_OTP_MESSAGE)
|
||||
{
|
||||
if (message.Command == DeepLinkContext.NEW_OTP_MESSAGE)
|
||||
{
|
||||
Options.OtpData = new OtpData((string)message.Data);
|
||||
}
|
||||
|
||||
Device.InvokeOnMainThreadAsync(async () =>
|
||||
{
|
||||
if (Current.MainPage is TabsPage tabsPage)
|
||||
{
|
||||
while (tabsPage.Navigation.ModalStack.Count > 0)
|
||||
{
|
||||
await tabsPage.Navigation.PopModalAsync(false);
|
||||
}
|
||||
if (message.Command == POP_ALL_AND_GO_TO_AUTOFILL_CIPHERS_MESSAGE)
|
||||
{
|
||||
Current.MainPage = new NavigationPage(new CipherSelectionPage(Options));
|
||||
}
|
||||
else if (message.Command == POP_ALL_AND_GO_TO_TAB_MYVAULT_MESSAGE)
|
||||
{
|
||||
Options.MyVaultTile = false;
|
||||
tabsPage.ResetToVaultPage();
|
||||
}
|
||||
else if (message.Command == POP_ALL_AND_GO_TO_TAB_GENERATOR_MESSAGE)
|
||||
{
|
||||
Options.GeneratorTile = false;
|
||||
tabsPage.ResetToGeneratorPage();
|
||||
}
|
||||
else if (message.Command == POP_ALL_AND_GO_TO_TAB_SEND_MESSAGE)
|
||||
{
|
||||
tabsPage.ResetToSendPage();
|
||||
}
|
||||
else if (message.Command == DeepLinkContext.NEW_OTP_MESSAGE)
|
||||
{
|
||||
tabsPage.ResetToVaultPage();
|
||||
await tabsPage.Navigation.PushModalAsync(new NavigationPage(new CipherSelectionPage(Options)));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (message.Command == "convertAccountToKeyConnector")
|
||||
{
|
||||
Device.BeginInvokeOnMainThread(async () =>
|
||||
{
|
||||
await Application.Current.MainPage.Navigation.PushModalAsync(
|
||||
new NavigationPage(new RemoveMasterPasswordPage()));
|
||||
});
|
||||
}
|
||||
else if (message.Command == Constants.ForceUpdatePassword)
|
||||
{
|
||||
Device.BeginInvokeOnMainThread(async () =>
|
||||
{
|
||||
await Application.Current.MainPage.Navigation.PushModalAsync(
|
||||
new NavigationPage(new UpdateTempPasswordPage()));
|
||||
});
|
||||
}
|
||||
else if (message.Command == "syncCompleted")
|
||||
{
|
||||
await _configService.GetAsync(true);
|
||||
}
|
||||
else if (message.Command == Constants.PasswordlessLoginRequestKey
|
||||
|| message.Command == "unlocked"
|
||||
|| message.Command == AccountsManagerMessageCommands.ACCOUNT_SWITCH_COMPLETED)
|
||||
{
|
||||
lock (_processingLoginRequestLock)
|
||||
{
|
||||
// lock doesn't allow for async execution
|
||||
CheckPasswordlessLoginRequestsAsync().Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async Task CheckPasswordlessLoginRequestsAsync()
|
||||
{
|
||||
if (!_isResumed)
|
||||
{
|
||||
_pendingCheckPasswordlessLoginRequests = true;
|
||||
return;
|
||||
}
|
||||
_pendingCheckPasswordlessLoginRequests = false;
|
||||
if (await _vaultTimeoutService.IsLockedAsync())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var notification = await _stateService.GetPasswordlessLoginNotificationAsync();
|
||||
if (notification == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (await CheckShouldSwitchActiveUserAsync(notification))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Delay to wait for the vault page to appear
|
||||
await Task.Delay(2000);
|
||||
// if there is a request modal opened ignore all incoming requests
|
||||
if (App.Current.MainPage.Navigation.ModalStack.Any(p => p is NavigationPage navPage && navPage.CurrentPage is LoginPasswordlessPage))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var loginRequestData = await _authService.GetPasswordlessLoginRequestByIdAsync(notification.Id);
|
||||
var page = new LoginPasswordlessPage(new LoginPasswordlessDetails()
|
||||
{
|
||||
PubKey = loginRequestData.PublicKey,
|
||||
Id = loginRequestData.Id,
|
||||
IpAddress = loginRequestData.RequestIpAddress,
|
||||
Email = await _stateService.GetEmailAsync(),
|
||||
FingerprintPhrase = loginRequestData.FingerprintPhrase,
|
||||
RequestDate = loginRequestData.CreationDate,
|
||||
DeviceType = loginRequestData.RequestDeviceType,
|
||||
Origin = loginRequestData.Origin
|
||||
});
|
||||
await _stateService.SetPasswordlessLoginNotificationAsync(null);
|
||||
_pushNotificationService.DismissLocalNotification(Constants.PasswordlessNotificationId);
|
||||
if (!loginRequestData.IsExpired)
|
||||
{
|
||||
await Device.InvokeOnMainThreadAsync(() => Application.Current.MainPage.Navigation.PushModalAsync(new NavigationPage(page)));
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> CheckShouldSwitchActiveUserAsync(PasswordlessRequestNotification notification)
|
||||
{
|
||||
var activeUserId = await _stateService.GetActiveUserIdAsync();
|
||||
if (notification.UserId == activeUserId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var notificationUserEmail = await _stateService.GetEmailAsync(notification.UserId);
|
||||
Device.BeginInvokeOnMainThread(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _deviceActionService.DisplayAlertAsync(AppResources.LogInRequested, string.Format(AppResources.LoginAttemptFromXDoYouWantToSwitchToThisAccount, notificationUserEmail), AppResources.Cancel, AppResources.Ok);
|
||||
if (result == AppResources.Ok)
|
||||
{
|
||||
await _stateService.SetActiveUserAsync(notification.UserId);
|
||||
_messagingService.Send(AccountsManagerMessageCommands.SWITCHED_ACCOUNT);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
public AppOptions Options { get; private set; }
|
||||
|
||||
protected async override void OnStart()
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("XF App: OnStart");
|
||||
_isResumed = true;
|
||||
await ClearCacheIfNeededAsync();
|
||||
Prime();
|
||||
if (string.IsNullOrWhiteSpace(Options.Uri))
|
||||
{
|
||||
var updated = await AppHelpers.PerformUpdateTasksAsync(_syncService, _deviceActionService,
|
||||
_stateService);
|
||||
if (!updated)
|
||||
{
|
||||
SyncIfNeeded();
|
||||
}
|
||||
}
|
||||
if (_pendingCheckPasswordlessLoginRequests)
|
||||
{
|
||||
_messagingService.Send(Constants.PasswordlessLoginRequestKey);
|
||||
}
|
||||
// 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)
|
||||
{
|
||||
await _vaultTimeoutService.CheckVaultTimeoutAsync();
|
||||
// Reset delay on every start
|
||||
_vaultTimeoutService.DelayLockAndLogoutMs = null;
|
||||
}
|
||||
|
||||
await _configService.GetAsync();
|
||||
_messagingService.Send("startEventTimer");
|
||||
}
|
||||
|
||||
protected async override void OnSleep()
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("XF App: OnSleep");
|
||||
_isResumed = false;
|
||||
// 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)
|
||||
{
|
||||
var isLocked = await _vaultTimeoutService.IsLockedAsync();
|
||||
if (!isLocked)
|
||||
{
|
||||
await _stateService.SetLastActiveTimeAsync(_deviceActionService.GetActiveTime());
|
||||
}
|
||||
if (!SetTabsPageFromAutofill(isLocked))
|
||||
{
|
||||
ClearAutofillUri();
|
||||
}
|
||||
await SleptAsync();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnResume()
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("XF App: OnResume");
|
||||
_isResumed = true;
|
||||
if (_pendingCheckPasswordlessLoginRequests)
|
||||
{
|
||||
_messagingService.Send(Constants.PasswordlessLoginRequestKey);
|
||||
}
|
||||
// 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)
|
||||
{
|
||||
ResumedAsync().FireAndForget();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SleptAsync()
|
||||
{
|
||||
await _vaultTimeoutService.CheckVaultTimeoutAsync();
|
||||
await ClearSensitiveFieldsAsync();
|
||||
_messagingService.Send("stopEventTimer");
|
||||
}
|
||||
|
||||
private async Task ResumedAsync()
|
||||
{
|
||||
await _stateService.CheckExtensionActiveUserAndSwitchIfNeededAsync();
|
||||
await _vaultTimeoutService.CheckVaultTimeoutAsync();
|
||||
await ClearSensitiveFieldsAsync();
|
||||
_messagingService.Send("startEventTimer");
|
||||
await UpdateThemeAsync();
|
||||
await ClearCacheIfNeededAsync();
|
||||
Prime();
|
||||
SyncIfNeeded();
|
||||
if (Current.MainPage is NavigationPage navPage && navPage.CurrentPage is LockPage lockPage)
|
||||
{
|
||||
await lockPage.PromptBiometricAfterResumeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task UpdateThemeAsync()
|
||||
{
|
||||
await Device.InvokeOnMainThreadAsync(() =>
|
||||
{
|
||||
ThemeManager.SetTheme(Current.Resources);
|
||||
_messagingService.Send(ThemeManager.UPDATED_THEME_MESSAGE_KEY);
|
||||
});
|
||||
}
|
||||
|
||||
private async Task ClearSensitiveFieldsAsync()
|
||||
{
|
||||
await Device.InvokeOnMainThreadAsync(() =>
|
||||
{
|
||||
_messagingService.Send(Constants.ClearSensitiveFields);
|
||||
});
|
||||
}
|
||||
|
||||
private void SetCulture()
|
||||
{
|
||||
// Calendars are removed by linker. ref https://bugzilla.xamarin.com/show_bug.cgi?id=59077
|
||||
new System.Globalization.ThaiBuddhistCalendar();
|
||||
new System.Globalization.HijriCalendar();
|
||||
new System.Globalization.UmAlQuraCalendar();
|
||||
}
|
||||
|
||||
private async Task ClearCacheIfNeededAsync()
|
||||
{
|
||||
var lastClear = await _stateService.GetLastFileCacheClearAsync();
|
||||
if ((DateTime.UtcNow - lastClear.GetValueOrDefault(DateTime.MinValue)).TotalDays >= 1)
|
||||
{
|
||||
var task = Task.Run(() => _fileService.ClearCacheAsync());
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearAutofillUri()
|
||||
{
|
||||
// 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 && !string.IsNullOrWhiteSpace(Options.Uri))
|
||||
{
|
||||
Options.Uri = null;
|
||||
}
|
||||
}
|
||||
|
||||
private bool SetTabsPageFromAutofill(bool isLocked)
|
||||
{
|
||||
// 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 && !string.IsNullOrWhiteSpace(Options.Uri) &&
|
||||
!Options.FromAutofillFramework)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
Device.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
Options.Uri = null;
|
||||
if (isLocked)
|
||||
{
|
||||
Current.MainPage = new NavigationPage(new LockPage());
|
||||
}
|
||||
else
|
||||
{
|
||||
Current.MainPage = new TabsPage();
|
||||
}
|
||||
});
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void Prime()
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
var word = EEFLongWordList.Instance.List[1];
|
||||
var parsedDomain = DomainName.TryParse("https://bitwarden.com", out var domainName);
|
||||
});
|
||||
}
|
||||
|
||||
private void Bootstrap()
|
||||
{
|
||||
InitializeComponent();
|
||||
SetCulture();
|
||||
ThemeManager.SetTheme(Current.Resources);
|
||||
Current.RequestedThemeChanged += (s, a) =>
|
||||
{
|
||||
UpdateThemeAsync();
|
||||
};
|
||||
Current.MainPage = new NavigationPage(new HomePage(Options));
|
||||
_accountsManager.NavigateOnAccountChangeAsync().FireAndForget();
|
||||
ServiceContainer.Resolve<MobilePlatformUtilsService>("platformUtilsService").Init();
|
||||
}
|
||||
|
||||
private void SyncIfNeeded()
|
||||
{
|
||||
if (Microsoft.Maui.Networking.Connectivity.NetworkAccess == Microsoft.Maui.Networking.NetworkAccess.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var lastSync = await _syncService.GetLastSyncAsync();
|
||||
if (lastSync == null || ((DateTime.UtcNow - lastSync) > TimeSpan.FromMinutes(30)))
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
await _syncService.FullSyncAsync(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public async Task SetPreviousPageInfoAsync()
|
||||
{
|
||||
PreviousPageInfo lastPageBeforeLock = null;
|
||||
if (Current.MainPage is TabbedPage tabbedPage && tabbedPage.Navigation.ModalStack.Count > 0)
|
||||
{
|
||||
var topPage = tabbedPage.Navigation.ModalStack[tabbedPage.Navigation.ModalStack.Count - 1];
|
||||
if (topPage is NavigationPage navPage)
|
||||
{
|
||||
if (navPage.CurrentPage is CipherDetailsPage cipherDetailsPage)
|
||||
{
|
||||
lastPageBeforeLock = new PreviousPageInfo
|
||||
{
|
||||
Page = "view",
|
||||
CipherId = cipherDetailsPage.ViewModel.CipherId
|
||||
};
|
||||
}
|
||||
else if (navPage.CurrentPage is CipherAddEditPage cipherAddEditPage && cipherAddEditPage.ViewModel.EditMode)
|
||||
{
|
||||
lastPageBeforeLock = new PreviousPageInfo
|
||||
{
|
||||
Page = "edit",
|
||||
CipherId = cipherAddEditPage.ViewModel.CipherId
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
await _stateService.SetPreviousPageInfoAsync(lastPageBeforeLock);
|
||||
}
|
||||
|
||||
public void Navigate(NavigationTarget navTarget, INavigationParams navParams)
|
||||
{
|
||||
switch (navTarget)
|
||||
{
|
||||
case NavigationTarget.HomeLogin:
|
||||
Current.MainPage = new NavigationPage(new HomePage(Options));
|
||||
break;
|
||||
case NavigationTarget.Login:
|
||||
if (navParams is LoginNavigationParams loginParams)
|
||||
{
|
||||
Current.MainPage = new NavigationPage(new LoginPage(loginParams.Email, Options));
|
||||
}
|
||||
break;
|
||||
case NavigationTarget.Lock:
|
||||
if (navParams is LockNavigationParams lockParams)
|
||||
{
|
||||
Current.MainPage = new NavigationPage(new LockPage(Options, lockParams.AutoPromptBiometric));
|
||||
}
|
||||
else
|
||||
{
|
||||
Current.MainPage = new NavigationPage(new LockPage(Options));
|
||||
}
|
||||
break;
|
||||
case NavigationTarget.Home:
|
||||
Current.MainPage = new TabsPage(Options);
|
||||
break;
|
||||
case NavigationTarget.AddEditCipher:
|
||||
Current.MainPage = new NavigationPage(new CipherAddEditPage(appOptions: Options));
|
||||
break;
|
||||
case NavigationTarget.AutofillCiphers:
|
||||
case NavigationTarget.OtpCipherSelection:
|
||||
Current.MainPage = new NavigationPage(new CipherSelectionPage(Options));
|
||||
break;
|
||||
case NavigationTarget.SendAddEdit:
|
||||
Current.MainPage = new NavigationPage(new SendAddEditPage(Options));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user