Skip to content

Commit 710a1d7

Browse files
committed
Merge branch 'dev' of github.com:Flow-Launcher/Flow.Launcher into JsonRPCPluginSettingControl
2 parents 054d165 + fac8b76 commit 710a1d7

File tree

125 files changed

+4439
-1328
lines changed

Some content is hidden

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

125 files changed

+4439
-1328
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
using Flow.Launcher.Infrastructure.Http;
2+
using Flow.Launcher.Infrastructure.Logger;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Text.Json;
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
9+
namespace Flow.Launcher.Core.ExternalPlugins
10+
{
11+
public static class PluginsManifest
12+
{
13+
static PluginsManifest()
14+
{
15+
UpdateTask = UpdateManifestAsync();
16+
}
17+
18+
public static List<UserPlugin> UserPlugins { get; private set; } = new List<UserPlugin>();
19+
20+
public static Task UpdateTask { get; private set; }
21+
22+
private static readonly SemaphoreSlim manifestUpdateLock = new(1);
23+
24+
public static Task UpdateManifestAsync()
25+
{
26+
if (manifestUpdateLock.CurrentCount == 0)
27+
{
28+
return UpdateTask;
29+
}
30+
31+
return UpdateTask = DownloadManifestAsync();
32+
}
33+
34+
private async static Task DownloadManifestAsync()
35+
{
36+
try
37+
{
38+
await manifestUpdateLock.WaitAsync().ConfigureAwait(false);
39+
40+
await using var jsonStream = await Http.GetStreamAsync("https://raw.githubusercontent.com/Flow-Launcher/Flow.Launcher.PluginsManifest/plugin_api_v2/plugins.json")
41+
.ConfigureAwait(false);
42+
43+
UserPlugins = await JsonSerializer.DeserializeAsync<List<UserPlugin>>(jsonStream).ConfigureAwait(false);
44+
}
45+
catch (Exception e)
46+
{
47+
Log.Exception("|PluginManagement.GetManifest|Encountered error trying to download plugins manifest", e);
48+
49+
UserPlugins = new List<UserPlugin>();
50+
}
51+
finally
52+
{
53+
manifestUpdateLock.Release();
54+
}
55+
}
56+
}
57+
}
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-

2-
namespace Flow.Launcher.Plugin.PluginsManager.Models
1+
namespace Flow.Launcher.Core.ExternalPlugins
32
{
4-
public class UserPlugin
3+
public record UserPlugin
54
{
65
public string ID { get; set; }
76
public string Name { get; set; }
@@ -12,5 +11,6 @@ public class UserPlugin
1211
public string Website { get; set; }
1312
public string UrlDownload { get; set; }
1413
public string UrlSourceCode { get; set; }
14+
public string IcoPath { get; set; }
1515
}
1616
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@
5353
</ItemGroup>
5454

5555
<ItemGroup>
56-
<PackageReference Include="Droplex" Version="1.3.1" />
57-
<PackageReference Include="FSharp.Core" Version="4.7.1" />
56+
<PackageReference Include="Droplex" Version="1.4.0" />
57+
<PackageReference Include="FSharp.Core" Version="5.0.2" />
5858
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="2.1.3" />
5959
<PackageReference Include="squirrel.windows" Version="1.5.2" />
6060
</ItemGroup>

Flow.Launcher.Core/Plugin/PluginsLoader.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ public static IEnumerable<PluginPair> PythonPlugins(List<PluginMetadata> source,
120120

121121
var pythonPath = string.Empty;
122122

123-
if (MessageBox.Show("Flow detected you have installed Python plugins, " +
124-
"would you like to install Python to run them? " +
123+
if (MessageBox.Show("Flow detected you have installed Python plugins, which " +
124+
"will need Python to run. Would you like to download Python? " +
125125
Environment.NewLine + Environment.NewLine +
126126
"Click no if it's already installed, " +
127127
"and you will be prompted to select the folder that contains the Python executable",

Flow.Launcher.Core/Plugin/QueryBuilder.cs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,35 +10,31 @@ public static class QueryBuilder
1010
public static Query Build(string text, Dictionary<string, PluginPair> nonGlobalPlugins)
1111
{
1212
// replace multiple white spaces with one white space
13-
var terms = text.Split(new[] { Query.TermSeperater }, StringSplitOptions.RemoveEmptyEntries);
13+
var terms = text.Split(Query.TermSeparator, StringSplitOptions.RemoveEmptyEntries);
1414
if (terms.Length == 0)
1515
{ // nothing was typed
1616
return null;
1717
}
1818

19-
var rawQuery = string.Join(Query.TermSeperater, terms);
19+
var rawQuery = string.Join(Query.TermSeparator, terms);
2020
string actionKeyword, search;
2121
string possibleActionKeyword = terms[0];
22-
List<string> actionParameters;
22+
string[] searchTerms;
23+
2324
if (nonGlobalPlugins.TryGetValue(possibleActionKeyword, out var pluginPair) && !pluginPair.Metadata.Disabled)
2425
{ // use non global plugin for query
2526
actionKeyword = possibleActionKeyword;
26-
actionParameters = terms.Skip(1).ToList();
27-
search = actionParameters.Count > 0 ? rawQuery.Substring(actionKeyword.Length + 1) : string.Empty;
27+
search = terms.Length > 1 ? rawQuery[(actionKeyword.Length + 1)..] : string.Empty;
28+
searchTerms = terms[1..];
2829
}
2930
else
3031
{ // non action keyword
3132
actionKeyword = string.Empty;
3233
search = rawQuery;
34+
searchTerms = terms;
3335
}
3436

35-
var query = new Query
36-
{
37-
Terms = terms,
38-
RawQuery = rawQuery,
39-
ActionKeyword = actionKeyword,
40-
Search = search
41-
};
37+
var query = new Query(rawQuery, search,terms, searchTerms, actionKeyword);
4238

4339
return query;
4440
}

Flow.Launcher.Core/Resource/Theme.cs

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,9 @@ private ResourceDictionary CurrentThemeResourceDictionary()
145145
public ResourceDictionary GetResourceDictionary()
146146
{
147147
var dict = CurrentThemeResourceDictionary();
148-
149-
Style queryBoxStyle = dict["QueryBoxStyle"] as Style;
150-
Style querySuggestionBoxStyle = dict["QuerySuggestionBoxStyle"] as Style;
151-
152-
if (queryBoxStyle != null && querySuggestionBoxStyle != null)
148+
149+
if (dict["QueryBoxStyle"] is Style queryBoxStyle &&
150+
dict["QuerySuggestionBoxStyle"] is Style querySuggestionBoxStyle)
153151
{
154152
var fontFamily = new FontFamily(Settings.QueryBoxFont);
155153
var fontStyle = FontHelper.GetFontStyleFromInvariantStringOrNormal(Settings.QueryBoxFontStyle);
@@ -174,19 +172,22 @@ public ResourceDictionary GetResourceDictionary()
174172
querySuggestionBoxStyle.Setters.Add(new Setter(TextBox.FontStretchProperty, fontStretch));
175173
}
176174

177-
Style resultItemStyle = dict["ItemTitleStyle"] as Style;
178-
Style resultSubItemStyle = dict["ItemSubTitleStyle"] as Style;
179-
Style resultItemSelectedStyle = dict["ItemTitleSelectedStyle"] as Style;
180-
Style resultSubItemSelectedStyle = dict["ItemSubTitleSelectedStyle"] as Style;
181-
if (resultItemStyle != null && resultSubItemStyle != null && resultSubItemSelectedStyle != null && resultItemSelectedStyle != null)
175+
if (dict["ItemTitleStyle"] is Style resultItemStyle &&
176+
dict["ItemSubTitleStyle"] is Style resultSubItemStyle &&
177+
dict["ItemSubTitleSelectedStyle"] is Style resultSubItemSelectedStyle &&
178+
dict["ItemTitleSelectedStyle"] is Style resultItemSelectedStyle &&
179+
dict["ItemHotkeyStyle"] is Style resultHotkeyItemStyle &&
180+
dict["ItemHotkeySelectedStyle"] is Style resultHotkeyItemSelectedStyle)
182181
{
183182
Setter fontFamily = new Setter(TextBlock.FontFamilyProperty, new FontFamily(Settings.ResultFont));
184183
Setter fontStyle = new Setter(TextBlock.FontStyleProperty, FontHelper.GetFontStyleFromInvariantStringOrNormal(Settings.ResultFontStyle));
185184
Setter fontWeight = new Setter(TextBlock.FontWeightProperty, FontHelper.GetFontWeightFromInvariantStringOrNormal(Settings.ResultFontWeight));
186185
Setter fontStretch = new Setter(TextBlock.FontStretchProperty, FontHelper.GetFontStretchFromInvariantStringOrNormal(Settings.ResultFontStretch));
187186

188187
Setter[] setters = { fontFamily, fontStyle, fontWeight, fontStretch };
189-
Array.ForEach(new[] { resultItemStyle, resultSubItemStyle, resultItemSelectedStyle, resultSubItemSelectedStyle }, o => Array.ForEach(setters, p => o.Setters.Add(p)));
188+
Array.ForEach(
189+
new[] { resultItemStyle, resultSubItemStyle, resultItemSelectedStyle, resultSubItemSelectedStyle, resultHotkeyItemStyle, resultHotkeyItemSelectedStyle }, o
190+
=> Array.ForEach(setters, p => o.Setters.Add(p)));
190191
}
191192

192193
var windowStyle = dict["WindowStyle"] as Style;
@@ -236,17 +237,19 @@ private string GetThemePath(string themeName)
236237

237238
public void AddDropShadowEffectToCurrentTheme()
238239
{
239-
var dict = CurrentThemeResourceDictionary();
240+
var dict = GetResourceDictionary();
240241

241242
var windowBorderStyle = dict["WindowBorderStyle"] as Style;
242243

243-
var effectSetter = new Setter();
244-
effectSetter.Property = Border.EffectProperty;
245-
effectSetter.Value = new DropShadowEffect
244+
var effectSetter = new Setter
246245
{
247-
Opacity = 0.9,
248-
ShadowDepth = 2,
249-
BlurRadius = 15
246+
Property = Border.EffectProperty,
247+
Value = new DropShadowEffect
248+
{
249+
Opacity = 0.4,
250+
ShadowDepth = 2,
251+
BlurRadius = 15
252+
}
250253
};
251254

252255
var marginSetter = windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == Border.MarginProperty) as Setter;
@@ -261,7 +264,7 @@ public void AddDropShadowEffectToCurrentTheme()
261264
}
262265
else
263266
{
264-
var baseMargin = (Thickness) marginSetter.Value;
267+
var baseMargin = (Thickness)marginSetter.Value;
265268
var newMargin = new Thickness(
266269
baseMargin.Left + ShadowExtraMargin,
267270
baseMargin.Top + ShadowExtraMargin,
@@ -282,8 +285,8 @@ public void RemoveDropShadowEffectFromCurrentTheme()
282285

283286
var effectSetter = windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == Border.EffectProperty) as Setter;
284287
var marginSetter = windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == Border.MarginProperty) as Setter;
285-
286-
if(effectSetter != null)
288+
289+
if (effectSetter != null)
287290
{
288291
windowBorderStyle.Setters.Remove(effectSetter);
289292
}
@@ -371,11 +374,11 @@ private bool IsBlurTheme()
371374
private void SetWindowAccent(Window w, AccentState state)
372375
{
373376
var windowHelper = new WindowInteropHelper(w);
374-
377+
375378
// this determines the width of the main query window
376379
w.Width = mainWindowWidth;
377380
windowHelper.EnsureHandle();
378-
381+
379382
var accent = new AccentPolicy { AccentState = state };
380383
var accentStructSize = Marshal.SizeOf(accent);
381384

Flow.Launcher.Core/Updater.cs

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using Flow.Launcher.Infrastructure.UserSettings;
1717
using Flow.Launcher.Plugin;
1818
using System.Text.Json.Serialization;
19+
using System.Threading;
1920

2021
namespace Flow.Launcher.Core
2122
{
@@ -28,21 +29,21 @@ public Updater(string gitHubRepository)
2829
GitHubRepository = gitHubRepository;
2930
}
3031

31-
public async Task UpdateApp(IPublicAPI api, bool silentUpdate = true)
32+
private SemaphoreSlim UpdateLock { get; } = new SemaphoreSlim(1);
33+
34+
public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)
3235
{
36+
await UpdateLock.WaitAsync();
3337
try
3438
{
35-
UpdateInfo newUpdateInfo;
36-
3739
if (!silentUpdate)
3840
api.ShowMsg(api.GetTranslation("pleaseWait"),
39-
api.GetTranslation("update_flowlauncher_update_check"));
41+
api.GetTranslation("update_flowlauncher_update_check"));
4042

4143
using var updateManager = await GitHubUpdateManager(GitHubRepository).ConfigureAwait(false);
4244

43-
4445
// UpdateApp CheckForUpdate will return value only if the app is squirrel installed
45-
newUpdateInfo = await updateManager.CheckForUpdate().NonNull().ConfigureAwait(false);
46+
var newUpdateInfo = await updateManager.CheckForUpdate().NonNull().ConfigureAwait(false);
4647

4748
var newReleaseVersion = Version.Parse(newUpdateInfo.FutureReleaseEntry.Version.ToString());
4849
var currentVersion = Version.Parse(Constant.Version);
@@ -58,7 +59,7 @@ public async Task UpdateApp(IPublicAPI api, bool silentUpdate = true)
5859

5960
if (!silentUpdate)
6061
api.ShowMsg(api.GetTranslation("update_flowlauncher_update_found"),
61-
api.GetTranslation("update_flowlauncher_updating"));
62+
api.GetTranslation("update_flowlauncher_updating"));
6263

6364
await updateManager.DownloadReleases(newUpdateInfo.ReleasesToApply).ConfigureAwait(false);
6465

@@ -70,8 +71,8 @@ public async Task UpdateApp(IPublicAPI api, bool silentUpdate = true)
7071
FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination);
7172
if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination))
7273
MessageBox.Show(string.Format(api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
73-
DataLocation.PortableDataPath,
74-
targetDestination));
74+
DataLocation.PortableDataPath,
75+
targetDestination));
7576
}
7677
else
7778
{
@@ -87,12 +88,15 @@ public async Task UpdateApp(IPublicAPI api, bool silentUpdate = true)
8788
UpdateManager.RestartApp(Constant.ApplicationFileName);
8889
}
8990
}
90-
catch (Exception e) when (e is HttpRequestException || e is WebException || e is SocketException || e.InnerException is TimeoutException)
91+
catch (Exception e) when (e is HttpRequestException or WebException or SocketException || e.InnerException is TimeoutException)
9192
{
9293
Log.Exception($"|Updater.UpdateApp|Check your connection and proxy settings to github-cloud.s3.amazonaws.com.", e);
9394
api.ShowMsg(api.GetTranslation("update_flowlauncher_fail"),
94-
api.GetTranslation("update_flowlauncher_check_connection"));
95-
return;
95+
api.GetTranslation("update_flowlauncher_check_connection"));
96+
}
97+
finally
98+
{
99+
UpdateLock.Release();
96100
}
97101
}
98102

@@ -115,13 +119,16 @@ private async Task<UpdateManager> GitHubUpdateManager(string repository)
115119
var uri = new Uri(repository);
116120
var api = $"https://api.github.com/repos{uri.AbsolutePath}/releases";
117121

118-
var jsonStream = await Http.GetStreamAsync(api).ConfigureAwait(false);
122+
await using var jsonStream = await Http.GetStreamAsync(api).ConfigureAwait(false);
119123

120124
var releases = await System.Text.Json.JsonSerializer.DeserializeAsync<List<GithubRelease>>(jsonStream).ConfigureAwait(false);
121125
var latest = releases.Where(r => !r.Prerelease).OrderByDescending(r => r.PublishedAt).First();
122126
var latestUrl = latest.HtmlUrl.Replace("/tag/", "/download/");
123-
124-
var client = new WebClient { Proxy = Http.WebProxy };
127+
128+
var client = new WebClient
129+
{
130+
Proxy = Http.WebProxy
131+
};
125132
var downloader = new FileDownloader(client);
126133

127134
var manager = new UpdateManager(latestUrl, urlDownloader: downloader);

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,10 @@
5353
<PackageReference Include="Microsoft.VisualStudio.Threading" Version="16.10.56" />
5454
<PackageReference Include="NLog" Version="4.7.10" />
5555
<PackageReference Include="NLog.Schema" Version="4.7.10" />
56-
<PackageReference Include="NLog.Web.AspNetCore" Version="4.12.0" />
57-
<PackageReference Include="System.Drawing.Common" Version="4.7.0" />
56+
<PackageReference Include="NLog.Web.AspNetCore" Version="4.13.0" />
57+
<PackageReference Include="System.Drawing.Common" Version="5.0.2" />
58+
<!--ToolGood.Words.Pinyin v3.0.2.6 results in high memory usage when search with pinyin is enabled-->
59+
<!--Bumping to it or higher needs to test and ensure this is no longer a problem-->
5860
<PackageReference Include="ToolGood.Words.Pinyin" Version="3.0.1.4" />
5961
</ItemGroup>
6062

Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System.Collections.Generic;
1+
using System.Collections.Generic;
22
using Flow.Launcher.Plugin;
33

44
namespace Flow.Launcher.Infrastructure.UserSettings
@@ -15,13 +15,24 @@ public void UpdatePluginSettings(List<PluginMetadata> metadatas)
1515
if (Plugins.ContainsKey(metadata.ID))
1616
{
1717
var settings = Plugins[metadata.ID];
18-
19-
// TODO: Remove. This is backwards compatibility for 1.8.0 release.
20-
// Introduced two new action keywords in Explorer, so need to update plugin setting in the UserData folder.
18+
2119
if (metadata.ID == "572be03c74c642baae319fc283e561a8" && metadata.ActionKeywords.Count > settings.ActionKeywords.Count)
2220
{
23-
settings.ActionKeywords.Add(Query.GlobalPluginWildcardSign); // for index search
24-
settings.ActionKeywords.Add(Query.GlobalPluginWildcardSign); // for path search
21+
// TODO: Remove. This is backwards compatibility for Explorer 1.8.0 release.
22+
// Introduced two new action keywords in Explorer, so need to update plugin setting in the UserData folder.
23+
if (settings.Version.CompareTo("1.8.0") < 0)
24+
{
25+
settings.ActionKeywords.Add(Query.GlobalPluginWildcardSign); // for index search
26+
settings.ActionKeywords.Add(Query.GlobalPluginWildcardSign); // for path search
27+
settings.ActionKeywords.Add(Query.GlobalPluginWildcardSign); // for quick access action keyword
28+
}
29+
30+
// TODO: Remove. This is backwards compatibility for Explorer 1.9.0 release.
31+
// Introduced a new action keywords in Explorer since 1.8.0, so need to update plugin setting in the UserData folder.
32+
if (settings.Version.CompareTo("1.8.0") > 0)
33+
{
34+
settings.ActionKeywords.Add(Query.GlobalPluginWildcardSign); // for quick access action keyword
35+
}
2536
}
2637

2738
if (string.IsNullOrEmpty(settings.Version))

0 commit comments

Comments
 (0)