Use api functions instead

This commit is contained in:
Jack251970 2025-04-13 17:26:21 +08:00
parent e31f14e60d
commit dde933a96b
8 changed files with 80 additions and 65 deletions

View file

@ -1,21 +1,22 @@
using Microsoft.Win32;
using Squirrel;
using System;
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows;
using Flow.Launcher.Infrastructure;
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.Infrastructure;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedCommands;
using Microsoft.Win32;
using Squirrel;
namespace Flow.Launcher.Core.Configuration
{
public class Portable : IPortable
{
private static readonly string ClassName = nameof(Portable);
private readonly IPublicAPI API = Ioc.Default.GetRequiredService<IPublicAPI>();
/// <summary>
@ -51,7 +52,7 @@ namespace Flow.Launcher.Core.Configuration
}
catch (Exception e)
{
Log.Exception("|Portable.DisablePortableMode|Error occurred while disabling portable mode", e);
API.LogException(ClassName, "Error occurred while disabling portable mode", e);
}
}
@ -75,7 +76,7 @@ namespace Flow.Launcher.Core.Configuration
}
catch (Exception e)
{
Log.Exception("|Portable.EnablePortableMode|Error occurred while enabling portable mode", e);
API.LogException(ClassName, "Error occurred while enabling portable mode", e);
}
}

View file

@ -1,7 +1,4 @@
using Flow.Launcher.Infrastructure.Http;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Plugin;
using System;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
@ -11,11 +8,18 @@ using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure.Http;
using Flow.Launcher.Plugin;
namespace Flow.Launcher.Core.ExternalPlugins
{
public record CommunityPluginSource(string ManifestFileUrl)
{
// We should not initialize API in static constructor because it will create another API instance
private static IPublicAPI api = null;
private static IPublicAPI API => api ??= Ioc.Default.GetRequiredService<IPublicAPI>();
private static readonly string ClassName = nameof(CommunityPluginSource);
private string latestEtag = "";
@ -37,7 +41,7 @@ namespace Flow.Launcher.Core.ExternalPlugins
/// </remarks>
public async Task<List<UserPlugin>> FetchAsync(CancellationToken token)
{
Log.Info(ClassName, $"Loading plugins from {ManifestFileUrl}");
API.LogInfo(ClassName, $"Loading plugins from {ManifestFileUrl}");
var request = new HttpRequestMessage(HttpMethod.Get, ManifestFileUrl);
@ -55,18 +59,17 @@ namespace Flow.Launcher.Core.ExternalPlugins
.ConfigureAwait(false);
latestEtag = response.Headers.ETag?.Tag;
Log.Info(ClassName, $"Loaded {plugins.Count} plugins from {ManifestFileUrl}");
API.LogInfo(ClassName, $"Loaded {plugins.Count} plugins from {ManifestFileUrl}");
return plugins;
}
else if (response.StatusCode == HttpStatusCode.NotModified)
{
Log.Info(ClassName, $"Resource {ManifestFileUrl} has not been modified.");
API.LogInfo(ClassName, $"Resource {ManifestFileUrl} has not been modified.");
return plugins;
}
else
{
Log.Warn(ClassName,
$"Failed to load resource {ManifestFileUrl} with response {response.StatusCode}");
API.LogWarn(ClassName, $"Failed to load resource {ManifestFileUrl} with response {response.StatusCode}");
return plugins;
}
}
@ -74,11 +77,11 @@ namespace Flow.Launcher.Core.ExternalPlugins
{
if (e is HttpRequestException or WebException or SocketException || e.InnerException is TimeoutException)
{
Log.Exception(ClassName, $"Check your connection and proxy settings to {ManifestFileUrl}.", e);
API.LogException(ClassName, $"Check your connection and proxy settings to {ManifestFileUrl}.", e);
}
else
{
Log.Exception(ClassName, "Error Occurred", e);
API.LogException(ClassName, "Error Occurred", e);
}
return plugins;
}

View file

@ -5,7 +5,6 @@ using System.Linq;
using System.Windows;
using System.Windows.Forms;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedCommands;
@ -14,6 +13,8 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
public abstract class AbstractPluginEnvironment
{
private static readonly string ClassName = nameof(AbstractPluginEnvironment);
protected readonly IPublicAPI API = Ioc.Default.GetRequiredService<IPublicAPI>();
internal abstract string Language { get; }
@ -120,7 +121,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
else
{
API.ShowMsgBox(string.Format(API.GetTranslation("runtimePluginUnableToSetExecutablePath"), Language));
Log.Error("PluginsLoader",
API.LogError(ClassName,
$"Not able to successfully set {EnvName} path, setting's plugin executable path variable is still an empty string.",
$"{Language}Environment");

View file

@ -3,14 +3,20 @@ using System.Collections.Generic;
using System.Linq;
using System.IO;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Plugin;
using System.Text.Json;
using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Core.Plugin
{
internal abstract class PluginConfig
{
private static readonly string ClassName = nameof(PluginConfig);
// We should not initialize API in static constructor because it will create another API instance
private static IPublicAPI api = null;
private static IPublicAPI API => api ??= Ioc.Default.GetRequiredService<IPublicAPI>();
/// <summary>
/// Parse plugin metadata in the given directories
/// </summary>
@ -32,7 +38,7 @@ namespace Flow.Launcher.Core.Plugin
}
catch (Exception e)
{
Log.Exception($"|PluginConfig.ParsePLuginConfigs|Can't delete <{directory}>", e);
API.LogException(ClassName, $"Can't delete <{directory}>", e);
}
}
else
@ -49,11 +55,11 @@ namespace Flow.Launcher.Core.Plugin
duplicateList
.ForEach(
x => Log.Warn("PluginConfig",
string.Format("Duplicate plugin name: {0}, id: {1}, version: {2} " +
"not loaded due to version not the highest of the duplicates",
x.Name, x.ID, x.Version),
"GetUniqueLatestPluginMetadata"));
x => API.LogWarn(ClassName,
string.Format("Duplicate plugin name: {0}, id: {1}, version: {2} " +
"not loaded due to version not the highest of the duplicates",
x.Name, x.ID, x.Version),
"GetUniqueLatestPluginMetadata"));
return uniqueList;
}
@ -101,7 +107,7 @@ namespace Flow.Launcher.Core.Plugin
string configPath = Path.Combine(pluginDirectory, Constant.PluginMetadataFileName);
if (!File.Exists(configPath))
{
Log.Error($"|PluginConfig.GetPluginMetadata|Didn't find config file <{configPath}>");
API.LogError(ClassName, $"Didn't find config file <{configPath}>");
return null;
}
@ -117,19 +123,19 @@ namespace Flow.Launcher.Core.Plugin
}
catch (Exception e)
{
Log.Exception($"|PluginConfig.GetPluginMetadata|invalid json for config <{configPath}>", e);
API.LogException(ClassName, $"Invalid json for config <{configPath}>", e);
return null;
}
if (!AllowedLanguage.IsAllowed(metadata.Language))
{
Log.Error($"|PluginConfig.GetPluginMetadata|Invalid language <{metadata.Language}> for config <{configPath}>");
API.LogError(ClassName, $"Invalid language <{metadata.Language}> for config <{configPath}>");
return null;
}
if (!File.Exists(metadata.ExecuteFilePath))
{
Log.Error($"|PluginConfig.GetPluginMetadata|execute file path didn't exist <{metadata.ExecuteFilePath}> for conifg <{configPath}");
API.LogError(ClassName, $"Execute file path didn't exist <{metadata.ExecuteFilePath}> for conifg <{configPath}");
return null;
}

View file

@ -9,7 +9,6 @@ using System.Threading.Tasks;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core.ExternalPlugins;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedCommands;
@ -214,12 +213,12 @@ namespace Flow.Launcher.Core.Plugin
() => pair.Plugin.InitAsync(new PluginInitContext(pair.Metadata, API)));
pair.Metadata.InitTime += milliseconds;
Log.Info(
$"|PluginManager.InitializePlugins|Total init cost for <{pair.Metadata.Name}> is <{pair.Metadata.InitTime}ms>");
API.LogInfo(ClassName,
$"Total init cost for <{pair.Metadata.Name}> is <{pair.Metadata.InitTime}ms>");
}
catch (Exception e)
{
Log.Exception(ClassName, $"Fail to Init plugin: {pair.Metadata.Name}", e);
API.LogException(ClassName, $"Fail to Init plugin: {pair.Metadata.Name}", e);
pair.Metadata.Disabled = true;
failedPlugins.Enqueue(pair);
}
@ -370,8 +369,8 @@ namespace Flow.Launcher.Core.Plugin
}
catch (Exception e)
{
Log.Exception(
$"|PluginManager.GetContextMenusForPlugin|Can't load context menus for plugin <{pluginPair.Metadata.Name}>",
API.LogException(ClassName,
$"Can't load context menus for plugin <{pluginPair.Metadata.Name}>",
e);
}
}
@ -563,7 +562,7 @@ namespace Flow.Launcher.Core.Plugin
}
catch (Exception e)
{
Log.Exception($"|PluginManager.InstallPlugin|Failed to delete temp folder {tempFolderPluginPath}", e);
API.LogException(ClassName, $"Failed to delete temp folder {tempFolderPluginPath}", e);
}
if (checkModified)
@ -608,7 +607,7 @@ namespace Flow.Launcher.Core.Plugin
}
catch (Exception e)
{
Log.Exception($"|PluginManager.UninstallPlugin|Failed to delete plugin settings folder for {plugin.Name}", e);
API.LogException(ClassName, $"Failed to delete plugin settings folder for {plugin.Name}", e);
API.ShowMsg(API.GetTranslation("failedToRemovePluginSettingsTitle"),
string.Format(API.GetTranslation("failedToRemovePluginSettingsMessage"), plugin.Name));
}
@ -624,7 +623,7 @@ namespace Flow.Launcher.Core.Plugin
}
catch (Exception e)
{
Log.Exception($"|PluginManager.UninstallPlugin|Failed to delete plugin cache folder for {plugin.Name}", e);
API.LogException(ClassName, $"Failed to delete plugin cache folder for {plugin.Name}", e);
API.ShowMsg(API.GetTranslation("failedToRemovePluginCacheTitle"),
string.Format(API.GetTranslation("failedToRemovePluginCacheMessage"), plugin.Name));
}

View file

@ -6,7 +6,6 @@ using System.Reflection;
using System.Windows;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using System.Globalization;
@ -17,11 +16,14 @@ namespace Flow.Launcher.Core.Resource
{
public class Internationalization
{
private static readonly string ClassName = nameof(Internationalization);
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 IPublicAPI _api;
private readonly List<string> _languageDirectories = new();
private readonly List<ResourceDictionary> _oldResources = new();
private readonly string SystemLanguageCode;
@ -29,6 +31,7 @@ namespace Flow.Launcher.Core.Resource
public Internationalization(Settings settings)
{
_settings = settings;
_api = Ioc.Default.GetRequiredService<IPublicAPI>();
AddFlowLauncherLanguageDirectory();
SystemLanguageCode = GetSystemLanguageCodeAtStartup();
}
@ -80,7 +83,7 @@ namespace Flow.Launcher.Core.Resource
}
else
{
Log.Error($"|Internationalization.AddPluginLanguageDirectories|Can't find plugin path <{location}> for <{plugin.Metadata.Name}>");
_api.LogError(ClassName, $"Can't find plugin path <{location}> for <{plugin.Metadata.Name}>");
}
}
@ -144,13 +147,13 @@ namespace Flow.Launcher.Core.Resource
_settings.Language = isSystem ? Constant.SystemLanguageCode : language.LanguageCode;
}
private static Language GetLanguageByLanguageCode(string languageCode)
private Language GetLanguageByLanguageCode(string languageCode)
{
var lowercase = languageCode.ToLower();
var language = AvailableLanguages.GetAvailableLanguages().FirstOrDefault(o => o.LanguageCode.ToLower() == lowercase);
if (language == null)
{
Log.Error($"|Internationalization.GetLanguageByLanguageCode|Language code can't be found <{languageCode}>");
_api.LogError(ClassName, $"Language code can't be found <{languageCode}>");
return AvailableLanguages.English;
}
else
@ -239,7 +242,7 @@ namespace Flow.Launcher.Core.Resource
return list;
}
public static string GetTranslation(string key)
public string GetTranslation(string key)
{
var translation = Application.Current.TryFindResource(key);
if (translation is string)
@ -248,7 +251,7 @@ namespace Flow.Launcher.Core.Resource
}
else
{
Log.Error($"|Internationalization.GetTranslation|No Translation for key {key}");
_api.LogError(ClassName, $"No Translation for key {key}");
return $"No Translation for key {key}";
}
}
@ -266,12 +269,12 @@ namespace Flow.Launcher.Core.Resource
}
catch (Exception e)
{
Log.Exception($"|Internationalization.UpdatePluginMetadataTranslations|Failed for <{p.Metadata.Name}>", e);
_api.LogException(ClassName, $"Failed for <{p.Metadata.Name}>", e);
}
}
}
private static string LanguageFile(string folder, string language)
private string LanguageFile(string folder, string language)
{
if (Directory.Exists(folder))
{
@ -282,7 +285,7 @@ namespace Flow.Launcher.Core.Resource
}
else
{
Log.Error($"|Internationalization.LanguageFile|Language path can't be found <{path}>");
_api.LogError(ClassName, $"Language path can't be found <{path}>");
var english = Path.Combine(folder, DefaultFile);
if (File.Exists(english))
{
@ -290,7 +293,7 @@ namespace Flow.Launcher.Core.Resource
}
else
{
Log.Error($"|Internationalization.LanguageFile|Default English Language path can't be found <{path}>");
_api.LogError(ClassName, $"Default English Language path can't be found <{path}>");
return string.Empty;
}
}

View file

@ -13,7 +13,6 @@ using System.Windows.Media.Effects;
using System.Windows.Shell;
using System.Windows.Threading;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedModels;
@ -25,6 +24,8 @@ namespace Flow.Launcher.Core.Resource
{
#region Properties & Fields
private readonly string ClassName = nameof(Theme);
public bool BlurEnabled { get; private set; }
private const string ThemeMetadataNamePrefix = "Name:";
@ -73,7 +74,7 @@ namespace Flow.Launcher.Core.Resource
}
else
{
Log.Error("Current theme resource not found. Initializing with default theme.");
_api.LogError(ClassName, "Current theme resource not found. Initializing with default theme.");
_oldTheme = Constant.DefaultTheme;
};
}
@ -92,7 +93,7 @@ namespace Flow.Launcher.Core.Resource
}
catch (Exception e)
{
Log.Exception($"|Theme.MakesureThemeDirectoriesExist|Exception when create directory <{dir}>", e);
_api.LogException(ClassName, $"Exception when create directory <{dir}>", e);
}
}
}
@ -135,7 +136,7 @@ namespace Flow.Launcher.Core.Resource
}
catch (Exception e)
{
Log.Exception("Error occurred while updating theme fonts", e);
_api.LogException(ClassName, "Error occurred while updating theme fonts", e);
}
}
@ -387,7 +388,7 @@ namespace Flow.Launcher.Core.Resource
var matchingTheme = themes.FirstOrDefault(t => t.FileNameWithoutExtension == _settings.Theme);
if (matchingTheme == null)
{
Log.Warn($"No matching theme found for '{_settings.Theme}'. Falling back to the first available theme.");
_api.LogWarn(ClassName, $"No matching theme found for '{_settings.Theme}'. Falling back to the first available theme.");
}
return matchingTheme ?? themes.FirstOrDefault();
}
@ -440,7 +441,7 @@ namespace Flow.Launcher.Core.Resource
}
catch (DirectoryNotFoundException)
{
Log.Error($"|Theme.ChangeTheme|Theme <{theme}> path can't be found");
_api.LogError(ClassName, $"Theme <{theme}> path can't be found");
if (theme != Constant.DefaultTheme)
{
_api.ShowMsgBox(string.Format(_api.GetTranslation("theme_load_failure_path_not_exists"), theme));
@ -450,7 +451,7 @@ namespace Flow.Launcher.Core.Resource
}
catch (XamlParseException)
{
Log.Error($"|Theme.ChangeTheme|Theme <{theme}> fail to parse");
_api.LogError(ClassName, $"Theme <{theme}> fail to parse");
if (theme != Constant.DefaultTheme)
{
_api.ShowMsgBox(string.Format(_api.GetTranslation("theme_load_failure_parse_error"), theme));

View file

@ -12,7 +12,6 @@ using System.Windows;
using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Http;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using JetBrains.Annotations;
@ -24,6 +23,8 @@ namespace Flow.Launcher.Core
{
public string GitHubRepository { get; init; }
private static readonly string ClassName = nameof(Updater);
private readonly IPublicAPI _api;
public Updater(IPublicAPI publicAPI, string gitHubRepository)
@ -51,7 +52,7 @@ namespace Flow.Launcher.Core
var newReleaseVersion = Version.Parse(newUpdateInfo.FutureReleaseEntry.Version.ToString());
var currentVersion = Version.Parse(Constant.Version);
Log.Info($"|Updater.UpdateApp|Future Release <{Formatted(newUpdateInfo.FutureReleaseEntry)}>");
_api.LogInfo(ClassName, $"Future Release <{Formatted(newUpdateInfo.FutureReleaseEntry)}>");
if (newReleaseVersion <= currentVersion)
{
@ -84,7 +85,7 @@ namespace Flow.Launcher.Core
var newVersionTips = NewVersionTips(newReleaseVersion.ToString());
Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}");
_api.LogInfo(ClassName, $"Update success:{newVersionTips}");
if (_api.ShowMsgBox(newVersionTips, _api.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
@ -95,11 +96,11 @@ namespace Flow.Launcher.Core
{
if (e is HttpRequestException or WebException or SocketException || e.InnerException is TimeoutException)
{
Log.Exception($"|Updater.UpdateApp|Check your connection and proxy settings to github-cloud.s3.amazonaws.com.", e);
_api.LogException(ClassName, $"Check your connection and proxy settings to github-cloud.s3.amazonaws.com.", e);
}
else
{
Log.Exception($"|Updater.UpdateApp|Error Occurred", e);
_api.LogException(ClassName, $"Error Occurred", e);
}
if (!silentUpdate)