Added the option to close DB without saving

Changed the way recent files are retrieved
Stopped showing the DB Closed exception on suspend
Reordering entries works
Moved code from infra to application
Cleanup
This commit is contained in:
Geoffroy BONNEVILLE
2020-04-09 19:43:06 +02:00
parent 14fd4634db
commit d972b6cb5a
35 changed files with 141 additions and 100 deletions

View File

@@ -119,7 +119,7 @@
<Compile Include="Group\Commands\AddGroup\AddGroupCommand.cs" />
<Compile Include="Group\Commands\CreateEntry\CreateEntryCommand.cs" />
<Compile Include="Group\Commands\CreateGroup\CreateGroupCommand.cs" />
<Compile Include="Group\Commands\InsertEntry\InsertEntryCommand.cs" />
<Compile Include="Group\Commands\MoveEntry\MoveEntryCommand.cs" />
<Compile Include="Group\Commands\RemoveEntry\RemoveEntryCommand.cs" />
<Compile Include="Group\Commands\RemoveGroup\RemoveGroupCommand.cs" />
<Compile Include="Group\Commands\SortEntries\SortEntriesCommand.cs" />

View File

@@ -27,7 +27,7 @@ namespace ModernKeePass.Application.Common.Interfaces
void CloseDatabase();
Task AddEntry(string parentGroupId, string entryId);
Task InsertEntry(string parentGroupId, string entryId, int index);
Task MoveEntry(string parentGroupId, string entryId, int index);
Task AddGroup(string parentGroupId, string groupId);
void UpdateEntry(string entryId, string fieldName, object fieldValue);
void UpdateGroup(string groupId);

View File

@@ -8,7 +8,7 @@ namespace ModernKeePass.Application.Common.Interfaces
{
int EntryCount { get; }
Task<FileInfo> Get(string token, bool updateAccessTime = false);
Task<IEnumerable<FileInfo>> GetAll();
IEnumerable<FileInfo> GetAll();
Task Add(FileInfo recentItem);
void ClearAll();
}

View File

@@ -1,6 +1,7 @@
using MediatR;
using ModernKeePass.Application.Common.Interfaces;
using ModernKeePass.Application.Database.Models;
using ModernKeePass.Domain.Common;
namespace ModernKeePass.Application.Database.Queries.GetDatabase
{
@@ -26,7 +27,7 @@ namespace ModernKeePass.Application.Database.Queries.GetDatabase
database.Name = _databaseProxy.Name;
database.RootGroupId = _databaseProxy.RootGroupId;
database.IsRecycleBinEnabled = _databaseProxy.IsRecycleBinEnabled;
database.RecycleBinId = _databaseProxy.RecycleBinId;
database.RecycleBinId = _databaseProxy.RecycleBinId == Constants.EmptyId ? null : _databaseProxy.RecycleBinId;
database.Compression = _databaseProxy.Compression;
database.CipherId = _databaseProxy.CipherId;
database.KeyDerivationId = _databaseProxy.KeyDerivationId;

View File

@@ -5,28 +5,28 @@ using ModernKeePass.Application.Entry.Models;
using ModernKeePass.Application.Group.Models;
using ModernKeePass.Domain.Exceptions;
namespace ModernKeePass.Application.Group.Commands.InsertEntry
namespace ModernKeePass.Application.Group.Commands.MoveEntry
{
public class InsertEntryCommand : IRequest
public class MoveEntryCommand : IRequest
{
public GroupVm ParentGroup { get; set; }
public EntryVm Entry { get; set; }
public int Index { get; set; }
public class InsertEntryCommandHandler : IAsyncRequestHandler<InsertEntryCommand>
public class MoveEntryCommandHandler : IAsyncRequestHandler<MoveEntryCommand>
{
private readonly IDatabaseProxy _database;
public InsertEntryCommandHandler(IDatabaseProxy database)
public MoveEntryCommandHandler(IDatabaseProxy database)
{
_database = database;
}
public async Task Handle(InsertEntryCommand message)
public async Task Handle(MoveEntryCommand message)
{
if (!_database.IsOpen) throw new DatabaseClosedException();
await _database.InsertEntry(message.ParentGroup.Id, message.Entry.Id, message.Index);
await _database.MoveEntry(message.ParentGroup.Id, message.Entry.Id, message.Index);
message.ParentGroup.Entries.Insert(message.Index, message.Entry);
}
}

View File

@@ -1,5 +1,6 @@
using MediatR;
using ModernKeePass.Application.Common.Interfaces;
using ModernKeePass.Domain.Common;
using ModernKeePass.Domain.Exceptions;
namespace ModernKeePass.Application.Parameters.Commands.SetRecycleBin
@@ -19,8 +20,8 @@ namespace ModernKeePass.Application.Parameters.Commands.SetRecycleBin
public void Handle(SetRecycleBinCommand message)
{
if (_database.IsOpen) _database.RecycleBinId = message.RecycleBinId;
else throw new DatabaseClosedException();
if (!_database.IsOpen) throw new DatabaseClosedException();
_database.RecycleBinId = message.RecycleBinId ?? Constants.EmptyId;
}
}
}

View File

@@ -0,0 +1,7 @@
namespace ModernKeePass.Domain.Common
{
public static class Constants
{
public static string EmptyId => "00000000000000000000000000000000";
}
}

View File

@@ -76,6 +76,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="AOP\NotifyPropertyChangedBase.cs" />
<Compile Include="Common\Constants.cs" />
<Compile Include="Dtos\Credentials.cs" />
<Compile Include="Dtos\FileInfo.cs" />
<Compile Include="Dtos\PasswordGenerationOptions.cs" />

View File

@@ -45,18 +45,13 @@ namespace ModernKeePass.Infrastructure.KeePass
public string RecycleBinId
{
get
get
{
if (_pwDatabase.RecycleBinEnabled && !_pwDatabase.RecycleBinUuid.Equals(PwUuid.Zero))
{
return _pwDatabase.RecycleBinUuid.ToHexString();
}
return null;
return _pwDatabase.RecycleBinUuid.ToHexString();
}
set
{
_pwDatabase.RecycleBinUuid = value != null ? BuildIdFromString(value) : PwUuid.Zero;
_pwDatabase.RecycleBinUuid = BuildIdFromString(value);
_pwDatabase.RecycleBinChanged = _dateTime.Now;
}
}
@@ -152,7 +147,7 @@ namespace ModernKeePass.Infrastructure.KeePass
});
}
public async Task<byte[]> SaveDatabase(byte[] newFileContents)
public async Task<byte[]> SaveDatabase(byte[] newFileContents)
{
return await Task.Run(() =>
{
@@ -176,12 +171,15 @@ namespace ModernKeePass.Infrastructure.KeePass
});
}
public async Task InsertEntry(string parentGroupId, string entryId, int index)
public async Task MoveEntry(string parentGroupId, string entryId, int index)
{
await Task.Run(() =>
{
var parentPwGroup = _pwDatabase.RootGroup.FindGroup(BuildIdFromString(parentGroupId), true);
var pwEntry = _pwDatabase.RootGroup.FindEntry(BuildIdFromString(entryId), true);
var currentIndex = (uint)parentPwGroup.Entries.IndexOf(pwEntry);
parentPwGroup.Entries.RemoveAt(currentIndex);
parentPwGroup.Entries.Insert((uint)index, pwEntry);
});
}

View File

@@ -12,15 +12,15 @@ namespace ModernKeePass.Infrastructure.UWP
{
public async Task<byte[]> OpenBinaryFile(string path)
{
var file = await StorageApplicationPermissions.FutureAccessList.GetFileAsync(path);
var result = await FileIO.ReadBufferAsync(file);
var file = await StorageApplicationPermissions.FutureAccessList.GetFileAsync(path).AsTask();
var result = await FileIO.ReadBufferAsync(file).AsTask();
return result.ToArray();
}
public async Task<IList<string>> OpenTextFile(string path)
{
var file = await StorageApplicationPermissions.FutureAccessList.GetFileAsync(path);
var result = await FileIO.ReadLinesAsync(file);
var file = await StorageApplicationPermissions.FutureAccessList.GetFileAsync(path).AsTask();
var result = await FileIO.ReadLinesAsync(file).AsTask();
return result;
}
@@ -31,8 +31,8 @@ namespace ModernKeePass.Infrastructure.UWP
public async Task WriteBinaryContentsToFile(string path, byte[] contents)
{
var file = await StorageApplicationPermissions.FutureAccessList.GetFileAsync(path);
await FileIO.WriteBytesAsync(file, contents);
var file = await StorageApplicationPermissions.FutureAccessList.GetFileAsync(path).AsTask();
await FileIO.WriteBytesAsync(file, contents).AsTask();
}
}
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Windows.Storage.AccessCache;
using ModernKeePass.Application.Common.Interfaces;
@@ -10,51 +11,52 @@ namespace ModernKeePass.Infrastructure.UWP
public class UwpRecentFilesClient: IRecentProxy
{
private readonly StorageItemMostRecentlyUsedList _mru = StorageApplicationPermissions.MostRecentlyUsedList;
private readonly StorageItemAccessList _fal = StorageApplicationPermissions.FutureAccessList;
public int EntryCount => _mru.Entries.Count;
public async Task<FileInfo> Get(string token, bool updateAccessTime = false)
{
var file = await _mru.GetFileAsync(token, updateAccessTime ? AccessCacheOptions.None : AccessCacheOptions.SuppressAccessTimeUpdate);
StorageApplicationPermissions.FutureAccessList.AddOrReplace(token, file);
return new FileInfo
try
{
Id = token,
Name = file.DisplayName,
Path = file.Path
};
var file = await _mru.GetFileAsync(token,
updateAccessTime ? AccessCacheOptions.None : AccessCacheOptions.SuppressAccessTimeUpdate).AsTask().ConfigureAwait(false);
_fal.AddOrReplace(token, file);
return new FileInfo
{
Id = token,
Name = file.DisplayName,
Path = file.Path
};
}
catch (Exception)
{
_mru.Remove(token);
return null;
}
}
public async Task<IEnumerable<FileInfo>> GetAll()
public IEnumerable<FileInfo> GetAll()
{
var result = new List<FileInfo>();
foreach (var entry in _mru.Entries)
return _mru.Entries.Select(e => new FileInfo
{
try
{
var recentItem = await Get(entry.Token);
result.Add(recentItem);
}
catch (Exception)
{
_mru.Remove(entry.Token);
}
}
return result;
Id = e.Token,
Name = e.Metadata?.Substring(e.Metadata.LastIndexOf("\\", StringComparison.OrdinalIgnoreCase) + 1),
Path = e.Metadata
});
}
public async Task Add(FileInfo recentItem)
{
var file = await StorageApplicationPermissions.FutureAccessList.GetFileAsync(recentItem.Id);
_mru.Add(file);
var file = await _fal.GetFileAsync(recentItem.Id).AsTask();
_mru.Add(file, file.Path);
}
public void ClearAll()
{
for (var i = _mru.Entries.Count; i > 0; i--)
foreach (var entry in _mru.Entries)
{
var entry = _mru.Entries[i];
StorageApplicationPermissions.FutureAccessList.Remove(entry.Token);
if (_fal.ContainsItem(entry.Token)) _fal.Remove(entry.Token);
_mru.Remove(entry.Token);
}
}

View File

@@ -34,7 +34,7 @@ namespace ModernKeePass.Actions
DependencyProperty.Register("Command", typeof(ICommand), typeof(DeleteEntityAction),
new PropertyMetadata(null));
public DeleteEntityAction() : this(App.Services.GetService<IMediator>()) { }
public DeleteEntityAction() : this(App.Services.GetRequiredService<IMediator>()) { }
public DeleteEntityAction(IMediator mediator)
{
@@ -58,7 +58,7 @@ namespace ModernKeePass.Actions
ToastNotificationHelper.ShowMovedToast(Entity, resource.GetResourceValue("EntityDeleting"), text);
Entity.MarkForDelete(resource.GetResourceValue("RecycleBinTitle"));
Command.Execute(null);
}, null).GetAwaiter();
}, null).GetAwaiter().GetResult();
return null;
}

View File

@@ -101,7 +101,7 @@ namespace ModernKeePass
savePicker.FileTypeChoices.Add(_resource.GetResourceValue("MessageDialogSaveErrorFileTypeDesc"),
new List<string> {".kdbx"});
var file = await savePicker.PickSaveFileAsync();
var file = await savePicker.PickSaveFileAsync().AsTask();
if (file != null)
{
var token = StorageApplicationPermissions.FutureAccessList.Add(file);
@@ -213,15 +213,20 @@ namespace ModernKeePass
{
if (_settings.GetSetting("SaveSuspend", true))
{
await _mediator.Send(new SaveDatabaseCommand());
await _mediator.Send(new SaveDatabaseCommand()).ConfigureAwait(false);
}
await _mediator.Send(new CloseDatabaseCommand());
await _mediator.Send(new CloseDatabaseCommand()).ConfigureAwait(false);
}
catch (DatabaseClosedException)
{
// Do nothing on purpose
}
catch (Exception exception)
{
ToastNotificationHelper.ShowErrorToast(exception);
}
await SuspensionManager.SaveAsync();
await SuspensionManager.SaveAsync().ConfigureAwait(false);
deferral.Complete();
}

View File

@@ -15,7 +15,7 @@ namespace ModernKeePass.Common
messageDialog.Commands.Add(new UICommand(actionButtonText, actionCommand));
// Show the message dialog
await messageDialog.ShowAsync();
await messageDialog.ShowAsync().AsTask();
}
public static async Task ShowErrorDialog(Exception exception)
@@ -25,7 +25,7 @@ namespace ModernKeePass.Common
var messageDialog = CreateBasicDialog(exception.Message, exception.StackTrace, "OK");
// Show the message dialog
await messageDialog.ShowAsync();
await messageDialog.ShowAsync().AsTask();;
}
public static async Task ShowNotificationDialog(string title, string message)
@@ -33,7 +33,7 @@ namespace ModernKeePass.Common
var dialog = CreateBasicDialog(title, message, "OK");
// Show the message dialog
await dialog.ShowAsync();
await dialog.ShowAsync().AsTask();;
}
private static MessageDialog CreateBasicDialog(string title, string message, string dismissActionText, UICommandInvokedHandler cancelCommand = null)

View File

@@ -492,4 +492,10 @@
<data name="NewImportFormat.Text" xml:space="preserve">
<value>Format</value>
</data>
<data name="CloseButton.Content" xml:space="preserve">
<value>Close without saving</value>
</data>
<data name="CloseDesc.Text" xml:space="preserve">
<value>This will close the currently opened database without saving the changes.</value>
</data>
</root>

View File

@@ -495,4 +495,10 @@
<data name="NewImportFormatHelp.Text" xml:space="preserve">
<value>Le fichier CSV doit être formatté de la façon suivante: Nom du compte;Login;Mot de passe:URL;Commentaires</value>
</data>
<data name="CloseButton.Content" xml:space="preserve">
<value>Fermer sans sauvegarder</value>
</data>
<data name="CloseDesc.Text" xml:space="preserve">
<value>Cela va fermer la base de données ouverte sans sauvegarder les changements.</value>
</data>
</root>

View File

@@ -115,7 +115,7 @@ namespace ModernKeePass.ViewModels
private readonly ISettingsProxy _settings;
private readonly ResourceHelper _resource;
public CompositeKeyVm() : this(App.Services.GetService<IMediator>(), App.Services.GetService<ISettingsProxy>()) { }
public CompositeKeyVm() : this(App.Services.GetRequiredService<IMediator>(), App.Services.GetRequiredService<ISettingsProxy>()) { }
public CompositeKeyVm(IMediator mediator, ISettingsProxy settings)
{

View File

@@ -219,7 +219,7 @@ namespace ModernKeePass.ViewModels
public EntryDetailVm() { }
internal EntryDetailVm(string entryId, bool isNewEntry = false) : this(entryId, App.Services.GetService<IMediator>(), isNewEntry) { }
internal EntryDetailVm(string entryId, bool isNewEntry = false) : this(entryId, App.Services.GetRequiredService<IMediator>(), isNewEntry) { }
public EntryDetailVm(string entryId, IMediator mediator, bool isNewEntry = false)
{
@@ -232,7 +232,7 @@ namespace ModernKeePass.ViewModels
if (isNewEntry) GeneratePassword().GetAwaiter().GetResult();
IsSelected = true;
SaveCommand = new RelayCommand(() => _mediator.Send(new SaveDatabaseCommand()));
SaveCommand = new RelayCommand(async () => await _mediator.Send(new SaveDatabaseCommand()));
GeneratePasswordCommand = new RelayCommand(async () => await GeneratePassword());
UndoDeleteCommand = new RelayCommand(async () => await Move(_parent), () => _parent != null);
}

View File

@@ -16,8 +16,7 @@ using ModernKeePass.Application.Group.Commands.AddGroup;
using ModernKeePass.Application.Group.Commands.CreateEntry;
using ModernKeePass.Application.Group.Commands.CreateGroup;
using ModernKeePass.Application.Group.Commands.DeleteGroup;
using ModernKeePass.Application.Group.Commands.InsertEntry;
using ModernKeePass.Application.Group.Commands.RemoveEntry;
using ModernKeePass.Application.Group.Commands.MoveEntry;
using ModernKeePass.Application.Group.Commands.RemoveGroup;
using ModernKeePass.Application.Group.Commands.SortEntries;
using ModernKeePass.Application.Group.Commands.SortGroups;
@@ -33,9 +32,9 @@ namespace ModernKeePass.ViewModels
{
public class GroupDetailVm : NotifyPropertyChangedBase, IVmEntity, ISelectableModel
{
public ObservableCollection<EntryVm> Entries => new ObservableCollection<EntryVm>(_group.Entries);
public ObservableCollection<EntryVm> Entries { get; }
public ObservableCollection<GroupVm> Groups => new ObservableCollection<GroupVm>(_group.SubGroups);
public ObservableCollection<GroupVm> Groups { get; }
public IEnumerable<EntryVm> SubEntries
{
@@ -124,7 +123,7 @@ namespace ModernKeePass.ViewModels
public GroupDetailVm() {}
internal GroupDetailVm(string groupId) : this(groupId, App.Services.GetService<IMediator>())
internal GroupDetailVm(string groupId) : this(groupId, App.Services.GetRequiredService<IMediator>())
{ }
public GroupDetailVm(string groupId, IMediator mediator, bool isEditMode = false)
@@ -141,12 +140,14 @@ namespace ModernKeePass.ViewModels
SaveCommand = new RelayCommand(async () => await _mediator.Send(new SaveDatabaseCommand()));
SortEntriesCommand = new RelayCommand(async () =>
await SortEntriesAsync().ConfigureAwait(false), () => IsEditMode);
await SortEntriesAsync(), () => IsEditMode);
SortGroupsCommand = new RelayCommand(async () =>
await SortGroupsAsync().ConfigureAwait(false), () => IsEditMode);
await SortGroupsAsync(), () => IsEditMode);
UndoDeleteCommand = new RelayCommand(async () => await Move(_parent), () => _parent != null);
Entries = new ObservableCollection<EntryVm>(_group.Entries);
Entries.CollectionChanged += Entries_CollectionChanged;
Groups = new ObservableCollection<GroupVm>(_group.SubGroups);
}
private async void Entries_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
@@ -156,7 +157,6 @@ namespace ModernKeePass.ViewModels
case NotifyCollectionChangedAction.Remove:
var oldIndex = e.OldStartingIndex;
_reorderedEntry = _group.Entries[oldIndex];
await _mediator.Send(new RemoveEntryCommand {Entry = _reorderedEntry, ParentGroup = _group});
break;
case NotifyCollectionChangedAction.Add:
if (_reorderedEntry == null)
@@ -166,7 +166,7 @@ namespace ModernKeePass.ViewModels
}
else
{
await _mediator.Send(new InsertEntryCommand {Entry = _reorderedEntry, ParentGroup = _group, Index = e.NewStartingIndex});
await _mediator.Send(new MoveEntryCommand {Entry = _reorderedEntry, ParentGroup = _group, Index = e.NewStartingIndex});
}
break;
}

View File

@@ -38,7 +38,7 @@ namespace ModernKeePass.ViewModels
set { SetProperty(ref _isSelected, value); }
}
public RecentItemVm(FileInfo file): this(App.Services.GetService<IRecentProxy>(), file) {}
public RecentItemVm(FileInfo file): this(App.Services.GetRequiredService<IRecentProxy>(), file) {}
public RecentItemVm(IRecentProxy recent, FileInfo file)
{
_recent = recent;

View File

@@ -77,7 +77,7 @@ namespace ModernKeePass.ViewModels
}
}
public SettingsDatabaseVm() : this(App.Services.GetService<IMediator>()) { }
public SettingsDatabaseVm() : this(App.Services.GetRequiredService<IMediator>()) { }
public SettingsDatabaseVm(IMediator mediator)
{

View File

@@ -8,7 +8,7 @@ namespace ModernKeePass.ViewModels
{
private readonly ISettingsProxy _settings;
public SettingsNewVm() : this(App.Services.GetService<ISettingsProxy>())
public SettingsNewVm() : this(App.Services.GetRequiredService<ISettingsProxy>())
{ }
public SettingsNewVm(ISettingsProxy settings)

View File

@@ -7,7 +7,7 @@ namespace ModernKeePass.ViewModels
{
private readonly ISettingsProxy _settings;
public SettingsSaveVm() : this(App.Services.GetService<ISettingsProxy>())
public SettingsSaveVm() : this(App.Services.GetRequiredService<ISettingsProxy>())
{ }
public SettingsSaveVm(ISettingsProxy settings)

View File

@@ -50,7 +50,7 @@ namespace ModernKeePass.ViewModels
public MainVm() {}
internal MainVm(Frame referenceFrame, Frame destinationFrame, FileInfo databaseFile = null) : this(referenceFrame, destinationFrame,
App.Services.GetService<IMediator>(), App.Services.GetService<IRecentProxy>(), databaseFile)
App.Services.GetRequiredService<IMediator>(), App.Services.GetRequiredService<IRecentProxy>(), databaseFile)
{ }
public MainVm(Frame referenceFrame, Frame destinationFrame, IMediator mediator, IRecentProxy recent, FileInfo databaseFile = null)

View File

@@ -32,7 +32,7 @@ namespace ModernKeePass.ViewModels
private set { SetProperty(ref _path, value); }
}
public OpenVm(): this(App.Services.GetService<IRecentProxy>()) { }
public OpenVm(): this(App.Services.GetRequiredService<IRecentProxy>()) { }
public OpenVm(IRecentProxy recent)
{

View File

@@ -1,5 +1,6 @@
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
using Microsoft.Extensions.DependencyInjection;
using ModernKeePass.Application.Common.Interfaces;
@@ -41,15 +42,15 @@ namespace ModernKeePass.ViewModels
public ICommand ClearAllCommand { get; }
public RecentVm() : this (App.Services.GetService<IRecentProxy>())
public RecentVm() : this (App.Services.GetRequiredService<IRecentProxy>())
{ }
public RecentVm(IRecentProxy recent)
{
_recent = recent;
ClearAllCommand = new RelayCommand(ClearAll);
var recentItems = _recent.GetAll().GetAwaiter().GetResult().Select(r => new RecentItemVm(r));
var recentItems = _recent.GetAll().Select(r => new RecentItemVm(r));
RecentItems = new ObservableCollection<RecentItemVm>(recentItems);
if (RecentItems.Count > 0)
SelectedItem = RecentItems[0];

View File

@@ -11,7 +11,7 @@ namespace ModernKeePass.ViewModels
public class SaveVm
{
private readonly IMediator _mediator;
public SaveVm() : this(App.Services.GetService<IMediator>()) { }
public SaveVm() : this(App.Services.GetRequiredService<IMediator>()) { }
public SaveVm(IMediator mediator)
{
@@ -21,7 +21,7 @@ namespace ModernKeePass.ViewModels
public async Task Save(bool close = true)
{
await _mediator.Send(new SaveDatabaseCommand());
if (close) await _mediator.Send(new CloseDatabaseCommand());
if (close) await Close();
}
public async Task Save(StorageFile file)
@@ -29,5 +29,10 @@ namespace ModernKeePass.ViewModels
var token = StorageApplicationPermissions.FutureAccessList.Add(file);
await _mediator.Send(new SaveDatabaseCommand { FilePath = token });
}
public async Task Close()
{
await _mediator.Send(new CloseDatabaseCommand());
}
}
}

View File

@@ -43,7 +43,7 @@ namespace ModernKeePass.ViewModels
}
}
public SettingsVm() : this(App.Services.GetService<IMediator>()) { }
public SettingsVm() : this(App.Services.GetRequiredService<IMediator>()) { }
public SettingsVm(IMediator mediator)
{

View File

@@ -27,7 +27,7 @@ namespace ModernKeePass.Views
picker.FileTypeFilter.Add(".csv");
// Application now has read/write access to the picked file
var file = await picker.PickSingleFileAsync();
var file = await picker.PickSingleFileAsync().AsTask();
if (file == null) return;
}

View File

@@ -34,7 +34,7 @@ namespace ModernKeePass.Views
};
savePicker.FileTypeChoices.Add("KeePass 2.x database", new List<string> { ".kdbx" });
var file = await savePicker.PickSaveFileAsync();
var file = await savePicker.PickSaveFileAsync().AsTask();
if (file == null) return;
var token = StorageApplicationPermissions.FutureAccessList.Add(file);
@@ -72,7 +72,7 @@ namespace ModernKeePass.Views
picker.FileTypeFilter.Add(Model.ImportFileExtensionFilter);
// Application now has read/write access to the picked file
Model.ImportFile = await picker.PickSingleFileAsync();
Model.ImportFile = await picker.PickSingleFileAsync().AsTask();
if (Model.ImportFile != null) ImportFileLink.Content = Model.ImportFile.Name;
}
}

View File

@@ -42,7 +42,7 @@ namespace ModernKeePass.Views
picker.FileTypeFilter.Add(".kdbx");
// Application now has read/write access to the picked file
var file = await picker.PickSingleFileAsync();
var file = await picker.PickSingleFileAsync().AsTask();
if (file == null) return;

View File

@@ -12,12 +12,10 @@
mc:Ignorable="d">
<Page.Resources>
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<CollectionViewSource x:Name="RecentItemsSource" Source="{Binding RecentItems}" />
<viewModels:RecentVm x:Key="ViewModel"/>
<!--<CollectionViewSource x:Name="RecentItemsSource" Source="{Binding RecentItems}" />-->
</Page.Resources>
<Page.DataContext>
<viewModels:RecentVm/>
</Page.DataContext>
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}" DataContext="{StaticResource ViewModel}">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="*" />
@@ -29,7 +27,7 @@
</StackPanel>
</HyperlinkButton>
<ListView Grid.Row="1"
ItemsSource="{Binding Source={StaticResource RecentItemsSource}}"
ItemsSource="{Binding RecentItems}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
ItemContainerStyle="{StaticResource ListViewLeftIndicatorItemExpanded}">
<ListView.ItemTemplate>
@@ -47,8 +45,10 @@
<TextBlock Grid.Row="1" Text="{Binding Path}" Padding="5,0,0,0" FontSize="10" />
<userControls:CompositeKeyUserControl Grid.Row="2" x:Name="DatabaseUserControl" x:Uid="CompositeKeyOpenButton" HorizontalAlignment="Stretch" MinWidth="400" Margin="0,10,0,0" Visibility="{Binding IsSelected, Converter={StaticResource BooleanToVisibilityConverter}}" DatabaseFilePath="{Binding Token}">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="ValidationChecked">
<core:EventTriggerBehavior EventName="ValidationChecking">
<core:CallMethodAction TargetObject="{Binding}" MethodName="UpdateAccessTime" />
</core:EventTriggerBehavior>
<core:EventTriggerBehavior EventName="ValidationChecked">
<core:NavigateToPageAction TargetPage="ModernKeePass.Views.GroupDetailPage" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>

View File

@@ -15,5 +15,7 @@
<TextBlock x:Uid="SaveDesc" Style="{StaticResource BodyTextBlockStyle}" Margin="15,0,0,30" />
<HyperlinkButton x:Uid="SaveAsButton" Click="SaveAsButton_OnClick" Foreground="{StaticResource MainColor}" Style="{StaticResource MainColorHyperlinkButton}" />
<TextBlock x:Uid="SaveAsDesc" Style="{StaticResource BodyTextBlockStyle}" Margin="15,0,0,30" />
<HyperlinkButton x:Uid="CloseButton" Click="CloseButton_OnClick" Foreground="{StaticResource MainColor}" Style="{StaticResource MainColorHyperlinkButton}" />
<TextBlock x:Uid="CloseDesc" Style="{StaticResource BodyTextBlockStyle}" Margin="15,0,0,30" />
</StackPanel>
</Page>

View File

@@ -43,11 +43,17 @@ namespace ModernKeePass.Views
};
savePicker.FileTypeChoices.Add("KeePass 2.x database", new List<string> { ".kdbx" });
var file = await savePicker.PickSaveFileAsync();
var file = await savePicker.PickSaveFileAsync().AsTask();
if (file == null) return;
await Model.Save(file);
_mainFrame.Navigate(typeof(MainPage));
}
private async void CloseButton_OnClick(object sender, RoutedEventArgs e)
{
await Model.Close();
_mainFrame.Navigate(typeof(MainPage));
}
}
}

View File

@@ -77,7 +77,7 @@ namespace ModernKeePass.Views.UserControls
public bool ShowComplexityIndicator => CreateNew || UpdateKey;
public CompositeKeyUserControl(): this(App.Services.GetService<IMediator>())
public CompositeKeyUserControl(): this(App.Services.GetRequiredService<IMediator>())
{ }
public CompositeKeyUserControl(IMediator mediator)