diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs index bc924926c..f61d4615a 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs @@ -18,6 +18,8 @@ namespace Flow.Launcher.Infrastructure.Image private static readonly ConcurrentDictionary GuidToKey = new ConcurrentDictionary(); private static IImageHashGenerator _hashGenerator; private static bool EnableImageHash = true; + public static ImageSource defaultImage { get; } = new BitmapImage(new Uri(Constant.MissingImgIcon)); + private static readonly string[] ImageExtensions = { @@ -37,6 +39,7 @@ namespace Flow.Launcher.Infrastructure.Image var usage = LoadStorageToConcurrentDictionary(); + foreach (var icon in new[] { Constant.DefaultIcon, Constant.MissingImgIcon }) { ImageSource img = new BitmapImage(new Uri(icon)); @@ -213,13 +216,10 @@ namespace Flow.Launcher.Infrastructure.Image public static bool CacheContainImage(string path) { - return ImageCache.ContainsKey(path); - } - public static ImageSource LoadDefault(bool loadFullImage = false) - { - return LoadInternal(Constant.MissingImgIcon, loadFullImage).ImageSource; + return ImageCache.ContainsKey(path) && ImageCache[path] != null; } + public static ImageSource Load(string path, bool loadFullImage = false) { var imageResult = LoadInternal(path, loadFullImage); @@ -230,7 +230,7 @@ namespace Flow.Launcher.Infrastructure.Image string hash = EnableImageHash ? _hashGenerator.GetHashFromImage(img) : null; if (hash != null) { - + if (GuidToKey.TryGetValue(hash, out string key)) { // image already exists img = ImageCache[key] ?? img; diff --git a/Flow.Launcher/ViewModel/ResultViewModel.cs b/Flow.Launcher/ViewModel/ResultViewModel.cs index 8ce35227f..511df5e59 100644 --- a/Flow.Launcher/ViewModel/ResultViewModel.cs +++ b/Flow.Launcher/ViewModel/ResultViewModel.cs @@ -8,18 +8,57 @@ using Flow.Launcher.Infrastructure.Image; using Flow.Launcher.Infrastructure.Logger; using Flow.Launcher.Infrastructure.UserSettings; using Flow.Launcher.Plugin; - +using Microsoft.FSharp.Core; namespace Flow.Launcher.ViewModel { public class ResultViewModel : BaseModel { + public class LazyAsync : Lazy> + { + private T defaultValue; + + + private readonly Action _updateCallback; + public T Value + { + get + { + if (!IsValueCreated) + { + base.Value.ContinueWith(_ => + { + _updateCallback(); + }); + return defaultValue; + } + else if (!base.Value.IsCompleted) + { + return defaultValue; + } + else return base.Value.Result; + } + } + public LazyAsync(Func> factory, T defaultValue, Action updateCallback) : base(factory) + { + if (defaultValue != null) + { + this.defaultValue = defaultValue; + } + _updateCallback = updateCallback; + + } + } + public ResultViewModel(Result result, Settings settings) { if (result != null) { Result = result; - Image = new Lazy(SetImage); + Image = new LazyAsync(SetImage, ImageLoader.defaultImage, () => + { + OnPropertyChanged(nameof(Image)); + }); } Settings = settings; @@ -39,9 +78,9 @@ namespace Flow.Launcher.ViewModel ? Result.SubTitle : Result.SubTitleToolTip; - public Lazy Image { get; set; } + public LazyAsync Image { get; set; } - private ImageSource SetImage() + private async Task SetImage() { var imagePath = Result.IcoPath; if (string.IsNullOrEmpty(imagePath) && Result.Icon != null) @@ -62,14 +101,9 @@ namespace Flow.Launcher.ViewModel return ImageLoader.Load(imagePath); else { - Task.Run(() => - { - Image = new Lazy(() => ImageLoader.Load(imagePath)); - OnPropertyChanged(nameof(Image)); - }); - - return ImageLoader.LoadDefault(); + return await Task.Run(() => ImageLoader.Load(imagePath)); } + } public Result Result { get; }