using AsyncEvent; using FileTime.Core.Models; using FileTime.Core.Providers; namespace FileTime.Core.Search { public class SearchContainer : AbstractContainer { private int _childContainerCounter; private int _childElementCounter; private readonly List _containers; private IReadOnlyList _items; private readonly List _elements; private readonly IReadOnlyList _containersReadOnly; private readonly IReadOnlyList _elementsReadOnly; public SearchTaskBase SearchTaskBase { get; } public IContainer SearchBaseContainer { get; } public override bool IsExists => throw new NotImplementedException(); public SearchContainer(IContainer searchBaseContainer, SearchTaskBase searchTaskBase) : base(searchBaseContainer.Provider, searchBaseContainer.GetParent()!, searchBaseContainer.Name) { SearchBaseContainer = searchBaseContainer; SearchTaskBase = searchTaskBase; _containers = new List(); _elements = new List(); _containersReadOnly = _containers.AsReadOnly(); _elementsReadOnly = _elements.AsReadOnly(); _items = _containers.Cast().Concat(_elements).ToList().AsReadOnly(); UseLazyLoad = true; CanHandleEscape = true; CanDelete = SupportsDelete.False; } public async Task RunWithLazyLoading(Func func, CancellationToken token = default) { try { LazyLoading = true; await LazyLoadingChanged.InvokeAsync(this, LazyLoading, token); await func(token); } finally { LazyLoading = false; await LazyLoadingChanged.InvokeAsync(this, LazyLoading, token); } } public async Task AddContainer(IContainer 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, "element" + _childElementCounter++, SearchTaskBase.GetDisplayName(element)); _elements.Add(childElement); await UpdateChildren(); } private async Task UpdateChildren() { _items = _containers.Cast().Concat(_elements).ToList().AsReadOnly(); await RefreshAsync(); } public override async Task RefreshAsync(CancellationToken token = default) { if (Refreshed != null) await Refreshed.InvokeAsync(this, AsyncEventArgs.Empty, token); } public override Task?> GetContainers(CancellationToken token = default) => Task.FromResult((IReadOnlyList?)_containersReadOnly); public override Task?> GetElements(CancellationToken token = default) => Task.FromResult((IReadOnlyList?)_elementsReadOnly); public override Task?> GetItems(CancellationToken token = default) => Task.FromResult((IReadOnlyList?)_items); public override Task CloneAsync() => Task.FromResult((IContainer)this); public override Task CreateContainerAsync(string name) => throw new NotSupportedException(); public override Task CreateElementAsync(string name) => throw new NotSupportedException(); public override Task Delete(bool hardDelete = false) => throw new NotSupportedException(); public override Task> RefreshItems(CancellationToken token = default) => throw new NotImplementedException(); public override Task Rename(string newName) => throw new NotSupportedException(); public override Task HandleEscape() { if (SearchTaskBase.Cancel()) return Task.FromResult(new ContainerEscapeResult(true)); return Task.FromResult(new ContainerEscapeResult(SearchBaseContainer)); } } }