2026-02-24 11:52:23 +00:00
using System ;
2016-03-28 00:09:40 +00:00
using System.Collections.Generic ;
2022-08-08 04:31:38 +00:00
using System.ComponentModel ;
2021-01-08 08:00:06 +00:00
using System.IO ;
2021-02-14 10:08:30 +00:00
using System.Runtime.CompilerServices ;
2021-01-08 08:00:06 +00:00
using System.Threading ;
using System.Threading.Tasks ;
2024-11-27 02:07:03 +00:00
using System.Windows ;
2025-04-02 10:22:36 +00:00
using System.Windows.Media ;
2025-04-08 07:56:54 +00:00
using Flow.Launcher.Plugin.SharedModels ;
using JetBrains.Annotations ;
2014-07-05 15:10:34 +00:00
2020-04-21 09:12:17 +00:00
namespace Flow.Launcher.Plugin
2014-07-05 15:10:34 +00:00
{
2015-01-19 11:14:02 +00:00
/// <summary>
/// Public APIs that plugin can use
/// </summary>
2014-07-05 15:10:34 +00:00
public interface IPublicAPI
{
2015-01-19 11:14:02 +00:00
/// <summary>
2025-02-22 11:32:08 +00:00
/// Change Flow.Launcher query.
2025-02-22 12:16:36 +00:00
/// When current results are from context menu or history, it will go back to query results before changing query.
2015-01-19 11:14:02 +00:00
/// </summary>
/// <param name="query">query text</param>
/// <param name="requery">
2025-07-07 11:57:03 +00:00
/// Force requery. By default, Flow Launcher will not fire query if your query is same with existing one.
/// Set this to <see langword="true"/> to force Flow Launcher re-querying
2015-01-19 11:14:02 +00:00
/// </param>
2014-07-05 15:10:34 +00:00
void ChangeQuery ( string query , bool requery = false ) ;
2015-11-26 02:04:44 +00:00
/// <summary>
2020-04-22 10:26:09 +00:00
/// Restart Flow Launcher
2021-05-16 07:14:55 +00:00
/// </summary>
2020-04-30 06:54:13 +00:00
void RestartApp ( ) ;
2021-10-09 09:36:38 +00:00
/// <summary>
2021-11-17 18:59:37 +00:00
/// Run a shell command
2021-10-09 09:36:38 +00:00
/// </summary>
/// <param name="cmd">The command or program to run</param>
2021-11-17 18:59:37 +00:00
/// <param name="filename">the shell type to run, e.g. powershell.exe</param>
2021-11-17 10:00:36 +00:00
/// <exception cref="FileNotFoundException">Thrown when unable to find the file specified in the command </exception>
/// <exception cref="Win32Exception">Thrown when error occurs during the execution of the command </exception>
2021-11-17 18:56:51 +00:00
void ShellRun ( string cmd , string filename = "cmd.exe" ) ;
2023-06-09 09:59:49 +00:00
2021-11-30 09:15:55 +00:00
/// <summary>
2023-06-09 09:59:49 +00:00
/// Copies the passed in text and shows a message indicating whether the operation was completed successfully.
/// When directCopy is set to true and passed in text is the path to a file or directory,
/// the actual file/directory will be copied to clipboard. Otherwise the text itself will still be copied to clipboard.
2021-11-30 09:15:55 +00:00
/// </summary>
2022-08-08 04:31:38 +00:00
/// <param name="text">Text to save on clipboard</param>
2023-06-09 09:59:49 +00:00
/// <param name="directCopy">When true it will directly copy the file/folder from the path specified in text</param>
2025-07-07 11:57:03 +00:00
/// <param name="showDefaultNotification">Whether to show the default notification from this method after copy is done.
2023-06-11 11:59:08 +00:00
/// It will show file/folder/text is copied successfully.
/// Turn this off to show your own notification after copy is done.</param>>
public void CopyToClipboard ( string text , bool directCopy = false , bool showDefaultNotification = true ) ;
2021-10-09 09:36:38 +00:00
2019-08-22 11:37:36 +00:00
/// <summary>
2021-05-16 07:14:55 +00:00
/// Save everything, all of Flow Launcher and plugins' data and settings
2019-08-22 11:37:36 +00:00
/// </summary>
void SaveAppAllSettings ( ) ;
2021-05-13 12:49:41 +00:00
/// <summary>
2021-05-16 07:14:55 +00:00
/// Save all Flow's plugins settings
2021-05-13 12:49:41 +00:00
/// </summary>
void SavePluginSettings ( ) ;
2019-10-06 02:44:38 +00:00
/// <summary>
2025-07-07 11:57:03 +00:00
/// Reloads any Plugins that have the
2019-10-06 02:44:38 +00:00
/// IReloadable implemented. It refeshes
/// Plugin's in memory data with new content
/// added by user.
/// </summary>
2021-01-02 07:52:41 +00:00
Task ReloadAllPluginData ( ) ;
2019-10-06 02:44:38 +00:00
2020-02-25 10:08:51 +00:00
/// <summary>
2020-04-22 10:26:09 +00:00
/// Check for new Flow Launcher update
2020-02-25 10:08:51 +00:00
/// </summary>
void CheckForNewUpdate ( ) ;
2021-04-15 22:53:19 +00:00
/// <summary>
/// Show the error message using Flow's standard error icon.
/// </summary>
/// <param name="title">Message title</param>
/// <param name="subTitle">Optional message subtitle</param>
void ShowMsgError ( string title , string subTitle = "" ) ;
2025-06-09 06:39:44 +00:00
/// <summary>
/// Show the error message using Flow's standard error icon.
/// </summary>
/// <param name="title">Message title</param>
/// <param name="buttonText">Message button content</param>
/// <param name="buttonAction">Message button action</param>
/// <param name="subTitle">Optional message subtitle</param>
void ShowMsgErrorWithButton ( string title , string buttonText , Action buttonAction , string subTitle = "" ) ;
2021-10-17 02:28:55 +00:00
/// <summary>
/// Show the MainWindow when hiding
/// </summary>
void ShowMainWindow ( ) ;
2025-07-07 11:57:03 +00:00
2025-05-21 19:14:30 +00:00
/// <summary>
/// Focus the query text box in the main window
/// </summary>
void FocusQueryTextBox ( ) ;
2021-10-17 02:28:55 +00:00
2023-05-11 14:57:10 +00:00
/// <summary>
/// Hide MainWindow
/// </summary>
void HideMainWindow ( ) ;
/// <summary>
/// Representing whether the main window is visible
/// </summary>
/// <returns></returns>
bool IsMainWindowVisible ( ) ;
2023-07-03 21:42:41 +00:00
/// <summary>
2025-07-07 11:57:03 +00:00
/// Invoked when the visibility of the main window has changed. Currently, the plugin will continue to be subscribed even if it is turned off.
2023-07-03 21:42:41 +00:00
/// </summary>
event VisibilityChangedEventHandler VisibilityChanged ;
2015-01-19 11:14:02 +00:00
/// <summary>
/// Show message box
/// </summary>
/// <param name="title">Message title</param>
/// <param name="subTitle">Message subtitle</param>
/// <param name="iconPath">Message icon path (relative path to your plugin folder)</param>
2020-03-31 11:00:09 +00:00
void ShowMsg ( string title , string subTitle = "" , string iconPath = "" ) ;
/// <summary>
/// Show message box
/// </summary>
/// <param name="title">Message title</param>
/// <param name="subTitle">Message subtitle</param>
/// <param name="iconPath">Message icon path (relative path to your plugin folder)</param>
/// <param name="useMainWindowAsOwner">when true will use main windows as the owner</param>
void ShowMsg ( string title , string subTitle , string iconPath , bool useMainWindowAsOwner = true ) ;
2014-07-05 15:10:34 +00:00
2025-06-09 06:39:44 +00:00
/// <summary>
/// Show message box with button
/// </summary>
/// <param name="title">Message title</param>
/// <param name="buttonText">Message button content</param>
/// <param name="buttonAction">Message button action</param>
/// <param name="subTitle">Message subtitle</param>
/// <param name="iconPath">Message icon path (relative path to your plugin folder)</param>
void ShowMsgWithButton ( string title , string buttonText , Action buttonAction , string subTitle = "" , string iconPath = "" ) ;
/// <summary>
/// Show message box with button
/// </summary>
/// <param name="title">Message title</param>
/// <param name="buttonText">Message button content</param>
/// <param name="buttonAction">Message button action</param>
/// <param name="subTitle">Message subtitle</param>
/// <param name="iconPath">Message icon path (relative path to your plugin folder)</param>
/// <param name="useMainWindowAsOwner">when true will use main windows as the owner</param>
void ShowMsgWithButton ( string title , string buttonText , Action buttonAction , string subTitle , string iconPath , bool useMainWindowAsOwner = true ) ;
2015-01-19 11:14:02 +00:00
/// <summary>
/// Open setting dialog
/// </summary>
2016-05-22 18:16:39 +00:00
void OpenSettingDialog ( ) ;
2015-02-04 15:16:41 +00:00
2015-01-19 11:14:02 +00:00
/// <summary>
/// Get translation of current language
/// You need to implement IPluginI18n if you want to support multiple languages for your plugin
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
2015-01-06 15:24:11 +00:00
string GetTranslation ( string key ) ;
2015-01-19 11:14:02 +00:00
/// <summary>
2025-07-07 11:57:03 +00:00
/// Get all loaded plugins
2015-01-19 11:14:02 +00:00
/// </summary>
2026-02-24 11:52:23 +00:00
/// <remarks>
/// Will also return any plugins not fully initialized yet
/// </remarks>
2015-01-19 11:14:02 +00:00
/// <returns></returns>
2014-07-05 15:10:34 +00:00
List < PluginPair > GetAllPlugins ( ) ;
2014-07-19 02:12:11 +00:00
2026-02-24 11:52:23 +00:00
/// <summary>
/// Get all initialized plugins
/// </summary>
/// <param name="includeFailed">
/// Whether to include plugins that failed to initialize
/// </param>
/// <returns></returns>
List < PluginPair > GetAllInitializedPlugins ( bool includeFailed ) ;
2021-11-27 20:26:20 +00:00
/// <summary>
2025-04-09 04:37:42 +00:00
/// Registers a callback function for global keyboard events.
/// </summary>
/// <param name="callback">
/// The callback function to invoke when a global keyboard event occurs.
/// <para>
/// Parameters:
/// <list type="number">
/// <item><description>int: The type of <see cref="KeyEvent"/> (key down, key up, etc.)</description></item>
/// <item><description>int: The virtual key code of the pressed/released key</description></item>
/// <item><description><see cref="SpecialKeyState"/>: The state of modifier keys (Ctrl, Alt, Shift, etc.)</description></item>
/// </list>
/// </para>
/// <para>
/// Returns: <c>true</c> to allow normal system processing of the key event,
/// or <c>false</c> to intercept and prevent default handling.
/// </para>
/// </param>
/// <remarks>
/// This callback will be invoked for all keyboard events system-wide.
/// Use with caution as intercepting system keys may affect normal system operation.
/// </remarks>
2021-11-27 20:26:20 +00:00
public void RegisterGlobalKeyboardCallback ( Func < int , int , SpecialKeyState , bool > callback ) ;
2025-04-09 04:37:42 +00:00
2021-11-27 20:26:20 +00:00
/// <summary>
/// Remove a callback for Global Keyboard Event
/// </summary>
2025-04-09 04:37:42 +00:00
/// <param name="callback">
/// The callback function to invoke when a global keyboard event occurs.
/// <para>
/// Parameters:
/// <list type="number">
/// <item><description>int: The type of <see cref="KeyEvent"/> (key down, key up, etc.)</description></item>
/// <item><description>int: The virtual key code of the pressed/released key</description></item>
/// <item><description><see cref="SpecialKeyState"/>: The state of modifier keys (Ctrl, Alt, Shift, etc.)</description></item>
/// </list>
/// </para>
/// <para>
/// Returns: <c>true</c> to allow normal system processing of the key event,
/// or <c>false</c> to intercept and prevent default handling.
/// </para>
/// </param>
2021-11-27 20:26:20 +00:00
public void RemoveGlobalKeyboardCallback ( Func < int , int , SpecialKeyState , bool > callback ) ;
2021-02-14 10:25:09 +00:00
/// <summary>
2021-02-14 19:42:18 +00:00
/// Fuzzy Search the string with the given query. This is the core search mechanism Flow uses
2021-02-14 10:25:09 +00:00
/// </summary>
2021-02-14 19:42:18 +00:00
/// <param name="query">Query string</param>
/// <param name="stringToCompare">The string that will be compared against the query</param>
2021-02-14 10:25:09 +00:00
/// <returns>Match results</returns>
2021-01-08 08:00:06 +00:00
MatchResult FuzzySearch ( string query , string stringToCompare ) ;
2021-02-14 10:25:09 +00:00
/// <summary>
2025-07-07 11:57:03 +00:00
/// Http download the specific url and return as string
2021-02-14 10:25:09 +00:00
/// </summary>
/// <param name="url">URL to call Http Get</param>
/// <param name="token">Cancellation Token</param>
/// <returns>Task to get string result</returns>
2021-01-08 08:00:06 +00:00
Task < string > HttpGetStringAsync ( string url , CancellationToken token = default ) ;
2021-02-14 10:25:09 +00:00
/// <summary>
2025-07-07 11:57:03 +00:00
/// Http download the specific url and return as stream
2021-02-14 10:25:09 +00:00
/// </summary>
/// <param name="url">URL to call Http Get</param>
/// <param name="token">Cancellation Token</param>
/// <returns>Task to get stream result</returns>
2021-01-08 08:00:06 +00:00
Task < Stream > HttpGetStreamAsync ( string url , CancellationToken token = default ) ;
2021-01-08 08:05:50 +00:00
2021-02-14 10:25:09 +00:00
/// <summary>
/// Download the specific url to a cretain file path
/// </summary>
/// <param name="url">URL to download file</param>
2022-08-08 04:31:38 +00:00
/// <param name="filePath">path to save downloaded file</param>
2025-01-11 05:24:41 +00:00
/// <param name="reportProgress">
/// Action to report progress. The input of the action is the progress value which is a double value between 0 and 100.
/// It will be called if url support range request and the reportProgress is not null.
/// </param>
2021-02-14 10:25:09 +00:00
/// <param name="token">place to store file</param>
/// <returns>Task showing the progress</returns>
2025-01-11 05:24:41 +00:00
Task HttpDownloadAsync ( [ NotNull ] string url , [ NotNull ] string filePath , Action < double > reportProgress = null , CancellationToken token = default ) ;
2021-01-08 08:08:39 +00:00
2021-02-14 10:25:09 +00:00
/// <summary>
2025-04-17 14:48:38 +00:00
/// Add ActionKeyword and update action keyword metadata for specific plugin.
2025-02-25 07:46:45 +00:00
/// Before adding, please check if action keyword is already assigned by <see cref="ActionKeywordAssigned"/>
2021-02-14 10:25:09 +00:00
/// </summary>
/// <param name="pluginId">ID for plugin that needs to add action keyword</param>
/// <param name="newActionKeyword">The actionkeyword that is supposed to be added</param>
2025-04-17 14:47:58 +00:00
/// <remarks>
/// If new action keyword contains any whitespace, FL will still add it but it will not work for users.
/// So plugin should check the whitespace before calling this function.
/// </remarks>
2021-01-08 08:08:39 +00:00
void AddActionKeyword ( string pluginId , string newActionKeyword ) ;
2021-02-14 10:25:09 +00:00
/// <summary>
2025-02-24 01:53:00 +00:00
/// Remove ActionKeyword and update action keyword metadata for specific plugin
2021-02-14 10:25:09 +00:00
/// </summary>
/// <param name="pluginId">ID for plugin that needs to remove action keyword</param>
2022-08-08 04:31:38 +00:00
/// <param name="oldActionKeyword">The actionkeyword that is supposed to be removed</param>
2021-01-08 08:08:39 +00:00
void RemoveActionKeyword ( string pluginId , string oldActionKeyword ) ;
2022-07-01 04:56:15 +00:00
/// <summary>
/// Check whether specific ActionKeyword is assigned to any of the plugin
/// </summary>
/// <param name="actionKeyword">The actionkeyword for checking</param>
/// <returns>True if the actionkeyword is already assigned, False otherwise</returns>
bool ActionKeywordAssigned ( string actionKeyword ) ;
2021-02-14 10:25:09 +00:00
/// <summary>
2021-02-14 19:42:18 +00:00
/// Log debug message
2021-02-14 10:25:09 +00:00
/// Message will only be logged in Debug mode
/// </summary>
2021-02-14 10:08:30 +00:00
void LogDebug ( string className , string message , [ CallerMemberName ] string methodName = "" ) ;
2021-02-14 10:25:09 +00:00
/// <summary>
2021-02-14 19:42:18 +00:00
/// Log info message
2021-02-14 10:25:09 +00:00
/// </summary>
2021-02-14 10:08:30 +00:00
void LogInfo ( string className , string message , [ CallerMemberName ] string methodName = "" ) ;
2021-02-14 10:25:09 +00:00
/// <summary>
2021-02-14 19:42:18 +00:00
/// Log warning message
2021-02-14 10:25:09 +00:00
/// </summary>
2021-02-14 10:08:30 +00:00
void LogWarn ( string className , string message , [ CallerMemberName ] string methodName = "" ) ;
2025-04-01 03:47:18 +00:00
/// <summary>
2025-04-08 08:12:10 +00:00
/// Log error message. Preferred error logging method for plugins.
2025-04-01 03:47:18 +00:00
/// </summary>
void LogError ( string className , string message , [ CallerMemberName ] string methodName = "" ) ;
2021-02-14 10:08:30 +00:00
2021-02-14 10:25:09 +00:00
/// <summary>
2025-07-07 11:57:03 +00:00
/// Log an Exception. Will throw if in debug mode so developer will be aware,
/// otherwise logs the eror message. This is the primary logging method used for Flow
2021-02-14 10:25:09 +00:00
/// </summary>
2021-02-14 10:08:30 +00:00
void LogException ( string className , string message , Exception e , [ CallerMemberName ] string methodName = "" ) ;
2021-02-14 10:25:09 +00:00
/// <summary>
2021-05-13 11:29:21 +00:00
/// Load JsonStorage for current plugin's setting. This is the method used to load settings from json in Flow.
2021-05-13 05:37:41 +00:00
/// When the file is not exist, it will create a new instance for the specific type.
2021-02-14 10:25:09 +00:00
/// </summary>
/// <typeparam name="T">Type for deserialization</typeparam>
/// <returns></returns>
2021-05-13 11:29:21 +00:00
T LoadSettingJsonStorage < T > ( ) where T : new ( ) ;
2021-02-14 10:08:30 +00:00
2021-02-14 10:25:09 +00:00
/// <summary>
2025-04-17 14:48:38 +00:00
/// Save JsonStorage for current plugin's setting. This is the method used to save settings to json in Flow.
2021-03-27 09:26:53 +00:00
/// This method will save the original instance loaded with LoadJsonStorage.
2025-04-17 14:48:38 +00:00
/// This API call is for manually Save.
/// Flow will automatically save all setting type that has called <see cref="LoadSettingJsonStorage"/> or <see cref="SaveSettingJsonStorage"/> previously.
2021-02-14 10:25:09 +00:00
/// </summary>
/// <typeparam name="T">Type for Serialization</typeparam>
/// <returns></returns>
2021-05-13 11:29:21 +00:00
void SaveSettingJsonStorage < T > ( ) where T : new ( ) ;
2021-11-06 00:23:09 +00:00
/// <summary>
2021-11-10 21:40:15 +00:00
/// Open directory in an explorer configured by user via Flow's Settings. The default is Windows Explorer
2021-11-06 00:23:09 +00:00
/// </summary>
/// <param name="DirectoryPath">Directory Path to open</param>
2023-03-08 10:47:49 +00:00
/// <param name="FileNameOrFilePath">Extra FileName Info</param>
public void OpenDirectory ( string DirectoryPath , string FileNameOrFilePath = null ) ;
2021-12-05 07:19:16 +00:00
2021-12-09 03:39:31 +00:00
/// <summary>
2025-06-03 15:06:24 +00:00
/// Opens the URL using the browser with the given Uri object, even if the URL is a local file.
/// The browser and mode used is based on what's configured in Flow's default browser settings.
/// </summary>
2025-06-03 15:08:51 +00:00
public void OpenWebUrl ( Uri url , bool? inPrivate = null ) ;
2025-06-03 15:06:24 +00:00
/// <summary>
/// Opens the URL using the browser with the given string, even if the URL is a local file.
/// The browser and mode used is based on what's configured in Flow's default browser settings.
/// Non-C# plugins should use this method.
/// </summary>
2025-06-03 15:08:51 +00:00
public void OpenWebUrl ( string url , bool? inPrivate = null ) ;
2025-06-03 15:06:24 +00:00
2021-12-09 03:39:31 +00:00
/// <summary>
2025-06-13 12:02:34 +00:00
/// Opens the URL with the given Uri object in browser if scheme is Http or Https.
/// If the URL is a local file, it will instead be opened with the default application for that file type.
2022-02-03 21:26:42 +00:00
/// The browser and mode used is based on what's configured in Flow's default browser settings.
/// </summary>
public void OpenUrl ( Uri url , bool? inPrivate = null ) ;
/// <summary>
2025-06-13 12:02:34 +00:00
/// Opens the URL with the given string in browser if scheme is Http or Https.
/// If the URL is a local file, it will instead be opened with the default application for that file type.
2022-02-03 21:26:42 +00:00
/// The browser and mode used is based on what's configured in Flow's default browser settings.
/// Non-C# plugins should use this method.
2021-12-09 03:39:31 +00:00
/// </summary>
public void OpenUrl ( string url , bool? inPrivate = null ) ;
2022-01-30 21:34:02 +00:00
/// <summary>
2022-02-03 21:26:42 +00:00
/// Opens the application URI with the given Uri object, e.g. obsidian://search-query-example
/// </summary>
public void OpenAppUri ( Uri appUri ) ;
/// <summary>
/// Opens the application URI with the given string, e.g. obsidian://search-query-example
/// Non-C# plugins should use this method
2022-01-30 21:34:02 +00:00
/// </summary>
public void OpenAppUri ( string appUri ) ;
2024-01-14 13:31:21 +00:00
/// <summary>
/// Toggles Game Mode. off -> on and backwards
/// </summary>
public void ToggleGameMode ( ) ;
/// <summary>
/// Switches Game Mode to given value
/// </summary>
/// <param name="value">New Game Mode status</param>
public void SetGameMode ( bool value ) ;
/// <summary>
/// Representing Game Mode status
/// </summary>
/// <returns></returns>
public bool IsGameModeOn ( ) ;
2024-02-23 21:28:16 +00:00
/// <summary>
2024-02-25 02:29:14 +00:00
/// Reloads the query.
2025-07-07 11:57:03 +00:00
/// When current results are from context menu or history, it will go back to query results before re-querying.
2024-02-23 21:28:16 +00:00
/// </summary>
2024-02-25 02:29:14 +00:00
/// <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 ) ;
2024-11-21 11:18:05 +00:00
/// <summary>
/// Back to the query results.
/// This method should run when selected item is from context menu or history.
/// </summary>
public void BackToQueryResults ( ) ;
2024-12-08 05:24:31 +00:00
2024-11-27 02:07:03 +00:00
/// <summary>
2024-12-07 11:21:08 +00:00
/// Displays a standardised Flow message box.
2024-11-27 02:07:03 +00:00
/// </summary>
2024-12-01 11:55:07 +00:00
/// <param name="messageBoxText">The message of the message box.</param>
/// <param name="caption">The caption of the message box.</param>
/// <param name="button">Specifies which button or buttons to display.</param>
/// <param name="icon">Specifies the icon to display.</param>
/// <param name="defaultResult">Specifies the default result of the message box.</param>
/// <returns>Specifies which message box button is clicked by the user.</returns>
public MessageBoxResult ShowMsgBox ( string messageBoxText , string caption = "" , MessageBoxButton button = MessageBoxButton . OK , MessageBoxImage icon = MessageBoxImage . None , MessageBoxResult defaultResult = MessageBoxResult . OK ) ;
2025-01-04 16:08:56 +00:00
/// <summary>
2025-02-26 12:11:27 +00:00
/// Displays a standardised Flow progress box.
2025-01-04 16:08:56 +00:00
/// </summary>
2025-02-26 12:11:27 +00:00
/// <param name="caption">The caption of the progress box.</param>
2025-01-10 11:13:19 +00:00
/// <param name="reportProgressAsync">
/// Time-consuming task function, whose input is the action to report progress.
/// The input of the action is the progress value which is a double value between 0 and 100.
/// If there are any exceptions, this action will be null.
/// </param>
2025-02-26 12:11:27 +00:00
/// <param name="cancelProgress">When user cancel the progress, this action will be called.</param>
/// <returns></returns>
public Task ShowProgressBoxAsync ( string caption , Func < Action < double > , Task > reportProgressAsync , Action cancelProgress = null ) ;
2025-02-28 03:26:14 +00:00
/// <summary>
/// Start the loading bar in main window
/// </summary>
public void StartLoadingBar ( ) ;
/// <summary>
/// Stop the loading bar in main window
/// </summary>
public void StopLoadingBar ( ) ;
2025-04-04 12:10:39 +00:00
/// <summary>
/// Get all available themes
/// </summary>
/// <returns></returns>
public List < ThemeData > GetAvailableThemes ( ) ;
/// <summary>
/// Get the current theme
/// </summary>
/// <returns></returns>
public ThemeData GetCurrentTheme ( ) ;
/// <summary>
/// Set the current theme
/// </summary>
/// <param name="theme"></param>
2025-04-08 08:41:06 +00:00
/// <returns>
/// True if the theme is set successfully, false otherwise.
/// </returns>
public bool SetCurrentTheme ( ThemeData theme ) ;
2025-04-05 12:44:08 +00:00
2025-04-09 04:31:53 +00:00
/// <summary>
2025-04-01 06:19:59 +00:00
/// Save all Flow's plugins caches
/// </summary>
void SavePluginCaches ( ) ;
/// <summary>
/// Load BinaryStorage for current plugin's cache. This is the method used to load cache from binary in Flow.
/// When the file is not exist, it will create a new instance for the specific type.
/// </summary>
/// <typeparam name="T">Type for deserialization</typeparam>
/// <param name="cacheName">Cache file name</param>
/// <param name="cacheDirectory">Cache directory from plugin metadata</param>
/// <param name="defaultData">Default data to return</param>
/// <returns></returns>
/// <remarks>
2025-04-08 11:28:29 +00:00
/// BinaryStorage utilizes MemoryPack, which means the object must be MemoryPackSerializable <see href="https://github.com/Cysharp/MemoryPack"/>
2025-04-01 06:19:59 +00:00
/// </remarks>
Task < T > LoadCacheBinaryStorageAsync < T > ( string cacheName , string cacheDirectory , T defaultData ) where T : new ( ) ;
/// <summary>
2025-04-17 14:48:38 +00:00
/// Save BinaryStorage for current plugin's cache. This is the method used to save cache to binary in Flow.
2025-04-01 06:19:59 +00:00
/// This method will save the original instance loaded with LoadCacheBinaryStorageAsync.
2025-04-17 14:48:38 +00:00
/// This API call is for manually Save.
/// Flow will automatically save all cache type that has called <see cref="LoadCacheBinaryStorageAsync"/> or <see cref="SaveCacheBinaryStorageAsync"/> previously.
2025-04-01 06:19:59 +00:00
/// </summary>
/// <typeparam name="T">Type for Serialization</typeparam>
/// <param name="cacheName">Cache file name</param>
/// <param name="cacheDirectory">Cache directory from plugin metadata</param>
/// <returns></returns>
/// <remarks>
2025-04-08 11:42:59 +00:00
/// BinaryStorage utilizes MemoryPack, which means the object must be MemoryPackSerializable <see href="https://github.com/Cysharp/MemoryPack"/>
2025-04-01 06:19:59 +00:00
/// </remarks>
Task SaveCacheBinaryStorageAsync < T > ( string cacheName , string cacheDirectory ) where T : new ( ) ;
2025-04-05 12:42:48 +00:00
2025-04-09 04:31:53 +00:00
/// <summary>
2025-04-09 08:15:37 +00:00
/// Load image from path.
/// Support local, remote and data:image url.
/// Support png, jpg, jpeg, gif, bmp, tiff, ico, svg image files.
2025-04-02 10:34:04 +00:00
/// If image path is missing, it will return a missing icon.
2025-04-02 10:22:36 +00:00
/// </summary>
/// <param name="path">The path of the image.</param>
/// <param name="loadFullImage">
/// Load full image or not.
/// </param>
/// <param name="cacheImage">
/// Cache the image or not. Cached image will be stored in FL cache.
/// If the image is just used one time, it's better to set this to false.
/// </param>
/// <returns></returns>
ValueTask < ImageSource > LoadImageAsync ( string path , bool loadFullImage = false , bool cacheImage = true ) ;
2025-04-05 12:43:36 +00:00
2025-04-09 04:31:53 +00:00
/// <summary>
2025-04-04 08:05:33 +00:00
/// Update the plugin manifest
/// </summary>
/// <param name="usePrimaryUrlOnly">
/// FL has multiple urls to download the plugin manifest. Set this to true to only use the primary url.
/// </param>
/// <param name="token"></param>
2025-04-04 08:33:03 +00:00
/// <returns>True if the manifest is updated successfully, false otherwise</returns>
2025-04-04 08:05:33 +00:00
public Task < bool > UpdatePluginManifestAsync ( bool usePrimaryUrlOnly = false , CancellationToken token = default ) ;
/// <summary>
2025-05-02 04:26:14 +00:00
/// Get the plugin manifest.
2025-04-04 08:05:33 +00:00
/// </summary>
2025-05-02 04:26:14 +00:00
/// <remarks>
/// If Flow cannot get manifest data, this could be null
/// </remarks>
2025-04-04 08:05:33 +00:00
/// <returns></returns>
2025-04-04 08:33:03 +00:00
public IReadOnlyList < UserPlugin > GetPluginManifest ( ) ;
/// <summary>
/// Check if the plugin has been modified.
/// If this plugin is updated, installed or uninstalled and users do not restart the app,
/// it will be marked as modified
/// </summary>
/// <param name="id">Plugin id</param>
/// <returns></returns>
public bool PluginModified ( string id ) ;
/// <summary>
/// Update a plugin to new version, from a zip file. By default will remove the zip file if update is via url,
/// unless it's a local path installation
/// </summary>
/// <param name="pluginMetadata">The metadata of the old plugin to update</param>
/// <param name="plugin">The new plugin to update</param>
/// <param name="zipFilePath">
/// Path to the zip file containing the plugin. It will be unzipped to the temporary directory, removed and installed.
/// </param>
2025-07-01 01:05:21 +00:00
/// <returns>
/// True if the plugin is updated successfully, false otherwise.
/// </returns>
public Task < bool > UpdatePluginAsync ( PluginMetadata pluginMetadata , UserPlugin plugin , string zipFilePath ) ;
2025-04-04 08:33:03 +00:00
/// <summary>
/// Install a plugin. By default will remove the zip file if installation is from url,
/// unless it's a local path installation
/// </summary>
/// <param name="plugin">The plugin to install</param>
/// <param name="zipFilePath">
/// Path to the zip file containing the plugin. It will be unzipped to the temporary directory, removed and installed.
/// </param>
2025-07-01 01:05:21 +00:00
/// <returns>
/// True if the plugin is installed successfully, false otherwise.
/// </returns>
public bool InstallPlugin ( UserPlugin plugin , string zipFilePath ) ;
2025-04-04 08:33:03 +00:00
/// <summary>
/// Uninstall a plugin
/// </summary>
/// <param name="pluginMetadata">The metadata of the plugin to uninstall</param>
/// <param name="removePluginSettings">
/// Plugin has their own settings. If this is set to true, the plugin settings will be removed.
/// </param>
2025-07-01 01:05:21 +00:00
/// <returns>
/// True if the plugin is updated successfully, false otherwise.
/// </returns>
public Task < bool > UninstallPluginAsync ( PluginMetadata pluginMetadata , bool removePluginSettings = false ) ;
2025-04-08 13:32:18 +00:00
/// <summary>
/// Log debug message of the time taken to execute a method
/// Message will only be logged in Debug mode
/// </summary>
/// <returns>The time taken to execute the method in milliseconds</returns>
2025-04-08 13:38:17 +00:00
public long StopwatchLogDebug ( string className , string message , Action action , [ CallerMemberName ] string methodName = "" ) ;
2025-04-08 13:32:18 +00:00
/// <summary>
/// Log debug message of the time taken to execute a method asynchronously
/// Message will only be logged in Debug mode
/// </summary>
/// <returns>The time taken to execute the method in milliseconds</returns>
2025-04-08 13:38:17 +00:00
public Task < long > StopwatchLogDebugAsync ( string className , string message , Func < Task > action , [ CallerMemberName ] string methodName = "" ) ;
2025-04-08 13:32:18 +00:00
/// <summary>
/// Log info message of the time taken to execute a method
/// </summary>
/// <returns>The time taken to execute the method in milliseconds</returns>
2025-04-08 13:38:17 +00:00
public long StopwatchLogInfo ( string className , string message , Action action , [ CallerMemberName ] string methodName = "" ) ;
2025-04-08 13:32:18 +00:00
/// <summary>
/// Log info message of the time taken to execute a method asynchronously
/// </summary>
/// <returns>The time taken to execute the method in milliseconds</returns>
2025-04-08 13:38:17 +00:00
public Task < long > StopwatchLogInfoAsync ( string className , string message , Func < Task > action , [ CallerMemberName ] string methodName = "" ) ;
2025-07-05 05:35:28 +00:00
/// <summary>
/// Representing whether the application is using a dark theme
/// </summary>
/// <returns></returns>
bool IsApplicationDarkTheme ( ) ;
/// <summary>
2025-07-07 11:57:03 +00:00
/// Invoked when the actual theme of the application has changed. Currently, the plugin will continue to be subscribed even if it is turned off.
2025-07-05 05:35:28 +00:00
/// </summary>
event ActualApplicationThemeChangedEventHandler ActualApplicationThemeChanged ;
2025-07-20 01:58:30 +00:00
/// <summary>
2025-07-21 11:33:57 +00:00
/// Get the user data directory of Flow Launcher.
2025-07-20 01:58:30 +00:00
/// </summary>
/// <returns></returns>
string GetDataDirectory ( ) ;
/// <summary>
/// Get the log directory of Flow Launcher.
/// </summary>
/// <returns></returns>
string GetLogDirectory ( ) ;
2014-07-05 15:10:34 +00:00
}
}