Top navigation, search delete

This commit is contained in:
2023-07-28 17:10:50 +02:00
parent ee42e38e45
commit ed6864e127
27 changed files with 320 additions and 149 deletions

View File

@@ -7,12 +7,14 @@ namespace FileTime.App.Search;
public class SearchContentProvider : ContentProviderBase, ISearchContentProvider
{
private readonly ISearchManager _searchManager;
private readonly ITimelessContentProvider _timelessContentProvider;
private readonly List<SearchTask> _searchTasks = new();
public const string ContentProviderName = "search";
public SearchContentProvider(ISearchManager searchManager) : base(ContentProviderName)
public SearchContentProvider(ITimelessContentProvider timelessContentProvider)
: base(ContentProviderName, timelessContentProvider)
{
_searchManager = searchManager;
_timelessContentProvider = timelessContentProvider;
}
public override Task<IItem> GetItemByNativePathAsync(
@@ -21,9 +23,12 @@ public class SearchContentProvider : ContentProviderBase, ISearchContentProvider
bool forceResolve = false,
AbsolutePathType forceResolvePathType = AbsolutePathType.Unknown,
ItemInitializationSettings itemInitializationSettings = default
) =>
Task.FromResult((IItem) _searchManager.SearchTasks
)
{
if (nativePath.Path == ContentProviderName) return Task.FromResult((IItem) this);
return Task.FromResult((IItem) _searchTasks
.First(searchTask => searchTask.SearchContainer.NativePath == nativePath).SearchContainer);
}
public override NativePath GetNativePath(FullName fullName) => new(fullName.Path);
public override FullName GetFullName(NativePath nativePath) => new(nativePath.Path);
@@ -36,4 +41,34 @@ public class SearchContentProvider : ContentProviderBase, ISearchContentProvider
=> Task.FromResult(null as byte[]);
public override bool CanHandlePath(NativePath path) => path.Path.StartsWith(ContentProviderName);
public async Task<ISearchTask> StartSearchAsync(ISearchMatcher matcher, IContainer searchIn)
{
var searchTask = new SearchTask(
searchIn,
this,
_timelessContentProvider,
matcher,
new AbsolutePath(_timelessContentProvider, this)
);
_searchTasks.Add(searchTask);
await searchTask.StartAsync();
Items.Add(new AbsolutePath(_timelessContentProvider, searchTask.SearchContainer));
return searchTask;
}
public void RemoveSearch(FullName searchFullName)
{
var searchTask = _searchTasks.FirstOrDefault(t => t.SearchContainer.FullName == searchFullName);
if (searchTask is null) return;
_searchTasks.Remove(searchTask);
var searchItem = Items.FirstOrDefault(c => c.Path == searchTask.SearchContainer.FullName);
if (searchItem is not null)
{
Items.Remove(searchItem);
}
}
}

View File

@@ -0,0 +1,13 @@
using FileTime.Core.ContentAccess;
using FileTime.Core.Models;
namespace FileTime.App.Search;
public class SearchItemDeleter : IItemDeleter<ISearchContentProvider>
{
public Task DeleteAsync(ISearchContentProvider contentProvider, FullName fullName)
{
contentProvider.RemoveSearch(fullName);
return Task.CompletedTask;
}
}

View File

@@ -1,35 +0,0 @@
using FileTime.Core.Models;
using Microsoft.Extensions.DependencyInjection;
namespace FileTime.App.Search;
public class SearchManager : ISearchManager
{
private readonly IServiceProvider _serviceProvider;
private ISearchContentProvider? _searchContainerProvider;
private readonly List<SearchTask> _searchTasks = new();
public IReadOnlyList<ISearchTask> SearchTasks { get; }
public SearchManager(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
SearchTasks = _searchTasks.AsReadOnly();
}
public async Task<ISearchTask> StartSearchAsync(ISearchMatcher matcher, IContainer searchIn)
{
_searchContainerProvider ??= _serviceProvider.GetRequiredService<ISearchContentProvider>();
var searchTask = new SearchTask(
searchIn,
_searchContainerProvider,
matcher
);
_searchTasks.Add(searchTask);
await searchTask.StartAsync();
return searchTask;
}
}

View File

@@ -10,6 +10,7 @@ namespace FileTime.App.Search;
public class SearchTask : ISearchTask
{
private readonly IContainer _baseContainer;
private readonly ITimelessContentProvider _timelessContentProvider;
private readonly ISearchMatcher _matcher;
private readonly Container _container;
private readonly ObservableCollection<Exception> _exceptions = new();
@@ -22,19 +23,22 @@ public class SearchTask : ISearchTask
public SearchTask(
IContainer baseContainer,
IContentProvider contentProvider,
ISearchMatcher matcher
ISearchContentProvider contentProvider,
ITimelessContentProvider timelessContentProvider,
ISearchMatcher matcher,
AbsolutePath parent
)
{
var randomId = $"{SearchContentProvider.ContentProviderName}/{_searchId++}_{baseContainer.Name}";
_baseContainer = baseContainer;
_timelessContentProvider = timelessContentProvider;
_matcher = matcher;
_container = new Container(
baseContainer.Name,
baseContainer.DisplayName,
new FullName(randomId),
new NativePath(randomId),
null,
parent,
false,
true,
null,
@@ -85,7 +89,11 @@ public class SearchTask : ISearchTask
foreach (var itemPath in items)
{
var item = await itemPath.ResolveAsync();
var item = await itemPath.ResolveAsync(
itemInitializationSettings: new ItemInitializationSettings
{
Parent = new AbsolutePath(_timelessContentProvider, _container)
});
if (await _matcher.IsItemMatchAsync(item))
{
_items.Add(itemPath);

View File

@@ -10,7 +10,8 @@ public static class Startup
{
services.TryAddSingleton<ISearchContentProvider, SearchContentProvider>();
services.AddSingleton<IContentProvider>(sp => sp.GetRequiredService<ISearchContentProvider>());
services.TryAddSingleton<ISearchManager, SearchManager>();
services.TryAddSingleton<IItemDeleter<ISearchContentProvider>, SearchItemDeleter>();
services.TryAddSingleton<IItemDeleter<SearchContentProvider>>(sp => sp.GetRequiredService<IItemDeleter<ISearchContentProvider>>());
return services;
}