2017-01-28 07:13:28 +03:00
|
|
|
|
using System;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Acr.UserDialogs;
|
|
|
|
|
using Bit.App.Abstractions;
|
|
|
|
|
using Bit.App.Controls;
|
|
|
|
|
using Bit.App.Models.Page;
|
|
|
|
|
using Bit.App.Resources;
|
|
|
|
|
using Xamarin.Forms;
|
|
|
|
|
using XLabs.Ioc;
|
|
|
|
|
using Bit.App.Utilities;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using Bit.App.Models;
|
2017-01-31 03:26:39 +03:00
|
|
|
|
using System.Collections.Generic;
|
2017-10-19 20:44:05 +03:00
|
|
|
|
using Bit.App.Enums;
|
2017-01-28 07:13:28 +03:00
|
|
|
|
|
|
|
|
|
namespace Bit.App.Pages
|
|
|
|
|
{
|
2017-10-19 04:35:33 +03:00
|
|
|
|
public class VaultAutofillListCiphersPage : ExtendedContentPage
|
2017-01-28 07:13:28 +03:00
|
|
|
|
{
|
2017-10-19 03:55:33 +03:00
|
|
|
|
private readonly ICipherService _cipherService;
|
2017-02-03 06:20:45 +03:00
|
|
|
|
private readonly IDeviceInfoService _deviceInfoService;
|
2017-11-22 07:08:45 +03:00
|
|
|
|
private readonly IDeviceActionService _deviceActionService;
|
2017-02-09 07:58:37 +03:00
|
|
|
|
private readonly ISettingsService _settingsService;
|
2017-10-20 23:10:22 +03:00
|
|
|
|
private readonly IAppSettingsService _appSettingsService;
|
2017-01-28 07:13:28 +03:00
|
|
|
|
private CancellationTokenSource _filterResultsCancellationTokenSource;
|
2017-01-31 03:26:39 +03:00
|
|
|
|
private readonly string _name;
|
2017-11-21 00:07:33 +03:00
|
|
|
|
private readonly AppOptions _appOptions;
|
2017-01-28 07:13:28 +03:00
|
|
|
|
|
2017-11-21 00:07:33 +03:00
|
|
|
|
public VaultAutofillListCiphersPage(AppOptions appOptions)
|
2017-01-28 07:13:28 +03:00
|
|
|
|
: base(true)
|
|
|
|
|
{
|
2017-11-21 00:07:33 +03:00
|
|
|
|
_appOptions = appOptions;
|
|
|
|
|
Uri = appOptions.Uri;
|
|
|
|
|
if(Uri.StartsWith(Constants.AndroidAppProtocol))
|
2017-04-28 19:25:29 +03:00
|
|
|
|
{
|
2017-11-21 00:07:33 +03:00
|
|
|
|
_name = Uri.Substring(Constants.AndroidAppProtocol.Length);
|
2017-04-28 19:25:29 +03:00
|
|
|
|
}
|
2017-11-21 00:07:33 +03:00
|
|
|
|
else if(!System.Uri.TryCreate(Uri, UriKind.Absolute, out Uri uri) ||
|
2017-09-07 06:08:24 +03:00
|
|
|
|
!DomainName.TryParseBaseDomain(uri.Host, out _name))
|
2017-01-31 03:26:39 +03:00
|
|
|
|
{
|
2017-04-28 19:25:29 +03:00
|
|
|
|
_name = "--";
|
2017-01-31 03:26:39 +03:00
|
|
|
|
}
|
2017-02-03 06:20:45 +03:00
|
|
|
|
|
2017-10-19 03:55:33 +03:00
|
|
|
|
_cipherService = Resolver.Resolve<ICipherService>();
|
2017-02-03 06:20:45 +03:00
|
|
|
|
_deviceInfoService = Resolver.Resolve<IDeviceInfoService>();
|
2017-11-22 07:08:45 +03:00
|
|
|
|
_deviceActionService = Resolver.Resolve<IDeviceActionService>();
|
2017-02-09 07:58:37 +03:00
|
|
|
|
_settingsService = Resolver.Resolve<ISettingsService>();
|
2017-02-14 06:35:16 +03:00
|
|
|
|
UserDialogs = Resolver.Resolve<IUserDialogs>();
|
2017-10-20 23:10:22 +03:00
|
|
|
|
_appSettingsService = Resolver.Resolve<IAppSettingsService>();
|
2017-02-06 07:55:46 +03:00
|
|
|
|
GoogleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
|
2017-01-28 07:13:28 +03:00
|
|
|
|
|
|
|
|
|
Init();
|
|
|
|
|
}
|
2017-02-06 07:55:46 +03:00
|
|
|
|
|
2017-10-19 04:35:33 +03:00
|
|
|
|
public ExtendedObservableCollection<VaultListPageModel.AutofillGrouping> PresentationCiphersGroup { get; private set; }
|
2017-02-14 03:12:02 +03:00
|
|
|
|
= new ExtendedObservableCollection<VaultListPageModel.AutofillGrouping>();
|
2017-01-31 03:26:39 +03:00
|
|
|
|
public StackLayout NoDataStackLayout { get; set; }
|
2017-01-28 07:13:28 +03:00
|
|
|
|
public ListView ListView { get; set; }
|
2017-01-31 03:26:39 +03:00
|
|
|
|
public ActivityIndicator LoadingIndicator { get; set; }
|
2017-02-17 08:16:09 +03:00
|
|
|
|
private SearchToolBarItem SearchItem { get; set; }
|
2017-10-19 04:35:33 +03:00
|
|
|
|
private AddCipherToolBarItem AddCipherItem { get; set; }
|
2017-02-06 07:55:46 +03:00
|
|
|
|
private IGoogleAnalyticsService GoogleAnalyticsService { get; set; }
|
2017-02-14 06:35:16 +03:00
|
|
|
|
private IUserDialogs UserDialogs { get; set; }
|
2017-02-06 07:55:46 +03:00
|
|
|
|
private string Uri { get; set; }
|
2017-01-28 07:13:28 +03:00
|
|
|
|
|
|
|
|
|
private void Init()
|
|
|
|
|
{
|
2017-01-31 03:26:39 +03:00
|
|
|
|
var noDataLabel = new Label
|
|
|
|
|
{
|
2017-10-19 04:53:44 +03:00
|
|
|
|
Text = string.Format(AppResources.NoItemsForUri, _name ?? "--"),
|
2017-01-31 03:26:39 +03:00
|
|
|
|
HorizontalTextAlignment = TextAlignment.Center,
|
|
|
|
|
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
|
|
|
|
|
Style = (Style)Application.Current.Resources["text-muted"]
|
|
|
|
|
};
|
|
|
|
|
|
2017-10-19 04:35:33 +03:00
|
|
|
|
var addCipherButton = new ExtendedButton
|
2017-01-31 03:26:39 +03:00
|
|
|
|
{
|
2017-10-19 04:53:44 +03:00
|
|
|
|
Text = AppResources.AddAnItem,
|
2017-10-19 04:35:33 +03:00
|
|
|
|
Command = new Command(() => AddCipherAsync()),
|
2017-01-31 03:26:39 +03:00
|
|
|
|
Style = (Style)Application.Current.Resources["btn-primaryAccent"]
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
NoDataStackLayout = new StackLayout
|
|
|
|
|
{
|
2017-10-19 04:35:33 +03:00
|
|
|
|
Children = { noDataLabel, addCipherButton },
|
2017-01-31 03:26:39 +03:00
|
|
|
|
VerticalOptions = LayoutOptions.CenterAndExpand,
|
|
|
|
|
Padding = new Thickness(20, 0),
|
|
|
|
|
Spacing = 20
|
|
|
|
|
};
|
|
|
|
|
|
2017-10-19 04:35:33 +03:00
|
|
|
|
AddCipherItem = new AddCipherToolBarItem(this);
|
|
|
|
|
ToolbarItems.Add(AddCipherItem);
|
2017-02-17 08:16:09 +03:00
|
|
|
|
SearchItem = new SearchToolBarItem(this);
|
|
|
|
|
ToolbarItems.Add(SearchItem);
|
2017-01-28 07:13:28 +03:00
|
|
|
|
|
|
|
|
|
ListView = new ListView(ListViewCachingStrategy.RecycleElement)
|
|
|
|
|
{
|
2017-02-14 03:12:02 +03:00
|
|
|
|
IsGroupingEnabled = true,
|
2017-10-19 04:35:33 +03:00
|
|
|
|
ItemsSource = PresentationCiphersGroup,
|
2017-01-28 07:13:28 +03:00
|
|
|
|
HasUnevenRows = true,
|
2017-11-25 07:15:25 +03:00
|
|
|
|
GroupHeaderTemplate = new DataTemplate(() => new SectionHeaderViewCell(
|
|
|
|
|
nameof(VaultListPageModel.AutofillGrouping.Name))),
|
2017-01-31 03:26:39 +03:00
|
|
|
|
ItemTemplate = new DataTemplate(() => new VaultListViewCell(
|
2017-10-19 04:35:33 +03:00
|
|
|
|
(VaultListPageModel.Cipher l) => MoreClickedAsync(l)))
|
2017-01-28 07:13:28 +03:00
|
|
|
|
};
|
|
|
|
|
|
2017-05-30 21:13:53 +03:00
|
|
|
|
if(Device.RuntimePlatform == Device.iOS)
|
2017-01-28 07:13:28 +03:00
|
|
|
|
{
|
|
|
|
|
ListView.RowHeight = -1;
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-19 04:53:44 +03:00
|
|
|
|
Title = string.Format(AppResources.ItemsForUri, _name ?? "--");
|
2017-01-31 03:26:39 +03:00
|
|
|
|
|
|
|
|
|
LoadingIndicator = new ActivityIndicator
|
|
|
|
|
{
|
|
|
|
|
IsRunning = true,
|
|
|
|
|
VerticalOptions = LayoutOptions.CenterAndExpand,
|
|
|
|
|
HorizontalOptions = LayoutOptions.Center
|
|
|
|
|
};
|
2017-01-28 07:13:28 +03:00
|
|
|
|
|
2017-01-31 03:26:39 +03:00
|
|
|
|
Content = LoadingIndicator;
|
2017-01-28 07:13:28 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void OnAppearing()
|
|
|
|
|
{
|
|
|
|
|
base.OnAppearing();
|
2017-10-19 04:35:33 +03:00
|
|
|
|
ListView.ItemSelected += CipherSelected;
|
|
|
|
|
AddCipherItem.InitEvents();
|
2017-02-17 08:16:09 +03:00
|
|
|
|
SearchItem.InitEvents();
|
2017-01-28 07:13:28 +03:00
|
|
|
|
_filterResultsCancellationTokenSource = FetchAndLoadVault();
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-17 08:16:09 +03:00
|
|
|
|
protected override void OnDisappearing()
|
|
|
|
|
{
|
|
|
|
|
base.OnDisappearing();
|
2017-10-19 04:35:33 +03:00
|
|
|
|
ListView.ItemSelected -= CipherSelected;
|
|
|
|
|
AddCipherItem.Dispose();
|
2017-02-17 08:16:09 +03:00
|
|
|
|
SearchItem.Dispose();
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-31 03:26:39 +03:00
|
|
|
|
protected override bool OnBackButtonPressed()
|
2017-01-28 07:13:28 +03:00
|
|
|
|
{
|
2017-02-06 07:55:46 +03:00
|
|
|
|
GoogleAnalyticsService.TrackExtensionEvent("BackClosed", Uri.StartsWith("http") ? "Website" : "App");
|
2017-11-22 07:08:45 +03:00
|
|
|
|
_deviceActionService.CloseAutofill();
|
2017-01-31 03:26:39 +03:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2017-01-28 07:13:28 +03:00
|
|
|
|
|
2017-01-31 03:26:39 +03:00
|
|
|
|
private void AdjustContent()
|
|
|
|
|
{
|
2017-10-19 04:35:33 +03:00
|
|
|
|
if(PresentationCiphersGroup.Count > 0)
|
2017-01-31 03:26:39 +03:00
|
|
|
|
{
|
|
|
|
|
Content = ListView;
|
|
|
|
|
}
|
|
|
|
|
else
|
2017-01-28 07:13:28 +03:00
|
|
|
|
{
|
2017-01-31 03:26:39 +03:00
|
|
|
|
Content = NoDataStackLayout;
|
2017-01-28 07:13:28 +03:00
|
|
|
|
}
|
2017-01-31 03:26:39 +03:00
|
|
|
|
}
|
2017-01-28 07:13:28 +03:00
|
|
|
|
|
2017-01-31 03:26:39 +03:00
|
|
|
|
private CancellationTokenSource FetchAndLoadVault()
|
|
|
|
|
{
|
|
|
|
|
var cts = new CancellationTokenSource();
|
2017-01-28 07:13:28 +03:00
|
|
|
|
_filterResultsCancellationTokenSource?.Cancel();
|
|
|
|
|
|
|
|
|
|
Task.Run(async () =>
|
|
|
|
|
{
|
2017-02-14 06:10:34 +03:00
|
|
|
|
var autofillGroupings = new List<VaultListPageModel.AutofillGrouping>();
|
2017-10-19 04:35:33 +03:00
|
|
|
|
var ciphers = await _cipherService.GetAllAsync(Uri);
|
2017-02-14 06:10:34 +03:00
|
|
|
|
|
2017-11-21 00:07:33 +03:00
|
|
|
|
if(_appOptions.FillType.HasValue && _appOptions.FillType.Value != CipherType.Login)
|
2017-02-14 06:10:34 +03:00
|
|
|
|
{
|
2017-11-21 00:07:33 +03:00
|
|
|
|
var others = ciphers?.Item3.Where(c => c.Type == _appOptions.FillType.Value)
|
|
|
|
|
.Select(c => new VaultListPageModel.AutofillCipher(c, _appSettingsService, false))
|
|
|
|
|
.OrderBy(s => s.Name)
|
|
|
|
|
.ThenBy(s => s.Subtitle)
|
|
|
|
|
.ToList();
|
|
|
|
|
if(others?.Any() ?? false)
|
|
|
|
|
{
|
|
|
|
|
autofillGroupings.Add(new VaultListPageModel.AutofillGrouping(others, AppResources.Items));
|
|
|
|
|
}
|
2017-02-14 06:10:34 +03:00
|
|
|
|
}
|
2017-11-21 00:07:33 +03:00
|
|
|
|
else
|
2017-02-14 03:12:02 +03:00
|
|
|
|
{
|
2017-11-21 00:07:33 +03:00
|
|
|
|
var normalLogins = ciphers?.Item1
|
|
|
|
|
.Select(l => new VaultListPageModel.AutofillCipher(l, _appSettingsService, false))
|
|
|
|
|
.OrderBy(s => s.Name)
|
|
|
|
|
.ThenBy(s => s.Subtitle)
|
|
|
|
|
.ToList();
|
|
|
|
|
if(normalLogins?.Any() ?? false)
|
|
|
|
|
{
|
|
|
|
|
autofillGroupings.Add(new VaultListPageModel.AutofillGrouping(normalLogins,
|
|
|
|
|
AppResources.MatchingItems));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var fuzzyLogins = ciphers?.Item2
|
|
|
|
|
.Select(l => new VaultListPageModel.AutofillCipher(l, _appSettingsService, true))
|
|
|
|
|
.OrderBy(s => s.Name)
|
|
|
|
|
.ThenBy(s => s.Subtitle)
|
|
|
|
|
.ToList();
|
|
|
|
|
if(fuzzyLogins?.Any() ?? false)
|
|
|
|
|
{
|
|
|
|
|
autofillGroupings.Add(new VaultListPageModel.AutofillGrouping(fuzzyLogins,
|
|
|
|
|
AppResources.PossibleMatchingItems));
|
|
|
|
|
}
|
2017-02-14 06:10:34 +03:00
|
|
|
|
}
|
2017-01-28 07:13:28 +03:00
|
|
|
|
|
2017-01-31 03:26:39 +03:00
|
|
|
|
Device.BeginInvokeOnMainThread(() =>
|
|
|
|
|
{
|
2017-02-14 06:10:34 +03:00
|
|
|
|
if(autofillGroupings.Any())
|
|
|
|
|
{
|
2017-10-19 04:35:33 +03:00
|
|
|
|
PresentationCiphersGroup.ResetWithRange(autofillGroupings);
|
2017-02-14 06:10:34 +03:00
|
|
|
|
}
|
|
|
|
|
|
2017-01-31 03:26:39 +03:00
|
|
|
|
AdjustContent();
|
|
|
|
|
});
|
2017-01-28 07:13:28 +03:00
|
|
|
|
}, cts.Token);
|
|
|
|
|
|
|
|
|
|
return cts;
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-19 04:35:33 +03:00
|
|
|
|
private async void CipherSelected(object sender, SelectedItemChangedEventArgs e)
|
2017-01-28 07:13:28 +03:00
|
|
|
|
{
|
2017-10-19 04:35:33 +03:00
|
|
|
|
var cipher = e.SelectedItem as VaultListPageModel.AutofillCipher;
|
|
|
|
|
if(cipher == null)
|
2017-02-14 06:10:34 +03:00
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-02-03 06:20:45 +03:00
|
|
|
|
|
2017-09-08 16:16:21 +03:00
|
|
|
|
if(_deviceInfoService.Version < 21)
|
2017-02-03 06:20:45 +03:00
|
|
|
|
{
|
2017-10-19 04:35:33 +03:00
|
|
|
|
MoreClickedAsync(cipher);
|
2017-02-14 06:10:34 +03:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
bool doAutofill = true;
|
2017-10-19 04:35:33 +03:00
|
|
|
|
if(cipher.Fuzzy)
|
2017-02-14 06:10:34 +03:00
|
|
|
|
{
|
2017-02-14 06:35:16 +03:00
|
|
|
|
doAutofill = await UserDialogs.ConfirmAsync(
|
2017-02-14 06:10:34 +03:00
|
|
|
|
string.Format(AppResources.BitwardenAutofillServiceMatchConfirm, _name),
|
|
|
|
|
okText: AppResources.Yes, cancelText: AppResources.No);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(doAutofill)
|
|
|
|
|
{
|
|
|
|
|
GoogleAnalyticsService.TrackExtensionEvent("AutoFilled", Uri.StartsWith("http") ? "Website" : "App");
|
2017-11-22 07:08:45 +03:00
|
|
|
|
_deviceActionService.Autofill(cipher);
|
2017-02-14 06:10:34 +03:00
|
|
|
|
}
|
2017-02-03 06:20:45 +03:00
|
|
|
|
}
|
|
|
|
|
|
2017-02-14 06:10:34 +03:00
|
|
|
|
((ListView)sender).SelectedItem = null;
|
2017-01-28 07:13:28 +03:00
|
|
|
|
}
|
|
|
|
|
|
2017-10-19 04:35:33 +03:00
|
|
|
|
private async void AddCipherAsync()
|
2017-01-28 07:13:28 +03:00
|
|
|
|
{
|
2017-11-21 00:07:33 +03:00
|
|
|
|
if(_appOptions.FillType.HasValue && _appOptions.FillType != CipherType.Login)
|
|
|
|
|
{
|
|
|
|
|
var pageForOther = new VaultAddCipherPage(_appOptions.FillType.Value, null, null, true);
|
|
|
|
|
await Navigation.PushForDeviceAsync(pageForOther);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var pageForLogin = new VaultAddCipherPage(CipherType.Login, Uri, _name, true);
|
|
|
|
|
await Navigation.PushForDeviceAsync(pageForLogin);
|
2017-01-28 07:13:28 +03:00
|
|
|
|
}
|
|
|
|
|
|
2017-10-19 04:35:33 +03:00
|
|
|
|
private async void MoreClickedAsync(VaultListPageModel.Cipher cipher)
|
2017-01-28 07:13:28 +03:00
|
|
|
|
{
|
2017-01-31 03:26:39 +03:00
|
|
|
|
var buttons = new List<string> { AppResources.View, AppResources.Edit };
|
2017-10-19 04:35:33 +03:00
|
|
|
|
|
2017-10-19 21:30:12 +03:00
|
|
|
|
if(cipher.Type == CipherType.Login)
|
2017-01-28 07:13:28 +03:00
|
|
|
|
{
|
2017-10-20 19:47:05 +03:00
|
|
|
|
if(!string.IsNullOrWhiteSpace(cipher.LoginPassword.Value))
|
2017-10-19 04:35:33 +03:00
|
|
|
|
{
|
|
|
|
|
buttons.Add(AppResources.CopyPassword);
|
|
|
|
|
}
|
2017-10-20 19:47:05 +03:00
|
|
|
|
if(!string.IsNullOrWhiteSpace(cipher.LoginUsername))
|
2017-10-19 04:35:33 +03:00
|
|
|
|
{
|
|
|
|
|
buttons.Add(AppResources.CopyUsername);
|
|
|
|
|
}
|
2017-01-31 03:26:39 +03:00
|
|
|
|
}
|
2017-10-19 21:30:12 +03:00
|
|
|
|
else if(cipher.Type == CipherType.Card)
|
2017-01-31 03:26:39 +03:00
|
|
|
|
{
|
2017-10-19 04:35:33 +03:00
|
|
|
|
if(!string.IsNullOrWhiteSpace(cipher.CardNumber))
|
|
|
|
|
{
|
|
|
|
|
buttons.Add(AppResources.CopyNumber);
|
|
|
|
|
}
|
|
|
|
|
if(!string.IsNullOrWhiteSpace(cipher.CardCode.Value))
|
|
|
|
|
{
|
|
|
|
|
buttons.Add(AppResources.CopySecurityCode);
|
|
|
|
|
}
|
2017-01-28 07:13:28 +03:00
|
|
|
|
}
|
|
|
|
|
|
2017-10-19 04:35:33 +03:00
|
|
|
|
var selection = await DisplayActionSheet(cipher.Name, AppResources.Cancel, null, buttons.ToArray());
|
2017-01-31 03:26:39 +03:00
|
|
|
|
|
|
|
|
|
if(selection == AppResources.View)
|
|
|
|
|
{
|
2017-10-20 18:25:34 +03:00
|
|
|
|
var page = new VaultViewCipherPage(cipher.Type, cipher.Id);
|
2017-01-31 03:26:39 +03:00
|
|
|
|
await Navigation.PushForDeviceAsync(page);
|
|
|
|
|
}
|
|
|
|
|
else if(selection == AppResources.Edit)
|
2017-01-28 07:13:28 +03:00
|
|
|
|
{
|
2017-10-19 21:30:12 +03:00
|
|
|
|
var page = new VaultEditCipherPage(cipher.Id);
|
2017-01-31 03:26:39 +03:00
|
|
|
|
await Navigation.PushForDeviceAsync(page);
|
|
|
|
|
}
|
|
|
|
|
else if(selection == AppResources.CopyPassword)
|
|
|
|
|
{
|
2017-10-20 19:47:05 +03:00
|
|
|
|
Copy(cipher.LoginPassword.Value, AppResources.Password);
|
2017-01-31 03:26:39 +03:00
|
|
|
|
}
|
|
|
|
|
else if(selection == AppResources.CopyUsername)
|
|
|
|
|
{
|
2017-10-20 19:47:05 +03:00
|
|
|
|
Copy(cipher.LoginUsername, AppResources.Username);
|
2017-10-19 04:35:33 +03:00
|
|
|
|
}
|
|
|
|
|
else if(selection == AppResources.CopyNumber)
|
|
|
|
|
{
|
|
|
|
|
Copy(cipher.CardNumber, AppResources.Number);
|
|
|
|
|
}
|
|
|
|
|
else if(selection == AppResources.CopySecurityCode)
|
|
|
|
|
{
|
|
|
|
|
Copy(cipher.CardCode.Value, AppResources.SecurityCode);
|
2017-01-28 07:13:28 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-31 03:26:39 +03:00
|
|
|
|
private void Copy(string copyText, string alertLabel)
|
2017-01-28 07:13:28 +03:00
|
|
|
|
{
|
2017-11-22 07:08:45 +03:00
|
|
|
|
_deviceActionService.CopyToClipboard(copyText);
|
2017-02-14 06:35:16 +03:00
|
|
|
|
UserDialogs.Toast(string.Format(AppResources.ValueHasBeenCopied, alertLabel));
|
2017-01-31 03:26:39 +03:00
|
|
|
|
}
|
2017-01-28 07:13:28 +03:00
|
|
|
|
|
2017-10-19 04:35:33 +03:00
|
|
|
|
private class AddCipherToolBarItem : ExtendedToolbarItem
|
2017-01-31 03:26:39 +03:00
|
|
|
|
{
|
2017-10-19 04:35:33 +03:00
|
|
|
|
public AddCipherToolBarItem(VaultAutofillListCiphersPage page)
|
|
|
|
|
: base(() => page.AddCipherAsync())
|
2017-01-28 07:13:28 +03:00
|
|
|
|
{
|
2017-01-31 03:26:39 +03:00
|
|
|
|
Text = AppResources.Add;
|
2017-10-19 04:35:33 +03:00
|
|
|
|
Icon = "plus.png";
|
2017-02-14 06:35:16 +03:00
|
|
|
|
Priority = 2;
|
2017-01-28 07:13:28 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-02-03 06:20:45 +03:00
|
|
|
|
|
2017-02-17 08:16:09 +03:00
|
|
|
|
private class SearchToolBarItem : ExtendedToolbarItem
|
2017-02-03 06:20:45 +03:00
|
|
|
|
{
|
2017-10-19 04:35:33 +03:00
|
|
|
|
private readonly VaultAutofillListCiphersPage _page;
|
2017-02-03 06:20:45 +03:00
|
|
|
|
|
2017-10-19 04:35:33 +03:00
|
|
|
|
public SearchToolBarItem(VaultAutofillListCiphersPage page)
|
2017-02-03 06:20:45 +03:00
|
|
|
|
{
|
|
|
|
|
_page = page;
|
2017-02-14 06:35:16 +03:00
|
|
|
|
Text = AppResources.Search;
|
2017-10-19 04:35:33 +03:00
|
|
|
|
Icon = "search.png";
|
2017-02-14 06:35:16 +03:00
|
|
|
|
Priority = 1;
|
2017-02-17 08:16:09 +03:00
|
|
|
|
ClickAction = () => DoClick();
|
2017-02-03 06:20:45 +03:00
|
|
|
|
}
|
|
|
|
|
|
2017-02-17 08:16:09 +03:00
|
|
|
|
private void DoClick()
|
2017-02-03 06:20:45 +03:00
|
|
|
|
{
|
2017-02-14 06:10:34 +03:00
|
|
|
|
_page.GoogleAnalyticsService.TrackExtensionEvent("CloseToSearch",
|
|
|
|
|
_page.Uri.StartsWith("http") ? "Website" : "App");
|
2017-11-17 21:03:43 +03:00
|
|
|
|
Application.Current.MainPage = new ExtendedNavigationPage(new VaultListCiphersPage(false, _page.Uri));
|
2017-02-14 06:35:16 +03:00
|
|
|
|
_page.UserDialogs.Toast(string.Format(AppResources.BitwardenAutofillServiceSearch, _page._name),
|
2017-02-18 08:23:47 +03:00
|
|
|
|
TimeSpan.FromSeconds(10));
|
2017-02-14 03:12:02 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-01-28 07:13:28 +03:00
|
|
|
|
}
|
|
|
|
|
}
|