diff --git a/src/App/Pages/Accounts/TwoFactorPage.xaml b/src/App/Pages/Accounts/TwoFactorPage.xaml index 8a2eea9c6..c4f4666d2 100644 --- a/src/App/Pages/Accounts/TwoFactorPage.xaml +++ b/src/App/Pages/Accounts/TwoFactorPage.xaml @@ -17,15 +17,19 @@ - + - + ("stateService"); _i18nService = ServiceContainer.Resolve("i18nService"); _appIdService = ServiceContainer.Resolve("appIdService"); + _logger = ServiceContainer.Resolve(); PageTitle = AppResources.TwoStepLogin; SubmitCommand = new Command(async () => await SubmitAsync()); + MoreCommand = new AsyncCommand(MoreAsync, onException: _logger.Exception, allowsMultipleExecutions: false); } public string TotpInstruction @@ -111,6 +116,7 @@ namespace Bit.App.Pages }); } public Command SubmitCommand { get; } + public ICommand MoreCommand { get; } public Action TwoFactorAuthSuccessAction { get; set; } public Action StartSetPasswordAction { get; set; } public Action CloseAction { get; set; } @@ -337,6 +343,15 @@ namespace Bit.App.Pages } } + private async Task MoreAsync() + { + var selection = await _deviceActionService.DisplayActionSheetAsync(AppResources.Options, AppResources.Cancel, null, AppResources.UseAnotherTwoStepMethod); + if (selection == AppResources.UseAnotherTwoStepMethod) + { + await AnotherMethodAsync(); + } + } + public async Task AnotherMethodAsync() { var supportedProviders = _authService.GetSupportedTwoFactorProviders(); diff --git a/src/iOS.Autofill/CredentialProviderViewController.cs b/src/iOS.Autofill/CredentialProviderViewController.cs index 9bd087f17..269f4d039 100644 --- a/src/iOS.Autofill/CredentialProviderViewController.cs +++ b/src/iOS.Autofill/CredentialProviderViewController.cs @@ -18,6 +18,7 @@ using CoreNFC; using Foundation; using UIKit; using Xamarin.Forms; +using Xamarin.Forms.Platform.iOS; namespace Bit.iOS.Autofill { diff --git a/src/iOS.Autofill/iOS.Autofill.csproj b/src/iOS.Autofill/iOS.Autofill.csproj index 451361ac6..f1cec9d61 100644 --- a/src/iOS.Autofill/iOS.Autofill.csproj +++ b/src/iOS.Autofill/iOS.Autofill.csproj @@ -253,6 +253,17 @@ + + + Resources\more_vert.png + + + Resources\more_vert%402x.png + + + Resources\more_vert%403x.png + + 4.4.0 diff --git a/src/iOS.Core/Services/DeviceActionService.cs b/src/iOS.Core/Services/DeviceActionService.cs index 22701bc73..71546f4ae 100644 --- a/src/iOS.Core/Services/DeviceActionService.cs +++ b/src/iOS.Core/Services/DeviceActionService.cs @@ -84,6 +84,12 @@ namespace Bit.iOS.Core.Services HideLoadingAsync().GetAwaiter().GetResult(); } + var vc = GetPresentedViewController(); + if (vc is null) + { + return Task.CompletedTask; + } + var result = new TaskCompletionSource(); var loadingIndicator = new UIActivityIndicatorView(new CGRect(10, 5, 50, 50)); @@ -96,8 +102,7 @@ namespace Bit.iOS.Core.Services _progressAlert.View.TintColor = UIColor.Black; _progressAlert.View.Add(loadingIndicator); - var vc = GetPresentedViewController(); - vc?.PresentViewController(_progressAlert, false, () => result.TrySetResult(0)); + vc.PresentViewController(_progressAlert, false, () => result.TrySetResult(0)); return result.Task; } @@ -205,6 +210,12 @@ namespace Bit.iOS.Core.Services string text = null, string okButtonText = null, string cancelButtonText = null, bool numericKeyboard = false, bool autofocus = true, bool password = false) { + var vc = GetPresentedViewController(); + if (vc is null) + { + return null; + } + var result = new TaskCompletionSource(); var alert = UIAlertController.Create(title ?? string.Empty, description, UIAlertControllerStyle.Alert); UITextField input = null; @@ -234,8 +245,7 @@ namespace Bit.iOS.Core.Services input.KeyboardAppearance = UIKeyboardAppearance.Dark; } }); - var vc = GetPresentedViewController(); - vc?.PresentViewController(alert, true, null); + vc.PresentViewController(alert, true, null); return result.Task; } @@ -312,6 +322,12 @@ namespace Bit.iOS.Core.Services public Task DisplayAlertAsync(string title, string message, string cancel, params string[] buttons) { + var vc = GetPresentedViewController(); + if (vc is null) + { + return null; + } + var result = new TaskCompletionSource(); var alert = UIAlertController.Create(title ?? string.Empty, message, UIAlertControllerStyle.Alert); if (!string.IsNullOrWhiteSpace(cancel)) @@ -328,8 +344,7 @@ namespace Bit.iOS.Core.Services result.TrySetResult(button); })); } - var vc = GetPresentedViewController(); - vc?.PresentViewController(alert, true, null); + vc.PresentViewController(alert, true, null); return result.Task; } @@ -340,8 +355,12 @@ namespace Bit.iOS.Core.Services { return app.MainPage.DisplayActionSheet(title, cancel, destruction, buttons); } - var result = new TaskCompletionSource(); var vc = GetPresentedViewController(); + if (vc is null) + { + return null; + } + var result = new TaskCompletionSource(); var sheet = UIAlertController.Create(title, null, UIAlertControllerStyle.ActionSheet); if (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad) { diff --git a/src/iOS.Extension/iOS.Extension.csproj b/src/iOS.Extension/iOS.Extension.csproj index 8907ca640..d11ce857b 100644 --- a/src/iOS.Extension/iOS.Extension.csproj +++ b/src/iOS.Extension/iOS.Extension.csproj @@ -230,6 +230,15 @@ + + Resources\more_vert.png + + + Resources\more_vert%402x.png + + + Resources\more_vert%403x.png + diff --git a/src/iOS.ShareExtension/iOS.ShareExtension.csproj b/src/iOS.ShareExtension/iOS.ShareExtension.csproj index 5109c8886..37c743f11 100644 --- a/src/iOS.ShareExtension/iOS.ShareExtension.csproj +++ b/src/iOS.ShareExtension/iOS.ShareExtension.csproj @@ -227,6 +227,15 @@ Resources\logo.png + + Resources\more_vert.png + + + Resources\more_vert%402x.png + + + Resources\more_vert%403x.png + Resources\bwi-font.ttf