diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml index 7f8557c28..f69f23f6b 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml @@ -11,6 +11,11 @@ Plugin Install Plugin Uninstall Install failed: unable to find the plugin.json metadata file from the new 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. + Plugin Update + diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs index 58ec5005f..43f92e7b9 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs @@ -42,9 +42,13 @@ namespace Flow.Launcher.Plugin.PluginsManager var pluginManager = new PluginsManager(Context, Settings); if (!string.IsNullOrEmpty(search) - && ($"{Settings.UninstallHotkey} ".StartsWith(search) || search.StartsWith($"{Settings.UninstallHotkey} "))) + && ($"{Settings.HotkeyUninstall} ".StartsWith(search) || search.StartsWith($"{Settings.HotkeyUninstall} "))) return pluginManager.RequestUninstall(search); - + + if (!string.IsNullOrEmpty(search) + && ($"{Settings.HotkeyUpdate} ".StartsWith(search) || search.StartsWith($"{Settings.HotkeyUpdate} "))) + return pluginManager.RequestUpdate(search); + return pluginManager.RequestInstallOrUpdate(search); } diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Models/UserPlugin.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/Models/UserPlugin.cs index 3bc44e0f6..c1af3014b 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Models/UserPlugin.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Models/UserPlugin.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - + namespace Flow.Launcher.Plugin.PluginsManager.Models { public class UserPlugin diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index 1b13dabf8..37051e4da 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -62,12 +62,82 @@ namespace Flow.Launcher.Plugin.PluginsManager Log.Exception("PluginsManager", "An error occured while downloading plugin", e, "PluginDownload"); } - Application.Current.Dispatcher.Invoke(() => Install(plugin, filePath)); + Application.Current.Dispatcher.Invoke(() => { Install(plugin, filePath); Context.API.RestartApp(); }); } - internal void Update(string search) + internal List RequestUpdate(string search) { + var autocompletedResults = AutoCompleteReturnAllResults(search, + Settings.HotkeyUpdate, + "Update", + "Select a plugin to update"); + if (autocompletedResults.Any()) + return autocompletedResults; + + var uninstallSearch = search.Replace(Settings.HotkeyUpdate, string.Empty).TrimStart(); + + + var resultsForUpdate = + from existingPlugin in Context.API.GetAllPlugins() + join pluginFromManifest in pluginsManifest.UserPlugins + on existingPlugin.Metadata.ID equals pluginFromManifest.ID + where existingPlugin.Metadata.Version != pluginFromManifest.Version + select + new + { + pluginFromManifest.Name, + pluginFromManifest.Author, + CurrentVersion = existingPlugin.Metadata.Version, + NewVersion = pluginFromManifest.Version, + existingPlugin.Metadata.IcoPath, + PluginExistingMetadata = existingPlugin.Metadata, + PluginNewUserPlugin = pluginFromManifest + }; + + if (!resultsForUpdate.Any()) + return new List { + new Result + { + Title = Context.API.GetTranslation("plugin_pluginsmanager_update_noresult_title"), + SubTitle = Context.API.GetTranslation("plugin_pluginsmanager_update_noresult_subtitle"), + IcoPath = icoPath + }}; + + + var results = resultsForUpdate + .Select(x => + new Result + { + Title = $"{x.Name} by {x.Author}", + SubTitle = $"Update from version {x.CurrentVersion} to {x.NewVersion}", + IcoPath = x.IcoPath, + Action = e => + { + string message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_prompt"), + x.Name, x.Author, + Environment.NewLine, Environment.NewLine); + + if (MessageBox.Show(message, Context.API.GetTranslation("plugin_pluginsmanager_update_title"), + MessageBoxButton.YesNo) == MessageBoxResult.Yes) + { + Uninstall(x.PluginExistingMetadata); + + var downloadToFilePath = Path.Combine(DataLocation.PluginsDirectory, $"{x.Name}-{x.NewVersion}.zip"); + Http.Download(x.PluginNewUserPlugin.UrlDownload, downloadToFilePath); + Install(x.PluginNewUserPlugin, downloadToFilePath); + + Context.API.RestartApp(); + + return true; + } + + return false; + } + }) + .ToList(); + + return Search(results, uninstallSearch); } internal bool PluginExists(string id) @@ -150,21 +220,19 @@ namespace Flow.Launcher.Plugin.PluginsManager string newPluginPath = Path.Combine(DataLocation.PluginsDirectory, $"{plugin.Name}-{plugin.Version}"); Directory.Move(pluginFolderPath, newPluginPath); - - Context.API.RestartApp(); } internal List RequestUninstall(string search) { var autocompletedResults = AutoCompleteReturnAllResults(search, - Settings.UninstallHotkey, + Settings.HotkeyUninstall, "Uninstall", "Select a plugin to uninstall"); if (autocompletedResults.Any()) return autocompletedResults; - var uninstallSearch = search.Replace(Settings.UninstallHotkey, string.Empty).TrimStart(); + var uninstallSearch = search.Replace(Settings.HotkeyUninstall, string.Empty).TrimStart(); var results= Context.API .GetAllPlugins() @@ -176,10 +244,21 @@ namespace Flow.Launcher.Plugin.PluginsManager IcoPath = x.Metadata.IcoPath, Action = e => { - Application.Current.MainWindow.Hide(); - Uninstall(x.Metadata); + string message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_uninstall_prompt"), + x.Metadata.Name, x.Metadata.Author, + Environment.NewLine, Environment.NewLine); - return true; + if (MessageBox.Show(message, Context.API.GetTranslation("plugin_pluginsmanager_uninstall_title"), + MessageBoxButton.YesNo) == MessageBoxResult.Yes) + { + Application.Current.MainWindow.Hide(); + Uninstall(x.Metadata); + Context.API.RestartApp(); + + return true; + } + + return false; } }) .ToList(); @@ -189,17 +268,8 @@ namespace Flow.Launcher.Plugin.PluginsManager private void Uninstall(PluginMetadata plugin) { - string message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_uninstall_prompt"), - plugin.Name, plugin.Author, - Environment.NewLine, Environment.NewLine); - - if (MessageBox.Show(message, Context.API.GetTranslation("plugin_pluginsmanager_uninstall_title"), - MessageBoxButton.YesNo) == MessageBoxResult.Yes) - { - using var _ = File.CreateText(Path.Combine(plugin.PluginDirectory, "NeedDelete.txt")); - - Context.API.RestartApp(); - } + // Marked for deletion. Will be deleted on next start up + using var _ = File.CreateText(Path.Combine(plugin.PluginDirectory, "NeedDelete.txt")); } private List AutoCompleteReturnAllResults(string search, string hotkey, string title, string subtitle) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Settings.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/Settings.cs index 0c647e6ae..e2e8d22e5 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Settings.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Settings.cs @@ -6,6 +6,8 @@ namespace Flow.Launcher.Plugin.PluginsManager { internal class Settings { - internal string UninstallHotkey { get; set; } = "uninstall"; + internal string HotkeyUninstall { get; set; } = "uninstall"; + + internal string HotkeyUpdate { get; set; } = "update"; } }