From 5734126c317de2b0340495b2117e6677f90a71e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81d=C3=A1m=20Kov=C3=A1cs?= Date: Tue, 22 Feb 2022 14:37:14 +0100 Subject: [PATCH] Search improvements, bugfix --- src/Core/FileTime.Core/Components/Tab.cs | 4 +++ src/Core/FileTime.Core/Models/IFile.cs | 8 +++++ .../Search/ChildSearchElement.cs | 11 ++++--- .../FileTime.Core/Search/NameSearchTask.cs | 2 +- .../FileTime.Core/Search/SearchContainer.cs | 10 +++---- .../Services/ItemNameConverterService.cs | 3 +- .../Application/TabContainer.cs | 4 +-- .../ItemViewModelIsAttibuteTypeConverter.cs | 9 ++++-- .../FileTime.Avalonia/Models/AttibuteType.cs | 2 +- .../ViewModels/ContainerViewModel.cs | 8 ++++- .../ViewModels/ElementViewModel.cs | 8 ++++- .../ViewModels/IItemViewModel.cs | 1 + .../ItemPreview/SearchContainerPreview.cs | 4 +-- .../ItemPreview/SearchElementPreview.cs | 4 +-- .../FileTime.Avalonia/Views/ItemView.axaml | 29 +++++++++---------- .../FileTime.Providers.Local/LocalFile.cs | 2 +- 16 files changed, 69 insertions(+), 40 deletions(-) create mode 100644 src/Core/FileTime.Core/Models/IFile.cs diff --git a/src/Core/FileTime.Core/Components/Tab.cs b/src/Core/FileTime.Core/Components/Tab.cs index c7f6f24..3ae136b 100644 --- a/src/Core/FileTime.Core/Components/Tab.cs +++ b/src/Core/FileTime.Core/Components/Tab.cs @@ -42,6 +42,10 @@ namespace FileTime.Core.Components if (_currentLocation != null) { _currentLocation.Refreshed.Remove(HandleCurrentLocationRefresh); + if(_currentLocation is SearchContainer searchContainer) + { + searchContainer.SearchTaskBase.Cancel(); + } } _currentLocation = value; diff --git a/src/Core/FileTime.Core/Models/IFile.cs b/src/Core/FileTime.Core/Models/IFile.cs new file mode 100644 index 0000000..4c50f5b --- /dev/null +++ b/src/Core/FileTime.Core/Models/IFile.cs @@ -0,0 +1,8 @@ +namespace FileTime.Core.Models +{ + public interface IFile : IElement + { + string Attributes { get; } + DateTime CreatedAt { get; } + } +} \ No newline at end of file diff --git a/src/Core/FileTime.Core/Search/ChildSearchElement.cs b/src/Core/FileTime.Core/Search/ChildSearchElement.cs index 08e1494..e0ac039 100644 --- a/src/Core/FileTime.Core/Search/ChildSearchElement.cs +++ b/src/Core/FileTime.Core/Search/ChildSearchElement.cs @@ -5,12 +5,15 @@ namespace FileTime.Core.Search { public class ChildSearchElement : AbstractElement { - public ChildSearchElement(SearchContainer searchContainer, IContentProvider provider, IContainer parent, string name, string displayName, List searchDisplayName) : base(provider, parent, name) + public IElement BaseElement { get; } + + public ChildSearchElement(SearchContainer searchContainer, IContentProvider provider, IContainer parent, IElement baseElement, string name, List searchDisplayName) : base(provider, parent, name) { - DisplayName = displayName; + DisplayName = baseElement.DisplayName; NativePath = FullName; SearchContainer = searchContainer; SearchDisplayName = searchDisplayName; + BaseElement = baseElement; } public SearchContainer SearchContainer { get; } @@ -24,9 +27,9 @@ namespace FileTime.Core.Search public override Task GetContentWriterAsync() => throw new NotSupportedException(); - public override Task GetElementSize(CancellationToken token = default) => Task.FromResult((long?)null); + public override async Task GetElementSize(CancellationToken token = default) => await BaseElement.GetElementSize(token); - public override string GetPrimaryAttributeText() => ""; + public override string GetPrimaryAttributeText() => BaseElement.GetPrimaryAttributeText(); public override Task Rename(string newName) => throw new NotSupportedException(); } diff --git a/src/Core/FileTime.Core/Search/NameSearchTask.cs b/src/Core/FileTime.Core/Search/NameSearchTask.cs index a2c28b2..14e9557 100644 --- a/src/Core/FileTime.Core/Search/NameSearchTask.cs +++ b/src/Core/FileTime.Core/Search/NameSearchTask.cs @@ -16,6 +16,6 @@ namespace FileTime.Core.Search protected override Task IsItemMatch(IItem item) => Task.FromResult(item.Name.Contains(_name)); - public override List GetDisplayName(IItem item) => _itemNameConverterService.GetDisplayName(item, _name); + public override List GetDisplayName(IItem item) => _itemNameConverterService.GetDisplayName(item.DisplayName, _name); } } \ No newline at end of file diff --git a/src/Core/FileTime.Core/Search/SearchContainer.cs b/src/Core/FileTime.Core/Search/SearchContainer.cs index 1c6c372..f16a426 100644 --- a/src/Core/FileTime.Core/Search/SearchContainer.cs +++ b/src/Core/FileTime.Core/Search/SearchContainer.cs @@ -15,7 +15,7 @@ namespace FileTime.Core.Search private readonly IReadOnlyList _containersReadOnly; private readonly IReadOnlyList _elementsReadOnly; - private readonly SearchTaskBase _searchTaskBase; + public SearchTaskBase SearchTaskBase { get; } public IContainer SearchBaseContainer { get; } public override bool IsExists => throw new NotImplementedException(); @@ -25,7 +25,7 @@ namespace FileTime.Core.Search SearchBaseContainer = searchBaseContainer; _containers = new List(); _elements = new List(); - _searchTaskBase = searchTaskBase; + SearchTaskBase = searchTaskBase; _containersReadOnly = _containers.AsReadOnly(); _elementsReadOnly = _elements.AsReadOnly(); @@ -52,14 +52,14 @@ namespace FileTime.Core.Search public async Task AddContainer(IContainer container) { - var childContainer = new ChildSearchContainer(this, Provider, container, "container" + _childContainerCounter++, container.DisplayName, _searchTaskBase.GetDisplayName(container)); + var childContainer = new ChildSearchContainer(this, Provider, container, "container" + _childContainerCounter++, container.DisplayName, SearchTaskBase.GetDisplayName(container)); _containers.Add(childContainer); await UpdateChildren(); } public async Task AddElement(IElement element) { - var childElement = new ChildSearchElement(this, Provider, element.GetParent()!, "element" + _childElementCounter++, element.DisplayName, _searchTaskBase.GetDisplayName(element)); + var childElement = new ChildSearchElement(this, Provider, element.GetParent()!, element, "element" + _childElementCounter++, SearchTaskBase.GetDisplayName(element)); _elements.Add(childElement); await UpdateChildren(); } @@ -95,7 +95,7 @@ namespace FileTime.Core.Search public override Task HandleEscape() { - if (_searchTaskBase.Cancel()) return Task.FromResult(new ContainerEscapeResult(true)); + if (SearchTaskBase.Cancel()) return Task.FromResult(new ContainerEscapeResult(true)); return Task.FromResult(new ContainerEscapeResult(SearchBaseContainer)); } diff --git a/src/Core/FileTime.Core/Services/ItemNameConverterService.cs b/src/Core/FileTime.Core/Services/ItemNameConverterService.cs index f9f3d97..4a75556 100644 --- a/src/Core/FileTime.Core/Services/ItemNameConverterService.cs +++ b/src/Core/FileTime.Core/Services/ItemNameConverterService.cs @@ -4,12 +4,11 @@ namespace FileTime.Core.Services { public class ItemNameConverterService { - public List GetDisplayName(IItem item, string? searchText) + public List GetDisplayName(string name, string? searchText) { var nameParts = new List(); searchText = searchText?.ToLower(); - var name = item is IElement ? GetFileName(item.DisplayName) : item.DisplayName; if (!string.IsNullOrEmpty(searchText)) { var nameLeft = name; diff --git a/src/GuiApp/FileTime.Avalonia/Application/TabContainer.cs b/src/GuiApp/FileTime.Avalonia/Application/TabContainer.cs index fdc77af..e856aa0 100644 --- a/src/GuiApp/FileTime.Avalonia/Application/TabContainer.cs +++ b/src/GuiApp/FileTime.Avalonia/Application/TabContainer.cs @@ -218,13 +218,13 @@ namespace FileTime.Avalonia.Application else if (currentSelectenItem.Item is ChildSearchContainer searchContainer) { var searchContainerPreview = _serviceProvider.GetService()!; - await searchContainerPreview.Init(searchContainer, _currentLocation.Container); + searchContainerPreview.Init(searchContainer, _currentLocation.Container); preview = searchContainerPreview; } else if (currentSelectenItem.Item is ChildSearchElement searchElement) { var searchElementPreview = _serviceProvider.GetService()!; - await searchElementPreview.Init(searchElement, _currentLocation.Container); + searchElementPreview.Init(searchElement, _currentLocation.Container); preview = searchElementPreview; } else if (currentSelectenItem is ElementViewModel elementViewModel) diff --git a/src/GuiApp/FileTime.Avalonia/Converters/ItemViewModelIsAttibuteTypeConverter.cs b/src/GuiApp/FileTime.Avalonia/Converters/ItemViewModelIsAttibuteTypeConverter.cs index 29590a4..df9a1cb 100644 --- a/src/GuiApp/FileTime.Avalonia/Converters/ItemViewModelIsAttibuteTypeConverter.cs +++ b/src/GuiApp/FileTime.Avalonia/Converters/ItemViewModelIsAttibuteTypeConverter.cs @@ -3,6 +3,7 @@ using System.Globalization; using Avalonia.Data.Converters; using FileTime.Avalonia.Models; using FileTime.Avalonia.ViewModels; +using FileTime.Core.Models; using FileTime.Providers.Local; namespace FileTime.Avalonia.Converters @@ -12,7 +13,9 @@ namespace FileTime.Avalonia.Converters public bool Invert { get; set; } public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { - var result = parameter is AttibuteType targetAttribute && GetAttibuteType(value) == targetAttribute; + var attributeType = GetAttibuteType(value); + if (parameter == null) return attributeType; + var result = parameter is AttibuteType targetAttribute && attributeType == targetAttribute; if (Invert && parameter is AttibuteType) result = !result; return result; } @@ -21,9 +24,9 @@ namespace FileTime.Avalonia.Converters { if (value is ElementViewModel elementVM) { - if (elementVM.Element is LocalFile) + if (elementVM.BaseElement is IFile) { - return AttibuteType.LocalFile; + return AttibuteType.File; } return AttibuteType.Element; } diff --git a/src/GuiApp/FileTime.Avalonia/Models/AttibuteType.cs b/src/GuiApp/FileTime.Avalonia/Models/AttibuteType.cs index feb9b9e..be613c7 100644 --- a/src/GuiApp/FileTime.Avalonia/Models/AttibuteType.cs +++ b/src/GuiApp/FileTime.Avalonia/Models/AttibuteType.cs @@ -2,7 +2,7 @@ namespace FileTime.Avalonia.Models { public enum AttibuteType { - LocalFile, + File, Element, Container } diff --git a/src/GuiApp/FileTime.Avalonia/ViewModels/ContainerViewModel.cs b/src/GuiApp/FileTime.Avalonia/ViewModels/ContainerViewModel.cs index 5fa478e..da1bc25 100644 --- a/src/GuiApp/FileTime.Avalonia/ViewModels/ContainerViewModel.cs +++ b/src/GuiApp/FileTime.Avalonia/ViewModels/ContainerViewModel.cs @@ -13,6 +13,7 @@ using System.Threading.Tasks; using FileTime.Avalonia.Application; using System.Threading; using FileTime.Core.Services; +using FileTime.Core.Search; namespace FileTime.Avalonia.ViewModels { @@ -29,6 +30,9 @@ namespace FileTime.Avalonia.ViewModels [Property] private IContainer _container; + [Property] + private IContainer _baseContainer; + [Property] private bool _isSelected; @@ -45,6 +49,7 @@ namespace FileTime.Avalonia.ViewModels private List _exceptions; public IItem Item => _container; + public IItem BaseItem => _baseContainer; private ObservableCollection _containers = new(); @@ -70,7 +75,7 @@ namespace FileTime.Avalonia.ViewModels _ => ItemViewMode.Default }; - public List DisplayName => ItemNameConverterService.GetDisplayName(Item, AppState.ViewMode == Application.ViewMode.RapidTravel ? AppState.RapidTravelText : null); + public List DisplayName => ItemNameConverterService.GetDisplayName(Item.DisplayName, AppState.ViewMode == Application.ViewMode.RapidTravel ? AppState.RapidTravelText : null); public Task Containers => GetContainers(); public Task Elements => GetElements(); @@ -127,6 +132,7 @@ namespace FileTime.Avalonia.ViewModels Parent = parent; Container = container; + BaseContainer = container is ChildSearchContainer childSearchContainer ? childSearchContainer.BaseContainer : container; Container.Refreshed.Add(Container_Refreshed); Container.LazyLoadingChanged.Add(Container_LazyLoadingChanged); } diff --git a/src/GuiApp/FileTime.Avalonia/ViewModels/ElementViewModel.cs b/src/GuiApp/FileTime.Avalonia/ViewModels/ElementViewModel.cs index cc33895..10b5270 100644 --- a/src/GuiApp/FileTime.Avalonia/ViewModels/ElementViewModel.cs +++ b/src/GuiApp/FileTime.Avalonia/ViewModels/ElementViewModel.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using FileTime.Avalonia.Application; using FileTime.Core.Services; +using FileTime.Core.Search; namespace FileTime.Avalonia.ViewModels { @@ -15,10 +16,14 @@ namespace FileTime.Avalonia.ViewModels public partial class ElementViewModel : IItemViewModel { public IItem Item => _element; + public IItem BaseItem => _baseElement; [Property] private IElement _element; + [Property] + private IElement _baseElement; + [Property] private bool _isSelected; @@ -48,11 +53,12 @@ namespace FileTime.Avalonia.ViewModels _ => ItemViewMode.Default }; - public List DisplayName => ItemNameConverterService.GetDisplayName(Item, AppState.ViewMode == Application.ViewMode.RapidTravel ? AppState.RapidTravelText : null); + public List DisplayName => ItemNameConverterService.GetDisplayName(ItemNameConverterService.GetFileName(Item.DisplayName), AppState.ViewMode == Application.ViewMode.RapidTravel ? AppState.RapidTravelText : null); public ElementViewModel(IElement element, ContainerViewModel parent, ItemNameConverterService itemNameConverterService, AppState appState) : this(itemNameConverterService, appState) { Element = element; + BaseElement = element is ChildSearchElement childSearchElement ? childSearchElement.BaseElement : element; Parent = parent; } diff --git a/src/GuiApp/FileTime.Avalonia/ViewModels/IItemViewModel.cs b/src/GuiApp/FileTime.Avalonia/ViewModels/IItemViewModel.cs index 6cdd42a..78bf785 100644 --- a/src/GuiApp/FileTime.Avalonia/ViewModels/IItemViewModel.cs +++ b/src/GuiApp/FileTime.Avalonia/ViewModels/IItemViewModel.cs @@ -7,6 +7,7 @@ namespace FileTime.Avalonia.ViewModels public interface IItemViewModel { IItem Item { get; } + IItem BaseItem { get; } bool IsSelected { get; set; } bool IsAlternative { get; set; } diff --git a/src/GuiApp/FileTime.Avalonia/ViewModels/ItemPreview/SearchContainerPreview.cs b/src/GuiApp/FileTime.Avalonia/ViewModels/ItemPreview/SearchContainerPreview.cs index f6644dd..c090caf 100644 --- a/src/GuiApp/FileTime.Avalonia/ViewModels/ItemPreview/SearchContainerPreview.cs +++ b/src/GuiApp/FileTime.Avalonia/ViewModels/ItemPreview/SearchContainerPreview.cs @@ -23,11 +23,11 @@ namespace FileTime.Avalonia.ViewModels.ItemPreview [Property] private string? _realtiveParentPath; - public async Task Init(ChildSearchContainer container, IContainer currentLocation) + public void Init(ChildSearchContainer container, IContainer currentLocation) { var pathCommonPath = PathHelper.GetCommonPath(currentLocation.FullName!, container.FullName!); RealtiveParentPath = new AbsolutePath(null!, container.FullName!.Substring(pathCommonPath.Length).Trim(Constants.SeparatorChar), AbsolutePathType.Unknown, null).GetParentPath(); - ItemNameParts = await Task.Run(async () => await Dispatcher.UIThread.InvokeAsync(() => container.SearchDisplayName.Select(p => new ItemNamePartViewModel(p.Text, p.IsSpecial ? TextDecorations.Underline : null)).ToList())); + Task.Run(async () => ItemNameParts = await Dispatcher.UIThread.InvokeAsync(() => container.SearchDisplayName.ConvertAll(p => new ItemNamePartViewModel(p.Text, p.IsSpecial ? TextDecorations.Underline : null)))); } } } \ No newline at end of file diff --git a/src/GuiApp/FileTime.Avalonia/ViewModels/ItemPreview/SearchElementPreview.cs b/src/GuiApp/FileTime.Avalonia/ViewModels/ItemPreview/SearchElementPreview.cs index ba6a714..21f91b1 100644 --- a/src/GuiApp/FileTime.Avalonia/ViewModels/ItemPreview/SearchElementPreview.cs +++ b/src/GuiApp/FileTime.Avalonia/ViewModels/ItemPreview/SearchElementPreview.cs @@ -25,11 +25,11 @@ namespace FileTime.Avalonia.ViewModels.ItemPreview [Property] private string? _realtiveParentPath; - public async Task Init(ChildSearchElement element, IContainer currentLocation) + public void Init(ChildSearchElement element, IContainer currentLocation) { var pathCommonPath = PathHelper.GetCommonPath(currentLocation.FullName!, element.FullName!); RealtiveParentPath = new AbsolutePath(null!, element.FullName!.Substring(pathCommonPath.Length).Trim(Constants.SeparatorChar), AbsolutePathType.Unknown, null).GetParentPath(); - ItemNameParts = await Task.Run(async () => await Dispatcher.UIThread.InvokeAsync(() => element.SearchDisplayName.Select(p => new ItemNamePartViewModel(p.Text, p.IsSpecial ? TextDecorations.Underline : null)).ToList())); + Task.Run(async () => ItemNameParts = await Dispatcher.UIThread.InvokeAsync(() => element.SearchDisplayName.ConvertAll(p => new ItemNamePartViewModel(p.Text, p.IsSpecial ? TextDecorations.Underline : null)))); } } } \ No newline at end of file diff --git a/src/GuiApp/FileTime.Avalonia/Views/ItemView.axaml b/src/GuiApp/FileTime.Avalonia/Views/ItemView.axaml index b39c726..482b1ff 100644 --- a/src/GuiApp/FileTime.Avalonia/Views/ItemView.axaml +++ b/src/GuiApp/FileTime.Avalonia/Views/ItemView.axaml @@ -5,7 +5,7 @@ mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="FileTime.Avalonia.Views.ItemView" xmlns:models="using:FileTime.Avalonia.Models" - x:Name="ItemRoot" + x:Name="ItemRoot" HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch" Background="{Binding ViewMode,Converter={StaticResource ItemViewModeToBackgroundConverter}}"> @@ -55,29 +55,28 @@ + IsVisible="{Binding Converter={StaticResource ItemViewModelIsAttibuteTypeConverter},ConverterParameter={x:Static models:AttibuteType.File}}"> - + - - - + + + - - + - - + + - - - - - + + + diff --git a/src/Providers/FileTime.Providers.Local/LocalFile.cs b/src/Providers/FileTime.Providers.Local/LocalFile.cs index 51ce643..e734e44 100644 --- a/src/Providers/FileTime.Providers.Local/LocalFile.cs +++ b/src/Providers/FileTime.Providers.Local/LocalFile.cs @@ -7,7 +7,7 @@ using Mono.Unix; namespace FileTime.Providers.Local { - public class LocalFile : IElement + public class LocalFile : IFile { public FileInfo File { get; }