diff --git a/ModernKeePass/Actions/ToastAction.cs b/ModernKeePass/Actions/ToastAction.cs
new file mode 100644
index 0000000..e6da006
--- /dev/null
+++ b/ModernKeePass/Actions/ToastAction.cs
@@ -0,0 +1,33 @@
+using Windows.UI.Xaml;
+using Microsoft.Xaml.Interactivity;
+using ModernKeePass.Common;
+
+namespace ModernKeePass.Actions
+{
+ public class ToastAction : DependencyObject, IAction
+ {
+ public string Title
+ {
+ get { return (string)GetValue(TitleProperty); }
+ set { SetValue(TitleProperty, value); }
+ }
+
+ public static readonly DependencyProperty TitleProperty =
+ DependencyProperty.Register("Title", typeof(string), typeof(ToastAction), new PropertyMetadata(string.Empty));
+
+ public string Message
+ {
+ get { return (string)GetValue(MessageProperty); }
+ set { SetValue(MessageProperty, value); }
+ }
+
+ public static readonly DependencyProperty MessageProperty =
+ DependencyProperty.Register("Message", typeof(string), typeof(ToastAction), new PropertyMetadata(string.Empty));
+
+ public object Execute(object sender, object parameter)
+ {
+ ToastNotificationHelper.ShowGenericToast(Title, Message);
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/ModernKeePass/App.xaml.cs b/ModernKeePass/App.xaml.cs
index 4d4957d..6255ae4 100644
--- a/ModernKeePass/App.xaml.cs
+++ b/ModernKeePass/App.xaml.cs
@@ -114,7 +114,8 @@ namespace ModernKeePass
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
- //TODO: Load state from previously terminated application
+ // Load state from previously terminated application
+ await SuspensionManager.RestoreAsync();
#if DEBUG
await MessageDialogHelper.ShowNotificationDialog("App terminated", "Windows or an error made the app terminate");
#endif
@@ -164,7 +165,7 @@ namespace ModernKeePass
/// Details about the navigation failure
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
- throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
+ throw new NavigationException(e.SourcePageType);
}
///
@@ -174,7 +175,7 @@ namespace ModernKeePass
///
/// The source of the suspend request.
/// Details about the suspend request.
- private void OnSuspending(object sender, SuspendingEventArgs e)
+ private async void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
var database = DatabaseService.Instance;
@@ -187,6 +188,7 @@ namespace ModernKeePass
{
ToastNotificationHelper.ShowErrorToast(exception);
}
+ await SuspensionManager.SaveAsync();
deferral.Complete();
}
diff --git a/ModernKeePass/Common/SuspensionManager.cs b/ModernKeePass/Common/SuspensionManager.cs
index da57a4e..3b00613 100644
--- a/ModernKeePass/Common/SuspensionManager.cs
+++ b/ModernKeePass/Common/SuspensionManager.cs
@@ -17,7 +17,7 @@ namespace ModernKeePass.Common
/// carry across sessions, but that should be discarded when an application crashes or is
/// upgraded.
///
- internal sealed class SuspensionManager
+ internal static class SuspensionManager
{
private static Dictionary _sessionState = new Dictionary();
private static readonly List _knownTypes = new List();
diff --git a/ModernKeePass/Exceptions/DatabaseOpenedException.cs b/ModernKeePass/Exceptions/DatabaseOpenedException.cs
deleted file mode 100644
index 52f2b01..0000000
--- a/ModernKeePass/Exceptions/DatabaseOpenedException.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System;
-
-namespace ModernKeePass.Exceptions
-{
- public class DatabaseOpenedException: Exception
- {
-
- }
-}
diff --git a/ModernKeePass/Exceptions/NavigationException.cs b/ModernKeePass/Exceptions/NavigationException.cs
new file mode 100644
index 0000000..a42109f
--- /dev/null
+++ b/ModernKeePass/Exceptions/NavigationException.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace ModernKeePass.Exceptions
+{
+ public class NavigationException: Exception
+ {
+ public NavigationException(Type pageType) : base($"Failed to load Page {pageType.FullName}")
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/ModernKeePass/ModernKeePass.App.csproj b/ModernKeePass/ModernKeePass.App.csproj
index c889842..2f71684 100644
--- a/ModernKeePass/ModernKeePass.App.csproj
+++ b/ModernKeePass/ModernKeePass.App.csproj
@@ -111,11 +111,12 @@
+
App.xaml
-
+
diff --git a/ModernKeePass/Strings/en-US/CodeBehind.resw b/ModernKeePass/Strings/en-US/CodeBehind.resw
index dc123e7..5314966 100644
--- a/ModernKeePass/Strings/en-US/CodeBehind.resw
+++ b/ModernKeePass/Strings/en-US/CodeBehind.resw
@@ -294,4 +294,7 @@
Save error
+
+ Database successfully saved!
+
\ No newline at end of file
diff --git a/ModernKeePass/Strings/en-US/Resources.resw b/ModernKeePass/Strings/en-US/Resources.resw
index 1a15826..2359568 100644
--- a/ModernKeePass/Strings/en-US/Resources.resw
+++ b/ModernKeePass/Strings/en-US/Resources.resw
@@ -387,4 +387,13 @@
History
+
+ Login successfully copied!
+
+
+ Password successfully copied!
+
+
+ URL successfully copied!
+
\ No newline at end of file
diff --git a/ModernKeePass/Strings/fr-FR/CodeBehind.resw b/ModernKeePass/Strings/fr-FR/CodeBehind.resw
index 18ab9bd..c7e8214 100644
--- a/ModernKeePass/Strings/fr-FR/CodeBehind.resw
+++ b/ModernKeePass/Strings/fr-FR/CodeBehind.resw
@@ -187,7 +187,7 @@
Attention
- Suprression
+ Suppression
Restauré
@@ -208,10 +208,10 @@
Entrée replacée dans son groupe d'origine
- Groupe supprimé défnitivement
+ Groupe supprimé définitivement
- Êtes-vous sûr de vouloir supprimer ce group et toutes ses entrées ?
+ Êtes-vous sûr de vouloir supprimer ce groupe et toutes ses entrées ?
Groupe placé dans la Corbeille
@@ -294,4 +294,7 @@
Erreur de sauvegarde
+
+ Base de données sauvegardée avec succès !
+
\ No newline at end of file
diff --git a/ModernKeePass/Strings/fr-FR/Resources.resw b/ModernKeePass/Strings/fr-FR/Resources.resw
index b33fda5..9845612 100644
--- a/ModernKeePass/Strings/fr-FR/Resources.resw
+++ b/ModernKeePass/Strings/fr-FR/Resources.resw
@@ -387,4 +387,13 @@
Historique
+
+ Login copié avec succès !
+
+
+ Mot de passe copié avec succès !
+
+
+ URL copié avec succès !
+
\ No newline at end of file
diff --git a/ModernKeePass/Views/GroupDetailPage.xaml b/ModernKeePass/Views/GroupDetailPage.xaml
index 0464e7b..ee6c65f 100644
--- a/ModernKeePass/Views/GroupDetailPage.xaml
+++ b/ModernKeePass/Views/GroupDetailPage.xaml
@@ -153,6 +153,7 @@
+
@@ -160,6 +161,7 @@
+
@@ -167,6 +169,7 @@
+
diff --git a/ModernKeePass/Views/UserControls/CompositeKeyUserControl.xaml.cs b/ModernKeePass/Views/UserControls/CompositeKeyUserControl.xaml.cs
index a476e34..c7253aa 100644
--- a/ModernKeePass/Views/UserControls/CompositeKeyUserControl.xaml.cs
+++ b/ModernKeePass/Views/UserControls/CompositeKeyUserControl.xaml.cs
@@ -103,6 +103,9 @@ namespace ModernKeePass.Views.UserControls
async command =>
{
database.Save();
+ ToastNotificationHelper.ShowGenericToast(
+ database.Name,
+ resource.GetResourceValue("ToastSavedMessage"));
database.Close(false);
await OpenDatabase(resource);
},
diff --git a/ModernKeePassApp.Test/DatabaseTests.cs b/ModernKeePassApp.Test/DatabaseTests.cs
index 77965ac..cf5286f 100644
--- a/ModernKeePassApp.Test/DatabaseTests.cs
+++ b/ModernKeePassApp.Test/DatabaseTests.cs
@@ -17,9 +17,8 @@ namespace ModernKeePassApp.Test
public void TestCreate()
{
Assert.IsTrue(_database.IsClosed);
- _database.DatabaseFile = ApplicationData.Current.TemporaryFolder.CreateFileAsync("NewDatabase.kdbx").GetAwaiter().GetResult();
- Assert.IsTrue(_database.IsFileOpen);
- OpenOrCreateDatabase(true);
+ var databaseFile = ApplicationData.Current.TemporaryFolder.CreateFileAsync("NewDatabase.kdbx").GetAwaiter().GetResult();
+ OpenOrCreateDatabase(databaseFile, true);
_database.Close();
Assert.IsTrue(_database.IsClosed);
}
@@ -28,9 +27,8 @@ namespace ModernKeePassApp.Test
public void TestOpen()
{
Assert.IsTrue(_database.IsClosed);
- _database.DatabaseFile = Package.Current.InstalledLocation.GetFileAsync(@"Data\TestDatabase.kdbx").GetAwaiter().GetResult();
- Assert.IsTrue(_database.IsFileOpen);
- OpenOrCreateDatabase(false);
+ var databaseFile = Package.Current.InstalledLocation.GetFileAsync(@"Data\TestDatabase.kdbx").GetAwaiter().GetResult();
+ OpenOrCreateDatabase(databaseFile, false);
}
[TestMethod]
@@ -44,16 +42,16 @@ namespace ModernKeePassApp.Test
TestOpen();
}
- private void OpenOrCreateDatabase(bool createNew)
+ private void OpenOrCreateDatabase(StorageFile databaseFile, bool createNew)
{
Assert.ThrowsException(
- () => _database.Open(null, createNew));
+ () => _database.Open(databaseFile, null, createNew));
var compositeKey = new CompositeKeyVm(_database, new ResourceServiceMock())
{
HasPassword = true,
Password = "test"
};
- compositeKey.OpenDatabase(createNew).GetAwaiter().GetResult();
+ compositeKey.OpenDatabase(databaseFile, createNew).GetAwaiter().GetResult();
Assert.IsTrue(_database.IsOpen);
}
}
diff --git a/ModernKeePassApp.Test/Mock/DatabaseServiceMock.cs b/ModernKeePassApp.Test/Mock/DatabaseServiceMock.cs
index 767f5c5..20f6731 100644
--- a/ModernKeePassApp.Test/Mock/DatabaseServiceMock.cs
+++ b/ModernKeePassApp.Test/Mock/DatabaseServiceMock.cs
@@ -11,13 +11,11 @@ namespace ModernKeePassApp.Test.Mock
public class DatabaseServiceMock : IDatabaseService
{
private bool _isOpen;
- private bool _isClosed;
private CompositeKey _compositeKey;
-
+ private StorageFile _databaseFile;
+
public PwCompressionAlgorithm CompressionAlgorithm { get; set; }
-
- public StorageFile DatabaseFile { get; set; }
-
+
public CompositeKey CompositeKey
{
get { return _compositeKey; }
@@ -30,10 +28,6 @@ namespace ModernKeePassApp.Test.Mock
public bool IsOpen => _isOpen;
- public bool IsFileOpen => DatabaseFile != null;
-
- public bool IsClosed => _isClosed;
-
public bool HasChanged { get; set; }
public string Name => "MockDatabase";
@@ -51,7 +45,6 @@ namespace ModernKeePassApp.Test.Mock
public void Close(bool releaseFile = true)
{
- _isClosed = true;
_isOpen = false;
}
@@ -59,17 +52,17 @@ namespace ModernKeePassApp.Test.Mock
{
throw new NotImplementedException();
}
-
- public void Open(CompositeKey key, bool createNew = false)
+
+ public void Open(StorageFile databaseFile, CompositeKey key, bool createNew = false)
{
+ _databaseFile = databaseFile;
_compositeKey = key;
_isOpen = true;
- _isClosed = false;
}
public void ReOpen()
{
- Open(_compositeKey);
+ Open(_databaseFile, _compositeKey);
}
public void Save()
diff --git a/ModernKeePassApp.Test/ViewModelsTests.cs b/ModernKeePassApp.Test/ViewModelsTests.cs
index 056d743..affb584 100644
--- a/ModernKeePassApp.Test/ViewModelsTests.cs
+++ b/ModernKeePassApp.Test/ViewModelsTests.cs
@@ -31,15 +31,15 @@ namespace ModernKeePassApp.Test
var mainVm = new MainVm(null, null, database, _resource, _recent);
Assert.AreEqual(1, mainVm.MainMenuItems.Count());
var firstGroup = mainVm.MainMenuItems.FirstOrDefault();
- Assert.AreEqual(7, firstGroup.Count());
+ Assert.AreEqual(7, firstGroup?.Count());
- database.DatabaseFile = Package.Current.InstalledLocation.GetFileAsync(@"Data\TestDatabase.kdbx")
+ var databaseFile = Package.Current.InstalledLocation.GetFileAsync(@"Data\TestDatabase.kdbx")
.GetAwaiter().GetResult();
- mainVm = new MainVm(null, null, database, _resource, _recent);
+ mainVm = new MainVm(null, null, database, _resource, _recent, databaseFile);
Assert.IsNotNull(mainVm.SelectedItem);
Assert.AreEqual(typeof(OpenDatabasePage), ((MainMenuItemVm) mainVm.SelectedItem).PageType);
- database.Open(null);
+ database.Open(databaseFile, null);
mainVm = new MainVm(null, null, database, _resource, _recent);
Assert.IsNotNull(mainVm.SelectedItem);
Assert.AreEqual(2, mainVm.MainMenuItems.Count());
@@ -51,7 +51,7 @@ namespace ModernKeePassApp.Test
{
var database = new DatabaseServiceMock();
var compositeKeyVm = new CompositeKeyVm(database, _resource);
- Assert.IsTrue(compositeKeyVm.OpenDatabase(false).GetAwaiter().GetResult());
+ Assert.IsTrue(compositeKeyVm.OpenDatabase(null, false).GetAwaiter().GetResult());
compositeKeyVm.StatusType = 1;
compositeKeyVm.Password = "test";
Assert.AreEqual(0, compositeKeyVm.StatusType);
@@ -61,13 +61,10 @@ namespace ModernKeePassApp.Test
[TestMethod]
public void TestOpenVm()
{
- var database = new DatabaseServiceMock
- {
- DatabaseFile = Package.Current.InstalledLocation.GetFileAsync(@"Data\TestDatabase.kdbx")
- .GetAwaiter().GetResult()
- };
- var openVm = new OpenVm(database);
- Assert.IsTrue(openVm.ShowPasswordBox);
+ var databaseFile = Package.Current.InstalledLocation.GetFileAsync(@"Data\TestDatabase.kdbx")
+ .GetAwaiter().GetResult();
+ var openVm = new OpenVm(databaseFile);
+ Assert.IsTrue(openVm.IsFileSelected);
Assert.AreEqual("MockDatabase", openVm.Name);
}
@@ -94,7 +91,7 @@ namespace ModernKeePassApp.Test
{
var database = new DatabaseServiceMock();
var saveVm = new SaveVm(database);
- database.Open(null);
+ database.Open(null, null);
saveVm.Save(false);
Assert.IsTrue(database.IsOpen);
saveVm.Save();
@@ -108,7 +105,7 @@ namespace ModernKeePassApp.Test
Assert.AreEqual(1, settingsVm.MenuItems.Count());
var firstGroup = settingsVm.MenuItems.FirstOrDefault();
// All groups have an empty title, so all settings are put inside the empty group
- Assert.AreEqual(4, firstGroup.Count());
+ Assert.AreEqual(4, firstGroup?.Count());
Assert.IsNotNull(settingsVm.SelectedItem);
var selectedItem = (ListMenuItemVm) settingsVm.SelectedItem;
Assert.AreEqual(typeof(SettingsNewDatabasePage), selectedItem.PageType);