diff --git a/src/AppCommon/FileTime.App.Core.Abstraction/Services/ICommandHandler.cs b/src/AppCommon/FileTime.App.Core.Abstraction/Services/ICommandHandler.cs new file mode 100644 index 0000000..67156c7 --- /dev/null +++ b/src/AppCommon/FileTime.App.Core.Abstraction/Services/ICommandHandler.cs @@ -0,0 +1,10 @@ +using FileTime.App.Core.Command; + +namespace FileTime.App.Core.Services +{ + public interface ICommandHandler + { + bool CanHandleCommand(Commands command); + Task HandleCommandAsync(Commands command); + } +} \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core/Services/CommandHandler/CommandHanderBase.cs b/src/AppCommon/FileTime.App.Core/Services/CommandHandler/CommandHanderBase.cs new file mode 100644 index 0000000..1a6d545 --- /dev/null +++ b/src/AppCommon/FileTime.App.Core/Services/CommandHandler/CommandHanderBase.cs @@ -0,0 +1,23 @@ +using FileTime.App.Core.Command; + +namespace FileTime.App.Core.Services.CommandHandler +{ + public abstract class CommandHanderBase : ICommandHandler + { + private readonly Dictionary> _commandHandlers = new(); + public bool CanHandleCommand(Commands command) => _commandHandlers.ContainsKey(command); + + public async Task HandleCommandAsync(Commands command) => await _commandHandlers[command].Invoke(); + + protected void AddCommandHandler(Commands command, Func handler) => _commandHandlers.Add(command, handler); + protected void AddCommandHandlers(IEnumerable<(Commands command, Func handler)> commandHandlers) + { + foreach (var (command, handler) in commandHandlers) + { + AddCommandHandler(command, handler); + } + } + + protected void RemoveCommandHandler(Commands command) => _commandHandlers.Remove(command); + } +} \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core/Services/CommandHandler/NavigationCommandHandler.cs b/src/AppCommon/FileTime.App.Core/Services/CommandHandler/NavigationCommandHandler.cs new file mode 100644 index 0000000..2c38e0f --- /dev/null +++ b/src/AppCommon/FileTime.App.Core/Services/CommandHandler/NavigationCommandHandler.cs @@ -0,0 +1,71 @@ +using System.Reactive.Linq; +using FileTime.App.Core.Command; +using FileTime.App.Core.Extensions; +using FileTime.App.Core.ViewModels; +using FileTime.Core.Models; + +namespace FileTime.App.Core.Services.CommandHandler +{ + public class NavigationCommandHandler : CommandHanderBase + { + private readonly IAppState _appState; + private ITabViewModel? _selectedTab; + private IContainer? _currentLocation; + private IItemViewModel? _currentSelectedItem; + private List _currentItems = new(); + + public NavigationCommandHandler(IAppState appState) + { + _appState = appState; + + _appState.SelectedTab.Subscribe(t => _selectedTab = t); + _appState.SelectedTab.Select(t => t == null ? Observable.Return(null) : t.CurrentLocation).Switch().Subscribe(l => _currentLocation = l); + _appState.SelectedTab.Select(t => t == null ? Observable.Return(null) : t.CurrentSelectedItem).Switch().Subscribe(l => _currentSelectedItem = l); + _appState.SelectedTab.Select(t => t == null ? Observable.Return(Enumerable.Empty()) : t.CurrentItems).Switch().Subscribe(i => _currentItems = i.ToList()); + + AddCommandHandlers(new (Commands, Func)[] + { + (Commands.GoUp, GoUp), + (Commands.MoveCursorDown, MoveCursorDown), + (Commands.MoveCursorUp, MoveCursorUp), + (Commands.Open, OpenContainer), + }); + } + + private Task OpenContainer() + { + if (_currentSelectedItem is not IContainerViewModel containerViewModel || containerViewModel.Container is null) return Task.CompletedTask; + + _selectedTab?.Tab?.SetCurrentLocation(containerViewModel.Container); + return Task.CompletedTask; + } + + private async Task GoUp() + { + if (_currentLocation?.Parent is not IAbsolutePath parentPath || await parentPath.ResolveAsyncSafe() is not IContainer newContainer) return; + _selectedTab?.Tab?.SetCurrentLocation(newContainer); + } + + private Task MoveCursorDown() + { + SelectNewSelectedItem(i => i.SkipWhile(i => i != _currentSelectedItem).Skip(1).FirstOrDefault()); + return Task.CompletedTask; + } + + private Task MoveCursorUp() + { + SelectNewSelectedItem(i => i.TakeWhile(i => i != _currentSelectedItem).LastOrDefault()); + return Task.CompletedTask; + } + + private void SelectNewSelectedItem(Func, IItemViewModel?> getNewSelected) + { + if (_selectedTab is null || _currentLocation is null) return; + + var newSelectedItem = getNewSelected(_currentItems); + if (newSelectedItem == null) return; + + _selectedTab.Tab?.SetSelectedItem(newSelectedItem.ToAbsolutePath()); + } + } +} \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core/Services/CommandHandlerService.cs b/src/AppCommon/FileTime.App.Core/Services/CommandHandlerService.cs index 2baf417..0f8d740 100644 --- a/src/AppCommon/FileTime.App.Core/Services/CommandHandlerService.cs +++ b/src/AppCommon/FileTime.App.Core/Services/CommandHandlerService.cs @@ -1,129 +1,79 @@ -using System.Reactive.Linq; using FileTime.App.Core.Command; -using FileTime.App.Core.Extensions; -using FileTime.App.Core.ViewModels; -using FileTime.Core.Models; namespace FileTime.App.Core.Services { public class CommandHandlerService : ICommandHandlerService { - private readonly Dictionary> _commandHandlers; - private readonly IAppState _appState; - private ITabViewModel? _selectedTab; - private IContainer? _currentLocation; - private IItemViewModel? _currentSelectedItem; - private List _currentItems = new(); + private readonly IEnumerable _commandHandlers; - public CommandHandlerService(IAppState appState) + public CommandHandlerService(IEnumerable commandHandlers) { - _appState = appState; + _commandHandlers = commandHandlers; - _appState.SelectedTab.Subscribe(t => _selectedTab = t); - _appState.SelectedTab.Select(t => t == null ? Observable.Return(null) : t.CurrentLocation).Switch().Subscribe(l => _currentLocation = l); - _appState.SelectedTab.Select(t => t == null ? Observable.Return(null) : t.CurrentSelectedItem).Switch().Subscribe(l => _currentSelectedItem = l); - _appState.SelectedTab.Select(t => t == null ? Observable.Return(Enumerable.Empty()) : t.CurrentItems).Switch().Subscribe(i => _currentItems = i.ToList()); + //(Commands.AutoRefresh, ToggleAutoRefresh), + //(Commands.ChangeTimelineMode, ChangeTimelineMode), + //(Commands.CloseTab, CloseTab), + //(Commands.Compress, Compress), + //(Commands.Copy, Copy), + //(Commands.CopyHash, CopyHash), + //(Commands.CopyPath, CopyPath), + //(Commands.CreateContainer, CreateContainer), + //(Commands.CreateElement, CreateElement), + //(Commands.Cut, Cut), + //(Commands.Edit, Edit), + //(Commands.EnterRapidTravel, EnterRapidTravelMode), + //(Commands.FindByName, FindByName), + //(Commands.FindByNameRegex, FindByNameRegex), + //(Commands.GoToHome, GotToHome), + //(Commands.GoToPath, GoToContainer), + //(Commands.GoToProvider, GotToProvider), + //(Commands.GoToRoot, GotToRoot), + //(Commands.HardDelete, HardDelete), + //(Commands.Mark, MarkCurrentItem), + //(Commands.MoveCursorDownPage, MoveCursorDownPage), + //(Commands.MoveCursorUpPage, MoveCursorUpPage), + //(Commands.MoveToFirst, MoveToFirst), + //(Commands.MoveToLast, MoveToLast), + //(Commands.NextTimelineBlock, SelectNextTimelineBlock), + //(Commands.NextTimelineCommand, SelectNextTimelineCommand), + //(Commands.OpenInFileBrowser, OpenInDefaultFileExplorer), + //(Commands.OpenOrRun, OpenOrRun), + //(Commands.PasteMerge, PasteMerge), + //(Commands.PasteOverwrite, PasteOverwrite), + //(Commands.PasteSkip, PasteSkip), + //(Commands.PinFavorite, PinFavorite), + //(Commands.PreviousTimelineBlock, SelectPreviousTimelineBlock), + //(Commands.PreviousTimelineCommand, SelectPreviousTimelineCommand), + //(Commands.Refresh, RefreshCurrentLocation), + //(Commands.Rename, Rename), + //(Commands.RunCommand, RunCommandInContainer), + //(Commands.ScanContainerSize, ScanContainerSize), + //(Commands.ShowAllShotcut, ShowAllShortcut), + //(Commands.SoftDelete, SoftDelete), + //(Commands.SwitchToLastTab, async() => await SwitchToTab(-1)), + //(Commands.SwitchToTab1, async() => await SwitchToTab(1)), + //(Commands.SwitchToTab2, async() => await SwitchToTab(2)), + //(Commands.SwitchToTab3, async() => await SwitchToTab(3)), + //(Commands.SwitchToTab4, async() => await SwitchToTab(4)), + //(Commands.SwitchToTab5, async() => await SwitchToTab(5)), + //(Commands.SwitchToTab6, async() => await SwitchToTab(6)), + //(Commands.SwitchToTab7, async() => await SwitchToTab(7)), + //(Commands.SwitchToTab8, async() => await SwitchToTab(8)), + //(Commands.TimelinePause, PauseTimeline), + //(Commands.TimelineRefresh, RefreshTimeline), + //(Commands.TimelineStart, ContinueTimeline), + //(Commands.ToggleAdvancedIcons, ToggleAdvancedIcons), + //(Commands.ToggleHidden, ToggleHidden), + } - _commandHandlers = new Dictionary> + public async Task HandleCommandAsync(Commands command) + { + var handler = _commandHandlers.FirstOrDefault(h => h.CanHandleCommand(command)); + + if (handler != null) { - //{Commands.AutoRefresh, ToggleAutoRefresh}, - //{Commands.ChangeTimelineMode, ChangeTimelineMode}, - //{Commands.CloseTab, CloseTab}, - //{Commands.Compress, Compress}, - //{Commands.Copy, Copy}, - //{Commands.CopyHash, CopyHash}, - //{Commands.CopyPath, CopyPath}, - //{Commands.CreateContainer, CreateContainer}, - //{Commands.CreateElement, CreateElement}, - //{Commands.Cut, Cut}, - //{Commands.Edit, Edit}, - //{Commands.EnterRapidTravel, EnterRapidTravelMode}, - //{Commands.FindByName, FindByName}, - //{Commands.FindByNameRegex, FindByNameRegex}, - //{Commands.GoToHome, GotToHome}, - //{Commands.GoToPath, GoToContainer}, - //{Commands.GoToProvider, GotToProvider}, - //{Commands.GoToRoot, GotToRoot}, - {Commands.GoUp, GoUp}, - //{Commands.HardDelete, HardDelete}, - //{Commands.Mark, MarkCurrentItem}, - {Commands.MoveCursorDown, MoveCursorDown}, - //{Commands.MoveCursorDownPage, MoveCursorDownPage}, - {Commands.MoveCursorUp, MoveCursorUp}, - //{Commands.MoveCursorUpPage, MoveCursorUpPage}, - //{Commands.MoveToFirst, MoveToFirst}, - //{Commands.MoveToLast, MoveToLast}, - //{Commands.NextTimelineBlock, SelectNextTimelineBlock}, - //{Commands.NextTimelineCommand, SelectNextTimelineCommand}, - {Commands.Open, OpenContainer}, - //{Commands.OpenInFileBrowser, OpenInDefaultFileExplorer}, - //{Commands.OpenOrRun, OpenOrRun}, - //{Commands.PasteMerge, PasteMerge}, - //{Commands.PasteOverwrite, PasteOverwrite}, - //{Commands.PasteSkip, PasteSkip}, - //{Commands.PinFavorite, PinFavorite}, - //{Commands.PreviousTimelineBlock, SelectPreviousTimelineBlock}, - //{Commands.PreviousTimelineCommand, SelectPreviousTimelineCommand}, - //{Commands.Refresh, RefreshCurrentLocation}, - //{Commands.Rename, Rename}, - //{Commands.RunCommand, RunCommandInContainer}, - //{Commands.ScanContainerSize, ScanContainerSize}, - //{Commands.ShowAllShotcut, ShowAllShortcut}, - //{Commands.SoftDelete, SoftDelete}, - //{Commands.SwitchToLastTab, async() => await SwitchToTab(-1)}, - //{Commands.SwitchToTab1, async() => await SwitchToTab(1)}, - //{Commands.SwitchToTab2, async() => await SwitchToTab(2)}, - //{Commands.SwitchToTab3, async() => await SwitchToTab(3)}, - //{Commands.SwitchToTab4, async() => await SwitchToTab(4)}, - //{Commands.SwitchToTab5, async() => await SwitchToTab(5)}, - //{Commands.SwitchToTab6, async() => await SwitchToTab(6)}, - //{Commands.SwitchToTab7, async() => await SwitchToTab(7)}, - //{Commands.SwitchToTab8, async() => await SwitchToTab(8)}, - //{Commands.TimelinePause, PauseTimeline}, - //{Commands.TimelineRefresh, RefreshTimeline}, - //{Commands.TimelineStart, ContinueTimeline}, - //{Commands.ToggleAdvancedIcons, ToggleAdvancedIcons}, - //{Commands.ToggleHidden, ToggleHidden}, - }; - } - - public async Task HandleCommandAsync(Commands command) => - await _commandHandlers[command].Invoke(); - - private Task OpenContainer() - { - if (_currentSelectedItem is not IContainerViewModel containerViewModel || containerViewModel.Container is null) return Task.CompletedTask; - - _selectedTab?.Tab?.SetCurrentLocation(containerViewModel.Container); - return Task.CompletedTask; - } - - private async Task GoUp() - { - if (_currentLocation?.Parent is not IAbsolutePath parentPath || await parentPath.ResolveAsyncSafe() is not IContainer newContainer) return; - _selectedTab?.Tab?.SetCurrentLocation(newContainer); - } - - private Task MoveCursorDown() - { - SelectNewSelectedItem(i => i.SkipWhile(i => i != _currentSelectedItem).Skip(1).FirstOrDefault()); - return Task.CompletedTask; - } - - private Task MoveCursorUp() - { - SelectNewSelectedItem(i => i.TakeWhile(i => i != _currentSelectedItem).LastOrDefault()); - return Task.CompletedTask; - } - - private void SelectNewSelectedItem(Func, IItemViewModel?> getNewSelected) - { - if (_selectedTab is null || _currentLocation is null) return; - - var newSelectedItem = getNewSelected(_currentItems); - if (newSelectedItem == null) return; - - _selectedTab.Tab?.SetSelectedItem(newSelectedItem.ToAbsolutePath()); + await handler.HandleCommandAsync(command); + } } } } \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core/Startup.cs b/src/AppCommon/FileTime.App.Core/Startup.cs new file mode 100644 index 0000000..831794d --- /dev/null +++ b/src/AppCommon/FileTime.App.Core/Startup.cs @@ -0,0 +1,27 @@ +using FileTime.App.Core.Services; +using FileTime.App.Core.Services.CommandHandler; +using FileTime.App.Core.ViewModels; +using Microsoft.Extensions.DependencyInjection; + +namespace FileTime.App.Core +{ + public static class Startup + { + public static IServiceCollection AddCoreAppServices(this IServiceCollection serviceCollection) + { + return serviceCollection + .AddTransient() + .AddTransient() + .AddTransient() + .AddTransient() + .AddSingleton() + .AddCommandHandlers(); + } + + private static IServiceCollection AddCommandHandlers(this IServiceCollection serviceCollection) + { + return serviceCollection + .AddSingleton(); + } + } +} \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.DependencyInjection/DependencyInjection.cs b/src/AppCommon/FileTime.App.DependencyInjection/DependencyInjection.cs index 3a4e9ea..967ea73 100644 --- a/src/AppCommon/FileTime.App.DependencyInjection/DependencyInjection.cs +++ b/src/AppCommon/FileTime.App.DependencyInjection/DependencyInjection.cs @@ -1,3 +1,5 @@ +using FileTime.App.Core; +using FileTime.Core.Services; using FileTime.Providers.Local; using Microsoft.Extensions.DependencyInjection; @@ -10,6 +12,8 @@ namespace FileTime.App.DependencyInjection serviceCollection ??= new ServiceCollection(); return serviceCollection + .AddTransient() + .AddCoreAppServices() .AddLocalServices(); } } diff --git a/src/AppCommon/FileTime.App.DependencyInjection/FileTime.App.DependencyInjection.csproj b/src/AppCommon/FileTime.App.DependencyInjection/FileTime.App.DependencyInjection.csproj index 9252fe1..16d495d 100644 --- a/src/AppCommon/FileTime.App.DependencyInjection/FileTime.App.DependencyInjection.csproj +++ b/src/AppCommon/FileTime.App.DependencyInjection/FileTime.App.DependencyInjection.csproj @@ -10,6 +10,7 @@ + diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp.App/App.axaml.cs b/src/GuiApp/Avalonia/FileTime.GuiApp.App/App.axaml.cs index d988d57..3349073 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp.App/App.axaml.cs +++ b/src/GuiApp/Avalonia/FileTime.GuiApp.App/App.axaml.cs @@ -17,6 +17,7 @@ namespace FileTime.GuiApp .RegisterDefaultServices() .AddConfiguration() .RegisterLogging() + .RegisterServices() .AddViewModels() .BuildServiceProvider() .InitSerilog(); diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp.App/Startup.cs b/src/GuiApp/Avalonia/FileTime.GuiApp.App/Startup.cs index c55da1f..c689247 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp.App/Startup.cs +++ b/src/GuiApp/Avalonia/FileTime.GuiApp.App/Startup.cs @@ -1,9 +1,7 @@ using System; using System.IO; -using FileTime.App.Core; using FileTime.App.Core.Services; using FileTime.App.Core.ViewModels; -using FileTime.Core.Services; using FileTime.GuiApp.Configuration; using FileTime.GuiApp.Logging; using FileTime.GuiApp.Services; @@ -23,17 +21,12 @@ namespace FileTime.GuiApp .AddSingleton() .AddSingleton() .AddSingleton(s => s.GetRequiredService()) - .AddSingleton(s => s.GetRequiredService()) - .AddSingleton() - .AddSingleton() + .AddSingleton(s => s.GetRequiredService()); + } + internal static IServiceCollection RegisterServices(this IServiceCollection serviceCollection) + { + return serviceCollection .AddSingleton() - //TODO: move?? - .AddTransient() - .AddTransient() - .AddTransient() - .AddTransient() - .AddTransient() - .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton()