Implement Async Result Execution to stop JsonRPCPlugin hang Flow when executing results

This commit is contained in:
Hongtao Zhang 2022-04-12 04:30:04 -05:00
parent d1c69d601b
commit 4cee1b9740
3 changed files with 53 additions and 39 deletions

View file

@ -115,7 +115,7 @@ namespace Flow.Launcher.Core.Plugin
foreach (var result in queryResponseModel.Result)
{
result.Action = c =>
result.ActionAsync = async c =>
{
UpdateSettings(result.SettingsChange);
@ -133,15 +133,15 @@ namespace Flow.Launcher.Core.Plugin
}
else
{
var actionResponse = Request(result.JsonRPCAction);
var actionResponse = await RequestAsync(result.JsonRPCAction);
if (string.IsNullOrEmpty(actionResponse))
if (actionResponse.Length == 0)
{
return !result.JsonRPCAction.DontHideAfterAction;
}
var jsonRpcRequestModel =
JsonSerializer.Deserialize<JsonRPCRequestModel>(actionResponse, options);
var jsonRpcRequestModel = await
JsonSerializer.DeserializeAsync<JsonRPCRequestModel>(actionResponse, options);
if (jsonRpcRequestModel?.Method?.StartsWith("Flow.Launcher.") ?? false)
{
@ -166,19 +166,20 @@ namespace Flow.Launcher.Core.Plugin
private void ExecuteFlowLauncherAPI(string method, object[] parameters)
{
var parametersTypeArray = parameters.Select(param => param.GetType()).ToArray();
MethodInfo methodInfo = PluginManager.API.GetType().GetMethod(method, parametersTypeArray);
if (methodInfo != null)
var methodInfo = typeof(IPublicAPI).GetMethod(method, parametersTypeArray);
if (methodInfo == null)
{
return;
}
try
{
methodInfo.Invoke(PluginManager.API, parameters);
}
catch (Exception)
{
try
{
methodInfo.Invoke(PluginManager.API, parameters);
}
catch (Exception)
{
#if (DEBUG)
throw;
throw;
#endif
}
}
}
@ -365,8 +366,7 @@ namespace Flow.Launcher.Core.Plugin
var settingWindow = new UserControl();
var mainPanel = new StackPanel
{
Margin = settingPanelMargin,
Orientation = Orientation.Vertical
Margin = settingPanelMargin, Orientation = Orientation.Vertical
};
settingWindow.Content = mainPanel;
@ -374,8 +374,7 @@ namespace Flow.Launcher.Core.Plugin
{
var panel = new StackPanel
{
Orientation = Orientation.Horizontal,
Margin = settingControlMargin
Orientation = Orientation.Horizontal, Margin = settingControlMargin
};
var name = new TextBlock()
{

View file

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Media;
namespace Flow.Launcher.Plugin
@ -85,6 +86,14 @@ namespace Flow.Launcher.Plugin
/// </summary>
public Func<ActionContext, bool> Action { get; set; }
/// <summary>
/// Delegate. An Async action to take in the form of a function call when the result has been selected
/// <returns>
/// true to hide flowlauncher after select result
/// </returns>
/// </summary>
public Func<ActionContext, ValueTask<bool>> ActionAsync { get; set; }
/// <summary>
/// Priority of the current result
/// <value>default: 0</value>
@ -169,5 +178,10 @@ namespace Flow.Launcher.Plugin
/// Show message as ToolTip on result SubTitle hover over
/// </summary>
public string SubTitleToolTip { get; set; }
public ValueTask<bool> ExecuteAsync(ActionContext context)
{
return ActionAsync?.Invoke(context) ?? ValueTask.FromResult(Action?.Invoke(context) ?? false);
}
}
}

View file

@ -194,37 +194,38 @@ namespace Flow.Launcher.ViewModel
PluginManager.API.OpenUrl("https://github.com/Flow-Launcher/Flow.Launcher/wiki/Flow-Launcher/");
});
OpenSettingCommand = new RelayCommand(_ => { App.API.OpenSettingDialog(); });
OpenResultCommand = new RelayCommand(index =>
OpenResultCommand = new RelayCommand(async index =>
{
var results = SelectedResults;
if (index != null)
{
results.SelectedIndex = int.Parse(index.ToString());
results.SelectedIndex = int.Parse(index.ToString()!);
}
var result = results.SelectedItem?.Result;
if (result != null) // SelectedItem returns null if selection is empty.
if (result == null)
{
bool hideWindow = result.Action != null && result.Action(new ActionContext
{
SpecialKeyState = GlobalHotkey.CheckModifiers()
});
return;
}
var hideWindow = await result.ExecuteAsync(new ActionContext
{
SpecialKeyState = GlobalHotkey.CheckModifiers()
}).ConfigureAwait(false);
if (hideWindow)
{
Hide();
}
if (hideWindow)
{
Hide();
}
if (SelectedIsFromQueryResults())
{
_userSelectedRecord.Add(result);
_history.Add(result.OriginQuery.RawQuery);
}
else
{
SelectedResults = Results;
}
if (SelectedIsFromQueryResults())
{
_userSelectedRecord.Add(result);
_history.Add(result.OriginQuery.RawQuery);
}
else
{
SelectedResults = Results;
}
});