Opening Databases now use a Messenger service

This commit is contained in:
Geoffroy BONNEVILLE
2020-04-21 17:13:39 +02:00
parent 004f1a35a8
commit 0b19d8d50a
21 changed files with 240 additions and 146 deletions

View File

@@ -10,8 +10,10 @@ using Windows.Storage.Pickers;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation; using Windows.UI.Xaml.Navigation;
using GalaSoft.MvvmLight.Messaging;
using GalaSoft.MvvmLight.Views; using GalaSoft.MvvmLight.Views;
using MediatR; using MediatR;
using Messages;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.HockeyApp; using Microsoft.HockeyApp;
using ModernKeePass.Application; using ModernKeePass.Application;
@@ -39,6 +41,8 @@ namespace ModernKeePass
private readonly IMediator _mediator; private readonly IMediator _mediator;
private readonly ISettingsProxy _settings; private readonly ISettingsProxy _settings;
private readonly INavigationService _navigation; private readonly INavigationService _navigation;
private readonly IMessenger _messenger;
private readonly IHockeyClient _hockey;
public static IServiceProvider Services { get; private set; } public static IServiceProvider Services { get; private set; }
@@ -48,16 +52,6 @@ namespace ModernKeePass
/// </summary> /// </summary>
public App() public App()
{ {
#if DEBUG
HockeyClient.Current.Configure("2fe83672-887b-4910-b9de-93a4398d0f8f");
#else
HockeyClient.Current.Configure("9eb5fbb79b484fbd8daf04635e975c84");
#endif
InitializeComponent();
Suspending += OnSuspending;
Resuming += OnResuming;
UnhandledException += OnUnhandledException;
// Setup DI // Setup DI
IServiceCollection serviceCollection = new ServiceCollection(); IServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddApplication(); serviceCollection.AddApplication();
@@ -71,8 +65,47 @@ namespace ModernKeePass
_resource = Services.GetService<IResourceProxy>(); _resource = Services.GetService<IResourceProxy>();
_settings = Services.GetService<ISettingsProxy>(); _settings = Services.GetService<ISettingsProxy>();
_navigation = Services.GetService<INavigationService>(); _navigation = Services.GetService<INavigationService>();
_messenger = Services.GetService<IMessenger>();
_hockey = Services.GetService<IHockeyClient>();
InitializeComponent();
Suspending += OnSuspending;
Resuming += OnResuming;
UnhandledException += OnUnhandledException;
ReceiveGlobalMessage();
} }
#region Messages
private void ReceiveGlobalMessage()
{
_messenger.Register<DatabaseAlreadyOpenedMessage>(this, async action => await ShowDatabaseOpenedDialog(action));
}
private async Task ShowDatabaseOpenedDialog(DatabaseAlreadyOpenedMessage message)
{
await MessageDialogHelper.ShowActionDialog(_resource.GetResourceValue("MessageDialogDBOpenTitle"),
string.Format(_resource.GetResourceValue("MessageDialogDBOpenDesc"), message.OpenedDatabase.Name),
_resource.GetResourceValue("MessageDialogDBOpenButtonSave"),
_resource.GetResourceValue("MessageDialogDBOpenButtonDiscard"),
async command =>
{
await _mediator.Send(new SaveDatabaseCommand());
ToastNotificationHelper.ShowGenericToast(
message.OpenedDatabase.Name,
_resource.GetResourceValue("ToastSavedMessage"));
await _mediator.Send(new CloseDatabaseCommand());
_messenger.Send(new DatabaseClosedMessage());
},
async command =>
{
await _mediator.Send(new CloseDatabaseCommand());
_messenger.Send(new DatabaseClosedMessage());
});
}
#endregion
#region Event Handlers #region Event Handlers
private async void OnUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs) private async void OnUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs)
@@ -89,7 +122,7 @@ namespace ModernKeePass
{ {
var innerException = realException.InnerException; var innerException = realException.InnerException;
unhandledExceptionEventArgs.Handled = true; unhandledExceptionEventArgs.Handled = true;
HockeyClient.Current.TrackException(innerException); _hockey.TrackException(innerException);
await MessageDialogHelper.ShowActionDialog(_resource.GetResourceValue("MessageDialogSaveErrorTitle"), await MessageDialogHelper.ShowActionDialog(_resource.GetResourceValue("MessageDialogSaveErrorTitle"),
innerException?.Message, innerException?.Message,
_resource.GetResourceValue("MessageDialogSaveErrorButtonSaveAs"), _resource.GetResourceValue("MessageDialogSaveErrorButtonSaveAs"),
@@ -123,7 +156,7 @@ namespace ModernKeePass
protected override async void OnLaunched(LaunchActivatedEventArgs args) protected override async void OnLaunched(LaunchActivatedEventArgs args)
{ {
await OnLaunchOrActivated(args); await OnLaunchOrActivated(args);
await HockeyClient.Current.SendCrashesAsync(/* sendWithoutAsking: true */); await _hockey.SendCrashesAsync(/* sendWithoutAsking: true */);
} }
protected override async void OnActivated(IActivatedEventArgs args) protected override async void OnActivated(IActivatedEventArgs args)

View File

@@ -1,7 +1,9 @@
using System.Reflection; using System.Reflection;
using AutoMapper; using AutoMapper;
using GalaSoft.MvvmLight.Messaging;
using GalaSoft.MvvmLight.Views; using GalaSoft.MvvmLight.Views;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.HockeyApp;
using ModernKeePass.Common; using ModernKeePass.Common;
using ModernKeePass.Views; using ModernKeePass.Views;
@@ -23,6 +25,17 @@ namespace ModernKeePass
nav.Configure(Constants.Navigation.GroupPage, typeof(GroupDetailPage)); nav.Configure(Constants.Navigation.GroupPage, typeof(GroupDetailPage));
return nav; return nav;
}); });
services.AddSingleton(provider => Messenger.Default);
services.AddSingleton(provider =>
{
#if DEBUG
HockeyClient.Current.Configure("2fe83672-887b-4910-b9de-93a4398d0f8f");
#else
HockeyClient.Current.Configure("9eb5fbb79b484fbd8daf04635e975c84");
#endif
return HockeyClient.Current;
});
return services; return services;
} }

View File

@@ -264,4 +264,7 @@
<data name="HistoryDeleteTitle" xml:space="preserve"> <data name="HistoryDeleteTitle" xml:space="preserve">
<value>Delete history entry ?</value> <value>Delete history entry ?</value>
</data> </data>
<data name="CompositeKeyOpenButtonLabel" xml:space="preserve">
<value>Open</value>
</data>
</root> </root>

View File

@@ -264,4 +264,7 @@
<data name="HistoryDeleteTitle" xml:space="preserve"> <data name="HistoryDeleteTitle" xml:space="preserve">
<value>Supprimer cet historique ?</value> <value>Supprimer cet historique ?</value>
</data> </data>
<data name="CompositeKeyOpenButtonLabel" xml:space="preserve">
<value>Open</value>
</data>
</root> </root>

View File

@@ -42,8 +42,7 @@ namespace ModernKeePass.ViewModels
public ICommand ClearAllCommand { get; } public ICommand ClearAllCommand { get; }
public RecentVm() : this (App.Services.GetRequiredService<IRecentProxy>()) public RecentVm() : this (App.Services.GetRequiredService<IRecentProxy>()) { }
{ }
public RecentVm(IRecentProxy recent) public RecentVm(IRecentProxy recent)
{ {
@@ -56,6 +55,11 @@ namespace ModernKeePass.ViewModels
SelectedItem = RecentItems[0]; SelectedItem = RecentItems[0];
} }
public void UpdateAccessTime(string token)
{
_recent.Get(token, true).Wait();
}
private void ClearAll() private void ClearAll()
{ {
_recent.ClearAll(); _recent.ClearAll();

View File

@@ -58,16 +58,10 @@ namespace ModernKeePass.Views
{ {
NavigationHelper.OnNavigatedTo(e); NavigationHelper.OnNavigatedTo(e);
var args = e.Parameter as PasswordEventArgs;
if (args != null)
DataContext = new GroupDetailVm(args.RootGroupId);
else
{
var navigationItem = e.Parameter as NavigationItem; var navigationItem = e.Parameter as NavigationItem;
if (navigationItem != null) if (navigationItem != null)
DataContext = new GroupDetailVm(navigationItem.Id) { IsEditMode = navigationItem.IsNew }; DataContext = new GroupDetailVm(navigationItem.Id) { IsEditMode = navigationItem.IsNew };
} }
}
protected override void OnNavigatedFrom(NavigationEventArgs e) protected override void OnNavigatedFrom(NavigationEventArgs e)
{ {

View File

@@ -5,19 +5,15 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="using:ModernKeePass.ViewModels" xmlns:viewModels="using:ModernKeePass.ViewModels"
xmlns:converters="using:ModernKeePass.Converters" xmlns:converters="using:ModernKeePass.Converters"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
xmlns:userControls="using:ModernKeePass.Views.UserControls" xmlns:userControls="using:ModernKeePass.Views.UserControls"
x:Class="ModernKeePass.Views.OpenDatabasePage" x:Class="ModernKeePass.Views.OpenDatabasePage"
mc:Ignorable="d"> mc:Ignorable="d">
<Page.Resources> <Page.Resources>
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/> <converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<viewModels:OpenVm x:Key="ViewModel"/>
</Page.Resources> </Page.Resources>
<Page.DataContext>
<viewModels:OpenVm/>
</Page.DataContext>
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" DataContext="{StaticResource ViewModel}">
<HyperlinkButton x:Uid="OpenBrowseButton" Click="ButtonBase_OnClick" Foreground="{StaticResource MainColor}" Style="{StaticResource MainColorHyperlinkButton}" /> <HyperlinkButton x:Uid="OpenBrowseButton" Click="ButtonBase_OnClick" Foreground="{StaticResource MainColor}" Style="{StaticResource MainColorHyperlinkButton}" />
<TextBlock Style="{StaticResource BodyTextBlockStyle}" Margin="15,0,0,30" x:Uid="OpenBrowseDesc" /> <TextBlock Style="{StaticResource BodyTextBlockStyle}" Margin="15,0,0,30" x:Uid="OpenBrowseDesc" />
<!--<HyperlinkButton x:Uid="OpenUrlButton" IsEnabled="False" Foreground="{StaticResource MainColor}" Style="{StaticResource MainColorHyperlinkButton}" /> <!--<HyperlinkButton x:Uid="OpenUrlButton" IsEnabled="False" Foreground="{StaticResource MainColor}" Style="{StaticResource MainColorHyperlinkButton}" />
@@ -25,13 +21,7 @@
<Border HorizontalAlignment="Left" BorderThickness="1" BorderBrush="AliceBlue" Width="550" Visibility="{Binding IsFileSelected, Converter={StaticResource BooleanToVisibilityConverter}}"> <Border HorizontalAlignment="Left" BorderThickness="1" BorderBrush="AliceBlue" Width="550" Visibility="{Binding IsFileSelected, Converter={StaticResource BooleanToVisibilityConverter}}">
<StackPanel Margin="25,0,25,0"> <StackPanel Margin="25,0,25,0">
<TextBlock Text="{Binding Name}" /> <TextBlock Text="{Binding Name}" />
<userControls:OpenDatabaseUserControl DatabaseFilePath="{Binding Token}"> <userControls:OpenDatabaseUserControl DatabaseFilePath="{Binding Token}" />
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="DatabaseOpened">
<core:NavigateToPageAction TargetPage="ModernKeePass.Views.GroupDetailPage" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</userControls:OpenDatabaseUserControl>
</StackPanel> </StackPanel>
</Border> </Border>
</StackPanel> </StackPanel>

View File

@@ -3,7 +3,13 @@ using Windows.Storage.AccessCache;
using Windows.Storage.Pickers; using Windows.Storage.Pickers;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Navigation; using Windows.UI.Xaml.Navigation;
using GalaSoft.MvvmLight.Messaging;
using GalaSoft.MvvmLight.Views;
using Messages;
using Microsoft.Extensions.DependencyInjection;
using ModernKeePass.Common;
using ModernKeePass.Domain.Dtos; using ModernKeePass.Domain.Dtos;
using ModernKeePass.Models;
using ModernKeePass.ViewModels; using ModernKeePass.ViewModels;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
@@ -15,11 +21,24 @@ namespace ModernKeePass.Views
/// </summary> /// </summary>
public sealed partial class OpenDatabasePage public sealed partial class OpenDatabasePage
{ {
public OpenVm Model => (OpenVm)DataContext; private readonly INavigationService _navigation;
private OpenVm Model => (OpenVm)Resources["ViewModel"];
public OpenDatabasePage() public OpenDatabasePage(): this(
App.Services.GetRequiredService<INavigationService>(),
App.Services.GetRequiredService<IMessenger>()) { }
public OpenDatabasePage(INavigationService navigation, IMessenger messenger)
{ {
_navigation = navigation;
InitializeComponent(); InitializeComponent();
messenger.Register<DatabaseOpenedMessage>(this, NavigateToPage);
}
private void NavigateToPage(DatabaseOpenedMessage message)
{
_navigation.NavigateTo(Constants.Navigation.GroupPage, new NavigationItem { Id = message.RootGroupId });
} }
protected override async void OnNavigatedTo(NavigationEventArgs e) protected override async void OnNavigatedTo(NavigationEventArgs e)

View File

@@ -5,17 +5,14 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="using:ModernKeePass.ViewModels" xmlns:viewModels="using:ModernKeePass.ViewModels"
xmlns:converters="using:ModernKeePass.Converters" xmlns:converters="using:ModernKeePass.Converters"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
xmlns:userControls="using:ModernKeePass.Views.UserControls" xmlns:userControls="using:ModernKeePass.Views.UserControls"
x:Class="ModernKeePass.Views.RecentDatabasesPage" x:Class="ModernKeePass.Views.RecentDatabasesPage"
mc:Ignorable="d"> mc:Ignorable="d">
<Page.Resources> <Page.Resources>
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/> <converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<viewModels:RecentVm x:Key="ViewModel"/> <viewModels:RecentVm x:Key="ViewModel"/>
<!--<CollectionViewSource x:Name="RecentItemsSource" Source="{Binding RecentItems}" />-->
</Page.Resources> </Page.Resources>
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}" DataContext="{StaticResource ViewModel}"> <Grid x:Name="Grid" Background="{StaticResource ApplicationPageBackgroundThemeBrush}" DataContext="{StaticResource ViewModel}">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="40" /> <RowDefinition Height="40" />
<RowDefinition Height="*" /> <RowDefinition Height="*" />
@@ -43,16 +40,10 @@
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Text="{Binding Name}" Padding="5,0,0,0" /> <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" /> <TextBlock Grid.Row="1" Text="{Binding Path}" Padding="5,0,0,0" FontSize="10" />
<userControls:OpenDatabaseUserControl Grid.Row="2" HorizontalAlignment="Stretch" MinWidth="400" Margin="0,10,0,0" Visibility="{Binding IsSelected, Converter={StaticResource BooleanToVisibilityConverter}}" DatabaseFilePath="{Binding Token}"> <userControls:OpenDatabaseUserControl Grid.Row="2"
<interactivity:Interaction.Behaviors> HorizontalAlignment="Stretch" MinWidth="400" Margin="0,10,0,0"
<core:EventTriggerBehavior EventName="DatabaseOpening"> Visibility="{Binding IsSelected, Converter={StaticResource BooleanToVisibilityConverter}}"
<core:CallMethodAction TargetObject="{Binding}" MethodName="UpdateAccessTime" /> DatabaseFilePath="{Binding Token}" />
</core:EventTriggerBehavior>
<core:EventTriggerBehavior EventName="DatabaseOpened">
<core:NavigateToPageAction TargetPage="ModernKeePass.Views.GroupDetailPage" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</userControls:OpenDatabaseUserControl>
</Grid> </Grid>
</DataTemplate> </DataTemplate>
</ListView.ItemTemplate> </ListView.ItemTemplate>

View File

@@ -1,5 +1,13 @@
// Pour en savoir plus sur le modèle d'élément Page vierge, consultez la page http://go.microsoft.com/fwlink/?LinkId=234238 // Pour en savoir plus sur le modèle d'élément Page vierge, consultez la page http://go.microsoft.com/fwlink/?LinkId=234238
using GalaSoft.MvvmLight.Messaging;
using GalaSoft.MvvmLight.Views;
using Messages;
using Microsoft.Extensions.DependencyInjection;
using ModernKeePass.Common;
using ModernKeePass.Models;
using ModernKeePass.ViewModels;
namespace ModernKeePass.Views namespace ModernKeePass.Views
{ {
/// <summary> /// <summary>
@@ -7,9 +15,29 @@ namespace ModernKeePass.Views
/// </summary> /// </summary>
public sealed partial class RecentDatabasesPage public sealed partial class RecentDatabasesPage
{ {
public RecentDatabasesPage() private RecentVm Model => (RecentVm)Resources["ViewModel"];
private readonly INavigationService _navigation;
private readonly IMessenger _messenger;
public RecentDatabasesPage(): this(
App.Services.GetRequiredService<INavigationService>(),
App.Services.GetRequiredService<IMessenger>())
{ }
public RecentDatabasesPage(INavigationService navigation, IMessenger messenger)
{ {
_navigation = navigation;
_messenger = messenger;
InitializeComponent(); InitializeComponent();
messenger.Register<DatabaseOpeningMessage>(this, action => Model.UpdateAccessTime(action.Token));
messenger.Register<DatabaseOpenedMessage>(this, NavigateToPage);
}
private void NavigateToPage(DatabaseOpenedMessage message)
{
_navigation.NavigateTo(Constants.Navigation.GroupPage, new NavigationItem { Id = message.RootGroupId });
} }
} }
} }

View File

@@ -1,4 +1,4 @@
<UserControl <UserControl x:Name="UserControl"
x:Class="ModernKeePass.Views.UserControls.OpenDatabaseUserControl" x:Class="ModernKeePass.Views.UserControls.OpenDatabaseUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
@@ -43,10 +43,9 @@
Click="KeyFileButton_Click" Click="KeyFileButton_Click"
Style="{StaticResource MainColorHyperlinkButton}" /> Style="{StaticResource MainColorHyperlinkButton}" />
<Button Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2" <Button Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2"
x:Name="OpenButton" Content="{Binding OpenButtonLabel}"
x:Uid="OpenDatabaseControlButton" Command="{Binding OpenDatabaseCommand}"
Click="OpenButton_OnClick" CommandParameter="{Binding DatabaseFilePath, ElementName=UserControl}"
IsEnabled="{Binding IsValid}"
Style="{StaticResource MainColorButton}" /> Style="{StaticResource MainColorButton}" />
<TextBlock Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="3" Height="Auto" FontSize="14" FontWeight="Light" <TextBlock Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="3" Height="Auto" FontSize="14" FontWeight="Light"
Text="{Binding Status}" Text="{Binding Status}"

View File

@@ -1,19 +1,12 @@
using System; using System;
using System.Threading.Tasks;
using Windows.Storage.AccessCache; using Windows.Storage.AccessCache;
using Windows.Storage.Pickers; using Windows.Storage.Pickers;
using Windows.System; using Windows.System;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Input;
using MediatR; using GalaSoft.MvvmLight.Messaging;
using Messages;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
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.Common;
using ModernKeePass.Events;
using ModernKeePass.Extensions;
using ModernKeePass.ViewModels; 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 // Pour en savoir plus sur le modèle d'élément Contrôle utilisateur, consultez la page http://go.microsoft.com/fwlink/?LinkId=234236
@@ -22,8 +15,6 @@ namespace ModernKeePass.Views.UserControls
{ {
public sealed partial class OpenDatabaseUserControl public sealed partial class OpenDatabaseUserControl
{ {
private readonly IMediator _mediator;
private readonly IResourceProxy _resource;
public OpenDatabaseControlVm Model => Grid.DataContext as OpenDatabaseControlVm; public OpenDatabaseControlVm Model => Grid.DataContext as OpenDatabaseControlVm;
public string DatabaseFilePath public string DatabaseFilePath
@@ -38,54 +29,19 @@ namespace ModernKeePass.Views.UserControls
typeof(OpenDatabaseUserControl), typeof(OpenDatabaseUserControl),
new PropertyMetadata(null, (o, args) => { })); new PropertyMetadata(null, (o, args) => { }));
public OpenDatabaseUserControl() : this(App.Services.GetRequiredService<IMediator>(), App.Services.GetRequiredService<IResourceProxy>()) { } public OpenDatabaseUserControl() : this(App.Services.GetRequiredService<IMessenger>()) { }
public OpenDatabaseUserControl(IMediator mediator, IResourceProxy resource) public OpenDatabaseUserControl(IMessenger messenger)
{ {
_mediator = mediator;
_resource = resource;
InitializeComponent(); InitializeComponent();
messenger.Register<DatabaseClosedMessage>(this, async action => await Model.OpenDatabase(DatabaseFilePath));
} }
public event EventHandler DatabaseOpening; private async void PasswordBox_KeyDown(object sender, KeyRoutedEventArgs e)
public event EventHandler<PasswordEventArgs> DatabaseOpened;
private async void OpenButton_OnClick(object sender, RoutedEventArgs e)
{
DatabaseOpening?.Invoke(this, new EventArgs());
var database = await _mediator.Send(new GetDatabaseQuery());
if (database.IsOpen)
{
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"));
await _mediator.Send(new CloseDatabaseCommand());
await OpenDatabase();
},
async command =>
{
await _mediator.Send(new CloseDatabaseCommand());
await OpenDatabase();
});
}
else
{
await OpenDatabase();
}
}
private void PasswordBox_KeyDown(object sender, KeyRoutedEventArgs e)
{ {
if (e.Key != VirtualKey.Enter || !Model.IsValid) return; if (e.Key != VirtualKey.Enter || !Model.IsValid) return;
OpenButton_OnClick(sender, e); await Model.TryOpenDatabase(DatabaseFilePath);
// Stop the event from triggering twice // Stop the event from triggering twice
e.Handled = true; e.Handled = true;
} }
@@ -106,17 +62,5 @@ namespace ModernKeePass.Views.UserControls
var token = StorageApplicationPermissions.FutureAccessList.Add(file); var token = StorageApplicationPermissions.FutureAccessList.Add(file);
Model.KeyFilePath = token; Model.KeyFilePath = token;
} }
private async Task OpenDatabase()
{
var oldLabel = OpenButton.Content;
OpenButton.Content = _resource.GetResourceValue("CompositeKeyOpening");
if (await Dispatcher.RunTaskAsync(async () => await Model.OpenDatabase(DatabaseFilePath)))
{
DatabaseOpened?.Invoke(this, new PasswordEventArgs(Model.RootGroupId));
}
OpenButton.Content = oldLabel;
}
} }
} }

View File

@@ -0,0 +1,9 @@
using ModernKeePass.Application.Database.Models;
namespace Messages
{
public class DatabaseAlreadyOpenedMessage
{
public DatabaseVm OpenedDatabase { get; set; }
}
}

View File

@@ -0,0 +1,7 @@
namespace Messages
{
public class DatabaseClosedMessage
{
}
}

View File

@@ -0,0 +1,7 @@
namespace Messages
{
public class DatabaseOpenedMessage
{
public string RootGroupId { get; set; }
}
}

View File

@@ -0,0 +1,7 @@
namespace Messages
{
public class DatabaseOpeningMessage
{
public string Token { get; set; }
}
}

View File

@@ -0,0 +1,8 @@
namespace Messages
{
public class NavigateToPageMessage
{
public string Destination { get; set; }
public object Parameter { get; set; }
}
}

View File

@@ -0,0 +1,7 @@
namespace Messages
{
public class SaveErrorMessage
{
}
}

View File

@@ -1,6 +1,4 @@
using Microsoft.Extensions.DependencyInjection; using ModernKeePass.Domain.AOP;
using ModernKeePass.Application.Common.Interfaces;
using ModernKeePass.Domain.AOP;
using ModernKeePass.Domain.Dtos; using ModernKeePass.Domain.Dtos;
using ModernKeePass.Domain.Interfaces; using ModernKeePass.Domain.Interfaces;
@@ -8,7 +6,6 @@ namespace ModernKeePass.ViewModels.ListItems
{ {
public class RecentItemVm: NotifyPropertyChangedBase, ISelectableModel public class RecentItemVm: NotifyPropertyChangedBase, ISelectableModel
{ {
private readonly IRecentProxy _recent;
private bool _isSelected; private bool _isSelected;
private string _name; private string _name;
private string _token; private string _token;
@@ -38,19 +35,11 @@ namespace ModernKeePass.ViewModels.ListItems
set { SetProperty(ref _isSelected, value); } set { SetProperty(ref _isSelected, value); }
} }
public RecentItemVm(FileInfo file): this(App.Services.GetRequiredService<IRecentProxy>(), file) {} public RecentItemVm(FileInfo file)
public RecentItemVm(IRecentProxy recent, FileInfo file)
{ {
_recent = recent;
Token = file.Id; Token = file.Id;
Name = file.Name; Name = file.Name;
Path = file.Path; Path = file.Path;
} }
// Called from XAML
public void UpdateAccessTime()
{
_recent.Get(Token, true).Wait();
}
} }
} }

View File

@@ -1,12 +1,14 @@
using System; using System;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using MediatR; using MediatR;
using Messages;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using ModernKeePass.Application.Common.Interfaces; using ModernKeePass.Application.Common.Interfaces;
using ModernKeePass.Application.Database.Queries.GetDatabase; using ModernKeePass.Application.Database.Queries.GetDatabase;
using ModernKeePass.Application.Database.Queries.OpenDatabase; using ModernKeePass.Application.Database.Queries.OpenDatabase;
using ModernKeePass.Common;
using ModernKeePass.Domain.AOP; using ModernKeePass.Domain.AOP;
namespace ModernKeePass.ViewModels namespace ModernKeePass.ViewModels
@@ -28,6 +30,7 @@ namespace ModernKeePass.ViewModels
{ {
SetProperty(ref _hasPassword, value); SetProperty(ref _hasPassword, value);
OnPropertyChanged(nameof(IsValid)); OnPropertyChanged(nameof(IsValid));
OpenDatabaseCommand.RaiseCanExecuteChanged();
} }
} }
@@ -38,6 +41,7 @@ namespace ModernKeePass.ViewModels
{ {
SetProperty(ref _hasKeyFile, value); SetProperty(ref _hasKeyFile, value);
OnPropertyChanged(nameof(IsValid)); OnPropertyChanged(nameof(IsValid));
OpenDatabaseCommand.RaiseCanExecuteChanged();
} }
} }
@@ -73,6 +77,7 @@ namespace ModernKeePass.ViewModels
{ {
_keyFilePath = value; _keyFilePath = value;
OnPropertyChanged(nameof(IsValid)); OnPropertyChanged(nameof(IsValid));
OpenDatabaseCommand.RaiseCanExecuteChanged();
} }
} }
@@ -82,10 +87,17 @@ namespace ModernKeePass.ViewModels
set { SetProperty(ref _keyFileText, value); } set { SetProperty(ref _keyFileText, value); }
} }
public string RootGroupId { get; set; } public string OpenButtonLabel
{
get { return _openButtonLabel; }
set { SetProperty(ref _openButtonLabel, value); }
}
public RelayCommand<string> OpenDatabaseCommand { get; }
protected readonly IMediator Mediator; protected readonly IMediator Mediator;
private readonly IResourceProxy _resource; private readonly IResourceProxy _resource;
private readonly IMessenger _messenger;
private bool _hasPassword; private bool _hasPassword;
private bool _hasKeyFile; private bool _hasKeyFile;
private bool _isOpening; private bool _isOpening;
@@ -94,35 +106,55 @@ namespace ModernKeePass.ViewModels
private StatusTypes _statusType; private StatusTypes _statusType;
private string _keyFilePath; private string _keyFilePath;
private string _keyFileText; private string _keyFileText;
private string _openButtonLabel;
public OpenDatabaseControlVm() : this( public OpenDatabaseControlVm() : this(
App.Services.GetRequiredService<IMediator>(), App.Services.GetRequiredService<IMediator>(),
App.Services.GetRequiredService<IResourceProxy>()) App.Services.GetRequiredService<IResourceProxy>(),
App.Services.GetRequiredService<IMessenger>())
{ } { }
public OpenDatabaseControlVm(IMediator mediator, IResourceProxy resource) public OpenDatabaseControlVm(IMediator mediator, IResourceProxy resource, IMessenger messenger)
{ {
Mediator = mediator; Mediator = mediator;
_resource = resource; _resource = resource;
_messenger = messenger;
OpenDatabaseCommand = new RelayCommand<string>(async databaseFilePath => await TryOpenDatabase(databaseFilePath), _ => IsValid);
_keyFileText = _resource.GetResourceValue("CompositeKeyDefaultKeyFile"); _keyFileText = _resource.GetResourceValue("CompositeKeyDefaultKeyFile");
_openButtonLabel = _resource.GetResourceValue("CompositeKeyOpenButtonLabel");
} }
public async Task<bool> OpenDatabase(string databaseFilePath) public async Task TryOpenDatabase(string databaseFilePath)
{ {
_messenger.Send(new DatabaseOpeningMessage {Token = databaseFilePath});
var database = await Mediator.Send(new GetDatabaseQuery());
if (database.IsOpen)
{
_messenger.Send(new DatabaseAlreadyOpenedMessage { OpenedDatabase = database });
}
else await OpenDatabase(databaseFilePath);
}
public async Task OpenDatabase(string databaseFilePath)
{
var oldLabel = _openButtonLabel;
OpenButtonLabel = _resource.GetResourceValue("CompositeKeyOpening");
_isOpening = true;
try try
{ {
_isOpening = true;
OnPropertyChanged(nameof(IsValid)); OnPropertyChanged(nameof(IsValid));
OpenDatabaseCommand.RaiseCanExecuteChanged();
await Mediator.Send(new OpenDatabaseQuery await Mediator.Send(new OpenDatabaseQuery
{ {
FilePath = databaseFilePath, FilePath = databaseFilePath,
KeyFilePath = HasKeyFile ? KeyFilePath : null, KeyFilePath = HasKeyFile ? KeyFilePath : null,
Password = HasPassword ? Password : null, Password = HasPassword ? Password : null,
}); });
RootGroupId = (await Mediator.Send(new GetDatabaseQuery())).RootGroupId; var rootGroupId = (await Mediator.Send(new GetDatabaseQuery())).RootGroupId;
return true;
_messenger.Send(new DatabaseOpenedMessage { RootGroupId = rootGroupId });
} }
catch (ArgumentException) catch (ArgumentException)
{ {
@@ -140,8 +172,9 @@ namespace ModernKeePass.ViewModels
{ {
_isOpening = false; _isOpening = false;
OnPropertyChanged(nameof(IsValid)); OnPropertyChanged(nameof(IsValid));
OpenDatabaseCommand.RaiseCanExecuteChanged();
OpenButtonLabel = oldLabel;
} }
return false;
} }
private void UpdateStatus(string text, StatusTypes type) private void UpdateStatus(string text, StatusTypes type)

View File

@@ -36,6 +36,12 @@
<Compile Include="$(MSBuildThisFileDirectory)Events\PasswordEventArgs.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Events\PasswordEventArgs.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\ColorExtensions.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Extensions\ColorExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\DispatcherTaskExtensions.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Extensions\DispatcherTaskExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Messages\DatabaseAlreadyOpenedMessage.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Messages\DatabaseClosedMessage.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Messages\DatabaseOpenedMessage.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Messages\DatabaseOpeningMessage.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Messages\NavigateToPageMessage.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Messages\SaveErrorMessage.cs" />
<Compile Include="$(MSBuildThisFileDirectory)TemplateSelectors\FirstItemDataTemplateSelector.cs" /> <Compile Include="$(MSBuildThisFileDirectory)TemplateSelectors\FirstItemDataTemplateSelector.cs" />
<Compile Include="$(MSBuildThisFileDirectory)TemplateSelectors\SelectableDataTemplateSelector.cs" /> <Compile Include="$(MSBuildThisFileDirectory)TemplateSelectors\SelectableDataTemplateSelector.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\Items\ListMenuItemVm.cs" /> <Compile Include="$(MSBuildThisFileDirectory)ViewModels\Items\ListMenuItemVm.cs" />