diff --git a/Flow.Launcher.Plugin/Feature.cs b/Flow.Launcher.Plugin/Feature.cs deleted file mode 100644 index 81839d81613..00000000000 --- a/Flow.Launcher.Plugin/Feature.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; - -namespace Flow.Launcher.Plugin -{ - public interface IFeatures { } - - public interface IContextMenu : IFeatures - { - List LoadContextMenus(Result selectedResult); - } - - /// - /// Represent plugins that support internationalization - /// - public interface IPluginI18n : IFeatures - { - string GetTranslatedPluginTitle(); - - string GetTranslatedPluginDescription(); - } - - public interface IResultUpdated : IFeatures - { - event ResultUpdatedEventHandler ResultsUpdated; - } - - public delegate void ResultUpdatedEventHandler(IResultUpdated sender, ResultUpdatedEventArgs e); - - public class ResultUpdatedEventArgs : EventArgs - { - public List Results; - public Query Query; - } -} diff --git a/Flow.Launcher.Plugin/Features.cs b/Flow.Launcher.Plugin/Features.cs new file mode 100644 index 00000000000..5b9c6a7b910 --- /dev/null +++ b/Flow.Launcher.Plugin/Features.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Threading; + +namespace Flow.Launcher.Plugin +{ + /// + /// Base Interface for Flow's special plugin feature interface + /// + public interface IFeatures + { + } +} \ No newline at end of file diff --git a/Flow.Launcher.Plugin/IAsyncPlugin.cs b/Flow.Launcher.Plugin/Interfaces/IAsyncPlugin.cs similarity index 100% rename from Flow.Launcher.Plugin/IAsyncPlugin.cs rename to Flow.Launcher.Plugin/Interfaces/IAsyncPlugin.cs diff --git a/Flow.Launcher.Plugin/Interfaces/IAsyncReloadable.cs b/Flow.Launcher.Plugin/Interfaces/IAsyncReloadable.cs index fc4ac471550..bd4500a7ef6 100644 --- a/Flow.Launcher.Plugin/Interfaces/IAsyncReloadable.cs +++ b/Flow.Launcher.Plugin/Interfaces/IAsyncReloadable.cs @@ -13,8 +13,8 @@ namespace Flow.Launcher.Plugin /// The command that allows user to manual reload is exposed via Plugin.Sys, and /// it will call the plugins that have implemented this interface. /// - public interface IAsyncReloadable + public interface IAsyncReloadable : IFeatures { Task ReloadDataAsync(); } -} +} \ No newline at end of file diff --git a/Flow.Launcher.Plugin/Interfaces/IContextMenu.cs b/Flow.Launcher.Plugin/Interfaces/IContextMenu.cs new file mode 100644 index 00000000000..5befbf5c986 --- /dev/null +++ b/Flow.Launcher.Plugin/Interfaces/IContextMenu.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Flow.Launcher.Plugin +{ + public interface IContextMenu : IFeatures + { + List LoadContextMenus(Result selectedResult); + } +} \ No newline at end of file diff --git a/Flow.Launcher.Plugin/IPlugin.cs b/Flow.Launcher.Plugin/Interfaces/IPlugin.cs similarity index 100% rename from Flow.Launcher.Plugin/IPlugin.cs rename to Flow.Launcher.Plugin/Interfaces/IPlugin.cs diff --git a/Flow.Launcher.Plugin/Interfaces/IPluginI18n.cs b/Flow.Launcher.Plugin/Interfaces/IPluginI18n.cs new file mode 100644 index 00000000000..e332d450eae --- /dev/null +++ b/Flow.Launcher.Plugin/Interfaces/IPluginI18n.cs @@ -0,0 +1,12 @@ +namespace Flow.Launcher.Plugin +{ + /// + /// Represent plugins that support internationalization + /// + public interface IPluginI18n : IFeatures + { + string GetTranslatedPluginTitle(); + + string GetTranslatedPluginDescription(); + } +} \ No newline at end of file diff --git a/Flow.Launcher.Plugin/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs similarity index 100% rename from Flow.Launcher.Plugin/IPublicAPI.cs rename to Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs diff --git a/Flow.Launcher.Plugin/Interfaces/IReloadable.cs b/Flow.Launcher.Plugin/Interfaces/IReloadable.cs index 31611519cd1..bd1ad406efd 100644 --- a/Flow.Launcher.Plugin/Interfaces/IReloadable.cs +++ b/Flow.Launcher.Plugin/Interfaces/IReloadable.cs @@ -15,8 +15,8 @@ /// If requiring reloading data asynchronously, please use the IAsyncReloadable interface /// /// - public interface IReloadable + public interface IReloadable : IFeatures { void ReloadData(); } -} +} \ No newline at end of file diff --git a/Flow.Launcher.Plugin/Interfaces/IResultUpdated.cs b/Flow.Launcher.Plugin/Interfaces/IResultUpdated.cs new file mode 100644 index 00000000000..fd21460ac55 --- /dev/null +++ b/Flow.Launcher.Plugin/Interfaces/IResultUpdated.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Flow.Launcher.Plugin +{ + public interface IResultUpdated : IFeatures + { + event ResultUpdatedEventHandler ResultsUpdated; + } + + public delegate void ResultUpdatedEventHandler(IResultUpdated sender, ResultUpdatedEventArgs e); + + public class ResultUpdatedEventArgs : EventArgs + { + public List Results; + public Query Query; + public CancellationToken Token { get; init; } + } +} \ No newline at end of file diff --git a/Flow.Launcher.Plugin/Interfaces/ISavable.cs b/Flow.Launcher.Plugin/Interfaces/ISavable.cs index 6f408dc2ee9..2d13eaa6e1c 100644 --- a/Flow.Launcher.Plugin/Interfaces/ISavable.cs +++ b/Flow.Launcher.Plugin/Interfaces/ISavable.cs @@ -5,8 +5,8 @@ /// Otherwise if LoadSettingJsonStorage or SaveSettingJsonStorage has been callded, /// plugin settings will be automatically saved (see Flow.Launcher/PublicAPIInstance.SavePluginSettings) by Flow /// - public interface ISavable + public interface ISavable : IFeatures { void Save(); } -} +} \ No newline at end of file diff --git a/Flow.Launcher.Plugin/ISettingProvider.cs b/Flow.Launcher.Plugin/Interfaces/ISettingProvider.cs similarity index 100% rename from Flow.Launcher.Plugin/ISettingProvider.cs rename to Flow.Launcher.Plugin/Interfaces/ISettingProvider.cs diff --git a/Flow.Launcher.Plugin/README.md b/Flow.Launcher.Plugin/README.md index 3b4d1598a20..5c5b7c3edc1 100644 --- a/Flow.Launcher.Plugin/README.md +++ b/Flow.Launcher.Plugin/README.md @@ -3,4 +3,4 @@ * Defines base objects and interfaces for plugins * Plugin authors making C# plugins should reference this DLL via nuget -* Contains base commands used by all plugins +* Contains commands and models that can be used by plugins diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index 1bdf6af1e10..2fd00224c0f 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -135,14 +135,17 @@ private void RegisterResultsUpdatedEvent() var plugin = (IResultUpdated)pair.Plugin; plugin.ResultsUpdated += (s, e) => { - if (e.Query.RawQuery == QueryText) // TODO: allow cancellation + if (e.Query.RawQuery != QueryText || e.Token.IsCancellationRequested) { - PluginManager.UpdatePluginMetadata(e.Results, pair.Metadata, e.Query); - if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(e.Results, pair.Metadata, e.Query, _updateToken))) - { - Log.Error("MainViewModel", "Unable to add item to Result Update Queue"); - } - ; + return; + } + + var token = e.Token == default ? _updateToken : e.Token; + + PluginManager.UpdatePluginMetadata(e.Results, pair.Metadata, e.Query); + if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(e.Results, pair.Metadata, e.Query, token))) + { + Log.Error("MainViewModel", "Unable to add item to Result Update Queue"); } }; } @@ -460,7 +463,7 @@ private void QueryHistory() } private readonly IReadOnlyList _emptyResult = new List(); - + private async void QueryResults() { _updateSource?.Cancel(); @@ -554,7 +557,7 @@ async Task QueryTask(PluginPair plugin) await Task.Yield(); IReadOnlyList results = await PluginManager.QueryForPluginAsync(plugin, query, currentCancellationToken); - + currentCancellationToken.ThrowIfCancellationRequested(); results ??= _emptyResult;