2017-10-31 12:14:26 +01:00
|
|
|
|
using System;
|
2020-04-15 19:06:13 +02:00
|
|
|
|
using System.Collections.ObjectModel;
|
2020-04-16 19:43:17 +02:00
|
|
|
|
using System.Linq;
|
2020-03-27 13:27:29 +01:00
|
|
|
|
using System.Threading.Tasks;
|
2020-03-30 19:43:04 +02:00
|
|
|
|
using Windows.UI.Xaml.Controls;
|
2020-04-14 17:49:29 +02:00
|
|
|
|
using Windows.UI.Xaml.Media;
|
2020-04-22 16:21:47 +02:00
|
|
|
|
using GalaSoft.MvvmLight;
|
2020-04-23 19:00:38 +02:00
|
|
|
|
using GalaSoft.MvvmLight.Command;
|
2020-04-21 19:12:26 +02:00
|
|
|
|
using GalaSoft.MvvmLight.Views;
|
2020-03-27 13:27:29 +01:00
|
|
|
|
using MediatR;
|
2020-05-04 12:48:27 +02:00
|
|
|
|
using Messages;
|
2020-04-22 11:58:06 +02:00
|
|
|
|
using ModernKeePass.Application.Common.Interfaces;
|
2020-03-27 13:27:29 +01:00
|
|
|
|
using ModernKeePass.Application.Database.Commands.SaveDatabase;
|
2020-03-27 18:45:13 +01:00
|
|
|
|
using ModernKeePass.Application.Database.Models;
|
|
|
|
|
using ModernKeePass.Application.Database.Queries.GetDatabase;
|
2020-05-07 12:11:12 +02:00
|
|
|
|
using ModernKeePass.Application.Entry.Commands.AddAttachment;
|
2020-04-14 19:59:19 +02:00
|
|
|
|
using ModernKeePass.Application.Entry.Commands.AddHistory;
|
2020-05-07 12:11:12 +02:00
|
|
|
|
using ModernKeePass.Application.Entry.Commands.DeleteAttachment;
|
2020-05-11 10:53:14 +02:00
|
|
|
|
using ModernKeePass.Application.Entry.Commands.DeleteField;
|
2020-04-16 14:08:50 +02:00
|
|
|
|
using ModernKeePass.Application.Entry.Commands.DeleteHistory;
|
2020-04-15 19:06:13 +02:00
|
|
|
|
using ModernKeePass.Application.Entry.Commands.RestoreHistory;
|
2020-05-11 10:53:14 +02:00
|
|
|
|
using ModernKeePass.Application.Entry.Commands.UpsertField;
|
2020-04-02 19:12:16 +02:00
|
|
|
|
using ModernKeePass.Application.Entry.Models;
|
|
|
|
|
using ModernKeePass.Application.Entry.Queries.GetEntry;
|
2020-03-30 19:43:04 +02:00
|
|
|
|
using ModernKeePass.Application.Group.Commands.AddEntry;
|
2020-04-02 19:12:16 +02:00
|
|
|
|
using ModernKeePass.Application.Group.Commands.DeleteEntry;
|
2020-03-30 19:43:04 +02:00
|
|
|
|
using ModernKeePass.Application.Group.Commands.RemoveEntry;
|
2020-04-02 19:12:16 +02:00
|
|
|
|
using ModernKeePass.Application.Group.Queries.GetGroup;
|
2020-03-31 19:19:02 +02:00
|
|
|
|
using ModernKeePass.Domain.Enums;
|
2020-04-02 19:12:16 +02:00
|
|
|
|
using ModernKeePass.Application.Group.Models;
|
2020-04-28 18:54:37 +02:00
|
|
|
|
using ModernKeePass.Common;
|
2020-05-06 18:54:39 +02:00
|
|
|
|
using ModernKeePass.Domain.Dtos;
|
2020-05-04 12:48:27 +02:00
|
|
|
|
using ModernKeePass.Domain.Exceptions;
|
2020-06-04 16:29:26 +02:00
|
|
|
|
using ModernKeePass.Domain.Interfaces;
|
2020-04-14 17:49:29 +02:00
|
|
|
|
using ModernKeePass.Extensions;
|
2020-04-28 18:54:37 +02:00
|
|
|
|
using ModernKeePass.Models;
|
2020-05-20 11:59:40 +02:00
|
|
|
|
using ModernKeePass.ViewModels.ListItems;
|
2017-09-12 18:20:32 +02:00
|
|
|
|
|
|
|
|
|
namespace ModernKeePass.ViewModels
|
|
|
|
|
{
|
2020-05-04 12:48:27 +02:00
|
|
|
|
public class EntryDetailVm : ViewModelBase
|
2017-09-12 18:20:32 +02:00
|
|
|
|
{
|
2020-06-04 16:29:26 +02:00
|
|
|
|
public bool HasExpired => HasExpirationDate && ExpiryDate < _dateTime.Now;
|
2020-05-25 19:23:32 +02:00
|
|
|
|
|
2020-06-04 16:29:26 +02:00
|
|
|
|
public string Id => _current.Id;
|
2020-06-09 20:18:17 +02:00
|
|
|
|
|
2020-04-16 14:08:50 +02:00
|
|
|
|
public bool IsRecycleOnDelete
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
var database = Database;
|
|
|
|
|
return database.IsRecycleBinEnabled && _parent.Id != database.RecycleBinId;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-05-06 18:54:39 +02:00
|
|
|
|
|
2020-06-08 14:16:54 +02:00
|
|
|
|
public ObservableCollection<IEntityVm> History { get; private set; }
|
2020-05-20 11:59:40 +02:00
|
|
|
|
public ObservableCollection<EntryFieldVm> AdditionalFields { get; private set; }
|
2020-05-06 18:54:39 +02:00
|
|
|
|
public ObservableCollection<Attachment> Attachments { get; private set; }
|
2020-03-30 19:43:04 +02:00
|
|
|
|
|
2018-06-15 18:07:44 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Determines if the Entry is current or from history
|
|
|
|
|
/// </summary>
|
2020-04-16 14:08:50 +02:00
|
|
|
|
public bool IsCurrentEntry => SelectedIndex == 0;
|
2020-05-06 18:54:39 +02:00
|
|
|
|
|
2020-04-16 14:08:50 +02:00
|
|
|
|
public int SelectedIndex
|
|
|
|
|
{
|
|
|
|
|
get { return _selectedIndex; }
|
|
|
|
|
set
|
|
|
|
|
{
|
2020-04-22 16:21:47 +02:00
|
|
|
|
Set(() => SelectedIndex, ref _selectedIndex, value);
|
|
|
|
|
RaisePropertyChanged(nameof(IsCurrentEntry));
|
2020-05-07 12:11:12 +02:00
|
|
|
|
AddAttachmentCommand.RaiseCanExecuteChanged();
|
2020-04-16 14:08:50 +02:00
|
|
|
|
}
|
2020-04-03 17:33:53 +02:00
|
|
|
|
}
|
2017-10-16 18:31:45 +02:00
|
|
|
|
|
2020-05-11 10:53:14 +02:00
|
|
|
|
public int AdditionalFieldSelectedIndex
|
|
|
|
|
{
|
|
|
|
|
get { return _additionalFieldSelectedIndex; }
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
Set(() => AdditionalFieldSelectedIndex, ref _additionalFieldSelectedIndex, value);
|
|
|
|
|
DeleteAdditionalField.RaiseCanExecuteChanged();
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-05-18 14:14:28 +02:00
|
|
|
|
|
2020-03-27 13:27:29 +01:00
|
|
|
|
public string Title
|
2017-09-26 14:32:15 +02:00
|
|
|
|
{
|
2020-06-04 16:29:26 +02:00
|
|
|
|
get { return _current.Title.Value; }
|
2020-03-31 19:19:02 +02:00
|
|
|
|
set
|
|
|
|
|
{
|
2020-06-04 16:29:26 +02:00
|
|
|
|
_current.Title.Value = value;
|
|
|
|
|
SetFieldValue(_current.Title.Name, value, false).ConfigureAwait(false).GetAwaiter();
|
2020-03-31 19:19:02 +02:00
|
|
|
|
}
|
2017-09-26 14:32:15 +02:00
|
|
|
|
}
|
2017-10-11 11:20:05 +02:00
|
|
|
|
|
2017-09-26 14:32:15 +02:00
|
|
|
|
public string UserName
|
|
|
|
|
{
|
2020-06-04 16:29:26 +02:00
|
|
|
|
get { return _current.Username.Value; }
|
2020-04-30 19:40:48 +02:00
|
|
|
|
set
|
|
|
|
|
{
|
2020-06-04 16:29:26 +02:00
|
|
|
|
_current.Username.Value = value;
|
|
|
|
|
SetFieldValue(_current.Username.Name, value, false).ConfigureAwait(false).GetAwaiter();
|
2020-04-30 19:40:48 +02:00
|
|
|
|
RaisePropertyChanged(nameof(UserName));
|
|
|
|
|
}
|
2017-09-26 14:32:15 +02:00
|
|
|
|
}
|
2017-11-06 19:01:01 +01:00
|
|
|
|
|
2017-09-26 14:32:15 +02:00
|
|
|
|
public string Password
|
|
|
|
|
{
|
2020-06-04 16:29:26 +02:00
|
|
|
|
get { return _cryptography.UnProtect(_current.Password.Value).GetAwaiter().GetResult(); }
|
2017-10-13 11:48:58 +02:00
|
|
|
|
set
|
|
|
|
|
{
|
2020-05-18 22:20:31 +02:00
|
|
|
|
var protectedPassword = _cryptography.Protect(value).ConfigureAwait(false).GetAwaiter().GetResult();
|
2020-06-04 16:29:26 +02:00
|
|
|
|
_current.Password.Value = protectedPassword;
|
|
|
|
|
SetFieldValue(_current.Password.Name, protectedPassword, true).ConfigureAwait(false).GetAwaiter();
|
2020-05-20 11:59:40 +02:00
|
|
|
|
|
2020-04-22 16:21:47 +02:00
|
|
|
|
RaisePropertyChanged(nameof(Password));
|
2017-10-13 11:48:58 +02:00
|
|
|
|
}
|
2017-09-26 14:32:15 +02:00
|
|
|
|
}
|
2018-02-23 18:09:21 +01:00
|
|
|
|
|
2017-09-26 14:32:15 +02:00
|
|
|
|
public string Url
|
|
|
|
|
{
|
2020-06-04 16:29:26 +02:00
|
|
|
|
get { return _current.Url.Value; }
|
2020-03-31 19:19:02 +02:00
|
|
|
|
set
|
|
|
|
|
{
|
2020-06-04 16:29:26 +02:00
|
|
|
|
_current.Url.Value = value;
|
|
|
|
|
SetFieldValue(_current.Url.Name, value, false).ConfigureAwait(false).GetAwaiter();
|
2020-04-30 19:40:48 +02:00
|
|
|
|
RaisePropertyChanged(nameof(Url));
|
2020-03-31 19:19:02 +02:00
|
|
|
|
}
|
2017-09-26 14:32:15 +02:00
|
|
|
|
}
|
2018-06-15 18:07:44 +02:00
|
|
|
|
|
2017-09-26 14:32:15 +02:00
|
|
|
|
public string Notes
|
|
|
|
|
{
|
2020-06-04 16:29:26 +02:00
|
|
|
|
get { return _current.Notes.Value; }
|
2020-03-31 19:19:02 +02:00
|
|
|
|
set
|
|
|
|
|
{
|
2020-06-04 16:29:26 +02:00
|
|
|
|
_current.Notes.Value = value;
|
|
|
|
|
SetFieldValue(_current.Notes.Name, value, false).ConfigureAwait(false).GetAwaiter();
|
2020-03-31 19:19:02 +02:00
|
|
|
|
}
|
2017-09-26 14:32:15 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-03-30 19:43:04 +02:00
|
|
|
|
public Symbol Icon
|
2017-09-29 18:08:20 +02:00
|
|
|
|
{
|
2020-06-04 16:29:26 +02:00
|
|
|
|
get { return (Symbol)Enum.Parse(typeof(Symbol), _current.Icon.ToString()); }
|
2020-03-31 19:19:02 +02:00
|
|
|
|
set
|
|
|
|
|
{
|
2020-06-04 16:29:26 +02:00
|
|
|
|
_current.Icon = (Icon)Enum.Parse(typeof(Icon), value.ToString());
|
|
|
|
|
SetFieldValue(EntryFieldName.Icon, _current.Icon, false).ConfigureAwait(false).GetAwaiter();
|
2020-03-31 19:19:02 +02:00
|
|
|
|
}
|
2017-09-29 18:08:20 +02:00
|
|
|
|
}
|
2017-10-06 14:56:16 +02:00
|
|
|
|
|
2017-10-18 13:57:10 +02:00
|
|
|
|
public DateTimeOffset ExpiryDate
|
|
|
|
|
{
|
2020-06-04 16:29:26 +02:00
|
|
|
|
get { return _current.ExpirationDate; }
|
2018-07-24 17:52:44 +02:00
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (!HasExpirationDate) return;
|
2020-04-14 13:44:07 +02:00
|
|
|
|
|
2020-06-04 16:29:26 +02:00
|
|
|
|
_current.ExpirationDate = value.Date;
|
|
|
|
|
SetFieldValue(EntryFieldName.ExpirationDate, _current.ExpirationDate, false).ConfigureAwait(false).GetAwaiter();
|
2018-07-24 17:52:44 +02:00
|
|
|
|
}
|
2017-10-18 13:57:10 +02:00
|
|
|
|
}
|
2017-11-06 19:01:01 +01:00
|
|
|
|
|
2017-10-18 13:57:10 +02:00
|
|
|
|
public TimeSpan ExpiryTime
|
|
|
|
|
{
|
2020-06-04 16:29:26 +02:00
|
|
|
|
get { return _current.ExpirationDate.TimeOfDay; }
|
2018-07-24 17:52:44 +02:00
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (!HasExpirationDate) return;
|
2020-04-14 13:44:07 +02:00
|
|
|
|
|
2020-06-04 16:29:26 +02:00
|
|
|
|
_current.ExpirationDate = _current.ExpirationDate.Date.Add(value);
|
|
|
|
|
SetFieldValue(EntryFieldName.ExpirationDate, _current.ExpirationDate, false).ConfigureAwait(false).GetAwaiter();
|
2018-07-24 17:52:44 +02:00
|
|
|
|
}
|
2017-10-18 13:57:10 +02:00
|
|
|
|
}
|
2020-03-31 19:19:02 +02:00
|
|
|
|
|
|
|
|
|
public bool HasExpirationDate
|
2017-10-06 14:56:16 +02:00
|
|
|
|
{
|
2020-06-04 16:29:26 +02:00
|
|
|
|
get { return _current.HasExpirationDate; }
|
2017-10-13 11:48:58 +02:00
|
|
|
|
set
|
|
|
|
|
{
|
2020-06-04 16:29:26 +02:00
|
|
|
|
_current.HasExpirationDate = value;
|
2020-05-26 13:38:07 +02:00
|
|
|
|
SetFieldValue(EntryFieldName.HasExpirationDate, value, false).ConfigureAwait(false).GetAwaiter();
|
2020-04-22 16:21:47 +02:00
|
|
|
|
RaisePropertyChanged(nameof(HasExpirationDate));
|
2017-10-13 11:48:58 +02:00
|
|
|
|
}
|
2017-10-06 14:56:16 +02:00
|
|
|
|
}
|
2020-03-31 19:19:02 +02:00
|
|
|
|
|
2020-04-14 17:49:29 +02:00
|
|
|
|
public SolidColorBrush BackgroundColor
|
2017-12-14 17:15:28 +01:00
|
|
|
|
{
|
2020-06-04 16:29:26 +02:00
|
|
|
|
get { return _current?.BackgroundColor.ToSolidColorBrush(); }
|
2017-12-14 17:15:28 +01:00
|
|
|
|
set
|
|
|
|
|
{
|
2020-06-04 16:29:26 +02:00
|
|
|
|
_current.BackgroundColor = value.ToColor();
|
|
|
|
|
SetFieldValue(EntryFieldName.BackgroundColor, _current.BackgroundColor, false).ConfigureAwait(false).GetAwaiter();
|
2017-12-14 17:15:28 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-03-31 19:19:02 +02:00
|
|
|
|
|
2020-04-14 17:49:29 +02:00
|
|
|
|
public SolidColorBrush ForegroundColor
|
2017-10-06 17:57:36 +02:00
|
|
|
|
{
|
2020-06-04 16:29:26 +02:00
|
|
|
|
get { return _current?.ForegroundColor.ToSolidColorBrush(); }
|
2017-10-13 11:48:58 +02:00
|
|
|
|
set
|
|
|
|
|
{
|
2020-06-04 16:29:26 +02:00
|
|
|
|
_current.ForegroundColor = value.ToColor();
|
|
|
|
|
SetFieldValue(EntryFieldName.ForegroundColor, _current.ForegroundColor, false).ConfigureAwait(false).GetAwaiter();
|
2017-10-13 11:48:58 +02:00
|
|
|
|
}
|
2017-10-06 17:57:36 +02:00
|
|
|
|
}
|
2020-05-14 13:32:44 +02:00
|
|
|
|
|
2020-04-20 20:02:43 +02:00
|
|
|
|
public RelayCommand SaveCommand { get; }
|
2020-04-28 15:20:47 +02:00
|
|
|
|
public RelayCommand<string> MoveCommand { get; }
|
2020-04-20 20:02:43 +02:00
|
|
|
|
public RelayCommand RestoreCommand { get; }
|
2020-04-21 19:12:26 +02:00
|
|
|
|
public RelayCommand DeleteCommand { get; }
|
2020-06-04 16:29:26 +02:00
|
|
|
|
public RelayCommand AddAdditionalField { get; }
|
|
|
|
|
public RelayCommand<EntryFieldVm> DeleteAdditionalField { get; }
|
|
|
|
|
public RelayCommand<Attachment> OpenAttachmentCommand { get; }
|
|
|
|
|
public RelayCommand AddAttachmentCommand { get; }
|
|
|
|
|
public RelayCommand<Attachment> DeleteAttachmentCommand { get; }
|
|
|
|
|
public RelayCommand<EntryVm> SetCurrentEntryCommand { get; }
|
2020-04-14 13:44:07 +02:00
|
|
|
|
|
|
|
|
|
private DatabaseVm Database => _mediator.Send(new GetDatabaseQuery()).GetAwaiter().GetResult();
|
2020-05-11 19:22:41 +02:00
|
|
|
|
|
2020-03-27 13:27:29 +01:00
|
|
|
|
private readonly IMediator _mediator;
|
2020-04-21 19:12:26 +02:00
|
|
|
|
private readonly INavigationService _navigation;
|
2020-04-22 11:58:06 +02:00
|
|
|
|
private readonly IResourceProxy _resource;
|
|
|
|
|
private readonly IDialogService _dialog;
|
2020-04-23 19:00:38 +02:00
|
|
|
|
private readonly INotificationService _notification;
|
2020-05-06 18:54:39 +02:00
|
|
|
|
private readonly IFileProxy _file;
|
2020-05-18 14:14:28 +02:00
|
|
|
|
private readonly ICryptographyClient _cryptography;
|
2020-06-04 16:29:26 +02:00
|
|
|
|
private readonly IDateTime _dateTime;
|
2020-04-25 22:03:47 +02:00
|
|
|
|
private GroupVm _parent;
|
2020-06-04 16:29:26 +02:00
|
|
|
|
private EntryVm _current;
|
2020-04-16 14:08:50 +02:00
|
|
|
|
private int _selectedIndex;
|
2020-05-11 19:22:41 +02:00
|
|
|
|
private int _additionalFieldSelectedIndex = -1;
|
2020-05-14 13:32:44 +02:00
|
|
|
|
private bool _isDirty;
|
2020-05-11 10:53:14 +02:00
|
|
|
|
|
2020-06-04 16:29:26 +02:00
|
|
|
|
public EntryDetailVm(IMediator mediator, INavigationService navigation, IResourceProxy resource, IDialogService dialog, INotificationService notification, IFileProxy file, ICryptographyClient cryptography, IDateTime dateTime)
|
2017-09-13 18:37:44 +02:00
|
|
|
|
{
|
2020-03-27 13:27:29 +01:00
|
|
|
|
_mediator = mediator;
|
2020-04-21 19:12:26 +02:00
|
|
|
|
_navigation = navigation;
|
2020-04-22 11:58:06 +02:00
|
|
|
|
_resource = resource;
|
|
|
|
|
_dialog = dialog;
|
2020-04-23 19:00:38 +02:00
|
|
|
|
_notification = notification;
|
2020-05-06 18:54:39 +02:00
|
|
|
|
_file = file;
|
2020-05-18 14:14:28 +02:00
|
|
|
|
_cryptography = cryptography;
|
2020-06-04 16:29:26 +02:00
|
|
|
|
_dateTime = dateTime;
|
2018-06-20 18:41:56 +02:00
|
|
|
|
|
2020-04-14 13:44:07 +02:00
|
|
|
|
SaveCommand = new RelayCommand(async () => await SaveChanges(), () => Database.IsDirty);
|
2020-04-30 19:40:48 +02:00
|
|
|
|
MoveCommand = new RelayCommand<string>(async destination => await Move(destination), destination => _parent != null && !string.IsNullOrEmpty(destination) && destination != _parent.Id);
|
2020-04-15 19:06:13 +02:00
|
|
|
|
RestoreCommand = new RelayCommand(async () => await RestoreHistory());
|
2020-04-21 19:12:26 +02:00
|
|
|
|
DeleteCommand = new RelayCommand(async () => await AskForDelete());
|
2020-05-11 19:22:41 +02:00
|
|
|
|
AddAdditionalField = new RelayCommand(AddField, () => IsCurrentEntry);
|
2020-05-20 11:59:40 +02:00
|
|
|
|
DeleteAdditionalField = new RelayCommand<EntryFieldVm>(async field => await DeleteField(field), field => field != null && IsCurrentEntry);
|
2020-05-06 18:54:39 +02:00
|
|
|
|
OpenAttachmentCommand = new RelayCommand<Attachment>(async attachment => await OpenAttachment(attachment));
|
2020-05-07 12:11:12 +02:00
|
|
|
|
AddAttachmentCommand = new RelayCommand(async () => await AddAttachment(), () => IsCurrentEntry);
|
2020-05-11 19:22:41 +02:00
|
|
|
|
DeleteAttachmentCommand = new RelayCommand<Attachment>(async attachment => await DeleteAttachment(attachment), _ => IsCurrentEntry);
|
2020-06-04 16:29:26 +02:00
|
|
|
|
SetCurrentEntryCommand = new RelayCommand<EntryVm>(SetCurrentEntry, entry => entry != null);
|
2020-05-04 14:29:52 +02:00
|
|
|
|
|
|
|
|
|
MessengerInstance.Register<DatabaseSavedMessage>(this, _ => SaveCommand.RaiseCanExecuteChanged());
|
2020-05-12 17:14:30 +02:00
|
|
|
|
MessengerInstance.Register<EntryFieldValueChangedMessage>(this, async message => await SetFieldValue(message.FieldName, message.FieldValue, message.IsProtected));
|
|
|
|
|
MessengerInstance.Register<EntryFieldNameChangedMessage>(this, async message => await UpdateFieldName(message.OldName, message.NewName, message.Value, message.IsProtected));
|
2020-05-25 19:23:32 +02:00
|
|
|
|
MessengerInstance.Register<PasswordGeneratedMessage>(this, message => Password = message.Password);
|
2020-04-21 19:12:26 +02:00
|
|
|
|
}
|
2020-05-11 10:53:14 +02:00
|
|
|
|
|
2020-04-25 22:03:47 +02:00
|
|
|
|
public async Task Initialize(string entryId)
|
|
|
|
|
{
|
2020-05-07 12:11:12 +02:00
|
|
|
|
SelectedIndex = 0;
|
2020-06-04 16:29:26 +02:00
|
|
|
|
_current = await _mediator.Send(new GetEntryQuery { Id = entryId });
|
2020-06-08 14:16:54 +02:00
|
|
|
|
SetCurrentEntry(_current);
|
2020-06-04 16:29:26 +02:00
|
|
|
|
_parent = await _mediator.Send(new GetGroupQuery { Id = _current.ParentGroupId });
|
2020-06-08 14:16:54 +02:00
|
|
|
|
History = new ObservableCollection<IEntityVm> { _current };
|
2020-06-04 16:29:26 +02:00
|
|
|
|
foreach (var entry in _current.History.Skip(1))
|
2020-04-25 22:03:47 +02:00
|
|
|
|
{
|
|
|
|
|
History.Add(entry);
|
|
|
|
|
}
|
2020-05-14 13:32:44 +02:00
|
|
|
|
History.CollectionChanged += (sender, args) =>
|
|
|
|
|
{
|
|
|
|
|
SelectedIndex = 0;
|
|
|
|
|
SaveCommand.RaiseCanExecuteChanged();
|
|
|
|
|
};
|
2020-04-25 22:03:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-11 10:53:14 +02:00
|
|
|
|
public async Task AddHistory()
|
|
|
|
|
{
|
2020-06-08 14:16:54 +02:00
|
|
|
|
if (_isDirty && Database.IsOpen) await _mediator.Send(new AddHistoryCommand { Entry = History[0] as EntryVm });
|
2020-05-11 10:53:14 +02:00
|
|
|
|
}
|
2018-06-20 18:41:56 +02:00
|
|
|
|
|
2020-05-11 10:53:14 +02:00
|
|
|
|
public void GoToGroup(string groupId)
|
|
|
|
|
{
|
|
|
|
|
_navigation.NavigateTo(Constants.Navigation.GroupPage, new NavigationItem { Id = groupId });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task Move(string destination)
|
2017-10-18 10:32:51 +02:00
|
|
|
|
{
|
2020-04-28 15:20:47 +02:00
|
|
|
|
await _mediator.Send(new AddEntryCommand { ParentGroupId = destination, EntryId = Id });
|
|
|
|
|
await _mediator.Send(new RemoveEntryCommand { ParentGroupId = _parent.Id, EntryId = Id });
|
2020-04-28 18:54:37 +02:00
|
|
|
|
GoToGroup(destination);
|
2017-10-31 18:49:18 +01:00
|
|
|
|
}
|
2020-04-03 17:33:53 +02:00
|
|
|
|
|
2020-05-12 17:14:30 +02:00
|
|
|
|
private async Task SetFieldValue(string fieldName, object value, bool isProtected)
|
2018-06-18 18:40:00 +02:00
|
|
|
|
{
|
2020-05-20 11:59:40 +02:00
|
|
|
|
await _mediator.Send(new UpsertFieldCommand { EntryId = Id, FieldName = fieldName, FieldValue = value, IsProtected = isProtected});
|
2020-05-14 13:32:44 +02:00
|
|
|
|
UpdateDirtyStatus(true);
|
2020-04-14 19:59:19 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-12 17:14:30 +02:00
|
|
|
|
private async Task UpdateFieldName(string oldName, string newName, string value, bool isProtected)
|
2020-04-14 19:59:19 +02:00
|
|
|
|
{
|
2020-05-11 10:53:14 +02:00
|
|
|
|
if (!string.IsNullOrEmpty(oldName)) await _mediator.Send(new DeleteFieldCommand { EntryId = Id, FieldName = oldName });
|
2020-05-12 17:14:30 +02:00
|
|
|
|
await SetFieldValue(newName, value, isProtected);
|
2018-06-18 18:40:00 +02:00
|
|
|
|
}
|
2020-04-16 14:08:50 +02:00
|
|
|
|
|
2020-05-11 10:53:14 +02:00
|
|
|
|
private void AddField()
|
2020-05-06 18:54:39 +02:00
|
|
|
|
{
|
2020-05-20 11:59:40 +02:00
|
|
|
|
AdditionalFields.Add(new EntryFieldVm(_cryptography));
|
2020-05-11 10:53:14 +02:00
|
|
|
|
AdditionalFieldSelectedIndex = AdditionalFields.Count - 1;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-20 11:59:40 +02:00
|
|
|
|
private async Task DeleteField(EntryFieldVm field)
|
2020-05-11 10:53:14 +02:00
|
|
|
|
{
|
|
|
|
|
AdditionalFields.Remove(field);
|
|
|
|
|
if (!string.IsNullOrEmpty(field.Name))
|
|
|
|
|
{
|
|
|
|
|
await _mediator.Send(new DeleteFieldCommand {EntryId = Id, FieldName = field.Name});
|
2020-05-14 13:32:44 +02:00
|
|
|
|
UpdateDirtyStatus(true);
|
2020-05-11 10:53:14 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task AskForDelete()
|
|
|
|
|
{
|
|
|
|
|
if (IsCurrentEntry)
|
|
|
|
|
{
|
|
|
|
|
if (IsRecycleOnDelete)
|
|
|
|
|
{
|
|
|
|
|
await Delete();
|
2020-05-14 13:32:44 +02:00
|
|
|
|
_notification.Show(_resource.GetResourceValue("EntityDeleting"), string.Format(_resource.GetResourceValue("EntryRecycled"), Title));
|
2020-05-11 10:53:14 +02:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2020-05-14 13:32:44 +02:00
|
|
|
|
await _dialog.ShowMessage(
|
|
|
|
|
string.Format(_resource.GetResourceValue("EntryDeletingConfirmation"), Title),
|
|
|
|
|
_resource.GetResourceValue("EntityDeleting"),
|
2020-05-11 10:53:14 +02:00
|
|
|
|
_resource.GetResourceValue("EntityDeleteActionButton"),
|
|
|
|
|
_resource.GetResourceValue("EntityDeleteCancelButton"),
|
|
|
|
|
async isOk =>
|
|
|
|
|
{
|
|
|
|
|
if (isOk) await Delete();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2020-05-14 13:32:44 +02:00
|
|
|
|
await _dialog.ShowMessage(_resource.GetResourceValue("HistoryDeleteDescription"),
|
|
|
|
|
_resource.GetResourceValue("HistoryDeleteTitle"),
|
2020-05-11 10:53:14 +02:00
|
|
|
|
_resource.GetResourceValue("EntityDeleteActionButton"),
|
|
|
|
|
_resource.GetResourceValue("EntityDeleteCancelButton"), async isOk =>
|
|
|
|
|
{
|
|
|
|
|
if (!isOk) return;
|
2020-06-08 14:16:54 +02:00
|
|
|
|
await _mediator.Send(new DeleteHistoryCommand { Entry = History[0] as EntryVm, HistoryIndex = History.Count - SelectedIndex - 1 });
|
2020-05-11 10:53:14 +02:00
|
|
|
|
History.RemoveAt(SelectedIndex);
|
|
|
|
|
});
|
|
|
|
|
}
|
2020-05-06 18:54:39 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-04-16 14:08:50 +02:00
|
|
|
|
private async Task RestoreHistory()
|
2020-04-01 12:48:36 +02:00
|
|
|
|
{
|
2020-06-08 14:16:54 +02:00
|
|
|
|
await _mediator.Send(new RestoreHistoryCommand { Entry = History[0] as EntryVm, HistoryIndex = History.Count - SelectedIndex - 1 });
|
2020-06-04 16:29:26 +02:00
|
|
|
|
History.Insert(0, _current);
|
2020-04-01 12:48:36 +02:00
|
|
|
|
}
|
2020-04-22 11:58:06 +02:00
|
|
|
|
|
2020-04-14 13:44:07 +02:00
|
|
|
|
private async Task SaveChanges()
|
|
|
|
|
{
|
2020-04-14 19:59:19 +02:00
|
|
|
|
await AddHistory();
|
2020-05-04 12:48:27 +02:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
await _mediator.Send(new SaveDatabaseCommand());
|
|
|
|
|
}
|
|
|
|
|
catch (SaveException e)
|
|
|
|
|
{
|
|
|
|
|
MessengerInstance.Send(new SaveErrorMessage { Message = e.Message });
|
|
|
|
|
}
|
2020-05-14 13:32:44 +02:00
|
|
|
|
UpdateDirtyStatus(false);
|
2020-04-14 13:44:07 +02:00
|
|
|
|
}
|
2020-04-23 19:00:38 +02:00
|
|
|
|
|
|
|
|
|
private async Task Delete()
|
|
|
|
|
{
|
|
|
|
|
await _mediator.Send(new DeleteEntryCommand
|
|
|
|
|
{
|
|
|
|
|
EntryId = Id,
|
2020-06-04 16:29:26 +02:00
|
|
|
|
ParentGroupId = _current.ParentGroupId,
|
2020-04-23 19:00:38 +02:00
|
|
|
|
RecycleBinName = _resource.GetResourceValue("RecycleBinTitle")
|
|
|
|
|
});
|
2020-05-14 13:32:44 +02:00
|
|
|
|
_isDirty = false;
|
2020-04-23 19:00:38 +02:00
|
|
|
|
_navigation.GoBack();
|
|
|
|
|
}
|
2020-04-28 18:54:37 +02:00
|
|
|
|
|
2020-05-06 18:54:39 +02:00
|
|
|
|
private async Task OpenAttachment(Attachment attachment)
|
2020-04-28 18:54:37 +02:00
|
|
|
|
{
|
2020-05-06 18:54:39 +02:00
|
|
|
|
var extensionIndex = attachment.Name.LastIndexOf('.');
|
|
|
|
|
var fileInfo = await _file.CreateFile(attachment.Name,
|
|
|
|
|
attachment.Name.Substring(extensionIndex, attachment.Name.Length - extensionIndex),
|
|
|
|
|
string.Empty,
|
|
|
|
|
false);
|
|
|
|
|
if (fileInfo == null) return;
|
|
|
|
|
await _file.WriteBinaryContentsToFile(fileInfo.Id, attachment.Content);
|
2020-04-28 18:54:37 +02:00
|
|
|
|
}
|
2020-05-07 12:11:12 +02:00
|
|
|
|
|
|
|
|
|
private async Task AddAttachment()
|
|
|
|
|
{
|
|
|
|
|
var fileInfo = await _file.OpenFile(string.Empty, Domain.Common.Constants.Extensions.Any, false);
|
|
|
|
|
if (fileInfo == null) return;
|
|
|
|
|
var contents = await _file.ReadBinaryFile(fileInfo.Id);
|
2020-06-04 16:29:26 +02:00
|
|
|
|
await _mediator.Send(new AddAttachmentCommand { Entry = _current, AttachmentName = fileInfo.Name, AttachmentContent = contents });
|
2020-05-07 12:11:12 +02:00
|
|
|
|
Attachments.Add(new Attachment { Name = fileInfo.Name, Content = contents });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task DeleteAttachment(Attachment attachment)
|
|
|
|
|
{
|
2020-06-04 16:29:26 +02:00
|
|
|
|
await _mediator.Send(new DeleteAttachmentCommand { Entry = _current, AttachmentName = attachment.Name });
|
2020-05-07 12:11:12 +02:00
|
|
|
|
Attachments.Remove(attachment);
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-14 13:32:44 +02:00
|
|
|
|
private void UpdateDirtyStatus(bool isDirty)
|
|
|
|
|
{
|
|
|
|
|
SaveCommand.RaiseCanExecuteChanged();
|
|
|
|
|
_isDirty = isDirty;
|
|
|
|
|
}
|
2020-06-04 16:29:26 +02:00
|
|
|
|
|
|
|
|
|
private void SetCurrentEntry(EntryVm entry)
|
|
|
|
|
{
|
|
|
|
|
_current = entry;
|
|
|
|
|
AdditionalFields =
|
|
|
|
|
new ObservableCollection<EntryFieldVm>(
|
|
|
|
|
entry.AdditionalFields.Select(f =>
|
|
|
|
|
{
|
|
|
|
|
var field = new EntryFieldVm(_cryptography);
|
|
|
|
|
field.Initialize(f.Name, f.Value, f.IsProtected);
|
|
|
|
|
return field;
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
Attachments = new ObservableCollection<Attachment>(entry.Attachments.Select(f => new Attachment
|
|
|
|
|
{
|
|
|
|
|
Name = f.Key,
|
|
|
|
|
Content = f.Value
|
|
|
|
|
}));
|
|
|
|
|
Attachments.CollectionChanged += (sender, args) =>
|
|
|
|
|
{
|
|
|
|
|
UpdateDirtyStatus(true);
|
|
|
|
|
};
|
|
|
|
|
RaisePropertyChanged(string.Empty);
|
|
|
|
|
}
|
2017-09-12 18:20:32 +02:00
|
|
|
|
}
|
|
|
|
|
}
|