diff --git a/src/App/App.csproj b/src/App/App.csproj
index 3683ae922..bb33b6b15 100644
--- a/src/App/App.csproj
+++ b/src/App/App.csproj
@@ -57,6 +57,9 @@
AttachmentsPage.xaml
+
+ AutofillCiphersPage.xaml
+
CollectionsPage.xaml
diff --git a/src/App/App.xaml.cs b/src/App/App.xaml.cs
index cb12d7adb..3184a024e 100644
--- a/src/App/App.xaml.cs
+++ b/src/App/App.xaml.cs
@@ -180,6 +180,10 @@ namespace Bit.App
{
Current.MainPage = new NavigationPage(new AddEditPage(appOptions: _appOptions));
}
+ else if(_appOptions.Uri != null)
+ {
+ Current.MainPage = new NavigationPage(new AutofillCiphersPage(_appOptions));
+ }
else
{
Current.MainPage = new TabsPage();
diff --git a/src/App/Pages/Vault/AutofillCiphersPage.xaml b/src/App/Pages/Vault/AutofillCiphersPage.xaml
new file mode 100644
index 000000000..d195664da
--- /dev/null
+++ b/src/App/Pages/Vault/AutofillCiphersPage.xaml
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ RecycleElement
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/App/Pages/Vault/AutofillCiphersPage.xaml.cs b/src/App/Pages/Vault/AutofillCiphersPage.xaml.cs
new file mode 100644
index 000000000..9f9b2bbb7
--- /dev/null
+++ b/src/App/Pages/Vault/AutofillCiphersPage.xaml.cs
@@ -0,0 +1,53 @@
+using Bit.App.Models;
+using Xamarin.Forms;
+
+namespace Bit.App.Pages
+{
+ public partial class AutofillCiphersPage : BaseContentPage
+ {
+ private AutofillCiphersPageViewModel _vm;
+ private readonly AppOptions _appOptions;
+
+ public AutofillCiphersPage(AppOptions appOptions)
+ {
+ _appOptions = appOptions;
+ InitializeComponent();
+ _vm = BindingContext as AutofillCiphersPageViewModel;
+ _vm.Page = this;
+ _vm.Init(appOptions);
+ }
+
+ protected async override void OnAppearing()
+ {
+ base.OnAppearing();
+ await LoadOnAppearedAsync(_mainLayout, false, async () =>
+ {
+ await _vm.LoadAsync();
+ }, _mainContent);
+ }
+
+ private async void RowSelected(object sender, SelectedItemChangedEventArgs e)
+ {
+ ((ListView)sender).SelectedItem = null;
+ if(!DoOnce())
+ {
+ return;
+ }
+
+ if(e.SelectedItem is GroupingsPageListItem item && item.Cipher != null)
+ {
+ // TODO
+ }
+ }
+
+ private void AddButton_Clicked(object sender, System.EventArgs e)
+ {
+
+ }
+
+ private void Search_Clicked(object sender, System.EventArgs e)
+ {
+
+ }
+ }
+}
diff --git a/src/App/Pages/Vault/AutofillCiphersPageViewModel.cs b/src/App/Pages/Vault/AutofillCiphersPageViewModel.cs
new file mode 100644
index 000000000..9fad79d8e
--- /dev/null
+++ b/src/App/Pages/Vault/AutofillCiphersPageViewModel.cs
@@ -0,0 +1,105 @@
+using Bit.App.Models;
+using Bit.App.Resources;
+using Bit.Core;
+using Bit.Core.Abstractions;
+using Bit.Core.Models.View;
+using Bit.Core.Utilities;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Xamarin.Forms;
+
+namespace Bit.App.Pages
+{
+ public class AutofillCiphersPageViewModel : BaseViewModel
+ {
+ private readonly IPlatformUtilsService _platformUtilsService;
+ private readonly ICipherService _cipherService;
+ private readonly ISearchService _searchService;
+ private CancellationTokenSource _searchCancellationTokenSource;
+
+ private AppOptions _appOptions;
+ private string _name;
+ private string _uri;
+ private bool _showNoData;
+ private bool _showList;
+
+ public AutofillCiphersPageViewModel()
+ {
+ _platformUtilsService = ServiceContainer.Resolve("platformUtilsService");
+ _cipherService = ServiceContainer.Resolve("cipherService");
+ _searchService = ServiceContainer.Resolve("searchService");
+
+ GroupedItems = new ExtendedObservableCollection();
+ CipherOptionsCommand = new Command(CipherOptionsAsync);
+ }
+
+ public Command CipherOptionsCommand { get; set; }
+ public ExtendedObservableCollection GroupedItems { get; set; }
+
+ public bool ShowNoData
+ {
+ get => _showNoData;
+ set => SetProperty(ref _showNoData, value);
+ }
+
+ public bool ShowList
+ {
+ get => _showList;
+ set => SetProperty(ref _showList, value);
+ }
+
+ public void Init(AppOptions appOptions)
+ {
+ _appOptions = appOptions;
+ _uri = appOptions.Uri;
+ if(_uri.StartsWith(Constants.AndroidAppProtocol))
+ {
+ _name = _uri.Substring(Constants.AndroidAppProtocol.Length);
+ }
+ else if(!Uri.TryCreate(_uri, UriKind.Absolute, out Uri uri) ||
+ !DomainName.TryParseBaseDomain(uri.Host, out _name))
+ {
+ _name = "--";
+ }
+ PageTitle = string.Format(AppResources.ItemsForUri, _name ?? "--");
+ }
+
+ public async Task LoadAsync()
+ {
+ ShowNoData = false;
+ ShowList = false;
+
+ var ciphers = await _cipherService.GetAllDecryptedByUrlAsync(_uri, null);
+ var matching = ciphers.Item1?.Select(c => new GroupingsPageListItem { Cipher = c }).ToList();
+ var matchingGroup = new GroupingsPageListGroup(matching, AppResources.MatchingItems, matching.Count, false);
+ var fuzzy = ciphers.Item2?.Select(c => new GroupingsPageListItem { Cipher = c }).ToList();
+ var fuzzyGroup = new GroupingsPageListGroup(fuzzy, AppResources.PossibleMatchingItems, fuzzy.Count, false);
+ GroupedItems.ResetWithRange(new List { matchingGroup, fuzzyGroup });
+
+ ShowNoData = !matching.Any() && !fuzzy.Any();
+ ShowList = !ShowNoData;
+ }
+
+ public async Task SelectCipherAsync(CipherView cipher)
+ {
+ // TODO
+ }
+
+ private async void CipherOptionsAsync(CipherView cipher)
+ {
+ if(!(Page as BaseContentPage).DoOnce())
+ {
+ return;
+ }
+ var option = await Page.DisplayActionSheet(cipher.Name, AppResources.Cancel, null, "1", "2");
+ if(option == AppResources.Cancel)
+ {
+ return;
+ }
+ // TODO: process options
+ }
+ }
+}
diff --git a/src/App/Pages/Vault/GroupingsPage/GroupingsPage.xaml b/src/App/Pages/Vault/GroupingsPage/GroupingsPage.xaml
index 79bd4d400..202ff8cf5 100644
--- a/src/App/Pages/Vault/GroupingsPage/GroupingsPage.xaml
+++ b/src/App/Pages/Vault/GroupingsPage/GroupingsPage.xaml
@@ -64,7 +64,7 @@
HorizontalTextAlignment="Center">
diff --git a/src/App/Pages/Vault/GroupingsPage/GroupingsPageViewModel.cs b/src/App/Pages/Vault/GroupingsPage/GroupingsPageViewModel.cs
index 72774d208..9eb810017 100644
--- a/src/App/Pages/Vault/GroupingsPage/GroupingsPageViewModel.cs
+++ b/src/App/Pages/Vault/GroupingsPage/GroupingsPageViewModel.cs
@@ -46,7 +46,6 @@ namespace Bit.App.Pages
Refreshing = true;
await LoadAsync();
});
- AddCipherCommand = new Command(() => { /* TODO */ });
CipherOptionsCommand = new Command(CipherOptionsAsync);
}
@@ -104,7 +103,6 @@ namespace Bit.App.Pages
}
public ExtendedObservableCollection GroupedItems { get; set; }
public Command RefreshCommand { get; set; }
- public Command AddCipherCommand { get; set; }
public Command CipherOptionsCommand { get; set; }
public async Task LoadAsync()