From dcff003c28ca6f9c740a940431775254b0b3e1d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81d=C3=A1m=20Kov=C3=A1cs?= Date: Tue, 24 May 2022 14:22:33 +0200 Subject: [PATCH] CreateElement --- .../UserCommand/CreateElement.cs | 13 ++ ...emManipulationUserCommandHandlerService.cs | 21 ++- ...faultIdentifiableCommandHandlerRegister.cs | 1 + .../DependencyInjection.cs | 5 +- .../Create/CreateContainerCommand.cs | 137 ++++++++++++++++++ .../CreateContainer/CreateContainerCommand.cs | 108 +------------- .../CreateElement/CreateElementCommand.cs | 19 +++ .../Configuration/MainConfiguration.cs | 2 +- 8 files changed, 201 insertions(+), 105 deletions(-) create mode 100644 src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/CreateElement.cs create mode 100644 src/Core/FileTime.Core.Command/Create/CreateContainerCommand.cs create mode 100644 src/Core/FileTime.Core.Command/CreateElement/CreateElementCommand.cs diff --git a/src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/CreateElement.cs b/src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/CreateElement.cs new file mode 100644 index 0000000..11f5254 --- /dev/null +++ b/src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/CreateElement.cs @@ -0,0 +1,13 @@ +namespace FileTime.App.Core.UserCommand; + +public sealed class CreateElement : IIdentifiableUserCommand +{ + public const string CommandName = "create_element"; + public static CreateElement Instance { get; } = new CreateElement(); + + private CreateElement() + { + } + + public string UserCommandID => CommandName; +} \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core/Services/UserCommandHandler/ItemManipulationUserCommandHandlerService.cs b/src/AppCommon/FileTime.App.Core/Services/UserCommandHandler/ItemManipulationUserCommandHandlerService.cs index df19b87..2dcf5c9 100644 --- a/src/AppCommon/FileTime.App.Core/Services/UserCommandHandler/ItemManipulationUserCommandHandlerService.cs +++ b/src/AppCommon/FileTime.App.Core/Services/UserCommandHandler/ItemManipulationUserCommandHandlerService.cs @@ -5,6 +5,7 @@ using FileTime.App.Core.UserCommand; using FileTime.App.Core.ViewModels; using FileTime.Core.Command; using FileTime.Core.Command.CreateContainer; +using FileTime.Core.Command.CreateElement; using FileTime.Core.Interactions; using FileTime.Core.Models; using FileTime.Core.Timeline; @@ -56,6 +57,7 @@ public class ItemManipulationUserCommandHandlerService : UserCommandHandlerServi new TypeUserCommandHandler(MarkItem), new TypeUserCommandHandler(Paste), new TypeUserCommandHandler(CreateContainer), + new TypeUserCommandHandler(CreateElement), }); } @@ -136,8 +138,25 @@ public class ItemManipulationUserCommandHandlerService : UserCommandHandlerServi if (_currentLocation?.FullName is null || newContainerName is null) return; var command = _serviceProvider - .GetInitableResolver(_currentLocation.FullName, newContainerName) + .GetInitableResolver(_currentLocation.FullName, newContainerName) .GetRequiredService(); await _commandScheduler.AddCommand(command); } + + private async Task CreateElement() + { + var containerNameInput = new TextInputElement("Element name"); + + await _inputInterface.ReadInputs(new List() { containerNameInput }); + + //TODO: message on empty result + var newContainerName = containerNameInput.Value; + + if (_currentLocation?.FullName is null || newContainerName is null) return; + + var command = _serviceProvider + .GetInitableResolver(_currentLocation.FullName, newContainerName) + .GetRequiredService(); + await _commandScheduler.AddCommand(command); + } } \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core/StartupServices/DefaultIdentifiableCommandHandlerRegister.cs b/src/AppCommon/FileTime.App.Core/StartupServices/DefaultIdentifiableCommandHandlerRegister.cs index fc5e399..7afbeb1 100644 --- a/src/AppCommon/FileTime.App.Core/StartupServices/DefaultIdentifiableCommandHandlerRegister.cs +++ b/src/AppCommon/FileTime.App.Core/StartupServices/DefaultIdentifiableCommandHandlerRegister.cs @@ -14,6 +14,7 @@ public class DefaultIdentifiableCommandHandlerRegister : IStartupHandler AddUserCommand(CloseTabCommand.Instance); AddUserCommand(CopyCommand.Instance); AddUserCommand(CreateContainer.Instance); + AddUserCommand(CreateElement.Instance); AddUserCommand(EnterRapidTravelCommand.Instance); AddUserCommand(ExitRapidTravelCommand.Instance); AddUserCommand(GoUpCommand.Instance); diff --git a/src/AppCommon/FileTime.App.DependencyInjection/DependencyInjection.cs b/src/AppCommon/FileTime.App.DependencyInjection/DependencyInjection.cs index e8fa76b..7562c32 100644 --- a/src/AppCommon/FileTime.App.DependencyInjection/DependencyInjection.cs +++ b/src/AppCommon/FileTime.App.DependencyInjection/DependencyInjection.cs @@ -1,6 +1,7 @@ using FileTime.App.Core; using FileTime.Core.Command; using FileTime.Core.Command.CreateContainer; +using FileTime.Core.Command.CreateElement; using FileTime.Core.ContentAccess; using FileTime.Core.Services; using FileTime.Core.Timeline; @@ -31,6 +32,8 @@ public static class DependencyInjection public static IServiceCollection RegisterCommands(this IServiceCollection serviceCollection) { - return serviceCollection.AddTransient(); + return serviceCollection + .AddTransient() + .AddTransient(); } } \ No newline at end of file diff --git a/src/Core/FileTime.Core.Command/Create/CreateContainerCommand.cs b/src/Core/FileTime.Core.Command/Create/CreateContainerCommand.cs new file mode 100644 index 0000000..5674b36 --- /dev/null +++ b/src/Core/FileTime.Core.Command/Create/CreateContainerCommand.cs @@ -0,0 +1,137 @@ +using FileTime.Core.ContentAccess; +using FileTime.Core.Enums; +using FileTime.Core.Extensions; +using FileTime.Core.Models; +using FileTime.Core.Timeline; +using InitableService; + +namespace FileTime.Core.Command.Create; + +public abstract class CreateItemBase : IExecutableCommand, IInitable +{ + private readonly ITimelessContentProvider _timelessContentProvider; + private readonly IContentAccessorFactory _contentAccessorFactory; + public FullName? Parent { get; private set; } + public string? NewItemName { get; private set; } + + protected CreateItemBase( + ITimelessContentProvider timelessContentProvider, + IContentAccessorFactory contentAccessorFactory) + { + _timelessContentProvider = timelessContentProvider; + _contentAccessorFactory = contentAccessorFactory; + } + + public async Task CanRun(PointInTime currentTime) + { + if (Parent is null) + { + throw new ArgumentNullException(nameof(Parent), + $"Property {nameof(Parent)} is not initialized. Call the {nameof(Init)} method before using the command."); + } + + if (NewItemName is null) + { + throw new ArgumentNullException(nameof(NewItemName), + $"Property {nameof(NewItemName)} is not initialized. Call the {nameof(Init)} method before using the command."); + } + + try + { + var parent = await ResolveParentAsync(); + if (parent is not IContainer parentContainer) return CanCommandRun.False; + + var items = await parentContainer.Items.GetItemsAsync(); + if (items is null) return CanCommandRun.Forcable; + + var existingItem = items.FirstOrDefault(i => i.Path.GetName() == NewItemName); + + return existingItem switch + { + null => CanCommandRun.True, + { Type: AbsolutePathType.Container } => CanCommandRun.Forcable, + _ => CanCommandRun.False + }; + } + catch + { + } + + return CanCommandRun.False; + } + + public Task SimulateCommand(PointInTime currentTime) + { + if (Parent is null) + { + throw new ArgumentNullException(nameof(Parent), + $"Property {nameof(Parent)} is not initialized. Call the {nameof(Init)} method before using the command."); + } + + if (NewItemName is null) + { + throw new ArgumentNullException(nameof(NewItemName), + $"Property {nameof(NewItemName)} is not initialized. Call the {nameof(Init)} method before using the command."); + } + + return Task.FromResult( + currentTime.WithDifferences(newPointInTime => + new List() + { + new( + DifferenceActionType.Create, + new AbsolutePath(_timelessContentProvider, + newPointInTime, + Parent.GetChild(NewItemName), + AbsolutePathType.Container + ) + ) + } + ) + ); + } + + public async Task Execute() + { + if (Parent is null) + { + throw new ArgumentNullException(nameof(Parent), + $"Property {nameof(Parent)} is not initialized. Call the {nameof(Init)} method before using the command."); + } + + if (NewItemName is null) + { + throw new ArgumentNullException(nameof(NewItemName), + $"Property {nameof(NewItemName)} is not initialized. Call the {nameof(Init)} method before using the command."); + } + + var resolvedParent = await _timelessContentProvider.GetItemByFullNameAsync(Parent, PointInTime.Present); + var itemCreator = _contentAccessorFactory.GetItemCreator(resolvedParent.Provider); + await CreateItem(itemCreator, resolvedParent); + } + + abstract protected Task CreateItem(IItemCreator itemCreator, IItem resolvedParent); + + private async Task ResolveParentAsync() + { + if (Parent is null) + { + throw new ArgumentNullException(nameof(Parent), + $"Property {nameof(Parent)} is not initialized. Call the {nameof(Init)} method before using the command."); + } + + if (NewItemName is null) + { + throw new ArgumentNullException(nameof(NewItemName), + $"Property {nameof(NewItemName)} is not initialized. Call the {nameof(Init)} method before using the command."); + } + + return await _timelessContentProvider.GetItemByFullNameAsync(Parent, PointInTime.Present); + } + + public void Init(FullName parent, string newContainerName) + { + Parent = parent; + NewItemName = newContainerName; + } +} \ No newline at end of file diff --git a/src/Core/FileTime.Core.Command/CreateContainer/CreateContainerCommand.cs b/src/Core/FileTime.Core.Command/CreateContainer/CreateContainerCommand.cs index cb7e6e9..443b10d 100644 --- a/src/Core/FileTime.Core.Command/CreateContainer/CreateContainerCommand.cs +++ b/src/Core/FileTime.Core.Command/CreateContainer/CreateContainerCommand.cs @@ -1,115 +1,19 @@ +using FileTime.Core.Command.Create; using FileTime.Core.ContentAccess; -using FileTime.Core.Enums; -using FileTime.Core.Extensions; using FileTime.Core.Models; using FileTime.Core.Timeline; -using InitableService; namespace FileTime.Core.Command.CreateContainer; -public class CreateContainerCommand : IExecutableCommand, IInitable +public class CreateContainerCommand : CreateItemBase { - private readonly ITimelessContentProvider _timelessContentProvider; - private readonly IContentAccessorFactory _contentAccessorFactory; - public FullName? Parent { get; private set; } - public string? NewContainerName { get; private set; } - - public CreateContainerCommand( - ITimelessContentProvider timelessContentProvider, - IContentAccessorFactory contentAccessorFactory) + public CreateContainerCommand(ITimelessContentProvider timelessContentProvider, IContentAccessorFactory contentAccessorFactory) + : base(timelessContentProvider, contentAccessorFactory) { - _timelessContentProvider = timelessContentProvider; - _contentAccessorFactory = contentAccessorFactory; } - public async Task CanRun(PointInTime currentTime) + protected override async Task CreateItem(IItemCreator itemCreator, IItem resolvedParent) { - if (Parent is null) - throw new ArgumentNullException(nameof(Parent), - $"Property {nameof(Parent)} is not initialized. Call the {nameof(Init)} method before using the command."); - if (NewContainerName is null) - throw new ArgumentNullException(nameof(NewContainerName), - $"Property {nameof(NewContainerName)} is not initialized. Call the {nameof(Init)} method before using the command."); - - try - { - var parent = await ResolveParentAsync(); - if (parent is not IContainer parentContainer) return CanCommandRun.False; - - var items = await parentContainer.Items.GetItemsAsync(); - if (items is null) return CanCommandRun.Forcable; - - var existingItem = items.FirstOrDefault(i => i.Path.GetName() == NewContainerName); - - return existingItem switch - { - null => CanCommandRun.True, - { Type: AbsolutePathType.Container } => CanCommandRun.Forcable, - _ => CanCommandRun.False - }; - } - catch - { - } - - return CanCommandRun.False; - } - - public Task SimulateCommand(PointInTime currentTime) - { - if (Parent is null) - throw new ArgumentNullException(nameof(Parent), - $"Property {nameof(Parent)} is not initialized. Call the {nameof(Init)} method before using the command."); - if (NewContainerName is null) - throw new ArgumentNullException(nameof(NewContainerName), - $"Property {nameof(NewContainerName)} is not initialized. Call the {nameof(Init)} method before using the command."); - - return Task.FromResult( - currentTime.WithDifferences(newPointInTime => - new List() - { - new( - DifferenceActionType.Create, - new AbsolutePath(_timelessContentProvider, - newPointInTime, - Parent.GetChild(NewContainerName), - AbsolutePathType.Container - ) - ) - } - ) - ); - } - - public async Task Execute() - { - if (Parent is null) - throw new ArgumentNullException(nameof(Parent), - $"Property {nameof(Parent)} is not initialized. Call the {nameof(Init)} method before using the command."); - if (NewContainerName is null) - throw new ArgumentNullException(nameof(NewContainerName), - $"Property {nameof(NewContainerName)} is not initialized. Call the {nameof(Init)} method before using the command."); - - var resolvedParent = await _timelessContentProvider.GetItemByFullNameAsync(Parent, PointInTime.Present); - var itemCreator = _contentAccessorFactory.GetItemCreator(resolvedParent.Provider); - await itemCreator.CreateContainerAsync(resolvedParent.Provider, Parent.GetChild(NewContainerName)); - } - - private async Task ResolveParentAsync() - { - if (Parent is null) - throw new ArgumentNullException(nameof(Parent), - $"Property {nameof(Parent)} is not initialized. Call the {nameof(Init)} method before using the command."); - if (NewContainerName is null) - throw new ArgumentNullException(nameof(NewContainerName), - $"Property {nameof(NewContainerName)} is not initialized. Call the {nameof(Init)} method before using the command."); - - return await _timelessContentProvider.GetItemByFullNameAsync(Parent, PointInTime.Present); - } - - public void Init(FullName parent, string newContainerName) - { - Parent = parent; - NewContainerName = newContainerName; + await itemCreator.CreateContainerAsync(resolvedParent.Provider, Parent!.GetChild(NewItemName!)); } } \ No newline at end of file diff --git a/src/Core/FileTime.Core.Command/CreateElement/CreateElementCommand.cs b/src/Core/FileTime.Core.Command/CreateElement/CreateElementCommand.cs new file mode 100644 index 0000000..cebd9c8 --- /dev/null +++ b/src/Core/FileTime.Core.Command/CreateElement/CreateElementCommand.cs @@ -0,0 +1,19 @@ +using FileTime.Core.Command.Create; +using FileTime.Core.ContentAccess; +using FileTime.Core.Models; +using FileTime.Core.Timeline; + +namespace FileTime.Core.Command.CreateElement; + +public class CreateElementCommand : CreateItemBase +{ + public CreateElementCommand(ITimelessContentProvider timelessContentProvider, IContentAccessorFactory contentAccessorFactory) + : base(timelessContentProvider, contentAccessorFactory) + { + } + + protected override async Task CreateItem(IItemCreator itemCreator, IItem resolvedParent) + { + await itemCreator.CreateElementAsync(resolvedParent.Provider, Parent!.GetChild(NewItemName!)); + } +} \ No newline at end of file diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp.Abstractions/Configuration/MainConfiguration.cs b/src/GuiApp/Avalonia/FileTime.GuiApp.Abstractions/Configuration/MainConfiguration.cs index 914646b..cf6349d 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp.Abstractions/Configuration/MainConfiguration.cs +++ b/src/GuiApp/Avalonia/FileTime.GuiApp.Abstractions/Configuration/MainConfiguration.cs @@ -49,7 +49,7 @@ public static class MainConfiguration //new CommandBindingConfiguration(ConfigCommand.CopyPath, new[] { Key.C, Key.P }), new CommandBindingConfiguration(CreateContainer.CommandName, Key.F7), new CommandBindingConfiguration(CreateContainer.CommandName, new[] { Key.C, Key.C }), - //new CommandBindingConfiguration(ConfigCommand.CreateElement, new[] { Key.C, Key.E }), + new CommandBindingConfiguration(CreateElement.CommandName, new[] { Key.C, Key.E }), //new CommandBindingConfiguration(ConfigCommand.Cut, new[] { Key.D, Key.D }), //new CommandBindingConfiguration(ConfigCommand.Edit, new KeyConfig(Key.F4)), new CommandBindingConfiguration(EnterRapidTravelCommand.CommandName, new KeyConfig(Key.OemComma, shift: true)),