From 3abd05f6b3a687e73fc9e6ab0f09ec2af2f6c06a Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sat, 18 Nov 2023 14:58:16 +0800 Subject: [PATCH 001/576] Implement double pinyin --- .../DoublePinAlphabet.cs | 193 ++++++++++++++++++ .../UserSettings/Settings.cs | 2 + 2 files changed, 195 insertions(+) create mode 100644 Flow.Launcher.Infrastructure/DoublePinAlphabet.cs diff --git a/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs b/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs new file mode 100644 index 00000000000..607582097f9 --- /dev/null +++ b/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs @@ -0,0 +1,193 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text; +using Flow.Launcher.Infrastructure.UserSettings; +using ToolGood.Words.Pinyin; + +namespace Flow.Launcher.Infrastructure +{ + public class DoublePinAlphabet : IAlphabet + { + private ConcurrentDictionary _doublePinCache = + new ConcurrentDictionary(); + + private Settings _settings; + + public void Initialize([NotNull] Settings settings) + { + _settings = settings ?? throw new ArgumentNullException(nameof(settings)); + } + + public bool CanBeTranslated(string stringToTranslate) + { + return WordsHelper.HasChinese(stringToTranslate); + } + + public (string translation, TranslationMapping map) Translate(string content) + { + if (_settings.ShouldUseDoublePin) + { + if (!_doublePinCache.ContainsKey(content)) + { + return BuildCacheFromContent(content); + } + else + { + return _doublePinCache[content]; + } + } + return (content, null); + } + + private (string translation, TranslationMapping map) BuildCacheFromContent(string content) + { + if (WordsHelper.HasChinese(content)) + { + var resultList = WordsHelper.GetPinyinList(content).Select(ToDoublePin).ToArray(); + StringBuilder resultBuilder = new StringBuilder(); + TranslationMapping map = new TranslationMapping(); + + bool pre = false; + + for (int i = 0; i < resultList.Length; i++) + { + if (content[i] >= 0x3400 && content[i] <= 0x9FD5) + { + map.AddNewIndex(i, resultBuilder.Length, resultList[i].Length + 1); + resultBuilder.Append(' '); + resultBuilder.Append(resultList[i]); + pre = true; + } + else + { + if (pre) + { + pre = false; + resultBuilder.Append(' '); + } + + resultBuilder.Append(resultList[i]); + } + } + + map.endConstruct(); + + var key = resultBuilder.ToString(); + map.setKey(key); + + return _doublePinCache[content] = (key, map); + } + else + { + return (content, null); + } + } + + private static readonly ReadOnlyDictionary special = new(new Dictionary(){ + {"a", "aa"}, + {"ai", "ai"}, + {"an", "an"}, + {"ang", "ah"}, + {"ao", "ao"}, + {"e", "ee"}, + {"ei", "ei"}, + {"en", "en"}, + {"er", "er"}, + {"o", "oo"}, + {"ou", "ou"} + }); + + + private static readonly ReadOnlyDictionary first = new(new Dictionary(){ + {"ch", "i"}, + {"sh", "u"}, + {"zh", "v"} + }); + + + private static readonly ReadOnlyDictionary second = new(new Dictionary() + { + {"ua", "x"}, + {"ei", "w"}, + {"e", "e"}, + {"ou", "z"}, + {"iu", "q"}, + {"ve", "t"}, + {"ue", "t"}, + {"u", "u"}, + {"i", "i"}, + {"o", "o"}, + {"uo", "o"}, + {"ie", "p"}, + {"a", "a"}, + {"ong", "s"}, + {"iong", "s"}, + {"ai", "d"}, + {"ing", "k"}, + {"uai", "k"}, + {"ang", "h"}, + {"uan", "r"}, + {"an", "j"}, + {"en", "f"}, + {"ia", "x"}, + {"iang", "l"}, + {"uang", "l"}, + {"eng", "g"}, + {"in", "b"}, + {"ao", "c"}, + {"v", "v"}, + {"ui", "v"}, + {"un", "y"}, + {"iao", "n"}, + {"ian", "m"} + }); + + private static string ToDoublePin(string fullPinyin) + { + // Assuming s is valid + StringBuilder doublePin = new StringBuilder(); + + if (fullPinyin.Length <= 3 && (fullPinyin[0] == 'a' || fullPinyin[0] == 'e' || fullPinyin[0] == 'o')) + { + if (special.ContainsKey(fullPinyin)) + { + return special[fullPinyin]; + } + } + + // zh, ch, sh + if (fullPinyin.Length >= 2 && first.ContainsKey(fullPinyin[..2])) + { + doublePin.Append(first[fullPinyin[..2]]); + + if (second.TryGetValue(fullPinyin[2..], out string tmp)) + { + doublePin.Append(tmp); + } + else + { + doublePin.Append(fullPinyin[2..]); + } + } + else + { + doublePin.Append(fullPinyin[0]); + + if (second.TryGetValue(fullPinyin[1..], out string tmp)) + { + doublePin.Append(tmp); + } + else + { + doublePin.Append(fullPinyin[1..]); + } + } + + return doublePin.ToString(); + } + } +} diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index 4588466652e..8d94cdba56a 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -185,6 +185,8 @@ public CustomBrowserViewModel CustomBrowser /// when false Alphabet static service will always return empty results /// public bool ShouldUsePinyin { get; set; } = false; + + public bool ShouldUseDoublePin { get; set; } = false; public bool AlwaysPreview { get; set; } = false; public bool AlwaysStartEn { get; set; } = false; From fb6635344b8e5ecae06aadd31a3b112471b48ae2 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sat, 18 Nov 2023 14:58:23 +0800 Subject: [PATCH 002/576] Test double pinyin --- Flow.Launcher/App.xaml.cs | 2 +- Flow.Launcher/PublicAPIInstance.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs index 765a1a5593a..d74ea62fb1b 100644 --- a/Flow.Launcher/App.xaml.cs +++ b/Flow.Launcher/App.xaml.cs @@ -30,7 +30,7 @@ public partial class App : IDisposable, ISingleInstanceApp private SettingWindowViewModel _settingsVM; private readonly Updater _updater = new Updater(Flow.Launcher.Properties.Settings.Default.GithubRepo); private readonly Portable _portable = new Portable(); - private readonly PinyinAlphabet _alphabet = new PinyinAlphabet(); + private readonly DoublePinAlphabet _alphabet = new DoublePinAlphabet(); private StringMatcher _stringMatcher; [STAThread] diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index b49bf39d3c5..952ce0edb9b 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -32,11 +32,11 @@ public class PublicAPIInstance : IPublicAPI { private readonly SettingWindowViewModel _settingsVM; private readonly MainViewModel _mainVM; - private readonly PinyinAlphabet _alphabet; + private readonly DoublePinAlphabet _alphabet; #region Constructor - public PublicAPIInstance(SettingWindowViewModel settingsVM, MainViewModel mainVM, PinyinAlphabet alphabet) + public PublicAPIInstance(SettingWindowViewModel settingsVM, MainViewModel mainVM, DoublePinAlphabet alphabet) { _settingsVM = settingsVM; _mainVM = mainVM; From f6ae71a99f838b2237c14c62c6daff5e97e6eec0 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sat, 18 Nov 2023 20:24:13 +0800 Subject: [PATCH 003/576] Only convert to double pinyin when meeting Chinese --- Flow.Launcher.Infrastructure/DoublePinAlphabet.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs b/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs index 607582097f9..e09046410aa 100644 --- a/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs +++ b/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs @@ -47,7 +47,7 @@ public bool CanBeTranslated(string stringToTranslate) { if (WordsHelper.HasChinese(content)) { - var resultList = WordsHelper.GetPinyinList(content).Select(ToDoublePin).ToArray(); + var resultList = WordsHelper.GetPinyinList(content); StringBuilder resultBuilder = new StringBuilder(); TranslationMapping map = new TranslationMapping(); @@ -57,9 +57,10 @@ public bool CanBeTranslated(string stringToTranslate) { if (content[i] >= 0x3400 && content[i] <= 0x9FD5) { - map.AddNewIndex(i, resultBuilder.Length, resultList[i].Length + 1); + string dp = ToDoublePin(resultList[i].ToLower()); + map.AddNewIndex(i, resultBuilder.Length, dp.Length + 1); resultBuilder.Append(' '); - resultBuilder.Append(resultList[i]); + resultBuilder.Append(dp); pre = true; } else From e5285b19921ae2cc49b6f55ebe5772a77f05cd54 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sun, 19 Nov 2023 12:30:17 +0800 Subject: [PATCH 004/576] Temp: compatibility with full pinyin option --- Flow.Launcher.Infrastructure/DoublePinAlphabet.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs b/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs index e09046410aa..e6930ad931a 100644 --- a/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs +++ b/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs @@ -29,7 +29,7 @@ public bool CanBeTranslated(string stringToTranslate) public (string translation, TranslationMapping map) Translate(string content) { - if (_settings.ShouldUseDoublePin) + if (_settings.ShouldUsePinyin) { if (!_doublePinCache.ContainsKey(content)) { @@ -57,7 +57,7 @@ public bool CanBeTranslated(string stringToTranslate) { if (content[i] >= 0x3400 && content[i] <= 0x9FD5) { - string dp = ToDoublePin(resultList[i].ToLower()); + string dp = _settings.ShouldUseDoublePin ? resultList[i] : ToDoublePin(resultList[i].ToLower()); map.AddNewIndex(i, resultBuilder.Length, dp.Length + 1); resultBuilder.Append(' '); resultBuilder.Append(dp); From 99ff3b2ec5c9a4d8b4f136735a866f52914c246e Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Mon, 20 Nov 2023 22:49:39 +0800 Subject: [PATCH 005/576] Fix wrong condition --- Flow.Launcher.Infrastructure/DoublePinAlphabet.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs b/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs index e6930ad931a..a1eb788d730 100644 --- a/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs +++ b/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs @@ -57,7 +57,7 @@ public bool CanBeTranslated(string stringToTranslate) { if (content[i] >= 0x3400 && content[i] <= 0x9FD5) { - string dp = _settings.ShouldUseDoublePin ? resultList[i] : ToDoublePin(resultList[i].ToLower()); + string dp = _settings.ShouldUseDoublePin ? ToDoublePin(resultList[i].ToLower()) : resultList[i]; map.AddNewIndex(i, resultBuilder.Length, dp.Length + 1); resultBuilder.Append(' '); resultBuilder.Append(dp); From 46d49d8fdf373e020481b111cbd23bf8ee09538d Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sat, 25 May 2024 15:02:37 +0800 Subject: [PATCH 006/576] Only translate when string is double pinyin --- Flow.Launcher.Infrastructure/DoublePinAlphabet.cs | 4 ++-- Flow.Launcher.Infrastructure/PinyinAlphabet.cs | 4 ++-- Flow.Launcher.Infrastructure/StringMatcher.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs b/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs index a1eb788d730..945f47a56b0 100644 --- a/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs +++ b/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs @@ -22,9 +22,9 @@ public void Initialize([NotNull] Settings settings) _settings = settings ?? throw new ArgumentNullException(nameof(settings)); } - public bool CanBeTranslated(string stringToTranslate) + public bool ShouldTranslate(string stringToTranslate) { - return WordsHelper.HasChinese(stringToTranslate); + return stringToTranslate.Length % 2 == 0 && !WordsHelper.HasChinese(stringToTranslate); } public (string translation, TranslationMapping map) Translate(string content) diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs index 7d72359684d..961af1d322f 100644 --- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs +++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs @@ -119,7 +119,7 @@ public interface IAlphabet /// /// String to translate. /// - public bool CanBeTranslated(string stringToTranslate); + public bool ShouldTranslate(string stringToTranslate); } public class PinyinAlphabet : IAlphabet @@ -134,7 +134,7 @@ public void Initialize([NotNull] Settings settings) _settings = settings ?? throw new ArgumentNullException(nameof(settings)); } - public bool CanBeTranslated(string stringToTranslate) + public bool ShouldTranslate(string stringToTranslate) { return WordsHelper.HasChinese(stringToTranslate); } diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs index bd5dbdda9be..4929e4cd2cf 100644 --- a/Flow.Launcher.Infrastructure/StringMatcher.cs +++ b/Flow.Launcher.Infrastructure/StringMatcher.cs @@ -61,7 +61,7 @@ public MatchResult FuzzyMatch(string query, string stringToCompare, MatchOption query = query.Trim(); TranslationMapping translationMapping = null; - if (_alphabet is not null && !_alphabet.CanBeTranslated(query)) + if (_alphabet is not null && _alphabet.ShouldTranslate(query)) { // We assume that if a query can be translated (containing characters of a language, like Chinese) // it actually means user doesn't want it to be translated to English letters. From b1cb852673005e955b1d4bd0bb2ed692e44308c9 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sun, 2 Jun 2024 14:18:57 +0800 Subject: [PATCH 007/576] Extract classes --- Flow.Launcher.Infrastructure/IAlphabet.cs | 22 ++++ .../PinyinAlphabet.cs | 113 ------------------ .../TranslationMapping.cs | 99 +++++++++++++++ 3 files changed, 121 insertions(+), 113 deletions(-) create mode 100644 Flow.Launcher.Infrastructure/IAlphabet.cs create mode 100644 Flow.Launcher.Infrastructure/TranslationMapping.cs diff --git a/Flow.Launcher.Infrastructure/IAlphabet.cs b/Flow.Launcher.Infrastructure/IAlphabet.cs new file mode 100644 index 00000000000..e79ec0c6d6f --- /dev/null +++ b/Flow.Launcher.Infrastructure/IAlphabet.cs @@ -0,0 +1,22 @@ +namespace Flow.Launcher.Infrastructure +{ + /// + /// Translate a language to English letters using a given rule. + /// + public interface IAlphabet + { + /// + /// Translate a string to English letters, using a given rule. + /// + /// String to translate. + /// + public (string translation, TranslationMapping map) Translate(string stringToTranslate); + + /// + /// Determine if a string can be translated to English letter with this Alphabet. + /// + /// String to translate. + /// + public bool ShouldTranslate(string stringToTranslate); + } +} diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs index 961af1d322f..d98d823d7b9 100644 --- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs +++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs @@ -9,119 +9,6 @@ namespace Flow.Launcher.Infrastructure { - public class TranslationMapping - { - private bool constructed; - - private List originalIndexs = new List(); - private List translatedIndexs = new List(); - private int translatedLength = 0; - - public string key { get; private set; } - - public void setKey(string key) - { - this.key = key; - } - - public void AddNewIndex(int originalIndex, int translatedIndex, int length) - { - if (constructed) - throw new InvalidOperationException("Mapping shouldn't be changed after constructed"); - - originalIndexs.Add(originalIndex); - translatedIndexs.Add(translatedIndex); - translatedIndexs.Add(translatedIndex + length); - translatedLength += length - 1; - } - - public int MapToOriginalIndex(int translatedIndex) - { - if (translatedIndex > translatedIndexs.Last()) - return translatedIndex - translatedLength - 1; - - int lowerBound = 0; - int upperBound = originalIndexs.Count - 1; - - int count = 0; - - // Corner case handle - if (translatedIndex < translatedIndexs[0]) - return translatedIndex; - if (translatedIndex > translatedIndexs.Last()) - { - int indexDef = 0; - for (int k = 0; k < originalIndexs.Count; k++) - { - indexDef += translatedIndexs[k * 2 + 1] - translatedIndexs[k * 2]; - } - - return translatedIndex - indexDef - 1; - } - - // Binary Search with Range - for (int i = originalIndexs.Count / 2;; count++) - { - if (translatedIndex < translatedIndexs[i * 2]) - { - // move to lower middle - upperBound = i; - i = (i + lowerBound) / 2; - } - else if (translatedIndex > translatedIndexs[i * 2 + 1] - 1) - { - lowerBound = i; - // move to upper middle - // due to floor of integer division, move one up on corner case - i = (i + upperBound + 1) / 2; - } - else - return originalIndexs[i]; - - if (upperBound - lowerBound <= 1 && - translatedIndex > translatedIndexs[lowerBound * 2 + 1] && - translatedIndex < translatedIndexs[upperBound * 2]) - { - int indexDef = 0; - - for (int j = 0; j < upperBound; j++) - { - indexDef += translatedIndexs[j * 2 + 1] - translatedIndexs[j * 2]; - } - - return translatedIndex - indexDef - 1; - } - } - } - - public void endConstruct() - { - if (constructed) - throw new InvalidOperationException("Mapping has already been constructed"); - constructed = true; - } - } - - /// - /// Translate a language to English letters using a given rule. - /// - public interface IAlphabet - { - /// - /// Translate a string to English letters, using a given rule. - /// - /// String to translate. - /// - public (string translation, TranslationMapping map) Translate(string stringToTranslate); - - /// - /// Determine if a string can be translated to English letter with this Alphabet. - /// - /// String to translate. - /// - public bool ShouldTranslate(string stringToTranslate); - } - public class PinyinAlphabet : IAlphabet { private ConcurrentDictionary _pinyinCache = diff --git a/Flow.Launcher.Infrastructure/TranslationMapping.cs b/Flow.Launcher.Infrastructure/TranslationMapping.cs new file mode 100644 index 00000000000..f288c816a64 --- /dev/null +++ b/Flow.Launcher.Infrastructure/TranslationMapping.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Flow.Launcher.Infrastructure +{ + public class TranslationMapping + { + private bool constructed; + + private List originalIndexs = new List(); + private List translatedIndexs = new List(); + private int translatedLength = 0; + + public string key { get; private set; } + + public void setKey(string key) + { + this.key = key; + } + + public void AddNewIndex(int originalIndex, int translatedIndex, int length) + { + if (constructed) + throw new InvalidOperationException("Mapping shouldn't be changed after constructed"); + + originalIndexs.Add(originalIndex); + translatedIndexs.Add(translatedIndex); + translatedIndexs.Add(translatedIndex + length); + translatedLength += length - 1; + } + + public int MapToOriginalIndex(int translatedIndex) + { + if (translatedIndex > translatedIndexs.Last()) + return translatedIndex - translatedLength - 1; + + int lowerBound = 0; + int upperBound = originalIndexs.Count - 1; + + int count = 0; + + // Corner case handle + if (translatedIndex < translatedIndexs[0]) + return translatedIndex; + if (translatedIndex > translatedIndexs.Last()) + { + int indexDef = 0; + for (int k = 0; k < originalIndexs.Count; k++) + { + indexDef += translatedIndexs[k * 2 + 1] - translatedIndexs[k * 2]; + } + + return translatedIndex - indexDef - 1; + } + + // Binary Search with Range + for (int i = originalIndexs.Count / 2;; count++) + { + if (translatedIndex < translatedIndexs[i * 2]) + { + // move to lower middle + upperBound = i; + i = (i + lowerBound) / 2; + } + else if (translatedIndex > translatedIndexs[i * 2 + 1] - 1) + { + lowerBound = i; + // move to upper middle + // due to floor of integer division, move one up on corner case + i = (i + upperBound + 1) / 2; + } + else + return originalIndexs[i]; + + if (upperBound - lowerBound <= 1 && + translatedIndex > translatedIndexs[lowerBound * 2 + 1] && + translatedIndex < translatedIndexs[upperBound * 2]) + { + int indexDef = 0; + + for (int j = 0; j < upperBound; j++) + { + indexDef += translatedIndexs[j * 2 + 1] - translatedIndexs[j * 2]; + } + + return translatedIndex - indexDef - 1; + } + } + } + + public void endConstruct() + { + if (constructed) + throw new InvalidOperationException("Mapping has already been constructed"); + constructed = true; + } + } +} From 6807afbe6d753eed6984e1b1ab6019e2864767cd Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sun, 2 Jun 2024 14:03:00 +0800 Subject: [PATCH 008/576] Remove unused alphabet arg in PublicAPIInstance --- Flow.Launcher/App.xaml.cs | 2 +- Flow.Launcher/PublicAPIInstance.cs | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs index d74ea62fb1b..560bb052b19 100644 --- a/Flow.Launcher/App.xaml.cs +++ b/Flow.Launcher/App.xaml.cs @@ -74,7 +74,7 @@ await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () => PluginManager.LoadPlugins(_settings.PluginSettings); _mainVM = new MainViewModel(_settings); - API = new PublicAPIInstance(_settingsVM, _mainVM, _alphabet); + API = new PublicAPIInstance(_settingsVM, _mainVM); Http.API = API; Http.Proxy = _settings.Proxy; diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index 952ce0edb9b..e14d692cd65 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -32,15 +32,13 @@ public class PublicAPIInstance : IPublicAPI { private readonly SettingWindowViewModel _settingsVM; private readonly MainViewModel _mainVM; - private readonly DoublePinAlphabet _alphabet; #region Constructor - public PublicAPIInstance(SettingWindowViewModel settingsVM, MainViewModel mainVM, DoublePinAlphabet alphabet) + public PublicAPIInstance(SettingWindowViewModel settingsVM, MainViewModel mainVM) { _settingsVM = settingsVM; _mainVM = mainVM; - _alphabet = alphabet; GlobalHotkey.hookedKeyboardCallback = KListener_hookedKeyboardCallback; WebRequest.RegisterPrefix("data", new DataWebRequestFactory()); } From a2efa11699fed4b3aac21bdff26555ce57b274aa Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sun, 2 Jun 2024 14:19:27 +0800 Subject: [PATCH 009/576] Merge DoublePinAlphabet logic --- .../DoublePinAlphabet.cs | 194 ------------------ .../PinyinAlphabet.cs | 127 +++++++++++- .../UserSettings/Settings.cs | 3 +- Flow.Launcher/App.xaml.cs | 2 +- 4 files changed, 121 insertions(+), 205 deletions(-) delete mode 100644 Flow.Launcher.Infrastructure/DoublePinAlphabet.cs diff --git a/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs b/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs deleted file mode 100644 index 945f47a56b0..00000000000 --- a/Flow.Launcher.Infrastructure/DoublePinAlphabet.cs +++ /dev/null @@ -1,194 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Text; -using Flow.Launcher.Infrastructure.UserSettings; -using ToolGood.Words.Pinyin; - -namespace Flow.Launcher.Infrastructure -{ - public class DoublePinAlphabet : IAlphabet - { - private ConcurrentDictionary _doublePinCache = - new ConcurrentDictionary(); - - private Settings _settings; - - public void Initialize([NotNull] Settings settings) - { - _settings = settings ?? throw new ArgumentNullException(nameof(settings)); - } - - public bool ShouldTranslate(string stringToTranslate) - { - return stringToTranslate.Length % 2 == 0 && !WordsHelper.HasChinese(stringToTranslate); - } - - public (string translation, TranslationMapping map) Translate(string content) - { - if (_settings.ShouldUsePinyin) - { - if (!_doublePinCache.ContainsKey(content)) - { - return BuildCacheFromContent(content); - } - else - { - return _doublePinCache[content]; - } - } - return (content, null); - } - - private (string translation, TranslationMapping map) BuildCacheFromContent(string content) - { - if (WordsHelper.HasChinese(content)) - { - var resultList = WordsHelper.GetPinyinList(content); - StringBuilder resultBuilder = new StringBuilder(); - TranslationMapping map = new TranslationMapping(); - - bool pre = false; - - for (int i = 0; i < resultList.Length; i++) - { - if (content[i] >= 0x3400 && content[i] <= 0x9FD5) - { - string dp = _settings.ShouldUseDoublePin ? ToDoublePin(resultList[i].ToLower()) : resultList[i]; - map.AddNewIndex(i, resultBuilder.Length, dp.Length + 1); - resultBuilder.Append(' '); - resultBuilder.Append(dp); - pre = true; - } - else - { - if (pre) - { - pre = false; - resultBuilder.Append(' '); - } - - resultBuilder.Append(resultList[i]); - } - } - - map.endConstruct(); - - var key = resultBuilder.ToString(); - map.setKey(key); - - return _doublePinCache[content] = (key, map); - } - else - { - return (content, null); - } - } - - private static readonly ReadOnlyDictionary special = new(new Dictionary(){ - {"a", "aa"}, - {"ai", "ai"}, - {"an", "an"}, - {"ang", "ah"}, - {"ao", "ao"}, - {"e", "ee"}, - {"ei", "ei"}, - {"en", "en"}, - {"er", "er"}, - {"o", "oo"}, - {"ou", "ou"} - }); - - - private static readonly ReadOnlyDictionary first = new(new Dictionary(){ - {"ch", "i"}, - {"sh", "u"}, - {"zh", "v"} - }); - - - private static readonly ReadOnlyDictionary second = new(new Dictionary() - { - {"ua", "x"}, - {"ei", "w"}, - {"e", "e"}, - {"ou", "z"}, - {"iu", "q"}, - {"ve", "t"}, - {"ue", "t"}, - {"u", "u"}, - {"i", "i"}, - {"o", "o"}, - {"uo", "o"}, - {"ie", "p"}, - {"a", "a"}, - {"ong", "s"}, - {"iong", "s"}, - {"ai", "d"}, - {"ing", "k"}, - {"uai", "k"}, - {"ang", "h"}, - {"uan", "r"}, - {"an", "j"}, - {"en", "f"}, - {"ia", "x"}, - {"iang", "l"}, - {"uang", "l"}, - {"eng", "g"}, - {"in", "b"}, - {"ao", "c"}, - {"v", "v"}, - {"ui", "v"}, - {"un", "y"}, - {"iao", "n"}, - {"ian", "m"} - }); - - private static string ToDoublePin(string fullPinyin) - { - // Assuming s is valid - StringBuilder doublePin = new StringBuilder(); - - if (fullPinyin.Length <= 3 && (fullPinyin[0] == 'a' || fullPinyin[0] == 'e' || fullPinyin[0] == 'o')) - { - if (special.ContainsKey(fullPinyin)) - { - return special[fullPinyin]; - } - } - - // zh, ch, sh - if (fullPinyin.Length >= 2 && first.ContainsKey(fullPinyin[..2])) - { - doublePin.Append(first[fullPinyin[..2]]); - - if (second.TryGetValue(fullPinyin[2..], out string tmp)) - { - doublePin.Append(tmp); - } - else - { - doublePin.Append(fullPinyin[2..]); - } - } - else - { - doublePin.Append(fullPinyin[0]); - - if (second.TryGetValue(fullPinyin[1..], out string tmp)) - { - doublePin.Append(tmp); - } - else - { - doublePin.Append(fullPinyin[1..]); - } - } - - return doublePin.ToString(); - } - } -} diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs index d98d823d7b9..37e4f93d292 100644 --- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs +++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs @@ -1,18 +1,18 @@ using System; using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; using System.Text; using JetBrains.Annotations; using Flow.Launcher.Infrastructure.UserSettings; using ToolGood.Words.Pinyin; +using System.Collections.Generic; +using System.Collections.ObjectModel; namespace Flow.Launcher.Infrastructure { public class PinyinAlphabet : IAlphabet { - private ConcurrentDictionary _pinyinCache = - new ConcurrentDictionary(); + private readonly ConcurrentDictionary _pinyinCache = + new(); private Settings _settings; @@ -23,20 +23,22 @@ public void Initialize([NotNull] Settings settings) public bool ShouldTranslate(string stringToTranslate) { - return WordsHelper.HasChinese(stringToTranslate); + return _settings.UseDoublePinyin ? + (WordsHelper.HasChinese(stringToTranslate) && stringToTranslate.Length % 2 == 0) : + WordsHelper.HasChinese(stringToTranslate); } public (string translation, TranslationMapping map) Translate(string content) { if (_settings.ShouldUsePinyin) { - if (!_pinyinCache.ContainsKey(content)) + if (!_pinyinCache.TryGetValue(content, out var value)) { return BuildCacheFromContent(content); } else { - return _pinyinCache[content]; + return value; } } return (content, null); @@ -57,9 +59,10 @@ public bool ShouldTranslate(string stringToTranslate) { if (content[i] >= 0x3400 && content[i] <= 0x9FD5) { - map.AddNewIndex(i, resultBuilder.Length, resultList[i].Length + 1); + string dp = _settings.UseDoublePinyin ? ToDoublePin(resultList[i].ToLower()) : resultList[i]; + map.AddNewIndex(i, resultBuilder.Length, dp.Length + 1); resultBuilder.Append(' '); - resultBuilder.Append(resultList[i]); + resultBuilder.Append(dp); pre = true; } else @@ -86,5 +89,111 @@ public bool ShouldTranslate(string stringToTranslate) return (content, null); } } + + #region Double Pinyin + + private static readonly ReadOnlyDictionary special = new(new Dictionary(){ + {"a", "aa"}, + {"ai", "ai"}, + {"an", "an"}, + {"ang", "ah"}, + {"ao", "ao"}, + {"e", "ee"}, + {"ei", "ei"}, + {"en", "en"}, + {"er", "er"}, + {"o", "oo"}, + {"ou", "ou"} + }); + + + private static readonly ReadOnlyDictionary first = new(new Dictionary(){ + {"ch", "i"}, + {"sh", "u"}, + {"zh", "v"} + }); + + + private static readonly ReadOnlyDictionary second = new(new Dictionary() + { + {"ua", "x"}, + {"ei", "w"}, + {"e", "e"}, + {"ou", "z"}, + {"iu", "q"}, + {"ve", "t"}, + {"ue", "t"}, + {"u", "u"}, + {"i", "i"}, + {"o", "o"}, + {"uo", "o"}, + {"ie", "p"}, + {"a", "a"}, + {"ong", "s"}, + {"iong", "s"}, + {"ai", "d"}, + {"ing", "k"}, + {"uai", "k"}, + {"ang", "h"}, + {"uan", "r"}, + {"an", "j"}, + {"en", "f"}, + {"ia", "x"}, + {"iang", "l"}, + {"uang", "l"}, + {"eng", "g"}, + {"in", "b"}, + {"ao", "c"}, + {"v", "v"}, + {"ui", "v"}, + {"un", "y"}, + {"iao", "n"}, + {"ian", "m"} + }); + + private static string ToDoublePin(string fullPinyin) + { + // Assuming s is valid + StringBuilder doublePin = new StringBuilder(); + + if (fullPinyin.Length <= 3 && (fullPinyin[0] == 'a' || fullPinyin[0] == 'e' || fullPinyin[0] == 'o')) + { + if (special.TryGetValue(fullPinyin, out var value)) + { + return value; + } + } + + // zh, ch, sh + if (fullPinyin.Length >= 2 && first.ContainsKey(fullPinyin[..2])) + { + doublePin.Append(first[fullPinyin[..2]]); + + if (second.TryGetValue(fullPinyin[2..], out string tmp)) + { + doublePin.Append(tmp); + } + else + { + doublePin.Append(fullPinyin[2..]); + } + } + else + { + doublePin.Append(fullPinyin[0]); + + if (second.TryGetValue(fullPinyin[1..], out string tmp)) + { + doublePin.Append(tmp); + } + else + { + doublePin.Append(fullPinyin[1..]); + } + } + + return doublePin.ToString(); + } + #endregion } } diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index 8d94cdba56a..e79c3f52d4d 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -186,7 +186,8 @@ public CustomBrowserViewModel CustomBrowser /// public bool ShouldUsePinyin { get; set; } = false; - public bool ShouldUseDoublePin { get; set; } = false; + public bool UseDoublePinyin { get; set; } = false; + public bool AlwaysPreview { get; set; } = false; public bool AlwaysStartEn { get; set; } = false; diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs index 560bb052b19..83870837a0b 100644 --- a/Flow.Launcher/App.xaml.cs +++ b/Flow.Launcher/App.xaml.cs @@ -30,7 +30,7 @@ public partial class App : IDisposable, ISingleInstanceApp private SettingWindowViewModel _settingsVM; private readonly Updater _updater = new Updater(Flow.Launcher.Properties.Settings.Default.GithubRepo); private readonly Portable _portable = new Portable(); - private readonly DoublePinAlphabet _alphabet = new DoublePinAlphabet(); + private readonly PinyinAlphabet _alphabet = new PinyinAlphabet(); private StringMatcher _stringMatcher; [STAThread] From 12c4e37a95df44fc968a6459e7a3cbf6de4063e6 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sun, 2 Jun 2024 14:33:49 +0800 Subject: [PATCH 010/576] Developing --- Flow.Launcher.Infrastructure/UserSettings/Settings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index e79c3f52d4d..30e3b77beee 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -186,7 +186,7 @@ public CustomBrowserViewModel CustomBrowser /// public bool ShouldUsePinyin { get; set; } = false; - public bool UseDoublePinyin { get; set; } = false; + public bool UseDoublePinyin { get; set; } = true; //For developing public bool AlwaysPreview { get; set; } = false; public bool AlwaysStartEn { get; set; } = false; From f673000d67e4ff1180e6d2856bf85f1640433a7c Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sun, 2 Jun 2024 14:37:15 +0800 Subject: [PATCH 011/576] Fix ShouldTranslate() --- Flow.Launcher.Infrastructure/PinyinAlphabet.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs index 37e4f93d292..b48a6109042 100644 --- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs +++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs @@ -23,9 +23,9 @@ public void Initialize([NotNull] Settings settings) public bool ShouldTranslate(string stringToTranslate) { - return _settings.UseDoublePinyin ? - (WordsHelper.HasChinese(stringToTranslate) && stringToTranslate.Length % 2 == 0) : - WordsHelper.HasChinese(stringToTranslate); + return _settings.UseDoublePinyin ? + (!WordsHelper.HasChinese(stringToTranslate) && stringToTranslate.Length % 2 == 0) : + !WordsHelper.HasChinese(stringToTranslate); } public (string translation, TranslationMapping map) Translate(string content) From b10a6e19df5afcbd13ca612f6e6952f19a3b9dde Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sun, 2 Jun 2024 15:18:24 +0800 Subject: [PATCH 012/576] Capitalize first letter --- .../PinyinAlphabet.cs | 84 +++++++++---------- 1 file changed, 41 insertions(+), 43 deletions(-) diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs index b48a6109042..cbec7feae04 100644 --- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs +++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs @@ -46,71 +46,69 @@ public bool ShouldTranslate(string stringToTranslate) private (string translation, TranslationMapping map) BuildCacheFromContent(string content) { - if (WordsHelper.HasChinese(content)) + if (!WordsHelper.HasChinese(content)) { - var resultList = WordsHelper.GetPinyinList(content); + return (content, null); + } - StringBuilder resultBuilder = new StringBuilder(); - TranslationMapping map = new TranslationMapping(); + var resultList = WordsHelper.GetPinyinList(content); - bool pre = false; + StringBuilder resultBuilder = new StringBuilder(); + TranslationMapping map = new TranslationMapping(); - for (int i = 0; i < resultList.Length; i++) + bool pre = false; + + for (int i = 0; i < resultList.Length; i++) + { + if (content[i] >= 0x3400 && content[i] <= 0x9FD5) { - if (content[i] >= 0x3400 && content[i] <= 0x9FD5) + string dp = _settings.UseDoublePinyin ? ToDoublePin(resultList[i]) : resultList[i]; + map.AddNewIndex(i, resultBuilder.Length, dp.Length + 1); + resultBuilder.Append(' '); + resultBuilder.Append(dp); + pre = true; + } + else + { + if (pre) { - string dp = _settings.UseDoublePinyin ? ToDoublePin(resultList[i].ToLower()) : resultList[i]; - map.AddNewIndex(i, resultBuilder.Length, dp.Length + 1); + pre = false; resultBuilder.Append(' '); - resultBuilder.Append(dp); - pre = true; } - else - { - if (pre) - { - pre = false; - resultBuilder.Append(' '); - } - resultBuilder.Append(resultList[i]); - } + resultBuilder.Append(resultList[i]); } + } - map.endConstruct(); + map.endConstruct(); - var key = resultBuilder.ToString(); - map.setKey(key); + var key = resultBuilder.ToString(); + map.setKey(key); - return _pinyinCache[content] = (key, map); - } - else - { - return (content, null); - } + return _pinyinCache[content] = (key, map); } #region Double Pinyin private static readonly ReadOnlyDictionary special = new(new Dictionary(){ - {"a", "aa"}, - {"ai", "ai"}, - {"an", "an"}, - {"ang", "ah"}, - {"ao", "ao"}, - {"e", "ee"}, - {"ei", "ei"}, - {"en", "en"}, - {"er", "er"}, - {"o", "oo"}, - {"ou", "ou"} + {"A", "aa"}, + {"Ai", "ai"}, + {"An", "an"}, + {"Ang", "ah"}, + {"Ao", "ao"}, + {"E", "ee"}, + {"Ei", "ei"}, + {"En", "en"}, + {"Er", "er"}, + {"O", "oo"}, + {"Ou", "ou"} }); private static readonly ReadOnlyDictionary first = new(new Dictionary(){ - {"ch", "i"}, - {"sh", "u"}, - {"zh", "v"} + {"Ch", "i"}, + {"Sh", "u"}, + {"Zh", "v"} }); From b816d1b866aa93b6d8f2da9f5cef334bda64748b Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sun, 2 Jun 2024 15:21:04 +0800 Subject: [PATCH 013/576] Remove unused key in pinyin alphabet --- Flow.Launcher.Infrastructure/PinyinAlphabet.cs | 1 - Flow.Launcher.Infrastructure/TranslationMapping.cs | 7 ------- 2 files changed, 8 deletions(-) diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs index cbec7feae04..10799c676f1 100644 --- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs +++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs @@ -83,7 +83,6 @@ public bool ShouldTranslate(string stringToTranslate) map.endConstruct(); var key = resultBuilder.ToString(); - map.setKey(key); return _pinyinCache[content] = (key, map); } diff --git a/Flow.Launcher.Infrastructure/TranslationMapping.cs b/Flow.Launcher.Infrastructure/TranslationMapping.cs index f288c816a64..c976fc522d6 100644 --- a/Flow.Launcher.Infrastructure/TranslationMapping.cs +++ b/Flow.Launcher.Infrastructure/TranslationMapping.cs @@ -12,13 +12,6 @@ public class TranslationMapping private List translatedIndexs = new List(); private int translatedLength = 0; - public string key { get; private set; } - - public void setKey(string key) - { - this.key = key; - } - public void AddNewIndex(int originalIndex, int translatedIndex, int length) { if (constructed) From dd29b4ad4419aad72c58f0dac10f4f4a2e7e530b Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sat, 22 Jun 2024 19:31:47 -0500 Subject: [PATCH 014/576] velopack prepare --- Flow.Launcher.Core/Flow.Launcher.Core.csproj | 1 + Flow.Launcher.Core/Updater.cs | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Flow.Launcher.Core/Flow.Launcher.Core.csproj b/Flow.Launcher.Core/Flow.Launcher.Core.csproj index fe2cb7e58e2..a141243b7ac 100644 --- a/Flow.Launcher.Core/Flow.Launcher.Core.csproj +++ b/Flow.Launcher.Core/Flow.Launcher.Core.csproj @@ -57,6 +57,7 @@ + diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs index 3f64b273e4c..df2b2dae73b 100644 --- a/Flow.Launcher.Core/Updater.cs +++ b/Flow.Launcher.Core/Updater.cs @@ -45,8 +45,8 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true) // UpdateApp CheckForUpdate will return value only if the app is squirrel installed var newUpdateInfo = await updateManager.CheckForUpdate().NonNull().ConfigureAwait(false); - var newReleaseVersion = Version.Parse(newUpdateInfo.FutureReleaseEntry.Version.ToString()); - var currentVersion = Version.Parse(Constant.Version); + var newReleaseVersion = SemanticVersioning.Version.Parse(newUpdateInfo.FutureReleaseEntry.Version.ToString()); + var currentVersion = SemanticVersioning.Version.Parse(Constant.Version); Log.Info($"|Updater.UpdateApp|Future Release <{newUpdateInfo.FutureReleaseEntry.Formatted()}>"); @@ -127,7 +127,7 @@ private async Task GitHubUpdateManagerAsync(string repository) await using var jsonStream = await Http.GetStreamAsync(api).ConfigureAwait(false); var releases = await System.Text.Json.JsonSerializer.DeserializeAsync>(jsonStream).ConfigureAwait(false); - var latest = releases.Where(r => !r.Prerelease).OrderByDescending(r => r.PublishedAt).First(); + var latest = releases.OrderByDescending(r => r.PublishedAt).First(); var latestUrl = latest.HtmlUrl.Replace("/tag/", "/download/"); var client = new WebClient From 865c865942a0c24efb31c1fbb36f6c4eca45db03 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Wed, 26 Feb 2025 22:37:41 +0800 Subject: [PATCH 015/576] update to .net 9 --- Flow.Launcher.Core/Flow.Launcher.Core.csproj | 2 +- .../Flow.Launcher.Infrastructure.csproj | 2 +- .../Flow.Launcher.Plugin.csproj | 2 +- Flow.Launcher.Test/Flow.Launcher.Test.csproj | 2 +- Flow.Launcher/Flow.Launcher.csproj | 3 +-- .../Net7.0-SelfContained.pubxml | 18 ------------------ ...Flow.Launcher.Plugin.BrowserBookmark.csproj | 2 +- .../Flow.Launcher.Plugin.Calculator.csproj | 2 +- .../Flow.Launcher.Plugin.Explorer.csproj | 2 +- ...Flow.Launcher.Plugin.PluginIndicator.csproj | 2 +- .../Flow.Launcher.Plugin.PluginsManager.csproj | 2 +- .../Flow.Launcher.Plugin.ProcessKiller.csproj | 2 +- .../Flow.Launcher.Plugin.Program.csproj | 2 +- .../Flow.Launcher.Plugin.Shell.csproj | 2 +- .../Flow.Launcher.Plugin.Sys.csproj | 2 +- .../Flow.Launcher.Plugin.Url.csproj | 2 +- .../Flow.Launcher.Plugin.WebSearch.csproj | 2 +- ...Flow.Launcher.Plugin.WindowsSettings.csproj | 2 +- README.md | 4 ++-- Scripts/flowlauncher.nuspec | 2 +- Scripts/post_build.ps1 | 2 +- 21 files changed, 21 insertions(+), 40 deletions(-) delete mode 100644 Flow.Launcher/Properties/PublishProfiles/Net7.0-SelfContained.pubxml diff --git a/Flow.Launcher.Core/Flow.Launcher.Core.csproj b/Flow.Launcher.Core/Flow.Launcher.Core.csproj index df2f4d2cbf0..8997ff58cc6 100644 --- a/Flow.Launcher.Core/Flow.Launcher.Core.csproj +++ b/Flow.Launcher.Core/Flow.Launcher.Core.csproj @@ -1,7 +1,7 @@ - net7.0-windows + net9.0-windows true true Library diff --git a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj index 5d8b264251a..ed753b76780 100644 --- a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj +++ b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj @@ -1,7 +1,7 @@ - net7.0-windows + net9.0-windows {4FD29318-A8AB-4D8F-AA47-60BC241B8DA3} Library true diff --git a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj index 2feb21b12aa..05c780cd8d4 100644 --- a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj +++ b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj @@ -1,7 +1,7 @@ - net7.0-windows + net9.0-windows {8451ECDD-2EA4-4966-BB0A-7BBC40138E80} true Library diff --git a/Flow.Launcher.Test/Flow.Launcher.Test.csproj b/Flow.Launcher.Test/Flow.Launcher.Test.csproj index 0241a374e41..f04a9dcc94f 100644 --- a/Flow.Launcher.Test/Flow.Launcher.Test.csproj +++ b/Flow.Launcher.Test/Flow.Launcher.Test.csproj @@ -1,7 +1,7 @@ - net7.0-windows10.0.19041.0 + net9.0-windows10.0.19041.0 {FF742965-9A80-41A5-B042-D6C7D3A21708} Library Properties diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj index 0baa1bef503..ef8bd8a3adc 100644 --- a/Flow.Launcher/Flow.Launcher.csproj +++ b/Flow.Launcher/Flow.Launcher.csproj @@ -2,7 +2,7 @@ WinExe - net7.0-windows10.0.19041.0 + net9.0-windows10.0.19041.0 true false Flow.Launcher.App @@ -90,7 +90,6 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - diff --git a/Flow.Launcher/Properties/PublishProfiles/Net7.0-SelfContained.pubxml b/Flow.Launcher/Properties/PublishProfiles/Net7.0-SelfContained.pubxml deleted file mode 100644 index 0e5cf4489b2..00000000000 --- a/Flow.Launcher/Properties/PublishProfiles/Net7.0-SelfContained.pubxml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - FileSystem - Release - Any CPU - net7.0-windows10.0.19041.0 - ..\Output\Release\ - win-x64 - true - False - False - False - - diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj index d7a626e1d5d..de6c017f29a 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj @@ -2,7 +2,7 @@ Library - net7.0-windows + net9.0-windows true {9B130CC5-14FB-41FF-B310-0A95B6894C37} Properties diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj b/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj index 1b985acf9b1..0c2a08bf3f9 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj @@ -2,7 +2,7 @@ Library - net7.0-windows + net9.0-windows {59BD9891-3837-438A-958D-ADC7F91F6F7E} Properties Flow.Launcher.Plugin.Calculator diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj index 29925aeef9f..7a5809ad7a6 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj @@ -2,7 +2,7 @@ Library - net7.0-windows + net9.0-windows true true true diff --git a/Plugins/Flow.Launcher.Plugin.PluginIndicator/Flow.Launcher.Plugin.PluginIndicator.csproj b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Flow.Launcher.Plugin.PluginIndicator.csproj index 21d964c1126..d9e434f95d7 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginIndicator/Flow.Launcher.Plugin.PluginIndicator.csproj +++ b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Flow.Launcher.Plugin.PluginIndicator.csproj @@ -2,7 +2,7 @@ Library - net7.0-windows + net9.0-windows {FDED22C8-B637-42E8-824A-63B5B6E05A3A} Properties Flow.Launcher.Plugin.PluginIndicator diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Flow.Launcher.Plugin.PluginsManager.csproj b/Plugins/Flow.Launcher.Plugin.PluginsManager/Flow.Launcher.Plugin.PluginsManager.csproj index b438305d627..b9c181fa33a 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Flow.Launcher.Plugin.PluginsManager.csproj +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Flow.Launcher.Plugin.PluginsManager.csproj @@ -1,7 +1,7 @@  Library - net7.0-windows + net9.0-windows true true true diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Flow.Launcher.Plugin.ProcessKiller.csproj b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Flow.Launcher.Plugin.ProcessKiller.csproj index 4e216b7b26a..7394e8a1190 100644 --- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Flow.Launcher.Plugin.ProcessKiller.csproj +++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Flow.Launcher.Plugin.ProcessKiller.csproj @@ -2,7 +2,7 @@ Library - net7.0-windows + net9.0-windows Flow.Launcher.Plugin.ProcessKiller Flow.Launcher.Plugin.ProcessKiller Flow-Launcher diff --git a/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj b/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj index 99c1a12e9b3..0c45a8590e2 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj +++ b/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj @@ -2,7 +2,7 @@ Library - net7.0-windows10.0.19041.0 + net9.0-windows10.0.19041.0 {FDB3555B-58EF-4AE6-B5F1-904719637AB4} Properties Flow.Launcher.Plugin.Program diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Flow.Launcher.Plugin.Shell.csproj b/Plugins/Flow.Launcher.Plugin.Shell/Flow.Launcher.Plugin.Shell.csproj index 8f443214bba..89410b7c91f 100644 --- a/Plugins/Flow.Launcher.Plugin.Shell/Flow.Launcher.Plugin.Shell.csproj +++ b/Plugins/Flow.Launcher.Plugin.Shell/Flow.Launcher.Plugin.Shell.csproj @@ -2,7 +2,7 @@ Library - net7.0-windows + net9.0-windows {C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0} Properties Flow.Launcher.Plugin.Shell diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj b/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj index dbc36ad424b..999003fd835 100644 --- a/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj +++ b/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj @@ -2,7 +2,7 @@ Library - net7.0-windows + net9.0-windows {0B9DE348-9361-4940-ADB6-F5953BFFCCEC} Properties Flow.Launcher.Plugin.Sys diff --git a/Plugins/Flow.Launcher.Plugin.Url/Flow.Launcher.Plugin.Url.csproj b/Plugins/Flow.Launcher.Plugin.Url/Flow.Launcher.Plugin.Url.csproj index 6d338733e31..fdfe03224c1 100644 --- a/Plugins/Flow.Launcher.Plugin.Url/Flow.Launcher.Plugin.Url.csproj +++ b/Plugins/Flow.Launcher.Plugin.Url/Flow.Launcher.Plugin.Url.csproj @@ -2,7 +2,7 @@ Library - net7.0-windows + net9.0-windows {A3DCCBCA-ACC1-421D-B16E-210896234C26} true Properties diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Flow.Launcher.Plugin.WebSearch.csproj b/Plugins/Flow.Launcher.Plugin.WebSearch/Flow.Launcher.Plugin.WebSearch.csproj index 55d69d5260c..3850cd3d2f0 100644 --- a/Plugins/Flow.Launcher.Plugin.WebSearch/Flow.Launcher.Plugin.WebSearch.csproj +++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Flow.Launcher.Plugin.WebSearch.csproj @@ -2,7 +2,7 @@ Library - net7.0-windows + net9.0-windows {403B57F2-1856-4FC7-8A24-36AB346B763E} Properties true diff --git a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Flow.Launcher.Plugin.WindowsSettings.csproj b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Flow.Launcher.Plugin.WindowsSettings.csproj index 73fcd9f83eb..879cea6f8c7 100644 --- a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Flow.Launcher.Plugin.WindowsSettings.csproj +++ b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Flow.Launcher.Plugin.WindowsSettings.csproj @@ -1,7 +1,7 @@  Library - net7.0-windows + net9.0-windows true true false diff --git a/README.md b/README.md index 02ffc79328a..2b307e09a25 100644 --- a/README.md +++ b/README.md @@ -391,7 +391,7 @@ Get in touch if you like to join the Flow-Launcher Team and help build this grea - Install Visual Studio 2022 -- Install .Net 7 SDK +- Install .Net 9 SDK - via Visual Studio installer - via winget `winget install Microsoft.DotNet.SDK.7` - - Manually from [here](https://dotnet.microsoft.com/en-us/download/dotnet/7.0) + - Manually from [here](https://dotnet.microsoft.com/en-us/download/dotnet/9.0) diff --git a/Scripts/flowlauncher.nuspec b/Scripts/flowlauncher.nuspec index 8d753bc8c83..fa12150cc7c 100644 --- a/Scripts/flowlauncher.nuspec +++ b/Scripts/flowlauncher.nuspec @@ -11,6 +11,6 @@ Flow Launcher - Quick file search and app launcher for Windows with community-made plugins - + diff --git a/Scripts/post_build.ps1 b/Scripts/post_build.ps1 index 1757ed99e22..da5672e325d 100644 --- a/Scripts/post_build.ps1 +++ b/Scripts/post_build.ps1 @@ -99,7 +99,7 @@ function Pack-Squirrel-Installer ($path, $version, $output) { function Publish-Self-Contained ($p) { $csproj = Join-Path "$p" "Flow.Launcher/Flow.Launcher.csproj" -Resolve - $profile = Join-Path "$p" "Flow.Launcher/Properties/PublishProfiles/Net7.0-SelfContained.pubxml" -Resolve + $profile = Join-Path "$p" "Flow.Launcher/Properties/PublishProfiles/net9.0-SelfContained.pubxml" -Resolve # we call dotnet publish on the main project. # The other projects should have been built in Release at this point. From bfa1c91d339518b40c14a24c7f18f3b0c1128176 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Wed, 26 Feb 2025 22:46:08 +0800 Subject: [PATCH 016/576] fix typo --- Scripts/post_build.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/post_build.ps1 b/Scripts/post_build.ps1 index da5672e325d..a76f8258e16 100644 --- a/Scripts/post_build.ps1 +++ b/Scripts/post_build.ps1 @@ -99,7 +99,7 @@ function Pack-Squirrel-Installer ($path, $version, $output) { function Publish-Self-Contained ($p) { $csproj = Join-Path "$p" "Flow.Launcher/Flow.Launcher.csproj" -Resolve - $profile = Join-Path "$p" "Flow.Launcher/Properties/PublishProfiles/net9.0-SelfContained.pubxml" -Resolve + $profile = Join-Path "$p" "Flow.Launcher/Properties/PublishProfiles/Net9.0-SelfContained.pubxml" -Resolve # we call dotnet publish on the main project. # The other projects should have been built in Release at this point. From 563cb74997dac2c54bbce7a3f7a57167bf2c3200 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Wed, 26 Feb 2025 22:57:31 +0800 Subject: [PATCH 017/576] add ignored publish profile --- .../Properties/Net9.0-SelfContained.pubxml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 Flow.Launcher/Properties/Net9.0-SelfContained.pubxml diff --git a/Flow.Launcher/Properties/Net9.0-SelfContained.pubxml b/Flow.Launcher/Properties/Net9.0-SelfContained.pubxml new file mode 100644 index 00000000000..ff4111116e0 --- /dev/null +++ b/Flow.Launcher/Properties/Net9.0-SelfContained.pubxml @@ -0,0 +1,18 @@ + + + + + FileSystem + Release + Any CPU + net9.0-windows10.0.19041.0 + ..\Output\Release\ + win-x64 + true + False + False + False + + From 684ff1080b3ff17047bf24145c8a82f62703b918 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Wed, 26 Feb 2025 23:12:29 +0800 Subject: [PATCH 018/576] add ignored publish profile file --- .../Net9.0-SelfContained.pubxml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 Flow.Launcher/Properties/PublishProfiles/Net9.0-SelfContained.pubxml diff --git a/Flow.Launcher/Properties/PublishProfiles/Net9.0-SelfContained.pubxml b/Flow.Launcher/Properties/PublishProfiles/Net9.0-SelfContained.pubxml new file mode 100644 index 00000000000..b9b6776d1d1 --- /dev/null +++ b/Flow.Launcher/Properties/PublishProfiles/Net9.0-SelfContained.pubxml @@ -0,0 +1,18 @@ + + + + + FileSystem + Release + Any CPU + net9.0-windows10.0.19041.0 + ..\Output\Release\ + win-x64 + true + False + False + False + + From debd4159f14416d5fb887918837b0a916a94ae71 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Fri, 28 Feb 2025 02:15:52 -0600 Subject: [PATCH 019/576] update system.drawing.common --- .../Flow.Launcher.Infrastructure.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj index ed753b76780..89fc211b90a 100644 --- a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj +++ b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj @@ -67,7 +67,7 @@ - + From 555188058d34c0e690e3005f29213eadca2e41a9 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Fri, 28 Feb 2025 02:23:45 -0600 Subject: [PATCH 020/576] restore package with lock file --- Flow.Launcher.Core/Flow.Launcher.Core.csproj | 1 + Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj | 1 + Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj | 1 + Flow.Launcher/Flow.Launcher.csproj | 1 + 4 files changed, 4 insertions(+) diff --git a/Flow.Launcher.Core/Flow.Launcher.Core.csproj b/Flow.Launcher.Core/Flow.Launcher.Core.csproj index 8997ff58cc6..2ec88b2d34c 100644 --- a/Flow.Launcher.Core/Flow.Launcher.Core.csproj +++ b/Flow.Launcher.Core/Flow.Launcher.Core.csproj @@ -12,6 +12,7 @@ false false en + true diff --git a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj index 89fc211b90a..4d6c06773c6 100644 --- a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj +++ b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj @@ -12,6 +12,7 @@ false false true + true diff --git a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj index 05c780cd8d4..fc988c1bc82 100644 --- a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj +++ b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj @@ -11,6 +11,7 @@ false false false + true diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj index ef8bd8a3adc..58d96d7f586 100644 --- a/Flow.Launcher/Flow.Launcher.csproj +++ b/Flow.Launcher/Flow.Launcher.csproj @@ -12,6 +12,7 @@ false false en + true From d57eb6c8d4f788cebcfd0716ef415e17d9517d83 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Fri, 28 Feb 2025 02:27:29 -0600 Subject: [PATCH 021/576] add packages.lock.json --- Flow.Launcher.Core/packages.lock.json | 238 +++++++ .../packages.lock.json | 155 +++++ Flow.Launcher.Plugin/packages.lock.json | 77 ++ Flow.Launcher/packages.lock.json | 655 ++++++++++++++++++ 4 files changed, 1125 insertions(+) create mode 100644 Flow.Launcher.Core/packages.lock.json create mode 100644 Flow.Launcher.Infrastructure/packages.lock.json create mode 100644 Flow.Launcher.Plugin/packages.lock.json create mode 100644 Flow.Launcher/packages.lock.json diff --git a/Flow.Launcher.Core/packages.lock.json b/Flow.Launcher.Core/packages.lock.json new file mode 100644 index 00000000000..0c513951b82 --- /dev/null +++ b/Flow.Launcher.Core/packages.lock.json @@ -0,0 +1,238 @@ +{ + "version": 1, + "dependencies": { + "net9.0-windows7.0": { + "Droplex": { + "type": "Direct", + "requested": "[1.7.0, )", + "resolved": "1.7.0", + "contentHash": "wutfIus/Ufw/9TDsp86R1ycnIH+wWrj4UhcmrzAHWjsdyC2iM07WEQ9+APTB7pQynsDnYH1r2i58XgAJ3lxUXA==", + "dependencies": { + "YamlDotNet": "9.1.0" + } + }, + "FSharp.Core": { + "type": "Direct", + "requested": "[9.0.101, )", + "resolved": "9.0.101", + "contentHash": "3/YR1SDWFA+Ojx9HiBwND+0UR8ZWoeZfkhD0DWAPCDdr/YI+CyFkArmMGzGSyPXeYtjG0sy0emzfyNwjt7zhig==" + }, + "Meziantou.Framework.Win32.Jobs": { + "type": "Direct", + "requested": "[3.4.0, )", + "resolved": "3.4.0", + "contentHash": "5GGLckfpwoC1jznInEYfK2INrHyD7K1RtwZJ98kNPKBU6jeu24i4zfgDGHHfb+eK3J+eFPAxo0aYcbUxNXIbNw==" + }, + "Microsoft.IO.RecyclableMemoryStream": { + "type": "Direct", + "requested": "[3.0.1, )", + "resolved": "3.0.1", + "contentHash": "s/s20YTVY9r9TPfTrN5g8zPF1YhwxyqO6PxUkrYTGI2B+OGPe9AdajWZrLhFqXIvqIW23fnUE4+ztrUWNU1+9g==" + }, + "squirrel.windows": { + "type": "Direct", + "requested": "[1.5.2, )", + "resolved": "1.5.2", + "contentHash": "89Y/CFxWm7SEOjvuV2stVa8p+SNM9GOLk4tUNm2nUF792nfkimAgwRA/umVsdyd/OXBH8byXSh4V1qck88ZAyQ==", + "dependencies": { + "DeltaCompressionDotNet": "[1.0.0, 2.0.0)", + "Mono.Cecil": "0.9.6.1", + "Splat": "1.6.2" + } + }, + "StreamJsonRpc": { + "type": "Direct", + "requested": "[2.20.20, )", + "resolved": "2.20.20", + "contentHash": "gwG7KViLbSWS7EI0kYevinVmIga9wZNrpSY/FnWyC6DbdjKJ1xlv/FV1L9b0rLkVP8cGxfIMexdvo/+2W5eq6Q==", + "dependencies": { + "MessagePack": "2.5.187", + "Microsoft.VisualStudio.Threading": "17.10.48", + "Microsoft.VisualStudio.Threading.Analyzers": "17.10.48", + "Microsoft.VisualStudio.Validation": "17.8.8", + "Nerdbank.Streams": "2.11.74", + "Newtonsoft.Json": "13.0.1", + "System.IO.Pipelines": "8.0.0" + } + }, + "Ben.Demystifier": { + "type": "Transitive", + "resolved": "0.4.1", + "contentHash": "axFeEMfmEORy3ipAzOXG/lE+KcNptRbei3F0C4kQCdeiQtW+qJW90K5iIovITGrdLt8AjhNCwk5qLSX9/rFpoA==", + "dependencies": { + "System.Reflection.Metadata": "5.0.0" + } + }, + "BitFaster.Caching": { + "type": "Transitive", + "resolved": "2.5.3", + "contentHash": "Vo/39qcam5Xe+DbyfH0JZyqPswdOoa7jv4PGtRJ6Wj8AU+aZ+TuJRlJcIe+MQjRTJwliI8k8VSQpN8sEoBIv2g==" + }, + "CommunityToolkit.Mvvm": { + "type": "Transitive", + "resolved": "8.4.0", + "contentHash": "tqVU8yc/ADO9oiTRyTnwhFN68hCwvkliMierptWOudIAvWY1mWCh5VFh+guwHJmpMwfg0J0rY+yyd5Oy7ty9Uw==" + }, + "DeltaCompressionDotNet": { + "type": "Transitive", + "resolved": "1.0.0", + "contentHash": "nwbZAYd+DblXAIzlnwDSnl0CiCm8jWLfHSYnoN4wYhtIav6AegB3+T/vKzLbU2IZlPB8Bvl8U3NXpx3eaz+N5w==" + }, + "JetBrains.Annotations": { + "type": "Transitive", + "resolved": "2024.3.0", + "contentHash": "ox5pkeLQXjvJdyAB4b2sBYAlqZGLh3PjSnP1bQNVx72ONuTJ9+34/+Rq91Fc0dG29XG9RgZur9+NcP4riihTug==" + }, + "MemoryPack": { + "type": "Transitive", + "resolved": "1.21.3", + "contentHash": "cwCtED8y400vMWx/Vp0QCSeEpVFjDU4JwF52VX9WTaqVERUvNqjG9n6osFlmFuytegyXnHvYEu1qRJ8rv/rkbg==", + "dependencies": { + "MemoryPack.Core": "1.21.3", + "MemoryPack.Generator": "1.21.3" + } + }, + "MemoryPack.Core": { + "type": "Transitive", + "resolved": "1.21.3", + "contentHash": "ajrYoBWT2aKeH4tlY8q/1C9qK1R/NK+7FkuVOX58ebOSxkABoFTqCR7W+Zk2rakUHZiEgNdRqO67hiRZPq6fLA==" + }, + "MemoryPack.Generator": { + "type": "Transitive", + "resolved": "1.21.3", + "contentHash": "hYU0TAIarDKnbkNIWvb7P4zBUL+CTahkuNkczsKvycSMR5kiwQ4IfLexywNKX3s05Izp4gzDSPbueepNWZRpWA==" + }, + "MessagePack": { + "type": "Transitive", + "resolved": "2.5.187", + "contentHash": "uW4j8m4Nc+2Mk5n6arOChavJ9bLjkis0qWASOj2h2OwmfINuzYv+mjCHUymrYhmyyKTu3N+ObtTXAY4uQ7jIhg==", + "dependencies": { + "MessagePack.Annotations": "2.5.187", + "Microsoft.NET.StringTools": "17.6.3" + } + }, + "MessagePack.Annotations": { + "type": "Transitive", + "resolved": "2.5.187", + "contentHash": "/IvvMMS8opvlHjEJ/fR2Cal4Co726Kj77Z8KiohFhuHfLHHmb9uUxW5+tSCL4ToKFfkQlrS3HD638mRq83ySqA==" + }, + "Microsoft.NET.StringTools": { + "type": "Transitive", + "resolved": "17.6.3", + "contentHash": "N0ZIanl1QCgvUumEL1laasU0a7sOE5ZwLZVTn0pAePnfhq8P7SvTjF8Axq+CnavuQkmdQpGNXQ1efZtu5kDFbA==" + }, + "Microsoft.VisualStudio.Threading": { + "type": "Transitive", + "resolved": "17.12.19", + "contentHash": "eLiGMkMYyaSguqHs3lsrFxy3tAWSLuPEL2pIWRcADMDVAs2xqm3dr1d9QYjiEusTgiClF9KD6OB2NdZP72Oy0Q==", + "dependencies": { + "Microsoft.VisualStudio.Threading.Analyzers": "17.12.19", + "Microsoft.VisualStudio.Validation": "17.8.8" + } + }, + "Microsoft.VisualStudio.Threading.Analyzers": { + "type": "Transitive", + "resolved": "17.12.19", + "contentHash": "v3IYeedjoktvZ+GqYmLudxZJngmf/YWIxNT2Uy6QMMN19cvw+nkWoip1Gr1RtnFkUo1MPUVMis4C8Kj8d8DpSQ==" + }, + "Microsoft.VisualStudio.Validation": { + "type": "Transitive", + "resolved": "17.8.8", + "contentHash": "rWXThIpyQd4YIXghNkiv2+VLvzS+MCMKVRDR0GAMlflsdo+YcAN2g2r5U1Ah98OFjQMRexTFtXQQ2LkajxZi3g==" + }, + "Microsoft.Win32.SystemEvents": { + "type": "Transitive", + "resolved": "9.0.2", + "contentHash": "5BkGZ6mHp2dHydR29sb0fDfAuqkv30AHtTih8wMzvPZysOmBFvHfnkR2w3tsc0pSiIg8ZoKyefJXWy9r3pBh0w==" + }, + "Mono.Cecil": { + "type": "Transitive", + "resolved": "0.9.6.1", + "contentHash": "yMsurNaOxxKIjyW9pEB+tRrR1S3DFnN1+iBgKvYvXG8kW0Y6yknJeMAe/tl3+P78/2C6304TgF7aVqpqXgEQ9Q==" + }, + "Nerdbank.Streams": { + "type": "Transitive", + "resolved": "2.11.74", + "contentHash": "r4G7uHHfoo8LCilPOdtf2C+Q5ymHOAXtciT4ZtB2xRlAvv4gPkWBYNAijFblStv3+uidp81j5DP11jMZl4BfJw==", + "dependencies": { + "Microsoft.VisualStudio.Threading": "17.10.48", + "Microsoft.VisualStudio.Validation": "17.8.8", + "System.IO.Pipelines": "8.0.0" + } + }, + "Newtonsoft.Json": { + "type": "Transitive", + "resolved": "13.0.1", + "contentHash": "ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==" + }, + "NLog": { + "type": "Transitive", + "resolved": "4.7.10", + "contentHash": "rcegW7kYOCjl7wX0SzsqpPBqnJ51JKi1WkYb6QBVX0Wc5IgH19Pv4t/co+T0s06OS0Ne44xgkY/mHg0PdrmJow==" + }, + "PropertyChanged.Fody": { + "type": "Transitive", + "resolved": "3.4.0", + "contentHash": "IAZyq0uolKo2WYm4mjx+q7A8fSGFT0x2e1s3y+ODn4JI0kqTDoo9GF2tdaypUzRFJZfdMxfC5HZW9QzdJLtOnA==", + "dependencies": { + "Fody": "6.5.1" + } + }, + "Splat": { + "type": "Transitive", + "resolved": "1.6.2", + "contentHash": "DeH0MxPU+D4JchkIDPYG4vUT+hsWs9S41cFle0/4K5EJMXWurx5DzAkj2366DfK14/XKNhsu6tCl4dZXJ3CD4w==" + }, + "System.Drawing.Common": { + "type": "Transitive", + "resolved": "9.0.2", + "contentHash": "JU947wzf8JbBS16Y5EIZzAlyQU+k68D7LRx6y03s2wlhlvLqkt/8uPBrjv2hJnnaJKbdb0GhQ3JZsfYXhrRjyg==", + "dependencies": { + "Microsoft.Win32.SystemEvents": "9.0.2" + } + }, + "System.IO.Pipelines": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "FHNOatmUq0sqJOkTx+UF/9YK1f180cnW5FVqnQMvYUN0elp6wFzbtPSiqbo1/ru8ICp43JM1i7kKkk6GsNGHlA==" + }, + "System.Reflection.Metadata": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "5NecZgXktdGg34rh1OenY1rFNDCI8xSjFr+Z4OU4cU06AQHUdRnIIEeWENu3Wl4YowbzkymAIMvi3WyK9U53pQ==" + }, + "ToolGood.Words.Pinyin": { + "type": "Transitive", + "resolved": "3.0.1.4", + "contentHash": "uQo97618y9yzLDxrnehPN+/tuiOlk5BqieEdwctHZOAS9miMXnHKgMFYVw8CSGXRglyTYXlrW7qtUlU7Fje5Ew==" + }, + "YamlDotNet": { + "type": "Transitive", + "resolved": "9.1.0", + "contentHash": "fuvGXU4Ec5HrsmEc+BiFTNPCRf1cGBI2kh/3RzMWgddM2M4ALhbSPoI3X3mhXZUD1qqQd9oSkFAtWjpz8z9eRg==" + }, + "flow.launcher.infrastructure": { + "type": "Project", + "dependencies": { + "Ben.Demystifier": "[0.4.1, )", + "BitFaster.Caching": "[2.5.3, )", + "CommunityToolkit.Mvvm": "[8.4.0, )", + "Flow.Launcher.Plugin": "[4.4.0, )", + "MemoryPack": "[1.21.3, )", + "Microsoft.VisualStudio.Threading": "[17.12.19, )", + "NLog": "[4.7.10, )", + "PropertyChanged.Fody": "[3.4.0, )", + "System.Drawing.Common": "[9.0.2, )", + "ToolGood.Words.Pinyin": "[3.0.1.4, )" + } + }, + "flow.launcher.plugin": { + "type": "Project", + "dependencies": { + "JetBrains.Annotations": "[2024.3.0, )", + "PropertyChanged.Fody": "[3.4.0, )" + } + } + } + } +} \ No newline at end of file diff --git a/Flow.Launcher.Infrastructure/packages.lock.json b/Flow.Launcher.Infrastructure/packages.lock.json new file mode 100644 index 00000000000..f38f91ef97c --- /dev/null +++ b/Flow.Launcher.Infrastructure/packages.lock.json @@ -0,0 +1,155 @@ +{ + "version": 1, + "dependencies": { + "net9.0-windows7.0": { + "Ben.Demystifier": { + "type": "Direct", + "requested": "[0.4.1, )", + "resolved": "0.4.1", + "contentHash": "axFeEMfmEORy3ipAzOXG/lE+KcNptRbei3F0C4kQCdeiQtW+qJW90K5iIovITGrdLt8AjhNCwk5qLSX9/rFpoA==", + "dependencies": { + "System.Reflection.Metadata": "5.0.0" + } + }, + "BitFaster.Caching": { + "type": "Direct", + "requested": "[2.5.3, )", + "resolved": "2.5.3", + "contentHash": "Vo/39qcam5Xe+DbyfH0JZyqPswdOoa7jv4PGtRJ6Wj8AU+aZ+TuJRlJcIe+MQjRTJwliI8k8VSQpN8sEoBIv2g==" + }, + "CommunityToolkit.Mvvm": { + "type": "Direct", + "requested": "[8.4.0, )", + "resolved": "8.4.0", + "contentHash": "tqVU8yc/ADO9oiTRyTnwhFN68hCwvkliMierptWOudIAvWY1mWCh5VFh+guwHJmpMwfg0J0rY+yyd5Oy7ty9Uw==" + }, + "Fody": { + "type": "Direct", + "requested": "[6.5.5, )", + "resolved": "6.5.5", + "contentHash": "Krca41L/PDva1VsmDec5n52cQZxQAQp/bsHdzsNi8iLLI0lqKL94fNIkNaC8tVolUkCyWsbzvxfxJCeD2789fA==" + }, + "MemoryPack": { + "type": "Direct", + "requested": "[1.21.3, )", + "resolved": "1.21.3", + "contentHash": "cwCtED8y400vMWx/Vp0QCSeEpVFjDU4JwF52VX9WTaqVERUvNqjG9n6osFlmFuytegyXnHvYEu1qRJ8rv/rkbg==", + "dependencies": { + "MemoryPack.Core": "1.21.3", + "MemoryPack.Generator": "1.21.3" + } + }, + "Microsoft.VisualStudio.Threading": { + "type": "Direct", + "requested": "[17.12.19, )", + "resolved": "17.12.19", + "contentHash": "eLiGMkMYyaSguqHs3lsrFxy3tAWSLuPEL2pIWRcADMDVAs2xqm3dr1d9QYjiEusTgiClF9KD6OB2NdZP72Oy0Q==", + "dependencies": { + "Microsoft.VisualStudio.Threading.Analyzers": "17.12.19", + "Microsoft.VisualStudio.Validation": "17.8.8" + } + }, + "Microsoft.Windows.CsWin32": { + "type": "Direct", + "requested": "[0.3.106, )", + "resolved": "0.3.106", + "contentHash": "Mx5fK7uN6fwLR4wUghs6//HonAnwPBNmC2oonyJVhCUlHS/r6SUS3NkBc3+gaQiv+0/9bqdj1oSCKQFkNI+21Q==", + "dependencies": { + "Microsoft.Windows.SDK.Win32Docs": "0.1.42-alpha", + "Microsoft.Windows.SDK.Win32Metadata": "60.0.34-preview", + "Microsoft.Windows.WDK.Win32Metadata": "0.11.4-experimental" + } + }, + "NLog": { + "type": "Direct", + "requested": "[4.7.10, )", + "resolved": "4.7.10", + "contentHash": "rcegW7kYOCjl7wX0SzsqpPBqnJ51JKi1WkYb6QBVX0Wc5IgH19Pv4t/co+T0s06OS0Ne44xgkY/mHg0PdrmJow==" + }, + "PropertyChanged.Fody": { + "type": "Direct", + "requested": "[3.4.0, )", + "resolved": "3.4.0", + "contentHash": "IAZyq0uolKo2WYm4mjx+q7A8fSGFT0x2e1s3y+ODn4JI0kqTDoo9GF2tdaypUzRFJZfdMxfC5HZW9QzdJLtOnA==", + "dependencies": { + "Fody": "6.5.1" + } + }, + "System.Drawing.Common": { + "type": "Direct", + "requested": "[9.0.2, )", + "resolved": "9.0.2", + "contentHash": "JU947wzf8JbBS16Y5EIZzAlyQU+k68D7LRx6y03s2wlhlvLqkt/8uPBrjv2hJnnaJKbdb0GhQ3JZsfYXhrRjyg==", + "dependencies": { + "Microsoft.Win32.SystemEvents": "9.0.2" + } + }, + "ToolGood.Words.Pinyin": { + "type": "Direct", + "requested": "[3.0.1.4, )", + "resolved": "3.0.1.4", + "contentHash": "uQo97618y9yzLDxrnehPN+/tuiOlk5BqieEdwctHZOAS9miMXnHKgMFYVw8CSGXRglyTYXlrW7qtUlU7Fje5Ew==" + }, + "JetBrains.Annotations": { + "type": "Transitive", + "resolved": "2024.3.0", + "contentHash": "ox5pkeLQXjvJdyAB4b2sBYAlqZGLh3PjSnP1bQNVx72ONuTJ9+34/+Rq91Fc0dG29XG9RgZur9+NcP4riihTug==" + }, + "MemoryPack.Core": { + "type": "Transitive", + "resolved": "1.21.3", + "contentHash": "ajrYoBWT2aKeH4tlY8q/1C9qK1R/NK+7FkuVOX58ebOSxkABoFTqCR7W+Zk2rakUHZiEgNdRqO67hiRZPq6fLA==" + }, + "MemoryPack.Generator": { + "type": "Transitive", + "resolved": "1.21.3", + "contentHash": "hYU0TAIarDKnbkNIWvb7P4zBUL+CTahkuNkczsKvycSMR5kiwQ4IfLexywNKX3s05Izp4gzDSPbueepNWZRpWA==" + }, + "Microsoft.VisualStudio.Threading.Analyzers": { + "type": "Transitive", + "resolved": "17.12.19", + "contentHash": "v3IYeedjoktvZ+GqYmLudxZJngmf/YWIxNT2Uy6QMMN19cvw+nkWoip1Gr1RtnFkUo1MPUVMis4C8Kj8d8DpSQ==" + }, + "Microsoft.VisualStudio.Validation": { + "type": "Transitive", + "resolved": "17.8.8", + "contentHash": "rWXThIpyQd4YIXghNkiv2+VLvzS+MCMKVRDR0GAMlflsdo+YcAN2g2r5U1Ah98OFjQMRexTFtXQQ2LkajxZi3g==" + }, + "Microsoft.Win32.SystemEvents": { + "type": "Transitive", + "resolved": "9.0.2", + "contentHash": "5BkGZ6mHp2dHydR29sb0fDfAuqkv30AHtTih8wMzvPZysOmBFvHfnkR2w3tsc0pSiIg8ZoKyefJXWy9r3pBh0w==" + }, + "Microsoft.Windows.SDK.Win32Docs": { + "type": "Transitive", + "resolved": "0.1.42-alpha", + "contentHash": "Z/9po23gUA9aoukirh2ItMU2ZS9++Js9Gdds9fu5yuMojDrmArvY2y+tq9985tR3cxFxpZO1O35Wjfo0khj5HA==" + }, + "Microsoft.Windows.SDK.Win32Metadata": { + "type": "Transitive", + "resolved": "60.0.34-preview", + "contentHash": "TA3DUNi4CTeo+ItTXBnGZFt2159XOGSl0UOlG5vjDj4WHqZjhwYyyUnzOtrbCERiSaP2Hzg7otJNWwOSZgutyA==" + }, + "Microsoft.Windows.WDK.Win32Metadata": { + "type": "Transitive", + "resolved": "0.11.4-experimental", + "contentHash": "bf5MCmUyZf0gBlYQjx9UpRAZWBkRndyt9XicR+UNLvAUAFTZQbu6YaX/sNKZlR98Grn0gydfh/yT4I3vc0AIQA==", + "dependencies": { + "Microsoft.Windows.SDK.Win32Metadata": "60.0.34-preview" + } + }, + "System.Reflection.Metadata": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "5NecZgXktdGg34rh1OenY1rFNDCI8xSjFr+Z4OU4cU06AQHUdRnIIEeWENu3Wl4YowbzkymAIMvi3WyK9U53pQ==" + }, + "flow.launcher.plugin": { + "type": "Project", + "dependencies": { + "JetBrains.Annotations": "[2024.3.0, )", + "PropertyChanged.Fody": "[3.4.0, )" + } + } + } + } +} \ No newline at end of file diff --git a/Flow.Launcher.Plugin/packages.lock.json b/Flow.Launcher.Plugin/packages.lock.json new file mode 100644 index 00000000000..6cdf96e0719 --- /dev/null +++ b/Flow.Launcher.Plugin/packages.lock.json @@ -0,0 +1,77 @@ +{ + "version": 1, + "dependencies": { + "net9.0-windows7.0": { + "Fody": { + "type": "Direct", + "requested": "[6.5.4, )", + "resolved": "6.5.4", + "contentHash": "GXZuti428IZctfby10xkMbWLCibcb6s29I/psLbBoO2vHJI5eTNVybnlV/Wi1tlIu9GG0bgW/PQwMH+MCldHxw==" + }, + "JetBrains.Annotations": { + "type": "Direct", + "requested": "[2024.3.0, )", + "resolved": "2024.3.0", + "contentHash": "ox5pkeLQXjvJdyAB4b2sBYAlqZGLh3PjSnP1bQNVx72ONuTJ9+34/+Rq91Fc0dG29XG9RgZur9+NcP4riihTug==" + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[1.1.1, )", + "resolved": "1.1.1", + "contentHash": "IaJGnOv/M7UQjRJks7B6p7pbPnOwisYGOIzqCz5ilGFTApZ3ktOR+6zJ12ZRPInulBmdAf1SrGdDG2MU8g6XTw==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "1.1.1", + "Microsoft.SourceLink.Common": "1.1.1" + } + }, + "Microsoft.Windows.CsWin32": { + "type": "Direct", + "requested": "[0.3.106, )", + "resolved": "0.3.106", + "contentHash": "Mx5fK7uN6fwLR4wUghs6//HonAnwPBNmC2oonyJVhCUlHS/r6SUS3NkBc3+gaQiv+0/9bqdj1oSCKQFkNI+21Q==", + "dependencies": { + "Microsoft.Windows.SDK.Win32Docs": "0.1.42-alpha", + "Microsoft.Windows.SDK.Win32Metadata": "60.0.34-preview", + "Microsoft.Windows.WDK.Win32Metadata": "0.11.4-experimental" + } + }, + "PropertyChanged.Fody": { + "type": "Direct", + "requested": "[3.4.0, )", + "resolved": "3.4.0", + "contentHash": "IAZyq0uolKo2WYm4mjx+q7A8fSGFT0x2e1s3y+ODn4JI0kqTDoo9GF2tdaypUzRFJZfdMxfC5HZW9QzdJLtOnA==", + "dependencies": { + "Fody": "6.5.1" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "1.1.1", + "contentHash": "AT3HlgTjsqHnWpBHSNeR0KxbLZD7bztlZVj7I8vgeYG9SYqbeFGh0TM/KVtC6fg53nrWHl3VfZFvb5BiQFcY6Q==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "1.1.1", + "contentHash": "WMcGpWKrmJmzrNeuaEb23bEMnbtR/vLmvZtkAP5qWu7vQsY59GqfRJd65sFpBszbd2k/bQ8cs8eWawQKAabkVg==" + }, + "Microsoft.Windows.SDK.Win32Docs": { + "type": "Transitive", + "resolved": "0.1.42-alpha", + "contentHash": "Z/9po23gUA9aoukirh2ItMU2ZS9++Js9Gdds9fu5yuMojDrmArvY2y+tq9985tR3cxFxpZO1O35Wjfo0khj5HA==" + }, + "Microsoft.Windows.SDK.Win32Metadata": { + "type": "Transitive", + "resolved": "60.0.34-preview", + "contentHash": "TA3DUNi4CTeo+ItTXBnGZFt2159XOGSl0UOlG5vjDj4WHqZjhwYyyUnzOtrbCERiSaP2Hzg7otJNWwOSZgutyA==" + }, + "Microsoft.Windows.WDK.Win32Metadata": { + "type": "Transitive", + "resolved": "0.11.4-experimental", + "contentHash": "bf5MCmUyZf0gBlYQjx9UpRAZWBkRndyt9XicR+UNLvAUAFTZQbu6YaX/sNKZlR98Grn0gydfh/yT4I3vc0AIQA==", + "dependencies": { + "Microsoft.Windows.SDK.Win32Metadata": "60.0.34-preview" + } + } + } + } +} \ No newline at end of file diff --git a/Flow.Launcher/packages.lock.json b/Flow.Launcher/packages.lock.json new file mode 100644 index 00000000000..2768db74bde --- /dev/null +++ b/Flow.Launcher/packages.lock.json @@ -0,0 +1,655 @@ +{ + "version": 1, + "dependencies": { + "net9.0-windows10.0.19041": { + "ChefKeys": { + "type": "Direct", + "requested": "[0.1.2, )", + "resolved": "0.1.2", + "contentHash": "hnayWejg57tg8+lZ1Q/zPR8tj9ezUtB1sY8aCv9jiZ+3wcqK0eGL+Skt9OzT9mjSsBIg4o9Jv1HdQdzjd1lkQw==" + }, + "CommunityToolkit.Mvvm": { + "type": "Direct", + "requested": "[8.4.0, )", + "resolved": "8.4.0", + "contentHash": "tqVU8yc/ADO9oiTRyTnwhFN68hCwvkliMierptWOudIAvWY1mWCh5VFh+guwHJmpMwfg0J0rY+yyd5Oy7ty9Uw==" + }, + "Fody": { + "type": "Direct", + "requested": "[6.5.4, )", + "resolved": "6.5.4", + "contentHash": "GXZuti428IZctfby10xkMbWLCibcb6s29I/psLbBoO2vHJI5eTNVybnlV/Wi1tlIu9GG0bgW/PQwMH+MCldHxw==" + }, + "InputSimulator": { + "type": "Direct", + "requested": "[1.0.4, )", + "resolved": "1.0.4", + "contentHash": "D0LvRCPQMX6/FJHBjng+RO+wRDuHTJrfo7IAc7rmkPvRqchdVGJWg3y70peOtDy3OLNK+HSOwVkH4GiuLnkKgA==" + }, + "Microsoft.Extensions.DependencyInjection": { + "type": "Direct", + "requested": "[7.0.0, )", + "resolved": "7.0.0", + "contentHash": "elNeOmkeX3eDVG6pYVeV82p29hr+UKDaBhrZyWvWLw/EVZSYEkZlQdkp0V39k/Xehs2Qa0mvoCvkVj3eQxNQ1Q==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0" + } + }, + "Microsoft.Extensions.Hosting": { + "type": "Direct", + "requested": "[7.0.0, )", + "resolved": "7.0.0", + "contentHash": "4nFc8xCfK26G524ioreZvz/IeIKN/gY1LApoGpaIThKqBdTwauUo4ETCf12lQcoefijqe3Imnfvnk31IezFatg==", + "dependencies": { + "Microsoft.Extensions.Configuration": "7.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "7.0.0", + "Microsoft.Extensions.Configuration.Binder": "7.0.0", + "Microsoft.Extensions.Configuration.CommandLine": "7.0.0", + "Microsoft.Extensions.Configuration.EnvironmentVariables": "7.0.0", + "Microsoft.Extensions.Configuration.FileExtensions": "7.0.0", + "Microsoft.Extensions.Configuration.Json": "7.0.0", + "Microsoft.Extensions.Configuration.UserSecrets": "7.0.0", + "Microsoft.Extensions.DependencyInjection": "7.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0", + "Microsoft.Extensions.FileProviders.Abstractions": "7.0.0", + "Microsoft.Extensions.FileProviders.Physical": "7.0.0", + "Microsoft.Extensions.Hosting.Abstractions": "7.0.0", + "Microsoft.Extensions.Logging": "7.0.0", + "Microsoft.Extensions.Logging.Abstractions": "7.0.0", + "Microsoft.Extensions.Logging.Configuration": "7.0.0", + "Microsoft.Extensions.Logging.Console": "7.0.0", + "Microsoft.Extensions.Logging.Debug": "7.0.0", + "Microsoft.Extensions.Logging.EventLog": "7.0.0", + "Microsoft.Extensions.Logging.EventSource": "7.0.0", + "Microsoft.Extensions.Options": "7.0.0" + } + }, + "Microsoft.Toolkit.Uwp.Notifications": { + "type": "Direct", + "requested": "[7.1.3, )", + "resolved": "7.1.3", + "contentHash": "A1dglAzb24gjehmb7DwGd07mfyZ1gacAK7ObE0KwDlRc3mayH2QW7cSOy3TkkyELjLg19OQBuhPOj4SpXET9lg==", + "dependencies": { + "Microsoft.Win32.Registry": "4.7.0", + "System.Drawing.Common": "4.7.0", + "System.Reflection.Emit": "4.7.0", + "System.ValueTuple": "4.5.0" + } + }, + "Microsoft.Windows.CsWin32": { + "type": "Direct", + "requested": "[0.3.106, )", + "resolved": "0.3.106", + "contentHash": "Mx5fK7uN6fwLR4wUghs6//HonAnwPBNmC2oonyJVhCUlHS/r6SUS3NkBc3+gaQiv+0/9bqdj1oSCKQFkNI+21Q==", + "dependencies": { + "Microsoft.Windows.SDK.Win32Docs": "0.1.42-alpha", + "Microsoft.Windows.SDK.Win32Metadata": "60.0.34-preview", + "Microsoft.Windows.WDK.Win32Metadata": "0.11.4-experimental" + } + }, + "ModernWpfUI": { + "type": "Direct", + "requested": "[0.9.4, )", + "resolved": "0.9.4", + "contentHash": "HJ07Be9KOiGKGcMLz/AwY+84h3yGHRPuYpYXCE6h1yPtaFwGMWfanZ70jX7W5XWx8+Qk1vGox+WGKgxxsy6EHw==" + }, + "NHotkey.Wpf": { + "type": "Direct", + "requested": "[3.0.0, )", + "resolved": "3.0.0", + "contentHash": "BIUKlhTG5KtFf9OQzWvkmVmktt5/FFj6AOEgag8Uf0R2YdZt5ajUzs3sVskcJcT2TztWlEHKQr1jFj3KQ0D9Nw==", + "dependencies": { + "NHotkey": "3.0.0" + } + }, + "PropertyChanged.Fody": { + "type": "Direct", + "requested": "[3.4.0, )", + "resolved": "3.4.0", + "contentHash": "IAZyq0uolKo2WYm4mjx+q7A8fSGFT0x2e1s3y+ODn4JI0kqTDoo9GF2tdaypUzRFJZfdMxfC5HZW9QzdJLtOnA==", + "dependencies": { + "Fody": "6.5.1" + } + }, + "SemanticVersioning": { + "type": "Direct", + "requested": "[3.0.0, )", + "resolved": "3.0.0", + "contentHash": "RR+8GbPQ/gjDqov/1QN1OPoUlbUruNwcL3WjWCeLw+MY7+od/ENhnkYxCfAC6rQLIu3QifaJt3kPYyP3RumqMQ==" + }, + "TaskScheduler": { + "type": "Direct", + "requested": "[2.11.0, )", + "resolved": "2.11.0", + "contentHash": "p9wH58XSNIyUtO7PIFAEldaKUzpYmlj+YWAfnUqBKnGxIZRY51I9BrsBGJijUVwlxrgmLLPUigRIv2ZTD4uPJA==", + "dependencies": { + "Microsoft.Win32.Registry": "5.0.0", + "System.Diagnostics.EventLog": "8.0.0", + "System.Security.AccessControl": "6.0.1" + } + }, + "VirtualizingWrapPanel": { + "type": "Direct", + "requested": "[2.1.1, )", + "resolved": "2.1.1", + "contentHash": "Fc/yjU8jqC3qpIsNxeO5RjK2lPU7xnJtBLMSQ6L9egA2PyJLQeVeXpG8WBb5N1kN15rlJEYG8dHWJ5qUGgaNrg==" + }, + "Ben.Demystifier": { + "type": "Transitive", + "resolved": "0.4.1", + "contentHash": "axFeEMfmEORy3ipAzOXG/lE+KcNptRbei3F0C4kQCdeiQtW+qJW90K5iIovITGrdLt8AjhNCwk5qLSX9/rFpoA==", + "dependencies": { + "System.Reflection.Metadata": "5.0.0" + } + }, + "BitFaster.Caching": { + "type": "Transitive", + "resolved": "2.5.3", + "contentHash": "Vo/39qcam5Xe+DbyfH0JZyqPswdOoa7jv4PGtRJ6Wj8AU+aZ+TuJRlJcIe+MQjRTJwliI8k8VSQpN8sEoBIv2g==" + }, + "DeltaCompressionDotNet": { + "type": "Transitive", + "resolved": "1.0.0", + "contentHash": "nwbZAYd+DblXAIzlnwDSnl0CiCm8jWLfHSYnoN4wYhtIav6AegB3+T/vKzLbU2IZlPB8Bvl8U3NXpx3eaz+N5w==" + }, + "Droplex": { + "type": "Transitive", + "resolved": "1.7.0", + "contentHash": "wutfIus/Ufw/9TDsp86R1ycnIH+wWrj4UhcmrzAHWjsdyC2iM07WEQ9+APTB7pQynsDnYH1r2i58XgAJ3lxUXA==", + "dependencies": { + "YamlDotNet": "9.1.0" + } + }, + "FSharp.Core": { + "type": "Transitive", + "resolved": "9.0.101", + "contentHash": "3/YR1SDWFA+Ojx9HiBwND+0UR8ZWoeZfkhD0DWAPCDdr/YI+CyFkArmMGzGSyPXeYtjG0sy0emzfyNwjt7zhig==" + }, + "JetBrains.Annotations": { + "type": "Transitive", + "resolved": "2024.3.0", + "contentHash": "ox5pkeLQXjvJdyAB4b2sBYAlqZGLh3PjSnP1bQNVx72ONuTJ9+34/+Rq91Fc0dG29XG9RgZur9+NcP4riihTug==" + }, + "MemoryPack": { + "type": "Transitive", + "resolved": "1.21.3", + "contentHash": "cwCtED8y400vMWx/Vp0QCSeEpVFjDU4JwF52VX9WTaqVERUvNqjG9n6osFlmFuytegyXnHvYEu1qRJ8rv/rkbg==", + "dependencies": { + "MemoryPack.Core": "1.21.3", + "MemoryPack.Generator": "1.21.3" + } + }, + "MemoryPack.Core": { + "type": "Transitive", + "resolved": "1.21.3", + "contentHash": "ajrYoBWT2aKeH4tlY8q/1C9qK1R/NK+7FkuVOX58ebOSxkABoFTqCR7W+Zk2rakUHZiEgNdRqO67hiRZPq6fLA==" + }, + "MemoryPack.Generator": { + "type": "Transitive", + "resolved": "1.21.3", + "contentHash": "hYU0TAIarDKnbkNIWvb7P4zBUL+CTahkuNkczsKvycSMR5kiwQ4IfLexywNKX3s05Izp4gzDSPbueepNWZRpWA==" + }, + "MessagePack": { + "type": "Transitive", + "resolved": "2.5.187", + "contentHash": "uW4j8m4Nc+2Mk5n6arOChavJ9bLjkis0qWASOj2h2OwmfINuzYv+mjCHUymrYhmyyKTu3N+ObtTXAY4uQ7jIhg==", + "dependencies": { + "MessagePack.Annotations": "2.5.187", + "Microsoft.NET.StringTools": "17.6.3" + } + }, + "MessagePack.Annotations": { + "type": "Transitive", + "resolved": "2.5.187", + "contentHash": "/IvvMMS8opvlHjEJ/fR2Cal4Co726Kj77Z8KiohFhuHfLHHmb9uUxW5+tSCL4ToKFfkQlrS3HD638mRq83ySqA==" + }, + "Meziantou.Framework.Win32.Jobs": { + "type": "Transitive", + "resolved": "3.4.0", + "contentHash": "5GGLckfpwoC1jznInEYfK2INrHyD7K1RtwZJ98kNPKBU6jeu24i4zfgDGHHfb+eK3J+eFPAxo0aYcbUxNXIbNw==" + }, + "Microsoft.Extensions.Configuration": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "tldQUBWt/xeH2K7/hMPPo5g8zuLc3Ro9I5d4o/XrxvxOCA2EZBtW7bCHHTc49fcBtvB8tLAb/Qsmfrq+2SJ4vA==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "7.0.0", + "Microsoft.Extensions.Primitives": "7.0.0" + } + }, + "Microsoft.Extensions.Configuration.Abstractions": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "f34u2eaqIjNO9YLHBz8rozVZ+TcFiFs0F3r7nUJd7FRkVSxk8u4OpoK226mi49MwexHOR2ibP9MFvRUaLilcQQ==", + "dependencies": { + "Microsoft.Extensions.Primitives": "7.0.0" + } + }, + "Microsoft.Extensions.Configuration.Binder": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "tgU4u7bZsoS9MKVRiotVMAwHtbREHr5/5zSEV+JPhg46+ox47Au84E3D2IacAaB0bk5ePNaNieTlPrfjbbRJkg==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "7.0.0" + } + }, + "Microsoft.Extensions.Configuration.CommandLine": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "a8Iq8SCw5m8W5pZJcPCgBpBO4E89+NaObPng+ApIhrGSv9X4JPrcFAaGM4sDgR0X83uhLgsNJq8VnGP/wqhr8A==", + "dependencies": { + "Microsoft.Extensions.Configuration": "7.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "7.0.0" + } + }, + "Microsoft.Extensions.Configuration.EnvironmentVariables": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "RIkfqCkvrAogirjsqSrG1E1FxgrLsOZU2nhRbl07lrajnxzSU2isj2lwQah0CtCbLWo/pOIukQzM1GfneBUnxA==", + "dependencies": { + "Microsoft.Extensions.Configuration": "7.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "7.0.0" + } + }, + "Microsoft.Extensions.Configuration.FileExtensions": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "xk2lRJ1RDuqe57BmgvRPyCt6zyePKUmvT6iuXqiHR+/OIIgWVR8Ff5k2p6DwmqY8a17hx/OnrekEhziEIeQP6Q==", + "dependencies": { + "Microsoft.Extensions.Configuration": "7.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "7.0.0", + "Microsoft.Extensions.FileProviders.Abstractions": "7.0.0", + "Microsoft.Extensions.FileProviders.Physical": "7.0.0", + "Microsoft.Extensions.Primitives": "7.0.0" + } + }, + "Microsoft.Extensions.Configuration.Json": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "LDNYe3uw76W35Jci+be4LDf2lkQZe0A7EEYQVChFbc509CpZ4Iupod8li4PUXPBhEUOFI/rlQNf5xkzJRQGvtA==", + "dependencies": { + "Microsoft.Extensions.Configuration": "7.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "7.0.0", + "Microsoft.Extensions.Configuration.FileExtensions": "7.0.0", + "Microsoft.Extensions.FileProviders.Abstractions": "7.0.0", + "System.Text.Json": "7.0.0" + } + }, + "Microsoft.Extensions.Configuration.UserSecrets": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "33HPW1PmB2RS0ietBQyvOxjp4O3wlt+4tIs8KPyMn1kqp04goiZGa7+3mc69NRLv6bphkLDy0YR7Uw3aZyf8Zw==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "7.0.0", + "Microsoft.Extensions.Configuration.Json": "7.0.0", + "Microsoft.Extensions.FileProviders.Abstractions": "7.0.0", + "Microsoft.Extensions.FileProviders.Physical": "7.0.0" + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "h3j/QfmFN4S0w4C2A6X7arXij/M/OVw3uQHSOFxnND4DyAzO1F9eMX7Eti7lU/OkSthEE0WzRsfT/Dmx86jzCw==" + }, + "Microsoft.Extensions.FileProviders.Abstractions": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "NyawiW9ZT/liQb34k9YqBSNPLuuPkrjMgQZ24Y/xXX1RoiBkLUdPMaQTmxhZ5TYu8ZKZ9qayzil75JX95vGQUg==", + "dependencies": { + "Microsoft.Extensions.Primitives": "7.0.0" + } + }, + "Microsoft.Extensions.FileProviders.Physical": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "K8D2MTR+EtzkbZ8z80LrG7Ur64R7ZZdRLt1J5cgpc/pUWl0C6IkAUapPuK28oionHueCPELUqq0oYEvZfalNdg==", + "dependencies": { + "Microsoft.Extensions.FileProviders.Abstractions": "7.0.0", + "Microsoft.Extensions.FileSystemGlobbing": "7.0.0", + "Microsoft.Extensions.Primitives": "7.0.0" + } + }, + "Microsoft.Extensions.FileSystemGlobbing": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "2jONjKHiF+E92ynz2ZFcr9OvxIw+rTGMPEH+UZGeHTEComVav93jQUWGkso8yWwVBcEJGcNcZAaqY01FFJcj7w==" + }, + "Microsoft.Extensions.Hosting.Abstractions": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "43n9Je09z0p/7ViPxfRqs5BUItRLNVh5b6JH40F2Agkh2NBsY/jpNYTtbCcxrHCsA3oRmbR6RJBzUutB4VZvNQ==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "7.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0", + "Microsoft.Extensions.FileProviders.Abstractions": "7.0.0" + } + }, + "Microsoft.Extensions.Logging": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "Nw2muoNrOG5U5qa2ZekXwudUn2BJcD41e65zwmDHb1fQegTX66UokLWZkJRpqSSHXDOWZ5V0iqhbxOEky91atA==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "7.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0", + "Microsoft.Extensions.Logging.Abstractions": "7.0.0", + "Microsoft.Extensions.Options": "7.0.0" + } + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "kmn78+LPVMOWeITUjIlfxUPDsI0R6G0RkeAMBmQxAJ7vBJn4q2dTva7pWi65ceN5vPGjJ9q/Uae2WKgvfktJAw==" + }, + "Microsoft.Extensions.Logging.Configuration": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "FLDA0HcffKA8ycoDQLJuCNGIE42cLWPxgdQGRBaSzZrYTkMBjnf9zrr8pGT06psLq9Q+RKWmmZczQ9bCrXEBcA==", + "dependencies": { + "Microsoft.Extensions.Configuration": "7.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "7.0.0", + "Microsoft.Extensions.Configuration.Binder": "7.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0", + "Microsoft.Extensions.Logging": "7.0.0", + "Microsoft.Extensions.Logging.Abstractions": "7.0.0", + "Microsoft.Extensions.Options": "7.0.0", + "Microsoft.Extensions.Options.ConfigurationExtensions": "7.0.0" + } + }, + "Microsoft.Extensions.Logging.Console": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "qt5n8bHLZPUfuRnFxJKW5q9ZwOTncdh96rtWzWpX3Y/064MlxzCSw2ELF5Jlwdo+Y4wK3I47NmUTFsV7Sg8rqg==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0", + "Microsoft.Extensions.Logging": "7.0.0", + "Microsoft.Extensions.Logging.Abstractions": "7.0.0", + "Microsoft.Extensions.Logging.Configuration": "7.0.0", + "Microsoft.Extensions.Options": "7.0.0", + "System.Text.Json": "7.0.0" + } + }, + "Microsoft.Extensions.Logging.Debug": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "tFGGyPDpJ8ZdQdeckCArP7nZuoY3am9zJWuvp4OD1bHq65S0epW9BNHzAWeaIO4eYwWnGm1jRNt3vRciH8H6MA==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0", + "Microsoft.Extensions.Logging": "7.0.0", + "Microsoft.Extensions.Logging.Abstractions": "7.0.0" + } + }, + "Microsoft.Extensions.Logging.EventLog": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "Rp7cYL9xQRVTgjMl77H5YDxszAaO+mlA+KT0BnLSVhuCoKQQOOs1sSK2/x8BK2dZ/lKeAC/CVF+20Ef2dpKXwg==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0", + "Microsoft.Extensions.Logging": "7.0.0", + "Microsoft.Extensions.Logging.Abstractions": "7.0.0", + "Microsoft.Extensions.Options": "7.0.0", + "System.Diagnostics.EventLog": "7.0.0" + } + }, + "Microsoft.Extensions.Logging.EventSource": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "MxQXndQFviIyOPqyMeLNshXnmqcfzEHE2wWcr7BF1unSisJgouZ3tItnq+aJLGPojrW8OZSC/ZdRoR6wAq+c7w==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0", + "Microsoft.Extensions.Logging": "7.0.0", + "Microsoft.Extensions.Logging.Abstractions": "7.0.0", + "Microsoft.Extensions.Options": "7.0.0", + "Microsoft.Extensions.Primitives": "7.0.0", + "System.Text.Json": "7.0.0" + } + }, + "Microsoft.Extensions.Options": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "lP1yBnTTU42cKpMozuafbvNtQ7QcBjr/CcK3bYOGEMH55Fjt+iecXjT6chR7vbgCMqy3PG3aNQSZgo/EuY/9qQ==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0", + "Microsoft.Extensions.Primitives": "7.0.0" + } + }, + "Microsoft.Extensions.Options.ConfigurationExtensions": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "95UnxZkkFdXxF6vSrtJsMHCzkDeSMuUWGs2hDT54cX+U5eVajrCJ3qLyQRW+CtpTt5OJ8bmTvpQVHu1DLhH+cA==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "7.0.0", + "Microsoft.Extensions.Configuration.Binder": "7.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0", + "Microsoft.Extensions.Options": "7.0.0", + "Microsoft.Extensions.Primitives": "7.0.0" + } + }, + "Microsoft.Extensions.Primitives": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "um1KU5kxcRp3CNuI8o/GrZtD4AIOXDk+RLsytjZ9QPok3ttLUelLKpilVPuaFT3TFjOhSibUAso0odbOaCDj3Q==" + }, + "Microsoft.IO.RecyclableMemoryStream": { + "type": "Transitive", + "resolved": "3.0.1", + "contentHash": "s/s20YTVY9r9TPfTrN5g8zPF1YhwxyqO6PxUkrYTGI2B+OGPe9AdajWZrLhFqXIvqIW23fnUE4+ztrUWNU1+9g==" + }, + "Microsoft.NET.StringTools": { + "type": "Transitive", + "resolved": "17.6.3", + "contentHash": "N0ZIanl1QCgvUumEL1laasU0a7sOE5ZwLZVTn0pAePnfhq8P7SvTjF8Axq+CnavuQkmdQpGNXQ1efZtu5kDFbA==" + }, + "Microsoft.VisualStudio.Threading": { + "type": "Transitive", + "resolved": "17.12.19", + "contentHash": "eLiGMkMYyaSguqHs3lsrFxy3tAWSLuPEL2pIWRcADMDVAs2xqm3dr1d9QYjiEusTgiClF9KD6OB2NdZP72Oy0Q==", + "dependencies": { + "Microsoft.VisualStudio.Threading.Analyzers": "17.12.19", + "Microsoft.VisualStudio.Validation": "17.8.8" + } + }, + "Microsoft.VisualStudio.Threading.Analyzers": { + "type": "Transitive", + "resolved": "17.12.19", + "contentHash": "v3IYeedjoktvZ+GqYmLudxZJngmf/YWIxNT2Uy6QMMN19cvw+nkWoip1Gr1RtnFkUo1MPUVMis4C8Kj8d8DpSQ==" + }, + "Microsoft.VisualStudio.Validation": { + "type": "Transitive", + "resolved": "17.8.8", + "contentHash": "rWXThIpyQd4YIXghNkiv2+VLvzS+MCMKVRDR0GAMlflsdo+YcAN2g2r5U1Ah98OFjQMRexTFtXQQ2LkajxZi3g==" + }, + "Microsoft.Win32.Registry": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==", + "dependencies": { + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "Microsoft.Win32.SystemEvents": { + "type": "Transitive", + "resolved": "9.0.2", + "contentHash": "5BkGZ6mHp2dHydR29sb0fDfAuqkv30AHtTih8wMzvPZysOmBFvHfnkR2w3tsc0pSiIg8ZoKyefJXWy9r3pBh0w==" + }, + "Microsoft.Windows.SDK.Win32Docs": { + "type": "Transitive", + "resolved": "0.1.42-alpha", + "contentHash": "Z/9po23gUA9aoukirh2ItMU2ZS9++Js9Gdds9fu5yuMojDrmArvY2y+tq9985tR3cxFxpZO1O35Wjfo0khj5HA==" + }, + "Microsoft.Windows.SDK.Win32Metadata": { + "type": "Transitive", + "resolved": "60.0.34-preview", + "contentHash": "TA3DUNi4CTeo+ItTXBnGZFt2159XOGSl0UOlG5vjDj4WHqZjhwYyyUnzOtrbCERiSaP2Hzg7otJNWwOSZgutyA==" + }, + "Microsoft.Windows.WDK.Win32Metadata": { + "type": "Transitive", + "resolved": "0.11.4-experimental", + "contentHash": "bf5MCmUyZf0gBlYQjx9UpRAZWBkRndyt9XicR+UNLvAUAFTZQbu6YaX/sNKZlR98Grn0gydfh/yT4I3vc0AIQA==", + "dependencies": { + "Microsoft.Windows.SDK.Win32Metadata": "60.0.34-preview" + } + }, + "Mono.Cecil": { + "type": "Transitive", + "resolved": "0.9.6.1", + "contentHash": "yMsurNaOxxKIjyW9pEB+tRrR1S3DFnN1+iBgKvYvXG8kW0Y6yknJeMAe/tl3+P78/2C6304TgF7aVqpqXgEQ9Q==" + }, + "Nerdbank.Streams": { + "type": "Transitive", + "resolved": "2.11.74", + "contentHash": "r4G7uHHfoo8LCilPOdtf2C+Q5ymHOAXtciT4ZtB2xRlAvv4gPkWBYNAijFblStv3+uidp81j5DP11jMZl4BfJw==", + "dependencies": { + "Microsoft.VisualStudio.Threading": "17.10.48", + "Microsoft.VisualStudio.Validation": "17.8.8", + "System.IO.Pipelines": "8.0.0" + } + }, + "Newtonsoft.Json": { + "type": "Transitive", + "resolved": "13.0.1", + "contentHash": "ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==" + }, + "NHotkey": { + "type": "Transitive", + "resolved": "3.0.0", + "contentHash": "IEghs0QqWsQYH0uUmvIl0Ye6RaebWRh38eB6ToOkDnQucTYRGFOgtig0gSxlwCszTilYFz3n1ZuY762x+kDR3A==" + }, + "NLog": { + "type": "Transitive", + "resolved": "4.7.10", + "contentHash": "rcegW7kYOCjl7wX0SzsqpPBqnJ51JKi1WkYb6QBVX0Wc5IgH19Pv4t/co+T0s06OS0Ne44xgkY/mHg0PdrmJow==" + }, + "Splat": { + "type": "Transitive", + "resolved": "1.6.2", + "contentHash": "DeH0MxPU+D4JchkIDPYG4vUT+hsWs9S41cFle0/4K5EJMXWurx5DzAkj2366DfK14/XKNhsu6tCl4dZXJ3CD4w==" + }, + "squirrel.windows": { + "type": "Transitive", + "resolved": "1.5.2", + "contentHash": "89Y/CFxWm7SEOjvuV2stVa8p+SNM9GOLk4tUNm2nUF792nfkimAgwRA/umVsdyd/OXBH8byXSh4V1qck88ZAyQ==", + "dependencies": { + "DeltaCompressionDotNet": "[1.0.0, 2.0.0)", + "Mono.Cecil": "0.9.6.1", + "Splat": "1.6.2" + } + }, + "StreamJsonRpc": { + "type": "Transitive", + "resolved": "2.20.20", + "contentHash": "gwG7KViLbSWS7EI0kYevinVmIga9wZNrpSY/FnWyC6DbdjKJ1xlv/FV1L9b0rLkVP8cGxfIMexdvo/+2W5eq6Q==", + "dependencies": { + "MessagePack": "2.5.187", + "Microsoft.VisualStudio.Threading": "17.10.48", + "Microsoft.VisualStudio.Threading.Analyzers": "17.10.48", + "Microsoft.VisualStudio.Validation": "17.8.8", + "Nerdbank.Streams": "2.11.74", + "Newtonsoft.Json": "13.0.1", + "System.IO.Pipelines": "8.0.0" + } + }, + "System.Diagnostics.EventLog": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "fdYxcRjQqTTacKId/2IECojlDSFvp7LP5N78+0z/xH7v/Tuw5ZAxu23Y6PTCRinqyu2ePx+Gn1098NC6jM6d+A==" + }, + "System.Drawing.Common": { + "type": "Transitive", + "resolved": "9.0.2", + "contentHash": "JU947wzf8JbBS16Y5EIZzAlyQU+k68D7LRx6y03s2wlhlvLqkt/8uPBrjv2hJnnaJKbdb0GhQ3JZsfYXhrRjyg==", + "dependencies": { + "Microsoft.Win32.SystemEvents": "9.0.2" + } + }, + "System.IO.Pipelines": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "FHNOatmUq0sqJOkTx+UF/9YK1f180cnW5FVqnQMvYUN0elp6wFzbtPSiqbo1/ru8ICp43JM1i7kKkk6GsNGHlA==" + }, + "System.Reflection.Emit": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "VR4kk8XLKebQ4MZuKuIni/7oh+QGFmZW3qORd1GvBq/8026OpW501SzT/oypwiQl4TvT8ErnReh/NzY9u+C6wQ==" + }, + "System.Reflection.Metadata": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "5NecZgXktdGg34rh1OenY1rFNDCI8xSjFr+Z4OU4cU06AQHUdRnIIEeWENu3Wl4YowbzkymAIMvi3WyK9U53pQ==" + }, + "System.Security.AccessControl": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "IQ4NXP/B3Ayzvw0rDQzVTYsCKyy0Jp9KI6aYcK7UnGVlR9+Awz++TIPCQtPYfLJfOpm8ajowMR09V7quD3sEHw==" + }, + "System.Security.Principal.Windows": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==" + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "OP6umVGxc0Z0MvZQBVigj4/U31Pw72ITihDWP9WiWDm+q5aoe0GaJivsfYGq53o6dxH7DcXWiCTl7+0o2CGdmg==" + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "DaGSsVqKsn/ia6RG8frjwmJonfos0srquhw09TlT8KRw5I43E+4gs+/bZj4K0vShJ5H9imCuXupb4RmS+dBy3w==", + "dependencies": { + "System.Text.Encodings.Web": "7.0.0" + } + }, + "System.ValueTuple": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==" + }, + "ToolGood.Words.Pinyin": { + "type": "Transitive", + "resolved": "3.0.1.4", + "contentHash": "uQo97618y9yzLDxrnehPN+/tuiOlk5BqieEdwctHZOAS9miMXnHKgMFYVw8CSGXRglyTYXlrW7qtUlU7Fje5Ew==" + }, + "YamlDotNet": { + "type": "Transitive", + "resolved": "9.1.0", + "contentHash": "fuvGXU4Ec5HrsmEc+BiFTNPCRf1cGBI2kh/3RzMWgddM2M4ALhbSPoI3X3mhXZUD1qqQd9oSkFAtWjpz8z9eRg==" + }, + "flow.launcher.core": { + "type": "Project", + "dependencies": { + "Droplex": "[1.7.0, )", + "FSharp.Core": "[9.0.101, )", + "Flow.Launcher.Infrastructure": "[1.0.0, )", + "Flow.Launcher.Plugin": "[4.4.0, )", + "Meziantou.Framework.Win32.Jobs": "[3.4.0, )", + "Microsoft.IO.RecyclableMemoryStream": "[3.0.1, )", + "StreamJsonRpc": "[2.20.20, )", + "squirrel.windows": "[1.5.2, )" + } + }, + "flow.launcher.infrastructure": { + "type": "Project", + "dependencies": { + "Ben.Demystifier": "[0.4.1, )", + "BitFaster.Caching": "[2.5.3, )", + "CommunityToolkit.Mvvm": "[8.4.0, )", + "Flow.Launcher.Plugin": "[4.4.0, )", + "MemoryPack": "[1.21.3, )", + "Microsoft.VisualStudio.Threading": "[17.12.19, )", + "NLog": "[4.7.10, )", + "PropertyChanged.Fody": "[3.4.0, )", + "System.Drawing.Common": "[9.0.2, )", + "ToolGood.Words.Pinyin": "[3.0.1.4, )" + } + }, + "flow.launcher.plugin": { + "type": "Project", + "dependencies": { + "JetBrains.Annotations": "[2024.3.0, )", + "PropertyChanged.Fody": "[3.4.0, )" + } + } + } + } +} \ No newline at end of file From a3a819cacba667c6af5bc3dbd61e002e9b0de95b Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Fri, 28 Feb 2025 23:08:19 +0800 Subject: [PATCH 022/576] update packages.lock.json --- Flow.Launcher/packages.lock.json | 46 ++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/Flow.Launcher/packages.lock.json b/Flow.Launcher/packages.lock.json index 2768db74bde..0170650443a 100644 --- a/Flow.Launcher/packages.lock.json +++ b/Flow.Launcher/packages.lock.json @@ -26,6 +26,17 @@ "resolved": "1.0.4", "contentHash": "D0LvRCPQMX6/FJHBjng+RO+wRDuHTJrfo7IAc7rmkPvRqchdVGJWg3y70peOtDy3OLNK+HSOwVkH4GiuLnkKgA==" }, + "Jack251970.TaskScheduler": { + "type": "Direct", + "requested": "[2.12.1, )", + "resolved": "2.12.1", + "contentHash": "+epAtsLMugiznJCNRYCYB6eBcr+bx+CVlwPWMprO5CbnNkWu9mlSV8XN5BQJrGYwmlAtlGfZA3p3PcFFlrgR6A==", + "dependencies": { + "Microsoft.Win32.Registry": "5.0.0", + "System.Diagnostics.EventLog": "8.0.0", + "System.Security.AccessControl": "6.0.1" + } + }, "Microsoft.Extensions.DependencyInjection": { "type": "Direct", "requested": "[7.0.0, )", @@ -37,13 +48,13 @@ }, "Microsoft.Extensions.Hosting": { "type": "Direct", - "requested": "[7.0.0, )", - "resolved": "7.0.0", - "contentHash": "4nFc8xCfK26G524ioreZvz/IeIKN/gY1LApoGpaIThKqBdTwauUo4ETCf12lQcoefijqe3Imnfvnk31IezFatg==", + "requested": "[7.0.1, )", + "resolved": "7.0.1", + "contentHash": "aoeMou6XSW84wiqd895OdaGyO9PfH6nohQJ0XBcshRDafbdIU6PQIVl8TpOCssPYq3ciRseP5064hbFyCR9J9w==", "dependencies": { "Microsoft.Extensions.Configuration": "7.0.0", "Microsoft.Extensions.Configuration.Abstractions": "7.0.0", - "Microsoft.Extensions.Configuration.Binder": "7.0.0", + "Microsoft.Extensions.Configuration.Binder": "7.0.3", "Microsoft.Extensions.Configuration.CommandLine": "7.0.0", "Microsoft.Extensions.Configuration.EnvironmentVariables": "7.0.0", "Microsoft.Extensions.Configuration.FileExtensions": "7.0.0", @@ -61,7 +72,8 @@ "Microsoft.Extensions.Logging.Debug": "7.0.0", "Microsoft.Extensions.Logging.EventLog": "7.0.0", "Microsoft.Extensions.Logging.EventSource": "7.0.0", - "Microsoft.Extensions.Options": "7.0.0" + "Microsoft.Extensions.Options": "7.0.1", + "System.Diagnostics.DiagnosticSource": "7.0.1" } }, "Microsoft.Toolkit.Uwp.Notifications": { @@ -117,17 +129,6 @@ "resolved": "3.0.0", "contentHash": "RR+8GbPQ/gjDqov/1QN1OPoUlbUruNwcL3WjWCeLw+MY7+od/ENhnkYxCfAC6rQLIu3QifaJt3kPYyP3RumqMQ==" }, - "TaskScheduler": { - "type": "Direct", - "requested": "[2.11.0, )", - "resolved": "2.11.0", - "contentHash": "p9wH58XSNIyUtO7PIFAEldaKUzpYmlj+YWAfnUqBKnGxIZRY51I9BrsBGJijUVwlxrgmLLPUigRIv2ZTD4uPJA==", - "dependencies": { - "Microsoft.Win32.Registry": "5.0.0", - "System.Diagnostics.EventLog": "8.0.0", - "System.Security.AccessControl": "6.0.1" - } - }, "VirtualizingWrapPanel": { "type": "Direct", "requested": "[2.1.1, )", @@ -227,8 +228,8 @@ }, "Microsoft.Extensions.Configuration.Binder": { "type": "Transitive", - "resolved": "7.0.0", - "contentHash": "tgU4u7bZsoS9MKVRiotVMAwHtbREHr5/5zSEV+JPhg46+ox47Au84E3D2IacAaB0bk5ePNaNieTlPrfjbbRJkg==", + "resolved": "7.0.3", + "contentHash": "1eRFwJBrkkncTpvh6mivB8zg4uBVm6+Y6stEJERrVEqZZc8Hvf+N1iIgj2ySYDUQko4J1Gw1rLf1M8bG83F0eA==", "dependencies": { "Microsoft.Extensions.Configuration.Abstractions": "7.0.0" } @@ -405,8 +406,8 @@ }, "Microsoft.Extensions.Options": { "type": "Transitive", - "resolved": "7.0.0", - "contentHash": "lP1yBnTTU42cKpMozuafbvNtQ7QcBjr/CcK3bYOGEMH55Fjt+iecXjT6chR7vbgCMqy3PG3aNQSZgo/EuY/9qQ==", + "resolved": "7.0.1", + "contentHash": "pZRDYdN1FpepOIfHU62QoBQ6zdAoTvnjxFfqAzEd9Jhb2dfhA5i6jeTdgGgcgTWFRC7oT0+3XrbQu4LjvgX1Nw==", "dependencies": { "Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0", "Microsoft.Extensions.Primitives": "7.0.0" @@ -549,6 +550,11 @@ "System.IO.Pipelines": "8.0.0" } }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "7.0.1", + "contentHash": "T9SLFxzDp0SreCffRDXSAS5G+lq6E8qP4knHS2IBjwCdx2KEvGnGZsq7gFpselYOda7l6gXsJMD93TQsFj/URA==" + }, "System.Diagnostics.EventLog": { "type": "Transitive", "resolved": "8.0.0", From e7ec5e3dd40f0955f6da139772002d87e8a207f3 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Fri, 28 Feb 2025 23:40:23 +0800 Subject: [PATCH 023/576] remove space from the font name --- Flow.Launcher/Flow.Launcher.csproj | 2 +- ...{Segoe Fluent Icons.ttf => SegoeFluentIcons.ttf} | Bin 2 files changed, 1 insertion(+), 1 deletion(-) rename Flow.Launcher/Resources/{Segoe Fluent Icons.ttf => SegoeFluentIcons.ttf} (100%) diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj index 44c5a5f3ab5..6ab69c1d2c1 100644 --- a/Flow.Launcher/Flow.Launcher.csproj +++ b/Flow.Launcher/Flow.Launcher.csproj @@ -78,7 +78,7 @@ Designer PreserveNewest - + PreserveNewest diff --git a/Flow.Launcher/Resources/Segoe Fluent Icons.ttf b/Flow.Launcher/Resources/SegoeFluentIcons.ttf similarity index 100% rename from Flow.Launcher/Resources/Segoe Fluent Icons.ttf rename to Flow.Launcher/Resources/SegoeFluentIcons.ttf From 02662a390d4d51dcdd002cffe2e6d810936c2ff3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Mar 2025 22:13:25 +0000 Subject: [PATCH 024/576] Bump System.Data.OleDb from 8.0.1 to 9.0.3 Bumps [System.Data.OleDb](https://github.com/dotnet/runtime) from 8.0.1 to 9.0.3. - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v8.0.1...v9.0.3) --- updated-dependencies: - dependency-name: System.Data.OleDb dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .../Flow.Launcher.Plugin.Explorer.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj index 54921702730..4138381477b 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj @@ -46,7 +46,7 @@ - + From d2229f69b60ebd642f27e077846283f92a6ffc2f Mon Sep 17 00:00:00 2001 From: Kevin Zhang <45326534+taooceros@users.noreply.github.com> Date: Tue, 25 Mar 2025 22:35:20 -0500 Subject: [PATCH 025/576] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2b307e09a25..c02b93694e4 100644 --- a/README.md +++ b/README.md @@ -393,5 +393,5 @@ Get in touch if you like to join the Flow-Launcher Team and help build this grea - Install .Net 9 SDK - via Visual Studio installer - - via winget `winget install Microsoft.DotNet.SDK.7` + - via winget `winget install Microsoft.DotNet.SDK.9` - Manually from [here](https://dotnet.microsoft.com/en-us/download/dotnet/9.0) From 9e8a950580becfb5f232df40c2a73e65a5e30200 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sat, 5 Apr 2025 23:01:09 +0800 Subject: [PATCH 026/576] Fix build issue & Improve code quality --- .../PinyinAlphabet.cs | 21 +++++-------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs index e12764ed37b..a63dd99d9aa 100644 --- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs +++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs @@ -1,7 +1,5 @@ -using System; -using System.Collections.Concurrent; +using System.Collections.Concurrent; using System.Text; -using JetBrains.Annotations; using Flow.Launcher.Infrastructure.UserSettings; using ToolGood.Words.Pinyin; using System.Collections.Generic; @@ -15,11 +13,11 @@ public class PinyinAlphabet : IAlphabet private readonly ConcurrentDictionary _pinyinCache = new(); - private Settings _settings; + private readonly Settings _settings; - public void Initialize([NotNull] Settings settings) + public PinyinAlphabet() { - _settings = settings ?? throw new ArgumentNullException(nameof(settings)); + _settings = Ioc.Default.GetRequiredService(); } public bool ShouldTranslate(string stringToTranslate) @@ -109,16 +107,6 @@ public bool ShouldTranslate(string stringToTranslate) {"Sh", "u"}, {"Zh", "v"} }); - - public PinyinAlphabet() - { - Initialize(Ioc.Default.GetRequiredService()); - } - - private void Initialize([NotNull] Settings settings) - { - _settings = settings ?? throw new ArgumentNullException(nameof(settings)); - } private static readonly ReadOnlyDictionary second = new(new Dictionary() { @@ -200,6 +188,7 @@ private static string ToDoublePin(string fullPinyin) return doublePin.ToString(); } + #endregion } } From a8a305fce08c19f9e64fd450c94974d5cca17e4d Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sat, 5 Apr 2025 23:02:28 +0800 Subject: [PATCH 027/576] Improve code quality --- Flow.Launcher.Infrastructure/PinyinAlphabet.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs index a63dd99d9aa..3b24ecc2b89 100644 --- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs +++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs @@ -1,10 +1,10 @@ using System.Collections.Concurrent; -using System.Text; -using Flow.Launcher.Infrastructure.UserSettings; -using ToolGood.Words.Pinyin; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Text; using CommunityToolkit.Mvvm.DependencyInjection; +using Flow.Launcher.Infrastructure.UserSettings; +using ToolGood.Words.Pinyin; namespace Flow.Launcher.Infrastructure { @@ -52,12 +52,12 @@ public bool ShouldTranslate(string stringToTranslate) var resultList = WordsHelper.GetPinyinList(content); - StringBuilder resultBuilder = new StringBuilder(); - TranslationMapping map = new TranslationMapping(); + var resultBuilder = new StringBuilder(); + var map = new TranslationMapping(); - bool pre = false; + var pre = false; - for (int i = 0; i < resultList.Length; i++) + for (var i = 0; i < resultList.Length; i++) { if (content[i] >= 0x3400 && content[i] <= 0x9FD5) { @@ -148,7 +148,7 @@ public bool ShouldTranslate(string stringToTranslate) private static string ToDoublePin(string fullPinyin) { // Assuming s is valid - StringBuilder doublePin = new StringBuilder(); + var doublePin = new StringBuilder(); if (fullPinyin.Length <= 3 && (fullPinyin[0] == 'a' || fullPinyin[0] == 'e' || fullPinyin[0] == 'o')) { From 5be732d533278ab7ce897fd69c3cd6245741af84 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sat, 5 Apr 2025 23:04:12 +0800 Subject: [PATCH 028/576] Use var when neccessary --- Flow.Launcher.Infrastructure/PinyinAlphabet.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs index 3b24ecc2b89..7bcc7025187 100644 --- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs +++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs @@ -163,7 +163,7 @@ private static string ToDoublePin(string fullPinyin) { doublePin.Append(first[fullPinyin[..2]]); - if (second.TryGetValue(fullPinyin[2..], out string tmp)) + if (second.TryGetValue(fullPinyin[2..], out var tmp)) { doublePin.Append(tmp); } @@ -176,7 +176,7 @@ private static string ToDoublePin(string fullPinyin) { doublePin.Append(fullPinyin[0]); - if (second.TryGetValue(fullPinyin[1..], out string tmp)) + if (second.TryGetValue(fullPinyin[1..], out var tmp)) { doublePin.Append(tmp); } From 1f458d3b564a37944a7a10183fc9be5696cf2e95 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 9 Apr 2025 20:06:17 +0800 Subject: [PATCH 029/576] Fix typos & Code quality --- .../TranslationMapping.cs | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/Flow.Launcher.Infrastructure/TranslationMapping.cs b/Flow.Launcher.Infrastructure/TranslationMapping.cs index c976fc522d6..b33a094db89 100644 --- a/Flow.Launcher.Infrastructure/TranslationMapping.cs +++ b/Flow.Launcher.Infrastructure/TranslationMapping.cs @@ -8,8 +8,9 @@ public class TranslationMapping { private bool constructed; - private List originalIndexs = new List(); - private List translatedIndexs = new List(); + private readonly List originalIndexes = new(); + private readonly List translatedIndexes = new(); + private int translatedLength = 0; public void AddNewIndex(int originalIndex, int translatedIndex, int length) @@ -17,46 +18,47 @@ public void AddNewIndex(int originalIndex, int translatedIndex, int length) if (constructed) throw new InvalidOperationException("Mapping shouldn't be changed after constructed"); - originalIndexs.Add(originalIndex); - translatedIndexs.Add(translatedIndex); - translatedIndexs.Add(translatedIndex + length); + originalIndexes.Add(originalIndex); + translatedIndexes.Add(translatedIndex); + translatedIndexes.Add(translatedIndex + length); translatedLength += length - 1; } public int MapToOriginalIndex(int translatedIndex) { - if (translatedIndex > translatedIndexs.Last()) + if (translatedIndex > translatedIndexes.Last()) return translatedIndex - translatedLength - 1; int lowerBound = 0; - int upperBound = originalIndexs.Count - 1; + int upperBound = originalIndexes.Count - 1; int count = 0; // Corner case handle - if (translatedIndex < translatedIndexs[0]) + if (translatedIndex < translatedIndexes[0]) return translatedIndex; - if (translatedIndex > translatedIndexs.Last()) + + if (translatedIndex > translatedIndexes.Last()) { int indexDef = 0; - for (int k = 0; k < originalIndexs.Count; k++) + for (int k = 0; k < originalIndexes.Count; k++) { - indexDef += translatedIndexs[k * 2 + 1] - translatedIndexs[k * 2]; + indexDef += translatedIndexes[k * 2 + 1] - translatedIndexes[k * 2]; } return translatedIndex - indexDef - 1; } // Binary Search with Range - for (int i = originalIndexs.Count / 2;; count++) + for (int i = originalIndexes.Count / 2;; count++) { - if (translatedIndex < translatedIndexs[i * 2]) + if (translatedIndex < translatedIndexes[i * 2]) { // move to lower middle upperBound = i; i = (i + lowerBound) / 2; } - else if (translatedIndex > translatedIndexs[i * 2 + 1] - 1) + else if (translatedIndex > translatedIndexes[i * 2 + 1] - 1) { lowerBound = i; // move to upper middle @@ -64,17 +66,19 @@ public int MapToOriginalIndex(int translatedIndex) i = (i + upperBound + 1) / 2; } else - return originalIndexs[i]; + { + return originalIndexes[i]; + } if (upperBound - lowerBound <= 1 && - translatedIndex > translatedIndexs[lowerBound * 2 + 1] && - translatedIndex < translatedIndexs[upperBound * 2]) + translatedIndex > translatedIndexes[lowerBound * 2 + 1] && + translatedIndex < translatedIndexes[upperBound * 2]) { int indexDef = 0; for (int j = 0; j < upperBound; j++) { - indexDef += translatedIndexs[j * 2 + 1] - translatedIndexs[j * 2]; + indexDef += translatedIndexes[j * 2 + 1] - translatedIndexes[j * 2]; } return translatedIndex - indexDef - 1; From 4b7db3cbd62233323bccfdd2188f28e8b6434a43 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 10 Apr 2025 09:36:47 +0800 Subject: [PATCH 030/576] Make function static --- Flow.Launcher.Infrastructure/StringMatcher.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs index 7045517f585..2882cb8f03e 100644 --- a/Flow.Launcher.Infrastructure/StringMatcher.cs +++ b/Flow.Launcher.Infrastructure/StringMatcher.cs @@ -228,7 +228,7 @@ public MatchResult FuzzyMatch(string query, string stringToCompare, MatchOption return new MatchResult(false, UserSettingSearchPrecision); } - private bool IsAcronym(string stringToCompare, int compareStringIndex) + private static bool IsAcronym(string stringToCompare, int compareStringIndex) { if (IsAcronymChar(stringToCompare, compareStringIndex) || IsAcronymNumber(stringToCompare, compareStringIndex)) return true; @@ -237,7 +237,7 @@ private bool IsAcronym(string stringToCompare, int compareStringIndex) } // When counting acronyms, treat a set of numbers as one acronym ie. Visual 2019 as 2 acronyms instead of 5 - private bool IsAcronymCount(string stringToCompare, int compareStringIndex) + private static bool IsAcronymCount(string stringToCompare, int compareStringIndex) { if (IsAcronymChar(stringToCompare, compareStringIndex)) return true; From f5fd6b569ca8466fe4922aa1bd975622217c81ee Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 10 Apr 2025 09:56:27 +0800 Subject: [PATCH 031/576] Use ReadOnlySpan instead --- .../PinyinAlphabet.cs | 43 ++++++++++++------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs index 7bcc7025187..1637a285c3f 100644 --- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs +++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs @@ -1,4 +1,5 @@ -using System.Collections.Concurrent; +using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Text; @@ -148,9 +149,11 @@ public bool ShouldTranslate(string stringToTranslate) private static string ToDoublePin(string fullPinyin) { // Assuming s is valid + var fullPinyinSpan = fullPinyin.AsSpan(); var doublePin = new StringBuilder(); - if (fullPinyin.Length <= 3 && (fullPinyin[0] == 'a' || fullPinyin[0] == 'e' || fullPinyin[0] == 'o')) + // Handle special cases (a, o, e) + if (fullPinyin.Length <= 3 && (fullPinyinSpan[0] == 'a' || fullPinyinSpan[0] == 'e' || fullPinyinSpan[0] == 'o')) { if (special.TryGetValue(fullPinyin, out var value)) { @@ -158,31 +161,41 @@ private static string ToDoublePin(string fullPinyin) } } - // zh, ch, sh - if (fullPinyin.Length >= 2 && first.ContainsKey(fullPinyin[..2])) + // Check for initials that are two characters long (zh, ch, sh) + if (fullPinyin.Length >= 2) { - doublePin.Append(first[fullPinyin[..2]]); - - if (second.TryGetValue(fullPinyin[2..], out var tmp)) - { - doublePin.Append(tmp); - } - else + var firstTwo = fullPinyinSpan[..2]; + var firstTwoString = firstTwo.ToString(); + if (first.ContainsKey(firstTwoString)) { - doublePin.Append(fullPinyin[2..]); + doublePin.Append(firstTwoString); + + var lastTwo = fullPinyinSpan[2..]; + var lastTwoString = lastTwo.ToString(); + if (second.TryGetValue(lastTwoString, out var tmp)) + { + doublePin.Append(tmp); + } + else + { + doublePin.Append(lastTwo); + } } } + // Handle single-character initials else { - doublePin.Append(fullPinyin[0]); + doublePin.Append(fullPinyinSpan[0]); - if (second.TryGetValue(fullPinyin[1..], out var tmp)) + var lastOne = fullPinyinSpan[1..]; + var lastOneString = lastOne.ToString(); + if (second.TryGetValue(lastOneString, out var tmp)) { doublePin.Append(tmp); } else { - doublePin.Append(fullPinyin[1..]); + doublePin.Append(lastOne); } } From 8aa36f38c82a388c386d7e3d86c44798dad632ad Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Tue, 13 May 2025 21:50:13 +0800 Subject: [PATCH 032/576] Add ShowAtTopmost in settings --- .../UserSettings/Settings.cs | 38 +++++++++++++++---- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index 34bf4f90e5c..3f382c276aa 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -59,8 +59,11 @@ public string Language get => _language; set { - _language = value; - OnPropertyChanged(); + if (_language != value) + { + _language = value; + OnPropertyChanged(); + } } } public string Theme @@ -68,7 +71,7 @@ public string Theme get => _theme; set { - if (value != _theme) + if (_theme != value) { _theme = value; OnPropertyChanged(); @@ -283,9 +286,12 @@ public SearchPrecisionScore QuerySearchPrecision get => _querySearchPrecision; set { - _querySearchPrecision = value; - if (_stringMatcher != null) - _stringMatcher.UserSettingSearchPrecision = value; + if (_querySearchPrecision != value) + { + _querySearchPrecision = value; + if (_stringMatcher != null) + _stringMatcher.UserSettingSearchPrecision = value; + } } } @@ -348,12 +354,28 @@ public bool HideNotifyIcon get => _hideNotifyIcon; set { - _hideNotifyIcon = value; - OnPropertyChanged(); + if (_hideNotifyIcon != value) + { + _hideNotifyIcon = value; + OnPropertyChanged(); + } } } public bool LeaveCmdOpen { get; set; } public bool HideWhenDeactivated { get; set; } = true; + private bool _showAtTopmost; + public bool ShowAtTopmost + { + get => _showAtTopmost; + set + { + if (_showAtTopmost != value) + { + _showAtTopmost = value; + OnPropertyChanged(); + } + } + } public bool SearchQueryResultsWithDelay { get; set; } public int SearchDelayTime { get; set; } = 150; From 587ab629aa9b831ba8ed684eb2039dbba6b28ff1 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Tue, 13 May 2025 21:54:03 +0800 Subject: [PATCH 033/576] Support changing ShowAtTopmost --- Flow.Launcher/MainWindow.xaml.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index 46eeb2adc6e..72a990ada70 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -84,6 +84,8 @@ public MainWindow() _viewModel = Ioc.Default.GetRequiredService(); DataContext = _viewModel; + Topmost = _settings.ShowAtTopmost; + InitializeComponent(); UpdatePosition(); @@ -283,6 +285,9 @@ private async void OnLoaded(object sender, RoutedEventArgs _) _viewModel.QueryResults(); } break; + case nameof(Settings.ShowAtTopmost): + Topmost = _settings.ShowAtTopmost; + break; } }; From 4e88ce3f48b9eae47dc57c595acfe7862b540476 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Tue, 13 May 2025 22:01:36 +0800 Subject: [PATCH 034/576] Set ShowAtTopmost default to true --- Flow.Launcher.Infrastructure/UserSettings/Settings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index 3f382c276aa..7cd3821dc0b 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -363,7 +363,7 @@ public bool HideNotifyIcon } public bool LeaveCmdOpen { get; set; } public bool HideWhenDeactivated { get; set; } = true; - private bool _showAtTopmost; + private bool _showAtTopmost = true; public bool ShowAtTopmost { get => _showAtTopmost; From b8f743eb4c2ad44bc89366698a6ee8543d1d5343 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Tue, 13 May 2025 22:06:04 +0800 Subject: [PATCH 035/576] Add ui in general setting page --- Flow.Launcher/Languages/en.xaml | 2 ++ .../SettingPages/Views/SettingsPaneGeneral.xaml | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 22ab2016cc0..f728f10955e 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -131,6 +131,8 @@ Show History Results in Home Page Maximum History Results Shown in Home Page This can only be edited if plugin supports Home feature and Home Page is enabled. + Show Search Window at Topmost + Show search window above other windows Search Plugin diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml index c0c5613de04..fba1b3d865e 100644 --- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml +++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml @@ -77,6 +77,17 @@ OnContent="{DynamicResource enable}" /> + + + + From b636f253e65114639dca2aa7d14271d013a993a6 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Tue, 13 May 2025 22:52:06 +0800 Subject: [PATCH 036/576] Add blank line --- Flow.Launcher.Infrastructure/UserSettings/Settings.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index 7cd3821dc0b..8dc48f7f24e 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -363,6 +363,7 @@ public bool HideNotifyIcon } public bool LeaveCmdOpen { get; set; } public bool HideWhenDeactivated { get; set; } = true; + private bool _showAtTopmost = true; public bool ShowAtTopmost { From f7f52e269a8f0aa7883169c82425fd9738a8dc7f Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 21 May 2025 14:31:09 +0800 Subject: [PATCH 037/576] Set culture info before creating application --- .../Resource/Internationalization.cs | 34 ++++++---- .../UserSettings/Settings.cs | 13 +++- Flow.Launcher/App.xaml.cs | 62 ++++++++++++------- 3 files changed, 71 insertions(+), 38 deletions(-) diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs index b32b09e8fc8..3329e3a96b0 100644 --- a/Flow.Launcher.Core/Resource/Internationalization.cs +++ b/Flow.Launcher.Core/Resource/Internationalization.cs @@ -1,16 +1,17 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Reflection; +using System.Threading; +using System.Threading.Tasks; using System.Windows; +using CommunityToolkit.Mvvm.DependencyInjection; using Flow.Launcher.Core.Plugin; using Flow.Launcher.Infrastructure; using Flow.Launcher.Infrastructure.UserSettings; using Flow.Launcher.Plugin; -using System.Globalization; -using System.Threading.Tasks; -using CommunityToolkit.Mvvm.DependencyInjection; namespace Flow.Launcher.Core.Resource { @@ -29,13 +30,12 @@ public class Internationalization private readonly Settings _settings; private readonly List _languageDirectories = new(); private readonly List _oldResources = new(); - private readonly string SystemLanguageCode; + private static string SystemLanguageCode; public Internationalization(Settings settings) { _settings = settings; AddFlowLauncherLanguageDirectory(); - SystemLanguageCode = GetSystemLanguageCodeAtStartup(); } private void AddFlowLauncherLanguageDirectory() @@ -44,7 +44,7 @@ private void AddFlowLauncherLanguageDirectory() _languageDirectories.Add(directory); } - private static string GetSystemLanguageCodeAtStartup() + public static void InitSystemLanguageCode() { var availableLanguages = AvailableLanguages.GetAvailableLanguages(); @@ -65,11 +65,11 @@ private static string GetSystemLanguageCodeAtStartup() string.Equals(languageCode, threeLetterCode, StringComparison.OrdinalIgnoreCase) || string.Equals(languageCode, fullName, StringComparison.OrdinalIgnoreCase)) { - return languageCode; + SystemLanguageCode = languageCode; } } - return DefaultLanguageCode; + SystemLanguageCode = DefaultLanguageCode; } private void AddPluginLanguageDirectories() @@ -173,15 +173,25 @@ private async Task ChangeLanguageAsync(Language language) LoadLanguage(language); } - // Culture of main thread - // Use CreateSpecificCulture to preserve possible user-override settings in Windows, if Flow's language culture is the same as Windows's - CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture(language.LanguageCode); - CultureInfo.CurrentUICulture = CultureInfo.CurrentCulture; + // Change culture info + ChangeCultureInfo(language.LanguageCode); // Raise event for plugins after culture is set await Task.Run(UpdatePluginMetadataTranslations); } + public static void ChangeCultureInfo(string languageCode) + { + // Culture of main thread + // Use CreateSpecificCulture to preserve possible user-override settings in Windows, if Flow's language culture is the same as Windows's + var currentCulture = CultureInfo.CreateSpecificCulture(languageCode); + CultureInfo.CurrentCulture = currentCulture; + CultureInfo.CurrentUICulture = currentCulture; + var thread = Thread.CurrentThread; + thread.CurrentCulture = currentCulture; + thread.CurrentUICulture = currentCulture; + } + public bool PromptShouldUsePinyin(string languageCodeToSet) { var languageToSet = GetLanguageByLanguageCode(languageCodeToSet); diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index 027eb3f926d..7933d08ea34 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -25,7 +25,13 @@ public void SetStorage(FlowLauncherJsonStorage storage) public void Initialize() { + // Initialize dependency injection instances after Ioc.Default is created _stringMatcher = Ioc.Default.GetRequiredService(); + + // Initialize application resources after application is created + var settingWindowFont = new FontFamily(SettingWindowFont); + Application.Current.Resources["SettingWindowFont"] = settingWindowFont; + Application.Current.Resources["ContentControlThemeFontFamily"] = settingWindowFont; } public void Save() @@ -114,8 +120,11 @@ public string SettingWindowFont { _settingWindowFont = value; OnPropertyChanged(); - Application.Current.Resources["SettingWindowFont"] = new FontFamily(value); - Application.Current.Resources["ContentControlThemeFontFamily"] = new FontFamily(value); + if (Application.Current != null) + { + Application.Current.Resources["SettingWindowFont"] = new FontFamily(value); + Application.Current.Resources["ContentControlThemeFontFamily"] = new FontFamily(value); + } } } } diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs index 942e9447037..fd64ad3e0b1 100644 --- a/Flow.Launcher/App.xaml.cs +++ b/Flow.Launcher/App.xaml.cs @@ -41,9 +41,9 @@ public partial class App : IDisposable, ISingleInstanceApp private static readonly string ClassName = nameof(App); private static bool _disposed; + private static Settings _settings; private static MainWindow _mainWindow; private readonly MainViewModel _mainVM; - private readonly Settings _settings; // To prevent two disposals running at the same time. private static readonly object _disposingLock = new(); @@ -55,19 +55,7 @@ public partial class App : IDisposable, ISingleInstanceApp public App() { // Initialize settings - try - { - var storage = new FlowLauncherJsonStorage(); - _settings = storage.Load(); - _settings.SetStorage(storage); - _settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled(); - } - catch (Exception e) - { - ShowErrorMsgBoxAndFailFast("Cannot load setting storage, please check local data directory", e); - return; - } - + _settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled(); // Configure the dependency injection container try { @@ -119,16 +107,6 @@ public App() ShowErrorMsgBoxAndFailFast("Cannot initialize api and settings, please open new issue in Flow.Launcher", e); return; } - - // Local function - static void ShowErrorMsgBoxAndFailFast(string message, Exception e) - { - // Firstly show users the message - MessageBox.Show(e.ToString(), message, MessageBoxButton.OK, MessageBoxImage.Error); - - // Flow cannot construct its App instance, so ensure Flow crashes w/ the exception info. - Environment.FailFast(message, e); - } } #endregion @@ -138,6 +116,29 @@ static void ShowErrorMsgBoxAndFailFast(string message, Exception e) [STAThread] public static void Main() { + // Initialize settings so that we can get language code + try + { + var storage = new FlowLauncherJsonStorage(); + _settings = storage.Load(); + _settings.SetStorage(storage); + } + catch (Exception e) + { + ShowErrorMsgBoxAndFailFast("Cannot load setting storage, please check local data directory", e); + return; + } + + // Initialize system language before changing culture info + Internationalization.InitSystemLanguageCode(); + + // Change culture info before application creation to localize WinForm windows + if (_settings.Language != Constant.SystemLanguageCode) + { + Internationalization.ChangeCultureInfo(_settings.Language); + } + + // Start the application as a single instance if (SingleInstance.InitializeAsFirstInstance()) { using var application = new App(); @@ -148,6 +149,19 @@ public static void Main() #endregion + #region Fail Fast + + private static void ShowErrorMsgBoxAndFailFast(string message, Exception e) + { + // Firstly show users the message + MessageBox.Show(e.ToString(), message, MessageBoxButton.OK, MessageBoxImage.Error); + + // Flow cannot construct its App instance, so ensure Flow crashes w/ the exception info. + Environment.FailFast(message, e); + } + + #endregion + #region App Events #pragma warning disable VSTHRD100 // Avoid async void methods From b0997449c17117214a246c537b2472db5fb88596 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 21 May 2025 14:38:15 +0800 Subject: [PATCH 038/576] Handle CultureNotFoundException --- Flow.Launcher.Core/Resource/Internationalization.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs index 3329e3a96b0..24edc5ed8fe 100644 --- a/Flow.Launcher.Core/Resource/Internationalization.cs +++ b/Flow.Launcher.Core/Resource/Internationalization.cs @@ -184,7 +184,15 @@ public static void ChangeCultureInfo(string languageCode) { // Culture of main thread // Use CreateSpecificCulture to preserve possible user-override settings in Windows, if Flow's language culture is the same as Windows's - var currentCulture = CultureInfo.CreateSpecificCulture(languageCode); + CultureInfo currentCulture; + try + { + currentCulture = CultureInfo.CreateSpecificCulture(languageCode); + } + catch (CultureNotFoundException) + { + currentCulture = CultureInfo.CreateSpecificCulture(SystemLanguageCode); + } CultureInfo.CurrentCulture = currentCulture; CultureInfo.CurrentUICulture = currentCulture; var thread = Thread.CurrentThread; From 949344a51e9062828e800149adb91165cc8882c3 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 22 May 2025 17:32:33 +0800 Subject: [PATCH 039/576] Add internal model for plugin management --- .../UserSettings/Settings.cs | 2 + Flow.Launcher/Languages/en.xaml | 18 ++ .../Views/SettingsPaneGeneral.xaml | 11 + .../ViewModel/PluginStoreItemViewModel.cs | 270 ++++++++++++++++-- Flow.Launcher/ViewModel/PluginViewModel.cs | 23 +- 5 files changed, 280 insertions(+), 44 deletions(-) diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index ce1269a2995..024e727ce7f 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -176,6 +176,8 @@ public bool ShowHomePage public bool ShowHistoryResultsForHomePage { get; set; } = false; public int MaxHistoryResultsToShowForHomePage { get; set; } = 5; + public bool AutoRestartAfterChanging { get; set; } = false; + public int CustomExplorerIndex { get; set; } = 0; [JsonIgnore] diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 22ab2016cc0..24f74e15daa 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -131,6 +131,8 @@ Show History Results in Home Page Maximum History Results Shown in Home Page This can only be edited if plugin supports Home feature and Home Page is enabled. + Automatically restart after changing plugins + Automatically restart Flow Launcher after installing/uninstalling/updating plugins Search Plugin @@ -184,6 +186,22 @@ New Version This plugin has been updated within the last 7 days New Update is Available + Error installing plugin + Error uninstalling plugin + Error updating plugin + Keep plugin settings + Do you want to keep the settings of the plugin for the next usage? + Plugin {0} successfully installed. Please restart Flow. + Plugin {0} successfully uninstalled. Please restart Flow. + Plugin {0} successfully updated. Please restart Flow. + Plugin install + {0} by {1} {2}{2}Would you like to install this plugin? + Plugin uninstall + {0} by {1} {2}{2}Would you like to uninstall this plugin? + Plugin udpate + {0} by {1} {2}{2}Would you like to update this plugin? + Downloading plugin + Automatically restart after installing/uninstalling/updating plugins in plugin store Theme diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml index c0c5613de04..452e026d703 100644 --- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml +++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml @@ -202,6 +202,17 @@ + + + + PluginManager.GetPluginForId("9f8f9b14-2518-4907-b211-35ab6290dee7"); + private static readonly string ClassName = nameof(PluginStoreItemViewModel); + + private static readonly Settings Settings = Ioc.Default.GetRequiredService(); + + private readonly UserPlugin _newPlugin; + private readonly PluginPair _oldPluginPair; + public PluginStoreItemViewModel(UserPlugin plugin) { - _plugin = plugin; + _newPlugin = plugin; + _oldPluginPair = PluginManager.GetPluginForId(plugin.ID); } - private UserPlugin _plugin; - - public string ID => _plugin.ID; - public string Name => _plugin.Name; - public string Description => _plugin.Description; - public string Author => _plugin.Author; - public string Version => _plugin.Version; - public string Language => _plugin.Language; - public string Website => _plugin.Website; - public string UrlDownload => _plugin.UrlDownload; - public string UrlSourceCode => _plugin.UrlSourceCode; - public string IcoPath => _plugin.IcoPath; + public string ID => _newPlugin.ID; + public string Name => _newPlugin.Name; + public string Description => _newPlugin.Description; + public string Author => _newPlugin.Author; + public string Version => _newPlugin.Version; + public string Language => _newPlugin.Language; + public string Website => _newPlugin.Website; + public string UrlDownload => _newPlugin.UrlDownload; + public string UrlSourceCode => _newPlugin.UrlSourceCode; + public string IcoPath => _newPlugin.IcoPath; - public bool LabelInstalled => PluginManager.GetPluginForId(_plugin.ID) != null; - public bool LabelUpdate => LabelInstalled && new Version(_plugin.Version) > new Version(PluginManager.GetPluginForId(_plugin.ID).Metadata.Version); + public bool LabelInstalled => _oldPluginPair != null; + public bool LabelUpdate => LabelInstalled && new Version(_newPlugin.Version) > new Version(_oldPluginPair.Metadata.Version); internal const string None = "None"; internal const string RecentlyUpdated = "RecentlyUpdated"; @@ -41,15 +51,15 @@ public string Category get { string category = None; - if (DateTime.Now - _plugin.LatestReleaseDate < TimeSpan.FromDays(7)) + if (DateTime.Now - _newPlugin.LatestReleaseDate < TimeSpan.FromDays(7)) { category = RecentlyUpdated; } - if (DateTime.Now - _plugin.DateAdded < TimeSpan.FromDays(7)) + if (DateTime.Now - _newPlugin.DateAdded < TimeSpan.FromDays(7)) { category = NewRelease; } - if (PluginManager.GetPluginForId(_plugin.ID) != null) + if (_oldPluginPair != null) { category = Installed; } @@ -59,11 +69,223 @@ public string Category } [RelayCommand] - private void ShowCommandQuery(string action) + private async Task ShowCommandQueryAsync(string action) + { + switch (action) + { + case "install": + await InstallPluginAsync(_newPlugin); + break; + case "uninstall": + await UninstallPluginAsync(_oldPluginPair.Metadata); + break; + case "update": + await UpdatePluginAsync(_newPlugin, _oldPluginPair.Metadata); + break; + } + } + + internal static async Task InstallPluginAsync(UserPlugin newPlugin) + { + if (App.API.ShowMsgBox( + string.Format( + App.API.GetTranslation("InstallPromptSubtitle"), + newPlugin.Name, newPlugin.Author, Environment.NewLine), + App.API.GetTranslation("InstallPromptTitle"), + button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return; + + try + { + // at minimum should provide a name, but handle plugin that is not downloaded from plugins manifest and is a url download + var downloadFilename = string.IsNullOrEmpty(newPlugin.Version) + ? $"{newPlugin.Name}-{Guid.NewGuid()}.zip" + : $"{newPlugin.Name}-{newPlugin.Version}.zip"; + + var filePath = Path.Combine(Path.GetTempPath(), downloadFilename); + + using var cts = new CancellationTokenSource(); + + if (!newPlugin.IsFromLocalInstallPath) + { + await DownloadFileAsync( + $"{App.API.GetTranslation("DownloadingPlugin")} {newPlugin.Name}", + newPlugin.UrlDownload, filePath, cts); + } + else + { + filePath = newPlugin.LocalInstallPath; + } + + // check if user cancelled download before installing plugin + if (cts.IsCancellationRequested) + { + return; + } + else + { + if (!File.Exists(filePath)) + { + throw new FileNotFoundException($"Plugin {newPlugin.ID} zip file not found at {filePath}", filePath); + } + + App.API.InstallPlugin(newPlugin, filePath); + + if (!newPlugin.IsFromLocalInstallPath) + { + File.Delete(filePath); + } + } + } + catch (Exception e) + { + App.API.LogException(ClassName, "Failed to install plugin", e); + App.API.ShowMsgError(App.API.GetTranslation("ErrorInstallingPlugin")); + } + + if (Settings.AutoRestartAfterChanging) + { + App.API.RestartApp(); + } + else + { + App.API.ShowMsg( + App.API.GetTranslation("installbtn"), + string.Format( + App.API.GetTranslation( + "InstallSuccessNoRestart"), + newPlugin.Name)); + } + } + + internal static async Task UninstallPluginAsync(PluginMetadata oldPlugin) { - var actionKeyword = PluginManagerData.Metadata.ActionKeywords.Any() ? PluginManagerData.Metadata.ActionKeywords[0] + " " : String.Empty; - App.API.ChangeQuery($"{actionKeyword}{action} {_plugin.Name}"); - App.API.ShowMainWindow(); + if (App.API.ShowMsgBox( + string.Format( + App.API.GetTranslation("UninstallPromptSubtitle"), + oldPlugin.Name, oldPlugin.Author, Environment.NewLine), + App.API.GetTranslation("UninstallPromptTitle"), + button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return; + + var removePluginSettings = App.API.ShowMsgBox( + App.API.GetTranslation("KeepPluginSettingsSubtitle"), + App.API.GetTranslation("KeepPluginSettingsTitle"), + button: MessageBoxButton.YesNo) == MessageBoxResult.No; + + try + { + await App.API.UninstallPluginAsync(oldPlugin, removePluginSettings); + } + catch (Exception e) + { + App.API.LogException(ClassName, "Failed to uninstall plugin", e); + App.API.ShowMsgError(App.API.GetTranslation("ErrorUninstallingPlugin")); + } + + if (Settings.AutoRestartAfterChanging) + { + App.API.RestartApp(); + } + else + { + App.API.ShowMsg( + App.API.GetTranslation("uninstallbtn"), + string.Format( + App.API.GetTranslation( + "UninstallSuccessNoRestart"), + oldPlugin.Name)); + } + } + + internal static async Task UpdatePluginAsync(UserPlugin newPlugin, PluginMetadata oldPlugin) + { + if (App.API.ShowMsgBox( + string.Format( + App.API.GetTranslation("UpdatePromptSubtitle"), + oldPlugin.Name, oldPlugin.Author, Environment.NewLine), + App.API.GetTranslation("UpdatePromptTitle"), + button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return; + + try + { + var filePath = Path.Combine(Path.GetTempPath(), $"{newPlugin.Name}-{newPlugin.Version}.zip"); + + using var cts = new CancellationTokenSource(); + + if (!newPlugin.IsFromLocalInstallPath) + { + await DownloadFileAsync( + $"{App.API.GetTranslation("DownloadingPlugin")} {newPlugin.Name}", + newPlugin.UrlDownload, filePath, cts); + } + else + { + filePath = newPlugin.LocalInstallPath; + } + + // check if user cancelled download before installing plugin + if (cts.IsCancellationRequested) + { + return; + } + else + { + await App.API.UpdatePluginAsync(oldPlugin, newPlugin, filePath); + } + } + catch (Exception e) + { + App.API.LogException(ClassName, "Failed to update plugin", e); + App.API.ShowMsgError(App.API.GetTranslation("ErrorUpdatingPlugin")); + } + + if (Settings.AutoRestartAfterChanging) + { + App.API.RestartApp(); + } + else + { + App.API.ShowMsg( + App.API.GetTranslation("updatebtn"), + string.Format( + App.API.GetTranslation( + "UpdateSuccessNoRestart"), + newPlugin.Name)); + } + } + + private static async Task DownloadFileAsync(string prgBoxTitle, string downloadUrl, string filePath, CancellationTokenSource cts, bool deleteFile = true, bool showProgress = true) + { + if (deleteFile && File.Exists(filePath)) + File.Delete(filePath); + + if (showProgress) + { + var exceptionHappened = false; + await App.API.ShowProgressBoxAsync(prgBoxTitle, + async (reportProgress) => + { + if (reportProgress == null) + { + // when reportProgress is null, it means there is expcetion with the progress box + // so we record it with exceptionHappened and return so that progress box will close instantly + exceptionHappened = true; + return; + } + else + { + await App.API.HttpDownloadAsync(downloadUrl, filePath, reportProgress, cts.Token).ConfigureAwait(false); + } + }, cts.Cancel); + + // if exception happened while downloading and user does not cancel downloading, + // we need to redownload the plugin + if (exceptionHappened && (!cts.IsCancellationRequested)) + await App.API.HttpDownloadAsync(downloadUrl, filePath, token: cts.Token).ConfigureAwait(false); + } + else + { + await App.API.HttpDownloadAsync(downloadUrl, filePath, token: cts.Token).ConfigureAwait(false); + } } } } diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs index 01fa3d20326..bda05a02d80 100644 --- a/Flow.Launcher/ViewModel/PluginViewModel.cs +++ b/Flow.Launcher/ViewModel/PluginViewModel.cs @@ -1,5 +1,4 @@ -using System.Linq; -using System.Threading.Tasks; +using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Media; @@ -32,21 +31,6 @@ public PluginPair PluginPair } } - private static string PluginManagerActionKeyword - { - get - { - var keyword = PluginManager - .GetPluginForId("9f8f9b14-2518-4907-b211-35ab6290dee7") - .Metadata.ActionKeywords.FirstOrDefault(); - return keyword switch - { - null or "*" => string.Empty, - _ => keyword - }; - } - } - private async Task LoadIconAsync() { Image = await App.API.LoadImageAsync(PluginPair.Metadata.IcoPath); @@ -186,10 +170,9 @@ private void OpenSourceCodeLink() } [RelayCommand] - private void OpenDeletePluginWindow() + private async Task OpenDeletePluginWindowAsync() { - App.API.ChangeQuery($"{PluginManagerActionKeyword} uninstall {PluginPair.Metadata.Name}".Trim(), true); - App.API.ShowMainWindow(); + await PluginStoreItemViewModel.UninstallPluginAsync(PluginPair.Metadata); } [RelayCommand] From 76736b785091873534770d4806572f2641f20adf Mon Sep 17 00:00:00 2001 From: Jack Ye <1160210343@qq.com> Date: Thu, 22 May 2025 17:37:27 +0800 Subject: [PATCH 040/576] Fix typo Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- Flow.Launcher/Languages/en.xaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 24f74e15daa..2166bdd8c30 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -198,7 +198,7 @@ {0} by {1} {2}{2}Would you like to install this plugin? Plugin uninstall {0} by {1} {2}{2}Would you like to uninstall this plugin? - Plugin udpate + Plugin update {0} by {1} {2}{2}Would you like to update this plugin? Downloading plugin Automatically restart after installing/uninstalling/updating plugins in plugin store From c6c7ff882e6745216c828559191966753553e839 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 22 May 2025 17:40:26 +0800 Subject: [PATCH 041/576] Handle default --- Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs index 3e823d635b4..a69c0dbd795 100644 --- a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs +++ b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs @@ -82,6 +82,8 @@ private async Task ShowCommandQueryAsync(string action) case "update": await UpdatePluginAsync(_newPlugin, _oldPluginPair.Metadata); break; + default: + break; } } From 6044f87e806c97cd96f9d62beb6fb3a868ba1efe Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 22 May 2025 17:41:13 +0800 Subject: [PATCH 042/576] Do not restart on failure --- Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs index a69c0dbd795..6b2cf6eed50 100644 --- a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs +++ b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs @@ -142,6 +142,7 @@ await DownloadFileAsync( { App.API.LogException(ClassName, "Failed to install plugin", e); App.API.ShowMsgError(App.API.GetTranslation("ErrorInstallingPlugin")); + return; // don’t restart on failure } if (Settings.AutoRestartAfterChanging) @@ -181,6 +182,7 @@ internal static async Task UninstallPluginAsync(PluginMetadata oldPlugin) { App.API.LogException(ClassName, "Failed to uninstall plugin", e); App.API.ShowMsgError(App.API.GetTranslation("ErrorUninstallingPlugin")); + return; // don’t restart on failure } if (Settings.AutoRestartAfterChanging) @@ -238,6 +240,7 @@ await DownloadFileAsync( { App.API.LogException(ClassName, "Failed to update plugin", e); App.API.ShowMsgError(App.API.GetTranslation("ErrorUpdatingPlugin")); + return; // don’t restart on failure } if (Settings.AutoRestartAfterChanging) From 383c0aeffc9afc1351f3c008d62aa0915ddc0da4 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 23 May 2025 13:41:59 +0800 Subject: [PATCH 043/576] Improve code quality --- Flow.Launcher.Core/Plugin/PluginManager.cs | 209 +++++++++++++++++ .../ViewModel/PluginStoreItemViewModel.cs | 221 +----------------- Flow.Launcher/ViewModel/PluginViewModel.cs | 2 +- 3 files changed, 213 insertions(+), 219 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs index aae8dd76419..5b14ad0b762 100644 --- a/Flow.Launcher.Core/Plugin/PluginManager.cs +++ b/Flow.Launcher.Core/Plugin/PluginManager.cs @@ -6,6 +6,7 @@ using System.Text.Json; using System.Threading; using System.Threading.Tasks; +using System.Windows; using CommunityToolkit.Mvvm.DependencyInjection; using Flow.Launcher.Core.ExternalPlugins; using Flow.Launcher.Infrastructure; @@ -24,6 +25,8 @@ public static class PluginManager { private static readonly string ClassName = nameof(PluginManager); + private static readonly Settings FlowSettings = Ioc.Default.GetRequiredService(); + private static IEnumerable _contextMenuPlugins; private static IEnumerable _homePlugins; @@ -547,6 +550,177 @@ public static async Task UninstallPluginAsync(PluginMetadata plugin, bool remove await UninstallPluginAsync(plugin, removePluginFromSettings, removePluginSettings, true); } + public static async Task InstallPluginAndCheckRestartAsync(UserPlugin newPlugin) + { + if (API.ShowMsgBox( + string.Format( + API.GetTranslation("InstallPromptSubtitle"), + newPlugin.Name, newPlugin.Author, Environment.NewLine), + API.GetTranslation("InstallPromptTitle"), + button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return; + + try + { + // at minimum should provide a name, but handle plugin that is not downloaded from plugins manifest and is a url download + var downloadFilename = string.IsNullOrEmpty(newPlugin.Version) + ? $"{newPlugin.Name}-{Guid.NewGuid()}.zip" + : $"{newPlugin.Name}-{newPlugin.Version}.zip"; + + var filePath = Path.Combine(Path.GetTempPath(), downloadFilename); + + using var cts = new CancellationTokenSource(); + + if (!newPlugin.IsFromLocalInstallPath) + { + await DownloadFileAsync( + $"{API.GetTranslation("DownloadingPlugin")} {newPlugin.Name}", + newPlugin.UrlDownload, filePath, cts); + } + else + { + filePath = newPlugin.LocalInstallPath; + } + + // check if user cancelled download before installing plugin + if (cts.IsCancellationRequested) + { + return; + } + else + { + if (!File.Exists(filePath)) + { + throw new FileNotFoundException($"Plugin {newPlugin.ID} zip file not found at {filePath}", filePath); + } + + API.InstallPlugin(newPlugin, filePath); + + if (!newPlugin.IsFromLocalInstallPath) + { + File.Delete(filePath); + } + } + } + catch (Exception e) + { + API.LogException(ClassName, "Failed to install plugin", e); + API.ShowMsgError(API.GetTranslation("ErrorInstallingPlugin")); + return; // don’t restart on failure + } + + if (FlowSettings.AutoRestartAfterChanging) + { + API.RestartApp(); + } + else + { + API.ShowMsg( + API.GetTranslation("installbtn"), + string.Format( + API.GetTranslation( + "InstallSuccessNoRestart"), + newPlugin.Name)); + } + } + + public static async Task UninstallPluginAndCheckRestartAsync(PluginMetadata oldPlugin) + { + if (API.ShowMsgBox( + string.Format( + API.GetTranslation("UninstallPromptSubtitle"), + oldPlugin.Name, oldPlugin.Author, Environment.NewLine), + API.GetTranslation("UninstallPromptTitle"), + button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return; + + var removePluginSettings = API.ShowMsgBox( + API.GetTranslation("KeepPluginSettingsSubtitle"), + API.GetTranslation("KeepPluginSettingsTitle"), + button: MessageBoxButton.YesNo) == MessageBoxResult.No; + + try + { + await API.UninstallPluginAsync(oldPlugin, removePluginSettings); + } + catch (Exception e) + { + API.LogException(ClassName, "Failed to uninstall plugin", e); + API.ShowMsgError(API.GetTranslation("ErrorUninstallingPlugin")); + return; // don’t restart on failure + } + + if (FlowSettings.AutoRestartAfterChanging) + { + API.RestartApp(); + } + else + { + API.ShowMsg( + API.GetTranslation("uninstallbtn"), + string.Format( + API.GetTranslation( + "UninstallSuccessNoRestart"), + oldPlugin.Name)); + } + } + + public static async Task UpdatePluginAndCheckRestartAsync(UserPlugin newPlugin, PluginMetadata oldPlugin) + { + if (API.ShowMsgBox( + string.Format( + API.GetTranslation("UpdatePromptSubtitle"), + oldPlugin.Name, oldPlugin.Author, Environment.NewLine), + API.GetTranslation("UpdatePromptTitle"), + button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return; + + try + { + var filePath = Path.Combine(Path.GetTempPath(), $"{newPlugin.Name}-{newPlugin.Version}.zip"); + + using var cts = new CancellationTokenSource(); + + if (!newPlugin.IsFromLocalInstallPath) + { + await DownloadFileAsync( + $"{API.GetTranslation("DownloadingPlugin")} {newPlugin.Name}", + newPlugin.UrlDownload, filePath, cts); + } + else + { + filePath = newPlugin.LocalInstallPath; + } + + // check if user cancelled download before installing plugin + if (cts.IsCancellationRequested) + { + return; + } + else + { + await API.UpdatePluginAsync(oldPlugin, newPlugin, filePath); + } + } + catch (Exception e) + { + API.LogException(ClassName, "Failed to update plugin", e); + API.ShowMsgError(API.GetTranslation("ErrorUpdatingPlugin")); + return; // don’t restart on failure + } + + if (FlowSettings.AutoRestartAfterChanging) + { + API.RestartApp(); + } + else + { + API.ShowMsg( + API.GetTranslation("updatebtn"), + string.Format( + API.GetTranslation( + "UpdateSuccessNoRestart"), + newPlugin.Name)); + } + } + #endregion #region Internal functions @@ -694,6 +868,41 @@ internal static async Task UninstallPluginAsync(PluginMetadata plugin, bool remo } } + internal static async Task DownloadFileAsync(string prgBoxTitle, string downloadUrl, string filePath, CancellationTokenSource cts, bool deleteFile = true, bool showProgress = true) + { + if (deleteFile && File.Exists(filePath)) + File.Delete(filePath); + + if (showProgress) + { + var exceptionHappened = false; + await API.ShowProgressBoxAsync(prgBoxTitle, + async (reportProgress) => + { + if (reportProgress == null) + { + // when reportProgress is null, it means there is expcetion with the progress box + // so we record it with exceptionHappened and return so that progress box will close instantly + exceptionHappened = true; + return; + } + else + { + await API.HttpDownloadAsync(downloadUrl, filePath, reportProgress, cts.Token).ConfigureAwait(false); + } + }, cts.Cancel); + + // if exception happened while downloading and user does not cancel downloading, + // we need to redownload the plugin + if (exceptionHappened && (!cts.IsCancellationRequested)) + await API.HttpDownloadAsync(downloadUrl, filePath, token: cts.Token).ConfigureAwait(false); + } + else + { + await API.HttpDownloadAsync(downloadUrl, filePath, token: cts.Token).ConfigureAwait(false); + } + } + #endregion } } diff --git a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs index 6b2cf6eed50..a504b7a051b 100644 --- a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs +++ b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs @@ -1,12 +1,7 @@ using System; -using System.IO; -using System.Threading; using System.Threading.Tasks; -using System.Windows; -using CommunityToolkit.Mvvm.DependencyInjection; using CommunityToolkit.Mvvm.Input; using Flow.Launcher.Core.Plugin; -using Flow.Launcher.Infrastructure.UserSettings; using Flow.Launcher.Plugin; using Version = SemanticVersioning.Version; @@ -14,10 +9,6 @@ namespace Flow.Launcher.ViewModel { public partial class PluginStoreItemViewModel : BaseModel { - private static readonly string ClassName = nameof(PluginStoreItemViewModel); - - private static readonly Settings Settings = Ioc.Default.GetRequiredService(); - private readonly UserPlugin _newPlugin; private readonly PluginPair _oldPluginPair; @@ -74,223 +65,17 @@ private async Task ShowCommandQueryAsync(string action) switch (action) { case "install": - await InstallPluginAsync(_newPlugin); + await PluginManager.InstallPluginAndCheckRestartAsync(_newPlugin); break; case "uninstall": - await UninstallPluginAsync(_oldPluginPair.Metadata); + await PluginManager.UninstallPluginAndCheckRestartAsync(_oldPluginPair.Metadata); break; case "update": - await UpdatePluginAsync(_newPlugin, _oldPluginPair.Metadata); + await PluginManager.UpdatePluginAndCheckRestartAsync(_newPlugin, _oldPluginPair.Metadata); break; default: break; } } - - internal static async Task InstallPluginAsync(UserPlugin newPlugin) - { - if (App.API.ShowMsgBox( - string.Format( - App.API.GetTranslation("InstallPromptSubtitle"), - newPlugin.Name, newPlugin.Author, Environment.NewLine), - App.API.GetTranslation("InstallPromptTitle"), - button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return; - - try - { - // at minimum should provide a name, but handle plugin that is not downloaded from plugins manifest and is a url download - var downloadFilename = string.IsNullOrEmpty(newPlugin.Version) - ? $"{newPlugin.Name}-{Guid.NewGuid()}.zip" - : $"{newPlugin.Name}-{newPlugin.Version}.zip"; - - var filePath = Path.Combine(Path.GetTempPath(), downloadFilename); - - using var cts = new CancellationTokenSource(); - - if (!newPlugin.IsFromLocalInstallPath) - { - await DownloadFileAsync( - $"{App.API.GetTranslation("DownloadingPlugin")} {newPlugin.Name}", - newPlugin.UrlDownload, filePath, cts); - } - else - { - filePath = newPlugin.LocalInstallPath; - } - - // check if user cancelled download before installing plugin - if (cts.IsCancellationRequested) - { - return; - } - else - { - if (!File.Exists(filePath)) - { - throw new FileNotFoundException($"Plugin {newPlugin.ID} zip file not found at {filePath}", filePath); - } - - App.API.InstallPlugin(newPlugin, filePath); - - if (!newPlugin.IsFromLocalInstallPath) - { - File.Delete(filePath); - } - } - } - catch (Exception e) - { - App.API.LogException(ClassName, "Failed to install plugin", e); - App.API.ShowMsgError(App.API.GetTranslation("ErrorInstallingPlugin")); - return; // don’t restart on failure - } - - if (Settings.AutoRestartAfterChanging) - { - App.API.RestartApp(); - } - else - { - App.API.ShowMsg( - App.API.GetTranslation("installbtn"), - string.Format( - App.API.GetTranslation( - "InstallSuccessNoRestart"), - newPlugin.Name)); - } - } - - internal static async Task UninstallPluginAsync(PluginMetadata oldPlugin) - { - if (App.API.ShowMsgBox( - string.Format( - App.API.GetTranslation("UninstallPromptSubtitle"), - oldPlugin.Name, oldPlugin.Author, Environment.NewLine), - App.API.GetTranslation("UninstallPromptTitle"), - button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return; - - var removePluginSettings = App.API.ShowMsgBox( - App.API.GetTranslation("KeepPluginSettingsSubtitle"), - App.API.GetTranslation("KeepPluginSettingsTitle"), - button: MessageBoxButton.YesNo) == MessageBoxResult.No; - - try - { - await App.API.UninstallPluginAsync(oldPlugin, removePluginSettings); - } - catch (Exception e) - { - App.API.LogException(ClassName, "Failed to uninstall plugin", e); - App.API.ShowMsgError(App.API.GetTranslation("ErrorUninstallingPlugin")); - return; // don’t restart on failure - } - - if (Settings.AutoRestartAfterChanging) - { - App.API.RestartApp(); - } - else - { - App.API.ShowMsg( - App.API.GetTranslation("uninstallbtn"), - string.Format( - App.API.GetTranslation( - "UninstallSuccessNoRestart"), - oldPlugin.Name)); - } - } - - internal static async Task UpdatePluginAsync(UserPlugin newPlugin, PluginMetadata oldPlugin) - { - if (App.API.ShowMsgBox( - string.Format( - App.API.GetTranslation("UpdatePromptSubtitle"), - oldPlugin.Name, oldPlugin.Author, Environment.NewLine), - App.API.GetTranslation("UpdatePromptTitle"), - button: MessageBoxButton.YesNo) != MessageBoxResult.Yes) return; - - try - { - var filePath = Path.Combine(Path.GetTempPath(), $"{newPlugin.Name}-{newPlugin.Version}.zip"); - - using var cts = new CancellationTokenSource(); - - if (!newPlugin.IsFromLocalInstallPath) - { - await DownloadFileAsync( - $"{App.API.GetTranslation("DownloadingPlugin")} {newPlugin.Name}", - newPlugin.UrlDownload, filePath, cts); - } - else - { - filePath = newPlugin.LocalInstallPath; - } - - // check if user cancelled download before installing plugin - if (cts.IsCancellationRequested) - { - return; - } - else - { - await App.API.UpdatePluginAsync(oldPlugin, newPlugin, filePath); - } - } - catch (Exception e) - { - App.API.LogException(ClassName, "Failed to update plugin", e); - App.API.ShowMsgError(App.API.GetTranslation("ErrorUpdatingPlugin")); - return; // don’t restart on failure - } - - if (Settings.AutoRestartAfterChanging) - { - App.API.RestartApp(); - } - else - { - App.API.ShowMsg( - App.API.GetTranslation("updatebtn"), - string.Format( - App.API.GetTranslation( - "UpdateSuccessNoRestart"), - newPlugin.Name)); - } - } - - private static async Task DownloadFileAsync(string prgBoxTitle, string downloadUrl, string filePath, CancellationTokenSource cts, bool deleteFile = true, bool showProgress = true) - { - if (deleteFile && File.Exists(filePath)) - File.Delete(filePath); - - if (showProgress) - { - var exceptionHappened = false; - await App.API.ShowProgressBoxAsync(prgBoxTitle, - async (reportProgress) => - { - if (reportProgress == null) - { - // when reportProgress is null, it means there is expcetion with the progress box - // so we record it with exceptionHappened and return so that progress box will close instantly - exceptionHappened = true; - return; - } - else - { - await App.API.HttpDownloadAsync(downloadUrl, filePath, reportProgress, cts.Token).ConfigureAwait(false); - } - }, cts.Cancel); - - // if exception happened while downloading and user does not cancel downloading, - // we need to redownload the plugin - if (exceptionHappened && (!cts.IsCancellationRequested)) - await App.API.HttpDownloadAsync(downloadUrl, filePath, token: cts.Token).ConfigureAwait(false); - } - else - { - await App.API.HttpDownloadAsync(downloadUrl, filePath, token: cts.Token).ConfigureAwait(false); - } - } } } diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs index bda05a02d80..f902fb03775 100644 --- a/Flow.Launcher/ViewModel/PluginViewModel.cs +++ b/Flow.Launcher/ViewModel/PluginViewModel.cs @@ -172,7 +172,7 @@ private void OpenSourceCodeLink() [RelayCommand] private async Task OpenDeletePluginWindowAsync() { - await PluginStoreItemViewModel.UninstallPluginAsync(PluginPair.Metadata); + await PluginManager.UninstallPluginAndCheckRestartAsync(PluginPair.Metadata); } [RelayCommand] From 5bae2020313e836ed8c15699cb007f260dce67be Mon Sep 17 00:00:00 2001 From: 01Dri Date: Sun, 25 May 2025 02:34:24 -0300 Subject: [PATCH 044/576] Columns - Path and Name --- .../Views/ExplorerSettings.xaml | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml index 4302e721a51..3ef61573de2 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml @@ -718,9 +718,27 @@ BorderThickness="1" DragEnter="lbxAccessLinks_DragEnter" Drop="LbxAccessLinks_OnDrop" - ItemTemplate="{StaticResource ListViewTemplateAccessLinks}" ItemsSource="{Binding Settings.QuickAccessLinks}" - SelectedItem="{Binding SelectedQuickAccessLink}" /> + SelectedItem="{Binding SelectedQuickAccessLink, Mode=TwoWay}"> + + + + + + + + + + + + + + + + + + + Date: Sun, 25 May 2025 02:34:48 -0300 Subject: [PATCH 045/576] AccessLink Refactor --- .../Search/QuickAccessLinks/AccessLink.cs | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/AccessLink.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/AccessLink.cs index 1975211f9bc..8650b4c4c5c 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/AccessLink.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/AccessLink.cs @@ -9,21 +9,20 @@ public class AccessLink public string Path { get; set; } public ResultType Type { get; set; } = ResultType.Folder; - - [JsonIgnore] - public string Name + + public string Name { get; set; } + + private string GetPathName() { - get - { - var path = Path.EndsWith(Constants.DirectorySeparator) ? Path[0..^1] : Path; + var path = Path.EndsWith(Constants.DirectorySeparator) ? Path[0..^1] : Path; - if (path.EndsWith(':')) - return path[0..^1] + " Drive"; + if (path.EndsWith(':')) + return path[0..^1] + " Drive"; - return path.Split(new[] { System.IO.Path.DirectorySeparatorChar }, StringSplitOptions.None) - .Last(); - } + return path.Split(new[] { System.IO.Path.DirectorySeparatorChar }, StringSplitOptions.None) + .Last(); } + } } From 179babe31371c27e55108c42e4e216ad595c6643 Mon Sep 17 00:00:00 2001 From: 01Dri Date: Sun, 25 May 2025 02:35:09 -0300 Subject: [PATCH 046/576] New window to add/edit quick access link --- .../Languages/en.xaml | 1 + .../Views/QuickAccessLinkSettings.xaml | 136 ++++++++++++++++++ .../Views/QuickAccessLinkSettings.xaml.cs | 114 +++++++++++++++ 3 files changed, 251 insertions(+) create mode 100644 Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml create mode 100644 Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml index eefd6f4eb53..960373ef1a7 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml @@ -92,6 +92,7 @@ Permanently delete current file Permanently delete current folder Path: + Name: Delete the selected Run as different user Run the selected using a different user account diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml new file mode 100644 index 00000000000..e6ad44e4ef9 --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs new file mode 100644 index 00000000000..9d2c54e2d98 --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Windows; +using System.Windows.Forms; +using Flow.Launcher.Plugin.Explorer.Search; +using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks; + +namespace Flow.Launcher.Plugin.Explorer.Views; + +public partial class QuickAccessLinkSettings : INotifyPropertyChanged +{ + + private string _selectedPath; + public string SelectedPath + { + get => _selectedPath; + set + { + if (_selectedPath != value) + { + _selectedPath = value; + OnPropertyChanged(); + SelectedName = GetPathName(); + } + } + } + + + private string _selectedName; + public string SelectedName + { + get => _selectedName; + set + { + if (_selectedName != value) + { + _selectedName = value; + OnPropertyChanged(); + } + } + } + + + public QuickAccessLinkSettings() + { + InitializeComponent(); + } + + + + private void BtnCancel_OnClick(object sender, RoutedEventArgs e) + { + DialogResult = false; + Close(); + } + + private void OnDoneButtonClick(object sender, RoutedEventArgs e) + { + var container = Settings.QuickAccessLinks; + + + // Lembrar de colocar uma logica pra evitar path e name vazios + var newAccessLink = new AccessLink + { + Name = SelectedName, + Path = SelectedPath + }; + container.Add(newAccessLink); + DialogResult = false; + Close(); + } + + private void SelectPath_OnClick(object commandParameter, RoutedEventArgs e) + { + var folderBrowserDialog = new FolderBrowserDialog(); + + if (folderBrowserDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) + return; + + SelectedPath = folderBrowserDialog.SelectedPath; + } + + private string GetPathName() + { + if (string.IsNullOrEmpty(SelectedPath)) return ""; + var path = SelectedPath.EndsWith(Constants.DirectorySeparator) ? SelectedPath[0..^1] : SelectedPath; + + if (path.EndsWith(':')) + return path[0..^1] + " Drive"; + + return path.Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.None) + .Last(); + } + + public event PropertyChangedEventHandler PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected bool SetField(ref T field, T value, [CallerMemberName] string propertyName = null) + { + if (EqualityComparer.Default.Equals(field, value)) return false; + field = value; + OnPropertyChanged(propertyName); + return true; + } +} + From 3777e2b6d86bfa2f689c942ee9bbf186dc50138d Mon Sep 17 00:00:00 2001 From: 01Dri Date: Sun, 25 May 2025 02:36:55 -0300 Subject: [PATCH 047/576] Changing QuickAccessLinks property to static This change is necessary for quick access settings window --- Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs index 4f83fc72e5b..2380a1ec934 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs @@ -15,7 +15,7 @@ public class Settings { public int MaxResult { get; set; } = 100; - public ObservableCollection QuickAccessLinks { get; set; } = new(); + public static ObservableCollection QuickAccessLinks { get; set; } = new(); public ObservableCollection IndexSearchExcludedSubdirectoryPaths { get; set; } = new ObservableCollection(); From 61aca7409668890b1a55a14457ec02f0414d1209 Mon Sep 17 00:00:00 2001 From: 01Dri Date: Sun, 25 May 2025 02:41:17 -0300 Subject: [PATCH 048/576] Separating add commands between QuickAccessLink and IndexSearchExcludedPaths --- .../ViewModels/SettingsViewModel.cs | 27 ++++++++++--------- .../Views/ExplorerSettings.xaml | 4 +-- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs index fb33dacab01..508e20893ab 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs @@ -365,27 +365,28 @@ private void ShowUnselectedMessage() } [RelayCommand] - private void AddLink(object commandParameter) + private void AddQuickAccessLink(object commandParameter) { - var container = commandParameter switch - { - "QuickAccessLink" => Settings.QuickAccessLinks, - "IndexSearchExcludedPaths" => Settings.IndexSearchExcludedSubdirectoryPaths, - _ => throw new ArgumentOutOfRangeException(nameof(commandParameter)) - }; - - ArgumentNullException.ThrowIfNull(container); - + var quickAccessLinkSettings = new QuickAccessLinkSettings(); + quickAccessLinkSettings.ShowDialog(); + } + + + [RelayCommand] + private void AddIndexSearchExcludePaths(object commandParameter) + { + var container = Settings.IndexSearchExcludedSubdirectoryPaths; + var folderBrowserDialog = new FolderBrowserDialog(); - + if (folderBrowserDialog.ShowDialog() != DialogResult.OK) return; - + var newAccessLink = new AccessLink { Path = folderBrowserDialog.SelectedPath }; - + container.Add(newAccessLink); } diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml index 3ef61573de2..07f05b1c1a1 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml @@ -762,7 +762,7 @@ From bc2648c216b4ee485c584bd81e1abb3ada9ba3cb Mon Sep 17 00:00:00 2001 From: 01Dri Date: Sun, 25 May 2025 16:05:26 -0300 Subject: [PATCH 056/576] Code quality --- .../ViewModels/SettingsViewModel.cs | 4 ++-- .../Views/QuickAccessLinkSettings.xaml.cs | 23 ++++++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs index 447e7273692..6237deabb20 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs @@ -383,14 +383,14 @@ private void EditQuickAccessLink(object commandParameter) return; } - var quickAccessLinkSettings = new QuickAccessLinkSettings(Settings,SelectedQuickAccessLink); + var quickAccessLinkSettings = new QuickAccessLinkSettings(Settings.QuickAccessLinks,SelectedQuickAccessLink); quickAccessLinkSettings.ShowDialog(); } [RelayCommand] private void AddQuickAccessLink(object commandParameter) { - var quickAccessLinkSettings = new QuickAccessLinkSettings(Settings); + var quickAccessLinkSettings = new QuickAccessLinkSettings(Settings.QuickAccessLinks); quickAccessLinkSettings.ShowDialog(); } diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs index 5eda62558b2..28cd68bad98 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Runtime.CompilerServices; @@ -53,20 +54,21 @@ public string SelectedName private bool IsEdit { get; set; } [CanBeNull] private AccessLink SelectedAccessLink { get; set; } - private Settings Settings { get; } - public QuickAccessLinkSettings(Settings settings) + public ObservableCollection QuickAccessLinks { get; set; } + + public QuickAccessLinkSettings(ObservableCollection quickAccessLinks) { - Settings = settings; + QuickAccessLinks = quickAccessLinks; InitializeComponent(); } - public QuickAccessLinkSettings(Settings settings,AccessLink selectedAccessLink) + public QuickAccessLinkSettings(ObservableCollection quickAccessLinks,AccessLink selectedAccessLink) { IsEdit = true; _selectedName = selectedAccessLink.Name; _selectedPath = selectedAccessLink.Path; SelectedAccessLink = selectedAccessLink; - Settings = settings; + QuickAccessLinks = quickAccessLinks; InitializeComponent(); } @@ -88,7 +90,7 @@ private void OnDoneButtonClick(object sender, RoutedEventArgs e) return; } - if (Settings.QuickAccessLinks.Any(x => x.Path == SelectedPath && x.Name == SelectedName)) + if (QuickAccessLinks.Any(x => x.Path == SelectedPath && x.Name == SelectedName)) { var warning = Main.Context.API.GetTranslation("plugin_explorer_quick_access_link_select_different_folder"); Main.Context.API.ShowMsgBox(warning); @@ -99,9 +101,8 @@ private void OnDoneButtonClick(object sender, RoutedEventArgs e) EditAccessLink(); return; } - var container = Settings.QuickAccessLinks; var newAccessLink = new AccessLink { Name = SelectedName, Path = SelectedPath }; - container.Add(newAccessLink); + QuickAccessLinks.Add(newAccessLink); DialogResult = false; Close(); } @@ -120,12 +121,12 @@ private void EditAccessLink() { if (SelectedAccessLink == null)throw new ArgumentException("Access Link object is null"); - var obj = Settings.QuickAccessLinks.FirstOrDefault(x => x.GetHashCode() == SelectedAccessLink.GetHashCode()); - int index = Settings.QuickAccessLinks.IndexOf(obj); + var obj = QuickAccessLinks.FirstOrDefault(x => x.GetHashCode() == SelectedAccessLink.GetHashCode()); + int index = QuickAccessLinks.IndexOf(obj); if (index >= 0) { SelectedAccessLink = new AccessLink { Name = SelectedName, Path = SelectedPath }; - Settings.QuickAccessLinks[index] = SelectedAccessLink; + QuickAccessLinks[index] = SelectedAccessLink; } DialogResult = false; IsEdit = false; From cd62e7b5dc4695a83339d2a02c9682603d775479 Mon Sep 17 00:00:00 2001 From: 01Dri Date: Sun, 25 May 2025 16:11:03 -0300 Subject: [PATCH 057/576] uP --- .../Helper/{FolderPathHelper.cs => PathHelper.cs} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename Plugins/Flow.Launcher.Plugin.Explorer/Helper/{FolderPathHelper.cs => PathHelper.cs} (94%) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Helper/FolderPathHelper.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Helper/PathHelper.cs similarity index 94% rename from Plugins/Flow.Launcher.Plugin.Explorer/Helper/FolderPathHelper.cs rename to Plugins/Flow.Launcher.Plugin.Explorer/Helper/PathHelper.cs index 74e23be3a7d..36b098d1edf 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Helper/FolderPathHelper.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Helper/PathHelper.cs @@ -5,7 +5,7 @@ namespace Flow.Launcher.Plugin.Explorer.Helper; -public static class FolderPathHelper +public static class PathHelper { public static string GetPathName(this string selectedPath) { From 29831d61bb2b496b88ecd8588c0518e506d7ea3e Mon Sep 17 00:00:00 2001 From: 01Dri Date: Sun, 25 May 2025 16:48:20 -0300 Subject: [PATCH 058/576] AI Review Refactor suggestion --- .../Languages/en.xaml | 2 +- .../ViewModels/SettingsViewModel.cs | 10 ++++---- .../Views/QuickAccessLinkSettings.xaml.cs | 23 ++++++++++--------- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml index ef55a408818..cc6b58e42b6 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml @@ -6,7 +6,7 @@ Please make a selection first Please select a folder path. - Please choose a different name or folder path. + Please choose a different name or folder path. Please select a folder link Are you sure you want to delete {0}? Are you sure you want to permanently delete this file? diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs index 6237deabb20..d6effb4e26c 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs @@ -9,6 +9,7 @@ using System.Windows; using System.Windows.Forms; using CommunityToolkit.Mvvm.Input; +using Flow.Launcher.Plugin.Explorer.Helper; using Flow.Launcher.Plugin.Explorer.Search; using Flow.Launcher.Plugin.Explorer.Search.Everything; using Flow.Launcher.Plugin.Explorer.Search.Everything.Exceptions; @@ -352,7 +353,7 @@ private void EditIndexSearchExcludePaths(object commandParameter) collection.Remove(SelectedIndexSearchExcludedPath); collection.Add(new AccessLink { - Path = path, Type = selectedType, + Path = path, Type = selectedType, Name = path.GetPathName() }); } @@ -368,10 +369,12 @@ private void AddIndexSearchExcludePaths(object commandParameter) var newAccessLink = new AccessLink { + Name = folderBrowserDialog.SelectedPath.GetPathName(), Path = folderBrowserDialog.SelectedPath }; container.Add(newAccessLink); + Save(); } [RelayCommand] @@ -382,16 +385,15 @@ private void EditQuickAccessLink(object commandParameter) ShowUnselectedMessage(); return; } - var quickAccessLinkSettings = new QuickAccessLinkSettings(Settings.QuickAccessLinks,SelectedQuickAccessLink); - quickAccessLinkSettings.ShowDialog(); + if (quickAccessLinkSettings.ShowDialog() == true) Save(); } [RelayCommand] private void AddQuickAccessLink(object commandParameter) { var quickAccessLinkSettings = new QuickAccessLinkSettings(Settings.QuickAccessLinks); - quickAccessLinkSettings.ShowDialog(); + if (quickAccessLinkSettings.ShowDialog() == true) Save(); } diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs index 28cd68bad98..388fc2c9189 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs @@ -52,9 +52,9 @@ public string SelectedName } private bool IsEdit { get; set; } - [CanBeNull] private AccessLink SelectedAccessLink { get; set; } + [CanBeNull] private AccessLink SelectedAccessLink { get; } - public ObservableCollection QuickAccessLinks { get; set; } + public ObservableCollection QuickAccessLinks { get; } public QuickAccessLinkSettings(ObservableCollection quickAccessLinks) { @@ -89,10 +89,12 @@ private void OnDoneButtonClick(object sender, RoutedEventArgs e) Main.Context.API.ShowMsgBox(warning); return; } - - if (QuickAccessLinks.Any(x => x.Path == SelectedPath && x.Name == SelectedName)) + + if (QuickAccessLinks.Any(x => + x.Path.Equals(SelectedPath, StringComparison.OrdinalIgnoreCase) && + x.Name.Equals(SelectedName, StringComparison.OrdinalIgnoreCase))) { - var warning = Main.Context.API.GetTranslation("plugin_explorer_quick_access_link_select_different_folder"); + var warning = Main.Context.API.GetTranslation("plugin_explorer_quick_access_link_path_already_exists"); Main.Context.API.ShowMsgBox(warning); return; } @@ -103,7 +105,7 @@ private void OnDoneButtonClick(object sender, RoutedEventArgs e) } var newAccessLink = new AccessLink { Name = SelectedName, Path = SelectedPath }; QuickAccessLinks.Add(newAccessLink); - DialogResult = false; + DialogResult = true; Close(); } @@ -121,14 +123,13 @@ private void EditAccessLink() { if (SelectedAccessLink == null)throw new ArgumentException("Access Link object is null"); - var obj = QuickAccessLinks.FirstOrDefault(x => x.GetHashCode() == SelectedAccessLink.GetHashCode()); - int index = QuickAccessLinks.IndexOf(obj); + var index = QuickAccessLinks.IndexOf(SelectedAccessLink); if (index >= 0) { - SelectedAccessLink = new AccessLink { Name = SelectedName, Path = SelectedPath }; - QuickAccessLinks[index] = SelectedAccessLink; + var updatedLink = new AccessLink { Name = SelectedName, Path = SelectedPath }; + QuickAccessLinks[index] = updatedLink; } - DialogResult = false; + DialogResult = true; IsEdit = false; Close(); } From 4a50eec281e6013301efd5b56eb5c601d3921565 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 30 May 2025 10:59:22 +0800 Subject: [PATCH 059/576] Remove TranslationConverter & project reference in Explorer plugin --- .../Resource/TranslationConverter.cs | 25 ------------------- .../UserSettings/CustomShortcutModel.cs | 8 ++++++ .../Resources/SettingWindowStyle.xaml | 1 - .../Views/SettingsPaneHotkey.xaml | 2 +- .../Flow.Launcher.Plugin.Explorer.csproj | 3 +-- .../ViewModels/ActionKeywordModel.cs | 2 ++ .../Views/ExplorerSettings.xaml | 6 ++--- 7 files changed, 14 insertions(+), 33 deletions(-) delete mode 100644 Flow.Launcher.Core/Resource/TranslationConverter.cs diff --git a/Flow.Launcher.Core/Resource/TranslationConverter.cs b/Flow.Launcher.Core/Resource/TranslationConverter.cs deleted file mode 100644 index eb0032758b4..00000000000 --- a/Flow.Launcher.Core/Resource/TranslationConverter.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Globalization; -using System.Windows.Data; -using CommunityToolkit.Mvvm.DependencyInjection; -using Flow.Launcher.Plugin; - -namespace Flow.Launcher.Core.Resource -{ - public class TranslationConverter : IValueConverter - { - // We should not initialize API in static constructor because it will create another API instance - private static IPublicAPI api = null; - private static IPublicAPI API => api ??= Ioc.Default.GetRequiredService(); - - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - var key = value.ToString(); - if (string.IsNullOrEmpty(key)) return key; - return API.GetTranslation(key); - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => - throw new InvalidOperationException(); - } -} diff --git a/Flow.Launcher.Infrastructure/UserSettings/CustomShortcutModel.cs b/Flow.Launcher.Infrastructure/UserSettings/CustomShortcutModel.cs index 2d15b54c5be..2603d46751c 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/CustomShortcutModel.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/CustomShortcutModel.cs @@ -1,6 +1,8 @@ using System; using System.Text.Json.Serialization; using System.Threading.Tasks; +using CommunityToolkit.Mvvm.DependencyInjection; +using Flow.Launcher.Plugin; namespace Flow.Launcher.Infrastructure.UserSettings { @@ -53,6 +55,12 @@ public class BaseBuiltinShortcutModel : ShortcutBaseModel { public string Description { get; set; } + public string LocalizedDescription => API.GetTranslation(Description); + + // We should not initialize API in static constructor because it will create another API instance + private static IPublicAPI api = null; + private static IPublicAPI API => api ??= Ioc.Default.GetRequiredService(); + public BaseBuiltinShortcutModel(string key, string description) { Key = key; diff --git a/Flow.Launcher/Resources/SettingWindowStyle.xaml b/Flow.Launcher/Resources/SettingWindowStyle.xaml index fc9246aa33d..3ebd22c742c 100644 --- a/Flow.Launcher/Resources/SettingWindowStyle.xaml +++ b/Flow.Launcher/Resources/SettingWindowStyle.xaml @@ -6,7 +6,6 @@ - F1 M512,512z M0,0z M448,256C448,150,362,64,256,64L256,448C362,448,448,362,448,256z M0,256A256,256,0,1,1,512,256A256,256,0,1,1,0,256z diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml index b1d72ede5bf..861e9d29481 100644 --- a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml +++ b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml @@ -424,7 +424,7 @@ - + diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj index 98164f48971..93691814aee 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj @@ -46,6 +46,7 @@ + @@ -53,8 +54,6 @@ - - diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/ActionKeywordModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/ActionKeywordModel.cs index d4cd1348e9b..745032d2c3d 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/ActionKeywordModel.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/ActionKeywordModel.cs @@ -24,6 +24,8 @@ internal ActionKeywordModel(Settings.ActionKeyword actionKeyword, string descrip public string Description { get; private init; } + public string LocalizedDescription => Main.Context.API.GetTranslation(Description); + internal Settings.ActionKeyword KeywordProperty { get; } private void OnPropertyChanged([CallerMemberName] string propertyName = "") diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml index 4302e721a51..c034ac0e116 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml @@ -3,7 +3,6 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:converters="clr-namespace:Flow.Launcher.Plugin.Explorer.Views.Converters" - xmlns:core="clr-namespace:Flow.Launcher.Core.Resource;assembly=Flow.Launcher.Core" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:qa="clr-namespace:Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks" @@ -109,7 +108,7 @@ + Text="{Binding LocalizedDescription, Mode=OneTime}"> + - @@ -163,653 +79,685 @@ + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + \ No newline at end of file diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml.cs b/Flow.Launcher/ReleaseNotesWindow.xaml.cs new file mode 100644 index 00000000000..18c67ac5b79 --- /dev/null +++ b/Flow.Launcher/ReleaseNotesWindow.xaml.cs @@ -0,0 +1,149 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Input; +using Flow.Launcher.Infrastructure.Http; + +namespace Flow.Launcher +{ + public partial class ReleaseNotesWindow : Window + { + public ReleaseNotesWindow() + { + InitializeComponent(); + } + + #region Window Events + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")] + private async void Window_Loaded(object sender, RoutedEventArgs e) + { + RefreshMaximizeRestoreButton(); + MarkdownViewer.Markdown = await GetReleaseNotesMarkdownAsync(); + } + + private void OnCloseExecuted(object sender, ExecutedRoutedEventArgs e) + { + Close(); + } + + #endregion + + #region Window Custom TitleBar + + private void OnMinimizeButtonClick(object sender, RoutedEventArgs e) + { + WindowState = WindowState.Minimized; + } + + private void OnMaximizeRestoreButtonClick(object sender, RoutedEventArgs e) + { + WindowState = WindowState switch + { + WindowState.Maximized => WindowState.Normal, + _ => WindowState.Maximized + }; + } + + private void OnCloseButtonClick(object sender, RoutedEventArgs e) + { + Close(); + } + + private void RefreshMaximizeRestoreButton() + { + if (WindowState == WindowState.Maximized) + { + MaximizeButton.Visibility = Visibility.Hidden; + RestoreButton.Visibility = Visibility.Visible; + } + else + { + MaximizeButton.Visibility = Visibility.Visible; + RestoreButton.Visibility = Visibility.Hidden; + } + } + + private void Window_StateChanged(object sender, EventArgs e) + { + RefreshMaximizeRestoreButton(); + } + + #endregion + + #region Release Notes + + private static async Task GetReleaseNotesMarkdownAsync() + { + var releaseNotesJSON = await Http.GetStringAsync("https://api.github.com/repos/Flow-Launcher/Flow.Launcher/releases"); + var releases = JsonSerializer.Deserialize>(releaseNotesJSON); + + // Get the latest releases + var latestReleases = releases.OrderByDescending(release => release.PublishedDate).Take(3); + + // Build the release notes in Markdown format + var releaseNotesHtmlBuilder = new StringBuilder(string.Empty); + foreach (var release in latestReleases) + { + releaseNotesHtmlBuilder.AppendLine("# " + release.Name); + + // Add unit for images: Replace with + var notes = ImageUnitRegex().Replace(release.ReleaseNotes, m => + { + var prefix = m.Groups[1].Value; + var widthValue = m.Groups[2].Value; + var quote = m.Groups[3].Value; + var suffix = m.Groups[4].Value; + // Only replace if width is number like 500 without units like 500px + if (IsNumber(widthValue)) + return $"{prefix}{widthValue}px{quote}{suffix}"; + return m.Value; + }); + + releaseNotesHtmlBuilder.AppendLine(notes); + releaseNotesHtmlBuilder.AppendLine(" "); + } + + return releaseNotesHtmlBuilder.ToString(); + } + + private static bool IsNumber(string input) + { + if (string.IsNullOrEmpty(input)) + return false; + + foreach (char c in input) + { + if (!char.IsDigit(c)) + return false; + } + return true; + } + + private sealed class GitHubReleaseInfo + { + [JsonPropertyName("published_at")] + public DateTimeOffset PublishedDate { get; set; } + + [JsonPropertyName("name")] + public string Name { get; set; } + + [JsonPropertyName("tag_name")] + public string TagName { get; set; } + + [JsonPropertyName("body")] + public string ReleaseNotes { get; set; } + } + + [GeneratedRegex("(]*width\\s*=\\s*[\"']?)(\\d+)([\"']?)([^>]*>)", RegexOptions.IgnoreCase, "en-GB")] + private static partial Regex ImageUnitRegex(); + + #endregion + } +} From 7117ba05ee4ef544f4bc0c7c648fa3e5f8c25971 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 6 Jun 2025 23:08:41 +0800 Subject: [PATCH 146/576] Test release notes window --- Flow.Launcher/MainWindow.xaml.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index a77d6471c7a..b266d3dc074 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -132,6 +132,9 @@ private void OnLoaded(object sender, RoutedEventArgs _) welcomeWindow.Show(); } + var releaseNotesWindow = new ReleaseNotesWindow(); + releaseNotesWindow.Show(); + // Initialize place holder SetupPlaceholderText(); _viewModel.PlaceholderText = _settings.PlaceholderText; From c241d21a4a9259a3ce1eb50f21b0624c6780cba0 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 6 Jun 2025 23:51:26 +0800 Subject: [PATCH 147/576] Fix height --- Flow.Launcher/ReleaseNotesWindow.xaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml b/Flow.Launcher/ReleaseNotesWindow.xaml index 132de63c8b5..e61986aea85 100644 --- a/Flow.Launcher/ReleaseNotesWindow.xaml +++ b/Flow.Launcher/ReleaseNotesWindow.xaml @@ -157,7 +157,7 @@ Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="5" - MaxHeight="510" + Height="510" Margin="15 0 20 0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" From af0e1180a5cbc18cba3090f10595e58ab12e7ac6 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 6 Jun 2025 23:52:34 +0800 Subject: [PATCH 148/576] Use loaded event & Add style --- Flow.Launcher/ReleaseNotesWindow.xaml | 3 ++- Flow.Launcher/ReleaseNotesWindow.xaml.cs | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml b/Flow.Launcher/ReleaseNotesWindow.xaml index e61986aea85..7b2e5f7e72c 100644 --- a/Flow.Launcher/ReleaseNotesWindow.xaml +++ b/Flow.Launcher/ReleaseNotesWindow.xaml @@ -161,7 +161,8 @@ Margin="15 0 20 0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" - ClickAction="SafetyDisplayWithRelativePath" /> + ClickAction="SafetyDisplayWithRelativePath" + Loaded="MarkdownViewer_Loaded" /> diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml.cs b/Flow.Launcher/ReleaseNotesWindow.xaml.cs index 18c67ac5b79..4f0c1a9ce28 100644 --- a/Flow.Launcher/ReleaseNotesWindow.xaml.cs +++ b/Flow.Launcher/ReleaseNotesWindow.xaml.cs @@ -9,6 +9,7 @@ using System.Windows; using System.Windows.Input; using Flow.Launcher.Infrastructure.Http; +using MdXaml; namespace Flow.Launcher { @@ -21,11 +22,9 @@ public ReleaseNotesWindow() #region Window Events - [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")] - private async void Window_Loaded(object sender, RoutedEventArgs e) + private void Window_Loaded(object sender, RoutedEventArgs e) { RefreshMaximizeRestoreButton(); - MarkdownViewer.Markdown = await GetReleaseNotesMarkdownAsync(); } private void OnCloseExecuted(object sender, ExecutedRoutedEventArgs e) @@ -82,6 +81,11 @@ private void Window_StateChanged(object sender, EventArgs e) private static async Task GetReleaseNotesMarkdownAsync() { var releaseNotesJSON = await Http.GetStringAsync("https://api.github.com/repos/Flow-Launcher/Flow.Launcher/releases"); + + if (string.IsNullOrEmpty(releaseNotesJSON)) + { + return string.Empty; + } var releases = JsonSerializer.Deserialize>(releaseNotesJSON); // Get the latest releases @@ -145,5 +149,12 @@ private sealed class GitHubReleaseInfo private static partial Regex ImageUnitRegex(); #endregion + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")] + private async void MarkdownViewer_Loaded(object sender, RoutedEventArgs e) + { + MarkdownViewer.MarkdownStyle = MarkdownStyle.GithubLike; + MarkdownViewer.Markdown = await GetReleaseNotesMarkdownAsync(); + } } } From 02496214ea2cabbd0037bc83f3e9e03125311222 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sat, 7 Jun 2025 00:07:44 +0800 Subject: [PATCH 149/576] Add progress ring --- Flow.Launcher/ReleaseNotesWindow.xaml | 23 ++++++++++++++++ Flow.Launcher/ReleaseNotesWindow.xaml.cs | 34 +++++++++++++++++++++--- 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml b/Flow.Launcher/ReleaseNotesWindow.xaml index 7b2e5f7e72c..f70fa6f5c9c 100644 --- a/Flow.Launcher/ReleaseNotesWindow.xaml +++ b/Flow.Launcher/ReleaseNotesWindow.xaml @@ -163,6 +163,29 @@ VerticalAlignment="Stretch" ClickAction="SafetyDisplayWithRelativePath" Loaded="MarkdownViewer_Loaded" /> + + + + + - - - - - - - - - + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + @@ -118,14 +117,14 @@ x:Name="btnCancel" Width="145" Height="30" - Margin="10 0 5 0" + Margin="10 0 10 0" Click="BtnCancel_OnClick" Content="{DynamicResource cancel}" /> + + + + + + + + + + + + + + +