Skip to content

New API Function LoadImageAsync #3412

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Apr 8, 2025
14 changes: 8 additions & 6 deletions Flow.Launcher.Infrastructure/Image/ImageLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ public static bool TryGetValue(string path, bool loadFullImage, out ImageSource
return ImageCache.TryGetValue(path, loadFullImage, out image);
}

public static async ValueTask<ImageSource> LoadAsync(string path, bool loadFullImage = false)
public static async ValueTask<ImageSource> LoadAsync(string path, bool loadFullImage = false, bool cacheImage = true)
{
var imageResult = await LoadInternalAsync(path, loadFullImage);

Expand All @@ -300,16 +300,18 @@ public static async ValueTask<ImageSource> LoadAsync(string path, bool loadFullI
// image already exists
img = ImageCache[key, loadFullImage] ?? img;
}
else
else if (cacheImage)
{
// new guid

// save guid key
GuidToKey[hash] = path;
}
}

// update cache
ImageCache[path, loadFullImage] = img;
if (cacheImage)
{
// update cache
ImageCache[path, loadFullImage] = img;
}
}

return img;
Expand Down
15 changes: 15 additions & 0 deletions Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;

namespace Flow.Launcher.Plugin
{
Expand Down Expand Up @@ -346,6 +347,20 @@ public interface IPublicAPI
public void StopLoadingBar();

/// <summary>
/// Load image from path. Support local, remote and data:image url.
/// If image path is missing, it will return a missing icon.
/// </summary>
/// <param name="path">The path of the image.</param>
/// <param name="loadFullImage">
/// Load full image or not.
/// </param>
/// <param name="cacheImage">
/// Cache the image or not. Cached image will be stored in FL cache.
/// If the image is just used one time, it's better to set this to false.
/// </param>
/// <returns></returns>
ValueTask<ImageSource> LoadImageAsync(string path, bool loadFullImage = false, bool cacheImage = true);

/// Update the plugin manifest
/// </summary>
/// <param name="usePrimaryUrlOnly">
Expand Down
2 changes: 1 addition & 1 deletion Flow.Launcher/MessageBoxEx.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ private static async Task SetImageOfMessageBoxAsync(MessageBoxImage icon)
private async Task SetImageAsync(string imageName)
{
var imagePath = Path.Combine(Constant.ProgramDirectory, "Images", imageName);
var imageSource = await ImageLoader.LoadAsync(imagePath);
var imageSource = await App.API.LoadImageAsync(imagePath);
Img.Source = imageSource;
}

Expand Down
6 changes: 3 additions & 3 deletions Flow.Launcher/Msg.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public Msg()

private async System.Threading.Tasks.Task LoadImageAsync()
{
imgClose.Source = await ImageLoader.LoadAsync(Path.Combine(Infrastructure.Constant.ProgramDirectory, "Images\\close.png"));
imgClose.Source = await App.API.LoadImageAsync(Path.Combine(Constant.ProgramDirectory, "Images\\close.png"));
}

void imgClose_MouseUp(object sender, MouseButtonEventArgs e)
Expand Down Expand Up @@ -71,11 +71,11 @@ public async void Show(string title, string subTitle, string iconPath)

if (!File.Exists(iconPath))
{
imgIco.Source = await ImageLoader.LoadAsync(Path.Combine(Constant.ProgramDirectory, "Images\\app.png"));
imgIco.Source = await App.API.LoadImageAsync(Path.Combine(Constant.ProgramDirectory, "Images\\app.png"));
}
else
{
imgIco.Source = await ImageLoader.LoadAsync(iconPath);
imgIco.Source = await App.API.LoadImageAsync(iconPath);
}

Show();
Expand Down
4 changes: 4 additions & 0 deletions Flow.Launcher/PublicAPIInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using CommunityToolkit.Mvvm.DependencyInjection;
using Squirrel;
using Flow.Launcher.Core;
Expand Down Expand Up @@ -355,6 +356,9 @@ public MessageBoxResult ShowMsgBox(string messageBoxText, string caption = "", M

public Task ShowProgressBoxAsync(string caption, Func<Action<double>, Task> reportProgressAsync, Action cancelProgress = null) => ProgressBoxEx.ShowAsync(caption, reportProgressAsync, cancelProgress);

public ValueTask<ImageSource> LoadImageAsync(string path, bool loadFullImage = false, bool cacheImage = true) =>
ImageLoader.LoadAsync(path, loadFullImage, cacheImage);

public Task<bool> UpdatePluginManifestAsync(bool usePrimaryUrlOnly = false, CancellationToken token = default) =>
PluginsManifest.UpdateManifestAsync(usePrimaryUrlOnly, token);

Expand Down
2 changes: 1 addition & 1 deletion Flow.Launcher/ViewModel/MainViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1168,7 +1168,7 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
else if (plugins.Count == 1)
{
PluginIconPath = plugins.Single().Metadata.IcoPath;
PluginIconSource = await ImageLoader.LoadAsync(PluginIconPath);
PluginIconSource = await App.API.LoadImageAsync(PluginIconPath);
SearchIconVisibility = Visibility.Hidden;
}
else
Expand Down
2 changes: 1 addition & 1 deletion Flow.Launcher/ViewModel/PluginViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ private static string PluginManagerActionKeyword

private async Task LoadIconAsync()
{
Image = await ImageLoader.LoadAsync(PluginPair.Metadata.IcoPath);
Image = await App.API.LoadImageAsync(PluginPair.Metadata.IcoPath);
OnPropertyChanged(nameof(Image));
}

Expand Down
2 changes: 1 addition & 1 deletion Flow.Launcher/ViewModel/ResultViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ private async Task<ImageSource> LoadImageInternalAsync(string imagePath, Result.
}
}

return await ImageLoader.LoadAsync(imagePath, loadFullImage).ConfigureAwait(false);
return await App.API.LoadImageAsync(imagePath, loadFullImage).ConfigureAwait(false);
}

private async Task LoadImageAsync()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Flow.Launcher.Infrastructure.Image;
using Flow.Launcher.Plugin.Explorer.Search;

namespace Flow.Launcher.Plugin.Explorer.Views;
Expand Down Expand Up @@ -89,7 +88,7 @@ public PreviewPanel(Settings settings, string filePath)

private async Task LoadImageAsync()
{
PreviewImage = await ImageLoader.LoadAsync(FilePath, true).ConfigureAwait(false);
PreviewImage = await Main.Context.API.LoadImageAsync(FilePath, true).ConfigureAwait(false);
}

public event PropertyChangedEventHandler? PropertyChanged;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Flow.Launcher.Infrastructure.Image;
using System;
using System;
using System.IO;
using System.Threading.Tasks;
#pragma warning disable IDE0005
Expand Down Expand Up @@ -41,8 +40,8 @@ public void CopyNewImageToUserDataDirectoryIfRequired(
#if DEBUG
throw;
#else
Main._context.API.ShowMsgBox(string.Format("Copying the selected image file to {0} has failed, changes will now be reverted", destinationFileNameFullPath));
UpdateIconAttributes(selectedSearchSource, fullPathToOriginalImage);
Main._context.API.ShowMsgBox(string.Format("Copying the selected image file to {0} has failed, changes will now be reverted", destinationFileNameFullPath));
UpdateIconAttributes(selectedSearchSource, fullPathToOriginalImage);
#endif
}
}
Expand All @@ -61,7 +60,7 @@ internal bool ShouldProvideHint(string fullPathToSelectedImage)

internal async ValueTask<ImageSource> LoadPreviewIconAsync(string pathToPreviewIconImage)
{
return await ImageLoader.LoadAsync(pathToPreviewIconImage);
return await Main._context.API.LoadImageAsync(pathToPreviewIconImage);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Flow.Launcher.Infrastructure.Http;
using Flow.Launcher.Infrastructure.Logger;
using System.Net.Http;
using System.Threading;

Expand All @@ -22,11 +20,11 @@ public override async Task<List<string>> SuggestionsAsync(string query, Cancella
try
{
const string api = "http://suggestion.baidu.com/su?json=1&wd=";
result = await Http.GetAsync(api + Uri.EscapeDataString(query), token).ConfigureAwait(false);
result = await Main._context.API.HttpGetStringAsync(api + Uri.EscapeDataString(query), token).ConfigureAwait(false);
}
catch (Exception e) when (e is HttpRequestException or {InnerException: TimeoutException})
{
Log.Exception("|Baidu.Suggestions|Can't get suggestion from baidu", e);
Main._context.API.LogException(nameof(Baidu), "Can't get suggestion from Baidu", e);
return null;
}

Expand All @@ -41,7 +39,7 @@ public override async Task<List<string>> SuggestionsAsync(string query, Cancella
}
catch (JsonException e)
{
Log.Exception("|Baidu.Suggestions|can't parse suggestions", e);
Main._context.API.LogException(nameof(Baidu), "Can't parse suggestions", e);
return new List<string>();
}

Expand Down
16 changes: 5 additions & 11 deletions Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Bing.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using Flow.Launcher.Infrastructure.Http;
using Flow.Launcher.Infrastructure.Logger;
using System;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
Expand All @@ -10,16 +8,15 @@

namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
{
class Bing : SuggestionSource
public class Bing : SuggestionSource
{
public override async Task<List<string>> SuggestionsAsync(string query, CancellationToken token)
{

try
{
const string api = "https://api.bing.com/qsonhs.aspx?q=";

await using var resultStream = await Http.GetStreamAsync(api + Uri.EscapeDataString(query), token).ConfigureAwait(false);
await using var resultStream = await Main._context.API.HttpGetStreamAsync(api + Uri.EscapeDataString(query), token).ConfigureAwait(false);

using var json = (await JsonDocument.ParseAsync(resultStream, cancellationToken: token));
var root = json.RootElement.GetProperty("AS");
Expand All @@ -33,18 +30,15 @@ public override async Task<List<string>> SuggestionsAsync(string query, Cancella
.EnumerateArray()
.Select(s => s.GetProperty("Txt").GetString()))
.ToList();



}
catch (Exception e) when (e is HttpRequestException or { InnerException: TimeoutException })
{
Log.Exception("|Baidu.Suggestions|Can't get suggestion from baidu", e);
Main._context.API.LogException(nameof(Bing), "Can't get suggestion from Bing", e);
return null;
}
catch (JsonException e)
{
Log.Exception("|Bing.Suggestions|can't parse suggestions", e);
Main._context.API.LogException(nameof(Bing), "Can't parse suggestions", e);
return new List<string>();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Flow.Launcher.Infrastructure.Http;
using Flow.Launcher.Infrastructure.Logger;
using System.Net.Http;
using System.Threading;
using System.Text.Json;
Expand All @@ -25,7 +23,7 @@ public override async Task<List<string>> SuggestionsAsync(string query, Cancella
{
const string api = "https://duckduckgo.com/ac/?type=list&q=";

await using var resultStream = await Http.GetStreamAsync(api + Uri.EscapeDataString(query), token: token).ConfigureAwait(false);
await using var resultStream = await Main._context.API.HttpGetStreamAsync(api + Uri.EscapeDataString(query), token: token).ConfigureAwait(false);

using var json = await JsonDocument.ParseAsync(resultStream, cancellationToken: token);

Expand All @@ -36,12 +34,12 @@ public override async Task<List<string>> SuggestionsAsync(string query, Cancella
}
catch (Exception e) when (e is HttpRequestException or {InnerException: TimeoutException})
{
Log.Exception("|DuckDuckGo.Suggestions|Can't get suggestion from DuckDuckGo", e);
Main._context.API.LogException(nameof(DuckDuckGo), "Can't get suggestion from DuckDuckGo", e);
return null;
}
catch (JsonException e)
{
Log.Exception("|DuckDuckGo.Suggestions|can't parse suggestions", e);
Main._context.API.LogException(nameof(DuckDuckGo), "Can't parse suggestions", e);
return new List<string>();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Flow.Launcher.Infrastructure.Http;
using Flow.Launcher.Infrastructure.Logger;
using System.Net.Http;
using System.Threading;
using System.Text.Json;
Expand All @@ -18,7 +16,7 @@ public override async Task<List<string>> SuggestionsAsync(string query, Cancella
{
const string api = "https://www.google.com/complete/search?output=chrome&q=";

await using var resultStream = await Http.GetStreamAsync(api + Uri.EscapeDataString(query), token: token).ConfigureAwait(false);
await using var resultStream = await Main._context.API.HttpGetStreamAsync(api + Uri.EscapeDataString(query), token: token).ConfigureAwait(false);

using var json = await JsonDocument.ParseAsync(resultStream, cancellationToken: token);

Expand All @@ -29,12 +27,12 @@ public override async Task<List<string>> SuggestionsAsync(string query, Cancella
}
catch (Exception e) when (e is HttpRequestException or {InnerException: TimeoutException})
{
Log.Exception("|Baidu.Suggestions|Can't get suggestion from baidu", e);
Main._context.API.LogException(nameof(Google), "Can't get suggestion from Google", e);
return null;
}
catch (JsonException e)
{
Log.Exception("|Google.Suggestions|can't parse suggestions", e);
Main._context.API.LogException(nameof(Google), "Can't parse suggestions", e);
return new List<string>();
}
}
Expand Down
Loading