refactor(ui): Material icons for list, folder and smart-list icon keys with legacy mapping

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
mika kuns
2026-10-01 16:50:31 +02:00
co-authored by Claude Sonnet 5.5
parent aef41f0594
commit 7c0fe92a3e
4 changed files with 93 additions and 18 deletions
@@ -157,12 +157,11 @@ public sealed partial class ListSettingsModalViewModel : ViewModelBase
/// <summary>Default icon for folders, kept apart from <see cref="DefaultIcon"/> so lists never look like folders.</summary>
public const string DefaultFolderIcon = "Folder";
// Curated subset of the Icon.* geometry library in IslandStyles.axaml — window chrome and
// pure stroke icons (PathIcon fills, so those render invisible) are deliberately left out.
// Grouped by theme so the picker grid reads in rows; every entry needs a matching
// "Icon.<key>" StreamGeometry or it renders as an empty slot.
public static readonly string[] IconOptions =
[
// Curated picker set, grouped by theme so the grid reads in rows. Each legacy key is offered as its
// MDI replacement (IconKeyConverter.LegacyKinds); "Dot" and "Folder" stay bare because they are the
// default-icon constants the sidebar compares against.
public static readonly string[] IconOptions = new[]
{
// general
"Dot", "Folder", "Star", "Sun", "Calendar", "Clock", "Inbox", "Mail", "Text", "Search", "Grid",
// dev
@@ -171,7 +170,7 @@ public sealed partial class ListSettingsModalViewModel : ViewModelBase
"Activity", "Eye", "Check", "Warning", "Chart", "Rocket", "Bulb", "Broom", "AgentSuggested", "Settings",
// things
"Box", "Truck", "MapPin", "Camera", "Image", "Barcode", "Skull",
];
}.Select(k => k is DefaultIcon or DefaultFolderIcon ? k : IconKeyConverter.MdiPrefix + IconKeyConverter.LegacyKinds[k]).ToArray();
/// <summary>Cap on search hits so the picker's WrapPanel stays responsive.</summary>
public const int MaxIconResults = 200;
@@ -195,9 +194,10 @@ public sealed partial class ListSettingsModalViewModel : ViewModelBase
// Separate from Icon: swapping Icons makes the ListBox push null here, which must not wipe the choice.
[ObservableProperty] private string? _selectedIconOption = DefaultIcon;
/// <summary>True for a curated key or an existing "mdi:" kind.</summary>
/// <summary>True for a curated key, a legacy bare key still stored in the DB, or an existing "mdi:" kind.</summary>
public static bool IsKnownIcon(string? key) =>
key is not null && (IconOptions.Contains(key)
|| IconKeyConverter.LegacyKinds.ContainsKey(key)
|| (key.StartsWith(IconKeyConverter.MdiPrefix, StringComparison.Ordinal)
&& Enum.TryParse<MaterialIconKind>(key[IconKeyConverter.MdiPrefix.Length..], out _)));