mirror of
https://github.com/bitwarden/mobile
synced 2025-12-05 23:53:33 +00:00
[EC-528] Refactor Custom Fields into separate components (#1662)
* Refactored CustomFields to stop using RepeaterView and use BindableLayout and divided the different types on different files and added a factory to create them * Fix formatting
This commit is contained in:
committed by
GitHub
parent
2016eadb0d
commit
b7048de2a1
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Lists.ItemViewModels.CustomFields;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core;
|
||||
@@ -25,6 +26,7 @@ namespace Bit.App.Pages
|
||||
private readonly IMessagingService _messagingService;
|
||||
private readonly IEventService _eventService;
|
||||
private readonly IPolicyService _policyService;
|
||||
private readonly ICustomFieldItemFactory _customFieldItemFactory;
|
||||
private readonly IClipboardService _clipboardService;
|
||||
|
||||
private bool _showNotesSeparator;
|
||||
@@ -74,6 +76,7 @@ namespace Bit.App.Pages
|
||||
_collectionService = ServiceContainer.Resolve<ICollectionService>("collectionService");
|
||||
_eventService = ServiceContainer.Resolve<IEventService>("eventService");
|
||||
_policyService = ServiceContainer.Resolve<IPolicyService>("policyService");
|
||||
_customFieldItemFactory = ServiceContainer.Resolve<ICustomFieldItemFactory>("customFieldItemFactory");
|
||||
_clipboardService = ServiceContainer.Resolve<IClipboardService>("clipboardService");
|
||||
|
||||
GeneratePasswordCommand = new Command(GeneratePassword);
|
||||
@@ -81,12 +84,12 @@ namespace Bit.App.Pages
|
||||
ToggleCardNumberCommand = new Command(ToggleCardNumber);
|
||||
ToggleCardCodeCommand = new Command(ToggleCardCode);
|
||||
UriOptionsCommand = new Command<LoginUriView>(UriOptions);
|
||||
FieldOptionsCommand = new Command<CipherAddEditPageFieldViewModel>(FieldOptions);
|
||||
FieldOptionsCommand = new Command<ICustomFieldItemViewModel>(FieldOptions);
|
||||
PasswordPromptHelpCommand = new Command(PasswordPromptHelp);
|
||||
CopyCommand = new AsyncCommand(CopyTotpClipboardAsync, onException: ex => _logger.Exception(ex), allowsMultipleExecutions: false);
|
||||
GenerateUsernameCommand = new AsyncCommand(GenerateUsernameAsync, onException: ex => OnGenerateUsernameException(ex), allowsMultipleExecutions: false);
|
||||
Uris = new ExtendedObservableCollection<LoginUriView>();
|
||||
Fields = new ExtendedObservableCollection<CipherAddEditPageFieldViewModel>();
|
||||
Fields = new ExtendedObservableCollection<ICustomFieldItemViewModel>();
|
||||
Collections = new ExtendedObservableCollection<CollectionViewModel>();
|
||||
AllowPersonal = true;
|
||||
|
||||
@@ -161,7 +164,7 @@ namespace Bit.App.Pages
|
||||
public List<KeyValuePair<string, string>> FolderOptions { get; set; }
|
||||
public List<KeyValuePair<string, string>> OwnershipOptions { get; set; }
|
||||
public ExtendedObservableCollection<LoginUriView> Uris { get; set; }
|
||||
public ExtendedObservableCollection<CipherAddEditPageFieldViewModel> Fields { get; set; }
|
||||
public ExtendedObservableCollection<ICustomFieldItemViewModel> Fields { get; set; }
|
||||
public ExtendedObservableCollection<CollectionViewModel> Collections { get; set; }
|
||||
|
||||
public int TypeSelectedIndex
|
||||
@@ -414,7 +417,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
if (Cipher.Fields != null)
|
||||
{
|
||||
Fields.ResetWithRange(Cipher.Fields?.Select(f => new CipherAddEditPageFieldViewModel(Cipher, f)));
|
||||
Fields.ResetWithRange(Cipher.Fields?.Select(f => _customFieldItemFactory.CreateCustomFieldItem(f, true, Cipher, null, null, FieldOptionsCommand)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -656,7 +659,7 @@ namespace Bit.App.Pages
|
||||
Uris.Add(new LoginUriView());
|
||||
}
|
||||
|
||||
public async void FieldOptions(CipherAddEditPageFieldViewModel field)
|
||||
public async void FieldOptions(ICustomFieldItemViewModel field)
|
||||
{
|
||||
if (!(Page as CipherAddEditPage).DoOnce())
|
||||
{
|
||||
@@ -718,15 +721,15 @@ namespace Bit.App.Pages
|
||||
}
|
||||
if (Fields == null)
|
||||
{
|
||||
Fields = new ExtendedObservableCollection<CipherAddEditPageFieldViewModel>();
|
||||
Fields = new ExtendedObservableCollection<ICustomFieldItemViewModel>();
|
||||
}
|
||||
var type = fieldTypeOptions.FirstOrDefault(f => f.Value == typeSelection).Key;
|
||||
Fields.Add(new CipherAddEditPageFieldViewModel(Cipher, new FieldView
|
||||
Fields.Add(_customFieldItemFactory.CreateCustomFieldItem(new FieldView
|
||||
{
|
||||
Type = type,
|
||||
Name = string.IsNullOrWhiteSpace(name) ? null : name,
|
||||
NewField = true,
|
||||
}));
|
||||
}, true, Cipher, null, null, FieldOptionsCommand));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -788,7 +791,7 @@ namespace Bit.App.Pages
|
||||
TriggerCipherChanged();
|
||||
|
||||
// Linked Custom Fields only apply to a specific item type
|
||||
foreach (var field in Fields.Where(f => f.IsLinkedType).ToList())
|
||||
foreach (var field in Fields.OfType<LinkedCustomFieldItemViewModel>().ToList())
|
||||
{
|
||||
Fields.Remove(field);
|
||||
}
|
||||
@@ -871,113 +874,4 @@ namespace Bit.App.Pages
|
||||
await Page.DisplayAlert(AppResources.AnErrorHasOccurred, AppResources.GenericErrorMessage, AppResources.Ok);
|
||||
}
|
||||
}
|
||||
|
||||
public class CipherAddEditPageFieldViewModel : ExtendedViewModel
|
||||
{
|
||||
private II18nService _i18nService;
|
||||
private FieldView _field;
|
||||
private CipherView _cipher;
|
||||
private bool _showHiddenValue;
|
||||
private bool _booleanValue;
|
||||
private int _linkedFieldOptionSelectedIndex;
|
||||
private string[] _additionalFieldProperties = new string[]
|
||||
{
|
||||
nameof(IsBooleanType),
|
||||
nameof(IsHiddenType),
|
||||
nameof(IsTextType),
|
||||
nameof(IsLinkedType),
|
||||
};
|
||||
|
||||
public CipherAddEditPageFieldViewModel(CipherView cipher, FieldView field)
|
||||
{
|
||||
_i18nService = ServiceContainer.Resolve<II18nService>("i18nService");
|
||||
_cipher = cipher;
|
||||
Field = field;
|
||||
ToggleHiddenValueCommand = new Command(ToggleHiddenValue);
|
||||
BooleanValue = IsBooleanType && field.Value == "true";
|
||||
LinkedFieldOptionSelectedIndex = !Field.LinkedId.HasValue ? 0 :
|
||||
LinkedFieldOptions.FindIndex(lfo => lfo.Value == Field.LinkedId.Value);
|
||||
}
|
||||
|
||||
public FieldView Field
|
||||
{
|
||||
get => _field;
|
||||
set => SetProperty(ref _field, value, additionalPropertyNames: _additionalFieldProperties);
|
||||
}
|
||||
|
||||
public bool ShowHiddenValue
|
||||
{
|
||||
get => _showHiddenValue;
|
||||
set => SetProperty(ref _showHiddenValue, value,
|
||||
additionalPropertyNames: new string[]
|
||||
{
|
||||
nameof(ShowHiddenValueIcon)
|
||||
});
|
||||
}
|
||||
|
||||
public bool BooleanValue
|
||||
{
|
||||
get => _booleanValue;
|
||||
set
|
||||
{
|
||||
SetProperty(ref _booleanValue, value);
|
||||
if (IsBooleanType)
|
||||
{
|
||||
Field.Value = value ? "true" : "false";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int LinkedFieldOptionSelectedIndex
|
||||
{
|
||||
get => _linkedFieldOptionSelectedIndex;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _linkedFieldOptionSelectedIndex, value))
|
||||
{
|
||||
LinkedFieldValueChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<KeyValuePair<string, LinkedIdType>> LinkedFieldOptions
|
||||
{
|
||||
get => _cipher.LinkedFieldOptions?
|
||||
.Select(kvp => new KeyValuePair<string, LinkedIdType>(_i18nService.T(kvp.Key), kvp.Value))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public Command ToggleHiddenValueCommand { get; set; }
|
||||
|
||||
public string ShowHiddenValueIcon => _showHiddenValue ? BitwardenIcons.EyeSlash : BitwardenIcons.Eye;
|
||||
public bool IsTextType => _field.Type == FieldType.Text;
|
||||
public bool IsBooleanType => _field.Type == FieldType.Boolean;
|
||||
public bool IsHiddenType => _field.Type == FieldType.Hidden;
|
||||
public bool IsLinkedType => _field.Type == FieldType.Linked;
|
||||
public bool ShowViewHidden => IsHiddenType && (_cipher.ViewPassword || _field.NewField);
|
||||
|
||||
public void ToggleHiddenValue()
|
||||
{
|
||||
ShowHiddenValue = !ShowHiddenValue;
|
||||
if (ShowHiddenValue && _cipher?.Id != null)
|
||||
{
|
||||
var eventService = ServiceContainer.Resolve<IEventService>("eventService");
|
||||
var task = eventService.CollectAsync(EventType.Cipher_ClientToggledHiddenFieldVisible, _cipher.Id);
|
||||
}
|
||||
}
|
||||
|
||||
public void TriggerFieldChanged()
|
||||
{
|
||||
TriggerPropertyChanged(nameof(Field), _additionalFieldProperties);
|
||||
}
|
||||
|
||||
private void LinkedFieldValueChanged()
|
||||
{
|
||||
if (Field != null && LinkedFieldOptionSelectedIndex > -1)
|
||||
{
|
||||
Field.LinkedId = LinkedFieldOptions.Find(lfo =>
|
||||
lfo.Value == LinkedFieldOptions[LinkedFieldOptionSelectedIndex].Value).Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user