mirror of
https://github.com/wismna/ModernKeePass.git
synced 2025-10-03 15:40:18 -04:00
WIP Windows 10
Dependencies finally installed Removal of useless code Big cleanup in XAML styles (override colors the correct way)
This commit is contained in:
116
Win10App/ViewModels/EntriesVm.cs
Normal file
116
Win10App/ViewModels/EntriesVm.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.Threading.Tasks;
|
||||
using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Views;
|
||||
using MediatR;
|
||||
using ModernKeePass.Application.Common.Interfaces;
|
||||
using ModernKeePass.Application.Entry.Models;
|
||||
using ModernKeePass.Application.Group.Commands.AddEntry;
|
||||
using ModernKeePass.Application.Group.Commands.CreateEntry;
|
||||
using ModernKeePass.Application.Group.Commands.DeleteEntry;
|
||||
using ModernKeePass.Application.Group.Commands.MoveEntry;
|
||||
using ModernKeePass.Application.Group.Models;
|
||||
using ModernKeePass.Application.Group.Queries.GetGroup;
|
||||
using ModernKeePass.ViewModels.ListItems;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class EntriesVm : ViewModelBase
|
||||
{
|
||||
private readonly IMediator _mediator;
|
||||
private readonly INavigationService _navigation;
|
||||
private readonly INotificationService _notification;
|
||||
private readonly IDialogService _dialog;
|
||||
private readonly IResourceProxy _resource;
|
||||
|
||||
private GroupVm _parentGroup;
|
||||
private EntryItemVm _reorderedEntry;
|
||||
private EntryItemVm _selectedEntry;
|
||||
|
||||
public ObservableCollection<EntryItemVm> Entries { get; set; }
|
||||
|
||||
public EntryItemVm SelectedEntry
|
||||
{
|
||||
get => _selectedEntry;
|
||||
set => Set(() => SelectedEntry, ref _selectedEntry, value);
|
||||
}
|
||||
|
||||
public EntriesVm(IMediator mediator, INavigationService navigation, INotificationService notification, IDialogService dialog, IResourceProxy resource)
|
||||
{
|
||||
_mediator = mediator;
|
||||
_navigation = navigation;
|
||||
_notification = notification;
|
||||
_dialog = dialog;
|
||||
_resource = resource;
|
||||
}
|
||||
|
||||
public async Task Initialize(string groupId)
|
||||
{
|
||||
_parentGroup = await _mediator.Send(new GetGroupQuery {Id = groupId});
|
||||
Entries = new ObservableCollection<EntryItemVm>(_parentGroup.Entries);
|
||||
Entries.CollectionChanged += EntriesOnCollectionChanged;
|
||||
}
|
||||
|
||||
private async void EntriesOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
switch (e.Action)
|
||||
{
|
||||
case NotifyCollectionChangedAction.Remove:
|
||||
var oldIndex = e.OldStartingIndex;
|
||||
_reorderedEntry = Entries[oldIndex];
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Add:
|
||||
if (_reorderedEntry == null)
|
||||
{
|
||||
var entry = (EntryVm)e.NewItems[0];
|
||||
await _mediator.Send(new AddEntryCommand { EntryId = entry.Id, ParentGroupId = _parentGroup.Id });
|
||||
}
|
||||
else
|
||||
{
|
||||
await _mediator.Send(new MoveEntryCommand { Entry = _reorderedEntry, ParentGroup = _parentGroup, Index = e.NewStartingIndex });
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task AskForDelete(EntryItemVm entry)
|
||||
{
|
||||
if (IsRecycleOnDelete)
|
||||
{
|
||||
await Delete(entry);
|
||||
_notification.Show(_resource.GetResourceValue("EntryRecyclingConfirmation"), _resource.GetResourceValue("EntryRecycled"));
|
||||
}
|
||||
else
|
||||
{
|
||||
await _dialog.ShowMessage(_resource.GetResourceValue("EntryDeletingConfirmation"),
|
||||
_resource.GetResourceValue("EntityDeleteTitle"),
|
||||
_resource.GetResourceValue("EntityDeleteActionButton"),
|
||||
_resource.GetResourceValue("EntityDeleteCancelButton"),
|
||||
async isOk =>
|
||||
{
|
||||
if (isOk) await Delete(entry);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Delete(EntryItemVm entry)
|
||||
{
|
||||
await _mediator.Send(new DeleteEntryCommand
|
||||
{
|
||||
EntryId = entry.Id,
|
||||
ParentGroupId = _parentGroup.Id,
|
||||
RecycleBinName = _resource.GetResourceValue("RecycleBinTitle")
|
||||
});
|
||||
Entries.Remove(entry);
|
||||
}
|
||||
|
||||
public async Task AddNewEntry(string text)
|
||||
{
|
||||
var entry = await _mediator.Send(new CreateEntryCommand { ParentGroup = _parentGroup });
|
||||
entry.Title = text;
|
||||
Entries.Add(entry);
|
||||
SelectedEntry = entry;
|
||||
}
|
||||
}
|
||||
}
|
57
Win10App/ViewModels/GroupsVm.cs
Normal file
57
Win10App/ViewModels/GroupsVm.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using Autofac;
|
||||
using ModernKeePass.Domain.AOP;
|
||||
using ModernKeePass.Domain.Entities;
|
||||
using ModernKeePass.Domain.Enums;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
using ModernKeePass.ViewModels.ListItems;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class GroupsVm : NotifyPropertyChangedBase
|
||||
{
|
||||
private string _title;
|
||||
private string _newGroupName;
|
||||
|
||||
public string Title
|
||||
{
|
||||
get => _title;
|
||||
set
|
||||
{
|
||||
_title = value;
|
||||
OnPropertyChanged(nameof(Title));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: check why binding not working
|
||||
public string NewGroupName
|
||||
{
|
||||
get => _newGroupName;
|
||||
set
|
||||
{
|
||||
_newGroupName = value;
|
||||
OnPropertyChanged(nameof(NewGroupName));
|
||||
}
|
||||
}
|
||||
|
||||
public GroupItemVm RootItemVm { get; set; }
|
||||
|
||||
public GroupsVm(): this(App.Container.Resolve<IDatabaseService>().RootGroupEntity)
|
||||
{ }
|
||||
|
||||
public GroupsVm(GroupEntity groupEntity)
|
||||
{
|
||||
Title = groupEntity.Name;
|
||||
RootItemVm = new GroupItemVm(groupEntity, null);
|
||||
}
|
||||
|
||||
public void AddNewGroup(string groupName = "")
|
||||
{
|
||||
var group = new GroupEntity
|
||||
{
|
||||
Name = groupName,
|
||||
Icon = Icon.Folder,
|
||||
};
|
||||
RootItemVm.Children.Add(new GroupItemVm(group, RootItemVm));
|
||||
}
|
||||
}
|
||||
}
|
145
Win10App/ViewModels/ListItems/EntryItemVm.cs
Normal file
145
Win10App/ViewModels/ListItems/EntryItemVm.cs
Normal file
@@ -0,0 +1,145 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Windows.UI;
|
||||
using ModernKeePass.Domain.Entities;
|
||||
using ModernKeePass.Domain.Enums;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels.ListItems
|
||||
{
|
||||
public class EntryItemVm : NotifyPropertyChangedBase
|
||||
{
|
||||
private readonly ISecurityService _securityService;
|
||||
|
||||
public EntryEntity EntryEntity { get; }
|
||||
public GroupItemVm Parent { get; }
|
||||
|
||||
public bool HasExpired => HasExpirationDate && EntryEntity.ExpirationDate < DateTime.Now;
|
||||
|
||||
public bool HasUrl => !string.IsNullOrEmpty(Url);
|
||||
|
||||
public double PasswordComplexityIndicator => _securityService.EstimatePasswordComplexity(Password);
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => EntryEntity.Name;
|
||||
set
|
||||
{
|
||||
EntryEntity.Name = value;
|
||||
OnPropertyChanged(nameof(Name));
|
||||
}
|
||||
}
|
||||
|
||||
public string UserName
|
||||
{
|
||||
get => EntryEntity.UserName;
|
||||
set => EntryEntity.UserName = value;
|
||||
}
|
||||
|
||||
public string Password
|
||||
{
|
||||
get => EntryEntity.Password;
|
||||
set
|
||||
{
|
||||
EntryEntity.Password = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string Url
|
||||
{
|
||||
get => EntryEntity.Url?.ToString();
|
||||
set => EntryEntity.Url = new Uri(value);
|
||||
}
|
||||
|
||||
public string Notes
|
||||
{
|
||||
get => EntryEntity.Notes;
|
||||
set => EntryEntity.Notes = value;
|
||||
}
|
||||
|
||||
public Icon Icon
|
||||
{
|
||||
get => HasExpired ? Icon.Important : EntryEntity.Icon;
|
||||
set => EntryEntity.Icon = value;
|
||||
}
|
||||
|
||||
public DateTimeOffset ExpiryDate
|
||||
{
|
||||
get => EntryEntity.ExpirationDate;
|
||||
set
|
||||
{
|
||||
if (!HasExpirationDate) return;
|
||||
EntryEntity.ExpirationDate = value;
|
||||
}
|
||||
}
|
||||
|
||||
public TimeSpan ExpiryTime
|
||||
{
|
||||
get => EntryEntity.ExpirationDate.TimeOfDay;
|
||||
set
|
||||
{
|
||||
if (!HasExpirationDate) return;
|
||||
EntryEntity.ExpirationDate = EntryEntity.ExpirationDate.Date.Add(value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasExpirationDate
|
||||
{
|
||||
get => EntryEntity.HasExpirationDate;
|
||||
set
|
||||
{
|
||||
EntryEntity.HasExpirationDate = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public Color BackgroundColor
|
||||
{
|
||||
get => Color.FromArgb(EntryEntity.BackgroundColor.A, EntryEntity.BackgroundColor.R, EntryEntity.BackgroundColor.G, EntryEntity.BackgroundColor.B);
|
||||
set
|
||||
{
|
||||
EntryEntity.BackgroundColor = System.Drawing.Color.FromArgb(value.A, value.R, value.G, value.B);
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public Color ForegroundColor
|
||||
{
|
||||
get => Color.FromArgb(EntryEntity.ForegroundColor.A, EntryEntity.ForegroundColor.R, EntryEntity.ForegroundColor.G, EntryEntity.ForegroundColor.B);
|
||||
set
|
||||
{
|
||||
EntryEntity.ForegroundColor = System.Drawing.Color.FromArgb(value.A, value.R, value.G, value.B);
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<EntryItemVm> History
|
||||
{
|
||||
get
|
||||
{
|
||||
var history = new Stack<EntryItemVm>();
|
||||
foreach (var historyEntry in EntryEntity.History)
|
||||
{
|
||||
history.Push(new EntryItemVm(_securityService, historyEntry, Parent));
|
||||
}
|
||||
history.Push(this);
|
||||
|
||||
return history;
|
||||
}
|
||||
}
|
||||
public Dictionary<string, string> AdditionalFields => EntryEntity.AdditionalFields;
|
||||
|
||||
public EntryItemVm(EntryEntity entryEntity, GroupItemVm parentGroup): this(App.Container.Resolve<ISecurityService>(), entryEntity, parentGroup)
|
||||
{ }
|
||||
|
||||
public EntryItemVm(ISecurityService securityService, EntryEntity entryEntity, GroupItemVm parentGroup)
|
||||
{
|
||||
_securityService = securityService;
|
||||
EntryEntity = entryEntity;
|
||||
Parent = parentGroup;
|
||||
}
|
||||
|
||||
public override string ToString() => EntryEntity.LastModificationDate.ToString("g");
|
||||
}
|
||||
}
|
99
Win10App/ViewModels/ListItems/GroupItemVm.cs
Normal file
99
Win10App/ViewModels/ListItems/GroupItemVm.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using ModernKeePass.Domain.Entities;
|
||||
using ModernKeePass.Domain.Enums;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels.ListItems
|
||||
{
|
||||
public class GroupItemVm: NotifyPropertyChangedBase
|
||||
{
|
||||
private readonly IDatabaseService _databaseService;
|
||||
//private Group _reorderedGroup;
|
||||
private bool _isEditMode;
|
||||
|
||||
public GroupEntity GroupEntity { get; }
|
||||
public GroupItemVm ParentVm { get; }
|
||||
|
||||
public bool IsEditMode
|
||||
{
|
||||
get => _isEditMode;
|
||||
set
|
||||
{
|
||||
_isEditMode = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string Text
|
||||
{
|
||||
get => GroupEntity.Name;
|
||||
set
|
||||
{
|
||||
GroupEntity.Name = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<EntryItemVm> SubEntries
|
||||
{
|
||||
get
|
||||
{
|
||||
var subEntries = new List<EntryItemVm>();
|
||||
subEntries.AddRange(Entries);
|
||||
foreach (var group in Children)
|
||||
{
|
||||
subEntries.AddRange(group.SubEntries);
|
||||
}
|
||||
|
||||
return subEntries;
|
||||
}
|
||||
}
|
||||
|
||||
public Icon Symbol => GroupEntity.Icon;
|
||||
public List<EntryItemVm> Entries { get; }
|
||||
public ObservableCollection<GroupItemVm> Children { get; set; } = new ObservableCollection<GroupItemVm>();
|
||||
|
||||
public GroupItemVm(GroupEntity groupEntity, GroupItemVm parent): this(App.Container.Resolve<IDatabaseService>(), groupEntity, parent)
|
||||
{ }
|
||||
|
||||
public GroupItemVm(IDatabaseService databaseService, GroupEntity groupEntity, GroupItemVm parentVm)
|
||||
{
|
||||
_databaseService = databaseService;
|
||||
GroupEntity = groupEntity;
|
||||
ParentVm = parentVm;
|
||||
|
||||
Entries = new List<EntryItemVm>();
|
||||
foreach (var entry in groupEntity.Entries)
|
||||
{
|
||||
Entries.Add(new EntryItemVm(entry, this));
|
||||
}
|
||||
|
||||
foreach (var subGroup in groupEntity.SubGroups)
|
||||
{
|
||||
Children.Add(new GroupItemVm(subGroup, this));
|
||||
}
|
||||
Children.CollectionChanged += Children_CollectionChanged;
|
||||
}
|
||||
|
||||
// TODO: not triggered when reordering
|
||||
private void Children_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
switch (e.Action)
|
||||
{
|
||||
case NotifyCollectionChangedAction.Remove:
|
||||
/*var oldIndex = (uint)e.OldStartingIndex;
|
||||
_reorderedGroup = Group.SubGroups.GetAt(oldIndex);
|
||||
Group.SubGroups.RemoveAt(oldIndex);*/
|
||||
_databaseService.DeleteEntity((Entity)e.OldItems[0]);
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Add:
|
||||
/*if (_reorderedGroup == null) Group.AddGroup(((GroupItem)e.NewItems[0]).Group, true);
|
||||
else Group.Groups.Insert((uint)e.NewStartingIndex, _reorderedGroup);*/
|
||||
_databaseService.AddEntity(ParentVm.GroupEntity, (Entity)e.NewItems[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
24
Win10App/ViewModels/MainVm.cs
Normal file
24
Win10App/ViewModels/MainVm.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using Windows.Storage;
|
||||
using MediatR;
|
||||
using ModernKeePass.Application.Common.Interfaces;
|
||||
using ModernKeePass.Application.Database.Queries.GetDatabase;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class MainVm
|
||||
{
|
||||
public bool IsDatabaseOpened { get; }
|
||||
public bool HasRecentItems { get; }
|
||||
|
||||
public string OpenedDatabaseName { get; }
|
||||
public IStorageFile File { get; set; }
|
||||
|
||||
public MainVm(IMediator mediator, IRecentProxy recent)
|
||||
{
|
||||
var database = mediator.Send(new GetDatabaseQuery()).GetAwaiter().GetResult();
|
||||
IsDatabaseOpened = database.IsOpen;
|
||||
OpenedDatabaseName = database.Name;
|
||||
HasRecentItems = recent.EntryCount > 0;
|
||||
}
|
||||
}
|
||||
}
|
16
Win10App/ViewModels/SettingsVm.cs
Normal file
16
Win10App/ViewModels/SettingsVm.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using MediatR;
|
||||
using ModernKeePass.Application.Database.Queries.GetDatabase;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class SettingsVm
|
||||
{
|
||||
public bool IsDatabaseOpened { get; }
|
||||
|
||||
public SettingsVm(IMediator mediator)
|
||||
{
|
||||
var database = mediator.Send(new GetDatabaseQuery()).GetAwaiter().GetResult();
|
||||
IsDatabaseOpened = database.IsOpen;
|
||||
}
|
||||
}
|
||||
}
|
48
Win10App/ViewModels/ViewModelLocator.cs
Normal file
48
Win10App/ViewModels/ViewModelLocator.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
In App.xaml:
|
||||
<Application.Resources>
|
||||
<vm:ViewModelLocator xmlns:vm="clr-namespace:ModernKeePass"
|
||||
x:Key="Locator" />
|
||||
</Application.Resources>
|
||||
|
||||
In the View:
|
||||
DataContext="{Binding Source={StaticResource Locator}, Path=ViewModelName}"
|
||||
|
||||
You can also use Blend to do all this with the tool's support.
|
||||
See http://www.galasoft.ch/mvvm
|
||||
*/
|
||||
|
||||
using System;
|
||||
using CommonServiceLocator;
|
||||
using GalaSoft.MvvmLight.Ioc;
|
||||
using ModernKeePass.ViewModels.ListItems;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
/// <summary>
|
||||
/// This class contains static references to all the view models in the
|
||||
/// application and provides an entry point for the bindings.
|
||||
/// </summary>
|
||||
public class ViewModelLocator : ViewModelLocatorCommon
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ViewModelLocator class.
|
||||
/// </summary>
|
||||
public ViewModelLocator()
|
||||
{
|
||||
SimpleIoc.Default.Register<SettingsVm>();
|
||||
SimpleIoc.Default.Register<MainVm>();
|
||||
SimpleIoc.Default.Register<GroupsVm>();
|
||||
SimpleIoc.Default.Register<EntriesVm>();
|
||||
SimpleIoc.Default.Register<GroupItemVm>();
|
||||
SimpleIoc.Default.Register<EntryItemVm>();
|
||||
}
|
||||
|
||||
public MainVm Main => ServiceLocator.Current.GetInstance<MainVm>(Guid.NewGuid().ToString());
|
||||
public SettingsVm Settings => ServiceLocator.Current.GetInstance<SettingsVm>(Guid.NewGuid().ToString());
|
||||
public GroupsVm Groups => ServiceLocator.Current.GetInstance<GroupsVm>(Guid.NewGuid().ToString());
|
||||
public EntriesVm Entries => ServiceLocator.Current.GetInstance<EntriesVm>(Guid.NewGuid().ToString());
|
||||
public GroupItemVm GroupItem => ServiceLocator.Current.GetInstance<GroupItemVm>(Guid.NewGuid().ToString());
|
||||
public EntryItemVm EntryItem => ServiceLocator.Current.GetInstance<EntryItemVm>(Guid.NewGuid().ToString());
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user