Skip to content

Commit 471c3ed

Browse files
committed
Add BadgePath & BadgeIcon property
1 parent 579dc06 commit 471c3ed

File tree

2 files changed

+102
-59
lines changed

2 files changed

+102
-59
lines changed

Flow.Launcher.Plugin/Result.cs

Lines changed: 93 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,19 @@ namespace Flow.Launcher.Plugin
1212
/// </summary>
1313
public class Result
1414
{
15+
/// <summary>
16+
/// Maximum score. This can be useful when set one result to the top by default. This is the score for the results set to the topmost by users.
17+
/// </summary>
18+
public const int MaxScore = int.MaxValue;
19+
1520
private string _pluginDirectory;
1621

1722
private string _icoPath;
1823

1924
private string _copyText = string.Empty;
2025

26+
private string _badgePath;
27+
2128
/// <summary>
2229
/// The title of the result. This is always required.
2330
/// </summary>
@@ -80,6 +87,33 @@ public string IcoPath
8087
}
8188
}
8289

90+
/// <summary>
91+
/// The image to be displayed for the badge of the result.
92+
/// </summary>
93+
/// <value>Can be a local file path or a URL.</value>
94+
/// <remarks>If null or empty, will use plugin icon</remarks>
95+
public string BadgePath
96+
{
97+
get => _badgePath;
98+
set
99+
{
100+
// As a standard this property will handle prepping and converting to absolute local path for icon image processing
101+
if (!string.IsNullOrEmpty(value)
102+
&& !string.IsNullOrEmpty(PluginDirectory)
103+
&& !Path.IsPathRooted(value)
104+
&& !value.StartsWith("http://", StringComparison.OrdinalIgnoreCase)
105+
&& !value.StartsWith("https://", StringComparison.OrdinalIgnoreCase)
106+
&& !value.StartsWith("data:image", StringComparison.OrdinalIgnoreCase))
107+
{
108+
_badgePath = Path.Combine(PluginDirectory, value);
109+
}
110+
else
111+
{
112+
_badgePath = value;
113+
}
114+
}
115+
}
116+
83117
/// <summary>
84118
/// Determines if Icon has a border radius
85119
/// </summary>
@@ -94,7 +128,12 @@ public string IcoPath
94128
/// <summary>
95129
/// Delegate to load an icon for this result.
96130
/// </summary>
97-
public IconDelegate Icon;
131+
public IconDelegate Icon { get; set; }
132+
133+
/// <summary>
134+
/// Delegate to load an icon for the badge of this result.
135+
/// </summary>
136+
public IconDelegate BadgeIcon { get; set; }
98137

99138
/// <summary>
100139
/// Information for Glyph Icon (Prioritized than IcoPath/Icon if user enable Glyph Icons)
@@ -154,47 +193,6 @@ public string PluginDirectory
154193
}
155194
}
156195

157-
/// <inheritdoc />
158-
public override string ToString()
159-
{
160-
return Title + SubTitle + Score;
161-
}
162-
163-
/// <summary>
164-
/// Clones the current result
165-
/// </summary>
166-
public Result Clone()
167-
{
168-
return new Result
169-
{
170-
Title = Title,
171-
SubTitle = SubTitle,
172-
ActionKeywordAssigned = ActionKeywordAssigned,
173-
CopyText = CopyText,
174-
AutoCompleteText = AutoCompleteText,
175-
IcoPath = IcoPath,
176-
RoundedIcon = RoundedIcon,
177-
Icon = Icon,
178-
Glyph = Glyph,
179-
Action = Action,
180-
AsyncAction = AsyncAction,
181-
Score = Score,
182-
TitleHighlightData = TitleHighlightData,
183-
OriginQuery = OriginQuery,
184-
PluginDirectory = PluginDirectory,
185-
ContextData = ContextData,
186-
PluginID = PluginID,
187-
TitleToolTip = TitleToolTip,
188-
SubTitleToolTip = SubTitleToolTip,
189-
PreviewPanel = PreviewPanel,
190-
ProgressBar = ProgressBar,
191-
ProgressBarColor = ProgressBarColor,
192-
Preview = Preview,
193-
AddSelectedCount = AddSelectedCount,
194-
RecordKey = RecordKey
195-
};
196-
}
197-
198196
/// <summary>
199197
/// Additional data associated with this result
200198
/// </summary>
@@ -223,16 +221,6 @@ public Result Clone()
223221
/// </summary>
224222
public Lazy<UserControl> PreviewPanel { get; set; }
225223

226-
/// <summary>
227-
/// Run this result, asynchronously
228-
/// </summary>
229-
/// <param name="context"></param>
230-
/// <returns></returns>
231-
public ValueTask<bool> ExecuteAsync(ActionContext context)
232-
{
233-
return AsyncAction?.Invoke(context) ?? ValueTask.FromResult(Action?.Invoke(context) ?? false);
234-
}
235-
236224
/// <summary>
237225
/// Progress bar display. Providing an int value between 0-100 will trigger the progress bar to be displayed on the result
238226
/// </summary>
@@ -254,11 +242,6 @@ public ValueTask<bool> ExecuteAsync(ActionContext context)
254242
/// </summary>
255243
public bool AddSelectedCount { get; set; } = true;
256244

257-
/// <summary>
258-
/// Maximum score. This can be useful when set one result to the top by default. This is the score for the results set to the topmost by users.
259-
/// </summary>
260-
public const int MaxScore = int.MaxValue;
261-
262245
/// <summary>
263246
/// The key to identify the record. This is used when FL checks whether the result is the topmost record. Or FL calculates the hashcode of the result for user selected records.
264247
/// This can be useful when your plugin will change the Title or SubTitle of the result dynamically.
@@ -267,6 +250,59 @@ public ValueTask<bool> ExecuteAsync(ActionContext context)
267250
/// </summary>
268251
public string RecordKey { get; set; } = null;
269252

253+
/// <summary>
254+
/// Run this result, asynchronously
255+
/// </summary>
256+
/// <param name="context"></param>
257+
/// <returns></returns>
258+
public ValueTask<bool> ExecuteAsync(ActionContext context)
259+
{
260+
return AsyncAction?.Invoke(context) ?? ValueTask.FromResult(Action?.Invoke(context) ?? false);
261+
}
262+
263+
/// <inheritdoc />
264+
public override string ToString()
265+
{
266+
return Title + SubTitle + Score;
267+
}
268+
269+
/// <summary>
270+
/// Clones the current result
271+
/// </summary>
272+
public Result Clone()
273+
{
274+
return new Result
275+
{
276+
Title = Title,
277+
SubTitle = SubTitle,
278+
ActionKeywordAssigned = ActionKeywordAssigned,
279+
CopyText = CopyText,
280+
AutoCompleteText = AutoCompleteText,
281+
IcoPath = IcoPath,
282+
BadgePath = BadgePath,
283+
RoundedIcon = RoundedIcon,
284+
Icon = Icon,
285+
BadgeIcon = BadgeIcon,
286+
Glyph = Glyph,
287+
Action = Action,
288+
AsyncAction = AsyncAction,
289+
Score = Score,
290+
TitleHighlightData = TitleHighlightData,
291+
OriginQuery = OriginQuery,
292+
PluginDirectory = PluginDirectory,
293+
ContextData = ContextData,
294+
PluginID = PluginID,
295+
TitleToolTip = TitleToolTip,
296+
SubTitleToolTip = SubTitleToolTip,
297+
PreviewPanel = PreviewPanel,
298+
ProgressBar = ProgressBar,
299+
ProgressBarColor = ProgressBarColor,
300+
Preview = Preview,
301+
AddSelectedCount = AddSelectedCount,
302+
RecordKey = RecordKey
303+
};
304+
}
305+
270306
/// <summary>
271307
/// Info of the preview section of a <see cref="Result"/>
272308
/// </summary>

Flow.Launcher/ViewModel/MainViewModel.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,8 +1268,7 @@ async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
12681268
// Task.Yield will force it to run in ThreadPool
12691269
await Task.Yield();
12701270

1271-
IReadOnlyList<Result> results =
1272-
await PluginManager.QueryForPluginAsync(plugin, query, token);
1271+
var results = await PluginManager.QueryForPluginAsync(plugin, query, token);
12731272

12741273
if (token.IsCancellationRequested)
12751274
return;
@@ -1285,6 +1284,14 @@ async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
12851284
resultsCopy = DeepCloneResults(results, token);
12861285
}
12871286

1287+
foreach (var result in results)
1288+
{
1289+
if (string.IsNullOrEmpty(result.BadgePath))
1290+
{
1291+
result.BadgePath = plugin.Metadata.IcoPath;
1292+
}
1293+
}
1294+
12881295
if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(resultsCopy, plugin.Metadata, query,
12891296
token, reSelect)))
12901297
{

0 commit comments

Comments
 (0)