Skip to content

Commit ae1d9af

Browse files
Feature: Added "open all" when right clicking a tag in the sidebar (#12991)
1 parent fefee98 commit ae1d9af

File tree

6 files changed

+64
-40
lines changed

6 files changed

+64
-40
lines changed

src/Files.App/Actions/Content/Tags/OpenAllTaggedActions.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ public OpenAllTaggedActions()
3333

3434
public async Task ExecuteAsync()
3535
{
36-
var files = _tagsContext.TaggedItems.Where(item => !item.IsFolder);
37-
var folders = _tagsContext.TaggedItems.Where(item => item.IsFolder);
36+
var files = _tagsContext.TaggedItems.Where(item => !item.isFolder);
37+
var folders = _tagsContext.TaggedItems.Where(item => item.isFolder);
3838

3939
await Task.WhenAll(files.Select(file
40-
=> NavigationHelpers.OpenPath(file.Path, _pageContext.ShellPage!)));
40+
=> NavigationHelpers.OpenPath(file.path, _pageContext.ShellPage!)));
4141

42-
folders.ForEach(async folder => await NavigationHelpers.OpenPathInNewTab(folder.Path));
42+
folders.ForEach(async folder => await NavigationHelpers.OpenPathInNewTab(folder.path));
4343
}
4444

4545
private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e)
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
// Copyright (c) 2023 Files Community
22
// Licensed under the MIT License. See the LICENSE.
33

4-
using Files.App.ViewModels.Widgets;
5-
64
namespace Files.App.Data.Contexts
75
{
86
interface ITagsContext: INotifyPropertyChanged
97
{
10-
IEnumerable<FileTagsItemViewModel> TaggedItems { get; }
8+
IEnumerable<(string path, bool isFolder)> TaggedItems { get; }
119
}
1210
}

src/Files.App/Data/Contexts/Tags/TagsContext.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ namespace Files.App.Data.Contexts
88
{
99
sealed class TagsContext : ITagsContext
1010
{
11-
private static readonly IReadOnlyList<FileTagsItemViewModel> _emptyTaggedItemsList
12-
= Enumerable.Empty<FileTagsItemViewModel>().ToImmutableList();
11+
private static readonly IReadOnlyList<(string path, bool isFolder)> _emptyTaggedItemsList
12+
= Enumerable.Empty<(string path, bool isFolder)>().ToImmutableList();
1313

1414
public event PropertyChangedEventHandler? PropertyChanged;
1515

16-
private IEnumerable<FileTagsItemViewModel> _TaggedItems = _emptyTaggedItemsList;
17-
public IEnumerable<FileTagsItemViewModel> TaggedItems
16+
private IEnumerable<(string path, bool isFolder)> _TaggedItems = _emptyTaggedItemsList;
17+
public IEnumerable<(string path, bool isFolder)> TaggedItems
1818
{
1919
get => _TaggedItems;
2020
set
@@ -29,12 +29,13 @@ public IEnumerable<FileTagsItemViewModel> TaggedItems
2929

3030
public TagsContext()
3131
{
32-
FileTagsContainerViewModel.SelectedTagsChanged += FileTagsContainerViewModel_SelectedTagsChanged;
32+
FileTagsContainerViewModel.SelectedTagChanged += SelectedTagsChanged;
33+
SidebarControl.SelectedTagChanged += SelectedTagsChanged;
3334
}
3435

35-
private void FileTagsContainerViewModel_SelectedTagsChanged(object sender, IEnumerable<FileTagsItemViewModel> items)
36+
private void SelectedTagsChanged(object _, SelectedTagChangedEventArgs e)
3637
{
37-
TaggedItems = items;
38+
TaggedItems = e.Items;
3839
}
3940
}
4041
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Copyright (c) 2023 Files Community
2+
// Licensed under the MIT License. See the LICENSE.
3+
4+
namespace Files.App.Data.EventArguments
5+
{
6+
public record SelectedTagChangedEventArgs(IEnumerable<(string path, bool isFolder)> Items);
7+
}

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

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,18 @@
11
// Copyright (c) 2023 Files Community
22
// Licensed under the MIT License. See the LICENSE.
33

4-
using CommunityToolkit.Mvvm.DependencyInjection;
5-
using CommunityToolkit.Mvvm.Input;
64
using CommunityToolkit.WinUI.UI;
7-
using Files.App.Data.Commands;
8-
using Files.App.Data.Items;
9-
using Files.App.Data.Models;
10-
using Files.App.Extensions;
115
using Files.App.Helpers.ContextFlyouts;
126
using Files.App.Services;
13-
using Files.App.Utils.Shell;
14-
using Files.App.ViewModels;
157
using Files.App.ViewModels.Dialogs;
16-
using Files.Core.Services;
17-
using Files.Core.Services.Settings;
18-
using Files.Shared.Extensions;
8+
using Files.Core.Storage;
9+
using Files.Core.Storage.Extensions;
1910
using Microsoft.UI.Input;
2011
using Microsoft.UI.Xaml;
2112
using Microsoft.UI.Xaml.Controls;
2213
using Microsoft.UI.Xaml.Controls.Primitives;
2314
using Microsoft.UI.Xaml.Input;
24-
using System;
25-
using System.Collections.Generic;
26-
using System.ComponentModel;
27-
using System.Linq;
2815
using System.Runtime.CompilerServices;
29-
using System.Threading.Tasks;
3016
using System.Windows.Input;
3117
using Windows.ApplicationModel.DataTransfer;
3218
using Windows.ApplicationModel.DataTransfer.DragDrop;
@@ -38,10 +24,16 @@ namespace Files.App.UserControls
3824
{
3925
public sealed partial class SidebarControl : NavigationView, INotifyPropertyChanged
4026
{
41-
private readonly IUserSettingsService userSettingsService = Ioc.Default.GetRequiredService<IUserSettingsService>();
42-
private readonly ICommandManager commands = Ioc.Default.GetRequiredService<ICommandManager>();
27+
private readonly IUserSettingsService userSettingsService;
4328

44-
public IQuickAccessService QuickAccessService { get; } = Ioc.Default.GetRequiredService<IQuickAccessService>();
29+
private readonly ICommandManager commands;
30+
31+
private readonly IFileTagsService _fileTagsService;
32+
public IQuickAccessService QuickAccessService { get; }
33+
34+
public delegate void SelectedTagChangedEventHandler(object sender, SelectedTagChangedEventArgs e);
35+
36+
public static event SelectedTagChangedEventHandler? SelectedTagChanged;
4537

4638
public delegate void SidebarItemInvokedEventHandler(object sender, SidebarItemInvokedEventArgs e);
4739

@@ -130,6 +122,11 @@ public UIElement TabContent
130122

131123
public SidebarControl()
132124
{
125+
userSettingsService = Ioc.Default.GetRequiredService<IUserSettingsService>();
126+
commands = Ioc.Default.GetRequiredService<ICommandManager>();
127+
_fileTagsService = Ioc.Default.GetRequiredService<IFileTagsService>();
128+
QuickAccessService = Ioc.Default.GetRequiredService<IQuickAccessService>();
129+
133130
InitializeComponent();
134131

135132
dragOverSectionTimer = DispatcherQueue.CreateTimer();
@@ -190,6 +187,8 @@ private List<ContextMenuFlyoutItemViewModel> GetLocationItemMenuItems(INavigatio
190187
var isDriveItem = item is DriveItem;
191188
var isDriveItemPinned = isDriveItem && ((DriveItem)item).IsPinned;
192189

190+
var isTagItem = item is FileTagItem;
191+
193192
return new List<ContextMenuFlyoutItemViewModel>()
194193
{
195194
new ContextMenuFlyoutItemViewModel()
@@ -240,6 +239,10 @@ private List<ContextMenuFlyoutItemViewModel> GetLocationItemMenuItems(INavigatio
240239
Command = OpenInNewPaneCommand,
241240
ShowItem = options.IsLocationItem && userSettingsService.GeneralSettingsService.ShowOpenInNewPane
242241
},
242+
new ContextMenuFlyoutItemViewModelBuilder(commands.OpenAllTaggedItems)
243+
{
244+
IsVisible = isTagItem
245+
}.Build(),
243246
new ContextMenuFlyoutItemViewModel()
244247
{
245248
Text = "PinToFavorites".GetLocalizedResource(),
@@ -456,14 +459,29 @@ private void PaneRoot_RightTapped(object sender, RightTappedRoutedEventArgs e)
456459
e.Handled = true;
457460
}
458461

459-
private void NavigationViewItem_RightTapped(object sender, RightTappedRoutedEventArgs e)
462+
private async void NavigationViewItem_RightTapped(object sender, RightTappedRoutedEventArgs e)
460463
{
461464
var itemContextMenuFlyout = new CommandBarFlyout { Placement = FlyoutPlacementMode.Full };
462465
itemContextMenuFlyout.Opening += (sender, e) => App.LastOpenedFlyout = sender as CommandBarFlyout;
463466
if (sender is not NavigationViewItem sidebarItem ||
464467
sidebarItem.DataContext is not INavigationControlItem item)
465468
return;
466469

470+
if (item is FileTagItem tagItem)
471+
{
472+
var cts = new CancellationTokenSource();
473+
var items = new List<(string path, bool isFolder)>();
474+
475+
await foreach (var taggedItem in _fileTagsService.GetItemsForTagAsync(tagItem.FileTag.Uid, cts.Token))
476+
{
477+
items.Add((
478+
taggedItem.Storable.TryGetPath() ?? string.Empty,
479+
taggedItem.Storable is IFolder));
480+
}
481+
482+
SelectedTagChanged?.Invoke(this, new SelectedTagChangedEventArgs(items));
483+
}
484+
467485
rightClickedItem = item;
468486

469487
var menuItems = GetLocationItemMenuItems(item, itemContextMenuFlyout);
@@ -626,7 +644,7 @@ private async void NavigationViewLocationItem_DragOver(object sender, DragEventA
626644
}
627645
CompleteDragEventArgs(e, captionText, operationType);
628646
}
629-
}
647+
}
630648

631649
deferral.Complete();
632650
}
@@ -665,7 +683,7 @@ private async void NavigationViewLocationItem_Drop(object sender, DragEventArgs
665683
foreach (var item in storageItems)
666684
{
667685
if (item.ItemType == FilesystemItemType.Directory && !SidebarPinnedModel.FavoriteItems.Contains(item.Path))
668-
QuickAccessService.PinToSidebar(item.Path);
686+
await QuickAccessService.PinToSidebar(item.Path);
669687
}
670688
}
671689
else

src/Files.App/ViewModels/Widgets/FileTagsContainerViewModel.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) 2023 Files Community
22
// Licensed under the MIT License. See the LICENSE.
33

4-
using Files.Core.Services;
4+
using Files.Core.Storage;
55
using Files.Shared.Utils;
66

77
namespace Files.App.ViewModels.Widgets
@@ -18,9 +18,9 @@ public sealed partial class FileTagsContainerViewModel : ObservableObject, IAsyn
1818

1919
private readonly ICommandManager _commands;
2020

21-
public delegate void SelectedTagsChangedEventHandler(object sender, IEnumerable<FileTagsItemViewModel> items);
21+
public delegate void SelectedTagChangedEventHandler(object sender, SelectedTagChangedEventArgs e);
2222

23-
public static event SelectedTagsChangedEventHandler? SelectedTagsChanged;
23+
public static event SelectedTagChangedEventHandler? SelectedTagChanged;
2424

2525
public ObservableCollection<FileTagsItemViewModel> Tags { get; }
2626

@@ -60,7 +60,7 @@ private Task ViewMore(CancellationToken cancellationToken)
6060
[RelayCommand]
6161
private Task OpenAll(CancellationToken cancellationToken)
6262
{
63-
SelectedTagsChanged?.Invoke(this, Tags);
63+
SelectedTagChanged?.Invoke(this, new SelectedTagChangedEventArgs(Tags.Select(tag => (tag.Path, tag.IsFolder))));
6464

6565
return _commands.OpenAllTaggedItems.ExecuteAsync();
6666
}

0 commit comments

Comments
 (0)