Skip to content

Commit 05ea094

Browse files
committed
refactor(ui): centralize visible text/icons at Item layer
1 parent 7d7d63d commit 05ea094

12 files changed

Lines changed: 425 additions & 266 deletions

CmdPalWebSearchShortcut/WebSearchShortcut/Commands/OpenHomePageCommand.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
using Microsoft.CommandPalette.Extensions.Toolkit;
22
using WebSearchShortcut.Browsers;
3-
using WebSearchShortcut.Helpers;
4-
using WebSearchShortcut.Properties;
53

64
namespace WebSearchShortcut.Commands;
75

@@ -12,8 +10,8 @@ internal sealed partial class OpenHomePageCommand : InvokableCommand
1210

1311
internal OpenHomePageCommand(WebSearchShortcutDataEntry shortcut)
1412
{
15-
Name = StringFormatter.Format(Resources.OpenHomePage_NameTemplate, new() { ["engine"] = shortcut.Name });
16-
Icon = Icons.Search;
13+
Name = $"[UNBOUND] {nameof(OpenHomePageCommand)}.{nameof(Name)} required - shortcut='{shortcut.Name}'";
14+
1715
_shortcut = shortcut;
1816
_browserInfo = new BrowserExecutionInfo(shortcut);
1917
}

CmdPalWebSearchShortcut/WebSearchShortcut/Commands/SearchWebCommand.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
using Microsoft.CommandPalette.Extensions.Toolkit;
22
using WebSearchShortcut.Browsers;
3-
using WebSearchShortcut.Helpers;
4-
using WebSearchShortcut.Properties;
53

64
namespace WebSearchShortcut.Commands;
75

@@ -14,8 +12,8 @@ internal sealed partial class SearchWebCommand : InvokableCommand
1412

1513
public SearchWebCommand(WebSearchShortcutDataEntry shortcut, string query)
1614
{
17-
Name = StringFormatter.Format(Resources.SearchQuery_NameTemplate, new() { ["engine"] = shortcut.Name, ["query"] = query });
18-
Icon = Icons.Search;
15+
Name = $"[UNBOUND] {nameof(SearchWebCommand)}.{nameof(Name)} required - shortcut='{shortcut.Name}', query='{query}'";
16+
1917
_query = query;
2018
_shortcut = shortcut;
2119
_browserInfo = new BrowserExecutionInfo(shortcut);

CmdPalWebSearchShortcut/WebSearchShortcut/Forms/AddShortcutForm.cs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,29 +32,29 @@ public AddShortcutForm(WebSearchShortcutDataEntry? shortcut)
3232
{
3333
"id": "name",
3434
"type": "Input.Text",
35-
"label": {{JsonSerializer.Serialize(Resources.AddShortcutForm_NameLabel, AppJsonSerializerContext.Default.String)}},
35+
"label": {{JsonSerializer.Serialize(Resources.AddShortcutForm_Name_Label, AppJsonSerializerContext.Default.String)}},
3636
"value": {{JsonSerializer.Serialize(name, AppJsonSerializerContext.Default.String)}},
3737
"isRequired": true,
38-
"errorMessage": {{JsonSerializer.Serialize(Resources.AddShortcutForm_NameErrorMessage, AppJsonSerializerContext.Default.String)}}
38+
"errorMessage": {{JsonSerializer.Serialize(Resources.AddShortcutForm_Name_ErrorMessage, AppJsonSerializerContext.Default.String)}}
3939
},
4040
{
4141
"id": "url",
4242
"type": "Input.Text",
4343
"style": "Url",
44-
"label": {{JsonSerializer.Serialize(Resources.AddShortcutForm_UrlLabel, AppJsonSerializerContext.Default.String)}},
45-
"placeholder": {{JsonSerializer.Serialize(Resources.AddShortcutForm_UrlPlaceholder, AppJsonSerializerContext.Default.String)}},
44+
"label": {{JsonSerializer.Serialize(Resources.AddShortcutForm_Url_Label, AppJsonSerializerContext.Default.String)}},
45+
"placeholder": {{JsonSerializer.Serialize(Resources.AddShortcutForm_Url_Placeholder, AppJsonSerializerContext.Default.String)}},
4646
"value": {{JsonSerializer.Serialize(url, AppJsonSerializerContext.Default.String)}},
4747
"isRequired": true,
48-
"errorMessage": {{JsonSerializer.Serialize(Resources.AddShortcutForm_UrlErrorMessage, AppJsonSerializerContext.Default.String)}}
48+
"errorMessage": {{JsonSerializer.Serialize(Resources.AddShortcutForm_Url_ErrorMessage, AppJsonSerializerContext.Default.String)}}
4949
},
5050
{
5151
"id": "suggestionProvider",
5252
"type": "Input.ChoiceSet",
53-
"label": {{JsonSerializer.Serialize(Resources.AddShortcutForm_SuggestionProviderLabel, AppJsonSerializerContext.Default.String)}},
54-
"placeholder": {{JsonSerializer.Serialize(Resources.AddShortcutForm_SuggestionProviderPlaceholder, AppJsonSerializerContext.Default.String)}},
53+
"label": {{JsonSerializer.Serialize(Resources.AddShortcutForm_SuggestionProvider_Label, AppJsonSerializerContext.Default.String)}},
54+
"placeholder": {{JsonSerializer.Serialize(Resources.AddShortcutForm_SuggestionProvider_Placeholder, AppJsonSerializerContext.Default.String)}},
5555
"choices": [
5656
{
57-
"title": {{JsonSerializer.Serialize(Resources.AddShortcutForm_SuggestionProviderNone, AppJsonSerializerContext.Default.String)}},
57+
"title": {{JsonSerializer.Serialize(Resources.AddShortcutForm_SuggestionProvider_None, AppJsonSerializerContext.Default.String)}},
5858
"value": ""
5959
},
6060
{{SuggestionsRegistry.ProviderNames.Select(key => $$"""
@@ -71,28 +71,28 @@ public AddShortcutForm(WebSearchShortcutDataEntry? shortcut)
7171
"type": "Input.Text",
7272
"style": "text",
7373
"id": "replaceWhitespace",
74-
"label": {{JsonSerializer.Serialize(Resources.AddShortcutForm_ReplaceWhitespaceLabel, AppJsonSerializerContext.Default.String)}},
75-
"placeholder": {{JsonSerializer.Serialize(Resources.AddShortcutForm_ReplaceWhitespacePlaceholder, AppJsonSerializerContext.Default.String)}},
74+
"label": {{JsonSerializer.Serialize(Resources.AddShortcutForm_ReplaceWhitespace_Label, AppJsonSerializerContext.Default.String)}},
75+
"placeholder": {{JsonSerializer.Serialize(Resources.AddShortcutForm_ReplaceWhitespace_Placeholder, AppJsonSerializerContext.Default.String)}},
7676
"value": {{JsonSerializer.Serialize(replaceWhitespace, AppJsonSerializerContext.Default.String)}},
7777
"errorMessage": "// Just for space between items"
7878
},
7979
{
8080
"type": "Input.Text",
8181
"style": "text",
8282
"id": "homePage",
83-
"label": {{JsonSerializer.Serialize(Resources.AddShortcutForm_HomepageLabel, AppJsonSerializerContext.Default.String)}},
84-
"placeholder": {{JsonSerializer.Serialize(Resources.AddShortcutForm_HomepagePlaceholder, AppJsonSerializerContext.Default.String)}},
83+
"label": {{JsonSerializer.Serialize(Resources.AddShortcutForm_Homepage_Label, AppJsonSerializerContext.Default.String)}},
84+
"placeholder": {{JsonSerializer.Serialize(Resources.AddShortcutForm_Homepage_Placeholder, AppJsonSerializerContext.Default.String)}},
8585
"value": {{JsonSerializer.Serialize(homePage, AppJsonSerializerContext.Default.String)}},
8686
"errorMessage": "// Just for space between items"
8787
},
8888
{
8989
"id": "browserPath",
9090
"type": "Input.ChoiceSet",
91-
"label": {{JsonSerializer.Serialize(Resources.AddShortcutForm_BrowserPathLabel, AppJsonSerializerContext.Default.String)}},
91+
"label": {{JsonSerializer.Serialize(Resources.AddShortcutForm_BrowserPath_Label, AppJsonSerializerContext.Default.String)}},
9292
"placeholder": {{JsonSerializer.Serialize(browserPath, AppJsonSerializerContext.Default.String)}},
9393
"choices": [
9494
{
95-
"title": {{JsonSerializer.Serialize(Resources.AddShortcutForm_BrowserPathDefault, AppJsonSerializerContext.Default.String)}},
95+
"title": {{JsonSerializer.Serialize(Resources.AddShortcutForm_BrowserPath_Default, AppJsonSerializerContext.Default.String)}},
9696
"value": ""
9797
},
9898
{{BrowserDiscovery.GetAllInstalledBrowsers()
@@ -112,8 +112,8 @@ public AddShortcutForm(WebSearchShortcutDataEntry? shortcut)
112112
"id": "browserArgs",
113113
"type": "Input.Text",
114114
"style": "text",
115-
"label": {{JsonSerializer.Serialize(Resources.AddShortcutForm_BrowserArgsLabel, AppJsonSerializerContext.Default.String)}},
116-
"placeholder": {{JsonSerializer.Serialize(Resources.AddShortcutForm_BrowserArgsPlaceholder, AppJsonSerializerContext.Default.String)}},
115+
"label": {{JsonSerializer.Serialize(Resources.AddShortcutForm_BrowserArgs_Label, AppJsonSerializerContext.Default.String)}},
116+
"placeholder": {{JsonSerializer.Serialize(Resources.AddShortcutForm_BrowserArgs_Placeholder, AppJsonSerializerContext.Default.String)}},
117117
"value": {{JsonSerializer.Serialize(browserArgs, AppJsonSerializerContext.Default.String)}},
118118
"errorMessage": "// Just for space between items"
119119
}

CmdPalWebSearchShortcut/WebSearchShortcut/Pages/AddShortcutPage.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,13 @@ internal sealed partial class AddShortcutPage : ContentPage
1111

1212
public AddShortcutPage(WebSearchShortcutDataEntry? shortcut)
1313
{
14-
var name = shortcut?.Name ?? string.Empty;
15-
var url = shortcut?.Url ?? string.Empty;
16-
var isAdd = string.IsNullOrEmpty(name) && string.IsNullOrEmpty(url);
14+
bool isAdd = shortcut is null;
15+
16+
Title = isAdd ? Resources.AddShortcutPage_Title_Add : Resources.AddShortcutPage_Title_Edit;
17+
Name = $"[UNBOUND] {nameof(AddShortcutPage)}.{nameof(Name)} required - shortcut={(shortcut is null ? "null" : $"'{shortcut.Name}'")}";
18+
Icon = isAdd ? IconHelpers.FromRelativePath("Assets\\SearchAdd.png") : Icons.Edit;
1719

1820
_addShortcutForm = new AddShortcutForm(shortcut);
19-
Icon = IconHelpers.FromRelativePath("Assets\\SearchAdd.png");
20-
Title = isAdd ? Resources.AddShortcut_AddTitle : Resources.SearchShortcut_EditTitle;
21-
Name = isAdd ? Resources.AddShortcut_AddName : Resources.SearchShortcut_EditName;
2221
}
2322

2423
internal event TypedEventHandler<object, WebSearchShortcutDataEntry>? AddedCommand

CmdPalWebSearchShortcut/WebSearchShortcut/Pages/SearchWebPage.cs

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,13 @@ namespace WebSearchShortcut;
1414
internal sealed partial class SearchWebPage : DynamicListPage
1515
{
1616
private readonly WebSearchShortcutDataEntry _shortcut;
17-
private readonly IListItem _openHomePageItem;
17+
18+
private readonly IListItem _openHomepageListItem;
19+
private readonly IContextItem _openHomepageContextItem;
20+
1821
private IListItem[] _items = [];
1922
private IListItem[] _suggestionItems = [];
23+
2024
private int _lastUpdateSearchTextEpoch;
2125
private readonly Lock _swapSuggestionsCancellationSourceLock = new();
2226
private readonly Lock _renderLock = new();
@@ -25,16 +29,28 @@ internal sealed partial class SearchWebPage : DynamicListPage
2529

2630
public SearchWebPage(WebSearchShortcutDataEntry shortcut)
2731
{
32+
Title = StringFormatter.Format(Resources.SearchWebPage_TitleTemplate, new() { ["shortcut"] = shortcut.Name });
33+
Name = $"[UNBOUND] {nameof(SearchWebPage)}.{nameof(Name)} required - shortcut='{shortcut.Name}'";
34+
Icon = IconService.GetIconInfo(shortcut);
35+
2836
_shortcut = shortcut;
2937

30-
Name = shortcut.Name;
31-
Icon = IconService.GetIconInfo(shortcut);
32-
_openHomePageItem = new ListItem(new OpenHomePageCommand(shortcut))
38+
var openHomepagecommand = new OpenHomePageCommand(shortcut)
3339
{
34-
Title = StringFormatter.Format(Resources.OpenHomePage_TitleTemplate, new() { ["engine"] = Name })
40+
Name = StringFormatter.Format(Resources.OpenHomepageItem_NameTemplate, new() { ["shortcut"] = shortcut.Name })
41+
};
42+
_openHomepageListItem = new ListItem(openHomepagecommand)
43+
{
44+
Title = StringFormatter.Format(Resources.OpenHomepageItem_TitleTemplate, new() { ["shortcut"] = shortcut.Name }),
45+
Icon = Icons.Home
46+
};
47+
_openHomepageContextItem = new CommandContextItem(openHomepagecommand)
48+
{
49+
Title = StringFormatter.Format(Resources.OpenHomepageItem_TitleTemplate, new() { ["shortcut"] = shortcut.Name }),
50+
Icon = Icons.Home
3551
};
3652

37-
_items = [_openHomePageItem];
53+
_items = [_openHomepageListItem];
3854
}
3955

4056
public override IListItem[] GetItems() => Volatile.Read(ref _items);
@@ -54,6 +70,7 @@ public override async void UpdateSearchText(string oldSearch, string newSearch)
5470
if (currentEpoch != Volatile.Read(ref _lastUpdateSearchTextEpoch))
5571
{
5672
currentCancellationSource?.Dispose();
73+
5774
return;
5875
}
5976

@@ -72,7 +89,7 @@ public override async void UpdateSearchText(string oldSearch, string newSearch)
7289
{
7390
UpdateSuggestionItems([], currentEpoch);
7491

75-
RenderItems([_openHomePageItem], currentEpoch);
92+
RenderItems([_openHomepageListItem], currentEpoch);
7693

7794
return;
7895
}
@@ -107,7 +124,8 @@ public override async void UpdateSearchText(string oldSearch, string newSearch)
107124
currentCancellationSource!.Dispose();
108125
}
109126

110-
if (currentEpoch != Volatile.Read(ref _lastUpdateSearchTextEpoch)) return;
127+
if (currentEpoch != Volatile.Read(ref _lastUpdateSearchTextEpoch))
128+
return;
111129

112130
UpdateSuggestionItems(suggestionItems, currentEpoch);
113131

@@ -148,11 +166,17 @@ private ListItem[] BuildPrimaryItems(string searchText)
148166
{
149167
return
150168
[
151-
new ListItem(new SearchWebCommand(_shortcut, searchText))
169+
new ListItem(
170+
new SearchWebCommand(_shortcut, searchText)
171+
{
172+
Name = StringFormatter.Format(Resources.SearchQueryItem_NameTemplate, new() { ["shortcut"] = _shortcut.Name, ["query"] = searchText }),
173+
}
174+
)
152175
{
153-
Title = searchText,
154-
Subtitle = StringFormatter.Format(Resources.SearchQuery_SubtitleTemplate, new() { ["engine"] = Name, ["query"] = searchText }),
155-
MoreCommands = [new CommandContextItem(new OpenHomePageCommand(_shortcut))]
176+
Title = StringFormatter.Format(Resources.SearchQueryItem_TitleTemplate, new() { ["shortcut"] = _shortcut.Name, ["query"] = searchText }),
177+
Subtitle = StringFormatter.Format(Resources.SearchQueryItem_SubtitleTemplate, new() { ["shortcut"] = _shortcut.Name, ["query"] = searchText }),
178+
Icon = Icons.Search,
179+
MoreCommands = [_openHomepageContextItem]
156180
}
157181
];
158182
}
@@ -166,12 +190,18 @@ private async Task<ListItem[]> FetchSuggestionItemsAsync(string searchText, Canc
166190

167191
return
168192
[
169-
.. suggestions.Select(suggestion => new ListItem(new SearchWebCommand(_shortcut, suggestion.Title))
193+
.. suggestions.Select(suggestion => new ListItem(
194+
new SearchWebCommand(_shortcut, suggestion.Title)
195+
{
196+
Name = StringFormatter.Format(Resources.SearchQueryItem_NameTemplate, new() { ["shortcut"] = _shortcut.Name, ["query"] = suggestion.Title })
197+
}
198+
)
170199
{
171-
Title = suggestion.Title,
172-
Subtitle = suggestion.Description ?? StringFormatter.Format(Resources.SearchQuery_SubtitleTemplate, new() { ["engine"] = Name, ["query"] = suggestion.Title }),
200+
Title = StringFormatter.Format(Resources.SearchQueryItem_TitleTemplate, new() { ["shortcut"] = _shortcut.Name, ["query"] = suggestion.Title }),
201+
Subtitle = suggestion.Description ?? StringFormatter.Format(Resources.SearchQueryItem_SubtitleTemplate, new() { ["shortcut"] = _shortcut.Name, ["query"] = suggestion.Title }),
202+
Icon = Icons.Search,
173203
TextToSuggest = suggestion.Title,
174-
MoreCommands = [new CommandContextItem(new OpenHomePageCommand(_shortcut))]
204+
MoreCommands = [_openHomepageContextItem]
175205
})
176206
];
177207
}

CmdPalWebSearchShortcut/WebSearchShortcut/Properties/Icons.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,13 @@ namespace WebSearchShortcut.Properties;
99
/// <summary>
1010
/// Provides commonly used icons for the WebSearchShortcut application
1111
/// </summary>
12-
public static class Icons
12+
internal static class Icons
1313
{
14+
/// <summary>
15+
/// Default fallback icon for links
16+
/// </summary>
17+
public static IconInfo Link { get; } = new("🔗");
18+
1419
/// <summary>
1520
/// Edit icon (pencil)
1621
/// </summary>
@@ -22,9 +27,9 @@ public static class Icons
2227
public static IconInfo Delete { get; } = new("\uE74D");
2328

2429
/// <summary>
25-
/// Default fallback icon for links
30+
/// Homepage icon
2631
/// </summary>
27-
public static IconInfo Link { get; } = new("🔗");
32+
public static IconInfo Home { get; } = new("\uE80F");
2833

2934
/// <summary>
3035
/// Search icon

0 commit comments

Comments
 (0)