mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
[Peek]Asynchronously display correct folder size (#31504)
* asynchronously display correct folder size * use async
This commit is contained in:
committed by
GitHub
parent
79de69547e
commit
1f9fd2631c
@@ -102,32 +102,6 @@ namespace Peek.Common.Extensions
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ulong GetSizeInBytes(this IFileSystemItem item)
|
|
||||||
{
|
|
||||||
ulong sizeInBytes = 0;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
switch (item)
|
|
||||||
{
|
|
||||||
case FolderItem _:
|
|
||||||
FileSystemObject fileSystemObject = new FileSystemObject();
|
|
||||||
Folder folder = fileSystemObject.GetFolder(item.Path);
|
|
||||||
sizeInBytes = (ulong)folder.Size;
|
|
||||||
break;
|
|
||||||
case FileItem _:
|
|
||||||
sizeInBytes = item.FileSizeBytes;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
sizeInBytes = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sizeInBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task<string> GetContentTypeAsync(this IFileSystemItem item)
|
public static async Task<string> GetContentTypeAsync(this IFileSystemItem item)
|
||||||
{
|
{
|
||||||
string contentType = string.Empty;
|
string contentType = string.Empty;
|
||||||
|
|||||||
@@ -349,9 +349,7 @@ namespace Peek.FilePreviewer
|
|||||||
string dateModifiedFormatted = string.IsNullOrEmpty(dateModified) ? string.Empty : "\n" + ReadableStringHelper.FormatResourceString("PreviewTooltip_DateModified", dateModified);
|
string dateModifiedFormatted = string.IsNullOrEmpty(dateModified) ? string.Empty : "\n" + ReadableStringHelper.FormatResourceString("PreviewTooltip_DateModified", dateModified);
|
||||||
sb.Append(dateModifiedFormatted);
|
sb.Append(dateModifiedFormatted);
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
string fileSize = ReadableStringHelper.BytesToReadableString(Item.FileSizeBytes);
|
||||||
ulong bytes = await Task.Run(Item.GetSizeInBytes);
|
|
||||||
string fileSize = ReadableStringHelper.BytesToReadableString(bytes);
|
|
||||||
string fileSizeFormatted = string.IsNullOrEmpty(fileSize) ? string.Empty : "\n" + ReadableStringHelper.FormatResourceString("PreviewTooltip_FileSize", fileSize);
|
string fileSizeFormatted = string.IsNullOrEmpty(fileSize) ? string.Empty : "\n" + ReadableStringHelper.FormatResourceString("PreviewTooltip_FileSize", fileSize);
|
||||||
sb.Append(fileSizeFormatted);
|
sb.Append(fileSizeFormatted);
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,13 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using ManagedCommon;
|
||||||
using Microsoft.UI.Dispatching;
|
using Microsoft.UI.Dispatching;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
using Microsoft.UI.Xaml.Media.Imaging;
|
using Microsoft.UI.Xaml.Media.Imaging;
|
||||||
using Peek.Common.Extensions;
|
using Peek.Common.Extensions;
|
||||||
using Peek.Common.Helpers;
|
using Peek.Common.Helpers;
|
||||||
@@ -20,6 +23,11 @@ namespace Peek.FilePreviewer.Previewers
|
|||||||
{
|
{
|
||||||
public partial class UnsupportedFilePreviewer : ObservableObject, IUnsupportedFilePreviewer, IDisposable
|
public partial class UnsupportedFilePreviewer : ObservableObject, IUnsupportedFilePreviewer, IDisposable
|
||||||
{
|
{
|
||||||
|
private static readonly EnumerationOptions _fileEnumOptions = new() { MatchType = MatchType.Win32, AttributesToSkip = 0, IgnoreInaccessible = true };
|
||||||
|
private static readonly EnumerationOptions _directoryEnumOptions = new() { MatchType = MatchType.Win32, AttributesToSkip = FileAttributes.ReparsePoint, IgnoreInaccessible = true };
|
||||||
|
private readonly DispatcherTimer _folderSizeDispatcherTimer = new();
|
||||||
|
private ulong _folderSize;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private UnsupportedFilePreviewData preview = new UnsupportedFilePreviewData();
|
private UnsupportedFilePreviewData preview = new UnsupportedFilePreviewData();
|
||||||
|
|
||||||
@@ -28,6 +36,9 @@ namespace Peek.FilePreviewer.Previewers
|
|||||||
|
|
||||||
public UnsupportedFilePreviewer(IFileSystemItem file)
|
public UnsupportedFilePreviewer(IFileSystemItem file)
|
||||||
{
|
{
|
||||||
|
_folderSizeDispatcherTimer.Interval = TimeSpan.FromMilliseconds(500);
|
||||||
|
_folderSizeDispatcherTimer.Tick += FolderSizeDispatcherTimer_Tick;
|
||||||
|
|
||||||
Item = file;
|
Item = file;
|
||||||
Preview.FileName = file.Name;
|
Preview.FileName = file.Name;
|
||||||
Preview.DateModified = file.DateModified?.ToString(CultureInfo.CurrentCulture);
|
Preview.DateModified = file.DateModified?.ToString(CultureInfo.CurrentCulture);
|
||||||
@@ -46,6 +57,7 @@ namespace Peek.FilePreviewer.Previewers
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
_folderSizeDispatcherTimer.Tick -= FolderSizeDispatcherTimer_Tick;
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,21 +129,25 @@ namespace Peek.FilePreviewer.Previewers
|
|||||||
|
|
||||||
var isTaskSuccessful = await TaskExtension.RunSafe(async () =>
|
var isTaskSuccessful = await TaskExtension.RunSafe(async () =>
|
||||||
{
|
{
|
||||||
// File Properties
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
|
||||||
|
|
||||||
var bytes = await Task.Run(Item.GetSizeInBytes);
|
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
var type = await Task.Run(Item.GetContentTypeAsync);
|
var type = await Task.Run(Item.GetContentTypeAsync);
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
var readableFileSize = ReadableStringHelper.BytesToReadableString(bytes);
|
|
||||||
|
|
||||||
isDisplayValid = type != null;
|
isDisplayValid = type != null;
|
||||||
|
|
||||||
|
var readableFileSize = string.Empty;
|
||||||
|
|
||||||
|
if (Item is FileItem)
|
||||||
|
{
|
||||||
|
readableFileSize = ReadableStringHelper.BytesToReadableString(Item.FileSizeBytes);
|
||||||
|
}
|
||||||
|
else if (Item is FolderItem)
|
||||||
|
{
|
||||||
|
ComputeFolderSize(cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
await Dispatcher.RunOnUiThread(() =>
|
await Dispatcher.RunOnUiThread(() =>
|
||||||
{
|
{
|
||||||
Preview.FileSize = readableFileSize;
|
Preview.FileSize = readableFileSize;
|
||||||
@@ -150,5 +166,71 @@ namespace Peek.FilePreviewer.Previewers
|
|||||||
|
|
||||||
return !isLoadingIconPreviewSuccessful || !isLoadingDisplayInfoSuccessful;
|
return !isLoadingIconPreviewSuccessful || !isLoadingDisplayInfoSuccessful;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ComputeFolderSize(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
Task.Run(
|
||||||
|
async () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Special folders like recycle bin don't have a path
|
||||||
|
if (string.IsNullOrWhiteSpace(Item.Path))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await Dispatcher.RunOnUiThread(_folderSizeDispatcherTimer.Start);
|
||||||
|
GetDirectorySize(new DirectoryInfo(Item.Path), cancellationToken);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.LogError("Failed to calculate folder size", ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
await Dispatcher.RunOnUiThread(_folderSizeDispatcherTimer.Stop);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If everything went well, ensure the UI is updated
|
||||||
|
await Dispatcher.RunOnUiThread(UpdateFolderSize);
|
||||||
|
},
|
||||||
|
cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GetDirectorySize(DirectoryInfo directory, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var files = directory.GetFiles("*", _fileEnumOptions);
|
||||||
|
for (var i = 0; i < files.Length; i++)
|
||||||
|
{
|
||||||
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
var f = files[i];
|
||||||
|
if (f.Length > 0)
|
||||||
|
{
|
||||||
|
_folderSize += Convert.ToUInt64(f.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var directories = directory.GetDirectories("*", _directoryEnumOptions);
|
||||||
|
for (var i = 0; i < directories.Length; i++)
|
||||||
|
{
|
||||||
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
GetDirectorySize(directories[i], cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateFolderSize()
|
||||||
|
{
|
||||||
|
Preview.FileSize = ReadableStringHelper.BytesToReadableString(_folderSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FolderSizeDispatcherTimer_Tick(object? sender, object e)
|
||||||
|
{
|
||||||
|
UpdateFolderSize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -339,14 +339,23 @@ namespace Peek.UI.Views
|
|||||||
|
|
||||||
private void UpdateDefaultAppToLaunch()
|
private void UpdateDefaultAppToLaunch()
|
||||||
{
|
{
|
||||||
// Update the name of default app to launch
|
if (Item is FileItem)
|
||||||
DefaultAppName = DefaultAppHelper.TryGetDefaultAppName(Item.Extension);
|
{
|
||||||
|
// Update the name of default app to launch
|
||||||
|
DefaultAppName = DefaultAppHelper.TryGetDefaultAppName(Item.Extension);
|
||||||
|
|
||||||
string openWithAppTextFormat = ResourceLoaderInstance.ResourceLoader.GetString("LaunchAppButton_OpenWithApp_Text");
|
string openWithAppTextFormat = ResourceLoaderInstance.ResourceLoader.GetString("LaunchAppButton_OpenWithApp_Text");
|
||||||
OpenWithAppText = string.Format(CultureInfo.InvariantCulture, openWithAppTextFormat, DefaultAppName);
|
OpenWithAppText = string.Format(CultureInfo.InvariantCulture, openWithAppTextFormat, DefaultAppName);
|
||||||
|
|
||||||
string openWithAppToolTipFormat = ResourceLoaderInstance.ResourceLoader.GetString("LaunchAppButton_OpenWithApp_ToolTip");
|
string openWithAppToolTipFormat = ResourceLoaderInstance.ResourceLoader.GetString("LaunchAppButton_OpenWithApp_ToolTip");
|
||||||
OpenWithAppToolTip = string.Format(CultureInfo.InvariantCulture, openWithAppToolTipFormat, DefaultAppName);
|
OpenWithAppToolTip = string.Format(CultureInfo.InvariantCulture, openWithAppToolTipFormat, DefaultAppName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DefaultAppName = string.Empty;
|
||||||
|
OpenWithAppText = string.Empty;
|
||||||
|
OpenWithAppToolTip = string.Empty;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user