diff --git a/src/iOS.Autofill/LoginListViewController.cs b/src/iOS.Autofill/LoginListViewController.cs
index 2935bc5dd..01456e672 100644
--- a/src/iOS.Autofill/LoginListViewController.cs
+++ b/src/iOS.Autofill/LoginListViewController.cs
@@ -1,12 +1,11 @@
using System;
-using System.Linq;
using Bit.iOS.Autofill.Models;
using Foundation;
using UIKit;
-using Bit.iOS.Core.Utilities;
using Bit.iOS.Core.Controllers;
using Bit.App.Resources;
using Bit.iOS.Core.Views;
+using Bit.iOS.Autofill.Utilities;
namespace Bit.iOS.Autofill
{
@@ -87,7 +86,7 @@ namespace Bit.iOS.Autofill
private LoginListViewController _controller;
public TableSource(LoginListViewController controller)
- :base(controller.Context, controller)
+ : base(controller.Context, controller)
{
_context = controller.Context;
_controller = controller;
@@ -95,77 +94,8 @@ namespace Bit.iOS.Autofill
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
- tableView.DeselectRow(indexPath, true);
- tableView.EndEditing(true);
-
- if(_tableItems == null || _tableItems.Count() == 0)
- {
- _controller.PerformSegue("loginAddSegue", this);
- return;
- }
-
- var item = _tableItems.ElementAt(indexPath.Row);
- if(item == null)
- {
- _controller.CPViewController.CompleteRequest(null, null, null);
- return;
- }
-
- if(!string.IsNullOrWhiteSpace(item.Password))
- {
- string totp = null;
- if(!_settings.GetValueOrDefault(App.Constants.SettingDisableTotpCopy, false))
- {
- totp = GetTotp(item);
- }
-
- _controller.CPViewController.CompleteRequest(item.Username, item.Password, totp);
- }
- else if(!string.IsNullOrWhiteSpace(item.Username) || !string.IsNullOrWhiteSpace(item.Totp.Value))
- {
- var sheet = Dialogs.CreateActionSheet(item.Name, _controller);
- if(!string.IsNullOrWhiteSpace(item.Username))
- {
- sheet.AddAction(UIAlertAction.Create(AppResources.CopyUsername, UIAlertActionStyle.Default, a =>
- {
- UIPasteboard clipboard = UIPasteboard.General;
- clipboard.String = item.Username;
- var alert = Dialogs.CreateMessageAlert(AppResources.CopyUsername);
- _controller.PresentViewController(alert, true, () =>
- {
- _controller.DismissViewController(true, null);
- });
- }));
- }
-
- if(!string.IsNullOrWhiteSpace(item.Totp.Value))
- {
- sheet.AddAction(UIAlertAction.Create(AppResources.CopyTotp, UIAlertActionStyle.Default, a =>
- {
- var totp = GetTotp(item);
- if(string.IsNullOrWhiteSpace(totp))
- {
- return;
- }
-
- UIPasteboard clipboard = UIPasteboard.General;
- clipboard.String = totp;
- var alert = Dialogs.CreateMessageAlert(AppResources.CopiedTotp);
- _controller.PresentViewController(alert, true, () =>
- {
- _controller.DismissViewController(true, null);
- });
- }));
- }
-
- sheet.AddAction(UIAlertAction.Create(AppResources.Cancel, UIAlertActionStyle.Cancel, null));
- _controller.PresentViewController(sheet, true, null);
- }
- else
- {
- var alert = Dialogs.CreateAlert(null, AppResources.NoUsernamePasswordConfigured, AppResources.Ok);
- _controller.PresentViewController(alert, true, null);
- }
+ AutofillHelpers.TableRowSelected(tableView, indexPath, this,
+ _controller.CPViewController, _controller, _settings, "loginAddSegue");
}
}
}
diff --git a/src/iOS.Autofill/LoginSearchViewController.cs b/src/iOS.Autofill/LoginSearchViewController.cs
index 8bcc35a09..59ec6506d 100644
--- a/src/iOS.Autofill/LoginSearchViewController.cs
+++ b/src/iOS.Autofill/LoginSearchViewController.cs
@@ -1,14 +1,11 @@
using System;
-using System.Linq;
using Bit.iOS.Autofill.Models;
using Foundation;
using UIKit;
-using Bit.iOS.Core.Utilities;
using Bit.iOS.Core.Controllers;
using Bit.App.Resources;
using Bit.iOS.Core.Views;
-using System.Threading;
-using System.Threading.Tasks;
+using Bit.iOS.Autofill.Utilities;
namespace Bit.iOS.Autofill
{
@@ -36,7 +33,7 @@ namespace Bit.iOS.Autofill
TableView.RowHeight = UITableView.AutomaticDimension;
TableView.EstimatedRowHeight = 44;
TableView.Source = new TableSource(this);
- SearchBar.Delegate = new SearchDelegate(this);
+ SearchBar.Delegate = new ExtensionSearchDelegate(TableView);
await ((TableSource)TableView.Source).LoadItemsAsync(false, SearchBar.Text);
}
@@ -87,118 +84,8 @@ namespace Bit.iOS.Autofill
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
- tableView.DeselectRow(indexPath, true);
- tableView.EndEditing(true);
-
- if(_tableItems == null || _tableItems.Count() == 0)
- {
- _controller.PerformSegue("loginAddFromSearchSegue", this);
- return;
- }
-
- var item = _tableItems.ElementAt(indexPath.Row);
- if(item == null)
- {
- _controller.CPViewController.CompleteRequest(null, null, null);
- return;
- }
-
- if(!string.IsNullOrWhiteSpace(item.Password))
- {
- string totp = null;
- if(!_settings.GetValueOrDefault(App.Constants.SettingDisableTotpCopy, false))
- {
- totp = GetTotp(item);
- }
-
- _controller.CPViewController.CompleteRequest(item.Username, item.Password, totp);
- }
- else if(!string.IsNullOrWhiteSpace(item.Username) || !string.IsNullOrWhiteSpace(item.Totp.Value))
- {
- var sheet = Dialogs.CreateActionSheet(item.Name, _controller);
- if(!string.IsNullOrWhiteSpace(item.Username))
- {
- sheet.AddAction(UIAlertAction.Create(AppResources.CopyUsername, UIAlertActionStyle.Default, a =>
- {
- UIPasteboard clipboard = UIPasteboard.General;
- clipboard.String = item.Username;
- var alert = Dialogs.CreateMessageAlert(AppResources.CopyUsername);
- _controller.PresentViewController(alert, true, () =>
- {
- _controller.DismissViewController(true, null);
- });
- }));
- }
-
- if(!string.IsNullOrWhiteSpace(item.Totp.Value))
- {
- sheet.AddAction(UIAlertAction.Create(AppResources.CopyTotp, UIAlertActionStyle.Default, a =>
- {
- var totp = GetTotp(item);
- if(string.IsNullOrWhiteSpace(totp))
- {
- return;
- }
-
- UIPasteboard clipboard = UIPasteboard.General;
- clipboard.String = totp;
- var alert = Dialogs.CreateMessageAlert(AppResources.CopiedTotp);
- _controller.PresentViewController(alert, true, () =>
- {
- _controller.DismissViewController(true, null);
- });
- }));
- }
-
- sheet.AddAction(UIAlertAction.Create(AppResources.Cancel, UIAlertActionStyle.Cancel, null));
- _controller.PresentViewController(sheet, true, null);
- }
- else
- {
- var alert = Dialogs.CreateAlert(null, AppResources.NoUsernamePasswordConfigured, AppResources.Ok);
- _controller.PresentViewController(alert, true, null);
- }
- }
- }
-
- public class SearchDelegate : UISearchBarDelegate
- {
- private readonly LoginSearchViewController _controller;
- private CancellationTokenSource _filterResultsCancellationTokenSource;
-
- public SearchDelegate(LoginSearchViewController controller)
- {
- _controller = controller;
- }
-
- public override void TextChanged(UISearchBar searchBar, string searchText)
- {
- var cts = new CancellationTokenSource();
- Task.Run(() =>
- {
- NSRunLoop.Main.BeginInvokeOnMainThread(async () =>
- {
- if (!string.IsNullOrWhiteSpace(searchText))
- {
- await Task.Delay(300);
- if (searchText != searchBar.Text)
- {
- return;
- }
- else
- {
- _filterResultsCancellationTokenSource?.Cancel();
- }
- }
- try
- {
- ((TableSource)_controller.TableView.Source).FilterResults(searchText, cts.Token);
- _controller.TableView.ReloadData();
- }
- catch (OperationCanceledException) { }
- _filterResultsCancellationTokenSource = cts;
- });
- }, cts.Token);
+ AutofillHelpers.TableRowSelected(tableView, indexPath, this,
+ _controller.CPViewController, _controller, _settings, "loginAddFromSearchSegue");
}
}
}
diff --git a/src/iOS.Autofill/Utilities/AutofillHelpers.cs b/src/iOS.Autofill/Utilities/AutofillHelpers.cs
new file mode 100644
index 000000000..a56964841
--- /dev/null
+++ b/src/iOS.Autofill/Utilities/AutofillHelpers.cs
@@ -0,0 +1,91 @@
+using System;
+using System.Linq;
+using Bit.App.Resources;
+using Bit.iOS.Core.Utilities;
+using Bit.iOS.Core.Views;
+using Foundation;
+using Plugin.Settings.Abstractions;
+using UIKit;
+
+namespace Bit.iOS.Autofill.Utilities
+{
+ public static class AutofillHelpers
+ {
+ public static void TableRowSelected(UITableView tableView, NSIndexPath indexPath,
+ ExtensionTableSource tableSource, CredentialProviderViewController cpViewController,
+ UITableViewController controller, ISettings settings, string loginAddSegue)
+ {
+ tableView.DeselectRow(indexPath, true);
+ tableView.EndEditing(true);
+
+ if(tableSource.Items == null || tableSource.Items.Count() == 0)
+ {
+ controller.PerformSegue(loginAddSegue, tableSource);
+ return;
+ }
+
+ var item = tableSource.Items.ElementAt(indexPath.Row);
+ if(item == null)
+ {
+ cpViewController.CompleteRequest(null);
+ return;
+ }
+
+ if(!string.IsNullOrWhiteSpace(item.Password))
+ {
+ string totp = null;
+ if(!settings.GetValueOrDefault(App.Constants.SettingDisableTotpCopy, false))
+ {
+ totp = tableSource.GetTotp(item);
+ }
+
+ cpViewController.CompleteRequest(item.Username, item.Password, totp);
+ }
+ else if(!string.IsNullOrWhiteSpace(item.Username) || !string.IsNullOrWhiteSpace(item.Totp.Value))
+ {
+ var sheet = Dialogs.CreateActionSheet(item.Name, controller);
+ if(!string.IsNullOrWhiteSpace(item.Username))
+ {
+ sheet.AddAction(UIAlertAction.Create(AppResources.CopyUsername, UIAlertActionStyle.Default, a =>
+ {
+ UIPasteboard clipboard = UIPasteboard.General;
+ clipboard.String = item.Username;
+ var alert = Dialogs.CreateMessageAlert(AppResources.CopyUsername);
+ controller.PresentViewController(alert, true, () =>
+ {
+ controller.DismissViewController(true, null);
+ });
+ }));
+ }
+
+ if(!string.IsNullOrWhiteSpace(item.Totp.Value))
+ {
+ sheet.AddAction(UIAlertAction.Create(AppResources.CopyTotp, UIAlertActionStyle.Default, a =>
+ {
+ var totp = tableSource.GetTotp(item);
+ if(string.IsNullOrWhiteSpace(totp))
+ {
+ return;
+ }
+
+ UIPasteboard clipboard = UIPasteboard.General;
+ clipboard.String = totp;
+ var alert = Dialogs.CreateMessageAlert(AppResources.CopiedTotp);
+ controller.PresentViewController(alert, true, () =>
+ {
+ controller.DismissViewController(true, null);
+ });
+ }));
+ }
+
+ sheet.AddAction(UIAlertAction.Create(AppResources.Cancel, UIAlertActionStyle.Cancel, null));
+ controller.PresentViewController(sheet, true, null);
+ }
+ else
+ {
+ var alert = Dialogs.CreateAlert(null, AppResources.NoUsernamePasswordConfigured, AppResources.Ok);
+ controller.PresentViewController(alert, true, null);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/iOS.Autofill/iOS.Autofill.csproj b/src/iOS.Autofill/iOS.Autofill.csproj
index e508cc3f6..701d7b25b 100644
--- a/src/iOS.Autofill/iOS.Autofill.csproj
+++ b/src/iOS.Autofill/iOS.Autofill.csproj
@@ -213,6 +213,7 @@
SetupViewController.cs
+
@@ -299,5 +300,6 @@
+
\ No newline at end of file
diff --git a/src/iOS.Core/Views/ExtensionSearchDelegate.cs b/src/iOS.Core/Views/ExtensionSearchDelegate.cs
new file mode 100644
index 000000000..317d55138
--- /dev/null
+++ b/src/iOS.Core/Views/ExtensionSearchDelegate.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Foundation;
+using UIKit;
+
+namespace Bit.iOS.Core.Views
+{
+ public class ExtensionSearchDelegate : UISearchBarDelegate
+ {
+ private readonly UITableView _tableView;
+ private CancellationTokenSource _filterResultsCancellationTokenSource;
+
+ public ExtensionSearchDelegate(UITableView tableView)
+ {
+ _tableView = tableView;
+ }
+
+ public override void TextChanged(UISearchBar searchBar, string searchText)
+ {
+ var cts = new CancellationTokenSource();
+ Task.Run(() =>
+ {
+ NSRunLoop.Main.BeginInvokeOnMainThread(async () =>
+ {
+ if(!string.IsNullOrWhiteSpace(searchText))
+ {
+ await Task.Delay(300);
+ if(searchText != searchBar.Text)
+ {
+ return;
+ }
+ else
+ {
+ _filterResultsCancellationTokenSource?.Cancel();
+ }
+ }
+ try
+ {
+ ((ExtensionTableSource)_tableView.Source).FilterResults(searchText, cts.Token);
+ _tableView.ReloadData();
+ }
+ catch(OperationCanceledException) { }
+ _filterResultsCancellationTokenSource = cts;
+ });
+ }, cts.Token);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/iOS.Core/Views/ExtensionTableSource.cs b/src/iOS.Core/Views/ExtensionTableSource.cs
index 5eeca6abf..d9102d664 100644
--- a/src/iOS.Core/Views/ExtensionTableSource.cs
+++ b/src/iOS.Core/Views/ExtensionTableSource.cs
@@ -21,7 +21,6 @@ namespace Bit.iOS.Core.Views
private const string CellIdentifier = "TableCell";
private IEnumerable _allItems = new List();
- protected IEnumerable _tableItems = new List();
protected ICipherService _cipherService;
protected ISettings _settings;
private bool _accessPremium;
@@ -37,6 +36,8 @@ namespace Bit.iOS.Core.Views
_controller = controller;
}
+ public IEnumerable Items { get; private set; }
+
public async Task LoadItemsAsync(bool urlFilter = true, string searchFilter = null)
{
var combinedLogins = new List();
@@ -74,12 +75,12 @@ namespace Bit.iOS.Core.Views
if(string.IsNullOrWhiteSpace(searchFilter))
{
- _tableItems = _allItems.ToList();
+ Items = _allItems.ToList();
}
else
{
searchFilter = searchFilter.ToLower();
- _tableItems = _allItems
+ Items = _allItems
.Where(s => s.Name.ToLower().Contains(searchFilter) ||
(s.Username?.ToLower().Contains(searchFilter) ?? false) ||
(s.Uris?.FirstOrDefault()?.Uri.ToLower().Contains(searchFilter) ?? false))
@@ -92,12 +93,12 @@ namespace Bit.iOS.Core.Views
public override nint RowsInSection(UITableView tableview, nint section)
{
- return _tableItems == null || _tableItems.Count() == 0 ? 1 : _tableItems.Count();
+ return Items == null || Items.Count() == 0 ? 1 : Items.Count();
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
- if(_tableItems == null || _tableItems.Count() == 0)
+ if(Items == null || Items.Count() == 0)
{
var noDataCell = new UITableViewCell(UITableViewCellStyle.Default, "NoDataCell");
noDataCell.TextLabel.Text = AppResources.NoItemsTap;
@@ -121,17 +122,17 @@ namespace Bit.iOS.Core.Views
public override void WillDisplay(UITableView tableView, UITableViewCell cell, NSIndexPath indexPath)
{
- if(_tableItems == null || _tableItems.Count() == 0 || cell == null)
+ if(Items == null || Items.Count() == 0 || cell == null)
{
return;
}
- var item = _tableItems.ElementAt(indexPath.Row);
+ var item = Items.ElementAt(indexPath.Row);
cell.TextLabel.Text = item.Name;
cell.DetailTextLabel.Text = item.Username;
}
- protected string GetTotp(CipherViewModel item)
+ public string GetTotp(CipherViewModel item)
{
string totp = null;
if(_accessPremium)
diff --git a/src/iOS.Core/iOS.Core.csproj b/src/iOS.Core/iOS.Core.csproj
index da54de2ca..ba09d23f4 100644
--- a/src/iOS.Core/iOS.Core.csproj
+++ b/src/iOS.Core/iOS.Core.csproj
@@ -71,6 +71,7 @@
+
diff --git a/src/iOS.Extension/LoginListViewController.cs b/src/iOS.Extension/LoginListViewController.cs
index a7fec16aa..b332e51cc 100644
--- a/src/iOS.Extension/LoginListViewController.cs
+++ b/src/iOS.Extension/LoginListViewController.cs
@@ -107,13 +107,13 @@ namespace Bit.iOS.Extension
tableView.DeselectRow(indexPath, true);
tableView.EndEditing(true);
- if(_tableItems == null || _tableItems.Count() == 0)
+ if(Items == null || Items.Count() == 0)
{
_controller.PerformSegue("loginAddSegue", this);
return;
}
- var item = _tableItems.ElementAt(indexPath.Row);
+ var item = Items.ElementAt(indexPath.Row);
if(item == null)
{
_controller.LoadingController.CompleteRequest(null);