using System.ComponentModel; using System.Reactive.Linq; using DeclarativeProperty; using DynamicData; using FileTime.App.Core.Models.Enums; using FileTime.App.Core.Services; using FileTime.Core.Behaviors; using FileTime.Core.Helper; using FileTime.Core.Models; using MoreLinq; using MvvmGen; namespace FileTime.App.Core.ViewModels; [ViewModel] [Inject(typeof(IAppState), "_appState")] [Inject(typeof(IItemNameConverterService), "_itemNameConverterService")] public abstract partial class ItemViewModel : IItemViewModel { private ITabViewModel? _parentTab; [Property] private IItem? _baseItem; [Property] private string? _displayNameText; [Property] private IDeclarativeProperty _isSelected; [Property] private IObservable? _isMarked; [Property] private IObservable _viewMode; [Property] private DateTime? _createdAt; [Property] private string? _attributes; [Property] private IDeclarativeProperty _isAlternative; public IDeclarativeProperty>? DisplayName { get; private set; } public void Init( IItem item, ITabViewModel parentTab, ItemViewModelType itemViewModelType) { _parentTab = parentTab; var sourceCollection = itemViewModelType switch { ItemViewModelType.Main => parentTab.CurrentItems, ItemViewModelType.Parent => parentTab.ParentsChildren, ItemViewModelType.SelectedChild => parentTab.SelectedsChildren, _ => throw new InvalidEnumArgumentException() }; var displayName = itemViewModelType switch { ItemViewModelType.Main => _appState.RapidTravelText.Map(async (s, _) => _appState.ViewMode.Value != Models.Enums.ViewMode.RapidTravel && _appState.CurrentSelectedTab?.CurrentLocation.Value?.Provider is IItemNameConverterProvider nameConverterProvider ? (IReadOnlyList) await nameConverterProvider.GetItemNamePartsAsync(item) : _itemNameConverterService.GetDisplayName(item.DisplayName, s) ), _ => new DeclarativeProperty>(new List {new(item.DisplayName)}), }; BaseItem = item; DisplayName = displayName; DisplayNameText = item.DisplayName; IsMarked = itemViewModelType is ItemViewModelType.Main ? parentTab.MarkedItems.ToCollection().Select(m => m.Any(i => i.Path == item.FullName?.Path)) : Observable.Return(false); IsSelected = itemViewModelType is ItemViewModelType.Main ? parentTab.CurrentSelectedItem.Map(EqualsTo) : new DeclarativeProperty(IsInDeepestPath()); IsAlternative = sourceCollection.Map(c => c?.Index().FirstOrDefault(i => EqualsTo(i.Value)).Key % 2 == 0); ViewMode = Observable.CombineLatest(IsMarked, IsSelected, IsAlternative, GenerateViewMode).Throttle(TimeSpan.FromMilliseconds(10)); Attributes = item.Attributes; CreatedAt = item.CreatedAt; } private ItemViewMode GenerateViewMode(bool isMarked, bool isSelected, bool isAlternative) => (isMarked, isSelected, isAlternative) switch { (true, true, _) => ItemViewMode.MarkedSelected, (true, false, true) => ItemViewMode.MarkedAlternative, (false, true, _) => ItemViewMode.Selected, (false, false, true) => ItemViewMode.Alternative, (true, false, false) => ItemViewMode.Marked, _ => ItemViewMode.Default }; public bool EqualsTo(IItemViewModel? itemViewModel) { return BaseItem?.FullName?.Path is string path && path == itemViewModel?.BaseItem?.FullName?.Path; } private bool IsInDeepestPath() { if (_parentTab?.Tab?.LastDeepestSelectedPath is null || BaseItem?.FullName is null) { return false; } var ownFullName = BaseItem.FullName; var deepestPath = _parentTab.Tab.LastDeepestSelectedPath; var commonPath = FullName.CreateSafe(PathHelper.GetCommonPath(ownFullName.Path, deepestPath.Path)); return commonPath is not null && commonPath.Path == ownFullName.Path; } }