diff --git a/src/Files.App/Data/Models/RemovableDevice.cs b/src/Files.App/Data/Models/RemovableDevice.Windows.cs similarity index 100% rename from src/Files.App/Data/Models/RemovableDevice.cs rename to src/Files.App/Data/Models/RemovableDevice.Windows.cs diff --git a/src/Files.App/Files.App.csproj b/src/Files.App/Files.App.csproj index c4584b8d98c4..82dd3eb7800d 100644 --- a/src/Files.App/Files.App.csproj +++ b/src/Files.App/Files.App.csproj @@ -245,6 +245,7 @@ + diff --git a/src/Files.App/Utils/Storage/Helpers/SyncRootHelpers.Linux.cs b/src/Files.App/Utils/Storage/Helpers/SyncRootHelpers.Linux.cs new file mode 100644 index 000000000000..c1278b42223e --- /dev/null +++ b/src/Files.App/Utils/Storage/Helpers/SyncRootHelpers.Linux.cs @@ -0,0 +1,12 @@ +// Copyright (c) Files Community +// Licensed under the MIT License. + +namespace Files.App.Utils.Storage +{ + internal static class SyncRootHelpers + { + // LINUX-TODO(cloud): Windows cloud sync roots have no Linux equivalent; report no quota. + public static Task<(bool Success, ulong Capacity, ulong Used)> GetSyncRootQuotaAsync(string path) + => Task.FromResult((false, 0ul, 0ul)); + } +} diff --git a/src/Files.App/Utils/Storage/Helpers/SyncRootHelpers.cs b/src/Files.App/Utils/Storage/Helpers/SyncRootHelpers.Windows.cs similarity index 100% rename from src/Files.App/Utils/Storage/Helpers/SyncRootHelpers.cs rename to src/Files.App/Utils/Storage/Helpers/SyncRootHelpers.Windows.cs diff --git a/src/Files.App/ViewModels/UserControls/NavigationToolbarViewModel.Windows.cs b/src/Files.App/ViewModels/UserControls/NavigationToolbarViewModel.Windows.cs new file mode 100644 index 000000000000..7e6304367e39 --- /dev/null +++ b/src/Files.App/ViewModels/UserControls/NavigationToolbarViewModel.Windows.cs @@ -0,0 +1,63 @@ +// Copyright (c) Files Community +// Licensed under the MIT License. + +using Files.Shared.Helpers; +using System.IO; +using Windows.Win32; +using Windows.Win32.Storage.FileSystem; + +namespace Files.App.ViewModels.UserControls +{ + public sealed partial class NavigationToolbarViewModel + { + /// + /// Enumerates subfolders using Win32 API, including hidden folders based on user settings. + /// Returns null if the path cannot be enumerated with Win32. + /// + private unsafe List<(string Name, string Path, bool IsHidden)>? GetSubfolders(string parentPath) + { + WIN32_FIND_DATAW findData = default; + using FindCloseSafeHandle hFile = PInvoke.FindFirstFileEx( + $"{parentPath}{Path.DirectorySeparatorChar}*.*", + FINDEX_INFO_LEVELS.FindExInfoBasic, + &findData, + FINDEX_SEARCH_OPS.FindExSearchNameMatch, + FIND_FIRST_EX_FLAGS.FIND_FIRST_EX_LARGE_FETCH); + + if (hFile.IsInvalid) + return null; + + var showHidden = UserSettingsService.FoldersSettingsService.ShowHiddenItems; + var showSystem = UserSettingsService.FoldersSettingsService.ShowProtectedSystemFiles; + var showDot = UserSettingsService.FoldersSettingsService.ShowDotFiles; + var folders = new List<(string Name, string Path, bool IsHidden)>(); + + do + { + if (((FileAttributes)findData.dwFileAttributes & FileAttributes.Directory) == 0) + continue; + + string fileName = findData.cFileName.ToString(); + if (fileName is "." or "..") + continue; + + bool isHidden = ((FileAttributes)findData.dwFileAttributes & FileAttributes.Hidden) != 0; + bool isSystem = ((FileAttributes)findData.dwFileAttributes & FileAttributes.System) != 0; + + if (isHidden && (!showHidden || (isSystem && !showSystem))) + continue; + + if (fileName.StartsWith('.') && !showDot) + continue; + + folders.Add((fileName, Path.Combine(parentPath, fileName), isHidden)); + } + while (PInvoke.FindNextFile(hFile, out findData)); + + var naturalComparer = NaturalStringComparer.GetForProcessor(); + folders.Sort((a, b) => naturalComparer.Compare(a.Name, b.Name)); + + return folders; + } + } +} diff --git a/src/Files.App/ViewModels/UserControls/NavigationToolbarViewModel.cs b/src/Files.App/ViewModels/UserControls/NavigationToolbarViewModel.cs index 0117efa57cbc..03ca6d89c6b0 100644 --- a/src/Files.App/ViewModels/UserControls/NavigationToolbarViewModel.cs +++ b/src/Files.App/ViewModels/UserControls/NavigationToolbarViewModel.cs @@ -14,8 +14,6 @@ using System.Windows.Input; using Windows.ApplicationModel.DataTransfer; using WinRT; -using Windows.Win32; -using Windows.Win32.Storage.FileSystem; namespace Files.App.ViewModels.UserControls { @@ -712,7 +710,11 @@ public async Task SetPathBoxDropDownFlyoutAsync(MenuFlyout flyout, PathBoxItem p var path = pathItem.Path ?? throw new InvalidOperationException("The path box item does not have a path."); +#if WINDOWS var childFolders = OperatingSystem.IsWindows() ? GetSubfolders(path) : await GetSubfoldersAsync(path); +#else + var childFolders = await GetSubfoldersAsync(path); +#endif // Fall back to StorageFolder API for non-filesystem paths (e.g. FTP) if (childFolders is null) @@ -827,56 +829,6 @@ public async Task SetPathBoxDropDownFlyoutAsync(MenuFlyout flyout, PathBoxItem p } } - /// - /// Enumerates subfolders using Win32 API, including hidden folders based on user settings. - /// Returns null if the path cannot be enumerated with Win32. - /// - private unsafe List<(string Name, string Path, bool IsHidden)>? GetSubfolders(string parentPath) - { - WIN32_FIND_DATAW findData = default; - using FindCloseSafeHandle hFile = PInvoke.FindFirstFileEx( - $"{parentPath}{Path.DirectorySeparatorChar}*.*", - FINDEX_INFO_LEVELS.FindExInfoBasic, - &findData, - FINDEX_SEARCH_OPS.FindExSearchNameMatch, - FIND_FIRST_EX_FLAGS.FIND_FIRST_EX_LARGE_FETCH); - - if (hFile.IsInvalid) - return null; - - var showHidden = UserSettingsService.FoldersSettingsService.ShowHiddenItems; - var showSystem = UserSettingsService.FoldersSettingsService.ShowProtectedSystemFiles; - var showDot = UserSettingsService.FoldersSettingsService.ShowDotFiles; - var folders = new List<(string Name, string Path, bool IsHidden)>(); - - do - { - if (((FileAttributes)findData.dwFileAttributes & FileAttributes.Directory) == 0) - continue; - - string fileName = findData.cFileName.ToString(); - if (fileName is "." or "..") - continue; - - bool isHidden = ((FileAttributes)findData.dwFileAttributes & FileAttributes.Hidden) != 0; - bool isSystem = ((FileAttributes)findData.dwFileAttributes & FileAttributes.System) != 0; - - if (isHidden && (!showHidden || (isSystem && !showSystem))) - continue; - - if (fileName.StartsWith('.') && !showDot) - continue; - - folders.Add((fileName, Path.Combine(parentPath, fileName), isHidden)); - } - while (PInvoke.FindNextFile(hFile, out findData)); - - var naturalComparer = NaturalStringComparer.GetForProcessor(); - folders.Sort((a, b) => naturalComparer.Compare(a.Name, b.Name)); - - return folders; - } - private async Task LoadFlyoutItemIconAsync(MenuFlyoutItem flyoutItem, string path) { var imageSource = await NavigationHelpers.GetIconForPathAsync(path);