From 003df049e1c7f32313df55fccadab171b6833277 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sat, 17 May 2025 20:40:40 +1000 Subject: [PATCH 1/7] add dedicated clear result indicator for query and non-query usage --- Flow.Launcher/ViewModel/MainViewModel.cs | 36 ++++++++++++++++++------ 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index 401f71ae3ef..64fb85296fc 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -267,7 +267,7 @@ public void RegisterResultsUpdatedEvent() if (token.IsCancellationRequested) return; - if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(resultsCopy, pair.Metadata, e.Query, + if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(resultsCopy, pair.Metadata, e.Query, token))) { App.API.LogError(ClassName, "Unable to add item to Result Update Queue"); @@ -793,7 +793,7 @@ private ResultsViewModel SelectedResults public Visibility ProgressBarVisibility { get; set; } public Visibility MainWindowVisibility { get; set; } - + // This is to be used for determining the visibility status of the main window instead of MainWindowVisibility // because it is more accurate and reliable representation than using Visibility as a condition check public bool MainWindowVisibilityStatus { get; set; } = true; @@ -1070,7 +1070,7 @@ private bool CanExternalPreviewSelectedResult(out string path) path = QueryResultsPreviewed() ? Results.SelectedItem?.Result?.Preview.FilePath : string.Empty; return !string.IsNullOrEmpty(path); } - + private bool QueryResultsPreviewed() { var previewed = PreviewSelectedItem == Results.SelectedItem; @@ -1280,7 +1280,7 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b // Update the query's IsReQuery property to true if this is a re-query query.IsReQuery = isReQuery; - + ICollection plugins = Array.Empty(); if (currentIsHomeQuery) @@ -1312,8 +1312,7 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b } } - var validPluginNames = plugins.Select(x => $"<{x.Metadata.Name}>"); - App.API.LogDebug(ClassName, $"Valid <{plugins.Count}> plugins: {string.Join(" ", validPluginNames)}"); + App.API.LogDebug(ClassName, $"Valid <{plugins.Count}> plugins: {string.Join(" ", plugins.Select(x => $"<{x.Metadata.Name}>"))}"); // Do not wait for performance improvement /*if (string.IsNullOrEmpty(query.ActionKeyword)) @@ -1341,6 +1340,9 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b Task[] tasks; if (currentIsHomeQuery) { + if (ShouldClearExistingResultsForNonQuery(plugins)) + Results.Clear(); + tasks = plugins.Select(plugin => plugin.Metadata.HomeDisabled switch { false => QueryTaskAsync(plugin, currentCancellationToken), @@ -1432,7 +1434,7 @@ await PluginManager.QueryHomeForPluginAsync(plugin, query, token) : App.API.LogDebug(ClassName, $"Update results for plugin <{plugin.Metadata.Name}>"); // Indicate if to clear existing results so to show only ones from plugins with action keywords - var shouldClearExistingResults = ShouldClearExistingResults(query, currentIsHomeQuery); + var shouldClearExistingResults = ShouldClearExistingResultsForQuery(query, currentIsHomeQuery); _lastQuery = query; _previousIsHomeQuery = currentIsHomeQuery; @@ -1454,8 +1456,13 @@ void QueryHistoryTask(CancellationToken token) App.API.LogDebug(ClassName, $"Update results for history"); + // Indicate if to clear existing results so to show only ones from plugins with action keywords + var shouldClearExistingResults = ShouldClearExistingResultsForQuery(query, currentIsHomeQuery); + _lastQuery = query; + _previousIsHomeQuery = currentIsHomeQuery; + if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(results, _historyMetadata, query, - token))) + token, reSelect, shouldClearExistingResults))) { App.API.LogError(ClassName, "Unable to add item to Result Update Queue"); } @@ -1552,7 +1559,7 @@ private async Task BuildQueryAsync(IEnumerable builtIn /// The current query. /// A flag indicating if the current query is a home query. /// True if the existing results should be cleared, false otherwise. - private bool ShouldClearExistingResults(Query query, bool currentIsHomeQuery) + private bool ShouldClearExistingResultsForQuery(Query query, bool currentIsHomeQuery) { // If previous or current results are from home query, we need to clear them if (_previousIsHomeQuery || currentIsHomeQuery) @@ -1571,6 +1578,17 @@ private bool ShouldClearExistingResults(Query query, bool currentIsHomeQuery) return false; } + private bool ShouldClearExistingResultsForNonQuery(ICollection plugins) + { + if (!Settings.ShowHistoryResultsForHomePage && (plugins.Count == 0 || plugins.All(x => x.Metadata.HomeDisabled == true))) + { + App.API.LogDebug(ClassName, $"Cleared old results"); + return true; + } + + return false; + } + private Result ContextMenuTopMost(Result result) { Result menu; From b4955f7474ac7b07658fb40220551865cb9d96aa Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sat, 17 May 2025 20:41:25 +1000 Subject: [PATCH 2/7] add subscriber for show history result toggle in settings --- .../UserSettings/Settings.cs | 15 ++++++++++++++- Flow.Launcher/MainWindow.xaml.cs | 1 + 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index 34bf4f90e5c..387469d247d 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -173,7 +173,20 @@ public bool ShowHomePage } } - public bool ShowHistoryResultsForHomePage { get; set; } = false; + public bool _showHistoryResultsForHomePage { get; set; } = false; + public bool ShowHistoryResultsForHomePage + { + get => _showHistoryResultsForHomePage; + set + { + if(_showHistoryResultsForHomePage != value) + { + _showHistoryResultsForHomePage = value; + OnPropertyChanged(); + } + } + } + public int MaxHistoryResultsToShowForHomePage { get; set; } = 5; public int CustomExplorerIndex { get; set; } = 0; diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index e243549e31e..18bceedd863 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -275,6 +275,7 @@ private async void OnLoaded(object sender, RoutedEventArgs _) InitializeContextMenu(); break; case nameof(Settings.ShowHomePage): + case nameof(Settings.ShowHistoryResultsForHomePage): if (_viewModel.QueryResultsSelected() && string.IsNullOrEmpty(_viewModel.QueryText)) { _viewModel.QueryResults(); From 2941e036bc864507211ed37ed9ba2ec140862daf Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sat, 17 May 2025 21:08:18 +1000 Subject: [PATCH 3/7] add logging and method summaries --- Flow.Launcher/ViewModel/MainViewModel.cs | 23 +++++++++++++++++---- Flow.Launcher/ViewModel/ResultsViewModel.cs | 3 +++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index 64fb85296fc..bfda18b9a1d 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -1341,7 +1341,11 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b if (currentIsHomeQuery) { if (ShouldClearExistingResultsForNonQuery(plugins)) + { Results.Clear(); + App.API.LogDebug(ClassName, $"Existing results are cleared for non-query"); + } + tasks = plugins.Select(plugin => plugin.Metadata.HomeDisabled switch { @@ -1548,7 +1552,9 @@ private async Task BuildQueryAsync(IEnumerable builtIn /// /// Determines whether the existing search results should be cleared based on the current query and the previous query type. - /// This is needed because of the design that treats plugins with action keywords and global action keywords separately. Results are gathered + /// This is used to indicate to QueryTaskAsync or QueryHistoryTask whether to clear results. If both QueryTaskAsync and QueryHistoryTask + /// are not called then use ShouldClearExistingResultsForNonQuery instead. + /// This method needed because of the design that treats plugins with action keywords and global action keywords separately. Results are gathered /// either from plugins with matching action keywords or global action keyword, but not both. So when the current results are from plugins /// with a matching action keyword and a new result set comes from a new query with the global action keyword, the existing results need to be cleared, /// and vice versa. The same applies to home page query results. @@ -1564,25 +1570,34 @@ private bool ShouldClearExistingResultsForQuery(Query query, bool currentIsHomeQ // If previous or current results are from home query, we need to clear them if (_previousIsHomeQuery || currentIsHomeQuery) { - App.API.LogDebug(ClassName, $"Cleared old results"); + App.API.LogDebug(ClassName, $"Existing results should be cleared for query"); return true; } // If the last and current query are not home query type, we need to check the action keyword if (_lastQuery?.ActionKeyword != query?.ActionKeyword) { - App.API.LogDebug(ClassName, $"Cleared old results"); + App.API.LogDebug(ClassName, $"Existing results should be cleared for query"); return true; } return false; } + /// + /// Determines whether existing results should be cleared for non-query calls. + /// A non-query call is where QueryTaskAsync and QueryHistoryTask methods are both not called. + /// QueryTaskAsync and QueryHistoryTask both handle result updating (clearing if required) so directly calling + /// Results.Clear() is not required. However when both are not called, we need to directly clear results and this + /// method determines on the condition when clear results should happen. + /// + /// The collection of plugins to check. + /// True if existing results should be cleared, false otherwise. private bool ShouldClearExistingResultsForNonQuery(ICollection plugins) { if (!Settings.ShowHistoryResultsForHomePage && (plugins.Count == 0 || plugins.All(x => x.Metadata.HomeDisabled == true))) { - App.API.LogDebug(ClassName, $"Cleared old results"); + App.API.LogDebug(ClassName, $"Existing results should be cleared for non-query"); return true; } diff --git a/Flow.Launcher/ViewModel/ResultsViewModel.cs b/Flow.Launcher/ViewModel/ResultsViewModel.cs index cd2736afa37..46a92f75053 100644 --- a/Flow.Launcher/ViewModel/ResultsViewModel.cs +++ b/Flow.Launcher/ViewModel/ResultsViewModel.cs @@ -235,7 +235,10 @@ private List NewResults(ICollection resultsFo var newResults = resultsForUpdates.SelectMany(u => u.Results, (u, r) => new ResultViewModel(r, _settings)); if (resultsForUpdates.Any(x => x.shouldClearExistingResults)) + { + App.API.LogDebug("NewResults", $"Existing results are cleared for query"); return newResults.OrderByDescending(rv => rv.Result.Score).ToList(); + } return Results.Where(r => r?.Result != null && resultsForUpdates.All(u => u.ID != r.Result.PluginID)) .Concat(newResults) From 50fced959e768c333895af98e8323d6f1e67595a Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sat, 17 May 2025 21:10:47 +1000 Subject: [PATCH 4/7] remove async warning --- Flow.Launcher/MainWindow.xaml.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index 18bceedd863..f91d9d5597c 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -105,7 +105,7 @@ private void OnSourceInitialized(object sender, EventArgs e) Win32Helper.DisableControlBox(this); } - private async void OnLoaded(object sender, RoutedEventArgs _) + private void OnLoaded(object sender, RoutedEventArgs _) { // Check first launch if (_settings.FirstLaunch) From 073594fdeb365a504ac29927898136f3bcf0c076 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sat, 17 May 2025 22:02:45 +1000 Subject: [PATCH 5/7] formatting --- Flow.Launcher/ViewModel/MainViewModel.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index bfda18b9a1d..658eabde7f5 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -1280,8 +1280,6 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b // Update the query's IsReQuery property to true if this is a re-query query.IsReQuery = isReQuery; - - ICollection plugins = Array.Empty(); if (currentIsHomeQuery) { @@ -1345,7 +1343,6 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b Results.Clear(); App.API.LogDebug(ClassName, $"Existing results are cleared for non-query"); } - tasks = plugins.Select(plugin => plugin.Metadata.HomeDisabled switch { From 0b4409711115abb8baa34d7e82b7acd4aa467f99 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sat, 17 May 2025 22:12:35 +1000 Subject: [PATCH 6/7] fix encapsulation for show results --- 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 387469d247d..8890c4581d6 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -173,7 +173,7 @@ public bool ShowHomePage } } - public bool _showHistoryResultsForHomePage { get; set; } = false; + private bool _showHistoryResultsForHomePage = false; public bool ShowHistoryResultsForHomePage { get => _showHistoryResultsForHomePage; From 7399d112611cf785cba2dd9afb2f15e79451ad95 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sat, 17 May 2025 20:27:31 +0800 Subject: [PATCH 7/7] Add whitespace for if --- .../UserSettings/Settings.cs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index 8890c4581d6..9d2d854f4b3 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -179,7 +179,7 @@ public bool ShowHistoryResultsForHomePage get => _showHistoryResultsForHomePage; set { - if(_showHistoryResultsForHomePage != value) + if (_showHistoryResultsForHomePage != value) { _showHistoryResultsForHomePage = value; OnPropertyChanged(); @@ -404,29 +404,29 @@ public List RegisteredHotkeys var list = FixedHotkeys(); // Customizeable hotkeys - if(!string.IsNullOrEmpty(Hotkey)) + if (!string.IsNullOrEmpty(Hotkey)) list.Add(new(Hotkey, "flowlauncherHotkey", () => Hotkey = "")); - if(!string.IsNullOrEmpty(PreviewHotkey)) + if (!string.IsNullOrEmpty(PreviewHotkey)) list.Add(new(PreviewHotkey, "previewHotkey", () => PreviewHotkey = "")); - if(!string.IsNullOrEmpty(AutoCompleteHotkey)) + if (!string.IsNullOrEmpty(AutoCompleteHotkey)) list.Add(new(AutoCompleteHotkey, "autoCompleteHotkey", () => AutoCompleteHotkey = "")); - if(!string.IsNullOrEmpty(AutoCompleteHotkey2)) + if (!string.IsNullOrEmpty(AutoCompleteHotkey2)) list.Add(new(AutoCompleteHotkey2, "autoCompleteHotkey", () => AutoCompleteHotkey2 = "")); - if(!string.IsNullOrEmpty(SelectNextItemHotkey)) + if (!string.IsNullOrEmpty(SelectNextItemHotkey)) list.Add(new(SelectNextItemHotkey, "SelectNextItemHotkey", () => SelectNextItemHotkey = "")); - if(!string.IsNullOrEmpty(SelectNextItemHotkey2)) + if (!string.IsNullOrEmpty(SelectNextItemHotkey2)) list.Add(new(SelectNextItemHotkey2, "SelectNextItemHotkey", () => SelectNextItemHotkey2 = "")); - if(!string.IsNullOrEmpty(SelectPrevItemHotkey)) + if (!string.IsNullOrEmpty(SelectPrevItemHotkey)) list.Add(new(SelectPrevItemHotkey, "SelectPrevItemHotkey", () => SelectPrevItemHotkey = "")); - if(!string.IsNullOrEmpty(SelectPrevItemHotkey2)) + if (!string.IsNullOrEmpty(SelectPrevItemHotkey2)) list.Add(new(SelectPrevItemHotkey2, "SelectPrevItemHotkey", () => SelectPrevItemHotkey2 = "")); - if(!string.IsNullOrEmpty(SettingWindowHotkey)) + if (!string.IsNullOrEmpty(SettingWindowHotkey)) list.Add(new(SettingWindowHotkey, "SettingWindowHotkey", () => SettingWindowHotkey = "")); - if(!string.IsNullOrEmpty(OpenContextMenuHotkey)) + if (!string.IsNullOrEmpty(OpenContextMenuHotkey)) list.Add(new(OpenContextMenuHotkey, "OpenContextMenuHotkey", () => OpenContextMenuHotkey = "")); - if(!string.IsNullOrEmpty(SelectNextPageHotkey)) + if (!string.IsNullOrEmpty(SelectNextPageHotkey)) list.Add(new(SelectNextPageHotkey, "SelectNextPageHotkey", () => SelectNextPageHotkey = "")); - if(!string.IsNullOrEmpty(SelectPrevPageHotkey)) + if (!string.IsNullOrEmpty(SelectPrevPageHotkey)) list.Add(new(SelectPrevPageHotkey, "SelectPrevPageHotkey", () => SelectPrevPageHotkey = "")); if (!string.IsNullOrEmpty(CycleHistoryUpHotkey)) list.Add(new(CycleHistoryUpHotkey, "CycleHistoryUpHotkey", () => CycleHistoryUpHotkey = ""));