Skip to content

Code Quality: Refactored the code for Quick Access #16485

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

Closed
Closed
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
5 changes: 5 additions & 0 deletions src/Files.App.CsWin32/NativeMethods.txt
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ IApplicationDestinations
ApplicationDestinations
IApplicationDocumentLists
ApplicationDocumentLists
BHID_EnumItems
BHID_SFUIObject
IContextMenu
CMF_OPTIMIZEFORINVOKE
IPropertyStore
IApplicationActivationManager
MENU_ITEM_TYPE
COMPRESSION_FORMAT
Expand Down
33 changes: 14 additions & 19 deletions src/Files.App/Actions/Sidebar/PinFolderToSidebarAction.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
// Copyright (c) 2024 Files Community
// Licensed under the MIT License. See the LICENSE.

using Windows.Storage;
using System.Collections.Specialized;

namespace Files.App.Actions
{
internal sealed class PinFolderToSidebarAction : ObservableObject, IAction
{
private readonly IContentPageContext context;
private readonly IQuickAccessService service;
private readonly IContentPageContext context = Ioc.Default.GetRequiredService<IContentPageContext>();
private readonly IQuickAccessService service = Ioc.Default.GetRequiredService<IQuickAccessService>();

public string Label
=> "PinFolderToSidebar".GetLocalizedResource();
Expand All @@ -24,30 +24,25 @@ public bool IsExecutable

public PinFolderToSidebarAction()
{
context = Ioc.Default.GetRequiredService<IContentPageContext>();
service = Ioc.Default.GetRequiredService<IQuickAccessService>();

context.PropertyChanged += Context_PropertyChanged;
App.QuickAccessManager.UpdateQuickAccessWidget += QuickAccessManager_DataChanged;
service.PinnedFoldersChanged += QuickAccessService_CollectionChanged;
}

public async Task ExecuteAsync(object? parameter = null)
{
if (context.HasSelection)
{
var items = context.SelectedItems.Select(x => x.ItemPath).ToArray();
var items = context.HasSelection
? context.SelectedItems.Select(x => x.ItemPath).ToArray()
: context.Folder is not null
? [context.Folder.ItemPath]
: null;

await service.PinToSidebarAsync(items);
}
else if (context.Folder is not null)
{
await service.PinToSidebarAsync(context.Folder.ItemPath);
}
if (items is not null)
await service.PinFolderAsync(items);
}

private bool GetIsExecutable()
{
string[] pinnedFolders = [.. App.QuickAccessManager.Model.PinnedFolders];
string[] pinnedFolders = [.. service.Folders.Select(x => x.Path)];

return context.HasSelection
? context.SelectedItems.All(IsPinnable)
Expand All @@ -56,7 +51,7 @@ private bool GetIsExecutable()
bool IsPinnable(ListedItem item)
{
return
item.PrimaryItemAttribute is StorageItemTypes.Folder &&
item.PrimaryItemAttribute is Windows.Storage.StorageItemTypes.Folder &&
!pinnedFolders.Contains(item.ItemPath);
}
}
Expand All @@ -72,7 +67,7 @@ private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e)
}
}

private void QuickAccessManager_DataChanged(object? sender, ModifyQuickAccessEventArgs e)
private void QuickAccessService_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
OnPropertyChanged(nameof(IsExecutable));
}
Expand Down
32 changes: 15 additions & 17 deletions src/Files.App/Actions/Sidebar/UnpinFolderToSidebarAction.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
// Copyright (c) 2024 Files Community
// Licensed under the MIT License. See the LICENSE.

using System.Collections.Specialized;

namespace Files.App.Actions
{
internal sealed class UnpinFolderFromSidebarAction : ObservableObject, IAction
{
private readonly IContentPageContext context;
private readonly IQuickAccessService service;
private readonly IContentPageContext context = Ioc.Default.GetRequiredService<IContentPageContext>();
private readonly IQuickAccessService service = Ioc.Default.GetRequiredService<IQuickAccessService>();

public string Label
=> "UnpinFolderFromSidebar".GetLocalizedResource();
Expand All @@ -22,29 +24,25 @@ public bool IsExecutable

public UnpinFolderFromSidebarAction()
{
context = Ioc.Default.GetRequiredService<IContentPageContext>();
service = Ioc.Default.GetRequiredService<IQuickAccessService>();

context.PropertyChanged += Context_PropertyChanged;
App.QuickAccessManager.UpdateQuickAccessWidget += QuickAccessManager_DataChanged;
service.PinnedFoldersChanged += QuickAccessService_CollectionChanged;
}

public async Task ExecuteAsync(object? parameter = null)
{
if (context.HasSelection)
{
var items = context.SelectedItems.Select(x => x.ItemPath).ToArray();
await service.UnpinFromSidebarAsync(items);
}
else if (context.Folder is not null)
{
await service.UnpinFromSidebarAsync(context.Folder.ItemPath);
}
var items = context.HasSelection
? context.SelectedItems.Select(x => x.ItemPath).ToArray()
: context.Folder is not null
? [context.Folder.ItemPath]
: null;

if (items is not null)
await service.UnpinFolderAsync(items);
}

private bool GetIsExecutable()
{
string[] pinnedFolders = [.. App.QuickAccessManager.Model.PinnedFolders];
string[] pinnedFolders = [.. service.Folders.Select(x => x.Path)];

return context.HasSelection
? context.SelectedItems.All(IsPinned)
Expand All @@ -67,7 +65,7 @@ private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e)
}
}

private void QuickAccessManager_DataChanged(object? sender, ModifyQuickAccessEventArgs e)
private void QuickAccessService_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
OnPropertyChanged(nameof(IsExecutable));
}
Expand Down
2 changes: 0 additions & 2 deletions src/Files.App/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ public static CommandBarFlyout? LastOpenedFlyout
}

// TODO: Replace with DI
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 LibraryManager LibraryManager { get; private set; } = null!;
Expand Down Expand Up @@ -109,7 +108,6 @@ async Task ActivateAsync()
}

// TODO: Replace with DI
QuickAccessManager = Ioc.Default.GetRequiredService<QuickAccessManager>();
HistoryWrapper = Ioc.Default.GetRequiredService<StorageHistoryWrapper>();
FileTagsManager = Ioc.Default.GetRequiredService<FileTagsManager>();
LibraryManager = Ioc.Default.GetRequiredService<LibraryManager>();
Expand Down
10 changes: 2 additions & 8 deletions src/Files.App/Data/Contexts/SideBar/SideBarContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,7 @@ namespace Files.App.Data.Contexts
/// <inheritdoc cref="ISidebarContext"/>
internal sealed class SidebarContext : ObservableObject, ISidebarContext
{
private readonly PinnedFoldersManager favoriteModel = App.QuickAccessManager.Model;

private int PinnedFolderItemIndex =>
IsItemRightClicked
? favoriteModel.IndexOfItem(_RightClickedItem!)
: -1;
private readonly IQuickAccessService WindowsQuickAccessService = Ioc.Default.GetRequiredService<IQuickAccessService>();

private INavigationControlItem? _RightClickedItem = null;
public INavigationControlItem? RightClickedItem => _RightClickedItem;
Expand All @@ -22,7 +17,7 @@ internal sealed class SidebarContext : ObservableObject, ISidebarContext
public bool IsPinnedFolderItem =>
IsItemRightClicked &&
_RightClickedItem!.Section is SectionType.Pinned &&
PinnedFolderItemIndex is not -1;
WindowsQuickAccessService.IsPinned(_RightClickedItem.Path);

public DriveItem? OpenDriveItem
=> _RightClickedItem as DriveItem;
Expand All @@ -37,7 +32,6 @@ public void SidebarControl_RightClickedItemChanged(object? sender, INavigationCo
if (SetProperty(ref _RightClickedItem, e, nameof(RightClickedItem)))
{
OnPropertyChanged(nameof(IsItemRightClicked));
OnPropertyChanged(nameof(PinnedFolderItemIndex));
OnPropertyChanged(nameof(IsPinnedFolderItem));
OnPropertyChanged(nameof(OpenDriveItem));
}
Expand Down
62 changes: 15 additions & 47 deletions src/Files.App/Data/Contracts/IQuickAccessService.cs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add comments

Original file line number Diff line number Diff line change
@@ -1,56 +1,24 @@
// Copyright (c) 2024 Files Community
// Licensed under the MIT License. See the LICENSE.

using System.Collections.Specialized;

namespace Files.App.Data.Contracts
{
public interface IQuickAccessService
{
/// <summary>
/// Gets the list of quick access items
/// </summary>
/// <returns></returns>
Task<IEnumerable<ShellFileItem>> GetPinnedFoldersAsync();

/// <summary>
/// Pins a folder to the quick access list
/// </summary>
/// <param name="folderPath">The folder to pin</param>
/// <returns></returns>
Task PinToSidebarAsync(string folderPath);

/// <summary>
/// Pins folders to the quick access list
/// </summary>
/// <param name="folderPaths">The array of folders to pin</param>
/// <returns></returns>
Task PinToSidebarAsync(string[] folderPaths);

/// <summary>
/// Unpins a folder from the quick access list
/// </summary>
/// <param name="folderPath">The folder to unpin</param>
/// <returns></returns>
Task UnpinFromSidebarAsync(string folderPath);

/// <summary>
/// Unpins folders from the quick access list
/// </summary>
/// <param name="folderPaths">The array of folders to unpin</param>
/// <returns></returns>
Task UnpinFromSidebarAsync(string[] folderPaths);

/// <summary>
/// Checks if a folder is pinned to the quick access list
/// </summary>
/// <param name="folderPath">The path of the folder</param>
/// <returns>true if the item is pinned</returns>
bool IsItemPinned(string folderPath);

/// <summary>
/// Saves a state of pinned folder items in the sidebar
/// </summary>
/// <param name="items">The array of items to save</param>
/// <returns></returns>
Task SaveAsync(string[] items);
IReadOnlyList<INavigationControlItem> Folders { get; }

event EventHandler<NotifyCollectionChangedEventArgs>? PinnedFoldersChanged;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this event limited to pinned folders, or does it also notify when recent folders are added to the list?


Task InitializeAsync();

Task<bool> UpdatePinnedFoldersAsync();

bool IsPinned(string path);

Task<bool> PinFolderAsync(string[] paths);

Task<bool> UnpinFolderAsync(string[] paths);
}
}
4 changes: 3 additions & 1 deletion src/Files.App/Data/Items/DriveItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ namespace Files.App.Data.Items
{
public sealed class DriveItem : ObservableObject, INavigationControlItem, ILocatableFolder
{
private readonly IQuickAccessService QuickAccessService = Ioc.Default.GetRequiredService<IQuickAccessService>();

private BitmapImage icon;
public BitmapImage Icon
{
Expand Down Expand Up @@ -48,7 +50,7 @@ public bool IsNetwork
=> Type == DriveType.Network;

public bool IsPinned
=> App.QuickAccessManager.Model.PinnedFolders.Contains(path);
=> QuickAccessService.IsPinned(path);

public string MaxSpaceText
=> MaxSpace.ToSizeString();
Expand Down
4 changes: 3 additions & 1 deletion src/Files.App/Data/Items/ListedItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public class ListedItem : ObservableObject, IGroupableItem

protected static readonly IDateTimeFormatter dateTimeFormatter = Ioc.Default.GetRequiredService<IDateTimeFormatter>();

protected readonly IQuickAccessService QuickAccessService = Ioc.Default.GetRequiredService<IQuickAccessService>();

public bool IsHiddenItem { get; set; } = false;

public StorageItemTypes PrimaryItemAttribute { get; set; }
Expand Down Expand Up @@ -414,7 +416,7 @@ public override string ToString()
public bool IsGitItem => this is GitItem;
public virtual bool IsExecutable => !IsFolder && FileExtensionHelpers.IsExecutableFile(ItemPath);
public virtual bool IsScriptFile => FileExtensionHelpers.IsScriptFile(ItemPath);
public bool IsPinned => App.QuickAccessManager.Model.PinnedFolders.Contains(itemPath);
public bool IsPinned => QuickAccessService.IsPinned(itemPath);
public bool IsDriveRoot => ItemPath == PathNormalization.GetPathRoot(ItemPath);
public bool IsElevationRequired { get; set; }

Expand Down
2 changes: 1 addition & 1 deletion src/Files.App/Data/Items/LocationItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public bool IsExpanded

public bool IsInvalid { get; set; } = false;

public bool IsPinned => App.QuickAccessManager.Model.PinnedFolders.Contains(path);
public bool IsPinned { get; set; }

public SectionType Section { get; set; }

Expand Down
Loading