Flow.Launcher/Flow.Launcher/Storage/HistoryHelper.cs
Jack251970 e3527f47ea Add RecordKey for precise history matching and refactor
Added a `RecordKey` property to `HistoryItem` for unique identification of history records, enabling more accurate matching during queries and executions. Updated `HistoryHelper` methods to utilize `RecordKey` for matching, with fallback to `Title` and `SubTitle`. Enhanced `GetExecuteAction` with error handling, nullable reference types, and improved matching logic. Included `RecordKey` in `History` object creation. Enabled nullable reference types in `HistoryHelper.cs` for better code safety. Refactored code for clarity and maintainability.
2025-10-13 15:27:06 +08:00

67 lines
2.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Plugin;
namespace Flow.Launcher.Storage;
#nullable enable
public static class HistoryHelper
{
internal static List<HistoryItem> PopulateActions(this List<HistoryItem> items, bool isQuery)
{
foreach (var item in items)
{
if (item.QueryAction != null && item.ExecuteAction != null) continue;
if (isQuery && item.QueryAction == null) item.QueryAction = GetQueryAction(item.RawQuery);
if (!isQuery && item.ExecuteAction == null) item.ExecuteAction = GetExecuteAction(item.PluginID, item.RawQuery, item.Title, item.SubTitle, item.RecordKey) ?? GetQueryAction(item.RawQuery);
}
return items;
}
public static Func<ActionContext, bool> GetQueryAction(string rawQuery)
{
return _ =>
{
App.API.BackToQueryResults();
App.API.ChangeQuery(rawQuery);
return false;
};
}
private static Func<ActionContext, bool>? GetExecuteAction(string pluginId, string rawQuery, string title, string subTitle, string recordKey)
{
var plugin = PluginManager.GetPluginForId(pluginId);
if (plugin == null) return null;
var query = QueryBuilder.Build(rawQuery, PluginManager.NonGlobalPlugins);
if (query == null) return null;
try
{
#pragma warning disable VSTHRD002 // Avoid problematic synchronous waits
var freshResults = plugin.Plugin
.QueryAsync(query, CancellationToken.None)
.GetAwaiter()
.GetResult();
#pragma warning restore VSTHRD002 // Avoid problematic synchronous waits
// Try to match by record key first if it is valid, otherwise fall back to title + subtitle match
if (string.IsNullOrEmpty(recordKey))
{
return freshResults?.FirstOrDefault(r => r.Title == title && r.SubTitle == subTitle)?.Action;
}
else
{
return freshResults?.FirstOrDefault(r => r.RecordKey == recordKey)?.Action ??
freshResults?.FirstOrDefault(r => r.Title == title && r.SubTitle == subTitle)?.Action;
}
}
catch
{
return null;
}
}
}