Make drag-and-drop follow Windows Explorer and refresh the tree after folder operations.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -75,12 +75,17 @@ public sealed class NavigationTreeViewModel
|
||||
Roots.Add(thisPc);
|
||||
|
||||
var sources = await _sources.RefreshOnlineStateAsync(cancellationToken).ConfigureAwait(true);
|
||||
foreach (var source in sources.Where(s => !s.Kind.IsNetwork()))
|
||||
foreach (var source in sources.Where(s => !s.Kind.IsNetwork())
|
||||
.OrderBy(s => PathRules.DriveLetterSortKey(s.LastRootPath))
|
||||
.ThenBy(s => s.DisplayName, StringComparer.CurrentCultureIgnoreCase))
|
||||
{
|
||||
thisPc.Children.Add(CreateSourceNode(source, _sources.CanForget(source)));
|
||||
}
|
||||
|
||||
var network = sources.Where(s => s.Kind.IsNetwork()).ToList();
|
||||
var network = sources.Where(s => s.Kind.IsNetwork())
|
||||
.OrderBy(s => PathRules.DriveLetterSortKey(s.LastRootPath))
|
||||
.ThenBy(s => s.DisplayName, StringComparer.CurrentCultureIgnoreCase)
|
||||
.ToList();
|
||||
if (prefs.GroupNetworkPlaces && network.Count > 0)
|
||||
{
|
||||
var group = new NavNodeViewModel
|
||||
@@ -174,7 +179,7 @@ public sealed class NavigationTreeViewModel
|
||||
{
|
||||
var child = new NavNodeViewModel
|
||||
{
|
||||
Label = dir.Name,
|
||||
Label = dir.DisplayName ?? dir.Name,
|
||||
Path = dir.FullPath
|
||||
};
|
||||
AddPlaceholder(child);
|
||||
@@ -184,6 +189,78 @@ public sealed class NavigationTreeViewModel
|
||||
node.ChildrenLoaded = true;
|
||||
}
|
||||
|
||||
public async Task RefreshAfterChangesAsync(IEnumerable<string> directories)
|
||||
{
|
||||
var seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var raw in directories)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(raw) || LocationRoots.IsVirtual(raw))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var dir = PathRules.EnsureDirectoryTrailingSlashIfRoot(PathRules.FromExtended(raw).TrimEnd('\\'));
|
||||
if (!seen.Add(dir))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var node = FindByPath(Roots, dir);
|
||||
if (node is null || !node.ChildrenLoaded)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
await SyncChildrenAsync(node).ConfigureAwait(true);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SyncChildrenAsync(NavNodeViewModel node)
|
||||
{
|
||||
if (node.IsPlaceholder || node.IsGroup || LocationRoots.IsVirtual(node.Path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var listing = await _browse.ListAsync(node.Path).ConfigureAwait(true);
|
||||
var dirs = listing.Items
|
||||
.Where(i => i.IsDirectory)
|
||||
.OrderBy(i => i.Name, StringComparer.CurrentCultureIgnoreCase)
|
||||
.Take(200)
|
||||
.ToList();
|
||||
|
||||
var previous = node.Children.Where(c => !c.IsPlaceholder).ToList();
|
||||
var next = new List<NavNodeViewModel>(dirs.Count);
|
||||
foreach (var dir in dirs)
|
||||
{
|
||||
var match = previous.FirstOrDefault(c => PathsEqual(c.Path, dir.FullPath));
|
||||
if (match is null)
|
||||
{
|
||||
match = new NavNodeViewModel
|
||||
{
|
||||
Label = dir.DisplayName ?? dir.Name,
|
||||
Path = dir.FullPath
|
||||
};
|
||||
AddPlaceholder(match);
|
||||
}
|
||||
else
|
||||
{
|
||||
match.Label = dir.DisplayName ?? dir.Name;
|
||||
match.Path = dir.FullPath;
|
||||
}
|
||||
|
||||
next.Add(match);
|
||||
}
|
||||
|
||||
node.Children.Clear();
|
||||
foreach (var child in next)
|
||||
{
|
||||
node.Children.Add(child);
|
||||
}
|
||||
|
||||
node.ChildrenLoaded = true;
|
||||
}
|
||||
|
||||
public async Task RevealPathAsync(string path)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path) || Roots.Count == 0)
|
||||
|
||||
Reference in New Issue
Block a user