Merge pull request #3099 from Jack251970/dev3

Fix possible null reference when query is cancelled & Add new image icon for images whose formats are not support & Other improvements
This commit is contained in:
Kevin Zhang 2024-12-07 10:49:54 -08:00 committed by GitHub
commit 5f46ee746f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 36 additions and 15 deletions

View file

@ -31,6 +31,7 @@ namespace Flow.Launcher.Infrastructure
public static readonly string ErrorIcon = Path.Combine(ImagesDirectory, "app_error.png");
public static readonly string MissingImgIcon = Path.Combine(ImagesDirectory, "app_missing_img.png");
public static readonly string LoadingImgIcon = Path.Combine(ImagesDirectory, "loading.png");
public static readonly string ImageIcon = Path.Combine(ImagesDirectory, "image.png");
public static string PythonPath;
public static string NodePath;

View file

@ -22,6 +22,7 @@ namespace Flow.Launcher.Infrastructure.Image
private static readonly ConcurrentDictionary<string, string> GuidToKey = new();
private static IImageHashGenerator _hashGenerator;
private static readonly bool EnableImageHash = true;
public static ImageSource Image { get; } = new BitmapImage(new Uri(Constant.ImageIcon));
public static ImageSource MissingImage { get; } = new BitmapImage(new Uri(Constant.MissingImgIcon));
public static ImageSource LoadingImage { get; } = new BitmapImage(new Uri(Constant.LoadingImgIcon));
public const int SmallIconSize = 64;
@ -215,8 +216,16 @@ namespace Flow.Launcher.Infrastructure.Image
type = ImageType.ImageFile;
if (loadFullImage)
{
image = LoadFullImage(path);
type = ImageType.FullImageFile;
try
{
image = LoadFullImage(path);
type = ImageType.FullImageFile;
}
catch (NotSupportedException)
{
image = Image;
type = ImageType.Error;
}
}
else
{

Binary file not shown.

Before

Width:  |  Height:  |  Size: 687 B

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -308,7 +308,7 @@
VerticalAlignment="Center"
Panel.ZIndex="2"
RenderOptions.BitmapScalingMode="HighQuality"
Source="{Binding PluginIconPath}"
Source="{Binding PluginIconSource}"
Stretch="Uniform"
Style="{DynamicResource PluginActivationIcon}" />
<Canvas Style="{DynamicResource SearchIconPosition}">

View file

@ -1,29 +1,30 @@
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using Flow.Launcher.Plugin;
namespace Flow.Launcher.Storage
{
// todo this class is not thread safe.... but used from multiple threads.
public class TopMostRecord
{
[JsonInclude]
public Dictionary<string, Record> records { get; private set; } = new Dictionary<string, Record>();
public ConcurrentDictionary<string, Record> records { get; private set; } = new ConcurrentDictionary<string, Record>();
internal bool IsTopMost(Result result)
{
if (records.Count == 0 || !records.ContainsKey(result.OriginQuery.RawQuery))
if (records.IsEmpty || result.OriginQuery == null ||
!records.TryGetValue(result.OriginQuery.RawQuery, out var value))
{
return false;
}
// since this dictionary should be very small (or empty) going over it should be pretty fast.
return records[result.OriginQuery.RawQuery].Equals(result);
return value.Equals(result);
}
internal void Remove(Result result)
{
records.Remove(result.OriginQuery.RawQuery);
records.Remove(result.OriginQuery.RawQuery, out _);
}
internal void AddOrUpdate(Result result)
@ -34,17 +35,15 @@ namespace Flow.Launcher.Storage
Title = result.Title,
SubTitle = result.SubTitle
};
records[result.OriginQuery.RawQuery] = record;
records.AddOrUpdate(result.OriginQuery.RawQuery, record, (key, oldValue) => record);
}
public void Load(Dictionary<string, Record> dictionary)
{
records = dictionary;
records = new ConcurrentDictionary<string, Record>(dictionary);
}
}
public class Record
{
public string Title { get; set; }

View file

@ -51,6 +51,11 @@ namespace Flow.Launcher.Storage
private static int GenerateQueryAndResultHashCode(Query query, Result result)
{
if (query == null)
{
return GenerateResultHashCode(result);
}
int hashcode = GenerateStaticHashCode(query.ActionKeyword);
hashcode = GenerateStaticHashCode(query.Search, hashcode);
hashcode = GenerateStaticHashCode(result.Title, hashcode);
@ -101,4 +106,4 @@ namespace Flow.Launcher.Storage
return selectedCount;
}
}
}
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
@ -23,6 +23,8 @@ using CommunityToolkit.Mvvm.Input;
using System.Globalization;
using System.Windows.Input;
using System.ComponentModel;
using Flow.Launcher.Infrastructure.Image;
using System.Windows.Media;
namespace Flow.Launcher.ViewModel
{
@ -722,6 +724,8 @@ namespace Flow.Launcher.ViewModel
set => Settings.ResultSubItemFontSize = value;
}
public ImageSource PluginIconSource { get; private set; } = null;
public string PluginIconPath { get; set; } = null;
public string OpenResultCommandModifiers => Settings.OpenResultModifiers;
@ -1066,6 +1070,7 @@ namespace Flow.Launcher.ViewModel
Results.Clear();
Results.Visibility = Visibility.Collapsed;
PluginIconPath = null;
PluginIconSource = null;
SearchIconVisibility = Visibility.Visible;
return;
}
@ -1099,11 +1104,13 @@ namespace Flow.Launcher.ViewModel
if (plugins.Count == 1)
{
PluginIconPath = plugins.Single().Metadata.IcoPath;
PluginIconSource = await ImageLoader.LoadAsync(PluginIconPath);
SearchIconVisibility = Visibility.Hidden;
}
else
{
PluginIconPath = null;
PluginIconSource = null;
SearchIconVisibility = Visibility.Visible;
}