From 29bd72aa32edf69d03137551577a1090fbdb3935 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Garc=C3=ADa=20Ruiz?= Date: Thu, 9 Mar 2023 12:34:34 +0100 Subject: [PATCH 1/5] Add pinned items to taskbar jumplist --- src/Files.App/Helpers/JumpListManager.cs | 35 ++++++++++++---------- src/Files.App/Strings/en-US/Resources.resw | 3 ++ 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/Files.App/Helpers/JumpListManager.cs b/src/Files.App/Helpers/JumpListManager.cs index 0e16c81476ab..84eeeb383b22 100644 --- a/src/Files.App/Helpers/JumpListManager.cs +++ b/src/Files.App/Helpers/JumpListManager.cs @@ -27,6 +27,9 @@ public async Task InitializeAsync() if (JumpList.IsSupported()) { instance = await JumpList.LoadCurrentAsync(); + App.QuickAccessManager.PinnedItemsModified += QuickAccessManager_DataChanged; + + QuickAccessManager_DataChanged(null, null); // Disable automatic jumplist. It doesn't work with Files UWP. instance.SystemGroupKind = JumpListSystemGroupKind.None; @@ -48,14 +51,14 @@ public async void AddFolderToJumpList(string path) { if (instance is not null) { - AddFolder(path); + AddFolder(path, "ms-resource:///Resources/JumpListRecentGroupHeader"); await instance.SaveAsync(); } } catch { } } - private void AddFolder(string path) + private void AddFolder(string path, string group) { if (instance is not null) { @@ -65,9 +68,7 @@ private void AddFolder(string path) // Jumplist item argument can't end with a slash so append a character that can't exist in a directory name to support listing drives. var drive = App.DrivesManager.Drives.Where(drive => drive.Path == path).FirstOrDefault(); if (drive is null) - { return; - } displayName = drive.Text; path += '?'; @@ -76,13 +77,9 @@ private void AddFolder(string path) if (displayName is null) { if (path.Equals(CommonPaths.DesktopPath, StringComparison.OrdinalIgnoreCase)) - { displayName = "ms-resource:///Resources/Desktop"; - } else if (path.Equals(CommonPaths.DownloadsPath, StringComparison.OrdinalIgnoreCase)) - { displayName = "ms-resource:///Resources/Downloads"; - } else if (path.Equals(CommonPaths.RecycleBinPath, StringComparison.OrdinalIgnoreCase)) { var localSettings = ApplicationData.Current.LocalSettings; @@ -108,21 +105,22 @@ private void AddFolder(string path) } } else - { displayName = Path.GetFileName(path); - } } var jumplistItem = JumpListItem.CreateWithArguments(path, displayName); jumplistItem.Description = jumplistItem.Arguments; - jumplistItem.GroupName = "ms-resource:///Resources/JumpListRecentGroupHeader"; + jumplistItem.GroupName = group; jumplistItem.Logo = new Uri("ms-appx:///Assets/FolderIcon.png"); // Keep newer items at the top. instance.Items.Remove(instance.Items.FirstOrDefault(x => x.Arguments.Equals(path, StringComparison.OrdinalIgnoreCase))); instance.Items.Insert(0, jumplistItem); - JumpListItemPaths.Remove(JumpListItemPaths.FirstOrDefault(x => x.Equals(path, StringComparison.OrdinalIgnoreCase))); - JumpListItemPaths.Add(path); + + if (string.Equals(group, "ms-resource:///Resources/JumpListRecentGroupHeader", StringComparison.OrdinalIgnoreCase)) { + JumpListItemPaths.Remove(JumpListItemPaths.FirstOrDefault(x => x.Equals(path, StringComparison.OrdinalIgnoreCase))); + JumpListItemPaths.Add(path); + } } } @@ -133,9 +131,7 @@ public async void RemoveFolder(string path) try { if (instance is null) - { return; - } if (JumpListItemPaths.Remove(path)) { @@ -146,5 +142,14 @@ public async void RemoveFolder(string path) } catch { } } + + private async void QuickAccessManager_DataChanged(object sender, FileSystemEventArgs e) + { + if (instance is null) + return; + + App.QuickAccessManager.Model.FavoriteItems.ForEach(x => AddFolder(x, "ms-resource:///Resources/JumpListPinnedGroupHeader")); + await instance.SaveAsync(); + } } } diff --git a/src/Files.App/Strings/en-US/Resources.resw b/src/Files.App/Strings/en-US/Resources.resw index 011693e4492e..0d2e43c606eb 100644 --- a/src/Files.App/Strings/en-US/Resources.resw +++ b/src/Files.App/Strings/en-US/Resources.resw @@ -2610,4 +2610,7 @@ Unable to calculate hashes due to a system error + + Pinned + \ No newline at end of file From 0ffbf523a539b8d763cd986875bbc84e31ff7c97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Garc=C3=ADa=20Ruiz?= Date: Thu, 9 Mar 2023 13:28:45 +0100 Subject: [PATCH 2/5] Fix --- src/Files.App/Helpers/JumpListManager.cs | 23 +++++++++++++++------- src/Files.App/Strings/en-US/Resources.resw | 2 +- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/Files.App/Helpers/JumpListManager.cs b/src/Files.App/Helpers/JumpListManager.cs index 84eeeb383b22..5fab7519c8bf 100644 --- a/src/Files.App/Helpers/JumpListManager.cs +++ b/src/Files.App/Helpers/JumpListManager.cs @@ -1,4 +1,5 @@ using Files.App.Filesystem; +using Files.App.UserControls.Widgets; using Files.Shared.Extensions; using System; using System.Collections.Generic; @@ -27,7 +28,7 @@ public async Task InitializeAsync() if (JumpList.IsSupported()) { instance = await JumpList.LoadCurrentAsync(); - App.QuickAccessManager.PinnedItemsModified += QuickAccessManager_DataChanged; + App.QuickAccessManager.UpdateQuickAccessWidget += QuickAccessManager_DataChanged; QuickAccessManager_DataChanged(null, null); @@ -113,13 +114,19 @@ private void AddFolder(string path, string group) jumplistItem.GroupName = group; jumplistItem.Logo = new Uri("ms-appx:///Assets/FolderIcon.png"); - // Keep newer items at the top. - instance.Items.Remove(instance.Items.FirstOrDefault(x => x.Arguments.Equals(path, StringComparison.OrdinalIgnoreCase))); - instance.Items.Insert(0, jumplistItem); + if (string.Equals(group, "ms-resource:///Resources/JumpListRecentGroupHeader", StringComparison.OrdinalIgnoreCase)) + { + // Keep newer items at the top. + instance.Items.Remove(instance.Items.FirstOrDefault(x => x.Arguments.Equals(path, StringComparison.OrdinalIgnoreCase))); + instance.Items.Insert(0, jumplistItem); - if (string.Equals(group, "ms-resource:///Resources/JumpListRecentGroupHeader", StringComparison.OrdinalIgnoreCase)) { JumpListItemPaths.Remove(JumpListItemPaths.FirstOrDefault(x => x.Equals(path, StringComparison.OrdinalIgnoreCase))); - JumpListItemPaths.Add(path); + JumpListItemPaths.Add(path); + } + else + { + var pinnedItemsCount = instance.Items.Where(x => x.GroupName == "ms-resource:///Resources/JumpListPinnedGroupHeader").Count(); + instance.Items.Insert(pinnedItemsCount, jumplistItem); } } } @@ -143,11 +150,13 @@ public async void RemoveFolder(string path) catch { } } - private async void QuickAccessManager_DataChanged(object sender, FileSystemEventArgs e) + private async void QuickAccessManager_DataChanged(object sender, ModifyQuickAccessEventArgs e) { if (instance is null) return; + var itemsToRemove = instance.Items.Where(x => string.Equals(x.GroupName, "ms-resource:///Resources/JumpListPinnedGroupHeader", StringComparison.OrdinalIgnoreCase)).ToList(); + itemsToRemove.ForEach(x => instance.Items.Remove(x)); App.QuickAccessManager.Model.FavoriteItems.ForEach(x => AddFolder(x, "ms-resource:///Resources/JumpListPinnedGroupHeader")); await instance.SaveAsync(); } diff --git a/src/Files.App/Strings/en-US/Resources.resw b/src/Files.App/Strings/en-US/Resources.resw index 0d2e43c606eb..875b79ec6734 100644 --- a/src/Files.App/Strings/en-US/Resources.resw +++ b/src/Files.App/Strings/en-US/Resources.resw @@ -2611,6 +2611,6 @@ Unable to calculate hashes due to a system error - Pinned + Pinned items \ No newline at end of file From 23b151e1d2fdbbd4cd54a50b4db8cdff2cc369d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Garc=C3=ADa=20Ruiz?= Date: Thu, 9 Mar 2023 16:31:32 +0100 Subject: [PATCH 3/5] Fix issues --- .../DataModels/SidebarPinnedModel.cs | 11 ++++++- .../Widgets/QuickAccessWidget.xaml.cs | 33 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/Files.App/DataModels/SidebarPinnedModel.cs b/src/Files.App/DataModels/SidebarPinnedModel.cs index 27626eccfdbd..bbb0d1688497 100644 --- a/src/Files.App/DataModels/SidebarPinnedModel.cs +++ b/src/Files.App/DataModels/SidebarPinnedModel.cs @@ -4,6 +4,7 @@ using Files.App.Filesystem; using Files.App.Helpers; using Files.App.ServicesImplementation; +using Files.App.UserControls.Widgets; using Files.Backend.Services.Settings; using System; using System.Collections.Generic; @@ -193,7 +194,15 @@ public void RemoveStaleSidebarItems() } public async void LoadAsync(object? sender, FileSystemEventArgs e) - => await LoadAsync(); + { + App.QuickAccessManager.PinnedItemsWatcher.EnableRaisingEvents = false; + await LoadAsync(); + App.QuickAccessManager.UpdateQuickAccessWidget?.Invoke(null, new ModifyQuickAccessEventArgs(FavoriteItems.ToArray(), true) + { + Reset = true + }); + App.QuickAccessManager.PinnedItemsWatcher.EnableRaisingEvents = true; + } public async Task LoadAsync() => await UpdateItemsWithExplorer(); diff --git a/src/Files.App/UserControls/Widgets/QuickAccessWidget.xaml.cs b/src/Files.App/UserControls/Widgets/QuickAccessWidget.xaml.cs index 1121537990b2..c13157c0f3e5 100644 --- a/src/Files.App/UserControls/Widgets/QuickAccessWidget.xaml.cs +++ b/src/Files.App/UserControls/Widgets/QuickAccessWidget.xaml.cs @@ -41,12 +41,19 @@ public class ModifyQuickAccessEventArgs : EventArgs public string[] Paths { get; set; } public bool Add; public bool Pin = true; + public bool Reset = false; public ModifyQuickAccessEventArgs(string[] paths, bool add) { Paths = paths; Add = add; } + + public ModifyQuickAccessEventArgs() + { + Paths = Array.Empty(); + Add = false; + } } public class FolderCardItem : WidgetCardItem, IWidgetCardItem @@ -237,6 +244,32 @@ private async void ModifyItem(object? sender, ModifyQuickAccessEventArgs? e) await DispatcherQueue.EnqueueAsync(async () => { + if (e.Reset) + { + // Find the intersection between the two lists and determine whether to remove or add + var itemsToRemove = ItemsAdded.Where(x => !e.Paths.Contains(x.Path)).ToList(); + var itemsToAdd = e.Paths.Where(x => !ItemsAdded.Any(y => y.Path == x)).ToList(); + + // Remove items + foreach (var itemToRemove in itemsToRemove) + ItemsAdded.Remove(itemToRemove); + + // Add items + foreach (var itemToAdd in itemsToAdd) + { + var item = await App.QuickAccessManager.Model.CreateLocationItemFromPathAsync(itemToAdd); + var lastIndex = ItemsAdded.IndexOf(ItemsAdded.FirstOrDefault(x => !x.IsPinned)); + ItemsAdded.Insert(e.Pin && lastIndex >= 0 ? lastIndex : ItemsAdded.Count, new FolderCardItem(item, Path.GetFileName(item.Text), e.Pin) + { + Path = item.Path, + SelectCommand = QuickAccessCardCommand + }); + } + var cardLoadTasks = ItemsAdded.Select(cardItem => cardItem.LoadCardThumbnailAsync()); + await Task.WhenAll(cardLoadTasks); + + return; + } if (e.Add) { foreach (var itemToAdd in e.Paths) From 9571232abc29e3fddeb3b77b37ae83f0fb763af9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Garc=C3=ADa=20Ruiz?= Date: Fri, 10 Mar 2023 14:04:06 +0100 Subject: [PATCH 4/5] Add constant for the string resource --- src/Files.App/Helpers/JumpListManager.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Files.App/Helpers/JumpListManager.cs b/src/Files.App/Helpers/JumpListManager.cs index 5fab7519c8bf..5a0291001fbd 100644 --- a/src/Files.App/Helpers/JumpListManager.cs +++ b/src/Files.App/Helpers/JumpListManager.cs @@ -15,6 +15,8 @@ public sealed class JumpListManager { private JumpList instance = null; private List JumpListItemPaths { get; set; } + private readonly string JumpListRecentGroupHeader = "ms-resource:///Resources/JumpListRecentGroupHeader"; + private readonly string JumpListPinnedGroupHeader = "ms-resource:///Resources/JumpListPinnedGroupHeader"; public JumpListManager() { @@ -52,7 +54,7 @@ public async void AddFolderToJumpList(string path) { if (instance is not null) { - AddFolder(path, "ms-resource:///Resources/JumpListRecentGroupHeader"); + AddFolder(path, JumpListRecentGroupHeader); await instance.SaveAsync(); } } @@ -114,7 +116,7 @@ private void AddFolder(string path, string group) jumplistItem.GroupName = group; jumplistItem.Logo = new Uri("ms-appx:///Assets/FolderIcon.png"); - if (string.Equals(group, "ms-resource:///Resources/JumpListRecentGroupHeader", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(group, JumpListRecentGroupHeader, StringComparison.OrdinalIgnoreCase)) { // Keep newer items at the top. instance.Items.Remove(instance.Items.FirstOrDefault(x => x.Arguments.Equals(path, StringComparison.OrdinalIgnoreCase))); @@ -125,7 +127,7 @@ private void AddFolder(string path, string group) } else { - var pinnedItemsCount = instance.Items.Where(x => x.GroupName == "ms-resource:///Resources/JumpListPinnedGroupHeader").Count(); + var pinnedItemsCount = instance.Items.Where(x => x.GroupName == JumpListPinnedGroupHeader).Count(); instance.Items.Insert(pinnedItemsCount, jumplistItem); } } @@ -155,9 +157,9 @@ private async void QuickAccessManager_DataChanged(object sender, ModifyQuickAcce if (instance is null) return; - var itemsToRemove = instance.Items.Where(x => string.Equals(x.GroupName, "ms-resource:///Resources/JumpListPinnedGroupHeader", StringComparison.OrdinalIgnoreCase)).ToList(); + var itemsToRemove = instance.Items.Where(x => string.Equals(x.GroupName, JumpListPinnedGroupHeader, StringComparison.OrdinalIgnoreCase)).ToList(); itemsToRemove.ForEach(x => instance.Items.Remove(x)); - App.QuickAccessManager.Model.FavoriteItems.ForEach(x => AddFolder(x, "ms-resource:///Resources/JumpListPinnedGroupHeader")); + App.QuickAccessManager.Model.FavoriteItems.ForEach(x => AddFolder(x, JumpListPinnedGroupHeader)); await instance.SaveAsync(); } } From c13d2e47b9e00019dac87e01369a28c6d0c02fe2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Garc=C3=ADa=20Ruiz?= Date: Sat, 11 Mar 2023 13:27:35 +0100 Subject: [PATCH 5/5] Fix? --- src/Files.App/DataModels/SidebarPinnedModel.cs | 2 +- .../UserControls/Widgets/QuickAccessWidget.xaml.cs | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Files.App/DataModels/SidebarPinnedModel.cs b/src/Files.App/DataModels/SidebarPinnedModel.cs index bbb0d1688497..df3c90aa19f3 100644 --- a/src/Files.App/DataModels/SidebarPinnedModel.cs +++ b/src/Files.App/DataModels/SidebarPinnedModel.cs @@ -197,7 +197,7 @@ public async void LoadAsync(object? sender, FileSystemEventArgs e) { App.QuickAccessManager.PinnedItemsWatcher.EnableRaisingEvents = false; await LoadAsync(); - App.QuickAccessManager.UpdateQuickAccessWidget?.Invoke(null, new ModifyQuickAccessEventArgs(FavoriteItems.ToArray(), true) + App.QuickAccessManager.UpdateQuickAccessWidget?.Invoke(null, new ModifyQuickAccessEventArgs((await QuickAccessService.GetPinnedFoldersAsync()).Select(x => x.FilePath).ToArray(), true) { Reset = true }); diff --git a/src/Files.App/UserControls/Widgets/QuickAccessWidget.xaml.cs b/src/Files.App/UserControls/Widgets/QuickAccessWidget.xaml.cs index c13157c0f3e5..f80cbedfb5bc 100644 --- a/src/Files.App/UserControls/Widgets/QuickAccessWidget.xaml.cs +++ b/src/Files.App/UserControls/Widgets/QuickAccessWidget.xaml.cs @@ -8,6 +8,7 @@ using Files.App.ViewModels; using Files.App.ViewModels.Widgets; using Files.Backend.Services.Settings; +using Files.Shared; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Input; @@ -39,6 +40,7 @@ public class QuickAccessCardInvokedEventArgs : EventArgs public class ModifyQuickAccessEventArgs : EventArgs { public string[] Paths { get; set; } + public ShellFileItem[] Items { get; set; } public bool Add; public bool Pin = true; public bool Reset = false; @@ -49,10 +51,11 @@ public ModifyQuickAccessEventArgs(string[] paths, bool add) Add = add; } - public ModifyQuickAccessEventArgs() + public ModifyQuickAccessEventArgs(ShellFileItem[] items, bool add) { - Paths = Array.Empty(); - Add = false; + Paths = items.Select(x => x.FilePath).ToArray(); + Items = items; + Add = add; } } @@ -259,7 +262,9 @@ await DispatcherQueue.EnqueueAsync(async () => { var item = await App.QuickAccessManager.Model.CreateLocationItemFromPathAsync(itemToAdd); var lastIndex = ItemsAdded.IndexOf(ItemsAdded.FirstOrDefault(x => !x.IsPinned)); - ItemsAdded.Insert(e.Pin && lastIndex >= 0 ? lastIndex : ItemsAdded.Count, new FolderCardItem(item, Path.GetFileName(item.Text), e.Pin) + var isPinned = (bool?)e.Items.Where(x => x.FilePath == itemToAdd).FirstOrDefault().Properties["System.Home.IsPinned"] ?? false; + + ItemsAdded.Insert(isPinned && lastIndex >= 0 ? lastIndex : ItemsAdded.Count, new FolderCardItem(item, Path.GetFileName(item.Text), isPinned) { Path = item.Path, SelectCommand = QuickAccessCardCommand