From b66e79f97c6cafcf54bfd26f9636dd19680d83de Mon Sep 17 00:00:00 2001 From: Geoffroy BONNEVILLE Date: Tue, 14 Apr 2020 19:59:19 +0200 Subject: [PATCH] History *works* WIP on save on entry page doesn't show last change --- ModernKeePass.Application/Application.csproj | 1 + .../Common/Interfaces/IDatabaseProxy.cs | 1 + .../Commands/AddHistory/AddHistoryCommand.cs | 28 +++++ .../Entry/Models/EntryVm.cs | 1 + .../KeePass/KeePassDatabaseClient.cs | 9 +- .../Converters/IconToSymbolConverter.cs | 109 ------------------ ModernKeePass/ViewModels/EntryDetailVm.cs | 15 ++- ModernKeePass/Views/EntryDetailPage.xaml.cs | 5 +- 8 files changed, 54 insertions(+), 115 deletions(-) create mode 100644 ModernKeePass.Application/Entry/Commands/AddHistory/AddHistoryCommand.cs diff --git a/ModernKeePass.Application/Application.csproj b/ModernKeePass.Application/Application.csproj index 5e83155..0ce2905 100644 --- a/ModernKeePass.Application/Application.csproj +++ b/ModernKeePass.Application/Application.csproj @@ -88,6 +88,7 @@ + diff --git a/ModernKeePass.Application/Common/Interfaces/IDatabaseProxy.cs b/ModernKeePass.Application/Common/Interfaces/IDatabaseProxy.cs index c7c9458..a805cbb 100644 --- a/ModernKeePass.Application/Common/Interfaces/IDatabaseProxy.cs +++ b/ModernKeePass.Application/Common/Interfaces/IDatabaseProxy.cs @@ -21,6 +21,7 @@ namespace ModernKeePass.Application.Common.Interfaces Task Open(byte[] file, Credentials credentials); Task ReOpen(byte[] file); + void AddHistory(string entryId); Task Create(Credentials credentials, string name, DatabaseVersion version = DatabaseVersion.V2); Task SaveDatabase(); Task SaveDatabase(byte[] newFileContents); diff --git a/ModernKeePass.Application/Entry/Commands/AddHistory/AddHistoryCommand.cs b/ModernKeePass.Application/Entry/Commands/AddHistory/AddHistoryCommand.cs new file mode 100644 index 0000000..44f67a6 --- /dev/null +++ b/ModernKeePass.Application/Entry/Commands/AddHistory/AddHistoryCommand.cs @@ -0,0 +1,28 @@ +using MediatR; +using ModernKeePass.Application.Common.Interfaces; +using ModernKeePass.Domain.Exceptions; + +namespace ModernKeePass.Application.Entry.Commands.AddHistory +{ + public class AddHistoryCommand : IRequest + { + public string EntryId { get; set; } + + public class AddHistoryCommandHandler : IRequestHandler + { + private readonly IDatabaseProxy _database; + + public AddHistoryCommandHandler(IDatabaseProxy database) + { + _database = database; + } + + public void Handle(AddHistoryCommand message) + { + if (!_database.IsOpen) throw new DatabaseClosedException(); + + _database.AddHistory(message.EntryId); + } + } + } +} \ No newline at end of file diff --git a/ModernKeePass.Application/Entry/Models/EntryVm.cs b/ModernKeePass.Application/Entry/Models/EntryVm.cs index 85aafae..7b31543 100644 --- a/ModernKeePass.Application/Entry/Models/EntryVm.cs +++ b/ModernKeePass.Application/Entry/Models/EntryVm.cs @@ -28,6 +28,7 @@ namespace ModernKeePass.Application.Entry.Models public bool HasExpirationDate { get; set; } public DateTimeOffset ExpirationDate { get; set; } public DateTimeOffset ModificationDate { get; set; } + public bool IsDirty { get; set; } public override string ToString() { diff --git a/ModernKeePass.Infrastructure/KeePass/KeePassDatabaseClient.cs b/ModernKeePass.Infrastructure/KeePass/KeePassDatabaseClient.cs index 8af147c..705a09d 100644 --- a/ModernKeePass.Infrastructure/KeePass/KeePassDatabaseClient.cs +++ b/ModernKeePass.Infrastructure/KeePass/KeePassDatabaseClient.cs @@ -222,8 +222,6 @@ namespace ModernKeePass.Infrastructure.KeePass public void UpdateEntry(string entryId, string fieldName, object fieldValue) { var pwEntry = _pwDatabase.RootGroup.FindEntry(BuildIdFromString(entryId), true); - pwEntry.Touch(true); - pwEntry.CreateBackup(null); switch (fieldName) { @@ -252,6 +250,13 @@ namespace ModernKeePass.Infrastructure.KeePass } } + public void AddHistory(string entryId) + { + var pwEntry = _pwDatabase.RootGroup.FindEntry(BuildIdFromString(entryId), true); + pwEntry.Touch(true); + pwEntry.CreateBackup(null); + } + public void UpdateGroup(string groupId) { throw new NotImplementedException(); diff --git a/ModernKeePass/Converters/IconToSymbolConverter.cs b/ModernKeePass/Converters/IconToSymbolConverter.cs index 16b50bd..503a788 100644 --- a/ModernKeePass/Converters/IconToSymbolConverter.cs +++ b/ModernKeePass/Converters/IconToSymbolConverter.cs @@ -10,119 +10,10 @@ namespace ModernKeePass.Converters public object Convert(object value, Type targetType, object parameter, string language) { return Enum.Parse(typeof(Symbol), value.ToString()); - /*var icon = (Icon)value; - switch (icon) - { - case Icon.Delete: return Symbol.Delete; - case Icon.Edit: return Symbol.Edit; - case Icon.Save: return Symbol.Save; - case Icon.Cancel: return Symbol.Cancel; - case Icon.Accept: return Symbol.Accept; - case Icon.Home: return Symbol.Home; - case Icon.Camera: return Symbol.Camera; - case Icon.Setting: return Symbol.Setting; - case Icon.Mail: return Symbol.Mail; - case Icon.Find: return Symbol.Find; - case Icon.Help: return Symbol.Help; - case Icon.Clock: return Symbol.Clock; - case Icon.Crop: return Symbol.Crop; - case Icon.World: return Symbol.World; - case Icon.Flag: return Symbol.Flag; - case Icon.PreviewLink: return Symbol.PreviewLink; - case Icon.Document: return Symbol.Document; - case Icon.ProtectedDocument: return Symbol.ProtectedDocument; - case Icon.ContactInfo: return Symbol.ContactInfo; - case Icon.ViewAll: return Symbol.ViewAll; - case Icon.Rotate: return Symbol.Rotate; - case Icon.List: return Symbol.List; - case Icon.Shop: return Symbol.Shop; - case Icon.BrowsePhotos: return Symbol.BrowsePhotos; - case Icon.Caption: return Symbol.Caption; - case Icon.Repair: return Symbol.Repair; - case Icon.Page: return Symbol.Page; - case Icon.Paste: return Symbol.Paste; - case Icon.Important: return Symbol.Important; - case Icon.SlideShow: return Symbol.SlideShow; - case Icon.MapDrive: return Symbol.MapDrive; - case Icon.ContactPresence: return Symbol.ContactPresence; - case Icon.Contact: return Symbol.Contact; - case Icon.Folder: return Symbol.Folder; - case Icon.View: return Symbol.View; - case Icon.Permissions: return Symbol.Permissions; - case Icon.Map: return Symbol.Map; - case Icon.CellPhone: return Symbol.CellPhone; - case Icon.OutlineStar: return Symbol.OutlineStar; - case Icon.Calculator: return Symbol.Calculator; - case Icon.Library: return Symbol.Library; - case Icon.SyncFolder: return Symbol.SyncFolder; - case Icon.GoToStart: return Symbol.GoToStart; - case Icon.ZeroBars: return Symbol.ZeroBars; - case Icon.FourBars: return Symbol.FourBars; - case Icon.Scan: return Symbol.Scan; - case Icon.ReportHacked: return Symbol.ReportHacked; - case Icon.Stop: return Symbol.Stop; - default: - throw new ArgumentOutOfRangeException(); - }*/ } public object ConvertBack(object value, Type targetType, object parameter, string language) { - /*var symbol = (Symbol)value; - var defaultIcon = parameter != null ? int.Parse(parameter as string) : -1; - switch (symbol) - { - case Symbol.Delete: return Icon.Delete; - case Symbol.Edit: return Icon.Edit; - case Symbol.Save: return Icon.Save; - case Symbol.Cancel: return Icon.Cancel; - case Symbol.Accept: return Icon.Accept; - case Symbol.Home: return Icon.Home; - case Symbol.Camera: return Icon.Camera; - case Symbol.Setting: return Icon.Setting; - case Symbol.Mail: return Icon.Mail; - case Symbol.Find: return Icon.Find; - case Symbol.Help: return Icon.Help; - case Symbol.Clock: return Icon.Clock; - case Symbol.Crop: return Icon.Crop; - case Symbol.World: return Icon.World; - case Symbol.Flag: return Icon.Flag; - case Symbol.PreviewLink: return Icon.PreviewLink; - case Symbol.Document: return Icon.Document; - case Symbol.ProtectedDocument: return Icon.ProtectedDocument; - case Symbol.ContactInfo: return Icon.ContactInfo; - case Symbol.ViewAll: return Icon.ViewAll; - case Symbol.Rotate: return Icon.Rotate; - case Symbol.List: return Icon.List; - case Symbol.Shop: return Icon.Shop; - case Symbol.BrowsePhotos: return Icon.BrowsePhotos; - case Symbol.Caption: return Icon.Caption; - case Symbol.Repair: return Icon.Repair; - case Symbol.Page: return Icon.Page; - case Symbol.Paste: return Icon.Paste; - case Symbol.Important: return Icon.Important; - case Symbol.SlideShow: return Icon.SlideShow; - case Symbol.MapDrive: return Icon.MapDrive; - case Symbol.ContactPresence: return Icon.ContactPresence; - case Symbol.Contact: return Icon.Contact; - case Symbol.Folder: return Icon.Folder; - case Symbol.View: return Icon.View; - case Symbol.Permissions: return Icon.Permissions; - case Symbol.Map: return Icon.Map; - case Symbol.CellPhone: return Icon.CellPhone; - case Symbol.OutlineStar: return Icon.OutlineStar; - case Symbol.Calculator: return Icon.Calculator; - case Symbol.Library: return Icon.Library; - case Symbol.SyncFolder: return Icon.SyncFolder; - case Symbol.GoToStart: return Icon.GoToStart; - case Symbol.ZeroBars: return Icon.ZeroBars; - case Symbol.FourBars: return Icon.FourBars; - case Symbol.Scan: return Icon.Scan; - case Symbol.ReportHacked: return Icon.ReportHacked; - case Symbol.Stop: return Icon.Stop; - default: return defaultIcon; - }*/ - return Enum.Parse(typeof(Icon), value.ToString()); } } diff --git a/ModernKeePass/ViewModels/EntryDetailVm.cs b/ModernKeePass/ViewModels/EntryDetailVm.cs index 2f3ee01..21f54b6 100644 --- a/ModernKeePass/ViewModels/EntryDetailVm.cs +++ b/ModernKeePass/ViewModels/EntryDetailVm.cs @@ -9,6 +9,7 @@ using Microsoft.Extensions.DependencyInjection; using ModernKeePass.Application.Database.Commands.SaveDatabase; using ModernKeePass.Application.Database.Models; using ModernKeePass.Application.Database.Queries.GetDatabase; +using ModernKeePass.Application.Entry.Commands.AddHistory; using ModernKeePass.Application.Entry.Commands.SetFieldValue; using ModernKeePass.Application.Entry.Models; using ModernKeePass.Application.Entry.Queries.GetEntry; @@ -83,7 +84,7 @@ namespace ModernKeePass.ViewModels { _entry.Password = value; SetFieldValue(nameof(Password), value).Wait(); - OnPropertyChanged(); + OnPropertyChanged(nameof(Password)); OnPropertyChanged(nameof(PasswordComplexityIndicator)); } } @@ -246,7 +247,7 @@ namespace ModernKeePass.ViewModels public async Task MarkForDelete(string recycleBinTitle) { - await _mediator.Send(new DeleteEntryCommand {EntryId = _entry.Id, ParentGroupId = _entry.ParentGroupId, RecycleBinName = recycleBinTitle}); + await _mediator.Send(new DeleteEntryCommand {EntryId = Id, ParentGroupId = _entry.ParentGroupId, RecycleBinName = recycleBinTitle}); } public async Task Move(GroupVm destination) @@ -259,18 +260,28 @@ namespace ModernKeePass.ViewModels { await _mediator.Send(new SetFieldValueCommand { EntryId = Id, FieldName = fieldName, FieldValue = value }); ((RelayCommand)SaveCommand).RaiseCanExecuteChanged(); + _entry.IsDirty = true; + } + + public async Task AddHistory() + { + if (_entry.IsDirty) await _mediator.Send(new AddHistoryCommand {EntryId = Id}); } internal void SetEntry(EntryVm entry, int index) { _entry = entry; IsSelected = index == 0; + OnPropertyChanged(); } private async Task SaveChanges() { + await AddHistory(); await _mediator.Send(new SaveDatabaseCommand()); ((RelayCommand)SaveCommand).RaiseCanExecuteChanged(); + _entry.IsDirty = false; } + } } diff --git a/ModernKeePass/Views/EntryDetailPage.xaml.cs b/ModernKeePass/Views/EntryDetailPage.xaml.cs index 4d0a9e3..054b6fb 100644 --- a/ModernKeePass/Views/EntryDetailPage.xaml.cs +++ b/ModernKeePass/Views/EntryDetailPage.xaml.cs @@ -46,8 +46,9 @@ namespace ModernKeePass.Views if (args != null) DataContext = new EntryDetailVm(args); } - protected override void OnNavigatedFrom(NavigationEventArgs e) + protected override async void OnNavigatedFrom(NavigationEventArgs e) { + await Model.AddHistory(); NavigationHelper.OnNavigatedFrom(e); } @@ -69,7 +70,7 @@ namespace ModernKeePass.Views case -1: return; default: - var entry = listView?.SelectedItem as Application.Entry.Models.EntryVm; + var entry = listView.SelectedItem as Application.Entry.Models.EntryVm; Model.SetEntry(entry, index); break; }