WIP: RapidTravel, ModalService
This commit is contained in:
@@ -11,6 +11,11 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MvvmGen" Version="1.1.5" />
|
||||
<PackageReference Include="PropertyChanged.SourceGenerator" Version="1.0.3">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Reactive" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using DynamicData;
|
||||
using PropertyChanged.SourceGenerator;
|
||||
|
||||
namespace FileTime.App.Core.Models;
|
||||
|
||||
public class BindedCollection<T> : IDisposable
|
||||
public partial class BindedCollection<T> : IDisposable, INotifyPropertyChanged
|
||||
{
|
||||
private readonly IDisposable _disposable;
|
||||
public ReadOnlyObservableCollection<T> Collection { get; }
|
||||
private IDisposable? _innerDisposable;
|
||||
|
||||
[Notify] private ReadOnlyObservableCollection<T>? _collection;
|
||||
|
||||
public BindedCollection(IObservable<IChangeSet<T>> dynamicList)
|
||||
{
|
||||
_disposable = dynamicList
|
||||
@@ -14,12 +19,34 @@ public class BindedCollection<T> : IDisposable
|
||||
.DisposeMany()
|
||||
.Subscribe();
|
||||
|
||||
Collection = collection;
|
||||
_collection = collection;
|
||||
}
|
||||
|
||||
public BindedCollection(IObservable<IObservable<IChangeSet<T>>?> 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using DynamicData;
|
||||
using FileTime.App.Core.ViewModels;
|
||||
|
||||
namespace FileTime.App.Core.Services;
|
||||
|
||||
public interface IModalService
|
||||
{
|
||||
IObservable<IChangeSet<IModalViewModelBase>> OpenModals { get; }
|
||||
|
||||
void OpenModal(IModalViewModelBase modalToOpen);
|
||||
void CloseModal(IModalViewModelBase modalToClose);
|
||||
}
|
||||
@@ -8,9 +8,11 @@ public interface IAppState
|
||||
ObservableCollection<ITabViewModel> Tabs { get; }
|
||||
IObservable<ITabViewModel?> SelectedTab { get; }
|
||||
IObservable<string?> SearchText { get; }
|
||||
ViewMode ViewMode { get; }
|
||||
IObservable<ViewMode> ViewMode { get; }
|
||||
string RapidTravelText { get; set; }
|
||||
|
||||
void AddTab(ITabViewModel tabViewModel);
|
||||
void RemoveTab(ITabViewModel tabViewModel);
|
||||
void SetSearchText(string? searchText);
|
||||
void SwitchViewMode(ViewMode newViewMode);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace FileTime.App.Core.ViewModels;
|
||||
|
||||
public interface IModalViewModelBase
|
||||
{
|
||||
string Name { get; }
|
||||
}
|
||||
@@ -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<IAbsolutePath>? _markedItems;
|
||||
private readonly BindedCollection<IAbsolutePath>? _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<IAbsolutePath>(t.MarkedItems);
|
||||
});
|
||||
SaveSelectedTab(t => _selectedTab = t);
|
||||
SaveCurrentSelectedItem(i => _currentSelectedItem = i);
|
||||
|
||||
_markedItems = new BindedCollection<IAbsolutePath>(appState.SelectedTab.Select(t => t?.MarkedItems));
|
||||
|
||||
AddCommandHandlers(new (Commands, Func<Task>)[]
|
||||
{
|
||||
(Commands.Copy, Copy),
|
||||
@@ -55,9 +52,9 @@ public class ItemManipulationCommandHandler : CommandHandlerBase
|
||||
_clipboardService.Clear();
|
||||
_clipboardService.SetCommand<CopyCommand>();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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<Task>)[]
|
||||
{
|
||||
(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;
|
||||
}
|
||||
}
|
||||
@@ -13,17 +13,21 @@ 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>());
|
||||
private readonly BehaviorSubject<ViewMode> _viewMode = new(Models.Enums.ViewMode.Default);
|
||||
|
||||
[Property]
|
||||
private ViewMode _viewMode;
|
||||
public IObservable<ViewMode> ViewMode { get; private set; }
|
||||
|
||||
public ObservableCollection<ITabViewModel> Tabs { get; } = new();
|
||||
public IObservable<string?> SearchText { get; private set; }
|
||||
|
||||
public IObservable<ITabViewModel?> 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<ITabViewModel> tabs, ITabViewModel? expectedSelectedTab)
|
||||
|
||||
@@ -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<IAbsolutePath> _markedItems = new();
|
||||
private readonly List<IDisposable> _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<IItemViewModel>(c!));
|
||||
});
|
||||
|
||||
ParentsChildren.Subscribe(children =>
|
||||
{
|
||||
ParentsChildrenCollection?.Dispose();
|
||||
ParentsChildrenCollection = children.MapNull(c => new BindedCollection<IItemViewModel>(c!));
|
||||
});
|
||||
|
||||
SelectedsChildren.Subscribe(children =>
|
||||
{
|
||||
SelectedsChildrenCollection?.Dispose();
|
||||
SelectedsChildrenCollection = children.MapNull(c => new BindedCollection<IItemViewModel>(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<IChangeSet<IItemViewModel>>?) 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user