Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code Quality: Introduced IWindowsRecentItemsService #16150

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/Files.App.CsWin32/NativeMethods.txt
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,18 @@ IFileOperation
IShellItem2
PSGetPropertyKeyFromName
ShellExecuteEx
SHAddToRecentDocs
SHARD
BHID_EnumItems
FOLDERID_RecycleBinFolder
CoTaskMemFree
SHGetIDListFromObject
SHCreateItemFromIDList
BHID_SFUIObject
IContextMenu
CMF_NORMAL
CMF_OPTIMIZEFORINVOKE
IApplicationDestinations
ApplicationDestinations
IApplicationDocumentLists
ApplicationDocumentLists
14 changes: 0 additions & 14 deletions src/Files.App.CsWin32/Windows.Win32.Extras.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright (c) 2024 Files Community
// Licensed under the MIT License. See the LICENSE.

using System;
using System.Runtime.InteropServices;
using Windows.Win32.Foundation;

Expand All @@ -18,17 +17,4 @@ namespace UI.WindowsAndMessaging
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate LRESULT WNDPROC(HWND hWnd, uint msg, WPARAM wParam, LPARAM lParam);
}

namespace UI.Shell
{
public static partial class FOLDERID
{
public readonly static Guid FOLDERID_RecycleBinFolder = new(0xB7534046, 0x3ECB, 0x4C18, 0xBE, 0x4E, 0x64, 0xCD, 0x4C, 0xB7, 0xD6, 0xAC);
}

public static partial class BHID
{
public readonly static Guid BHID_EnumItems = new(0x94f60519, 0x2850, 0x4924, 0xaa, 0x5a, 0xd1, 0x5e, 0x84, 0x86, 0x80, 0x39);
}
}
}
2 changes: 0 additions & 2 deletions src/Files.App/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ public static CommandBarFlyout? LastOpenedFlyout
public static QuickAccessManager QuickAccessManager { get; private set; } = null!;
public static StorageHistoryWrapper HistoryWrapper { get; private set; } = null!;
public static FileTagsManager FileTagsManager { get; private set; } = null!;
public static RecentItems RecentItemsManager { get; private set; } = null!;
public static LibraryManager LibraryManager { get; private set; } = null!;
public static AppModel AppModel { get; private set; } = null!;
public static ILogger Logger { get; private set; } = null!;
Expand Down Expand Up @@ -114,7 +113,6 @@ async Task ActivateAsync()
QuickAccessManager = Ioc.Default.GetRequiredService<QuickAccessManager>();
HistoryWrapper = Ioc.Default.GetRequiredService<StorageHistoryWrapper>();
FileTagsManager = Ioc.Default.GetRequiredService<FileTagsManager>();
RecentItemsManager = Ioc.Default.GetRequiredService<RecentItems>();
LibraryManager = Ioc.Default.GetRequiredService<LibraryManager>();
Logger = Ioc.Default.GetRequiredService<ILogger<App>>();
AppModel = Ioc.Default.GetRequiredService<AppModel>();
Expand Down
58 changes: 58 additions & 0 deletions src/Files.App/Data/Contracts/IWindowsRecentItemsService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright (c) 2024 Files Community
// Licensed under the MIT License. See the LICENSE.

using System.Collections.Specialized;

namespace Files.App.Data.Contracts
{
/// <summary>
/// Provides manager of recent files and folders of File Explorer on Windows.
/// </summary>
public interface IWindowsRecentItemsService
{
/// <summary>
/// Gets recent files of File Explorer.
/// </summary>
IReadOnlyList<RecentItem> RecentFiles { get; }

/// <summary>
/// Gets recent folders of File Explorer.
/// </summary>
IReadOnlyList<RecentItem> RecentFolders { get; }

/// <summary>
/// Gets invoked when recent files of File Explorer have changed.
/// </summary>
event EventHandler<NotifyCollectionChangedEventArgs>? RecentFilesChanged;

/// <summary>
/// Gets invoked when recent folders of File Explorer have changed.
/// </summary>
event EventHandler<NotifyCollectionChangedEventArgs>? RecentFoldersChanged;

/// <summary>
/// Updates recent files of File Explorer.
/// </summary>
Task<bool> UpdateRecentFilesAsync();

/// <summary>
/// Updates recent folders of File Explorer.
/// </summary>
Task<bool> UpdateRecentFoldersAsync();

/// <summary>
/// Adds a recent file for File Explorer.
/// </summary>
bool Add(string path);

/// <summary>
/// Removes a recent folder for File Explorer.
/// </summary>
bool Remove(RecentItem item);

/// <summary>
/// Clears recent files and folders of File Explorer.
/// </summary>
bool Clear();
}
}
65 changes: 65 additions & 0 deletions src/Files.App/Data/Items/WidgetRecentItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (c) 2024 Files Community
// Licensed under the MIT License. See the LICENSE.

using Microsoft.UI.Xaml.Media.Imaging;
using Windows.Win32;
using Windows.Win32.UI.Shell;

namespace Files.App.Data.Items
{
/// <summary>
/// Represents an item for recent item of File Explorer on Windows.
/// </summary>
public sealed class RecentItem : WidgetCardItem, IEquatable<RecentItem>, IDisposable
{
private BitmapImage? _Icon;
/// <summary>
/// Gets or sets thumbnail icon of the recent item.
/// </summary>
public BitmapImage? Icon
{
get => _Icon;
set => SetProperty(ref _Icon, value);
}

/// <summary>
/// Gets or sets name of the recent item.
/// </summary>
public required string Name { get; set; }

/// <summary>
/// Gets or sets target path of the recent item.
/// </summary>
public required DateTime LastModified { get; set; }

/// <summary>
/// Gets or initializes PIDL of the recent item.
/// </summary>
/// <remarks>
/// This has to be removed in the future.
/// </remarks>
public unsafe required ComPtr<IShellItem> ShellItem { get; init; }

/// <summary>
/// Loads thumbnail icon of the recent item.
/// </summary>
/// <returns></returns>
public async Task LoadRecentItemIconAsync()
{
var result = await FileThumbnailHelper.GetIconAsync(Path, Constants.ShellIconSizes.Small, false, IconOptions.UseCurrentScale);

var bitmapImage = await result.ToBitmapAsync();
if (bitmapImage is not null)
Icon = bitmapImage;
}

public override int GetHashCode() => (Path, Name).GetHashCode();
public override bool Equals(object? other) => other is RecentItem item && Equals(item);
public bool Equals(RecentItem? other) => other is not null && other.Name == Name && other.Path == Path;

public unsafe void Dispose()
{
ShellItem.Dispose();
}
}
}
1 change: 0 additions & 1 deletion src/Files.App/GlobalUsings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
global using global::Files.App.Utils.FileTags;
global using global::Files.App.Utils.Git;
global using global::Files.App.Utils.Library;
global using global::Files.App.Utils.RecentItem;
global using global::Files.App.Utils.Serialization;
global using global::Files.App.Utils.Shell;
global using global::Files.App.Utils.StatusCenter;
Expand Down
2 changes: 1 addition & 1 deletion src/Files.App/Helpers/Application/AppLifecycleHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ public static IHost ConfigureHost()
.AddSingleton<ITagsContext, TagsContext>()
.AddSingleton<ISidebarContext, SidebarContext>()
// Services
.AddSingleton<IWindowsRecentItemsService, WindowsRecentItemsService>()
.AddSingleton<IWindowsIniService, WindowsIniService>()
.AddSingleton<IWindowsWallpaperService, WindowsWallpaperService>()
.AddSingleton<IWindowsSecurityService, WindowsSecurityService>()
Expand Down Expand Up @@ -224,7 +225,6 @@ public static IHost ConfigureHost()
.AddSingleton<QuickAccessManager>()
.AddSingleton<StorageHistoryWrapper>()
.AddSingleton<FileTagsManager>()
.AddSingleton<RecentItems>()
.AddSingleton<LibraryManager>()
.AddSingleton<AppModel>()
).Build();
Expand Down
7 changes: 4 additions & 3 deletions src/Files.App/Helpers/Navigation/NavigationHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace Files.App.Helpers
{
public static class NavigationHelpers
{
private static readonly IWindowsRecentItemsService WindowsRecentItemsService = Ioc.Default.GetRequiredService<IWindowsRecentItemsService>();
private static MainPageViewModel MainPageViewModel { get; } = Ioc.Default.GetRequiredService<MainPageViewModel>();
private static DrivesViewModel DrivesViewModel { get; } = Ioc.Default.GetRequiredService<DrivesViewModel>();
private static INetworkService NetworkService { get; } = Ioc.Default.GetRequiredService<INetworkService>();
Expand Down Expand Up @@ -524,7 +525,7 @@ private static async Task<FilesystemResult> OpenDirectory(string path, IShellPag
{
// Add location to Recent Items List
if (childFolder.Item is SystemStorageFolder)
App.RecentItemsManager.AddToRecentItems(childFolder.Path);
WindowsRecentItemsService.Add(childFolder.Path);
});
if (!opened)
opened = (FilesystemResult)FolderHelpers.CheckFolderAccessWithWin32(path);
Expand Down Expand Up @@ -556,7 +557,7 @@ private static async Task<FilesystemResult> OpenFile(string path, IShellPage ass
StorageFileWithPath childFile = await associatedInstance.ShellViewModel.GetFileWithPathFromPathAsync(shortcutInfo.TargetPath);
// Add location to Recent Items List
if (childFile?.Item is SystemStorageFile)
App.RecentItemsManager.AddToRecentItems(childFile.Path);
WindowsRecentItemsService.Add(childFile.Path);
}
await Win32Helper.InvokeWin32ComponentAsync(shortcutInfo.TargetPath, associatedInstance, $"{args} {shortcutInfo.Arguments}", shortcutInfo.RunAsAdmin, shortcutInfo.WorkingDirectory);
}
Expand All @@ -573,7 +574,7 @@ private static async Task<FilesystemResult> OpenFile(string path, IShellPage ass
{
// Add location to Recent Items List
if (childFile.Item is SystemStorageFile)
App.RecentItemsManager.AddToRecentItems(childFile.Path);
WindowsRecentItemsService.Add(childFile.Path);

if (openViaApplicationPicker)
{
Expand Down
5 changes: 4 additions & 1 deletion src/Files.App/Helpers/UI/UIFilesystemHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,10 @@ public static async Task CreateFileFromDialogResultTypeAsync(AddItemDialogItemTy

// Add newly created item to recent files list
if (created.Status == ReturnResult.Success && created.Item?.Path is not null)
App.RecentItemsManager.AddToRecentItems(created.Item.Path);
{
IWindowsRecentItemsService windowsRecentItemsService = Ioc.Default.GetRequiredService<IWindowsRecentItemsService>();
windowsRecentItemsService.Add(created.Item.Path);
}
else if (created.Status == ReturnResult.AccessUnauthorized)
{
await DialogDisplayHelper.ShowDialogAsync
Expand Down
4 changes: 2 additions & 2 deletions src/Files.App/Services/Storage/StorageTrashBinService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,13 @@ public unsafe bool RestoreAllTrashes()
try
{
// Get IShellItem for Recycle Bin
var recycleBinFolderId = FOLDERID.FOLDERID_RecycleBinFolder;
var recycleBinFolderId = PInvoke.FOLDERID_RecycleBinFolder;
var shellItemGuid = typeof(IShellItem).GUID;
PInvoke.SHGetKnownFolderItem(&recycleBinFolderId, KNOWN_FOLDER_FLAG.KF_FLAG_DEFAULT, HANDLE.Null, &shellItemGuid, (void**)&recycleBinFolderShellItem);

// Get IEnumShellItems for Recycle Bin
Guid enumShellItemGuid = typeof(IEnumShellItems).GUID;
var enumItemsBHID = BHID.BHID_EnumItems;
var enumItemsBHID = PInvoke.BHID_EnumItems;
recycleBinFolderShellItem->BindToHandler(null, &enumItemsBHID, &enumShellItemGuid, (void**)&enumShellItems);

// Initialize how to perform the operation
Expand Down
Loading