Enter/Exit folder
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
55
src/AppCommon/FileTime.App.Core/ViewModels/AppStateBase.cs
Normal file
55
src/AppCommon/FileTime.App.Core/ViewModels/AppStateBase.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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>()));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user