Skip to content

Commit c880c1e

Browse files
committed
feat: add settings that let users set a display cap and tune the history-to-suggestions ratio, plus per-shortcut controls to enable or disable saving history
1 parent f35a80e commit c880c1e

12 files changed

Lines changed: 339 additions & 16 deletions

CmdPalWebSearchShortcut/WebSearchShortcut/Commands/SearchWebCommand.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ public SearchWebCommand(WebSearchShortcutDataEntry shortcut, string query)
1818
_query = query;
1919
_shortcut = shortcut;
2020
_browserInfo = new BrowserExecutionInfo(shortcut);
21-
// _settingsManager = settingsManager;
2221
}
2322

2423
public override CommandResult Invoke()
@@ -29,12 +28,8 @@ public override CommandResult Invoke()
2928
return CommandResult.KeepOpen();
3029
}
3130

32-
HistoryService.Add(_shortcut.Name, _query);
33-
34-
// if (_settingsManager.ShowHistory != Resources.history_none)
35-
// {
36-
// _settingsManager.SaveHistory(new HistoryItem(Arguments, DateTime.Now));
37-
// }
31+
if (_shortcut.RecordHistory ?? true)
32+
HistoryService.Add(_shortcut.Name, _query);
3833

3934
return CommandResult.Dismiss();
4035
}

CmdPalWebSearchShortcut/WebSearchShortcut/Forms/AddShortcutForm.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
using System;
12
using System.Linq;
23
using System.Text.Json;
34
using System.Text.Json.Nodes;
4-
using Microsoft.CommandPalette.Extensions.Toolkit;
55
using Windows.Foundation;
6+
using Microsoft.CommandPalette.Extensions.Toolkit;
67
using WebSearchShortcut.Browsers;
78
using WebSearchShortcut.Properties;
89

@@ -19,6 +20,7 @@ public AddShortcutForm(WebSearchShortcutDataEntry? shortcut)
1920
var url = shortcut?.Url ?? string.Empty;
2021
var suggestionProvider = shortcut?.SuggestionProvider ?? string.Empty;
2122
var replaceWhitespace = shortcut?.ReplaceWhitespace ?? string.Empty;
23+
var recordHistory = shortcut?.RecordHistory ?? true;
2224
var homePage = shortcut?.HomePage ?? string.Empty;
2325
var browserPath = shortcut?.BrowserPath ?? string.Empty;
2426
var browserArgs = shortcut?.BrowserArgs ?? string.Empty;
@@ -68,6 +70,13 @@ public AddShortcutForm(WebSearchShortcutDataEntry? shortcut)
6870
"value": {{JsonSerializer.Serialize(suggestionProvider, AppJsonSerializerContext.Default.String)}},
6971
"errorMessage": "// Just for space between items"
7072
},
73+
{
74+
"id": "recordHistory",
75+
"type": "Input.Toggle",
76+
"label": {{JsonSerializer.Serialize(Resources.AddShortcutForm_RecordHistory_Label, AppJsonSerializerContext.Default.String)}},
77+
"title": {{JsonSerializer.Serialize(Resources.AddShortcutForm_RecordHistory_Title, AppJsonSerializerContext.Default.String)}},
78+
"value": {{JsonSerializer.Serialize(recordHistory ? "true" : "false", AppJsonSerializerContext.Default.String)}}
79+
},
7180
{
7281
"id": "homePage",
7382
"type": "Input.Text",
@@ -127,6 +136,7 @@ public AddShortcutForm(WebSearchShortcutDataEntry? shortcut)
127136
"url": "url",
128137
"suggestionProvider": "suggestionProvider",
129138
"replaceWhitespace": "replaceWhitespace",
139+
"recordHistory": "recordHistory",
130140
"homePage": "homePage",
131141
"browserPath": "browserPath",
132142
"browserArgs": "browserArgs"
@@ -149,11 +159,13 @@ public override CommandResult SubmitForm(string inputs)
149159
shortcut.Url = root["url"]?.GetValue<string>() ?? string.Empty;
150160
shortcut.SuggestionProvider = root["suggestionProvider"]?.GetValue<string>() ?? string.Empty;
151161
shortcut.ReplaceWhitespace = root["replaceWhitespace"]?.GetValue<string>() ?? string.Empty;
162+
shortcut.RecordHistory = string.Equals(root["recordHistory"]?.GetValue<string>() ?? "true", "true", StringComparison.OrdinalIgnoreCase);
152163
shortcut.HomePage = root["homePage"]?.GetValue<string>() ?? string.Empty;
153164
shortcut.BrowserPath = root["browserPath"]?.GetValue<string>() ?? string.Empty;
154165
shortcut.BrowserArgs = root["browserArgs"]?.GetValue<string>() ?? string.Empty;
155166

156167
AddedCommand?.Invoke(this, shortcut);
168+
157169
return CommandResult.GoHome();
158170
}
159171
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
using System.Collections.Generic;
2+
using System.Text.Json.Nodes;
3+
4+
namespace Microsoft.CommandPalette.Extensions.Toolkit;
5+
6+
public sealed class IntSetting : Setting<int>
7+
{
8+
public int? Min { get; set; }
9+
public int? Max { get; set; }
10+
public string Placeholder { get; set; } = string.Empty;
11+
12+
private IntSetting()
13+
: base()
14+
{
15+
Value = 0;
16+
}
17+
18+
public IntSetting(string key, int defaultValue, int? min = null, int? max = null)
19+
: base(key, defaultValue)
20+
{
21+
Min = min;
22+
Max = max;
23+
}
24+
25+
public IntSetting(string key, string label, string description, int defaultValue,
26+
int? min = null, int? max = null)
27+
: base(key, label, description, defaultValue)
28+
{
29+
Min = min;
30+
Max = max;
31+
}
32+
33+
public override Dictionary<string, object> ToDictionary()
34+
{
35+
var dict = new Dictionary<string, object>
36+
{
37+
{ "id", Key },
38+
{ "type", "Input.Number" },
39+
{ "title", Label },
40+
{ "label", Description },
41+
{ "value", Value },
42+
{ "isRequired", IsRequired },
43+
{ "errorMessage", ErrorMessage },
44+
{ "placeholder", Placeholder },
45+
};
46+
47+
if (Min.HasValue) dict["min"] = Min.Value;
48+
if (Max.HasValue) dict["max"] = Max.Value;
49+
50+
return dict;
51+
}
52+
53+
public static IntSetting LoadFromJson(JsonObject jsonObject) => new() { Value = jsonObject["value"]?.GetValue<int>() ?? 0 };
54+
55+
public override void Update(JsonObject payload)
56+
{
57+
if (payload.TryGetPropertyValue(Key, out JsonNode? node) && node is not null)
58+
{
59+
if (node is JsonValue jsonValue && jsonValue.TryGetValue<int>(out var value))
60+
{
61+
Value = value;
62+
}
63+
else if (int.TryParse(node.ToString(), out value))
64+
{
65+
Value = value;
66+
}
67+
}
68+
69+
if (Min.HasValue && Value < Min.Value) Value = Min.Value;
70+
if (Max.HasValue && Value > Max.Value) Value = Max.Value;
71+
}
72+
73+
public override string ToState()
74+
{
75+
return $"\"{Key}\": {Value}";
76+
}
77+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
using System.IO;
2+
using Windows.Foundation;
3+
using Microsoft.CommandPalette.Extensions.Toolkit;
4+
using WebSearchShortcut.Properties;
5+
6+
namespace WebSearchShortcut.Helpers;
7+
8+
internal class SettingsManager : JsonSettingsManager
9+
{
10+
private const string _namespace = "WebSearchShortcut";
11+
private static string Namespaced(string propertyName) => $"{_namespace}.{propertyName}";
12+
13+
private const int _defaultMaxDisplayCount = 20;
14+
private const int _defaultMaxHistoryDisplayCount = 3;
15+
16+
private readonly IntSetting _maxDisplayCount = new(
17+
Namespaced(nameof(MaxDisplayCount)),
18+
Resources.Settings_MaxDisplayCount_Label,
19+
Resources.Settings_MaxDisplayCount_Description,
20+
_defaultMaxDisplayCount,
21+
1, null
22+
)
23+
{ ErrorMessage = Resources.Settings_MaxDisplayCount_ErrorMessage };
24+
25+
private readonly IntSetting _maxHistoryDisplayCount = new(
26+
Namespaced(nameof(MaxHistoryDisplayCount)),
27+
Resources.Settings_MaxHistoryDisplayCount_Label,
28+
Resources.Settings_MaxHistoryDisplayCount_Description,
29+
_defaultMaxHistoryDisplayCount,
30+
0, null
31+
)
32+
{ ErrorMessage = Resources.Settings_MaxHistoryDisplayCount_ErrorMessage };
33+
34+
public int MaxDisplayCount => _maxDisplayCount.Value;
35+
public int MaxHistoryDisplayCount => _maxHistoryDisplayCount.Value;
36+
37+
public event TypedEventHandler<object, Settings>? SettingsChanged
38+
{
39+
add => Settings.SettingsChanged += value;
40+
remove => Settings.SettingsChanged -= value;
41+
}
42+
43+
internal static string SettingsJsonPath()
44+
{
45+
var directory = Utilities.BaseSettingsPath("Microsoft.CmdPal");
46+
47+
Directory.CreateDirectory(directory);
48+
49+
return Path.Combine(directory, "settings.json");
50+
}
51+
52+
public SettingsManager()
53+
{
54+
FilePath = SettingsJsonPath();
55+
56+
Settings.Add(_maxDisplayCount);
57+
Settings.Add(_maxHistoryDisplayCount);
58+
59+
LoadSettings();
60+
61+
Settings.SettingsChanged += (s, a) => SaveSettings();
62+
}
63+
}

CmdPalWebSearchShortcut/WebSearchShortcut/Pages/SearchWebPage.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@ namespace WebSearchShortcut;
1515

1616
internal sealed partial class SearchWebPage : DynamicListPage
1717
{
18-
private const int MaxHistoryDisplayCount = 3;
19-
private const int MaxDisplayCount = 100;
20-
2118
private readonly WebSearchShortcutDataEntry _shortcut;
2219

2320
private readonly ListItem _openHomepageListItem;
@@ -26,13 +23,15 @@ internal sealed partial class SearchWebPage : DynamicListPage
2623
private ListItem[] _suggestionItems = [];
2724
private IListItem[] _items = [];
2825

26+
private readonly SettingsManager _settingsManager;
27+
2928
private int _lastUpdateSearchTextEpoch;
3029
private readonly Lock _swapSuggestionsCancellationSourceLock = new();
3130
private readonly Lock _renderLock = new();
3231
private readonly Lock _updateSuggestionLock = new();
3332
private CancellationTokenSource? _previousSuggestionsCancellationSource;
3433

35-
public SearchWebPage(WebSearchShortcutDataEntry shortcut)
34+
public SearchWebPage(WebSearchShortcutDataEntry shortcut, SettingsManager settingsManager)
3635
{
3736
Id = shortcut.Id;
3837
Title = StringFormatter.Format(Resources.SearchWebPage_TitleTemplate, new() { ["shortcut"] = shortcut.Name });
@@ -55,6 +54,10 @@ public SearchWebPage(WebSearchShortcutDataEntry shortcut)
5554
Title = StringFormatter.Format(Resources.OpenHomepageItem_TitleTemplate, new() { ["shortcut"] = shortcut.Name }),
5655
Icon = Icons.Home
5756
};
57+
58+
_settingsManager = settingsManager;
59+
60+
_settingsManager.SettingsChanged += (s, a) => Rebuild();
5861
}
5962

6063
public override IListItem[] GetItems()
@@ -149,7 +152,7 @@ public override async void UpdateSearchText(string oldSearch, string newSearch)
149152
RenderItems(ItemIntegrate(primaryItems, historyItems, suggestionItems), currentEpoch);
150153
}
151154

152-
private static IListItem[] ItemIntegrate(ListItem[] primaryItems, ListItem[] historyItems, ListItem[] suggestionItems)
155+
private IListItem[] ItemIntegrate(ListItem[] primaryItems, ListItem[] historyItems, ListItem[] suggestionItems)
153156
{
154157
var primaryItemByTitle = primaryItems.ToDictionary(item => item.Title, item => item);
155158
var historyItemByTitle = historyItems.ToDictionary(item => item.Title, item => item);
@@ -208,7 +211,7 @@ private static IListItem[] ItemIntegrate(ListItem[] primaryItems, ListItem[] his
208211
items.Add(suggestoinItem);
209212
}
210213

211-
return [.. items.Take(MaxDisplayCount)];
214+
return [.. items.Take(_settingsManager.MaxDisplayCount)];
212215
}
213216

214217
private void RenderItems(IListItem[] items, int currentUpdateSearchTextEpoch)
@@ -265,7 +268,7 @@ private ListItem[] BuildHistoryItems(string searchText)
265268
{
266269
var historyQueries = HistoryService
267270
.Search(_shortcut.Name, searchText)
268-
.Take(string.IsNullOrEmpty(searchText) ? MaxDisplayCount : MaxHistoryDisplayCount);
271+
.Take(string.IsNullOrEmpty(searchText) ? _settingsManager.MaxDisplayCount : _settingsManager.MaxHistoryDisplayCount);
269272

270273
return [
271274
.. historyQueries.Select(historyQuery => new ListItem(

CmdPalWebSearchShortcut/WebSearchShortcut/Properties/Resources.Designer.cs

Lines changed: 72 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)