Enter/Exit folder

This commit is contained in:
2022-04-11 22:09:32 +02:00
parent b6b8a7b3f8
commit 6245744612
56 changed files with 835 additions and 152 deletions

View File

@@ -0,0 +1,8 @@
namespace FileTime.App.Core.Models.Enums
{
public enum ViewMode
{
Default,
RapidTravel
}
}

View File

@@ -0,0 +1,9 @@
using FileTime.App.Core.Command;
namespace FileTime.App.Core.Services
{
public interface ICommandHandlerService
{
Task HandleCommandAsync(Commands command);
}
}

View File

@@ -1,14 +1,14 @@
using System.Collections.ObjectModel;
using FileTime.App.Core.ViewModels;
using FileTime.App.Core.Models.Enums;
namespace FileTime.App.Core
namespace FileTime.App.Core.ViewModels
{
public interface IAppState
{
ObservableCollection<ITabViewModel> Tabs { get; }
ITabViewModel? SelectedTab { get; }
IObservable<ITabViewModel?> SelectedTabObservable { get; }
IObservable<ITabViewModel?> SelectedTab { get; }
IObservable<string?> SearchText { get; }
ViewMode ViewMode { get; }
void AddTab(ITabViewModel tabViewModel);
void RemoveTab(ITabViewModel tabViewModel);

View File

@@ -5,5 +5,6 @@ namespace FileTime.App.Core.ViewModels
{
public interface IContainerViewModel : IItemViewModel, IInitable<IContainer, ITabViewModel, int>
{
IContainer? Container { get; }
}
}

View File

@@ -12,7 +12,7 @@ namespace FileTime.App.Core.ViewModels
IObservable<bool> IsSelected { get; }
IObservable<IContainer?>? CurrentLocation { get; }
IObservable<IItemViewModel?>? CurrentSelectedItem { get; }
IObservable<IReadOnlyList<IItemViewModel>>? CurrentItems { get; }
IObservable<IReadOnlyList<FullName>> MarkedItems { get; }
IObservable<IEnumerable<IItemViewModel>>? CurrentItems { get; }
IObservable<IEnumerable<FullName>> MarkedItems { get; }
}
}

View File

@@ -1,70 +0,0 @@
using System.Collections.ObjectModel;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using FileTime.App.Core.ViewModels;
using MvvmGen;
namespace FileTime.App.Core
{
[ViewModel]
public abstract partial class AppStateBase : IAppState
{
private readonly BehaviorSubject<string?> _searchText = new(null);
private readonly BehaviorSubject<ITabViewModel?> _selectedTabObservable = new(null);
private ITabViewModel? _selectedTab;
public ObservableCollection<ITabViewModel> Tabs { get; } = new();
public IObservable<string?> SearchText { get; private set; }
public IObservable<ITabViewModel?> SelectedTabObservable { get; private set; }
public ITabViewModel? SelectedTab
{
get => _selectedTab;
private set
{
if (value != _selectedTab)
{
_selectedTab = value;
OnPropertyChanged(nameof(SelectedTab));
_selectedTabObservable.OnNext(value);
}
}
}
partial void OnInitialize()
{
SearchText = _searchText.AsObservable();
SelectedTabObservable = _selectedTabObservable.AsObservable();
}
public void AddTab(ITabViewModel tabViewModel)
{
Tabs.Add(tabViewModel);
if (_selectedTab == null)
{
SelectedTab = Tabs.First();
}
}
public void RemoveTab(ITabViewModel tabViewModel)
{
if (!Tabs.Contains(tabViewModel)) return;
Tabs.Remove(tabViewModel);
if (_selectedTab == tabViewModel)
{
SelectedTab = Tabs.FirstOrDefault();
}
}
public void SetSearchText(string? searchText)
{
_searchText.OnNext(searchText);
}
public void SetSelectedTab(ITabViewModel tabToSelect)
{
SelectedTab = tabToSelect;
}
}
}

View File

@@ -7,6 +7,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="morelinq" Version="3.3.2" />
<PackageReference Include="MvvmGen" Version="1.1.5" />
<PackageReference Include="System.Reactive" Version="5.0.0" />
</ItemGroup>

View File

@@ -0,0 +1,104 @@
using System.Reactive.Linq;
using FileTime.App.Core.Command;
using FileTime.App.Core.ViewModels;
using FileTime.Core.Models;
namespace FileTime.App.Core.Services
{
public class CommandHandlerService : ICommandHandlerService
{
private readonly Dictionary<Commands, Func<Task>> _commandHandlers;
private readonly IAppState _appState;
private ITabViewModel? _selectedTab;
private IContainer? _currentLocation;
private IItemViewModel? _currentSelectedItem;
public CommandHandlerService(IAppState appState)
{
_appState = appState;
_appState.SelectedTab.Subscribe(t => _selectedTab = t);
_appState.SelectedTab.Select(t => t == null ? Observable.Return<IContainer?>(null) : t.CurrentLocation!).Switch().Subscribe(l => _currentLocation = l);
_appState.SelectedTab.Select(t => t == null ? Observable.Return<IItemViewModel?>(null) : t.CurrentSelectedItem!).Switch().Subscribe(l => _currentSelectedItem = l);
_commandHandlers = new Dictionary<Commands, Func<Task>>
{
//{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.ResolveAsync() is not IContainer newContainer) return;
_selectedTab?.Tab?.SetCurrentLocation(newContainer);
}
}
}

View File

@@ -0,0 +1,55 @@
using System.Collections.ObjectModel;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using FileTime.App.Core.Models.Enums;
using FileTime.App.Core.ViewModels;
using MvvmGen;
using MoreLinq;
namespace FileTime.App.Core.ViewModels
{
[ViewModel]
public abstract partial class AppStateBase : IAppState
{
private readonly BehaviorSubject<string?> _searchText = new(null);
private readonly BehaviorSubject<ITabViewModel?> _selectedTab = new(null);
private readonly BehaviorSubject<IEnumerable<ITabViewModel>> _tabs = new(Enumerable.Empty<ITabViewModel>());
[Property]
private ViewMode _viewMode;
public ObservableCollection<ITabViewModel> Tabs { get; } = new();
public IObservable<string?> SearchText { get; private set; }
public IObservable<ITabViewModel?> SelectedTab { get; private set; }
partial void OnInitialize()
{
Tabs.CollectionChanged += (_, _) => _tabs.OnNext(Tabs);
SearchText = _searchText.AsObservable();
SelectedTab = Observable.CombineLatest(_tabs, _selectedTab, GetSelectedTab);
}
public void AddTab(ITabViewModel tabViewModel)
{
Tabs.Add(tabViewModel);
}
public void RemoveTab(ITabViewModel tabViewModel)
{
if (!Tabs.Contains(tabViewModel)) return;
Tabs.Remove(tabViewModel);
}
public void SetSearchText(string? searchText) => _searchText.OnNext(searchText);
public void SetSelectedTab(ITabViewModel tabToSelect) => _selectedTab.OnNext(tabToSelect);
private ITabViewModel? GetSelectedTab(IEnumerable<ITabViewModel> tabs, ITabViewModel? expectedSelectedTab)
{
var (prefered, others) = tabs.OrderBy(t => t.TabNumber).Partition(t => t.TabNumber >= (expectedSelectedTab?.TabNumber ?? 0));
return prefered.Concat(others).FirstOrDefault();
}
}
}

View File

@@ -7,6 +7,8 @@ namespace FileTime.App.Core.ViewModels
[ViewModel(GenerateConstructor = false)]
public partial class ContainerViewModel : ItemViewModel, IContainerViewModel
{
public IContainer? Container => BaseItem as IContainer;
public ContainerViewModel(IItemNameConverterService _itemNameConverterService, IAppState _appState) : base(_itemNameConverterService, _appState)
{
}

View File

@@ -24,8 +24,8 @@ namespace FileTime.App.Core.ViewModels
public IObservable<IContainer?>? CurrentLocation { get; private set; }
public IObservable<IItemViewModel?>? CurrentSelectedItem { get; private set; }
public IObservable<IReadOnlyList<IItemViewModel>>? CurrentItems { get; private set; }
public IObservable<IReadOnlyList<FullName>> MarkedItems { get; }
public IObservable<IEnumerable<IItemViewModel>>? CurrentItems { get; private set; }
public IObservable<IEnumerable<FullName>> MarkedItems { get; }
public TabViewModel(
IServiceProvider serviceProvider,
@@ -37,7 +37,7 @@ namespace FileTime.App.Core.ViewModels
_appState = appState;
MarkedItems = _markedItems.Select(e => e.ToList()).AsObservable();
IsSelected = _appState.SelectedTabObservable.Select(s => s == this);
IsSelected = _appState.SelectedTab.Select(s => s == this);
}
public void Init(ITab tab, int tabNumber)
@@ -46,11 +46,15 @@ namespace FileTime.App.Core.ViewModels
TabNumber = tabNumber;
CurrentLocation = tab.CurrentLocation.AsObservable();
CurrentItems = tab.CurrentItems.Select(items => items.Select(MapItemToViewModel).ToList());
CurrentSelectedItem = Observable.CombineLatest(
CurrentItems,
tab.CurrentSelectedItem,
(currentItems, currentSelectedItemPath) => currentItems.FirstOrDefault(i => i.BaseItem?.FullName == currentSelectedItemPath?.Path));
CurrentItems = tab.CurrentItems.Select(items => items.Select(MapItemToViewModel).ToList()).Publish(Enumerable.Empty<IItemViewModel>()).RefCount();
CurrentSelectedItem =
Observable.CombineLatest(
CurrentItems,
tab.CurrentSelectedItem,
(currentItems, currentSelectedItemPath) => currentItems.FirstOrDefault(i => i.BaseItem?.FullName == currentSelectedItemPath?.Path)
)
.Publish(null)
.RefCount();
tab.CurrentLocation.Subscribe((_) => _markedItems.OnNext(Enumerable.Empty<FullName>()));
}