diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index 231e8cc0f..08035ee44 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -216,16 +216,21 @@ namespace Flow.Launcher.Infrastructure.UserSettings } } - private bool _showHistoryResultsForHomePage = false; - public bool ShowHistoryResultsForHomePage + private bool _showHistoryQueryResultsForHomePage = false; + public bool ShowHistoryQueryResultsForHomePage { - get => _showHistoryResultsForHomePage; + get => _showHistoryQueryResultsForHomePage; set { - if (_showHistoryResultsForHomePage != value) + if (_showHistoryQueryResultsForHomePage != value) { - _showHistoryResultsForHomePage = value; + _showHistoryQueryResultsForHomePage = value; OnPropertyChanged(); + if (value && _showHistoryExecutedResultsForHomePage) + { + _showHistoryExecutedResultsForHomePage = false; + OnPropertyChanged(nameof(ShowHistoryExecutedResultsForHomePage)); + } } } } @@ -241,6 +246,11 @@ namespace Flow.Launcher.Infrastructure.UserSettings { _showHistoryExecutedResultsForHomePage = value; OnPropertyChanged(); + if (value && _showHistoryQueryResultsForHomePage) + { + _showHistoryQueryResultsForHomePage = false; + OnPropertyChanged(nameof(ShowHistoryQueryResultsForHomePage)); + } } } } diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 0fd1af78d..abadab964 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -164,7 +164,11 @@ Please check your system registry access or contact support. Home Page Show home page results when query text is empty. - Show History Results in Home Page + Home Page History + Choose the type of history to show on the home page + Query History + Executed History + Show History Query Results in Home Page Show History Executed Results in Home Page Maximum History Results Shown in Home Page This can only be edited if plugin supports Home feature and Home Page is enabled. diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index 7b6a0d79b..e6696c34c 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -317,7 +317,7 @@ namespace Flow.Launcher InitializeContextMenu(); break; case nameof(Settings.ShowHomePage): - case nameof(Settings.ShowHistoryResultsForHomePage): + case nameof(Settings.ShowHistoryQueryResultsForHomePage): if (_viewModel.QueryResultsSelected() && string.IsNullOrEmpty(_viewModel.QueryText)) { _viewModel.QueryResults(); diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml index cfbe8c6c1..9fe45e89e 100644 --- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml +++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml @@ -373,39 +373,30 @@ OnContent="{DynamicResource enable}" /> - - - - - - - - - + + + + + + + + + + + - - - - Items { get; private set; } = new List(); - private int _maxHistory = 300; + [JsonInclude] public List Items { get; private set; } = []; + private const int MaxHistory = 300; public void Add(Result result) { - Items.Add(result); - } + var item = new ExecutedHistoryItem + { + Title = result.Title, + SubTitle = result.SubTitle, + IcoPath = result.IcoPath ?? string.Empty, + PluginID = result.PluginID, + OriginQuery = result.OriginQuery, + ExecutedDateTime = DateTime.Now + }; + var existing = Items.FirstOrDefault(x => x.OriginQuery.RawQuery == item.OriginQuery.RawQuery && x.PluginID == item.PluginID); + if (existing != null) + { + Items.Remove(existing); + } + + Items.Add(item); + + if (Items.Count > MaxHistory) + { + Items.RemoveAt(0); + } + } } diff --git a/Flow.Launcher/Storage/ExecutedHistoryItem.cs b/Flow.Launcher/Storage/ExecutedHistoryItem.cs new file mode 100644 index 000000000..8ae6d3336 --- /dev/null +++ b/Flow.Launcher/Storage/ExecutedHistoryItem.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Flow.Launcher.Plugin; + +namespace Flow.Launcher.Storage; +public class ExecutedHistoryItem +{ + public string Title { get; set; } = string.Empty; + public string SubTitle { get; set; } = string.Empty; + public string IcoPath { get; set; } = string.Empty; + public string PluginID { get; set; } = string.Empty; + public Query OriginQuery { get; set; } = null!; + public DateTime ExecutedDateTime { get; set; } +} diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index d492f28c5..abdd239e9 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -41,9 +41,11 @@ namespace Flow.Launcher.ViewModel private string _ignoredQueryText; // Used to ignore query text change when switching between context menu and query results private readonly FlowLauncherJsonStorage _historyItemsStorage; + private readonly FlowLauncherJsonStorage _executedHistoryStorage; private readonly FlowLauncherJsonStorage _userSelectedRecordStorage; private readonly FlowLauncherJsonStorageTopMostRecord _topMostRecord; private readonly History _history; + private readonly ExecutedHistory _executedHistory; private int lastHistoryIndex = 1; private readonly UserSelectedRecord _userSelectedRecord; @@ -148,9 +150,11 @@ namespace Flow.Launcher.ViewModel }; _historyItemsStorage = new FlowLauncherJsonStorage(); + _executedHistoryStorage = new FlowLauncherJsonStorage(); _userSelectedRecordStorage = new FlowLauncherJsonStorage(); _topMostRecord = new FlowLauncherJsonStorageTopMostRecord(); _history = _historyItemsStorage.Load(); + _executedHistory = _executedHistoryStorage.Load(); _userSelectedRecord = _userSelectedRecordStorage.Load(); ContextMenu = new ResultsViewModel(Settings, this) @@ -529,6 +533,9 @@ namespace Flow.Launcher.ViewModel if (QueryResultsSelected()) { + if(Settings.ShowHistoryExecutedResultsForHomePage) + _executedHistory.Add(result); + _userSelectedRecord.Add(result); _history.Add(result.OriginQuery.RawQuery); lastHistoryIndex = 1; @@ -1448,10 +1455,14 @@ namespace Flow.Launcher.ViewModel }).ToArray(); // Query history results for home page firstly so it will be put on top of the results - if (Settings.ShowHistoryResultsForHomePage) + if (Settings.ShowHistoryQueryResultsForHomePage) { QueryHistoryTask(currentCancellationToken); } + else if (Settings.ShowHistoryExecutedResultsForHomePage) + { + QueryExecutedHistoryTask(currentCancellationToken); + } } else { @@ -1574,6 +1585,41 @@ namespace Flow.Launcher.ViewModel App.API.LogError(ClassName, "Unable to add item to Result Update Queue"); } } + + void QueryExecutedHistoryTask(CancellationToken token) + { + var historyItems = _executedHistory.Items.TakeLast(Settings.MaxHistoryResultsToShowForHomePage).Reverse(); + + var results = new List(); + foreach (var item in historyItems) + { + var result = new Result + { + Title = item.Title, + SubTitle = item.SubTitle, + IcoPath = item.IcoPath, + PluginID = item.PluginID, + OriginQuery = item.OriginQuery, + Action = _ => + { + App.API.ChangeQuery(item.OriginQuery.RawQuery); + return false; + }, + Glyph = new GlyphInfo(FontFamily: "/Resources/#Segoe Fluent Icons", Glyph: "\uE81C") + }; + results.Add(result); + } + + if (token.IsCancellationRequested) return; + + App.API.LogDebug(ClassName, "Update results for executed history"); + + if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(results, _historyMetadata, query, + token, reSelect))) + { + App.API.LogError(ClassName, "Unable to add item to Result Update Queue"); + } + } } private async Task ConstructQueryAsync(string queryText, IEnumerable customShortcuts, @@ -1698,7 +1744,7 @@ namespace Flow.Launcher.ViewModel /// 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))) + if (!Settings.ShowHistoryQueryResultsForHomePage && (plugins.Count == 0 || plugins.All(x => x.Metadata.HomeDisabled == true))) { App.API.LogDebug(ClassName, $"Existing results should be cleared for non-query"); return true; @@ -2163,6 +2209,7 @@ namespace Flow.Launcher.ViewModel public void Save() { _historyItemsStorage.Save(); + _executedHistoryStorage.Save(); _userSelectedRecordStorage.Save(); _topMostRecord.Save(); }