mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Merge pull request #3175 from Jack251970/dev4
Introduce Dependency Injection for Better Development Experience
This commit is contained in:
commit
e299721e96
37 changed files with 288 additions and 262 deletions
|
|
@ -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<IPublicAPI>();
|
||||
|
||||
/// <summary>
|
||||
/// As at Squirrel.Windows version 1.5.2, UpdateManager needs to be disposed after finish
|
||||
/// </summary>
|
||||
|
|
@ -40,7 +44,7 @@ namespace Flow.Launcher.Core.Configuration
|
|||
#endif
|
||||
IndicateDeletion(DataLocation.PortableDataPath);
|
||||
|
||||
MessageBoxEx.Show("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);
|
||||
|
||||
MessageBoxEx.Show("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, MessageBoxEx.Show);
|
||||
FilesFolders.CopyAll(fromLocation, toLocation, (s) => API.ShowMsgBox(s));
|
||||
VerifyUserDataAfterMove(fromLocation, toLocation);
|
||||
}
|
||||
|
||||
public void VerifyUserDataAfterMove(string fromLocation, string toLocation)
|
||||
{
|
||||
FilesFolders.VerifyBothFolderFilesEqual(fromLocation, toLocation, MessageBoxEx.Show);
|
||||
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, MessageBoxEx.Show);
|
||||
FilesFolders.RemoveFolderIfExists(roamingDataDir, (s) => API.ShowMsgBox(s));
|
||||
|
||||
if (MessageBoxEx.Show("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, MessageBoxEx.Show);
|
||||
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, MessageBoxEx.Show);
|
||||
FilesFolders.RemoveFolderIfExists(portableDataDir, (s) => API.ShowMsgBox(s));
|
||||
|
||||
MessageBoxEx.Show("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)
|
||||
{
|
||||
MessageBoxEx.Show(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));
|
||||
|
||||
|
|
|
|||
|
|
@ -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<IPublicAPI>();
|
||||
|
||||
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<PluginMetadata> PluginMetadataList;
|
||||
|
||||
|
|
@ -57,7 +60,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
|
|||
EnvName,
|
||||
Environment.NewLine
|
||||
);
|
||||
if (MessageBoxEx.Show(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
|
||||
{
|
||||
MessageBoxEx.Show(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, MessageBoxEx.Show);
|
||||
FilesFolders.RemoveFolderIfExists(installedDirPath, (s) => API.ShowMsgBox(s));
|
||||
|
||||
InstallEnvironment();
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
|
|||
|
||||
internal override void InstallEnvironment()
|
||||
{
|
||||
FilesFolders.RemoveFolderIfExists(InstallPath, MessageBoxEx.Show);
|
||||
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
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
|
|||
|
||||
internal override void InstallEnvironment()
|
||||
{
|
||||
FilesFolders.RemoveFolderIfExists(InstallPath, MessageBoxEx.Show);
|
||||
FilesFolders.RemoveFolderIfExists(InstallPath, (s) => API.ShowMsgBox(s));
|
||||
|
||||
DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath).Wait();
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
|
|||
|
||||
internal override void InstallEnvironment()
|
||||
{
|
||||
FilesFolders.RemoveFolderIfExists(InstallPath, MessageBoxEx.Show);
|
||||
FilesFolders.RemoveFolderIfExists(InstallPath, (s) => API.ShowMsgBox(s));
|
||||
|
||||
DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath).Wait();
|
||||
|
||||
|
|
|
|||
|
|
@ -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<PluginPair> GlobalPlugins = new();
|
||||
public static readonly Dictionary<string, PluginPair> NonGlobalPlugins = new();
|
||||
|
||||
public static IPublicAPI API { private set; get; }
|
||||
public static IPublicAPI API { get; private set; } = Ioc.Default.GetRequiredService<IPublicAPI>();
|
||||
|
||||
private static PluginsSettings Settings;
|
||||
private static List<PluginMetadata> _metadatas;
|
||||
|
|
@ -158,9 +159,8 @@ namespace Flow.Launcher.Core.Plugin
|
|||
/// Call initialize for all plugins
|
||||
/// </summary>
|
||||
/// <returns>return the list of failed to init plugins or null for none</returns>
|
||||
public static async Task InitializePluginsAsync(IPublicAPI api)
|
||||
public static async Task InitializePluginsAsync()
|
||||
{
|
||||
API = api;
|
||||
var failedPlugins = new ConcurrentQueue<PluginPair>();
|
||||
|
||||
var InitTasks = AllPlugins.Select(pair => Task.Run(async delegate
|
||||
|
|
@ -204,7 +204,7 @@ namespace Flow.Launcher.Core.Plugin
|
|||
}
|
||||
|
||||
InternationalizationManager.Instance.AddPluginLanguageDirectories(GetPluginsForInterface<IPluginI18n>());
|
||||
InternationalizationManager.Instance.ChangeLanguage(InternationalizationManager.Instance.Settings.Language);
|
||||
InternationalizationManager.Instance.ChangeLanguage(Ioc.Default.GetRequiredService<Settings>().Language);
|
||||
|
||||
if (failedPlugins.Any())
|
||||
{
|
||||
|
|
@ -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) => API.ShowMsgBox(s));
|
||||
|
||||
try
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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(() =>
|
||||
{
|
||||
MessageBoxEx.Show($"{errorMessage}{Environment.NewLine}{Environment.NewLine}" +
|
||||
Ioc.Default.GetRequiredService<IPublicAPI>().ShowMsgBox($"{errorMessage}{Environment.NewLine}{Environment.NewLine}" +
|
||||
$"{errorPluginString}{Environment.NewLine}{Environment.NewLine}" +
|
||||
$"Please refer to the logs for more information", "",
|
||||
MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
|
|
|
|||
|
|
@ -11,22 +11,24 @@ 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
|
||||
{
|
||||
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<string> _languageDirectories = new List<string>();
|
||||
private readonly List<ResourceDictionary> _oldResources = new List<ResourceDictionary>();
|
||||
private readonly string SystemLanguageCode;
|
||||
|
||||
public Internationalization()
|
||||
public Internationalization(Settings settings)
|
||||
{
|
||||
_settings = settings;
|
||||
AddFlowLauncherLanguageDirectory();
|
||||
SystemLanguageCode = GetSystemLanguageCodeAtStartup();
|
||||
}
|
||||
|
|
@ -141,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();
|
||||
|
|
@ -152,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)
|
||||
|
|
@ -162,7 +164,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 (Ioc.Default.GetRequiredService<IPublicAPI>().ShowMsgBox(text, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -1,26 +1,12 @@
|
|||
namespace Flow.Launcher.Core.Resource
|
||||
using System;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
|
||||
namespace Flow.Launcher.Core.Resource
|
||||
{
|
||||
[Obsolete("InternationalizationManager.Instance is obsolete. Use Ioc.Default.GetRequiredService<Internationalization>() instead.")]
|
||||
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<Internationalization>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,12 @@ using System.Windows.Controls;
|
|||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Effects;
|
||||
using System.Windows.Shell;
|
||||
using Flow.Launcher.Infrastructure;
|
||||
using Flow.Launcher.Infrastructure.Logger;
|
||||
using Flow.Launcher.Infrastructure.UserSettings;
|
||||
using System.Windows.Shell;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using Flow.Launcher.Plugin;
|
||||
|
||||
namespace Flow.Launcher.Core.Resource
|
||||
{
|
||||
|
|
@ -23,10 +25,11 @@ namespace Flow.Launcher.Core.Resource
|
|||
|
||||
private const int ShadowExtraMargin = 32;
|
||||
|
||||
private readonly List<string> _themeDirectories = new List<string>();
|
||||
private readonly IPublicAPI _api;
|
||||
private readonly Settings _settings;
|
||||
private readonly List<string> _themeDirectories = new();
|
||||
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);
|
||||
|
|
@ -36,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();
|
||||
|
|
@ -88,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
|
||||
|
|
@ -99,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);
|
||||
|
|
@ -109,7 +115,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));
|
||||
_api.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_path_not_exists"), theme));
|
||||
ChangeTheme(defaultTheme);
|
||||
}
|
||||
return false;
|
||||
|
|
@ -119,7 +125,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));
|
||||
_api.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_parse_error"), theme));
|
||||
ChangeTheme(defaultTheme);
|
||||
}
|
||||
return false;
|
||||
|
|
@ -147,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)
|
||||
{
|
||||
|
|
@ -156,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));
|
||||
|
|
@ -184,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(
|
||||
|
|
@ -199,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(
|
||||
|
|
@ -212,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;
|
||||
|
|
@ -220,7 +226,7 @@ namespace Flow.Launcher.Core.Resource
|
|||
|
||||
private ResourceDictionary GetCurrentResourceDictionary( )
|
||||
{
|
||||
return GetResourceDictionary(Settings.Theme);
|
||||
return GetResourceDictionary(_settings.Theme);
|
||||
}
|
||||
|
||||
public List<ThemeData> LoadAvailableThemes()
|
||||
|
|
|
|||
|
|
@ -1,26 +1,12 @@
|
|||
namespace Flow.Launcher.Core.Resource
|
||||
using System;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
|
||||
namespace Flow.Launcher.Core.Resource
|
||||
{
|
||||
[Obsolete("ThemeManager.Instance is obsolete. Use Ioc.Default.GetRequiredService<Theme>() instead.")]
|
||||
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<Theme>();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,23 +22,26 @@ namespace Flow.Launcher.Core
|
|||
{
|
||||
public class Updater
|
||||
{
|
||||
public string GitHubRepository { get; }
|
||||
public string GitHubRepository { get; init; }
|
||||
|
||||
public Updater(string gitHubRepository)
|
||||
private readonly IPublicAPI _api;
|
||||
|
||||
public Updater(IPublicAPI publicAPI, string gitHubRepository)
|
||||
{
|
||||
_api = publicAPI;
|
||||
GitHubRepository = gitHubRepository;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
|
@ -53,13 +56,13 @@ namespace Flow.Launcher.Core
|
|||
if (newReleaseVersion <= currentVersion)
|
||||
{
|
||||
if (!silentUpdate)
|
||||
MessageBoxEx.Show(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);
|
||||
|
||||
|
|
@ -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, 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) => _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 (MessageBoxEx.Show(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);
|
||||
}
|
||||
|
|
@ -96,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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Ben.Demystifier" Version="0.4.1" />
|
||||
<PackageReference Include="BitFaster.Caching" Version="2.5.3" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
||||
<PackageReference Include="Fody" Version="6.5.5">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
|
|
|
|||
|
|
@ -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,8 +18,6 @@ namespace Flow.Launcher.Infrastructure.Http
|
|||
|
||||
private static HttpClient client = new HttpClient();
|
||||
|
||||
public static IPublicAPI API { get; set; }
|
||||
|
||||
static Http()
|
||||
{
|
||||
// need to be added so it would work on a win10 machine
|
||||
|
|
@ -78,7 +77,7 @@ namespace Flow.Launcher.Infrastructure.Http
|
|||
}
|
||||
catch (UriFormatException e)
|
||||
{
|
||||
API.ShowMsg("Please try again", "Unable to parse Http Proxy");
|
||||
Ioc.Default.GetRequiredService<IPublicAPI>().ShowMsg("Please try again", "Unable to parse Http Proxy");
|
||||
Log.Exception("Flow.Launcher.Infrastructure.Http", "Unable to parse Uri", e);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Settings>());
|
||||
}
|
||||
|
||||
private void Initialize([NotNull] Settings settings)
|
||||
{
|
||||
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,35 @@
|
|||
using Flow.Launcher.Plugin.SharedModels;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using Flow.Launcher.Plugin.SharedModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Flow.Launcher.Infrastructure.UserSettings;
|
||||
|
||||
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(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 StringMatcher Instance { get; internal set; }
|
||||
|
||||
public static MatchResult FuzzySearch(string query, string stringToCompare)
|
||||
{
|
||||
return Instance.FuzzyMatch(query, stringToCompare);
|
||||
return Ioc.Default.GetRequiredService<StringMatcher>().FuzzyMatch(query, stringToCompare);
|
||||
}
|
||||
|
||||
public MatchResult FuzzyMatch(string query, string stringToCompare)
|
||||
|
|
@ -241,16 +248,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<int> spaceIndices, int firstMatchIndex)
|
||||
private static int CalculateClosestSpaceIndex(List<int> spaceIndices, int firstMatchIndex)
|
||||
{
|
||||
var closestSpaceIndex = -1;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
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 CommunityToolkit.Mvvm.DependencyInjection;
|
||||
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 +14,24 @@ namespace Flow.Launcher.Infrastructure.UserSettings
|
|||
{
|
||||
public class Settings : BaseModel, IHotkeySettings
|
||||
{
|
||||
private FlowLauncherJsonStorage<Settings> _storage;
|
||||
private StringMatcher _stringMatcher = null;
|
||||
|
||||
public void SetStorage(FlowLauncherJsonStorage<Settings> storage)
|
||||
{
|
||||
_storage = storage;
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
_stringMatcher = Ioc.Default.GetRequiredService<StringMatcher>();
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
_storage.Save();
|
||||
}
|
||||
|
||||
private string language = Constant.SystemLanguageCode;
|
||||
private string _theme = Constant.DefaultTheme;
|
||||
public string Hotkey { get; set; } = $"{KeyConstant.Alt} + {KeyConstant.Space}";
|
||||
|
|
@ -180,7 +199,6 @@ namespace Flow.Launcher.Infrastructure.UserSettings
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// when false Alphabet static service will always return empty results
|
||||
/// </summary>
|
||||
|
|
@ -198,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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,10 @@ namespace Flow.Launcher.Test
|
|||
private const string MicrosoftSqlServerManagementStudio = "Microsoft SQL Server Management Studio";
|
||||
private const string VisualStudioCode = "Visual Studio Code";
|
||||
|
||||
public static List<string> GetSearchStrings()
|
||||
=> new()
|
||||
private readonly IAlphabet alphabet = null;
|
||||
|
||||
public List<string> GetSearchStrings()
|
||||
=> new List<string>
|
||||
{
|
||||
Chrome,
|
||||
"Choose which programs you want Windows to use for activities like web browsing, editing photos, sending e-mail, and playing music.",
|
||||
|
|
@ -60,7 +62,7 @@ namespace Flow.Launcher.Test
|
|||
};
|
||||
|
||||
var results = new List<Result>();
|
||||
var matcher = new StringMatcher();
|
||||
var matcher = new StringMatcher(alphabet);
|
||||
foreach (var str in sources)
|
||||
{
|
||||
results.Add(new Result
|
||||
|
|
@ -82,7 +84,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;
|
||||
|
||||
ClassicAssert.True(scoreResult == 0);
|
||||
|
|
@ -98,7 +100,7 @@ namespace Flow.Launcher.Test
|
|||
string searchTerm)
|
||||
{
|
||||
var results = new List<Result>();
|
||||
var matcher = new StringMatcher();
|
||||
var matcher = new StringMatcher(alphabet);
|
||||
foreach (var str in GetSearchStrings())
|
||||
{
|
||||
results.Add(new Result
|
||||
|
|
@ -148,7 +150,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
|
||||
|
|
@ -182,7 +184,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);
|
||||
|
|
@ -233,7 +235,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);
|
||||
|
|
@ -261,7 +263,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);
|
||||
|
|
@ -294,7 +296,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);
|
||||
|
|
@ -324,7 +326,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;
|
||||
|
|
@ -359,7 +361,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;
|
||||
ClassicAssert.IsTrue(score == desiredScore,
|
||||
$@"Query: ""{queryString}""
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ namespace Flow.Launcher
|
|||
else
|
||||
{
|
||||
string msg = translater.GetTranslation("newActionKeywordsHasBeenAssigned");
|
||||
MessageBoxEx.Show(msg);
|
||||
App.API.ShowMsgBox(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -14,24 +15,52 @@ 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;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
|
||||
|
||||
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;
|
||||
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;
|
||||
private readonly Settings _settings;
|
||||
|
||||
public App()
|
||||
{
|
||||
// Initialize settings
|
||||
var storage = new FlowLauncherJsonStorage<Settings>();
|
||||
_settings = storage.Load();
|
||||
_settings.SetStorage(storage);
|
||||
_settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled();
|
||||
|
||||
// Configure the dependency injection container
|
||||
var host = Host.CreateDefaultBuilder()
|
||||
.UseContentRoot(AppContext.BaseDirectory)
|
||||
.ConfigureServices(services => services
|
||||
.AddSingleton(_ => _settings)
|
||||
.AddSingleton(sp => new Updater(sp.GetRequiredService<IPublicAPI>(), Launcher.Properties.Settings.Default.GithubRepo))
|
||||
.AddSingleton<Portable>()
|
||||
.AddSingleton<SettingWindowViewModel>()
|
||||
.AddSingleton<IAlphabet, PinyinAlphabet>()
|
||||
.AddSingleton<StringMatcher>()
|
||||
.AddSingleton<Internationalization>()
|
||||
.AddSingleton<IPublicAPI, PublicAPIInstance>()
|
||||
.AddSingleton<MainViewModel>()
|
||||
.AddSingleton<Theme>()
|
||||
).Build();
|
||||
Ioc.Default.ConfigureServices(host.Services);
|
||||
|
||||
// Initialize the public API and Settings first
|
||||
API = Ioc.Default.GetRequiredService<IPublicAPI>();
|
||||
_settings.Initialize();
|
||||
}
|
||||
|
||||
[STAThread]
|
||||
public static void Main()
|
||||
|
|
@ -50,52 +79,40 @@ namespace Flow.Launcher
|
|||
{
|
||||
await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
|
||||
{
|
||||
_portable.PreStartCleanUpAfterPortabilityUpdate();
|
||||
Ioc.Default.GetRequiredService<Portable>().PreStartCleanUpAfterPortabilityUpdate();
|
||||
|
||||
Log.Info(
|
||||
"|App.OnStartup|Begin Flow Launcher startup ----------------------------------------------------");
|
||||
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(_updater, _portable);
|
||||
_settings = _settingsVM.Settings;
|
||||
_settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled();
|
||||
|
||||
AbstractPluginEnvironment.PreStartPluginExecutablePathUpdate(_settings);
|
||||
|
||||
_alphabet.Initialize(_settings);
|
||||
_stringMatcher = new StringMatcher(_alphabet);
|
||||
StringMatcher.Instance = _stringMatcher;
|
||||
_stringMatcher.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);
|
||||
_mainVM = new MainViewModel(_settings);
|
||||
|
||||
API = new PublicAPIInstance(_settingsVM, _mainVM, _alphabet);
|
||||
|
||||
Http.API = API;
|
||||
Http.Proxy = _settings.Proxy;
|
||||
|
||||
await PluginManager.InitializePluginsAsync(API);
|
||||
await PluginManager.InitializePluginsAsync();
|
||||
await imageLoadertask;
|
||||
|
||||
var window = new MainWindow(_settings, _mainVM);
|
||||
var mainVM = Ioc.Default.GetRequiredService<MainViewModel>();
|
||||
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();
|
||||
|
||||
// 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);
|
||||
|
|
@ -141,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<Updater>().UpdateAppAsync();
|
||||
|
||||
while (await timer.WaitForNextTickAsync())
|
||||
// check updates on startup
|
||||
await _updater.UpdateAppAsync(API);
|
||||
await Ioc.Default.GetRequiredService<Updater>().UpdateAppAsync();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -188,7 +205,7 @@ namespace Flow.Launcher
|
|||
|
||||
public void OnSecondAppStarted()
|
||||
{
|
||||
_mainVM.Show();
|
||||
Ioc.Default.GetRequiredService<MainViewModel>().Show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 readonly Settings _settings;
|
||||
private bool update;
|
||||
private CustomPluginHotkey updateCustomHotkey;
|
||||
|
||||
public CustomQueryHotkeySetting(SettingWindow settingWidow, Settings settings)
|
||||
public CustomQueryHotkeySetting(Settings settings)
|
||||
{
|
||||
_settingWidow = settingWidow;
|
||||
_settings = settings;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
|
@ -63,7 +60,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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
|
|
@ -90,6 +90,8 @@
|
|||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="InputSimulator" Version="1.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
|
||||
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.106">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
|
|
|
|||
|
|
@ -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<MainViewModel>();
|
||||
_settings = Ioc.Default.GetService<Settings>();
|
||||
|
||||
SetHotkey(_settings.Hotkey, OnToggleHotkey);
|
||||
LoadCustomPluginHotkey();
|
||||
|
|
@ -85,7 +84,7 @@ internal static class HotKeyMapper
|
|||
hotkeyStr));
|
||||
string errorMsg = string.Format(InternationalizationManager.Instance.GetTranslation("registerHotkeyFailed"), hotkeyStr);
|
||||
string errorMsgTitle = InternationalizationManager.Instance.GetTranslation("MessageBoxTitle");
|
||||
MessageBoxEx.Show(errorMsg, errorMsgTitle);
|
||||
App.API.ShowMsgBox(errorMsg, errorMsgTitle);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
<Window
|
||||
x:Class="Flow.Launcher.Core.MessageBoxEx"
|
||||
x:Class="Flow.Launcher.MessageBoxEx"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Flow.Launcher.Core"
|
||||
xmlns:local="clr-namespace:Flow.Launcher"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
x:Name="MessageBoxWindow"
|
||||
Width="420"
|
||||
|
|
@ -7,7 +7,7 @@ using Flow.Launcher.Infrastructure;
|
|||
using Flow.Launcher.Infrastructure.Image;
|
||||
using Flow.Launcher.Infrastructure.Logger;
|
||||
|
||||
namespace Flow.Launcher.Core
|
||||
namespace Flow.Launcher
|
||||
{
|
||||
public partial class MessageBoxEx : Window
|
||||
{
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,23 +25,23 @@ using Flow.Launcher.Infrastructure.Storage;
|
|||
using System.Collections.Concurrent;
|
||||
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 SettingWindowViewModel _settingsVM;
|
||||
private readonly Settings _settings;
|
||||
private readonly MainViewModel _mainVM;
|
||||
private readonly PinyinAlphabet _alphabet;
|
||||
|
||||
#region Constructor
|
||||
|
||||
public PublicAPIInstance(SettingWindowViewModel settingsVM, MainViewModel mainVM, PinyinAlphabet alphabet)
|
||||
public PublicAPIInstance(Settings settings, MainViewModel mainVM)
|
||||
{
|
||||
_settingsVM = settingsVM;
|
||||
_settings = settings;
|
||||
_mainVM = mainVM;
|
||||
_alphabet = alphabet;
|
||||
GlobalHotkey.hookedKeyboardCallback = KListener_hookedKeyboardCallback;
|
||||
WebRequest.RegisterPrefix("data", new DataWebRequestFactory());
|
||||
}
|
||||
|
|
@ -78,14 +78,15 @@ namespace Flow.Launcher
|
|||
|
||||
public event VisibilityChangedEventHandler VisibilityChanged { add => _mainVM.VisibilityChanged += value; remove => _mainVM.VisibilityChanged -= value; }
|
||||
|
||||
public void CheckForNewUpdate() => _settingsVM.UpdateApp();
|
||||
// Must use Ioc.Default.GetRequiredService<Updater>() to avoid circular dependency
|
||||
public void CheckForNewUpdate() => _ = Ioc.Default.GetRequiredService<Updater>().UpdateAppAsync(false);
|
||||
|
||||
public void SaveAppAllSettings()
|
||||
{
|
||||
PluginManager.Save();
|
||||
_mainVM.Save();
|
||||
_settingsVM.Save();
|
||||
ImageLoader.Save();
|
||||
_settings.Save();
|
||||
_ = ImageLoader.Save();
|
||||
}
|
||||
|
||||
public Task ReloadAllPluginData() => PluginManager.ReloadDataAsync();
|
||||
|
|
@ -105,7 +106,7 @@ namespace Flow.Launcher
|
|||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
SettingWindow sw = SingletonWindowOpener.Open<SettingWindow>(this, _settingsVM);
|
||||
SettingWindow sw = SingletonWindowOpener.Open<SettingWindow>();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -247,7 +248,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 +269,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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
|
|||
|
||||
private void UpdateApp()
|
||||
{
|
||||
_ = _updater.UpdateAppAsync(App.API, false);
|
||||
_ = _updater.UpdateAppAsync(false);
|
||||
}
|
||||
|
||||
public bool AutoUpdates
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
@ -42,11 +41,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,11 +66,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 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]
|
||||
|
|
@ -88,11 +87,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 +111,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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
{
|
||||
_settings = viewModel.Settings;
|
||||
var viewModel = Ioc.Default.GetRequiredService<SettingWindowViewModel>();
|
||||
_settings = Ioc.Default.GetRequiredService<Settings>();
|
||||
DataContext = viewModel;
|
||||
_viewModel = viewModel;
|
||||
_api = api;
|
||||
_updater = Ioc.Default.GetRequiredService<Updater>();
|
||||
_portable = Ioc.Default.GetRequiredService<Portable>();
|
||||
_api = Ioc.Default.GetRequiredService<IPublicAPI>();
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
@ -56,13 +57,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>();
|
||||
Settings.PropertyChanged += (_, args) =>
|
||||
{
|
||||
switch (args.PropertyName)
|
||||
|
|
|
|||
|
|
@ -1,66 +1,46 @@
|
|||
using Flow.Launcher.Core;
|
||||
using Flow.Launcher.Core.Configuration;
|
||||
using Flow.Launcher.Infrastructure.Storage;
|
||||
using Flow.Launcher.Infrastructure.UserSettings;
|
||||
using Flow.Launcher.Infrastructure.UserSettings;
|
||||
using Flow.Launcher.Plugin;
|
||||
|
||||
namespace Flow.Launcher.ViewModel;
|
||||
|
||||
public class SettingWindowViewModel : BaseModel
|
||||
public partial class SettingWindowViewModel : BaseModel
|
||||
{
|
||||
private readonly FlowLauncherJsonStorage<Settings> _storage;
|
||||
private readonly Settings _settings;
|
||||
|
||||
public Updater Updater { get; }
|
||||
|
||||
public IPortable Portable { get; }
|
||||
|
||||
public Settings Settings { get; }
|
||||
|
||||
public SettingWindowViewModel(Updater updater, IPortable portable)
|
||||
public SettingWindowViewModel(Settings settings)
|
||||
{
|
||||
_storage = new FlowLauncherJsonStorage<Settings>();
|
||||
|
||||
Updater = updater;
|
||||
Portable = portable;
|
||||
Settings = _storage.Load();
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
public async void UpdateApp()
|
||||
{
|
||||
await Updater.UpdateAppAsync(App.API, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Save Flow settings. Plugins settings are not included.
|
||||
/// </summary>
|
||||
public void Save()
|
||||
{
|
||||
_storage.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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue