Skip to content

Commit 17a0834

Browse files
committed
Support query for plugins with home query interface
1 parent 0f09fea commit 17a0834

File tree

4 files changed

+104
-23
lines changed

4 files changed

+104
-23
lines changed

Flow.Launcher.Core/Plugin/PluginManager.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public static class PluginManager
2525
private static readonly string ClassName = nameof(PluginManager);
2626

2727
private static IEnumerable<PluginPair> _contextMenuPlugins;
28+
private static IEnumerable<PluginPair> _homePlugins;
2829

2930
public static List<PluginPair> AllPlugins { get; private set; }
3031
public static readonly HashSet<PluginPair> GlobalPlugins = new();
@@ -227,6 +228,8 @@ public static async Task InitializePluginsAsync()
227228
await Task.WhenAll(InitTasks);
228229

229230
_contextMenuPlugins = GetPluginsForInterface<IContextMenu>();
231+
_homePlugins = GetPluginsForInterface<IAsyncHomeQuery>();
232+
230233
foreach (var plugin in AllPlugins)
231234
{
232235
// set distinct on each plugin's action keywords helps only firing global(*) and action keywords once where a plugin
@@ -274,6 +277,14 @@ public static ICollection<PluginPair> ValidPluginsForQuery(Query query)
274277
};
275278
}
276279

280+
public static ICollection<PluginPair> ValidPluginsForHomeQuery(Query query)
281+
{
282+
if (query is not null)
283+
return Array.Empty<PluginPair>();
284+
285+
return _homePlugins.ToList();
286+
}
287+
277288
public static async Task<List<Result>> QueryForPluginAsync(PluginPair pair, Query query, CancellationToken token)
278289
{
279290
var results = new List<Result>();
@@ -318,6 +329,36 @@ public static async Task<List<Result>> QueryForPluginAsync(PluginPair pair, Quer
318329
return results;
319330
}
320331

332+
public static async Task<List<Result>> QueryHomeForPluginAsync(PluginPair pair, CancellationToken token)
333+
{
334+
var results = new List<Result>();
335+
var metadata = pair.Metadata;
336+
337+
try
338+
{
339+
var milliseconds = await API.StopwatchLogDebugAsync(ClassName, $"Cost for {metadata.Name}",
340+
async () => results = await ((IAsyncHomeQuery)pair.Plugin).HomeQueryAsync(token).ConfigureAwait(false));
341+
342+
token.ThrowIfCancellationRequested();
343+
if (results == null)
344+
return null;
345+
UpdatePluginMetadata(results, metadata);
346+
347+
token.ThrowIfCancellationRequested();
348+
}
349+
catch (OperationCanceledException)
350+
{
351+
// null will be fine since the results will only be added into queue if the token hasn't been cancelled
352+
return null;
353+
}
354+
catch (Exception e)
355+
{
356+
API.LogException(ClassName, $"Failed to query home for plugin: {metadata.Name}", e);
357+
return null;
358+
}
359+
return results;
360+
}
361+
321362
public static void UpdatePluginMetadata(IReadOnlyList<Result> results, PluginMetadata metadata, Query query)
322363
{
323364
foreach (var r in results)
@@ -333,6 +374,16 @@ public static void UpdatePluginMetadata(IReadOnlyList<Result> results, PluginMet
333374
}
334375
}
335376

377+
private static void UpdatePluginMetadata(IReadOnlyList<Result> results, PluginMetadata metadata)
378+
{
379+
foreach (var r in results)
380+
{
381+
r.PluginDirectory = metadata.PluginDirectory;
382+
r.PluginID = metadata.ID;
383+
r.OriginQuery = null;
384+
}
385+
}
386+
336387
/// <summary>
337388
/// get specified plugin, return null if not found
338389
/// </summary>

Flow.Launcher.Infrastructure/UserSettings/Settings.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,11 @@ public string PlaceholderText
158158
}
159159
}
160160
}
161+
162+
public bool ShowHomeQuery { get; set; } = true;
163+
public bool ShowHistoryRecordsForHomeQuery { get; set; } = false;
164+
public int HistoryRecordsCountForHomeQuery { get; set; } = 5;
165+
161166
public int CustomExplorerIndex { get; set; } = 0;
162167

163168
[JsonIgnore]

Flow.Launcher.Plugin/Result.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,9 @@ public string BadgeIcoPath
174174
/// <summary>
175175
/// Query information associated with the result
176176
/// </summary>
177+
/// <remarks>
178+
/// If the query is for home query, this will be null
179+
/// </remarks>
177180
internal Query OriginQuery { get; set; }
178181

179182
/// <summary>

Flow.Launcher/ViewModel/MainViewModel.cs

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,21 +1198,31 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
11981198
_updateSource?.Cancel();
11991199

12001200
var query = await ConstructQueryAsync(QueryText, Settings.CustomShortcuts, Settings.BuiltinShortcuts);
1201+
var homeQuery = query == null;
1202+
ICollection<PluginPair> plugins = Array.Empty<PluginPair>();
12011203

12021204
if (query == null) // shortcut expanded
12031205
{
1204-
// Hide and clear results again because running query may show and add some results
1205-
Results.Visibility = Visibility.Collapsed;
1206-
Results.Clear();
1206+
if (Settings.ShowHomeQuery)
1207+
{
1208+
plugins = PluginManager.ValidPluginsForHomeQuery(query);
1209+
}
1210+
1211+
if (plugins.Count == 0)
1212+
{
1213+
// Hide and clear results again because running query may show and add some results
1214+
Results.Visibility = Visibility.Collapsed;
1215+
Results.Clear();
12071216

1208-
// Reset plugin icon
1209-
PluginIconPath = null;
1210-
PluginIconSource = null;
1211-
SearchIconVisibility = Visibility.Visible;
1217+
// Reset plugin icon
1218+
PluginIconPath = null;
1219+
PluginIconSource = null;
1220+
SearchIconVisibility = Visibility.Visible;
12121221

1213-
// Hide progress bar again because running query may set this to visible
1214-
ProgressBarVisibility = Visibility.Hidden;
1215-
return;
1222+
// Hide progress bar again because running query may set this to visible
1223+
ProgressBarVisibility = Visibility.Hidden;
1224+
return;
1225+
}
12161226
}
12171227

12181228
_updateSource = new CancellationTokenSource();
@@ -1226,27 +1236,37 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
12261236
if (_updateSource.Token.IsCancellationRequested) return;
12271237

12281238
// Update the query's IsReQuery property to true if this is a re-query
1229-
query.IsReQuery = isReQuery;
1239+
if (!homeQuery) query.IsReQuery = isReQuery;
12301240

12311241
// handle the exclusiveness of plugin using action keyword
12321242
RemoveOldQueryResults(query);
12331243

12341244
_lastQuery = query;
12351245

1236-
var plugins = PluginManager.ValidPluginsForQuery(query);
1237-
1238-
if (plugins.Count == 1)
1239-
{
1240-
PluginIconPath = plugins.Single().Metadata.IcoPath;
1241-
PluginIconSource = await App.API.LoadImageAsync(PluginIconPath);
1242-
SearchIconVisibility = Visibility.Hidden;
1243-
}
1244-
else
1246+
if (homeQuery)
12451247
{
1248+
// Do not show plugin icon if this is a home query
12461249
PluginIconPath = null;
12471250
PluginIconSource = null;
12481251
SearchIconVisibility = Visibility.Visible;
12491252
}
1253+
else
1254+
{
1255+
plugins = PluginManager.ValidPluginsForQuery(query);
1256+
1257+
if (plugins.Count == 1)
1258+
{
1259+
PluginIconPath = plugins.Single().Metadata.IcoPath;
1260+
PluginIconSource = await App.API.LoadImageAsync(PluginIconPath);
1261+
SearchIconVisibility = Visibility.Hidden;
1262+
}
1263+
else
1264+
{
1265+
PluginIconPath = null;
1266+
PluginIconSource = null;
1267+
SearchIconVisibility = Visibility.Visible;
1268+
}
1269+
}
12501270

12511271
// Do not wait for performance improvement
12521272
/*if (string.IsNullOrEmpty(query.ActionKeyword))
@@ -1303,7 +1323,7 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
13031323
// Local function
13041324
async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
13051325
{
1306-
if (searchDelay)
1326+
if (searchDelay && !homeQuery) // Do not delay for home query
13071327
{
13081328
var searchDelayTime = plugin.Metadata.SearchDelayTime ?? Settings.SearchDelayTime;
13091329

@@ -1316,7 +1336,9 @@ async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
13161336
// Task.Yield will force it to run in ThreadPool
13171337
await Task.Yield();
13181338

1319-
var results = await PluginManager.QueryForPluginAsync(plugin, query, token);
1339+
var results = homeQuery ?
1340+
await PluginManager.QueryHomeForPluginAsync(plugin, token) :
1341+
await PluginManager.QueryForPluginAsync(plugin, query, token);
13201342

13211343
if (token.IsCancellationRequested) return;
13221344

@@ -1616,7 +1638,7 @@ public async void Hide()
16161638
break;
16171639
case LastQueryMode.ActionKeywordPreserved:
16181640
case LastQueryMode.ActionKeywordSelected:
1619-
var newQuery = _lastQuery.ActionKeyword;
1641+
var newQuery = _lastQuery?.ActionKeyword;
16201642

16211643
if (!string.IsNullOrEmpty(newQuery))
16221644
newQuery += " ";

0 commit comments

Comments
 (0)