Moved application code to the Application layer

Imported Win10 project
Code cleanup
WIP - Use common UWP services for Win8.1 and Win10
This commit is contained in:
Geoffroy BONNEVILLE
2020-04-06 20:20:45 +02:00
parent e795a8c3c4
commit 56d93a5187
292 changed files with 48614 additions and 837 deletions

View File

@@ -1,11 +1,11 @@
using System.Windows.Input;
using Windows.UI.Xaml;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Xaml.Interactivity;
using ModernKeePass.Application.Database.Queries.GetDatabase;
using ModernKeePass.Common;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
using ModernKeePass.ViewModels;
namespace ModernKeePass.Actions
@@ -34,7 +34,7 @@ namespace ModernKeePass.Actions
DependencyProperty.Register("Command", typeof(ICommand), typeof(DeleteEntityAction),
new PropertyMetadata(null));
public DeleteEntityAction() : this(App.Mediator) { }
public DeleteEntityAction() : this(App.Services.GetService<IMediator>()) { }
public DeleteEntityAction(IMediator mediator)
{
@@ -43,7 +43,7 @@ namespace ModernKeePass.Actions
public object Execute(object sender, object parameter)
{
var resource = new ResourcesService();
var resource = new ResourceHelper();
var type = Entity is GroupDetailVm ? "Group" : "Entry";
var isRecycleOnDelete = _mediator.Send(new GetDatabaseQuery()).GetAwaiter().GetResult().IsRecycleBinEnabled;

View File

@@ -14,14 +14,15 @@ using MediatR;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.HockeyApp;
using ModernKeePass.Application;
using ModernKeePass.Application.Common.Interfaces;
using ModernKeePass.Application.Database.Commands.CloseDatabase;
using ModernKeePass.Application.Database.Commands.SaveDatabase;
using ModernKeePass.Application.Database.Queries.GetDatabase;
using ModernKeePass.Application.Database.Queries.ReOpenDatabase;
using ModernKeePass.Common;
using ModernKeePass.Domain.Dtos;
using ModernKeePass.Domain.Exceptions;
using ModernKeePass.Infrastructure;
using ModernKeePass.Services;
using ModernKeePass.Views;
// The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227
@@ -33,9 +34,11 @@ namespace ModernKeePass
/// </summary>
sealed partial class App
{
public IServiceProvider Services { get; }
private readonly IResourceProxy _resource;
private readonly IMediator _mediator;
private readonly ISettingsProxy _settings;
public static IMediator Mediator { get; private set; }
public static IServiceProvider Services { get; private set; }
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
@@ -56,10 +59,15 @@ namespace ModernKeePass
// Setup DI
IServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddApplication();
serviceCollection.AddInfrastructure();
serviceCollection.AddInfrastructureCommon();
serviceCollection.AddInfrastructureKeePass();
serviceCollection.AddInfrastructureUwp();
serviceCollection.AddAppAutomapper();
Services = serviceCollection.BuildServiceProvider();
Mediator = Services.GetService<IMediator>();
_mediator = Services.GetService<IMediator>();
_resource = Services.GetService<IResourceProxy>();
_settings = Services.GetService<ISettingsProxy>();
}
#region Event Handlers
@@ -74,30 +82,29 @@ namespace ModernKeePass
? exception.InnerException
: exception;
var resource = new ResourcesService();
if (realException is SaveException)
{
unhandledExceptionEventArgs.Handled = true;
await MessageDialogHelper.ShowActionDialog(resource.GetResourceValue("MessageDialogSaveErrorTitle"),
await MessageDialogHelper.ShowActionDialog(_resource.GetResourceValue("MessageDialogSaveErrorTitle"),
realException.InnerException.Message,
resource.GetResourceValue("MessageDialogSaveErrorButtonSaveAs"),
resource.GetResourceValue("MessageDialogSaveErrorButtonDiscard"),
_resource.GetResourceValue("MessageDialogSaveErrorButtonSaveAs"),
_resource.GetResourceValue("MessageDialogSaveErrorButtonDiscard"),
async command =>
{
var database = await Mediator.Send(new GetDatabaseQuery());
var database = await _mediator.Send(new GetDatabaseQuery());
var savePicker = new FileSavePicker
{
SuggestedStartLocation = PickerLocationId.DocumentsLibrary,
SuggestedFileName = $"{database.Name} - copy"
};
savePicker.FileTypeChoices.Add(resource.GetResourceValue("MessageDialogSaveErrorFileTypeDesc"),
savePicker.FileTypeChoices.Add(_resource.GetResourceValue("MessageDialogSaveErrorFileTypeDesc"),
new List<string> {".kdbx"});
var file = await savePicker.PickSaveFileAsync();
if (file != null)
{
var token = StorageApplicationPermissions.FutureAccessList.Add(file);
await Mediator.Send(new SaveDatabaseCommand { FilePath = token });
await _mediator.Send(new SaveDatabaseCommand { FilePath = token });
}
}, null);
}
@@ -124,7 +131,7 @@ namespace ModernKeePass
#if DEBUG
if (System.Diagnostics.Debugger.IsAttached)
{
//DebugSettings.EnableFrameRateCounter = true;
DebugSettings.EnableFrameRateCounter = true;
}
#endif
@@ -167,7 +174,7 @@ namespace ModernKeePass
try
{
await Mediator.Send(new ReOpenDatabaseQuery());
await _mediator.Send(new ReOpenDatabaseQuery());
#if DEBUG
ToastNotificationHelper.ShowGenericToast("App resumed", "Database reopened (changes were saved)");
#endif
@@ -203,11 +210,11 @@ namespace ModernKeePass
var deferral = e.SuspendingOperation.GetDeferral();
try
{
if (SettingsService.Instance.GetSetting("SaveSuspend", true))
if (_settings.GetSetting("SaveSuspend", true))
{
await Mediator.Send(new SaveDatabaseCommand());
await _mediator.Send(new SaveDatabaseCommand());
}
await Mediator.Send(new CloseDatabaseCommand());
await _mediator.Send(new CloseDatabaseCommand());
}
catch (Exception exception)
{
@@ -226,7 +233,22 @@ namespace ModernKeePass
base.OnFileActivated(args);
var rootFrame = new Frame();
var file = args.Files[0] as StorageFile;
rootFrame.Navigate(typeof(MainPage), file);
if (file != null)
{
var token = StorageApplicationPermissions.FutureAccessList.Add(file);
var fileInfo = new FileInfo
{
Path = token,
Name = file.DisplayName
};
rootFrame.Navigate(typeof(MainPage), fileInfo);
}
else
{
rootFrame.Navigate(typeof(MainPage));
}
Window.Current.Content = rootFrame;
Window.Current.Activate();
}

View File

@@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Windows.System;
using Windows.UI.Core;
using Windows.UI.Xaml;

View File

@@ -1,28 +0,0 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace ModernKeePass.Common
{
public class NotifyPropertyChangedBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetProperty<T>(ref T property, T value, [CallerMemberName] string propertyName = "")
{
if (EqualityComparer<T>.Default.Equals(property, value))
{
return false;
}
property = value;
OnPropertyChanged(propertyName);
return true;
}
}
}

View File

@@ -1,9 +1,8 @@
using Windows.ApplicationModel.Resources;
using ModernKeePass.Interfaces;
namespace ModernKeePass.Services
namespace ModernKeePass.Common
{
public class ResourcesService: IResourceService
public class ResourceHelper
{
private const string ResourceFileName = "CodeBehind";
private readonly ResourceLoader _resourceLoader = ResourceLoader.GetForCurrentView();
@@ -14,4 +13,4 @@ namespace ModernKeePass.Services
return resource;
}
}
}
}

View File

@@ -3,7 +3,6 @@ using Windows.Data.Json;
using Windows.Data.Xml.Dom;
using Windows.UI.Notifications;
using ModernKeePass.Interfaces;
using ModernKeePass.ViewModels;
namespace ModernKeePass.Common
{

View File

@@ -1,35 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.Storage;
using ModernKeePass.Interfaces;
namespace ModernKeePass.ImportFormats
{
public class CsvImportFormat: IFormat
{
public bool HasHeaderRow { get; set; } = true;
public char Delimiter { get; set; } = ';';
public char LineDelimiter { get; set; } = '\n';
public async Task<List<Dictionary<string, string>>> Import(IStorageFile source)
{
var parsedResult = new List<Dictionary<string, string>>();
var content = await FileIO.ReadLinesAsync(source);
foreach (var line in content)
{
var fields = line.Split(Delimiter);
var recordItem = new Dictionary<string, string>();
var i = 0;
foreach (var field in fields)
{
recordItem.Add(i.ToString(), field);
i++;
}
parsedResult.Add(recordItem);
}
return parsedResult;
}
}
}

View File

@@ -1,16 +0,0 @@
using Windows.Storage;
using ModernKeePass.Interfaces;
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace ModernKeePass.ImportFormats
{
public class NullImportFormat: IFormat
{
public Task<List<Dictionary<string, string>>> Import(IStorageFile source)
{
throw new NotImplementedException();
}
}
}

View File

@@ -1,11 +0,0 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.Storage;
namespace ModernKeePass.Interfaces
{
public interface IFormat
{
Task<List<Dictionary<string, string>>> Import(IStorageFile source);
}
}

View File

@@ -1,9 +0,0 @@
using System.Reflection;
namespace ModernKeePass.Interfaces
{
public interface IProxyInvocationHandler
{
object Invoke(object proxy, MethodInfo method, object[] parameters);
}
}

View File

@@ -1,11 +0,0 @@
using Windows.Storage;
namespace ModernKeePass.Interfaces
{
public interface IRecentItem
{
StorageFile DatabaseFile { get; }
string Token { get; }
string Name { get; }
}
}

View File

@@ -1,15 +0,0 @@
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using Windows.Storage;
namespace ModernKeePass.Interfaces
{
public interface IRecentService
{
int EntryCount { get; }
Task<IStorageItem> GetFileAsync(string token);
ObservableCollection<IRecentItem> GetAllFiles(bool removeIfNonExistant = true);
void Add(IStorageItem file, string metadata);
void ClearAll();
}
}

View File

@@ -1,7 +0,0 @@
namespace ModernKeePass.Interfaces
{
public interface IResourceService
{
string GetResourceValue(string key);
}
}

View File

@@ -1,8 +0,0 @@
namespace ModernKeePass.Interfaces
{
public interface ISettingsService
{
T GetSetting<T>(string property, T defaultValue = default(T));
void PutSetting<T>(string property, T value);
}
}

View File

@@ -1,194 +0,0 @@
using System;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Windows.Storage;
using Microsoft.HockeyApp;
using ModernKeePass.Domain.Exceptions;
using ModernKeePass.Interfaces;
using ModernKeePass.ViewModels;
using ModernKeePassLib;
using ModernKeePassLib.Cryptography.KeyDerivation;
using ModernKeePassLib.Interfaces;
using ModernKeePassLib.Keys;
using ModernKeePassLib.Serialization;
namespace ModernKeePass.Services
{
public class DatabaseService: SingletonServiceBase<DatabaseService>, IDatabaseService
{
private readonly PwDatabase _pwDatabase = new PwDatabase();
private readonly ISettingsService _settings;
private StorageFile _databaseFile;
private GroupVm _recycleBin;
private CompositeKey _compositeKey;
public GroupVm RootGroup { get; set; }
public GroupVm RecycleBin
{
get { return _recycleBin; }
set
{
_recycleBin = value;
_pwDatabase.RecycleBinUuid = _recycleBin?.IdUuid;
}
}
public string Name => _databaseFile?.Name;
public bool RecycleBinEnabled
{
get { return _pwDatabase.RecycleBinEnabled; }
set { _pwDatabase.RecycleBinEnabled = value; }
}
public PwUuid DataCipher
{
get { return _pwDatabase.DataCipherUuid; }
set { _pwDatabase.DataCipherUuid = value; }
}
public PwCompressionAlgorithm CompressionAlgorithm
{
get { return _pwDatabase.Compression; }
set { _pwDatabase.Compression = value; }
}
public KdfParameters KeyDerivation
{
get { return _pwDatabase.KdfParameters; }
set { _pwDatabase.KdfParameters = value; }
}
public bool IsOpen => _pwDatabase.IsOpen;
public bool IsFileOpen => !_pwDatabase.IsOpen && _databaseFile != null;
public bool IsClosed => _databaseFile == null;
public bool HasChanged { get; set; }
public DatabaseService() : this(SettingsService.Instance)
{
}
public DatabaseService(ISettingsService settings)
{
_settings = settings;
}
/// <summary>
/// Open a KeePass database
/// </summary>
/// <param name="databaseFile">The database file</param>
/// <param name="key">The database composite key</param>
/// <param name="createNew">True to create a new database before opening it</param>
/// <returns>An error message, if any</returns>
public async Task Open(StorageFile databaseFile, CompositeKey key, bool createNew = false)
{
try
{
if (databaseFile == null)
{
throw new ArgumentNullException(nameof(databaseFile));
}
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
_compositeKey = key;
var fileContents = await FileIO.ReadBufferAsync(databaseFile);
var ioConnection = IOConnectionInfo.FromByteArray(fileContents.ToArray());
if (createNew)
{
_pwDatabase.New(ioConnection, key);
var fileFormat = _settings.GetSetting<string>("DefaultFileFormat");
switch (fileFormat)
{
case "4":
KeyDerivation = KdfPool.Get("Argon2").GetDefaultParameters();
break;
}
}
else _pwDatabase.Open(ioConnection, key, new NullStatusLogger());
_databaseFile = databaseFile;
RootGroup = new GroupVm(_pwDatabase.RootGroup, null, RecycleBinEnabled ? _pwDatabase.RecycleBinUuid : null);
}
catch (InvalidCompositeKeyException ex)
{
HockeyClient.Current.TrackException(ex);
throw new ArgumentException(ex.Message, ex);
}
}
public async Task ReOpen()
{
await Open(_databaseFile, _compositeKey);
}
/// <summary>
/// Commit the changes to the currently opened database to file
/// </summary>
public void Save()
{
if (!IsOpen) return;
try
{
_pwDatabase.Save(new NullStatusLogger());
}
catch (Exception e)
{
throw new SaveException(e);
}
}
/// <summary>
/// Save the current database to another file and open it
/// </summary>
/// <param name="file">The new database file</param>
public async Task Save(StorageFile file)
{
var oldFile = _databaseFile;
_databaseFile = file;
try
{
var fileContents = await FileIO.ReadBufferAsync(file);
_pwDatabase.SaveAs(IOConnectionInfo.FromByteArray(fileContents.ToArray()), true, new NullStatusLogger());
}
catch
{
_databaseFile = oldFile;
throw;
}
}
/// <summary>
/// Close the currently opened database
/// </summary>
public void Close(bool releaseFile = true)
{
_pwDatabase?.Close();
if (releaseFile) _databaseFile = null;
}
public void AddDeletedItem(PwUuid id)
{
_pwDatabase.DeletedObjects.Add(new PwDeletedObject(id, DateTime.UtcNow));
}
public void CreateRecycleBin(string title)
{
RecycleBin = RootGroup.AddNewGroup(title);
RecycleBin.IsSelected = true;
RecycleBin.IconId = (int)PwIcon.TrashBin;
}
public void UpdateCompositeKey(CompositeKey newCompositeKey)
{
if (newCompositeKey == null) return;
_compositeKey = newCompositeKey;
_pwDatabase.MasterKey = newCompositeKey;
}
}
}

View File

@@ -1,25 +0,0 @@
using System.Threading.Tasks;
using Windows.Storage;
using ModernKeePass.Interfaces;
using ModernKeePass.ViewModels;
namespace ModernKeePass.Services
{
public class ImportService : IImportService<IFormat>
{
public async Task Import(IFormat format, IStorageFile source, GroupVm group)
{
var data = await format.Import(source);
foreach (var entity in data)
{
var entry = group.AddNewEntry();
entry.Title = entity["0"];
entry.UserName = entity["1"];
entry.Password = entity["2"];
if (entity.Count > 3) entry.Url = entity["3"];
if (entity.Count > 4) entry.Notes = entity["4"];
}
}
}
}

View File

@@ -1,50 +0,0 @@
using System;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using ModernKeePass.Interfaces;
using Windows.Storage;
using Windows.Storage.AccessCache;
using ModernKeePass.ViewModels;
namespace ModernKeePass.Services
{
public class RecentService : SingletonServiceBase<RecentService>, IRecentService
{
private readonly StorageItemMostRecentlyUsedList _mru = StorageApplicationPermissions.MostRecentlyUsedList;
public int EntryCount => _mru.Entries.Count;
public ObservableCollection<IRecentItem> GetAllFiles(bool removeIfNonExistant = true)
{
var result = new ObservableCollection<IRecentItem>();
foreach (var entry in _mru.Entries)
{
try
{
var file = _mru.GetFileAsync(entry.Token, AccessCacheOptions.SuppressAccessTimeUpdate).GetAwaiter().GetResult();
result.Add(new RecentItemVm(entry.Token, entry.Metadata, file));
}
catch (Exception)
{
if (removeIfNonExistant) _mru.Remove(entry.Token);
}
}
return result;
}
public void Add(IStorageItem file, string metadata)
{
_mru.Add(file, metadata);
}
public void ClearAll()
{
_mru.Clear();
}
public async Task<IStorageItem> GetFileAsync(string token)
{
return await _mru.GetFileAsync(token);
}
}
}

View File

@@ -1,31 +0,0 @@
using System;
using Windows.Foundation.Collections;
using Windows.Storage;
using ModernKeePass.Interfaces;
namespace ModernKeePass.Services
{
public class SettingsService : SingletonServiceBase<SettingsService>, ISettingsService
{
private readonly IPropertySet _values = ApplicationData.Current.LocalSettings.Values;
public T GetSetting<T>(string property, T defaultValue = default(T))
{
try
{
return (T)Convert.ChangeType(_values[property], typeof(T));
}
catch (InvalidCastException)
{
return defaultValue;
}
}
public void PutSetting<T>(string property, T value)
{
if (_values.ContainsKey(property))
_values[property] = value;
else _values.Add(property, value);
}
}
}

View File

@@ -1,12 +0,0 @@
using System;
namespace ModernKeePass.Services
{
public abstract class SingletonServiceBase<T> where T : new()
{
private static readonly Lazy<T> LazyInstance =
new Lazy<T>(() => new T());
public static T Instance => LazyInstance.Value;
}
}

View File

@@ -1,17 +1,16 @@
using System;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.AccessCache;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
using ModernKeePass.Application.Database.Commands.UpdateCredentials;
using ModernKeePass.Application.Database.Queries.GetDatabase;
using ModernKeePass.Application.Database.Queries.OpenDatabase;
using ModernKeePass.Application.Security.Commands.GenerateKeyFile;
using ModernKeePass.Application.Security.Queries.EstimatePasswordComplexity;
using ModernKeePass.Domain.AOP;
using ModernKeePass.Domain.Dtos;
using ModernKeePass.Common;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
namespace ModernKeePass.ViewModels
{
@@ -55,7 +54,7 @@ namespace ModernKeePass.ViewModels
}
}
public bool IsValid => !_isOpening && (HasPassword || HasKeyFile && KeyFile != null || HasUserAccount);
public bool IsValid => !_isOpening && (HasPassword || HasKeyFile && KeyFilePath != null || HasUserAccount);
public string Status
{
@@ -75,20 +74,19 @@ namespace ModernKeePass.ViewModels
set
{
_password = value;
OnPropertyChanged("PasswordComplexityIndicator");
OnPropertyChanged(nameof(PasswordComplexityIndicator));
StatusType = (int)StatusTypes.Normal;
Status = string.Empty;
}
}
public StorageFile KeyFile
public string KeyFilePath
{
get { return _keyFile; }
get { return _keyFilePath; }
set
{
_keyFile = value;
KeyFileText = value?.Name;
OnPropertyChanged("IsValid");
_keyFilePath = value;
OnPropertyChanged(nameof(IsValid));
}
}
@@ -109,21 +107,21 @@ namespace ModernKeePass.ViewModels
private string _password = string.Empty;
private string _status;
private StatusTypes _statusType;
private StorageFile _keyFile;
private string _keyFilePath;
private string _keyFileText;
private readonly IMediator _mediator;
private readonly IResourceService _resource;
private readonly ResourceHelper _resource;
public CompositeKeyVm() : this(App.Mediator, new ResourcesService()) { }
public CompositeKeyVm() : this(App.Services.GetService<IMediator>()) { }
public CompositeKeyVm(IMediator mediator, IResourceService resource)
public CompositeKeyVm(IMediator mediator)
{
_mediator = mediator;
_resource = resource;
_resource = new ResourceHelper();
_keyFileText = _resource.GetResourceValue("CompositeKeyDefaultKeyFile");
}
public async Task<bool> OpenDatabase(StorageFile databaseFile, bool createNew)
public async Task<bool> OpenDatabase(string databaseFilePath, bool createNew)
{
try
{
@@ -131,9 +129,9 @@ namespace ModernKeePass.ViewModels
OnPropertyChanged(nameof(IsValid));
await _mediator.Send(new OpenDatabaseQuery {
FilePath = StorageApplicationPermissions.FutureAccessList.Add(databaseFile),
KeyFilePath = HasKeyFile && KeyFile != null ? StorageApplicationPermissions.FutureAccessList.Add(KeyFile) : null,
Password = Password = HasPassword ? Password : null,
FilePath = databaseFilePath,
KeyFilePath = HasKeyFile ? KeyFilePath : null,
Password = HasPassword ? Password : null,
});
RootGroupId = (await _mediator.Send(new GetDatabaseQuery())).RootGroupId;
return true;
@@ -163,18 +161,18 @@ namespace ModernKeePass.ViewModels
{
await _mediator.Send(new UpdateCredentialsCommand
{
KeyFilePath = HasKeyFile && KeyFile != null ? StorageApplicationPermissions.FutureAccessList.Add(KeyFile) : null,
Password = Password = HasPassword ? Password : null,
KeyFilePath = HasKeyFile ? KeyFilePath : null,
Password = HasPassword ? Password : null,
});
UpdateStatus(_resource.GetResourceValue("CompositeKeyUpdated"), StatusTypes.Success);
}
public async Task CreateKeyFile(StorageFile file)
public async Task CreateKeyFile(FileInfo file)
{
var token = StorageApplicationPermissions.FutureAccessList.Add(file);
// TODO: implement entropy generator
await _mediator.Send(new GenerateKeyFileCommand {KeyFilePath = token});
KeyFile = file;
await _mediator.Send(new GenerateKeyFileCommand {KeyFilePath = file.Path});
KeyFilePath = file.Path;
KeyFileText = file.Name;
}
private void UpdateStatus(string text, StatusTypes type)

View File

@@ -5,6 +5,7 @@ using System.Threading.Tasks;
using System.Windows.Input;
using Windows.UI.Xaml.Controls;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
using ModernKeePass.Application.Database.Commands.SaveDatabase;
using ModernKeePass.Application.Database.Models;
using ModernKeePass.Application.Database.Queries.GetDatabase;
@@ -22,6 +23,7 @@ using ModernKeePass.Domain.Enums;
using ModernKeePass.Domain.Interfaces;
using ModernKeePass.Interfaces;
using ModernKeePass.Application.Group.Models;
using ModernKeePass.Domain.AOP;
namespace ModernKeePass.ViewModels
{
@@ -49,21 +51,13 @@ namespace ModernKeePass.ViewModels
public bool IsSelected
{
get { return _isSelected; }
set
{
_isSelected = value;
OnPropertyChanged();
}
set { SetProperty(ref _isSelected, value); }
}
public double PasswordLength
{
get { return _passwordLength; }
set
{
_passwordLength = value;
OnPropertyChanged();
}
set { SetProperty(ref _passwordLength, value); }
}
public string Title
@@ -191,31 +185,19 @@ namespace ModernKeePass.ViewModels
public bool IsEditMode
{
get { return IsSelected && _isEditMode; }
set
{
_isEditMode = value;
OnPropertyChanged();
}
set { SetProperty(ref _isEditMode, value); }
}
public bool IsVisible
{
get { return _isVisible; }
set
{
_isVisible = value;
OnPropertyChanged();
}
set { SetProperty(ref _isVisible, value); }
}
public bool IsRevealPassword
{
get { return _isRevealPassword; }
set
{
_isRevealPassword = value;
OnPropertyChanged();
}
set { SetProperty(ref _isRevealPassword, value); }
}
public bool CanRestore => _entry.ParentGroupId == _database.RecycleBinId;
@@ -237,7 +219,7 @@ namespace ModernKeePass.ViewModels
public EntryDetailVm() { }
internal EntryDetailVm(string entryId, bool isNewEntry = false) : this(entryId, App.Mediator, isNewEntry) { }
internal EntryDetailVm(string entryId, bool isNewEntry = false) : this(entryId, App.Services.GetService<IMediator>(), isNewEntry) { }
public EntryDetailVm(string entryId, IMediator mediator, bool isNewEntry = false)
{

View File

@@ -6,6 +6,7 @@ using System.Threading.Tasks;
using System.Windows.Input;
using Windows.UI.Xaml.Controls;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
using ModernKeePass.Application.Database.Commands.SaveDatabase;
using ModernKeePass.Application.Database.Models;
using ModernKeePass.Application.Database.Queries.GetDatabase;
@@ -23,6 +24,7 @@ using ModernKeePass.Application.Group.Commands.SortGroups;
using ModernKeePass.Application.Group.Models;
using ModernKeePass.Application.Group.Queries.GetGroup;
using ModernKeePass.Common;
using ModernKeePass.Domain.AOP;
using ModernKeePass.Domain.Enums;
using ModernKeePass.Domain.Interfaces;
using ModernKeePass.Interfaces;
@@ -122,7 +124,7 @@ namespace ModernKeePass.ViewModels
public GroupDetailVm() {}
internal GroupDetailVm(string groupId) : this(groupId, App.Mediator)
internal GroupDetailVm(string groupId) : this(groupId, App.Services.GetService<IMediator>())
{ }
public GroupDetailVm(string groupId, IMediator mediator, bool isEditMode = false)

View File

@@ -1,8 +1,7 @@
using System;
using Windows.UI.Xaml.Controls;
using ModernKeePass.Common;
using ModernKeePass.Domain.AOP;
using ModernKeePass.Domain.Interfaces;
using ModernKeePass.Interfaces;
namespace ModernKeePass.ViewModels
{

View File

@@ -1,20 +1,20 @@
using System.Threading.Tasks;
using Windows.Storage;
using ModernKeePass.Common;
using Microsoft.Extensions.DependencyInjection;
using ModernKeePass.Application.Common.Interfaces;
using ModernKeePass.Domain.AOP;
using ModernKeePass.Domain.Dtos;
using ModernKeePass.Domain.Interfaces;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
namespace ModernKeePass.ViewModels
{
public class RecentItemVm: NotifyPropertyChangedBase, ISelectableModel, IRecentItem
public class RecentItemVm: NotifyPropertyChangedBase, ISelectableModel
{
private readonly IRecentProxy _recent;
private bool _isSelected;
public StorageFile DatabaseFile { get; }
public string Token { get; }
public string Name { get; }
public string Path => DatabaseFile?.Path;
public string Path => string.Empty;
public bool IsSelected
{
@@ -22,22 +22,17 @@ namespace ModernKeePass.ViewModels
set { SetProperty(ref _isSelected, value); }
}
public RecentItemVm() {}
public RecentItemVm(string token, string metadata, IStorageItem file)
public RecentItemVm(FileInfo file): this(App.Services.GetService<IRecentProxy>(), file) {}
public RecentItemVm(IRecentProxy recent, FileInfo file)
{
Token = token;
Name = metadata;
DatabaseFile = file as StorageFile;
_recent = recent;
Token = file.Path;
Name = file.Name;
}
public void UpdateAccessTime()
public async Task UpdateAccessTime()
{
UpdateAccessTime(RecentService.Instance).Wait();
}
public async Task UpdateAccessTime(IRecentService recent)
{
await recent.GetFileAsync(Token);
await _recent.Get(Token);
}
}
}

View File

@@ -2,6 +2,7 @@
using System.Collections.ObjectModel;
using System.Linq;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
using ModernKeePass.Application.Common.Interfaces;
using ModernKeePass.Application.Database.Models;
using ModernKeePass.Application.Database.Queries.GetDatabase;
@@ -15,7 +16,7 @@ using ModernKeePass.Application.Parameters.Models;
using ModernKeePass.Application.Parameters.Queries.GetCiphers;
using ModernKeePass.Application.Parameters.Queries.GetCompressions;
using ModernKeePass.Application.Parameters.Queries.GetKeyDerivations;
using ModernKeePass.Common;
using ModernKeePass.Domain.AOP;
namespace ModernKeePass.ViewModels
{
@@ -73,7 +74,7 @@ namespace ModernKeePass.ViewModels
set { _mediator.Send(new SetRecycleBinCommand { RecycleBinId = value.Id}).Wait(); }
}
public SettingsDatabaseVm() : this(App.Mediator) { }
public SettingsDatabaseVm() : this(App.Services.GetService<IMediator>()) { }
public SettingsDatabaseVm(IMediator mediator)
{

View File

@@ -1,17 +1,17 @@
using System.Collections.Generic;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
using Microsoft.Extensions.DependencyInjection;
using ModernKeePass.Application.Common.Interfaces;
namespace ModernKeePass.ViewModels
{
public class SettingsNewVm
{
private readonly ISettingsService _settings;
private readonly ISettingsProxy _settings;
public SettingsNewVm() : this(SettingsService.Instance)
public SettingsNewVm() : this(App.Services.GetService<ISettingsProxy>())
{ }
public SettingsNewVm(ISettingsService settings)
public SettingsNewVm(ISettingsProxy settings)
{
_settings = settings;
}

View File

@@ -1,16 +1,16 @@
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
using Microsoft.Extensions.DependencyInjection;
using ModernKeePass.Application.Common.Interfaces;
namespace ModernKeePass.ViewModels
{
public class SettingsSaveVm
{
private readonly ISettingsService _settings;
private readonly ISettingsProxy _settings;
public SettingsSaveVm() : this(SettingsService.Instance)
public SettingsSaveVm() : this(App.Services.GetService<ISettingsProxy>())
{ }
public SettingsSaveVm(ISettingsService settings)
public SettingsSaveVm(ISettingsProxy settings)
{
_settings = settings;
}

View File

@@ -1,14 +1,15 @@
using System.Collections.ObjectModel;
using System.Linq;
using Windows.ApplicationModel;
using Windows.Storage;
using Windows.UI.Xaml.Controls;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
using ModernKeePass.Application.Common.Interfaces;
using ModernKeePass.Application.Database.Queries.GetDatabase;
using ModernKeePass.Common;
using ModernKeePass.Domain.AOP;
using ModernKeePass.Domain.Dtos;
using ModernKeePass.Domain.Interfaces;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
using ModernKeePass.Views;
namespace ModernKeePass.ViewModels
@@ -48,12 +49,13 @@ namespace ModernKeePass.ViewModels
public MainVm() {}
internal MainVm(Frame referenceFrame, Frame destinationFrame, StorageFile databaseFile = null) : this(referenceFrame, destinationFrame,
App.Mediator, new ResourcesService(), RecentService.Instance, databaseFile)
internal MainVm(Frame referenceFrame, Frame destinationFrame, FileInfo databaseFile = null) : this(referenceFrame, destinationFrame,
App.Services.GetService<IMediator>(), App.Services.GetService<IRecentProxy>(), databaseFile)
{ }
public MainVm(Frame referenceFrame, Frame destinationFrame, IMediator mediator, IResourceService resource, IRecentService recent, StorageFile databaseFile = null)
public MainVm(Frame referenceFrame, Frame destinationFrame, IMediator mediator, IRecentProxy recent, FileInfo databaseFile = null)
{
var resource = new ResourceHelper();
var database = mediator.Send(new GetDatabaseQuery()).GetAwaiter().GetResult();
var mainMenuItems = new ObservableCollection<MainMenuItemVm>

View File

@@ -1,6 +1,8 @@
using System.Threading.Tasks;
using Windows.Storage;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
using ModernKeePass.Application.Common.Interfaces;
using ModernKeePass.Application.Database.Queries.GetDatabase;
using ModernKeePass.Application.Entry.Commands.SetFieldValue;
using ModernKeePass.Application.Group.Commands.CreateEntry;
@@ -8,15 +10,13 @@ using ModernKeePass.Application.Group.Commands.CreateGroup;
using ModernKeePass.Application.Group.Models;
using ModernKeePass.Application.Group.Queries.GetGroup;
using ModernKeePass.Domain.Enums;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
namespace ModernKeePass.ViewModels
{
public class NewVm : OpenVm
{
private readonly IMediator _mediator;
private readonly ISettingsService _settings;
private readonly ISettingsProxy _settings;
private string _importFormatHelp;
public string Password { get; set; }
@@ -26,7 +26,7 @@ namespace ModernKeePass.ViewModels
public string ImportFileExtensionFilter { get; set; } = "*";
public IFormat ImportFormat { get; set; }
public IImportFormat ImportFormat { get; set; }
public string ImportFormatHelp
{
@@ -38,9 +38,9 @@ namespace ModernKeePass.ViewModels
}
}
public NewVm(): this(App.Mediator, new SettingsService()) { }
public NewVm(): this(App.Services.GetService<IMediator>(), App.Services.GetService<ISettingsProxy>()) { }
public NewVm(IMediator mediator, ISettingsService settings)
public NewVm(IMediator mediator, ISettingsProxy settings)
{
_mediator = mediator;
_settings = settings;

View File

@@ -1,38 +1,38 @@
using Windows.Storage;
using ModernKeePass.Common;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using ModernKeePass.Application.Common.Interfaces;
using ModernKeePass.Domain.AOP;
using ModernKeePass.Domain.Dtos;
namespace ModernKeePass.ViewModels
{
public class OpenVm: NotifyPropertyChangedBase
{
private readonly IRecentService _recent;
public bool IsFileSelected => DatabaseFile != null;
private readonly IRecentProxy _recent;
public bool IsFileSelected => !string.IsNullOrEmpty(Path);
public string Name => DatabaseFile?.DisplayName;
public string Name { get; private set; }
public string Path { get; private set; }
public StorageFile DatabaseFile { get; private set; }
public OpenVm(): this(App.Services.GetService<IRecentProxy>()) { }
public OpenVm(): this(new RecentService()) { }
public OpenVm(IRecentService recent)
public OpenVm(IRecentProxy recent)
{
_recent = recent;
}
public void OpenFile(StorageFile file)
public async Task OpenFile(FileInfo file)
{
DatabaseFile = file;
OnPropertyChanged("Name");
OnPropertyChanged("IsFileSelected");
OnPropertyChanged("DatabaseFile");
AddToRecentList(file);
Name = file.Name;
Path = file.Path;
OnPropertyChanged(nameof(Name));
OnPropertyChanged(nameof(IsFileSelected));
await AddToRecentList(file);
}
private void AddToRecentList(StorageFile file)
private async Task AddToRecentList(FileInfo file)
{
_recent.Add(file, file.DisplayName);
await _recent.Add(file);
}
}
}

View File

@@ -1,19 +1,21 @@
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Input;
using Microsoft.Extensions.DependencyInjection;
using ModernKeePass.Application.Common.Interfaces;
using ModernKeePass.Common;
using ModernKeePass.Domain.AOP;
using ModernKeePass.Domain.Interfaces;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
namespace ModernKeePass.ViewModels
{
public class RecentVm : NotifyPropertyChangedBase, IHasSelectableObject
{
private readonly IRecentService _recent;
private readonly IRecentProxy _recent;
private ISelectableModel _selectedItem;
private ObservableCollection<IRecentItem> _recentItems = new ObservableCollection<IRecentItem>();
private ObservableCollection<RecentItemVm> _recentItems;
public ObservableCollection<IRecentItem> RecentItems
public ObservableCollection<RecentItemVm> RecentItems
{
get { return _recentItems; }
set { SetProperty(ref _recentItems, value); }
@@ -39,15 +41,16 @@ namespace ModernKeePass.ViewModels
public ICommand ClearAllCommand { get; }
public RecentVm() : this (RecentService.Instance)
public RecentVm() : this (App.Services.GetService<IRecentProxy>())
{ }
public RecentVm(IRecentService recent)
public RecentVm(IRecentProxy recent)
{
_recent = recent;
ClearAllCommand = new RelayCommand(ClearAll);
RecentItems = _recent.GetAllFiles();
RecentItems = new ObservableCollection<RecentItemVm>(_recent.GetAll().GetAwaiter().GetResult()
.Select(r => new RecentItemVm(r)));
if (RecentItems.Count > 0)
SelectedItem = RecentItems[0] as RecentItemVm;
}

View File

@@ -2,6 +2,7 @@
using Windows.Storage;
using Windows.Storage.AccessCache;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
using ModernKeePass.Application.Database.Commands.CloseDatabase;
using ModernKeePass.Application.Database.Commands.SaveDatabase;
@@ -10,7 +11,7 @@ namespace ModernKeePass.ViewModels
public class SaveVm
{
private readonly IMediator _mediator;
public SaveVm() : this(App.Mediator) { }
public SaveVm() : this(App.Services.GetService<IMediator>()) { }
public SaveVm(IMediator mediator)
{

View File

@@ -2,12 +2,12 @@
using System.Linq;
using Windows.UI.Xaml.Controls;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
using ModernKeePass.Application.Database.Queries.GetDatabase;
using ModernKeePass.Common;
using ModernKeePass.Domain.AOP;
using ModernKeePass.Domain.Interfaces;
using ModernKeePass.Interfaces;
using ModernKeePass.Views;
using ModernKeePass.Services;
namespace ModernKeePass.ViewModels
{
@@ -43,10 +43,11 @@ namespace ModernKeePass.ViewModels
}
}
public SettingsVm() : this(App.Mediator, new ResourcesService()) { }
public SettingsVm() : this(App.Services.GetService<IMediator>()) { }
public SettingsVm(IMediator mediator, IResourceService resource)
public SettingsVm(IMediator mediator)
{
var resource = new ResourceHelper();
var database = mediator.Send(new GetDatabaseQuery()).GetAwaiter().GetResult();
var menuItems = new ObservableCollection<ListMenuItemVm>
{

View File

@@ -5,7 +5,6 @@ using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Navigation;
using ModernKeePass.Common;
using ModernKeePass.Domain.Interfaces;
using ModernKeePass.Interfaces;
namespace ModernKeePass.Views.BasePages
{

View File

@@ -1,6 +1,6 @@
using Windows.Storage;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using ModernKeePass.Domain.Dtos;
using ModernKeePass.ViewModels;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
@@ -33,7 +33,7 @@ namespace ModernKeePass.Views
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
var file = e.Parameter as StorageFile;
var file = e.Parameter as FileInfo;
DataContext = new MainVm(Frame, MenuFrame, file);
}
}

View File

@@ -21,7 +21,7 @@
<Border HorizontalAlignment="Left" BorderThickness="1" BorderBrush="AliceBlue" Width="550" Visibility="{Binding IsFileSelected, Converter={StaticResource BooleanToVisibilityConverter}}">
<StackPanel Margin="25,0,25,0">
<TextBlock Text="{Binding Name}" />
<userControls:CompositeKeyUserControl x:Uid="CompositeKeyNewButton" CreateNew="True" DatabaseFile="{Binding DatabaseFile}" ValidationChecked="CompositeKeyUserControl_OnValidationChecked" />
<userControls:CompositeKeyUserControl x:Uid="CompositeKeyNewButton" CreateNew="True" DatabaseFilePath="{Binding Path}" ValidationChecked="CompositeKeyUserControl_OnValidationChecked" />
</StackPanel>
</Border>
<CheckBox x:Name="CheckBox" x:Uid="NewImportCheckbox" Margin="15,10,0,0" IsChecked="{Binding IsImportChecked, Mode=TwoWay}" Visibility="{Binding IsFileSelected, Converter={StaticResource BooleanToVisibilityConverter}}" />

View File

@@ -1,12 +1,14 @@
using System;
using System.Collections.Generic;
using Windows.Storage.AccessCache;
using Windows.Storage.Pickers;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using ModernKeePass.Common;
using ModernKeePass.Domain.Dtos;
using ModernKeePass.Events;
using ModernKeePass.ImportFormats;
using ModernKeePass.Services;
using ModernKeePass.Infrastructure.File;
using ModernKeePass.ViewModels;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
@@ -44,22 +46,26 @@ namespace ModernKeePass.Views
var file = await savePicker.PickSaveFileAsync();
if (file == null) return;
Model.OpenFile(file);
var token = StorageApplicationPermissions.FutureAccessList.Add(file);
var fileInfo = new FileInfo
{
Path = token,
Name = file.DisplayName
};
await Model.OpenFile(fileInfo);
}
private void ImportFormatComboBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var resources = new ResourcesService();
var resource = new ResourceHelper();
var comboBox = sender as ComboBox;
switch (comboBox?.SelectedIndex)
{
case 0:
Model.ImportFormat = new CsvImportFormat();
Model.ImportFileExtensionFilter = ".csv";
Model.ImportFormatHelp = resources.GetResourceValue("NewImportFormatHelpCSV");
break;
default:
Model.ImportFormat = new NullImportFormat();
Model.ImportFormatHelp = resource.GetResourceValue("NewImportFormatHelpCSV");
break;
}
}

View File

@@ -5,7 +5,8 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="using:ModernKeePass.ViewModels"
xmlns:converters="using:ModernKeePass.Converters"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity" xmlns:Core="using:Microsoft.Xaml.Interactions.Core"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
xmlns:userControls="using:ModernKeePass.Views.UserControls"
x:Class="ModernKeePass.Views.OpenDatabasePage"
mc:Ignorable="d">
@@ -24,11 +25,11 @@
<Border HorizontalAlignment="Left" BorderThickness="1" BorderBrush="AliceBlue" Width="550" Visibility="{Binding IsFileSelected, Converter={StaticResource BooleanToVisibilityConverter}}">
<StackPanel Margin="25,0,25,0">
<TextBlock Text="{Binding Name}" />
<userControls:CompositeKeyUserControl x:Uid="CompositeKeyOpenButton" DatabaseFile="{Binding DatabaseFile}">
<userControls:CompositeKeyUserControl x:Uid="CompositeKeyOpenButton" DatabaseFilePath="{Binding Path}">
<interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="ValidationChecked">
<Core:NavigateToPageAction TargetPage="ModernKeePass.Views.GroupDetailPage" />
</Core:EventTriggerBehavior>
<core:EventTriggerBehavior EventName="ValidationChecked">
<core:NavigateToPageAction TargetPage="ModernKeePass.Views.GroupDetailPage" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</userControls:CompositeKeyUserControl>
</StackPanel>

View File

@@ -1,8 +1,9 @@
using System;
using Windows.Storage;
using Windows.Storage.AccessCache;
using Windows.Storage.Pickers;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Navigation;
using ModernKeePass.Domain.Dtos;
using ModernKeePass.ViewModels;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
@@ -21,13 +22,13 @@ namespace ModernKeePass.Views
InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
var file = e.Parameter as StorageFile;
var file = e.Parameter as FileInfo;
if (file != null)
{
Model.OpenFile(file);
await Model.OpenFile(file);
}
}
@@ -43,7 +44,15 @@ namespace ModernKeePass.Views
// Application now has read/write access to the picked file
var file = await picker.PickSingleFileAsync();
if (file == null) return;
Model.OpenFile(file);
var token = StorageApplicationPermissions.FutureAccessList.Add(file);
var fileInfo = new FileInfo
{
Path = token,
Name = file.DisplayName
};
await Model.OpenFile(fileInfo);
}
}
}

View File

@@ -45,7 +45,7 @@
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Text="{Binding Name}" Padding="5,0,0,0" />
<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}}" DatabaseFile="{Binding DatabaseFile}">
<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 Path}">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="ValidationChecked">
<core:CallMethodAction TargetObject="{Binding}" MethodName="UpdateAccessTime" />

View File

@@ -11,7 +11,7 @@
mc:Ignorable="d" >
<UserControl.Resources>
<converters:ProgressBarLegalValuesConverter x:Key="ProgressBarLegalValuesConverter"/>
<converters:DoubleToSolidColorBrushConverter x:Key="DoubleToForegroungBrushConverter"/>
<converters:DoubleToSolidColorBrushConverter x:Key="DoubleToForegroundBrushConverter"/>
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<converters:DiscreteIntToSolidColorBrushConverter x:Key="DiscreteIntToSolidColorBrushConverter"/>
<converters:EmptyStringToVisibilityConverter x:Key="EmptyStringToVisibilityConverter"/>
@@ -42,7 +42,7 @@
<ProgressBar Grid.Row="0" Grid.Column="1"
Maximum="128" VerticalAlignment="Bottom"
Value="{Binding PasswordComplexityIndicator, ConverterParameter=0\,128, Converter={StaticResource ProgressBarLegalValuesConverter}}"
Foreground="{Binding PasswordComplexityIndicator, ConverterParameter=128, Converter={StaticResource DoubleToForegroungBrushConverter}}"
Foreground="{Binding PasswordComplexityIndicator, ConverterParameter=128, Converter={StaticResource DoubleToForegroundBrushConverter}}"
Visibility="{Binding ShowComplexityIndicator, ElementName=UserControl, Converter={StaticResource BooleanToVisibilityConverter}}" />
<CheckBox Grid.Row="1" Grid.Column="0" IsChecked="{Binding HasKeyFile, Mode=TwoWay}" />
<HyperlinkButton Grid.Row="1" Grid.Column="1" Margin="-15,0,0,0" Content="{Binding KeyFileText}" IsEnabled="{Binding HasKeyFile}" Click="KeyFileButton_Click" Style="{StaticResource MainColorHyperlinkButton}" />

View File

@@ -1,20 +1,20 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.AccessCache;
using Windows.Storage.Pickers;
using Windows.System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Input;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
using ModernKeePass.Application.Database.Commands.CloseDatabase;
using ModernKeePass.Application.Database.Commands.SaveDatabase;
using ModernKeePass.Application.Database.Queries.GetDatabase;
using ModernKeePass.Common;
using ModernKeePass.Domain.Dtos;
using ModernKeePass.Events;
using ModernKeePass.Extensions;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
using ModernKeePass.ViewModels;
// Pour en savoir plus sur le modèle d'élément Contrôle utilisateur, consultez la page http://go.microsoft.com/fwlink/?LinkId=234236
@@ -24,6 +24,7 @@ namespace ModernKeePass.Views.UserControls
public sealed partial class CompositeKeyUserControl
{
private readonly IMediator _mediator;
private readonly ResourceHelper _resource;
public CompositeKeyVm Model => Grid.DataContext as CompositeKeyVm;
public bool CreateNew
@@ -62,26 +63,27 @@ namespace ModernKeePass.Views.UserControls
typeof(CompositeKeyUserControl),
new PropertyMetadata("OK", (o, args) => { }));
public StorageFile DatabaseFile
public string DatabaseFilePath
{
get { return (StorageFile)GetValue(DatabaseFileProperty); }
set { SetValue(DatabaseFileProperty, value); }
get { return (string)GetValue(DatabaseFilePathProperty); }
set { SetValue(DatabaseFilePathProperty, value); }
}
public static readonly DependencyProperty DatabaseFileProperty =
public static readonly DependencyProperty DatabaseFilePathProperty =
DependencyProperty.Register(
"DatabaseFile",
typeof(StorageFile),
"DatabaseFilePath",
typeof(string),
typeof(CompositeKeyUserControl),
new PropertyMetadata(null, (o, args) => { }));
public bool ShowComplexityIndicator => CreateNew || UpdateKey;
public CompositeKeyUserControl(): this(App.Mediator)
public CompositeKeyUserControl(): this(App.Services.GetService<IMediator>())
{ }
public CompositeKeyUserControl(IMediator mediator)
{
_mediator = mediator;
_resource = new ResourceHelper();
InitializeComponent();
}
@@ -100,31 +102,30 @@ namespace ModernKeePass.Views.UserControls
else
{
var database = await _mediator.Send(new GetDatabaseQuery());
var resource = new ResourcesService();
if (database.IsOpen)
{
await MessageDialogHelper.ShowActionDialog(resource.GetResourceValue("MessageDialogDBOpenTitle"),
string.Format(resource.GetResourceValue("MessageDialogDBOpenDesc"), database.Name),
resource.GetResourceValue("MessageDialogDBOpenButtonSave"),
resource.GetResourceValue("MessageDialogDBOpenButtonDiscard"),
await MessageDialogHelper.ShowActionDialog(_resource.GetResourceValue("MessageDialogDBOpenTitle"),
string.Format(_resource.GetResourceValue("MessageDialogDBOpenDesc"), database.Name),
_resource.GetResourceValue("MessageDialogDBOpenButtonSave"),
_resource.GetResourceValue("MessageDialogDBOpenButtonDiscard"),
async command =>
{
await _mediator.Send(new SaveDatabaseCommand());
ToastNotificationHelper.ShowGenericToast(
database.Name,
resource.GetResourceValue("ToastSavedMessage"));
_resource.GetResourceValue("ToastSavedMessage"));
await _mediator.Send(new CloseDatabaseCommand());
await OpenDatabase(resource);
await OpenDatabase();
},
async command =>
{
await _mediator.Send(new CloseDatabaseCommand());
await OpenDatabase(resource);
await OpenDatabase();
});
}
else
{
await OpenDatabase(resource);
await OpenDatabase();
}
}
}
@@ -151,7 +152,9 @@ namespace ModernKeePass.Views.UserControls
// Application now has read/write access to the picked file
var file = await picker.PickSingleFileAsync();
if (file == null) return;
Model.KeyFile = file;
var token = StorageApplicationPermissions.FutureAccessList.Add(file);
Model.KeyFilePath = token;
}
private async void CreateKeyFileButton_Click(object sender, RoutedEventArgs e)
@@ -166,14 +169,19 @@ namespace ModernKeePass.Views.UserControls
var file = await savePicker.PickSaveFileAsync();
if (file == null) return;
await Model.CreateKeyFile(file);
var token = StorageApplicationPermissions.FutureAccessList.Add(file);
await Model.CreateKeyFile(new FileInfo
{
Path = token,
Name = file.DisplayName
});
}
private async Task OpenDatabase(IResourceService resource)
private async Task OpenDatabase()
{
var oldLabel = ButtonLabel;
ButtonLabel = resource.GetResourceValue("CompositeKeyOpening");
if (await Dispatcher.RunTaskAsync(async () => await Model.OpenDatabase(DatabaseFile, CreateNew)))
ButtonLabel = _resource.GetResourceValue("CompositeKeyOpening");
if (await Dispatcher.RunTaskAsync(async () => await Model.OpenDatabase(DatabaseFilePath, CreateNew)))
{
ValidationChecked?.Invoke(this, new PasswordEventArgs(Model.RootGroupId));
}

View File

@@ -117,32 +117,19 @@
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<Compile Include="Common\ResourceHelper.cs" />
<Compile Include="Converters\IconToSymbolConverter.cs" />
<Compile Include="DependencyInjection.cs" />
<Compile Include="ImportFormats\CsvImportFormat.cs" />
<Compile Include="ImportFormats\NullImportFormat.cs" />
<Compile Include="Interfaces\IFormat.cs" />
<Compile Include="Interfaces\IProxyInvocationHandler.cs" />
<Compile Include="Interfaces\IRecentService.cs" />
<Compile Include="Interfaces\IRecentItem.cs" />
<Compile Include="Interfaces\IResourceService.cs" />
<Compile Include="Services\SingletonServiceBase.cs" />
<Compile Include="TemplateSelectors\SelectableDataTemplateSelector.cs" />
<Compile Include="ViewModels\Items\SettingsSaveVm.cs" />
<Compile Include="Views\MainPageFrames\DonatePage.xaml.cs">
<DependentUpon>DonatePage.xaml</DependentUpon>
</Compile>
<Content Include="Services\DatabaseService.cs" />
<Compile Include="Interfaces\ISettingsService.cs" />
<Compile Include="Common\MessageDialogHelper.cs" />
<Compile Include="Common\NavigationHelper.cs" />
<Compile Include="Common\NotifyPropertyChangedBase.cs" />
<Compile Include="Common\ObservableDictionary.cs" />
<Compile Include="Common\RelayCommand.cs" />
<Compile Include="Common\SuspensionManager.cs" />
<Compile Include="Services\RecentService.cs" />
<Compile Include="Services\ResourcesService.cs" />
<Compile Include="Services\SettingsService.cs" />
<Compile Include="Common\ToastNotificationHelper.cs" />
<Compile Include="Converters\DiscreteIntToSolidColorBrushConverter.cs" />
<Compile Include="Converters\EmptyStringToVisibilityConverter.cs" />