From 4c5eae895b83c87ed56555765cc798d4624702a8 Mon Sep 17 00:00:00 2001
From: Florian Grabmeier
Date: Wed, 1 Nov 2023 17:35:00 +0100
Subject: [PATCH 001/161] Implement CloseShellAfterPress (no logic)
Signed-off-by: Florian Grabmeier
---
Plugins/Flow.Launcher.Plugin.Shell/Languages/de.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Shell/Languages/en.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Shell/Main.cs | 12 ++++++++++--
Plugins/Flow.Launcher.Plugin.Shell/Settings.cs | 2 ++
Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml | 6 ++++++
.../Flow.Launcher.Plugin.Shell/ShellSetting.xaml.cs | 12 ++++++++++++
6 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/de.xaml
index 3fa7c64fa..8aae3a5fd 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/de.xaml
@@ -2,6 +2,7 @@
Ersetzt Win+R
+ Schließe die Kommandozeilte nachdem eine Taste gedrückt wurde
Schließe die Kommandozeilte nicht nachdem der Befehl ausgeführt wurde
Immer als Administrator ausführen
Als anderer Benutzer ausführen
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/en.xaml
index 9a692cac3..88fa264d0 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/en.xaml
@@ -3,6 +3,7 @@
xmlns:system="clr-namespace:System;assembly=mscorlib">
Replace Win+R
+ Close Command Prompt after pressing any key
Do not close Command Prompt after command execution
Always run as administrator
Run as different user
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
index 66917d594..b963302db 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -187,7 +187,7 @@ namespace Flow.Launcher.Plugin.Shell
return history.ToList();
}
- private ProcessStartInfo PrepareProcessStartInfo(string command, bool runAsAdministrator = false)
+ private ProcessStartInfo PrepareProcessStartInfo(string command, bool runAsAdministrator = false) //TODO: implement logic for CloseCMDAfterPress
{
command = command.Trim();
command = Environment.ExpandEnvironmentVariables(command);
@@ -203,7 +203,7 @@ namespace Flow.Launcher.Plugin.Shell
case Shell.Cmd:
{
info.FileName = "cmd.exe";
- info.Arguments = $"{(_settings.LeaveShellOpen ? "/k" : "/c")} {command}";
+ info.Arguments = $"{(_settings.LeaveShellOpen ? "/k" : "/c")} {command} {(_settings.CloseShellAfterPress ? "& pause" : "")}";
//// Use info.Arguments instead of info.ArgumentList to enable users better control over the arguments they are writing.
//// Previous code using ArgumentList, commands needed to be separated correctly:
@@ -233,6 +233,10 @@ namespace Flow.Launcher.Plugin.Shell
{
info.ArgumentList.Add("-Command");
info.ArgumentList.Add(command);
+ if (_settings.CloseShellAfterPress)
+ {
+ info.ArgumentList.Add("; pause");
+ }
}
break;
}
@@ -246,6 +250,10 @@ namespace Flow.Launcher.Plugin.Shell
}
info.ArgumentList.Add("-Command");
info.ArgumentList.Add(command);
+ if (_settings.CloseShellAfterPress)
+ {
+ info.ArgumentList.Add("; pause");
+ }
break;
}
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Settings.cs b/Plugins/Flow.Launcher.Plugin.Shell/Settings.cs
index 47b46055c..6f47d5d17 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Settings.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Settings.cs
@@ -7,6 +7,8 @@ namespace Flow.Launcher.Plugin.Shell
public Shell Shell { get; set; } = Shell.Cmd;
public bool ReplaceWinR { get; set; } = false;
+
+ public bool CloseShellAfterPress { get; set; } = false;
public bool LeaveShellOpen { get; set; }
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml b/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml
index 240bda953..960272f0f 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml
@@ -22,6 +22,12 @@
Margin="10,10,5,5"
HorizontalAlignment="Left"
Content="{DynamicResource flowlauncher_plugin_cmd_relace_winr}" />
+
+ {
+ _settings.CloseShellAfterPress = true;
+ };
+
+ CloseShellAfterPress.Unchecked += (o, e) =>
+ {
+ _settings.CloseShellAfterPress = false;
+ };
+
LeaveShellOpen.Checked += (o, e) =>
{
_settings.LeaveShellOpen = true;
From 06211a181e9e7d2760456c485b1a0c45cde20a11 Mon Sep 17 00:00:00 2001
From: Florian Grabmeier
Date: Sun, 5 Nov 2023 14:30:12 +0100
Subject: [PATCH 002/161] Add more language support for new shell option
Signed-off-by: Florian Grabmeier
---
Plugins/Flow.Launcher.Plugin.Shell/Languages/ar.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Shell/Languages/cs.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Shell/Languages/da.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Shell/Languages/es-419.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Shell/Languages/es.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Shell/Languages/fr.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Shell/Languages/it.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Shell/Languages/ja.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Shell/Languages/ko.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Shell/Languages/nb.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Shell/Languages/nl.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Shell/Languages/pl.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Shell/Languages/pt-br.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Shell/Languages/pt-pt.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Shell/Languages/ru.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Shell/Languages/sk.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Shell/Languages/sr.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Shell/Languages/tr.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Shell/Languages/uk-UA.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Shell/Languages/zh-cn.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Shell/Languages/zh-tw.xaml | 1 +
21 files changed, 21 insertions(+)
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/ar.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/ar.xaml
index 0ccfd8c9a..77fbcf8d4 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/ar.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/ar.xaml
@@ -2,6 +2,7 @@
Replace Win+R
+ Close Command Prompt after pressing any key
Do not close Command Prompt after command execution
Always run as administrator
Run as different user
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/cs.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/cs.xaml
index 2c764d845..30d15ec76 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/cs.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/cs.xaml
@@ -2,6 +2,7 @@
Nahradit Win+R
+ Po stisknutí libovolné klávesy zavřít příkazový řádek
Po dokončení příkazu příkazový řádek nezavírejte
Vždy spustit jako správce
Spustit jako jiný uživatel
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/da.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/da.xaml
index 0ccfd8c9a..77fbcf8d4 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/da.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/da.xaml
@@ -2,6 +2,7 @@
Replace Win+R
+ Close Command Prompt after pressing any key
Do not close Command Prompt after command execution
Always run as administrator
Run as different user
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/es-419.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/es-419.xaml
index 284a2a0e6..122198357 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/es-419.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/es-419.xaml
@@ -2,6 +2,7 @@
Reemplazar Win+R
+ Cerrar Símbolo del sistema después de pulsar cualquier tecla
No cerrar Símbolo del Sistema tras ejecutar el comando
Siempre ejecutar como administrador
Ejecutar como otro usuario
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/es.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/es.xaml
index 8bf1a2c11..ff01f30d6 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/es.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/es.xaml
@@ -2,6 +2,7 @@
Reemplazar Win+R
+ Cerrar Símbolo del sistema después de pulsar cualquier tecla
No cerrar el símbolo del sistema después de la ejecución del comando
Ejecutar siempre como administrador
Ejecutar como usuario diferente
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/fr.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/fr.xaml
index d08efb9b8..438f8cc8f 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/fr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/fr.xaml
@@ -2,6 +2,7 @@
Remplacer Win+R
+ Fermer l'invite de commande après avoir appuyé sur n'importe quelle touche
Ne pas fermer l'invite de commandes après l'exécution de la commande
Toujours exécuter en tant qu'administrateur
Exécuter en tant qu'utilisateur différent
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/it.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/it.xaml
index de40b0c47..fa7df2c07 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/it.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/it.xaml
@@ -2,6 +2,7 @@
Sostituisci Win+R
+ Chiudere il prompt dei comandi dopo aver premuto qualsiasi tasto
Non chiudere il prompt dei comandi dopo l'esecuzione dei comandi
Esegui sempre come amministratore
Esegui come utente differente
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/ja.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/ja.xaml
index 0ccfd8c9a..77fbcf8d4 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/ja.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/ja.xaml
@@ -2,6 +2,7 @@
Replace Win+R
+ Close Command Prompt after pressing any key
Do not close Command Prompt after command execution
Always run as administrator
Run as different user
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/ko.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/ko.xaml
index 014a46dfc..9531fe832 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/ko.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/ko.xaml
@@ -2,6 +2,7 @@
Win+R 단축키 대체
+ 아무 키나 누른 후 명령 프롬프트 닫기
명령 실행 후 명령 프롬프트를 닫지 않음
항상 관리자 권한으로 실행
다른 유저 권한으로 실행
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/nb.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/nb.xaml
index 0ccfd8c9a..77fbcf8d4 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/nb.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/nb.xaml
@@ -2,6 +2,7 @@
Replace Win+R
+ Close Command Prompt after pressing any key
Do not close Command Prompt after command execution
Always run as administrator
Run as different user
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/nl.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/nl.xaml
index 0ccfd8c9a..77fbcf8d4 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/nl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/nl.xaml
@@ -2,6 +2,7 @@
Replace Win+R
+ Close Command Prompt after pressing any key
Do not close Command Prompt after command execution
Always run as administrator
Run as different user
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/pl.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/pl.xaml
index c851be93b..d83386d2d 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/pl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/pl.xaml
@@ -2,6 +2,7 @@
Zastąp Win+R
+ Zamykanie wiersza polecenia po naciśnięciu dowolnego klawisza
Nie zamykaj wiersza poleceń po wykonaniu polecenia
Always run as administrator
Run as different user
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/pt-br.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/pt-br.xaml
index 6a0a3c8fd..ef0223dd9 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/pt-br.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/pt-br.xaml
@@ -2,6 +2,7 @@
Substituir Win+R
+ Fechar o Prompt de Comando após pressionar qualquer tecla
Não feche o Prompt de Comando após a execução do comando
Sempre executar como administrador
Run as different user
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/pt-pt.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/pt-pt.xaml
index 33d7f35a6..f91fcd888 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/pt-pt.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/pt-pt.xaml
@@ -2,6 +2,7 @@
Substituir Win+R
+ Fechar linha de comandos depois de pressionar qualquer tecla
Não fechar linha de comandos depois de executar o comando
Executar sempre como administrador
Executar com outro utilizador
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/ru.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/ru.xaml
index 0ccfd8c9a..77fbcf8d4 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/ru.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/ru.xaml
@@ -2,6 +2,7 @@
Replace Win+R
+ Close Command Prompt after pressing any key
Do not close Command Prompt after command execution
Always run as administrator
Run as different user
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/sk.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/sk.xaml
index 0b76303df..76221a0ef 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/sk.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/sk.xaml
@@ -2,6 +2,7 @@
Nahradiť Win+R
+ Zatvoriť príkazový riadok po stlačení ľubovoľnej klávesy
Nezatvárať príkazový riadok po dokončení príkazu
Spustiť vždy ako správca
Spustiť ako iný používateľ
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/sr.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/sr.xaml
index 0ccfd8c9a..77fbcf8d4 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/sr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/sr.xaml
@@ -2,6 +2,7 @@
Replace Win+R
+ Close Command Prompt after pressing any key
Do not close Command Prompt after command execution
Always run as administrator
Run as different user
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/tr.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/tr.xaml
index c6433cef1..437e25f18 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/tr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/tr.xaml
@@ -2,6 +2,7 @@
Win+R kısayolunu kullan
+ Herhangi bir tuşa basıldıktan sonra komut istemini kapat
Çalıştırma sona erdikten sonra komut istemini kapatma
Always run as administrator
Run as different user
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/uk-UA.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/uk-UA.xaml
index 0ccfd8c9a..77fbcf8d4 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/uk-UA.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/uk-UA.xaml
@@ -2,6 +2,7 @@
Replace Win+R
+ Close Command Prompt after pressing any key
Do not close Command Prompt after command execution
Always run as administrator
Run as different user
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/zh-cn.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/zh-cn.xaml
index 916542c3a..07e8142d7 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/zh-cn.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/zh-cn.xaml
@@ -2,6 +2,7 @@
替换 Win+R
+ 按任意键后关闭命令窗口
执行后不关闭命令窗口
始终以管理员身份运行
以其他用户身份运行
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/zh-tw.xaml
index 7ddc58918..58e1a11f8 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/zh-tw.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/zh-tw.xaml
@@ -2,6 +2,7 @@
取代 Win+R
+ 按任意鍵後關閉命令提示字元視窗
執行後不關閉命令提示字元視窗
一律以系統管理員身分執行
Run as different user
From 276c6eda6b0e1cd648278eeebcf53ac22540b9d5 Mon Sep 17 00:00:00 2001
From: Florian Grabmeier
Date: Sat, 11 Nov 2023 12:36:09 +0100
Subject: [PATCH 003/161] Fix overlapping layout
Signed-off-by: Florian Grabmeier
---
Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml b/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml
index 960272f0f..2f02ef723 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml
@@ -15,6 +15,7 @@
+
CMD
@@ -50,7 +51,7 @@
Pwsh
RunCommand
-
+
Date: Sat, 11 Nov 2023 13:47:22 +0100
Subject: [PATCH 004/161] Disable conflicting options
Signed-off-by: Florian Grabmeier
---
Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml.cs | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml.cs
index c89e481d7..24365f2aa 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml.cs
@@ -43,21 +43,27 @@ namespace Flow.Launcher.Plugin.Shell
CloseShellAfterPress.Checked += (o, e) =>
{
_settings.CloseShellAfterPress = true;
+ LeaveShellOpen.IsChecked = false;
+ LeaveShellOpen.IsEnabled = false;
};
CloseShellAfterPress.Unchecked += (o, e) =>
{
_settings.CloseShellAfterPress = false;
+ LeaveShellOpen.IsEnabled = true;
};
LeaveShellOpen.Checked += (o, e) =>
{
_settings.LeaveShellOpen = true;
+ CloseShellAfterPress.IsChecked = false;
+ CloseShellAfterPress.IsEnabled = false;
};
LeaveShellOpen.Unchecked += (o, e) =>
{
_settings.LeaveShellOpen = false;
+ CloseShellAfterPress.IsEnabled = true;
};
AlwaysRunAsAdministrator.Checked += (o, e) =>
From ab7685e9ea9bf58a4f1bf3c519ca7cebd1ca1880 Mon Sep 17 00:00:00 2001
From: Garulf <535299+Garulf@users.noreply.github.com>
Date: Sat, 18 Nov 2023 21:45:06 -0500
Subject: [PATCH 005/161] Show a result error instead of popping up dialog
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index f8c9a3f17..31ded2baf 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -210,7 +210,18 @@ namespace Flow.Launcher.Core.Plugin
}
catch (Exception e)
{
- throw new FlowPluginException(metadata, e);
+ Result r = new()
+ {
+ Title = $"{metadata.Name}: {e.GetType().Name}",
+ SubTitle = "ERROR: There was an error loading this plugin!",
+ IcoPath = "Images\\app_error.png",
+ PluginDirectory = metadata.PluginDirectory,
+ ActionKeywordAssigned = query.ActionKeyword,
+ PluginID = metadata.ID,
+ OriginQuery = query,
+ Action = _ => { throw new FlowPluginException(metadata, e);}
+ };
+ results.Add(r);
}
return results;
}
From 57b78b5797850c04317f2b6e313ded170a5bc16a Mon Sep 17 00:00:00 2001
From: Florian Grabmeier
Date: Sun, 19 Nov 2023 17:07:29 +0100
Subject: [PATCH 006/161] Fix merge
Signed-off-by: Florian Grabmeier
---
.../Languages/en.xaml | 2 ++
.../PluginsManager.cs | 17 +++++++++++++++++
2 files changed, 19 insertions(+)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
index 42a1ac9b8..cc2360edf 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
@@ -30,6 +30,8 @@
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.
+ Update All Plugins
+ Would you like to update all 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)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 00f77f872..03802ff9e 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -296,6 +296,23 @@ namespace Flow.Launcher.Plugin.PluginsManager
}
});
+ if (resultsForUpdate.Count() > 1)
+ {
+ var updateAllResult = new Result
+ {
+ Title = Context.API.GetTranslation("plugin_pluginsmanager_update_all_title"),
+ SubTitle = Context.API.GetTranslation("plugin_pluginsmanager_update_all_subtitle"),
+ IcoPath = icoPath,
+ Action = e =>
+ {
+ // TODO: logic here
+ return true;
+ },
+ ContextData = new UserPlugin()
+ };
+ results = results.Prepend(updateAllResult);
+ }
+
return Search(results, search);
}
From cb59b6b2645753847ed2e91d8dd6044455bf8b0f Mon Sep 17 00:00:00 2001
From: Florian Grabmeier
Date: Wed, 22 Nov 2023 14:25:17 +0100
Subject: [PATCH 007/161] Implemet basic update all logic
Signed-off-by: Florian Grabmeier
---
.../PluginsManager.cs | 77 +++++++++++++++++--
1 file changed, 71 insertions(+), 6 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 03802ff9e..159950ac2 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -7,6 +7,7 @@ using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin.SharedCommands;
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
@@ -167,7 +168,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
Log.Exception("PluginsManager", "An error occurred while downloading plugin", e);
return;
}
-
+
if (Settings.AutoRestartAfterChanging)
{
Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_installing_plugin"),
@@ -292,7 +293,8 @@ namespace Flow.Launcher.Plugin.PluginsManager
ContextData =
new UserPlugin
{
- Website = x.PluginNewUserPlugin.Website, UrlSourceCode = x.PluginNewUserPlugin.UrlSourceCode
+ Website = x.PluginNewUserPlugin.Website,
+ UrlSourceCode = x.PluginNewUserPlugin.UrlSourceCode
}
});
@@ -305,8 +307,70 @@ namespace Flow.Launcher.Plugin.PluginsManager
IcoPath = icoPath,
Action = e =>
{
- // TODO: logic here
- return true;
+ string message;
+ //TODO: display all plugins to be updated in the message
+ if (/*Settings.AutoRestartAfterChanging*/ false) // TODO: remove false
+ {
+ message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_subtitle"), "FlowLauncher will restart after updating all plugins.",
+ Environment.NewLine, Environment.NewLine);
+ }
+ else
+ {
+ message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_subtitle"),
+ Environment.NewLine);
+ }
+ if (MessageBox.Show(message,
+ Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
+ MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+ {
+ Debug.Print("Looping through plugins to update");
+ foreach (var plugin in resultsForUpdate)
+ {
+ Debug.Print($"Updating {plugin.Name}");
+ var downloadToFilePath = Path.Combine(Path.GetTempPath(),
+ $"{plugin.Name}-{plugin.NewVersion}.zip");
+
+ _ = Task.Run(async delegate
+ {
+ if (File.Exists(downloadToFilePath))
+ {
+ File.Delete(downloadToFilePath);
+ }
+
+ await Http.DownloadAsync(plugin.PluginNewUserPlugin.UrlDownload, downloadToFilePath)
+ .ConfigureAwait(false);
+
+ PluginManager.UpdatePlugin(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin, downloadToFilePath);
+
+ //TODO: fix
+ // 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 {plugin.Name}",
+ t.Exception.InnerException);
+ Context.API.ShowMsg(
+ Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
+ string.Format(
+ Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"),
+ plugin.Name));
+ }, TaskContinuationOptions.OnlyOnFaulted);
+ }
+ Debug.Print("Finished updating all plugins");
+ return true; // User confirmed to update all plugins
+ }
+ return false; //user cancelled
},
ContextData = new UserPlugin()
};
@@ -454,7 +518,8 @@ namespace Flow.Launcher.Plugin.PluginsManager
string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_duplicate"), plugin.Name));
Log.Exception("Flow.Launcher.Plugin.PluginsManager", e.Message, e);
}
- catch (ArgumentException 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);
@@ -518,7 +583,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
{
try
{
- PluginManager.UninstallPlugin(plugin, removeSettings:true);
+ PluginManager.UninstallPlugin(plugin, removeSettings: true);
}
catch (ArgumentException e)
{
From 8180c1cd40ea5410a3a3b6f5df8ddf34dc690470 Mon Sep 17 00:00:00 2001
From: Florian Grabmeier
Date: Wed, 22 Nov 2023 14:49:43 +0100
Subject: [PATCH 008/161] Display correct messages
Signed-off-by: Florian Grabmeier
---
.../Languages/en.xaml | 2 +-
.../PluginsManager.cs | 46 +++++++++----------
2 files changed, 22 insertions(+), 26 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
index cc2360edf..99daa40f3 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
@@ -30,7 +30,7 @@
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.
- Update All Plugins
+ Update all plugins
Would you like to update all plugins?
Plugin {0} successfully updated. Restarting Flow, please wait...
Installing from an unknown source
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 159950ac2..57f252e4c 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -308,25 +308,21 @@ namespace Flow.Launcher.Plugin.PluginsManager
Action = e =>
{
string message;
- //TODO: display all plugins to be updated in the message
- if (/*Settings.AutoRestartAfterChanging*/ false) // TODO: remove false
+ if (Settings.AutoRestartAfterChanging)
{
- message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_subtitle"), "FlowLauncher will restart after updating all plugins.",
- Environment.NewLine, Environment.NewLine);
+ message = "Would you like to update all plugins?\nFlowLauncher will restart after updating all plugins.\n";
}
else
{
- message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_subtitle"),
- Environment.NewLine);
+ message = "Would you like to update all plugins?\nFlowLauncher will restart after updating all plugins.\n";
}
+
if (MessageBox.Show(message,
Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
- Debug.Print("Looping through plugins to update");
foreach (var plugin in resultsForUpdate)
{
- Debug.Print($"Updating {plugin.Name}");
var downloadToFilePath = Path.Combine(Path.GetTempPath(),
$"{plugin.Name}-{plugin.NewVersion}.zip");
@@ -342,20 +338,6 @@ namespace Flow.Launcher.Plugin.PluginsManager
PluginManager.UpdatePlugin(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin, downloadToFilePath);
- //TODO: fix
- // 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 {plugin.Name}",
@@ -367,10 +349,24 @@ namespace Flow.Launcher.Plugin.PluginsManager
plugin.Name));
}, TaskContinuationOptions.OnlyOnFaulted);
}
- Debug.Print("Finished updating all plugins");
- return true; // User confirmed to update all plugins
+
+ if (Settings.AutoRestartAfterChanging)
+ {
+ Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
+ string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_success_restart"),
+ "all"));
+ 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"),
+ "all"));
+ }
+
+ return true;
}
- return false; //user cancelled
+ return false;
},
ContextData = new UserPlugin()
};
From a3b9a4f9d01e64c5deb6b9425d07d58426fe86c5 Mon Sep 17 00:00:00 2001
From: Florian Grabmeier
Date: Wed, 22 Nov 2023 14:55:53 +0100
Subject: [PATCH 009/161] Run updates in parallel
Signed-off-by: Florian Grabmeier
---
.../PluginsManager.cs | 41 +++++++++----------
1 file changed, 20 insertions(+), 21 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 57f252e4c..e57530270 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -321,34 +321,33 @@ namespace Flow.Launcher.Plugin.PluginsManager
Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
- foreach (var plugin in resultsForUpdate)
+ Parallel.ForEach(resultsForUpdate, plugin =>
{
- var downloadToFilePath = Path.Combine(Path.GetTempPath(),
- $"{plugin.Name}-{plugin.NewVersion}.zip");
+ var downloadToFilePath = Path.Combine(Path.GetTempPath(), $"{plugin.Name}-{plugin.NewVersion}.zip");
_ = Task.Run(async delegate
+ {
+ if (File.Exists(downloadToFilePath))
{
- if (File.Exists(downloadToFilePath))
- {
- File.Delete(downloadToFilePath);
- }
+ File.Delete(downloadToFilePath);
+ }
- await Http.DownloadAsync(plugin.PluginNewUserPlugin.UrlDownload, downloadToFilePath)
- .ConfigureAwait(false);
+ await Http.DownloadAsync(plugin.PluginNewUserPlugin.UrlDownload, downloadToFilePath)
+ .ConfigureAwait(false);
- PluginManager.UpdatePlugin(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin, downloadToFilePath);
+ PluginManager.UpdatePlugin(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin, downloadToFilePath);
- }).ContinueWith(t =>
- {
- Log.Exception("PluginsManager", $"Update failed for {plugin.Name}",
- t.Exception.InnerException);
- Context.API.ShowMsg(
- Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
- string.Format(
- Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"),
- plugin.Name));
- }, TaskContinuationOptions.OnlyOnFaulted);
- }
+ }).ContinueWith(t =>
+ {
+ Log.Exception("PluginsManager", $"Update failed for {plugin.Name}",
+ t.Exception.InnerException);
+ Context.API.ShowMsg(
+ Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
+ string.Format(
+ Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"),
+ plugin.Name));
+ }, TaskContinuationOptions.OnlyOnFaulted);
+ });
if (Settings.AutoRestartAfterChanging)
{
From 4ed1c3c442e724b17551ad3ad3095cd21d7cd599 Mon Sep 17 00:00:00 2001
From: Florian Grabmeier
Date: Thu, 23 Nov 2023 08:53:47 +0100
Subject: [PATCH 010/161] Update prompts
Signed-off-by: Florian Grabmeier
---
.../Languages/en.xaml | 4 ++++
.../PluginsManager.cs | 14 ++++++++------
2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
index 99daa40f3..004d81e8b 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
@@ -32,6 +32,9 @@
Please check if you can connect to github.com. This error means you may not be able to install or update plugins.
Update all plugins
Would you like to update all plugins?
+ Would you like to update {0} plugins?{1}FlowLauncher will restart after updating all plugins.
+ Would you like to update {0} plugins?
+ {0} plugins successfully updated. Restarting Flow, please wait...
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)
@@ -39,6 +42,7 @@
Plugin {0} successfully installed. Please restart Flow.
Plugin {0} successfully uninstalled. Please restart Flow.
Plugin {0} successfully updated. Please restart Flow.
+ {0} plugins successfully updated. Please restart Flow.
Plugin {0} has already been modified. Please restart Flow before making any further changes.
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index e57530270..88ad8ed32 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -310,11 +310,13 @@ namespace Flow.Launcher.Plugin.PluginsManager
string message;
if (Settings.AutoRestartAfterChanging)
{
- message = "Would you like to update all plugins?\nFlowLauncher will restart after updating all plugins.\n";
+ message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_prompt"),
+ resultsForUpdate.Count(), Environment.NewLine);
}
else
{
- message = "Would you like to update all plugins?\nFlowLauncher will restart after updating all plugins.\n";
+ message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_prompt_no_restart"),
+ resultsForUpdate.Count());
}
if (MessageBox.Show(message,
@@ -352,15 +354,15 @@ namespace Flow.Launcher.Plugin.PluginsManager
if (Settings.AutoRestartAfterChanging)
{
Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
- string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_success_restart"),
- "all"));
+ string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_success_restart"),
+ resultsForUpdate.Count()));
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"),
- "all"));
+ string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_success_no_restart"),
+ resultsForUpdate.Count()));
}
return true;
From a84e509aabbb726c81bf547d0ea48d35df933caa Mon Sep 17 00:00:00 2001
From: Garulf <535299+Garulf@users.noreply.github.com>
Date: Fri, 24 Nov 2023 13:15:17 -0500
Subject: [PATCH 011/161] Use proper error icon constant
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 31ded2baf..a297de63e 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -214,7 +214,7 @@ namespace Flow.Launcher.Core.Plugin
{
Title = $"{metadata.Name}: {e.GetType().Name}",
SubTitle = "ERROR: There was an error loading this plugin!",
- IcoPath = "Images\\app_error.png",
+ IcoPath = Flow.Launcher.Infrastructure.Constant.ErrorIcon,
PluginDirectory = metadata.PluginDirectory,
ActionKeywordAssigned = query.ActionKeyword,
PluginID = metadata.ID,
From 0e226d7a5b60f61b5bc68d6c72647bd1050334f1 Mon Sep 17 00:00:00 2001
From: Garulf <535299+Garulf@users.noreply.github.com>
Date: Fri, 24 Nov 2023 13:15:29 -0500
Subject: [PATCH 012/161] Reword title and subtitle
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index a297de63e..7454b5a94 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -212,8 +212,8 @@ namespace Flow.Launcher.Core.Plugin
{
Result r = new()
{
- Title = $"{metadata.Name}: {e.GetType().Name}",
- SubTitle = "ERROR: There was an error loading this plugin!",
+ Title = $"{metadata.Name}: Failed to respond!",
+ SubTitle = "Select this result for more info",
IcoPath = Flow.Launcher.Infrastructure.Constant.ErrorIcon,
PluginDirectory = metadata.PluginDirectory,
ActionKeywordAssigned = query.ActionKeyword,
From f684883d7250996dd8656e40b711697d875ad4d8 Mon Sep 17 00:00:00 2001
From: Garulf <535299+Garulf@users.noreply.github.com>
Date: Fri, 24 Nov 2023 13:15:58 -0500
Subject: [PATCH 013/161] Insure result is never in front of relevant results
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 7454b5a94..eec906807 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -219,7 +219,8 @@ namespace Flow.Launcher.Core.Plugin
ActionKeywordAssigned = query.ActionKeyword,
PluginID = metadata.ID,
OriginQuery = query,
- Action = _ => { throw new FlowPluginException(metadata, e);}
+ Action = _ => { throw new FlowPluginException(metadata, e);},
+ Score = -100
};
results.Add(r);
}
From 44fb863f075a4227b3d4b026340ab9d90040b270 Mon Sep 17 00:00:00 2001
From: Hongtao Zhang
Date: Sun, 26 Nov 2023 09:33:34 -0600
Subject: [PATCH 014/161] minor fix jsonrpc errorstream and expect.txt
---
.github/actions/spelling/expect.txt | 4 ----
Flow.Launcher.Core/Plugin/ProcessStreamPluginV2.cs | 4 +++-
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt
index d0fee9559..f2be7fb3b 100644
--- a/.github/actions/spelling/expect.txt
+++ b/.github/actions/spelling/expect.txt
@@ -1,7 +1,6 @@
crowdin
DWM
workflows
-Wpf
wpf
actionkeyword
stackoverflow
@@ -20,9 +19,7 @@ Prioritise
Segoe
Google
Customise
-UWP
uwp
-Uwp
Bokmal
Bokm
uninstallation
@@ -61,7 +58,6 @@ popup
ptr
pluginindicator
TobiasSekan
-Img
img
resx
bak
diff --git a/Flow.Launcher.Core/Plugin/ProcessStreamPluginV2.cs b/Flow.Launcher.Core/Plugin/ProcessStreamPluginV2.cs
index 24d06d975..a476f06e9 100644
--- a/Flow.Launcher.Core/Plugin/ProcessStreamPluginV2.cs
+++ b/Flow.Launcher.Core/Plugin/ProcessStreamPluginV2.cs
@@ -17,7 +17,7 @@ namespace Flow.Launcher.Core.Plugin
protected abstract ProcessStartInfo StartInfo { get; set; }
- public Process ClientProcess { get; set; }
+ protected Process ClientProcess { get; set; }
public override async Task InitAsync(PluginInitContext context)
{
@@ -33,6 +33,8 @@ namespace Flow.Launcher.Core.Plugin
SetupPipe(ClientProcess);
+ ErrorStream = ClientProcess.StandardError;
+
await base.InitAsync(context);
}
From 1bd16cccaf67ceeafb6bf76febfd2348a2e0fcd4 Mon Sep 17 00:00:00 2001
From: Hongtao Zhang
Date: Sun, 26 Nov 2023 09:37:43 -0600
Subject: [PATCH 015/161] remove duplicate expect
---
.github/actions/spelling/expect.txt | 2 --
1 file changed, 2 deletions(-)
diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt
index f2be7fb3b..0d4dde36b 100644
--- a/.github/actions/spelling/expect.txt
+++ b/.github/actions/spelling/expect.txt
@@ -74,7 +74,6 @@ WCA_ACCENT_POLICY
HGlobal
dopusrt
firefox
-Firefox
msedge
svgc
ime
@@ -83,7 +82,6 @@ txb
btn
otf
searchplugin
-Noresult
wpftk
mkv
flac
From 86b81f16e46089cb1976d1bc05712b9201225765 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 4 Dec 2023 22:58:51 +0000
Subject: [PATCH 016/161] Bump actions/setup-dotnet from 3 to 4
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 3 to 4.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](https://github.com/actions/setup-dotnet/compare/v3...v4)
---
updated-dependencies:
- dependency-name: actions/setup-dotnet
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot]
---
.github/workflows/default_plugins.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/default_plugins.yml b/.github/workflows/default_plugins.yml
index 8000c5456..a2283defe 100644
--- a/.github/workflows/default_plugins.yml
+++ b/.github/workflows/default_plugins.yml
@@ -13,7 +13,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Setup .NET
- uses: actions/setup-dotnet@v3
+ uses: actions/setup-dotnet@v4
with:
dotnet-version: 7.0.x
From 7a603f5504b22edd4b959a7b81fef5ff47afc692 Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Wed, 6 Dec 2023 22:42:24 +0800
Subject: [PATCH 017/161] Fix spell check
- fix crash
- fix missing dict
---
.github/actions/spelling/expect.txt | 4 +++-
.github/actions/spelling/patterns.txt | 3 +++
.github/workflows/spelling.yml | 7 +++----
3 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt
index 0d4dde36b..8e29be550 100644
--- a/.github/actions/spelling/expect.txt
+++ b/.github/actions/spelling/expect.txt
@@ -102,4 +102,6 @@ Preinstalled
errormetadatafile
noresult
pluginsmanager
-alreadyexists
\ No newline at end of file
+alreadyexists
+JsonRPC
+JsonRPCV2
diff --git a/.github/actions/spelling/patterns.txt b/.github/actions/spelling/patterns.txt
index 903714aef..f29f57ad5 100644
--- a/.github/actions/spelling/patterns.txt
+++ b/.github/actions/spelling/patterns.txt
@@ -118,3 +118,6 @@
# UWP
[Uu][Ww][Pp]
+
+# version suffix v#
+(?:(?<=[A-Z]{2})V|(?<=[a-z]{2}|[A-Z]{2})v)\d+(?:\b|(?=[a-zA-Z_]))
diff --git a/.github/workflows/spelling.yml b/.github/workflows/spelling.yml
index 97d3cccb3..7aaa9296a 100644
--- a/.github/workflows/spelling.yml
+++ b/.github/workflows/spelling.yml
@@ -73,7 +73,7 @@ jobs:
steps:
- name: check-spelling
id: spelling
- uses: check-spelling/check-spelling@v0.0.22
+ uses: check-spelling/check-spelling@prerelease
with:
suppress_push_for_open_pull_request: 1
checkout: true
@@ -91,10 +91,9 @@ jobs:
extra_dictionaries:
cspell:software-terms/dict/softwareTerms.txt
cspell:win32/src/win32.txt
- cspell:php/src/php.txt
cspell:filetypes/filetypes.txt
cspell:csharp/csharp.txt
- cspell:dotnet/src/dotnet.txt
+ cspell:dotnet/dict/dotnet.txt
cspell:python/src/common/extra.txt
cspell:python/src/python/python-lib.txt
cspell:aws/aws.txt
@@ -130,7 +129,7 @@ jobs:
if: (success() || failure()) && needs.spelling.outputs.followup && contains(github.event_name, 'pull_request')
steps:
- name: comment
- uses: check-spelling/check-spelling@v0.0.22
+ uses: check-spelling/check-spelling@prerelease
with:
checkout: true
spell_check_this: check-spelling/spell-check-this@main
From a9e1cdffd51a2041953f11f6a279ab5bef437152 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Thu, 7 Dec 2023 22:15:29 +0000
Subject: [PATCH 018/161] Bump actions/stale from 8 to 9
Bumps [actions/stale](https://github.com/actions/stale) from 8 to 9.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v8...v9)
---
updated-dependencies:
- dependency-name: actions/stale
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot]
---
.github/workflows/stale.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
index caac10c93..dd3fb2fca 100644
--- a/.github/workflows/stale.yml
+++ b/.github/workflows/stale.yml
@@ -13,7 +13,7 @@ jobs:
issues: write
pull-requests: write
steps:
- - uses: actions/stale@v8
+ - uses: actions/stale@v9
with:
stale-issue-message: 'This issue is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 5 days.'
days-before-stale: 45
From bdc9d02f93021c0aaf107638d1d4a2ddbb76650d Mon Sep 17 00:00:00 2001
From: Hongtao Zhang
Date: Sun, 10 Dec 2023 02:26:43 -0600
Subject: [PATCH 019/161] update StreamJsonRPC, use System.Text.Json and apply
serialization Option to the formatter; fix empty setting still trigger
setting initialization
---
Flow.Launcher.Core/Flow.Launcher.Core.csproj | 2 +-
.../Plugin/JsonRPCPluginSettings.cs | 52 +++++++++----------
Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs | 8 ++-
3 files changed, 28 insertions(+), 34 deletions(-)
diff --git a/Flow.Launcher.Core/Flow.Launcher.Core.csproj b/Flow.Launcher.Core/Flow.Launcher.Core.csproj
index 312dfdd9e..5cd09d407 100644
--- a/Flow.Launcher.Core/Flow.Launcher.Core.csproj
+++ b/Flow.Launcher.Core/Flow.Launcher.Core.csproj
@@ -57,7 +57,7 @@
-
+
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
index 3ffac1343..3848af6a4 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -15,11 +15,11 @@ namespace Flow.Launcher.Core.Plugin
public required string SettingPath { get; init; }
public Dictionary SettingControls { get; } = new();
-
+
public IReadOnlyDictionary Inner => Settings;
protected ConcurrentDictionary Settings { get; set; }
public required IPublicAPI API { get; init; }
-
+
private JsonStorage> _storage;
// maybe move to resource?
@@ -37,18 +37,18 @@ namespace Flow.Launcher.Core.Plugin
_storage = new JsonStorage>(SettingPath);
Settings = await _storage.LoadAsync();
- if (Settings != null)
+ if (Settings != null || Configuration == null)
{
return;
}
- foreach (var (type, attributes) in Configuration.Body)
+ foreach (var (type, attributes) in Configuration.Body)
{
if (attributes.Name == null)
{
continue;
}
-
+
if (!Settings.ContainsKey(attributes.Name))
{
Settings[attributes.Name] = attributes.DefaultValue;
@@ -56,7 +56,7 @@ namespace Flow.Launcher.Core.Plugin
}
}
-
+
public void UpdateSettings(IReadOnlyDictionary settings)
{
if (settings == null || settings.Count == 0)
@@ -80,34 +80,35 @@ namespace Flow.Launcher.Core.Plugin
comboBox.Dispatcher.Invoke(() => comboBox.SelectedItem = value);
break;
case CheckBox checkBox:
- checkBox.Dispatcher.Invoke(() => checkBox.IsChecked = value is bool isChecked ? isChecked : bool.Parse(value as string ?? string.Empty));
+ checkBox.Dispatcher.Invoke(() =>
+ checkBox.IsChecked = value is bool isChecked
+ ? isChecked
+ : bool.Parse(value as string ?? string.Empty));
break;
}
}
}
+
Save();
}
-
+
public async Task SaveAsync()
{
await _storage.SaveAsync();
}
-
+
public void Save()
{
_storage.Save();
}
-
+
public Control CreateSettingPanel()
{
- if (Settings == null)
+ if (Settings == null || Settings.Count == 0)
return new();
var settingWindow = new UserControl();
- var mainPanel = new Grid
- {
- Margin = settingPanelMargin, VerticalAlignment = VerticalAlignment.Center
- };
+ var mainPanel = new Grid { Margin = settingPanelMargin, VerticalAlignment = VerticalAlignment.Center };
ColumnDefinition gridCol1 = new ColumnDefinition();
ColumnDefinition gridCol2 = new ColumnDefinition();
@@ -242,10 +243,7 @@ namespace Flow.Launcher.Core.Plugin
Margin = new Thickness(10, 0, 0, 0), Content = "Browse"
};
- var dockPanel = new DockPanel()
- {
- Margin = settingControlMargin
- };
+ var dockPanel = new DockPanel() { Margin = settingControlMargin };
DockPanel.SetDock(Btn, Dock.Right);
dockPanel.Children.Add(Btn);
@@ -352,7 +350,10 @@ namespace Flow.Launcher.Core.Plugin
case "checkbox":
var checkBox = new CheckBox
{
- IsChecked = Settings[attribute.Name] is bool isChecked ? isChecked : bool.Parse(attribute.DefaultValue),
+ IsChecked =
+ Settings[attribute.Name] is bool isChecked
+ ? isChecked
+ : bool.Parse(attribute.DefaultValue),
Margin = settingCheckboxMargin,
HorizontalAlignment = System.Windows.HorizontalAlignment.Right,
ToolTip = attribute.Description
@@ -375,14 +376,12 @@ namespace Flow.Launcher.Core.Plugin
break;
case "hyperlink":
- var hyperlink = new Hyperlink
- {
- ToolTip = attribute.Description, NavigateUri = attribute.url
- };
+ var hyperlink = new Hyperlink { ToolTip = attribute.Description, NavigateUri = attribute.url };
var linkbtn = new System.Windows.Controls.Button
{
- HorizontalAlignment = System.Windows.HorizontalAlignment.Right, Margin = settingControlMargin
+ HorizontalAlignment = System.Windows.HorizontalAlignment.Right,
+ Margin = settingControlMargin
};
linkbtn.Content = attribute.urlLabel;
@@ -408,12 +407,9 @@ namespace Flow.Launcher.Core.Plugin
mainPanel.Children.Add(panel);
mainPanel.Children.Add(contentControl);
rowCount++;
-
}
return settingWindow;
}
-
-
}
}
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
index 60130843e..390da072b 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 JsonMessageFormatter();
+ var formatter = new SystemTextJsonFormatter { JsonSerializerOptions = RequestSerializeOption };
var handler = new NewLineDelimitedMessageHandler(ClientPipe,
formatter);
@@ -100,10 +100,8 @@ namespace Flow.Launcher.Core.Plugin
RPC.AddLocalRpcMethod("UpdateResults", new Action((rawQuery, response) =>
{
var results = ParseResults(response);
- ResultsUpdated?.Invoke(this, new ResultUpdatedEventArgs { Query = new Query()
- {
- RawQuery = rawQuery
- }, Results = results });
+ ResultsUpdated?.Invoke(this,
+ new ResultUpdatedEventArgs { Query = new Query() { RawQuery = rawQuery }, Results = results });
}));
RPC.SynchronizationContext = null;
RPC.StartListening();
From 651711711d19bcef33fa593272474e364262b4cc Mon Sep 17 00:00:00 2001
From: Florian Grabmeier
Date: Wed, 13 Dec 2023 18:35:34 +0100
Subject: [PATCH 020/161] Implement pause/exit logic
Signed-off-by: Florian Grabmeier
---
.../Flow.Launcher.Plugin.Shell/Languages/en.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Shell/Main.cs | 16 ++++------------
2 files changed, 5 insertions(+), 12 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/en.xaml
index 88fa264d0..52aaf3c27 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/en.xaml
@@ -4,6 +4,7 @@
Replace Win+R
Close Command Prompt after pressing any key
+ Press any key to close this window...
Do not close Command Prompt after command execution
Always run as administrator
Run as different user
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
index b963302db..f3c34d41d 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -187,7 +187,7 @@ namespace Flow.Launcher.Plugin.Shell
return history.ToList();
}
- private ProcessStartInfo PrepareProcessStartInfo(string command, bool runAsAdministrator = false) //TODO: implement logic for CloseCMDAfterPress
+ private ProcessStartInfo PrepareProcessStartInfo(string command, bool runAsAdministrator = false)
{
command = command.Trim();
command = Environment.ExpandEnvironmentVariables(command);
@@ -203,7 +203,7 @@ namespace Flow.Launcher.Plugin.Shell
case Shell.Cmd:
{
info.FileName = "cmd.exe";
- info.Arguments = $"{(_settings.LeaveShellOpen ? "/k" : "/c")} {command} {(_settings.CloseShellAfterPress ? "& pause" : "")}";
+ info.Arguments = $"{(_settings.LeaveShellOpen ? "/k" : "/c")} {command} {(_settings.CloseShellAfterPress ? $"&& echo {context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")} && pause > nul /c" : "")}";
//// Use info.Arguments instead of info.ArgumentList to enable users better control over the arguments they are writing.
//// Previous code using ArgumentList, commands needed to be separated correctly:
@@ -232,11 +232,7 @@ namespace Flow.Launcher.Plugin.Shell
else
{
info.ArgumentList.Add("-Command");
- info.ArgumentList.Add(command);
- if (_settings.CloseShellAfterPress)
- {
- info.ArgumentList.Add("; pause");
- }
+ info.ArgumentList.Add($"{command}; {(_settings.CloseShellAfterPress ? $"Write-Host '{context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")}'; [System.Console]::ReadKey(); exit" : "")}");
}
break;
}
@@ -249,11 +245,7 @@ namespace Flow.Launcher.Plugin.Shell
info.ArgumentList.Add("-NoExit");
}
info.ArgumentList.Add("-Command");
- info.ArgumentList.Add(command);
- if (_settings.CloseShellAfterPress)
- {
- info.ArgumentList.Add("; pause");
- }
+ info.ArgumentList.Add($"{command}; {(_settings.CloseShellAfterPress ? $"Write-Host '{context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")}'; [System.Console]::ReadKey(); exit" : "")}");
break;
}
From 5169a16458ad8a7f9feab74e885354659ea82095 Mon Sep 17 00:00:00 2001
From: flox_x <93255373+flooxo@users.noreply.github.com>
Date: Fri, 15 Dec 2023 17:57:04 +0100
Subject: [PATCH 021/161] Apply suggestions from code review
Typo
Co-authored-by: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
---
Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
index 004d81e8b..a89d9df21 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
@@ -32,7 +32,7 @@
Please check if you can connect to github.com. This error means you may not be able to install or update plugins.
Update all plugins
Would you like to update all plugins?
- Would you like to update {0} plugins?{1}FlowLauncher will restart after updating all plugins.
+ Would you like to update {0} plugins?{1}Flow Launcher will restart after updating all plugins.
Would you like to update {0} plugins?
{0} plugins successfully updated. Restarting Flow, please wait...
Plugin {0} successfully updated. Restarting Flow, please wait...
From 35d006bfdac1e686dd4299bede723220cd686ddd Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Mon, 18 Dec 2023 13:02:28 +0800
Subject: [PATCH 022/161] Add "Sign Out" as an alias for "Log Off"
Closes #2214
---
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 43f293f74..b457a7a4d 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -148,7 +148,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = "Log Off",
+ Title = "Log Off/Sign Out",
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_log_off"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe77b"),
IcoPath = "Images\\logoff.png",
From c2ff04f0adea82902decfa08d437c15a070191ab Mon Sep 17 00:00:00 2001
From: Hongtao Zhang
Date: Mon, 18 Dec 2023 00:30:18 -0600
Subject: [PATCH 023/161] add a safety check for getproperty
---
.../ChromiumBookmarkLoader.cs | 44 ++++++++++++-------
1 file changed, 28 insertions(+), 16 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
index 14b791c48..1e4f3f9ac 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
@@ -2,12 +2,14 @@
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
+using Flow.Launcher.Infrastructure.Logger;
namespace Flow.Launcher.Plugin.BrowserBookmark
{
public abstract class ChromiumBookmarkLoader : IBookmarkLoader
{
public abstract List GetBookmarks();
+
protected List LoadBookmarks(string browserDataPath, string name)
{
var bookmarks = new List();
@@ -19,53 +21,63 @@ namespace Flow.Launcher.Plugin.BrowserBookmark
var bookmarkPath = Path.Combine(profile, "Bookmarks");
if (!File.Exists(bookmarkPath))
continue;
-
+
Main.RegisterBookmarkFile(bookmarkPath);
var source = name + (Path.GetFileName(profile) == "Default" ? "" : $" ({Path.GetFileName(profile)})");
bookmarks.AddRange(LoadBookmarksFromFile(bookmarkPath, source));
}
+
return bookmarks;
}
protected List LoadBookmarksFromFile(string path, string source)
{
if (!File.Exists(path))
- return new();
+ return new List();
var bookmarks = new List();
using var jsonDocument = JsonDocument.Parse(File.ReadAllText(path));
if (!jsonDocument.RootElement.TryGetProperty("roots", out var rootElement))
- return new();
+ return new List();
foreach (var folder in rootElement.EnumerateObject())
{
if (folder.Value.ValueKind == JsonValueKind.Object)
EnumerateFolderBookmark(folder.Value, bookmarks, source);
}
+
return bookmarks;
}
- private void EnumerateFolderBookmark(JsonElement folderElement, List bookmarks, string source)
+ private void EnumerateFolderBookmark(JsonElement folderElement, ICollection bookmarks,
+ string source)
{
if (!folderElement.TryGetProperty("children", out var childrenElement))
return;
foreach (var subElement in childrenElement.EnumerateArray())
{
- switch (subElement.GetProperty("type").GetString())
+ if (subElement.TryGetProperty("type", out var type))
{
- case "folder":
- case "workspace": // Edge Workspace
- EnumerateFolderBookmark(subElement, bookmarks, source);
- break;
- default:
- bookmarks.Add(new Bookmark(
- subElement.GetProperty("name").GetString(),
- subElement.GetProperty("url").GetString(),
- source));
- break;
+ switch (type.GetString())
+ {
+ case "folder":
+ case "workspace": // Edge Workspace
+ EnumerateFolderBookmark(subElement, bookmarks, source);
+ break;
+ default:
+ bookmarks.Add(new Bookmark(
+ subElement.GetProperty("name").GetString(),
+ subElement.GetProperty("url").GetString(),
+ source));
+ break;
+ }
+ }
+ else
+ {
+ Log.Error(
+ $"ChromiumBookmarkLoader: EnumerateFolderBookmark: type property not found for {subElement.GetString()}");
}
}
-
}
}
}
From 2107402ba8f830fa49722f32230028431b436bc4 Mon Sep 17 00:00:00 2001
From: Garulf <535299+Garulf@users.noreply.github.com>
Date: Tue, 26 Dec 2023 09:46:34 -0500
Subject: [PATCH 024/161] Override clipboard paste event
---
Flow.Launcher/MainWindow.xaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml
index 88e95aa69..b65fbc7bb 100644
--- a/Flow.Launcher/MainWindow.xaml
+++ b/Flow.Launcher/MainWindow.xaml
@@ -221,6 +221,7 @@
Visibility="Visible">
+
From db6e54160f96377113074c5ad6d5a6ca93deee63 Mon Sep 17 00:00:00 2001
From: Garulf <535299+Garulf@users.noreply.github.com>
Date: Tue, 26 Dec 2023 09:46:46 -0500
Subject: [PATCH 025/161] Handle clipboard paste event if text
---
Flow.Launcher/MainWindow.xaml.cs | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 3a914d488..461a64436 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -71,6 +71,15 @@ namespace Flow.Launcher
App.API.CopyToClipboard(QueryTextBox.SelectedText, showDefaultNotification: false);
}
}
+
+ private void OnPaste(object sender, ExecutedRoutedEventArgs e)
+ {
+ if (System.Windows.Clipboard.ContainsText())
+ {
+ _viewModel.QueryText = System.Windows.Clipboard.GetText().Replace("\n", String.Empty).Replace("\r", String.Empty);
+ e.Handled = true;
+ }
+ }
private async void OnClosing(object sender, CancelEventArgs e)
{
From e8d4afbf317b12bd7aba97f49da671e25b7d45fd Mon Sep 17 00:00:00 2001
From: Garulf <535299+Garulf@users.noreply.github.com>
Date: Tue, 26 Dec 2023 09:59:01 -0500
Subject: [PATCH 026/161] Use ChangeQueryText func
---
Flow.Launcher/MainWindow.xaml.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 461a64436..7d1a68125 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -76,7 +76,7 @@ namespace Flow.Launcher
{
if (System.Windows.Clipboard.ContainsText())
{
- _viewModel.QueryText = System.Windows.Clipboard.GetText().Replace("\n", String.Empty).Replace("\r", String.Empty);
+ _viewModel.ChangeQueryText(System.Windows.Clipboard.GetText().Replace("\n", String.Empty).Replace("\r", String.Empty));
e.Handled = true;
}
}
From 0d9f345199ed59a127d3bd2c3c85a1c5ce03ca36 Mon Sep 17 00:00:00 2001
From: NoPlagiarism <37241775+NoPlagiarism@users.noreply.github.com>
Date: Wed, 27 Dec 2023 14:54:29 +0500
Subject: [PATCH 027/161] README: Add links to community plugins
---
README.md | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/README.md b/README.md
index f121f2b75..1b415b0a2 100644
--- a/README.md
+++ b/README.md
@@ -222,28 +222,27 @@ And you can download
-### SpotifyPremium
+### [SpotifyPremium](https://github.com/fow5040/Flow.Launcher.Plugin.SpotifyPremium)
-
-### Steam Search
+### [Steam Search](https://github.com/Garulf/Steam-Search)
-### Clipboard History
+### [Clipboard History](https://github.com/liberize/Flow.Launcher.Plugin.ClipboardHistory)
-### Home Assistant Commander
+### [Home Assistant Commander](https://github.com/Garulf/HA-Commander)
-### Colors
+### [Colors](https://github.com/Flow-Launcher/Flow.Launcher.Plugin.Color)
-### GitHub
+### [GitHub](https://github.com/JohnTheGr8/Flow.Plugin.Github)
-### Window Walker
+### [Window Walker](https://github.com/taooceros/Flow.Plugin.WindowWalker)
......and more!
From f4887fa9c669e5dfa22a686c38e131cb8eb01f3a Mon Sep 17 00:00:00 2001
From: NoPlagiarism <37241775+NoPlagiarism@users.noreply.github.com>
Date: Wed, 27 Dec 2023 15:05:00 +0500
Subject: [PATCH 028/161] Spelling: Add Softpedia to expected
---
.github/actions/spelling/expect.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt
index 8e29be550..2d6fdb7f0 100644
--- a/.github/actions/spelling/expect.txt
+++ b/.github/actions/spelling/expect.txt
@@ -105,3 +105,4 @@ pluginsmanager
alreadyexists
JsonRPC
JsonRPCV2
+Softpedia
From d0f25036cac1531a9a706fba9138ca53a6539930 Mon Sep 17 00:00:00 2001
From: Florian Grabmeier
Date: Wed, 27 Dec 2023 18:44:20 +0100
Subject: [PATCH 029/161] Remove translations
Signed-off-by: Florian Grabmeier
---
Plugins/Flow.Launcher.Plugin.Shell/Languages/ar.xaml | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Languages/cs.xaml | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Languages/da.xaml | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Languages/de.xaml | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Languages/es-419.xaml | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Languages/es.xaml | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Languages/fr.xaml | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Languages/it.xaml | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Languages/ja.xaml | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Languages/ko.xaml | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Languages/nb.xaml | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Languages/nl.xaml | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Languages/pl.xaml | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Languages/pt-br.xaml | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Languages/pt-pt.xaml | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Languages/ru.xaml | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Languages/sk.xaml | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Languages/sr.xaml | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Languages/tr.xaml | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Languages/uk-UA.xaml | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Languages/zh-cn.xaml | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Languages/zh-tw.xaml | 1 -
22 files changed, 22 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/ar.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/ar.xaml
index 77fbcf8d4..0ccfd8c9a 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/ar.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/ar.xaml
@@ -2,7 +2,6 @@
Replace Win+R
- Close Command Prompt after pressing any key
Do not close Command Prompt after command execution
Always run as administrator
Run as different user
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/cs.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/cs.xaml
index 30d15ec76..2c764d845 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/cs.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/cs.xaml
@@ -2,7 +2,6 @@
Nahradit Win+R
- Po stisknutí libovolné klávesy zavřít příkazový řádek
Po dokončení příkazu příkazový řádek nezavírejte
Vždy spustit jako správce
Spustit jako jiný uživatel
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/da.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/da.xaml
index 77fbcf8d4..0ccfd8c9a 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/da.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/da.xaml
@@ -2,7 +2,6 @@
Replace Win+R
- Close Command Prompt after pressing any key
Do not close Command Prompt after command execution
Always run as administrator
Run as different user
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/de.xaml
index 8aae3a5fd..3fa7c64fa 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/de.xaml
@@ -2,7 +2,6 @@
Ersetzt Win+R
- Schließe die Kommandozeilte nachdem eine Taste gedrückt wurde
Schließe die Kommandozeilte nicht nachdem der Befehl ausgeführt wurde
Immer als Administrator ausführen
Als anderer Benutzer ausführen
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/es-419.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/es-419.xaml
index 122198357..284a2a0e6 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/es-419.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/es-419.xaml
@@ -2,7 +2,6 @@
Reemplazar Win+R
- Cerrar Símbolo del sistema después de pulsar cualquier tecla
No cerrar Símbolo del Sistema tras ejecutar el comando
Siempre ejecutar como administrador
Ejecutar como otro usuario
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/es.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/es.xaml
index ff01f30d6..8bf1a2c11 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/es.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/es.xaml
@@ -2,7 +2,6 @@
Reemplazar Win+R
- Cerrar Símbolo del sistema después de pulsar cualquier tecla
No cerrar el símbolo del sistema después de la ejecución del comando
Ejecutar siempre como administrador
Ejecutar como usuario diferente
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/fr.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/fr.xaml
index 438f8cc8f..d08efb9b8 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/fr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/fr.xaml
@@ -2,7 +2,6 @@
Remplacer Win+R
- Fermer l'invite de commande après avoir appuyé sur n'importe quelle touche
Ne pas fermer l'invite de commandes après l'exécution de la commande
Toujours exécuter en tant qu'administrateur
Exécuter en tant qu'utilisateur différent
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/it.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/it.xaml
index fa7df2c07..de40b0c47 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/it.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/it.xaml
@@ -2,7 +2,6 @@
Sostituisci Win+R
- Chiudere il prompt dei comandi dopo aver premuto qualsiasi tasto
Non chiudere il prompt dei comandi dopo l'esecuzione dei comandi
Esegui sempre come amministratore
Esegui come utente differente
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/ja.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/ja.xaml
index 77fbcf8d4..0ccfd8c9a 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/ja.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/ja.xaml
@@ -2,7 +2,6 @@
Replace Win+R
- Close Command Prompt after pressing any key
Do not close Command Prompt after command execution
Always run as administrator
Run as different user
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/ko.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/ko.xaml
index 9531fe832..014a46dfc 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/ko.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/ko.xaml
@@ -2,7 +2,6 @@
Win+R 단축키 대체
- 아무 키나 누른 후 명령 프롬프트 닫기
명령 실행 후 명령 프롬프트를 닫지 않음
항상 관리자 권한으로 실행
다른 유저 권한으로 실행
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/nb.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/nb.xaml
index 77fbcf8d4..0ccfd8c9a 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/nb.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/nb.xaml
@@ -2,7 +2,6 @@
Replace Win+R
- Close Command Prompt after pressing any key
Do not close Command Prompt after command execution
Always run as administrator
Run as different user
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/nl.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/nl.xaml
index 77fbcf8d4..0ccfd8c9a 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/nl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/nl.xaml
@@ -2,7 +2,6 @@
Replace Win+R
- Close Command Prompt after pressing any key
Do not close Command Prompt after command execution
Always run as administrator
Run as different user
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/pl.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/pl.xaml
index d83386d2d..c851be93b 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/pl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/pl.xaml
@@ -2,7 +2,6 @@
Zastąp Win+R
- Zamykanie wiersza polecenia po naciśnięciu dowolnego klawisza
Nie zamykaj wiersza poleceń po wykonaniu polecenia
Always run as administrator
Run as different user
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/pt-br.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/pt-br.xaml
index ef0223dd9..6a0a3c8fd 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/pt-br.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/pt-br.xaml
@@ -2,7 +2,6 @@
Substituir Win+R
- Fechar o Prompt de Comando após pressionar qualquer tecla
Não feche o Prompt de Comando após a execução do comando
Sempre executar como administrador
Run as different user
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/pt-pt.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/pt-pt.xaml
index f91fcd888..33d7f35a6 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/pt-pt.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/pt-pt.xaml
@@ -2,7 +2,6 @@
Substituir Win+R
- Fechar linha de comandos depois de pressionar qualquer tecla
Não fechar linha de comandos depois de executar o comando
Executar sempre como administrador
Executar com outro utilizador
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/ru.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/ru.xaml
index 77fbcf8d4..0ccfd8c9a 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/ru.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/ru.xaml
@@ -2,7 +2,6 @@
Replace Win+R
- Close Command Prompt after pressing any key
Do not close Command Prompt after command execution
Always run as administrator
Run as different user
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/sk.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/sk.xaml
index 76221a0ef..0b76303df 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/sk.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/sk.xaml
@@ -2,7 +2,6 @@
Nahradiť Win+R
- Zatvoriť príkazový riadok po stlačení ľubovoľnej klávesy
Nezatvárať príkazový riadok po dokončení príkazu
Spustiť vždy ako správca
Spustiť ako iný používateľ
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/sr.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/sr.xaml
index 77fbcf8d4..0ccfd8c9a 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/sr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/sr.xaml
@@ -2,7 +2,6 @@
Replace Win+R
- Close Command Prompt after pressing any key
Do not close Command Prompt after command execution
Always run as administrator
Run as different user
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/tr.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/tr.xaml
index 437e25f18..c6433cef1 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/tr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/tr.xaml
@@ -2,7 +2,6 @@
Win+R kısayolunu kullan
- Herhangi bir tuşa basıldıktan sonra komut istemini kapat
Çalıştırma sona erdikten sonra komut istemini kapatma
Always run as administrator
Run as different user
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/uk-UA.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/uk-UA.xaml
index 77fbcf8d4..0ccfd8c9a 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/uk-UA.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/uk-UA.xaml
@@ -2,7 +2,6 @@
Replace Win+R
- Close Command Prompt after pressing any key
Do not close Command Prompt after command execution
Always run as administrator
Run as different user
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/zh-cn.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/zh-cn.xaml
index 07e8142d7..916542c3a 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/zh-cn.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/zh-cn.xaml
@@ -2,7 +2,6 @@
替换 Win+R
- 按任意键后关闭命令窗口
执行后不关闭命令窗口
始终以管理员身份运行
以其他用户身份运行
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/zh-tw.xaml
index 58e1a11f8..7ddc58918 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/zh-tw.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/zh-tw.xaml
@@ -2,7 +2,6 @@
取代 Win+R
- 按任意鍵後關閉命令提示字元視窗
執行後不關閉命令提示字元視窗
一律以系統管理員身分執行
Run as different user
From dcaa74dbe5ae30f1ce99fa5ddb51ce67072efcb3 Mon Sep 17 00:00:00 2001
From: Florian Grabmeier
Date: Fri, 29 Dec 2023 11:17:46 +0100
Subject: [PATCH 030/161] Fix reduce nesting
Signed-off-by: Florian Grabmeier
---
.../PluginsManager.cs | 91 ++++++++++---------
1 file changed, 46 insertions(+), 45 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 88ad8ed32..fd5cbbe98 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -321,53 +321,54 @@ namespace Flow.Launcher.Plugin.PluginsManager
if (MessageBox.Show(message,
Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
- MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+ MessageBoxButton.YesNo) == MessageBoxResult.No)
{
- Parallel.ForEach(resultsForUpdate, plugin =>
- {
- var downloadToFilePath = Path.Combine(Path.GetTempPath(), $"{plugin.Name}-{plugin.NewVersion}.zip");
-
- _ = Task.Run(async delegate
- {
- if (File.Exists(downloadToFilePath))
- {
- File.Delete(downloadToFilePath);
- }
-
- await Http.DownloadAsync(plugin.PluginNewUserPlugin.UrlDownload, downloadToFilePath)
- .ConfigureAwait(false);
-
- PluginManager.UpdatePlugin(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin, downloadToFilePath);
-
- }).ContinueWith(t =>
- {
- Log.Exception("PluginsManager", $"Update failed for {plugin.Name}",
- t.Exception.InnerException);
- Context.API.ShowMsg(
- Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
- string.Format(
- Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"),
- plugin.Name));
- }, TaskContinuationOptions.OnlyOnFaulted);
- });
-
- if (Settings.AutoRestartAfterChanging)
- {
- Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
- string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_success_restart"),
- resultsForUpdate.Count()));
- Context.API.RestartApp();
- }
- else
- {
- Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
- string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_success_no_restart"),
- resultsForUpdate.Count()));
- }
-
- return true;
+ return false;
}
- return false;
+
+ Parallel.ForEach(resultsForUpdate, plugin =>
+ {
+ var downloadToFilePath = Path.Combine(Path.GetTempPath(), $"{plugin.Name}-{plugin.NewVersion}.zip");
+
+ _ = Task.Run(async delegate
+ {
+ if (File.Exists(downloadToFilePath))
+ {
+ File.Delete(downloadToFilePath);
+ }
+
+ await Http.DownloadAsync(plugin.PluginNewUserPlugin.UrlDownload, downloadToFilePath)
+ .ConfigureAwait(false);
+
+ PluginManager.UpdatePlugin(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin, downloadToFilePath);
+
+ }).ContinueWith(t =>
+ {
+ Log.Exception("PluginsManager", $"Update failed for {plugin.Name}",
+ t.Exception.InnerException);
+ Context.API.ShowMsg(
+ Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
+ string.Format(
+ Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"),
+ plugin.Name));
+ }, TaskContinuationOptions.OnlyOnFaulted);
+ });
+
+ if (Settings.AutoRestartAfterChanging)
+ {
+ Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
+ string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_success_restart"),
+ resultsForUpdate.Count()));
+ Context.API.RestartApp();
+ }
+ else
+ {
+ Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
+ string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_success_no_restart"),
+ resultsForUpdate.Count()));
+ }
+
+ return true;
},
ContextData = new UserPlugin()
};
From 2b8e46611f3259313423fb660418969773e8126e Mon Sep 17 00:00:00 2001
From: Florian Grabmeier
Date: Wed, 3 Jan 2024 09:52:12 +0100
Subject: [PATCH 031/161] Add translation keys for sys commands
Signed-off-by: Florian Grabmeier
---
.../Languages/en.xaml | 21 ++++++++++
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 38 +++++++++----------
2 files changed, 40 insertions(+), 19 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml
index a9aae930a..7399a55e7 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml
@@ -7,6 +7,27 @@
Command
Description
+ Shutdown
+ Restart
+ Restart With Advanced Boot Options
+ Log Off
+ Lock
+ Sleep
+ Hibernate
+ Index Option
+ Empty Recycle Bin
+ Open Recycle Bin
+ Exit
+ Save Settings
+ Restart Flow Launcher"
+ Settings
+ Reload Plugin Data
+ Check For Update
+ Open Log Location
+ Flow Launcher Tips
+ Flow Launcher UserData Folder
+
+
Shutdown Computer
Restart Computer
Restart the computer with Advanced Boot Options for Safe and Debugging modes, as well as other options
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 43f293f74..293fe5869 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -89,7 +89,7 @@ namespace Flow.Launcher.Plugin.Sys
{
new Result
{
- Title = "Shutdown",
+ Title = context.API.GetTranslation("flowlauncher_plugin_sys_shutdown_computer_cmd"),
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_shutdown_computer"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe7e8"),
IcoPath = "Images\\shutdown.png",
@@ -109,7 +109,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = "Restart",
+ Title = context.API.GetTranslation("flowlauncher_plugin_sys_restart_computer_cmd"),
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_restart_computer"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe777"),
IcoPath = "Images\\restart.png",
@@ -129,7 +129,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = "Restart With Advanced Boot Options",
+ Title = context.API.GetTranslation("flowlauncher_plugin_sys_restart_advanced_cmd"),
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_restart_advanced"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xecc5"),
IcoPath = "Images\\restart_advanced.png",
@@ -148,7 +148,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = "Log Off",
+ Title = context.API.GetTranslation("flowlauncher_plugin_sys_log_off_cmd"),
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_log_off"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe77b"),
IcoPath = "Images\\logoff.png",
@@ -167,7 +167,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = "Lock",
+ Title = context.API.GetTranslation("flowlauncher_plugin_sys_lock_cmd"),
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_lock"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe72e"),
IcoPath = "Images\\lock.png",
@@ -179,7 +179,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = "Sleep",
+ Title = context.API.GetTranslation("flowlauncher_plugin_sys_sleep_cmd"),
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_sleep"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xec46"),
IcoPath = "Images\\sleep.png",
@@ -187,7 +187,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = "Hibernate",
+ Title = context.API.GetTranslation("flowlauncher_plugin_sys_hibernate_cmd"),
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_hibernate"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe945"),
IcoPath = "Images\\hibernate.png",
@@ -204,7 +204,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = "Index Option",
+ Title = context.API.GetTranslation("flowlauncher_plugin_sys_restart_explorer_cmd"),
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_indexoption"),
IcoPath = "Images\\indexoption.png",
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe773"),
@@ -219,7 +219,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = "Empty Recycle Bin",
+ Title = context.API.GetTranslation("flowlauncher_plugin_sys_emptyrecyclebin_cmd"),
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_emptyrecyclebin"),
IcoPath = "Images\\recyclebin.png",
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe74d"),
@@ -242,7 +242,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = "Open Recycle Bin",
+ Title = context.API.GetTranslation("flowlauncher_plugin_sys_openrecyclebin_cmd"),
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_openrecyclebin"),
IcoPath = "Images\\openrecyclebin.png",
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe74d"),
@@ -257,7 +257,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = "Exit",
+ Title = context.API.GetTranslation("flowlauncher_plugin_sys_exit_cmd"),
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_exit"),
IcoPath = "Images\\app.png",
Action = c =>
@@ -268,7 +268,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = "Save Settings",
+ Title = context.API.GetTranslation("flowlauncher_plugin_sys_save_all_settings_cmd"),
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_save_all_settings"),
IcoPath = "Images\\app.png",
Action = c =>
@@ -281,7 +281,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = "Restart Flow Launcher",
+ Title = context.API.GetTranslation("flowlauncher_plugin_sys_restart_cmd"),
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_restart"),
IcoPath = "Images\\app.png",
Action = c =>
@@ -292,7 +292,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = "Settings",
+ Title = context.API.GetTranslation("flowlauncher_plugin_sys_setting_cmd"),
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_setting"),
IcoPath = "Images\\app.png",
Action = c =>
@@ -303,7 +303,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = "Reload Plugin Data",
+ Title = context.API.GetTranslation("flowlauncher_plugin_sys_reload_plugin_data_cmd"),
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_reload_plugin_data"),
IcoPath = "Images\\app.png",
Action = c =>
@@ -323,7 +323,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = "Check For Update",
+ Title = context.API.GetTranslation("flowlauncher_plugin_sys_check_for_update_cmd"),
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_check_for_update"),
IcoPath = "Images\\checkupdate.png",
Action = c =>
@@ -335,7 +335,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = "Open Log Location",
+ Title = context.API.GetTranslation("flowlauncher_plugin_sys_open_log_location_cmd"),
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_open_log_location"),
IcoPath = "Images\\app.png",
Action = c =>
@@ -347,7 +347,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = "Flow Launcher Tips",
+ Title = context.API.GetTranslation("flowlauncher_plugin_sys_open_docs_tips_cmd"),
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_open_docs_tips"),
IcoPath = "Images\\app.png",
Action = c =>
@@ -358,7 +358,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = "Flow Launcher UserData Folder",
+ Title = context.API.GetTranslation("flowlauncher_plugin_sys_open_userdata_location_cmd"),
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_open_userdata_location"),
IcoPath = "Images\\app.png",
Action = c =>
From 570b2029e625e7edd7bcfa4648e106bbb08d45e6 Mon Sep 17 00:00:00 2001
From: Florian Grabmeier
Date: Wed, 3 Jan 2024 10:05:39 +0100
Subject: [PATCH 032/161] Update wrong key translation
Signed-off-by: Florian Grabmeier
---
Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml
index 7399a55e7..446290347 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml
@@ -10,7 +10,7 @@
Shutdown
Restart
Restart With Advanced Boot Options
- Log Off
+ Log Off/Sign Out
Lock
Sleep
Hibernate
From 26c35a84b1569724c27ff38da9bc4086ec861953 Mon Sep 17 00:00:00 2001
From: Florian Grabmeier
Date: Wed, 3 Jan 2024 09:29:56 +0100
Subject: [PATCH 033/161] Fix use async
Signed-off-by: Florian Grabmeier
---
.../PluginsManager.cs | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index fd5cbbe98..cd77e6daf 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -305,7 +305,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
Title = Context.API.GetTranslation("plugin_pluginsmanager_update_all_title"),
SubTitle = Context.API.GetTranslation("plugin_pluginsmanager_update_all_subtitle"),
IcoPath = icoPath,
- Action = e =>
+ AsyncAction = async e =>
{
string message;
if (Settings.AutoRestartAfterChanging)
@@ -326,11 +326,11 @@ namespace Flow.Launcher.Plugin.PluginsManager
return false;
}
- Parallel.ForEach(resultsForUpdate, plugin =>
+ await Task.WhenAll(resultsForUpdate.Select(async plugin =>
{
var downloadToFilePath = Path.Combine(Path.GetTempPath(), $"{plugin.Name}-{plugin.NewVersion}.zip");
- _ = Task.Run(async delegate
+ try
{
if (File.Exists(downloadToFilePath))
{
@@ -341,18 +341,17 @@ namespace Flow.Launcher.Plugin.PluginsManager
.ConfigureAwait(false);
PluginManager.UpdatePlugin(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin, downloadToFilePath);
-
- }).ContinueWith(t =>
+ }
+ catch (Exception ex)
{
- Log.Exception("PluginsManager", $"Update failed for {plugin.Name}",
- t.Exception.InnerException);
+ Log.Exception("PluginsManager", $"Update failed for {plugin.Name}", ex.InnerException);
Context.API.ShowMsg(
Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
string.Format(
Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"),
plugin.Name));
- }, TaskContinuationOptions.OnlyOnFaulted);
- });
+ }
+ }));
if (Settings.AutoRestartAfterChanging)
{
From c3cf3d9e7e9dd17c71a8fcbb4e3c4abf9223689e Mon Sep 17 00:00:00 2001
From: NoPlagiarism <37241775+NoPlagiarism@users.noreply.github.com>
Date: Thu, 11 Jan 2024 15:27:35 +0500
Subject: [PATCH 034/161] [Calculator] Allow more functions to be used
---
Plugins/Flow.Launcher.Plugin.Calculator/Main.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs
index e2aa5860c..684de33d8 100644
--- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs
@@ -19,6 +19,7 @@ namespace Flow.Launcher.Plugin.Caculator
@"sin|cos|tan|arcsin|arccos|arctan|" +
@"eigval|eigvec|eig|sum|polar|plot|round|sort|real|zeta|" +
@"bin2dec|hex2dec|oct2dec|" +
+ @"factorial|sign|isprime|isinfty|" +
@"==|~=|&&|\|\||" +
@"[ei]|[0-9]|[\+\-\*\/\^\., ""]|[\(\)\|\!\[\]]" +
@")+$", RegexOptions.Compiled);
From 19dc86a23b5a8535b731e5381c6ed103d7b21fab Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Sat, 13 Jan 2024 12:05:11 +0800
Subject: [PATCH 035/161] [ci skip] Update system commands in README
Fix #1819
---
README.md | 42 +++++++++++++++++++++---------------------
1 file changed, 21 insertions(+), 21 deletions(-)
diff --git a/README.md b/README.md
index 1b415b0a2..2d748aab8 100644
--- a/README.md
+++ b/README.md
@@ -286,27 +286,27 @@ And you can download .
/// We use conditional http requests to keep repeat requests fast.
@@ -32,12 +39,15 @@ namespace Flow.Launcher.Core.ExternalPlugins
request.Headers.Add("If-None-Match", latestEtag);
- using var response = await Http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token).ConfigureAwait(false);
+ using var response = await Http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token)
+ .ConfigureAwait(false);
if (response.StatusCode == HttpStatusCode.OK)
{
- this.plugins = await response.Content.ReadFromJsonAsync>(cancellationToken: token).ConfigureAwait(false);
- this.latestEtag = response.Headers.ETag.Tag;
+ this.plugins = await response.Content
+ .ReadFromJsonAsync>(PluginStoreItemSerializationOption, cancellationToken: token)
+ .ConfigureAwait(false);
+ this.latestEtag = response.Headers.ETag?.Tag;
Log.Info(nameof(CommunityPluginSource), $"Loaded {this.plugins.Count} plugins from {ManifestFileUrl}");
return this.plugins;
@@ -49,7 +59,8 @@ namespace Flow.Launcher.Core.ExternalPlugins
}
else
{
- Log.Warn(nameof(CommunityPluginSource), $"Failed to load resource {ManifestFileUrl} with response {response.StatusCode}");
+ Log.Warn(nameof(CommunityPluginSource),
+ $"Failed to load resource {ManifestFileUrl} with response {response.StatusCode}");
throw new Exception($"Failed to load resource {ManifestFileUrl} with response {response.StatusCode}");
}
}
diff --git a/Flow.Launcher.Core/ExternalPlugins/UserPlugin.cs b/Flow.Launcher.Core/ExternalPlugins/UserPlugin.cs
index bb1279b2c..64c4cd627 100644
--- a/Flow.Launcher.Core/ExternalPlugins/UserPlugin.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/UserPlugin.cs
@@ -14,8 +14,8 @@ namespace Flow.Launcher.Core.ExternalPlugins
public string UrlDownload { get; set; }
public string UrlSourceCode { get; set; }
public string IcoPath { get; set; }
- public DateTime LatestReleaseDate { get; set; }
- public DateTime DateAdded { get; set; }
+ public DateTime? LatestReleaseDate { get; set; }
+ public DateTime? DateAdded { get; set; }
}
}
From e6fb59e64a7821c0b434e92d7640dc349ee5ddfc Mon Sep 17 00:00:00 2001
From: NoPlagiarism <37241775+NoPlagiarism@users.noreply.github.com>
Date: Sun, 14 Jan 2024 18:31:21 +0500
Subject: [PATCH 037/161] Add ToggleGameMode to system commands
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 17 +++++++++++++++++
Flow.Launcher/PublicAPIInstance.cs | 16 ++++++++++++++++
.../Flow.Launcher.Plugin.Sys/Languages/ar.xaml | 1 +
.../Flow.Launcher.Plugin.Sys/Languages/cs.xaml | 1 +
.../Flow.Launcher.Plugin.Sys/Languages/da.xaml | 1 +
.../Flow.Launcher.Plugin.Sys/Languages/de.xaml | 1 +
.../Flow.Launcher.Plugin.Sys/Languages/en.xaml | 3 ++-
.../Languages/es-419.xaml | 1 +
.../Flow.Launcher.Plugin.Sys/Languages/es.xaml | 1 +
.../Flow.Launcher.Plugin.Sys/Languages/fr.xaml | 1 +
.../Flow.Launcher.Plugin.Sys/Languages/it.xaml | 1 +
.../Flow.Launcher.Plugin.Sys/Languages/ja.xaml | 1 +
.../Flow.Launcher.Plugin.Sys/Languages/ko.xaml | 1 +
.../Flow.Launcher.Plugin.Sys/Languages/nb.xaml | 1 +
.../Flow.Launcher.Plugin.Sys/Languages/nl.xaml | 1 +
.../Flow.Launcher.Plugin.Sys/Languages/pl.xaml | 1 +
.../Languages/pt-br.xaml | 1 +
.../Languages/pt-pt.xaml | 1 +
.../Flow.Launcher.Plugin.Sys/Languages/ru.xaml | 1 +
.../Flow.Launcher.Plugin.Sys/Languages/sk.xaml | 1 +
.../Flow.Launcher.Plugin.Sys/Languages/sr.xaml | 1 +
.../Flow.Launcher.Plugin.Sys/Languages/tr.xaml | 1 +
.../Languages/uk-UA.xaml | 1 +
.../Languages/zh-cn.xaml | 1 +
.../Languages/zh-tw.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 12 ++++++++++++
README.md | 2 ++
27 files changed, 71 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 474ad6f0a..49fe680f1 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -274,5 +274,22 @@ namespace Flow.Launcher.Plugin
/// Non-C# plugins should use this method
///
public void OpenAppUri(string appUri);
+
+ ///
+ /// Toggles Game Mode. off -> on and backwards
+ ///
+ public void ToggleGameMode();
+
+ ///
+ /// Switches Game Mode to given value
+ ///
+ /// New Game Mode status
+ public void SetGameMode(bool value);
+
+ ///
+ /// Representing Game Mode status
+ ///
+ ///
+ public bool IsGameModeOn();
}
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index def54e04b..36309a22a 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -294,6 +294,22 @@ namespace Flow.Launcher
OpenUri(appUri);
}
+ public void ToggleGameMode()
+ {
+ _mainVM.ToggleGameMode();
+ }
+
+ public void SetGameMode(bool value)
+ {
+ _mainVM.GameModeStatus = value;
+ }
+
+ public bool IsGameModeOn()
+ {
+ return _mainVM.GameModeStatus;
+ }
+
+
private readonly List> _globalKeyboardHandlers = new();
public void RegisterGlobalKeyboardCallback(Func callback) => _globalKeyboardHandlers.Add(callback);
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/ar.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/ar.xaml
index 9ada8533b..2357454d0 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/ar.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/ar.xaml
@@ -24,6 +24,7 @@
Check for new Flow Launcher update
Visit Flow Launcher's documentation for more help and how to use tips
Open the location where Flow Launcher's settings are stored
+ Toggle Game Mode
Success
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/cs.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/cs.xaml
index 7ac077c77..1505f6e65 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/cs.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/cs.xaml
@@ -24,6 +24,7 @@
Zkontrolovat aktualizace Flow Launcheru
Další nápovědu a tipy k jeho používání najdete v dokumentaci ke službě Flow Launcher
Otevře místo, kde jsou uložena nastavení Flow Launcher
+ Toggle Game Mode
Úspěšné
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/da.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/da.xaml
index 129f40bae..d726432d6 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/da.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/da.xaml
@@ -24,6 +24,7 @@
Check for new Flow Launcher update
Visit Flow Launcher's documentation for more help and how to use tips
Open the location where Flow Launcher's settings are stored
+ Toggle Game Mode
Fortsæt
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/de.xaml
index 052166e28..e33dc7bdb 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/de.xaml
@@ -24,6 +24,7 @@
Check for new Flow Launcher update
Visit Flow Launcher's documentation for more help and how to use tips
Open the location where Flow Launcher's settings are stored
+ Toggle Game Mode
Erfolgreich
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml
index a9aae930a..a5a6035bc 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml
@@ -26,8 +26,9 @@
Check for new Flow Launcher update
Visit Flow Launcher's documentation for more help and how to use tips
Open the location where Flow Launcher's settings are stored
+ Toggle Game Mode
-
+
Success
All Flow Launcher settings saved
Reloaded all applicable plugin data
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/es-419.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/es-419.xaml
index 9ada8533b..2357454d0 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/es-419.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/es-419.xaml
@@ -24,6 +24,7 @@
Check for new Flow Launcher update
Visit Flow Launcher's documentation for more help and how to use tips
Open the location where Flow Launcher's settings are stored
+ Toggle Game Mode
Success
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/es.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/es.xaml
index 1005e4b8f..2d32da003 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/es.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/es.xaml
@@ -24,6 +24,7 @@
Busca actualizaciones de Flow Launcher
Accede a la documentación de Flow Launcher para más ayuda y consejos de uso
Abre la ubicación donde se almacena la configuración de Flow Launcher
+ Toggle Game Mode
Correcto
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/fr.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/fr.xaml
index cfd2fb832..62e66c64b 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/fr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/fr.xaml
@@ -24,6 +24,7 @@
Vérifier de nouvelles mises à jour Flow Launcher
Consultez la documentation de Flow Launcher pour plus d'aide et comment utiliser les conseils.
Ouvrez l'emplacement où les paramètres de Flow Launcher sont stockés
+ Toggle Game Mode
Ajouté avec succès
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/it.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/it.xaml
index 3451f4aa6..5691201a8 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/it.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/it.xaml
@@ -24,6 +24,7 @@
Controlla il nuovo aggiornamento di Flow Launcher
Visita la documentazione di Flow Launcher per maggiori informazioni e suggerimenti su come usarlo
Apri la posizione in cui vengono memorizzate le impostazioni di Flow Launcher
+ Toggle Game Mode
Successo
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/ja.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/ja.xaml
index 169135a69..66c6c3bed 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/ja.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/ja.xaml
@@ -24,6 +24,7 @@
Check for new Flow Launcher update
Visit Flow Launcher's documentation for more help and how to use tips
Open the location where Flow Launcher's settings are stored
+ Toggle Game Mode
成功しまし
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/ko.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/ko.xaml
index dab69b706..35951a583 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/ko.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/ko.xaml
@@ -24,6 +24,7 @@
Flow Launcher 새 업데이트 확인
Flow Launcher의 도움말 및 사용안내
Flow Launcher의 설정이 저장된 위치 열기
+ Toggle Game Mode
성공
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/nb.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/nb.xaml
index 9ada8533b..2357454d0 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/nb.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/nb.xaml
@@ -24,6 +24,7 @@
Check for new Flow Launcher update
Visit Flow Launcher's documentation for more help and how to use tips
Open the location where Flow Launcher's settings are stored
+ Toggle Game Mode
Success
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/nl.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/nl.xaml
index 05e33adef..85c04371c 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/nl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/nl.xaml
@@ -24,6 +24,7 @@
Check for new Flow Launcher update
Visit Flow Launcher's documentation for more help and how to use tips
Open the location where Flow Launcher's settings are stored
+ Toggle Game Mode
Succesvol
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/pl.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/pl.xaml
index f8e857d1c..d01d780ae 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/pl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/pl.xaml
@@ -24,6 +24,7 @@
Check for new Flow Launcher update
Visit Flow Launcher's documentation for more help and how to use tips
Open the location where Flow Launcher's settings are stored
+ Toggle Game Mode
Sukces
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/pt-br.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/pt-br.xaml
index a78a71c56..0bc352d80 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/pt-br.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/pt-br.xaml
@@ -24,6 +24,7 @@
Check for new Flow Launcher update
Visit Flow Launcher's documentation for more help and how to use tips
Open the location where Flow Launcher's settings are stored
+ Toggle Game Mode
Sucesso
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/pt-pt.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/pt-pt.xaml
index e53fd601d..f76c1f178 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/pt-pt.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/pt-pt.xaml
@@ -24,6 +24,7 @@
Procurar por novas versões do Flow Launcher
Aceda à documentação para mais informações e dicas de utilização
Abrir localização onde as definições do Flow Launcher estão guardadas
+ Toggle Game Mode
Sucesso
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/ru.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/ru.xaml
index 233754f80..3092c6299 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/ru.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/ru.xaml
@@ -24,6 +24,7 @@
Check for new Flow Launcher update
Visit Flow Launcher's documentation for more help and how to use tips
Open the location where Flow Launcher's settings are stored
+ Toggle Game Mode
Успешно
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/sk.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/sk.xaml
index 516b792c5..dcad0ccee 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/sk.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/sk.xaml
@@ -24,6 +24,7 @@
Skontrolovať aktualizácie Flow Launchera
V dokumentácii k aplikácii Flow Launcher nájdete ďalšiu pomoc a tipy na používanie
Otvoriť umiestnenie, kde sú uložené nastavenia Flow Launchera
+ Toggle Game Mode
Úspešné
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/sr.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/sr.xaml
index 561811679..e8ba99c9a 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/sr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/sr.xaml
@@ -24,6 +24,7 @@
Check for new Flow Launcher update
Visit Flow Launcher's documentation for more help and how to use tips
Open the location where Flow Launcher's settings are stored
+ Toggle Game Mode
Uspešno
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/tr.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/tr.xaml
index 3d847d7fa..c66601dba 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/tr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/tr.xaml
@@ -24,6 +24,7 @@
Check for new Flow Launcher update
Visit Flow Launcher's documentation for more help and how to use tips
Open the location where Flow Launcher's settings are stored
+ Toggle Game Mode
Başarılı
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/uk-UA.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/uk-UA.xaml
index cf5a3bed4..ac73513f4 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/uk-UA.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/uk-UA.xaml
@@ -24,6 +24,7 @@
Check for new Flow Launcher update
Visit Flow Launcher's documentation for more help and how to use tips
Open the location where Flow Launcher's settings are stored
+ Toggle Game Mode
Успішно
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/zh-cn.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/zh-cn.xaml
index e9bf86065..cba1e5fbe 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/zh-cn.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/zh-cn.xaml
@@ -24,6 +24,7 @@
检查新的 Flow Launcher 更新
访问 Flow Launcher 的文档以获取更多帮助以及使用技巧
打开Flow Launcher 设置文件夹
+ Toggle Game Mode
成功
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/zh-tw.xaml
index 09b099bdc..cc469f808 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/zh-tw.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/zh-tw.xaml
@@ -24,6 +24,7 @@
Check for new Flow Launcher update
Visit Flow Launcher's documentation for more help and how to use tips
Open the location where Flow Launcher's settings are stored
+ Toggle Game Mode
成
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index b457a7a4d..750ab476c 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -366,6 +366,18 @@ namespace Flow.Launcher.Plugin.Sys
context.API.OpenDirectory(DataLocation.DataDirectory());
return true;
}
+ },
+ new Result
+ {
+ Title = "Toggle Game Mode",
+ SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_toggle_game_mode"),
+ IcoPath = "Images\\app.png",
+ Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\ue7fc"),
+ Action = c =>
+ {
+ context.API.ToggleGameMode();
+ return true;
+ }
}
});
diff --git a/README.md b/README.md
index 1b415b0a2..2f28495c3 100644
--- a/README.md
+++ b/README.md
@@ -206,6 +206,7 @@ And you can download
@@ -307,6 +308,7 @@ And you can download
-
## 🎅 New Features🤶
+
### Preview Panel
+
- Use the F1 key to open/hide the preview panel.
@@ -34,6 +35,7 @@ Dedicated to making your workflow flow more seamless. Search everything from app
- This feature is currently in its early stages.
### Everything Plugin Merged Into Explorer
+
- Switch easily between Everything and Windows Search to take advantage of both search engines (remember to remove existing Everything plugin).
@@ -46,6 +48,7 @@ Dedicated to making your workflow flow more seamless. Search everything from app
- Display the date and time when the search window is triggered.
### Drag & Drop
+
- Drag an item to Discord or computer location.
@@ -59,24 +62,28 @@ Dedicated to making your workflow flow more seamless. Search everything from app
- New shortcut functionality to set additional action keywords or search terms.
### Improved Program Plugin
+
- PATH is now indexed
- Support for .url files, flow can now search installed steam/epic games.
- Improved UWP indexing.
### Improved Memory Usage
+
- Fixed a memory leak and reduced overall memory usage.
### Improved Plugin / Plugin Store
+
- Search plugins in the Plugin Store and existing plugin tab.
- Categorised sections in Plugin Store to easily see new and updated plugins.
### Improved Non-C# Plugin's Panel Design
+
- The design has been adjusted to align to the overall look and feel of flow.
- Simplified the information displayed on buttons
-🚂Full Changelogs
+🚂[Full Changelogs](https://github.com/Flow-Launcher/Flow.Launcher/releases)
@@ -105,7 +112,7 @@ Dedicated to making your workflow flow more seamless. Search everything from app
> When installing for the first time Windows may raise an issue about security due to code not being signed, if you downloaded from this repo then you are good to continue the set up.
-And you can download early access version.
+And you can download [early access version](https://github.com/Flow-Launcher/Prereleases/releases).
@@ -115,12 +122,10 @@ And you can download
-
- Search for apps, files or file contents.
-
- Support search using environment variable paths.
### Web Searches & URLs
@@ -129,8 +134,6 @@ And you can download
-
-
### Browser Bookmarks
@@ -140,7 +143,7 @@ And you can download
- Provides system related commands. shutdown, lock, settings, etc.
-- System command list
+- [System command list](#system-command-list)
### Calculator
@@ -152,7 +155,6 @@ And you can download
-
- Run batch and PowerShell commands as Administrator or a different user.
- Ctrl+Enter to Run as Administrator.
@@ -168,7 +170,6 @@ And you can download
@@ -224,16 +225,19 @@ And you can download
### [Steam Search](https://github.com/Garulf/Steam-Search)
+
-
### [Clipboard History](https://github.com/liberize/Flow.Launcher.Plugin.ClipboardHistory)
+
### [Home Assistant Commander](https://github.com/Garulf/HA-Commander)
+
### [Colors](https://github.com/Flow-Launcher/Flow.Launcher.Plugin.Color)
@@ -241,49 +245,48 @@ And you can download
### [GitHub](https://github.com/JohnTheGr8/Flow.Plugin.Github)
+
### [Window Walker](https://github.com/taooceros/Flow.Plugin.WindowWalker)
+
-......and more!
+......and [more!](https://flowlauncher.com/docs/#/plugins)
### 🛒 Plugin Store
-
- You can view the full plugin list or quickly install a plugin via the Plugin Store menu inside Settings
- or type `pm` `install`/`uninstall`/`update` + the plugin name in the search window,
-
## ⌨️ Hotkeys
-| Hotkey | Description |
-| ------------------------------------------------------------ | -------------------------------------------- |
-| Alt+ Space | Open search window (default and configurable)|
-| Enter | Execute |
-| Ctrl+Shift+Enter | Run as admin |
-| ↑↓ | Scroll up & down |
-| ←→ | Back to result / Open Context Menu |
-| Ctrl +O , Shift +Enter | Open Context Menu |
-| Tab | Autocomplete |
-| F1 | Toggle Preview Panel (default and configurable)|
-| Esc | Back to results / hide search window |
-| Ctrl +C | Copy the actual folder / file |
-| Ctrl +I | Open flow's settings |
-| Ctrl +R | Run the current query again (refresh results)|
-| F5 | Reload all plugin data |
-| Ctrl + F12 | Toggle Game Mode when in search window |
-| Ctrl + +,- | Quickly change maximum results shown |
-| Ctrl + [,] | Quickly change search window width |
-| Ctrl + H | Open search history |
-| Ctrl + Backspace | Back to previous directory |
-
+| Hotkey | Description |
+| ------------------------------------------------------------------ | ---------------------------------------------- |
+| Alt+ Space | Open search window (default and configurable) |
+| Enter | Execute |
+| Ctrl+Shift+Enter | Run as admin |
+| ↑↓ | Scroll up & down |
+| ←→ | Back to result / Open Context Menu |
+| Ctrl +O , Shift +Enter | Open Context Menu |
+| Tab | Autocomplete |
+| F1 | Toggle Preview Panel (default and configurable)|
+| Esc | Back to results / hide search window |
+| Ctrl +C | Copy the actual folder / file |
+| Ctrl +I | Open flow's settings |
+| Ctrl +R | Run the current query again (refresh results) |
+| F5 | Reload all plugin data |
+| Ctrl + F12 | Toggle Game Mode when in search window |
+| Ctrl + +,- | Quickly change maximum results shown |
+| Ctrl + [,] | Quickly change search window width |
+| Ctrl + H | Open search history |
+| Ctrl + Backspace | Back to previous directory |
## System Command List
@@ -320,7 +323,7 @@ And you can download
-
+
@@ -336,16 +339,15 @@ And you can download
-
-
### Mentions
-- Why I Chose to Support Flow-Launcher - Appwrite
-- Softpedia Editor's Pick
+
+- [Why I Chose to Support Flow-Launcher](https://dev.to/appwrite/appwrite-loves-open-source-why-i-chose-to-support-flow-launcher-54pj) - Appwrite
+- [Softpedia Editor's Pick](https://www.softpedia.com/get/System/Launchers-Shutdown-Tools/Flow-Launcher.shtml)
@@ -377,7 +379,7 @@ Get in touch if you like to join the Flow-Launcher Team and help build this grea
- Install Visual Studio 2022
-- Install .Net 7 SDK
+- Install .Net 7 SDK
- via Visual Studio installer
- via winget `winget install Microsoft.DotNet.SDK.7`
- Manually from [here](https://dotnet.microsoft.com/en-us/download/dotnet/7.0)
From 224dab70a96b75c9de81a47a12b921bced2cb2e3 Mon Sep 17 00:00:00 2001
From: Florian Grabmeier
Date: Mon, 15 Jan 2024 16:16:07 +0100
Subject: [PATCH 039/161] Add dynamic title
Signed-off-by: Florian Grabmeier
---
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 90 ++++++++++++++++++------
1 file changed, 67 insertions(+), 23 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 293fe5869..37ea6b7ea 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -2,11 +2,13 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
+using System.Linq;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Interop;
using Flow.Launcher.Infrastructure;
+using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin.SharedCommands;
using Application = System.Windows.Application;
@@ -19,6 +21,7 @@ namespace Flow.Launcher.Plugin.Sys
public class Main : IPlugin, ISettingProvider, IPluginI18n
{
private PluginInitContext context;
+ private Dictionary KeywordTitleMappings = new Dictionary();
#region DllImport
@@ -59,6 +62,8 @@ namespace Flow.Launcher.Plugin.Sys
var results = new List();
foreach (var c in commands)
{
+ c.Title = GetDynamicTitle(query, c);
+
var titleMatch = StringMatcher.FuzzySearch(query.Search, c.Title);
var subTitleMatch = StringMatcher.FuzzySearch(query.Search, c.SubTitle);
@@ -77,9 +82,48 @@ namespace Flow.Launcher.Plugin.Sys
return results;
}
+ private string GetDynamicTitle(Query query, Result result)
+ {
+ var pair = KeywordTitleMappings
+ .Where(kvp => kvp.Key == result.Title && kvp.Key != kvp.Value)
+ .FirstOrDefault();
+
+ if (pair.Equals(default))
+ {
+ Log.Error($"Dynamic Title not found for: {result.Title}");
+ return "Title Not Found";
+ }
+
+ var englishTitleMatch = StringMatcher.FuzzySearch(query.Search, pair.Key);
+ var translatedTitleMatch = StringMatcher.FuzzySearch(query.Search, pair.Value);
+
+ return englishTitleMatch.Score >= translatedTitleMatch.Score ? pair.Key : pair.Value;
+ }
+
public void Init(PluginInitContext context)
{
this.context = context;
+ KeywordTitleMappings = new Dictionary{
+ {"Shutdown", context.API.GetTranslation("flowlauncher_plugin_sys_shutdown_computer_cmd")},
+ {"Restart", context.API.GetTranslation("flowlauncher_plugin_sys_restart_computer_cmd")},
+ {"Restart With Advanced Boot Options", context.API.GetTranslation("flowlauncher_plugin_sys_restart_advanced_cmd")},
+ {"Log Off/Sign Out", context.API.GetTranslation("flowlauncher_plugin_sys_log_off_cmd")},
+ {"Lock", context.API.GetTranslation("flowlauncher_plugin_sys_lock_cmd")},
+ {"Sleep", context.API.GetTranslation("flowlauncher_plugin_sys_sleep_cmd")},
+ {"Hibernate", context.API.GetTranslation("flowlauncher_plugin_sys_hibernate_cmd")},
+ {"Index Option", context.API.GetTranslation("flowlauncher_plugin_sys_indexoption_cmd")},
+ {"Empty Recycle Bin", context.API.GetTranslation("flowlauncher_plugin_sys_emptyrecyclebin_cmd")},
+ {"Open Recycle Bin", context.API.GetTranslation("flowlauncher_plugin_sys_openrecyclebin_cmd")},
+ {"Exit", context.API.GetTranslation("flowlauncher_plugin_sys_exit_cmd")},
+ {"Save Settings", context.API.GetTranslation("flowlauncher_plugin_sys_save_all_settings_cmd")},
+ {"Restart Flow Launcher", context.API.GetTranslation("flowlauncher_plugin_sys_restart_cmd")},
+ {"Settings", context.API.GetTranslation("flowlauncher_plugin_sys_setting_cmd")},
+ {"Reload Plugin Data", context.API.GetTranslation("flowlauncher_plugin_sys_reload_plugin_data_cmd")},
+ {"Check For Update", context.API.GetTranslation("flowlauncher_plugin_sys_check_for_update_cmd")},
+ {"Open Log Location", context.API.GetTranslation("flowlauncher_plugin_sys_open_log_location_cmd")},
+ {"Flow Launcher Tips", context.API.GetTranslation("flowlauncher_plugin_sys_open_docs_tips_cmd")},
+ {"Flow Launcher UserData Folder", context.API.GetTranslation("flowlauncher_plugin_sys_open_userdata_location_cmd")}
+ };
}
private List Commands()
@@ -89,7 +133,7 @@ namespace Flow.Launcher.Plugin.Sys
{
new Result
{
- Title = context.API.GetTranslation("flowlauncher_plugin_sys_shutdown_computer_cmd"),
+ Title = "Shutdown",
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_shutdown_computer"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe7e8"),
IcoPath = "Images\\shutdown.png",
@@ -109,7 +153,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = context.API.GetTranslation("flowlauncher_plugin_sys_restart_computer_cmd"),
+ Title = "Restart",
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_restart_computer"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe777"),
IcoPath = "Images\\restart.png",
@@ -129,7 +173,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = context.API.GetTranslation("flowlauncher_plugin_sys_restart_advanced_cmd"),
+ Title = "Restart With Advanced Boot Options",
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_restart_advanced"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xecc5"),
IcoPath = "Images\\restart_advanced.png",
@@ -139,7 +183,7 @@ namespace Flow.Launcher.Plugin.Sys
context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_restart_computer_advanced"),
context.API.GetTranslation("flowlauncher_plugin_sys_restart_computer"),
MessageBoxButton.YesNo, MessageBoxImage.Warning);
-
+
if (result == MessageBoxResult.Yes)
Process.Start("shutdown", "/r /o /t 0");
@@ -148,7 +192,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = context.API.GetTranslation("flowlauncher_plugin_sys_log_off_cmd"),
+ Title = "Log Off/Sign Out",
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_log_off"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe77b"),
IcoPath = "Images\\logoff.png",
@@ -158,7 +202,7 @@ namespace Flow.Launcher.Plugin.Sys
context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_logoff_computer"),
context.API.GetTranslation("flowlauncher_plugin_sys_log_off"),
MessageBoxButton.YesNo, MessageBoxImage.Warning);
-
+
if (result == MessageBoxResult.Yes)
ExitWindowsEx(EWX_LOGOFF, 0);
@@ -167,7 +211,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = context.API.GetTranslation("flowlauncher_plugin_sys_lock_cmd"),
+ Title = "Lock",
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_lock"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe72e"),
IcoPath = "Images\\lock.png",
@@ -179,7 +223,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = context.API.GetTranslation("flowlauncher_plugin_sys_sleep_cmd"),
+ Title = "Sleep",
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_sleep"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xec46"),
IcoPath = "Images\\sleep.png",
@@ -187,7 +231,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = context.API.GetTranslation("flowlauncher_plugin_sys_hibernate_cmd"),
+ Title = "Hibernate",
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_hibernate"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe945"),
IcoPath = "Images\\hibernate.png",
@@ -198,13 +242,13 @@ namespace Flow.Launcher.Plugin.Sys
info.UseShellExecute = true;
ShellCommand.Execute(info);
-
+
return true;
}
},
new Result
{
- Title = context.API.GetTranslation("flowlauncher_plugin_sys_restart_explorer_cmd"),
+ Title = "Index Option",
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_indexoption"),
IcoPath = "Images\\indexoption.png",
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe773"),
@@ -219,7 +263,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = context.API.GetTranslation("flowlauncher_plugin_sys_emptyrecyclebin_cmd"),
+ Title = "Empty Recycle Bin",
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_emptyrecyclebin"),
IcoPath = "Images\\recyclebin.png",
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe74d"),
@@ -242,7 +286,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = context.API.GetTranslation("flowlauncher_plugin_sys_openrecyclebin_cmd"),
+ Title = "Open Recycle Bin",
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_openrecyclebin"),
IcoPath = "Images\\openrecyclebin.png",
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe74d"),
@@ -257,7 +301,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = context.API.GetTranslation("flowlauncher_plugin_sys_exit_cmd"),
+ Title = "Exit",
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_exit"),
IcoPath = "Images\\app.png",
Action = c =>
@@ -268,7 +312,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = context.API.GetTranslation("flowlauncher_plugin_sys_save_all_settings_cmd"),
+ Title = "Save Settings",
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_save_all_settings"),
IcoPath = "Images\\app.png",
Action = c =>
@@ -281,7 +325,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = context.API.GetTranslation("flowlauncher_plugin_sys_restart_cmd"),
+ Title = "Restart Flow Launcher",
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_restart"),
IcoPath = "Images\\app.png",
Action = c =>
@@ -292,7 +336,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = context.API.GetTranslation("flowlauncher_plugin_sys_setting_cmd"),
+ Title = "Settings",
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_setting"),
IcoPath = "Images\\app.png",
Action = c =>
@@ -303,7 +347,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = context.API.GetTranslation("flowlauncher_plugin_sys_reload_plugin_data_cmd"),
+ Title = "Reload Plugin Data",
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_reload_plugin_data"),
IcoPath = "Images\\app.png",
Action = c =>
@@ -317,13 +361,13 @@ namespace Flow.Launcher.Plugin.Sys
context.API.GetTranslation(
"flowlauncher_plugin_sys_dlgtext_all_applicableplugins_reloaded")),
System.Threading.Tasks.TaskScheduler.Current);
-
+
return true;
}
},
new Result
{
- Title = context.API.GetTranslation("flowlauncher_plugin_sys_check_for_update_cmd"),
+ Title = "Check For Update",
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_check_for_update"),
IcoPath = "Images\\checkupdate.png",
Action = c =>
@@ -335,7 +379,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = context.API.GetTranslation("flowlauncher_plugin_sys_open_log_location_cmd"),
+ Title = "Open Log Location",
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_open_log_location"),
IcoPath = "Images\\app.png",
Action = c =>
@@ -347,7 +391,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = context.API.GetTranslation("flowlauncher_plugin_sys_open_docs_tips_cmd"),
+ Title = "Flow Launcher Tips",
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_open_docs_tips"),
IcoPath = "Images\\app.png",
Action = c =>
@@ -358,7 +402,7 @@ namespace Flow.Launcher.Plugin.Sys
},
new Result
{
- Title = context.API.GetTranslation("flowlauncher_plugin_sys_open_userdata_location_cmd"),
+ Title = "Flow Launcher UserData Folder",
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_open_userdata_location"),
IcoPath = "Images\\app.png",
Action = c =>
From c80a638b65e9632fe8778d646e40923dd908b199 Mon Sep 17 00:00:00 2001
From: Hongtao Zhang
Date: Mon, 15 Jan 2024 16:49:46 -0600
Subject: [PATCH 040/161] fix multiple enumeration and revert logic for single
update
---
.../PluginsManager.cs | 235 ++++++++++--------
1 file changed, 133 insertions(+), 102 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index cd77e6daf..8cd58ac52 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -60,7 +60,8 @@ namespace Flow.Launcher.Plugin.PluginsManager
AutoCompleteText = $"{Context.CurrentPluginMetadata.ActionKeyword} {Settings.InstallCommand} ",
Action = _ =>
{
- Context.API.ChangeQuery($"{Context.CurrentPluginMetadata.ActionKeyword} {Settings.InstallCommand} ");
+ Context.API.ChangeQuery(
+ $"{Context.CurrentPluginMetadata.ActionKeyword} {Settings.InstallCommand} ");
return false;
}
},
@@ -71,7 +72,8 @@ namespace Flow.Launcher.Plugin.PluginsManager
AutoCompleteText = $"{Context.CurrentPluginMetadata.ActionKeyword} {Settings.UninstallCommand} ",
Action = _ =>
{
- Context.API.ChangeQuery($"{Context.CurrentPluginMetadata.ActionKeyword} {Settings.UninstallCommand} ");
+ Context.API.ChangeQuery(
+ $"{Context.CurrentPluginMetadata.ActionKeyword} {Settings.UninstallCommand} ");
return false;
}
},
@@ -82,7 +84,8 @@ namespace Flow.Launcher.Plugin.PluginsManager
AutoCompleteText = $"{Context.CurrentPluginMetadata.ActionKeyword} {Settings.UpdateCommand} ",
Action = _ =>
{
- Context.API.ChangeQuery($"{Context.CurrentPluginMetadata.ActionKeyword} {Settings.UpdateCommand} ");
+ Context.API.ChangeQuery(
+ $"{Context.CurrentPluginMetadata.ActionKeyword} {Settings.UpdateCommand} ");
return false;
}
}
@@ -121,14 +124,14 @@ namespace Flow.Launcher.Plugin.PluginsManager
if (Settings.AutoRestartAfterChanging)
{
message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_prompt"),
- plugin.Name, plugin.Author,
- Environment.NewLine, Environment.NewLine);
+ 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);
+ plugin.Name, plugin.Author,
+ Environment.NewLine);
}
if (MessageBox.Show(message, Context.API.GetTranslation("plugin_pluginsmanager_install_title"),
@@ -155,16 +158,17 @@ 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.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)
{
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;
}
@@ -172,27 +176,29 @@ namespace Flow.Launcher.Plugin.PluginsManager
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));
+ 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));
+ string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_success_no_restart"),
+ plugin.Name));
}
}
- internal async ValueTask> RequestUpdateAsync(string search, CancellationToken token, bool usePrimaryUrlOnly = false)
+ internal async ValueTask> RequestUpdateAsync(string search, CancellationToken token,
+ bool usePrimaryUrlOnly = false)
{
await PluginsManifest.UpdateManifestAsync(token, usePrimaryUrlOnly);
- var resultsForUpdate =
+ var resultsForUpdate = (
from existingPlugin in Context.API.GetAllPlugins()
join pluginFromManifest in PluginsManifest.UserPlugins
on existingPlugin.Metadata.ID equals pluginFromManifest.ID
- where existingPlugin.Metadata.Version.CompareTo(pluginFromManifest.Version) <
+ where String.Compare(existingPlugin.Metadata.Version, pluginFromManifest.Version,
+ StringComparison.InvariantCulture) <
0 // if current version precedes manifest version
&& !PluginManager.PluginModified(existingPlugin.Metadata.ID)
select
@@ -205,7 +211,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
existingPlugin.Metadata.IcoPath,
PluginExistingMetadata = existingPlugin.Metadata,
PluginNewUserPlugin = pluginFromManifest
- };
+ }).ToList();
if (!resultsForUpdate.Any())
return new List
@@ -227,68 +233,77 @@ namespace Flow.Launcher.Plugin.PluginsManager
IcoPath = x.IcoPath,
Action = e =>
{
-
string message;
if (Settings.AutoRestartAfterChanging)
{
- message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_prompt"),
- x.Name, x.Author,
- Environment.NewLine, Environment.NewLine);
+ 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);
+ 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"),
- MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+ MessageBoxButton.YesNo) != MessageBoxResult.Yes)
{
- var downloadToFilePath = Path.Combine(Path.GetTempPath(),
- $"{x.Name}-{x.NewVersion}.zip");
-
- _ = Task.Run(async delegate
- {
- if (File.Exists(downloadToFilePath))
- {
- File.Delete(downloadToFilePath);
- }
-
- await Http.DownloadAsync(x.PluginNewUserPlugin.UrlDownload, downloadToFilePath)
- .ConfigureAwait(false);
-
- PluginManager.UpdatePlugin(x.PluginExistingMetadata, x.PluginNewUserPlugin, downloadToFilePath);
-
- 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}",
- t.Exception.InnerException);
- Context.API.ShowMsg(
- Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
- string.Format(
- Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"),
- x.Name));
- }, TaskContinuationOptions.OnlyOnFaulted);
-
- return true;
+ return false;
}
- return false;
+ var downloadToFilePath = Path.Combine(Path.GetTempPath(),
+ $"{x.Name}-{x.NewVersion}.zip");
+
+ _ = Task.Run(async delegate
+ {
+ if (File.Exists(downloadToFilePath))
+ {
+ File.Delete(downloadToFilePath);
+ }
+
+ await Http.DownloadAsync(x.PluginNewUserPlugin.UrlDownload, downloadToFilePath)
+ .ConfigureAwait(false);
+
+ PluginManager.UpdatePlugin(x.PluginExistingMetadata, x.PluginNewUserPlugin,
+ downloadToFilePath);
+
+ 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}",
+ t.Exception.InnerException);
+ Context.API.ShowMsg(
+ Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
+ string.Format(
+ Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"),
+ x.Name));
+ }, TaskContinuationOptions.OnlyOnFaulted);
+
+ return true;
+
},
ContextData =
new UserPlugin
@@ -298,6 +313,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
}
});
+ // Update all result
if (resultsForUpdate.Count() > 1)
{
var updateAllResult = new Result
@@ -310,25 +326,28 @@ namespace Flow.Launcher.Plugin.PluginsManager
string message;
if (Settings.AutoRestartAfterChanging)
{
- message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_prompt"),
- resultsForUpdate.Count(), Environment.NewLine);
+ message = string.Format(
+ Context.API.GetTranslation("plugin_pluginsmanager_update_all_prompt"),
+ resultsForUpdate.Count(), Environment.NewLine);
}
else
{
- message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_prompt_no_restart"),
- resultsForUpdate.Count());
+ message = string.Format(
+ Context.API.GetTranslation("plugin_pluginsmanager_update_all_prompt_no_restart"),
+ resultsForUpdate.Count());
}
if (MessageBox.Show(message,
- Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
- MessageBoxButton.YesNo) == MessageBoxResult.No)
+ Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
+ MessageBoxButton.YesNo) == MessageBoxResult.No)
{
return false;
}
await Task.WhenAll(resultsForUpdate.Select(async plugin =>
{
- var downloadToFilePath = Path.Combine(Path.GetTempPath(), $"{plugin.Name}-{plugin.NewVersion}.zip");
+ var downloadToFilePath = Path.Combine(Path.GetTempPath(),
+ $"{plugin.Name}-{plugin.NewVersion}.zip");
try
{
@@ -340,7 +359,8 @@ namespace Flow.Launcher.Plugin.PluginsManager
await Http.DownloadAsync(plugin.PluginNewUserPlugin.UrlDownload, downloadToFilePath)
.ConfigureAwait(false);
- PluginManager.UpdatePlugin(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin, downloadToFilePath);
+ PluginManager.UpdatePlugin(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin,
+ downloadToFilePath);
}
catch (Exception ex)
{
@@ -356,15 +376,17 @@ namespace Flow.Launcher.Plugin.PluginsManager
if (Settings.AutoRestartAfterChanging)
{
Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
- string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_success_restart"),
- resultsForUpdate.Count()));
+ string.Format(
+ Context.API.GetTranslation("plugin_pluginsmanager_update_all_success_restart"),
+ resultsForUpdate.Count()));
Context.API.RestartApp();
}
else
{
Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
- string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_success_no_restart"),
- resultsForUpdate.Count()));
+ string.Format(
+ Context.API.GetTranslation("plugin_pluginsmanager_update_all_success_no_restart"),
+ resultsForUpdate.Count()));
}
return true;
@@ -429,9 +451,11 @@ namespace Flow.Launcher.Plugin.PluginsManager
if (Settings.WarnFromUnknownSource)
{
if (!InstallSourceKnown(plugin.UrlDownload)
- && MessageBox.Show(string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_unknown_source_warning"),
+ && MessageBox.Show(string.Format(
+ Context.API.GetTranslation("plugin_pluginsmanager_install_unknown_source_warning"),
Environment.NewLine),
- Context.API.GetTranslation("plugin_pluginsmanager_install_unknown_source_warning_title"),
+ Context.API.GetTranslation(
+ "plugin_pluginsmanager_install_unknown_source_warning_title"),
MessageBoxButton.YesNo) == MessageBoxResult.No)
return false;
}
@@ -443,10 +467,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
}
};
- return new List
- {
- result
- };
+ return new List { result };
}
private bool InstallSourceKnown(string url)
@@ -455,10 +476,12 @@ namespace Flow.Launcher.Plugin.PluginsManager
var acceptedSource = "https://github.com";
var constructedUrlPart = string.Format("{0}/{1}/", acceptedSource, author);
- return url.StartsWith(acceptedSource) && Context.API.GetAllPlugins().Any(x => x.Metadata.Website.StartsWith(constructedUrlPart));
+ return url.StartsWith(acceptedSource) &&
+ Context.API.GetAllPlugins().Any(x => x.Metadata.Website.StartsWith(constructedUrlPart));
}
- internal async ValueTask> RequestInstallOrUpdate(string search, CancellationToken token, bool usePrimaryUrlOnly = false)
+ internal async ValueTask> RequestInstallOrUpdate(string search, CancellationToken token,
+ bool usePrimaryUrlOnly = false)
{
await PluginsManifest.UpdateManifestAsync(token, usePrimaryUrlOnly);
@@ -497,7 +520,8 @@ namespace Flow.Launcher.Plugin.PluginsManager
private void Install(UserPlugin plugin, string downloadedFilePath)
{
if (!File.Exists(downloadedFilePath))
- throw new FileNotFoundException($"Plugin {plugin.ID} zip file not found at {downloadedFilePath}", downloadedFilePath);
+ throw new FileNotFoundException($"Plugin {plugin.ID} zip file not found at {downloadedFilePath}",
+ downloadedFilePath);
try
{
PluginManager.InstallPlugin(plugin, downloadedFilePath);
@@ -506,19 +530,21 @@ namespace Flow.Launcher.Plugin.PluginsManager
catch (FileNotFoundException e)
{
Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
- Context.API.GetTranslation("plugin_pluginsmanager_install_errormetadatafile"));
+ Context.API.GetTranslation("plugin_pluginsmanager_install_errormetadatafile"));
Log.Exception("Flow.Launcher.Plugin.PluginsManager", e.Message, 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));
+ 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));
+ string.Format(Context.API.GetTranslation("plugin_pluginsmanager_plugin_modified_error"),
+ plugin.Name));
Log.Exception("Flow.Launcher.Plugin.PluginsManager", e.Message, e);
}
}
@@ -538,15 +564,17 @@ namespace Flow.Launcher.Plugin.PluginsManager
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);
+ 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);
+ message = string.Format(
+ Context.API.GetTranslation("plugin_pluginsmanager_uninstall_prompt_no_restart"),
+ x.Metadata.Name, x.Metadata.Author,
+ Environment.NewLine);
}
if (MessageBox.Show(message,
@@ -561,9 +589,12 @@ namespace Flow.Launcher.Plugin.PluginsManager
}
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));
+ 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;
@@ -586,7 +617,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
{
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"));
+ Context.API.GetTranslation("plugin_pluginsmanager_plugin_modified_error"));
}
}
}
From 9d5f74ca8f3126d277580905a90aad4605c8e069 Mon Sep 17 00:00:00 2001
From: Florian Grabmeier
Date: Mon, 15 Jan 2024 20:33:53 +0100
Subject: [PATCH 041/161] Add sound effect volume
Signed-off-by: Florian Grabmeier
---
.../UserSettings/Settings.cs | 2 +
Flow.Launcher/Languages/en.xaml | 2 +
Flow.Launcher/MainWindow.xaml.cs | 7 +-
Flow.Launcher/Resources/open.wav | Bin 80116 -> 105884 bytes
Flow.Launcher/SettingWindow.xaml | 78 +++++++++++++++---
.../ViewModel/SettingWindowViewModel.cs | 9 ++
6 files changed, 83 insertions(+), 15 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index ca1674315..274f88dc6 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -54,6 +54,8 @@ namespace Flow.Launcher.Infrastructure.UserSettings
public bool UseGlyphIcons { get; set; } = true;
public bool UseAnimation { get; set; } = true;
public bool UseSound { get; set; } = true;
+ public double SoundVolume { get; set; } = 50;
+
public bool UseClock { get; set; } = true;
public bool UseDate { get; set; } = false;
public string TimeFormat { get; set; } = "hh:mm tt";
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index d36a49538..4bc79ccb3 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -156,6 +156,8 @@
Dark
Sound Effect
Play a small sound when the search window opens
+ Sound Effect Volume
+ Adjust the volume of the sound effect
Animation
Use Animation in UI
Animation Speed
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 3a914d488..70765c1dc 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -23,8 +23,7 @@ using System.Windows.Threading;
using System.Windows.Data;
using ModernWpf.Controls;
using Key = System.Windows.Input.Key;
-using System.Media;
-using static Flow.Launcher.ViewModel.SettingWindowViewModel;
+using System.Windows.Media;
namespace Flow.Launcher
{
@@ -39,7 +38,7 @@ namespace Flow.Launcher
private ContextMenu contextMenu;
private MainViewModel _viewModel;
private bool _animating;
- SoundPlayer animationSound = new SoundPlayer(AppDomain.CurrentDomain.BaseDirectory + "Resources\\open.wav");
+ MediaPlayer animationSound = new MediaPlayer();
#endregion
@@ -113,6 +112,8 @@ namespace Flow.Launcher
{
if (_settings.UseSound)
{
+ animationSound.Open(new Uri(AppDomain.CurrentDomain.BaseDirectory + "Resources\\open.wav"));
+ animationSound.Volume = _settings.SoundVolume / 100.0;
animationSound.Play();
}
UpdatePosition();
diff --git a/Flow.Launcher/Resources/open.wav b/Flow.Launcher/Resources/open.wav
index 4f13724f7093ad2d66c595cf8a672b6dabf008ba..0f692c75b377aec4a8682fc978d5d821ee39247b 100644
GIT binary patch
literal 105884
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