mirror of
https://github.com/bitwarden/android.git
synced 2024-12-24 18:08:26 +03:00
reuse code
This commit is contained in:
parent
44fe5af4fb
commit
f416f95b77
8 changed files with 162 additions and 201 deletions
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
91
src/iOS.Autofill/Utilities/AutofillHelpers.cs
Normal file
91
src/iOS.Autofill/Utilities/AutofillHelpers.cs
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -213,6 +213,7 @@
|
|||
<Compile Include="SetupViewController.designer.cs">
|
||||
<DependentUpon>SetupViewController.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Utilities\AutofillHelpers.cs" />
|
||||
<None Include="Info.plist" />
|
||||
<None Include="Entitlements.plist" />
|
||||
<Compile Include="PasswordGeneratorViewController.cs" />
|
||||
|
@ -299,5 +300,6 @@
|
|||
<ItemGroup>
|
||||
<BundleResource Include="Resources\check%403x.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.AppExtension.CSharp.targets" />
|
||||
</Project>
|
49
src/iOS.Core/Views/ExtensionSearchDelegate.cs
Normal file
49
src/iOS.Core/Views/ExtensionSearchDelegate.cs
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,7 +21,6 @@ namespace Bit.iOS.Core.Views
|
|||
private const string CellIdentifier = "TableCell";
|
||||
|
||||
private IEnumerable<CipherViewModel> _allItems = new List<CipherViewModel>();
|
||||
protected IEnumerable<CipherViewModel> _tableItems = new List<CipherViewModel>();
|
||||
protected ICipherService _cipherService;
|
||||
protected ISettings _settings;
|
||||
private bool _accessPremium;
|
||||
|
@ -37,6 +36,8 @@ namespace Bit.iOS.Core.Views
|
|||
_controller = controller;
|
||||
}
|
||||
|
||||
public IEnumerable<CipherViewModel> Items { get; private set; }
|
||||
|
||||
public async Task LoadItemsAsync(bool urlFilter = true, string searchFilter = null)
|
||||
{
|
||||
var combinedLogins = new List<Cipher>();
|
||||
|
@ -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)
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
<Compile Include="Views\SliderTableViewCell.cs" />
|
||||
<Compile Include="Views\SwitchTableViewCell.cs" />
|
||||
<Compile Include="Views\FormEntryTableViewCell.cs" />
|
||||
<Compile Include="Views\ExtensionSearchDelegate.cs" />
|
||||
<Compile Include="Views\Toast.cs" />
|
||||
<Compile Include="Models\CipherViewModel.cs" />
|
||||
<Compile Include="Utilities\ASHelpers.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);
|
||||
|
|
Loading…
Reference in a new issue