mirror of
https://github.com/KeyKeeperApp/KeyKeeper.git
synced 2026-05-04 05:46:29 +03:00
merge branch 'feature/confirmation-at-closing'
This commit is contained in:
@@ -8,6 +8,7 @@ namespace KeyKeeper.ViewModels;
|
||||
public class UnlockedRepositoryViewModel : ViewModelBase
|
||||
{
|
||||
private IPassStore passStore;
|
||||
private bool hasUnsavedChanges;
|
||||
|
||||
public IEnumerable<PassStoreEntryPassword> Passwords
|
||||
{
|
||||
@@ -19,9 +20,20 @@ public class UnlockedRepositoryViewModel : ViewModelBase
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasUnsavedChanges
|
||||
{
|
||||
get => hasUnsavedChanges;
|
||||
private set
|
||||
{
|
||||
hasUnsavedChanges = value;
|
||||
OnPropertyChanged(nameof(HasUnsavedChanges));
|
||||
}
|
||||
}
|
||||
|
||||
public UnlockedRepositoryViewModel(IPassStore store)
|
||||
{
|
||||
passStore = store;
|
||||
HasUnsavedChanges = false;
|
||||
}
|
||||
|
||||
public void AddEntry(PassStoreEntry entry)
|
||||
@@ -29,6 +41,7 @@ public class UnlockedRepositoryViewModel : ViewModelBase
|
||||
if (entry is PassStoreEntryPassword)
|
||||
{
|
||||
(passStore.GetRootDirectory() as PassStoreEntryGroup)!.ChildEntries.Add(entry);
|
||||
HasUnsavedChanges = true;
|
||||
OnPropertyChanged(nameof(Passwords));
|
||||
}
|
||||
}
|
||||
@@ -36,6 +49,7 @@ public class UnlockedRepositoryViewModel : ViewModelBase
|
||||
public void DeleteEntry(Guid id)
|
||||
{
|
||||
(passStore.GetRootDirectory() as PassStoreEntryGroup)!.DeleteEntry(id);
|
||||
HasUnsavedChanges = true;
|
||||
OnPropertyChanged(nameof(Passwords));
|
||||
}
|
||||
|
||||
@@ -52,5 +66,6 @@ public class UnlockedRepositoryViewModel : ViewModelBase
|
||||
public void Save()
|
||||
{
|
||||
passStore.Save();
|
||||
HasUnsavedChanges = false;
|
||||
}
|
||||
}
|
||||
29
src/KeyKeeper/Views/CloseConfirmationDialog.axaml
Normal file
29
src/KeyKeeper/Views/CloseConfirmationDialog.axaml
Normal file
@@ -0,0 +1,29 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
x:Class="KeyKeeper.Views.CloseConfirmationDialog"
|
||||
Width="420"
|
||||
Height="170"
|
||||
CanResize="False"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Title="Confirm close"
|
||||
Background="White">
|
||||
<Grid Margin="16" RowDefinitions="*,Auto">
|
||||
<TextBlock Text="Save changes before closing the storage?"
|
||||
TextWrapping="Wrap"
|
||||
Foreground="Black"
|
||||
FontSize="16"/>
|
||||
|
||||
<StackPanel Grid.Row="1"
|
||||
Orientation="Horizontal"
|
||||
HorizontalAlignment="Right"
|
||||
Spacing="8"
|
||||
Margin="0,16,0,0">
|
||||
<Button Content="Save"
|
||||
Click="Save_Click" />
|
||||
<Button Content="Do not save"
|
||||
Click="Discard_Click" />
|
||||
<Button Content="Cancel"
|
||||
Click="Cancel_Click" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
52
src/KeyKeeper/Views/CloseConfirmationDialog.axaml.cs
Normal file
52
src/KeyKeeper/Views/CloseConfirmationDialog.axaml.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace KeyKeeper.Views;
|
||||
|
||||
public enum CloseConfirmationResult
|
||||
{
|
||||
Save,
|
||||
Discard,
|
||||
Cancel,
|
||||
}
|
||||
|
||||
public partial class CloseConfirmationDialog : Window
|
||||
{
|
||||
private bool closingWithResult;
|
||||
|
||||
public CloseConfirmationDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnClosing(WindowClosingEventArgs e)
|
||||
{
|
||||
if (!closingWithResult)
|
||||
{
|
||||
e.Cancel = true;
|
||||
closingWithResult = true;
|
||||
Close(CloseConfirmationResult.Cancel);
|
||||
return;
|
||||
}
|
||||
|
||||
base.OnClosing(e);
|
||||
}
|
||||
|
||||
private void Save_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
closingWithResult = true;
|
||||
Close(CloseConfirmationResult.Save);
|
||||
}
|
||||
|
||||
private void Discard_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
closingWithResult = true;
|
||||
Close(CloseConfirmationResult.Discard);
|
||||
}
|
||||
|
||||
private void Cancel_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
closingWithResult = true;
|
||||
Close(CloseConfirmationResult.Cancel);
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
xmlns:i="using:Avalonia.Interactivity"
|
||||
xmlns:kkp="using:KeyKeeper.Views"
|
||||
x:Class="KeyKeeper.Views.RepositoryWindow"
|
||||
Closing="RepositoryWindow_Closing"
|
||||
Title="KeyKeeper - Password store"
|
||||
CanResize="False"
|
||||
Width="800"
|
||||
|
||||
@@ -12,6 +12,9 @@ namespace KeyKeeper.Views;
|
||||
|
||||
public partial class RepositoryWindow : Window
|
||||
{
|
||||
private bool allowClose;
|
||||
private bool closeConfirmationShown;
|
||||
|
||||
public RepositoryWindow(RepositoryWindowViewModel model)
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -27,6 +30,45 @@ public partial class RepositoryWindow : Window
|
||||
base.OnOpened(e);
|
||||
}
|
||||
|
||||
private async void RepositoryWindow_Closing(object? sender, WindowClosingEventArgs e)
|
||||
{
|
||||
if (allowClose || closeConfirmationShown)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (DataContext is RepositoryWindowViewModel checkVm &&
|
||||
checkVm.CurrentPage is UnlockedRepositoryViewModel unlockedVm &&
|
||||
!unlockedVm.HasUnsavedChanges)
|
||||
{
|
||||
allowClose = true;
|
||||
return;
|
||||
}
|
||||
|
||||
e.Cancel = true;
|
||||
closeConfirmationShown = true;
|
||||
|
||||
var dialog = new CloseConfirmationDialog();
|
||||
var result = await dialog.ShowDialog<CloseConfirmationResult?>(this);
|
||||
|
||||
closeConfirmationShown = false;
|
||||
|
||||
if (result == null || result == CloseConfirmationResult.Cancel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (result == CloseConfirmationResult.Save &&
|
||||
DataContext is RepositoryWindowViewModel vm &&
|
||||
vm.CurrentPage is UnlockedRepositoryViewModel pageVm)
|
||||
{
|
||||
pageVm.Save();
|
||||
}
|
||||
|
||||
allowClose = true;
|
||||
Close();
|
||||
}
|
||||
|
||||
private async void AddEntryButton_Click(object sender, RoutedEventArgs args)
|
||||
{
|
||||
if (DataContext is RepositoryWindowViewModel vm_ && vm_.CurrentPage is UnlockedRepositoryViewModel vm)
|
||||
|
||||
Reference in New Issue
Block a user