95 lines
3.7 KiB
C#
95 lines
3.7 KiB
C#
using System.Collections.ObjectModel;
|
|
using System.Reactive.Linq;
|
|
using System.Reactive.Subjects;
|
|
using DeclarativeProperty;
|
|
using FileTime.App.Core.Configuration;
|
|
using FileTime.App.Core.Models.Enums;
|
|
using FileTime.Core.Models.Extensions;
|
|
using MoreLinq;
|
|
using PropertyChanged.SourceGenerator;
|
|
|
|
namespace FileTime.App.Core.ViewModels;
|
|
|
|
public abstract partial class AppStateBase : IAppState
|
|
{
|
|
private readonly BehaviorSubject<string?> _searchText = new(null);
|
|
private readonly DeclarativeProperty<ITabViewModel?> _selectedTab = new(null);
|
|
private readonly DeclarativeProperty<ViewMode> _viewMode = new(Models.Enums.ViewMode.Default);
|
|
private readonly ObservableCollection<ITabViewModel> _tabs = new();
|
|
private readonly DeclarativeProperty<string?> _rapidTravelText;
|
|
|
|
public IDeclarativeProperty<ViewMode> ViewMode { get; }
|
|
|
|
public ReadOnlyObservableCollection<ITabViewModel> Tabs { get; }
|
|
public IObservable<string?> SearchText { get; }
|
|
|
|
public IDeclarativeProperty<ITabViewModel?> SelectedTab { get; }
|
|
public IDeclarativeProperty<string?> RapidTravelText { get; }
|
|
public IDeclarativeProperty<string?> RapidTravelTextDebounced { get; }
|
|
|
|
public IDeclarativeProperty<string?> ContainerStatus { get; }
|
|
[Notify] public List<KeyConfig> PreviousKeys { get; } = new();
|
|
[Notify] public bool NoCommandFound { get; set; }
|
|
|
|
protected AppStateBase()
|
|
{
|
|
_rapidTravelText = new ("");
|
|
RapidTravelText = _rapidTravelText.DistinctUntilChanged();
|
|
RapidTravelTextDebounced = RapidTravelText
|
|
.Debounce(v =>
|
|
string.IsNullOrEmpty(v)
|
|
? TimeSpan.Zero
|
|
: TimeSpan.FromMilliseconds(200)
|
|
, resetTimer: true
|
|
);
|
|
|
|
ViewMode = _viewMode;
|
|
|
|
SearchText = _searchText.AsObservable();
|
|
SelectedTab = DeclarativePropertyHelpers.CombineLatest<ObservableCollection<ITabViewModel>, ITabViewModel, ITabViewModel>(
|
|
_tabs.Watch()!,
|
|
_selectedTab!,
|
|
(tabs, selectedTab) => Task.FromResult(GetSelectedTab(tabs, selectedTab)!)
|
|
)!;
|
|
|
|
Tabs = new ReadOnlyObservableCollection<ITabViewModel>(_tabs);
|
|
|
|
ContainerStatus = SelectedTab
|
|
.Map(t => t?.CurrentLocation)
|
|
.Switch()
|
|
.Map(c => c?.GetExtension<StatusProviderContainerExtension>()?.GetStatusProperty())
|
|
.Switch()!;
|
|
}
|
|
|
|
public void AddTab(ITabViewModel tabViewModel)
|
|
{
|
|
if (_tabs.Any(t => t.TabNumber == tabViewModel.TabNumber))
|
|
throw new ArgumentException($"There is a tab with the same tab number {tabViewModel.TabNumber}.", nameof(tabViewModel));
|
|
|
|
var index = _tabs.Count(t => t.TabNumber < tabViewModel.TabNumber);
|
|
_tabs.Insert(index, tabViewModel);
|
|
}
|
|
|
|
public void RemoveTab(ITabViewModel tabViewModel)
|
|
{
|
|
if (!_tabs.Contains(tabViewModel)) return;
|
|
|
|
_tabs.Remove(tabViewModel);
|
|
}
|
|
|
|
public void SetSearchText(string? searchText) => _searchText.OnNext(searchText);
|
|
|
|
public async Task SwitchViewModeAsync(ViewMode newViewMode) => await _viewMode.SetValue(newViewMode);
|
|
|
|
public async Task SetSelectedTabAsync(ITabViewModel tabToSelect) => await _selectedTab.SetValue(tabToSelect);
|
|
public async Task SetRapidTravelTextAsync(string? text) => await _rapidTravelText.SetValue(text);
|
|
|
|
private ITabViewModel? GetSelectedTab(IEnumerable<ITabViewModel> tabs, ITabViewModel? expectedSelectedTab)
|
|
{
|
|
var (preferred, others) =
|
|
tabs
|
|
.OrderBy(t => t.TabNumber)
|
|
.Partition(t => t.TabNumber >= (expectedSelectedTab?.TabNumber ?? 0));
|
|
return preferred.Concat(others.Reverse()).FirstOrDefault();
|
|
}
|
|
} |