Skip to content

Commit bf110dc

Browse files
committed
fixing and improving pages
1 parent c6d623c commit bf110dc

13 files changed

Lines changed: 752 additions & 205 deletions

File tree

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System;
2+
3+
namespace TidyWindow.App.Helpers;
4+
5+
public static class ByteSizeFormatter
6+
{
7+
/// <summary>
8+
/// Formats a byte count into a human-friendly string using a base of 1024 with up to one decimal place.
9+
/// </summary>
10+
public static string FormatBytes(long bytes)
11+
{
12+
if (bytes <= 0)
13+
{
14+
return "0 B";
15+
}
16+
17+
var units = new[] { "B", "KB", "MB", "GB", "TB", "PB" };
18+
var value = (double)bytes;
19+
var unitIndex = 0;
20+
21+
while (value >= 1024 && unitIndex < units.Length - 1)
22+
{
23+
value /= 1024;
24+
unitIndex++;
25+
}
26+
27+
return unitIndex == 0
28+
? $"{bytes} {units[unitIndex]}"
29+
: $"{value:0.#} {units[unitIndex]}";
30+
}
31+
}

src/TidyWindow.App/ViewModels/CleanupViewModel.cs

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using System.Text;
1111
using System.Threading;
1212
using System.Threading.Tasks;
13+
using System.Windows.Threading;
1314
using CommunityToolkit.Mvvm.ComponentModel;
1415
using CommunityToolkit.Mvvm.Input;
1516
using TidyWindow.App.Services;
@@ -217,7 +218,7 @@ public sealed partial class CleanupViewModel : ViewModelBase
217218
private const int DefaultPreviewCount = 50;
218219
private const int MaxLockInspectionItemsPerCategory = 32;
219220
private const int MaxLockInspectionSampleTotal = 600;
220-
private const int PreviewUiYieldInterval = 6;
221+
private const int PreviewUiYieldInterval = 3;
221222

222223
private readonly CleanupPreviewFilter _previewFilter;
223224
private readonly PreviewPagingController _previewPagingController;
@@ -349,6 +350,9 @@ public CleanupViewModel(
349350
[ObservableProperty]
350351
private bool _isBusy;
351352

353+
[ObservableProperty]
354+
private bool _isDeletionPreparationInProgress;
355+
352356
[ObservableProperty]
353357
private string _headline = "Preview and clean up system clutter";
354358

@@ -922,7 +926,9 @@ private async Task RunPreviewAsync()
922926
ClearTargets();
923927
CurrentPage = 1;
924928

925-
var report = await _cleanupService.PreviewAsync(IncludeDownloads, IncludeBrowserHistory, PreviewCount, SelectedItemKind);
929+
var report = await Task.Run(
930+
() => _cleanupService.PreviewAsync(IncludeDownloads, IncludeBrowserHistory, PreviewCount, SelectedItemKind),
931+
CancellationToken.None).ConfigureAwait(true);
926932

927933
var previewPrep = await Task.Run(() =>
928934
{
@@ -990,11 +996,11 @@ await TransitionToPhaseAsync(
990996
}
991997

992998
[RelayCommand(CanExecute = nameof(CanDeleteSelected))]
993-
private Task DeleteSelectedAsync()
999+
private async Task DeleteSelectedAsync()
9941000
{
995-
if (IsBusy)
1001+
if (IsBusy || IsDeletionPreparationInProgress)
9961002
{
997-
return Task.CompletedTask;
1003+
return;
9981004
}
9991005

10001006
var itemsToDelete = Targets
@@ -1003,11 +1009,32 @@ private Task DeleteSelectedAsync()
10031009

10041010
if (itemsToDelete.Count == 0)
10051011
{
1006-
return Task.CompletedTask;
1012+
return;
10071013
}
10081014

1009-
PrepareDeletionConfirmation(itemsToDelete);
1010-
return Task.CompletedTask;
1015+
var previousBusyMessage = BusyStatusMessage;
1016+
var previousBusyDetail = BusyStatusDetail;
1017+
1018+
IsDeletionPreparationInProgress = true;
1019+
BusyStatusMessage = "Preparing confirmation…";
1020+
BusyStatusDetail = "Summarizing your selection before showing the sheet.";
1021+
1022+
try
1023+
{
1024+
// Let the dispatcher paint the overlay before any heavier UI-thread work runs.
1025+
await Dispatcher.Yield(DispatcherPriority.Render);
1026+
1027+
// Force a UI pass so the overlay renders before prep.
1028+
var dispatcher = Dispatcher.FromThread(Thread.CurrentThread) ?? Dispatcher.CurrentDispatcher;
1029+
await dispatcher.InvokeAsync(() => { }, DispatcherPriority.Background);
1030+
PrepareDeletionConfirmation(itemsToDelete);
1031+
}
1032+
finally
1033+
{
1034+
BusyStatusMessage = previousBusyMessage;
1035+
BusyStatusDetail = previousBusyDetail;
1036+
IsDeletionPreparationInProgress = false;
1037+
}
10111038
}
10121039

10131040
[RelayCommand]
@@ -1088,7 +1115,7 @@ private void HideRunConfirmationPopup()
10881115
}
10891116
}
10901117

1091-
private bool CanDeleteSelected() => !IsBusy && HasSelection && !IsConfirmationSheetVisible;
1118+
private bool CanDeleteSelected() => !IsBusy && !IsDeletionPreparationInProgress && HasSelection && !IsConfirmationSheetVisible;
10921119

10931120
private void PrepareDeletionConfirmation(List<(CleanupTargetGroupViewModel group, CleanupPreviewItemViewModel item)> itemsToDelete)
10941121
{
@@ -3097,6 +3124,11 @@ partial void OnIsBusyChanged(bool value)
30973124
ShowRunConfirmationPopupCommand.NotifyCanExecuteChanged();
30983125
}
30993126

3127+
partial void OnIsDeletionPreparationInProgressChanged(bool value)
3128+
{
3129+
DeleteSelectedCommand.NotifyCanExecuteChanged();
3130+
}
3131+
31003132
partial void OnBusyStatusMessageChanged(string value)
31013133
{
31023134
OnPropertyChanged(nameof(ActiveOperationStatus));
@@ -3533,10 +3565,17 @@ private async Task AddTargetGroupsAsync(IReadOnlyList<CleanupTargetReport> targe
35333565
return;
35343566
}
35353567

3568+
var materialized = await Task.Run(() =>
3569+
targets
3570+
.Where(static target => target is not null)
3571+
.Select(static target => new CleanupTargetGroupViewModel(target))
3572+
.ToList(),
3573+
CancellationToken.None).ConfigureAwait(true);
3574+
35363575
var added = 0;
3537-
foreach (var target in targets)
3576+
foreach (var group in materialized)
35383577
{
3539-
AddTargetGroup(new CleanupTargetGroupViewModel(target));
3578+
AddTargetGroup(group);
35403579
added++;
35413580

35423581
if (added % PreviewUiYieldInterval == 0)

0 commit comments

Comments
 (0)