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,140 @@
using Explorer.Plugin.Abstractions;
using Explorer.Windows;
namespace Explorer.Plugin.OneDrive;
public sealed class OneDriveStorageProvider : IStorageProvider
{
public const string ProviderId = "onedrive";
private readonly object _gate = new();
private IReadOnlyList<ProviderPlace>? _places;
public ProviderManifest Manifest { get; } = new(
ProviderId,
"OneDrive",
"1.0.0",
ProviderIsolation.InProcess);
public ProviderCapability GetCapabilities()
=> ProviderCapability.CloudState | ProviderCapability.Pin | ProviderCapability.Dehydrate;
public bool TryMatchRoot(string path)
{
if (string.IsNullOrWhiteSpace(path))
{
return false;
}
foreach (var root in GetPlaces())
{
if (IsUnder(root.Path, path))
{
return true;
}
}
return CloudFilesNative.IsCloudSyncRoot(path);
}
public Task<IReadOnlyList<ProviderItemState>> GetItemStatesAsync(
IReadOnlyList<string> paths,
CancellationToken cancellationToken = default)
{
var results = new List<ProviderItemState>(paths.Count);
foreach (var path in paths)
{
cancellationToken.ThrowIfCancellationRequested();
if (!TryMatchRoot(path))
{
continue;
}
try
{
var attrs = (int)File.GetAttributes(path);
var isDir = (attrs & (int)FileAttributes.Directory) != 0;
long logical = 0;
if (!isDir)
{
try { logical = new FileInfo(path).Length; } catch { /* locked */ }
}
var allocated = CloudFilesNative.TryGetAllocatedSize(path);
var placeholder = CloudFilesNative.TryGetPlaceholderState(attrs, 0);
results.Add(OneDrivePlaceholderState.FromLocalSignals(
ProviderId, path, attrs, 0, logical, allocated, placeholder));
}
catch
{
// fail-open for this item
}
}
return Task.FromResult<IReadOnlyList<ProviderItemState>>(results);
}
public Task<ProviderActionResult> TryInvokeAsync(ProviderActionRequest request, CancellationToken cancellationToken = default)
{
var capabilities = GetCapabilities();
var needed = request.Action switch
{
ProviderAction.Pin or ProviderAction.Unpin => ProviderCapability.Pin,
ProviderAction.Dehydrate => ProviderCapability.Dehydrate,
_ => ProviderCapability.None
};
if (needed == ProviderCapability.None || (capabilities & needed) == 0)
{
return Task.FromResult(new ProviderActionResult(ProviderActionStatus.Unsupported, "This action is not available."));
}
var pin = request.Action switch
{
ProviderAction.Pin => CloudFilesNative.PinPinned,
ProviderAction.Unpin or ProviderAction.Dehydrate => CloudFilesNative.PinUnpinned,
_ => CloudFilesNative.PinUnspecified
};
var failed = 0;
foreach (var path in request.Paths)
{
cancellationToken.ThrowIfCancellationRequested();
if (!CloudFilesNative.TrySetPinState(path, pin))
{
failed++;
}
}
if (failed == 0)
{
return Task.FromResult(new ProviderActionResult(ProviderActionStatus.Succeeded));
}
if (failed == request.Paths.Count)
{
return Task.FromResult(new ProviderActionResult(ProviderActionStatus.Failed, "OneDrive could not change the pin state."));
}
return Task.FromResult(new ProviderActionResult(ProviderActionStatus.Failed, $"OneDrive could not change the pin state for {failed} item(s)."));
}
public Task<ProviderQuota?> TryGetQuotaAsync(string rootPath, CancellationToken cancellationToken = default)
=> Task.FromResult<ProviderQuota?>(null);
public IReadOnlyList<ProviderPlace> GetPlaces()
{
lock (_gate)
{
return _places ??= OneDrivePlaceDiscovery.Discover();
}
}
private static bool IsUnder(string root, string path)
{
var a = root.TrimEnd('\\');
var b = path.TrimEnd('\\');
return b.Equals(a, StringComparison.OrdinalIgnoreCase)
|| b.StartsWith(a + "\\", StringComparison.OrdinalIgnoreCase);
}
}