From 20ffff6d1b8464d6aa20c7e32e12aac1e5abd6a0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 9 Jan 2025 21:30:11 +0800
Subject: [PATCH 01/31] Use api to call api functions
---
Flow.Launcher/ActionKeywords.xaml.cs | 2 +-
Flow.Launcher/App.xaml.cs | 4 +++-
Flow.Launcher/CustomQueryHotkeySetting.xaml.cs | 2 +-
Flow.Launcher/CustomShortcutSetting.xaml.cs | 4 ++--
Flow.Launcher/Helper/HotKeyMapper.cs | 2 +-
Flow.Launcher/PriorityChangeWindow.xaml.cs | 4 ++--
.../ViewModels/SettingsPaneAboutViewModel.cs | 2 +-
.../ViewModels/SettingsPaneHotkeyViewModel.cs | 12 ++++++------
.../ViewModels/SettingsPaneProxyViewModel.cs | 2 +-
.../ViewModels/SettingsPaneThemeViewModel.cs | 2 +-
10 files changed, 19 insertions(+), 17 deletions(-)
diff --git a/Flow.Launcher/ActionKeywords.xaml.cs b/Flow.Launcher/ActionKeywords.xaml.cs
index ba47a4ded..c3966e618 100644
--- a/Flow.Launcher/ActionKeywords.xaml.cs
+++ b/Flow.Launcher/ActionKeywords.xaml.cs
@@ -44,7 +44,7 @@ namespace Flow.Launcher
else
{
string msg = translater.GetTranslation("newActionKeywordsHasBeenAssigned");
- MessageBoxEx.Show(msg);
+ App.API.ShowMsgBox(msg);
}
}
}
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 4d1adc6cd..58da35e85 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -15,13 +15,15 @@ using Flow.Launcher.Infrastructure.Http;
using Flow.Launcher.Infrastructure.Image;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
+using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
namespace Flow.Launcher
{
- public partial class App : IDisposable, ISingleInstanceApp
+ public partial class App : IDisposable, ISingleInstanceApp, IApp
{
+ public IPublicAPI PublicAPI => API;
public static PublicAPIInstance API { get; private set; }
private const string Unique = "Flow.Launcher_Unique_Application_Mutex";
private static bool _disposed;
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index 81e7600b8..47460ff7d 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -63,7 +63,7 @@ namespace Flow.Launcher
o.ActionKeyword == item.ActionKeyword && o.Hotkey == item.Hotkey);
if (updateCustomHotkey == null)
{
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("invalidPluginHotkey"));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("invalidPluginHotkey"));
Close();
return;
}
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml.cs b/Flow.Launcher/CustomShortcutSetting.xaml.cs
index dec3506eb..4589b45ec 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml.cs
+++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs
@@ -43,13 +43,13 @@ namespace Flow.Launcher
{
if (String.IsNullOrEmpty(Key) || String.IsNullOrEmpty(Value))
{
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("emptyShortcut"));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("emptyShortcut"));
return;
}
// Check if key is modified or adding a new one
if (((update && originalKey != Key) || !update) && _hotkeyVm.DoesShortcutExist(Key))
{
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("duplicateShortcut"));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("duplicateShortcut"));
return;
}
DialogResult = !update || originalKey != Key || originalValue != Value;
diff --git a/Flow.Launcher/Helper/HotKeyMapper.cs b/Flow.Launcher/Helper/HotKeyMapper.cs
index 8b30b8be1..b40406e42 100644
--- a/Flow.Launcher/Helper/HotKeyMapper.cs
+++ b/Flow.Launcher/Helper/HotKeyMapper.cs
@@ -46,7 +46,7 @@ internal static class HotKeyMapper
{
string errorMsg = string.Format(InternationalizationManager.Instance.GetTranslation("registerHotkeyFailed"), hotkeyStr);
string errorMsgTitle = InternationalizationManager.Instance.GetTranslation("MessageBoxTitle");
- MessageBoxEx.Show(errorMsg, errorMsgTitle);
+ App.API.ShowMsgBox(errorMsg, errorMsgTitle);
}
}
diff --git a/Flow.Launcher/PriorityChangeWindow.xaml.cs b/Flow.Launcher/PriorityChangeWindow.xaml.cs
index 2154b058d..fbe2a941d 100644
--- a/Flow.Launcher/PriorityChangeWindow.xaml.cs
+++ b/Flow.Launcher/PriorityChangeWindow.xaml.cs
@@ -24,7 +24,7 @@ namespace Flow.Launcher
this.pluginViewModel = pluginViewModel;
if (plugin == null)
{
- MessageBoxEx.Show(translater.GetTranslation("cannotFindSpecifiedPlugin"));
+ App.API.ShowMsgBox(translater.GetTranslation("cannotFindSpecifiedPlugin"));
Close();
}
}
@@ -44,7 +44,7 @@ namespace Flow.Launcher
else
{
string msg = translater.GetTranslation("invalidPriority");
- MessageBoxEx.Show(msg);
+ App.API.ShowMsgBox(msg);
}
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
index 6e81db5e0..05fb16f5c 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -62,7 +62,7 @@ public partial class SettingsPaneAboutViewModel : BaseModel
[RelayCommand]
private void AskClearLogFolderConfirmation()
{
- var confirmResult = MessageBoxEx.Show(
+ var confirmResult = App.API.ShowMsgBox(
InternationalizationManager.Instance.GetTranslation("clearlogfolderMessage"),
InternationalizationManager.Instance.GetTranslation("clearlogfolder"),
MessageBoxButton.YesNo
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
index 6d8af9a3f..fb57f499b 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
@@ -42,11 +42,11 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
var item = SelectedCustomPluginHotkey;
if (item is null)
{
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
return;
}
- var result = MessageBoxEx.Show(
+ var result = App.API.ShowMsgBox(
string.Format(
InternationalizationManager.Instance.GetTranslation("deleteCustomHotkeyWarning"), item.Hotkey
),
@@ -67,7 +67,7 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
var item = SelectedCustomPluginHotkey;
if (item is null)
{
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
return;
}
@@ -88,11 +88,11 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
var item = SelectedCustomShortcut;
if (item is null)
{
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
return;
}
- var result = MessageBoxEx.Show(
+ var result = App.API.ShowMsgBox(
string.Format(
InternationalizationManager.Instance.GetTranslation("deleteCustomShortcutWarning"), item.Key, item.Value
),
@@ -112,7 +112,7 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
var item = SelectedCustomShortcut;
if (item is null)
{
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
return;
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneProxyViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneProxyViewModel.cs
index 1c840fb27..e2f9e516c 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneProxyViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneProxyViewModel.cs
@@ -22,7 +22,7 @@ public partial class SettingsPaneProxyViewModel : BaseModel
private void OnTestProxyClicked()
{
var message = TestProxy();
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation(message));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation(message));
}
private string TestProxy()
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
index 8d8ccb780..980b2a811 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -49,7 +49,7 @@ public partial class SettingsPaneThemeViewModel : BaseModel
{
if (ThemeManager.Instance.BlurEnabled && value)
{
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("shadowEffectNotAllowed"));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("shadowEffectNotAllowed"));
return;
}
From 8b910500c6f3a2fe170cdc8261c6d0add722b744 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 9 Jan 2025 21:43:33 +0800
Subject: [PATCH 02/31] Add IApp & AppExtensions for accessing the properties &
functions from anywhere in the application
---
Flow.Launcher.Core/AppExtensions.cs | 15 +++++++++++++++
Flow.Launcher.Core/IApp.cs | 13 +++++++++++++
2 files changed, 28 insertions(+)
create mode 100644 Flow.Launcher.Core/AppExtensions.cs
create mode 100644 Flow.Launcher.Core/IApp.cs
diff --git a/Flow.Launcher.Core/AppExtensions.cs b/Flow.Launcher.Core/AppExtensions.cs
new file mode 100644
index 000000000..b02612d72
--- /dev/null
+++ b/Flow.Launcher.Core/AppExtensions.cs
@@ -0,0 +1,15 @@
+using System.Windows;
+using Flow.Launcher.Plugin;
+
+namespace Flow.Launcher.Core;
+
+///
+/// Extension properties and functions of the current application singleton object.
+///
+public static class AppExtensions
+{
+ ///
+ /// Gets the public API of the current application singleton object.
+ ///
+ public static IPublicAPI API => (Application.Current as IApp)!.PublicAPI;
+}
diff --git a/Flow.Launcher.Core/IApp.cs b/Flow.Launcher.Core/IApp.cs
new file mode 100644
index 000000000..233fd5ed1
--- /dev/null
+++ b/Flow.Launcher.Core/IApp.cs
@@ -0,0 +1,13 @@
+using Flow.Launcher.Plugin;
+
+namespace Flow.Launcher.Core
+{
+ ///
+ /// Interface for the current application singleton object exposing the properties
+ /// and functions that can be accessed from anywhere in the application.
+ ///
+ public interface IApp
+ {
+ public IPublicAPI PublicAPI { get; }
+ }
+}
From 88e84378daee2906bdbfa131ba4d012225464df1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 9 Jan 2025 21:44:24 +0800
Subject: [PATCH 03/31] Use api in app extensions to call api functions
---
Flow.Launcher.Core/Configuration/Portable.cs | 20 +++++++++----------
.../Environments/AbstractPluginEnvironment.cs | 6 +++---
.../Environments/PythonEnvironment.cs | 2 +-
.../Environments/TypeScriptEnvironment.cs | 2 +-
.../Environments/TypeScriptV2Environment.cs | 2 +-
Flow.Launcher.Core/Plugin/PluginManager.cs | 2 +-
Flow.Launcher.Core/Plugin/PluginsLoader.cs | 2 +-
.../Resource/Internationalization.cs | 2 +-
Flow.Launcher.Core/Resource/Theme.cs | 4 ++--
Flow.Launcher.Core/Updater.cs | 10 +++++-----
10 files changed, 26 insertions(+), 26 deletions(-)
diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs
index d7c73fb46..cb375c586 100644
--- a/Flow.Launcher.Core/Configuration/Portable.cs
+++ b/Flow.Launcher.Core/Configuration/Portable.cs
@@ -40,7 +40,7 @@ namespace Flow.Launcher.Core.Configuration
#endif
IndicateDeletion(DataLocation.PortableDataPath);
- MessageBoxEx.Show("Flow Launcher needs to restart to finish disabling portable mode, " +
+ AppExtensions.API.ShowMsgBox("Flow Launcher needs to restart to finish disabling portable mode, " +
"after the restart your portable data profile will be deleted and roaming data profile kept");
UpdateManager.RestartApp(Constant.ApplicationFileName);
@@ -64,7 +64,7 @@ namespace Flow.Launcher.Core.Configuration
#endif
IndicateDeletion(DataLocation.RoamingDataPath);
- MessageBoxEx.Show("Flow Launcher needs to restart to finish enabling portable mode, " +
+ AppExtensions.API.ShowMsgBox("Flow Launcher needs to restart to finish enabling portable mode, " +
"after the restart your roaming data profile will be deleted and portable data profile kept");
UpdateManager.RestartApp(Constant.ApplicationFileName);
@@ -95,13 +95,13 @@ namespace Flow.Launcher.Core.Configuration
public void MoveUserDataFolder(string fromLocation, string toLocation)
{
- FilesFolders.CopyAll(fromLocation, toLocation, MessageBoxEx.Show);
+ FilesFolders.CopyAll(fromLocation, toLocation, (s) => AppExtensions.API.ShowMsgBox(s));
VerifyUserDataAfterMove(fromLocation, toLocation);
}
public void VerifyUserDataAfterMove(string fromLocation, string toLocation)
{
- FilesFolders.VerifyBothFolderFilesEqual(fromLocation, toLocation, MessageBoxEx.Show);
+ FilesFolders.VerifyBothFolderFilesEqual(fromLocation, toLocation, (s) => AppExtensions.API.ShowMsgBox(s));
}
public void CreateShortcuts()
@@ -157,13 +157,13 @@ namespace Flow.Launcher.Core.Configuration
// delete it and prompt the user to pick the portable data location
if (File.Exists(roamingDataDeleteFilePath))
{
- FilesFolders.RemoveFolderIfExists(roamingDataDir, MessageBoxEx.Show);
+ FilesFolders.RemoveFolderIfExists(roamingDataDir, (s) => AppExtensions.API.ShowMsgBox(s));
- if (MessageBoxEx.Show("Flow Launcher has detected you enabled portable mode, " +
+ if (AppExtensions.API.ShowMsgBox("Flow Launcher has detected you enabled portable mode, " +
"would you like to move it to a different location?", string.Empty,
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
- FilesFolders.OpenPath(Constant.RootDirectory, MessageBoxEx.Show);
+ FilesFolders.OpenPath(Constant.RootDirectory, (s) => AppExtensions.API.ShowMsgBox(s));
Environment.Exit(0);
}
@@ -172,9 +172,9 @@ namespace Flow.Launcher.Core.Configuration
// delete it and notify the user about it.
else if (File.Exists(portableDataDeleteFilePath))
{
- FilesFolders.RemoveFolderIfExists(portableDataDir, MessageBoxEx.Show);
+ FilesFolders.RemoveFolderIfExists(portableDataDir, (s) => AppExtensions.API.ShowMsgBox(s));
- MessageBoxEx.Show("Flow Launcher has detected you disabled portable mode, " +
+ AppExtensions.API.ShowMsgBox("Flow Launcher has detected you disabled portable mode, " +
"the relevant shortcuts and uninstaller entry have been created");
}
}
@@ -186,7 +186,7 @@ namespace Flow.Launcher.Core.Configuration
if (roamingLocationExists && portableLocationExists)
{
- MessageBoxEx.Show(string.Format("Flow Launcher detected your user data exists both in {0} and " +
+ AppExtensions.API.ShowMsgBox(string.Format("Flow Launcher detected your user data exists both in {0} and " +
"{1}. {2}{2}Please delete {1} in order to proceed. No changes have occurred.",
DataLocation.PortableDataPath, DataLocation.RoamingDataPath, Environment.NewLine));
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
index 6d41e2383..cada05031 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
@@ -57,7 +57,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
EnvName,
Environment.NewLine
);
- if (MessageBoxEx.Show(noRuntimeMessage, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
+ if (AppExtensions.API.ShowMsgBox(noRuntimeMessage, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
{
var msg = string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginChooseRuntimeExecutable"), EnvName);
string selectedFile;
@@ -82,7 +82,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
}
else
{
- MessageBoxEx.Show(string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginUnableToSetExecutablePath"), Language));
+ AppExtensions.API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginUnableToSetExecutablePath"), Language));
Log.Error("PluginsLoader",
$"Not able to successfully set {EnvName} path, setting's plugin executable path variable is still an empty string.",
$"{Language}Environment");
@@ -98,7 +98,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
if (expectedPath == currentPath)
return;
- FilesFolders.RemoveFolderIfExists(installedDirPath, MessageBoxEx.Show);
+ FilesFolders.RemoveFolderIfExists(installedDirPath, (s) => AppExtensions.API.ShowMsgBox(s));
InstallEnvironment();
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
index 96c29646e..56bc20b4f 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
@@ -28,7 +28,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
internal override void InstallEnvironment()
{
- FilesFolders.RemoveFolderIfExists(InstallPath, MessageBoxEx.Show);
+ FilesFolders.RemoveFolderIfExists(InstallPath, (s) => AppExtensions.API.ShowMsgBox(s));
// Python 3.11.4 is no longer Windows 7 compatible. If user is on Win 7 and
// uses Python plugin they need to custom install and use v3.8.9
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
index 0d6f109e0..1d43b815a 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
@@ -25,7 +25,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
internal override void InstallEnvironment()
{
- FilesFolders.RemoveFolderIfExists(InstallPath, MessageBoxEx.Show);
+ FilesFolders.RemoveFolderIfExists(InstallPath, (s) => AppExtensions.API.ShowMsgBox(s));
DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath).Wait();
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
index 582a4407c..49bf4e958 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
@@ -25,7 +25,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
internal override void InstallEnvironment()
{
- FilesFolders.RemoveFolderIfExists(InstallPath, MessageBoxEx.Show);
+ FilesFolders.RemoveFolderIfExists(InstallPath, (s) => AppExtensions.API.ShowMsgBox(s));
DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath).Wait();
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 5c4eaa1da..9e1cf3b9d 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -519,7 +519,7 @@ namespace Flow.Launcher.Core.Plugin
var newPluginPath = Path.Combine(installDirectory, folderName);
- FilesFolders.CopyAll(pluginFolderPath, newPluginPath, MessageBoxEx.Show);
+ FilesFolders.CopyAll(pluginFolderPath, newPluginPath, (s) => AppExtensions.API.ShowMsgBox(s));
Directory.Delete(tempFolderPluginPath, true);
diff --git a/Flow.Launcher.Core/Plugin/PluginsLoader.cs b/Flow.Launcher.Core/Plugin/PluginsLoader.cs
index 7973c66ba..8cbeb7473 100644
--- a/Flow.Launcher.Core/Plugin/PluginsLoader.cs
+++ b/Flow.Launcher.Core/Plugin/PluginsLoader.cs
@@ -119,7 +119,7 @@ namespace Flow.Launcher.Core.Plugin
_ = Task.Run(() =>
{
- MessageBoxEx.Show($"{errorMessage}{Environment.NewLine}{Environment.NewLine}" +
+ AppExtensions.API.ShowMsgBox($"{errorMessage}{Environment.NewLine}{Environment.NewLine}" +
$"{errorPluginString}{Environment.NewLine}{Environment.NewLine}" +
$"Please refer to the logs for more information", "",
MessageBoxButton.OK, MessageBoxImage.Warning);
diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs
index 1505e84f8..a1cefabe3 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -124,7 +124,7 @@ namespace Flow.Launcher.Core.Resource
// "Do you want to search with pinyin?"
string text = languageToSet == AvailableLanguages.Chinese ? "是否启用拼音搜索?" : "是否啓用拼音搜索?" ;
- if (MessageBoxEx.Show(text, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
+ if (AppExtensions.API.ShowMsgBox(text, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
return false;
return true;
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index 1d8409306..8622d4caf 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -108,7 +108,7 @@ namespace Flow.Launcher.Core.Resource
Log.Error($"|Theme.ChangeTheme|Theme <{theme}> path can't be found");
if (theme != defaultTheme)
{
- MessageBoxEx.Show(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_path_not_exists"), theme));
+ AppExtensions.API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_path_not_exists"), theme));
ChangeTheme(defaultTheme);
}
return false;
@@ -118,7 +118,7 @@ namespace Flow.Launcher.Core.Resource
Log.Error($"|Theme.ChangeTheme|Theme <{theme}> fail to parse");
if (theme != defaultTheme)
{
- MessageBoxEx.Show(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_parse_error"), theme));
+ AppExtensions.API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_parse_error"), theme));
ChangeTheme(defaultTheme);
}
return false;
diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs
index b92d86568..8745d54b7 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -53,7 +53,7 @@ namespace Flow.Launcher.Core
if (newReleaseVersion <= currentVersion)
{
if (!silentUpdate)
- MessageBoxEx.Show(api.GetTranslation("update_flowlauncher_already_on_latest"));
+ AppExtensions.API.ShowMsgBox(api.GetTranslation("update_flowlauncher_already_on_latest"));
return;
}
@@ -68,9 +68,9 @@ namespace Flow.Launcher.Core
if (DataLocation.PortableDataLocationInUse())
{
var targetDestination = updateManager.RootAppDirectory + $"\\app-{newReleaseVersion.ToString()}\\{DataLocation.PortableFolderName}";
- FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination, MessageBoxEx.Show);
- if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination, MessageBoxEx.Show))
- MessageBoxEx.Show(string.Format(api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
+ FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination, (s) => AppExtensions.API.ShowMsgBox(s));
+ if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination, (s) => AppExtensions.API.ShowMsgBox(s)))
+ AppExtensions.API.ShowMsgBox(string.Format(api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
DataLocation.PortableDataPath,
targetDestination));
}
@@ -83,7 +83,7 @@ namespace Flow.Launcher.Core
Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}");
- if (MessageBoxEx.Show(newVersionTips, api.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+ if (AppExtensions.API.ShowMsgBox(newVersionTips, api.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
UpdateManager.RestartApp(Constant.ApplicationFileName);
}
From 2716c40c0bd7229fed198d3ba75fd27fb0816084 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 9 Jan 2025 21:50:07 +0800
Subject: [PATCH 04/31] Move MessageBoxEx to main project for better
development experience
---
{Flow.Launcher.Core => Flow.Launcher}/MessageBoxEx.xaml | 4 ++--
{Flow.Launcher.Core => Flow.Launcher}/MessageBoxEx.xaml.cs | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
rename {Flow.Launcher.Core => Flow.Launcher}/MessageBoxEx.xaml (98%)
rename {Flow.Launcher.Core => Flow.Launcher}/MessageBoxEx.xaml.cs (99%)
diff --git a/Flow.Launcher.Core/MessageBoxEx.xaml b/Flow.Launcher/MessageBoxEx.xaml
similarity index 98%
rename from Flow.Launcher.Core/MessageBoxEx.xaml
rename to Flow.Launcher/MessageBoxEx.xaml
index fff107a68..be12ca16c 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml
+++ b/Flow.Launcher/MessageBoxEx.xaml
@@ -1,9 +1,9 @@
Date: Sun, 12 Jan 2025 18:44:52 +0800
Subject: [PATCH 05/31] Improve Settings management
---
.../UserSettings/Settings.cs | 16 ++++++++++++++--
Flow.Launcher/App.xaml.cs | 8 ++++++--
.../ViewModel/SettingWindowViewModel.cs | 13 +++----------
3 files changed, 23 insertions(+), 14 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 0bcc9368d..3e43e3d32 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -1,10 +1,10 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Text.Json.Serialization;
using System.Windows;
using Flow.Launcher.Infrastructure.Hotkey;
+using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedModels;
using Flow.Launcher.ViewModel;
@@ -13,6 +13,18 @@ namespace Flow.Launcher.Infrastructure.UserSettings
{
public class Settings : BaseModel, IHotkeySettings
{
+ private FlowLauncherJsonStorage _storage;
+
+ public void Initialize(FlowLauncherJsonStorage storage)
+ {
+ _storage = storage;
+ }
+
+ public void Save()
+ {
+ _storage.Save();
+ }
+
private string language = "en";
private string _theme = Constant.DefaultTheme;
public string Hotkey { get; set; } = $"{KeyConstant.Alt} + {KeyConstant.Space}";
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 58da35e85..9d7a0671e 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -14,6 +14,7 @@ using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Http;
using Flow.Launcher.Infrastructure.Image;
using Flow.Launcher.Infrastructure.Logger;
+using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
@@ -52,6 +53,10 @@ namespace Flow.Launcher
{
await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
{
+ var storage = new FlowLauncherJsonStorage();
+ _settings = storage.Load();
+ _settings.Initialize(storage);
+
_portable.PreStartCleanUpAfterPortabilityUpdate();
Log.Info(
@@ -62,8 +67,7 @@ namespace Flow.Launcher
var imageLoadertask = ImageLoader.InitializeAsync();
- _settingsVM = new SettingWindowViewModel(_updater, _portable);
- _settings = _settingsVM.Settings;
+ _settingsVM = new SettingWindowViewModel(_settings, _updater, _portable);
_settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled();
AbstractPluginEnvironment.PreStartPluginExecutablePathUpdate(_settings);
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index 04dd6312b..95a1eb675 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -1,6 +1,5 @@
using Flow.Launcher.Core;
using Flow.Launcher.Core.Configuration;
-using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
@@ -8,21 +7,17 @@ namespace Flow.Launcher.ViewModel;
public class SettingWindowViewModel : BaseModel
{
- private readonly FlowLauncherJsonStorage _storage;
-
public Updater Updater { get; }
public IPortable Portable { get; }
public Settings Settings { get; }
- public SettingWindowViewModel(Updater updater, IPortable portable)
+ public SettingWindowViewModel(Settings settings, Updater updater, IPortable portable)
{
- _storage = new FlowLauncherJsonStorage();
-
+ Settings = settings;
Updater = updater;
Portable = portable;
- Settings = _storage.Load();
}
public async void UpdateApp()
@@ -30,14 +25,12 @@ public class SettingWindowViewModel : BaseModel
await Updater.UpdateAppAsync(App.API, false);
}
-
-
///
/// Save Flow settings. Plugins settings are not included.
///
public void Save()
{
- _storage.Save();
+ Settings.Save();
}
public double SettingWindowWidth
From 1b76a2bc1a1c3356b3bab5c3be61b3427b1de7fd Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 12 Jan 2025 19:45:36 +0800
Subject: [PATCH 06/31] Use dependency injection for all services
---
.../Flow.Launcher.Infrastructure.csproj | 1 +
.../PinyinAlphabet.cs | 8 ++-
Flow.Launcher.Infrastructure/StringMatcher.cs | 5 +-
Flow.Launcher/App.xaml.cs | 61 +++++++++++--------
Flow.Launcher/Flow.Launcher.csproj | 5 +-
Flow.Launcher/PublicAPIInstance.cs | 12 ++--
Flow.Launcher/ViewModel/MainViewModel.cs | 5 +-
.../ViewModel/SettingWindowViewModel.cs | 11 ++--
8 files changed, 65 insertions(+), 43 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
index 1475252ca..84b603161 100644
--- a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
+++ b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
@@ -54,6 +54,7 @@
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
index 7d7235968..8eaa757be 100644
--- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
+++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
@@ -6,6 +6,7 @@ using System.Text;
using JetBrains.Annotations;
using Flow.Launcher.Infrastructure.UserSettings;
using ToolGood.Words.Pinyin;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Infrastructure
{
@@ -129,7 +130,12 @@ namespace Flow.Launcher.Infrastructure
private Settings _settings;
- public void Initialize([NotNull] Settings settings)
+ public PinyinAlphabet()
+ {
+ Initialize(Ioc.Default.GetRequiredService());
+ }
+
+ private void Initialize([NotNull] Settings settings)
{
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
}
diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs
index bd5dbdda9..7134fc760 100644
--- a/Flow.Launcher.Infrastructure/StringMatcher.cs
+++ b/Flow.Launcher.Infrastructure/StringMatcher.cs
@@ -1,4 +1,5 @@
-using Flow.Launcher.Plugin.SharedModels;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Plugin.SharedModels;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -15,7 +16,7 @@ namespace Flow.Launcher.Infrastructure
public StringMatcher(IAlphabet alphabet = null)
{
- _alphabet = alphabet;
+ _alphabet = Ioc.Default.GetRequiredService();
}
public static StringMatcher Instance { get; internal set; }
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 9d7a0671e..8cd054148 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -4,6 +4,7 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core;
using Flow.Launcher.Core.Configuration;
using Flow.Launcher.Core.ExternalPlugins.Environments;
@@ -18,23 +19,18 @@ using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
namespace Flow.Launcher
{
- public partial class App : IDisposable, ISingleInstanceApp, IApp
+ public partial class App : IDisposable, ISingleInstanceApp
{
- public IPublicAPI PublicAPI => API;
public static PublicAPIInstance API { get; private set; }
private const string Unique = "Flow.Launcher_Unique_Application_Mutex";
private static bool _disposed;
private Settings _settings;
- private MainViewModel _mainVM;
- private SettingWindowViewModel _settingsVM;
- private readonly Updater _updater = new Updater(Flow.Launcher.Properties.Settings.Default.GithubRepo);
- private readonly Portable _portable = new Portable();
- private readonly PinyinAlphabet _alphabet = new PinyinAlphabet();
- private StringMatcher _stringMatcher;
[STAThread]
public static void Main()
@@ -53,37 +49,51 @@ namespace Flow.Launcher
{
await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
{
+ // Initialize settings
var storage = new FlowLauncherJsonStorage();
_settings = storage.Load();
_settings.Initialize(storage);
+ _settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled();
- _portable.PreStartCleanUpAfterPortabilityUpdate();
+ // Configure the dependency injection container
+ var host = Host.CreateDefaultBuilder()
+ .UseContentRoot(AppContext.BaseDirectory)
+ .ConfigureServices(services => services
+ .AddSingleton(_ => _settings)
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ ).Build();
+ Ioc.Default.ConfigureServices(host.Services);
- Log.Info(
- "|App.OnStartup|Begin Flow Launcher startup ----------------------------------------------------");
+ Ioc.Default.GetRequiredService().Initialize(Launcher.Properties.Settings.Default.GithubRepo);
+
+ Ioc.Default.GetRequiredService().PreStartCleanUpAfterPortabilityUpdate();
+
+ Log.Info("|App.OnStartup|Begin Flow Launcher startup ----------------------------------------------------");
Log.Info($"|App.OnStartup|Runtime info:{ErrorReporting.RuntimeInfo()}");
+
RegisterAppDomainExceptions();
RegisterDispatcherUnhandledException();
var imageLoadertask = ImageLoader.InitializeAsync();
- _settingsVM = new SettingWindowViewModel(_settings, _updater, _portable);
- _settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled();
-
AbstractPluginEnvironment.PreStartPluginExecutablePathUpdate(_settings);
- _alphabet.Initialize(_settings);
- _stringMatcher = new StringMatcher(_alphabet);
- StringMatcher.Instance = _stringMatcher;
- _stringMatcher.UserSettingSearchPrecision = _settings.QuerySearchPrecision;
+ var stringMatcher = Ioc.Default.GetRequiredService();
+ StringMatcher.Instance = stringMatcher;
+ stringMatcher.UserSettingSearchPrecision = _settings.QuerySearchPrecision;
InternationalizationManager.Instance.Settings = _settings;
InternationalizationManager.Instance.ChangeLanguage(_settings.Language);
PluginManager.LoadPlugins(_settings.PluginSettings);
- _mainVM = new MainViewModel(_settings);
- API = new PublicAPIInstance(_settingsVM, _mainVM, _alphabet);
+ API = Ioc.Default.GetRequiredService() as PublicAPIInstance;
Http.API = API;
Http.Proxy = _settings.Proxy;
@@ -91,14 +101,15 @@ namespace Flow.Launcher
await PluginManager.InitializePluginsAsync(API);
await imageLoadertask;
- var window = new MainWindow(_settings, _mainVM);
+ var mainVM = Ioc.Default.GetRequiredService();
+ var window = new MainWindow(_settings, mainVM);
Log.Info($"|App.OnStartup|Dependencies Info:{ErrorReporting.DependenciesInfo()}");
Current.MainWindow = window;
Current.MainWindow.Title = Constant.FlowLauncher;
- HotKeyMapper.Initialize(_mainVM);
+ HotKeyMapper.Initialize(mainVM);
// main windows needs initialized before theme change because of blur settings
ThemeManager.Instance.Settings = _settings;
@@ -147,11 +158,11 @@ namespace Flow.Launcher
{
// check update every 5 hours
var timer = new PeriodicTimer(TimeSpan.FromHours(5));
- await _updater.UpdateAppAsync(API);
+ await Ioc.Default.GetRequiredService().UpdateAppAsync(API);
while (await timer.WaitForNextTickAsync())
// check updates on startup
- await _updater.UpdateAppAsync(API);
+ await Ioc.Default.GetRequiredService().UpdateAppAsync(API);
}
});
}
@@ -194,7 +205,7 @@ namespace Flow.Launcher
public void OnSecondAppStarted()
{
- _mainVM.Show();
+ Ioc.Default.GetRequiredService().Show();
}
}
}
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index 4ec249c2b..cab3915d5 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -1,4 +1,4 @@
-
+
WinExe
@@ -83,12 +83,13 @@
-
all
runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
all
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index f0295cf24..50765294c 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -25,7 +25,7 @@ using Flow.Launcher.Infrastructure.Storage;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Collections.Specialized;
-using Flow.Launcher.Core;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher
{
@@ -33,15 +33,15 @@ namespace Flow.Launcher
{
private readonly SettingWindowViewModel _settingsVM;
private readonly MainViewModel _mainVM;
- private readonly PinyinAlphabet _alphabet;
+ private readonly IAlphabet _alphabet;
#region Constructor
- public PublicAPIInstance(SettingWindowViewModel settingsVM, MainViewModel mainVM, PinyinAlphabet alphabet)
+ public PublicAPIInstance()
{
- _settingsVM = settingsVM;
- _mainVM = mainVM;
- _alphabet = alphabet;
+ _settingsVM = Ioc.Default.GetRequiredService();
+ _mainVM = Ioc.Default.GetRequiredService();
+ _alphabet = Ioc.Default.GetRequiredService();
GlobalHotkey.hookedKeyboardCallback = KListener_hookedKeyboardCallback;
WebRequest.RegisterPrefix("data", new DataWebRequestFactory());
}
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 55bc8d1b3..f5141a8fa 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -25,6 +25,7 @@ using System.Windows.Input;
using System.ComponentModel;
using Flow.Launcher.Infrastructure.Image;
using System.Windows.Media;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.ViewModel
{
@@ -58,13 +59,13 @@ namespace Flow.Launcher.ViewModel
#region Constructor
- public MainViewModel(Settings settings)
+ public MainViewModel()
{
_queryTextBeforeLeaveResults = "";
_queryText = "";
_lastQuery = new Query();
- Settings = settings;
+ Settings = Ioc.Default.GetRequiredService();
Settings.PropertyChanged += (_, args) =>
{
switch (args.PropertyName)
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index 95a1eb675..7549db1a3 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -1,4 +1,5 @@
-using Flow.Launcher.Core;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Core;
using Flow.Launcher.Core.Configuration;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
@@ -13,11 +14,11 @@ public class SettingWindowViewModel : BaseModel
public Settings Settings { get; }
- public SettingWindowViewModel(Settings settings, Updater updater, IPortable portable)
+ public SettingWindowViewModel()
{
- Settings = settings;
- Updater = updater;
- Portable = portable;
+ Settings = Ioc.Default.GetRequiredService();
+ Updater = Ioc.Default.GetRequiredService();
+ Portable = Ioc.Default.GetRequiredService();
}
public async void UpdateApp()
From a748141b1e8d7342336068ef65cc0890eac63992 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 12 Jan 2025 19:47:49 +0800
Subject: [PATCH 07/31] Use IPublicAPI instead
---
Flow.Launcher/App.xaml.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 8cd054148..9b86c6cc4 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -27,7 +27,7 @@ namespace Flow.Launcher
{
public partial class App : IDisposable, ISingleInstanceApp
{
- public static PublicAPIInstance API { get; private set; }
+ public static IPublicAPI API { get; private set; }
private const string Unique = "Flow.Launcher_Unique_Application_Mutex";
private static bool _disposed;
private Settings _settings;
@@ -93,7 +93,7 @@ namespace Flow.Launcher
PluginManager.LoadPlugins(_settings.PluginSettings);
- API = Ioc.Default.GetRequiredService() as PublicAPIInstance;
+ API = Ioc.Default.GetRequiredService();
Http.API = API;
Http.Proxy = _settings.Proxy;
From 3cb9d1dce4b606cc80fb3a7fc9e51da08237c1b8 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 12 Jan 2025 20:04:44 +0800
Subject: [PATCH 08/31] Remove IApp & AppExtensions and use dependency
injection instead
---
Flow.Launcher.Core/AppExtensions.cs | 15 ------------
Flow.Launcher.Core/Configuration/Portable.cs | 24 +++++++++++--------
.../Environments/AbstractPluginEnvironment.cs | 11 +++++----
.../Environments/PythonEnvironment.cs | 2 +-
.../Environments/TypeScriptEnvironment.cs | 2 +-
.../Environments/TypeScriptV2Environment.cs | 2 +-
Flow.Launcher.Core/IApp.cs | 13 ----------
Flow.Launcher.Core/Plugin/PluginManager.cs | 2 +-
Flow.Launcher.Core/Plugin/PluginsLoader.cs | 3 ++-
.../Resource/Internationalization.cs | 3 ++-
Flow.Launcher.Core/Resource/Theme.cs | 7 ++++--
Flow.Launcher.Core/Updater.cs | 17 +++++++------
Flow.Launcher/App.xaml.cs | 2 ++
.../ViewModel/SettingWindowViewModel.cs | 10 ++++++--
14 files changed, 54 insertions(+), 59 deletions(-)
delete mode 100644 Flow.Launcher.Core/AppExtensions.cs
delete mode 100644 Flow.Launcher.Core/IApp.cs
diff --git a/Flow.Launcher.Core/AppExtensions.cs b/Flow.Launcher.Core/AppExtensions.cs
deleted file mode 100644
index b02612d72..000000000
--- a/Flow.Launcher.Core/AppExtensions.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System.Windows;
-using Flow.Launcher.Plugin;
-
-namespace Flow.Launcher.Core;
-
-///
-/// Extension properties and functions of the current application singleton object.
-///
-public static class AppExtensions
-{
- ///
- /// Gets the public API of the current application singleton object.
- ///
- public static IPublicAPI API => (Application.Current as IApp)!.PublicAPI;
-}
diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs
index cb375c586..069154364 100644
--- a/Flow.Launcher.Core/Configuration/Portable.cs
+++ b/Flow.Launcher.Core/Configuration/Portable.cs
@@ -9,11 +9,15 @@ using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin.SharedCommands;
using System.Linq;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Plugin;
namespace Flow.Launcher.Core.Configuration
{
public class Portable : IPortable
{
+ private readonly IPublicAPI API = Ioc.Default.GetRequiredService();
+
///
/// As at Squirrel.Windows version 1.5.2, UpdateManager needs to be disposed after finish
///
@@ -40,7 +44,7 @@ namespace Flow.Launcher.Core.Configuration
#endif
IndicateDeletion(DataLocation.PortableDataPath);
- AppExtensions.API.ShowMsgBox("Flow Launcher needs to restart to finish disabling portable mode, " +
+ API.ShowMsgBox("Flow Launcher needs to restart to finish disabling portable mode, " +
"after the restart your portable data profile will be deleted and roaming data profile kept");
UpdateManager.RestartApp(Constant.ApplicationFileName);
@@ -64,7 +68,7 @@ namespace Flow.Launcher.Core.Configuration
#endif
IndicateDeletion(DataLocation.RoamingDataPath);
- AppExtensions.API.ShowMsgBox("Flow Launcher needs to restart to finish enabling portable mode, " +
+ API.ShowMsgBox("Flow Launcher needs to restart to finish enabling portable mode, " +
"after the restart your roaming data profile will be deleted and portable data profile kept");
UpdateManager.RestartApp(Constant.ApplicationFileName);
@@ -95,13 +99,13 @@ namespace Flow.Launcher.Core.Configuration
public void MoveUserDataFolder(string fromLocation, string toLocation)
{
- FilesFolders.CopyAll(fromLocation, toLocation, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.CopyAll(fromLocation, toLocation, (s) => API.ShowMsgBox(s));
VerifyUserDataAfterMove(fromLocation, toLocation);
}
public void VerifyUserDataAfterMove(string fromLocation, string toLocation)
{
- FilesFolders.VerifyBothFolderFilesEqual(fromLocation, toLocation, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.VerifyBothFolderFilesEqual(fromLocation, toLocation, (s) => API.ShowMsgBox(s));
}
public void CreateShortcuts()
@@ -157,13 +161,13 @@ namespace Flow.Launcher.Core.Configuration
// delete it and prompt the user to pick the portable data location
if (File.Exists(roamingDataDeleteFilePath))
{
- FilesFolders.RemoveFolderIfExists(roamingDataDir, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.RemoveFolderIfExists(roamingDataDir, (s) => API.ShowMsgBox(s));
- if (AppExtensions.API.ShowMsgBox("Flow Launcher has detected you enabled portable mode, " +
+ if (API.ShowMsgBox("Flow Launcher has detected you enabled portable mode, " +
"would you like to move it to a different location?", string.Empty,
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
- FilesFolders.OpenPath(Constant.RootDirectory, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.OpenPath(Constant.RootDirectory, (s) => API.ShowMsgBox(s));
Environment.Exit(0);
}
@@ -172,9 +176,9 @@ namespace Flow.Launcher.Core.Configuration
// delete it and notify the user about it.
else if (File.Exists(portableDataDeleteFilePath))
{
- FilesFolders.RemoveFolderIfExists(portableDataDir, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.RemoveFolderIfExists(portableDataDir, (s) => API.ShowMsgBox(s));
- AppExtensions.API.ShowMsgBox("Flow Launcher has detected you disabled portable mode, " +
+ API.ShowMsgBox("Flow Launcher has detected you disabled portable mode, " +
"the relevant shortcuts and uninstaller entry have been created");
}
}
@@ -186,7 +190,7 @@ namespace Flow.Launcher.Core.Configuration
if (roamingLocationExists && portableLocationExists)
{
- AppExtensions.API.ShowMsgBox(string.Format("Flow Launcher detected your user data exists both in {0} and " +
+ API.ShowMsgBox(string.Format("Flow Launcher detected your user data exists both in {0} and " +
"{1}. {2}{2}Please delete {1} in order to proceed. No changes have occurred.",
DataLocation.PortableDataPath, DataLocation.RoamingDataPath, Environment.NewLine));
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
index cada05031..451df6147 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
@@ -8,11 +8,14 @@ using System.Linq;
using System.Windows;
using System.Windows.Forms;
using Flow.Launcher.Core.Resource;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
public abstract class AbstractPluginEnvironment
{
+ protected readonly IPublicAPI API = Ioc.Default.GetRequiredService();
+
internal abstract string Language { get; }
internal abstract string EnvName { get; }
@@ -25,7 +28,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
internal virtual string FileDialogFilter => string.Empty;
- internal abstract string PluginsSettingsFilePath { get; set; }
+ internal abstract string PluginsSettingsFilePath { get; set; }
internal List PluginMetadataList;
@@ -57,7 +60,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
EnvName,
Environment.NewLine
);
- if (AppExtensions.API.ShowMsgBox(noRuntimeMessage, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
+ if (API.ShowMsgBox(noRuntimeMessage, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
{
var msg = string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginChooseRuntimeExecutable"), EnvName);
string selectedFile;
@@ -82,7 +85,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
}
else
{
- AppExtensions.API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginUnableToSetExecutablePath"), Language));
+ API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginUnableToSetExecutablePath"), Language));
Log.Error("PluginsLoader",
$"Not able to successfully set {EnvName} path, setting's plugin executable path variable is still an empty string.",
$"{Language}Environment");
@@ -98,7 +101,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
if (expectedPath == currentPath)
return;
- FilesFolders.RemoveFolderIfExists(installedDirPath, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.RemoveFolderIfExists(installedDirPath, (s) => API.ShowMsgBox(s));
InstallEnvironment();
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
index 56bc20b4f..607c19062 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
@@ -28,7 +28,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
internal override void InstallEnvironment()
{
- FilesFolders.RemoveFolderIfExists(InstallPath, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.RemoveFolderIfExists(InstallPath, (s) => API.ShowMsgBox(s));
// Python 3.11.4 is no longer Windows 7 compatible. If user is on Win 7 and
// uses Python plugin they need to custom install and use v3.8.9
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
index 1d43b815a..399f7cc03 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
@@ -25,7 +25,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
internal override void InstallEnvironment()
{
- FilesFolders.RemoveFolderIfExists(InstallPath, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.RemoveFolderIfExists(InstallPath, (s) => API.ShowMsgBox(s));
DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath).Wait();
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
index 49bf4e958..e8cb72e11 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
@@ -25,7 +25,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
internal override void InstallEnvironment()
{
- FilesFolders.RemoveFolderIfExists(InstallPath, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.RemoveFolderIfExists(InstallPath, (s) => API.ShowMsgBox(s));
DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath).Wait();
diff --git a/Flow.Launcher.Core/IApp.cs b/Flow.Launcher.Core/IApp.cs
deleted file mode 100644
index 233fd5ed1..000000000
--- a/Flow.Launcher.Core/IApp.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using Flow.Launcher.Plugin;
-
-namespace Flow.Launcher.Core
-{
- ///
- /// Interface for the current application singleton object exposing the properties
- /// and functions that can be accessed from anywhere in the application.
- ///
- public interface IApp
- {
- public IPublicAPI PublicAPI { get; }
- }
-}
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 9e1cf3b9d..a776c10ab 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -519,7 +519,7 @@ namespace Flow.Launcher.Core.Plugin
var newPluginPath = Path.Combine(installDirectory, folderName);
- FilesFolders.CopyAll(pluginFolderPath, newPluginPath, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.CopyAll(pluginFolderPath, newPluginPath, (s) => API.ShowMsgBox(s));
Directory.Delete(tempFolderPluginPath, true);
diff --git a/Flow.Launcher.Core/Plugin/PluginsLoader.cs b/Flow.Launcher.Core/Plugin/PluginsLoader.cs
index 8cbeb7473..4827cf69d 100644
--- a/Flow.Launcher.Core/Plugin/PluginsLoader.cs
+++ b/Flow.Launcher.Core/Plugin/PluginsLoader.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core.ExternalPlugins.Environments;
#pragma warning disable IDE0005
using Flow.Launcher.Infrastructure.Logger;
@@ -119,7 +120,7 @@ namespace Flow.Launcher.Core.Plugin
_ = Task.Run(() =>
{
- AppExtensions.API.ShowMsgBox($"{errorMessage}{Environment.NewLine}{Environment.NewLine}" +
+ Ioc.Default.GetRequiredService().ShowMsgBox($"{errorMessage}{Environment.NewLine}{Environment.NewLine}" +
$"{errorPluginString}{Environment.NewLine}{Environment.NewLine}" +
$"Please refer to the logs for more information", "",
MessageBoxButton.OK, MessageBoxImage.Warning);
diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs
index a1cefabe3..de066dda1 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -11,6 +11,7 @@ using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using System.Globalization;
using System.Threading.Tasks;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Core.Resource
{
@@ -124,7 +125,7 @@ namespace Flow.Launcher.Core.Resource
// "Do you want to search with pinyin?"
string text = languageToSet == AvailableLanguages.Chinese ? "是否启用拼音搜索?" : "是否啓用拼音搜索?" ;
- if (AppExtensions.API.ShowMsgBox(text, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
+ if (Ioc.Default.GetRequiredService().ShowMsgBox(text, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
return false;
return true;
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index 8622d4caf..2749da532 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -11,6 +11,8 @@ using System.Windows.Media.Effects;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Plugin;
namespace Flow.Launcher.Core.Resource
{
@@ -22,6 +24,7 @@ namespace Flow.Launcher.Core.Resource
private const int ShadowExtraMargin = 32;
+ private readonly IPublicAPI API = Ioc.Default.GetRequiredService();
private readonly List _themeDirectories = new List();
private ResourceDictionary _oldResource;
private string _oldTheme;
@@ -108,7 +111,7 @@ namespace Flow.Launcher.Core.Resource
Log.Error($"|Theme.ChangeTheme|Theme <{theme}> path can't be found");
if (theme != defaultTheme)
{
- AppExtensions.API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_path_not_exists"), theme));
+ API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_path_not_exists"), theme));
ChangeTheme(defaultTheme);
}
return false;
@@ -118,7 +121,7 @@ namespace Flow.Launcher.Core.Resource
Log.Error($"|Theme.ChangeTheme|Theme <{theme}> fail to parse");
if (theme != defaultTheme)
{
- AppExtensions.API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_parse_error"), theme));
+ API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_parse_error"), theme));
ChangeTheme(defaultTheme);
}
return false;
diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs
index 8745d54b7..373418055 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -17,14 +17,17 @@ using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using System.Text.Json.Serialization;
using System.Threading;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Core
{
public class Updater
{
- public string GitHubRepository { get; }
+ private readonly IPublicAPI API = Ioc.Default.GetRequiredService();
- public Updater(string gitHubRepository)
+ public string GitHubRepository { get; set; }
+
+ public void Initialize(string gitHubRepository)
{
GitHubRepository = gitHubRepository;
}
@@ -53,7 +56,7 @@ namespace Flow.Launcher.Core
if (newReleaseVersion <= currentVersion)
{
if (!silentUpdate)
- AppExtensions.API.ShowMsgBox(api.GetTranslation("update_flowlauncher_already_on_latest"));
+ API.ShowMsgBox(api.GetTranslation("update_flowlauncher_already_on_latest"));
return;
}
@@ -68,9 +71,9 @@ namespace Flow.Launcher.Core
if (DataLocation.PortableDataLocationInUse())
{
var targetDestination = updateManager.RootAppDirectory + $"\\app-{newReleaseVersion.ToString()}\\{DataLocation.PortableFolderName}";
- FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination, (s) => AppExtensions.API.ShowMsgBox(s));
- if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination, (s) => AppExtensions.API.ShowMsgBox(s)))
- AppExtensions.API.ShowMsgBox(string.Format(api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
+ FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination, (s) => API.ShowMsgBox(s));
+ if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination, (s) => API.ShowMsgBox(s)))
+ API.ShowMsgBox(string.Format(api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
DataLocation.PortableDataPath,
targetDestination));
}
@@ -83,7 +86,7 @@ namespace Flow.Launcher.Core
Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}");
- if (AppExtensions.API.ShowMsgBox(newVersionTips, api.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+ if (API.ShowMsgBox(newVersionTips, api.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
UpdateManager.RestartApp(Constant.ApplicationFileName);
}
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 9b86c6cc4..0d6d9855c 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -74,6 +74,8 @@ namespace Flow.Launcher
Ioc.Default.GetRequiredService().PreStartCleanUpAfterPortabilityUpdate();
+ Ioc.Default.GetRequiredService().Initialize();
+
Log.Info("|App.OnStartup|Begin Flow Launcher startup ----------------------------------------------------");
Log.Info($"|App.OnStartup|Runtime info:{ErrorReporting.RuntimeInfo()}");
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index 7549db1a3..bbd47e731 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -8,15 +8,21 @@ namespace Flow.Launcher.ViewModel;
public class SettingWindowViewModel : BaseModel
{
- public Updater Updater { get; }
+ public Updater Updater { get; private set; }
- public IPortable Portable { get; }
+ public IPortable Portable { get; private set; }
public Settings Settings { get; }
public SettingWindowViewModel()
{
Settings = Ioc.Default.GetRequiredService();
+ }
+
+ public void Initialize()
+ {
+ // We don not initialize Updater and Portable in the constructor because we want to avoid
+ // recrusive dependency injection
Updater = Ioc.Default.GetRequiredService();
Portable = Ioc.Default.GetRequiredService();
}
From 2a423f09bb3fe6c3dfb6dd9f03cce4ce410c5936 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 13 Jan 2025 09:36:14 +0800
Subject: [PATCH 09/31] Improve code quality
---
Flow.Launcher.Infrastructure/StringMatcher.cs | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs
index 7134fc760..b3a265e29 100644
--- a/Flow.Launcher.Infrastructure/StringMatcher.cs
+++ b/Flow.Launcher.Infrastructure/StringMatcher.cs
@@ -8,13 +8,13 @@ namespace Flow.Launcher.Infrastructure
{
public class StringMatcher
{
- private readonly MatchOption _defaultMatchOption = new MatchOption();
+ private readonly MatchOption _defaultMatchOption = new();
public SearchPrecisionScore UserSettingSearchPrecision { get; set; }
private readonly IAlphabet _alphabet;
- public StringMatcher(IAlphabet alphabet = null)
+ public StringMatcher()
{
_alphabet = Ioc.Default.GetRequiredService();
}
@@ -242,16 +242,16 @@ namespace Flow.Launcher.Infrastructure
return false;
}
- private bool IsAcronymChar(string stringToCompare, int compareStringIndex)
+ private static bool IsAcronymChar(string stringToCompare, int compareStringIndex)
=> char.IsUpper(stringToCompare[compareStringIndex]) ||
compareStringIndex == 0 || // 0 index means char is the start of the compare string, which is an acronym
char.IsWhiteSpace(stringToCompare[compareStringIndex - 1]);
- private bool IsAcronymNumber(string stringToCompare, int compareStringIndex)
+ private static bool IsAcronymNumber(string stringToCompare, int compareStringIndex)
=> stringToCompare[compareStringIndex] >= 0 && stringToCompare[compareStringIndex] <= 9;
// To get the index of the closest space which preceeds the first matching index
- private int CalculateClosestSpaceIndex(List spaceIndices, int firstMatchIndex)
+ private static int CalculateClosestSpaceIndex(List spaceIndices, int firstMatchIndex)
{
var closestSpaceIndex = -1;
From ff110b3c49ec139da1222e3ffcb210596eb4642e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 13 Jan 2025 10:01:50 +0800
Subject: [PATCH 10/31] Fix test project build issue
---
Flow.Launcher.Infrastructure/StringMatcher.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs
index b3a265e29..5822057a2 100644
--- a/Flow.Launcher.Infrastructure/StringMatcher.cs
+++ b/Flow.Launcher.Infrastructure/StringMatcher.cs
@@ -14,9 +14,9 @@ namespace Flow.Launcher.Infrastructure
private readonly IAlphabet _alphabet;
- public StringMatcher()
+ public StringMatcher(IAlphabet alphabet = null)
{
- _alphabet = Ioc.Default.GetRequiredService();
+ _alphabet = alphabet ?? Ioc.Default.GetRequiredService();
}
public static StringMatcher Instance { get; internal set; }
From c3f71c213e8b24870292f4489515558850c9c5b7 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 13 Jan 2025 10:18:35 +0800
Subject: [PATCH 11/31] Revert "Fix test project build issue"
This reverts commit ff110b3c49ec139da1222e3ffcb210596eb4642e.
---
Flow.Launcher.Infrastructure/StringMatcher.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs
index 5822057a2..b3a265e29 100644
--- a/Flow.Launcher.Infrastructure/StringMatcher.cs
+++ b/Flow.Launcher.Infrastructure/StringMatcher.cs
@@ -14,9 +14,9 @@ namespace Flow.Launcher.Infrastructure
private readonly IAlphabet _alphabet;
- public StringMatcher(IAlphabet alphabet = null)
+ public StringMatcher()
{
- _alphabet = alphabet ?? Ioc.Default.GetRequiredService();
+ _alphabet = Ioc.Default.GetRequiredService();
}
public static StringMatcher Instance { get; internal set; }
From 3bebb690935e4b99a508f5a9e98593760f45360c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 13 Jan 2025 10:21:14 +0800
Subject: [PATCH 12/31] Fix unitest build issue
---
Flow.Launcher.Infrastructure/StringMatcher.cs | 6 +++++
Flow.Launcher.Test/FuzzyMatcherTest.cs | 22 ++++++++++---------
2 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs
index b3a265e29..f5f02cbfc 100644
--- a/Flow.Launcher.Infrastructure/StringMatcher.cs
+++ b/Flow.Launcher.Infrastructure/StringMatcher.cs
@@ -19,6 +19,12 @@ namespace Flow.Launcher.Infrastructure
_alphabet = Ioc.Default.GetRequiredService();
}
+ // This is a workaround to allow unit tests to set the instance
+ public StringMatcher(IAlphabet alphabet)
+ {
+ _alphabet = alphabet;
+ }
+
public static StringMatcher Instance { get; internal set; }
public static MatchResult FuzzySearch(string query, string stringToCompare)
diff --git a/Flow.Launcher.Test/FuzzyMatcherTest.cs b/Flow.Launcher.Test/FuzzyMatcherTest.cs
index d7f143218..d97ce227c 100644
--- a/Flow.Launcher.Test/FuzzyMatcherTest.cs
+++ b/Flow.Launcher.Test/FuzzyMatcherTest.cs
@@ -21,6 +21,8 @@ namespace Flow.Launcher.Test
private const string MicrosoftSqlServerManagementStudio = "Microsoft SQL Server Management Studio";
private const string VisualStudioCode = "Visual Studio Code";
+ private readonly IAlphabet alphabet = null;
+
public List GetSearchStrings()
=> new List
{
@@ -59,7 +61,7 @@ namespace Flow.Launcher.Test
};
var results = new List();
- var matcher = new StringMatcher();
+ var matcher = new StringMatcher(alphabet);
foreach (var str in sources)
{
results.Add(new Result
@@ -81,7 +83,7 @@ namespace Flow.Launcher.Test
public void WhenNotAllCharactersFoundInSearchString_ThenShouldReturnZeroScore(string searchString)
{
var compareString = "Can have rum only in my glass";
- var matcher = new StringMatcher();
+ var matcher = new StringMatcher(alphabet);
var scoreResult = matcher.FuzzyMatch(searchString, compareString).RawScore;
Assert.True(scoreResult == 0);
@@ -97,7 +99,7 @@ namespace Flow.Launcher.Test
string searchTerm)
{
var results = new List();
- var matcher = new StringMatcher();
+ var matcher = new StringMatcher(alphabet);
foreach (var str in GetSearchStrings())
{
results.Add(new Result
@@ -147,7 +149,7 @@ namespace Flow.Launcher.Test
string queryString, string compareString, int expectedScore)
{
// When, Given
- var matcher = new StringMatcher {UserSettingSearchPrecision = SearchPrecisionScore.Regular};
+ var matcher = new StringMatcher(alphabet) {UserSettingSearchPrecision = SearchPrecisionScore.Regular};
var rawScore = matcher.FuzzyMatch(queryString, compareString).RawScore;
// Should
@@ -181,7 +183,7 @@ namespace Flow.Launcher.Test
bool expectedPrecisionResult)
{
// When
- var matcher = new StringMatcher {UserSettingSearchPrecision = expectedPrecisionScore};
+ var matcher = new StringMatcher(alphabet) {UserSettingSearchPrecision = expectedPrecisionScore};
// Given
var matchResult = matcher.FuzzyMatch(queryString, compareString);
@@ -232,7 +234,7 @@ namespace Flow.Launcher.Test
bool expectedPrecisionResult)
{
// When
- var matcher = new StringMatcher {UserSettingSearchPrecision = expectedPrecisionScore};
+ var matcher = new StringMatcher(alphabet) {UserSettingSearchPrecision = expectedPrecisionScore};
// Given
var matchResult = matcher.FuzzyMatch(queryString, compareString);
@@ -260,7 +262,7 @@ namespace Flow.Launcher.Test
string queryString, string compareString1, string compareString2)
{
// When
- var matcher = new StringMatcher {UserSettingSearchPrecision = SearchPrecisionScore.Regular};
+ var matcher = new StringMatcher(alphabet) {UserSettingSearchPrecision = SearchPrecisionScore.Regular};
// Given
var compareString1Result = matcher.FuzzyMatch(queryString, compareString1);
@@ -293,7 +295,7 @@ namespace Flow.Launcher.Test
string queryString, string compareString1, string compareString2)
{
// When
- var matcher = new StringMatcher { UserSettingSearchPrecision = SearchPrecisionScore.Regular };
+ var matcher = new StringMatcher(alphabet) { UserSettingSearchPrecision = SearchPrecisionScore.Regular };
// Given
var compareString1Result = matcher.FuzzyMatch(queryString, compareString1);
@@ -323,7 +325,7 @@ namespace Flow.Launcher.Test
string secondName, string secondDescription, string secondExecutableName)
{
// Act
- var matcher = new StringMatcher();
+ var matcher = new StringMatcher(alphabet);
var firstNameMatch = matcher.FuzzyMatch(queryString, firstName).RawScore;
var firstDescriptionMatch = matcher.FuzzyMatch(queryString, firstDescription).RawScore;
var firstExecutableNameMatch = matcher.FuzzyMatch(queryString, firstExecutableName).RawScore;
@@ -358,7 +360,7 @@ namespace Flow.Launcher.Test
public void WhenGivenAnAcronymQuery_ShouldReturnAcronymScore(string queryString, string compareString,
int desiredScore)
{
- var matcher = new StringMatcher();
+ var matcher = new StringMatcher(alphabet);
var score = matcher.FuzzyMatch(queryString, compareString).Score;
Assert.IsTrue(score == desiredScore,
$@"Query: ""{queryString}""
From 8d8384965ea5d39c62d7ce2b865114555b393146 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 13 Jan 2025 12:00:45 +0800
Subject: [PATCH 13/31] Improve dependency injection in updater & settings view
model & settings page
---
Flow.Launcher.Core/Updater.cs | 20 ++++++++--------
Flow.Launcher/App.xaml.cs | 7 +++---
.../CustomQueryHotkeySetting.xaml.cs | 5 +---
Flow.Launcher/PublicAPIInstance.cs | 20 +++++++++++-----
.../ViewModels/SettingsPaneAboutViewModel.cs | 2 +-
.../SettingsPaneGeneralViewModel.cs | 2 +-
.../ViewModels/SettingsPaneHotkeyViewModel.cs | 5 ++--
Flow.Launcher/SettingWindow.xaml.cs | 18 ++++++++++-----
.../ViewModel/SettingWindowViewModel.cs | 23 ++-----------------
9 files changed, 46 insertions(+), 56 deletions(-)
diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs
index 373418055..7a25447b4 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -34,14 +34,14 @@ namespace Flow.Launcher.Core
private SemaphoreSlim UpdateLock { get; } = new SemaphoreSlim(1);
- public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)
+ public async Task UpdateAppAsync(bool silentUpdate = true)
{
await UpdateLock.WaitAsync().ConfigureAwait(false);
try
{
if (!silentUpdate)
- api.ShowMsg(api.GetTranslation("pleaseWait"),
- api.GetTranslation("update_flowlauncher_update_check"));
+ API.ShowMsg(API.GetTranslation("pleaseWait"),
+ API.GetTranslation("update_flowlauncher_update_check"));
using var updateManager = await GitHubUpdateManagerAsync(GitHubRepository).ConfigureAwait(false);
@@ -56,13 +56,13 @@ namespace Flow.Launcher.Core
if (newReleaseVersion <= currentVersion)
{
if (!silentUpdate)
- API.ShowMsgBox(api.GetTranslation("update_flowlauncher_already_on_latest"));
+ API.ShowMsgBox(API.GetTranslation("update_flowlauncher_already_on_latest"));
return;
}
if (!silentUpdate)
- api.ShowMsg(api.GetTranslation("update_flowlauncher_update_found"),
- api.GetTranslation("update_flowlauncher_updating"));
+ API.ShowMsg(API.GetTranslation("update_flowlauncher_update_found"),
+ API.GetTranslation("update_flowlauncher_updating"));
await updateManager.DownloadReleases(newUpdateInfo.ReleasesToApply).ConfigureAwait(false);
@@ -73,7 +73,7 @@ namespace Flow.Launcher.Core
var targetDestination = updateManager.RootAppDirectory + $"\\app-{newReleaseVersion.ToString()}\\{DataLocation.PortableFolderName}";
FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination, (s) => API.ShowMsgBox(s));
if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination, (s) => API.ShowMsgBox(s)))
- API.ShowMsgBox(string.Format(api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
+ API.ShowMsgBox(string.Format(API.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
DataLocation.PortableDataPath,
targetDestination));
}
@@ -86,7 +86,7 @@ namespace Flow.Launcher.Core
Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}");
- if (API.ShowMsgBox(newVersionTips, api.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+ if (API.ShowMsgBox(newVersionTips, API.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
UpdateManager.RestartApp(Constant.ApplicationFileName);
}
@@ -99,8 +99,8 @@ namespace Flow.Launcher.Core
Log.Exception($"|Updater.UpdateApp|Error Occurred", e);
if (!silentUpdate)
- api.ShowMsg(api.GetTranslation("update_flowlauncher_fail"),
- api.GetTranslation("update_flowlauncher_check_connection"));
+ API.ShowMsg(API.GetTranslation("update_flowlauncher_fail"),
+ API.GetTranslation("update_flowlauncher_check_connection"));
}
finally
{
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 0d6d9855c..9384aae3d 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -74,8 +74,6 @@ namespace Flow.Launcher
Ioc.Default.GetRequiredService().PreStartCleanUpAfterPortabilityUpdate();
- Ioc.Default.GetRequiredService().Initialize();
-
Log.Info("|App.OnStartup|Begin Flow Launcher startup ----------------------------------------------------");
Log.Info($"|App.OnStartup|Runtime info:{ErrorReporting.RuntimeInfo()}");
@@ -96,6 +94,7 @@ namespace Flow.Launcher
PluginManager.LoadPlugins(_settings.PluginSettings);
API = Ioc.Default.GetRequiredService();
+ ((PublicAPIInstance)API).Initialize();
Http.API = API;
Http.Proxy = _settings.Proxy;
@@ -160,11 +159,11 @@ namespace Flow.Launcher
{
// check update every 5 hours
var timer = new PeriodicTimer(TimeSpan.FromHours(5));
- await Ioc.Default.GetRequiredService().UpdateAppAsync(API);
+ await Ioc.Default.GetRequiredService().UpdateAppAsync();
while (await timer.WaitForNextTickAsync())
// check updates on startup
- await Ioc.Default.GetRequiredService().UpdateAppAsync(API);
+ await Ioc.Default.GetRequiredService().UpdateAppAsync();
}
});
}
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index 47460ff7d..eab2705d0 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -6,20 +6,17 @@ using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;
-using Flow.Launcher.Core;
namespace Flow.Launcher
{
public partial class CustomQueryHotkeySetting : Window
{
- private SettingWindow _settingWidow;
private bool update;
private CustomPluginHotkey updateCustomHotkey;
public Settings Settings { get; }
- public CustomQueryHotkeySetting(SettingWindow settingWidow, Settings settings)
+ public CustomQueryHotkeySetting(Settings settings)
{
- _settingWidow = settingWidow;
Settings = settings;
InitializeComponent();
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 50765294c..54e97f6c6 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -26,6 +26,7 @@ using System.Collections.Concurrent;
using System.Diagnostics;
using System.Collections.Specialized;
using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Core;
namespace Flow.Launcher
{
@@ -33,19 +34,26 @@ namespace Flow.Launcher
{
private readonly SettingWindowViewModel _settingsVM;
private readonly MainViewModel _mainVM;
- private readonly IAlphabet _alphabet;
- #region Constructor
+ private Updater _updater;
+
+ #region Constructor & Initialization
public PublicAPIInstance()
{
_settingsVM = Ioc.Default.GetRequiredService();
_mainVM = Ioc.Default.GetRequiredService();
- _alphabet = Ioc.Default.GetRequiredService();
GlobalHotkey.hookedKeyboardCallback = KListener_hookedKeyboardCallback;
WebRequest.RegisterPrefix("data", new DataWebRequestFactory());
}
+ public void Initialize()
+ {
+ // We need to initialize Updater not in the constructor because we want to avoid
+ // recrusive dependency injection
+ _updater = Ioc.Default.GetRequiredService();
+ }
+
#endregion
#region Public API
@@ -78,14 +86,14 @@ namespace Flow.Launcher
public event VisibilityChangedEventHandler VisibilityChanged { add => _mainVM.VisibilityChanged += value; remove => _mainVM.VisibilityChanged -= value; }
- public void CheckForNewUpdate() => _settingsVM.UpdateApp();
+ public void CheckForNewUpdate() => _ = _updater.UpdateAppAsync(false);
public void SaveAppAllSettings()
{
PluginManager.Save();
_mainVM.Save();
_settingsVM.Save();
- ImageLoader.Save();
+ _ = ImageLoader.Save();
}
public Task ReloadAllPluginData() => PluginManager.ReloadDataAsync();
@@ -105,7 +113,7 @@ namespace Flow.Launcher
{
Application.Current.Dispatcher.Invoke(() =>
{
- SettingWindow sw = SingletonWindowOpener.Open(this, _settingsVM);
+ SettingWindow sw = SingletonWindowOpener.Open();
});
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
index 05fb16f5c..cb434f399 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -96,7 +96,7 @@ public partial class SettingsPaneAboutViewModel : BaseModel
}
[RelayCommand]
- private Task UpdateApp() => _updater.UpdateAppAsync(App.API, false);
+ private Task UpdateApp() => _updater.UpdateAppAsync(false);
private void ClearLogFolder()
{
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index 3d94355e6..4e498ba23 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -160,7 +160,7 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
private void UpdateApp()
{
- _ = _updater.UpdateAppAsync(App.API, false);
+ _ = _updater.UpdateAppAsync(false);
}
public bool AutoUpdates
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
index fb57f499b..b13aaefe3 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
@@ -7,7 +7,6 @@ using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
-using Flow.Launcher.Core;
namespace Flow.Launcher.SettingPages.ViewModels;
@@ -71,7 +70,7 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
return;
}
- var window = new CustomQueryHotkeySetting(null, Settings);
+ var window = new CustomQueryHotkeySetting(Settings);
window.UpdateItem(item);
window.ShowDialog();
}
@@ -79,7 +78,7 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
[RelayCommand]
private void CustomHotkeyAdd()
{
- new CustomQueryHotkeySetting(null, Settings).ShowDialog();
+ new CustomQueryHotkeySetting(Settings).ShowDialog();
}
[RelayCommand]
diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs
index cb3f1e4a1..ab639e987 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -3,6 +3,7 @@ using System.Windows;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Interop;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core;
using Flow.Launcher.Core.Configuration;
using Flow.Launcher.Helper;
@@ -17,16 +18,21 @@ namespace Flow.Launcher;
public partial class SettingWindow
{
+ private readonly Updater _updater;
+ private readonly IPortable _portable;
private readonly IPublicAPI _api;
private readonly Settings _settings;
private readonly SettingWindowViewModel _viewModel;
- public SettingWindow(IPublicAPI api, SettingWindowViewModel viewModel)
+ public SettingWindow()
{
+ var viewModel = Ioc.Default.GetRequiredService();
_settings = viewModel.Settings;
DataContext = viewModel;
_viewModel = viewModel;
- _api = api;
+ _updater = Ioc.Default.GetRequiredService();
+ _portable = Ioc.Default.GetRequiredService();
+ _api = Ioc.Default.GetRequiredService();
InitializePosition();
InitializeComponent();
}
@@ -125,7 +131,7 @@ public partial class SettingWindow
WindowState = _settings.SettingWindowState;
}
- private bool IsPositionValid(double top, double left)
+ private static bool IsPositionValid(double top, double left)
{
foreach (var screen in Screen.AllScreens)
{
@@ -145,7 +151,7 @@ public partial class SettingWindow
var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.X, 0);
var dip2 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.Width, 0);
- var left = (dip2.X - this.ActualWidth) / 2 + dip1.X;
+ var left = (dip2.X - ActualWidth) / 2 + dip1.X;
return left;
}
@@ -154,13 +160,13 @@ public partial class SettingWindow
var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Y);
var dip2 = WindowsInteropHelper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Height);
- var top = (dip2.Y - this.ActualHeight) / 2 + dip1.Y - 20;
+ var top = (dip2.Y - ActualHeight) / 2 + dip1.Y - 20;
return top;
}
private void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
- var paneData = new PaneData(_settings, _viewModel.Updater, _viewModel.Portable);
+ var paneData = new PaneData(_settings, _updater, _portable);
if (args.IsSettingsSelected)
{
ContentFrame.Navigate(typeof(SettingsPaneGeneral), paneData);
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index bbd47e731..37276a1ad 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -1,37 +1,18 @@
using CommunityToolkit.Mvvm.DependencyInjection;
-using Flow.Launcher.Core;
-using Flow.Launcher.Core.Configuration;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
namespace Flow.Launcher.ViewModel;
-public class SettingWindowViewModel : BaseModel
+public partial class SettingWindowViewModel : BaseModel
{
- public Updater Updater { get; private set; }
-
- public IPortable Portable { get; private set; }
-
- public Settings Settings { get; }
+ public Settings Settings { get; init; }
public SettingWindowViewModel()
{
Settings = Ioc.Default.GetRequiredService();
}
- public void Initialize()
- {
- // We don not initialize Updater and Portable in the constructor because we want to avoid
- // recrusive dependency injection
- Updater = Ioc.Default.GetRequiredService();
- Portable = Ioc.Default.GetRequiredService();
- }
-
- public async void UpdateApp()
- {
- await Updater.UpdateAppAsync(App.API, false);
- }
-
///
/// Save Flow settings. Plugins settings are not included.
///
From ed399371976b60436eeb9042c59696859eed3caf Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 21 Jan 2025 16:19:28 +0800
Subject: [PATCH 14/31] Initialize App.API earlier & Improve code quality
---
Flow.Launcher/App.xaml.cs | 5 ++---
Flow.Launcher/PublicAPIInstance.cs | 13 ++-----------
2 files changed, 4 insertions(+), 14 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 9384aae3d..a64c9e750 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -70,6 +70,8 @@ namespace Flow.Launcher
).Build();
Ioc.Default.ConfigureServices(host.Services);
+ API = Ioc.Default.GetRequiredService();
+
Ioc.Default.GetRequiredService().Initialize(Launcher.Properties.Settings.Default.GithubRepo);
Ioc.Default.GetRequiredService().PreStartCleanUpAfterPortabilityUpdate();
@@ -93,9 +95,6 @@ namespace Flow.Launcher
PluginManager.LoadPlugins(_settings.PluginSettings);
- API = Ioc.Default.GetRequiredService();
- ((PublicAPIInstance)API).Initialize();
-
Http.API = API;
Http.Proxy = _settings.Proxy;
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 54e97f6c6..0329d6973 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -35,9 +35,7 @@ namespace Flow.Launcher
private readonly SettingWindowViewModel _settingsVM;
private readonly MainViewModel _mainVM;
- private Updater _updater;
-
- #region Constructor & Initialization
+ #region Constructor
public PublicAPIInstance()
{
@@ -47,13 +45,6 @@ namespace Flow.Launcher
WebRequest.RegisterPrefix("data", new DataWebRequestFactory());
}
- public void Initialize()
- {
- // We need to initialize Updater not in the constructor because we want to avoid
- // recrusive dependency injection
- _updater = Ioc.Default.GetRequiredService();
- }
-
#endregion
#region Public API
@@ -86,7 +77,7 @@ namespace Flow.Launcher
public event VisibilityChangedEventHandler VisibilityChanged { add => _mainVM.VisibilityChanged += value; remove => _mainVM.VisibilityChanged -= value; }
- public void CheckForNewUpdate() => _ = _updater.UpdateAppAsync(false);
+ public void CheckForNewUpdate() => _ = Ioc.Default.GetRequiredService().UpdateAppAsync(false);
public void SaveAppAllSettings()
{
From f9983b587712bdc439022f4ac19bda46133d9ab8 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 22 Jan 2025 12:25:56 +0800
Subject: [PATCH 15/31] Move dependency injection codes to constructor
---
Flow.Launcher/App.xaml.cs | 47 +++++++++++++++++++++------------------
1 file changed, 25 insertions(+), 22 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index a64c9e750..d983ab000 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -30,7 +30,31 @@ namespace Flow.Launcher
public static IPublicAPI API { get; private set; }
private const string Unique = "Flow.Launcher_Unique_Application_Mutex";
private static bool _disposed;
- private Settings _settings;
+ private readonly Settings _settings;
+
+ public App()
+ {
+ // Initialize settings
+ var storage = new FlowLauncherJsonStorage();
+ _settings = storage.Load();
+ _settings.Initialize(storage);
+ _settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled();
+
+ // Configure the dependency injection container
+ var host = Host.CreateDefaultBuilder()
+ .UseContentRoot(AppContext.BaseDirectory)
+ .ConfigureServices(services => services
+ .AddSingleton(_ => _settings)
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ ).Build();
+ Ioc.Default.ConfigureServices(host.Services);
+ }
[STAThread]
public static void Main()
@@ -49,27 +73,6 @@ namespace Flow.Launcher
{
await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
{
- // Initialize settings
- var storage = new FlowLauncherJsonStorage();
- _settings = storage.Load();
- _settings.Initialize(storage);
- _settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled();
-
- // Configure the dependency injection container
- var host = Host.CreateDefaultBuilder()
- .UseContentRoot(AppContext.BaseDirectory)
- .ConfigureServices(services => services
- .AddSingleton(_ => _settings)
- .AddSingleton()
- .AddSingleton()
- .AddSingleton()
- .AddSingleton()
- .AddSingleton()
- .AddSingleton()
- .AddSingleton()
- ).Build();
- Ioc.Default.ConfigureServices(host.Services);
-
API = Ioc.Default.GetRequiredService();
Ioc.Default.GetRequiredService().Initialize(Launcher.Properties.Settings.Default.GithubRepo);
From 23a1e5bc5853d2f6a4ba0e83c1c36ac960da40d9 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 27 Jan 2025 09:39:12 +0800
Subject: [PATCH 16/31] Initialize public api instance in constructor so that
we can use App.API all the time
---
Flow.Launcher/App.xaml.cs | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index d983ab000..f800ccd5d 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -54,6 +54,9 @@ namespace Flow.Launcher
.AddSingleton()
).Build();
Ioc.Default.ConfigureServices(host.Services);
+
+ // Initialize the public API first
+ API = Ioc.Default.GetRequiredService();
}
[STAThread]
@@ -73,8 +76,6 @@ namespace Flow.Launcher
{
await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
{
- API = Ioc.Default.GetRequiredService();
-
Ioc.Default.GetRequiredService().Initialize(Launcher.Properties.Settings.Default.GithubRepo);
Ioc.Default.GetRequiredService().PreStartCleanUpAfterPortabilityUpdate();
From ed16d340cb1c43464b9046a2672edc5d189c01bc Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 27 Jan 2025 09:40:24 +0800
Subject: [PATCH 17/31] Improve code quality
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 6 +++---
Flow.Launcher.Infrastructure/Http/Http.cs | 3 ++-
Flow.Launcher/App.xaml.cs | 3 +--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index a776c10ab..0e8a4b776 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -14,6 +14,7 @@ using ISavable = Flow.Launcher.Plugin.ISavable;
using Flow.Launcher.Plugin.SharedCommands;
using System.Text.Json;
using Flow.Launcher.Core.Resource;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Core.Plugin
{
@@ -28,7 +29,7 @@ namespace Flow.Launcher.Core.Plugin
public static readonly HashSet GlobalPlugins = new();
public static readonly Dictionary NonGlobalPlugins = new();
- public static IPublicAPI API { private set; get; }
+ public static IPublicAPI API { get; private set; } = Ioc.Default.GetRequiredService();
private static PluginsSettings Settings;
private static List _metadatas;
@@ -158,9 +159,8 @@ namespace Flow.Launcher.Core.Plugin
/// Call initialize for all plugins
///
/// return the list of failed to init plugins or null for none
- public static async Task InitializePluginsAsync(IPublicAPI api)
+ public static async Task InitializePluginsAsync()
{
- API = api;
var failedPlugins = new ConcurrentQueue();
var InitTasks = AllPlugins.Select(pair => Task.Run(async delegate
diff --git a/Flow.Launcher.Infrastructure/Http/Http.cs b/Flow.Launcher.Infrastructure/Http/Http.cs
index 14b8eef4e..3711a6b0d 100644
--- a/Flow.Launcher.Infrastructure/Http/Http.cs
+++ b/Flow.Launcher.Infrastructure/Http/Http.cs
@@ -8,6 +8,7 @@ using Flow.Launcher.Infrastructure.UserSettings;
using System;
using System.Threading;
using Flow.Launcher.Plugin;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Infrastructure.Http
{
@@ -17,7 +18,7 @@ namespace Flow.Launcher.Infrastructure.Http
private static HttpClient client = new HttpClient();
- public static IPublicAPI API { get; set; }
+ private static IPublicAPI API { get; set; } = Ioc.Default.GetRequiredService();
static Http()
{
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index f800ccd5d..5f7f097e0 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -99,10 +99,9 @@ namespace Flow.Launcher
PluginManager.LoadPlugins(_settings.PluginSettings);
- Http.API = API;
Http.Proxy = _settings.Proxy;
- await PluginManager.InitializePluginsAsync(API);
+ await PluginManager.InitializePluginsAsync();
await imageLoadertask;
var mainVM = Ioc.Default.GetRequiredService();
From 6a2389f4b8c95d87ee72041a0e78812333fe3fd3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 27 Jan 2025 10:45:05 +0800
Subject: [PATCH 18/31] Fix test project build issue
---
Flow.Launcher.Infrastructure/Http/Http.cs | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Http/Http.cs b/Flow.Launcher.Infrastructure/Http/Http.cs
index 3711a6b0d..78545a87b 100644
--- a/Flow.Launcher.Infrastructure/Http/Http.cs
+++ b/Flow.Launcher.Infrastructure/Http/Http.cs
@@ -18,8 +18,6 @@ namespace Flow.Launcher.Infrastructure.Http
private static HttpClient client = new HttpClient();
- private static IPublicAPI API { get; set; } = Ioc.Default.GetRequiredService();
-
static Http()
{
// need to be added so it would work on a win10 machine
@@ -79,7 +77,7 @@ namespace Flow.Launcher.Infrastructure.Http
}
catch (UriFormatException e)
{
- API.ShowMsg("Please try again", "Unable to parse Http Proxy");
+ Ioc.Default.GetRequiredService().ShowMsg("Please try again", "Unable to parse Http Proxy");
Log.Exception("Flow.Launcher.Infrastructure.Http", "Unable to parse Uri", e);
}
}
From c0720120737667f23815bdd62fe6c6bdf2f8182a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 23 Feb 2025 13:19:55 +0800
Subject: [PATCH 19/31] Fix parameter name issue.
---
Flow.Launcher/CustomQueryHotkeySetting.xaml.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index af3c8f6c9..53fa173a5 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -11,12 +11,13 @@ namespace Flow.Launcher
{
public partial class CustomQueryHotkeySetting : Window
{
+ private readonly Settings _settings;
private bool update;
private CustomPluginHotkey updateCustomHotkey;
public CustomQueryHotkeySetting(Settings settings)
{
- Settings = settings;
+ _settings = settings;
InitializeComponent();
}
From 39d7187713432d7bcf8c11911ff4a54c3d64c1c3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 23 Feb 2025 13:27:39 +0800
Subject: [PATCH 20/31] Use constructor injection for updater
---
Flow.Launcher.Core/Updater.cs | 7 ++++++-
Flow.Launcher/App.xaml.cs | 2 +-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs
index 7a25447b4..dd0864c19 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -23,10 +23,15 @@ namespace Flow.Launcher.Core
{
public class Updater
{
- private readonly IPublicAPI API = Ioc.Default.GetRequiredService();
+ private readonly IPublicAPI API;
public string GitHubRepository { get; set; }
+ public Updater(IPublicAPI publicAPI)
+ {
+ API = publicAPI;
+ }
+
public void Initialize(string gitHubRepository)
{
GitHubRepository = gitHubRepository;
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 5f7f097e0..b52ae7196 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -45,7 +45,7 @@ namespace Flow.Launcher
.UseContentRoot(AppContext.BaseDirectory)
.ConfigureServices(services => services
.AddSingleton(_ => _settings)
- .AddSingleton()
+ .AddSingleton(sp => new Updater(sp.GetRequiredService()))
.AddSingleton()
.AddSingleton()
.AddSingleton()
From 39d34b1a037e2e1a1ed3419faebeb39f693ea98d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 23 Feb 2025 13:31:07 +0800
Subject: [PATCH 21/31] Add circular dependency comments
---
Flow.Launcher/PublicAPIInstance.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 8bcd3e046..6123a93d9 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -77,6 +77,7 @@ namespace Flow.Launcher
public event VisibilityChangedEventHandler VisibilityChanged { add => _mainVM.VisibilityChanged += value; remove => _mainVM.VisibilityChanged -= value; }
+ // Must use Ioc.Default.GetRequiredService() to avoid circular dependency
public void CheckForNewUpdate() => _ = Ioc.Default.GetRequiredService().UpdateAppAsync(false);
public void SaveAppAllSettings()
From e022ad6acdf5d486578e59fc3a4f7a3dede2864a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 23 Feb 2025 13:40:10 +0800
Subject: [PATCH 22/31] Remove instance for StringMatcher
---
Flow.Launcher.Infrastructure/StringMatcher.cs | 4 +---
.../UserSettings/Settings.cs | 14 ++++++++++----
Flow.Launcher/App.xaml.cs | 9 ++++-----
3 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs
index f5f02cbfc..55aa0a1ec 100644
--- a/Flow.Launcher.Infrastructure/StringMatcher.cs
+++ b/Flow.Launcher.Infrastructure/StringMatcher.cs
@@ -25,11 +25,9 @@ namespace Flow.Launcher.Infrastructure
_alphabet = alphabet;
}
- public static StringMatcher Instance { get; internal set; }
-
public static MatchResult FuzzySearch(string query, string stringToCompare)
{
- return Instance.FuzzyMatch(query, stringToCompare);
+ return Ioc.Default.GetRequiredService().FuzzyMatch(query, stringToCompare);
}
public MatchResult FuzzyMatch(string query, string stringToCompare)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 2a9d901fa..d3f44530c 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -3,6 +3,7 @@ using System.Collections.ObjectModel;
using System.Drawing;
using System.Text.Json.Serialization;
using System.Windows;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Plugin;
@@ -14,12 +15,18 @@ namespace Flow.Launcher.Infrastructure.UserSettings
public class Settings : BaseModel, IHotkeySettings
{
private FlowLauncherJsonStorage _storage;
+ private StringMatcher _stringMatcher = null;
- public void Initialize(FlowLauncherJsonStorage storage)
+ public void SetStorage(FlowLauncherJsonStorage storage)
{
_storage = storage;
}
+ public void Initialize()
+ {
+ _stringMatcher = Ioc.Default.GetRequiredService();
+ }
+
public void Save()
{
_storage.Save();
@@ -192,7 +199,6 @@ namespace Flow.Launcher.Infrastructure.UserSettings
}
};
-
///
/// when false Alphabet static service will always return empty results
///
@@ -210,8 +216,8 @@ namespace Flow.Launcher.Infrastructure.UserSettings
set
{
_querySearchPrecision = value;
- if (StringMatcher.Instance != null)
- StringMatcher.Instance.UserSettingSearchPrecision = value;
+ if (_stringMatcher != null)
+ _stringMatcher.UserSettingSearchPrecision = value;
}
}
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index b52ae7196..b435b566f 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -37,7 +37,7 @@ namespace Flow.Launcher
// Initialize settings
var storage = new FlowLauncherJsonStorage();
_settings = storage.Load();
- _settings.Initialize(storage);
+ _settings.SetStorage(storage);
_settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled();
// Configure the dependency injection container
@@ -55,8 +55,9 @@ namespace Flow.Launcher
).Build();
Ioc.Default.ConfigureServices(host.Services);
- // Initialize the public API first
+ // Initialize the public API and Settings first
API = Ioc.Default.GetRequiredService();
+ _settings.Initialize();
}
[STAThread]
@@ -90,9 +91,7 @@ namespace Flow.Launcher
AbstractPluginEnvironment.PreStartPluginExecutablePathUpdate(_settings);
- var stringMatcher = Ioc.Default.GetRequiredService();
- StringMatcher.Instance = stringMatcher;
- stringMatcher.UserSettingSearchPrecision = _settings.QuerySearchPrecision;
+ Ioc.Default.GetRequiredService().UserSettingSearchPrecision = _settings.QuerySearchPrecision;
InternationalizationManager.Instance.Settings = _settings;
InternationalizationManager.Instance.ChangeLanguage(_settings.Language);
From a3964f56672d68b32e585d6d2399ed3442311f72 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 23 Feb 2025 13:51:37 +0800
Subject: [PATCH 23/31] Remove instance for Internationalization & Theme
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 2 +-
.../Resource/Internationalization.cs | 9 ++++---
.../Resource/InternationalizationManager.cs | 26 ++++---------------
Flow.Launcher.Core/Resource/Theme.cs | 9 ++++---
Flow.Launcher.Core/Resource/ThemeManager.cs | 24 +++--------------
Flow.Launcher.Core/Updater.cs | 1 -
Flow.Launcher/App.xaml.cs | 6 +++--
7 files changed, 25 insertions(+), 52 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 5ee723833..6e7b5ec60 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -204,7 +204,7 @@ namespace Flow.Launcher.Core.Plugin
}
InternationalizationManager.Instance.AddPluginLanguageDirectories(GetPluginsForInterface());
- InternationalizationManager.Instance.ChangeLanguage(InternationalizationManager.Instance.Settings.Language);
+ InternationalizationManager.Instance.ChangeLanguage(Ioc.Default.GetRequiredService().Language);
if (failedPlugins.Any())
{
diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs
index 884276f03..e2a66656a 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -17,17 +17,18 @@ namespace Flow.Launcher.Core.Resource
{
public class Internationalization
{
- public Settings Settings { get; set; }
private const string Folder = "Languages";
private const string DefaultLanguageCode = "en";
private const string DefaultFile = "en.xaml";
private const string Extension = ".xaml";
+ private readonly Settings _settings;
private readonly List _languageDirectories = new List();
private readonly List _oldResources = new List();
private readonly string SystemLanguageCode;
- public Internationalization()
+ public Internationalization(Settings settings)
{
+ _settings = settings;
AddFlowLauncherLanguageDirectory();
SystemLanguageCode = GetSystemLanguageCodeAtStartup();
}
@@ -142,7 +143,7 @@ namespace Flow.Launcher.Core.Resource
CultureInfo.CurrentUICulture = CultureInfo.CurrentCulture;
// Raise event after culture is set
- Settings.Language = isSystem ? Constant.SystemLanguageCode : language.LanguageCode;
+ _settings.Language = isSystem ? Constant.SystemLanguageCode : language.LanguageCode;
_ = Task.Run(() =>
{
UpdatePluginMetadataTranslations();
@@ -153,7 +154,7 @@ namespace Flow.Launcher.Core.Resource
{
var languageToSet = GetLanguageByLanguageCode(languageCodeToSet);
- if (Settings.ShouldUsePinyin)
+ if (_settings.ShouldUsePinyin)
return false;
if (languageToSet != AvailableLanguages.Chinese && languageToSet != AvailableLanguages.Chinese_TW)
diff --git a/Flow.Launcher.Core/Resource/InternationalizationManager.cs b/Flow.Launcher.Core/Resource/InternationalizationManager.cs
index 3d87626e6..79736edc3 100644
--- a/Flow.Launcher.Core/Resource/InternationalizationManager.cs
+++ b/Flow.Launcher.Core/Resource/InternationalizationManager.cs
@@ -1,26 +1,10 @@
-namespace Flow.Launcher.Core.Resource
+using CommunityToolkit.Mvvm.DependencyInjection;
+
+namespace Flow.Launcher.Core.Resource
{
public static class InternationalizationManager
{
- private static Internationalization instance;
- private static object syncObject = new object();
-
public static Internationalization Instance
- {
- get
- {
- if (instance == null)
- {
- lock (syncObject)
- {
- if (instance == null)
- {
- instance = new Internationalization();
- }
- }
- }
- return instance;
- }
- }
+ => Ioc.Default.GetRequiredService();
}
-}
\ No newline at end of file
+}
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index 0c91f69ca..b791915bc 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -25,11 +25,11 @@ namespace Flow.Launcher.Core.Resource
private const int ShadowExtraMargin = 32;
- private readonly IPublicAPI API = Ioc.Default.GetRequiredService();
+ private readonly IPublicAPI API;
+ private readonly Settings Settings;
private readonly List _themeDirectories = new List();
private ResourceDictionary _oldResource;
private string _oldTheme;
- public Settings Settings { get; set; }
private const string Folder = Constant.Themes;
private const string Extension = ".xaml";
private string DirectoryPath => Path.Combine(Constant.ProgramDirectory, Folder);
@@ -39,8 +39,11 @@ namespace Flow.Launcher.Core.Resource
private double mainWindowWidth;
- public Theme()
+ public Theme(IPublicAPI publicAPI, Settings settings)
{
+ API = publicAPI;
+ Settings = settings;
+
_themeDirectories.Add(DirectoryPath);
_themeDirectories.Add(UserDirectoryPath);
MakeSureThemeDirectoriesExist();
diff --git a/Flow.Launcher.Core/Resource/ThemeManager.cs b/Flow.Launcher.Core/Resource/ThemeManager.cs
index 71f9acaa5..68cd90a7e 100644
--- a/Flow.Launcher.Core/Resource/ThemeManager.cs
+++ b/Flow.Launcher.Core/Resource/ThemeManager.cs
@@ -1,26 +1,10 @@
-namespace Flow.Launcher.Core.Resource
+using CommunityToolkit.Mvvm.DependencyInjection;
+
+namespace Flow.Launcher.Core.Resource
{
public class ThemeManager
{
- private static Theme instance;
- private static object syncObject = new object();
-
public static Theme Instance
- {
- get
- {
- if (instance == null)
- {
- lock (syncObject)
- {
- if (instance == null)
- {
- instance = new Theme();
- }
- }
- }
- return instance;
- }
- }
+ => Ioc.Default.GetRequiredService();
}
}
diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs
index dd0864c19..073084e4d 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -17,7 +17,6 @@ using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using System.Text.Json.Serialization;
using System.Threading;
-using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Core
{
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index b435b566f..c5fe3159f 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -50,8 +50,10 @@ namespace Flow.Launcher
.AddSingleton()
.AddSingleton()
.AddSingleton()
+ .AddSingleton()
.AddSingleton()
.AddSingleton()
+ .AddSingleton()
).Build();
Ioc.Default.ConfigureServices(host.Services);
@@ -93,7 +95,7 @@ namespace Flow.Launcher
Ioc.Default.GetRequiredService().UserSettingSearchPrecision = _settings.QuerySearchPrecision;
- InternationalizationManager.Instance.Settings = _settings;
+ // TODO: Clean InternationalizationManager.Instance and InternationalizationManager.Instance.GetTranslation in future
InternationalizationManager.Instance.ChangeLanguage(_settings.Language);
PluginManager.LoadPlugins(_settings.PluginSettings);
@@ -114,7 +116,7 @@ namespace Flow.Launcher
HotKeyMapper.Initialize(mainVM);
// main windows needs initialized before theme change because of blur settings
- ThemeManager.Instance.Settings = _settings;
+ // TODO: Clean ThemeManager.Instance in future
ThemeManager.Instance.ChangeTheme(_settings.Theme);
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
From d4f90999c76ae3467c55fc71fda0aa4cb14d8e96 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 23 Feb 2025 13:55:33 +0800
Subject: [PATCH 24/31] Improve constructor injection for updater
---
Flow.Launcher.Core/Updater.cs | 8 ++------
Flow.Launcher/App.xaml.cs | 4 +---
2 files changed, 3 insertions(+), 9 deletions(-)
diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs
index 073084e4d..43d86a487 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -24,15 +24,11 @@ namespace Flow.Launcher.Core
{
private readonly IPublicAPI API;
- public string GitHubRepository { get; set; }
+ public string GitHubRepository { get; init; }
- public Updater(IPublicAPI publicAPI)
+ public Updater(IPublicAPI publicAPI, string gitHubRepository)
{
API = publicAPI;
- }
-
- public void Initialize(string gitHubRepository)
- {
GitHubRepository = gitHubRepository;
}
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index c5fe3159f..67e536b1b 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -45,7 +45,7 @@ namespace Flow.Launcher
.UseContentRoot(AppContext.BaseDirectory)
.ConfigureServices(services => services
.AddSingleton(_ => _settings)
- .AddSingleton(sp => new Updater(sp.GetRequiredService()))
+ .AddSingleton(sp => new Updater(sp.GetRequiredService(), Launcher.Properties.Settings.Default.GithubRepo))
.AddSingleton()
.AddSingleton()
.AddSingleton()
@@ -79,8 +79,6 @@ namespace Flow.Launcher
{
await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
{
- Ioc.Default.GetRequiredService().Initialize(Launcher.Properties.Settings.Default.GithubRepo);
-
Ioc.Default.GetRequiredService().PreStartCleanUpAfterPortabilityUpdate();
Log.Info("|App.OnStartup|Begin Flow Launcher startup ----------------------------------------------------");
From e989b5ac284f70aba9be1233f6ef2ee0e1608908 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 23 Feb 2025 14:35:37 +0800
Subject: [PATCH 25/31] Add instance obsolete message
---
Flow.Launcher.Core/Resource/InternationalizationManager.cs | 4 +++-
Flow.Launcher.Core/Resource/ThemeManager.cs | 4 +++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/InternationalizationManager.cs b/Flow.Launcher.Core/Resource/InternationalizationManager.cs
index 79736edc3..5d718466c 100644
--- a/Flow.Launcher.Core/Resource/InternationalizationManager.cs
+++ b/Flow.Launcher.Core/Resource/InternationalizationManager.cs
@@ -1,7 +1,9 @@
-using CommunityToolkit.Mvvm.DependencyInjection;
+using System;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Core.Resource
{
+ [Obsolete("InternationalizationManager.Instance is obsolete. Use Ioc.Default.GetRequiredService() instead.")]
public static class InternationalizationManager
{
public static Internationalization Instance
diff --git a/Flow.Launcher.Core/Resource/ThemeManager.cs b/Flow.Launcher.Core/Resource/ThemeManager.cs
index 68cd90a7e..3cbe8319a 100644
--- a/Flow.Launcher.Core/Resource/ThemeManager.cs
+++ b/Flow.Launcher.Core/Resource/ThemeManager.cs
@@ -1,7 +1,9 @@
-using CommunityToolkit.Mvvm.DependencyInjection;
+using System;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Core.Resource
{
+ [Obsolete("ThemeManager.Instance is obsolete. Use Ioc.Default.GetRequiredService() instead.")]
public class ThemeManager
{
public static Theme Instance
From 8496cfc819276a6808efac29867edf93bbec521b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 23 Feb 2025 14:37:29 +0800
Subject: [PATCH 26/31] Use Ioc.Default in initialize function
---
Flow.Launcher/App.xaml.cs | 2 +-
Flow.Launcher/Helper/HotKeyMapper.cs | 9 ++++-----
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 67e536b1b..48007e995 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -111,7 +111,7 @@ namespace Flow.Launcher
Current.MainWindow = window;
Current.MainWindow.Title = Constant.FlowLauncher;
- HotKeyMapper.Initialize(mainVM);
+ HotKeyMapper.Initialize();
// main windows needs initialized before theme change because of blur settings
// TODO: Clean ThemeManager.Instance in future
diff --git a/Flow.Launcher/Helper/HotKeyMapper.cs b/Flow.Launcher/Helper/HotKeyMapper.cs
index 79b524f50..7b2fdfcf4 100644
--- a/Flow.Launcher/Helper/HotKeyMapper.cs
+++ b/Flow.Launcher/Helper/HotKeyMapper.cs
@@ -5,10 +5,9 @@ using NHotkey;
using NHotkey.Wpf;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.ViewModel;
-using Flow.Launcher.Core;
using ChefKeys;
-using System.Globalization;
using Flow.Launcher.Infrastructure.Logger;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Helper;
@@ -17,10 +16,10 @@ internal static class HotKeyMapper
private static Settings _settings;
private static MainViewModel _mainViewModel;
- internal static void Initialize(MainViewModel mainVM)
+ internal static void Initialize()
{
- _mainViewModel = mainVM;
- _settings = _mainViewModel.Settings;
+ _mainViewModel = Ioc.Default.GetRequiredService();
+ _settings = Ioc.Default.GetService();
SetHotkey(_settings.Hotkey, OnToggleHotkey);
LoadCustomPluginHotkey();
From ad63b0e7f402037c73b3e46e1e270221e1d54fb7 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 23 Feb 2025 19:48:38 +0800
Subject: [PATCH 27/31] Improve code quality for field names
---
Flow.Launcher.Core/Resource/Theme.cs | 48 +++++++++----------
Flow.Launcher.Core/Updater.cs | 28 +++++------
.../Views/ActionKeywordSetting.xaml.cs | 12 ++---
3 files changed, 44 insertions(+), 44 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index b791915bc..4deea1f66 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -25,9 +25,9 @@ namespace Flow.Launcher.Core.Resource
private const int ShadowExtraMargin = 32;
- private readonly IPublicAPI API;
- private readonly Settings Settings;
- private readonly List _themeDirectories = new List();
+ private readonly IPublicAPI _api;
+ private readonly Settings _settings;
+ private readonly List _themeDirectories = new();
private ResourceDictionary _oldResource;
private string _oldTheme;
private const string Folder = Constant.Themes;
@@ -41,8 +41,8 @@ namespace Flow.Launcher.Core.Resource
public Theme(IPublicAPI publicAPI, Settings settings)
{
- API = publicAPI;
- Settings = settings;
+ _api = publicAPI;
+ _settings = settings;
_themeDirectories.Add(DirectoryPath);
_themeDirectories.Add(UserDirectoryPath);
@@ -94,7 +94,7 @@ namespace Flow.Launcher.Core.Resource
// to things like fonts
UpdateResourceDictionary(GetResourceDictionary(theme));
- Settings.Theme = theme;
+ _settings.Theme = theme;
//always allow re-loading default theme, in case of failure of switching to a new theme from default theme
@@ -105,7 +105,7 @@ namespace Flow.Launcher.Core.Resource
BlurEnabled = Win32Helper.IsBlurTheme();
- if (Settings.UseDropShadowEffect && !BlurEnabled)
+ if (_settings.UseDropShadowEffect && !BlurEnabled)
AddDropShadowEffectToCurrentTheme();
Win32Helper.SetBlurForWindow(Application.Current.MainWindow, BlurEnabled);
@@ -115,7 +115,7 @@ namespace Flow.Launcher.Core.Resource
Log.Error($"|Theme.ChangeTheme|Theme <{theme}> path can't be found");
if (theme != defaultTheme)
{
- API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_path_not_exists"), theme));
+ _api.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_path_not_exists"), theme));
ChangeTheme(defaultTheme);
}
return false;
@@ -125,7 +125,7 @@ namespace Flow.Launcher.Core.Resource
Log.Error($"|Theme.ChangeTheme|Theme <{theme}> fail to parse");
if (theme != defaultTheme)
{
- API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_parse_error"), theme));
+ _api.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_parse_error"), theme));
ChangeTheme(defaultTheme);
}
return false;
@@ -153,7 +153,7 @@ namespace Flow.Launcher.Core.Resource
return dict;
}
- private ResourceDictionary CurrentThemeResourceDictionary() => GetThemeResourceDictionary(Settings.Theme);
+ private ResourceDictionary CurrentThemeResourceDictionary() => GetThemeResourceDictionary(_settings.Theme);
public ResourceDictionary GetResourceDictionary(string theme)
{
@@ -162,10 +162,10 @@ namespace Flow.Launcher.Core.Resource
if (dict["QueryBoxStyle"] is Style queryBoxStyle &&
dict["QuerySuggestionBoxStyle"] is Style querySuggestionBoxStyle)
{
- var fontFamily = new FontFamily(Settings.QueryBoxFont);
- var fontStyle = FontHelper.GetFontStyleFromInvariantStringOrNormal(Settings.QueryBoxFontStyle);
- var fontWeight = FontHelper.GetFontWeightFromInvariantStringOrNormal(Settings.QueryBoxFontWeight);
- var fontStretch = FontHelper.GetFontStretchFromInvariantStringOrNormal(Settings.QueryBoxFontStretch);
+ var fontFamily = new FontFamily(_settings.QueryBoxFont);
+ var fontStyle = FontHelper.GetFontStyleFromInvariantStringOrNormal(_settings.QueryBoxFontStyle);
+ var fontWeight = FontHelper.GetFontWeightFromInvariantStringOrNormal(_settings.QueryBoxFontWeight);
+ var fontStretch = FontHelper.GetFontStretchFromInvariantStringOrNormal(_settings.QueryBoxFontStretch);
queryBoxStyle.Setters.Add(new Setter(TextBox.FontFamilyProperty, fontFamily));
queryBoxStyle.Setters.Add(new Setter(TextBox.FontStyleProperty, fontStyle));
@@ -190,10 +190,10 @@ namespace Flow.Launcher.Core.Resource
dict["ItemHotkeyStyle"] is Style resultHotkeyItemStyle &&
dict["ItemHotkeySelectedStyle"] is Style resultHotkeyItemSelectedStyle)
{
- Setter fontFamily = new Setter(TextBlock.FontFamilyProperty, new FontFamily(Settings.ResultFont));
- Setter fontStyle = new Setter(TextBlock.FontStyleProperty, FontHelper.GetFontStyleFromInvariantStringOrNormal(Settings.ResultFontStyle));
- Setter fontWeight = new Setter(TextBlock.FontWeightProperty, FontHelper.GetFontWeightFromInvariantStringOrNormal(Settings.ResultFontWeight));
- Setter fontStretch = new Setter(TextBlock.FontStretchProperty, FontHelper.GetFontStretchFromInvariantStringOrNormal(Settings.ResultFontStretch));
+ Setter fontFamily = new Setter(TextBlock.FontFamilyProperty, new FontFamily(_settings.ResultFont));
+ Setter fontStyle = new Setter(TextBlock.FontStyleProperty, FontHelper.GetFontStyleFromInvariantStringOrNormal(_settings.ResultFontStyle));
+ Setter fontWeight = new Setter(TextBlock.FontWeightProperty, FontHelper.GetFontWeightFromInvariantStringOrNormal(_settings.ResultFontWeight));
+ Setter fontStretch = new Setter(TextBlock.FontStretchProperty, FontHelper.GetFontStretchFromInvariantStringOrNormal(_settings.ResultFontStretch));
Setter[] setters = { fontFamily, fontStyle, fontWeight, fontStretch };
Array.ForEach(
@@ -205,10 +205,10 @@ namespace Flow.Launcher.Core.Resource
dict["ItemSubTitleStyle"] is Style resultSubItemStyle &&
dict["ItemSubTitleSelectedStyle"] is Style resultSubItemSelectedStyle)
{
- Setter fontFamily = new Setter(TextBlock.FontFamilyProperty, new FontFamily(Settings.ResultSubFont));
- Setter fontStyle = new Setter(TextBlock.FontStyleProperty, FontHelper.GetFontStyleFromInvariantStringOrNormal(Settings.ResultSubFontStyle));
- Setter fontWeight = new Setter(TextBlock.FontWeightProperty, FontHelper.GetFontWeightFromInvariantStringOrNormal(Settings.ResultSubFontWeight));
- Setter fontStretch = new Setter(TextBlock.FontStretchProperty, FontHelper.GetFontStretchFromInvariantStringOrNormal(Settings.ResultSubFontStretch));
+ Setter fontFamily = new Setter(TextBlock.FontFamilyProperty, new FontFamily(_settings.ResultSubFont));
+ Setter fontStyle = new Setter(TextBlock.FontStyleProperty, FontHelper.GetFontStyleFromInvariantStringOrNormal(_settings.ResultSubFontStyle));
+ Setter fontWeight = new Setter(TextBlock.FontWeightProperty, FontHelper.GetFontWeightFromInvariantStringOrNormal(_settings.ResultSubFontWeight));
+ Setter fontStretch = new Setter(TextBlock.FontStretchProperty, FontHelper.GetFontStretchFromInvariantStringOrNormal(_settings.ResultSubFontStretch));
Setter[] setters = { fontFamily, fontStyle, fontWeight, fontStretch };
Array.ForEach(
@@ -218,7 +218,7 @@ namespace Flow.Launcher.Core.Resource
/* Ignore Theme Window Width and use setting */
var windowStyle = dict["WindowStyle"] as Style;
- var width = Settings.WindowSize;
+ var width = _settings.WindowSize;
windowStyle.Setters.Add(new Setter(Window.WidthProperty, width));
mainWindowWidth = (double)width;
return dict;
@@ -226,7 +226,7 @@ namespace Flow.Launcher.Core.Resource
private ResourceDictionary GetCurrentResourceDictionary( )
{
- return GetResourceDictionary(Settings.Theme);
+ return GetResourceDictionary(_settings.Theme);
}
public List LoadAvailableThemes()
diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs
index 43d86a487..9a77ece32 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -22,13 +22,13 @@ namespace Flow.Launcher.Core
{
public class Updater
{
- private readonly IPublicAPI API;
-
public string GitHubRepository { get; init; }
+ private readonly IPublicAPI _api;
+
public Updater(IPublicAPI publicAPI, string gitHubRepository)
{
- API = publicAPI;
+ _api = publicAPI;
GitHubRepository = gitHubRepository;
}
@@ -40,8 +40,8 @@ namespace Flow.Launcher.Core
try
{
if (!silentUpdate)
- API.ShowMsg(API.GetTranslation("pleaseWait"),
- API.GetTranslation("update_flowlauncher_update_check"));
+ _api.ShowMsg(_api.GetTranslation("pleaseWait"),
+ _api.GetTranslation("update_flowlauncher_update_check"));
using var updateManager = await GitHubUpdateManagerAsync(GitHubRepository).ConfigureAwait(false);
@@ -56,13 +56,13 @@ namespace Flow.Launcher.Core
if (newReleaseVersion <= currentVersion)
{
if (!silentUpdate)
- API.ShowMsgBox(API.GetTranslation("update_flowlauncher_already_on_latest"));
+ _api.ShowMsgBox(_api.GetTranslation("update_flowlauncher_already_on_latest"));
return;
}
if (!silentUpdate)
- API.ShowMsg(API.GetTranslation("update_flowlauncher_update_found"),
- API.GetTranslation("update_flowlauncher_updating"));
+ _api.ShowMsg(_api.GetTranslation("update_flowlauncher_update_found"),
+ _api.GetTranslation("update_flowlauncher_updating"));
await updateManager.DownloadReleases(newUpdateInfo.ReleasesToApply).ConfigureAwait(false);
@@ -71,9 +71,9 @@ namespace Flow.Launcher.Core
if (DataLocation.PortableDataLocationInUse())
{
var targetDestination = updateManager.RootAppDirectory + $"\\app-{newReleaseVersion.ToString()}\\{DataLocation.PortableFolderName}";
- FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination, (s) => API.ShowMsgBox(s));
- if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination, (s) => API.ShowMsgBox(s)))
- API.ShowMsgBox(string.Format(API.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
+ FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination, (s) => _api.ShowMsgBox(s));
+ if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination, (s) => _api.ShowMsgBox(s)))
+ _api.ShowMsgBox(string.Format(_api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
DataLocation.PortableDataPath,
targetDestination));
}
@@ -86,7 +86,7 @@ namespace Flow.Launcher.Core
Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}");
- if (API.ShowMsgBox(newVersionTips, API.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+ if (_api.ShowMsgBox(newVersionTips, _api.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
UpdateManager.RestartApp(Constant.ApplicationFileName);
}
@@ -99,8 +99,8 @@ namespace Flow.Launcher.Core
Log.Exception($"|Updater.UpdateApp|Error Occurred", e);
if (!silentUpdate)
- API.ShowMsg(API.GetTranslation("update_flowlauncher_fail"),
- API.GetTranslation("update_flowlauncher_check_connection"));
+ _api.ShowMsg(_api.GetTranslation("update_flowlauncher_fail"),
+ _api.GetTranslation("update_flowlauncher_check_connection"));
}
finally
{
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs
index 34a5b2760..73c35b1c8 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs
@@ -31,13 +31,13 @@ namespace Flow.Launcher.Plugin.Explorer.Views
}
private string actionKeyword;
- private readonly IPublicAPI api;
+ private readonly IPublicAPI _api;
private bool _keywordEnabled;
public ActionKeywordSetting(ActionKeywordModel selectedActionKeyword, IPublicAPI api)
{
CurrentActionKeyword = selectedActionKeyword;
- this.api = api;
+ _api = api;
ActionKeyword = selectedActionKeyword.Keyword;
KeywordEnabled = selectedActionKeyword.Enabled;
@@ -62,14 +62,14 @@ namespace Flow.Launcher.Plugin.Explorer.Views
switch (CurrentActionKeyword.KeywordProperty, KeywordEnabled)
{
case (Settings.ActionKeyword.FileContentSearchActionKeyword, true):
- api.ShowMsgBox(api.GetTranslation("plugin_explorer_globalActionKeywordInvalid"));
+ _api.ShowMsgBox(_api.GetTranslation("plugin_explorer_globalActionKeywordInvalid"));
return;
case (Settings.ActionKeyword.QuickAccessActionKeyword, true):
- api.ShowMsgBox(api.GetTranslation("plugin_explorer_quickaccess_globalActionKeywordInvalid"));
+ _api.ShowMsgBox(_api.GetTranslation("plugin_explorer_quickaccess_globalActionKeywordInvalid"));
return;
}
- if (!KeywordEnabled || !api.ActionKeywordAssigned(ActionKeyword))
+ if (!KeywordEnabled || !_api.ActionKeywordAssigned(ActionKeyword))
{
DialogResult = true;
Close();
@@ -77,7 +77,7 @@ namespace Flow.Launcher.Plugin.Explorer.Views
}
// The keyword is not valid, so show message
- api.ShowMsgBox(api.GetTranslation("newActionKeywordsHasBeenAssigned"));
+ _api.ShowMsgBox(_api.GetTranslation("newActionKeywordsHasBeenAssigned"));
}
private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
From f5f0986036a2ab86771a264c32116d7093cbf2ff Mon Sep 17 00:00:00 2001
From: Hongtao Zhang
Date: Sun, 23 Feb 2025 21:54:08 +0800
Subject: [PATCH 28/31] remove some usage of Ioc.GetRequiredService when
injection is possible.
---
Flow.Launcher.Infrastructure/StringMatcher.cs | 9 +++----
Flow.Launcher/App.xaml.cs | 2 --
Flow.Launcher/PublicAPIInstance.cs | 4 ++--
Flow.Launcher/SettingWindow.xaml.cs | 2 +-
.../ViewModel/SettingWindowViewModel.cs | 24 +++++++++----------
5 files changed, 18 insertions(+), 23 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs
index 55aa0a1ec..2707308d5 100644
--- a/Flow.Launcher.Infrastructure/StringMatcher.cs
+++ b/Flow.Launcher.Infrastructure/StringMatcher.cs
@@ -3,6 +3,7 @@ using Flow.Launcher.Plugin.SharedModels;
using System;
using System.Collections.Generic;
using System.Linq;
+using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher.Infrastructure
{
@@ -14,15 +15,11 @@ namespace Flow.Launcher.Infrastructure
private readonly IAlphabet _alphabet;
- public StringMatcher()
- {
- _alphabet = Ioc.Default.GetRequiredService();
- }
-
// This is a workaround to allow unit tests to set the instance
- public StringMatcher(IAlphabet alphabet)
+ public StringMatcher(IAlphabet alphabet, Settings settings)
{
_alphabet = alphabet;
+ UserSettingSearchPrecision = settings.QuerySearchPrecision;
}
public static MatchResult FuzzySearch(string query, string stringToCompare)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 48007e995..952ca70c4 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -91,8 +91,6 @@ namespace Flow.Launcher
AbstractPluginEnvironment.PreStartPluginExecutablePathUpdate(_settings);
- Ioc.Default.GetRequiredService().UserSettingSearchPrecision = _settings.QuerySearchPrecision;
-
// TODO: Clean InternationalizationManager.Instance and InternationalizationManager.Instance.GetTranslation in future
InternationalizationManager.Instance.ChangeLanguage(_settings.Language);
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 6123a93d9..528f54172 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -247,7 +247,7 @@ namespace Flow.Launcher
public void OpenDirectory(string DirectoryPath, string FileNameOrFilePath = null)
{
using var explorer = new Process();
- var explorerInfo = _settingsVM.Settings.CustomExplorer;
+ var explorerInfo = _settingsVM._settings.CustomExplorer;
explorer.StartInfo = new ProcessStartInfo
{
@@ -268,7 +268,7 @@ namespace Flow.Launcher
{
if (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps)
{
- var browserInfo = _settingsVM.Settings.CustomBrowser;
+ var browserInfo = _settingsVM._settings.CustomBrowser;
var path = browserInfo.Path == "*" ? "" : browserInfo.Path;
diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs
index 8b15150cf..f87194c30 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -27,7 +27,7 @@ public partial class SettingWindow
public SettingWindow()
{
var viewModel = Ioc.Default.GetRequiredService();
- _settings = viewModel.Settings;
+ _settings = Ioc.Default.GetRequiredService();
DataContext = viewModel;
_viewModel = viewModel;
_updater = Ioc.Default.GetRequiredService();
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index 37276a1ad..0a1968d9d 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -6,11 +6,11 @@ namespace Flow.Launcher.ViewModel;
public partial class SettingWindowViewModel : BaseModel
{
- public Settings Settings { get; init; }
+ public readonly Settings _settings;
- public SettingWindowViewModel()
+ public SettingWindowViewModel(Settings settings)
{
- Settings = Ioc.Default.GetRequiredService();
+ _settings = settings;
}
///
@@ -18,30 +18,30 @@ public partial class SettingWindowViewModel : BaseModel
///
public void Save()
{
- Settings.Save();
+ _settings.Save();
}
public double SettingWindowWidth
{
- get => Settings.SettingWindowWidth;
- set => Settings.SettingWindowWidth = value;
+ get => _settings.SettingWindowWidth;
+ set => _settings.SettingWindowWidth = value;
}
public double SettingWindowHeight
{
- get => Settings.SettingWindowHeight;
- set => Settings.SettingWindowHeight = value;
+ get => _settings.SettingWindowHeight;
+ set => _settings.SettingWindowHeight = value;
}
public double? SettingWindowTop
{
- get => Settings.SettingWindowTop;
- set => Settings.SettingWindowTop = value;
+ get => _settings.SettingWindowTop;
+ set => _settings.SettingWindowTop = value;
}
public double? SettingWindowLeft
{
- get => Settings.SettingWindowLeft;
- set => Settings.SettingWindowLeft = value;
+ get => _settings.SettingWindowLeft;
+ set => _settings.SettingWindowLeft = value;
}
}
From ef68ccb70a231e823b7ee7555b548a856dba7606 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 23 Feb 2025 21:59:35 +0800
Subject: [PATCH 29/31] Fix unit test issue
---
Flow.Launcher.Infrastructure/StringMatcher.cs | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs
index 2707308d5..e85c5d6f4 100644
--- a/Flow.Launcher.Infrastructure/StringMatcher.cs
+++ b/Flow.Launcher.Infrastructure/StringMatcher.cs
@@ -15,13 +15,18 @@ namespace Flow.Launcher.Infrastructure
private readonly IAlphabet _alphabet;
- // This is a workaround to allow unit tests to set the instance
public StringMatcher(IAlphabet alphabet, Settings settings)
{
_alphabet = alphabet;
UserSettingSearchPrecision = settings.QuerySearchPrecision;
}
+ // This is a workaround to allow unit tests to set the instance
+ public StringMatcher(IAlphabet alphabet)
+ {
+ _alphabet = alphabet;
+ }
+
public static MatchResult FuzzySearch(string query, string stringToCompare)
{
return Ioc.Default.GetRequiredService().FuzzyMatch(query, stringToCompare);
From 91490c0251c8fe845d175522c54bf63b9c4b00ca Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 23 Feb 2025 22:05:49 +0800
Subject: [PATCH 30/31] Remove usage of _settingsVM._settings and make
_settings private
---
Flow.Launcher/PublicAPIInstance.cs | 7 +++++--
Flow.Launcher/ViewModel/SettingWindowViewModel.cs | 5 ++---
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 528f54172..6c6ba9f8c 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -27,11 +27,13 @@ using System.Diagnostics;
using System.Collections.Specialized;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core;
+using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher
{
public class PublicAPIInstance : IPublicAPI
{
+ private readonly Settings _settings;
private readonly SettingWindowViewModel _settingsVM;
private readonly MainViewModel _mainVM;
@@ -39,6 +41,7 @@ namespace Flow.Launcher
public PublicAPIInstance()
{
+ _settings = Ioc.Default.GetRequiredService();
_settingsVM = Ioc.Default.GetRequiredService();
_mainVM = Ioc.Default.GetRequiredService();
GlobalHotkey.hookedKeyboardCallback = KListener_hookedKeyboardCallback;
@@ -247,7 +250,7 @@ namespace Flow.Launcher
public void OpenDirectory(string DirectoryPath, string FileNameOrFilePath = null)
{
using var explorer = new Process();
- var explorerInfo = _settingsVM._settings.CustomExplorer;
+ var explorerInfo = _settings.CustomExplorer;
explorer.StartInfo = new ProcessStartInfo
{
@@ -268,7 +271,7 @@ namespace Flow.Launcher
{
if (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps)
{
- var browserInfo = _settingsVM._settings.CustomBrowser;
+ var browserInfo = _settings.CustomBrowser;
var path = browserInfo.Path == "*" ? "" : browserInfo.Path;
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index 0a1968d9d..51afe533d 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -1,12 +1,11 @@
-using CommunityToolkit.Mvvm.DependencyInjection;
-using Flow.Launcher.Infrastructure.UserSettings;
+using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
namespace Flow.Launcher.ViewModel;
public partial class SettingWindowViewModel : BaseModel
{
- public readonly Settings _settings;
+ private readonly Settings _settings;
public SettingWindowViewModel(Settings settings)
{
From 16798a06ce3874647da77d806503c1314ed95d3f Mon Sep 17 00:00:00 2001
From: Hongtao Zhang
Date: Mon, 24 Feb 2025 09:40:33 +0800
Subject: [PATCH 31/31] use constructor injection for PublicAPIInstance.cs
---
Flow.Launcher/PublicAPIInstance.cs | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 6c6ba9f8c..1a08150e5 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -34,16 +34,14 @@ namespace Flow.Launcher
public class PublicAPIInstance : IPublicAPI
{
private readonly Settings _settings;
- private readonly SettingWindowViewModel _settingsVM;
private readonly MainViewModel _mainVM;
#region Constructor
- public PublicAPIInstance()
+ public PublicAPIInstance(Settings settings, MainViewModel mainVM)
{
- _settings = Ioc.Default.GetRequiredService();
- _settingsVM = Ioc.Default.GetRequiredService();
- _mainVM = Ioc.Default.GetRequiredService();
+ _settings = settings;
+ _mainVM = mainVM;
GlobalHotkey.hookedKeyboardCallback = KListener_hookedKeyboardCallback;
WebRequest.RegisterPrefix("data", new DataWebRequestFactory());
}
@@ -87,7 +85,7 @@ namespace Flow.Launcher
{
PluginManager.Save();
_mainVM.Save();
- _settingsVM.Save();
+ _settings.Save();
_ = ImageLoader.Save();
}