diff --git a/src/AppCommon/FileTime.App.Core.Abstraction/FileTime.App.Core.Abstraction.csproj b/src/AppCommon/FileTime.App.Core.Abstraction/FileTime.App.Core.Abstraction.csproj index 64ce252..322fc5f 100644 --- a/src/AppCommon/FileTime.App.Core.Abstraction/FileTime.App.Core.Abstraction.csproj +++ b/src/AppCommon/FileTime.App.Core.Abstraction/FileTime.App.Core.Abstraction.csproj @@ -11,6 +11,11 @@ + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/AppCommon/FileTime.App.Core.Abstraction/Models/BindedCollection.cs b/src/AppCommon/FileTime.App.Core.Abstraction/Models/BindedCollection.cs index 8287d63..8c7292d 100644 --- a/src/AppCommon/FileTime.App.Core.Abstraction/Models/BindedCollection.cs +++ b/src/AppCommon/FileTime.App.Core.Abstraction/Models/BindedCollection.cs @@ -1,12 +1,17 @@ using System.Collections.ObjectModel; +using System.ComponentModel; using DynamicData; +using PropertyChanged.SourceGenerator; namespace FileTime.App.Core.Models; -public class BindedCollection : IDisposable +public partial class BindedCollection : IDisposable, INotifyPropertyChanged { private readonly IDisposable _disposable; - public ReadOnlyObservableCollection Collection { get; } + private IDisposable? _innerDisposable; + + [Notify] private ReadOnlyObservableCollection? _collection; + public BindedCollection(IObservable> dynamicList) { _disposable = dynamicList @@ -14,12 +19,34 @@ public class BindedCollection : IDisposable .DisposeMany() .Subscribe(); - Collection = collection; + _collection = collection; + } + + public BindedCollection(IObservable>?> dynamicListSource) + { + _disposable = dynamicListSource.Subscribe(dynamicList => + { + _innerDisposable?.Dispose(); + if (dynamicList is not null) + { + _innerDisposable = dynamicList + .Bind(out var collection) + .DisposeMany() + .Subscribe(); + + Collection = collection; + } + else + { + Collection = null; + } + }); } public void Dispose() { _disposable.Dispose(); + _innerDisposable?.Dispose(); GC.SuppressFinalize(this); } } \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core.Abstraction/Services/IModalService.cs b/src/AppCommon/FileTime.App.Core.Abstraction/Services/IModalService.cs new file mode 100644 index 0000000..36f91c7 --- /dev/null +++ b/src/AppCommon/FileTime.App.Core.Abstraction/Services/IModalService.cs @@ -0,0 +1,12 @@ +using DynamicData; +using FileTime.App.Core.ViewModels; + +namespace FileTime.App.Core.Services; + +public interface IModalService +{ + IObservable> OpenModals { get; } + + void OpenModal(IModalViewModelBase modalToOpen); + void CloseModal(IModalViewModelBase modalToClose); +} \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IAppState.cs b/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IAppState.cs index 77cc837..939a68f 100644 --- a/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IAppState.cs +++ b/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IAppState.cs @@ -8,9 +8,11 @@ public interface IAppState ObservableCollection Tabs { get; } IObservable SelectedTab { get; } IObservable SearchText { get; } - ViewMode ViewMode { get; } + IObservable ViewMode { get; } + string RapidTravelText { get; set; } void AddTab(ITabViewModel tabViewModel); void RemoveTab(ITabViewModel tabViewModel); void SetSearchText(string? searchText); + void SwitchViewMode(ViewMode newViewMode); } \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IModalViewModelBase.cs b/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IModalViewModelBase.cs new file mode 100644 index 0000000..78d73b9 --- /dev/null +++ b/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IModalViewModelBase.cs @@ -0,0 +1,6 @@ +namespace FileTime.App.Core.ViewModels; + +public interface IModalViewModelBase +{ + string Name { get; } +} \ 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 index f6d25de..6d16ca3 100644 --- a/src/AppCommon/FileTime.App.Core/Services/CommandHandler/ItemManipulationCommandHandler.cs +++ b/src/AppCommon/FileTime.App.Core/Services/CommandHandler/ItemManipulationCommandHandler.cs @@ -1,4 +1,4 @@ -using DynamicData; +using System.Reactive.Linq; using FileTime.App.Core.Command; using FileTime.App.Core.Models; using FileTime.App.Core.ViewModels; @@ -14,7 +14,7 @@ public class ItemManipulationCommandHandler : CommandHandlerBase private IItemViewModel? _currentSelectedItem; private readonly ICommandHandlerService _commandHandlerService; private readonly IClipboardService _clipboardService; - private BindedCollection? _markedItems; + private readonly BindedCollection? _markedItems; public ItemManipulationCommandHandler( IAppState appState, @@ -24,14 +24,11 @@ public class ItemManipulationCommandHandler : CommandHandlerBase _commandHandlerService = commandHandlerService; _clipboardService = clipboardService; - SaveSelectedTab(t => - { - _selectedTab = t; - _markedItems?.Dispose(); - _markedItems = t == null ? null : new BindedCollection(t.MarkedItems); - }); + SaveSelectedTab(t => _selectedTab = t); SaveCurrentSelectedItem(i => _currentSelectedItem = i); + _markedItems = new BindedCollection(appState.SelectedTab.Select(t => t?.MarkedItems)); + AddCommandHandlers(new (Commands, Func)[] { (Commands.Copy, Copy), @@ -55,9 +52,9 @@ public class ItemManipulationCommandHandler : CommandHandlerBase _clipboardService.Clear(); _clipboardService.SetCommand(); - if ((_markedItems?.Collection.Count ?? 0) > 0) + if ((_markedItems?.Collection?.Count ?? 0) > 0) { - foreach (var item in _markedItems!.Collection) + foreach (var item in _markedItems!.Collection!) { _clipboardService.AddContent(item); } diff --git a/src/AppCommon/FileTime.App.Core/Services/CommandHandler/NavigationCommandHandler.cs b/src/AppCommon/FileTime.App.Core/Services/CommandHandler/NavigationCommandHandler.cs index 82f4361..1af1243 100644 --- a/src/AppCommon/FileTime.App.Core/Services/CommandHandler/NavigationCommandHandler.cs +++ b/src/AppCommon/FileTime.App.Core/Services/CommandHandler/NavigationCommandHandler.cs @@ -1,6 +1,7 @@ using System.Reactive.Linq; using FileTime.App.Core.Command; using FileTime.App.Core.Extensions; +using FileTime.App.Core.Models.Enums; using FileTime.App.Core.ViewModels; using FileTime.Core.Models; @@ -8,6 +9,7 @@ namespace FileTime.App.Core.Services.CommandHandler; public class NavigationCommandHandler : CommandHandlerBase { + private readonly IAppState _appState; private ITabViewModel? _selectedTab; private IContainer? _currentLocation; private IItemViewModel? _currentSelectedItem; @@ -15,6 +17,8 @@ public class NavigationCommandHandler : CommandHandlerBase public NavigationCommandHandler(IAppState appState) : base(appState) { + _appState = appState; + SaveSelectedTab(t => _selectedTab = t); SaveCurrentSelectedItem(i => _currentSelectedItem = i); SaveCurrentLocation(l => _currentLocation = l); @@ -22,6 +26,7 @@ public class NavigationCommandHandler : CommandHandlerBase AddCommandHandlers(new (Commands, Func)[] { + (Commands.EnterRapidTravel, EnterRapidTravel), (Commands.GoUp, GoUp), (Commands.MoveCursorDown, MoveCursorDown), (Commands.MoveCursorUp, MoveCursorUp), @@ -64,4 +69,10 @@ public class NavigationCommandHandler : CommandHandlerBase _selectedTab.Tab?.SetSelectedItem(newSelectedItem.ToAbsolutePath()); } + + private Task EnterRapidTravel() + { + _appState.SwitchViewMode(ViewMode.RapidTravel); + return Task.CompletedTask; + } } \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core/ViewModels/AppStateBase.cs b/src/AppCommon/FileTime.App.Core/ViewModels/AppStateBase.cs index 1807c19..531e5a0 100644 --- a/src/AppCommon/FileTime.App.Core/ViewModels/AppStateBase.cs +++ b/src/AppCommon/FileTime.App.Core/ViewModels/AppStateBase.cs @@ -13,17 +13,21 @@ public abstract partial class AppStateBase : IAppState private readonly BehaviorSubject _searchText = new(null); private readonly BehaviorSubject _selectedTab = new(null); private readonly BehaviorSubject> _tabs = new(Enumerable.Empty()); + private readonly BehaviorSubject _viewMode = new(Models.Enums.ViewMode.Default); - [Property] - private ViewMode _viewMode; + public IObservable ViewMode { get; private set; } public ObservableCollection Tabs { get; } = new(); public IObservable SearchText { get; private set; } public IObservable SelectedTab { get; private set; } + [Property] private string _rapidTravelText = ""; + partial void OnInitialize() { + ViewMode = _viewMode.AsObservable(); + Tabs.CollectionChanged += (_, _) => _tabs.OnNext(Tabs); SearchText = _searchText.AsObservable(); SelectedTab = Observable.CombineLatest(_tabs, _selectedTab, GetSelectedTab); @@ -43,6 +47,11 @@ public abstract partial class AppStateBase : IAppState public void SetSearchText(string? searchText) => _searchText.OnNext(searchText); + public void SwitchViewMode(ViewMode newViewMode) + { + _viewMode.OnNext(newViewMode); + } + public void SetSelectedTab(ITabViewModel tabToSelect) => _selectedTab.OnNext(tabToSelect); private ITabViewModel? GetSelectedTab(IEnumerable tabs, ITabViewModel? expectedSelectedTab) diff --git a/src/AppCommon/FileTime.App.Core/ViewModels/TabViewModel.cs b/src/AppCommon/FileTime.App.Core/ViewModels/TabViewModel.cs index 353e141..2be14d2 100644 --- a/src/AppCommon/FileTime.App.Core/ViewModels/TabViewModel.cs +++ b/src/AppCommon/FileTime.App.Core/ViewModels/TabViewModel.cs @@ -6,7 +6,6 @@ using FileTime.App.Core.Models.Enums; using FileTime.App.Core.Services; using FileTime.Core.Models; using FileTime.Core.Services; -using FileTime.Tools.Extensions; using Microsoft.Extensions.DependencyInjection; using MvvmGen; @@ -21,7 +20,7 @@ public partial class TabViewModel : ITabViewModel, IDisposable private readonly IRxSchedulerService _rxSchedulerService; private readonly SourceList _markedItems = new(); private readonly List _disposables = new(); - private bool disposed; + private bool _disposed; public ITab? Tab { get; private set; } public int TabNumber { get; private set; } @@ -96,23 +95,9 @@ public partial class TabViewModel : ITabViewModel, IDisposable SelectedsChildrenCollectionObservable = InitAsd(SelectedsChildren); ParentsChildrenCollectionObservable = InitAsd(ParentsChildren); - CurrentItems.Subscribe(children => - { - CurrentItemsCollection?.Dispose(); - CurrentItemsCollection = children.MapNull(c => new BindedCollection(c!)); - }); - - ParentsChildren.Subscribe(children => - { - ParentsChildrenCollection?.Dispose(); - ParentsChildrenCollection = children.MapNull(c => new BindedCollection(c!)); - }); - - SelectedsChildren.Subscribe(children => - { - SelectedsChildrenCollection?.Dispose(); - SelectedsChildrenCollection = children.MapNull(c => new BindedCollection(c!)); - }); + CurrentItemsCollection = new(CurrentItems); + ParentsChildrenCollection = new(ParentsChildren); + SelectedsChildrenCollection = new(SelectedsChildren); tab.CurrentLocation.Subscribe((_) => _markedItems.Clear()); @@ -131,7 +116,7 @@ public partial class TabViewModel : ITabViewModel, IDisposable i?.TransformAsync(MapItem) .Transform(i => MapItemToViewModel(i, ItemViewModelType.SelectedChild))), currentSelectedItemThrottled - .Where(c => c is null || c is not IContainerViewModel) + .Where(c => c is null or not IContainerViewModel) .Select(_ => (IObservable>?) null) ) .ObserveOn(_rxSchedulerService.GetWorkerScheduler()) @@ -251,7 +236,7 @@ public partial class TabViewModel : ITabViewModel, IDisposable private void Dispose(bool disposing) { - if (!disposed && disposing) + if (!_disposed && disposing) { foreach (var disposable in _disposables) { @@ -265,6 +250,6 @@ public partial class TabViewModel : ITabViewModel, IDisposable } } - disposed = true; + _disposed = true; } } \ No newline at end of file diff --git a/src/Core/FileTime.Core.Abstraction/Models/IItemFilter.cs b/src/Core/FileTime.Core.Abstraction/Models/IItemFilter.cs new file mode 100644 index 0000000..f9a0b18 --- /dev/null +++ b/src/Core/FileTime.Core.Abstraction/Models/IItemFilter.cs @@ -0,0 +1,6 @@ +namespace FileTime.Core.Models; + +public record ItemFilter( + string Name, + Func Filter +); \ No newline at end of file diff --git a/src/Core/FileTime.Core.Abstraction/Models/ItemsTransformator.cs b/src/Core/FileTime.Core.Abstraction/Models/ItemsTransformator.cs deleted file mode 100644 index 7213d21..0000000 --- a/src/Core/FileTime.Core.Abstraction/Models/ItemsTransformator.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace FileTime.Core.Models; - -public record ItemsTransformator( - string Name, - Func, Task>> Transformator -); \ No newline at end of file diff --git a/src/Core/FileTime.Core.Abstraction/Services/ITab.cs b/src/Core/FileTime.Core.Abstraction/Services/ITab.cs index 6733f3f..9d6d6d3 100644 --- a/src/Core/FileTime.Core.Abstraction/Services/ITab.cs +++ b/src/Core/FileTime.Core.Abstraction/Services/ITab.cs @@ -11,8 +11,8 @@ public interface ITab : IInitable IObservable>?> CurrentItems { get; } void SetCurrentLocation(IContainer newLocation); - void AddSelectedItemsTransformator(ItemsTransformator transformator); - void RemoveSelectedItemsTransformator(ItemsTransformator transformator); - void RemoveSelectedItemsTransformatorByName(string name); + void AddItemFilter(ItemFilter filter); + void RemoveItemFilter(ItemFilter filter); + void RemoveItemFilter(string name); void SetSelectedItem(IAbsolutePath newSelectedItem); } \ No newline at end of file diff --git a/src/Core/FileTime.Core.Services/Tab.cs b/src/Core/FileTime.Core.Services/Tab.cs index 4063dd6..612eca1 100644 --- a/src/Core/FileTime.Core.Services/Tab.cs +++ b/src/Core/FileTime.Core.Services/Tab.cs @@ -1,6 +1,7 @@ using System.Reactive.Linq; using System.Reactive.Subjects; using DynamicData; +using DynamicData.Alias; using FileTime.Core.Models; namespace FileTime.Core.Services; @@ -9,7 +10,7 @@ public class Tab : ITab { private readonly BehaviorSubject _currentLocation = new(null); private readonly BehaviorSubject _currentSelectedItem = new(null); - private readonly List _transformators = new(); + private readonly SourceList _itemFilters = new(); private IAbsolutePath? _currentSelectedItemCached; public IObservable CurrentLocation { get; } @@ -21,16 +22,19 @@ public class Tab : ITab CurrentLocation = _currentLocation.DistinctUntilChanged().Publish(null).RefCount(); CurrentItems = Observable.Merge( - CurrentLocation - .Where(c => c is not null) - .Select(c => c!.Items) - .Switch() - .Select(items => items?.TransformAsync(MapItem)), + Observable.CombineLatest( + CurrentLocation + .Where(c => c is not null) + .Select(c => c!.Items) + .Switch() + .Select(items => items?.TransformAsync(MapItem)), + _itemFilters.Connect().StartWithEmpty().ToCollection(), + (items, filters) => items?.Where(i => filters.All(f => f.Filter(i)))), CurrentLocation .Where(c => c is null) - .Select(_ => (IObservable>?)null) + .Select(_ => (IObservable>?) null) ) - .Publish((IObservable>?)null) + .Publish((IObservable>?) null) .RefCount(); CurrentSelectedItem = @@ -79,9 +83,14 @@ public class Tab : ITab public void SetSelectedItem(IAbsolutePath newSelectedItem) => _currentSelectedItem.OnNext(newSelectedItem); - public void AddSelectedItemsTransformator(ItemsTransformator transformator) => _transformators.Add(transformator); - public void RemoveSelectedItemsTransformator(ItemsTransformator transformator) => _transformators.Remove(transformator); - public void RemoveSelectedItemsTransformatorByName(string name) => _transformators.RemoveAll(t => t.Name == name); + public void AddItemFilter(ItemFilter filter) => _itemFilters.Add(filter); + public void RemoveItemFilter(ItemFilter filter) => _itemFilters.Remove(filter); + + public void RemoveItemFilter(string name) + { + var itemsToRemove = _itemFilters.Items.Where(t => t.Name == name).ToList(); + _itemFilters.RemoveMany(itemsToRemove); + } public async Task OpenSelected() { diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp.App/Startup.cs b/src/GuiApp/Avalonia/FileTime.GuiApp.App/Startup.cs index f815899..e575363 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp.App/Startup.cs +++ b/src/GuiApp/Avalonia/FileTime.GuiApp.App/Startup.cs @@ -30,7 +30,8 @@ public static class Startup .AddSingleton() .AddSingleton() .AddSingleton() - .AddSingleton(); + .AddSingleton() + .AddSingleton(); } internal static IServiceCollection RegisterLogging(this IServiceCollection serviceCollection) diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/Services/KeyInputHandlerService.cs b/src/GuiApp/Avalonia/FileTime.GuiApp/Services/KeyInputHandlerService.cs index 3250918..7fdb666 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp/Services/KeyInputHandlerService.cs +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/Services/KeyInputHandlerService.cs @@ -11,6 +11,7 @@ public class KeyInputHandlerService : IKeyInputHandlerService private readonly IGuiAppState _appState; private readonly IDefaultModeKeyInputHandler _defaultModeKeyInputHandler; private readonly IRapidTravelModeKeyInputHandler _rapidTravelModeKeyInputHandler; + private ViewMode _viewMode; public KeyInputHandlerService( IGuiAppState appState, @@ -21,16 +22,18 @@ public class KeyInputHandlerService : IKeyInputHandlerService _appState = appState; _defaultModeKeyInputHandler = defaultModeKeyInputHandler; _rapidTravelModeKeyInputHandler = rapidTravelModeKeyInputHandler; + + appState.ViewMode.Subscribe(v => _viewMode = v); } public async Task ProcessKeyDown(Key key, KeyModifiers keyModifiers, Action setHandled) { - if (key == Key.LeftAlt - || key == Key.RightAlt - || key == Key.LeftShift - || key == Key.RightShift - || key == Key.LeftCtrl - || key == Key.RightCtrl) + if (key is Key.LeftAlt + or Key.RightAlt + or Key.LeftShift + or Key.RightShift + or Key.LeftCtrl + or Key.RightCtrl) { return; } @@ -43,7 +46,7 @@ public class KeyInputHandlerService : IKeyInputHandlerService var specialKeyStatus = new SpecialKeysStatus(isAltPressed, isShiftPressed, isCtrlPressed); - if (_appState.ViewMode == ViewMode.Default) + if (_viewMode == ViewMode.Default) { await _defaultModeKeyInputHandler.HandleInputKey(key, specialKeyStatus, setHandled); } diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/Services/KeyboardConfigurationService.cs b/src/GuiApp/Avalonia/FileTime.GuiApp/Services/KeyboardConfigurationService.cs index d5238a5..3ba414b 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp/Services/KeyboardConfigurationService.cs +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/Services/KeyboardConfigurationService.cs @@ -49,12 +49,6 @@ public class KeyboardConfigurationService : IKeyboardConfigurationService private static bool IsUniversal(CommandBindingConfiguration keyMapping) { - return keyMapping.Command == Commands.GoUp - || keyMapping.Command == Commands.Open - || keyMapping.Command == Commands.OpenOrRun - || keyMapping.Command == Commands.MoveCursorUp - || keyMapping.Command == Commands.MoveCursorDown - || keyMapping.Command == Commands.MoveCursorUpPage - || keyMapping.Command == Commands.MoveCursorDownPage; + return keyMapping.Command is Commands.GoUp or Commands.Open or Commands.OpenOrRun or Commands.MoveCursorUp or Commands.MoveCursorDown or Commands.MoveCursorUpPage or Commands.MoveCursorDownPage; } } \ No newline at end of file diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/Services/ModalService.cs b/src/GuiApp/Avalonia/FileTime.GuiApp/Services/ModalService.cs new file mode 100644 index 0000000..7d27802 --- /dev/null +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/Services/ModalService.cs @@ -0,0 +1,20 @@ +using DynamicData; +using FileTime.App.Core.Services; +using FileTime.App.Core.ViewModels; + +namespace FileTime.GuiApp.Services; + +public class ModalService : IModalService +{ + private readonly SourceList _openModals = new(); + public IObservable> OpenModals { get; } + + public ModalService() + { + OpenModals = _openModals.Connect(); + } + + public void OpenModal(IModalViewModelBase modalToOpen) => _openModals.Add(modalToOpen); + + public void CloseModal(IModalViewModelBase modalToClose) => _openModals.Remove(modalToClose); +} \ No newline at end of file diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/Services/RapidTravelModeKeyInputHandler.cs b/src/GuiApp/Avalonia/FileTime.GuiApp/Services/RapidTravelModeKeyInputHandler.cs index 7848e95..94051f6 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp/Services/RapidTravelModeKeyInputHandler.cs +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/Services/RapidTravelModeKeyInputHandler.cs @@ -1,29 +1,62 @@ using Avalonia.Input; +using FileTime.App.Core.Command; +using FileTime.App.Core.Models; +using FileTime.App.Core.Models.Enums; +using FileTime.App.Core.Services; +using FileTime.App.Core.ViewModels; +using FileTime.Core.Models; +using FileTime.Core.Services; +using FileTime.GuiApp.Configuration; +using FileTime.GuiApp.Extensions; using FileTime.GuiApp.Models; +using Microsoft.Extensions.Logging; namespace FileTime.GuiApp.Services; public class RapidTravelModeKeyInputHandler : IRapidTravelModeKeyInputHandler { + private const string RAPIDTRAVELFILTERNAME = "rapid_travel_filter"; + private readonly IAppState _appState; + private readonly IModalService _modalService; + private readonly IKeyboardConfigurationService _keyboardConfigurationService; + private readonly ICommandHandlerService _commandHandlerService; + private readonly ILogger _logger; + private readonly BindedCollection _openModals; + private ITabViewModel? _selectedTab; + + public RapidTravelModeKeyInputHandler( + IAppState appState, + IModalService modalService, + IKeyboardConfigurationService keyboardConfigurationService, + ICommandHandlerService commandHandlerService, + ILogger logger) + { + _appState = appState; + _modalService = modalService; + _keyboardConfigurationService = keyboardConfigurationService; + _commandHandlerService = commandHandlerService; + _logger = logger; + + _appState.SelectedTab.Subscribe(t => _selectedTab = t); + + _openModals = new BindedCollection(modalService.OpenModals); + } + public async Task HandleInputKey(Key key, SpecialKeysStatus specialKeysStatus, Action setHandled) { - /*var keyString = key.ToString(); + var keyString = key.ToString(); var updateRapidTravelFilter = false; if (key == Key.Escape) { setHandled(true); - if (_appState.IsAllShortcutVisible) + if ((_openModals.Collection?.Count ?? 0) > 0) { - _appState.IsAllShortcutVisible = false; - } - else if (_appState.MessageBoxText != null) - { - _appState.MessageBoxText = null; + _modalService.CloseModal(_openModals.Collection!.Last()); } else { - await _appState.ExitRapidTravelMode(); + _appState.SwitchViewMode(ViewMode.Default); } } else if (key == Key.Back) @@ -43,8 +76,8 @@ public class RapidTravelModeKeyInputHandler : IRapidTravelModeKeyInputHandler } else { - var currentKeyAsList = new List() { new KeyConfig(key) }; - var selectedCommandBinding = _keyboardConfigurationService.UniversalCommandBindings.FirstOrDefault(c => AreKeysEqual(c.Keys, currentKeyAsList)); + var currentKeyAsList = new List() {new KeyConfig(key)}; + var selectedCommandBinding = _keyboardConfigurationService.UniversalCommandBindings.FirstOrDefault(c => c.Keys.AreKeysEqual(currentKeyAsList)); if (selectedCommandBinding != null) { setHandled(true); @@ -54,16 +87,20 @@ public class RapidTravelModeKeyInputHandler : IRapidTravelModeKeyInputHandler if (updateRapidTravelFilter) { - var currentLocation = await _appState.SelectedTab.CurrentLocation.Container.WithoutVirtualContainer(MainPageViewModel.RAPIDTRAVEL); + if (_selectedTab?.Tab is not ITab tab) return; + + tab.RemoveItemFilter(RAPIDTRAVELFILTERNAME); + tab.AddItemFilter(new ItemFilter(RAPIDTRAVELFILTERNAME, i => i.Name.ToLower().Contains(_appState.RapidTravelText))); + /*var currentLocation = await _appState.SelectedTab.CurrentLocation.Container.WithoutVirtualContainer(MainPageViewModel.RAPIDTRAVEL); var newLocation = new VirtualContainer( currentLocation, new List, IEnumerable>>() { - container => container.Where(c => c.Name.ToLower().Contains(_appState.RapidTravelText)) + container => container.Where(c => c.Name.ToLower().Contains(_appState.RapidTravelText)) }, new List, IEnumerable>>() { - element => element.Where(e => e.Name.ToLower().Contains(_appState.RapidTravelText)) + element => element.Where(e => e.Name.ToLower().Contains(_appState.RapidTravelText)) }, virtualContainerName: MainPageViewModel.RAPIDTRAVEL ); @@ -81,7 +118,19 @@ public class RapidTravelModeKeyInputHandler : IRapidTravelModeKeyInputHandler else if (!currentLocationItems.Select(i => i.Item.Name).Any(n => n == selectedItemName)) { await _appState.SelectedTab.MoveCursorToFirst(); - } - }*/ + }*/ + } + } + + private async Task CallCommandAsync(Commands command) + { + try + { + await _commandHandlerService.HandleCommandAsync(command); + } + catch (Exception e) + { + _logger.LogError(e, "Unknown error while running command. {Command} {Error}", command, e); + } } } \ No newline at end of file diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/Views/MainWindow.axaml b/src/GuiApp/Avalonia/FileTime.GuiApp/Views/MainWindow.axaml index 41e5103..09216fc 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp/Views/MainWindow.axaml +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/Views/MainWindow.axaml @@ -236,6 +236,35 @@ + + + + + + + + + + + + + + + + + +