Skip to content

Commit 21ba7bf

Browse files
committed
Merge branch 'dev' of github.com:Flow-Launcher/Flow.Launcher into pluginlist_unselected_item
2 parents ab97a5c + 03ba623 commit 21ba7bf

File tree

160 files changed

+6813
-30511
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

160 files changed

+6813
-30511
lines changed

Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ public static async Task UpdateManifestAsync(CancellationToken token = default)
2929
var request = new HttpRequestMessage(HttpMethod.Get, manifestFileUrl);
3030
request.Headers.Add("If-None-Match", latestEtag);
3131

32-
var response = await Http.SendAsync(request, token).ConfigureAwait(false);
32+
using var response = await Http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token).ConfigureAwait(false);
3333

3434
if (response.StatusCode == HttpStatusCode.OK)
3535
{
3636
Log.Info($"|PluginsManifest.{nameof(UpdateManifestAsync)}|Fetched plugins from manifest repo");
3737

38-
var json = await response.Content.ReadAsStreamAsync(token).ConfigureAwait(false);
38+
await using var json = await response.Content.ReadAsStreamAsync(token).ConfigureAwait(false);
3939

4040
UserPlugins = await JsonSerializer.DeserializeAsync<List<UserPlugin>>(json, cancellationToken: token).ConfigureAwait(false);
4141

@@ -56,4 +56,4 @@ public static async Task UpdateManifestAsync(CancellationToken token = default)
5656
}
5757
}
5858
}
59-
}
59+
}

Flow.Launcher.Core/Flow.Launcher.Core.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
<ItemGroup>
5656
<PackageReference Include="Droplex" Version="1.4.1" />
5757
<PackageReference Include="FSharp.Core" Version="6.0.6" />
58-
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="2.1.3" />
58+
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="2.2.1" />
5959
<PackageReference Include="squirrel.windows" Version="1.5.2" NoWarn="NU1701" />
6060
</ItemGroup>
6161

Flow.Launcher.Core/Resource/Internationalization.cs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,16 @@ public void ChangeLanguage(Language language)
9696
{
9797
LoadLanguage(language);
9898
}
99-
Settings.Language = language.LanguageCode;
100-
CultureInfo.CurrentCulture = new CultureInfo(language.LanguageCode);
99+
// Culture of this thread
100+
// Use CreateSpecificCulture to preserve possible user-override settings in Windows
101+
CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture(language.LanguageCode);
101102
CultureInfo.CurrentUICulture = CultureInfo.CurrentCulture;
103+
// App domain
104+
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture(language.LanguageCode);
105+
CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.DefaultThreadCurrentCulture;
106+
107+
// Raise event after culture is set
108+
Settings.Language = language.LanguageCode;
102109
_ = Task.Run(() =>
103110
{
104111
UpdatePluginMetadataTranslations();
@@ -115,7 +122,11 @@ public bool PromptShouldUsePinyin(string languageCodeToSet)
115122
if (languageToSet != AvailableLanguages.Chinese && languageToSet != AvailableLanguages.Chinese_TW)
116123
return false;
117124

118-
if (MessageBox.Show("Do you want to turn on search with Pinyin?", string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
125+
// No other languages should show the following text so just make it hard-coded
126+
// "Do you want to search with pinyin?"
127+
string text = languageToSet == AvailableLanguages.Chinese ? "是否启用拼音搜索?" : "是否啓用拼音搜索?" ;
128+
129+
if (MessageBox.Show(text, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
119130
return false;
120131

121132
return true;
@@ -182,7 +193,7 @@ private void UpdatePluginMetadataTranslations()
182193
{
183194
p.Metadata.Name = pluginI18N.GetTranslatedPluginTitle();
184195
p.Metadata.Description = pluginI18N.GetTranslatedPluginDescription();
185-
pluginI18N.OnCultureInfoChanged(CultureInfo.CurrentCulture);
196+
pluginI18N.OnCultureInfoChanged(CultureInfo.DefaultThreadCurrentCulture);
186197
}
187198
catch (Exception e)
188199
{
@@ -221,4 +232,4 @@ public string LanguageFile(string folder, string language)
221232
}
222233
}
223234
}
224-
}
235+
}

Flow.Launcher.Core/Updater.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)
7979
await updateManager.CreateUninstallerRegistryEntry().ConfigureAwait(false);
8080
}
8181

82-
var newVersionTips = NewVersinoTips(newReleaseVersion.ToString());
82+
var newVersionTips = NewVersionTips(newReleaseVersion.ToString());
8383

8484
Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}");
8585

@@ -137,10 +137,10 @@ private async Task<UpdateManager> GitHubUpdateManagerAsync(string repository)
137137
return manager;
138138
}
139139

140-
public string NewVersinoTips(string version)
140+
public string NewVersionTips(string version)
141141
{
142-
var translater = InternationalizationManager.Instance;
143-
var tips = string.Format(translater.GetTranslation("newVersionTips"), version);
142+
var translator = InternationalizationManager.Instance;
143+
var tips = string.Format(translator.GetTranslation("newVersionTips"), version);
144144

145145
return tips;
146146
}

Flow.Launcher.Infrastructure/Constant.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System.Diagnostics;
1+
using System.Diagnostics;
22
using System.IO;
33
using System.Reflection;
44

@@ -21,6 +21,7 @@ public static class Constant
2121
public static readonly string PreinstalledDirectory = Path.Combine(ProgramDirectory, Plugins);
2222
public const string Issue = "https://github.com/Flow-Launcher/Flow.Launcher/issues/new";
2323
public static readonly string Version = FileVersionInfo.GetVersionInfo(Assembly.Location.NonNull()).ProductVersion;
24+
public static readonly string Dev = "Dev";
2425
public const string Documentation = "https://flowlauncher.com/docs/#/usage-tips";
2526

2627
public static readonly int ThumbnailSize = 64;
@@ -44,6 +45,7 @@ public static class Constant
4445
public const string Logs = "Logs";
4546

4647
public const string Website = "https://flowlauncher.com";
48+
public const string SponsorPage = "https://github.com/sponsors/Flow-Launcher";
4749
public const string GitHub = "https://github.com/Flow-Launcher/Flow.Launcher";
4850
public const string Docs = "https://flowlauncher.com/docs";
4951
}

Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,22 +58,11 @@
5858
<PackageReference Include="NLog.Schema" Version="4.7.10" />
5959
<PackageReference Include="NLog.Web.AspNetCore" Version="4.13.0" />
6060
<PackageReference Include="PropertyChanged.Fody" Version="3.4.0" />
61-
<PackageReference Include="System.Drawing.Common" Version="5.0.2" />
61+
<PackageReference Include="System.Drawing.Common" Version="5.0.3" />
6262
<!--ToolGood.Words.Pinyin v3.0.2.6 results in high memory usage when search with pinyin is enabled-->
6363
<!--Bumping to it or higher needs to test and ensure this is no longer a problem-->
6464
<PackageReference Include="ToolGood.Words.Pinyin" Version="3.0.1.4" />
6565
</ItemGroup>
6666

67-
<ItemGroup>
68-
<None Update="pinyindb\pinyin_gwoyeu_mapping.xml">
69-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
70-
</None>
71-
<None Update="pinyindb\pinyin_mapping.xml">
72-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
73-
</None>
74-
<None Update="pinyindb\unicode_to_hanyu_pinyin.txt">
75-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
76-
</None>
77-
</ItemGroup>
7867

7968
</Project>

Flow.Launcher.Infrastructure/Http/Http.cs

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public static void UpdateProxy(ProxyProperty property)
6868
var userName when string.IsNullOrEmpty(userName) =>
6969
(new Uri($"http://{Proxy.Server}:{Proxy.Port}"), null),
7070
_ => (new Uri($"http://{Proxy.Server}:{Proxy.Port}"),
71-
new NetworkCredential(Proxy.UserName, Proxy.Password))
71+
new NetworkCredential(Proxy.UserName, Proxy.Password))
7272
},
7373
_ => (null, null)
7474
},
@@ -79,7 +79,7 @@ var userName when string.IsNullOrEmpty(userName) =>
7979
_ => throw new ArgumentOutOfRangeException()
8080
};
8181
}
82-
catch(UriFormatException e)
82+
catch (UriFormatException e)
8383
{
8484
API.ShowMsg("Please try again", "Unable to parse Http Proxy");
8585
Log.Exception("Flow.Launcher.Infrastructure.Http", "Unable to parse Uri", e);
@@ -94,7 +94,7 @@ public static async Task DownloadAsync([NotNull] string url, [NotNull] string fi
9494
if (response.StatusCode == HttpStatusCode.OK)
9595
{
9696
await using var fileStream = new FileStream(filePath, FileMode.CreateNew);
97-
await response.Content.CopyToAsync(fileStream);
97+
await response.Content.CopyToAsync(fileStream, token);
9898
}
9999
else
100100
{
@@ -117,7 +117,7 @@ public static async Task DownloadAsync([NotNull] string url, [NotNull] string fi
117117
public static Task<string> GetAsync([NotNull] string url, CancellationToken token = default)
118118
{
119119
Log.Debug($"|Http.Get|Url <{url}>");
120-
return GetAsync(new Uri(url.Replace("#", "%23")), token);
120+
return GetAsync(new Uri(url), token);
121121
}
122122

123123
/// <summary>
@@ -130,36 +130,57 @@ public static async Task<string> GetAsync([NotNull] Uri url, CancellationToken t
130130
{
131131
Log.Debug($"|Http.Get|Url <{url}>");
132132
using var response = await client.GetAsync(url, token);
133-
var content = await response.Content.ReadAsStringAsync();
134-
if (response.StatusCode == HttpStatusCode.OK)
135-
{
136-
return content;
137-
}
138-
else
133+
var content = await response.Content.ReadAsStringAsync(token);
134+
if (response.StatusCode != HttpStatusCode.OK)
139135
{
140136
throw new HttpRequestException(
141137
$"Error code <{response.StatusCode}> with content <{content}> returned from <{url}>");
142138
}
139+
140+
return content;
143141
}
144142

145143
/// <summary>
146-
/// Asynchrously get the result as stream from url.
144+
/// Send a GET request to the specified Uri with an HTTP completion option and a cancellation token as an asynchronous operation.
145+
/// </summary>
146+
/// <param name="url">The Uri the request is sent to.</param>
147+
/// <param name="completionOption">An HTTP completion option value that indicates when the operation should be considered completed.</param>
148+
/// <param name="token">A cancellation token that can be used by other objects or threads to receive notice of cancellation</param>
149+
/// <returns></returns>
150+
public static Task<Stream> GetStreamAsync([NotNull] string url,
151+
CancellationToken token = default) => GetStreamAsync(new Uri(url), token);
152+
153+
154+
/// <summary>
155+
/// Send a GET request to the specified Uri with an HTTP completion option and a cancellation token as an asynchronous operation.
147156
/// </summary>
148157
/// <param name="url"></param>
158+
/// <param name="token"></param>
149159
/// <returns></returns>
150-
public static async Task<Stream> GetStreamAsync([NotNull] string url, CancellationToken token = default)
160+
public static async Task<Stream> GetStreamAsync([NotNull] Uri url,
161+
CancellationToken token = default)
162+
{
163+
Log.Debug($"|Http.Get|Url <{url}>");
164+
return await client.GetStreamAsync(url, token);
165+
}
166+
167+
public static async Task<HttpResponseMessage> GetResponseAsync(string url, HttpCompletionOption completionOption = HttpCompletionOption.ResponseContentRead,
168+
CancellationToken token = default)
169+
=> await GetResponseAsync(new Uri(url), completionOption, token);
170+
171+
public static async Task<HttpResponseMessage> GetResponseAsync([NotNull] Uri url, HttpCompletionOption completionOption = HttpCompletionOption.ResponseContentRead,
172+
CancellationToken token = default)
151173
{
152174
Log.Debug($"|Http.Get|Url <{url}>");
153-
var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token);
154-
return await response.Content.ReadAsStreamAsync();
175+
return await client.GetAsync(url, completionOption, token);
155176
}
156177

157178
/// <summary>
158179
/// Asynchrously send an HTTP request.
159180
/// </summary>
160-
public static async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken token = default)
181+
public static async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption = HttpCompletionOption.ResponseContentRead, CancellationToken token = default)
161182
{
162-
return await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token);
183+
return await client.SendAsync(request, completionOption, token);
163184
}
164185
}
165186
}

Flow.Launcher.Infrastructure/Image/ImageCache.cs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,41 +25,41 @@ public ImageUsage(int usage, ImageSource image)
2525
public class ImageCache
2626
{
2727
private const int MaxCached = 50;
28-
public ConcurrentDictionary<string, ImageUsage> Data { get; private set; } = new ConcurrentDictionary<string, ImageUsage>();
28+
public ConcurrentDictionary<(string, bool), ImageUsage> Data { get; } = new();
2929
private const int permissibleFactor = 2;
3030
private SemaphoreSlim semaphore = new(1, 1);
3131

32-
public void Initialization(Dictionary<string, int> usage)
32+
public void Initialization(Dictionary<(string, bool), int> usage)
3333
{
3434
foreach (var key in usage.Keys)
3535
{
3636
Data[key] = new ImageUsage(usage[key], null);
3737
}
3838
}
3939

40-
public ImageSource this[string path]
40+
public ImageSource this[string path, bool isFullImage = false]
4141
{
4242
get
4343
{
44-
if (Data.TryGetValue(path, out var value))
44+
if (!Data.TryGetValue((path, isFullImage), out var value))
4545
{
46-
value.usage++;
47-
return value.imageSource;
46+
return null;
4847
}
48+
value.usage++;
49+
return value.imageSource;
4950

50-
return null;
5151
}
5252
set
5353
{
5454
Data.AddOrUpdate(
55-
path,
56-
new ImageUsage(0, value),
57-
(k, v) =>
58-
{
59-
v.imageSource = value;
60-
v.usage++;
61-
return v;
62-
}
55+
(path, isFullImage),
56+
new ImageUsage(0, value),
57+
(k, v) =>
58+
{
59+
v.imageSource = value;
60+
v.usage++;
61+
return v;
62+
}
6363
);
6464

6565
SliceExtra();
@@ -82,9 +82,9 @@ async void SliceExtra()
8282
}
8383
}
8484

85-
public bool ContainsKey(string key)
85+
public bool ContainsKey(string key, bool isFullImage)
8686
{
87-
return key is not null && Data.ContainsKey(key) && Data[key].imageSource != null;
87+
return key is not null && Data.ContainsKey((key, isFullImage)) && Data[(key, isFullImage)].imageSource != null;
8888
}
8989

9090
public int CacheSize()
@@ -100,4 +100,4 @@ public int UniqueImagesInCache()
100100
return Data.Values.Select(x => x.imageSource).Distinct().Count();
101101
}
102102
}
103-
}
103+
}

0 commit comments

Comments
 (0)