diff --git a/src/Files.App/Strings/en-US/Resources.resw b/src/Files.App/Strings/en-US/Resources.resw index 266665c3a502..0612d6a14ba4 100644 --- a/src/Files.App/Strings/en-US/Resources.resw +++ b/src/Files.App/Strings/en-US/Resources.resw @@ -3487,6 +3487,9 @@ Processing items... + + Discovery in progress... + Speed: @@ -3618,6 +3621,10 @@ Copying {0, plural, one {# item} other {# items}} from "{1}" to "{2}" Shown in a StatusCenter card. + + Discovered {0, plural, one {# item} other {# items}} + Shown in a StatusCenter card during file discovery phase. + Canceled extracting "{0}" to "{1}" Shown in a StatusCenter card. @@ -3670,6 +3677,10 @@ Deleting {0, plural, one {# item} other {# items}} from "{1}" Shown in a StatusCenter card. + + Discovered {0, plural, one {# item} other {# items}} + Shown in a StatusCenter card during file discovery phase. + Canceled moving {0, plural, one {# item} other {# items}} to "{1}" Shown in a StatusCenter card. @@ -3694,6 +3705,10 @@ Moving {0, plural, one {# item} other {# items}} from "{1}" to "{2}" Shown in a StatusCenter card. + + Discovered {0, plural, one {# item} other {# items}} + Shown in a StatusCenter card during file discovery phase. + Error moving {0, plural, one {# item} other {# items}} to "{1}" Shown in a StatusCenter card. diff --git a/src/Files.App/Utils/StatusCenter/StatusCenterHelper.cs b/src/Files.App/Utils/StatusCenter/StatusCenterHelper.cs index 8669ba974e38..5bf5dc8c7182 100644 --- a/src/Files.App/Utils/StatusCenter/StatusCenterHelper.cs +++ b/src/Files.App/Utils/StatusCenter/StatusCenterHelper.cs @@ -611,7 +611,7 @@ public static StatusCenterItem AddCard_Prepare() false); } - public static void UpdateCardStrings(StatusCenterItem card) + public static void UpdateCardStrings(StatusCenterItem card, StatusCenterItemProgressModel? progressValue = null) { // Aren't used for now string sourcePath = string.Empty; @@ -645,9 +645,17 @@ public static void UpdateCardStrings(StatusCenterItem card) { case FileOperationType.Copy: { - string headerString = string.IsNullOrWhiteSpace(card.HeaderStringResource) ? string.Empty - : card.HeaderStringResource.GetLocalizedFormatResource(card.TotalItemsCount, destinationDirName); - card.Header = headerString; + string headerResource = card.HeaderStringResource; + + if (card.IsDiscovering && card.TotalItemsCount > 0 && card.IsInProgress) + headerResource = "StatusCenter_CopyDiscovery_Header"; + + if (string.IsNullOrWhiteSpace(headerResource)) + card.Header = string.Empty; + else if (headerResource == "StatusCenter_CopyDiscovery_Header") + card.Header = headerResource.GetLocalizedFormatResource(card.TotalItemsCount); + else + card.Header = headerResource.GetLocalizedFormatResource(card.TotalItemsCount, destinationDirName); string subHeaderString = string.IsNullOrWhiteSpace(card.SubHeaderStringResource) ? string.Empty : card.SubHeaderStringResource.GetLocalizedFormatResource(card.TotalItemsCount, sourcePath, destinationPath); @@ -656,9 +664,17 @@ public static void UpdateCardStrings(StatusCenterItem card) } case FileOperationType.Move: { - string headerString = string.IsNullOrWhiteSpace(card.HeaderStringResource) ? string.Empty - : card.HeaderStringResource.GetLocalizedFormatResource(card.TotalItemsCount, destinationDirName); - card.Header = headerString; + string headerResource = card.HeaderStringResource; + + if (card.IsDiscovering && card.TotalItemsCount > 0 && card.IsInProgress) + headerResource = "StatusCenter_MoveDiscovery_Header"; + + if (string.IsNullOrWhiteSpace(headerResource)) + card.Header = string.Empty; + else if (headerResource == "StatusCenter_MoveDiscovery_Header") + card.Header = headerResource.GetLocalizedFormatResource(card.TotalItemsCount); + else + card.Header = headerResource.GetLocalizedFormatResource(card.TotalItemsCount, destinationDirName); string subHeaderString = string.IsNullOrWhiteSpace(card.SubHeaderStringResource) ? string.Empty : card.SubHeaderStringResource.GetLocalizedFormatResource(card.TotalItemsCount, sourcePath, destinationPath); @@ -667,9 +683,17 @@ public static void UpdateCardStrings(StatusCenterItem card) } case FileOperationType.Delete: { - string headerString = string.IsNullOrWhiteSpace(card.HeaderStringResource) ? string.Empty - : card.HeaderStringResource.GetLocalizedFormatResource(card.TotalItemsCount, sourceDirName); - card.Header = headerString; + string headerResource = card.HeaderStringResource; + + if (card.IsDiscovering && card.TotalItemsCount > 0 && card.IsInProgress) + headerResource = "StatusCenter_DeleteDiscovery_Header"; + + if (string.IsNullOrWhiteSpace(headerResource)) + card.Header = string.Empty; + else if (headerResource == "StatusCenter_DeleteDiscovery_Header") + card.Header = headerResource.GetLocalizedFormatResource(card.TotalItemsCount); + else + card.Header = headerResource.GetLocalizedFormatResource(card.TotalItemsCount, sourceDirName); string subHeaderString = string.IsNullOrWhiteSpace(card.SubHeaderStringResource) ? string.Empty : card.SubHeaderStringResource.GetLocalizedFormatResource(card.TotalItemsCount, sourcePath); diff --git a/src/Files.App/Utils/StatusCenter/StatusCenterItem.cs b/src/Files.App/Utils/StatusCenter/StatusCenterItem.cs index f715fd7e94a4..dbd1b0b6b472 100644 --- a/src/Files.App/Utils/StatusCenter/StatusCenterItem.cs +++ b/src/Files.App/Utils/StatusCenter/StatusCenterItem.cs @@ -147,6 +147,8 @@ public StatusCenterItemProgressModel Progress public bool IsInProgress { get; private set; } + public bool IsDiscovering { get; private set; } = true; + public IEnumerable? Source { get; private set; } public IEnumerable? Destination { get; private set; } @@ -199,7 +201,7 @@ public StatusCenterItem( AnimatedIconState = "NormalOff"; SpeedGraphValues = []; CancelCommand = new RelayCommand(ExecuteCancelCommand); - Message = Strings.ProcessingItems.GetLocalizedResource(); + Message = Strings.DiscoveringItems.GetLocalizedResource(); Source = source; Destination = destination; @@ -327,8 +329,14 @@ private void ReportProgress(StatusCenterItemProgressModel value) if (TotalSize < value.TotalSize) TotalSize = value.TotalSize; + if (value.EnumerationCompleted && IsDiscovering) + { + IsDiscovering = false; + Message = Strings.ProcessingItems.GetLocalizedResource(); + } + // Update UI for strings - StatusCenterHelper.UpdateCardStrings(this); + StatusCenterHelper.UpdateCardStrings(this, value); OnPropertyChanged(nameof(HeaderTooltip)); // Graph item point @@ -382,7 +390,7 @@ private void ReportProgress(StatusCenterItemProgressModel value) SpeedGraphValues?.Add(point); // Add percentage to the header - if (!IsIndeterminateProgress) + if (!IsIndeterminateProgress && value.EnumerationCompleted) Header = $"{Header} ({ProgressPercentage}%)"; // Update UI of the address bar diff --git a/src/Files.App/Utils/Storage/Operations/FileOperationsHelpers.cs b/src/Files.App/Utils/Storage/Operations/FileOperationsHelpers.cs index 870a8d2563ad..b6e109e0fc64 100644 --- a/src/Files.App/Utils/Storage/Operations/FileOperationsHelpers.cs +++ b/src/Files.App/Utils/Storage/Operations/FileOperationsHelpers.cs @@ -207,6 +207,14 @@ public static Task SetClipboard(string[] filesToCopy, DataPackageOperation opera var cts = new CancellationTokenSource(); var sizeCalculator = new FileSizeCalculator(fileToDeletePath); + + // Track the count and update the progress + sizeCalculator.ItemsCountChanged += (newCount) => + { + fsProgress.ItemsCount = newCount; + fsProgress.Report(); + }; + var sizeTask = sizeCalculator.ComputeSizeAsync(cts.Token); sizeTask.ContinueWith(_ => { @@ -405,6 +413,14 @@ public static Task SetClipboard(string[] filesToCopy, DataPackageOperation opera var cts = new CancellationTokenSource(); var sizeCalculator = new FileSizeCalculator(fileToMovePath); + + // Track the count and update the progress + sizeCalculator.ItemsCountChanged += (newCount) => + { + fsProgress.ItemsCount = newCount; + fsProgress.Report(); + }; + var sizeTask = sizeCalculator.ComputeSizeAsync(cts.Token); sizeTask.ContinueWith(_ => { @@ -533,6 +549,14 @@ public static Task SetClipboard(string[] filesToCopy, DataPackageOperation opera var cts = new CancellationTokenSource(); var sizeCalculator = new FileSizeCalculator(fileToCopyPath); + + // Track the count and update the progress + sizeCalculator.ItemsCountChanged += (newCount) => + { + fsProgress.ItemsCount = newCount; + fsProgress.Report(); + }; + var sizeTask = sizeCalculator.ComputeSizeAsync(cts.Token); sizeTask.ContinueWith(_ => { diff --git a/src/Files.App/Utils/Storage/Operations/FileSizeCalculator.cs b/src/Files.App/Utils/Storage/Operations/FileSizeCalculator.cs index 3e60af00da9b..a260e315ebfb 100644 --- a/src/Files.App/Utils/Storage/Operations/FileSizeCalculator.cs +++ b/src/Files.App/Utils/Storage/Operations/FileSizeCalculator.cs @@ -18,6 +18,8 @@ internal sealed class FileSizeCalculator public int ItemsCount => _computedFiles.Count; public bool Completed { get; private set; } + public event Action? ItemsCountChanged; + public FileSizeCalculator(params string[] paths) { _paths = paths; @@ -118,7 +120,10 @@ private long ComputeFileSize(string path) null); if (!hFile.IsInvalid && PInvoke.GetFileSizeEx(hFile, out size) && _computedFiles.TryAdd(path, size)) + { Interlocked.Add(ref _size, size); + ItemsCountChanged?.Invoke(ItemsCount); + } return size; } diff --git a/src/Files.App/Utils/Storage/Operations/ShellFilesystemOperations.cs b/src/Files.App/Utils/Storage/Operations/ShellFilesystemOperations.cs index e512d9c39978..1db895210523 100644 --- a/src/Files.App/Utils/Storage/Operations/ShellFilesystemOperations.cs +++ b/src/Files.App/Utils/Storage/Operations/ShellFilesystemOperations.cs @@ -49,7 +49,7 @@ public async Task CopyItemsAsync(IList so StatusCenterItemProgressModel fsProgress = new( progress, - true, + false, FileSystemStatusCode.InProgress, source.Count);