Files
FileTime2/src/AppCommon/FileTime.App.Core/Services/UserCommandHandler/NavigationUserCommandHandlerService.cs

165 lines
5.8 KiB
C#

using FileTime.App.Core.Extensions;
using FileTime.App.Core.Models.Enums;
using FileTime.App.Core.UserCommand;
using FileTime.App.Core.ViewModels;
using FileTime.Core.Models;
using FileTime.Core.Services;
using FileTime.Core.Timeline;
using FileTime.Providers.Local;
using Microsoft.Extensions.DependencyInjection;
namespace FileTime.App.Core.Services.UserCommandHandler;
public class NavigationUserCommandHandlerService : UserCommandHandlerServiceBase
{
private readonly IAppState _appState;
private readonly IServiceProvider _serviceProvider;
private readonly ILocalContentProvider _localContentProvider;
private readonly IUserCommandHandlerService _userCommandHandlerService;
private readonly ITimelessContentProvider _timelessContentProvider;
private ITabViewModel? _selectedTab;
private IContainer? _currentLocation;
private IItemViewModel? _currentSelectedItem;
private IEnumerable<IItemViewModel> _currentItems = Enumerable.Empty<IItemViewModel>();
private ViewMode _viewMode;
public NavigationUserCommandHandlerService(
IAppState appState,
IServiceProvider serviceProvider,
ILocalContentProvider localContentProvider,
IUserCommandHandlerService userCommandHandlerService,
ITimelessContentProvider timelessContentProvider) : base(appState)
{
_appState = appState;
_serviceProvider = serviceProvider;
_localContentProvider = localContentProvider;
_userCommandHandlerService = userCommandHandlerService;
_timelessContentProvider = timelessContentProvider;
SaveSelectedTab(t => _selectedTab = t);
SaveCurrentSelectedItem(i => _currentSelectedItem = i);
SaveCurrentLocation(l => _currentLocation = l);
SaveCurrentItems(i => _currentItems = i);
appState.ViewMode.Subscribe(v => _viewMode = v);
AddCommandHandlers(new IUserCommandHandler[]
{
new TypeUserCommandHandler<CloseTabCommand>(CloseTab),
new TypeUserCommandHandler<EnterRapidTravelCommand>(EnterRapidTravel),
new TypeUserCommandHandler<ExitRapidTravelCommand>(ExitRapidTravel),
new TypeUserCommandHandler<GoUpCommand>(GoUp),
new TypeUserCommandHandler<MoveCursorDownCommand>(MoveCursorDown),
new TypeUserCommandHandler<MoveCursorUpCommand>(MoveCursorUp),
new TypeUserCommandHandler<OpenContainerCommand>(OpenContainer),
new TypeUserCommandHandler<OpenSelectedCommand>(OpenSelected),
new TypeUserCommandHandler<SwitchToTabCommand>(SwitchToTab),
});
}
private async Task OpenContainer(OpenContainerCommand command)
{
var resolvedPath = await command.Path.ResolveAsync();
if (resolvedPath is not IContainer resolvedContainer) return;
_selectedTab?.Tab?.SetCurrentLocation(resolvedContainer);
}
private Task OpenSelected()
{
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 AbsolutePath parentPath ||
await parentPath.ResolveAsyncSafe() is not IContainer newContainer) return;
_selectedTab?.Tab?.SetCurrentLocation(newContainer);
}
private Task MoveCursorDown()
{
SelectNewSelectedItem(i => i.SkipWhile(i => !i.EqualsTo(_currentSelectedItem)).Skip(1).FirstOrDefault());
return Task.CompletedTask;
}
private Task MoveCursorUp()
{
SelectNewSelectedItem(i => i.TakeWhile(i => !i.EqualsTo(_currentSelectedItem)).LastOrDefault());
return Task.CompletedTask;
}
private void SelectNewSelectedItem(Func<IEnumerable<IItemViewModel>, IItemViewModel?> getNewSelected)
{
if (_selectedTab is null || _currentLocation is null) return;
var newSelectedItem = getNewSelected(_currentItems);
if (newSelectedItem == null) return;
_selectedTab.Tab?.SetSelectedItem(newSelectedItem.ToAbsolutePath(_timelessContentProvider));
}
private Task EnterRapidTravel()
{
_appState.SwitchViewMode(ViewMode.RapidTravel);
return Task.CompletedTask;
}
private Task ExitRapidTravel()
{
_appState.SwitchViewMode(ViewMode.Default);
return Task.CompletedTask;
}
private Task SwitchToTab(SwitchToTabCommand command)
{
var number = command.TabNumber;
var tabViewModel = _appState.Tabs.FirstOrDefault(t => t.TabNumber == number);
if (number == -1)
{
var greatestNumber = _appState.Tabs.Max(t => t.TabNumber);
tabViewModel = _appState.Tabs.FirstOrDefault(t => t.TabNumber == greatestNumber);
}
else if (tabViewModel == null)
{
var tab = _serviceProvider.GetInitableResolver<IContainer>(_currentLocation ?? _localContentProvider)
.GetRequiredService<ITab>();
var newTabViewModel = _serviceProvider.GetInitableResolver(tab, number).GetRequiredService<ITabViewModel>();
_appState.AddTab(newTabViewModel);
tabViewModel = newTabViewModel;
}
if (_viewMode == ViewMode.RapidTravel)
{
_userCommandHandlerService.HandleCommandAsync(ExitRapidTravelCommand.Instance);
}
_appState.SetSelectedTab(tabViewModel!);
return Task.CompletedTask;
}
private Task CloseTab()
{
if (_appState.Tabs.Count < 2 || _selectedTab == null) return Task.CompletedTask;
var tabToRemove = _selectedTab;
_appState.RemoveTab(tabToRemove!);
try
{
tabToRemove.Dispose();
}
catch
{
}
return Task.CompletedTask;
}
}