Skip to content

Commit f4ddd25

Browse files
authored
Feature: Auto refresh after adding items if no directory watcher is available (#13068)
1 parent b707b56 commit f4ddd25

File tree

6 files changed

+55
-25
lines changed

6 files changed

+55
-25
lines changed

src/Files.App/Actions/FileSystem/CreateShortcutAction.cs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// Copyright (c) 2023 Files Community
22
// Licensed under the MIT License. See the LICENSE.
33

4-
using System.IO;
5-
64
namespace Files.App.Actions
75
{
86
internal class CreateShortcutAction : BaseUIAction, IAction
@@ -30,21 +28,9 @@ public CreateShortcutAction()
3028
context.PropertyChanged += Context_PropertyChanged;
3129
}
3230

33-
public async Task ExecuteAsync()
31+
public Task ExecuteAsync()
3432
{
35-
var currentPath = context.ShellPage?.FilesystemViewModel.WorkingDirectory;
36-
37-
if (App.LibraryManager.TryGetLibrary(currentPath ?? string.Empty, out var library) && !library.IsEmpty)
38-
currentPath = library.DefaultSaveFolder;
39-
40-
foreach (ListedItem selectedItem in context.SelectedItems)
41-
{
42-
var fileName = string.Format("ShortcutCreateNewSuffix".GetLocalizedResource(), selectedItem.Name) + ".lnk";
43-
var filePath = Path.Combine(currentPath ?? string.Empty, fileName);
44-
45-
if (!await FileOperationsHelpers.CreateOrUpdateLinkAsync(filePath, selectedItem.ItemPath))
46-
await UIFilesystemHelpers.HandleShortcutCannotBeCreated(fileName, selectedItem.ItemPath);
47-
}
33+
return UIFilesystemHelpers.CreateShortcutAsync(context.ShellPage, context.SelectedItems);
4834
}
4935

5036
private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e)

src/Files.App/Data/Models/ItemViewModel.cs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,8 @@ public bool AreDirectoriesSortedAlongsideFiles
381381
}
382382
}
383383

384+
public bool HasNoWatcher { get; private set; }
385+
384386
public ItemViewModel(FolderSettingsViewModel folderSettingsViewModel)
385387
{
386388
folderSettings = folderSettingsViewModel;
@@ -1381,7 +1383,8 @@ private async Task RapidAddItemsToCollection(string? path, LibraryItem? library
13811383
IsTypeCloudDrive = syncStatus != CloudDriveSyncStatus.NotSynced && syncStatus != CloudDriveSyncStatus.Unknown,
13821384
IsTypeGitRepository = GitDirectory is not null
13831385
});
1384-
WatchForDirectoryChanges(path, syncStatus);
1386+
if (!HasNoWatcher)
1387+
WatchForDirectoryChanges(path, syncStatus);
13851388
if (GitDirectory is not null)
13861389
WatchForGitChanges();
13871390
break;
@@ -1390,13 +1393,15 @@ private async Task RapidAddItemsToCollection(string? path, LibraryItem? library
13901393
case 1:
13911394
PageTypeUpdated?.Invoke(this, new PageTypeUpdatedEventArgs() { IsTypeCloudDrive = false, IsTypeRecycleBin = isRecycleBin });
13921395
currentStorageFolder ??= await FilesystemTasks.Wrap(() => StorageFileExtensions.DangerousGetFolderWithPathFromPathAsync(path));
1393-
WatchForStorageFolderChanges(currentStorageFolder?.Item);
1396+
if (!HasNoWatcher)
1397+
WatchForStorageFolderChanges(currentStorageFolder?.Item);
13941398
break;
13951399

13961400
// Watch for changes using Win32 in Box Drive folder (#7428) and network drives (#5869)
13971401
case 2:
13981402
PageTypeUpdated?.Invoke(this, new PageTypeUpdatedEventArgs() { IsTypeCloudDrive = false });
1399-
WatchForWin32FolderChanges(path);
1403+
if (!HasNoWatcher)
1404+
WatchForWin32FolderChanges(path);
14001405
break;
14011406

14021407
// Enumeration failed
@@ -1429,14 +1434,16 @@ public void CloseWatcher()
14291434
watcherCTS = new CancellationTokenSource();
14301435
}
14311436

1432-
public async Task<int> EnumerateItemsFromStandardFolderAsync(string path, CancellationToken cancellationToken, LibraryItem? library = null)
1437+
private async Task<int> EnumerateItemsFromStandardFolderAsync(string path, CancellationToken cancellationToken, LibraryItem? library = null)
14331438
{
14341439
// Flag to use FindFirstFileExFromApp or StorageFolder enumeration - Use storage folder for Box Drive (#4629)
14351440
var isBoxFolder = App.CloudDrivesManager.Drives.FirstOrDefault(x => x.Text == "Box")?.Path?.TrimEnd('\\') is string boxFolder && path.StartsWith(boxFolder);
14361441
bool isWslDistro = App.WSLDistroManager.TryGetDistro(path, out _);
1442+
bool isMtp = path.StartsWith(@"\\?\", StringComparison.Ordinal);
1443+
bool isShellFolder = path.StartsWith(@"\\SHELL\", StringComparison.Ordinal);
14371444
bool isNetwork = path.StartsWith(@"\\", StringComparison.Ordinal) &&
1438-
!path.StartsWith(@"\\?\", StringComparison.Ordinal) &&
1439-
!path.StartsWith(@"\\SHELL\", StringComparison.Ordinal) &&
1445+
!isMtp &&
1446+
!isShellFolder &&
14401447
!isWslDistro;
14411448
bool isFtp = FtpHelpers.IsFtpPath(path);
14421449
bool enumFromStorageFolder = isBoxFolder || isFtp;
@@ -1507,6 +1514,8 @@ await DialogDisplayHelper.ShowDialogAsync(
15071514
await ContextMenu.InvokeVerb("unlock-bde", pathRoot);
15081515
}
15091516

1517+
HasNoWatcher = isFtp || isWslDistro || isMtp || currentStorageFolder?.Item is ZipStorageFolder;
1518+
15101519
if (enumFromStorageFolder)
15111520
{
15121521
var basicProps = await rootFolder?.GetBasicPropertiesAsync();

src/Files.App/Helpers/UI/UIFilesystemHelpers.cs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,8 @@ public static async Task PasteItemAsync(string destinationPath, IShellPage assoc
231231
if (packageView && packageView.Result is not null)
232232
{
233233
await associatedInstance.FilesystemHelpers.PerformOperationTypeAsync(packageView.Result.RequestedOperation, packageView, destinationPath, false, true);
234-
associatedInstance?.SlimContentPage?.ItemManipulationModel?.RefreshItemsOpacity();
234+
associatedInstance.SlimContentPage?.ItemManipulationModel?.RefreshItemsOpacity();
235+
await associatedInstance.RefreshIfNoWatcherExists();
235236
}
236237
}
237238

@@ -264,6 +265,7 @@ public static async Task<bool> RenameFileItemAsync(ListedItem item, string newNa
264265
if (renamed == ReturnResult.Success)
265266
{
266267
associatedInstance.ToolbarViewModel.CanGoForward = false;
268+
await associatedInstance.RefreshIfNoWatcherExists();
267269
return true;
268270
}
269271

@@ -273,9 +275,10 @@ public static async Task<bool> RenameFileItemAsync(ListedItem item, string newNa
273275
public static async Task CreateFileFromDialogResultType(AddItemDialogItemType itemType, ShellNewEntry? itemInfo, IShellPage associatedInstance)
274276
{
275277
await CreateFileFromDialogResultTypeForResult(itemType, itemInfo, associatedInstance);
278+
await associatedInstance.RefreshIfNoWatcherExists();
276279
}
277280

278-
public static async Task<IStorageItem?> CreateFileFromDialogResultTypeForResult(AddItemDialogItemType itemType, ShellNewEntry? itemInfo, IShellPage associatedInstance)
281+
private static async Task<IStorageItem?> CreateFileFromDialogResultTypeForResult(AddItemDialogItemType itemType, ShellNewEntry? itemInfo, IShellPage associatedInstance)
279282
{
280283
string? currentPath = null;
281284

@@ -346,6 +349,7 @@ public static async Task CreateFolderWithSelectionAsync(IShellPage associatedIns
346349
return;
347350

348351
await associatedInstance.FilesystemHelpers.MoveItemsAsync(items, items.Select(x => PathNormalization.Combine(folder.Path, x.Name)), false, true);
352+
await associatedInstance.RefreshIfNoWatcherExists();
349353
}
350354
catch (Exception ex)
351355
{
@@ -365,6 +369,26 @@ public static void SetHiddenAttributeItem(ListedItem item, bool isHidden, ItemMa
365369
itemManipulationModel.RefreshItemsOpacity();
366370
}
367371

372+
public static async Task CreateShortcutAsync(IShellPage? associatedInstance, IReadOnlyList<ListedItem> selectedItems)
373+
{
374+
var currentPath = associatedInstance?.FilesystemViewModel.WorkingDirectory;
375+
376+
if (App.LibraryManager.TryGetLibrary(currentPath ?? string.Empty, out var library) && !library.IsEmpty)
377+
currentPath = library.DefaultSaveFolder;
378+
379+
foreach (ListedItem selectedItem in selectedItems)
380+
{
381+
var fileName = string.Format("ShortcutCreateNewSuffix".GetLocalizedResource(), selectedItem.Name) + ".lnk";
382+
var filePath = Path.Combine(currentPath ?? string.Empty, fileName);
383+
384+
if (!await FileOperationsHelpers.CreateOrUpdateLinkAsync(filePath, selectedItem.ItemPath))
385+
await HandleShortcutCannotBeCreated(fileName, selectedItem.ItemPath);
386+
}
387+
388+
if (associatedInstance is not null)
389+
await associatedInstance.RefreshIfNoWatcherExists();
390+
}
391+
368392
public static async Task CreateShortcutFromDialogAsync(IShellPage associatedInstance)
369393
{
370394
var currentPath = associatedInstance.FilesystemViewModel.WorkingDirectory;
@@ -382,6 +406,8 @@ public static async Task CreateShortcutFromDialogAsync(IShellPage associatedInst
382406
return;
383407

384408
await HandleShortcutCannotBeCreated(viewModel.ShortcutCompleteName, viewModel.DestinationItemPath);
409+
410+
await associatedInstance.RefreshIfNoWatcherExists();
385411
}
386412

387413
public static async Task<bool> HandleShortcutCannotBeCreated(string shortcutName, string destinationPath)

src/Files.App/ViewModels/LayoutModes/BaseLayoutViewModel.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ public async Task Drop(DragEventArgs e)
170170
{
171171
await _associatedInstance.FilesystemHelpers.PerformOperationTypeAsync(e.AcceptedOperation, e.DataView, _associatedInstance.FilesystemViewModel.WorkingDirectory, false, true);
172172
e.Handled = true;
173+
174+
await _associatedInstance.RefreshIfNoWatcherExists();
173175
}
174176

175177
deferral.Complete();

src/Files.App/Views/Shells/BaseShellPage.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Licensed under the MIT License. See the LICENSE.
33

44
using Files.App.UserControls.MultitaskingControl;
5-
using Files.Core.Services;
65
using Microsoft.UI.Input;
76
using Microsoft.UI.Xaml;
87
using Microsoft.UI.Xaml.Controls;
@@ -487,6 +486,12 @@ public Task TabItemDrop(object sender, DragEventArgs e)
487486
return SlimContentPage?.CommandsViewModel.Drop(e);
488487
}
489488

489+
public async Task RefreshIfNoWatcherExists()
490+
{
491+
if (FilesystemViewModel.HasNoWatcher)
492+
await Refresh_Click();
493+
}
494+
490495
public async Task Refresh_Click()
491496
{
492497
if (InstanceViewModel.IsPageTypeSearchResults)

src/Files.App/Views/Shells/IShellPage.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ public interface IShellPage : ITabItemContent, IMultiPaneInfo, IDisposable, INot
2525

2626
bool CanNavigateForward { get; }
2727

28+
Task RefreshIfNoWatcherExists();
29+
2830
Task Refresh_Click();
2931

3032
void Back_Click();

0 commit comments

Comments
 (0)