Skip to content

Commit 6b6fb1a

Browse files
authored
Feature: Show size when hovering over recycle bin (#10904)
1 parent ce6a837 commit 6b6fb1a

File tree

12 files changed

+82
-32
lines changed

12 files changed

+82
-32
lines changed

src/Files.App/DataModels/NavigationControlItems/LocationItem.cs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
using CommunityToolkit.Mvvm.ComponentModel;
2+
using CommunityToolkit.WinUI;
23
using Files.App.Extensions;
34
using Files.App.Filesystem;
45
using Files.App.Helpers;
6+
using Files.App.Shell;
57
using Files.Shared;
68
using Microsoft.UI.Xaml.Media;
79
using Microsoft.UI.Xaml.Media.Imaging;
810
using System;
11+
using System.IO;
12+
using System.Threading.Tasks;
913

1014
namespace Files.App.DataModels.NavigationControlItems
1115
{
@@ -36,7 +40,7 @@ public string Path
3640
}
3741
}
3842

39-
public string ToolTipText { get; private set; }
43+
public virtual string ToolTipText { get; set; }
4044
public FontFamily Font { get; set; }
4145
public NavigationControlItemType ItemType => NavigationControlItemType.Location;
4246
public bool IsDefaultLocation { get; set; }
@@ -58,5 +62,39 @@ public bool IsExpanded
5862
public ContextMenuOptions MenuOptions { get; set; }
5963

6064
public int CompareTo(INavigationControlItem other) => Text.CompareTo(other.Text);
65+
66+
public static T Create<T>() where T : LocationItem, new()
67+
{
68+
return new T();
69+
}
70+
}
71+
72+
public class RecycleBinLocationItem : LocationItem
73+
{
74+
public void RefreshSpaceUsed(object sender, FileSystemEventArgs e)
75+
{
76+
SpaceUsed = RecycleBinHelpers.GetSize();
77+
}
78+
79+
private ulong spaceUsed;
80+
public ulong SpaceUsed
81+
{
82+
get => spaceUsed;
83+
set
84+
{
85+
SetProperty(ref spaceUsed, value);
86+
App.Window.DispatcherQueue.EnqueueAsync(() => OnPropertyChanged(nameof(ToolTipText)));
87+
}
88+
}
89+
90+
public override string ToolTipText => SpaceUsed.ToSizeString();
91+
92+
public RecycleBinLocationItem()
93+
{
94+
SpaceUsed = RecycleBinHelpers.GetSize();
95+
96+
RecycleBinManager.Default.RecycleBinItemCreated += RefreshSpaceUsed;
97+
RecycleBinManager.Default.RecycleBinItemDeleted += RefreshSpaceUsed;
98+
}
6199
}
62-
}
100+
}

src/Files.App/DataModels/SidebarPinnedModel.cs

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -204,23 +204,27 @@ public async Task AddItemToSidebarAsync(string path)
204204
{
205205
var item = await FilesystemTasks.Wrap(() => DrivesManager.GetRootFromPathAsync(path));
206206
var res = await FilesystemTasks.Wrap(() => StorageFileExtensions.DangerousGetFolderFromPathAsync(path, item));
207-
var locationItem = new LocationItem
207+
LocationItem locationItem;
208+
209+
if (string.Equals(path, CommonPaths.RecycleBinPath, StringComparison.OrdinalIgnoreCase))
210+
locationItem = LocationItem.Create<RecycleBinLocationItem>();
211+
else
212+
locationItem = LocationItem.Create<LocationItem>();
213+
214+
locationItem.Font = App.AppModel.SymbolFontFamily;
215+
locationItem.Path = path;
216+
locationItem.Section = SectionType.Favorites;
217+
locationItem.MenuOptions = new ContextMenuOptions
208218
{
209-
Font = App.AppModel.SymbolFontFamily,
210-
Path = path,
211-
Section = SectionType.Favorites,
212-
MenuOptions = new ContextMenuOptions
213-
{
214-
IsLocationItem = true,
215-
ShowProperties = true,
216-
ShowUnpinItem = true,
217-
ShowShellItems = true,
218-
ShowEmptyRecycleBin = path == CommonPaths.RecycleBinPath,
219-
},
220-
IsDefaultLocation = false,
221-
Text = res.Result?.DisplayName ?? Path.GetFileName(path.TrimEnd('\\'))
219+
IsLocationItem = true,
220+
ShowProperties = true,
221+
ShowUnpinItem = true,
222+
ShowShellItems = true,
223+
ShowEmptyRecycleBin = string.Equals(path, CommonPaths.RecycleBinPath, StringComparison.OrdinalIgnoreCase)
222224
};
223-
225+
locationItem.IsDefaultLocation = false;
226+
locationItem.Text = res.Result?.DisplayName ?? Path.GetFileName(path.TrimEnd('\\'));
227+
224228
if (res || (FilesystemResult)FolderHelpers.CheckFolderAccessWithWin32(path))
225229
{
226230
locationItem.IsInvalid = false;

src/Files.App/Filesystem/FilesystemOperations/FilesystemOperations.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ await associatedInstance.FilesystemViewModel.GetFileFromPathAsync(iFilePath)
534534
if (!permanently)
535535
{
536536
// Enumerate Recycle Bin
537-
IEnumerable<ShellFileItem> nameMatchItems, items = await recycleBinHelpers.EnumerateRecycleBin();
537+
IEnumerable<ShellFileItem> nameMatchItems, items = await RecycleBinHelpers.EnumerateRecycleBin();
538538

539539
// Get name matching files
540540
if (FileExtensionHelpers.IsShortcutOrUrlFile(source.Path)) // We need to check if it is a shortcut file

src/Files.App/Filesystem/FilesystemOperations/Helpers/FilesystemHelpers.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ public async Task<ReturnResult> DeleteItemsAsync(IEnumerable<IStorageItemWithPat
128128
{
129129
if (recycleBinHelpers.IsPathUnderRecycleBin(src.Path))
130130
{
131-
binItems ??= await recycleBinHelpers.EnumerateRecycleBin();
131+
binItems ??= await RecycleBinHelpers.EnumerateRecycleBin();
132132
if (!binItems.IsEmpty()) // Might still be null because we're deserializing the list from Json
133133
{
134134
var matchingItem = binItems.FirstOrDefault(x => x.RecyclePath == src.Path); // Get original file name
@@ -376,7 +376,7 @@ public async Task<ReturnResult> CopyItemsFromClipboard(DataPackageView packageVi
376376
{
377377
if (recycleBinHelpers.IsPathUnderRecycleBin(item.Path))
378378
{
379-
binItems ??= await recycleBinHelpers.EnumerateRecycleBin();
379+
binItems ??= await RecycleBinHelpers.EnumerateRecycleBin();
380380
if (!binItems.IsEmpty()) // Might still be null because we're deserializing the list from Json
381381
{
382382
var matchingItem = binItems.FirstOrDefault(x => x.RecyclePath == item.Path); // Get original file name
@@ -521,7 +521,7 @@ public async Task<ReturnResult> MoveItemsFromClipboard(DataPackageView packageVi
521521
{
522522
if (recycleBinHelpers.IsPathUnderRecycleBin(item.Path))
523523
{
524-
binItems ??= await recycleBinHelpers.EnumerateRecycleBin();
524+
binItems ??= await RecycleBinHelpers.EnumerateRecycleBin();
525525
if (!binItems.IsEmpty()) // Might still be null because we're deserializing the list from Json
526526
{
527527
var matchingItem = binItems.FirstOrDefault(x => x.RecyclePath == item.Path); // Get original file name

src/Files.App/Filesystem/FilesystemOperations/ShellFilesystemOperations.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ public async Task<IStorageHistory> DeleteItemsAsync(IList<IStorageItemWithPath>
353353
{
354354
var sourceMatch = await recycledSources.Select(x => source.DistinctBy(x => x.Path)
355355
.SingleOrDefault(s => s.Path.Equals(x.Source, StringComparison.OrdinalIgnoreCase))).Where(x => x is not null).ToListAsync();
356+
356357
return new StorageHistory(FileOperationType.Recycle,
357358
sourceMatch,
358359
await recycledSources.Zip(sourceMatch, (rSrc, oSrc) => new { rSrc, oSrc })
@@ -669,6 +670,7 @@ public async Task<IStorageHistory> RestoreItemsFromTrashAsync(IList<IStorageItem
669670
.Select(src => StorageHelpers.FromPathAndType(
670671
Path.Combine(Path.GetDirectoryName(src.rSrc.Source), Path.GetFileName(src.rSrc.Source).Replace("$R", "$I", StringComparison.Ordinal)),
671672
src.oSrc.ItemType)).ToListAsync(), null, true, cancellationToken);
673+
672674
return new StorageHistory(FileOperationType.Restore,
673675
sourceMatch,
674676
await movedSources.Zip(sourceMatch, (rSrc, oSrc) => new { rSrc, oSrc })
@@ -748,7 +750,7 @@ private async Task<DialogResult> GetFileListDialog(IEnumerable<string> source, s
748750
{
749751
if (recycleBinHelpers.IsPathUnderRecycleBin(src))
750752
{
751-
binItems ??= await recycleBinHelpers.EnumerateRecycleBin();
753+
binItems ??= await RecycleBinHelpers.EnumerateRecycleBin();
752754
if (!binItems.IsEmpty()) // Might still be null because we're deserializing the list from Json
753755
{
754756
var matchingItem = binItems.FirstOrDefault(x => x.RecyclePath == src); // Get original file name

src/Files.App/Helpers/RecycleBinHelpers.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using Files.App.DataModels.NavigationControlItems;
12
using Files.App.Extensions;
23
using Files.App.Filesystem;
34
using Files.App.Shell;
@@ -22,11 +23,16 @@ public class RecycleBinHelpers
2223

2324
#endregion Private Members
2425

25-
public async Task<List<ShellFileItem>> EnumerateRecycleBin()
26+
public static async Task<List<ShellFileItem>> EnumerateRecycleBin()
2627
{
2728
return (await Win32Shell.GetShellFolderAsync(CommonPaths.RecycleBinPath, "Enumerate", 0, int.MaxValue)).Enumerate;
2829
}
2930

31+
public static ulong GetSize()
32+
{
33+
return (ulong)Win32Shell.QueryRecycleBin().BinSize;
34+
}
35+
3036
public async Task<bool> IsRecycleBinItem(IStorageItem item)
3137
{
3238
List<ShellFileItem> recycleBinItems = await EnumerateRecycleBin();

src/Files.App/UserControls/SidebarControl.xaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
RightTapped="NavigationViewItem_RightTapped"
6666
SelectsOnInvoked="{x:Bind SelectsOnInvoked}"
6767
Tag="{x:Bind Path}"
68-
ToolTipService.ToolTip="{x:Bind ToolTipText}">
68+
ToolTipService.ToolTip="{x:Bind ToolTipText, Mode=OneWay}">
6969
<NavigationViewItem.Icon>
7070
<ImageIcon Source="{x:Bind Icon, Mode=OneWay}" />
7171
</NavigationViewItem.Icon>
@@ -1188,6 +1188,6 @@
11881188
DriveNavItemTemplate="{StaticResource DriveNavItem}"
11891189
FileTagNavItemTemplate="{StaticResource FileTagNavItem}"
11901190
LinuxNavItemTemplate="{StaticResource LinuxNavItem}"
1191-
LocationNavItemTemplate="{StaticResource LocationNavItem}" />
1191+
LocationNavItemTemplate="{StaticResource LocationNavItem}"/>
11921192
</NavigationView.MenuItemTemplateSelector>
11931193
</NavigationView>

src/Files.App/UserControls/SidebarControl.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1233,4 +1233,4 @@ public class NavItemDataTemplateSelector : DataTemplateSelector
12331233
};
12341234
}
12351235
}
1236-
}
1236+
}

src/Files.App/ViewModels/ItemViewModel.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ public ItemViewModel(FolderSettingsViewModel folderSettingsViewModel)
386386

387387
private async void RecycleBinRefreshRequested(object sender, FileSystemEventArgs e)
388388
{
389-
if (@"Shell:RecycleBinFolder".Equals(CurrentFolder?.ItemPath, StringComparison.OrdinalIgnoreCase))
389+
if (CommonPaths.RecycleBinPath.Equals(CurrentFolder?.ItemPath, StringComparison.OrdinalIgnoreCase))
390390
{
391391
await dispatcherQueue.EnqueueAsync(() =>
392392
{
@@ -397,7 +397,7 @@ await dispatcherQueue.EnqueueAsync(() =>
397397

398398
private async void RecycleBinItemDeleted(object sender, FileSystemEventArgs e)
399399
{
400-
if (@"Shell:RecycleBinFolder".Equals(CurrentFolder?.ItemPath, StringComparison.OrdinalIgnoreCase))
400+
if (CommonPaths.RecycleBinPath.Equals(CurrentFolder?.ItemPath, StringComparison.OrdinalIgnoreCase))
401401
{
402402
// get the item that immediately follows matching item to be removed
403403
// if the matching item is the last item, try to get the previous item; otherwise, null
@@ -416,7 +416,7 @@ private async void RecycleBinItemDeleted(object sender, FileSystemEventArgs e)
416416

417417
private async void RecycleBinItemCreated(object sender, FileSystemEventArgs e)
418418
{
419-
if (@"Shell:RecycleBinFolder".Equals(CurrentFolder?.ItemPath, StringComparison.OrdinalIgnoreCase))
419+
if (CommonPaths.RecycleBinPath.Equals(CurrentFolder?.ItemPath, StringComparison.OrdinalIgnoreCase))
420420
{
421421
using var folderItem = SafetyExtensions.IgnoreExceptions(() => new ShellItem(e.FullPath));
422422
if (folderItem is null) return;

src/Files.App/ViewModels/SidebarViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -605,4 +605,4 @@ public GridLength TabControlMargin
605605
set => SetProperty(ref tabControlMargin, value);
606606
}
607607
}
608-
}
608+
}

0 commit comments

Comments
 (0)