Search improvements, bugfix

This commit is contained in:
2022-02-22 14:37:14 +01:00
parent 92f8e828b5
commit 5734126c31
16 changed files with 69 additions and 40 deletions

View File

@@ -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;

View File

@@ -0,0 +1,8 @@
namespace FileTime.Core.Models
{
public interface IFile : IElement
{
string Attributes { get; }
DateTime CreatedAt { get; }
}
}

View File

@@ -5,12 +5,15 @@ namespace FileTime.Core.Search
{
public class ChildSearchElement : AbstractElement<IContentProvider>
{
public ChildSearchElement(SearchContainer searchContainer, IContentProvider provider, IContainer parent, string name, string displayName, List<ItemNamePart> searchDisplayName) : base(provider, parent, name)
public IElement BaseElement { get; }
public ChildSearchElement(SearchContainer searchContainer, IContentProvider provider, IContainer parent, IElement baseElement, string name, List<ItemNamePart> 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<IContentWriter> GetContentWriterAsync() => throw new NotSupportedException();
public override Task<long?> GetElementSize(CancellationToken token = default) => Task.FromResult((long?)null);
public override async Task<long?> 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();
}

View File

@@ -16,6 +16,6 @@ namespace FileTime.Core.Search
protected override Task<bool> IsItemMatch(IItem item) => Task.FromResult(item.Name.Contains(_name));
public override List<ItemNamePart> GetDisplayName(IItem item) => _itemNameConverterService.GetDisplayName(item, _name);
public override List<ItemNamePart> GetDisplayName(IItem item) => _itemNameConverterService.GetDisplayName(item.DisplayName, _name);
}
}

View File

@@ -15,7 +15,7 @@ namespace FileTime.Core.Search
private readonly IReadOnlyList<IContainer> _containersReadOnly;
private readonly IReadOnlyList<IElement> _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<IContainer>();
_elements = new List<IElement>();
_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<ContainerEscapeResult> 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));
}

View File

@@ -4,12 +4,11 @@ namespace FileTime.Core.Services
{
public class ItemNameConverterService
{
public List<ItemNamePart> GetDisplayName(IItem item, string? searchText)
public List<ItemNamePart> GetDisplayName(string name, string? searchText)
{
var nameParts = new List<ItemNamePart>();
searchText = searchText?.ToLower();
var name = item is IElement ? GetFileName(item.DisplayName) : item.DisplayName;
if (!string.IsNullOrEmpty(searchText))
{
var nameLeft = name;

View File

@@ -218,13 +218,13 @@ namespace FileTime.Avalonia.Application
else if (currentSelectenItem.Item is ChildSearchContainer searchContainer)
{
var searchContainerPreview = _serviceProvider.GetService<SearchContainerPreview>()!;
await searchContainerPreview.Init(searchContainer, _currentLocation.Container);
searchContainerPreview.Init(searchContainer, _currentLocation.Container);
preview = searchContainerPreview;
}
else if (currentSelectenItem.Item is ChildSearchElement searchElement)
{
var searchElementPreview = _serviceProvider.GetService<SearchElementPreview>()!;
await searchElementPreview.Init(searchElement, _currentLocation.Container);
searchElementPreview.Init(searchElement, _currentLocation.Container);
preview = searchElementPreview;
}
else if (currentSelectenItem is ElementViewModel elementViewModel)

View File

@@ -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;
}

View File

@@ -2,7 +2,7 @@ namespace FileTime.Avalonia.Models
{
public enum AttibuteType
{
LocalFile,
File,
Element,
Container
}

View File

@@ -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<Exception> _exceptions;
public IItem Item => _container;
public IItem BaseItem => _baseContainer;
private ObservableCollection<ContainerViewModel> _containers = new();
@@ -70,7 +75,7 @@ namespace FileTime.Avalonia.ViewModels
_ => ItemViewMode.Default
};
public List<ItemNamePart> DisplayName => ItemNameConverterService.GetDisplayName(Item, AppState.ViewMode == Application.ViewMode.RapidTravel ? AppState.RapidTravelText : null);
public List<ItemNamePart> 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);
}

View File

@@ -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<ItemNamePart> DisplayName => ItemNameConverterService.GetDisplayName(Item, AppState.ViewMode == Application.ViewMode.RapidTravel ? AppState.RapidTravelText : null);
public List<ItemNamePart> 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;
}

View File

@@ -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; }

View File

@@ -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))));
}
}
}

View File

@@ -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))));
}
}
}

View File

@@ -55,29 +55,28 @@
<Grid Grid.Column="2" IsVisible="{Binding ShowAttributes,ElementName=ItemRoot}">
<Grid ColumnDefinitions="50,50,90,40,45"
HorizontalAlignment="Right"
IsVisible="{Binding Converter={StaticResource ItemViewModelIsAttibuteTypeConverter},ConverterParameter={x:Static models:AttibuteType.LocalFile}}">
IsVisible="{Binding Converter={StaticResource ItemViewModelIsAttibuteTypeConverter},ConverterParameter={x:Static models:AttibuteType.File}}">
<TextBlock HorizontalAlignment="Right" Classes="SmallText" Text="{Binding Item.Name, Converter={StaticResource GetFileExtensionConverter}}"/>
<TextBlock HorizontalAlignment="Right" Classes="SmallText" Text="{Binding BaseItem.DisplayName, Converter={StaticResource GetFileExtensionConverter}}"/>
<TextBlock HorizontalAlignment="Right" Classes="SmallText" Grid.Column="1" Text="{Binding Size, Converter={StaticResource FormatSizeConverter}, ConverterParameter=0}"/>
<TextBlock HorizontalAlignment="Right" Classes="SmallText" Grid.Column="2" Text="{Binding Item.CreatedAt, Converter={StaticResource DateTimeConverter}, ConverterParameter=yyyy-MM-dd}"/>
<TextBlock HorizontalAlignment="Right" Classes="SmallText" Grid.Column="3" Text="{Binding Item.CreatedAt, Converter={StaticResource DateTimeConverter}, ConverterParameter=hh:mm}"/>
<TextBlock HorizontalAlignment="Right" Classes="SmallText" Grid.Column="4" Text="{Binding Item.Attributes}"/>
<TextBlock HorizontalAlignment="Right" Classes="SmallText" Grid.Column="2" Text="{Binding BaseItem.CreatedAt, Converter={StaticResource DateTimeConverter}, ConverterParameter=yyyy-MM-dd}"/>
<TextBlock HorizontalAlignment="Right" Classes="SmallText" Grid.Column="3" Text="{Binding BaseItem.CreatedAt, Converter={StaticResource DateTimeConverter}, ConverterParameter=hh:mm}"/>
<TextBlock HorizontalAlignment="Right" Classes="SmallText" Grid.Column="4" Text="{Binding BaseItem.Attributes}"/>
</Grid>
<Grid ColumnDefinitions="90,40,45"
HorizontalAlignment="Right"
IsVisible="{Binding Converter={StaticResource ItemViewModelIsAttibuteTypeConverter},ConverterParameter={x:Static models:AttibuteType.Container}}">
<TextBlock HorizontalAlignment="Right" Classes="SmallText" Text="{Binding Item.CreatedAt, Converter={StaticResource DateTimeConverter}, ConverterParameter=yyyy-MM-dd}"/>
<TextBlock HorizontalAlignment="Right" Classes="SmallText" Grid.Column="1" Text="{Binding Item.CreatedAt, Converter={StaticResource DateTimeConverter}, ConverterParameter=hh:mm}"/>
<TextBlock HorizontalAlignment="Right" Classes="SmallText" Grid.Column="2" Text="{Binding Item.Attributes}"/>
<TextBlock HorizontalAlignment="Right" Classes="SmallText" Grid.Column="1" Text="{Binding BaseItem.CreatedAt, Converter={StaticResource DateTimeConverter}, ConverterParameter=hh:mm}"/>
<TextBlock HorizontalAlignment="Right" Classes="SmallText" Grid.Column="2" Text="{Binding BaseItem.Attributes}"/>
</Grid>
<Grid ColumnDefinitions="90,40,45"
<Grid ColumnDefinitions="50,50"
HorizontalAlignment="Right"
IsVisible="{Binding Converter={StaticResource ItemViewModelIsAttibuteTypeConverter},ConverterParameter={x:Static models:AttibuteType.Element}}">
<TextBlock HorizontalAlignment="Right" Classes="SmallText" Text="{Binding Item.CreatedAt, Converter={StaticResource DateTimeConverter}, ConverterParameter=yyyy-MM-dd}"/>
<TextBlock HorizontalAlignment="Right" Classes="SmallText" Grid.Column="1" Text="{Binding Item.CreatedAt, Converter={StaticResource DateTimeConverter}, ConverterParameter=hh:mm}"/>
<TextBlock HorizontalAlignment="Right" Classes="SmallText" Grid.Column="2" Text="{Binding Item.Attributes}"/>
<TextBlock HorizontalAlignment="Right" Classes="SmallText" Text="{Binding BaseItem.DisplayName, Converter={StaticResource GetFileExtensionConverter}}"/>
<TextBlock HorizontalAlignment="Right" Classes="SmallText" Grid.Column="1" Text="{Binding Size, Converter={StaticResource FormatSizeConverter}, ConverterParameter=0}"/>
</Grid>
</Grid>
</Grid>

View File

@@ -7,7 +7,7 @@ using Mono.Unix;
namespace FileTime.Providers.Local
{
public class LocalFile : IElement
public class LocalFile : IFile
{
public FileInfo File { get; }