Skip to content
Merged
7 changes: 7 additions & 0 deletions Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -291,5 +291,12 @@ public interface IPublicAPI
/// </summary>
/// <returns></returns>
public bool IsGameModeOn();

/// <summary>
/// Reloads the query.
/// This method should run
/// </summary>
/// <param name="reselect">Choose the first result after reload if true; keep the last selected result if false. Default is true.</param>
public void ReQuery(bool reselect = true);
}
}
2 changes: 2 additions & 0 deletions Flow.Launcher/PublicAPIInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,8 @@ public bool IsGameModeOn()
public void RegisterGlobalKeyboardCallback(Func<int, int, SpecialKeyState, bool> callback) => _globalKeyboardHandlers.Add(callback);
public void RemoveGlobalKeyboardCallback(Func<int, int, SpecialKeyState, bool> callback) => _globalKeyboardHandlers.Remove(callback);

public void ReQuery(bool reselect = true) => _mainVM.ReQuery(reselect);

#endregion

#region Private Methods
Expand Down
25 changes: 18 additions & 7 deletions Flow.Launcher/ViewModel/MainViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -210,14 +210,22 @@ private void LoadHistory()
}

[RelayCommand]
private void ReQuery()
public void ReQuery()
{
if (SelectedIsFromQueryResults())
{
QueryResults(isReQuery: true);
}
}

public void ReQuery(bool reselect)
{
if (SelectedIsFromQueryResults())
{
QueryResults(isReQuery: true, reSelect: reselect);
}
}

[RelayCommand]
private void LoadContextMenu()
{
Expand Down Expand Up @@ -775,7 +783,7 @@ private void QueryHistory()

private readonly IReadOnlyList<Result> _emptyResult = new List<Result>();

private async void QueryResults(bool isReQuery = false)
private async void QueryResults(bool isReQuery = false, bool reSelect = true)
{
_updateSource?.Cancel();

Expand Down Expand Up @@ -850,7 +858,7 @@ private async void QueryResults(bool isReQuery = false)

var tasks = plugins.Select(plugin => plugin.Metadata.Disabled switch
{
false => QueryTask(plugin),
false => QueryTask(plugin, reSelect),
true => Task.CompletedTask
}).ToArray();

Expand Down Expand Up @@ -878,7 +886,7 @@ private async void QueryResults(bool isReQuery = false)
}

// Local function
async Task QueryTask(PluginPair plugin)
async Task QueryTask(PluginPair plugin, bool reSelect = true)
{
// Since it is wrapped within a ThreadPool Thread, the synchronous context is null
// Task.Yield will force it to run in ThreadPool
Expand All @@ -892,7 +900,7 @@ async Task QueryTask(PluginPair plugin)
results ??= _emptyResult;

if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(results, plugin.Metadata, query,
currentCancellationToken)))
currentCancellationToken, reSelect)))
{
Log.Error("MainViewModel", "Unable to add item to Result Update Queue");
}
Expand Down Expand Up @@ -1133,7 +1141,7 @@ public void Save()
/// <summary>
/// To avoid deadlock, this method should not called from main thread
/// </summary>
public void UpdateResultView(IEnumerable<ResultsForUpdate> resultsForUpdates)
public void UpdateResultView(ICollection<ResultsForUpdate> resultsForUpdates)
{
if (!resultsForUpdates.Any())
return;
Expand Down Expand Up @@ -1172,7 +1180,10 @@ public void UpdateResultView(IEnumerable<ResultsForUpdate> resultsForUpdates)
}
}

Results.AddResults(resultsForUpdates, token);
// it should be the same for all results
bool reSelect = resultsForUpdates.First().ReSelectFirstResult;

Results.AddResults(resultsForUpdates, token, reSelect);
}

#endregion
Expand Down
24 changes: 7 additions & 17 deletions Flow.Launcher/ViewModel/ResultsForUpdate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,13 @@

namespace Flow.Launcher.ViewModel
{
public struct ResultsForUpdate
public record struct ResultsForUpdate(
IReadOnlyList<Result> Results,
PluginMetadata Metadata,
Query Query,
CancellationToken Token,
bool ReSelectFirstResult = true)
{
public IReadOnlyList<Result> Results { get; }

public PluginMetadata Metadata { get; }
public string ID { get; }

public Query Query { get; }
public CancellationToken Token { get; }

public ResultsForUpdate(IReadOnlyList<Result> results, PluginMetadata metadata, Query query, CancellationToken token)
{
Results = results;
Metadata = metadata;
Query = query;
Token = token;
ID = metadata.ID;
}
public string ID { get; } = Metadata.ID;
}
}
8 changes: 4 additions & 4 deletions Flow.Launcher/ViewModel/ResultsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,23 +147,23 @@ public void AddResults(List<Result> newRawResults, string resultId)
/// <summary>
/// To avoid deadlock, this method should not called from main thread
/// </summary>
public void AddResults(IEnumerable<ResultsForUpdate> resultsForUpdates, CancellationToken token)
public void AddResults(IEnumerable<ResultsForUpdate> resultsForUpdates, CancellationToken token, bool reselect = true)
{
var newResults = NewResults(resultsForUpdates);

if (token.IsCancellationRequested)
return;

UpdateResults(newResults, token);
UpdateResults(newResults, token, reselect);
}

private void UpdateResults(List<ResultViewModel> newResults, CancellationToken token = default)
private void UpdateResults(List<ResultViewModel> newResults, CancellationToken token = default, bool reselect = true)
{
lock (_collectionLock)
{
// update UI in one run, so it can avoid UI flickering
Results.Update(newResults, token);
if (Results.Any())
if (reselect && Results.Any())
SelectedItem = Results[0];
}

Expand Down