feat: radio button with history query option or history executed option

This commit is contained in:
01Dri 2025-10-02 00:03:48 -03:00
parent 3cc4f13f4d
commit c0369e6e76
7 changed files with 134 additions and 45 deletions

View file

@ -216,16 +216,21 @@ namespace Flow.Launcher.Infrastructure.UserSettings
} }
} }
private bool _showHistoryResultsForHomePage = false; private bool _showHistoryQueryResultsForHomePage = false;
public bool ShowHistoryResultsForHomePage public bool ShowHistoryQueryResultsForHomePage
{ {
get => _showHistoryResultsForHomePage; get => _showHistoryQueryResultsForHomePage;
set set
{ {
if (_showHistoryResultsForHomePage != value) if (_showHistoryQueryResultsForHomePage != value)
{ {
_showHistoryResultsForHomePage = value; _showHistoryQueryResultsForHomePage = value;
OnPropertyChanged(); OnPropertyChanged();
if (value && _showHistoryExecutedResultsForHomePage)
{
_showHistoryExecutedResultsForHomePage = false;
OnPropertyChanged(nameof(ShowHistoryExecutedResultsForHomePage));
}
} }
} }
} }
@ -241,6 +246,11 @@ namespace Flow.Launcher.Infrastructure.UserSettings
{ {
_showHistoryExecutedResultsForHomePage = value; _showHistoryExecutedResultsForHomePage = value;
OnPropertyChanged(); OnPropertyChanged();
if (value && _showHistoryQueryResultsForHomePage)
{
_showHistoryQueryResultsForHomePage = false;
OnPropertyChanged(nameof(ShowHistoryQueryResultsForHomePage));
}
} }
} }
} }

View file

@ -164,7 +164,11 @@
<system:String x:Key="KoreanImeSettingChangeFailSubTitle">Please check your system registry access or contact support.</system:String> <system:String x:Key="KoreanImeSettingChangeFailSubTitle">Please check your system registry access or contact support.</system:String>
<system:String x:Key="homePage">Home Page</system:String> <system:String x:Key="homePage">Home Page</system:String>
<system:String x:Key="homePageToolTip">Show home page results when query text is empty.</system:String> <system:String x:Key="homePageToolTip">Show home page results when query text is empty.</system:String>
<system:String x:Key="historyResultsForHomePage">Show History Results in Home Page</system:String> <system:String x:Key="homePageHistory">Home Page History</system:String>
<system:String x:Key="homePageHistoryTooltip">Choose the type of history to show on the home page</system:String>
<system:String x:Key="queryHistory">Query History</system:String>
<system:String x:Key="executedHistory">Executed History</system:String>
<system:String x:Key="historyQueryResultsForHomePage">Show History Query Results in Home Page</system:String>
<system:String x:Key="historyExecutedResultsForHomePage">Show History Executed Results in Home Page</system:String> <system:String x:Key="historyExecutedResultsForHomePage">Show History Executed Results in Home Page</system:String>
<system:String x:Key="historyResultsCountForHomePage">Maximum History Results Shown in Home Page</system:String> <system:String x:Key="historyResultsCountForHomePage">Maximum History Results Shown in Home Page</system:String>
<system:String x:Key="homeToggleBoxToolTip">This can only be edited if plugin supports Home feature and Home Page is enabled.</system:String> <system:String x:Key="homeToggleBoxToolTip">This can only be edited if plugin supports Home feature and Home Page is enabled.</system:String>

View file

@ -317,7 +317,7 @@ namespace Flow.Launcher
InitializeContextMenu(); InitializeContextMenu();
break; break;
case nameof(Settings.ShowHomePage): case nameof(Settings.ShowHomePage):
case nameof(Settings.ShowHistoryResultsForHomePage): case nameof(Settings.ShowHistoryQueryResultsForHomePage):
if (_viewModel.QueryResultsSelected() && string.IsNullOrEmpty(_viewModel.QueryText)) if (_viewModel.QueryResultsSelected() && string.IsNullOrEmpty(_viewModel.QueryText))
{ {
_viewModel.QueryResults(); _viewModel.QueryResults();

View file

@ -373,38 +373,29 @@
OnContent="{DynamicResource enable}" /> OnContent="{DynamicResource enable}" />
</cc:Card> </cc:Card>
<cc:ExCard Title="{DynamicResource historyResultsForHomePage}" Icon="&#xE81C;"> <cc:ExCard Title="{DynamicResource homePageHistory}" Margin="0 14 0 0" Icon="&#xE81C;" Sub="{DynamicResource homePageHistoryTooltip}">
<cc:ExCard.SideContent> <StackPanel Margin="15,10,0,0">
<ui:ToggleSwitch <RadioButton GroupName="HistoryType" Content="{DynamicResource historyQueryResultsForHomePage}"
IsOn="{Binding Settings.ShowHistoryResultsForHomePage}" IsChecked="{Binding Settings.ShowHistoryQueryResultsForHomePage}" />
OffContent="{DynamicResource disable}" <RadioButton GroupName="HistoryType" Content="{DynamicResource historyExecutedResultsForHomePage}"
OnContent="{DynamicResource enable}" /> IsChecked="{Binding Settings.ShowHistoryExecutedResultsForHomePage}"
</cc:ExCard.SideContent> Margin="0 0 0 0" />
<cc:Card Title="{DynamicResource historyResultsCountForHomePage}" Type="InsideFit">
<StackPanel Orientation="Vertical">
<ui:NumberBox
Width="120"
Margin="0 0 0 0"
Maximum="100"
Minimum="0"
SmallChange="5"
SpinButtonPlacementMode="Compact"
ValidationMode="InvalidInputOverwritten"
Value="{Binding MaxHistoryResultsToShowValue}" />
</StackPanel>
</cc:Card>
</cc:ExCard>
<cc:Card <cc:Card Title="{DynamicResource historyResultsCountForHomePage}" Type="InsideFit" Margin="0 10 0 0">
Title="{DynamicResource historyExecutedResultsForHomePage}" <StackPanel Orientation="Vertical">
Margin="0 14 0 0" <ui:NumberBox
Icon="&#xE81C;" Width="120"
Sub="{DynamicResource homePageToolTip}"> Margin="0 0 0 0"
<ui:ToggleSwitch Maximum="100"
IsOn="{Binding Settings.ShowHistoryExecutedResultsForHomePage}" Minimum="0"
OffContent="{DynamicResource disable}" SmallChange="5"
OnContent="{DynamicResource enable}" /> SpinButtonPlacementMode="Compact"
</cc:Card> ValidationMode="InvalidInputOverwritten"
Value="{Binding MaxHistoryResultsToShowValue}" />
</StackPanel>
</cc:Card>
</StackPanel>
</cc:ExCard>
<cc:Card <cc:Card
Title="{DynamicResource defaultFileManager}" Title="{DynamicResource defaultFileManager}"

View file

@ -5,17 +5,37 @@ using System.Text;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using System.Threading.Tasks; using System.Threading.Tasks;
using Flow.Launcher.Plugin; using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
namespace Flow.Launcher.Storage; namespace Flow.Launcher.Storage;
public class ExecutedHistory public class ExecutedHistory
{ {
[JsonInclude] [JsonInclude] public List<ExecutedHistoryItem> Items { get; private set; } = [];
public List<Result> Items { get; private set; } = new List<Result>(); private const int MaxHistory = 300;
private int _maxHistory = 300;
public void Add(Result result) 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);
}
}
} }

View file

@ -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; }
}

View file

@ -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 string _ignoredQueryText; // Used to ignore query text change when switching between context menu and query results
private readonly FlowLauncherJsonStorage<History> _historyItemsStorage; private readonly FlowLauncherJsonStorage<History> _historyItemsStorage;
private readonly FlowLauncherJsonStorage<ExecutedHistory> _executedHistoryStorage;
private readonly FlowLauncherJsonStorage<UserSelectedRecord> _userSelectedRecordStorage; private readonly FlowLauncherJsonStorage<UserSelectedRecord> _userSelectedRecordStorage;
private readonly FlowLauncherJsonStorageTopMostRecord _topMostRecord; private readonly FlowLauncherJsonStorageTopMostRecord _topMostRecord;
private readonly History _history; private readonly History _history;
private readonly ExecutedHistory _executedHistory;
private int lastHistoryIndex = 1; private int lastHistoryIndex = 1;
private readonly UserSelectedRecord _userSelectedRecord; private readonly UserSelectedRecord _userSelectedRecord;
@ -148,9 +150,11 @@ namespace Flow.Launcher.ViewModel
}; };
_historyItemsStorage = new FlowLauncherJsonStorage<History>(); _historyItemsStorage = new FlowLauncherJsonStorage<History>();
_executedHistoryStorage = new FlowLauncherJsonStorage<ExecutedHistory>();
_userSelectedRecordStorage = new FlowLauncherJsonStorage<UserSelectedRecord>(); _userSelectedRecordStorage = new FlowLauncherJsonStorage<UserSelectedRecord>();
_topMostRecord = new FlowLauncherJsonStorageTopMostRecord(); _topMostRecord = new FlowLauncherJsonStorageTopMostRecord();
_history = _historyItemsStorage.Load(); _history = _historyItemsStorage.Load();
_executedHistory = _executedHistoryStorage.Load();
_userSelectedRecord = _userSelectedRecordStorage.Load(); _userSelectedRecord = _userSelectedRecordStorage.Load();
ContextMenu = new ResultsViewModel(Settings, this) ContextMenu = new ResultsViewModel(Settings, this)
@ -529,6 +533,9 @@ namespace Flow.Launcher.ViewModel
if (QueryResultsSelected()) if (QueryResultsSelected())
{ {
if(Settings.ShowHistoryExecutedResultsForHomePage)
_executedHistory.Add(result);
_userSelectedRecord.Add(result); _userSelectedRecord.Add(result);
_history.Add(result.OriginQuery.RawQuery); _history.Add(result.OriginQuery.RawQuery);
lastHistoryIndex = 1; lastHistoryIndex = 1;
@ -1448,10 +1455,14 @@ namespace Flow.Launcher.ViewModel
}).ToArray(); }).ToArray();
// Query history results for home page firstly so it will be put on top of the results // 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); QueryHistoryTask(currentCancellationToken);
} }
else if (Settings.ShowHistoryExecutedResultsForHomePage)
{
QueryExecutedHistoryTask(currentCancellationToken);
}
} }
else else
{ {
@ -1574,6 +1585,41 @@ namespace Flow.Launcher.ViewModel
App.API.LogError(ClassName, "Unable to add item to Result Update Queue"); 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<Result>();
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<Query> ConstructQueryAsync(string queryText, IEnumerable<CustomShortcutModel> customShortcuts, private async Task<Query> ConstructQueryAsync(string queryText, IEnumerable<CustomShortcutModel> customShortcuts,
@ -1698,7 +1744,7 @@ namespace Flow.Launcher.ViewModel
/// <returns>True if existing results should be cleared, false otherwise.</returns> /// <returns>True if existing results should be cleared, false otherwise.</returns>
private bool ShouldClearExistingResultsForNonQuery(ICollection<PluginPair> plugins) private bool ShouldClearExistingResultsForNonQuery(ICollection<PluginPair> 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"); App.API.LogDebug(ClassName, $"Existing results should be cleared for non-query");
return true; return true;
@ -2163,6 +2209,7 @@ namespace Flow.Launcher.ViewModel
public void Save() public void Save()
{ {
_historyItemsStorage.Save(); _historyItemsStorage.Save();
_executedHistoryStorage.Save();
_userSelectedRecordStorage.Save(); _userSelectedRecordStorage.Save();
_topMostRecord.Save(); _topMostRecord.Save();
} }