mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Support query for plugins with home query interface
This commit is contained in:
parent
0f09fea30b
commit
17a0834bcd
4 changed files with 104 additions and 23 deletions
|
|
@ -25,6 +25,7 @@ namespace Flow.Launcher.Core.Plugin
|
|||
private static readonly string ClassName = nameof(PluginManager);
|
||||
|
||||
private static IEnumerable<PluginPair> _contextMenuPlugins;
|
||||
private static IEnumerable<PluginPair> _homePlugins;
|
||||
|
||||
public static List<PluginPair> AllPlugins { get; private set; }
|
||||
public static readonly HashSet<PluginPair> GlobalPlugins = new();
|
||||
|
|
@ -227,6 +228,8 @@ namespace Flow.Launcher.Core.Plugin
|
|||
await Task.WhenAll(InitTasks);
|
||||
|
||||
_contextMenuPlugins = GetPluginsForInterface<IContextMenu>();
|
||||
_homePlugins = GetPluginsForInterface<IAsyncHomeQuery>();
|
||||
|
||||
foreach (var plugin in AllPlugins)
|
||||
{
|
||||
// set distinct on each plugin's action keywords helps only firing global(*) and action keywords once where a plugin
|
||||
|
|
@ -274,6 +277,14 @@ namespace Flow.Launcher.Core.Plugin
|
|||
};
|
||||
}
|
||||
|
||||
public static ICollection<PluginPair> ValidPluginsForHomeQuery(Query query)
|
||||
{
|
||||
if (query is not null)
|
||||
return Array.Empty<PluginPair>();
|
||||
|
||||
return _homePlugins.ToList();
|
||||
}
|
||||
|
||||
public static async Task<List<Result>> QueryForPluginAsync(PluginPair pair, Query query, CancellationToken token)
|
||||
{
|
||||
var results = new List<Result>();
|
||||
|
|
@ -318,6 +329,36 @@ namespace Flow.Launcher.Core.Plugin
|
|||
return results;
|
||||
}
|
||||
|
||||
public static async Task<List<Result>> QueryHomeForPluginAsync(PluginPair pair, CancellationToken token)
|
||||
{
|
||||
var results = new List<Result>();
|
||||
var metadata = pair.Metadata;
|
||||
|
||||
try
|
||||
{
|
||||
var milliseconds = await API.StopwatchLogDebugAsync(ClassName, $"Cost for {metadata.Name}",
|
||||
async () => results = await ((IAsyncHomeQuery)pair.Plugin).HomeQueryAsync(token).ConfigureAwait(false));
|
||||
|
||||
token.ThrowIfCancellationRequested();
|
||||
if (results == null)
|
||||
return null;
|
||||
UpdatePluginMetadata(results, metadata);
|
||||
|
||||
token.ThrowIfCancellationRequested();
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// null will be fine since the results will only be added into queue if the token hasn't been cancelled
|
||||
return null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
API.LogException(ClassName, $"Failed to query home for plugin: {metadata.Name}", e);
|
||||
return null;
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public static void UpdatePluginMetadata(IReadOnlyList<Result> results, PluginMetadata metadata, Query query)
|
||||
{
|
||||
foreach (var r in results)
|
||||
|
|
@ -333,6 +374,16 @@ namespace Flow.Launcher.Core.Plugin
|
|||
}
|
||||
}
|
||||
|
||||
private static void UpdatePluginMetadata(IReadOnlyList<Result> results, PluginMetadata metadata)
|
||||
{
|
||||
foreach (var r in results)
|
||||
{
|
||||
r.PluginDirectory = metadata.PluginDirectory;
|
||||
r.PluginID = metadata.ID;
|
||||
r.OriginQuery = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// get specified plugin, return null if not found
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -158,6 +158,11 @@ namespace Flow.Launcher.Infrastructure.UserSettings
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowHomeQuery { get; set; } = true;
|
||||
public bool ShowHistoryRecordsForHomeQuery { get; set; } = false;
|
||||
public int HistoryRecordsCountForHomeQuery { get; set; } = 5;
|
||||
|
||||
public int CustomExplorerIndex { get; set; } = 0;
|
||||
|
||||
[JsonIgnore]
|
||||
|
|
|
|||
|
|
@ -174,6 +174,9 @@ namespace Flow.Launcher.Plugin
|
|||
/// <summary>
|
||||
/// Query information associated with the result
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the query is for home query, this will be null
|
||||
/// </remarks>
|
||||
internal Query OriginQuery { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -1198,21 +1198,31 @@ namespace Flow.Launcher.ViewModel
|
|||
_updateSource?.Cancel();
|
||||
|
||||
var query = await ConstructQueryAsync(QueryText, Settings.CustomShortcuts, Settings.BuiltinShortcuts);
|
||||
var homeQuery = query == null;
|
||||
ICollection<PluginPair> plugins = Array.Empty<PluginPair>();
|
||||
|
||||
if (query == null) // shortcut expanded
|
||||
{
|
||||
// Hide and clear results again because running query may show and add some results
|
||||
Results.Visibility = Visibility.Collapsed;
|
||||
Results.Clear();
|
||||
if (Settings.ShowHomeQuery)
|
||||
{
|
||||
plugins = PluginManager.ValidPluginsForHomeQuery(query);
|
||||
}
|
||||
|
||||
if (plugins.Count == 0)
|
||||
{
|
||||
// Hide and clear results again because running query may show and add some results
|
||||
Results.Visibility = Visibility.Collapsed;
|
||||
Results.Clear();
|
||||
|
||||
// Reset plugin icon
|
||||
PluginIconPath = null;
|
||||
PluginIconSource = null;
|
||||
SearchIconVisibility = Visibility.Visible;
|
||||
// Reset plugin icon
|
||||
PluginIconPath = null;
|
||||
PluginIconSource = null;
|
||||
SearchIconVisibility = Visibility.Visible;
|
||||
|
||||
// Hide progress bar again because running query may set this to visible
|
||||
ProgressBarVisibility = Visibility.Hidden;
|
||||
return;
|
||||
// Hide progress bar again because running query may set this to visible
|
||||
ProgressBarVisibility = Visibility.Hidden;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_updateSource = new CancellationTokenSource();
|
||||
|
|
@ -1226,27 +1236,37 @@ namespace Flow.Launcher.ViewModel
|
|||
if (_updateSource.Token.IsCancellationRequested) return;
|
||||
|
||||
// Update the query's IsReQuery property to true if this is a re-query
|
||||
query.IsReQuery = isReQuery;
|
||||
if (!homeQuery) query.IsReQuery = isReQuery;
|
||||
|
||||
// handle the exclusiveness of plugin using action keyword
|
||||
RemoveOldQueryResults(query);
|
||||
|
||||
_lastQuery = query;
|
||||
|
||||
var plugins = PluginManager.ValidPluginsForQuery(query);
|
||||
|
||||
if (plugins.Count == 1)
|
||||
{
|
||||
PluginIconPath = plugins.Single().Metadata.IcoPath;
|
||||
PluginIconSource = await App.API.LoadImageAsync(PluginIconPath);
|
||||
SearchIconVisibility = Visibility.Hidden;
|
||||
}
|
||||
else
|
||||
if (homeQuery)
|
||||
{
|
||||
// Do not show plugin icon if this is a home query
|
||||
PluginIconPath = null;
|
||||
PluginIconSource = null;
|
||||
SearchIconVisibility = Visibility.Visible;
|
||||
}
|
||||
else
|
||||
{
|
||||
plugins = PluginManager.ValidPluginsForQuery(query);
|
||||
|
||||
if (plugins.Count == 1)
|
||||
{
|
||||
PluginIconPath = plugins.Single().Metadata.IcoPath;
|
||||
PluginIconSource = await App.API.LoadImageAsync(PluginIconPath);
|
||||
SearchIconVisibility = Visibility.Hidden;
|
||||
}
|
||||
else
|
||||
{
|
||||
PluginIconPath = null;
|
||||
PluginIconSource = null;
|
||||
SearchIconVisibility = Visibility.Visible;
|
||||
}
|
||||
}
|
||||
|
||||
// Do not wait for performance improvement
|
||||
/*if (string.IsNullOrEmpty(query.ActionKeyword))
|
||||
|
|
@ -1303,7 +1323,7 @@ namespace Flow.Launcher.ViewModel
|
|||
// Local function
|
||||
async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
|
||||
{
|
||||
if (searchDelay)
|
||||
if (searchDelay && !homeQuery) // Do not delay for home query
|
||||
{
|
||||
var searchDelayTime = plugin.Metadata.SearchDelayTime ?? Settings.SearchDelayTime;
|
||||
|
||||
|
|
@ -1316,7 +1336,9 @@ namespace Flow.Launcher.ViewModel
|
|||
// Task.Yield will force it to run in ThreadPool
|
||||
await Task.Yield();
|
||||
|
||||
var results = await PluginManager.QueryForPluginAsync(plugin, query, token);
|
||||
var results = homeQuery ?
|
||||
await PluginManager.QueryHomeForPluginAsync(plugin, token) :
|
||||
await PluginManager.QueryForPluginAsync(plugin, query, token);
|
||||
|
||||
if (token.IsCancellationRequested) return;
|
||||
|
||||
|
|
@ -1616,7 +1638,7 @@ namespace Flow.Launcher.ViewModel
|
|||
break;
|
||||
case LastQueryMode.ActionKeywordPreserved:
|
||||
case LastQueryMode.ActionKeywordSelected:
|
||||
var newQuery = _lastQuery.ActionKeyword;
|
||||
var newQuery = _lastQuery?.ActionKeyword;
|
||||
|
||||
if (!string.IsNullOrEmpty(newQuery))
|
||||
newQuery += " ";
|
||||
|
|
|
|||
Loading…
Reference in a new issue