From 9c13416231074f78968640b0a4e87b4a00705651 Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Mon, 6 Sep 2021 12:31:07 -0500 Subject: [PATCH 01/92] Fixes Typo TermSeparator & remove the actionkeyword in Terms --- Flow.Launcher.Core/Plugin/QueryBuilder.cs | 24 +++++------- Flow.Launcher.Plugin/Query.cs | 37 +++++++------------ Flow.Launcher/ActionKeywords.xaml.cs | 2 +- Flow.Launcher/ViewModel/PluginViewModel.cs | 2 +- .../Main.cs | 2 +- .../Main.cs | 2 +- Plugins/Flow.Launcher.Plugin.Shell/Main.cs | 2 +- 7 files changed, 28 insertions(+), 43 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/QueryBuilder.cs b/Flow.Launcher.Core/Plugin/QueryBuilder.cs index df336e14b..444335afd 100644 --- a/Flow.Launcher.Core/Plugin/QueryBuilder.cs +++ b/Flow.Launcher.Core/Plugin/QueryBuilder.cs @@ -10,35 +10,31 @@ namespace Flow.Launcher.Core.Plugin public static Query Build(string text, Dictionary nonGlobalPlugins) { // replace multiple white spaces with one white space - var terms = text.Split(new[] { Query.TermSeperater }, StringSplitOptions.RemoveEmptyEntries); - if (terms.Length == 0) + var textSplit = text.Split(Query.TermSeparator, StringSplitOptions.RemoveEmptyEntries); + if (textSplit.Length == 0) { // nothing was typed return null; } - var rawQuery = string.Join(Query.TermSeperater, terms); + var rawQuery = string.Join(Query.TermSeparator, textSplit); string actionKeyword, search; - string possibleActionKeyword = terms[0]; - List actionParameters; + string possibleActionKeyword = textSplit[0]; + string[] terms; + if (nonGlobalPlugins.TryGetValue(possibleActionKeyword, out var pluginPair) && !pluginPair.Metadata.Disabled) { // use non global plugin for query actionKeyword = possibleActionKeyword; - actionParameters = terms.Skip(1).ToList(); - search = actionParameters.Count > 0 ? rawQuery.Substring(actionKeyword.Length + 1) : string.Empty; + search = textSplit.Length > 1 ? rawQuery[(actionKeyword.Length + 1)..] : string.Empty; + terms = textSplit[1..]; } else { // non action keyword actionKeyword = string.Empty; search = rawQuery; + terms = textSplit; } - var query = new Query - { - Terms = terms, - RawQuery = rawQuery, - ActionKeyword = actionKeyword, - Search = search - }; + var query = new Query(rawQuery, search, terms, actionKeyword); return query; } diff --git a/Flow.Launcher.Plugin/Query.cs b/Flow.Launcher.Plugin/Query.cs index 1eb5c9c14..05e34b9d9 100644 --- a/Flow.Launcher.Plugin/Query.cs +++ b/Flow.Launcher.Plugin/Query.cs @@ -1,4 +1,5 @@ -using System; +using JetBrains.Annotations; +using System; using System.Collections.Generic; using System.Linq; @@ -23,7 +24,7 @@ namespace Flow.Launcher.Plugin /// Raw query, this includes action keyword if it has /// We didn't recommend use this property directly. You should always use Search property. /// - public string RawQuery { get; internal set; } + public string RawQuery { get; internal init; } /// /// Search part of a query. @@ -31,45 +32,40 @@ namespace Flow.Launcher.Plugin /// Since we allow user to switch a exclusive plugin to generic plugin, /// so this property will always give you the "real" query part of the query /// - public string Search { get; internal set; } + public string Search { get; internal init; } /// /// The raw query splited into a string array. /// - public string[] Terms { get; set; } + public string[] Terms { get; init; } /// /// Query can be splited into multiple terms by whitespace /// - public const string TermSeperater = " "; + public const string TermSeparator = " "; /// /// User can set multiple action keywords seperated by ';' /// - public const string ActionKeywordSeperater = ";"; + public const string ActionKeywordSeparator = ";"; /// /// '*' is used for System Plugin /// public const string GlobalPluginWildcardSign = "*"; - public string ActionKeyword { get; set; } + public string ActionKeyword { get; init; } /// /// Return first search split by space if it has /// public string FirstSearch => SplitSearch(0); + private string _secondToEndSearch; + /// /// strings from second search (including) to last search /// - public string SecondToEndSearch - { - get - { - var index = string.IsNullOrEmpty(ActionKeyword) ? 1 : 2; - return string.Join(TermSeperater, Terms.Skip(index).ToArray()); - } - } + public string SecondToEndSearch => _secondToEndSearch ??= string.Join(' ', Terms.AsMemory(2)); /// /// Return second search split by space if it has @@ -83,16 +79,9 @@ namespace Flow.Launcher.Plugin private string SplitSearch(int index) { - try - { - return string.IsNullOrEmpty(ActionKeyword) ? Terms[index] : Terms[index + 1]; - } - catch (IndexOutOfRangeException) - { - return string.Empty; - } + return index < Terms.Length ? Terms[index] : string.Empty; } public override string ToString() => RawQuery; } -} +} \ No newline at end of file diff --git a/Flow.Launcher/ActionKeywords.xaml.cs b/Flow.Launcher/ActionKeywords.xaml.cs index 4a2368347..281be6e52 100644 --- a/Flow.Launcher/ActionKeywords.xaml.cs +++ b/Flow.Launcher/ActionKeywords.xaml.cs @@ -30,7 +30,7 @@ namespace Flow.Launcher private void ActionKeyword_OnLoaded(object sender, RoutedEventArgs e) { - tbOldActionKeyword.Text = string.Join(Query.ActionKeywordSeperater, plugin.Metadata.ActionKeywords.ToArray()); + tbOldActionKeyword.Text = string.Join(Query.ActionKeywordSeparator, plugin.Metadata.ActionKeywords.ToArray()); tbAction.Focus(); } diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs index 1ac320cf0..b0db8bca0 100644 --- a/Flow.Launcher/ViewModel/PluginViewModel.cs +++ b/Flow.Launcher/ViewModel/PluginViewModel.cs @@ -22,7 +22,7 @@ namespace Flow.Launcher.ViewModel public Visibility ActionKeywordsVisibility => PluginPair.Metadata.ActionKeywords.Count == 1 ? Visibility.Visible : Visibility.Collapsed; public string InitilizaTime => PluginPair.Metadata.InitTime.ToString() + "ms"; public string QueryTime => PluginPair.Metadata.AvgQueryTime + "ms"; - public string ActionKeywordsText => string.Join(Query.ActionKeywordSeperater, PluginPair.Metadata.ActionKeywords); + public string ActionKeywordsText => string.Join(Query.ActionKeywordSeparator, PluginPair.Metadata.ActionKeywords); public int Priority => PluginPair.Metadata.Priority; public void ChangeActionKeyword(string newActionKeyword, string oldActionKeyword) diff --git a/Plugins/Flow.Launcher.Plugin.PluginIndicator/Main.cs b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Main.cs index 190f40a03..a27986e75 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginIndicator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Main.cs @@ -27,7 +27,7 @@ namespace Flow.Launcher.Plugin.PluginIndicator IcoPath = metadata.IcoPath, Action = c => { - context.API.ChangeQuery($"{keyword}{Plugin.Query.TermSeperater}"); + context.API.ChangeQuery($"{keyword}{Plugin.Query.TermSeparator}"); return false; } }; diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs index c3d9d1ab2..29d3511eb 100644 --- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs @@ -25,7 +25,7 @@ namespace Flow.Launcher.Plugin.ProcessKiller { var termToSearch = query.Terms.Length <= 1 ? null - : string.Join(Plugin.Query.TermSeperater, query.Terms.Skip(1)).ToLower(); + : string.Join(Plugin.Query.TermSeparator, query.Terms.Skip(1)).ToLower(); var processlist = processHelper.GetMatchingProcesses(termToSearch); diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs index 58f8538f0..9ccb600e5 100644 --- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs @@ -297,7 +297,7 @@ namespace Flow.Launcher.Plugin.Shell private void OnWinRPressed() { - context.API.ChangeQuery($"{context.CurrentPluginMetadata.ActionKeywords[0]}{Plugin.Query.TermSeperater}"); + context.API.ChangeQuery($"{context.CurrentPluginMetadata.ActionKeywords[0]}{Plugin.Query.TermSeparator}"); // show the main window and set focus to the query box Window mainWindow = Application.Current.MainWindow; From 812703766ab03693ea1366052f9acb1682f8de41 Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Tue, 7 Sep 2021 17:07:21 -0500 Subject: [PATCH 02/92] Mark previous api as obsolete to preserve backward compatibility. --- Flow.Launcher.Core/Plugin/QueryBuilder.cs | 18 +++++++-------- Flow.Launcher.Plugin/Query.cs | 23 +++++++++++++++---- .../Main.cs | 4 ++-- .../Main.cs | 4 +--- 4 files changed, 30 insertions(+), 19 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/QueryBuilder.cs b/Flow.Launcher.Core/Plugin/QueryBuilder.cs index 444335afd..ef387b693 100644 --- a/Flow.Launcher.Core/Plugin/QueryBuilder.cs +++ b/Flow.Launcher.Core/Plugin/QueryBuilder.cs @@ -10,31 +10,31 @@ namespace Flow.Launcher.Core.Plugin public static Query Build(string text, Dictionary nonGlobalPlugins) { // replace multiple white spaces with one white space - var textSplit = text.Split(Query.TermSeparator, StringSplitOptions.RemoveEmptyEntries); - if (textSplit.Length == 0) + var terms = text.Split(Query.TermSeparator, StringSplitOptions.RemoveEmptyEntries); + if (terms.Length == 0) { // nothing was typed return null; } - var rawQuery = string.Join(Query.TermSeparator, textSplit); + var rawQuery = string.Join(Query.TermSeparator, terms); string actionKeyword, search; - string possibleActionKeyword = textSplit[0]; - string[] terms; + string possibleActionKeyword = terms[0]; + string[] searchTerms; if (nonGlobalPlugins.TryGetValue(possibleActionKeyword, out var pluginPair) && !pluginPair.Metadata.Disabled) { // use non global plugin for query actionKeyword = possibleActionKeyword; - search = textSplit.Length > 1 ? rawQuery[(actionKeyword.Length + 1)..] : string.Empty; - terms = textSplit[1..]; + search = terms.Length > 1 ? rawQuery[(actionKeyword.Length + 1)..] : string.Empty; + searchTerms = terms[1..]; } else { // non action keyword actionKeyword = string.Empty; search = rawQuery; - terms = textSplit; + searchTerms = terms; } - var query = new Query(rawQuery, search, terms, actionKeyword); + var query = new Query(rawQuery, search,terms, searchTerms, actionKeyword); return query; } diff --git a/Flow.Launcher.Plugin/Query.cs b/Flow.Launcher.Plugin/Query.cs index 05e34b9d9..12681388e 100644 --- a/Flow.Launcher.Plugin/Query.cs +++ b/Flow.Launcher.Plugin/Query.cs @@ -12,11 +12,11 @@ namespace Flow.Launcher.Plugin /// /// to allow unit tests for plug ins /// - public Query(string rawQuery, string search, string[] terms, string actionKeyword = "") + public Query(string rawQuery, string search, string[] terms, string[] searchTerms, string actionKeyword = "") { Search = search; RawQuery = rawQuery; - Terms = terms; + SearchTerms = searchTerms; ActionKeyword = actionKeyword; } @@ -35,18 +35,31 @@ namespace Flow.Launcher.Plugin public string Search { get; internal init; } /// - /// The raw query splited into a string array. + /// The search string split into a string array. /// + public string[] SearchTerms { get; init; } + + /// + /// The raw query split into a string array + /// + [Obsolete("It may or may not include action keyword, which can be confusing. Use SearchTerms instead")] public string[] Terms { get; init; } /// /// Query can be splited into multiple terms by whitespace /// public const string TermSeparator = " "; + + [Obsolete("Typo")] + public const string TermSeperater = TermSeparator; /// /// User can set multiple action keywords seperated by ';' /// public const string ActionKeywordSeparator = ";"; + + [Obsolete("Typo")] + public const string ActionKeywordSeperater = ActionKeywordSeparator; + /// /// '*' is used for System Plugin @@ -65,7 +78,7 @@ namespace Flow.Launcher.Plugin /// /// strings from second search (including) to last search /// - public string SecondToEndSearch => _secondToEndSearch ??= string.Join(' ', Terms.AsMemory(2)); + public string SecondToEndSearch => _secondToEndSearch ??= string.Join(' ', SearchTerms.AsMemory(2)); /// /// Return second search split by space if it has @@ -79,7 +92,7 @@ namespace Flow.Launcher.Plugin private string SplitSearch(int index) { - return index < Terms.Length ? Terms[index] : string.Empty; + return index < SearchTerms.Length ? SearchTerms[index] : string.Empty; } public override string ToString() => RawQuery; diff --git a/Plugins/Flow.Launcher.Plugin.PluginIndicator/Main.cs b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Main.cs index a27986e75..b046b2beb 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginIndicator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Main.cs @@ -12,11 +12,11 @@ namespace Flow.Launcher.Plugin.PluginIndicator { // if query contains more than one word, eg. github tips // user has decided to type something else rather than wanting to see the available action keywords - if (query.Terms.Length > 1) + if (query.SearchTerms.Length > 1) return new List(); var results = from keyword in PluginManager.NonGlobalPlugins.Keys - where keyword.StartsWith(query.Terms[0]) + where keyword.StartsWith(query.SearchTerms[0]) let metadata = PluginManager.NonGlobalPlugins[keyword].Metadata where !metadata.Disabled select new Result diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs index 29d3511eb..31b4a67ed 100644 --- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs @@ -23,9 +23,7 @@ namespace Flow.Launcher.Plugin.ProcessKiller public List Query(Query query) { - var termToSearch = query.Terms.Length <= 1 - ? null - : string.Join(Plugin.Query.TermSeparator, query.Terms.Skip(1)).ToLower(); + var termToSearch = query.Search; var processlist = processHelper.GetMatchingProcesses(termToSearch); From 9b84f6c559a1ac46fed6fd41c1dc3558dd63d289 Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Sat, 11 Sep 2021 09:41:39 -0500 Subject: [PATCH 03/92] fix an issue of joining string --- Flow.Launcher.Plugin/Query.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Plugin/Query.cs b/Flow.Launcher.Plugin/Query.cs index 12681388e..84dbb3b36 100644 --- a/Flow.Launcher.Plugin/Query.cs +++ b/Flow.Launcher.Plugin/Query.cs @@ -78,7 +78,7 @@ namespace Flow.Launcher.Plugin /// /// strings from second search (including) to last search /// - public string SecondToEndSearch => _secondToEndSearch ??= string.Join(' ', SearchTerms.AsMemory(2)); + public string SecondToEndSearch => _secondToEndSearch ??= string.Join(' ', SearchTerms[1..]); /// /// Return second search split by space if it has From 6a0b190120a37309573e710bdcfb07b8fde1f744 Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Mon, 20 Sep 2021 21:51:07 -0500 Subject: [PATCH 04/92] Fix Unassigned Terms --- Flow.Launcher.Plugin/Query.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher.Plugin/Query.cs b/Flow.Launcher.Plugin/Query.cs index 84dbb3b36..a4a806a62 100644 --- a/Flow.Launcher.Plugin/Query.cs +++ b/Flow.Launcher.Plugin/Query.cs @@ -16,6 +16,9 @@ namespace Flow.Launcher.Plugin { Search = search; RawQuery = rawQuery; +#pragma warning disable 618 Legacy Support + Terms = terms; +#pragma warning restore 618 SearchTerms = searchTerms; ActionKeyword = actionKeyword; } @@ -38,7 +41,7 @@ namespace Flow.Launcher.Plugin /// The search string split into a string array. /// public string[] SearchTerms { get; init; } - + /// /// The raw query split into a string array /// @@ -56,7 +59,7 @@ namespace Flow.Launcher.Plugin /// User can set multiple action keywords seperated by ';' /// public const string ActionKeywordSeparator = ";"; - + [Obsolete("Typo")] public const string ActionKeywordSeperater = ActionKeywordSeparator; From 7ff9b688c91af89a49b94ea1b67c09f9462241cd Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Tue, 21 Sep 2021 13:50:51 -0500 Subject: [PATCH 05/92] Refactor Bookmark plugin --- .../Bookmark.cs | 47 ++-------- .../ChromeBookmarkLoader.cs | 26 ++++++ .../ChromeBookmarks.cs | 87 ------------------- .../ChromiumBookmarkLoader.cs | 62 +++++++++++++ .../Commands/Bookmarks.cs | 6 +- .../EdgeBookmarkLoader.cs | 30 +++++++ .../EdgeBookmarks.cs | 87 ------------------- ...xBookmarks.cs => FirefoxBookmarkLoader.cs} | 33 +++---- .../IBookmarkLoader.cs | 9 ++ 9 files changed, 156 insertions(+), 231 deletions(-) create mode 100644 Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromeBookmarkLoader.cs delete mode 100644 Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromeBookmarks.cs create mode 100644 Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs create mode 100644 Plugins/Flow.Launcher.Plugin.BrowserBookmark/EdgeBookmarkLoader.cs delete mode 100644 Plugins/Flow.Launcher.Plugin.BrowserBookmark/EdgeBookmarks.cs rename Plugins/Flow.Launcher.Plugin.BrowserBookmark/{FirefoxBookmarks.cs => FirefoxBookmarkLoader.cs} (85%) create mode 100644 Plugins/Flow.Launcher.Plugin.BrowserBookmark/IBookmarkLoader.cs diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Bookmark.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Bookmark.cs index 790c03686..185cf1620 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Bookmark.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Bookmark.cs @@ -7,50 +7,19 @@ using System.Text; namespace Flow.Launcher.Plugin.BrowserBookmark { - public class Bookmark : IEquatable, IEqualityComparer + // Source may be important in the future + public record Bookmark(string Name, string Url, string Source = "") { - private string m_Name; - public string Name + public override int GetHashCode() { - get - { - return m_Name; - } - set - { - m_Name = value; - } - } - public string Url { get; set; } - public string Source { get; set; } - public int Score { get; set; } - - /* TODO: since Source maybe unimportant, we just need to compare Name and Url */ - public bool Equals(Bookmark other) - { - return Equals(this, other); - } - - public bool Equals(Bookmark x, Bookmark y) - { - if (Object.ReferenceEquals(x, y)) return true; - if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) - return false; - - return x.Name == y.Name && x.Url == y.Url; - } - - public int GetHashCode(Bookmark bookmark) - { - if (Object.ReferenceEquals(bookmark, null)) return 0; - int hashName = bookmark.Name == null ? 0 : bookmark.Name.GetHashCode(); - int hashUrl = bookmark.Url == null ? 0 : bookmark.Url.GetHashCode(); + var hashName = Name?.GetHashCode() ?? 0; + var hashUrl = Url?.GetHashCode() ?? 0; return hashName ^ hashUrl; } - public override int GetHashCode() + public virtual bool Equals(Bookmark other) { - return GetHashCode(this); + return other != null && Name == other.Name && Url == other.Url; } } -} +} \ No newline at end of file diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromeBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromeBookmarkLoader.cs new file mode 100644 index 000000000..7fdb86f31 --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromeBookmarkLoader.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; + +namespace Flow.Launcher.Plugin.BrowserBookmark +{ + public class ChromeBookmarkLoader : ChromiumBookmarkLoader + { + public override List GetBookmarks() + { + return LoadChromeBookmarks(); + } + + private List LoadChromeBookmarks() + { + var bookmarks = new List(); + String platformPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); + bookmarks.AddRange(LoadBookmarks(Path.Combine(platformPath, @"Google\Chrome\User Data"), "Google Chrome")); + bookmarks.AddRange(LoadBookmarks(Path.Combine(platformPath, @"Google\Chrome SxS\User Data"), "Google Chrome Canary")); + bookmarks.AddRange(LoadBookmarks(Path.Combine(platformPath, @"Chromium\User Data"), "Chromium")); + return bookmarks; + } + } +} \ No newline at end of file diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromeBookmarks.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromeBookmarks.cs deleted file mode 100644 index def7f3abe..000000000 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromeBookmarks.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text.RegularExpressions; - -namespace Flow.Launcher.Plugin.BrowserBookmark -{ - public class ChromeBookmarks - { - private List bookmarks = new List(); - - public List GetBookmarks() - { - bookmarks.Clear(); - LoadChromeBookmarks(); - - return bookmarks; - } - - private void ParseChromeBookmarks(String path, string source) - { - if (!File.Exists(path)) return; - - string all = File.ReadAllText(path); - Regex nameRegex = new Regex("\"name\": \"(?.*?)\""); - MatchCollection nameCollection = nameRegex.Matches(all); - Regex typeRegex = new Regex("\"type\": \"(?.*?)\""); - MatchCollection typeCollection = typeRegex.Matches(all); - Regex urlRegex = new Regex("\"url\": \"(?.*?)\""); - MatchCollection urlCollection = urlRegex.Matches(all); - - List names = (from Match match in nameCollection select match.Groups["name"].Value).ToList(); - List types = (from Match match in typeCollection select match.Groups["type"].Value).ToList(); - List urls = (from Match match in urlCollection select match.Groups["url"].Value).ToList(); - - int urlIndex = 0; - for (int i = 0; i < names.Count; i++) - { - string name = DecodeUnicode(names[i]); - string type = types[i]; - if (type == "url") - { - string url = urls[urlIndex]; - urlIndex++; - - if (url == null) continue; - if (url.StartsWith("javascript:", StringComparison.OrdinalIgnoreCase)) continue; - if (url.StartsWith("vbscript:", StringComparison.OrdinalIgnoreCase)) continue; - - bookmarks.Add(new Bookmark() - { - Name = name, - Url = url, - Source = source - }); - } - } - } - - private void LoadChromeBookmarks(string path, string name) - { - if (!Directory.Exists(path)) return; - var paths = Directory.GetDirectories(path); - - foreach (var profile in paths) - { - if (File.Exists(Path.Combine(profile, "Bookmarks"))) - ParseChromeBookmarks(Path.Combine(profile, "Bookmarks"), name + (Path.GetFileName(profile) == "Default" ? "" : (" (" + Path.GetFileName(profile) + ")"))); - } - } - - private void LoadChromeBookmarks() - { - String platformPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); - LoadChromeBookmarks(Path.Combine(platformPath, @"Google\Chrome\User Data"), "Google Chrome"); - LoadChromeBookmarks(Path.Combine(platformPath, @"Google\Chrome SxS\User Data"), "Google Chrome Canary"); - LoadChromeBookmarks(Path.Combine(platformPath, @"Chromium\User Data"), "Chromium"); - } - - private String DecodeUnicode(String dataStr) - { - Regex reg = new Regex(@"(?i)\\[uU]([0-9a-f]{4})"); - return reg.Replace(dataStr, m => ((char)Convert.ToInt32(m.Groups[1].Value, 16)).ToString()); - } - } -} \ No newline at end of file diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs new file mode 100644 index 000000000..7be66eea5 --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs @@ -0,0 +1,62 @@ +using Microsoft.AspNetCore.Authentication; +using System.Collections.Generic; +using System.IO; +using System.Text.Json; + +namespace Flow.Launcher.Plugin.BrowserBookmark +{ + public abstract class ChromiumBookmarkLoader : IBookmarkLoader + { + public abstract List GetBookmarks(); + protected List LoadBookmarks(string browserDataPath, string name) + { + var bookmarks = new List(); + if (!Directory.Exists(browserDataPath)) return bookmarks; + var paths = Directory.GetDirectories(browserDataPath); + + foreach (var profile in paths) + { + var bookmarkPath = Path.Combine(profile, "Bookmarks"); + if (!File.Exists(bookmarkPath)) + continue; + + var source = name + (Path.GetFileName(profile) == "Default" ? "" : $" ({Path.GetFileName(profile)})"); + bookmarks.AddRange(LoadBookmarksFromFile(bookmarkPath, source)); + } + return bookmarks; + } + + protected List LoadBookmarksFromFile(string path, string source) + { + var bookmarks = new List(); + using var jsonDocument = JsonDocument.Parse(File.ReadAllText(path)); + if (!jsonDocument.RootElement.TryGetProperty("roots", out var rootElement)) + return new(); + foreach (var folder in rootElement.EnumerateObject()) + { + EnumerateFolderBookmark(folder.Value, bookmarks, source); + } + return bookmarks; + } + + private void EnumerateFolderBookmark(JsonElement folderElement, List bookmarks, string source) + { + foreach (var subElement in folderElement.GetProperty("children").EnumerateArray()) + { + switch (subElement.GetProperty("type").GetString()) + { + case "folder": + EnumerateFolderBookmark(subElement, bookmarks, source); + break; + default: + bookmarks.Add(new Bookmark( + subElement.GetProperty("name").GetString(), + subElement.GetProperty("url").GetString(), + source)); + break; + } + } + + } + } +} \ No newline at end of file diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/Bookmarks.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/Bookmarks.cs index 60c4a0ee6..c7cf4867d 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/Bookmarks.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/Bookmarks.cs @@ -20,9 +20,9 @@ namespace Flow.Launcher.Plugin.BrowserBookmark.Commands { var allbookmarks = new List(); - var chromeBookmarks = new ChromeBookmarks(); - var mozBookmarks = new FirefoxBookmarks(); - var edgeBookmarks = new EdgeBookmarks(); + var chromeBookmarks = new ChromeBookmarkLoader(); + var mozBookmarks = new FirefoxBookmarkLoader(); + var edgeBookmarks = new EdgeBookmarkLoader(); //TODO: Let the user select which browser's bookmarks are displayed // Add Firefox bookmarks diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/EdgeBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/EdgeBookmarkLoader.cs new file mode 100644 index 000000000..d3f109445 --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/EdgeBookmarkLoader.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.Json; +using System.Text.RegularExpressions; + +namespace Flow.Launcher.Plugin.BrowserBookmark +{ + public class EdgeBookmarkLoader : ChromiumBookmarkLoader + { + + private readonly List _bookmarks = new(); + + private void LoadEdgeBookmarks() + { + var platformPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); + LoadBookmarks(Path.Combine(platformPath, @"Microsoft\Edge\User Data"), "Microsoft Edge"); + LoadBookmarks(Path.Combine(platformPath, @"Microsoft\Edge Dev\User Data"), "Microsoft Edge Dev"); + LoadBookmarks(Path.Combine(platformPath, @"Microsoft\Edge SxS\User Data"), "Microsoft Edge Canary"); + } + + public override List GetBookmarks() + { + _bookmarks.Clear(); + LoadEdgeBookmarks(); + return _bookmarks; + } + } +} \ No newline at end of file diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/EdgeBookmarks.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/EdgeBookmarks.cs deleted file mode 100644 index 376808549..000000000 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/EdgeBookmarks.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text.RegularExpressions; - -namespace Flow.Launcher.Plugin.BrowserBookmark -{ - public class EdgeBookmarks - { - private List bookmarks = new List(); - - public List GetBookmarks() - { - bookmarks.Clear(); - LoadEdgeBookmarks(); - - return bookmarks; - } - - private void ParseEdgeBookmarks(string path, string source) - { - if (!File.Exists(path)) return; - - string all = File.ReadAllText(path); - Regex nameRegex = new Regex("\"name\": \"(?.*?)\""); - MatchCollection nameCollection = nameRegex.Matches(all); - Regex typeRegex = new Regex("\"type\": \"(?.*?)\""); - MatchCollection typeCollection = typeRegex.Matches(all); - Regex urlRegex = new Regex("\"url\": \"(?.*?)\""); - MatchCollection urlCollection = urlRegex.Matches(all); - - List names = (from Match match in nameCollection select match.Groups["name"].Value).ToList(); - List types = (from Match match in typeCollection select match.Groups["type"].Value).ToList(); - List urls = (from Match match in urlCollection select match.Groups["url"].Value).ToList(); - - int urlIndex = 0; - for (int i = 0; i < names.Count; i++) - { - string name = DecodeUnicode(names[i]); - string type = types[i]; - if (type == "url") - { - string url = urls[urlIndex]; - urlIndex++; - - if (url == null) continue; - if (url.StartsWith("javascript:", StringComparison.OrdinalIgnoreCase)) continue; - if (url.StartsWith("vbscript:", StringComparison.OrdinalIgnoreCase)) continue; - - bookmarks.Add(new Bookmark() - { - Name = name, - Url = url, - Source = source - }); - } - } - } - - private void LoadEdgeBookmarks(string path, string name) - { - if (!Directory.Exists(path)) return; - var paths = Directory.GetDirectories(path); - - foreach (var profile in paths) - { - if (File.Exists(Path.Combine(profile, "Bookmarks"))) - ParseEdgeBookmarks(Path.Combine(profile, "Bookmarks"), name + (Path.GetFileName(profile) == "Default" ? "" : (" (" + Path.GetFileName(profile) + ")"))); - } - } - - private void LoadEdgeBookmarks() - { - string platformPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); - LoadEdgeBookmarks(Path.Combine(platformPath, @"Microsoft\Edge\User Data"), "Microsoft Edge"); - LoadEdgeBookmarks(Path.Combine(platformPath, @"Microsoft\Edge Dev\User Data"), "Microsoft Edge Dev"); - LoadEdgeBookmarks(Path.Combine(platformPath, @"Microsoft\Edge SxS\User Data"), "Microsoft Edge Canary"); - } - - private string DecodeUnicode(string dataStr) - { - Regex reg = new Regex(@"(?i)\\[uU]([0-9a-f]{4})"); - return reg.Replace(dataStr, m => ((char)Convert.ToInt32(m.Groups[1].Value, 16)).ToString()); - } - } -} \ No newline at end of file diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarks.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs similarity index 85% rename from Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarks.cs rename to Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs index b718da3cf..5d47c80e3 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarks.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs @@ -6,7 +6,7 @@ using System.Linq; namespace Flow.Launcher.Plugin.BrowserBookmark { - public class FirefoxBookmarks + public class FirefoxBookmarkLoader : IBookmarkLoader { private const string queryAllBookmarks = @"SELECT moz_places.url, moz_bookmarks.title FROM moz_places @@ -27,10 +27,10 @@ namespace Flow.Launcher.Plugin.BrowserBookmark if (string.IsNullOrEmpty(PlacesPath) || !File.Exists(PlacesPath)) return new List(); - var bookmarList = new List(); + var bookmarkList = new List(); // create the connection string and init the connection - string dbPath = string.Format(dbPathFormat, PlacesPath); + string dbPath = string.Format(dbPathFormat, PlacesPath); using (var dbConnection = new SQLiteConnection(dbPath)) { // Open connection to the database file and execute the query @@ -38,14 +38,13 @@ namespace Flow.Launcher.Plugin.BrowserBookmark var reader = new SQLiteCommand(queryAllBookmarks, dbConnection).ExecuteReader(); // return results in List format - bookmarList = reader.Select(x => new Bookmark() - { - Name = (x["title"] is DBNull) ? string.Empty : x["title"].ToString(), - Url = x["url"].ToString() - }).ToList(); + bookmarkList = reader.Select( + x => new Bookmark(x["title"] is DBNull ? string.Empty : x["title"].ToString(), + x["url"].ToString()) + ).ToList(); } - return bookmarList; + return bookmarkList; } /// @@ -63,7 +62,8 @@ namespace Flow.Launcher.Plugin.BrowserBookmark // get firefox default profile directory from profiles.ini string ini; - using (var sReader = new StreamReader(profileIni)) { + using (var sReader = new StreamReader(profileIni)) + { ini = sReader.ReadToEnd(); } @@ -95,7 +95,10 @@ namespace Flow.Launcher.Plugin.BrowserBookmark Version=2 */ - var lines = ini.Split(new string[] { "\r\n" }, StringSplitOptions.None).ToList(); + var lines = ini.Split(new string[] + { + "\r\n" + }, StringSplitOptions.None).ToList(); var defaultProfileFolderNameRaw = lines.Where(x => x.Contains("Default=") && x != "Default=1").FirstOrDefault() ?? string.Empty; @@ -104,14 +107,14 @@ namespace Flow.Launcher.Plugin.BrowserBookmark var defaultProfileFolderName = defaultProfileFolderNameRaw.Split('=').Last(); - var indexOfDefaultProfileAtttributePath = lines.IndexOf("Path="+ defaultProfileFolderName); + var indexOfDefaultProfileAtttributePath = lines.IndexOf("Path=" + defaultProfileFolderName); // Seen in the example above, the IsRelative attribute is always above the Path attribute var relativeAttribute = lines[indexOfDefaultProfileAtttributePath - 1]; return relativeAttribute == "0" // See above, the profile is located in a custom location, path is not relative, so IsRelative=0 - ? defaultProfileFolderName + @"\places.sqlite" - : Path.Combine(profileFolderPath, defaultProfileFolderName) + @"\places.sqlite"; + ? defaultProfileFolderName + @"\places.sqlite" + : Path.Combine(profileFolderPath, defaultProfileFolderName) + @"\places.sqlite"; } } } @@ -126,4 +129,4 @@ namespace Flow.Launcher.Plugin.BrowserBookmark } } } -} +} \ No newline at end of file diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/IBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/IBookmarkLoader.cs new file mode 100644 index 000000000..1dbd8b6bf --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/IBookmarkLoader.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Flow.Launcher.Plugin.BrowserBookmark +{ + public interface IBookmarkLoader + { + public List GetBookmarks(); + } +} \ No newline at end of file From d51579967bad180e9bc3da557674cfe1d40fa0c1 Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Wed, 22 Sep 2021 18:09:30 -0500 Subject: [PATCH 06/92] Further Refactor & add CustomBrowsers UI --- .../ChromeBookmarkLoader.cs | 3 +- .../ChromiumBookmarkLoader.cs | 5 +- .../{Bookmarks.cs => BookmarkLoader.cs} | 16 ++++--- .../CustomChromiumBookmarkLoader.cs | 14 ++++++ .../EdgeBookmarkLoader.cs | 1 + .../FirefoxBookmarkLoader.cs | 1 + ...low.Launcher.Plugin.BrowserBookmark.csproj | 4 ++ .../IBookmarkLoader.cs | 3 +- .../Main.cs | 6 +-- .../{ => Models}/Bookmark.cs | 11 ++--- .../Models/CustomBrowser.cs | 8 ++++ .../Models/Settings.cs | 20 +++++++- .../Views/CustomBrowserSetting.xaml | 36 +++++++++++++++ .../Views/CustomBrowserSetting.xaml.cs | 45 ++++++++++++++++++ .../Views/SettingsControl.xaml | 46 +++++++++++++++---- .../Views/SettingsControl.xaml.cs | 40 +++++++++++----- 16 files changed, 218 insertions(+), 41 deletions(-) rename Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/{Bookmarks.cs => BookmarkLoader.cs} (71%) create mode 100644 Plugins/Flow.Launcher.Plugin.BrowserBookmark/CustomChromiumBookmarkLoader.cs rename Plugins/Flow.Launcher.Plugin.BrowserBookmark/{ => Models}/Bookmark.cs (73%) create mode 100644 Plugins/Flow.Launcher.Plugin.BrowserBookmark/Models/CustomBrowser.cs create mode 100644 Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/CustomBrowserSetting.xaml create mode 100644 Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/CustomBrowserSetting.xaml.cs diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromeBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromeBookmarkLoader.cs index 7fdb86f31..d7cfcaf6a 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromeBookmarkLoader.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromeBookmarkLoader.cs @@ -1,4 +1,5 @@ -using System; +using Flow.Launcher.Plugin.BrowserBookmark.Models; +using System; using System.Collections.Generic; using System.IO; using System.Linq; diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs index 7be66eea5..a6edf3302 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Authentication; +using Flow.Launcher.Plugin.BrowserBookmark.Models; +using Microsoft.AspNetCore.Authentication; using System.Collections.Generic; using System.IO; using System.Text.Json; @@ -28,6 +29,8 @@ namespace Flow.Launcher.Plugin.BrowserBookmark protected List LoadBookmarksFromFile(string path, string source) { + if (!File.Exists(path)) + return new(); var bookmarks = new List(); using var jsonDocument = JsonDocument.Parse(File.ReadAllText(path)); if (!jsonDocument.RootElement.TryGetProperty("roots", out var rootElement)) diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/Bookmarks.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/BookmarkLoader.cs similarity index 71% rename from Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/Bookmarks.cs rename to Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/BookmarkLoader.cs index c7cf4867d..b4c6235e0 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/Bookmarks.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/BookmarkLoader.cs @@ -1,11 +1,12 @@ using System.Collections.Generic; using System.Linq; using Flow.Launcher.Infrastructure; +using Flow.Launcher.Plugin.BrowserBookmark.Models; using Flow.Launcher.Plugin.SharedModels; namespace Flow.Launcher.Plugin.BrowserBookmark.Commands { - internal static class Bookmarks + internal static class BookmarkLoader { internal static MatchResult MatchProgram(Bookmark bookmark, string queryString) { @@ -18,23 +19,24 @@ namespace Flow.Launcher.Plugin.BrowserBookmark.Commands internal static List LoadAllBookmarks() { - var allbookmarks = new List(); var chromeBookmarks = new ChromeBookmarkLoader(); var mozBookmarks = new FirefoxBookmarkLoader(); var edgeBookmarks = new EdgeBookmarkLoader(); + var allBookmarks = new List(); + //TODO: Let the user select which browser's bookmarks are displayed // Add Firefox bookmarks - mozBookmarks.GetBookmarks().ForEach(x => allbookmarks.Add(x)); + allBookmarks.AddRange(mozBookmarks.GetBookmarks()); // Add Chrome bookmarks - chromeBookmarks.GetBookmarks().ForEach(x => allbookmarks.Add(x)); + allBookmarks.AddRange(chromeBookmarks.GetBookmarks()); // Add Edge (Chromium) bookmarks - edgeBookmarks.GetBookmarks().ForEach(x => allbookmarks.Add(x)); + allBookmarks.AddRange(edgeBookmarks.GetBookmarks()); - return allbookmarks.Distinct().ToList(); + return allBookmarks.Distinct().ToList(); } } -} +} \ No newline at end of file diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/CustomChromiumBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/CustomChromiumBookmarkLoader.cs new file mode 100644 index 000000000..91189ace7 --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/CustomChromiumBookmarkLoader.cs @@ -0,0 +1,14 @@ +using Flow.Launcher.Plugin.BrowserBookmark.Models; +using System.Collections.Generic; + +namespace Flow.Launcher.Plugin.BrowserBookmark +{ + public class CustomChromiumBookmarkLoader : ChromiumBookmarkLoader + { + public string BrowserDataPath { get; init; } + public string BookmarkFilePath { get; init; } + public string BrowserName { get; init; } + + public override List GetBookmarks() => BrowserDataPath != null ? LoadBookmarks(BrowserDataPath, BrowserName) : LoadBookmarksFromFile(BookmarkFilePath, BrowserName); + } +} \ No newline at end of file diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/EdgeBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/EdgeBookmarkLoader.cs index d3f109445..d982ee99e 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/EdgeBookmarkLoader.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/EdgeBookmarkLoader.cs @@ -1,3 +1,4 @@ +using Flow.Launcher.Plugin.BrowserBookmark.Models; using System; using System.Collections.Generic; using System.IO; diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs index 5d47c80e3..3df034781 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs @@ -1,3 +1,4 @@ +using Flow.Launcher.Plugin.BrowserBookmark.Models; using System; using System.Collections.Generic; using System.Data.SQLite; 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 acfc79d7a..46313d38f 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj @@ -69,4 +69,8 @@ + + + + \ No newline at end of file diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/IBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/IBookmarkLoader.cs index 1dbd8b6bf..2c48cfd55 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/IBookmarkLoader.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/IBookmarkLoader.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using Flow.Launcher.Plugin.BrowserBookmark.Models; +using System.Collections.Generic; namespace Flow.Launcher.Plugin.BrowserBookmark { diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs index a0b443e75..eaf14d5c2 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs @@ -26,7 +26,7 @@ namespace Flow.Launcher.Plugin.BrowserBookmark _settings = context.API.LoadSettingJsonStorage(); - cachedBookmarks = Bookmarks.LoadAllBookmarks(); + cachedBookmarks = BookmarkLoader.LoadAllBookmarks(); } public List Query(Query query) @@ -45,7 +45,7 @@ namespace Flow.Launcher.Plugin.BrowserBookmark Title = c.Name, SubTitle = c.Url, IcoPath = @"Images\bookmark.png", - Score = Bookmarks.MatchProgram(c, param).Score, + Score = BookmarkLoader.MatchProgram(c, param).Score, Action = _ => { if (_settings.OpenInNewBrowserWindow) @@ -93,7 +93,7 @@ namespace Flow.Launcher.Plugin.BrowserBookmark { cachedBookmarks.Clear(); - cachedBookmarks = Bookmarks.LoadAllBookmarks(); + cachedBookmarks = BookmarkLoader.LoadAllBookmarks(); } public string GetTranslatedPluginTitle() diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Bookmark.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Models/Bookmark.cs similarity index 73% rename from Plugins/Flow.Launcher.Plugin.BrowserBookmark/Bookmark.cs rename to Plugins/Flow.Launcher.Plugin.BrowserBookmark/Models/Bookmark.cs index 185cf1620..c2fa9d977 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Bookmark.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Models/Bookmark.cs @@ -1,11 +1,6 @@ -using BinaryAnalysis.UnidecodeSharp; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Collections.Generic; - -namespace Flow.Launcher.Plugin.BrowserBookmark +namespace Flow.Launcher.Plugin.BrowserBookmark.Models { // Source may be important in the future public record Bookmark(string Name, string Url, string Source = "") @@ -21,5 +16,7 @@ namespace Flow.Launcher.Plugin.BrowserBookmark { return other != null && Name == other.Name && Url == other.Url; } + + public List CustomBrowsers { get; set; }= new(); } } \ No newline at end of file diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Models/CustomBrowser.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Models/CustomBrowser.cs new file mode 100644 index 000000000..1ddeab5df --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Models/CustomBrowser.cs @@ -0,0 +1,8 @@ +namespace Flow.Launcher.Plugin.BrowserBookmark.Models +{ + public class CustomBrowser : BaseModel + { + public string Name { get; set; } + public string Path { get; set; } + } +} \ No newline at end of file diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Models/Settings.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Models/Settings.cs index dc444fd73..e63b90dbc 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Models/Settings.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Models/Settings.cs @@ -1,9 +1,27 @@ -namespace Flow.Launcher.Plugin.BrowserBookmark.Models +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Text.Json.Serialization; + +namespace Flow.Launcher.Plugin.BrowserBookmark.Models { public class Settings : BaseModel { public bool OpenInNewBrowserWindow { get; set; } = true; public string BrowserPath { get; set; } + + public ObservableCollection CustomBrowsers { get; set; } = new() + { + new CustomBrowser + { + Name="awefawef", + Path="awefawef" + }, + new CustomBrowser + { + Name = "awefawefawefawef", + Path = "aweawefawfawef" + } + }; } } \ No newline at end of file diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/CustomBrowserSetting.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/CustomBrowserSetting.xaml new file mode 100644 index 000000000..2370789f1 --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/CustomBrowserSetting.xaml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + Date: Sat, 9 Oct 2021 20:58:22 +0900 Subject: [PATCH 22/92] - Remove Expander Button's Circle and adjust arrow size --- Flow.Launcher/App.xaml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Flow.Launcher/App.xaml b/Flow.Launcher/App.xaml index 1311de968..13d88e1c6 100644 --- a/Flow.Launcher/App.xaml +++ b/Flow.Launcher/App.xaml @@ -71,8 +71,8 @@ - - + + @@ -82,11 +82,11 @@ - + - + @@ -160,8 +160,8 @@ - - + + @@ -170,11 +170,11 @@ - + - + From 762df7fdd380926eaced688b2d2bfef713602f85 Mon Sep 17 00:00:00 2001 From: Dobin Park Date: Sat, 9 Oct 2021 22:22:47 +0900 Subject: [PATCH 23/92] - Remove colon Action keyword String - Fix layout for init/query time/version/plugin store - change action keyword to button - add listbox bottom margin - add margin when select list item for easy to distinguish. --- Flow.Launcher/Languages/en.xaml | 2 +- Flow.Launcher/SettingWindow.xaml | 80 +++++++++++++++++------------ Flow.Launcher/SettingWindow.xaml.cs | 14 +++-- 3 files changed, 58 insertions(+), 38 deletions(-) diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 60605df30..79b8ce669 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -46,7 +46,7 @@ Find more plugins On Off - Action keyword: + Action keyword Current action keyword: New action keyword: Current Priority: diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index 02de47fe7..47df70561 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -229,7 +229,7 @@ - + @@ -241,7 +241,7 @@ - + @@ -257,13 +257,6 @@ - @@ -542,7 +535,7 @@ Margin="0, 0, 0, 0" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ItemContainerStyle="{StaticResource PluginList}" ScrollViewer.IsDeferredScrollingEnabled="True" ScrollViewer.CanContentScroll="False" - Padding="0" Width="Auto" HorizontalAlignment="Stretch"> + Padding="0 0 0 18" Width="Auto" HorizontalAlignment="Stretch"> @@ -618,22 +611,36 @@ - - - + + + - + + + + @@ -652,29 +659,36 @@ - + Padding="0 12 0 0" > - - + + + - + - + - - + HorizontalAlignment="Right" FontSize="12" VerticalAlignment="Center"/> + + diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs index 08d0eb88a..9b5c34c44 100644 --- a/Flow.Launcher/SettingWindow.xaml.cs +++ b/Flow.Launcher/SettingWindow.xaml.cs @@ -193,14 +193,13 @@ namespace Flow.Launcher } - private void OnPluginActionKeywordsClick(object sender, MouseButtonEventArgs e) + private void OnPluginActionKeywordsClick(object sender, RoutedEventArgs e) { - if (e.ChangedButton == MouseButton.Left) - { + var id = viewModel.SelectedPlugin.PluginPair.Metadata.ID; ActionKeywords changeKeywordsWindow = new ActionKeywords(id, settings, viewModel.SelectedPlugin); changeKeywordsWindow.ShowDialog(); - } + } private void OnPluginNameClick(object sender, MouseButtonEventArgs e) @@ -266,6 +265,13 @@ namespace Flow.Launcher FilesFolders.OpenPath(Path.Combine(DataLocation.DataDirectory(), Constant.Themes)); } + /* + private void OnPluginActionKeywordsClick(object sender, RoutedEventArgs e) + { + + } + */ + /*private void OnPluginPriorityClick(object sender, RoutedEventArgs e) { From 4a4f0bbefbd24a0e2209b742934c4736dd573dcf Mon Sep 17 00:00:00 2001 From: Dobin Park Date: Sat, 9 Oct 2021 22:27:09 +0900 Subject: [PATCH 24/92] - Add plugin page title - Adjust listbox Margin for fit other setting page list. --- Flow.Launcher/SettingWindow.xaml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index 47df70561..38c739fb2 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -527,12 +527,20 @@ - - - + + + + + + + + + + + From 0d11b79ee31d21aacb6717e5b6a160e90ee5063d Mon Sep 17 00:00:00 2001 From: Dobin Park Date: Sun, 10 Oct 2021 00:02:41 +0900 Subject: [PATCH 25/92] - Adjust Shell, Calc, WebSearch Setting Margin --- .../Views/CalculatorSettings.xaml | 2 +- Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml | 2 +- Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml b/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml index 1330247b2..374bccf62 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml @@ -15,7 +15,7 @@ - + diff --git a/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml b/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml index 4cd4d8fa3..d9b1942f1 100644 --- a/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml +++ b/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml @@ -6,7 +6,7 @@ mc:Ignorable="d" Loaded="CMDSetting_OnLoaded" d:DesignHeight="300" d:DesignWidth="300"> - + diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml index c2f64bc7e..cb0b50069 100644 --- a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml +++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml @@ -32,7 +32,7 @@ - + From 2dc8bb386e41dbfb1b7d41c7f28726084cebc8e1 Mon Sep 17 00:00:00 2001 From: Dobin Park Date: Sun, 10 Oct 2021 00:33:11 +0900 Subject: [PATCH 26/92] - Add Automatically Hide Plugin Info Border by SettingControl Height --- Flow.Launcher/SettingWindow.xaml | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index 38c739fb2..769da568a 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -655,13 +655,23 @@ - - + + + From 2af186736a12f0d691c89475ec2e0a065cf3d431 Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Sat, 9 Oct 2021 11:34:41 -0500 Subject: [PATCH 27/92] Rename with async suffix and add lock to prevent concurrent update check --- Flow.Launcher.Core/Updater.cs | 37 +++++++++++-------- Flow.Launcher/App.xaml.cs | 4 +- .../ViewModel/SettingWindowViewModel.cs | 2 +- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs index 76713ce2a..e09c6380c 100644 --- a/Flow.Launcher.Core/Updater.cs +++ b/Flow.Launcher.Core/Updater.cs @@ -16,6 +16,7 @@ using Flow.Launcher.Infrastructure.Logger; using Flow.Launcher.Infrastructure.UserSettings; using Flow.Launcher.Plugin; using System.Text.Json.Serialization; +using System.Threading; namespace Flow.Launcher.Core { @@ -28,21 +29,21 @@ namespace Flow.Launcher.Core GitHubRepository = gitHubRepository; } - public async Task UpdateApp(IPublicAPI api, bool silentUpdate = true) + private SemaphoreSlim UpdateLock { get; } = new SemaphoreSlim(1); + + public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true) { + await UpdateLock.WaitAsync(); try { - UpdateInfo newUpdateInfo; - if (!silentUpdate) api.ShowMsg(api.GetTranslation("pleaseWait"), - api.GetTranslation("update_flowlauncher_update_check")); + api.GetTranslation("update_flowlauncher_update_check")); using var updateManager = await GitHubUpdateManager(GitHubRepository).ConfigureAwait(false); - // UpdateApp CheckForUpdate will return value only if the app is squirrel installed - newUpdateInfo = await updateManager.CheckForUpdate().NonNull().ConfigureAwait(false); + var newUpdateInfo = await updateManager.CheckForUpdate().NonNull().ConfigureAwait(false); var newReleaseVersion = Version.Parse(newUpdateInfo.FutureReleaseEntry.Version.ToString()); var currentVersion = Version.Parse(Constant.Version); @@ -58,7 +59,7 @@ namespace Flow.Launcher.Core if (!silentUpdate) api.ShowMsg(api.GetTranslation("update_flowlauncher_update_found"), - api.GetTranslation("update_flowlauncher_updating")); + api.GetTranslation("update_flowlauncher_updating")); await updateManager.DownloadReleases(newUpdateInfo.ReleasesToApply).ConfigureAwait(false); @@ -70,8 +71,8 @@ namespace Flow.Launcher.Core FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination); if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination)) MessageBox.Show(string.Format(api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"), - DataLocation.PortableDataPath, - targetDestination)); + DataLocation.PortableDataPath, + targetDestination)); } else { @@ -87,12 +88,15 @@ namespace Flow.Launcher.Core UpdateManager.RestartApp(Constant.ApplicationFileName); } } - catch (Exception e) when (e is HttpRequestException || e is WebException || e is SocketException || e.InnerException is TimeoutException) + catch (Exception e) when (e is HttpRequestException or WebException or SocketException || e.InnerException is TimeoutException) { Log.Exception($"|Updater.UpdateApp|Check your connection and proxy settings to github-cloud.s3.amazonaws.com.", e); api.ShowMsg(api.GetTranslation("update_flowlauncher_fail"), - api.GetTranslation("update_flowlauncher_check_connection")); - return; + api.GetTranslation("update_flowlauncher_check_connection")); + } + finally + { + UpdateLock.Release(); } } @@ -115,13 +119,16 @@ namespace Flow.Launcher.Core var uri = new Uri(repository); var api = $"https://api.github.com/repos{uri.AbsolutePath}/releases"; - var jsonStream = await Http.GetStreamAsync(api).ConfigureAwait(false); + 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 latestUrl = latest.HtmlUrl.Replace("/tag/", "/download/"); - - var client = new WebClient { Proxy = Http.WebProxy }; + + var client = new WebClient + { + Proxy = Http.WebProxy + }; var downloader = new FileDownloader(client); var manager = new UpdateManager(latestUrl, urlDownloader: downloader); diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs index c2a32100d..8c869e941 100644 --- a/Flow.Launcher/App.xaml.cs +++ b/Flow.Launcher/App.xaml.cs @@ -129,12 +129,12 @@ namespace Flow.Launcher var timer = new Timer(1000 * 60 * 60 * 5); timer.Elapsed += async (s, e) => { - await _updater.UpdateApp(API); + await _updater.UpdateAppAsync(API); }; timer.Start(); // check updates on startup - await _updater.UpdateApp(API); + await _updater.UpdateAppAsync(API); } }); } diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs index d3a4f9a83..e85d01b1b 100644 --- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs +++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs @@ -46,7 +46,7 @@ namespace Flow.Launcher.ViewModel public async void UpdateApp() { - await _updater.UpdateApp(App.API, false); + await _updater.UpdateAppAsync(App.API, false); } public bool AutoUpdates From 234816df4ba28485565ebb3d1c47fe743c355b97 Mon Sep 17 00:00:00 2001 From: Dobin Park Date: Sun, 10 Oct 2021 00:33:11 +0900 Subject: [PATCH 28/92] - Add Automatically Hide Plugin Info Border by SettingControl Height --- Flow.Launcher/SettingWindow.xaml | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index 38c739fb2..07882445c 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -636,7 +636,7 @@ ToolTip="Change Action Keywords" Margin="5 0 0 0" Cursor="Hand" FontWeight="Bold" Click="OnPluginActionKeywordsClick" HorizontalAlignment="Right" - Width="100" Height="32"> + Width="100" Height="40"> + + + + + From 2d98dcbfd8faa19706382febef4fda096a57c81c Mon Sep 17 00:00:00 2001 From: Dobin Park Date: Sun, 10 Oct 2021 06:19:15 +0900 Subject: [PATCH 29/92] - Add Author name in plugin list --- Flow.Launcher/Languages/en.xaml | 2 +- Flow.Launcher/SettingWindow.xaml | 226 +++++++++++++++++++++++++++++++ 2 files changed, 227 insertions(+), 1 deletion(-) diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 79b8ce669..9d9e69785 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -53,7 +53,7 @@ New Priority: Priority Plugin Directory - Author + Author: Init time: Query time: diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index b0f596372..c875d652c 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -806,6 +806,232 @@ --> + + + + + + + + + +  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 579f8c8b9eed6324b9924f6f35d1d9956e322658 Mon Sep 17 00:00:00 2001 From: Dobin Park Date: Sun, 10 Oct 2021 06:19:15 +0900 Subject: [PATCH 30/92] - Add Author name in plugin list --- Flow.Launcher/Languages/en.xaml | 2 +- Flow.Launcher/SettingWindow.xaml | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 79b8ce669..9d9e69785 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -53,7 +53,7 @@ New Priority: Priority Plugin Directory - Author + Author: Init time: Query time: diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index b0f596372..7b45c7448 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -690,9 +690,16 @@ Padding="0 12 0 0" > - + + + + + From 8174d54de659ec4f1fb850c195114fbee1cdfba2 Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Sat, 9 Oct 2021 17:58:40 -0500 Subject: [PATCH 31/92] Fix PriorityClick Logic Use sender to find actual pluginviewmodel instead of use selected --- Flow.Launcher/SettingWindow.xaml.cs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs index 9b5c34c44..4d36ec5da 100644 --- a/Flow.Launcher/SettingWindow.xaml.cs +++ b/Flow.Launcher/SettingWindow.xaml.cs @@ -13,6 +13,7 @@ using Flow.Launcher.Plugin; using Flow.Launcher.Plugin.SharedCommands; using Flow.Launcher.ViewModel; using Flow.Launcher.Helper; +using System.Windows.Controls; namespace Flow.Launcher { @@ -186,20 +187,18 @@ namespace Flow.Launcher private void OnPluginPriorityClick(object sender, RoutedEventArgs e) { - - - PriorityChangeWindow priorityChangeWindow = new PriorityChangeWindow(viewModel.SelectedPlugin.PluginPair.Metadata.ID, settings, viewModel.SelectedPlugin); + if (sender is Control { DataContext: PluginViewModel pluginViewModel }) + { + PriorityChangeWindow priorityChangeWindow = new PriorityChangeWindow(pluginViewModel.PluginPair.Metadata.ID, settings, pluginViewModel); priorityChangeWindow.ShowDialog(); - + } } private void OnPluginActionKeywordsClick(object sender, RoutedEventArgs e) { - - var id = viewModel.SelectedPlugin.PluginPair.Metadata.ID; - ActionKeywords changeKeywordsWindow = new ActionKeywords(id, settings, viewModel.SelectedPlugin); - changeKeywordsWindow.ShowDialog(); - + var id = viewModel.SelectedPlugin.PluginPair.Metadata.ID; + ActionKeywords changeKeywordsWindow = new ActionKeywords(id, settings, viewModel.SelectedPlugin); + changeKeywordsWindow.ShowDialog(); } private void OnPluginNameClick(object sender, MouseButtonEventArgs e) From 1e479edead18c1290327a908c49c34d5c326d852 Mon Sep 17 00:00:00 2001 From: Dobin Park Date: Sun, 10 Oct 2021 12:39:58 +0900 Subject: [PATCH 32/92] - Add plugin store tab (WIP) --- Flow.Launcher/SettingWindow.xaml | 87 +++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index bedad7f91..f58b17963 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -229,7 +229,7 @@ - + @@ -241,7 +241,7 @@ - + @@ -257,6 +257,14 @@ + + @@ -741,6 +749,81 @@ + + + + + + + + + +  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From a3a436c58bf0d41629ad20992542d8a4b81c8a6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Kubala?= <37414585+kubalav@users.noreply.github.com> Date: Sun, 10 Oct 2021 09:27:10 +0200 Subject: [PATCH 33/92] Update Slovak translation --- Flow.Launcher/Languages/sk.xaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Flow.Launcher/Languages/sk.xaml b/Flow.Launcher/Languages/sk.xaml index 5e63020a8..b766ccfa2 100644 --- a/Flow.Launcher/Languages/sk.xaml +++ b/Flow.Launcher/Languages/sk.xaml @@ -82,6 +82,8 @@ Ste si istý, že chcete odstrániť klávesovú skratku {0} pre plugin? Tieňový efekt v poli vyhľadávania Tieňový efekt významne využíva GPU. Neodporúča sa, ak je výkon počítača obmedzený. + Použiť ikony Segoe Fluent + Použiť ikony Segoe Fluent, ak sú podporované HTTP Proxy @@ -178,4 +180,4 @@ Aktualizovať súbory Aktualizovať popis - \ No newline at end of file + From 876d477f25cde4ee00c10ce56efd87e0aaa12df2 Mon Sep 17 00:00:00 2001 From: Dobin Park Date: Sun, 10 Oct 2021 22:21:32 +0900 Subject: [PATCH 34/92] - Add install button with hover --- Flow.Launcher/SettingWindow.xaml | 154 +++++++++++++++++++++++++++---- 1 file changed, 134 insertions(+), 20 deletions(-) diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index f58b17963..cb2146c53 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -260,10 +260,70 @@ @@ -785,34 +845,88 @@ Padding="0 0 0 0" Width="Auto" VerticalContentAlignment="Center" HorizontalAlignment="Stretch"> - + - - - - - - + + + + + + + - + + + - - + + + + - + - - + - + + + + + + + + + + + + + + + + + + From 4164b46f728cd413224f2811bf61996e88e14d29 Mon Sep 17 00:00:00 2001 From: Dobin Park Date: Mon, 11 Oct 2021 02:22:39 +0900 Subject: [PATCH 35/92] Add author and version in hover menu. --- Flow.Launcher/SettingWindow.xaml | 37 ++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index cb2146c53..260ab4280 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -852,7 +852,7 @@ - + @@ -905,21 +905,30 @@ - + - + - From ccb565e70a39541d1032bef97d3e6fe235bab72e Mon Sep 17 00:00:00 2001 From: Dobin Park Date: Mon, 11 Oct 2021 04:54:04 +0900 Subject: [PATCH 36/92] Responsive Width in Plugin Store List (WIP --- Flow.Launcher/SettingWindow.xaml | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index 260ab4280..c02c487a6 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -263,7 +263,9 @@ - + + + @@ -837,7 +839,7 @@ - - + + + + - + @@ -887,12 +892,12 @@ - + - - + + - - - - + + + + - - + + + - - - - + From 1317077dd8ab1102c97d93ad0477c255e4aa112b Mon Sep 17 00:00:00 2001 From: Dobin Park Date: Sun, 17 Oct 2021 10:57:50 +0900 Subject: [PATCH 66/92] - Change the popup to windows notification --- Flow.Launcher/Msg.xaml.cs | 66 ++++++++++++--------------------------- 1 file changed, 20 insertions(+), 46 deletions(-) diff --git a/Flow.Launcher/Msg.xaml.cs b/Flow.Launcher/Msg.xaml.cs index 6bb2fc2dc..c6b26ccd5 100644 --- a/Flow.Launcher/Msg.xaml.cs +++ b/Flow.Launcher/Msg.xaml.cs @@ -5,59 +5,30 @@ using System.Windows.Forms; using System.Windows.Input; using System.Windows.Media.Animation; using System.Windows.Media.Imaging; +using System.Windows.Media; using Flow.Launcher.Helper; using Flow.Launcher.Infrastructure; using Flow.Launcher.Infrastructure.Image; +using Windows.UI; +using Windows.Data; +using Windows.Data.Xml.Dom; +using Windows.UI.Notifications; namespace Flow.Launcher { public partial class Msg : Window { - Storyboard fadeOutStoryboard = new Storyboard(); - private bool closing; public Msg() { InitializeComponent(); - var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position); - var dipWorkingArea = WindowsInteropHelper.TransformPixelsToDIP(this, - screen.WorkingArea.Width, - screen.WorkingArea.Height); - Left = dipWorkingArea.X - Width; - Top = dipWorkingArea.Y; - showAnimation.From = dipWorkingArea.Y; - showAnimation.To = dipWorkingArea.Y - Height; - // Create the fade out storyboard - fadeOutStoryboard.Completed += fadeOutStoryboard_Completed; - DoubleAnimation fadeOutAnimation = new DoubleAnimation(dipWorkingArea.Y - Height, dipWorkingArea.Y, new Duration(TimeSpan.FromSeconds(5))) - { - AccelerationRatio = 0.2 - }; - Storyboard.SetTarget(fadeOutAnimation, this); - Storyboard.SetTargetProperty(fadeOutAnimation, new PropertyPath(TopProperty)); - fadeOutStoryboard.Children.Add(fadeOutAnimation); - - imgClose.Source = ImageLoader.Load(Path.Combine(Infrastructure.Constant.ProgramDirectory, "Images\\close.png")); - imgClose.MouseUp += imgClose_MouseUp; - } - - void imgClose_MouseUp(object sender, MouseButtonEventArgs e) - { - if (!closing) - { - closing = true; - fadeOutStoryboard.Begin(); - } - } - - private void fadeOutStoryboard_Completed(object sender, EventArgs e) - { - Close(); } public void Show(string title, string subTitle, string iconPath) { + + tbTitle.Text = title; tbSubTitle.Text = subTitle; if (string.IsNullOrEmpty(subTitle)) @@ -68,20 +39,23 @@ namespace Flow.Launcher { imgIco.Source = ImageLoader.Load(Path.Combine(Constant.ProgramDirectory, "Images\\app.png")); } - else { + else + { imgIco.Source = ImageLoader.Load(iconPath); } - Show(); + /* Using Windows Notification System */ + var ToastTitle = title; + var ToastsubTitle = subTitle; + var Icon = imgIco.Source; + var xml = $"\"meziantou\"/{ToastTitle}" + + $"{ToastsubTitle}"; + var toastXml = new XmlDocument(); + toastXml.LoadXml(xml); + var toast = new ToastNotification(toastXml); + ToastNotificationManager.CreateToastNotifier("Flow Launcher").Show(toast); - Dispatcher.InvokeAsync(async () => - { - if (!closing) - { - closing = true; - await Dispatcher.InvokeAsync(fadeOutStoryboard.Begin); - } - }); } + } } From 52b357952527ed9c1836b91ac2ac9cd53b229042 Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Sat, 16 Oct 2021 21:28:55 -0500 Subject: [PATCH 67/92] Implement Install & Refresh Button - Add ShowMainWindow API for IPublicAPI --- Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 5 +++ Flow.Launcher/PublicAPIInstance.cs | 2 + Flow.Launcher/SettingWindow.xaml | 40 ++++++++++--------- Flow.Launcher/SettingWindow.xaml.cs | 17 ++++++++ .../ViewModel/SettingWindowViewModel.cs | 7 ++++ 5 files changed, 53 insertions(+), 18 deletions(-) diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs index d9cdf5581..974eafa96 100644 --- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs +++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs @@ -59,6 +59,11 @@ namespace Flow.Launcher.Plugin /// Optional message subtitle void ShowMsgError(string title, string subTitle = ""); + /// + /// Show the MainWindow when hiding + /// + void ShowMainWindow(); + /// /// Show message box /// diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index 6f995671d..70d54619d 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -68,6 +68,8 @@ namespace Flow.Launcher public void RestarApp() => RestartApp(); + public void ShowMainWindow() => _mainVM.MainWindowVisibility = Visibility.Visible; + public void CheckForNewUpdate() => _settingsVM.UpdateApp(); public void SaveAppAllSettings() diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index 8a5feb866..8aaef7054 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -37,7 +37,7 @@ - + - @@ -998,7 +999,10 @@ - @@ -1079,7 +1083,7 @@ + Visibility="Visible" /> @@ -1112,7 +1116,7 @@ - + diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs index 4d36ec5da..4b58b9c6a 100644 --- a/Flow.Launcher/SettingWindow.xaml.cs +++ b/Flow.Launcher/SettingWindow.xaml.cs @@ -14,6 +14,7 @@ using Flow.Launcher.Plugin.SharedCommands; using Flow.Launcher.ViewModel; using Flow.Launcher.Helper; using System.Windows.Controls; +using Flow.Launcher.Core.ExternalPlugins; namespace Flow.Launcher { @@ -264,6 +265,22 @@ namespace Flow.Launcher FilesFolders.OpenPath(Path.Combine(DataLocation.DataDirectory(), Constant.Themes)); } + private void OnPluginStoreRefreshClick(object sender, RoutedEventArgs e) + { + _ = viewModel.RefreshExternalPluginsAsync(); + } + + private void OnExternalPluginInstallClick(object sender, RoutedEventArgs e) + { + if(sender is Button { DataContext: UserPlugin plugin }) + { + var pluginsManagerPlugin = PluginManager.GetPluginForId("9f8f9b14-2518-4907-b211-35ab6290dee7"); + var actionKeywrod = pluginsManagerPlugin.Metadata.ActionKeywords.Count == 0 ? "" : pluginsManagerPlugin.Metadata.ActionKeywords[0]; + API.ChangeQuery($"{actionKeywrod} install {plugin.Name}"); + API.ShowMainWindow(); + } + } + /* private void OnPluginActionKeywordsClick(object sender, RoutedEventArgs e) { diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs index 7f16da8ae..6bbf22c41 100644 --- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs +++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; +using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Media; @@ -265,6 +266,12 @@ namespace Flow.Launcher.ViewModel } } + public async Task RefreshExternalPluginsAsync() + { + await PluginsManifest.UpdateManifestAsync(); + OnPropertyChanged(nameof(ExternalPlugins)); + } + #endregion From da12a0616f461567bce4429a986ac3b10753669e Mon Sep 17 00:00:00 2001 From: Dobin Park Date: Sun, 17 Oct 2021 11:44:25 +0900 Subject: [PATCH 68/92] Add style for toggle button --- Flow.Launcher/SettingWindow.xaml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index 8aaef7054..e6612e4dc 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -37,7 +37,6 @@ - + + - - - - - - - - - + + + + + + + + + + + - + - + - - - - + + + - - - + + - - - + + + + - - - + + + - + - - - - - - - - + + + + + + - + - + - - + - - + - - - - - - - - - - - - + - - + - - + + + - - - + + - - - + + + + @@ -912,125 +915,128 @@ BorderThickness="1 1 1 2"/> - + - - - - - - - - + Padding="0 0 0 0" Width="Auto" VerticalContentAlignment="Center" HorizontalAlignment="Stretch"> + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - + + + - - - - - - + + + + + - + - + - - - - - + + + + + - - - - - - - + + + + + + + - - - + + - - - - + + + - + + - - - - - - - + + + + + - - - - + + + + + From 3bacb3fc0753ccb0c77814de465e120826df3063 Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Thu, 21 Oct 2021 22:29:03 -0500 Subject: [PATCH 78/92] Revert "add scroll movement with drag" This reverts commit f6d4736f1ab8766822f1d394d7dc3b3f4418110a. --- Flow.Launcher/SettingWindow.xaml | 444 +++++++++++++++---------------- 1 file changed, 219 insertions(+), 225 deletions(-) diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index 7c09a8d0f..a28886094 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -658,105 +658,103 @@ - - - - - - - - - - + + + + + + + + - - + - - - - - - - - + + + + + + + - - - - + + - + - - - - + + + - - - - - + + + + + + + + + + + - + - + - - - - + + + - - - + + - - - + + + + - - - + + + - + - - - - - - - - + + + + + + - + - + - - + - - + - - - - - - - - - - - - + - - + - - + + - - - + + + - - - - + + + @@ -915,128 +912,125 @@ BorderThickness="1 1 1 2"/> - - - - - - - - - - + ScrollViewer.IsDeferredScrollingEnabled="True" ScrollViewer.CanContentScroll="False" + Padding="0 0 0 0" Width="Auto" VerticalContentAlignment="Center" HorizontalAlignment="Stretch" ui:ScrollViewerHelper.AutoHideScrollBars="{Binding AutoHideScrollBar, Mode=OneWay}"> + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - + + + - - - - - - + + + + + - + - + - - - - - + + + + + - - - - - - - + + + + + + + - - - + + - - - - + + + - - + - - - - - - + + + + + - - - - - + + + + From 82464b79c511030713f21af05b1f2a171282f36b Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Thu, 21 Oct 2021 22:31:33 -0500 Subject: [PATCH 79/92] Remove deferred scroll option to enable direct scrolling --- Flow.Launcher/SettingWindow.xaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index a28886094..2dcc2fa02 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -662,7 +662,6 @@ ItemsSource="{Binding PluginViewModels}" Margin="5, 0, 0, 0" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ItemContainerStyle="{StaticResource PluginList}" - ScrollViewer.IsDeferredScrollingEnabled="True" ScrollViewer.CanContentScroll="False" Padding="0 0 7 0" Width="Auto" HorizontalAlignment="Stretch" SnapsToDevicePixels="True" ui:ScrollViewerHelper.AutoHideScrollBars="{Binding AutoHideScrollBar, Mode=OneWay}"> @@ -916,7 +915,6 @@ ItemsSource="{Binding ExternalPlugins}" Margin="6, 0, 0, 0" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ItemContainerStyle="{StaticResource StoreList}" SelectionMode="Single" - ScrollViewer.IsDeferredScrollingEnabled="True" ScrollViewer.CanContentScroll="False" Padding="0 0 0 0" Width="Auto" VerticalContentAlignment="Center" HorizontalAlignment="Stretch" ui:ScrollViewerHelper.AutoHideScrollBars="{Binding AutoHideScrollBar, Mode=OneWay}"> From 799ed81ef22106252a37462a3f9cea728c752eda Mon Sep 17 00:00:00 2001 From: Garulf <535299+Garulf@users.noreply.github.com> Date: Sat, 23 Oct 2021 05:44:12 -0400 Subject: [PATCH 80/92] Update en.xaml --- Flow.Launcher/Languages/en.xaml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 1dd6d3889..1e12c3d4e 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -19,29 +19,29 @@ Flow Launcher Settings General Portable Mode - All setting into single folder. You can use with USB drive or cloud. + Store all settings and user data in a central folder. Compatible with most removeable drives and cloud services. Start Flow Launcher on system startup Hide Flow Launcher when focus is lost Do not show new version notifications Remember last launch location Language Last Query Style - When you open Query box, decide what to do. + Show/Hide previous results when Flow Launcher is reactivated. Preserve Last Query Select last Query Empty last Query Maximum results shown Ignore hotkeys in fullscreen mode - If you're a gamer, We recommend turning it on. + Disable Flow Launcher activation when a Full screen application is active (Recommended for games). Python Directory Auto Update Auto Hide Scroll Bar in Setting - If you feel the scroll bar in the setting window is small, We recommend turning it off. + Hide the scroll bar when not in use. Select Hide Flow Launcher on startup Hide tray icon Query Search Precision - Search results become more accurate. + Changes minimum match score required for results. Should Use Pinyin Allows using Pinyin to search. Pinyin is the standard system of romanized spelling for translating Chinese Shadow effect is not allowed while current theme has blur effect enabled @@ -84,11 +84,11 @@ Hotkey Flow Launcher Hotkey - Enter the shortcut that open the Flow Launcher. + Enter shortcut to show/hide Flow Launcher. Open Result Modifiers - Shortcuts to select the result list. + Select a modifier to action results via keyboard. Show Hotkey - Display Shortcut in Result list . + Show result modifier with results. Custom Query Hotkey Query Delete @@ -197,4 +197,4 @@ Update files Update description - \ No newline at end of file + From e5a7c862b84790db7250ebaa8a8d7c122f847ab8 Mon Sep 17 00:00:00 2001 From: DB p Date: Sat, 23 Oct 2021 18:59:42 +0900 Subject: [PATCH 81/92] - remove AutoHideScrollbar tooltip --- Flow.Launcher/Languages/en.xaml | 1 - Flow.Launcher/Languages/ko.xaml | 1 - Flow.Launcher/SettingWindow.xaml | 2 -- 3 files changed, 4 deletions(-) diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 1e12c3d4e..5c27fd74b 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -36,7 +36,6 @@ Python Directory Auto Update Auto Hide Scroll Bar in Setting - Hide the scroll bar when not in use. Select Hide Flow Launcher on startup Hide tray icon diff --git a/Flow.Launcher/Languages/ko.xaml b/Flow.Launcher/Languages/ko.xaml index 6a145d670..79c7c12f7 100644 --- a/Flow.Launcher/Languages/ko.xaml +++ b/Flow.Launcher/Languages/ko.xaml @@ -36,7 +36,6 @@ Python 디렉토리 자동 업데이트 설정 창 스크롤바 숨기기 - 설정 창 스크롤바가 작다면 끄는 것을 추천합니다. 선택 시작 시 Flow Launcher 숨김 트레이 아이콘 숨기기 diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index 2dcc2fa02..980430b64 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -620,8 +620,6 @@ - Date: Sat, 23 Oct 2021 19:41:21 +0900 Subject: [PATCH 82/92] Remove Auto HIde Scrollbar section --- Flow.Launcher/SettingWindow.xaml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index 980430b64..fe5339045 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -615,17 +615,6 @@ DisplayMemberPath="Display" SelectedValuePath="LanguageCode" Grid.Column="2" /> - - - - - - - - From 1a5116023e1484cdc978302b36688092f88ff466 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Tue, 26 Oct 2021 06:41:25 +1100 Subject: [PATCH 83/92] remove auto hiding of setting window's scrollbar related 925f6bc55bd4b674951c02de4ffb7d472b1d8228, a452feb4c678ab1d8e8f9bce3919e91ef08edc22 --- Flow.Launcher.Infrastructure/UserSettings/Settings.cs | 2 -- Flow.Launcher/Languages/en.xaml | 1 - Flow.Launcher/Languages/ko.xaml | 1 - Flow.Launcher/Languages/sk.xaml | 2 -- Flow.Launcher/SettingWindow.xaml | 8 ++------ Flow.Launcher/ViewModel/SettingWindowViewModel.cs | 6 ------ 6 files changed, 2 insertions(+), 18 deletions(-) diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index 907314ba8..102446158 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -99,8 +99,6 @@ namespace Flow.Launcher.Infrastructure.UserSettings public bool RememberLastLaunchLocation { get; set; } public bool IgnoreHotkeysOnFullscreen { get; set; } - public bool AutoHideScrollBar { get; set; } - public HttpProxy Proxy { get; set; } = new HttpProxy(); [JsonConverter(typeof(JsonStringEnumConverter))] diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 5c27fd74b..8baab8355 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -35,7 +35,6 @@ Disable Flow Launcher activation when a Full screen application is active (Recommended for games). Python Directory Auto Update - Auto Hide Scroll Bar in Setting Select Hide Flow Launcher on startup Hide tray icon diff --git a/Flow.Launcher/Languages/ko.xaml b/Flow.Launcher/Languages/ko.xaml index 79c7c12f7..649895cea 100644 --- a/Flow.Launcher/Languages/ko.xaml +++ b/Flow.Launcher/Languages/ko.xaml @@ -35,7 +35,6 @@ 게이머라면 켜는 것을 추천합니다. Python 디렉토리 자동 업데이트 - 설정 창 스크롤바 숨기기 선택 시작 시 Flow Launcher 숨김 트레이 아이콘 숨기기 diff --git a/Flow.Launcher/Languages/sk.xaml b/Flow.Launcher/Languages/sk.xaml index b766ccfa2..70a5d3b7c 100644 --- a/Flow.Launcher/Languages/sk.xaml +++ b/Flow.Launcher/Languages/sk.xaml @@ -31,8 +31,6 @@ Ignorovať klávesové skratky v režime na celú obrazovku Priečinok s Pythonom Automatická aktualizácia - Automaticky skryť posuvník - Automaticky skrývať posuvník v okne nastavení a zobraziť ho, keď naň prejdete myšou Vybrať Schovať Flow Launcher po spustení Schovať ikonu z oblasti oznámení diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index fe5339045..8fc214da7 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -401,7 +401,6 @@ + Padding="0 0 7 0" Width="Auto" HorizontalAlignment="Stretch" SnapsToDevicePixels="True"> @@ -902,7 +901,7 @@ ItemsSource="{Binding ExternalPlugins}" Margin="6, 0, 0, 0" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ItemContainerStyle="{StaticResource StoreList}" SelectionMode="Single" - Padding="0 0 0 0" Width="Auto" VerticalContentAlignment="Center" HorizontalAlignment="Stretch" ui:ScrollViewerHelper.AutoHideScrollBars="{Binding AutoHideScrollBar, Mode=OneWay}"> + Padding="0 0 0 0" Width="Auto" VerticalContentAlignment="Center" HorizontalAlignment="Stretch"> @@ -1038,7 +1037,6 @@ @@ -1314,7 +1312,6 @@ @@ -1442,7 +1439,6 @@ diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs index 6bbf22c41..dde540b0c 100644 --- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs +++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs @@ -63,12 +63,6 @@ namespace Flow.Launcher.ViewModel } } - public bool AutoHideScrollBar - { - get => Settings.AutoHideScrollBar; - set => Settings.AutoHideScrollBar = value; - } - // This is only required to set at startup. When portable mode enabled/disabled a restart is always required private bool _portableMode = DataLocation.PortableDataLocationInUse(); public bool PortableMode From 6e6db2c67b835e04621852b4eb458981e19cc475 Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Mon, 25 Oct 2021 17:52:45 -0500 Subject: [PATCH 84/92] fix iconpath other than default icon --- Flow.Launcher/Notification.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher/Notification.cs b/Flow.Launcher/Notification.cs index 8933dc95e..b6aba7727 100644 --- a/Flow.Launcher/Notification.cs +++ b/Flow.Launcher/Notification.cs @@ -19,8 +19,8 @@ namespace Flow.Launcher { /* Using Windows Notification System */ var Icon = !File.Exists(iconPath) - ? ImageLoader.Load(Path.Combine(Constant.ProgramDirectory, "Images\\app.png")) - : ImageLoader.Load(iconPath); + ? Path.Combine(Constant.ProgramDirectory, "Images\\app.png") + : iconPath; var xml = $"\"meziantou\"/{title}" + $"{subTitle}"; From 8a59e87f997db2f4991de4786c5e2aa5bd7272d5 Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Mon, 25 Oct 2021 18:51:34 -0500 Subject: [PATCH 85/92] Fix unselected issue for bookmark plugin by using binding (Don't understand Reason it doesn't work before) --- .../Views/SettingsControl.xaml | 12 ++++---- .../Views/SettingsControl.xaml.cs | 30 +++++++++++-------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml index 7b7ccbeea..abe1f0ad5 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml @@ -22,12 +22,12 @@ diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml.cs index 2f67b999c..56fa58acf 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml.cs @@ -3,34 +3,38 @@ using System.Windows; using System.Windows.Controls; using Flow.Launcher.Plugin.BrowserBookmark.Models; using System.Windows.Input; +using System.ComponentModel; namespace Flow.Launcher.Plugin.BrowserBookmark.Views { /// /// Interaction logic for BrowserBookmark.xaml /// - public partial class SettingsControl + public partial class SettingsControl : INotifyPropertyChanged { public Settings Settings { get; } public CustomBrowser SelectedCustomBrowser { get; set; } + public bool OpenInNewBrowserWindow + { + get => Settings.OpenInNewBrowserWindow; + set + { + Settings.OpenInNewBrowserWindow = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(OpenInNewBrowserWindow))); + } + } + public bool OpenInNewTab + { + get => !OpenInNewBrowserWindow; + } public SettingsControl(Settings settings) { Settings = settings; InitializeComponent(); - NewWindowBrowser.IsChecked = Settings.OpenInNewBrowserWindow; - NewTabInBrowser.IsChecked = !Settings.OpenInNewBrowserWindow; } - private void OnNewBrowserWindowClick(object sender, RoutedEventArgs e) - { - Settings.OpenInNewBrowserWindow = true; - } - - private void OnNewTabClick(object sender, RoutedEventArgs e) - { - Settings.OpenInNewBrowserWindow = false; - } + public event PropertyChangedEventHandler PropertyChanged; private void OnChooseClick(object sender, RoutedEventArgs e) { @@ -61,7 +65,7 @@ namespace Flow.Launcher.Plugin.BrowserBookmark.Views private void DeleteCustomBrowser(object sender, RoutedEventArgs e) { - if(CustomBrowsers.SelectedItem is CustomBrowser selectedCustomBrowser) + if (CustomBrowsers.SelectedItem is CustomBrowser selectedCustomBrowser) { Settings.CustomChromiumBrowsers.Remove(selectedCustomBrowser); } From 5487834ed02626cd4836b6e95488d8205b37ed47 Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Mon, 25 Oct 2021 19:02:22 -0500 Subject: [PATCH 86/92] Add back field to avoid duplicate plugin control loading --- Flow.Launcher/SettingWindow.xaml | 4 ++-- Flow.Launcher/ViewModel/PluginViewModel.cs | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index 8fc214da7..ac6138644 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -774,7 +774,7 @@