mirror of
https://github.com/bitwarden/mobile.git
synced 2025-01-24 21:31:31 +01:00
PM-3350 Fix iOS extensions navigation and Window/RootViewController handling for TapGestureRecognizer to work
This commit is contained in:
parent
a5888827c9
commit
a4a3d31c19
@ -0,0 +1,51 @@
|
|||||||
|
#if ENABLED_TAP_GESTURE_RECOGNIZER_MAUI_EMBEDDED_WORKAROUND
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using AuthenticationServices;
|
||||||
|
using Bit.App.Abstractions;
|
||||||
|
using Bit.Core.Utilities;
|
||||||
|
using Bit.iOS.Autofill.Models;
|
||||||
|
using Bit.iOS.Core.Utilities;
|
||||||
|
using Microsoft.Maui.Controls;
|
||||||
|
using Microsoft.Maui.Platform;
|
||||||
|
using UIKit;
|
||||||
|
|
||||||
|
namespace Bit.iOS.Autofill
|
||||||
|
{
|
||||||
|
public partial class CredentialProviderViewController : ASCredentialProviderViewController, IAccountsManagerHost
|
||||||
|
{
|
||||||
|
const string STORYBOARD_NAME = "MainInterface";
|
||||||
|
Lazy<UIStoryboard> _storyboard = new Lazy<UIStoryboard>(() => UIStoryboard.FromName(STORYBOARD_NAME, null));
|
||||||
|
|
||||||
|
public void InitWithContext(Context context)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DismissLockAndContinue()
|
||||||
|
{
|
||||||
|
if (UIApplication.SharedApplication.KeyWindow is null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UIApplication.SharedApplication.KeyWindow.RootViewController = _storyboard.Value.InstantiateInitialViewController();
|
||||||
|
|
||||||
|
if (UIApplication.SharedApplication.KeyWindow?.RootViewController is CredentialProviderViewController cpvc)
|
||||||
|
{
|
||||||
|
cpvc.InitWithContext(_context);
|
||||||
|
cpvc.OnLockDismissedAsync().FireAndForget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NavigateToPage(ContentPage page)
|
||||||
|
{
|
||||||
|
var navigationPage = new NavigationPage(page);
|
||||||
|
|
||||||
|
var window = new Window(navigationPage);
|
||||||
|
window.ToHandler(MauiContextSingleton.Instance.MauiContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AuthenticationServices;
|
using AuthenticationServices;
|
||||||
using Bit.App.Abstractions;
|
using Bit.App.Abstractions;
|
||||||
@ -16,8 +17,7 @@ using Bit.iOS.Core.Views;
|
|||||||
using CoreFoundation;
|
using CoreFoundation;
|
||||||
using CoreNFC;
|
using CoreNFC;
|
||||||
using Foundation;
|
using Foundation;
|
||||||
using Microsoft.Maui.Controls;
|
using Microsoft.Maui.ApplicationModel;
|
||||||
using Microsoft.Maui.Platform;
|
|
||||||
using UIKit;
|
using UIKit;
|
||||||
|
|
||||||
namespace Bit.iOS.Autofill
|
namespace Bit.iOS.Autofill
|
||||||
@ -29,7 +29,7 @@ namespace Bit.iOS.Autofill
|
|||||||
private Core.NFCReaderDelegate _nfcDelegate = null;
|
private Core.NFCReaderDelegate _nfcDelegate = null;
|
||||||
private IAccountsManager _accountsManager;
|
private IAccountsManager _accountsManager;
|
||||||
|
|
||||||
private readonly LazyResolve<IStateService> _stateService = new LazyResolve<IStateService>("stateService");
|
private readonly LazyResolve<IStateService> _stateService = new LazyResolve<IStateService>();
|
||||||
|
|
||||||
public CredentialProviderViewController(IntPtr handle)
|
public CredentialProviderViewController(IntPtr handle)
|
||||||
: base(handle)
|
: base(handle)
|
||||||
@ -37,11 +37,13 @@ namespace Bit.iOS.Autofill
|
|||||||
ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
|
ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ASCredentialProviderExtensionContext ASExtensionContext => _context?.ExtContext as ASCredentialProviderExtensionContext;
|
||||||
|
|
||||||
public override void ViewDidLoad()
|
public override void ViewDidLoad()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
InitApp();
|
InitAppIfNeeded();
|
||||||
|
|
||||||
base.ViewDidLoad();
|
base.ViewDidLoad();
|
||||||
|
|
||||||
@ -51,6 +53,7 @@ namespace Bit.iOS.Autofill
|
|||||||
{
|
{
|
||||||
ExtContext = ExtensionContext
|
ExtContext = ExtensionContext
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -171,7 +174,7 @@ namespace Bit.iOS.Autofill
|
|||||||
if ((_context?.Configuring ?? true) && string.IsNullOrWhiteSpace(password))
|
if ((_context?.Configuring ?? true) && string.IsNullOrWhiteSpace(password))
|
||||||
{
|
{
|
||||||
ServiceContainer.Reset();
|
ServiceContainer.Reset();
|
||||||
ExtensionContext?.CompleteExtensionConfigurationRequest();
|
ASExtensionContext?.CompleteExtensionConfigurationRequest();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,7 +183,7 @@ namespace Bit.iOS.Autofill
|
|||||||
ServiceContainer.Reset();
|
ServiceContainer.Reset();
|
||||||
var err = new NSError(new NSString("ASExtensionErrorDomain"),
|
var err = new NSError(new NSString("ASExtensionErrorDomain"),
|
||||||
Convert.ToInt32(ASExtensionErrorCode.UserCanceled), null);
|
Convert.ToInt32(ASExtensionErrorCode.UserCanceled), null);
|
||||||
NSRunLoop.Main.BeginInvokeOnMainThread(() => ExtensionContext?.CancelRequest(err));
|
NSRunLoop.Main.BeginInvokeOnMainThread(() => ASExtensionContext?.CancelRequest(err));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,7 +201,7 @@ namespace Bit.iOS.Autofill
|
|||||||
await eventService.CollectAsync(Bit.Core.Enums.EventType.Cipher_ClientAutofilled, id);
|
await eventService.CollectAsync(Bit.Core.Enums.EventType.Cipher_ClientAutofilled, id);
|
||||||
}
|
}
|
||||||
ServiceContainer.Reset();
|
ServiceContainer.Reset();
|
||||||
ExtensionContext?.CompleteRequest(cred, null);
|
ASExtensionContext?.CompleteRequest(cred, null);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,38 +248,53 @@ namespace Bit.iOS.Autofill
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DismissLockAndContinue()
|
#if !ENABLED_TAP_GESTURE_RECOGNIZER_MAUI_EMBEDDED_WORKAROUND
|
||||||
|
public async void DismissLockAndContinue()
|
||||||
{
|
{
|
||||||
DismissViewController(false, async () =>
|
ClipLogger.Log("Dismiss lock and continue");
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (_context.CredentialIdentity != null)
|
|
||||||
{
|
|
||||||
await ProvideCredentialAsync();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (_context.Configuring)
|
|
||||||
{
|
|
||||||
PerformSegue("setupSegue", this);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_context.ServiceIdentifiers == null || _context.ServiceIdentifiers.Length == 0)
|
DismissViewController(false, async () => await OnLockDismissedAsync());
|
||||||
{
|
}
|
||||||
PerformSegue("loginSearchSegue", this);
|
|
||||||
}
|
private void NavigateToPage(ContentPage page)
|
||||||
else
|
{
|
||||||
{
|
var navigationPage = new NavigationPage(page);
|
||||||
PerformSegue("loginListSegue", this);
|
var uiController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
|
||||||
}
|
uiController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
|
||||||
}
|
|
||||||
catch (Exception ex)
|
PresentViewController(uiController, true, null);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public async Task OnLockDismissedAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_context.CredentialIdentity != null)
|
||||||
{
|
{
|
||||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
await MainThread.InvokeOnMainThreadAsync(() => ProvideCredentialAsync());
|
||||||
throw;
|
return;
|
||||||
}
|
}
|
||||||
});
|
if (_context.Configuring)
|
||||||
|
{
|
||||||
|
await MainThread.InvokeOnMainThreadAsync(() => PerformSegue("setupSegue", this));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_context.ServiceIdentifiers == null || _context.ServiceIdentifiers.Length == 0)
|
||||||
|
{
|
||||||
|
await MainThread.InvokeOnMainThreadAsync(() => PerformSegue("loginSearchSegue", this));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await MainThread.InvokeOnMainThreadAsync(() => PerformSegue("loginListSegue", this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ProvideCredentialAsync(bool userInteraction = true)
|
private async Task ProvideCredentialAsync(bool userInteraction = true)
|
||||||
@ -407,46 +425,25 @@ namespace Bit.iOS.Autofill
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void NavigateToPage(ContentPage page)
|
|
||||||
{
|
|
||||||
var navigationPage = new NavigationPage(page);
|
|
||||||
|
|
||||||
var window = new Window(navigationPage);
|
|
||||||
window.ToHandler(MauiContextSingleton.Instance.MauiContext);
|
|
||||||
|
|
||||||
var uiController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
|
|
||||||
uiController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
|
|
||||||
|
|
||||||
PresentViewController(uiController, true, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LaunchHomePage()
|
private void LaunchHomePage()
|
||||||
{
|
{
|
||||||
try
|
var appOptions = new AppOptions { IosExtension = true };
|
||||||
|
var homePage = new HomePage(appOptions);
|
||||||
|
var app = new App.App(appOptions);
|
||||||
|
ThemeManager.SetTheme(app.Resources);
|
||||||
|
ThemeManager.ApplyResourcesTo(homePage);
|
||||||
|
if (homePage.BindingContext is HomeViewModel vm)
|
||||||
{
|
{
|
||||||
var appOptions = new AppOptions { IosExtension = true };
|
vm.StartLoginAction = () => DismissViewController(false, () => LaunchLoginFlow(vm.Email));
|
||||||
var homePage = new HomePage(appOptions);
|
vm.StartRegisterAction = () => DismissViewController(false, () => LaunchRegisterFlow());
|
||||||
var app = new App.App(appOptions);
|
vm.StartSsoLoginAction = () => DismissViewController(false, () => LaunchLoginSsoFlow());
|
||||||
ThemeManager.SetTheme(app.Resources);
|
vm.StartEnvironmentAction = () => DismissViewController(false, () => LaunchEnvironmentFlow());
|
||||||
ThemeManager.ApplyResourcesTo(homePage);
|
vm.CloseAction = () => CompleteRequest();
|
||||||
if (homePage.BindingContext is HomeViewModel vm)
|
|
||||||
{
|
|
||||||
vm.StartLoginAction = () => DismissViewController(false, () => LaunchLoginFlow(vm.Email));
|
|
||||||
vm.StartRegisterAction = () => DismissViewController(false, () => LaunchRegisterFlow());
|
|
||||||
vm.StartSsoLoginAction = () => DismissViewController(false, () => LaunchLoginSsoFlow());
|
|
||||||
vm.StartEnvironmentAction = () => DismissViewController(false, () => LaunchEnvironmentFlow());
|
|
||||||
vm.CloseAction = () => CompleteRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
NavigateToPage(homePage);
|
|
||||||
|
|
||||||
LogoutIfAuthed();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
UIPasteboard.General.String = ex.ToString();
|
|
||||||
_labelErr.Text = ex.ToString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NavigateToPage(homePage);
|
||||||
|
|
||||||
|
LogoutIfAuthed();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LaunchEnvironmentFlow()
|
private void LaunchEnvironmentFlow()
|
||||||
|
@ -12,9 +12,6 @@ namespace Bit.iOS.Autofill
|
|||||||
[Register ("CredentialProviderViewController")]
|
[Register ("CredentialProviderViewController")]
|
||||||
partial class CredentialProviderViewController
|
partial class CredentialProviderViewController
|
||||||
{
|
{
|
||||||
[Outlet]
|
|
||||||
UIKit.UILabel _labelErr { get; set; }
|
|
||||||
|
|
||||||
[Outlet]
|
[Outlet]
|
||||||
[GeneratedCode ("iOS Designer", "1.0")]
|
[GeneratedCode ("iOS Designer", "1.0")]
|
||||||
UIKit.UIImageView Logo { get; set; }
|
UIKit.UIImageView Logo { get; set; }
|
||||||
@ -25,11 +22,6 @@ namespace Bit.iOS.Autofill
|
|||||||
Logo.Dispose ();
|
Logo.Dispose ();
|
||||||
Logo = null;
|
Logo = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_labelErr != null) {
|
|
||||||
_labelErr.Dispose ();
|
|
||||||
_labelErr = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,28 +18,18 @@
|
|||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="logo.png" translatesAutoresizingMaskIntoConstraints="NO" id="1713">
|
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="logo.png" translatesAutoresizingMaskIntoConstraints="NO" id="1713">
|
||||||
<rect key="frame" x="66" y="676" width="282" height="44"/>
|
<rect key="frame" x="66" y="396" width="282" height="44"/>
|
||||||
</imageView>
|
</imageView>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="No Error" textAlignment="natural" lineBreakMode="characterWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="HVp-Yu-JIZ">
|
|
||||||
<rect key="frame" x="5" y="187" width="404" height="26.5"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="22"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
</subviews>
|
||||||
<viewLayoutGuide key="safeArea" id="YG6-2d-qpF"/>
|
<viewLayoutGuide key="safeArea" id="YG6-2d-qpF"/>
|
||||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstItem="1713" firstAttribute="centerY" secondItem="44" secondAttribute="centerY" constant="250" id="1763"/>
|
<constraint firstItem="1713" firstAttribute="centerY" secondItem="44" secondAttribute="centerY" constant="-30" id="1763"/>
|
||||||
<constraint firstItem="1713" firstAttribute="centerX" secondItem="YG6-2d-qpF" secondAttribute="centerX" id="1764"/>
|
<constraint firstItem="1713" firstAttribute="centerX" secondItem="YG6-2d-qpF" secondAttribute="centerX" id="1764"/>
|
||||||
<constraint firstItem="HVp-Yu-JIZ" firstAttribute="top" secondItem="YG6-2d-qpF" secondAttribute="top" constant="139" id="Ay0-v3-kTO"/>
|
|
||||||
<constraint firstItem="HVp-Yu-JIZ" firstAttribute="trailing" secondItem="YG6-2d-qpF" secondAttribute="trailing" constant="-5" id="TdY-Cu-YFt"/>
|
|
||||||
<constraint firstItem="YG6-2d-qpF" firstAttribute="leading" secondItem="HVp-Yu-JIZ" secondAttribute="leading" constant="-5" id="lfV-6C-INq"/>
|
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="Logo" destination="1713" id="name-outlet-1713"/>
|
<outlet property="Logo" destination="1713" id="name-outlet-1713"/>
|
||||||
<outlet property="_labelErr" destination="HVp-Yu-JIZ" id="PjY-be-dhX"/>
|
|
||||||
<segue destination="oCZ-GQ-aOK" kind="show" identifier="loginListSegue" id="1679"/>
|
<segue destination="oCZ-GQ-aOK" kind="show" identifier="loginListSegue" id="1679"/>
|
||||||
<segue destination="6855" kind="presentation" identifier="lockPasswordSegue" id="9874"/>
|
<segue destination="6855" kind="presentation" identifier="lockPasswordSegue" id="9874"/>
|
||||||
<segue destination="10580" kind="presentation" identifier="setupSegue" modalTransitionStyle="coverVertical" id="11089"/>
|
<segue destination="10580" kind="presentation" identifier="setupSegue" modalTransitionStyle="coverVertical" id="11089"/>
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
<EnableDefaultCompileItems>False</EnableDefaultCompileItems>
|
<EnableDefaultCompileItems>False</EnableDefaultCompileItems>
|
||||||
|
|
||||||
|
<DefineConstants>$(DefineConstants);ENABLED_TAP_GESTURE_RECOGNIZER_MAUI_EMBEDDED_WORKAROUND</DefineConstants>
|
||||||
|
|
||||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">12.0</SupportedOSPlatformVersion>
|
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">12.0</SupportedOSPlatformVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
@ -78,6 +80,7 @@
|
|||||||
<Compile Include="Models\Context.cs" />
|
<Compile Include="Models\Context.cs" />
|
||||||
<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="CredentialProviderViewController.TapGestureHack.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<BundleResource Include="Resources\check.png" />
|
<BundleResource Include="Resources\check.png" />
|
||||||
|
68
src/iOS.Extension/LoadingViewController.TapGestureHack.cs
Normal file
68
src/iOS.Extension/LoadingViewController.TapGestureHack.cs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#if ENABLED_TAP_GESTURE_RECOGNIZER_MAUI_EMBEDDED_WORKAROUND
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using Bit.iOS.Core.Utilities;
|
||||||
|
using Bit.iOS.Extension.Models;
|
||||||
|
using Microsoft.Maui.Controls;
|
||||||
|
using Microsoft.Maui.Platform;
|
||||||
|
using UIKit;
|
||||||
|
|
||||||
|
namespace Bit.iOS.Extension
|
||||||
|
{
|
||||||
|
public partial class LoadingViewController : UIViewController
|
||||||
|
{
|
||||||
|
const string STORYBOARD_NAME = "MainInterface";
|
||||||
|
Lazy<UIStoryboard> _storyboard = new Lazy<UIStoryboard>(() => UIStoryboard.FromName(STORYBOARD_NAME, null));
|
||||||
|
|
||||||
|
public void InitWithContext(Context context)
|
||||||
|
{
|
||||||
|
ClipLogger.Log($"InitWithContext: {context?.UrlString}");
|
||||||
|
_context = context;
|
||||||
|
_shouldInitialize = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DismissLockAndContinue()
|
||||||
|
{
|
||||||
|
ClipLogger.Log("DismissLockAndContinue");
|
||||||
|
if (UIApplication.SharedApplication.KeyWindow is null)
|
||||||
|
{
|
||||||
|
ClipLogger.Log("KeyWindow is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UIApplication.SharedApplication.KeyWindow.RootViewController = _storyboard.Value.InstantiateInitialViewController();
|
||||||
|
|
||||||
|
if (UIApplication.SharedApplication.KeyWindow?.RootViewController is UINavigationController navContr)
|
||||||
|
{
|
||||||
|
var rootVC = navContr.ViewControllers.FirstOrDefault();
|
||||||
|
if (rootVC is LoadingViewController loadingVC)
|
||||||
|
{
|
||||||
|
ClipLogger.Log("Re-initing");
|
||||||
|
loadingVC.InitWithContext(_context);
|
||||||
|
loadingVC.ContinueOn();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ClipLogger.Log($"Not LVC: {rootVC?.GetType().FullName}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ClipLogger.Log($"DismissLockAndContinue RVC not correct: {UIApplication.SharedApplication.KeyWindow?.RootViewController?.GetType().FullName}");
|
||||||
|
}
|
||||||
|
ClipLogger.Log("DismissLockAndContinue Done");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NavigateToPage(ContentPage page)
|
||||||
|
{
|
||||||
|
ClipLogger.Log($"NavigateToPage {page?.GetType().FullName}");
|
||||||
|
var navigationPage = new NavigationPage(page);
|
||||||
|
|
||||||
|
var window = new Window(navigationPage);
|
||||||
|
window.ToHandler(MauiContextSingleton.Instance.MauiContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -12,15 +12,12 @@ using Bit.Core.Enums;
|
|||||||
using Bit.Core.Services;
|
using Bit.Core.Services;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Bit.iOS.Core;
|
using Bit.iOS.Core;
|
||||||
using Bit.iOS.Core.Controllers;
|
|
||||||
using Bit.iOS.Core.Models;
|
using Bit.iOS.Core.Models;
|
||||||
using Bit.iOS.Core.Utilities;
|
using Bit.iOS.Core.Utilities;
|
||||||
using Bit.iOS.Core.Views;
|
using Bit.iOS.Core.Views;
|
||||||
using Bit.iOS.Extension.Models;
|
using Bit.iOS.Extension.Models;
|
||||||
using CoreNFC;
|
using CoreNFC;
|
||||||
using Foundation;
|
using Foundation;
|
||||||
using Microsoft.Maui.Controls;
|
|
||||||
using Microsoft.Maui.Platform;
|
|
||||||
using MobileCoreServices;
|
using MobileCoreServices;
|
||||||
using UIKit;
|
using UIKit;
|
||||||
|
|
||||||
@ -32,6 +29,8 @@ namespace Bit.iOS.Extension
|
|||||||
private NFCNdefReaderSession _nfcSession = null;
|
private NFCNdefReaderSession _nfcSession = null;
|
||||||
private Core.NFCReaderDelegate _nfcDelegate = null;
|
private Core.NFCReaderDelegate _nfcDelegate = null;
|
||||||
|
|
||||||
|
private bool _shouldInitialize = true;
|
||||||
|
|
||||||
public LoadingViewController(IntPtr handle)
|
public LoadingViewController(IntPtr handle)
|
||||||
: base(handle)
|
: base(handle)
|
||||||
{ }
|
{ }
|
||||||
@ -44,8 +43,14 @@ namespace Bit.iOS.Extension
|
|||||||
base.ViewDidLoad();
|
base.ViewDidLoad();
|
||||||
Logo.Image = new UIImage(ThemeHelpers.LightTheme ? "logo.png" : "logo_white.png");
|
Logo.Image = new UIImage(ThemeHelpers.LightTheme ? "logo.png" : "logo_white.png");
|
||||||
View.BackgroundColor = ThemeHelpers.SplashBackgroundColor;
|
View.BackgroundColor = ThemeHelpers.SplashBackgroundColor;
|
||||||
|
|
||||||
|
if (!_shouldInitialize)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_context.ExtContext = ExtensionContext;
|
_context.ExtContext = ExtensionContext;
|
||||||
foreach (var item in ExtensionContext.InputItems)
|
foreach (var item in _context.ExtContext.InputItems)
|
||||||
{
|
{
|
||||||
var processed = false;
|
var processed = false;
|
||||||
foreach (var itemProvider in item.Attachments)
|
foreach (var itemProvider in item.Attachments)
|
||||||
@ -77,6 +82,11 @@ namespace Bit.iOS.Extension
|
|||||||
|
|
||||||
public override async void ViewDidAppear(bool animated)
|
public override async void ViewDidAppear(bool animated)
|
||||||
{
|
{
|
||||||
|
if (!_shouldInitialize)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
base.ViewDidAppear(animated);
|
base.ViewDidAppear(animated);
|
||||||
@ -111,6 +121,7 @@ namespace Bit.iOS.Extension
|
|||||||
{
|
{
|
||||||
if (navController.TopViewController is LoginListViewController listLoginController)
|
if (navController.TopViewController is LoginListViewController listLoginController)
|
||||||
{
|
{
|
||||||
|
|
||||||
listLoginController.Context = _context;
|
listLoginController.Context = _context;
|
||||||
listLoginController.LoadingController = this;
|
listLoginController.LoadingController = this;
|
||||||
segue.DestinationViewController.PresentationController.Delegate =
|
segue.DestinationViewController.PresentationController.Delegate =
|
||||||
@ -140,12 +151,23 @@ namespace Bit.iOS.Extension
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !ENABLED_TAP_GESTURE_RECOGNIZER_MAUI_EMBEDDED_WORKAROUND
|
||||||
public void DismissLockAndContinue()
|
public void DismissLockAndContinue()
|
||||||
{
|
{
|
||||||
Debug.WriteLine("BW Log, Dismissing lock controller.");
|
Debug.WriteLine("BW Log, Dismissing lock controller.");
|
||||||
DismissViewController(false, () => ContinueOn());
|
DismissViewController(false, () => ContinueOn());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void NavigateToPage(ContentPage page)
|
||||||
|
{
|
||||||
|
var navigationPage = new NavigationPage(page);
|
||||||
|
var uiController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
|
||||||
|
uiController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
|
||||||
|
|
||||||
|
PresentViewController(uiController, true, null);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
private void ContinueOn()
|
private void ContinueOn()
|
||||||
{
|
{
|
||||||
Debug.WriteLine("BW Log, Segue to setup, login add or list.");
|
Debug.WriteLine("BW Log, Segue to setup, login add or list.");
|
||||||
@ -221,7 +243,7 @@ namespace Bit.iOS.Extension
|
|||||||
await eventService.CollectAsync(Bit.Core.Enums.EventType.Cipher_ClientAutofilled, id);
|
await eventService.CollectAsync(Bit.Core.Enums.EventType.Cipher_ClientAutofilled, id);
|
||||||
}
|
}
|
||||||
ServiceContainer.Reset();
|
ServiceContainer.Reset();
|
||||||
ExtensionContext?.CompleteRequest(returningItems, null);
|
_context?.ExtContext?.CompleteRequest(returningItems, null);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,6 +435,11 @@ namespace Bit.iOS.Extension
|
|||||||
|
|
||||||
private void InitApp()
|
private void InitApp()
|
||||||
{
|
{
|
||||||
|
if (!_shouldInitialize)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Change for iOSCoreHelpers.InitApp(...) when implementing IAccountsManager here
|
// TODO: Change for iOSCoreHelpers.InitApp(...) when implementing IAccountsManager here
|
||||||
iOSCoreHelpers.SetupMaui();
|
iOSCoreHelpers.SetupMaui();
|
||||||
|
|
||||||
@ -481,10 +508,7 @@ namespace Bit.iOS.Extension
|
|||||||
vm.CloseAction = () => CompleteRequest(null, null);
|
vm.CloseAction = () => CompleteRequest(null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
var navigationPage = new NavigationPage(homePage);
|
NavigateToPage(homePage);
|
||||||
var loginController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
|
|
||||||
loginController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
|
|
||||||
PresentViewController(loginController, true, null);
|
|
||||||
|
|
||||||
LogoutIfAuthed();
|
LogoutIfAuthed();
|
||||||
}
|
}
|
||||||
@ -501,10 +525,7 @@ namespace Bit.iOS.Extension
|
|||||||
vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage());
|
vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage());
|
||||||
}
|
}
|
||||||
|
|
||||||
var navigationPage = new NavigationPage(environmentPage);
|
NavigateToPage(environmentPage);
|
||||||
var loginController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
|
|
||||||
loginController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
|
|
||||||
PresentViewController(loginController, true, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LaunchRegisterFlow()
|
private void LaunchRegisterFlow()
|
||||||
@ -519,10 +540,7 @@ namespace Bit.iOS.Extension
|
|||||||
vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage());
|
vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage());
|
||||||
}
|
}
|
||||||
|
|
||||||
var navigationPage = new NavigationPage(registerPage);
|
NavigateToPage(registerPage);
|
||||||
var loginController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
|
|
||||||
loginController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
|
|
||||||
PresentViewController(loginController, true, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LaunchLoginFlow(string email = null)
|
private void LaunchLoginFlow(string email = null)
|
||||||
@ -542,10 +560,7 @@ namespace Bit.iOS.Extension
|
|||||||
vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage());
|
vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage());
|
||||||
}
|
}
|
||||||
|
|
||||||
var navigationPage = new NavigationPage(loginPage);
|
NavigateToPage(loginPage);
|
||||||
var loginController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
|
|
||||||
loginController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
|
|
||||||
PresentViewController(loginController, true, null);
|
|
||||||
|
|
||||||
LogoutIfAuthed();
|
LogoutIfAuthed();
|
||||||
}
|
}
|
||||||
@ -565,10 +580,7 @@ namespace Bit.iOS.Extension
|
|||||||
vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage());
|
vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage());
|
||||||
}
|
}
|
||||||
|
|
||||||
var navigationPage = new NavigationPage(loginWithDevicePage);
|
NavigateToPage(loginWithDevicePage);
|
||||||
var loginController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
|
|
||||||
loginController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
|
|
||||||
PresentViewController(loginController, true, null);
|
|
||||||
|
|
||||||
LogoutIfAuthed();
|
LogoutIfAuthed();
|
||||||
}
|
}
|
||||||
@ -589,10 +601,7 @@ namespace Bit.iOS.Extension
|
|||||||
vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage());
|
vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage());
|
||||||
}
|
}
|
||||||
|
|
||||||
var navigationPage = new NavigationPage(loginPage);
|
NavigateToPage(loginPage);
|
||||||
var loginController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
|
|
||||||
loginController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
|
|
||||||
PresentViewController(loginController, true, null);
|
|
||||||
|
|
||||||
LogoutIfAuthed();
|
LogoutIfAuthed();
|
||||||
}
|
}
|
||||||
@ -619,10 +628,7 @@ namespace Bit.iOS.Extension
|
|||||||
vm.UpdateTempPasswordAction = () => DismissViewController(false, () => LaunchUpdateTempPasswordFlow());
|
vm.UpdateTempPasswordAction = () => DismissViewController(false, () => LaunchUpdateTempPasswordFlow());
|
||||||
}
|
}
|
||||||
|
|
||||||
var navigationPage = new NavigationPage(twoFactorPage);
|
NavigateToPage(twoFactorPage);
|
||||||
var twoFactorController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
|
|
||||||
twoFactorController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
|
|
||||||
PresentViewController(twoFactorController, true, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LaunchSetPasswordFlow()
|
private void LaunchSetPasswordFlow()
|
||||||
@ -638,10 +644,7 @@ namespace Bit.iOS.Extension
|
|||||||
vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage());
|
vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage());
|
||||||
}
|
}
|
||||||
|
|
||||||
var navigationPage = new NavigationPage(setPasswordPage);
|
NavigateToPage(setPasswordPage);
|
||||||
var setPasswordController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
|
|
||||||
setPasswordController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
|
|
||||||
PresentViewController(setPasswordController, true, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LaunchUpdateTempPasswordFlow()
|
private void LaunchUpdateTempPasswordFlow()
|
||||||
@ -656,10 +659,7 @@ namespace Bit.iOS.Extension
|
|||||||
vm.LogOutAction = () => DismissViewController(false, () => LaunchHomePage());
|
vm.LogOutAction = () => DismissViewController(false, () => LaunchHomePage());
|
||||||
}
|
}
|
||||||
|
|
||||||
var navigationPage = new NavigationPage(updateTempPasswordPage);
|
NavigateToPage(updateTempPasswordPage);
|
||||||
var updateTempPasswordController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
|
|
||||||
updateTempPasswordController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
|
|
||||||
PresentViewController(updateTempPasswordController, true, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LaunchDeviceApprovalOptionsFlow()
|
private void LaunchDeviceApprovalOptionsFlow()
|
||||||
@ -675,10 +675,7 @@ namespace Bit.iOS.Extension
|
|||||||
vm.LogInWithDeviceAction = () => DismissViewController(false, () => LaunchLoginWithDevice(AuthRequestType.AuthenticateAndUnlock, vm.Email, true));
|
vm.LogInWithDeviceAction = () => DismissViewController(false, () => LaunchLoginWithDevice(AuthRequestType.AuthenticateAndUnlock, vm.Email, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
var navigationPage = new NavigationPage(loginApproveDevicePage);
|
NavigateToPage(loginApproveDevicePage);
|
||||||
var loginApproveDeviceController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
|
|
||||||
loginApproveDeviceController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
|
|
||||||
PresentViewController(loginApproveDeviceController, true, null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
<ApplicationVersion>1</ApplicationVersion>
|
<ApplicationVersion>1</ApplicationVersion>
|
||||||
|
|
||||||
<EnableDefaultCompileItems>False</EnableDefaultCompileItems>
|
<EnableDefaultCompileItems>False</EnableDefaultCompileItems>
|
||||||
|
|
||||||
|
<DefineConstants>$(DefineConstants);ENABLED_TAP_GESTURE_RECOGNIZER_MAUI_EMBEDDED_WORKAROUND</DefineConstants>
|
||||||
|
|
||||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">11.0</SupportedOSPlatformVersion>
|
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">11.0</SupportedOSPlatformVersion>
|
||||||
<RootNamespace>Bit.iOS.Extension</RootNamespace>
|
<RootNamespace>Bit.iOS.Extension</RootNamespace>
|
||||||
@ -70,6 +72,7 @@
|
|||||||
</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="LoadingViewController.TapGestureHack.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Core\Core.csproj" />
|
<ProjectReference Include="..\Core\Core.csproj" />
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
#if ENABLED_TAP_GESTURE_RECOGNIZER_MAUI_EMBEDDED_WORKAROUND
|
||||||
|
|
||||||
|
using Bit.iOS.Core.Utilities;
|
||||||
|
using Microsoft.Maui.Controls;
|
||||||
|
using Microsoft.Maui.Platform;
|
||||||
|
using UIKit;
|
||||||
|
|
||||||
|
namespace Bit.iOS.ShareExtension
|
||||||
|
{
|
||||||
|
public partial class LoadingViewController : UIViewController
|
||||||
|
{
|
||||||
|
private void NavigateToPage(ContentPage page)
|
||||||
|
{
|
||||||
|
var navigationPage = new NavigationPage(page);
|
||||||
|
|
||||||
|
var window = new Window(navigationPage);
|
||||||
|
window.ToHandler(MauiContextSingleton.Instance.MauiContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -137,6 +137,23 @@ namespace Bit.iOS.ShareExtension
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !ENABLED_TAP_GESTURE_RECOGNIZER_MAUI_EMBEDDED_WORKAROUND
|
||||||
|
|
||||||
|
private void NavigateToPage(ContentPage page)
|
||||||
|
{
|
||||||
|
var navigationPage = new NavigationPage(page);
|
||||||
|
|
||||||
|
var window = new Window(navigationPage);
|
||||||
|
window.ToHandler(MauiContextSingleton.Instance.MauiContext);
|
||||||
|
|
||||||
|
_currentModalController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
|
||||||
|
_currentModalController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
|
||||||
|
_presentingOnNavigationPage = true;
|
||||||
|
PresentViewController(_currentModalController, true, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
public void DismissLockAndContinue()
|
public void DismissLockAndContinue()
|
||||||
{
|
{
|
||||||
Debug.WriteLine("BW Log, Dismissing lock controller.");
|
Debug.WriteLine("BW Log, Dismissing lock controller.");
|
||||||
@ -197,19 +214,6 @@ namespace Bit.iOS.ShareExtension
|
|||||||
NavigateToPage(sendPage);
|
NavigateToPage(sendPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void NavigateToPage(ContentPage page)
|
|
||||||
{
|
|
||||||
var navigationPage = new NavigationPage(page);
|
|
||||||
|
|
||||||
var window = new Window(navigationPage);
|
|
||||||
window.ToHandler(MauiContextSingleton.Instance.MauiContext);
|
|
||||||
|
|
||||||
_currentModalController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
|
|
||||||
_currentModalController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
|
|
||||||
_presentingOnNavigationPage = true;
|
|
||||||
PresentViewController(_currentModalController, true, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<(string, byte[])> LoadDataBytesAsync()
|
private async Task<(string, byte[])> LoadDataBytesAsync()
|
||||||
{
|
{
|
||||||
var itemProvider = ExtensionContext?.InputItems.FirstOrDefault()?.Attachments?.FirstOrDefault();
|
var itemProvider = ExtensionContext?.InputItems.FirstOrDefault()?.Attachments?.FirstOrDefault();
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
<ApplicationVersion>1</ApplicationVersion>
|
<ApplicationVersion>1</ApplicationVersion>
|
||||||
|
|
||||||
<EnableDefaultCompileItems>False</EnableDefaultCompileItems>
|
<EnableDefaultCompileItems>False</EnableDefaultCompileItems>
|
||||||
|
|
||||||
|
<DefineConstants>$(DefineConstants);ENABLED_TAP_GESTURE_RECOGNIZER_MAUI_EMBEDDED_WORKAROUND</DefineConstants>
|
||||||
|
|
||||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">11.0</SupportedOSPlatformVersion>
|
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">11.0</SupportedOSPlatformVersion>
|
||||||
<RootNamespace>Bit.iOS.ShareExtension</RootNamespace>
|
<RootNamespace>Bit.iOS.ShareExtension</RootNamespace>
|
||||||
@ -62,6 +64,7 @@
|
|||||||
<Compile Include="ExtensionNavigationController.designer.cs">
|
<Compile Include="ExtensionNavigationController.designer.cs">
|
||||||
<DependentUpon>ExtensionNavigationController.cs</DependentUpon>
|
<DependentUpon>ExtensionNavigationController.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="LoadingViewController.TapGestureHack.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<BundleResource Include="..\iOS\Resources\logo_white%403x.png">
|
<BundleResource Include="..\iOS\Resources\logo_white%403x.png">
|
||||||
|
Loading…
Reference in New Issue
Block a user