diff --git a/src/App/Controls/AuthenticatorViewCell/AuthenticatorViewCell.xaml b/src/App/Controls/AuthenticatorViewCell/AuthenticatorViewCell.xaml new file mode 100644 index 000000000..4d4e82554 --- /dev/null +++ b/src/App/Controls/AuthenticatorViewCell/AuthenticatorViewCell.xaml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/App/Controls/AuthenticatorViewCell/AuthenticatorViewCell.xaml.cs b/src/App/Controls/AuthenticatorViewCell/AuthenticatorViewCell.xaml.cs new file mode 100644 index 000000000..871c8a424 --- /dev/null +++ b/src/App/Controls/AuthenticatorViewCell/AuthenticatorViewCell.xaml.cs @@ -0,0 +1,71 @@ +using System; +using Bit.Core.Models.View; +using Xamarin.Forms; + +namespace Bit.App.Controls +{ + public partial class AuthenticatorViewCell : ExtendedGrid + { + public static readonly BindableProperty CipherProperty = BindableProperty.Create( + nameof(Cipher), typeof(CipherView), typeof(AuthenticatorViewCell), default(CipherView), BindingMode.OneWay); + + public static readonly BindableProperty WebsiteIconsEnabledProperty = BindableProperty.Create( + nameof(WebsiteIconsEnabled), typeof(bool?), typeof(AuthenticatorViewCell)); + + public static readonly BindableProperty ButtonCommandProperty = BindableProperty.Create( + nameof(ButtonCommand), typeof(Command), typeof(AuthenticatorViewCell)); + + public AuthenticatorViewCell() + { + InitializeComponent(); + } + + public bool? WebsiteIconsEnabled + { + get => (bool)GetValue(WebsiteIconsEnabledProperty); + set => SetValue(WebsiteIconsEnabledProperty, value); + } + + public CipherView Cipher + { + get => GetValue(CipherProperty) as CipherView; + set => SetValue(CipherProperty, value); + } + + public Command ButtonCommand + { + get => GetValue(ButtonCommandProperty) as Command; + set => SetValue(ButtonCommandProperty, value); + } + + protected override void OnPropertyChanged(string propertyName = null) + { + base.OnPropertyChanged(propertyName); + if (propertyName == CipherProperty.PropertyName) + { + if (Cipher == null) + { + return; + } + BindingContext = new AuthenticatorViewCellViewModel(Cipher, WebsiteIconsEnabled ?? false); + } + else if (propertyName == WebsiteIconsEnabledProperty.PropertyName) + { + if (Cipher == null) + { + return; + } + ((AuthenticatorViewCellViewModel)BindingContext).WebsiteIconsEnabled = WebsiteIconsEnabled ?? false; + } + } + + private void MoreButton_Clicked(object sender, EventArgs e) + { + var cipher = ((sender as MiButton)?.BindingContext as AuthenticatorViewCellViewModel)?.Cipher; + if (cipher != null) + { + ButtonCommand?.Execute(cipher); + } + } + } +} diff --git a/src/App/Controls/AuthenticatorViewCell/AuthenticatorViewCellViewModel.cs b/src/App/Controls/AuthenticatorViewCell/AuthenticatorViewCellViewModel.cs new file mode 100644 index 000000000..0010e6a3b --- /dev/null +++ b/src/App/Controls/AuthenticatorViewCell/AuthenticatorViewCellViewModel.cs @@ -0,0 +1,69 @@ +using Bit.App.Utilities; +using Bit.Core.Models.View; +using Bit.Core.Utilities; +using Xamarin.Forms; + +namespace Bit.App.Controls +{ + public class AuthenticatorViewCellViewModel : ExtendedViewModel + { + private CipherView _cipher; + private string _totpCodeFormatted = "938928"; + private string _totpSec; + private bool _websiteIconsEnabled; + private string _iconImageSource = string.Empty; + + public AuthenticatorViewCellViewModel(CipherView cipherView, bool websiteIconsEnabled) + { + Cipher = cipherView; + WebsiteIconsEnabled = websiteIconsEnabled; + } + + public Command CopyCommand { get; set; } + + public CipherView Cipher + { + get => _cipher; + set => SetProperty(ref _cipher, value); + } + + public string TotpCodeFormatted + { + get => _totpCodeFormatted; + set => SetProperty(ref _totpCodeFormatted, value); + } + + public string TotpSec + { + get => _totpSec; + set => SetProperty(ref _totpSec, value); + } + + public bool WebsiteIconsEnabled + { + get => _websiteIconsEnabled; + set => SetProperty(ref _websiteIconsEnabled, value); + } + + public bool ShowIconImage + { + get => WebsiteIconsEnabled + && !string.IsNullOrWhiteSpace(Cipher.Login?.Uri) + && IconImageSource != null; + } + + public string IconImageSource + { + get + { + if (_iconImageSource == string.Empty) // default value since icon source can return null + { + _iconImageSource = IconImageHelper.GetLoginIconImage(Cipher); + } + return _iconImageSource; + } + + } + } +} + diff --git a/src/App/Pages/Authenticator/AuthenticatorPage.xaml b/src/App/Pages/Authenticator/AuthenticatorPage.xaml index 933183ba8..6632216c8 100644 --- a/src/App/Pages/Authenticator/AuthenticatorPage.xaml +++ b/src/App/Pages/Authenticator/AuthenticatorPage.xaml @@ -20,6 +20,12 @@ SelectionMode="Single" SelectionChanged="RowSelected" StyleClass="list, list-platform"> + + + + + + diff --git a/src/App/Resources/AppResources.Designer.cs b/src/App/Resources/AppResources.Designer.cs index 931ef84f3..bde127d61 100644 --- a/src/App/Resources/AppResources.Designer.cs +++ b/src/App/Resources/AppResources.Designer.cs @@ -3761,6 +3761,12 @@ namespace Bit.App.Resources { } } + public static string RequestOTP { + get { + return ResourceManager.GetString("RequestOTP", resourceCulture); + } + } + public static string SendCode { get { return ResourceManager.GetString("SendCode", resourceCulture);