From 31131ea4a0379dfd8177c3605f1fab9460542928 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Thu, 28 Sep 2023 23:45:11 +0800 Subject: [PATCH 01/40] Remove download success notification --- .../Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index 683904ea0..6b6945d37 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -136,9 +136,6 @@ namespace Flow.Launcher.Plugin.PluginsManager { await Http.DownloadAsync(plugin.UrlDownload, filePath).ConfigureAwait(false); - Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin"), - string.Format(Context.API.GetTranslation("plugin_pluginsmanager_download_success"), plugin.Name)); - Install(plugin, filePath); } catch (Exception e) @@ -223,10 +220,6 @@ namespace Flow.Launcher.Plugin.PluginsManager await Http.DownloadAsync(x.PluginNewUserPlugin.UrlDownload, downloadToFilePath) .ConfigureAwait(false); - Context.API.ShowMsg( - Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin"), - string.Format(Context.API.GetTranslation("plugin_pluginsmanager_download_success"), x.Name)); - Install(x.PluginNewUserPlugin, downloadToFilePath); Context.API.RestartApp(); From 1334798c6d420dc1a0676835b5b41779924dc5f6 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Fri, 29 Sep 2023 13:06:42 +0800 Subject: [PATCH 02/40] Add AutoRestartAfterChanging option - Option and UI - New prompts and notification messages --- .../Languages/en.xaml | 11 ++- .../PluginsManager.cs | 96 +++++++++++++++---- .../Settings.cs | 2 + .../ViewModels/SettingsViewModel.cs | 6 ++ .../Views/PluginsManagerSettings.xaml | 12 +++ 5 files changed, 107 insertions(+), 20 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml index 1f74a49a2..d08087ac2 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml @@ -8,7 +8,9 @@ Successfully downloaded {0} Error: Unable to download the plugin {0} by {1} {2}{3}Would you like to uninstall this plugin? After the uninstallation Flow will automatically restart. + {0} by {1} {2}{2}Would you like to uninstall this plugin? {0} by {1} {2}{3}Would you like to install this plugin? After the installation Flow will automatically restart. + {0} by {1} {2}{2}Would you like to install this plugin? Plugin Install Installing Plugin Download and install {0} @@ -21,15 +23,19 @@ No update available All plugins are up to date {0} by {1} {2}{3}Would you like to update this plugin? After the update Flow will automatically restart. + {0} by {1} {2}{2}Would you like to update this plugin? Plugin Update This plugin has an update, would you like to see it? This plugin is already installed Plugin Manifest Download Failed Please check if you can connect to github.com. This error means you may not be able to install or update plugins. + Plugin {0} successfully updated. Restarting Flow, please wait... Installing from an unknown source You are installing this plugin from an unknown source and it may contain potential risks!{0}{0}Please ensure you understand where this plugin is from and that it is safe.{0}{0}Would you like to continue still?{0}{0}(You can switch off this warning via settings) - - + + Plugin {0} successfully installed. Please manually restart Flow. + Plugin {0} successfully uninstalled. Please manually restart Flow. + Plugin {0} successfully updated. Please manually restart Flow. Plugins Manager @@ -48,4 +54,5 @@ Install from unknown source warning + Automatically restart Flow Launcher after installing/uninstalling/updating plugins \ No newline at end of file diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index 6b6945d37..77fa3b981 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -117,9 +117,19 @@ namespace Flow.Launcher.Plugin.PluginsManager return; } - var message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_prompt"), - plugin.Name, plugin.Author, - Environment.NewLine, Environment.NewLine); + string message; + if (Settings.AutoRestartAfterChanging) + { + message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_prompt"), + plugin.Name, plugin.Author, + Environment.NewLine, Environment.NewLine); + } + else + { + message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_prompt_no_restart"), + plugin.Name, plugin.Author, + Environment.NewLine); + } if (MessageBox.Show(message, Context.API.GetTranslation("plugin_pluginsmanager_install_title"), MessageBoxButton.YesNo) == MessageBoxResult.No) @@ -140,6 +150,7 @@ namespace Flow.Launcher.Plugin.PluginsManager } catch (Exception e) { + // TODO use toast to optimize error prompt if (e is HttpRequestException) MessageBox.Show(Context.API.GetTranslation("plugin_pluginsmanager_download_error"), Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin")); @@ -153,10 +164,19 @@ namespace Flow.Launcher.Plugin.PluginsManager return; } - Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_installing_plugin"), - string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_success_restart"), plugin.Name)); - - Context.API.RestartApp(); + if (Settings.AutoRestartAfterChanging) + { + Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_installing_plugin"), + string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_success_restart"), + plugin.Name)); + Context.API.RestartApp(); + } + else + { + Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_installing_plugin"), + string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_success_no_restart"), + plugin.Name)); + } } internal async ValueTask> RequestUpdateAsync(string search, CancellationToken token, bool usePrimaryUrlOnly = false) @@ -201,10 +221,20 @@ namespace Flow.Launcher.Plugin.PluginsManager IcoPath = x.IcoPath, Action = e => { - string message = string.Format( - Context.API.GetTranslation("plugin_pluginsmanager_update_prompt"), - x.Name, x.Author, - Environment.NewLine, Environment.NewLine); + + string message; + if (Settings.AutoRestartAfterChanging) + { + message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_prompt"), + x.Name, x.Author, + Environment.NewLine, Environment.NewLine); + } + else + { + message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_prompt_no_restart"), + x.Name, x.Author, + Environment.NewLine); + } if (MessageBox.Show(message, Context.API.GetTranslation("plugin_pluginsmanager_update_title"), @@ -215,14 +245,26 @@ namespace Flow.Launcher.Plugin.PluginsManager var downloadToFilePath = Path.Combine(DataLocation.PluginsDirectory, $"{x.Name}-{x.NewVersion}.zip"); - Task.Run(async delegate + _ = Task.Run(async delegate { await Http.DownloadAsync(x.PluginNewUserPlugin.UrlDownload, downloadToFilePath) .ConfigureAwait(false); Install(x.PluginNewUserPlugin, downloadToFilePath); - Context.API.RestartApp(); + if (Settings.AutoRestartAfterChanging) + { + Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"), + string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_success_restart"), + x.Name)); + Context.API.RestartApp(); + } + else + { + Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"), + string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_success_no_restart"), + x.Name)); + } }).ContinueWith(t => { Log.Exception("PluginsManager", $"Update failed for {x.Name}", @@ -454,10 +496,19 @@ namespace Flow.Launcher.Plugin.PluginsManager IcoPath = x.Metadata.IcoPath, Action = e => { - string message = string.Format( - Context.API.GetTranslation("plugin_pluginsmanager_uninstall_prompt"), - x.Metadata.Name, x.Metadata.Author, - Environment.NewLine, Environment.NewLine); + string message; + if (Settings.AutoRestartAfterChanging) + { + message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_uninstall_prompt"), + x.Metadata.Name, x.Metadata.Author, + Environment.NewLine, Environment.NewLine); + } + else + { + message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_uninstall_prompt_no_restart"), + x.Metadata.Name, x.Metadata.Author, + Environment.NewLine); + } if (MessageBox.Show(message, Context.API.GetTranslation("plugin_pluginsmanager_uninstall_title"), @@ -465,7 +516,16 @@ namespace Flow.Launcher.Plugin.PluginsManager { Application.Current.MainWindow.Hide(); Uninstall(x.Metadata); - Context.API.RestartApp(); + if (Settings.AutoRestartAfterChanging) + { + Context.API.RestartApp(); + } + else + { + Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_uninstall_title"), + string.Format(Context.API.GetTranslation("plugin_pluginsmanager_uninstall_success_no_restart"), + x.Metadata.Name)); + } return true; } diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Settings.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/Settings.cs index aa35f02b5..f23ff71f0 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Settings.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Settings.cs @@ -9,5 +9,7 @@ internal const string UpdateCommand = "update"; public bool WarnFromUnknownSource { get; set; } = true; + + public bool AutoRestartAfterChanging { get; set; } = false; } } diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/ViewModels/SettingsViewModel.cs index 672884f80..1c71507fc 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/ViewModels/SettingsViewModel.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/ViewModels/SettingsViewModel.cs @@ -17,5 +17,11 @@ get => Settings.WarnFromUnknownSource; set => Settings.WarnFromUnknownSource = value; } + + public bool AutoRestartAfterChanging + { + get => Settings.AutoRestartAfterChanging; + set => Settings.AutoRestartAfterChanging = value; + } } } diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Views/PluginsManagerSettings.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Views/PluginsManagerSettings.xaml index a62a032f7..18be0d2ca 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Views/PluginsManagerSettings.xaml +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Views/PluginsManagerSettings.xaml @@ -12,10 +12,22 @@ + + + + + From 0c8729f7fb5edfed1dd2641c6d205013b81753e7 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Tue, 26 Sep 2023 20:16:20 +0800 Subject: [PATCH 03/40] Fix wrong doc --- Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs index 474ad6f0a..e6d9126c6 100644 --- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs +++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs @@ -107,7 +107,7 @@ namespace Flow.Launcher.Plugin /// /// Message title /// Message subtitle - /// Message icon path (relative path to your plugin folder) + /// Full path to icon void ShowMsg(string title, string subTitle = "", string iconPath = ""); /// @@ -115,7 +115,7 @@ namespace Flow.Launcher.Plugin /// /// Message title /// Message subtitle - /// Message icon path (relative path to your plugin folder) + /// Full path to icon /// when true will use main windows as the owner void ShowMsg(string title, string subTitle, string iconPath, bool useMainWindowAsOwner = true); From cc2ae7c768516db1d113b0088b75aa105f863feb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Oct 2023 23:09:43 +0000 Subject: [PATCH 04/40] Bump Microsoft.Data.Sqlite from 7.0.10 to 7.0.13 Bumps [Microsoft.Data.Sqlite](https://github.com/dotnet/efcore) from 7.0.10 to 7.0.13. - [Release notes](https://github.com/dotnet/efcore/releases) - [Commits](https://github.com/dotnet/efcore/compare/v7.0.10...v7.0.13) --- updated-dependencies: - dependency-name: Microsoft.Data.Sqlite dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .../Flow.Launcher.Plugin.BrowserBookmark.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj index 9701c2ee8..edaa3dd29 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj @@ -1,4 +1,4 @@ - + Library @@ -56,7 +56,7 @@ - + \ No newline at end of file From 8a9212099f84ce61da1a998c410ac960bac225ae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 22:29:01 +0000 Subject: [PATCH 05/40] Bump nunit from 3.13.3 to 3.14.0 Bumps [nunit](https://github.com/nunit/nunit) from 3.13.3 to 3.14.0. - [Release notes](https://github.com/nunit/nunit/releases) - [Changelog](https://github.com/nunit/nunit/blob/master/CHANGES.md) - [Commits](https://github.com/nunit/nunit/compare/v3.13.3...v3.14.0) --- updated-dependencies: - dependency-name: nunit dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Flow.Launcher.Test/Flow.Launcher.Test.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Test/Flow.Launcher.Test.csproj b/Flow.Launcher.Test/Flow.Launcher.Test.csproj index 3cd9e3df7..c662fdeff 100644 --- a/Flow.Launcher.Test/Flow.Launcher.Test.csproj +++ b/Flow.Launcher.Test/Flow.Launcher.Test.csproj @@ -49,7 +49,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 983a4c56871d6b4d0b78563d8816574981abea9a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Nov 2023 21:22:47 +0000 Subject: [PATCH 06/40] Bump FSharp.Core from 7.0.400 to 7.0.401 Bumps [FSharp.Core](https://github.com/dotnet/fsharp) from 7.0.400 to 7.0.401. - [Release notes](https://github.com/dotnet/fsharp/releases) - [Changelog](https://github.com/dotnet/fsharp/blob/main/release-notes.md) - [Commits](https://github.com/dotnet/fsharp/commits) --- updated-dependencies: - dependency-name: FSharp.Core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Flow.Launcher.Core/Flow.Launcher.Core.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Core/Flow.Launcher.Core.csproj b/Flow.Launcher.Core/Flow.Launcher.Core.csproj index 42f233dad..312dfdd9e 100644 --- a/Flow.Launcher.Core/Flow.Launcher.Core.csproj +++ b/Flow.Launcher.Core/Flow.Launcher.Core.csproj @@ -54,7 +54,7 @@ - + From 72134e8f9a9ae08b1af3935cc6d345d29aa3c445 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Wed, 8 Nov 2023 21:51:48 +0800 Subject: [PATCH 07/40] Tweak notification text Co-authored-by: Jeremy Wu --- .../Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml index d08087ac2..1daa73261 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml @@ -33,9 +33,9 @@ Installing from an unknown source You are installing this plugin from an unknown source and it may contain potential risks!{0}{0}Please ensure you understand where this plugin is from and that it is safe.{0}{0}Would you like to continue still?{0}{0}(You can switch off this warning via settings) - Plugin {0} successfully installed. Please manually restart Flow. - Plugin {0} successfully uninstalled. Please manually restart Flow. - Plugin {0} successfully updated. Please manually restart Flow. + Plugin {0} successfully installed. Please restart Flow. + Plugin {0} successfully uninstalled. Please restart Flow. + Plugin {0} successfully updated. Please restart Flow. Plugins Manager From 0870c5a783ce6bb73e696085d2b15a8b425925a7 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Wed, 8 Nov 2023 22:20:19 +0800 Subject: [PATCH 08/40] Revert "Fix wrong doc" This reverts commit 0c8729f7fb5edfed1dd2641c6d205013b81753e7. --- Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs index e6d9126c6..474ad6f0a 100644 --- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs +++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs @@ -107,7 +107,7 @@ namespace Flow.Launcher.Plugin /// /// Message title /// Message subtitle - /// Full path to icon + /// Message icon path (relative path to your plugin folder) void ShowMsg(string title, string subTitle = "", string iconPath = ""); /// @@ -115,7 +115,7 @@ namespace Flow.Launcher.Plugin /// /// Message title /// Message subtitle - /// Full path to icon + /// Message icon path (relative path to your plugin folder) /// when true will use main windows as the owner void ShowMsg(string title, string subTitle, string iconPath, bool useMainWindowAsOwner = true); From 7436aaa2bb1cc5c1bf72c7051db433ff8d5670db Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Thu, 9 Nov 2023 20:02:20 -0600 Subject: [PATCH 09/40] switch back to jsonmessageformatter --- Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs index 305ba9b65..60130843e 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs @@ -91,7 +91,7 @@ namespace Flow.Launcher.Core.Plugin private void SetupJsonRPC() { - var formatter = new SystemTextJsonFormatter(); + var formatter = new JsonMessageFormatter(); var handler = new NewLineDelimitedMessageHandler(ClientPipe, formatter); From 08da4e34df6ada1c5559c9f4169ac6271877798b Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sat, 11 Nov 2023 00:06:02 +0800 Subject: [PATCH 10/40] Use toast to improve consistency --- .../PluginsManager.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index 77fa3b981..5d18cf18f 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -148,19 +148,19 @@ namespace Flow.Launcher.Plugin.PluginsManager Install(plugin, filePath); } + catch (HttpRequestException e) + { + Context.API.ShowMsgError(string.Format(Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin"), plugin.Name), + Context.API.GetTranslation("plugin_pluginsmanager_download_error")); + Log.Exception("PluginsManager", "An error occurred while downloading plugin", e); + return; + } catch (Exception e) { - // TODO use toast to optimize error prompt - if (e is HttpRequestException) - MessageBox.Show(Context.API.GetTranslation("plugin_pluginsmanager_download_error"), - Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin")); - Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"), string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"), plugin.Name)); - - Log.Exception("PluginsManager", "An error occurred while downloading plugin", e, "InstallOrUpdate"); - + Log.Exception("PluginsManager", "An error occurred while downloading plugin", e); return; } From e7ffd573f0b6a9994e0e95d65f107356c7ccfec3 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sat, 11 Nov 2023 00:40:27 +0800 Subject: [PATCH 11/40] Move Install/Uninstall plugin logic to Core.PluginManager --- Flow.Launcher.Core/Plugin/PluginManager.cs | 104 ++++++++++++++++++ .../PluginsManager.cs | 103 +++-------------- 2 files changed, 120 insertions(+), 87 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs index f8c9a3f17..9010f8a6f 100644 --- a/Flow.Launcher.Core/Plugin/PluginManager.cs +++ b/Flow.Launcher.Core/Plugin/PluginManager.cs @@ -11,6 +11,9 @@ using Flow.Launcher.Infrastructure.Logger; using Flow.Launcher.Infrastructure.UserSettings; using Flow.Launcher.Plugin; using ISavable = Flow.Launcher.Plugin.ISavable; +using Flow.Launcher.Plugin.SharedCommands; +using Mono.Cecil; +using System.Text.Json; namespace Flow.Launcher.Core.Plugin { @@ -331,5 +334,106 @@ namespace Flow.Launcher.Core.Plugin RemoveActionKeyword(id, oldActionKeyword); } } + + private static string GetContainingFolderPathAfterUnzip(string unzippedParentFolderPath) + { + var unzippedFolderCount = Directory.GetDirectories(unzippedParentFolderPath).Length; + var unzippedFilesCount = Directory.GetFiles(unzippedParentFolderPath).Length; + + // adjust path depending on how the plugin is zipped up + // the recommended should be to zip up the folder not the contents + if (unzippedFolderCount == 1 && unzippedFilesCount == 0) + // folder is zipped up, unzipped plugin directory structure: tempPath/unzippedParentPluginFolder/pluginFolderName/ + return Directory.GetDirectories(unzippedParentFolderPath)[0]; + + if (unzippedFilesCount > 1) + // content is zipped up, unzipped plugin directory structure: tempPath/unzippedParentPluginFolder/ + return unzippedParentFolderPath; + + return string.Empty; + } + + private static bool SameOrLesserPluginVersionExists(string metadataPath) + { + var newMetadata = JsonSerializer.Deserialize(File.ReadAllText(metadataPath)); + return AllPlugins.Any(x => x.Metadata.ID == newMetadata.ID + && newMetadata.Version.CompareTo(x.Metadata.Version) <= 0); + } + + public static void Install(UserPlugin plugin, string downloadedFilePath) + { + var tempFolderPath = Path.Combine(Path.GetTempPath(), "flowlauncher"); + var tempFolderPluginPath = Path.Combine(tempFolderPath, "plugin"); + + if (Directory.Exists(tempFolderPath)) + Directory.Delete(tempFolderPath, true); + + Directory.CreateDirectory(tempFolderPath); + + var zipFilePath = Path.Combine(tempFolderPath, Path.GetFileName(downloadedFilePath)); + + File.Copy(downloadedFilePath, zipFilePath); + + File.Delete(downloadedFilePath); + + System.IO.Compression.ZipFile.ExtractToDirectory(zipFilePath, tempFolderPluginPath); + + var pluginFolderPath = GetContainingFolderPathAfterUnzip(tempFolderPluginPath); + + var metadataJsonFilePath = string.Empty; + if (File.Exists(Path.Combine(pluginFolderPath, Constant.PluginMetadataFileName))) + metadataJsonFilePath = Path.Combine(pluginFolderPath, Constant.PluginMetadataFileName); + + if (string.IsNullOrEmpty(metadataJsonFilePath) || string.IsNullOrEmpty(pluginFolderPath)) + { + throw new FileNotFoundException($"Unable to find plugin.json from the extracted zip file, or this path {pluginFolderPath} does not exist"); + } + + if (SameOrLesserPluginVersionExists(metadataJsonFilePath)) + { + throw new InvalidOperationException($"A plugin with the same ID and version already exists, or the version is greater than this downloaded plugin {plugin.Name}"); + } + + var folderName = string.IsNullOrEmpty(plugin.Version) ? $"{plugin.Name}-{Guid.NewGuid()}" : $"{plugin.Name}-{plugin.Version}"; + + var defaultPluginIDs = new List + { + "0ECADE17459B49F587BF81DC3A125110", // BrowserBookmark + "CEA0FDFC6D3B4085823D60DC76F28855", // Calculator + "572be03c74c642baae319fc283e561a8", // Explorer + "6A122269676E40EB86EB543B945932B9", // PluginIndicator + "9f8f9b14-2518-4907-b211-35ab6290dee7", // PluginsManager + "b64d0a79-329a-48b0-b53f-d658318a1bf6", // ProcessKiller + "791FC278BA414111B8D1886DFE447410", // Program + "D409510CD0D2481F853690A07E6DC426", // Shell + "CEA08895D2544B019B2E9C5009600DF4", // Sys + "0308FD86DE0A4DEE8D62B9B535370992", // URL + "565B73353DBF4806919830B9202EE3BF", // WebSearch + "5043CETYU6A748679OPA02D27D99677A" // WindowsSettings + }; + + // Treat default plugin differently, it needs to be removable along with each flow release + var installDirectory = !defaultPluginIDs.Any(x => x == plugin.ID) + ? DataLocation.PluginsDirectory + : Constant.PreinstalledDirectory; + + var newPluginPath = Path.Combine(installDirectory, folderName); + + FilesFolders.CopyAll(pluginFolderPath, newPluginPath); + + Directory.Delete(pluginFolderPath, true); + } + + public static void Uninstall(PluginMetadata plugin, bool removeSettings = true) + { + if (removeSettings) + { + Settings.Plugins.Remove(plugin.ID); + AllPlugins.RemoveAll(p => p.Metadata.ID == plugin.ID); + } + + // Marked for deletion. Will be deleted on next start up + using var _ = File.CreateText(Path.Combine(plugin.PluginDirectory, "NeedDelete.txt")); + } } } diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index 5d18cf18f..20644a2b2 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -10,7 +10,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; -using System.Text.Json; using System.Threading; using System.Threading.Tasks; using System.Windows; @@ -151,19 +150,19 @@ namespace Flow.Launcher.Plugin.PluginsManager catch (HttpRequestException e) { Context.API.ShowMsgError(string.Format(Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin"), plugin.Name), - Context.API.GetTranslation("plugin_pluginsmanager_download_error")); + Context.API.GetTranslation("plugin_pluginsmanager_download_error")); Log.Exception("PluginsManager", "An error occurred while downloading plugin", e); return; } catch (Exception e) { Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"), - string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"), - plugin.Name)); + string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"), + plugin.Name)); Log.Exception("PluginsManager", "An error occurred while downloading plugin", e); return; } - + if (Settings.AutoRestartAfterChanging) { Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_installing_plugin"), @@ -411,77 +410,22 @@ namespace Flow.Launcher.Plugin.PluginsManager { if (!File.Exists(downloadedFilePath)) return; - - var tempFolderPath = Path.Combine(Path.GetTempPath(), "flowlauncher"); - var tempFolderPluginPath = Path.Combine(tempFolderPath, "plugin"); - - if (Directory.Exists(tempFolderPath)) - Directory.Delete(tempFolderPath, true); - - Directory.CreateDirectory(tempFolderPath); - - var zipFilePath = Path.Combine(tempFolderPath, Path.GetFileName(downloadedFilePath)); - - File.Copy(downloadedFilePath, zipFilePath); - - File.Delete(downloadedFilePath); - - Utilities.UnZip(zipFilePath, tempFolderPluginPath, true); - - var pluginFolderPath = Utilities.GetContainingFolderPathAfterUnzip(tempFolderPluginPath); - - var metadataJsonFilePath = string.Empty; - if (File.Exists(Path.Combine(pluginFolderPath, Constant.PluginMetadataFileName))) - metadataJsonFilePath = Path.Combine(pluginFolderPath, Constant.PluginMetadataFileName); - - if (string.IsNullOrEmpty(metadataJsonFilePath) || string.IsNullOrEmpty(pluginFolderPath)) + try { + PluginManager.Install(plugin, downloadedFilePath); + } + catch(FileNotFoundException e) + { + Log.Exception("Flow.Launcher.Plugin.PluginsManager", e.Message, e); MessageBox.Show(Context.API.GetTranslation("plugin_pluginsmanager_install_errormetadatafile"), - Context.API.GetTranslation("plugin_pluginsmanager_install_error_title")); - - throw new FileNotFoundException( - string.Format("Unable to find plugin.json from the extracted zip file, or this path {0} does not exist", pluginFolderPath)); + Context.API.GetTranslation("plugin_pluginsmanager_install_error_title")); } - - if (SameOrLesserPluginVersionExists(metadataJsonFilePath)) + catch(InvalidOperationException e) { + Log.Exception("Flow.Launcher.Plugin.PluginsManager", e.Message, e); MessageBox.Show(string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_duplicate"), plugin.Name), - Context.API.GetTranslation("plugin_pluginsmanager_install_error_title")); - - throw new InvalidOperationException( - string.Format("A plugin with the same ID and version already exists, " + - "or the version is greater than this downloaded plugin {0}", - plugin.Name)); + Context.API.GetTranslation("plugin_pluginsmanager_install_error_title")); } - - var folderName = string.IsNullOrEmpty(plugin.Version) ? $"{plugin.Name}-{Guid.NewGuid()}" : $"{plugin.Name}-{plugin.Version}"; - - var defaultPluginIDs = new List - { - "0ECADE17459B49F587BF81DC3A125110", // BrowserBookmark - "CEA0FDFC6D3B4085823D60DC76F28855", // Calculator - "572be03c74c642baae319fc283e561a8", // Explorer - "6A122269676E40EB86EB543B945932B9", // PluginIndicator - "9f8f9b14-2518-4907-b211-35ab6290dee7", // PluginsManager - "b64d0a79-329a-48b0-b53f-d658318a1bf6", // ProcessKiller - "791FC278BA414111B8D1886DFE447410", // Program - "D409510CD0D2481F853690A07E6DC426", // Shell - "CEA08895D2544B019B2E9C5009600DF4", // Sys - "0308FD86DE0A4DEE8D62B9B535370992", // URL - "565B73353DBF4806919830B9202EE3BF", // WebSearch - "5043CETYU6A748679OPA02D27D99677A" // WindowsSettings - }; - - // Treat default plugin differently, it needs to be removable along with each flow release - var installDirectory = !defaultPluginIDs.Any(x => x == plugin.ID) - ? DataLocation.PluginsDirectory - : Constant.PreinstalledDirectory; - - var newPluginPath = Path.Combine(installDirectory, folderName); - - FilesFolders.CopyAll(pluginFolderPath, newPluginPath); - - Directory.Delete(pluginFolderPath, true); } internal List RequestUninstall(string search) @@ -537,24 +481,9 @@ namespace Flow.Launcher.Plugin.PluginsManager return Search(results, search); } - private void Uninstall(PluginMetadata plugin, bool removedSetting = true) + private static void Uninstall(PluginMetadata plugin, bool removeSettings = true) { - if (removedSetting) - { - PluginManager.Settings.Plugins.Remove(plugin.ID); - PluginManager.AllPlugins.RemoveAll(p => p.Metadata.ID == plugin.ID); - } - - // Marked for deletion. Will be deleted on next start up - using var _ = File.CreateText(Path.Combine(plugin.PluginDirectory, "NeedDelete.txt")); - } - - private bool SameOrLesserPluginVersionExists(string metadataPath) - { - var newMetadata = JsonSerializer.Deserialize(File.ReadAllText(metadataPath)); - return Context.API.GetAllPlugins() - .Any(x => x.Metadata.ID == newMetadata.ID - && newMetadata.Version.CompareTo(x.Metadata.Version) <= 0); + PluginManager.Uninstall(plugin, removeSettings); } } } From 5b2220b9dafda45af72a20ee7a12136b23fd3dee Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sat, 11 Nov 2023 00:47:18 +0800 Subject: [PATCH 12/40] Exclude installed plugins in pm install results --- Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index 20644a2b2..af68cc0a8 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -382,6 +382,7 @@ namespace Flow.Launcher.Plugin.PluginsManager var results = PluginsManifest .UserPlugins + .Where(x => !PluginExists(x.ID)) .Select(x => new Result { From 842451db69bba8b40449773a79a80ddda6418d5d Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sat, 11 Nov 2023 00:48:18 +0800 Subject: [PATCH 13/40] Show plugin icons in pm Install results --- Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index af68cc0a8..7b5c09fa7 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -388,7 +388,7 @@ namespace Flow.Launcher.Plugin.PluginsManager { Title = $"{x.Name} by {x.Author}", SubTitle = x.Description, - IcoPath = icoPath, + IcoPath = x.IcoPath, Action = e => { if (e.SpecialKeyState.CtrlPressed) From 41721150f91437dc62e9cc4a13bb852f16ebd9e2 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sat, 11 Nov 2023 01:20:32 +0800 Subject: [PATCH 14/40] Add glyphs for pm context menu --- Plugins/Flow.Launcher.Plugin.PluginsManager/ContextMenu.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/ContextMenu.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/ContextMenu.cs index 580954f3c..17e9fe2bc 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/ContextMenu.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/ContextMenu.cs @@ -13,6 +13,10 @@ namespace Flow.Launcher.Plugin.PluginsManager Context = context; } + private readonly GlyphInfo sourcecodeGlyph = new("/Resources/#Segoe Fluent Icons","\uE943"); + private readonly GlyphInfo issueGlyph = new("/Resources/#Segoe Fluent Icons", "\ued15"); + private readonly GlyphInfo manifestGlyph = new("/Resources/#Segoe Fluent Icons", "\uea37"); + public List LoadContextMenus(Result selectedResult) { if(selectedResult.ContextData is not UserPlugin pluginManifestInfo) @@ -36,6 +40,7 @@ namespace Flow.Launcher.Plugin.PluginsManager Title = Context.API.GetTranslation("plugin_pluginsmanager_plugin_contextmenu_gotosourcecode_title"), SubTitle = Context.API.GetTranslation("plugin_pluginsmanager_plugin_contextmenu_gotosourcecode_subtitle"), IcoPath = "Images\\sourcecode.png", + Glyph = sourcecodeGlyph, Action = _ => { Context.API.OpenUrl(pluginManifestInfo.UrlSourceCode); @@ -47,6 +52,7 @@ namespace Flow.Launcher.Plugin.PluginsManager Title = Context.API.GetTranslation("plugin_pluginsmanager_plugin_contextmenu_newissue_title"), SubTitle = Context.API.GetTranslation("plugin_pluginsmanager_plugin_contextmenu_newissue_subtitle"), IcoPath = "Images\\request.png", + Glyph = issueGlyph, Action = _ => { // standard UrlSourceCode format in PluginsManifest's plugins.json file: https://github.com/jjw24/Flow.Launcher.Plugin.Putty/tree/master @@ -63,6 +69,7 @@ namespace Flow.Launcher.Plugin.PluginsManager Title = Context.API.GetTranslation("plugin_pluginsmanager_plugin_contextmenu_pluginsmanifest_title"), SubTitle = Context.API.GetTranslation("plugin_pluginsmanager_plugin_contextmenu_pluginsmanifest_subtitle"), IcoPath = "Images\\manifestsite.png", + Glyph = manifestGlyph, Action = _ => { Context.API.OpenUrl("https://github.com/Flow-Launcher/Flow.Launcher.PluginsManifest"); From 54e255c504ce62c058e9baa255e95d6b73d64599 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sat, 11 Nov 2023 01:28:34 +0800 Subject: [PATCH 15/40] Fix typo --- Flow.Launcher.Core/Plugin/PluginManager.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs index 9010f8a6f..6720ee61a 100644 --- a/Flow.Launcher.Core/Plugin/PluginManager.cs +++ b/Flow.Launcher.Core/Plugin/PluginManager.cs @@ -12,7 +12,6 @@ using Flow.Launcher.Infrastructure.UserSettings; using Flow.Launcher.Plugin; using ISavable = Flow.Launcher.Plugin.ISavable; using Flow.Launcher.Plugin.SharedCommands; -using Mono.Cecil; using System.Text.Json; namespace Flow.Launcher.Core.Plugin From bf598887dd942e2e684e2ff3144b9fc9e944d261 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sat, 11 Nov 2023 01:34:01 +0800 Subject: [PATCH 16/40] Make settings field private --- Flow.Launcher.Core/Plugin/PluginManager.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs index 6720ee61a..ea8b79aa4 100644 --- a/Flow.Launcher.Core/Plugin/PluginManager.cs +++ b/Flow.Launcher.Core/Plugin/PluginManager.cs @@ -29,8 +29,7 @@ namespace Flow.Launcher.Core.Plugin public static IPublicAPI API { private set; get; } - // todo happlebao, this should not be public, the indicator function should be embeded - public static PluginsSettings Settings; + private static PluginsSettings Settings; private static List _metadatas; /// From 9f39dfceee916cbb83e9c88675f083af3abc7406 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Wed, 8 Nov 2023 22:12:01 +0800 Subject: [PATCH 17/40] Use FuzzySearch to search access links --- .../Search/QuickAccessLinks/QuickAccess.cs | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/QuickAccess.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/QuickAccess.cs index cdd2c93e6..85b595390 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/QuickAccess.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/QuickAccess.cs @@ -13,20 +13,17 @@ namespace Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks if (string.IsNullOrEmpty(query.Search)) return new List(); - string search = query.Search.ToLower(); - - var queriedAccessLinks = - accessLinks - .Where(x => x.Name.Contains(search, StringComparison.OrdinalIgnoreCase) || x.Path.Contains(search, StringComparison.OrdinalIgnoreCase)) + return accessLinks + .Where(x => Main.Context.API.FuzzySearch(query.Search, x.Name).IsSearchPrecisionScoreMet() || Main.Context.API.FuzzySearch(query.Search, x.Path).IsSearchPrecisionScoreMet()) .OrderBy(x => x.Type) - .ThenBy(x => x.Name); - - return queriedAccessLinks.Select(l => l.Type switch - { - ResultType.Folder => ResultManager.CreateFolderResult(l.Name, l.Path, l.Path, query, quickAccessResultScore), - ResultType.File => ResultManager.CreateFileResult(l.Path, query, quickAccessResultScore), - _ => throw new ArgumentOutOfRangeException() - }).ToList(); + .ThenBy(x => x.Name) + .Select(l => l.Type switch + { + ResultType.Folder => ResultManager.CreateFolderResult(l.Name, l.Path, l.Path, query, quickAccessResultScore), + ResultType.File => ResultManager.CreateFileResult(l.Path, query, quickAccessResultScore), + _ => throw new ArgumentOutOfRangeException() + }) + .ToList(); } internal static List AccessLinkListAll(Query query, IEnumerable accessLinks) From b7a78362bf38124ccbc72ec0419f611e5c97b530 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sat, 11 Nov 2023 10:25:45 +0800 Subject: [PATCH 18/40] Throw exception when zip not found --- Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index 7b5c09fa7..97cfb67d1 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -267,7 +267,7 @@ namespace Flow.Launcher.Plugin.PluginsManager }).ContinueWith(t => { Log.Exception("PluginsManager", $"Update failed for {x.Name}", - t.Exception.InnerException, "RequestUpdate"); + t.Exception.InnerException); Context.API.ShowMsg( Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"), string.Format( @@ -410,7 +410,7 @@ namespace Flow.Launcher.Plugin.PluginsManager private void Install(UserPlugin plugin, string downloadedFilePath) { if (!File.Exists(downloadedFilePath)) - return; + throw new FileNotFoundException($"Plugin {plugin.ID} zip file not found at {downloadedFilePath}", downloadedFilePath); try { PluginManager.Install(plugin, downloadedFilePath); From 69dad1be6c2bca648b54089f62047e78ecadc5e9 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sat, 11 Nov 2023 15:05:24 +0800 Subject: [PATCH 19/40] Check if plugin has been modified when installing/updating/uninstalling --- Flow.Launcher.Core/Plugin/PluginManager.cs | 56 ++++++++++++++++++- .../Languages/en.xaml | 4 +- .../PluginsManager.cs | 36 ++++++++---- 3 files changed, 81 insertions(+), 15 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs index ea8b79aa4..64e097379 100644 --- a/Flow.Launcher.Core/Plugin/PluginManager.cs +++ b/Flow.Launcher.Core/Plugin/PluginManager.cs @@ -31,6 +31,7 @@ namespace Flow.Launcher.Core.Plugin private static PluginsSettings Settings; private static List _metadatas; + private static List _modifiedPlugins = new List(); /// /// Directories that will hold Flow Launcher plugin directory @@ -358,8 +359,42 @@ namespace Flow.Launcher.Core.Plugin && newMetadata.Version.CompareTo(x.Metadata.Version) <= 0); } - public static void Install(UserPlugin plugin, string downloadedFilePath) + #region Public functions + + public static bool PluginModified(string uuid) { + return _modifiedPlugins.Contains(uuid); + } + + public static void UpdatePlugin(PluginMetadata existingVersion, UserPlugin newVersion, string downloadedFilePath) + { + InstallPlugin(newVersion, downloadedFilePath, checkModified:false); + UninstallPlugin(existingVersion, removeSettings:false, checkModified:false); + _modifiedPlugins.Add(existingVersion.ID); + } + + public static void InstallPlugin(UserPlugin plugin, string downloadedFilePath) + { + InstallPlugin(plugin, downloadedFilePath, true); + } + + public static void UninstallPlugin(PluginMetadata plugin, bool removeSettings = true) + { + UninstallPlugin(plugin, removeSettings, true); + } + + #endregion + + #region Internal functions + + internal static void InstallPlugin(UserPlugin plugin, string downloadedFilePath, bool checkModified) + { + if (checkModified && PluginModified(plugin.ID)) + { + // Distinguish exception from installing same or less version + throw new ArgumentException($"Plugin {plugin.Name} {plugin.ID} has been modified.", nameof(plugin)); + } + var tempFolderPath = Path.Combine(Path.GetTempPath(), "flowlauncher"); var tempFolderPluginPath = Path.Combine(tempFolderPath, "plugin"); @@ -420,10 +455,20 @@ namespace Flow.Launcher.Core.Plugin FilesFolders.CopyAll(pluginFolderPath, newPluginPath); Directory.Delete(pluginFolderPath, true); + + if (checkModified) + { + _modifiedPlugins.Add(plugin.ID); + } } - public static void Uninstall(PluginMetadata plugin, bool removeSettings = true) + internal static void UninstallPlugin(PluginMetadata plugin, bool removeSettings, bool checkModified) { + if (checkModified && PluginModified(plugin.ID)) + { + throw new ArgumentException($"Plugin {plugin.Name} has been modified"); + } + if (removeSettings) { Settings.Plugins.Remove(plugin.ID); @@ -432,6 +477,13 @@ namespace Flow.Launcher.Core.Plugin // Marked for deletion. Will be deleted on next start up using var _ = File.CreateText(Path.Combine(plugin.PluginDirectory, "NeedDelete.txt")); + + if (checkModified) + { + _modifiedPlugins.Add(plugin.ID); + } } + + #endregion } } diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml index 1daa73261..42a1ac9b8 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml @@ -20,6 +20,7 @@ Error: A plugin which has the same or greater version with {0} already exists. Error installing plugin Error occurred while trying to install {0} + Error uninstalling plugin No update available All plugins are up to date {0} by {1} {2}{3}Would you like to update this plugin? After the update Flow will automatically restart. @@ -36,7 +37,8 @@ Plugin {0} successfully installed. Please restart Flow. Plugin {0} successfully uninstalled. Please restart Flow. Plugin {0} successfully updated. Please restart Flow. - + Plugin {0} has already been modified. Please restart Flow before making any further changes. + Plugins Manager Management of installing, uninstalling or updating Flow Launcher plugins diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index 97cfb67d1..6667c3d4d 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -239,8 +239,6 @@ namespace Flow.Launcher.Plugin.PluginsManager Context.API.GetTranslation("plugin_pluginsmanager_update_title"), MessageBoxButton.YesNo) == MessageBoxResult.Yes) { - Uninstall(x.PluginExistingMetadata, false); - var downloadToFilePath = Path.Combine(DataLocation.PluginsDirectory, $"{x.Name}-{x.NewVersion}.zip"); @@ -249,7 +247,7 @@ namespace Flow.Launcher.Plugin.PluginsManager await Http.DownloadAsync(x.PluginNewUserPlugin.UrlDownload, downloadToFilePath) .ConfigureAwait(false); - Install(x.PluginNewUserPlugin, downloadToFilePath); + PluginManager.UpdatePlugin(x.PluginExistingMetadata, x.PluginNewUserPlugin, downloadToFilePath); if (Settings.AutoRestartAfterChanging) { @@ -413,19 +411,24 @@ namespace Flow.Launcher.Plugin.PluginsManager throw new FileNotFoundException($"Plugin {plugin.ID} zip file not found at {downloadedFilePath}", downloadedFilePath); try { - PluginManager.Install(plugin, downloadedFilePath); + PluginManager.InstallPlugin(plugin, downloadedFilePath); } - catch(FileNotFoundException e) + catch (FileNotFoundException e) { + Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"), + Context.API.GetTranslation("plugin_pluginsmanager_install_errormetadatafile")); Log.Exception("Flow.Launcher.Plugin.PluginsManager", e.Message, e); - MessageBox.Show(Context.API.GetTranslation("plugin_pluginsmanager_install_errormetadatafile"), - Context.API.GetTranslation("plugin_pluginsmanager_install_error_title")); } - catch(InvalidOperationException e) + catch (InvalidOperationException e) { + Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"), + string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_duplicate"), plugin.Name)); + Log.Exception("Flow.Launcher.Plugin.PluginsManager", e.Message, e); + } + catch (ArgumentException e) { + Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"), + string.Format(Context.API.GetTranslation("plugin_pluginsmanager_plugin_modified_error"), plugin.Name)); Log.Exception("Flow.Launcher.Plugin.PluginsManager", e.Message, e); - MessageBox.Show(string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_duplicate"), plugin.Name), - Context.API.GetTranslation("plugin_pluginsmanager_install_error_title")); } } @@ -482,9 +485,18 @@ namespace Flow.Launcher.Plugin.PluginsManager return Search(results, search); } - private static void Uninstall(PluginMetadata plugin, bool removeSettings = true) + private void Uninstall(PluginMetadata plugin) { - PluginManager.Uninstall(plugin, removeSettings); + try + { + PluginManager.UninstallPlugin(plugin, removeSettings:true); + } + catch (ArgumentException e) + { + Log.Exception("Flow.Launcher.Plugin.PluginsManager", e.Message, e); + Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_uninstall_error_title"), + Context.API.GetTranslation("plugin_pluginsmanager_plugin_modified_error")); + } } } } From 53eec760693b78b9d8954791fabc0a4d545c3579 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sat, 11 Nov 2023 15:17:24 +0800 Subject: [PATCH 20/40] Remove unused import --- .../Flow.Launcher.Plugin.PluginsManager.csproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Flow.Launcher.Plugin.PluginsManager.csproj b/Plugins/Flow.Launcher.Plugin.PluginsManager/Flow.Launcher.Plugin.PluginsManager.csproj index 51882a20e..92500ae6a 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Flow.Launcher.Plugin.PluginsManager.csproj +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Flow.Launcher.Plugin.PluginsManager.csproj @@ -36,8 +36,4 @@ PreserveNewest - - - - \ No newline at end of file From 50449de653d1fd5bec713eb3544b7a13823d73fc Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sat, 11 Nov 2023 15:29:55 +0800 Subject: [PATCH 21/40] Hide modified plugins in query results --- Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index 6667c3d4d..b04026804 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -188,6 +188,7 @@ namespace Flow.Launcher.Plugin.PluginsManager on existingPlugin.Metadata.ID equals pluginFromManifest.ID where existingPlugin.Metadata.Version.CompareTo(pluginFromManifest.Version) < 0 // if current version precedes manifest version + && !PluginManager.PluginModified(existingPlugin.Metadata.ID) select new { @@ -317,6 +318,7 @@ namespace Flow.Launcher.Plugin.PluginsManager var plugin = new UserPlugin { + // FIXME installing in store then install web ver ID = "", Name = name, Version = string.Empty, @@ -380,7 +382,7 @@ namespace Flow.Launcher.Plugin.PluginsManager var results = PluginsManifest .UserPlugins - .Where(x => !PluginExists(x.ID)) + .Where(x => !PluginExists(x.ID) && !PluginManager.PluginModified(x.ID)) .Select(x => new Result { From f6a4942a484704a74a5336036f25efe65f53feed Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sat, 11 Nov 2023 16:11:21 +0800 Subject: [PATCH 22/40] Refactor plugin zip logic - Download zip to temp folder - Unzip to unique folder --- Flow.Launcher.Core/Plugin/PluginManager.cs | 39 +++++++++---------- .../PluginsManager.cs | 5 ++- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs index 64e097379..47edc21c2 100644 --- a/Flow.Launcher.Core/Plugin/PluginManager.cs +++ b/Flow.Launcher.Core/Plugin/PluginManager.cs @@ -366,18 +366,28 @@ namespace Flow.Launcher.Core.Plugin return _modifiedPlugins.Contains(uuid); } - public static void UpdatePlugin(PluginMetadata existingVersion, UserPlugin newVersion, string downloadedFilePath) + + /// + /// Update a plugin to new version, from a zip file. Will Delete zip after updating. + /// + public static void UpdatePlugin(PluginMetadata existingVersion, UserPlugin newVersion, string zipFilePath) { - InstallPlugin(newVersion, downloadedFilePath, checkModified:false); + InstallPlugin(newVersion, zipFilePath, checkModified:false); UninstallPlugin(existingVersion, removeSettings:false, checkModified:false); _modifiedPlugins.Add(existingVersion.ID); } - public static void InstallPlugin(UserPlugin plugin, string downloadedFilePath) + /// + /// Install a plugin. Will Delete zip after updating. + /// + public static void InstallPlugin(UserPlugin plugin, string zipFilePath) { - InstallPlugin(plugin, downloadedFilePath, true); + InstallPlugin(plugin, zipFilePath, true); } + /// + /// Uninstall a plugin. + /// public static void UninstallPlugin(PluginMetadata plugin, bool removeSettings = true) { UninstallPlugin(plugin, removeSettings, true); @@ -387,7 +397,7 @@ namespace Flow.Launcher.Core.Plugin #region Internal functions - internal static void InstallPlugin(UserPlugin plugin, string downloadedFilePath, bool checkModified) + internal static void InstallPlugin(UserPlugin plugin, string zipFilePath, bool checkModified) { if (checkModified && PluginModified(plugin.ID)) { @@ -395,21 +405,10 @@ namespace Flow.Launcher.Core.Plugin throw new ArgumentException($"Plugin {plugin.Name} {plugin.ID} has been modified.", nameof(plugin)); } - var tempFolderPath = Path.Combine(Path.GetTempPath(), "flowlauncher"); - var tempFolderPluginPath = Path.Combine(tempFolderPath, "plugin"); - - if (Directory.Exists(tempFolderPath)) - Directory.Delete(tempFolderPath, true); - - Directory.CreateDirectory(tempFolderPath); - - var zipFilePath = Path.Combine(tempFolderPath, Path.GetFileName(downloadedFilePath)); - - File.Copy(downloadedFilePath, zipFilePath); - - File.Delete(downloadedFilePath); - + // Unzip plugin files to temp folder + var tempFolderPluginPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); System.IO.Compression.ZipFile.ExtractToDirectory(zipFilePath, tempFolderPluginPath); + File.Delete(zipFilePath); var pluginFolderPath = GetContainingFolderPathAfterUnzip(tempFolderPluginPath); @@ -454,7 +453,7 @@ namespace Flow.Launcher.Core.Plugin FilesFolders.CopyAll(pluginFolderPath, newPluginPath); - Directory.Delete(pluginFolderPath, true); + Directory.Delete(tempFolderPluginPath, true); if (checkModified) { diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index b04026804..1206a4cf9 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -139,7 +139,7 @@ namespace Flow.Launcher.Plugin.PluginsManager ? $"{plugin.Name}-{Guid.NewGuid()}.zip" : $"{plugin.Name}-{plugin.Version}.zip"; - var filePath = Path.Combine(DataLocation.PluginsDirectory, downloadFilename); + var filePath = Path.Combine(Path.GetTempPath(), downloadFilename); try { @@ -240,7 +240,7 @@ namespace Flow.Launcher.Plugin.PluginsManager Context.API.GetTranslation("plugin_pluginsmanager_update_title"), MessageBoxButton.YesNo) == MessageBoxResult.Yes) { - var downloadToFilePath = Path.Combine(DataLocation.PluginsDirectory, + var downloadToFilePath = Path.Combine(Path.GetTempPath(), $"{x.Name}-{x.NewVersion}.zip"); _ = Task.Run(async delegate @@ -414,6 +414,7 @@ namespace Flow.Launcher.Plugin.PluginsManager try { PluginManager.InstallPlugin(plugin, downloadedFilePath); + File.Delete(downloadedFilePath); } catch (FileNotFoundException e) { From af9c662892621b3be10d3be76fb1067a20cfd2e1 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sat, 11 Nov 2023 16:21:36 +0800 Subject: [PATCH 23/40] Remove comment --- Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index 1206a4cf9..3cfae97d5 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -318,7 +318,6 @@ namespace Flow.Launcher.Plugin.PluginsManager var plugin = new UserPlugin { - // FIXME installing in store then install web ver ID = "", Name = name, Version = string.Empty, From c18ae41e56f5b38ca4d702e58fa691e29ad7743d Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sun, 12 Nov 2023 11:42:13 +0800 Subject: [PATCH 24/40] Delete existing zip before downloading --- .../PluginsManager.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index 3cfae97d5..00f77f872 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -143,6 +143,11 @@ namespace Flow.Launcher.Plugin.PluginsManager try { + if (File.Exists(filePath)) + { + File.Delete(filePath); + } + await Http.DownloadAsync(plugin.UrlDownload, filePath).ConfigureAwait(false); Install(plugin, filePath); @@ -245,6 +250,11 @@ namespace Flow.Launcher.Plugin.PluginsManager _ = Task.Run(async delegate { + if (File.Exists(downloadToFilePath)) + { + File.Delete(downloadToFilePath); + } + await Http.DownloadAsync(x.PluginNewUserPlugin.UrlDownload, downloadToFilePath) .ConfigureAwait(false); From 439eebf6cb9f53c12caddc3a2348eaae6aac1402 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sun, 12 Nov 2023 12:34:38 +0800 Subject: [PATCH 25/40] Version bump 3.1.4 --- Plugins/Flow.Launcher.Plugin.Explorer/plugin.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/plugin.json b/Plugins/Flow.Launcher.Plugin.Explorer/plugin.json index 7dfa1656c..53d4049e6 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/plugin.json +++ b/Plugins/Flow.Launcher.Plugin.Explorer/plugin.json @@ -10,7 +10,7 @@ "Name": "Explorer", "Description": "Find and manage files and folders via Windows Search or Everything", "Author": "Jeremy Wu", - "Version": "3.1.3", + "Version": "3.1.4", "Language": "csharp", "Website": "https://github.com/Flow-Launcher/Flow.Launcher", "ExecuteFileName": "Flow.Launcher.Plugin.Explorer.dll", From 6eecc614a8713f3f472d48e682e0afb97c13b6c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 22:04:20 +0000 Subject: [PATCH 26/40] Bump JetBrains.Annotations from 2023.2.0 to 2023.3.0 Bumps [JetBrains.Annotations](https://github.com/JetBrains/JetBrains.Annotations) from 2023.2.0 to 2023.3.0. - [Commits](https://github.com/JetBrains/JetBrains.Annotations/compare/v2023.2.0...2023.3) --- updated-dependencies: - dependency-name: JetBrains.Annotations dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj index 1f28f5d32..76233c3a4 100644 --- a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj +++ b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj @@ -67,7 +67,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + From 7961ca14375effa978719b779861d324934df5fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 22:04:26 +0000 Subject: [PATCH 27/40] Bump VirtualizingWrapPanel from 1.5.7 to 1.5.8 Bumps [VirtualizingWrapPanel](https://github.com/sbaeumlisberger/VirtualizingWrapPanel) from 1.5.7 to 1.5.8. - [Release notes](https://github.com/sbaeumlisberger/VirtualizingWrapPanel/releases) - [Commits](https://github.com/sbaeumlisberger/VirtualizingWrapPanel/compare/v1.5.7...v1.5.8) --- updated-dependencies: - dependency-name: VirtualizingWrapPanel dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Flow.Launcher/Flow.Launcher.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj index e7b35e689..53c1bafc7 100644 --- a/Flow.Launcher/Flow.Launcher.csproj +++ b/Flow.Launcher/Flow.Launcher.csproj @@ -96,7 +96,7 @@ - + From 3ec27edf75fc70fecc9d8d2865fc0f5c9579f557 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sat, 18 Nov 2023 14:22:54 -0600 Subject: [PATCH 28/40] Use ConcurrentDictionary for JsonRPC Settings --- Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs index b87623c56..fd73a44cd 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; @@ -16,10 +17,10 @@ namespace Flow.Launcher.Core.Plugin public Dictionary SettingControls { get; } = new(); public IReadOnlyDictionary Inner => Settings; - protected Dictionary Settings { get; set; } + protected ConcurrentDictionary Settings { get; set; } public required IPublicAPI API { get; init; } - private JsonStorage> _storage; + private JsonStorage> _storage; // maybe move to resource? private static readonly Thickness settingControlMargin = new(0, 9, 18, 9); @@ -33,7 +34,7 @@ namespace Flow.Launcher.Core.Plugin public async Task InitializeAsync() { - _storage = new JsonStorage>(SettingPath); + _storage = new JsonStorage>(SettingPath); Settings = await _storage.LoadAsync(); foreach (var (type, attributes) in Configuration.Body) From 1cafae827889ac0520cd16e06512d447e3bcf604 Mon Sep 17 00:00:00 2001 From: Garulf <535299+Garulf@users.noreply.github.com> Date: Sat, 18 Nov 2023 18:43:17 -0500 Subject: [PATCH 29/40] Allow nullable for Configuration --- Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs index b87623c56..1b14597a4 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs @@ -10,7 +10,7 @@ namespace Flow.Launcher.Core.Plugin { public class JsonRPCPluginSettings { - public required JsonRpcConfigurationModel Configuration { get; init; } + public required JsonRpcConfigurationModel? Configuration { get; init; } public required string SettingPath { get; init; } public Dictionary SettingControls { get; } = new(); From 93100c0330b19d4861d6bb466f7468b8405866b6 Mon Sep 17 00:00:00 2001 From: Garulf <535299+Garulf@users.noreply.github.com> Date: Sat, 18 Nov 2023 18:43:42 -0500 Subject: [PATCH 30/40] Remove missing template file short circuit logic --- Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs index 330120c12..197932f04 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs @@ -126,8 +126,6 @@ namespace Flow.Launcher.Core.Plugin private async Task InitSettingAsync() { - if (!File.Exists(SettingConfigurationPath)) - return; var deserializer = new DeserializerBuilder().WithNamingConvention(CamelCaseNamingConvention.Instance) .Build(); From b67e815022416cc30b8aae926ef9216a08eecfa7 Mon Sep 17 00:00:00 2001 From: Garulf <535299+Garulf@users.noreply.github.com> Date: Sat, 18 Nov 2023 18:44:01 -0500 Subject: [PATCH 31/40] Load template file only if exists --- Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs index 197932f04..c6b56c81d 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs @@ -126,12 +126,15 @@ namespace Flow.Launcher.Core.Plugin private async Task InitSettingAsync() { + JsonRpcConfigurationModel configuration = null; + if (File.Exists(SettingConfigurationPath)) + { + var deserializer = new DeserializerBuilder().WithNamingConvention(CamelCaseNamingConvention.Instance).Build(); + configuration = + deserializer.Deserialize( + await File.ReadAllTextAsync(SettingConfigurationPath)); + } - var deserializer = new DeserializerBuilder().WithNamingConvention(CamelCaseNamingConvention.Instance) - .Build(); - var configuration = - deserializer.Deserialize( - await File.ReadAllTextAsync(SettingConfigurationPath)); Settings ??= new JsonRPCPluginSettings { From 388688e89c26d74490ac377e17f41a2b7765241e Mon Sep 17 00:00:00 2001 From: Garulf <535299+Garulf@users.noreply.github.com> Date: Sat, 18 Nov 2023 18:44:27 -0500 Subject: [PATCH 32/40] Short circuit template UI process if doesn't exist --- Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs index 1b14597a4..e26f5e7a7 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs @@ -36,6 +36,11 @@ namespace Flow.Launcher.Core.Plugin _storage = new JsonStorage>(SettingPath); Settings = await _storage.LoadAsync(); + if (Settings != null) + { + return; + } + foreach (var (type, attributes) in Configuration.Body) { if (attributes.Name == null) From ba9aba2bff27a94810496be498271d244bf1538c Mon Sep 17 00:00:00 2001 From: Garulf <535299+Garulf@users.noreply.github.com> Date: Sat, 18 Nov 2023 18:45:16 -0500 Subject: [PATCH 33/40] Allow new setting keys to be instantiated --- Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs index e26f5e7a7..842a91919 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs @@ -63,10 +63,7 @@ namespace Flow.Launcher.Core.Plugin foreach (var (key, value) in settings) { - if (Settings.ContainsKey(key)) - { - Settings[key] = value; - } + Settings[key] = value; if (SettingControls.TryGetValue(key, out var control)) { From 5c90946a6ee99df8973096fdba3d8d69b7b3617b Mon Sep 17 00:00:00 2001 From: Garulf <535299+Garulf@users.noreply.github.com> Date: Sat, 18 Nov 2023 18:45:24 -0500 Subject: [PATCH 34/40] Save to file on update --- Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs index 842a91919..06d9f8dec 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs @@ -83,6 +83,7 @@ namespace Flow.Launcher.Core.Plugin break; } } + Save(); } } From a86e7bcaa9ed3e9a0b456bea6708f0e8b24e1442 Mon Sep 17 00:00:00 2001 From: Garulf <535299+Garulf@users.noreply.github.com> Date: Sat, 18 Nov 2023 23:15:39 -0500 Subject: [PATCH 35/40] Remove save function from loop --- Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs index 06d9f8dec..43215bdd5 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs @@ -83,8 +83,8 @@ namespace Flow.Launcher.Core.Plugin break; } } - Save(); } + Save(); } public async Task SaveAsync() From b63c4eb2bfea0e80d1d0ac7e21f2e16e558a1686 Mon Sep 17 00:00:00 2001 From: Garulf <535299+Garulf@users.noreply.github.com> Date: Sun, 19 Nov 2023 09:11:27 -0500 Subject: [PATCH 36/40] Revert SettingsChanges to SettingsChange for backwards compatibility --- Flow.Launcher.Core/Plugin/JsonPRCModel.cs | 2 +- Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/JsonPRCModel.cs b/Flow.Launcher.Core/Plugin/JsonPRCModel.cs index 48606eea4..5b2a9f6cb 100644 --- a/Flow.Launcher.Core/Plugin/JsonPRCModel.cs +++ b/Flow.Launcher.Core/Plugin/JsonPRCModel.cs @@ -25,7 +25,7 @@ namespace Flow.Launcher.Core.Plugin public record JsonRPCResponseModel(int Id, JsonRPCErrorModel Error = default) : JsonRPCBase(Id, Error); public record JsonRPCQueryResponseModel(int Id, [property: JsonPropertyName("result")] List Result, - IReadOnlyDictionary SettingsChanges = null, + IReadOnlyDictionary SettingsChange = null, string DebugMessage = "", JsonRPCErrorModel Error = default) : JsonRPCResponseModel(Id, Error); diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs index 330120c12..b0075c8f0 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs @@ -94,7 +94,7 @@ namespace Flow.Launcher.Core.Plugin results.AddRange(queryResponseModel.Result); - Settings?.UpdateSettings(queryResponseModel.SettingsChanges); + Settings?.UpdateSettings(queryResponseModel.SettingsChange); return results; } From bf1e451351529ae4a65598faa0da6a9f376f4de7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 22:19:24 +0000 Subject: [PATCH 37/40] Bump System.Drawing.Common from 7.0.0 to 8.0.0 Bumps [System.Drawing.Common](https://github.com/dotnet/winforms) from 7.0.0 to 8.0.0. - [Release notes](https://github.com/dotnet/winforms/releases) - [Changelog](https://github.com/dotnet/winforms/blob/main/docs/release-activity.md) - [Commits](https://github.com/dotnet/winforms/commits/v8.0.0) --- updated-dependencies: - dependency-name: System.Drawing.Common dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .../Flow.Launcher.Infrastructure.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj index 2f5259039..8124a95de 100644 --- a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj +++ b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj @@ -58,7 +58,7 @@ - + From 6a302c928a3c15d5a97d00e69569413db7650f94 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 22:19:33 +0000 Subject: [PATCH 38/40] Bump Microsoft.NET.Test.Sdk from 17.7.2 to 17.8.0 Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.7.2 to 17.8.0. - [Release notes](https://github.com/microsoft/vstest/releases) - [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md) - [Commits](https://github.com/microsoft/vstest/compare/v17.7.2...v17.8.0) --- updated-dependencies: - dependency-name: Microsoft.NET.Test.Sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Flow.Launcher.Test/Flow.Launcher.Test.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Test/Flow.Launcher.Test.csproj b/Flow.Launcher.Test/Flow.Launcher.Test.csproj index c662fdeff..29414baa6 100644 --- a/Flow.Launcher.Test/Flow.Launcher.Test.csproj +++ b/Flow.Launcher.Test/Flow.Launcher.Test.csproj @@ -54,7 +54,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + \ No newline at end of file From a04bcce91e3dfbbfb98de891a118f0e1375c2a75 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 22:19:39 +0000 Subject: [PATCH 39/40] Bump Microsoft.Data.Sqlite from 7.0.13 to 8.0.0 Bumps [Microsoft.Data.Sqlite](https://github.com/dotnet/efcore) from 7.0.13 to 8.0.0. - [Release notes](https://github.com/dotnet/efcore/releases) - [Commits](https://github.com/dotnet/efcore/compare/v7.0.13...v8.0.0) --- updated-dependencies: - dependency-name: Microsoft.Data.Sqlite dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .../Flow.Launcher.Plugin.BrowserBookmark.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj index edaa3dd29..4ce8584fc 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj @@ -56,7 +56,7 @@ - + \ No newline at end of file From 6e385a3d7c622e438afd0747a690b11e634ab739 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sat, 25 Nov 2023 01:20:43 +0800 Subject: [PATCH 40/40] Revert "Bump System.Drawing.Common from 7.0.0 to 8.0.0" --- .../Flow.Launcher.Infrastructure.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj index 8124a95de..2f5259039 100644 --- a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj +++ b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj @@ -58,7 +58,7 @@ - +