From 35c050c612ea4c8ecdadb3ef44eb80a116921c92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81d=C3=A1m=20Kov=C3=A1cs?= Date: Sun, 24 Apr 2022 21:46:31 +0200 Subject: [PATCH] Marked items --- .../ViewModels/ITabViewModel.cs | 4 +++ .../CommandHandler/CommandHanderBase.cs | 27 +++++++++++++++ .../ItemManipulationCommandHandler.cs | 33 +++++++++++++++++++ .../NavigationCommandHandler.cs | 13 +++----- .../Services/CommandHandlerService.cs | 9 ++--- src/AppCommon/FileTime.App.Core/Startup.cs | 3 +- .../ViewModels/TabViewModel.cs | 33 ++++++++++++++++++- .../Avalonia/FileTime.GuiApp.App/Startup.cs | 4 +-- 8 files changed, 110 insertions(+), 16 deletions(-) create mode 100644 src/AppCommon/FileTime.App.Core/Services/CommandHandler/ItemManipulationCommandHandler.cs diff --git a/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/ITabViewModel.cs b/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/ITabViewModel.cs index 7eb3a41..8e7065a 100644 --- a/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/ITabViewModel.cs +++ b/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/ITabViewModel.cs @@ -22,5 +22,9 @@ namespace FileTime.App.Core.ViewModels BindedCollection? SelectedsChildrenCollection { get; } BindedCollection? ParentsChildrenCollection { get; } IObservable?> CurrentItemsCollectionObservable { get; } + void ClearMarkedItems(); + void RemoveMarkedItem(FullName item); + void AddMarkedItem(FullName item); + void ToggleMarkedItem(FullName item); } } \ 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 index 1a6d545..699ab43 100644 --- a/src/AppCommon/FileTime.App.Core/Services/CommandHandler/CommandHanderBase.cs +++ b/src/AppCommon/FileTime.App.Core/Services/CommandHandler/CommandHanderBase.cs @@ -1,10 +1,20 @@ +using System.Reactive.Linq; using FileTime.App.Core.Command; +using FileTime.App.Core.ViewModels; +using FileTime.Core.Models; namespace FileTime.App.Core.Services.CommandHandler { public abstract class CommandHanderBase : ICommandHandler { private readonly Dictionary> _commandHandlers = new(); + private readonly IAppState? _appState; + + protected CommandHanderBase(IAppState? appState = null) + { + _appState = appState; + } + public bool CanHandleCommand(Commands command) => _commandHandlers.ContainsKey(command); public async Task HandleCommandAsync(Commands command) => await _commandHandlers[command].Invoke(); @@ -19,5 +29,22 @@ namespace FileTime.App.Core.Services.CommandHandler } protected void RemoveCommandHandler(Commands command) => _commandHandlers.Remove(command); + + protected IDisposable SaveSelectedTab(Action handler) => RunWithAppState(appState => appState.SelectedTab.Subscribe(handler)); + protected IDisposable SaveCurrentSelectedItem(Action handler) + => RunWithAppState(appState => appState.SelectedTab.Select(t => t == null ? Observable.Return(null) : t.CurrentSelectedItem).Switch().Subscribe(handler)); + + protected IDisposable SaveCurrentLocation(Action handler) + => RunWithAppState(appState => appState.SelectedTab.Select(t => t == null ? Observable.Return(null) : t.CurrentLocation).Switch().Subscribe(handler)); + + protected IDisposable SaveCurrentItems(Action> handler) + => RunWithAppState(appState => appState.SelectedTab.Select(t => t?.CurrentItemsCollectionObservable ?? Observable.Return((IEnumerable?)Enumerable.Empty())).Switch().Subscribe(i => handler(i ?? Enumerable.Empty()))); + + private IDisposable RunWithAppState(Func act) + { + if (_appState == null) throw new NullReferenceException($"AppState is nit initialized in {nameof(CommandHanderBase)}."); + + return act(_appState); + } } } \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core/Services/CommandHandler/ItemManipulationCommandHandler.cs b/src/AppCommon/FileTime.App.Core/Services/CommandHandler/ItemManipulationCommandHandler.cs new file mode 100644 index 0000000..2b183b2 --- /dev/null +++ b/src/AppCommon/FileTime.App.Core/Services/CommandHandler/ItemManipulationCommandHandler.cs @@ -0,0 +1,33 @@ +using FileTime.App.Core.Command; +using FileTime.App.Core.ViewModels; + +namespace FileTime.App.Core.Services.CommandHandler +{ + public class ItemManipulationCommandHandler : CommandHanderBase + { + private ITabViewModel? _selectedTab; + private IItemViewModel? _currentSelectedItem; + private readonly ICommandHandlerService _commandHandlerService; + + public ItemManipulationCommandHandler(IAppState appState, ICommandHandlerService commandHandlerService) : base(appState) + { + _commandHandlerService = commandHandlerService; + + SaveSelectedTab(t => _selectedTab = t); + SaveCurrentSelectedItem(i => _currentSelectedItem = i); + + AddCommandHandlers(new (Commands, Func)[] + { + (Commands.Mark, MarkItem) + }); + } + + private async Task MarkItem() + { + if (_selectedTab == null || _currentSelectedItem?.BaseItem?.FullName == null) return; + + _selectedTab.ToggleMarkedItem(_currentSelectedItem.BaseItem.FullName); + await _commandHandlerService.HandleCommandAsync(Commands.MoveCursorDown); + } + } +} \ 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 index a1e9df3..28928d9 100644 --- a/src/AppCommon/FileTime.App.Core/Services/CommandHandler/NavigationCommandHandler.cs +++ b/src/AppCommon/FileTime.App.Core/Services/CommandHandler/NavigationCommandHandler.cs @@ -8,20 +8,17 @@ namespace FileTime.App.Core.Services.CommandHandler { public class NavigationCommandHandler : CommandHanderBase { - private readonly IAppState _appState; private ITabViewModel? _selectedTab; private IContainer? _currentLocation; private IItemViewModel? _currentSelectedItem; private IEnumerable _currentItems = Enumerable.Empty(); - public NavigationCommandHandler(IAppState appState) + public NavigationCommandHandler(IAppState appState) : base(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?.CurrentItemsCollectionObservable ?? Observable.Return((IEnumerable?)Enumerable.Empty())).Switch().Subscribe(i => _currentItems = i ?? Enumerable.Empty()); + SaveSelectedTab(t => _selectedTab = t); + SaveCurrentSelectedItem(i => _currentSelectedItem = i); + SaveCurrentLocation(l => _currentLocation = l); + SaveCurrentItems(i => _currentItems = i); AddCommandHandlers(new (Commands, Func)[] { diff --git a/src/AppCommon/FileTime.App.Core/Services/CommandHandlerService.cs b/src/AppCommon/FileTime.App.Core/Services/CommandHandlerService.cs index 0f8d740..eddfcc5 100644 --- a/src/AppCommon/FileTime.App.Core/Services/CommandHandlerService.cs +++ b/src/AppCommon/FileTime.App.Core/Services/CommandHandlerService.cs @@ -1,14 +1,15 @@ using FileTime.App.Core.Command; +using Microsoft.Extensions.DependencyInjection; namespace FileTime.App.Core.Services { public class CommandHandlerService : ICommandHandlerService { - private readonly IEnumerable _commandHandlers; + private readonly Lazy> _commandHandlers; - public CommandHandlerService(IEnumerable commandHandlers) + public CommandHandlerService(IServiceProvider serviceProvider) { - _commandHandlers = commandHandlers; + _commandHandlers = new Lazy>(() => serviceProvider.GetServices()); //(Commands.AutoRefresh, ToggleAutoRefresh), //(Commands.ChangeTimelineMode, ChangeTimelineMode), @@ -68,7 +69,7 @@ namespace FileTime.App.Core.Services public async Task HandleCommandAsync(Commands command) { - var handler = _commandHandlers.FirstOrDefault(h => h.CanHandleCommand(command)); + var handler = _commandHandlers.Value.FirstOrDefault(h => h.CanHandleCommand(command)); if (handler != null) { diff --git a/src/AppCommon/FileTime.App.Core/Startup.cs b/src/AppCommon/FileTime.App.Core/Startup.cs index 831794d..6773660 100644 --- a/src/AppCommon/FileTime.App.Core/Startup.cs +++ b/src/AppCommon/FileTime.App.Core/Startup.cs @@ -21,7 +21,8 @@ namespace FileTime.App.Core private static IServiceCollection AddCommandHandlers(this IServiceCollection serviceCollection) { return serviceCollection - .AddSingleton(); + .AddSingleton() + .AddSingleton(); } } } \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core/ViewModels/TabViewModel.cs b/src/AppCommon/FileTime.App.Core/ViewModels/TabViewModel.cs index 81f14a8..cd2142d 100644 --- a/src/AppCommon/FileTime.App.Core/ViewModels/TabViewModel.cs +++ b/src/AppCommon/FileTime.App.Core/ViewModels/TabViewModel.cs @@ -20,6 +20,7 @@ namespace FileTime.App.Core.ViewModels private readonly IAppState _appState; private readonly IRxSchedulerService _rxSchedulerService; private readonly BehaviorSubject> _markedItems = new(Enumerable.Empty()); + private readonly List _currentMarkedItems = new(); private readonly List _disposables = new(); private bool disposed; @@ -191,7 +192,37 @@ namespace FileTime.App.Core.ViewModels return elementViewModel; } - throw new ArgumentException($"{nameof(item)} is not {nameof(IContainer)} neighter {nameof(IElement)}"); + throw new ArgumentException($"{nameof(item)} is not {nameof(IContainer)} neither {nameof(IElement)}"); + } + + public void AddMarkedItem(FullName item) + { + _currentMarkedItems.Add(item); + _markedItems.OnNext(_currentMarkedItems); + } + + public void RemoveMarkedItem(FullName item) + { + _currentMarkedItems.RemoveAll(i => i.Path == item.Path); + _markedItems.OnNext(_currentMarkedItems); + } + + public void ToggleMarkedItem(FullName item) + { + if (_currentMarkedItems.Any(i => i.Path == item.Path)) + { + RemoveMarkedItem(item); + } + else + { + AddMarkedItem(item); + } + } + + public void ClearMarkedItems() + { + _currentMarkedItems.Clear(); + _markedItems.OnNext(_currentMarkedItems); } ~TabViewModel() => Dispose(false); diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp.App/Startup.cs b/src/GuiApp/Avalonia/FileTime.GuiApp.App/Startup.cs index c689247..fd03de2 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp.App/Startup.cs +++ b/src/GuiApp/Avalonia/FileTime.GuiApp.App/Startup.cs @@ -44,8 +44,8 @@ namespace FileTime.GuiApp { var configuration = new ConfigurationBuilder() .AddInMemoryCollection(MainConfiguration.Configuration) - .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) - .AddJsonFile($"appsettings.{Program.EnvironmentName}.json", true, true) + .AddJsonFile("appsettings.json", optional: true) + .AddJsonFile($"appsettings.{Program.EnvironmentName}.json", true) .Build(); return serviceCollection