Skip to content

Commit 2c6fdc0

Browse files
authored
Merge branch 'dev' into 250320BookmarkFavicon
2 parents 3387c2a + 3b43d45 commit 2c6fdc0

File tree

135 files changed

+6165
-3241
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

135 files changed

+6165
-3241
lines changed

Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs

Lines changed: 62 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
using Flow.Launcher.Infrastructure.Logger;
2-
using Flow.Launcher.Infrastructure.UserSettings;
3-
using Flow.Launcher.Plugin;
4-
using Flow.Launcher.Plugin.SharedCommands;
5-
using System;
1+
using System;
62
using System.Collections.Generic;
3+
using System.IO;
74
using System.Linq;
85
using System.Windows;
96
using System.Windows.Forms;
10-
using Flow.Launcher.Core.Resource;
117
using CommunityToolkit.Mvvm.DependencyInjection;
8+
using Flow.Launcher.Infrastructure.Logger;
9+
using Flow.Launcher.Infrastructure.UserSettings;
10+
using Flow.Launcher.Plugin;
11+
using Flow.Launcher.Plugin.SharedCommands;
1212

1313
namespace Flow.Launcher.Core.ExternalPlugins.Environments
1414
{
@@ -42,8 +42,11 @@ internal AbstractPluginEnvironment(List<PluginMetadata> pluginMetadataList, Plug
4242

4343
internal IEnumerable<PluginPair> Setup()
4444
{
45+
// If no plugin is using the language, return empty list
4546
if (!PluginMetadataList.Any(o => o.Language.Equals(Language, StringComparison.OrdinalIgnoreCase)))
47+
{
4648
return new List<PluginPair>();
49+
}
4750

4851
if (!string.IsNullOrEmpty(PluginsSettingsFilePath) && FilesFolders.FileExists(PluginsSettingsFilePath))
4952
{
@@ -55,24 +58,55 @@ internal IEnumerable<PluginPair> Setup()
5558
}
5659

5760
var noRuntimeMessage = string.Format(
58-
InternationalizationManager.Instance.GetTranslation("runtimePluginInstalledChooseRuntimePrompt"),
61+
API.GetTranslation("runtimePluginInstalledChooseRuntimePrompt"),
5962
Language,
6063
EnvName,
6164
Environment.NewLine
6265
);
6366
if (API.ShowMsgBox(noRuntimeMessage, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
6467
{
65-
var msg = string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginChooseRuntimeExecutable"), EnvName);
66-
string selectedFile;
68+
var msg = string.Format(API.GetTranslation("runtimePluginChooseRuntimeExecutable"), EnvName);
6769

68-
selectedFile = GetFileFromDialog(msg, FileDialogFilter);
70+
var selectedFile = GetFileFromDialog(msg, FileDialogFilter);
6971

7072
if (!string.IsNullOrEmpty(selectedFile))
73+
{
7174
PluginsSettingsFilePath = selectedFile;
72-
75+
}
7376
// Nothing selected because user pressed cancel from the file dialog window
74-
if (string.IsNullOrEmpty(selectedFile))
75-
InstallEnvironment();
77+
else
78+
{
79+
var forceDownloadMessage = string.Format(
80+
API.GetTranslation("runtimeExecutableInvalidChooseDownload"),
81+
Language,
82+
EnvName,
83+
Environment.NewLine
84+
);
85+
86+
// Let users select valid path or choose to download
87+
while (string.IsNullOrEmpty(selectedFile))
88+
{
89+
if (API.ShowMsgBox(forceDownloadMessage, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.Yes)
90+
{
91+
// Continue select file
92+
selectedFile = GetFileFromDialog(msg, FileDialogFilter);
93+
}
94+
else
95+
{
96+
// User selected no, break the loop
97+
break;
98+
}
99+
}
100+
101+
if (!string.IsNullOrEmpty(selectedFile))
102+
{
103+
PluginsSettingsFilePath = selectedFile;
104+
}
105+
else
106+
{
107+
InstallEnvironment();
108+
}
109+
}
76110
}
77111
else
78112
{
@@ -85,7 +119,7 @@ internal IEnumerable<PluginPair> Setup()
85119
}
86120
else
87121
{
88-
API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginUnableToSetExecutablePath"), Language));
122+
API.ShowMsgBox(string.Format(API.GetTranslation("runtimePluginUnableToSetExecutablePath"), Language));
89123
Log.Error("PluginsLoader",
90124
$"Not able to successfully set {EnvName} path, setting's plugin executable path variable is still an empty string.",
91125
$"{Language}Environment");
@@ -98,13 +132,11 @@ internal IEnumerable<PluginPair> Setup()
98132

99133
private void EnsureLatestInstalled(string expectedPath, string currentPath, string installedDirPath)
100134
{
101-
if (expectedPath == currentPath)
102-
return;
135+
if (expectedPath == currentPath) return;
103136

104137
FilesFolders.RemoveFolderIfExists(installedDirPath, (s) => API.ShowMsgBox(s));
105138

106139
InstallEnvironment();
107-
108140
}
109141

110142
internal abstract PluginPair CreatePluginPair(string filePath, PluginMetadata metadata);
@@ -116,13 +148,16 @@ private IEnumerable<PluginPair> SetPathForPluginPairs(string filePath, string la
116148
foreach (var metadata in PluginMetadataList)
117149
{
118150
if (metadata.Language.Equals(languageToSet, StringComparison.OrdinalIgnoreCase))
151+
{
152+
metadata.AssemblyName = string.Empty;
119153
pluginPairs.Add(CreatePluginPair(filePath, metadata));
154+
}
120155
}
121156

122157
return pluginPairs;
123158
}
124159

125-
private string GetFileFromDialog(string title, string filter = "")
160+
private static string GetFileFromDialog(string title, string filter = "")
126161
{
127162
var dlg = new OpenFileDialog
128163
{
@@ -136,7 +171,6 @@ private string GetFileFromDialog(string title, string filter = "")
136171

137172
var result = dlg.ShowDialog();
138173
return result == DialogResult.OK ? dlg.FileName : string.Empty;
139-
140174
}
141175

142176
/// <summary>
@@ -179,31 +213,33 @@ public static void PreStartPluginExecutablePathUpdate(Settings settings)
179213
else
180214
{
181215
if (IsUsingPortablePath(settings.PluginSettings.PythonExecutablePath, DataLocation.PythonEnvironmentName))
216+
{
182217
settings.PluginSettings.PythonExecutablePath
183218
= GetUpdatedEnvironmentPath(settings.PluginSettings.PythonExecutablePath);
219+
}
184220

185221
if (IsUsingPortablePath(settings.PluginSettings.NodeExecutablePath, DataLocation.NodeEnvironmentName))
222+
{
186223
settings.PluginSettings.NodeExecutablePath
187224
= GetUpdatedEnvironmentPath(settings.PluginSettings.NodeExecutablePath);
225+
}
188226
}
189227
}
190228

191229
private static bool IsUsingPortablePath(string filePath, string pluginEnvironmentName)
192230
{
193-
if (string.IsNullOrEmpty(filePath))
194-
return false;
231+
if (string.IsNullOrEmpty(filePath)) return false;
195232

196233
// DataLocation.PortableDataPath returns the current portable path, this determines if an out
197234
// of date path is also a portable path.
198-
var portableAppEnvLocation = $"UserData\\{DataLocation.PluginEnvironments}\\{pluginEnvironmentName}";
235+
var portableAppEnvLocation = Path.Combine("UserData", DataLocation.PluginEnvironments, pluginEnvironmentName);
199236

200237
return filePath.Contains(portableAppEnvLocation);
201238
}
202239

203240
private static bool IsUsingRoamingPath(string filePath)
204241
{
205-
if (string.IsNullOrEmpty(filePath))
206-
return false;
242+
if (string.IsNullOrEmpty(filePath)) return false;
207243

208244
return filePath.StartsWith(DataLocation.RoamingDataPath);
209245
}
@@ -213,8 +249,8 @@ private static string GetUpdatedEnvironmentPath(string filePath)
213249
var index = filePath.IndexOf(DataLocation.PluginEnvironments);
214250

215251
// get the substring after "Environments" because we can not determine it dynamically
216-
var ExecutablePathSubstring = filePath.Substring(index + DataLocation.PluginEnvironments.Count());
217-
return $"{DataLocation.PluginEnvironmentsPath}{ExecutablePathSubstring}";
252+
var executablePathSubstring = filePath[(index + DataLocation.PluginEnvironments.Length)..];
253+
return $"{DataLocation.PluginEnvironmentsPath}{executablePathSubstring}";
218254
}
219255
}
220256
}

Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
using Droplex;
1+
using System.Collections.Generic;
2+
using System.IO;
3+
using Droplex;
24
using Flow.Launcher.Core.Plugin;
35
using Flow.Launcher.Infrastructure.UserSettings;
46
using Flow.Launcher.Plugin;
57
using Flow.Launcher.Plugin.SharedCommands;
6-
using System.Collections.Generic;
7-
using System.IO;
88

99
namespace Flow.Launcher.Core.ExternalPlugins.Environments
1010
{
@@ -22,7 +22,11 @@ internal class PythonEnvironment : AbstractPluginEnvironment
2222

2323
internal override string FileDialogFilter => "Python|pythonw.exe";
2424

25-
internal override string PluginsSettingsFilePath { get => PluginSettings.PythonExecutablePath; set => PluginSettings.PythonExecutablePath = value; }
25+
internal override string PluginsSettingsFilePath
26+
{
27+
get => PluginSettings.PythonExecutablePath;
28+
set => PluginSettings.PythonExecutablePath = value;
29+
}
2630

2731
internal PythonEnvironment(List<PluginMetadata> pluginMetadataList, PluginsSettings pluginSettings) : base(pluginMetadataList, pluginSettings) { }
2832

Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
using System.Collections.Generic;
2+
using System.IO;
23
using Droplex;
4+
using Flow.Launcher.Core.Plugin;
35
using Flow.Launcher.Infrastructure.UserSettings;
4-
using Flow.Launcher.Plugin.SharedCommands;
56
using Flow.Launcher.Plugin;
6-
using System.IO;
7-
using Flow.Launcher.Core.Plugin;
7+
using Flow.Launcher.Plugin.SharedCommands;
88

99
namespace Flow.Launcher.Core.ExternalPlugins.Environments
1010
{
@@ -19,7 +19,11 @@ internal class TypeScriptEnvironment : AbstractPluginEnvironment
1919
internal override string InstallPath => Path.Combine(EnvPath, "Node-v16.18.0");
2020
internal override string ExecutablePath => Path.Combine(InstallPath, "node-v16.18.0-win-x64\\node.exe");
2121

22-
internal override string PluginsSettingsFilePath { get => PluginSettings.NodeExecutablePath; set => PluginSettings.NodeExecutablePath = value; }
22+
internal override string PluginsSettingsFilePath
23+
{
24+
get => PluginSettings.NodeExecutablePath;
25+
set => PluginSettings.NodeExecutablePath = value;
26+
}
2327

2428
internal TypeScriptEnvironment(List<PluginMetadata> pluginMetadataList, PluginsSettings pluginSettings) : base(pluginMetadataList, pluginSettings) { }
2529

Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
using System.Collections.Generic;
2+
using System.IO;
23
using Droplex;
4+
using Flow.Launcher.Core.Plugin;
35
using Flow.Launcher.Infrastructure.UserSettings;
4-
using Flow.Launcher.Plugin.SharedCommands;
56
using Flow.Launcher.Plugin;
6-
using System.IO;
7-
using Flow.Launcher.Core.Plugin;
7+
using Flow.Launcher.Plugin.SharedCommands;
88

99
namespace Flow.Launcher.Core.ExternalPlugins.Environments
1010
{
@@ -19,7 +19,11 @@ internal class TypeScriptV2Environment : AbstractPluginEnvironment
1919
internal override string InstallPath => Path.Combine(EnvPath, "Node-v16.18.0");
2020
internal override string ExecutablePath => Path.Combine(InstallPath, "node-v16.18.0-win-x64\\node.exe");
2121

22-
internal override string PluginsSettingsFilePath { get => PluginSettings.NodeExecutablePath; set => PluginSettings.NodeExecutablePath = value; }
22+
internal override string PluginsSettingsFilePath
23+
{
24+
get => PluginSettings.NodeExecutablePath;
25+
set => PluginSettings.NodeExecutablePath = value;
26+
}
2327

2428
internal TypeScriptV2Environment(List<PluginMetadata> pluginMetadataList, PluginsSettings pluginSettings) : base(pluginMetadataList, pluginSettings) { }
2529

Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,16 @@
11
using Flow.Launcher.Core.Resource;
2-
using Flow.Launcher.Infrastructure;
32
using System;
43
using System.Collections.Generic;
54
using System.Diagnostics;
65
using System.IO;
7-
using System.Linq;
86
using System.Text;
97
using System.Text.Json;
108
using System.Threading;
119
using System.Threading.Tasks;
1210
using Flow.Launcher.Infrastructure.Logger;
13-
using Flow.Launcher.Infrastructure.UserSettings;
1411
using Flow.Launcher.Plugin;
1512
using Microsoft.IO;
1613
using System.Windows;
17-
using System.Windows.Controls;
18-
using YamlDotNet.Serialization;
19-
using YamlDotNet.Serialization.NamingConventions;
20-
using CheckBox = System.Windows.Controls.CheckBox;
21-
using Control = System.Windows.Controls.Control;
22-
using Orientation = System.Windows.Controls.Orientation;
23-
using TextBox = System.Windows.Controls.TextBox;
24-
using UserControl = System.Windows.Controls.UserControl;
25-
using System.Windows.Documents;
2614

2715
namespace Flow.Launcher.Core.Plugin
2816
{
@@ -42,7 +30,7 @@ internal abstract class JsonRPCPlugin : JsonRPCPluginBase
4230
private int RequestId { get; set; }
4331

4432
private string SettingConfigurationPath => Path.Combine(Context.CurrentPluginMetadata.PluginDirectory, "SettingsTemplate.yaml");
45-
private string SettingPath => Path.Combine(DataLocation.PluginSettingsDirectory, Context.CurrentPluginMetadata.Name, "Settings.json");
33+
private string SettingPath => Path.Combine(Context.CurrentPluginMetadata.PluginSettingsDirectoryPath, "Settings.json");
4634

4735
public override List<Result> LoadContextMenus(Result selectedResult)
4836
{

Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,15 @@
11
using Flow.Launcher.Core.Resource;
2-
using Flow.Launcher.Infrastructure;
32
using System;
43
using System.Collections.Generic;
5-
using System.Diagnostics;
64
using System.IO;
75
using System.Linq;
8-
using System.Text;
96
using System.Text.Json;
107
using System.Threading;
118
using System.Threading.Tasks;
12-
using Flow.Launcher.Infrastructure.Logger;
13-
using Flow.Launcher.Infrastructure.UserSettings;
149
using Flow.Launcher.Plugin;
15-
using Microsoft.IO;
16-
using System.Windows;
17-
using System.Windows.Controls;
1810
using YamlDotNet.Serialization;
1911
using YamlDotNet.Serialization.NamingConventions;
20-
using CheckBox = System.Windows.Controls.CheckBox;
2112
using Control = System.Windows.Controls.Control;
22-
using Orientation = System.Windows.Controls.Orientation;
23-
using TextBox = System.Windows.Controls.TextBox;
24-
using UserControl = System.Windows.Controls.UserControl;
25-
using System.Windows.Documents;
26-
using static System.Windows.Forms.LinkLabel;
27-
using Droplex;
28-
using System.Windows.Forms;
29-
using Microsoft.VisualStudio.Threading;
3013

3114
namespace Flow.Launcher.Core.Plugin
3215
{
@@ -44,8 +27,7 @@ public abstract class JsonRPCPluginBase : IAsyncPlugin, IContextMenu, ISettingPr
4427
private string SettingConfigurationPath =>
4528
Path.Combine(Context.CurrentPluginMetadata.PluginDirectory, "SettingsTemplate.yaml");
4629

47-
private string SettingDirectory => Path.Combine(DataLocation.PluginSettingsDirectory,
48-
Context.CurrentPluginMetadata.Name);
30+
private string SettingDirectory => Context.CurrentPluginMetadata.PluginSettingsDirectoryPath;
4931

5032
private string SettingPath => Path.Combine(SettingDirectory, "Settings.json");
5133

@@ -166,13 +148,5 @@ public Control CreateSettingPanel()
166148
{
167149
return Settings.CreateSettingPanel();
168150
}
169-
170-
public void DeletePluginSettingsDirectory()
171-
{
172-
if (Directory.Exists(SettingDirectory))
173-
{
174-
Directory.Delete(SettingDirectory, true);
175-
}
176-
}
177151
}
178152
}

0 commit comments

Comments
 (0)