Skip to content

Commit 0eb8ac0

Browse files
Feature: Added Tags section in settings (#11320)
1 parent ec9d493 commit 0eb8ac0

File tree

9 files changed

+544
-475
lines changed

9 files changed

+544
-475
lines changed

src/Files.App/Dialogs/SettingsDialog.xaml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,21 @@
9595
<FontIcon Glyph="&#xE8B7;" />
9696
</NavigationViewItem.Icon>
9797
</NavigationViewItem>
98+
<NavigationViewItem
99+
AccessKey="T"
100+
AutomationProperties.AutomationId="SettingsItemTags"
101+
Content="{helpers:ResourceString Name=FileTags}"
102+
Tag="3">
103+
<NavigationViewItem.Icon>
104+
<FontIcon Glyph="&#xE1CB;" />
105+
</NavigationViewItem.Icon>
106+
</NavigationViewItem>
98107
<NavigationViewItem
99108
AccessKey="E"
100109
AutomationProperties.AutomationId="SettingsItemAdvanced"
101110
Content="{helpers:ResourceString Name=Advanced}"
102111
CornerRadius="0"
103-
Tag="3">
112+
Tag="4">
104113
<NavigationViewItem.Icon>
105114
<FontIcon Glyph="&#xF1AD;" />
106115
</NavigationViewItem.Icon>
@@ -109,7 +118,7 @@
109118
AccessKey="B"
110119
AutomationProperties.AutomationId="SettingsItemAbout"
111120
Content="{helpers:ResourceString Name=About}"
112-
Tag="4">
121+
Tag="5">
113122
<NavigationViewItem.Icon>
114123
<FontIcon FontSize="16" Glyph="&#xE946;" />
115124
</NavigationViewItem.Icon>

src/Files.App/Dialogs/SettingsDialog.xaml.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@ private void SettingsPane_SelectionChanged(NavigationView sender, NavigationView
5151
0 => SettingsContentFrame.Navigate(typeof(Appearance)),
5252
1 => SettingsContentFrame.Navigate(typeof(Preferences)),
5353
2 => SettingsContentFrame.Navigate(typeof(Folders)),
54-
3 => SettingsContentFrame.Navigate(typeof(Advanced)),
55-
4 => SettingsContentFrame.Navigate(typeof(About)),
54+
3 => SettingsContentFrame.Navigate(typeof(Tags)),
55+
4 => SettingsContentFrame.Navigate(typeof(Advanced)),
56+
5 => SettingsContentFrame.Navigate(typeof(About)),
5657
_ => SettingsContentFrame.Navigate(typeof(Appearance))
5758
};
5859
}

src/Files.App/ViewModels/SettingsViewModels/AdvancedViewModel.cs

Lines changed: 1 addition & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,12 @@
77
using Files.App.Helpers;
88
using Files.App.Shell;
99
using Files.Backend.Services.Settings;
10-
using Files.Backend.ViewModels.FileTags;
1110
using Files.Shared.Extensions;
1211
using Microsoft.Win32;
1312
using SevenZip;
1413
using System;
15-
using System.Collections.ObjectModel;
1614
using System.Diagnostics;
1715
using System.IO;
18-
using System.Linq;
1916
using System.Text;
2017
using System.Threading.Tasks;
2118
using System.Windows.Input;
@@ -31,25 +28,14 @@ public class AdvancedViewModel : ObservableObject
3128
private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetRequiredService<IUserSettingsService>();
3229

3330
private readonly IBundlesSettingsService bundlesSettingsService = Ioc.Default.GetRequiredService<IBundlesSettingsService>();
34-
31+
3532
private readonly IFileTagsSettingsService fileTagsSettingsService = Ioc.Default.GetRequiredService<IFileTagsSettingsService>();
3633

37-
private bool isBulkOperation = true;
38-
39-
private bool isDragStarting = true;
40-
4134
public ICommand SetAsDefaultExplorerCommand { get; }
4235
public ICommand SetAsOpenFileDialogCommand { get; }
4336
public ICommand ExportSettingsCommand { get; }
4437
public ICommand ImportSettingsCommand { get; }
4538
public ICommand OpenSettingsJsonCommand { get; }
46-
public ICommand AddTagCommand { get; }
47-
public ICommand SaveNewTagCommand { get; }
48-
public ICommand CancelNewTagCommand { get; }
49-
50-
public NewTagViewModel NewTag = new();
51-
52-
public ObservableCollection<ListedTagViewModel> Tags { get; set; }
5339

5440
public AdvancedViewModel()
5541
{
@@ -61,35 +47,6 @@ public AdvancedViewModel()
6147
ExportSettingsCommand = new AsyncRelayCommand(ExportSettings);
6248
ImportSettingsCommand = new AsyncRelayCommand(ImportSettings);
6349
OpenSettingsJsonCommand = new AsyncRelayCommand(OpenSettingsJson);
64-
65-
// Tags Commands
66-
AddTagCommand = new RelayCommand(DoAddNewTag);
67-
SaveNewTagCommand = new RelayCommand(DoSaveNewTag);
68-
CancelNewTagCommand = new RelayCommand(DoCancelNewTag);
69-
70-
Tags = new ObservableCollection<ListedTagViewModel>();
71-
Tags.CollectionChanged += Tags_CollectionChanged;
72-
fileTagsSettingsService.FileTagList?.ForEach(tag => Tags.Add(new ListedTagViewModel(tag)));
73-
74-
isBulkOperation = false;
75-
}
76-
77-
private void Tags_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
78-
{
79-
if (isBulkOperation)
80-
return;
81-
82-
// Reaordering ListView has no events, but its collection is updated twice,
83-
// first to remove the selected item, and second to add the item at the selected position.
84-
if (isDragStarting)
85-
{
86-
isDragStarting = false;
87-
return;
88-
}
89-
90-
isDragStarting = true;
91-
92-
fileTagsSettingsService.FileTagList = Tags.Select(tagVM => tagVM.Tag).ToList();
9350
}
9451

9552
private async Task OpenSettingsJson()
@@ -322,13 +279,6 @@ public bool IsSetAsOpenFileDialog
322279
set => SetProperty(ref isSetAsOpenFileDialog, value);
323280
}
324281

325-
private bool isCreatingNewTag;
326-
public bool IsCreatingNewTag
327-
{
328-
get => isCreatingNewTag;
329-
set => SetProperty(ref isCreatingNewTag, value);
330-
}
331-
332282
private FileSavePicker InitializeWithWindow(FileSavePicker obj)
333283
{
334284
WinRT.Interop.InitializeWithWindow.Initialize(obj, App.WindowHandle);
@@ -342,81 +292,5 @@ private FileOpenPicker InitializeWithWindow(FileOpenPicker obj)
342292

343293
return obj;
344294
}
345-
346-
private void DoAddNewTag()
347-
{
348-
NewTag.Reset();
349-
IsCreatingNewTag = true;
350-
}
351-
352-
private void DoSaveNewTag()
353-
{
354-
IsCreatingNewTag = false;
355-
356-
fileTagsSettingsService.CreateNewTag(NewTag.Name, NewTag.Color);
357-
358-
isBulkOperation = true;
359-
Tags.Clear();
360-
fileTagsSettingsService.FileTagList?.ForEach(tag => Tags.Add(new ListedTagViewModel(tag)));
361-
isBulkOperation = false;
362-
}
363-
364-
private void DoCancelNewTag()
365-
{
366-
IsCreatingNewTag = false;
367-
}
368-
369-
public void EditExistingTag(ListedTagViewModel item, string newName, string color)
370-
{
371-
fileTagsSettingsService.EditTag(item.Tag.Uid, newName, color);
372-
373-
isBulkOperation = true;
374-
Tags.Clear();
375-
fileTagsSettingsService.FileTagList?.ForEach(tag => Tags.Add(new ListedTagViewModel(tag)));
376-
isBulkOperation = false;
377-
}
378-
379-
public void DeleteExistingTag(ListedTagViewModel item)
380-
{
381-
isBulkOperation = true;
382-
Tags.Remove(item);
383-
isBulkOperation = false;
384-
385-
fileTagsSettingsService.DeleteTag(item.Tag.Uid);
386-
}
387-
}
388-
389-
public class NewTagViewModel : ObservableObject
390-
{
391-
private string name = string.Empty;
392-
public string Name
393-
{
394-
get => name;
395-
set
396-
{
397-
if (SetProperty(ref name, value))
398-
OnPropertyChanged(nameof(IsNameValid));
399-
}
400-
}
401-
402-
private string color = "#FFFFFFFF";
403-
public string Color
404-
{
405-
get => color;
406-
set => SetProperty(ref color, value);
407-
}
408-
409-
private bool isNameValid;
410-
public bool IsNameValid
411-
{
412-
get => isNameValid;
413-
set => SetProperty(ref isNameValid, value);
414-
}
415-
416-
public void Reset()
417-
{
418-
Name = string.Empty;
419-
Color = ColorHelpers.RandomColor();
420-
}
421295
}
422296
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
using CommunityToolkit.Mvvm.ComponentModel;
2+
using CommunityToolkit.Mvvm.DependencyInjection;
3+
using CommunityToolkit.Mvvm.Input;
4+
using Files.App.Helpers;
5+
using Files.Backend.Services.Settings;
6+
using Files.Backend.ViewModels.FileTags;
7+
using Files.Shared.Extensions;
8+
using System.Collections.ObjectModel;
9+
using System.Linq;
10+
using System.Windows.Input;
11+
12+
namespace Files.App.ViewModels.SettingsViewModels
13+
{
14+
public class TagsSettingsViewModel : ObservableObject
15+
{
16+
private readonly IFileTagsSettingsService fileTagsSettingsService = Ioc.Default.GetRequiredService<IFileTagsSettingsService>();
17+
18+
private bool isBulkOperation = true;
19+
20+
private bool isDragStarting = true;
21+
22+
private bool isCreatingNewTag;
23+
public bool IsCreatingNewTag
24+
{
25+
get => isCreatingNewTag;
26+
set => SetProperty(ref isCreatingNewTag, value);
27+
}
28+
29+
public ObservableCollection<ListedTagViewModel> Tags { get; set; }
30+
31+
public ICommand AddTagCommand { get; }
32+
public ICommand SaveNewTagCommand { get; }
33+
public ICommand CancelNewTagCommand { get; }
34+
35+
public NewTagViewModel NewTag = new();
36+
37+
public TagsSettingsViewModel()
38+
{
39+
// Tags Commands
40+
AddTagCommand = new RelayCommand(DoAddNewTag);
41+
SaveNewTagCommand = new RelayCommand(DoSaveNewTag);
42+
CancelNewTagCommand = new RelayCommand(DoCancelNewTag);
43+
44+
Tags = new ObservableCollection<ListedTagViewModel>();
45+
Tags.CollectionChanged += Tags_CollectionChanged;
46+
fileTagsSettingsService.FileTagList?.ForEach(tag => Tags.Add(new ListedTagViewModel(tag)));
47+
48+
isBulkOperation = false;
49+
}
50+
51+
private void Tags_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
52+
{
53+
if (isBulkOperation)
54+
return;
55+
56+
// Reaordering ListView has no events, but its collection is updated twice,
57+
// first to remove the selected item, and second to add the item at the selected position.
58+
if (isDragStarting)
59+
{
60+
isDragStarting = false;
61+
return;
62+
}
63+
isDragStarting = true;
64+
65+
fileTagsSettingsService.FileTagList = Tags.Select(tagVM => tagVM.Tag).ToList();
66+
}
67+
68+
private void DoAddNewTag()
69+
{
70+
NewTag.Reset();
71+
IsCreatingNewTag = true;
72+
}
73+
74+
private void DoSaveNewTag()
75+
{
76+
IsCreatingNewTag = false;
77+
78+
fileTagsSettingsService.CreateNewTag(NewTag.Name, NewTag.Color);
79+
80+
isBulkOperation = true;
81+
Tags.Clear();
82+
fileTagsSettingsService.FileTagList?.ForEach(tag => Tags.Add(new ListedTagViewModel(tag)));
83+
isBulkOperation = false;
84+
}
85+
86+
private void DoCancelNewTag()
87+
{
88+
IsCreatingNewTag = false;
89+
}
90+
91+
public void EditExistingTag(ListedTagViewModel item, string newName, string color)
92+
{
93+
fileTagsSettingsService.EditTag(item.Tag.Uid, newName, color);
94+
95+
isBulkOperation = true;
96+
Tags.Clear();
97+
fileTagsSettingsService.FileTagList?.ForEach(tag => Tags.Add(new ListedTagViewModel(tag)));
98+
isBulkOperation = false;
99+
}
100+
101+
public void DeleteExistingTag(ListedTagViewModel item)
102+
{
103+
isBulkOperation = true;
104+
Tags.Remove(item);
105+
isBulkOperation = false;
106+
107+
fileTagsSettingsService.DeleteTag(item.Tag.Uid);
108+
}
109+
}
110+
111+
public class NewTagViewModel : ObservableObject
112+
{
113+
private string name = string.Empty;
114+
public string Name
115+
{
116+
get => name;
117+
set
118+
{
119+
if (SetProperty(ref name, value))
120+
OnPropertyChanged(nameof(IsNameValid));
121+
}
122+
}
123+
124+
private string color = "#FFFFFFFF";
125+
public string Color
126+
{
127+
get => color;
128+
set => SetProperty(ref color, value);
129+
}
130+
131+
private bool isNameValid;
132+
public bool IsNameValid
133+
{
134+
get => isNameValid;
135+
set => SetProperty(ref isNameValid, value);
136+
}
137+
138+
public void Reset()
139+
{
140+
Name = string.Empty;
141+
Color = ColorHelpers.RandomColor();
142+
}
143+
}
144+
}

0 commit comments

Comments
 (0)