Changed most services to singletons

Refactor the Database Service (no more enum, ...)
Restored the Donate page with Paypal web page
Added (but not working) MS App Center integration
Corrected tests accordingly
WIP AOP to detect database changes
This commit is contained in:
BONNEVILLE Geoffroy
2018-02-23 18:09:21 +01:00
parent b46ab8db51
commit 7dbf93fe7b
35 changed files with 199 additions and 194 deletions

View File

@@ -0,0 +1,14 @@
using System;
using ModernKeePass.Services;
namespace ModernKeePass.Attributes
{
[AttributeUsage(AttributeTargets.All)]
public class DatabaseChangedAttribute: Attribute
{
public DatabaseChangedAttribute()
{
DatabaseService.Instance.HasChanged = true;
}
}
}

View File

@@ -0,0 +1,26 @@
using System.Reflection;
using ModernKeePass.Interfaces;
namespace ModernKeePass.Aop
{
public class DatabaseChangedProxy<T>: IProxyInvocationHandler
{
private readonly T _decorated;
private readonly IDatabaseService _databaseService;
public DatabaseChangedProxy(T decorated, IDatabaseService databaseService)
{
_decorated = decorated;
_databaseService = databaseService;
}
public object Invoke(object proxy, MethodInfo method, object[] parameters)
{
object retVal = null;
retVal = method.Invoke(proxy, parameters);
_databaseService.HasChanged = true;
return retVal;
}
}
}

View File

@@ -6,6 +6,9 @@ using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using Microsoft.AppCenter;
using Microsoft.AppCenter.Analytics;
using Microsoft.AppCenter.Push;
using ModernKeePass.Common;
using ModernKeePass.Exceptions;
using ModernKeePass.Services;
@@ -20,18 +23,16 @@ namespace ModernKeePass
/// </summary>
sealed partial class App
{
public DatabaseService Database { get; private set; }
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
AppCenter.Start("79d23520-a486-4f63-af81-8d90bf4e1bea", typeof(Analytics), typeof(Push));
InitializeComponent();
Suspending += OnSuspending;
UnhandledException += OnUnhandledException;
Database = new DatabaseService();
}
#region Event Handlers
@@ -49,12 +50,12 @@ namespace ModernKeePass
if (realException is SaveException)
{
unhandledExceptionEventArgs.Handled = true;
MessageDialogHelper.SaveErrorDialog(realException as SaveException, Database);
MessageDialogHelper.SaveErrorDialog(realException as SaveException, DatabaseService.Instance);
}
else if (realException is DatabaseOpenedException)
{
unhandledExceptionEventArgs.Handled = true;
MessageDialogHelper.SaveUnchangedDialog(realException as DatabaseOpenedException, Database);
MessageDialogHelper.SaveUnchangedDialog(realException as DatabaseOpenedException, DatabaseService.Instance);
}
}
@@ -153,8 +154,9 @@ namespace ModernKeePass
{
var deferral = e.SuspendingOperation.GetDeferral();
UnhandledException -= OnUnhandledException;
Database.Save();
await Database.Close();
var database = DatabaseService.Instance;
database.Save();
await database.Close();
deferral.Complete();
}
@@ -166,7 +168,7 @@ namespace ModernKeePass
{
base.OnFileActivated(args);
var rootFrame = new Frame();
Database.DatabaseFile = args.Files[0] as StorageFile;
DatabaseService.Instance.DatabaseFile = args.Files[0] as StorageFile;
rootFrame.Navigate(typeof(MainPage), args);
Window.Current.Content = rootFrame;
Window.Current.Activate();

View File

@@ -22,7 +22,7 @@ namespace ModernKeePass.Common
await messageDialog.ShowAsync();
}
public static void SaveErrorDialog(SaveException exception, IDatabase database)
public static void SaveErrorDialog(SaveException exception, IDatabaseService database)
{
ShowActionDialog("Save error", exception.InnerException.Message, "Save as", "Discard", async command =>
{
@@ -38,7 +38,7 @@ namespace ModernKeePass.Common
}, null);
}
public static void SaveUnchangedDialog(DatabaseOpenedException exception, IDatabase database)
public static void SaveUnchangedDialog(DatabaseOpenedException exception, IDatabaseService database)
{
ShowActionDialog("Opened database", $"Database {database.Name} is currently opened. What to you wish to do?", "Save changes", "Discard", command =>
{

View File

@@ -7,7 +7,7 @@ using ModernKeePassLib.Keys;
namespace ModernKeePass.Interfaces
{
public interface IDatabase
public interface IDatabaseService
{
string Name { get; }
bool RecycleBinEnabled { get; set; }
@@ -21,6 +21,7 @@ namespace ModernKeePass.Interfaces
bool IsOpen { get; }
bool IsFileOpen { get; }
bool IsClosed { get; }
bool HasChanged { get; set; }
Task Open(CompositeKey key, bool createNew);
void UpdateCompositeKey(CompositeKey key);

View File

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

View File

@@ -4,7 +4,7 @@ using Windows.Storage;
namespace ModernKeePass.Interfaces
{
public interface IRecent
public interface IRecentService
{
int EntryCount { get; }
Task<IStorageItem> GetFileAsync(string token);

View File

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

View File

@@ -1,6 +1,6 @@
namespace ModernKeePass.Interfaces
{
public interface ISettings
public interface ISettingsService
{
T GetSetting<T>(string property);
void PutSetting<T>(string property, T value);

View File

@@ -111,21 +111,24 @@
<Compile Include="Actions\ClipboardAction.cs" />
<Compile Include="Actions\NavigateToUrlAction.cs" />
<Compile Include="Actions\SetupFocusAction.cs" />
<Compile Include="Aop\DatabaseChangedProxy.cs" />
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<Compile Include="Aop\DatabaseChanged.cs" />
<Compile Include="Exceptions\DatabaseOpenedException.cs" />
<Compile Include="Interfaces\ILicenseService.cs" />
<Compile Include="Interfaces\IRecent.cs" />
<Compile Include="Interfaces\IProxyInvocationHandler.cs" />
<Compile Include="Interfaces\IRecentService.cs" />
<Compile Include="Interfaces\IRecentItem.cs" />
<Compile Include="Interfaces\IResource.cs" />
<Compile Include="Interfaces\IResourceService.cs" />
<Compile Include="Services\SingletonServiceBase.cs" />
<Compile Include="TemplateSelectors\SelectableDataTemplateSelector.cs" />
<Compile Include="ViewModels\DonateVm.cs" />
<Compile Include="Views\MainPageFrames\DonatePage.xaml.cs">
<DependentUpon>DonatePage.xaml</DependentUpon>
</Compile>
<Compile Include="Services\DatabaseService.cs" />
<Compile Include="Interfaces\ISettings.cs" />
<Compile Include="Interfaces\ISettingsService.cs" />
<Compile Include="Common\MessageDialogHelper.cs" />
<Compile Include="Common\NavigationHelper.cs" />
<Compile Include="Common\NotifyPropertyChangedBase.cs" />
@@ -142,7 +145,7 @@
<Compile Include="Converters\NullToBooleanConverter.cs" />
<Compile Include="Exceptions\SaveException.cs" />
<Compile Include="Extensions\DispatcherTaskExtensions.cs" />
<Compile Include="Interfaces\IDatabase.cs" />
<Compile Include="Interfaces\IDatabaseService.cs" />
<Compile Include="Interfaces\IHasSelectableObject.cs" />
<Compile Include="Interfaces\ISelectableModel.cs" />
<Compile Include="Views\BasePages\LayoutAwarePageBase.cs" />
@@ -337,6 +340,18 @@
<HintPath>..\packages\Portable.BouncyCastle.1.8.1.3\lib\netstandard1.0\BouncyCastle.Crypto.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.AppCenter, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AppCenter.1.4.0\lib\portable-net45+win8+wpa81+wp8\Microsoft.AppCenter.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.AppCenter.Analytics, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AppCenter.Analytics.1.4.0\lib\portable-net45+win8+wpa81+wp8\Microsoft.AppCenter.Analytics.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.AppCenter.Push, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AppCenter.Push.1.4.0\lib\portable-net45+win8+wpa81+wp8\Microsoft.AppCenter.Push.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Toolkit.Uwp.Notifications, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Toolkit.Uwp.Notifications.2.0.0\lib\dotnet\Microsoft.Toolkit.Uwp.Notifications.dll</HintPath>
<Private>True</Private>

View File

@@ -15,10 +15,10 @@ using ModernKeePassLib.Serialization;
namespace ModernKeePass.Services
{
public class DatabaseService: IDatabase
public class DatabaseService: SingletonServiceBase<DatabaseService>, IDatabaseService
{
private readonly PwDatabase _pwDatabase = new PwDatabase();
private readonly ISettings _settings;
private readonly ISettingsService _settings;
private StorageFile _realDatabaseFile;
private StorageFile _databaseFile;
private GroupVm _recycleBin;
@@ -48,7 +48,7 @@ namespace ModernKeePass.Services
get { return _databaseFile; }
set
{
if (IsOpen)
if (IsOpen && HasChanged)
{
throw new DatabaseOpenedException();
}
@@ -77,15 +77,18 @@ namespace ModernKeePass.Services
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() : this(new SettingsService())
{ }
public DatabaseService(ISettings settings)
public DatabaseService(ISettingsService settings)
{
_settings = settings;
}
/// <summary>
/// Open a KeePass database
/// </summary>
@@ -118,7 +121,7 @@ namespace ModernKeePass.Services
}
else _pwDatabase.Open(ioConnection, key, new NullStatusLogger());
if (!_pwDatabase.IsOpen) return;
//if (!_pwDatabase.IsOpen) return;
// Copy database in temp directory and use this file for operations
if (_settings.GetSetting<bool>("AntiCorruption"))

View File

@@ -6,7 +6,7 @@ using ModernKeePass.Interfaces;
namespace ModernKeePass.Services
{
public class LicenseService : ILicenseService
public class LicenseService : SingletonServiceBase<LicenseService>, ILicenseService
{
public enum PurchaseResult
{

View File

@@ -8,10 +8,10 @@ using ModernKeePass.ViewModels;
namespace ModernKeePass.Services
{
public class RecentService : IRecent
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)

View File

@@ -3,7 +3,7 @@ using ModernKeePass.Interfaces;
namespace ModernKeePass.Services
{
public class ResourcesService: IResource
public class ResourcesService: IResourceService
{
private const string ResourceFileName = "CodeBehind";
private readonly ResourceLoader _resourceLoader = ResourceLoader.GetForCurrentView();

View File

@@ -5,10 +5,10 @@ using ModernKeePass.Interfaces;
namespace ModernKeePass.Services
{
public class SettingsService : ISettings
public class SettingsService : SingletonServiceBase<SettingsService>, ISettingsService
{
private readonly IPropertySet _values = ApplicationData.Current.LocalSettings.Values;
public T GetSetting<T>(string property)
{
try

View File

@@ -0,0 +1,12 @@
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

@@ -22,7 +22,7 @@ namespace ModernKeePass.ViewModels
Success = 5
}
public IDatabase Database { get; set; }
public IDatabaseService Database { get; set; }
public bool HasPassword
{
@@ -111,11 +111,11 @@ namespace ModernKeePass.ViewModels
private StatusTypes _statusType;
private StorageFile _keyFile;
private string _keyFileText;
private readonly IResource _resource;
private readonly IResourceService _resource;
public CompositeKeyVm() : this((Application.Current as App)?.Database, new ResourcesService()) { }
public CompositeKeyVm() : this(DatabaseService.Instance, new ResourcesService()) { }
public CompositeKeyVm(IDatabase database, IResource resource)
public CompositeKeyVm(IDatabaseService database, IResourceService resource)
{
_resource = resource;
_keyFileText = _resource.GetResourceValue("CompositeKeyDefaultKeyFile");

View File

@@ -1,44 +0,0 @@
using System;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Windows.ApplicationModel.Store;
using ModernKeePass.Common;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
namespace ModernKeePass.ViewModels
{
public class DonateVm: NotifyPropertyChangedBase
{
public ObservableCollection<ProductListing> Donations { get; }
public ProductListing SelectedItem
{
get { return _selectedItem; }
set { SetProperty(ref _selectedItem, value); }
}
private readonly ILicenseService _license;
private ProductListing _selectedItem;
public DonateVm() : this (new LicenseService()) { }
public DonateVm(ILicenseService license)
{
// TODO: find a nice way to order products
_license = license;
Donations = new ObservableCollection<ProductListing>(
_license.Products.Values
/*.OrderBy(p => decimal.Parse(p.FormattedPrice.Replace('\u00A0', ' '), NumberStyles.Currency,
CultureInfo.CurrentCulture.NumberFormat))*/
);
}
public async Task<int> Purchase()
{
return await _license.Purchase(SelectedItem.ProductId);
}
}
}

View File

@@ -1,10 +1,11 @@
using System;
using System.ComponentModel;
using System.Text;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using ModernKeePass.Attributes;
using ModernKeePass.Interfaces;
using ModernKeePass.Mappings;
using ModernKeePass.Services;
using ModernKeePassLib;
using ModernKeePassLib.Cryptography.PasswordGenerator;
using ModernKeePassLib.Security;
@@ -67,6 +68,7 @@ namespace ModernKeePass.ViewModels
NotifyPropertyChanged("PasswordComplexityIndicator");
}
}
public string Url
{
get { return GetEntryValue(PwDefs.UrlField); }
@@ -155,7 +157,7 @@ namespace ModernKeePass.ViewModels
public event PropertyChangedEventHandler PropertyChanged;
private readonly PwEntry _pwEntry;
private readonly IDatabase _database;
private readonly IDatabaseService _database;
private bool _isEditMode;
private bool _isRevealPassword;
private double _passwordLength = 25;
@@ -168,9 +170,9 @@ namespace ModernKeePass.ViewModels
public EntryVm() { }
internal EntryVm(PwEntry entry, GroupVm parent) : this(entry, parent, (Application.Current as App)?.Database) { }
internal EntryVm(PwEntry entry, GroupVm parent) : this(entry, parent, DatabaseService.Instance) { }
public EntryVm(PwEntry entry, GroupVm parent, IDatabase database)
public EntryVm(PwEntry entry, GroupVm parent, IDatabaseService database)
{
_database = database;
_pwEntry = entry;
@@ -211,6 +213,7 @@ namespace ModernKeePass.ViewModels
return _pwEntry?.Strings.GetSafe(key).ReadString();
}
[DatabaseChanged]
private void SetEntryValue(string key, string newValue)
{
_pwEntry?.Strings.Set(key, new ProtectedString(true, newValue));

View File

@@ -3,11 +3,12 @@ using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using ModernKeePass.Attributes;
using ModernKeePass.Common;
using ModernKeePass.Interfaces;
using ModernKeePass.Mappings;
using ModernKeePass.Services;
using ModernKeePassLib;
namespace ModernKeePass.ViewModels
@@ -54,6 +55,7 @@ namespace ModernKeePass.ViewModels
public string Name
{
get { return _pwGroup == null ? string.Empty : _pwGroup.Name; }
[DatabaseChanged]
set { _pwGroup.Name = value; }
}
@@ -92,7 +94,7 @@ namespace ModernKeePass.ViewModels
}
private readonly PwGroup _pwGroup;
private readonly IDatabase _database;
private readonly IDatabaseService _database;
private bool _isEditMode;
private PwEntry _reorderedEntry;
private ObservableCollection<EntryVm> _entries = new ObservableCollection<EntryVm>();
@@ -101,10 +103,10 @@ namespace ModernKeePass.ViewModels
public GroupVm() {}
internal GroupVm(PwGroup pwGroup, GroupVm parent, PwUuid recycleBinId = null) : this(pwGroup, parent,
(Application.Current as App)?.Database, recycleBinId)
DatabaseService.Instance, recycleBinId)
{ }
public GroupVm(PwGroup pwGroup, GroupVm parent, IDatabase database, PwUuid recycleBinId = null)
public GroupVm(PwGroup pwGroup, GroupVm parent, IDatabaseService database, PwUuid recycleBinId = null)
{
_pwGroup = pwGroup;
_database = database;
@@ -115,7 +117,8 @@ namespace ModernKeePass.ViewModels
Entries.CollectionChanged += Entries_CollectionChanged;
Groups = new ObservableCollection<GroupVm>(pwGroup.Groups.Select(g => new GroupVm(g, this, recycleBinId)));
}
[DatabaseChanged]
private void Entries_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
@@ -131,7 +134,8 @@ namespace ModernKeePass.ViewModels
break;
}
}
[DatabaseChanged]
public GroupVm AddNewGroup(string name = "")
{
var pwGroup = new PwGroup(true, true, name, PwIcon.Folder);
@@ -162,6 +166,8 @@ namespace ModernKeePass.ViewModels
Move(PreviousGroup);
}
[DatabaseChanged]
public void Move(GroupVm destination)
{
PreviousGroup = ParentGroup;
@@ -189,6 +195,8 @@ namespace ModernKeePass.ViewModels
_database.Save();
}
[DatabaseChanged]
public void SortEntries()
{
var comparer = new PwEntryComparer(PwDefs.TitleField, true, false);
@@ -203,6 +211,8 @@ namespace ModernKeePass.ViewModels
}
}
[DatabaseChanged]
public void SortGroups()
{
try

View File

@@ -1,6 +1,5 @@
using Windows.Storage;
using ModernKeePass.Common;
using Windows.UI.Xaml;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
@@ -31,20 +30,20 @@ namespace ModernKeePass.ViewModels
public void OpenDatabaseFile()
{
OpenDatabaseFile((Application.Current as App)?.Database);
OpenDatabaseFile(DatabaseService.Instance);
}
public void OpenDatabaseFile(IDatabase database)
public void OpenDatabaseFile(IDatabaseService database)
{
database.DatabaseFile = DatabaseFile;
}
public void UpdateAccessTime()
{
UpdateAccessTime(new RecentService());
UpdateAccessTime(RecentService.Instance);
}
public async void UpdateAccessTime(IRecent recent)
public async void UpdateAccessTime(IRecentService recent)
{
await recent.GetFileAsync(Token);
}

View File

@@ -2,9 +2,9 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Windows.UI.Xaml;
using ModernKeePass.Common;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
using ModernKeePassLib;
using ModernKeePassLib.Cryptography.Cipher;
using ModernKeePassLib.Cryptography.KeyDerivation;
@@ -14,7 +14,7 @@ namespace ModernKeePass.ViewModels
// TODO: implement Kdf settings
public class SettingsDatabaseVm: NotifyPropertyChangedBase, IHasSelectableObject
{
private readonly IDatabase _database;
private readonly IDatabaseService _database;
private GroupVm _selectedItem;
public bool HasRecycleBin
@@ -88,9 +88,9 @@ namespace ModernKeePass.ViewModels
}
}
public SettingsDatabaseVm() : this((Application.Current as App)?.Database) { }
public SettingsDatabaseVm() : this(DatabaseService.Instance) { }
public SettingsDatabaseVm(IDatabase database)
public SettingsDatabaseVm(IDatabaseService database)
{
_database = database;
Groups = _database?.RootGroup.Groups;

View File

@@ -6,12 +6,12 @@ namespace ModernKeePass.ViewModels
{
public class SettingsNewVm
{
private ISettings _settings;
private ISettingsService _settings;
public SettingsNewVm() : this(new SettingsService())
public SettingsNewVm() : this(SettingsService.Instance)
{ }
public SettingsNewVm(ISettings settings)
public SettingsNewVm(ISettingsService settings)
{
_settings = settings;
}

View File

@@ -1,7 +1,6 @@
using System.Collections.ObjectModel;
using System.Linq;
using Windows.ApplicationModel;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using ModernKeePass.Common;
using ModernKeePass.Interfaces;
@@ -46,10 +45,10 @@ namespace ModernKeePass.ViewModels
public MainVm() {}
internal MainVm(Frame referenceFrame, Frame destinationFrame) : this(referenceFrame, destinationFrame,
(Application.Current as App)?.Database, new ResourcesService(), new RecentService())
DatabaseService.Instance, new ResourcesService(), RecentService.Instance)
{ }
public MainVm(Frame referenceFrame, Frame destinationFrame, IDatabase database, IResource resource, IRecent recent)
public MainVm(Frame referenceFrame, Frame destinationFrame, IDatabaseService database, IResourceService resource, IRecentService recent)
{
var isDatabaseOpen = database != null && database.IsOpen;
@@ -62,7 +61,7 @@ namespace ModernKeePass.ViewModels
Destination = destinationFrame,
Parameter = referenceFrame,
SymbolIcon = Symbol.Page2,
IsSelected = database != null && database.IsFileOpen
IsSelected = database != null && database.IsFileOpen && !database.IsOpen
},
new MainMenuItemVm
{
@@ -107,14 +106,14 @@ namespace ModernKeePass.ViewModels
PageType = typeof(AboutPage),
Destination = destinationFrame,
SymbolIcon = Symbol.Help
}/*,
},
new MainMenuItemVm
{
Title = resource.GetResourceValue("MainMenuItemDonate"),
PageType = typeof(DonatePage),
Destination = destinationFrame,
SymbolIcon = Symbol.Shop
}*/
}
};
// Auto-select the Recent Items menu item if the conditions are met
SelectedItem = mainMenuItems.FirstOrDefault(m => m.IsSelected);

View File

@@ -1,5 +1,4 @@
using Windows.Storage;
using Windows.UI.Xaml;
using ModernKeePass.Common;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
@@ -12,11 +11,11 @@ namespace ModernKeePass.ViewModels
public string Name => _database?.Name;
private readonly IDatabase _database;
private readonly IDatabaseService _database;
public OpenVm() : this((Application.Current as App)?.Database) { }
public OpenVm() : this(DatabaseService.Instance) { }
public OpenVm(IDatabase database)
public OpenVm(IDatabaseService database)
{
_database = database;
if (database == null || !database.IsFileOpen) return;
@@ -25,10 +24,10 @@ namespace ModernKeePass.ViewModels
public void OpenFile(StorageFile file)
{
OpenFile(file, new RecentService());
OpenFile(file, RecentService.Instance);
}
public void OpenFile(StorageFile file, IRecent recent)
public void OpenFile(StorageFile file, IRecentService recent)
{
_database.DatabaseFile = file;
OnPropertyChanged("Name");
@@ -36,7 +35,7 @@ namespace ModernKeePass.ViewModels
AddToRecentList(file, recent);
}
private void AddToRecentList(StorageFile file, IRecent recent)
private void AddToRecentList(StorageFile file, IRecentService recent)
{
recent.Add(file, file.DisplayName);
}

View File

@@ -7,7 +7,7 @@ namespace ModernKeePass.ViewModels
{
public class RecentVm : NotifyPropertyChangedBase, IHasSelectableObject
{
private readonly IRecent _recent;
private readonly IRecentService _recent;
private ISelectableModel _selectedItem;
private ObservableCollection<IRecentItem> _recentItems = new ObservableCollection<IRecentItem>();
@@ -35,10 +35,10 @@ namespace ModernKeePass.ViewModels
}
}
public RecentVm() : this (new RecentService())
public RecentVm() : this (RecentService.Instance)
{ }
public RecentVm(IRecent recent)
public RecentVm(IRecentService recent)
{
_recent = recent;
RecentItems = _recent.GetAllFiles();

View File

@@ -1,16 +1,16 @@
using System.Threading.Tasks;
using Windows.Storage;
using Windows.UI.Xaml;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
namespace ModernKeePass.ViewModels
{
public class SaveVm
{
private readonly IDatabase _database;
public SaveVm() : this((Application.Current as App)?.Database) { }
private readonly IDatabaseService _database;
public SaveVm() : this(DatabaseService.Instance) { }
public SaveVm(IDatabase database)
public SaveVm(IDatabaseService database)
{
_database = database;
}

View File

@@ -1,6 +1,5 @@
using System.Collections.ObjectModel;
using System.Linq;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using ModernKeePass.Common;
using ModernKeePass.Interfaces;
@@ -41,9 +40,9 @@ namespace ModernKeePass.ViewModels
}
}
public SettingsVm() : this((Application.Current as App)?.Database, new ResourcesService()) { }
public SettingsVm() : this(DatabaseService.Instance, new ResourcesService()) { }
public SettingsVm(IDatabase database, IResource resource)
public SettingsVm(IDatabaseService database, IResourceService resource)
{
var menuItems = new ObservableCollection<ListMenuItemVm>
{

View File

@@ -4,27 +4,6 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="using:ModernKeePass.ViewModels"
xmlns:converters="using:ModernKeePass.Converters"
mc:Ignorable="d">
<Page.DataContext>
<viewModels:DonateVm />
</Page.DataContext>
<Page.Resources>
<converters:NullToBooleanConverter x:Key="NullToBooleanConverter"/>
<CollectionViewSource
x:Name="DonateItemsSource"
Source="{Binding Donations}" />
</Page.Resources>
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Margin="10,0,0,0">
<TextBlock x:Uid="DonateDesc" Style="{StaticResource BodyTextBlockStyle}" />
<ItemsControl ItemsSource="{Binding Source={StaticResource DonateItemsSource}}" Margin="0,10,0,10">
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton GroupName="DonateOptions" Content="{Binding FormattedPrice}" Checked="ToggleButton_OnChecked" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button x:Uid="DonateButton" Click="ButtonBase_OnClick" IsEnabled="{Binding SelectedItem, Converter={StaticResource NullToBooleanConverter}}" />
</StackPanel>
<WebView Source="https://PayPal.Me/wismna"></WebView>
</Page>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.AppCenter" version="1.4.0" targetFramework="win81" />
<package id="Microsoft.AppCenter.Analytics" version="1.4.0" targetFramework="win81" />
<package id="Microsoft.AppCenter.Push" version="1.4.0" targetFramework="win81" />
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="win81" />
<package id="Microsoft.NETCore.Platforms" version="2.0.1" targetFramework="win81" />
<package id="Microsoft.NETCore.Portable.Compatibility" version="1.0.2" targetFramework="win81" />