diff --git a/Flow.Launcher/ViewModel/ResultViewModel.cs b/Flow.Launcher/ViewModel/ResultViewModel.cs index 4d32d792d..ab02abbef 100644 --- a/Flow.Launcher/ViewModel/ResultViewModel.cs +++ b/Flow.Launcher/ViewModel/ResultViewModel.cs @@ -112,8 +112,10 @@ namespace Flow.Launcher.ViewModel : Result.SubTitleToolTip; private volatile bool ImageLoaded; + private volatile bool PreviewImageLoaded; private ImageSource image = ImageLoader.DefaultImage; + private ImageSource previewImage = ImageLoader.DefaultImage; public ImageSource Image { @@ -130,6 +132,21 @@ namespace Flow.Launcher.ViewModel private set => image = value; } + public ImageSource PreviewImage + { + get + { + if (!PreviewImageLoaded) + { + PreviewImageLoaded = true; + _ = LoadPreviewImageAsync(); + } + + return previewImage; + } + private set => previewImage = value; + } + public GlyphInfo Glyph { get; set; } private async ValueTask LoadImageAsync() @@ -161,6 +178,36 @@ namespace Flow.Launcher.ViewModel Image = await Task.Run(() => ImageLoader.Load(imagePath)).ConfigureAwait(false); } + + private async ValueTask LoadPreviewImageAsync() + { + var imagePath = Result.PreviewImage ?? Result.IcoPath; + if (string.IsNullOrEmpty(imagePath) && Result.Icon != null) + { + try + { + previewImage = Result.Icon(); + return; + } + catch (Exception e) + { + Log.Exception( + $"|ResultViewModel.Image|IcoPath is empty and exception when calling Icon() for result <{Result.Title}> of plugin <{Result.PluginDirectory}>", + e); + } + } + + if (ImageLoader.CacheContainImage(imagePath, true)) + { + // will get here either when icoPath has value\icon delegate is null\when had exception in delegate + previewImage = ImageLoader.Load(imagePath, true); + return; + } + + // We need to modify the property not field here to trigger the OnPropertyChanged event + PreviewImage = await Task.Run(() => ImageLoader.Load(imagePath, true)).ConfigureAwait(false); + } + public Result Result { get; } public string QuerySuggestionText { get; set; }