diff --git a/src/App/App.csproj b/src/App/App.csproj
index 701e66807..2c0c961a5 100644
--- a/src/App/App.csproj
+++ b/src/App/App.csproj
@@ -51,6 +51,12 @@
GeneratorHistoryPage.xaml
+
+ AutofillPage.xaml
+
+
+ ExtensionPage.xaml
+
AutofillServicePage.xaml
diff --git a/src/App/Pages/Settings/AutofillPage.xaml b/src/App/Pages/Settings/AutofillPage.xaml
new file mode 100644
index 000000000..cb54cd74f
--- /dev/null
+++ b/src/App/Pages/Settings/AutofillPage.xaml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/App/Pages/Settings/AutofillPage.xaml.cs b/src/App/Pages/Settings/AutofillPage.xaml.cs
new file mode 100644
index 000000000..b3c7efb59
--- /dev/null
+++ b/src/App/Pages/Settings/AutofillPage.xaml.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace Bit.App.Pages
+{
+ public partial class AutofillPage : BaseContentPage
+ {
+ public AutofillPage()
+ {
+ InitializeComponent();
+ }
+
+ private void Close_Clicked(object sender, EventArgs e)
+ {
+ if(DoOnce())
+ {
+ Navigation.PopModalAsync();
+ }
+ }
+ }
+}
diff --git a/src/App/Pages/Settings/ExtensionPage.xaml b/src/App/Pages/Settings/ExtensionPage.xaml
new file mode 100644
index 000000000..4583e47b4
--- /dev/null
+++ b/src/App/Pages/Settings/ExtensionPage.xaml
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/App/Pages/Settings/ExtensionPage.xaml.cs b/src/App/Pages/Settings/ExtensionPage.xaml.cs
new file mode 100644
index 000000000..fd5e1ca8e
--- /dev/null
+++ b/src/App/Pages/Settings/ExtensionPage.xaml.cs
@@ -0,0 +1,46 @@
+using System;
+
+namespace Bit.App.Pages
+{
+ public partial class ExtensionPage : BaseContentPage
+ {
+ private readonly ExtensionPageViewModel _vm;
+
+ public ExtensionPage()
+ {
+ InitializeComponent();
+ _vm = BindingContext as ExtensionPageViewModel;
+ _vm.Page = this;
+ }
+
+ protected async override void OnAppearing()
+ {
+ base.OnAppearing();
+ await _vm.InitAsync();
+ }
+
+ private void SeeApps_Clicked(object sender, EventArgs e)
+ {
+ if(DoOnce())
+ {
+ _vm.SeeApps();
+ }
+ }
+
+ private void Show_Clicked(object sender, EventArgs e)
+ {
+ if(DoOnce())
+ {
+ _vm.ShowExtension();
+ }
+ }
+
+ private void Close_Clicked(object sender, EventArgs e)
+ {
+ if(DoOnce())
+ {
+ Navigation.PopModalAsync();
+ }
+ }
+ }
+}
diff --git a/src/App/Pages/Settings/ExtensionPageViewModel.cs b/src/App/Pages/Settings/ExtensionPageViewModel.cs
new file mode 100644
index 000000000..adc48d23e
--- /dev/null
+++ b/src/App/Pages/Settings/ExtensionPageViewModel.cs
@@ -0,0 +1,80 @@
+using Bit.App.Resources;
+using Bit.Core.Abstractions;
+using Bit.Core.Utilities;
+using System.Threading.Tasks;
+
+namespace Bit.App.Pages
+{
+ public class ExtensionPageViewModel : BaseViewModel
+ {
+ private const string StartedKey = "appExtensionStarted";
+ private const string ActivatedKey = "appExtensionActivated";
+
+ private readonly IMessagingService _messagingService;
+ private readonly IStorageService _storageService;
+ private readonly IPlatformUtilsService _platformUtilsService;
+
+ private bool _started;
+ private bool _activated;
+
+ public ExtensionPageViewModel()
+ {
+ _messagingService = ServiceContainer.Resolve("messagingService");
+ _storageService = ServiceContainer.Resolve("storageService");
+ _platformUtilsService = ServiceContainer.Resolve("platformUtilsService");
+ PageTitle = AppResources.AppExtension;
+ }
+
+ public bool Started
+ {
+ get => _started;
+ set => SetProperty(ref _started, value, additionalPropertyNames: new string[]
+ {
+ nameof(NotStarted),
+ nameof(StartedAndNotActivated),
+ nameof(StartedAndActivated)
+ });
+ }
+
+ public bool Activated
+ {
+ get => _activated;
+ set => SetProperty(ref _activated, value, additionalPropertyNames: new string[]
+ {
+ nameof(StartedAndNotActivated),
+ nameof(StartedAndActivated)
+ });
+ }
+
+ public bool NotStarted => !Started;
+ public bool StartedAndNotActivated => Started && !Activated;
+ public bool StartedAndActivated => Started && Activated;
+
+ public async Task InitAsync()
+ {
+ var started = await _storageService.GetAsync(StartedKey);
+ var activated = await _storageService.GetAsync(ActivatedKey);
+ Started = started.GetValueOrDefault();
+ Activated = activated.GetValueOrDefault();
+ }
+
+ public void SeeApps()
+ {
+ _platformUtilsService.LaunchUri("https://bitwarden.com/ios/");
+ }
+
+ public void ShowExtension()
+ {
+ _messagingService.Send("showAppExtension", this);
+ }
+
+ public void EnabledExtension(bool enabled)
+ {
+ Started = true;
+ if(!Activated && enabled)
+ {
+ Activated = enabled;
+ }
+ }
+ }
+}
diff --git a/src/App/Pages/Settings/SettingsPage/SettingsPage.xaml.cs b/src/App/Pages/Settings/SettingsPage/SettingsPage.xaml.cs
index f9a2236b3..59a2cb5dd 100644
--- a/src/App/Pages/Settings/SettingsPage/SettingsPage.xaml.cs
+++ b/src/App/Pages/Settings/SettingsPage/SettingsPage.xaml.cs
@@ -67,11 +67,11 @@ namespace Bit.App.Pages
}
else if(item.Name == AppResources.PasswordAutofill)
{
- // await Navigation.PushModalAsync(new NavigationPage(new OptionsPage()));
+ await Navigation.PushModalAsync(new NavigationPage(new AutofillPage()));
}
else if(item.Name == AppResources.AppExtension)
{
- // await Navigation.PushModalAsync(new NavigationPage(new OptionsPage()));
+ await Navigation.PushModalAsync(new NavigationPage(new ExtensionPage()));
}
else if(item.Name == AppResources.Options)
{
diff --git a/src/iOS.Extension/SetupViewController.cs b/src/iOS.Extension/SetupViewController.cs
index 3fd70a8e9..9eee2c2f9 100644
--- a/src/iOS.Extension/SetupViewController.cs
+++ b/src/iOS.Extension/SetupViewController.cs
@@ -18,6 +18,7 @@ namespace Bit.iOS.Extension
public override void ViewDidLoad()
{
+ base.ViewDidLoad();
var descriptor = UIFontDescriptor.PreferredBody;
DescriptionLabel.Text = $@"{AppResources.ExtensionSetup}
@@ -31,7 +32,6 @@ namespace Bit.iOS.Extension
BackButton.TintColor = ThemeHelpers.NavBarTextColor;
BackButton.Title = AppResources.Back;
- base.ViewDidLoad();
}
partial void BackButton_Activated(UIBarButtonItem sender)
diff --git a/src/iOS/AppDelegate.cs b/src/iOS/AppDelegate.cs
index 4c2938c15..5129ff404 100644
--- a/src/iOS/AppDelegate.cs
+++ b/src/iOS/AppDelegate.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Threading.Tasks;
using AuthenticationServices;
using Bit.App.Abstractions;
+using Bit.App.Pages;
using Bit.App.Resources;
using Bit.App.Services;
using Bit.App.Utilities;
@@ -79,7 +80,7 @@ namespace Bit.iOS
}
else if(message.Command == "showAppExtension")
{
-
+ Device.BeginInvokeOnMainThread(() => ShowAppExtension((ExtensionPageViewModel)message.Data));
}
else if(message.Command == "showStatusBar")
{
@@ -389,18 +390,20 @@ namespace Bit.iOS
});
}
- private void ShowAppExtension()
+ private void ShowAppExtension(ExtensionPageViewModel extensionPageViewModel)
{
var itemProvider = new NSItemProvider(new NSDictionary(), Core.Constants.UTTypeAppExtensionSetup);
var extensionItem = new NSExtensionItem
{
Attachments = new NSItemProvider[] { itemProvider }
};
- var activityViewController = new UIActivityViewController(new NSExtensionItem[] { extensionItem }, null);
- activityViewController.CompletionHandler = (activityType, completed) =>
+ var activityViewController = new UIActivityViewController(new NSExtensionItem[] { extensionItem }, null)
{
- // TODO
- //page.EnabledExtension(completed && activityType == "com.8bit.bitwarden.find-login-action-extension");
+ CompletionHandler = (activityType, completed) =>
+ {
+ extensionPageViewModel.EnabledExtension(
+ completed && activityType == "com.8bit.bitwarden.find-login-action-extension");
+ }
};
var modal = UIApplication.SharedApplication.KeyWindow.RootViewController.ModalViewController;
if(activityViewController.PopoverPresentationController != null)