Show folder names immediately and refresh stale index sizes without walking the whole drive.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-26 11:21:20 +02:00
parent 6fc7506eb7
commit e2916aef9c
88 changed files with 5373 additions and 544 deletions

View File

@@ -291,6 +291,43 @@ public class SourceManagerTests
await mgr.RefreshOnlineStateAsync(forceRefresh: true);
Assert.Equal(afterInit + 1, volumes.EnumerateCalls);
}
[Fact]
public async Task Reachable_unc_share_not_listed_as_a_drive_becomes_online()
{
var db = Path.Combine(Path.GetTempPath(), "ew-app", Guid.NewGuid().ToString("N"), "index.db");
await using var store = new SqliteIndexStore(db, NullLogger<SqliteIndexStore>.Instance);
await store.OpenAsync();
var volumes = new FakeVolumes();
var env = new FakeEnv(Path.GetDirectoryName(db)!);
var mgr = new SourceManager(store, volumes, env, new SystemClock(), NullLogger<SourceManager>.Instance);
await mgr.InitializeAsync();
var source = await mgr.AddUncAsync(@"\\nas\media");
Assert.Equal(SourceStatus.Offline, source.Status);
volumes.ReachablePaths.Add(@"\\nas\media");
await mgr.RefreshOnlineStateAsync(forceRefresh: true);
var again = Assert.Single(await store.Sources.GetAllAsync());
Assert.Equal(SourceStatus.Online, again.Status);
}
[Fact]
public async Task Mark_reachable_flips_offline_unc_immediately()
{
var db = Path.Combine(Path.GetTempPath(), "ew-app", Guid.NewGuid().ToString("N"), "index.db");
await using var store = new SqliteIndexStore(db, NullLogger<SqliteIndexStore>.Instance);
await store.OpenAsync();
var volumes = new FakeVolumes();
var env = new FakeEnv(Path.GetDirectoryName(db)!);
var mgr = new SourceManager(store, volumes, env, new SystemClock(), NullLogger<SourceManager>.Instance);
await mgr.InitializeAsync();
await mgr.AddUncAsync(@"\\nas\media");
var updated = await mgr.MarkReachableAsync(@"\\nas\media\clip.mkv");
Assert.NotNull(updated);
Assert.Equal(SourceStatus.Online, updated.Status);
Assert.Equal(SourceStatus.Online, (await store.Sources.GetAllAsync()).Single().Status);
}
}
file sealed class FakeVolumes : IVolumeService
@@ -310,12 +347,19 @@ file sealed class FakeVolumes : IVolumeService
v.RootPath.TrimEnd('\\').Equals(root, StringComparison.OrdinalIgnoreCase)
|| v.RootPath.Equals(path, StringComparison.OrdinalIgnoreCase));
}
public bool IsPathReachable(string path) => Online.Any(v => path.StartsWith(v.RootPath.TrimEnd('\\'), StringComparison.OrdinalIgnoreCase));
public bool IsPathReachable(string path)
=> Matches(Online.Select(v => v.RootPath), path) || Matches(ReachablePaths, path);
public List<string> ReachablePaths { get; } = [];
public VolumeSpace GetSpace(string path)
{
var fp = Probe(path);
return new VolumeSpace(fp?.CapacityBytes, fp?.FreeBytes);
}
private static bool Matches(IEnumerable<string> roots, string path)
=> roots.Any(root => path.StartsWith(root.TrimEnd('\\'), StringComparison.OrdinalIgnoreCase));
}
file sealed class FakeEnv : IAppEnvironment