diff --git a/src/Files.App/ViewModels/ShellViewModel.cs b/src/Files.App/ViewModels/ShellViewModel.cs index 843dd5d96bfe..1891e931047a 100644 --- a/src/Files.App/ViewModels/ShellViewModel.cs +++ b/src/Files.App/ViewModels/ShellViewModel.cs @@ -64,6 +64,12 @@ public sealed partial class ShellViewModel : ObservableObject, IDisposable // Only used for Binding and ApplyFilesAndFoldersChangesAsync, don't manipulate on this! public BulkConcurrentObservableCollection FilesAndFolders { get; } + /// + /// Gets the total count of all enumerated items including those that may be filtered from the display. + /// This represents the actual number of items in the directory, not just the visible ones. + /// + public int TotalItemCount => filesAndFolders?.Count ?? 0; + private LayoutPreferencesManager folderSettings = null; private ListedItem? currentFolder; @@ -2093,7 +2099,7 @@ public async Task CheckCloudDriveSyncStatusAsync(IStorageI else if (matchingStorageItem is BaseStorageFolder folder && folder.Properties != null) return await FilesystemTasks.Wrap(() => folder.Properties.RetrievePropertiesAsync(["System.FreeSpace", "System.Capacity", "System.SFGAOFlags"]).AsTask()); - return null; + return null; } private async Task WatchForStorageFolderChangesAsync(BaseStorageFolder? rootFolder) @@ -2244,6 +2250,7 @@ private void WatchForDirectoryChanges(string path, CloudDriveSyncStatus syncStat do { notifyInfo = ref Unsafe.As(ref buff[offset]); + string? FileName = null; unsafe { diff --git a/src/Files.App/ViewModels/UserControls/Previews/FolderPreviewViewModel.cs b/src/Files.App/ViewModels/UserControls/Previews/FolderPreviewViewModel.cs index f80160e0f2a1..c99e3923eb75 100644 --- a/src/Files.App/ViewModels/UserControls/Previews/FolderPreviewViewModel.cs +++ b/src/Files.App/ViewModels/UserControls/Previews/FolderPreviewViewModel.cs @@ -9,6 +9,8 @@ namespace Files.App.ViewModels.Previews { public sealed class FolderPreviewViewModel { + private readonly IContentPageContext _contentPageContext = Ioc.Default.GetRequiredService(); + public ListedItem Item { get; } public BitmapImage Thumbnail { get; set; } = new(); @@ -25,7 +27,9 @@ private async Task LoadPreviewAndDetailsAsync() { var rootItem = await FilesystemTasks.Wrap(() => DriveHelpers.GetRootFromPathAsync(Item.ItemPath)); Folder = await StorageFileExtensions.DangerousGetFolderFromPathAsync(Item.ItemPath, rootItem); - var items = await Folder.GetItemsAsync(); + + // Get actual item count including hidden files based on user settings + int itemCount = await GetItemCountAsync(); var result = await FileThumbnailHelper.GetIconAsync( Item.ItemPath, @@ -46,7 +50,7 @@ private async Task LoadPreviewAndDetailsAsync() Item.FileDetails = [ - GetFileProperty("PropertyItemCount", items.Count), + GetFileProperty("PropertyItemCount", itemCount), GetFileProperty("PropertyDateModified", info.DateModified), GetFileProperty("PropertyDateCreated", info.DateCreated), GetFileProperty("PropertyParsingPath", Folder.Path), @@ -67,6 +71,72 @@ private async Task LoadPreviewAndDetailsAsync() } } + private async Task GetItemCountAsync() + { + // If this is the current folder being viewed, use ShellViewModel's TotalItemCount + // which includes hidden files when the setting is enabled (same as status bar) + if (_contentPageContext.ShellPage?.ShellViewModel is not null && + _contentPageContext.Folder?.ItemPath == Item.ItemPath) + { + return _contentPageContext.ShellPage.ShellViewModel.TotalItemCount; + } + + // For other folders (e.g., selected folder in the file list), enumerate directly + // This respects the user's "Show hidden files" setting + return await Task.Run(() => CountItemsInFolder(Item.ItemPath)); + } + + private static int CountItemsInFolder(string folderPath) + { + try + { + var userSettingsService = Ioc.Default.GetRequiredService(); + var showHiddenItems = userSettingsService.FoldersSettingsService.ShowHiddenItems; + var showProtectedSystemFiles = userSettingsService.FoldersSettingsService.ShowProtectedSystemFiles; + + int count = 0; + var directory = new DirectoryInfo(folderPath); + + // Count files + foreach (var file in directory.EnumerateFiles()) + { + var isHidden = (file.Attributes & System.IO.FileAttributes.Hidden) != 0; + var isSystem = (file.Attributes & System.IO.FileAttributes.System) != 0; + + // Skip hidden & system files if their respective settings are off + if (isHidden && (!showHiddenItems || (isSystem && !showProtectedSystemFiles))) + continue; + + count++; + } + + // Count directories + foreach (var dir in directory.EnumerateDirectories()) + { + var isHidden = (dir.Attributes & System.IO.FileAttributes.Hidden) != 0; + var isSystem = (dir.Attributes & System.IO.FileAttributes.System) != 0; + + // Skip hidden & system directories if their respective settings are off + if (isHidden && (!showHiddenItems || (isSystem && !showProtectedSystemFiles))) + continue; + + count++; + } + + return count; + } + catch (UnauthorizedAccessException) + { + // If we can't access the folder, return 0 + return 0; + } + catch (Exception) + { + // For any other error, return 0 + return 0; + } + } + private static FileProperty GetFileProperty(string nameResource, object value) => new() { NameResource = nameResource, Value = value }; } diff --git a/src/Files.App/Views/Shells/BaseShellPage.cs b/src/Files.App/Views/Shells/BaseShellPage.cs index 92ff86db40a5..bbe8cdcc2ed9 100644 --- a/src/Files.App/Views/Shells/BaseShellPage.cs +++ b/src/Files.App/Views/Shells/BaseShellPage.cs @@ -223,7 +223,7 @@ protected async void FilesystemViewModel_DirectoryInfoUpdated(object sender, Eve if (ContentPage is null) return; - var directoryItemCountLocalization = Strings.Items.GetLocalizedFormatResource(ShellViewModel.FilesAndFolders.Count); + var directoryItemCountLocalization = Strings.Items.GetLocalizedFormatResource(ShellViewModel.TotalItemCount); BranchItem? headBranch = headBranch = InstanceViewModel.IsGitRepository ? await GitHelpers.GetRepositoryHead(InstanceViewModel.GitRepositoryPath) @@ -265,7 +265,7 @@ protected async void FilesystemViewModel_DirectoryInfoUpdated(object sender, Eve headBranch); } - contentPage.StatusBarViewModel.DirectoryItemCount = $"{ShellViewModel.FilesAndFolders.Count} {directoryItemCountLocalization}"; + contentPage.StatusBarViewModel.DirectoryItemCount = $"{ShellViewModel.TotalItemCount} {directoryItemCountLocalization}"; contentPage.UpdateSelectionSize(); }