Add Explorer Workbench with hierarchical, off-UI Storage analysis.

Storage queries run in the background with cancellation and covering indexes so switching views no longer freezes the UI.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-22 12:43:05 +02:00
commit e9aba73552
130 changed files with 15110 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
using Explorer.Domain;
using Explorer.Domain.Abstractions;
using Explorer.FileOperations;
namespace Explorer.FileOperations;
public sealed class FileOperationService
{
private readonly TransferQueue _queue;
private readonly IShellFileOperations _shell;
private readonly IFileSystemEnumerator _enumerator;
public FileOperationService(TransferQueue queue, IShellFileOperations shell, IFileSystemEnumerator enumerator)
{
_queue = queue;
_shell = shell;
_enumerator = enumerator;
}
public void Open(IReadOnlyList<string> paths)
{
foreach (var path in paths)
{
_shell.Open(path);
}
}
public Task CopyAsync(IReadOnlyList<string> sources, string destinationDirectory, CancellationToken cancellationToken = default)
=> _queue.EnqueueCopyAsync(sources, destinationDirectory, cancellationToken);
public Task MoveAsync(IReadOnlyList<string> sources, string destinationDirectory, CancellationToken cancellationToken = default)
=> _queue.EnqueueMoveAsync(sources, destinationDirectory, cancellationToken);
public Task DeleteAsync(IReadOnlyList<string> paths, CancellationToken cancellationToken = default)
=> _queue.EnqueueDeleteAsync(paths, cancellationToken);
public void Rename(string path, string newName)
{
var parent = PathRules.Parent(path);
var dest = Path.Combine(parent, newName);
var src = PathRules.ToExtended(path);
var dst = PathRules.ToExtended(dest);
if (Directory.Exists(src))
{
Directory.Move(src, dst);
}
else
{
File.Move(src, dst);
}
}
public string NewFolder(string parent)
{
var baseName = "New folder";
var name = baseName;
var i = 2;
var dest = Path.Combine(parent, name);
while (Directory.Exists(PathRules.ToExtended(dest)) || File.Exists(PathRules.ToExtended(dest)))
{
name = $"{baseName} ({i++})";
dest = Path.Combine(parent, name);
}
Directory.CreateDirectory(PathRules.ToExtended(dest));
return dest;
}
public FileSystemItem? GetItem(string path) => _enumerator.GetItem(path);
}