From 7ff3898bd99eab7ab8ee21c15e3602d59fedc945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81d=C3=A1m=20Kov=C3=A1cs?= Date: Fri, 1 Apr 2022 21:46:55 +0200 Subject: [PATCH] Item Attributes --- .../IContainerSizeContainerViewModel.cs | 2 +- .../ViewModels/IContainerViewModel.cs | 1 - .../ViewModels/IElementViewModel.cs | 2 +- .../ViewModels/IFileViewModel.cs | 1 - .../ViewModels/IItemViewModel.cs | 8 +++-- .../ContainerSizeContainerViewModel.cs | 8 +++-- .../ViewModels/ElementViewModel.cs | 8 +++-- .../ViewModels/FileViewModel.cs | 1 - .../ViewModels/ItemViewModel.cs | 14 ++++++-- .../ViewModels/TabViewModel.cs | 36 +++++++++++++++---- .../Models/IFileElement.cs | 2 +- .../FileTime.Core.Abstraction/Models/IItem.cs | 2 ++ src/Core/FileTime.Core.Models/Container.cs | 6 ++-- src/Core/FileTime.Core.Models/Element.cs | 6 ++-- src/Core/FileTime.Core.Models/FileElement.cs | 34 ++++++++++++++++++ .../ContentProviderBase.cs | 4 +++ src/Core/FileTime.Core.Services/Tab.cs | 5 --- .../Converters/NamePartShrinkerConverter.cs | 2 +- .../FileTime.GuiApp/Views/ItemView.axaml | 24 ++++++++----- .../LocalContentProvider.DirectoryHelper.cs | 23 ++++++++++++ .../LocalContentProvider.FileHelper.cs | 23 ++++++++++++ .../LocalContentProvider.cs | 6 +++- 22 files changed, 178 insertions(+), 40 deletions(-) create mode 100644 src/Core/FileTime.Core.Models/FileElement.cs create mode 100644 src/Providers/FileTime.Providers.Local/LocalContentProvider.DirectoryHelper.cs create mode 100644 src/Providers/FileTime.Providers.Local/LocalContentProvider.FileHelper.cs diff --git a/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IContainerSizeContainerViewModel.cs b/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IContainerSizeContainerViewModel.cs index b405f2d..855ef19 100644 --- a/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IContainerSizeContainerViewModel.cs +++ b/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IContainerSizeContainerViewModel.cs @@ -2,6 +2,6 @@ namespace FileTime.App.Core.ViewModels { public interface IContainerSizeContainerViewModel : IItemViewModel { - + long Size { get; set; } } } \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IContainerViewModel.cs b/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IContainerViewModel.cs index 26bb120..b94577e 100644 --- a/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IContainerViewModel.cs +++ b/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IContainerViewModel.cs @@ -2,6 +2,5 @@ namespace FileTime.App.Core.ViewModels { public interface IContainerViewModel : IItemViewModel { - } } \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IElementViewModel.cs b/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IElementViewModel.cs index b3ea19a..d977515 100644 --- a/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IElementViewModel.cs +++ b/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IElementViewModel.cs @@ -2,6 +2,6 @@ namespace FileTime.App.Core.ViewModels { public interface IElementViewModel : IItemViewModel { - + long? Size { get; set; } } } \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IFileViewModel.cs b/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IFileViewModel.cs index d6bd017..98656b2 100644 --- a/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IFileViewModel.cs +++ b/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IFileViewModel.cs @@ -2,6 +2,5 @@ namespace FileTime.App.Core.ViewModels { public interface IFileViewModel : IElementViewModel { - } } \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IItemViewModel.cs b/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IItemViewModel.cs index f299ca5..86afcc8 100644 --- a/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IItemViewModel.cs +++ b/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/IItemViewModel.cs @@ -1,3 +1,4 @@ +using System.Reactive.Subjects; using FileTime.App.Core.Models; using FileTime.App.Core.Models.Enums; using FileTime.Core.Models; @@ -6,10 +7,13 @@ namespace FileTime.App.Core.ViewModels { public interface IItemViewModel { - IItem? Item { get; set; } + IItem? BaseItem { get; set; } IObservable>? DisplayName { get; set; } IObservable? IsSelected { get; set; } IObservable? IsMarked { get; set; } - ItemViewMode ViewMode { get; set; } + BehaviorSubject IsAlternative { get; } + IObservable ViewMode { get; set; } + DateTime? CreatedAt { get; set; } + string? Attributes { get; set; } } } \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core/ViewModels/ContainerSizeContainerViewModel.cs b/src/AppCommon/FileTime.App.Core/ViewModels/ContainerSizeContainerViewModel.cs index 24b22fa..527e6a5 100644 --- a/src/AppCommon/FileTime.App.Core/ViewModels/ContainerSizeContainerViewModel.cs +++ b/src/AppCommon/FileTime.App.Core/ViewModels/ContainerSizeContainerViewModel.cs @@ -1,7 +1,11 @@ +using MvvmGen; + namespace FileTime.App.Core.ViewModels { - public class ContainerSizeContainerViewModel : ItemViewModel, IContainerSizeContainerViewModel + [ViewModel] + public partial class ContainerSizeContainerViewModel : ItemViewModel, IContainerSizeContainerViewModel { - + [Property] + private long _size; } } \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core/ViewModels/ElementViewModel.cs b/src/AppCommon/FileTime.App.Core/ViewModels/ElementViewModel.cs index 5aa99f2..60dbfdb 100644 --- a/src/AppCommon/FileTime.App.Core/ViewModels/ElementViewModel.cs +++ b/src/AppCommon/FileTime.App.Core/ViewModels/ElementViewModel.cs @@ -1,7 +1,11 @@ +using MvvmGen; + namespace FileTime.App.Core.ViewModels { - public class ElementViewModel : ItemViewModel, IElementViewModel + [ViewModel] + public partial class ElementViewModel : ItemViewModel, IElementViewModel { - + [Property] + private long? _size; } } \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core/ViewModels/FileViewModel.cs b/src/AppCommon/FileTime.App.Core/ViewModels/FileViewModel.cs index 9cd8407..60e3197 100644 --- a/src/AppCommon/FileTime.App.Core/ViewModels/FileViewModel.cs +++ b/src/AppCommon/FileTime.App.Core/ViewModels/FileViewModel.cs @@ -2,6 +2,5 @@ namespace FileTime.App.Core.ViewModels { public class FileViewModel : ElementViewModel, IFileViewModel { - } } \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core/ViewModels/ItemViewModel.cs b/src/AppCommon/FileTime.App.Core/ViewModels/ItemViewModel.cs index 4b8f0c0..8751aeb 100644 --- a/src/AppCommon/FileTime.App.Core/ViewModels/ItemViewModel.cs +++ b/src/AppCommon/FileTime.App.Core/ViewModels/ItemViewModel.cs @@ -1,3 +1,4 @@ +using System.Reactive.Subjects; using FileTime.App.Core.Models; using FileTime.App.Core.Models.Enums; using FileTime.Core.Models; @@ -9,7 +10,7 @@ namespace FileTime.App.Core.ViewModels public abstract partial class ItemViewModel : IItemViewModel { [Property] - private IItem? _item; + private IItem? _baseItem; [Property] private IObservable>? _displayName; @@ -21,6 +22,15 @@ namespace FileTime.App.Core.ViewModels private IObservable? _isMarked; [Property] - private ItemViewMode _viewMode; + private IObservable _viewMode; + + [Property] + private DateTime? _createdAt; + + [Property] + private string? _attributes; + + [Property] + private BehaviorSubject _isAlternative = new(false); } } \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core/ViewModels/TabViewModel.cs b/src/AppCommon/FileTime.App.Core/ViewModels/TabViewModel.cs index cfe3911..164c0e9 100644 --- a/src/AppCommon/FileTime.App.Core/ViewModels/TabViewModel.cs +++ b/src/AppCommon/FileTime.App.Core/ViewModels/TabViewModel.cs @@ -1,5 +1,6 @@ using System.Reactive.Linq; using System.Reactive.Subjects; +using FileTime.App.Core.Models.Enums; using FileTime.App.Core.Services; using FileTime.Core.Models; using FileTime.Core.Services; @@ -39,15 +40,16 @@ namespace FileTime.App.Core.ViewModels { CurrentLocation = tab.CurrentLocation.AsObservable(); CurrentItems = tab.CurrentItems.Select(items => items.Select(MapItemToViewModel).ToList()); - CurrentSelectedItem = CurrentItems.CombineLatest( + CurrentSelectedItem = Observable.CombineLatest( + CurrentItems, tab.CurrentSelectedItem, - (currentItems, currentSelectedItemPath) => currentItems.FirstOrDefault(i => i.Item?.FullName == currentSelectedItemPath?.Path)); + (currentItems, currentSelectedItemPath) => currentItems.FirstOrDefault(i => i.BaseItem?.FullName == currentSelectedItemPath?.Path)); tab.CurrentLocation.Subscribe((_) => _markedItems.OnNext(Enumerable.Empty())); Tab = tab; } - private IItemViewModel MapItemToViewModel(IItem item) + private IItemViewModel MapItemToViewModel(IItem item, int index) { if (item is IContainer container) { @@ -56,6 +58,14 @@ namespace FileTime.App.Core.ViewModels return containerViewModel; } + else if (item is IFileElement fileElement) + { + var fileViewModel = _serviceProvider.GetRequiredService(); + InitIItemViewModel(fileViewModel, item); + fileViewModel.Size = fileElement.Size; + + return fileViewModel; + } else if (item is IElement element) { var elementViewModel = _serviceProvider.GetRequiredService(); @@ -68,17 +78,29 @@ namespace FileTime.App.Core.ViewModels void InitIItemViewModel(IItemViewModel itemViewModel, IItem item) { - itemViewModel.Item = item; + itemViewModel.BaseItem = item; itemViewModel.DisplayName = _appState.SearchText.Select(s => _itemNameConverterService.GetDisplayName(item.DisplayName, s)); itemViewModel.IsMarked = MarkedItems.Select(m => m.Contains(item.FullName)); itemViewModel.IsSelected = MarkedItems.Select(m => m.Contains(item.FullName)); + itemViewModel.IsAlternative.OnNext(index % 2 == 0); + itemViewModel.ViewMode = Observable.CombineLatest(itemViewModel.IsMarked, itemViewModel.IsSelected, itemViewModel.IsAlternative, GenerateViewMode); + itemViewModel.Attributes = item.Attributes; + itemViewModel.CreatedAt = item.CreatedAt; } } - ~TabViewModel() + private ItemViewMode GenerateViewMode(bool isMarked, bool isSelected, bool sAlternative) + => (isMarked, isSelected, sAlternative) switch { - Dispose(false); - } + (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 + }; + + ~TabViewModel() => Dispose(false); public void Dispose() { diff --git a/src/Core/FileTime.Core.Abstraction/Models/IFileElement.cs b/src/Core/FileTime.Core.Abstraction/Models/IFileElement.cs index 1c907bd..6dff1a6 100644 --- a/src/Core/FileTime.Core.Abstraction/Models/IFileElement.cs +++ b/src/Core/FileTime.Core.Abstraction/Models/IFileElement.cs @@ -2,6 +2,6 @@ namespace FileTime.Core.Models { public interface IFileElement : IElement { - + long Size { get; } } } \ No newline at end of file diff --git a/src/Core/FileTime.Core.Abstraction/Models/IItem.cs b/src/Core/FileTime.Core.Abstraction/Models/IItem.cs index 8a297cf..d224e01 100644 --- a/src/Core/FileTime.Core.Abstraction/Models/IItem.cs +++ b/src/Core/FileTime.Core.Abstraction/Models/IItem.cs @@ -12,8 +12,10 @@ namespace FileTime.Core.Models FullName? Parent { get; } bool IsHidden { get; } bool IsExists { get; } + DateTime? CreatedAt { get; } SupportsDelete CanDelete { get; } bool CanRename { get; } IContentProvider Provider { get; } + string? Attributes { get; } } } \ No newline at end of file diff --git a/src/Core/FileTime.Core.Models/Container.cs b/src/Core/FileTime.Core.Models/Container.cs index 712f838..7c80911 100644 --- a/src/Core/FileTime.Core.Models/Container.cs +++ b/src/Core/FileTime.Core.Models/Container.cs @@ -3,16 +3,18 @@ using FileTime.Core.Services; namespace FileTime.Core.Models { - public record Container - (string Name, + public record Container( + string Name, string DisplayName, FullName FullName, NativePath NativePath, FullName Parent, bool IsHidden, bool IsExists, + DateTime? CreatedAt, SupportsDelete CanDelete, bool CanRename, + string? Attributes, IContentProvider Provider, IReadOnlyList Items) : IContainer; } \ No newline at end of file diff --git a/src/Core/FileTime.Core.Models/Element.cs b/src/Core/FileTime.Core.Models/Element.cs index d509be5..d74adc5 100644 --- a/src/Core/FileTime.Core.Models/Element.cs +++ b/src/Core/FileTime.Core.Models/Element.cs @@ -3,15 +3,17 @@ using FileTime.Core.Services; namespace FileTime.Core.Models { - public record Element - (string Name, + public record Element( + string Name, string DisplayName, FullName FullName, NativePath NativePath, FullName Parent, bool IsHidden, bool IsExists, + DateTime? CreatedAt, SupportsDelete CanDelete, bool CanRename, + string? Attributes, IContentProvider Provider) : IElement; } \ No newline at end of file diff --git a/src/Core/FileTime.Core.Models/FileElement.cs b/src/Core/FileTime.Core.Models/FileElement.cs new file mode 100644 index 0000000..7de3d8c --- /dev/null +++ b/src/Core/FileTime.Core.Models/FileElement.cs @@ -0,0 +1,34 @@ +using FileTime.Core.Enums; +using FileTime.Core.Services; + +namespace FileTime.Core.Models +{ + public record FileElement( + string Name, + string DisplayName, + FullName FullName, + NativePath NativePath, + FullName Parent, + bool IsHidden, + bool IsExists, + DateTime? CreatedAt, + SupportsDelete CanDelete, + bool CanRename, + string? Attributes, + IContentProvider Provider, + long Size) + : Element( + Name, + DisplayName, + FullName, + NativePath, + Parent, + IsHidden, + IsExists, + CreatedAt, + CanDelete, + CanRename, + Attributes, + Provider + ), IFileElement; +} \ No newline at end of file diff --git a/src/Core/FileTime.Core.Services/ContentProviderBase.cs b/src/Core/FileTime.Core.Services/ContentProviderBase.cs index f110036..e89dabc 100644 --- a/src/Core/FileTime.Core.Services/ContentProviderBase.cs +++ b/src/Core/FileTime.Core.Services/ContentProviderBase.cs @@ -29,6 +29,10 @@ namespace FileTime.Core.Services public FullName? Parent => null; + public DateTime? CreatedAt => null; + + public string? Attributes => null; + protected ContentProviderBase(string name) { DisplayName = Name = name; diff --git a/src/Core/FileTime.Core.Services/Tab.cs b/src/Core/FileTime.Core.Services/Tab.cs index 7877f72..e16a610 100644 --- a/src/Core/FileTime.Core.Services/Tab.cs +++ b/src/Core/FileTime.Core.Services/Tab.cs @@ -40,11 +40,6 @@ namespace FileTime.Core.Services ) .Merge(Constants.MaximumObservableMergeOperations); CurrentSelectedItem = CurrentLocation.Select(GetSelectedItemByLocation).Merge(_currentSelectedItem).Throttle(TimeSpan.FromMilliseconds(500)); - - CurrentItems.Subscribe(c => - { - ; - }); } public void Init(IContainer currentLocation) diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/Converters/NamePartShrinkerConverter.cs b/src/GuiApp/Avalonia/FileTime.GuiApp/Converters/NamePartShrinkerConverter.cs index fb8d62c..596cb3c 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp/Converters/NamePartShrinkerConverter.cs +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/Converters/NamePartShrinkerConverter.cs @@ -79,7 +79,7 @@ namespace FileTime.GuiApp.Converters if (trimmed) break; } - return newNameParts.OfType().ToList(); + return newNameParts.Where(f => f is not null).ToList()!; } private static List GetNamePartsForWidthPessimistic(IList nameParts, double maxWidth) diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/Views/ItemView.axaml b/src/GuiApp/Avalonia/FileTime.GuiApp/Views/ItemView.axaml index 5e97a7f..3fa6284 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp/Views/ItemView.axaml +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/Views/ItemView.axaml @@ -2,17 +2,21 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:appcore="using:FileTime.App.Core.ViewModels" xmlns:appcoreenums="using:FileTime.App.Core.Models.Enums" + xmlns:guiappvm="using:FileTime.GuiApp.ViewModels" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="FileTime.GuiApp.Views.ItemView" x:Name="ItemRoot" HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch" - Background="{Binding ViewMode,Converter={StaticResource ItemViewModeToBackgroundConverter}}"> + Background="{Binding ViewMode^,Converter={StaticResource ItemViewModeToBackgroundConverter}}" + x:CompileBindings="True" + x:DataType="appcore:IItemViewModel">