Skip to content

Commit de095ef

Browse files
authored
Merge branch 'dev' into PopupRedesign
2 parents 0742d03 + 8cb7cbb commit de095ef

File tree

81 files changed

+2800
-944
lines changed

Some content is hidden

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

81 files changed

+2800
-944
lines changed

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/UserSettings/Settings.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public string Language
3232
public string ResultFontStyle { get; set; }
3333
public string ResultFontWeight { get; set; }
3434
public string ResultFontStretch { get; set; }
35+
public bool UseGlyphIcons { get; set; } = true;
3536

3637

3738
/// <summary>

Flow.Launcher.Plugin/Query.cs

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System;
1+
using JetBrains.Annotations;
2+
using System;
23
using System.Collections.Generic;
34
using System.Linq;
45

@@ -11,65 +12,74 @@ public Query() { }
1112
/// <summary>
1213
/// to allow unit tests for plug ins
1314
/// </summary>
14-
public Query(string rawQuery, string search, string[] terms, string actionKeyword = "")
15+
public Query(string rawQuery, string search, string[] terms, string[] searchTerms, string actionKeyword = "")
1516
{
1617
Search = search;
1718
RawQuery = rawQuery;
1819
Terms = terms;
20+
SearchTerms = searchTerms;
1921
ActionKeyword = actionKeyword;
2022
}
2123

2224
/// <summary>
2325
/// Raw query, this includes action keyword if it has
2426
/// We didn't recommend use this property directly. You should always use Search property.
2527
/// </summary>
26-
public string RawQuery { get; internal set; }
28+
public string RawQuery { get; internal init; }
2729

2830
/// <summary>
2931
/// Search part of a query.
3032
/// This will not include action keyword if exclusive plugin gets it, otherwise it should be same as RawQuery.
3133
/// Since we allow user to switch a exclusive plugin to generic plugin,
3234
/// so this property will always give you the "real" query part of the query
3335
/// </summary>
34-
public string Search { get; internal set; }
36+
public string Search { get; internal init; }
3537

3638
/// <summary>
37-
/// The raw query splited into a string array.
39+
/// The search string split into a string array.
3840
/// </summary>
39-
public string[] Terms { get; set; }
41+
public string[] SearchTerms { get; init; }
42+
43+
/// <summary>
44+
/// The raw query split into a string array
45+
/// </summary>
46+
[Obsolete("It may or may not include action keyword, which can be confusing. Use SearchTerms instead")]
47+
public string[] Terms { get; init; }
4048

4149
/// <summary>
4250
/// Query can be splited into multiple terms by whitespace
4351
/// </summary>
44-
public const string TermSeperater = " ";
52+
public const string TermSeparator = " ";
53+
54+
[Obsolete("Typo")]
55+
public const string TermSeperater = TermSeparator;
4556
/// <summary>
4657
/// User can set multiple action keywords seperated by ';'
4758
/// </summary>
48-
public const string ActionKeywordSeperater = ";";
59+
public const string ActionKeywordSeparator = ";";
60+
61+
[Obsolete("Typo")]
62+
public const string ActionKeywordSeperater = ActionKeywordSeparator;
63+
4964

5065
/// <summary>
5166
/// '*' is used for System Plugin
5267
/// </summary>
5368
public const string GlobalPluginWildcardSign = "*";
5469

55-
public string ActionKeyword { get; set; }
70+
public string ActionKeyword { get; init; }
5671

5772
/// <summary>
5873
/// Return first search split by space if it has
5974
/// </summary>
6075
public string FirstSearch => SplitSearch(0);
6176

77+
private string _secondToEndSearch;
78+
6279
/// <summary>
6380
/// strings from second search (including) to last search
6481
/// </summary>
65-
public string SecondToEndSearch
66-
{
67-
get
68-
{
69-
var index = string.IsNullOrEmpty(ActionKeyword) ? 1 : 2;
70-
return string.Join(TermSeperater, Terms.Skip(index).ToArray());
71-
}
72-
}
82+
public string SecondToEndSearch => SearchTerms.Length > 1 ? (_secondToEndSearch ??= string.Join(' ', SearchTerms[1..])) : "";
7383

7484
/// <summary>
7585
/// Return second search split by space if it has
@@ -83,16 +93,9 @@ public string SecondToEndSearch
8393

8494
private string SplitSearch(int index)
8595
{
86-
try
87-
{
88-
return string.IsNullOrEmpty(ActionKeyword) ? Terms[index] : Terms[index + 1];
89-
}
90-
catch (IndexOutOfRangeException)
91-
{
92-
return string.Empty;
93-
}
96+
return index < SearchTerms.Length ? SearchTerms[index] : string.Empty;
9497
}
9598

9699
public override string ToString() => RawQuery;
97100
}
98-
}
101+
}

Flow.Launcher/ActionKeywords.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public ActionKeywords(string pluginId, Settings settings, PluginViewModel plugin
3030

3131
private void ActionKeyword_OnLoaded(object sender, RoutedEventArgs e)
3232
{
33-
tbOldActionKeyword.Text = string.Join(Query.ActionKeywordSeperater, plugin.Metadata.ActionKeywords.ToArray());
33+
tbOldActionKeyword.Text = string.Join(Query.ActionKeywordSeparator, plugin.Metadata.ActionKeywords.ToArray());
3434
tbAction.Focus();
3535
}
3636

Flow.Launcher/App.xaml.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,12 @@ private void AutoUpdates()
129129
var timer = new Timer(1000 * 60 * 60 * 5);
130130
timer.Elapsed += async (s, e) =>
131131
{
132-
await _updater.UpdateApp(API);
132+
await _updater.UpdateAppAsync(API);
133133
};
134134
timer.Start();
135135

136136
// check updates on startup
137-
await _updater.UpdateApp(API);
137+
await _updater.UpdateAppAsync(API);
138138
}
139139
});
140140
}

0 commit comments

Comments
 (0)