From 922c3d561153931a61eae909c10eca44bfcd8f5f Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sun, 17 Aug 2025 16:54:41 +0800 Subject: [PATCH 01/75] Upgrade nuget packages & Update lock files --- Flow.Launcher.Core/Flow.Launcher.Core.csproj | 2 +- Flow.Launcher.Core/packages.lock.json | 44 +-- .../Flow.Launcher.Infrastructure.csproj | 8 +- .../packages.lock.json | 38 +- .../Flow.Launcher.Plugin.csproj | 2 +- Flow.Launcher.Plugin/packages.lock.json | 6 +- Flow.Launcher.Test/Flow.Launcher.Test.csproj | 4 +- Flow.Launcher/Flow.Launcher.csproj | 6 +- Flow.Launcher/packages.lock.json | 356 +++++++++--------- ...low.Launcher.Plugin.BrowserBookmark.csproj | 4 +- .../Flow.Launcher.Plugin.Calculator.csproj | 2 +- .../Flow.Launcher.Plugin.Explorer.csproj | 4 +- .../Flow.Launcher.Plugin.Program.csproj | 4 +- 13 files changed, 240 insertions(+), 240 deletions(-) diff --git a/Flow.Launcher.Core/Flow.Launcher.Core.csproj b/Flow.Launcher.Core/Flow.Launcher.Core.csproj index 527950061..1aae953a4 100644 --- a/Flow.Launcher.Core/Flow.Launcher.Core.csproj +++ b/Flow.Launcher.Core/Flow.Launcher.Core.csproj @@ -55,7 +55,7 @@ - + diff --git a/Flow.Launcher.Core/packages.lock.json b/Flow.Launcher.Core/packages.lock.json index caec08ebf..598662936 100644 --- a/Flow.Launcher.Core/packages.lock.json +++ b/Flow.Launcher.Core/packages.lock.json @@ -13,9 +13,9 @@ }, "FSharp.Core": { "type": "Direct", - "requested": "[9.0.300, )", - "resolved": "9.0.300", - "contentHash": "TVt2J7RCE1KCS2IaONF+p8/KIZ1eHNbW+7qmKF6hGoD4tXl+o07ja1mPtFjMqRa5uHMFaTrGTPn/m945WnDLiQ==" + "requested": "[9.0.303, )", + "resolved": "9.0.303", + "contentHash": "6JlV8aD8qQvcmfoe/PMOxCHXc0uX4lR23u0fAyQtnVQxYULLoTZgwgZHSnRcuUHOvS3wULFWcwdnP1iwslH60g==" }, "Meziantou.Framework.Win32.Jobs": { "type": "Direct", @@ -90,8 +90,8 @@ }, "JetBrains.Annotations": { "type": "Transitive", - "resolved": "2024.3.0", - "contentHash": "ox5pkeLQXjvJdyAB4b2sBYAlqZGLh3PjSnP1bQNVx72ONuTJ9+34/+Rq91Fc0dG29XG9RgZur9+NcP4riihTug==" + "resolved": "2025.2.0", + "contentHash": "2BvMkOSW+50EbQFhWFIPWTqmcDLiyyjwkMN7lN386bhP2vN/7ts5t59qu11HtenmHFxqDzaD8J1fFoh+QTOzVA==" }, "MemoryPack": { "type": "Transitive", @@ -161,8 +161,8 @@ }, "Microsoft.Win32.SystemEvents": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "lFGY2aGgmMREPJEfOmZcA6v0CLjWVpcfNHRgqYMoSQhy80+GxhYqdW5xe+DCLrVqE1M7/0RpOkIo49/KH/cd/A==" + "resolved": "9.0.8", + "contentHash": "64oQBN8I8EOcyHGNt6+rlcqm4tlcKfqOpswtBCJZnpzBQ15L6IFKqjnbjbOWBpG9wKq9A/aC2LFSmSqplbwTYA==" }, "Mono.Cecil": { "type": "Transitive", @@ -199,21 +199,21 @@ }, "NLog": { "type": "Transitive", - "resolved": "6.0.1", - "contentHash": "qDWiqy8/xdpZKtHna/645KbalwP86N2NFJEzfqhcv+Si4V2iNaEfR/dCneuF/4+Dcwl3f7jHMXj3ndWYftV3Ug==" + "resolved": "6.0.3", + "contentHash": "5RMrpvadysflvDOi5ozD7aK1P+YL2DyZbQSxzE8qBKkw2pxPNOQA6vJtumcT6SuzE9qxhwGkQwMkLLaKnALwiw==" }, "NLog.OutputDebugString": { "type": "Transitive", - "resolved": "6.0.1", - "contentHash": "wwJCQLaHVzuRf8TsXB+EEdrzVvE3dnzCSMQMDgwkw3AXp8VSp3JSVF/Q/H0oEqggKgKhPs13hh3a7svyQr4s3A==", + "resolved": "6.0.3", + "contentHash": "0qojvaBMAruTDIbjRXMwft3hdkg8tPl0BMD8+tR8TpK78a8DrgKAq/h5LcHPQ/0xERZ66y+00bsn0n1VeJjlmg==", "dependencies": { - "NLog": "6.0.1" + "NLog": "6.0.3" } }, "SharpVectors.Wpf": { "type": "Transitive", - "resolved": "1.8.4.2", - "contentHash": "PNxLkMBJnV8A+6yH9OqOlhLJegvWP/dvh0rAJp2l0kcrR+rB4R2tQ9vhUqka+UilH4atN8T6zvjDOizVyfz2Ng==" + "resolved": "1.8.5", + "contentHash": "WURdBDq5AE8RjKV9pFS7lNkJe81gxja9SaMGE4URq9GJUZ6M+5DGUL0Lm3B0iYW2/Meyowaz4ffGsyW+RBSTtg==" }, "Splat": { "type": "Transitive", @@ -222,10 +222,10 @@ }, "System.Drawing.Common": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "1k/Pk7hcM3vP2tfIRRS2ECCCN7ya+hvocsM1JMc4ZDCU6qw7yOuUmqmCDfgXZ4Q4FS6jass2EAai5ByKodDi0g==", + "resolved": "9.0.8", + "contentHash": "ineIJmF+yuBEHGft9R153J9kmBFaeEfFL5Put5nzENneRcGGPUb3MvM8zrZ5pERQ0jPPSE3Wqw/clXvOq2F/Kw==", "dependencies": { - "Microsoft.Win32.SystemEvents": "9.0.7" + "Microsoft.Win32.SystemEvents": "9.0.8" } }, "System.IO.Pipelines": { @@ -259,17 +259,17 @@ "MemoryPack": "[1.21.4, )", "Microsoft.VisualStudio.Threading": "[17.14.15, )", "NHotkey.Wpf": "[3.0.0, )", - "NLog": "[6.0.1, )", - "NLog.OutputDebugString": "[6.0.1, )", - "SharpVectors.Wpf": "[1.8.4.2, )", - "System.Drawing.Common": "[9.0.7, )", + "NLog": "[6.0.3, )", + "NLog.OutputDebugString": "[6.0.3, )", + "SharpVectors.Wpf": "[1.8.5, )", + "System.Drawing.Common": "[9.0.8, )", "ToolGood.Words.Pinyin": "[3.1.0.3, )" } }, "flow.launcher.plugin": { "type": "Project", "dependencies": { - "JetBrains.Annotations": "[2024.3.0, )" + "JetBrains.Annotations": "[2025.2.0, )" } } } diff --git a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj index 51b1d5175..7bb8786cd 100644 --- a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj +++ b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj @@ -68,13 +68,13 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all - - + + diff --git a/Flow.Launcher.Infrastructure/packages.lock.json b/Flow.Launcher.Infrastructure/packages.lock.json index 87b4bb6da..bcb3031e0 100644 --- a/Flow.Launcher.Infrastructure/packages.lock.json +++ b/Flow.Launcher.Infrastructure/packages.lock.json @@ -78,17 +78,17 @@ }, "NLog": { "type": "Direct", - "requested": "[6.0.1, )", - "resolved": "6.0.1", - "contentHash": "qDWiqy8/xdpZKtHna/645KbalwP86N2NFJEzfqhcv+Si4V2iNaEfR/dCneuF/4+Dcwl3f7jHMXj3ndWYftV3Ug==" + "requested": "[6.0.3, )", + "resolved": "6.0.3", + "contentHash": "5RMrpvadysflvDOi5ozD7aK1P+YL2DyZbQSxzE8qBKkw2pxPNOQA6vJtumcT6SuzE9qxhwGkQwMkLLaKnALwiw==" }, "NLog.OutputDebugString": { "type": "Direct", - "requested": "[6.0.1, )", - "resolved": "6.0.1", - "contentHash": "wwJCQLaHVzuRf8TsXB+EEdrzVvE3dnzCSMQMDgwkw3AXp8VSp3JSVF/Q/H0oEqggKgKhPs13hh3a7svyQr4s3A==", + "requested": "[6.0.3, )", + "resolved": "6.0.3", + "contentHash": "0qojvaBMAruTDIbjRXMwft3hdkg8tPl0BMD8+tR8TpK78a8DrgKAq/h5LcHPQ/0xERZ66y+00bsn0n1VeJjlmg==", "dependencies": { - "NLog": "6.0.1" + "NLog": "6.0.3" } }, "PropertyChanged.Fody": { @@ -102,17 +102,17 @@ }, "SharpVectors.Wpf": { "type": "Direct", - "requested": "[1.8.4.2, )", - "resolved": "1.8.4.2", - "contentHash": "PNxLkMBJnV8A+6yH9OqOlhLJegvWP/dvh0rAJp2l0kcrR+rB4R2tQ9vhUqka+UilH4atN8T6zvjDOizVyfz2Ng==" + "requested": "[1.8.5, )", + "resolved": "1.8.5", + "contentHash": "WURdBDq5AE8RjKV9pFS7lNkJe81gxja9SaMGE4URq9GJUZ6M+5DGUL0Lm3B0iYW2/Meyowaz4ffGsyW+RBSTtg==" }, "System.Drawing.Common": { "type": "Direct", - "requested": "[9.0.7, )", - "resolved": "9.0.7", - "contentHash": "1k/Pk7hcM3vP2tfIRRS2ECCCN7ya+hvocsM1JMc4ZDCU6qw7yOuUmqmCDfgXZ4Q4FS6jass2EAai5ByKodDi0g==", + "requested": "[9.0.8, )", + "resolved": "9.0.8", + "contentHash": "ineIJmF+yuBEHGft9R153J9kmBFaeEfFL5Put5nzENneRcGGPUb3MvM8zrZ5pERQ0jPPSE3Wqw/clXvOq2F/Kw==", "dependencies": { - "Microsoft.Win32.SystemEvents": "9.0.7" + "Microsoft.Win32.SystemEvents": "9.0.8" } }, "ToolGood.Words.Pinyin": { @@ -123,8 +123,8 @@ }, "JetBrains.Annotations": { "type": "Transitive", - "resolved": "2024.3.0", - "contentHash": "ox5pkeLQXjvJdyAB4b2sBYAlqZGLh3PjSnP1bQNVx72ONuTJ9+34/+Rq91Fc0dG29XG9RgZur9+NcP4riihTug==" + "resolved": "2025.2.0", + "contentHash": "2BvMkOSW+50EbQFhWFIPWTqmcDLiyyjwkMN7lN386bhP2vN/7ts5t59qu11HtenmHFxqDzaD8J1fFoh+QTOzVA==" }, "MemoryPack.Core": { "type": "Transitive", @@ -156,8 +156,8 @@ }, "Microsoft.Win32.SystemEvents": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "lFGY2aGgmMREPJEfOmZcA6v0CLjWVpcfNHRgqYMoSQhy80+GxhYqdW5xe+DCLrVqE1M7/0RpOkIo49/KH/cd/A==" + "resolved": "9.0.8", + "contentHash": "64oQBN8I8EOcyHGNt6+rlcqm4tlcKfqOpswtBCJZnpzBQ15L6IFKqjnbjbOWBpG9wKq9A/aC2LFSmSqplbwTYA==" }, "Microsoft.Windows.SDK.Win32Docs": { "type": "Transitive", @@ -190,7 +190,7 @@ "flow.launcher.plugin": { "type": "Project", "dependencies": { - "JetBrains.Annotations": "[2024.3.0, )" + "JetBrains.Annotations": "[2025.2.0, )" } } } diff --git a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj index eee8d5f4e..ccb9332b4 100644 --- a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj +++ b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj @@ -73,7 +73,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Flow.Launcher.Plugin/packages.lock.json b/Flow.Launcher.Plugin/packages.lock.json index af835c598..56b343e6b 100644 --- a/Flow.Launcher.Plugin/packages.lock.json +++ b/Flow.Launcher.Plugin/packages.lock.json @@ -10,9 +10,9 @@ }, "JetBrains.Annotations": { "type": "Direct", - "requested": "[2024.3.0, )", - "resolved": "2024.3.0", - "contentHash": "ox5pkeLQXjvJdyAB4b2sBYAlqZGLh3PjSnP1bQNVx72ONuTJ9+34/+Rq91Fc0dG29XG9RgZur9+NcP4riihTug==" + "requested": "[2025.2.0, )", + "resolved": "2025.2.0", + "contentHash": "2BvMkOSW+50EbQFhWFIPWTqmcDLiyyjwkMN7lN386bhP2vN/7ts5t59qu11HtenmHFxqDzaD8J1fFoh+QTOzVA==" }, "Microsoft.SourceLink.GitHub": { "type": "Direct", diff --git a/Flow.Launcher.Test/Flow.Launcher.Test.csproj b/Flow.Launcher.Test/Flow.Launcher.Test.csproj index 33479c5a0..1164e5ebe 100644 --- a/Flow.Launcher.Test/Flow.Launcher.Test.csproj +++ b/Flow.Launcher.Test/Flow.Launcher.Test.csproj @@ -49,8 +49,8 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj index fe84b5e1e..6d6b454c0 100644 --- a/Flow.Launcher/Flow.Launcher.csproj +++ b/Flow.Launcher/Flow.Launcher.csproj @@ -137,8 +137,8 @@ - - + + @@ -148,7 +148,7 @@ - + diff --git a/Flow.Launcher/packages.lock.json b/Flow.Launcher/packages.lock.json index 1047b1f3f..483766978 100644 --- a/Flow.Launcher/packages.lock.json +++ b/Flow.Launcher/packages.lock.json @@ -71,41 +71,41 @@ }, "Microsoft.Extensions.DependencyInjection": { "type": "Direct", - "requested": "[9.0.7, )", - "resolved": "9.0.7", - "contentHash": "i05AYA91vgq0as84ROVCyltD2gnxaba/f1Qw2rG7mUsS0gv8cPTr1Gm7jPQHq7JTr4MJoQUcanLVs16tIOUJaQ==", + "requested": "[9.0.8, )", + "resolved": "9.0.8", + "contentHash": "JJjI2Fa+QtZcUyuNjbKn04OjIUX5IgFGFu/Xc+qvzh1rXdZHLcnqqVXhR4093bGirTwacRlHiVg1XYI9xum6QQ==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7" + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8" } }, "Microsoft.Extensions.Hosting": { "type": "Direct", - "requested": "[9.0.7, )", - "resolved": "9.0.7", - "contentHash": "Dkv55VfitwJjPUk9mFHxT9MJAd8su7eJNaCHhBU/Y9xFqw3ZNHwrpeptXeaXiaPtfQq+alMmawIz1Impk5pHkQ==", + "requested": "[9.0.8, )", + "resolved": "9.0.8", + "contentHash": "O2VlzORrBbS2it203k5FOHrudDdmdrJovA73P/shdRGeLzvet4e4yXhGx52V2PNjYBQ0IO5M4xiNcL+6xIX6Bg==", "dependencies": { - "Microsoft.Extensions.Configuration": "9.0.7", - "Microsoft.Extensions.Configuration.Abstractions": "9.0.7", - "Microsoft.Extensions.Configuration.Binder": "9.0.7", - "Microsoft.Extensions.Configuration.CommandLine": "9.0.7", - "Microsoft.Extensions.Configuration.EnvironmentVariables": "9.0.7", - "Microsoft.Extensions.Configuration.FileExtensions": "9.0.7", - "Microsoft.Extensions.Configuration.Json": "9.0.7", - "Microsoft.Extensions.Configuration.UserSecrets": "9.0.7", - "Microsoft.Extensions.DependencyInjection": "9.0.7", - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7", - "Microsoft.Extensions.Diagnostics": "9.0.7", - "Microsoft.Extensions.FileProviders.Abstractions": "9.0.7", - "Microsoft.Extensions.FileProviders.Physical": "9.0.7", - "Microsoft.Extensions.Hosting.Abstractions": "9.0.7", - "Microsoft.Extensions.Logging": "9.0.7", - "Microsoft.Extensions.Logging.Abstractions": "9.0.7", - "Microsoft.Extensions.Logging.Configuration": "9.0.7", - "Microsoft.Extensions.Logging.Console": "9.0.7", - "Microsoft.Extensions.Logging.Debug": "9.0.7", - "Microsoft.Extensions.Logging.EventLog": "9.0.7", - "Microsoft.Extensions.Logging.EventSource": "9.0.7", - "Microsoft.Extensions.Options": "9.0.7" + "Microsoft.Extensions.Configuration": "9.0.8", + "Microsoft.Extensions.Configuration.Abstractions": "9.0.8", + "Microsoft.Extensions.Configuration.Binder": "9.0.8", + "Microsoft.Extensions.Configuration.CommandLine": "9.0.8", + "Microsoft.Extensions.Configuration.EnvironmentVariables": "9.0.8", + "Microsoft.Extensions.Configuration.FileExtensions": "9.0.8", + "Microsoft.Extensions.Configuration.Json": "9.0.8", + "Microsoft.Extensions.Configuration.UserSecrets": "9.0.8", + "Microsoft.Extensions.DependencyInjection": "9.0.8", + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", + "Microsoft.Extensions.Diagnostics": "9.0.8", + "Microsoft.Extensions.FileProviders.Abstractions": "9.0.8", + "Microsoft.Extensions.FileProviders.Physical": "9.0.8", + "Microsoft.Extensions.Hosting.Abstractions": "9.0.8", + "Microsoft.Extensions.Logging": "9.0.8", + "Microsoft.Extensions.Logging.Abstractions": "9.0.8", + "Microsoft.Extensions.Logging.Configuration": "9.0.8", + "Microsoft.Extensions.Logging.Console": "9.0.8", + "Microsoft.Extensions.Logging.Debug": "9.0.8", + "Microsoft.Extensions.Logging.EventLog": "9.0.8", + "Microsoft.Extensions.Logging.EventSource": "9.0.8", + "Microsoft.Extensions.Options": "9.0.8" } }, "Microsoft.Toolkit.Uwp.Notifications": { @@ -154,9 +154,9 @@ }, "VirtualizingWrapPanel": { "type": "Direct", - "requested": "[2.3.0, )", - "resolved": "2.3.0", - "contentHash": "Dpmtcpn2HqAWZR0NkN7Qd4YCjf+sdQcemIMKm2suZVbOIB9NsmKZnYaQDIpXWTh87a9+nArVto6Od1cM2ohzCQ==" + "requested": "[2.3.1, )", + "resolved": "2.3.1", + "contentHash": "imph3SJqFFgX8vc7XRBcftfgzIL7Q+uE0Tvk7dbY0KY0tcqUCs0ZmKV3Gt9QX2745v6bSw6ns8UHpXtiptHqdA==" }, "AvalonEdit": { "type": "Transitive", @@ -196,8 +196,8 @@ }, "FSharp.Core": { "type": "Transitive", - "resolved": "9.0.300", - "contentHash": "TVt2J7RCE1KCS2IaONF+p8/KIZ1eHNbW+7qmKF6hGoD4tXl+o07ja1mPtFjMqRa5uHMFaTrGTPn/m945WnDLiQ==" + "resolved": "9.0.303", + "contentHash": "6JlV8aD8qQvcmfoe/PMOxCHXc0uX4lR23u0fAyQtnVQxYULLoTZgwgZHSnRcuUHOvS3wULFWcwdnP1iwslH60g==" }, "HtmlAgilityPack": { "type": "Transitive", @@ -211,8 +211,8 @@ }, "JetBrains.Annotations": { "type": "Transitive", - "resolved": "2024.3.0", - "contentHash": "ox5pkeLQXjvJdyAB4b2sBYAlqZGLh3PjSnP1bQNVx72ONuTJ9+34/+Rq91Fc0dG29XG9RgZur9+NcP4riihTug==" + "resolved": "2025.2.0", + "contentHash": "2BvMkOSW+50EbQFhWFIPWTqmcDLiyyjwkMN7lN386bhP2vN/7ts5t59qu11HtenmHFxqDzaD8J1fFoh+QTOzVA==" }, "MemoryPack": { "type": "Transitive", @@ -254,244 +254,244 @@ }, "Microsoft.Extensions.Configuration": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "oxGR51+w5cXm5B9gU6XwpAB2sTiyPSmZm7hjvv0rzRnmL5o/KZzE103AuQj7sK26OBupjVzU/bZxDWvvU4nhEg==", + "resolved": "9.0.8", + "contentHash": "6m+8Xgmf8UWL0p/oGqBM+0KbHE5/ePXbV1hKXgC59zEv0aa0DW5oiiyxDbK5kH5j4gIvyD5uWL0+HadKBJngvQ==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "9.0.7", - "Microsoft.Extensions.Primitives": "9.0.7" + "Microsoft.Extensions.Configuration.Abstractions": "9.0.8", + "Microsoft.Extensions.Primitives": "9.0.8" } }, "Microsoft.Extensions.Configuration.Abstractions": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "lut/kiVvNsQ120VERMUYSFhpXPpKjjql+giy03LesASPBBcC0o6+aoFdzJH9GaYpFTQ3fGVhVjKjvJDoAW5/IQ==", + "resolved": "9.0.8", + "contentHash": "yNou2KM35RvzOh4vUFtl2l33rWPvOCoba+nzEDJ+BgD8aOL/jew4WPCibQvntRfOJ2pJU8ARygSMD+pdjvDHuA==", "dependencies": { - "Microsoft.Extensions.Primitives": "9.0.7" + "Microsoft.Extensions.Primitives": "9.0.8" } }, "Microsoft.Extensions.Configuration.Binder": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "ExY+zXHhU4o9KC2alp3ZdLWyVWVRSn5INqax5ABk+HEOHlAHzomhJ7ek9HHliyOMiVGoYWYaMFOGr9q59mSAGA==", + "resolved": "9.0.8", + "contentHash": "0vK9DnYrYChdiH3yRZWkkp4x4LbrfkWEdBc5HOsQ8t/0CLOWKXKkkhOE8A1shlex0hGydbGrhObeypxz/QTm+w==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "9.0.7" + "Microsoft.Extensions.Configuration.Abstractions": "9.0.8" } }, "Microsoft.Extensions.Configuration.CommandLine": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "LqwdkMNFeRyuqExewBSaWj8roEgZH8JQ9zEAmHl5ZFcnhCvjAdHICdYVRIiSEq9RWGB731LL8kZJM8tdTKEscA==", + "resolved": "9.0.8", + "contentHash": "vB6eDQ5prED5jHBqmSDNYzlCXsTSylYY7co9c7guhnz0zhx+jZ8BTHgO7y/Wl1dV2jAO15mKNWuyHRIRtWwGQg==", "dependencies": { - "Microsoft.Extensions.Configuration": "9.0.7", - "Microsoft.Extensions.Configuration.Abstractions": "9.0.7" + "Microsoft.Extensions.Configuration": "9.0.8", + "Microsoft.Extensions.Configuration.Abstractions": "9.0.8" } }, "Microsoft.Extensions.Configuration.EnvironmentVariables": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "R8kgazVpDr4k1K7MeWPLAwsi5VpwrhE3ubXK38D9gpHEvf9XhZhJ8kWHKK00LDg5hJ7pMQLggdZ7XFdQ5182Ug==", + "resolved": "9.0.8", + "contentHash": "9qileEYXDodlPN9DfPd5sHSfU2nSrI1r5BHVqLaLyb/7mPi335cy4ar/0ix4tXb2Aer/Pu4e5/zdwxt7lrtSyQ==", "dependencies": { - "Microsoft.Extensions.Configuration": "9.0.7", - "Microsoft.Extensions.Configuration.Abstractions": "9.0.7" + "Microsoft.Extensions.Configuration": "9.0.8", + "Microsoft.Extensions.Configuration.Abstractions": "9.0.8" } }, "Microsoft.Extensions.Configuration.FileExtensions": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "3LVg32iMfR9ENeegXAo73L+877iOcQauLJsXlKZNVSsLA/HbPgClZdeMGdjLSkaidYw3l02XbXTlOdGYNgu91Q==", + "resolved": "9.0.8", + "contentHash": "2jgx58Jpk3oKT7KRn8x/cFf3QDTjQP+KUbyBnynAcB2iBx1Eq9EdNMCu0QEbYuaZOaQru/Kwdffary+hn58Wwg==", "dependencies": { - "Microsoft.Extensions.Configuration": "9.0.7", - "Microsoft.Extensions.Configuration.Abstractions": "9.0.7", - "Microsoft.Extensions.FileProviders.Abstractions": "9.0.7", - "Microsoft.Extensions.FileProviders.Physical": "9.0.7", - "Microsoft.Extensions.Primitives": "9.0.7" + "Microsoft.Extensions.Configuration": "9.0.8", + "Microsoft.Extensions.Configuration.Abstractions": "9.0.8", + "Microsoft.Extensions.FileProviders.Abstractions": "9.0.8", + "Microsoft.Extensions.FileProviders.Physical": "9.0.8", + "Microsoft.Extensions.Primitives": "9.0.8" } }, "Microsoft.Extensions.Configuration.Json": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "3HQV326liEInT9UKEc+k73f1ECwNhvDS/DJAe5WvtMKDJTJqTH2ujrUC2ZlK/j6pXyPbV9f0Ku8JB20JveGImg==", + "resolved": "9.0.8", + "contentHash": "vjxzcnL7ul322+kpvELisXaZl8/5MYs6JfI9DZLQWsao1nA/4FL48yPwDK986hbJTWc64JxOOaMym0SQ/dy32w==", "dependencies": { - "Microsoft.Extensions.Configuration": "9.0.7", - "Microsoft.Extensions.Configuration.Abstractions": "9.0.7", - "Microsoft.Extensions.Configuration.FileExtensions": "9.0.7", - "Microsoft.Extensions.FileProviders.Abstractions": "9.0.7" + "Microsoft.Extensions.Configuration": "9.0.8", + "Microsoft.Extensions.Configuration.Abstractions": "9.0.8", + "Microsoft.Extensions.Configuration.FileExtensions": "9.0.8", + "Microsoft.Extensions.FileProviders.Abstractions": "9.0.8" } }, "Microsoft.Extensions.Configuration.UserSecrets": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "ouDuPgRdeF4TJXKUh+lbm6QwyWwnCy+ijiqfFM2cI5NmW83MwKg1WNp2nCdMVcwQW8wJXteF/L9lA6ZPS3bCIQ==", + "resolved": "9.0.8", + "contentHash": "UgH18nQkuMJgxjn1539I83N6LhnKQlLhQm3ppe+PGsFpYsC6eGpF/1KvDRm/bmqsrg0NXhurrv4k2r0e8vWX/Q==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "9.0.7", - "Microsoft.Extensions.Configuration.Json": "9.0.7", - "Microsoft.Extensions.FileProviders.Abstractions": "9.0.7", - "Microsoft.Extensions.FileProviders.Physical": "9.0.7" + "Microsoft.Extensions.Configuration.Abstractions": "9.0.8", + "Microsoft.Extensions.Configuration.Json": "9.0.8", + "Microsoft.Extensions.FileProviders.Abstractions": "9.0.8", + "Microsoft.Extensions.FileProviders.Physical": "9.0.8" } }, "Microsoft.Extensions.DependencyInjection.Abstractions": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "iPK1FxbGFr2Xb+4Y+dTYI8Gupu9pOi8I3JPuPsrogUmEhe2hzZ9LpCmolMEBhVDo2ikcSr7G5zYiwaapHSQTew==" + "resolved": "9.0.8", + "contentHash": "xY3lTjj4+ZYmiKIkyWitddrp1uL5uYiweQjqo4BKBw01ZC4HhcfgLghDpPZcUlppgWAFqFy9SgkiYWOMx365pw==" }, "Microsoft.Extensions.Diagnostics": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "6ykfInm6yw7pPHJACgnrPUXxUWVslFnzad44K/siXk6Ovan6fNMnXxI5X9vphHJuZ4JbMOdPIgsfTmLD+Dyxug==", + "resolved": "9.0.8", + "contentHash": "BKkLCFXzJvNmdngeYBf72VXoZqTJSb1orvjdzDLaGobicoGFBPW8ug2ru1nnEewMEwJzMgnsjHQY8EaKWmVhKg==", "dependencies": { - "Microsoft.Extensions.Configuration": "9.0.7", - "Microsoft.Extensions.Diagnostics.Abstractions": "9.0.7", - "Microsoft.Extensions.Options.ConfigurationExtensions": "9.0.7" + "Microsoft.Extensions.Configuration": "9.0.8", + "Microsoft.Extensions.Diagnostics.Abstractions": "9.0.8", + "Microsoft.Extensions.Options.ConfigurationExtensions": "9.0.8" } }, "Microsoft.Extensions.Diagnostics.Abstractions": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "d39Ov1JpeWCGLCOTinlaDkujhrSAQ0HFxb7Su1BjhCKBfmDcQ6Ia1i3JI6kd3NFgwi1dexTunu82daDNwt7E6w==", + "resolved": "9.0.8", + "contentHash": "UDY7blv4DCyIJ/8CkNrQKLaAZFypXQavRZ2DWf/2zi1mxYYKKw2t8AOCBWxNntyPZHPGhtEmL3snFM98ADZqTw==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7", - "Microsoft.Extensions.Options": "9.0.7" + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", + "Microsoft.Extensions.Options": "9.0.8" } }, "Microsoft.Extensions.FileProviders.Abstractions": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "y9djCca1cz/oz/J8jTxtoecNiNvaiGBJeWd7XOPxonH+FnfHqcfslJMcSr5JMinmWFyS7eh3C9L6m6oURZ5lSA==", + "resolved": "9.0.8", + "contentHash": "4zZbQ4w+hCMm9J+z5NOj3giIPT2MhZxx05HX/MGuAmDBbjOuXlYIIRN+t4V6OLxy5nXZIcXO+dQMB/OWubuDkw==", "dependencies": { - "Microsoft.Extensions.Primitives": "9.0.7" + "Microsoft.Extensions.Primitives": "9.0.8" } }, "Microsoft.Extensions.FileProviders.Physical": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "JYEPYrb+YBpFTCdmSBrk8cg3wAi1V4so7ccq04qbhg3FQHQqgJk28L3heEOKMXcZobOBUjTnGCFJD49Ez9kG5w==", + "resolved": "9.0.8", + "contentHash": "FlOe2i7UUIfY0l0ChaIYtlXjdWWutR4DMRKZaGD6z4G1uVTteFkbBfxUIoi1uGmrZQxXe/yv/cfwiT0tK2xyXA==", "dependencies": { - "Microsoft.Extensions.FileProviders.Abstractions": "9.0.7", - "Microsoft.Extensions.FileSystemGlobbing": "9.0.7", - "Microsoft.Extensions.Primitives": "9.0.7" + "Microsoft.Extensions.FileProviders.Abstractions": "9.0.8", + "Microsoft.Extensions.FileSystemGlobbing": "9.0.8", + "Microsoft.Extensions.Primitives": "9.0.8" } }, "Microsoft.Extensions.FileSystemGlobbing": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "5VKpTH2ME0SSs0lrtkpKgjCeHzXR5ka/H+qThPwuWi78wHubApZ/atD7w69FDt0OOM7UMV6LIbkqEQgoby4IXA==" + "resolved": "9.0.8", + "contentHash": "96Ub5LmwYfIGVoXkbe4kjs+ivK6fLBTwKJAOMfUNV0R+AkZRItlgROFqXEWMUlXBTPM1/kKu26Ueu5As6RDzJA==" }, "Microsoft.Extensions.Hosting.Abstractions": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "yG2JCXAR+VqI1mKqynLPNJlNlrUJeEISEpX4UznOp2uM4IEFz3pDDauzyMvTjICutEJtOigJ1yWBvxbaIlibBw==", + "resolved": "9.0.8", + "contentHash": "WNrad20tySNCPe9aJUK7Wfwh+RiyLF+id02FKW8Qfc+HAzNQHazcqMXAbwG/kmbS89uvan/nKK1MufkRahjrJA==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "9.0.7", - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7", - "Microsoft.Extensions.Diagnostics.Abstractions": "9.0.7", - "Microsoft.Extensions.FileProviders.Abstractions": "9.0.7", - "Microsoft.Extensions.Logging.Abstractions": "9.0.7" + "Microsoft.Extensions.Configuration.Abstractions": "9.0.8", + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", + "Microsoft.Extensions.Diagnostics.Abstractions": "9.0.8", + "Microsoft.Extensions.FileProviders.Abstractions": "9.0.8", + "Microsoft.Extensions.Logging.Abstractions": "9.0.8" } }, "Microsoft.Extensions.Logging": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "fdIeQpXYV8yxSWG03cCbU2Otdrq4NWuhnQLXokWLv3L9YcK055E7u8WFJvP+uuP4CFeCEoqZQL4yPcjuXhCZrg==", + "resolved": "9.0.8", + "contentHash": "Z/7ze+0iheT7FJeZPqJKARYvyC2bmwu3whbm/48BJjdlGVvgDguoCqJIkI/67NkroTYobd5geai1WheNQvWrgA==", "dependencies": { - "Microsoft.Extensions.DependencyInjection": "9.0.7", - "Microsoft.Extensions.Logging.Abstractions": "9.0.7", - "Microsoft.Extensions.Options": "9.0.7" + "Microsoft.Extensions.DependencyInjection": "9.0.8", + "Microsoft.Extensions.Logging.Abstractions": "9.0.8", + "Microsoft.Extensions.Options": "9.0.8" } }, "Microsoft.Extensions.Logging.Abstractions": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "sMM6NEAdUTE/elJ2wqjOi0iBWqZmSyaTByLF9e8XHv6DRJFFnOe0N+s8Uc6C91E4SboQCfLswaBIZ+9ZXA98AA==", + "resolved": "9.0.8", + "contentHash": "pYnAffJL7ARD/HCnnPvnFKSIHnTSmWz84WIlT9tPeQ4lHNiu0Az7N/8itihWvcF8sT+VVD5lq8V+ckMzu4SbOw==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7" + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8" } }, "Microsoft.Extensions.Logging.Configuration": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "AEBty9rvFGvdFRqgIDEhQmiCnIfQWyzVoOZrO244cfu+n9M+wI1QLDpuROVILlplIBtLVmOezAF7d1H3Qog6Xw==", + "resolved": "9.0.8", + "contentHash": "Us4evDN3lbp1beVgrpxkSXKrbntVGAK+YbSo9P9driiU9PK05+ShhgesJ3aj7SuDfr3mqqcEgrMJ87Vu8t5dhw==", "dependencies": { - "Microsoft.Extensions.Configuration": "9.0.7", - "Microsoft.Extensions.Configuration.Abstractions": "9.0.7", - "Microsoft.Extensions.Configuration.Binder": "9.0.7", - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7", - "Microsoft.Extensions.Logging": "9.0.7", - "Microsoft.Extensions.Logging.Abstractions": "9.0.7", - "Microsoft.Extensions.Options": "9.0.7", - "Microsoft.Extensions.Options.ConfigurationExtensions": "9.0.7" + "Microsoft.Extensions.Configuration": "9.0.8", + "Microsoft.Extensions.Configuration.Abstractions": "9.0.8", + "Microsoft.Extensions.Configuration.Binder": "9.0.8", + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", + "Microsoft.Extensions.Logging": "9.0.8", + "Microsoft.Extensions.Logging.Abstractions": "9.0.8", + "Microsoft.Extensions.Options": "9.0.8", + "Microsoft.Extensions.Options.ConfigurationExtensions": "9.0.8" } }, "Microsoft.Extensions.Logging.Console": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "pEHlNa8iCfKsBFA3YVDn/8EicjSU/m8uDfyoR0i4svONDss4Yu9Kznw53E/TyI+TveTo7CwRid4kfd4pLYXBig==", + "resolved": "9.0.8", + "contentHash": "mPp9xB9MjiPuodh9z/+6zEGNj2kSVeXQtdbIBHlhUYqxX22gzJkx0ycPY42q4/OT/SzFV/TJ989Pa3sA/8ZBeA==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7", - "Microsoft.Extensions.Logging": "9.0.7", - "Microsoft.Extensions.Logging.Abstractions": "9.0.7", - "Microsoft.Extensions.Logging.Configuration": "9.0.7", - "Microsoft.Extensions.Options": "9.0.7" + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", + "Microsoft.Extensions.Logging": "9.0.8", + "Microsoft.Extensions.Logging.Abstractions": "9.0.8", + "Microsoft.Extensions.Logging.Configuration": "9.0.8", + "Microsoft.Extensions.Options": "9.0.8" } }, "Microsoft.Extensions.Logging.Debug": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "MxzZj7XbsYJwfjclVTjJym2/nVIkksu7l7tC/4HYy+YRdDmpE4B+hTzCXu3BNfLNhdLPZsWpyXuYe6UGgWDm3g==", + "resolved": "9.0.8", + "contentHash": "OwHQFVITsONEoizShc1yNYTUvMq0kT9j/LhwAKMsA7OZqtrBXuqjosbSvzkJZ9o+KWAozDh5Y1Vtpe5p/8/1qA==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7", - "Microsoft.Extensions.Logging": "9.0.7", - "Microsoft.Extensions.Logging.Abstractions": "9.0.7" + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", + "Microsoft.Extensions.Logging": "9.0.8", + "Microsoft.Extensions.Logging.Abstractions": "9.0.8" } }, "Microsoft.Extensions.Logging.EventLog": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "usrMVsY7c8M8fESt34Y3eEIQIlRlKXfPDlI+vYEb6xT7SUjhua2ey3NpHgQktiTgz8Uo5RiWqGD8ieiyo2WaDA==", + "resolved": "9.0.8", + "contentHash": "/gMwlll21UJcaXlitUqd+rs9jH36EJz5BpFVPshyOqz5u0qyV1pFnTWm5vhyx+g6gwVYENSLgpazR1urNv83xw==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7", - "Microsoft.Extensions.Logging": "9.0.7", - "Microsoft.Extensions.Logging.Abstractions": "9.0.7", - "Microsoft.Extensions.Options": "9.0.7", - "System.Diagnostics.EventLog": "9.0.7" + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", + "Microsoft.Extensions.Logging": "9.0.8", + "Microsoft.Extensions.Logging.Abstractions": "9.0.8", + "Microsoft.Extensions.Options": "9.0.8", + "System.Diagnostics.EventLog": "9.0.8" } }, "Microsoft.Extensions.Logging.EventSource": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "/wwi6ckTEegCExFV6gVToCO7CvysZnmE50fpdkYUsSMh0ue9vRkQ7uOqkHyHol93ASYTEahrp+guMtS/+fZKaA==", + "resolved": "9.0.8", + "contentHash": "aGMFc/1P+315d07iyxSe6lEoZ0JjOPJ+Mfv9rrV2PvR2DFu1/pSi/SItHw1iChJOZgslNKJE97g1a9nLX3qQYA==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7", - "Microsoft.Extensions.Logging": "9.0.7", - "Microsoft.Extensions.Logging.Abstractions": "9.0.7", - "Microsoft.Extensions.Options": "9.0.7", - "Microsoft.Extensions.Primitives": "9.0.7" + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", + "Microsoft.Extensions.Logging": "9.0.8", + "Microsoft.Extensions.Logging.Abstractions": "9.0.8", + "Microsoft.Extensions.Options": "9.0.8", + "Microsoft.Extensions.Primitives": "9.0.8" } }, "Microsoft.Extensions.Options": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "trJnF6cRWgR5uMmHpGoHmM1wOVFdIYlELlkO9zX+RfieK0321Y55zrcs4AaEymKup7dxgEN/uJU25CAcMNQRXw==", + "resolved": "9.0.8", + "contentHash": "OmTaQ0v4gxGQkehpwWIqPoEiwsPuG/u4HUsbOFoWGx4DKET2AXzopnFe/fE608FIhzc/kcg2p8JdyMRCCUzitQ==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7", - "Microsoft.Extensions.Primitives": "9.0.7" + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", + "Microsoft.Extensions.Primitives": "9.0.8" } }, "Microsoft.Extensions.Options.ConfigurationExtensions": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "pE/jeAWHEIy/8HsqYA+I1+toTsdvsv+WywAcRoNSvPoFwjOREa8Fqn7D0/i0PbiXsDLFupltTTctliePx8ib4w==", + "resolved": "9.0.8", + "contentHash": "eW2s6n06x0w6w4nsX+SvpgsFYkl+Y0CttYAt6DKUXeqprX+hzNqjSfOh637fwNJBg7wRBrOIRHe49gKiTgJxzQ==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "9.0.7", - "Microsoft.Extensions.Configuration.Binder": "9.0.7", - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7", - "Microsoft.Extensions.Options": "9.0.7", - "Microsoft.Extensions.Primitives": "9.0.7" + "Microsoft.Extensions.Configuration.Abstractions": "9.0.8", + "Microsoft.Extensions.Configuration.Binder": "9.0.8", + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", + "Microsoft.Extensions.Options": "9.0.8", + "Microsoft.Extensions.Primitives": "9.0.8" } }, "Microsoft.Extensions.Primitives": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "ti/zD9BuuO50IqlvhWQs9GHxkCmoph5BHjGiWKdg2t6Or8XoyAfRJiKag+uvd/fpASnNklfsB01WpZ4fhAe0VQ==" + "resolved": "9.0.8", + "contentHash": "tizSIOEsIgSNSSh+hKeUVPK7xmTIjR8s+mJWOu1KXV3htvNQiPMFRMO17OdI1y/4ZApdBVk49u/08QGC9yvLug==" }, "Microsoft.IO.RecyclableMemoryStream": { "type": "Transitive", @@ -552,8 +552,8 @@ }, "Microsoft.Win32.SystemEvents": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "lFGY2aGgmMREPJEfOmZcA6v0CLjWVpcfNHRgqYMoSQhy80+GxhYqdW5xe+DCLrVqE1M7/0RpOkIo49/KH/cd/A==" + "resolved": "9.0.8", + "contentHash": "64oQBN8I8EOcyHGNt6+rlcqm4tlcKfqOpswtBCJZnpzBQ15L6IFKqjnbjbOWBpG9wKq9A/aC2LFSmSqplbwTYA==" }, "Mono.Cecil": { "type": "Transitive", @@ -590,15 +590,15 @@ }, "NLog": { "type": "Transitive", - "resolved": "6.0.1", - "contentHash": "qDWiqy8/xdpZKtHna/645KbalwP86N2NFJEzfqhcv+Si4V2iNaEfR/dCneuF/4+Dcwl3f7jHMXj3ndWYftV3Ug==" + "resolved": "6.0.3", + "contentHash": "5RMrpvadysflvDOi5ozD7aK1P+YL2DyZbQSxzE8qBKkw2pxPNOQA6vJtumcT6SuzE9qxhwGkQwMkLLaKnALwiw==" }, "NLog.OutputDebugString": { "type": "Transitive", - "resolved": "6.0.1", - "contentHash": "wwJCQLaHVzuRf8TsXB+EEdrzVvE3dnzCSMQMDgwkw3AXp8VSp3JSVF/Q/H0oEqggKgKhPs13hh3a7svyQr4s3A==", + "resolved": "6.0.3", + "contentHash": "0qojvaBMAruTDIbjRXMwft3hdkg8tPl0BMD8+tR8TpK78a8DrgKAq/h5LcHPQ/0xERZ66y+00bsn0n1VeJjlmg==", "dependencies": { - "NLog": "6.0.1" + "NLog": "6.0.3" } }, "runtime.osx.10.10-x64.CoreCompat.System.Drawing": { @@ -608,8 +608,8 @@ }, "SharpVectors.Wpf": { "type": "Transitive", - "resolved": "1.8.4.2", - "contentHash": "PNxLkMBJnV8A+6yH9OqOlhLJegvWP/dvh0rAJp2l0kcrR+rB4R2tQ9vhUqka+UilH4atN8T6zvjDOizVyfz2Ng==" + "resolved": "1.8.5", + "contentHash": "WURdBDq5AE8RjKV9pFS7lNkJe81gxja9SaMGE4URq9GJUZ6M+5DGUL0Lm3B0iYW2/Meyowaz4ffGsyW+RBSTtg==" }, "Splat": { "type": "Transitive", @@ -672,15 +672,15 @@ }, "System.Diagnostics.EventLog": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "AJ+9fyCtQUImntxAJ9l4PZiCd4iepuk4pm7Qcno7PBIWQnfXlvwKuFsGk2H+QyY69GUVzDP2heELW6ho5BCXUg==" + "resolved": "9.0.8", + "contentHash": "gebRF3JLLJ76jz1CQpvwezNapZUjFq20JQsaGHzBH0DzlkHBLpdhwkOei9usiOkIGMwU/L0ALWpNe1JE+5/itw==" }, "System.Drawing.Common": { "type": "Transitive", - "resolved": "9.0.7", - "contentHash": "1k/Pk7hcM3vP2tfIRRS2ECCCN7ya+hvocsM1JMc4ZDCU6qw7yOuUmqmCDfgXZ4Q4FS6jass2EAai5ByKodDi0g==", + "resolved": "9.0.8", + "contentHash": "ineIJmF+yuBEHGft9R153J9kmBFaeEfFL5Put5nzENneRcGGPUb3MvM8zrZ5pERQ0jPPSE3Wqw/clXvOq2F/Kw==", "dependencies": { - "Microsoft.Win32.SystemEvents": "9.0.7" + "Microsoft.Win32.SystemEvents": "9.0.8" } }, "System.Globalization": { @@ -838,7 +838,7 @@ "type": "Project", "dependencies": { "Droplex": "[1.7.0, )", - "FSharp.Core": "[9.0.300, )", + "FSharp.Core": "[9.0.303, )", "Flow.Launcher.Infrastructure": "[1.0.0, )", "Flow.Launcher.Plugin": "[4.7.0, )", "Meziantou.Framework.Win32.Jobs": "[3.4.3, )", @@ -859,17 +859,17 @@ "MemoryPack": "[1.21.4, )", "Microsoft.VisualStudio.Threading": "[17.14.15, )", "NHotkey.Wpf": "[3.0.0, )", - "NLog": "[6.0.1, )", - "NLog.OutputDebugString": "[6.0.1, )", - "SharpVectors.Wpf": "[1.8.4.2, )", - "System.Drawing.Common": "[9.0.7, )", + "NLog": "[6.0.3, )", + "NLog.OutputDebugString": "[6.0.3, )", + "SharpVectors.Wpf": "[1.8.5, )", + "System.Drawing.Common": "[9.0.8, )", "ToolGood.Words.Pinyin": "[3.1.0.3, )" } }, "flow.launcher.plugin": { "type": "Project", "dependencies": { - "JetBrains.Annotations": "[2024.3.0, )" + "JetBrains.Annotations": "[2025.2.0, )" } } } diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj index 7d3cf164c..935c81859 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj @@ -99,9 +99,9 @@ - + - + diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj b/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj index 43a2c2f3c..23964f650 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj @@ -62,7 +62,7 @@ - + diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj index 2f24015ad..679a17f61 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj @@ -47,8 +47,8 @@ - - + + diff --git a/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj b/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj index da2b19d7c..c33a26300 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj +++ b/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj @@ -64,12 +64,12 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + \ No newline at end of file From b07763ad054e084a9decf196254dcdde877b1535 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Tue, 19 Aug 2025 14:27:45 +0800 Subject: [PATCH 02/75] Suppress FLSG0007 --- .../Flow.Launcher.Plugin.BrowserBookmark.csproj | 1 + .../Flow.Launcher.Plugin.Calculator.csproj | 1 + .../Flow.Launcher.Plugin.Explorer.csproj | 1 + 3 files changed, 3 insertions(+) diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj index 935c81859..055cee4b8 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj @@ -34,6 +34,7 @@ prompt 4 false + FLSG0007 diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj b/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj index 23964f650..7bfa2ba19 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj @@ -33,6 +33,7 @@ prompt 4 false + FLSG0007 diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj index 679a17f61..751f92557 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj @@ -19,6 +19,7 @@ ..\..\Output\Release\Plugins\Flow.Launcher.Plugin.Explorer + FLSG0007 From 6b6037388630ad78b5100dd2cc67f520164eac3b Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Mon, 25 Aug 2025 18:50:02 +0800 Subject: [PATCH 03/75] Upgrade nuget packages --- .../Flow.Launcher.Infrastructure.csproj | 2 +- Flow.Launcher.Infrastructure/packages.lock.json | 6 +++--- Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj | 2 +- Flow.Launcher.Plugin/packages.lock.json | 6 +++--- Flow.Launcher/Flow.Launcher.csproj | 2 +- Flow.Launcher/packages.lock.json | 6 +++--- .../Flow.Launcher.Plugin.BrowserBookmark.csproj | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj index 7bb8786cd..9f01d5d0f 100644 --- a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj +++ b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj @@ -56,7 +56,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Flow.Launcher.Infrastructure/packages.lock.json b/Flow.Launcher.Infrastructure/packages.lock.json index bcb3031e0..6786b0f49 100644 --- a/Flow.Launcher.Infrastructure/packages.lock.json +++ b/Flow.Launcher.Infrastructure/packages.lock.json @@ -25,9 +25,9 @@ }, "Fody": { "type": "Direct", - "requested": "[6.9.2, )", - "resolved": "6.9.2", - "contentHash": "YBHobPGogb0vYhGYIxn/ndWqTjNWZveDi5jdjrcshL2vjwU3gQGyDeI7vGgye+2rAM5fGRvlLgNWLW3DpviS/w==" + "requested": "[6.9.3, )", + "resolved": "6.9.3", + "contentHash": "1CUGgFdyECDKgi5HaUBhdv6k+VG9Iy4OCforGfHyar3xQXAJypZkzymgKtWj/4SPd6nSG0Qi7NH71qHrDSZLaA==" }, "InputSimulator": { "type": "Direct", diff --git a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj index ccb9332b4..fcc087b62 100644 --- a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj +++ b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj @@ -68,7 +68,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Flow.Launcher.Plugin/packages.lock.json b/Flow.Launcher.Plugin/packages.lock.json index 56b343e6b..b009c54c8 100644 --- a/Flow.Launcher.Plugin/packages.lock.json +++ b/Flow.Launcher.Plugin/packages.lock.json @@ -4,9 +4,9 @@ "net9.0-windows7.0": { "Fody": { "type": "Direct", - "requested": "[6.9.2, )", - "resolved": "6.9.2", - "contentHash": "YBHobPGogb0vYhGYIxn/ndWqTjNWZveDi5jdjrcshL2vjwU3gQGyDeI7vGgye+2rAM5fGRvlLgNWLW3DpviS/w==" + "requested": "[6.9.3, )", + "resolved": "6.9.3", + "contentHash": "1CUGgFdyECDKgi5HaUBhdv6k+VG9Iy4OCforGfHyar3xQXAJypZkzymgKtWj/4SPd6nSG0Qi7NH71qHrDSZLaA==" }, "JetBrains.Annotations": { "type": "Direct", diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj index 6d6b454c0..d7991572a 100644 --- a/Flow.Launcher/Flow.Launcher.csproj +++ b/Flow.Launcher/Flow.Launcher.csproj @@ -128,7 +128,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Flow.Launcher/packages.lock.json b/Flow.Launcher/packages.lock.json index 483766978..9b1bc94a7 100644 --- a/Flow.Launcher/packages.lock.json +++ b/Flow.Launcher/packages.lock.json @@ -16,9 +16,9 @@ }, "Fody": { "type": "Direct", - "requested": "[6.9.2, )", - "resolved": "6.9.2", - "contentHash": "YBHobPGogb0vYhGYIxn/ndWqTjNWZveDi5jdjrcshL2vjwU3gQGyDeI7vGgye+2rAM5fGRvlLgNWLW3DpviS/w==" + "requested": "[6.9.3, )", + "resolved": "6.9.3", + "contentHash": "1CUGgFdyECDKgi5HaUBhdv6k+VG9Iy4OCforGfHyar3xQXAJypZkzymgKtWj/4SPd6nSG0Qi7NH71qHrDSZLaA==" }, "MdXaml": { "type": "Direct", diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj index 055cee4b8..ee89df8d1 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj @@ -102,7 +102,7 @@ - + From 6e873abc7bcf7d21e5dd37f3f082785c02c087af Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sat, 30 Aug 2025 16:34:34 +0800 Subject: [PATCH 04/75] Upgrade nuget package & Fix lock file issue --- Flow.Launcher.Core/packages.lock.json | 8 ++++---- Flow.Launcher.Infrastructure/packages.lock.json | 6 +++--- Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj | 2 +- Flow.Launcher.Plugin/packages.lock.json | 6 +++--- Flow.Launcher/packages.lock.json | 8 ++++---- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Flow.Launcher.Core/packages.lock.json b/Flow.Launcher.Core/packages.lock.json index f5f81e874..e237568fa 100644 --- a/Flow.Launcher.Core/packages.lock.json +++ b/Flow.Launcher.Core/packages.lock.json @@ -90,8 +90,8 @@ }, "JetBrains.Annotations": { "type": "Transitive", - "resolved": "2025.2.0", - "contentHash": "2BvMkOSW+50EbQFhWFIPWTqmcDLiyyjwkMN7lN386bhP2vN/7ts5t59qu11HtenmHFxqDzaD8J1fFoh+QTOzVA==" + "resolved": "2025.2.1", + "contentHash": "63fHdqhM9JuFSithjKbbcEPf1BA76JyXgRqYO6paN9xcKeL6XvttjUUjrfiZ94v8aXn9+6U4pYSHIYAY+5qgFQ==" }, "MemoryPack": { "type": "Transitive", @@ -262,14 +262,14 @@ "NLog": "[6.0.3, )", "NLog.OutputDebugString": "[6.0.3, )", "SharpVectors.Wpf": "[1.8.5, )", - "System.Drawing.Common": "[9.0.8, )", + "System.Drawing.Common": "[7.0.0, )", "ToolGood.Words.Pinyin": "[3.1.0.3, )" } }, "flow.launcher.plugin": { "type": "Project", "dependencies": { - "JetBrains.Annotations": "[2025.2.0, )" + "JetBrains.Annotations": "[2025.2.1, )" } } } diff --git a/Flow.Launcher.Infrastructure/packages.lock.json b/Flow.Launcher.Infrastructure/packages.lock.json index ac00d0202..a1c56c4bf 100644 --- a/Flow.Launcher.Infrastructure/packages.lock.json +++ b/Flow.Launcher.Infrastructure/packages.lock.json @@ -123,8 +123,8 @@ }, "JetBrains.Annotations": { "type": "Transitive", - "resolved": "2025.2.0", - "contentHash": "2BvMkOSW+50EbQFhWFIPWTqmcDLiyyjwkMN7lN386bhP2vN/7ts5t59qu11HtenmHFxqDzaD8J1fFoh+QTOzVA==" + "resolved": "2025.2.1", + "contentHash": "63fHdqhM9JuFSithjKbbcEPf1BA76JyXgRqYO6paN9xcKeL6XvttjUUjrfiZ94v8aXn9+6U4pYSHIYAY+5qgFQ==" }, "MemoryPack.Core": { "type": "Transitive", @@ -190,7 +190,7 @@ "flow.launcher.plugin": { "type": "Project", "dependencies": { - "JetBrains.Annotations": "[2025.2.0, )" + "JetBrains.Annotations": "[2025.2.1, )" } } } diff --git a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj index fcc087b62..cf4aa02f0 100644 --- a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj +++ b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj @@ -73,7 +73,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Flow.Launcher.Plugin/packages.lock.json b/Flow.Launcher.Plugin/packages.lock.json index b009c54c8..1ba5b0103 100644 --- a/Flow.Launcher.Plugin/packages.lock.json +++ b/Flow.Launcher.Plugin/packages.lock.json @@ -10,9 +10,9 @@ }, "JetBrains.Annotations": { "type": "Direct", - "requested": "[2025.2.0, )", - "resolved": "2025.2.0", - "contentHash": "2BvMkOSW+50EbQFhWFIPWTqmcDLiyyjwkMN7lN386bhP2vN/7ts5t59qu11HtenmHFxqDzaD8J1fFoh+QTOzVA==" + "requested": "[2025.2.1, )", + "resolved": "2025.2.1", + "contentHash": "63fHdqhM9JuFSithjKbbcEPf1BA76JyXgRqYO6paN9xcKeL6XvttjUUjrfiZ94v8aXn9+6U4pYSHIYAY+5qgFQ==" }, "Microsoft.SourceLink.GitHub": { "type": "Direct", diff --git a/Flow.Launcher/packages.lock.json b/Flow.Launcher/packages.lock.json index a4a3bcd6c..ffaceb356 100644 --- a/Flow.Launcher/packages.lock.json +++ b/Flow.Launcher/packages.lock.json @@ -211,8 +211,8 @@ }, "JetBrains.Annotations": { "type": "Transitive", - "resolved": "2025.2.0", - "contentHash": "2BvMkOSW+50EbQFhWFIPWTqmcDLiyyjwkMN7lN386bhP2vN/7ts5t59qu11HtenmHFxqDzaD8J1fFoh+QTOzVA==" + "resolved": "2025.2.1", + "contentHash": "63fHdqhM9JuFSithjKbbcEPf1BA76JyXgRqYO6paN9xcKeL6XvttjUUjrfiZ94v8aXn9+6U4pYSHIYAY+5qgFQ==" }, "MemoryPack": { "type": "Transitive", @@ -862,14 +862,14 @@ "NLog": "[6.0.3, )", "NLog.OutputDebugString": "[6.0.3, )", "SharpVectors.Wpf": "[1.8.5, )", - "System.Drawing.Common": "[9.0.8, )", + "System.Drawing.Common": "[7.0.0, )", "ToolGood.Words.Pinyin": "[3.1.0.3, )" } }, "flow.launcher.plugin": { "type": "Project", "dependencies": { - "JetBrains.Annotations": "[2025.2.0, )" + "JetBrains.Annotations": "[2025.2.1, )" } } } From b501e52f5db305652b081a1bda22b10f17cd224c Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 5 Sep 2025 19:49:21 +0800 Subject: [PATCH 05/75] Upgrade nuget packages --- Flow.Launcher.Core/Flow.Launcher.Core.csproj | 2 +- Flow.Launcher.Core/packages.lock.json | 12 ++++++------ Flow.Launcher.Infrastructure/packages.lock.json | 6 +++--- Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj | 4 ++-- Flow.Launcher.Plugin/packages.lock.json | 6 +++--- Flow.Launcher/packages.lock.json | 12 ++++++------ 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/Flow.Launcher.Core/Flow.Launcher.Core.csproj b/Flow.Launcher.Core/Flow.Launcher.Core.csproj index 1aae953a4..1369d7e5d 100644 --- a/Flow.Launcher.Core/Flow.Launcher.Core.csproj +++ b/Flow.Launcher.Core/Flow.Launcher.Core.csproj @@ -56,7 +56,7 @@ - + diff --git a/Flow.Launcher.Core/packages.lock.json b/Flow.Launcher.Core/packages.lock.json index e237568fa..487c3c5a2 100644 --- a/Flow.Launcher.Core/packages.lock.json +++ b/Flow.Launcher.Core/packages.lock.json @@ -19,9 +19,9 @@ }, "Meziantou.Framework.Win32.Jobs": { "type": "Direct", - "requested": "[3.4.3, )", - "resolved": "3.4.3", - "contentHash": "REjInKnQ0OrhjjtSMPQtLtdURctCroB4L8Sd2gjTOYDysklvsdnrStx1tHS7uLv+fSyFF3aazZmo5Ka0v1oz/w==" + "requested": "[3.4.4, )", + "resolved": "3.4.4", + "contentHash": "AivBzH5wM1NHBLehclim+o37SmireP7JxCRUoTilsc/h7LH9+YCPjb6Ig6y0khnQhFcO1P8RHYw4oiR15TGHUg==" }, "Microsoft.IO.RecyclableMemoryStream": { "type": "Direct", @@ -90,8 +90,8 @@ }, "JetBrains.Annotations": { "type": "Transitive", - "resolved": "2025.2.1", - "contentHash": "63fHdqhM9JuFSithjKbbcEPf1BA76JyXgRqYO6paN9xcKeL6XvttjUUjrfiZ94v8aXn9+6U4pYSHIYAY+5qgFQ==" + "resolved": "2025.2.2", + "contentHash": "0X56ZRizuHdrnPpgXjWV7f2tQO1FlQg5O1967OGKnI/4ZRNOK642J8L7brM1nYvrxTTU5TP1yRyXLRLaXLPQ8A==" }, "MemoryPack": { "type": "Transitive", @@ -269,7 +269,7 @@ "flow.launcher.plugin": { "type": "Project", "dependencies": { - "JetBrains.Annotations": "[2025.2.1, )" + "JetBrains.Annotations": "[2025.2.2, )" } } } diff --git a/Flow.Launcher.Infrastructure/packages.lock.json b/Flow.Launcher.Infrastructure/packages.lock.json index a1c56c4bf..b1e416738 100644 --- a/Flow.Launcher.Infrastructure/packages.lock.json +++ b/Flow.Launcher.Infrastructure/packages.lock.json @@ -123,8 +123,8 @@ }, "JetBrains.Annotations": { "type": "Transitive", - "resolved": "2025.2.1", - "contentHash": "63fHdqhM9JuFSithjKbbcEPf1BA76JyXgRqYO6paN9xcKeL6XvttjUUjrfiZ94v8aXn9+6U4pYSHIYAY+5qgFQ==" + "resolved": "2025.2.2", + "contentHash": "0X56ZRizuHdrnPpgXjWV7f2tQO1FlQg5O1967OGKnI/4ZRNOK642J8L7brM1nYvrxTTU5TP1yRyXLRLaXLPQ8A==" }, "MemoryPack.Core": { "type": "Transitive", @@ -190,7 +190,7 @@ "flow.launcher.plugin": { "type": "Project", "dependencies": { - "JetBrains.Annotations": "[2025.2.1, )" + "JetBrains.Annotations": "[2025.2.2, )" } } } diff --git a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj index cf4aa02f0..f6e96c2ba 100644 --- a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj +++ b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj @@ -1,4 +1,4 @@ - + net9.0-windows @@ -73,7 +73,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Flow.Launcher.Plugin/packages.lock.json b/Flow.Launcher.Plugin/packages.lock.json index 1ba5b0103..10ca667ff 100644 --- a/Flow.Launcher.Plugin/packages.lock.json +++ b/Flow.Launcher.Plugin/packages.lock.json @@ -10,9 +10,9 @@ }, "JetBrains.Annotations": { "type": "Direct", - "requested": "[2025.2.1, )", - "resolved": "2025.2.1", - "contentHash": "63fHdqhM9JuFSithjKbbcEPf1BA76JyXgRqYO6paN9xcKeL6XvttjUUjrfiZ94v8aXn9+6U4pYSHIYAY+5qgFQ==" + "requested": "[2025.2.2, )", + "resolved": "2025.2.2", + "contentHash": "0X56ZRizuHdrnPpgXjWV7f2tQO1FlQg5O1967OGKnI/4ZRNOK642J8L7brM1nYvrxTTU5TP1yRyXLRLaXLPQ8A==" }, "Microsoft.SourceLink.GitHub": { "type": "Direct", diff --git a/Flow.Launcher/packages.lock.json b/Flow.Launcher/packages.lock.json index ffaceb356..5d1117627 100644 --- a/Flow.Launcher/packages.lock.json +++ b/Flow.Launcher/packages.lock.json @@ -211,8 +211,8 @@ }, "JetBrains.Annotations": { "type": "Transitive", - "resolved": "2025.2.1", - "contentHash": "63fHdqhM9JuFSithjKbbcEPf1BA76JyXgRqYO6paN9xcKeL6XvttjUUjrfiZ94v8aXn9+6U4pYSHIYAY+5qgFQ==" + "resolved": "2025.2.2", + "contentHash": "0X56ZRizuHdrnPpgXjWV7f2tQO1FlQg5O1967OGKnI/4ZRNOK642J8L7brM1nYvrxTTU5TP1yRyXLRLaXLPQ8A==" }, "MemoryPack": { "type": "Transitive", @@ -249,8 +249,8 @@ }, "Meziantou.Framework.Win32.Jobs": { "type": "Transitive", - "resolved": "3.4.3", - "contentHash": "REjInKnQ0OrhjjtSMPQtLtdURctCroB4L8Sd2gjTOYDysklvsdnrStx1tHS7uLv+fSyFF3aazZmo5Ka0v1oz/w==" + "resolved": "3.4.4", + "contentHash": "AivBzH5wM1NHBLehclim+o37SmireP7JxCRUoTilsc/h7LH9+YCPjb6Ig6y0khnQhFcO1P8RHYw4oiR15TGHUg==" }, "Microsoft.Extensions.Configuration": { "type": "Transitive", @@ -841,7 +841,7 @@ "FSharp.Core": "[9.0.303, )", "Flow.Launcher.Infrastructure": "[1.0.0, )", "Flow.Launcher.Plugin": "[4.7.0, )", - "Meziantou.Framework.Win32.Jobs": "[3.4.3, )", + "Meziantou.Framework.Win32.Jobs": "[3.4.4, )", "Microsoft.IO.RecyclableMemoryStream": "[3.0.1, )", "SemanticVersioning": "[3.0.0, )", "StreamJsonRpc": "[2.22.11, )", @@ -869,7 +869,7 @@ "flow.launcher.plugin": { "type": "Project", "dependencies": { - "JetBrains.Annotations": "[2025.2.1, )" + "JetBrains.Annotations": "[2025.2.2, )" } } } From 8e837b8e56487f943382601992ebef618acd15b5 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sat, 6 Sep 2025 13:37:27 +0800 Subject: [PATCH 06/75] Avoid clobbering inherited NoWarn; append instead. --- .../Flow.Launcher.Plugin.BrowserBookmark.csproj | 2 +- .../Flow.Launcher.Plugin.Calculator.csproj | 2 +- .../Flow.Launcher.Plugin.Explorer.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj index 6cabc686c..8dd06bfdb 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj @@ -34,7 +34,7 @@ prompt 4 false - FLSG0007 + $(NoWarn);FLSG0007 diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj b/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj index 7bfa2ba19..b3cee425d 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj @@ -33,7 +33,7 @@ prompt 4 false - FLSG0007 + $(NoWarn);FLSG0007 diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj index 9243ba155..da1dd55b9 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj @@ -19,7 +19,7 @@ ..\..\Output\Release\Plugins\Flow.Launcher.Plugin.Explorer - FLSG0007 + $(NoWarn);FLSG0007 From f40255bc8a65b921c9a1490fad7efde1fabc9a78 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sat, 6 Sep 2025 15:52:57 +0800 Subject: [PATCH 07/75] Use DialogJump to get explorer path --- .../FileExplorerHelper.cs | 75 ++----------------- 1 file changed, 5 insertions(+), 70 deletions(-) diff --git a/Flow.Launcher.Infrastructure/FileExplorerHelper.cs b/Flow.Launcher.Infrastructure/FileExplorerHelper.cs index 1085cc833..6e2d86849 100644 --- a/Flow.Launcher.Infrastructure/FileExplorerHelper.cs +++ b/Flow.Launcher.Infrastructure/FileExplorerHelper.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Windows.Win32; namespace Flow.Launcher.Infrastructure { @@ -13,9 +9,10 @@ namespace Flow.Launcher.Infrastructure /// public static string GetActiveExplorerPath() { - var explorerWindow = GetActiveExplorer(); - string locationUrl = explorerWindow?.LocationURL; - return !string.IsNullOrEmpty(locationUrl) ? GetDirectoryPath(new Uri(locationUrl).LocalPath) : null; + var explorerPath = DialogJump.DialogJump.GetActiveExplorerPath(); + return !string.IsNullOrEmpty(explorerPath) ? + GetDirectoryPath(new Uri(explorerPath).LocalPath) : + null; } /// @@ -23,74 +20,12 @@ namespace Flow.Launcher.Infrastructure /// private static string GetDirectoryPath(string path) { - if (!path.EndsWith("\\")) + if (!path.EndsWith('\\')) { return path + "\\"; } return path; } - - /// - /// Gets the file explorer that is currently in the foreground - /// - private static dynamic GetActiveExplorer() - { - Type type = Type.GetTypeFromProgID("Shell.Application"); - if (type == null) return null; - dynamic shell = Activator.CreateInstance(type); - if (shell == null) - { - return null; - } - - var explorerWindows = new List(); - var openWindows = shell.Windows(); - for (int i = 0; i < openWindows.Count; i++) - { - var window = openWindows.Item(i); - if (window == null) continue; - - // find the desired window and make sure that it is indeed a file explorer - // we don't want the Internet Explorer or the classic control panel - // ToLower() is needed, because Windows can report the path as "C:\\Windows\\Explorer.EXE" - if (Path.GetFileName((string)window.FullName)?.ToLower() == "explorer.exe") - { - explorerWindows.Add(window); - } - } - - if (explorerWindows.Count == 0) return null; - - var zOrders = GetZOrder(explorerWindows); - - return explorerWindows.Zip(zOrders).MinBy(x => x.Second).First; - } - - /// - /// Gets the z-order for one or more windows atomically with respect to each other. In Windows, smaller z-order is higher. If the window is not top level, the z order is returned as -1. - /// - private static IEnumerable GetZOrder(List hWnds) - { - var z = new int[hWnds.Count]; - for (var i = 0; i < hWnds.Count; i++) z[i] = -1; - - var index = 0; - var numRemaining = hWnds.Count; - PInvoke.EnumWindows((wnd, _) => - { - var searchIndex = hWnds.FindIndex(x => new IntPtr(x.HWND) == wnd); - if (searchIndex != -1) - { - z[searchIndex] = index; - numRemaining--; - if (numRemaining == 0) return false; - } - index++; - return true; - }, IntPtr.Zero); - - return z; - } } } From ca164b37db8e91ea8a08eb1a690cc4ce3051d296 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Sep 2025 22:07:50 +0000 Subject: [PATCH 08/75] Bump Microsoft.Data.Sqlite from 9.0.8 to 9.0.9 --- updated-dependencies: - dependency-name: Microsoft.Data.Sqlite dependency-version: 9.0.9 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .../Flow.Launcher.Plugin.BrowserBookmark.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj index 901dc2a37..3301b89b2 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj @@ -104,7 +104,7 @@ - + From e1079396c3bfb6e3a22ef4227900c91460cd300d Mon Sep 17 00:00:00 2001 From: dcog989 Date: Fri, 12 Sep 2025 19:20:19 +0100 Subject: [PATCH 09/75] backout 'smart' digit grouping, mages fixes + workaround Mages did not like the previous change to smart thousands / decimal so backed that out. Workaround for https://github.com/FlorianRappl/Mages/issues/132 --- .../Flow.Launcher.Plugin.Calculator/Main.cs | 168 +++++++----------- .../MainRegexHelper.cs | 2 +- 2 files changed, 65 insertions(+), 105 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs index 6878c54b4..d2e1ed821 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs @@ -13,7 +13,6 @@ namespace Flow.Launcher.Plugin.Calculator { public class Main : IPlugin, IPluginI18n, ISettingProvider { - private static readonly Regex RegValidExpressChar = MainRegexHelper.GetRegValidExpressChar(); private static readonly Regex RegBrackets = MainRegexHelper.GetRegBrackets(); private static readonly Regex ThousandGroupRegex = MainRegexHelper.GetThousandGroupRegex(); private static readonly Regex NumberRegex = MainRegexHelper.GetNumberRegex(); @@ -27,16 +26,6 @@ namespace Flow.Launcher.Plugin.Calculator private Settings _settings; private SettingsViewModel _viewModel; - /// - /// Holds the formatting information for a single query. - /// This is used to ensure thread safety by keeping query state local. - /// - private class ParsingContext - { - public string InputDecimalSeparator { get; set; } - public bool InputUsesGroupSeparators { get; set; } - } - public void Init(PluginInitContext context) { Context = context; @@ -59,24 +48,46 @@ namespace Flow.Launcher.Plugin.Calculator return new List(); } - var context = new ParsingContext(); - try { - var expression = NumberRegex.Replace(query.Search, m => NormalizeNumber(m.Value, context)); + var expression = NumberRegex.Replace(query.Search, m => NormalizeNumber(m.Value)); + + // WORKAROUND START: The 'pow' function in Mages v3.0.0 is broken. + // https://github.com/FlorianRappl/Mages/issues/132 + // We bypass it by rewriting any pow(x,y) expression to the equivalent (x^y) expression + // before the engine sees it. This loop handles nested calls. + string previous; + do + { + previous = expression; + expression = Regex.Replace(previous, @"\bpow\s*\(\s*([^,]+?)\s*,\s*([^)]+?)\s*\)", "($1^$2)"); + } while (previous != expression); + // WORKAROUND END var result = MagesEngine.Interpret(expression); - if (result?.ToString() == "NaN") + if (result == null || string.IsNullOrEmpty(result.ToString())) + { + return new List + { + new Result + { + Title = Localize.flowlauncher_plugin_calculator_expression_not_complete(), + IcoPath = "Images/calculator.png" + } + }; + } + + if (result.ToString() == "NaN") result = Localize.flowlauncher_plugin_calculator_not_a_number(); if (result is Function) result = Localize.flowlauncher_plugin_calculator_expression_not_complete(); - if (!string.IsNullOrEmpty(result?.ToString())) + if (!string.IsNullOrEmpty(result.ToString())) { decimal roundedResult = Math.Round(Convert.ToDecimal(result), _settings.MaxDecimalPlaces, MidpointRounding.AwayFromZero); - string newResult = FormatResult(roundedResult, context); + string newResult = FormatResult(roundedResult); return new List { @@ -104,115 +115,69 @@ namespace Flow.Launcher.Plugin.Calculator }; } } - catch (Exception) + catch (Exception e) { - // ignored + return new List + { + new Result + { + Title = e.Message, + SubTitle = "Calculator Exception", + IcoPath = "Images/calculator.png", + Score = 300 + } + }; } return new List(); } /// - /// Parses a string representation of a number, detecting its format. It uses structural analysis - /// and falls back to system culture for truly ambiguous cases (e.g., "1,234"). - /// It populates the provided ParsingContext with the detected format for later use. + /// Parses a string representation of a number using the system's current culture. /// /// A normalized number string with '.' as the decimal separator for the Mages engine. - private string NormalizeNumber(string numberStr, ParsingContext context) + private string NormalizeNumber(string numberStr) { - var systemGroupSep = CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator; - int dotCount = numberStr.Count(f => f == '.'); - int commaCount = numberStr.Count(f => f == ','); + var culture = CultureInfo.CurrentCulture; + var groupSep = culture.NumberFormat.NumberGroupSeparator; - // Case 1: Unambiguous mixed separators (e.g., "1.234,56") - if (dotCount > 0 && commaCount > 0) + // If the string contains the group separator, check if it's used correctly. + if (!string.IsNullOrEmpty(groupSep) && numberStr.Contains(groupSep)) { - context.InputUsesGroupSeparators = true; - if (numberStr.LastIndexOf('.') > numberStr.LastIndexOf(',')) + var parts = numberStr.Split(groupSep); + // If any part after the first (excluding a possible last part with a decimal) + // does not have 3 digits, then it's not a valid use of a thousand separator. + for (int i = 1; i < parts.Length; i++) { - context.InputDecimalSeparator = Dot; - return numberStr.Replace(Comma, string.Empty); - } - else - { - context.InputDecimalSeparator = Comma; - return numberStr.Replace(Dot, string.Empty).Replace(Comma, Dot); - } - } - - // Case 2: Only dots - if (dotCount > 0) - { - if (dotCount > 1) - { - context.InputUsesGroupSeparators = true; - return numberStr.Replace(Dot, string.Empty); - } - // A number is ambiguous if it has a single Dot in the thousands position, - // and does not start with a "0." or "." - bool isAmbiguous = numberStr.Length - numberStr.LastIndexOf('.') == 4 - && !numberStr.StartsWith("0.") - && !numberStr.StartsWith("."); - if (isAmbiguous) - { - if (systemGroupSep == Dot) + var part = parts[i]; + // The last part might contain a decimal separator. + if (i == parts.Length - 1 && part.Contains(culture.NumberFormat.NumberDecimalSeparator)) { - context.InputUsesGroupSeparators = true; - return numberStr.Replace(Dot, string.Empty); + part = part.Split(culture.NumberFormat.NumberDecimalSeparator)[0]; } - else + + if (part.Length != 3) { - context.InputDecimalSeparator = Dot; + // This is not a number with valid thousand separators, + // so it must be arguments to a function. Return it unmodified. return numberStr; } } - else // Unambiguous decimal (e.g., "12.34" or "0.123" or ".123") - { - context.InputDecimalSeparator = Dot; - return numberStr; - } } - // Case 3: Only commas - if (commaCount > 0) + // At this point, any group separators are in valid positions (or there are none). + // We can safely parse with the user's culture. + if (decimal.TryParse(numberStr, NumberStyles.Any, culture, out var number)) { - if (commaCount > 1) - { - context.InputUsesGroupSeparators = true; - return numberStr.Replace(Comma, string.Empty); - } - // A number is ambiguous if it has a single Comma in the thousands position, - // and does not start with a "0," or "," - bool isAmbiguous = numberStr.Length - numberStr.LastIndexOf(',') == 4 - && !numberStr.StartsWith("0,") - && !numberStr.StartsWith(","); - if (isAmbiguous) - { - if (systemGroupSep == Comma) - { - context.InputUsesGroupSeparators = true; - return numberStr.Replace(Comma, string.Empty); - } - else - { - context.InputDecimalSeparator = Comma; - return numberStr.Replace(Comma, Dot); - } - } - else // Unambiguous decimal (e.g., "12,34" or "0,123" or ",123") - { - context.InputDecimalSeparator = Comma; - return numberStr.Replace(Comma, Dot); - } + return number.ToString(CultureInfo.InvariantCulture); } - // Case 4: No separators return numberStr; } - private string FormatResult(decimal roundedResult, ParsingContext context) + private string FormatResult(decimal roundedResult) { - string decimalSeparator = context.InputDecimalSeparator ?? GetDecimalSeparator(); + string decimalSeparator = GetDecimalSeparator(); string groupSeparator = GetGroupSeparator(decimalSeparator); string resultStr = roundedResult.ToString(CultureInfo.InvariantCulture); @@ -221,7 +186,7 @@ namespace Flow.Launcher.Plugin.Calculator string integerPart = parts[0]; string fractionalPart = parts.Length > 1 ? parts[1] : string.Empty; - if (context.InputUsesGroupSeparators && integerPart.Length > 3) + if (integerPart.Length > 3) { integerPart = ThousandGroupRegex.Replace(integerPart, groupSeparator); } @@ -248,11 +213,6 @@ namespace Flow.Launcher.Plugin.Calculator return false; } - if (!RegValidExpressChar.IsMatch(query.Search)) - { - return false; - } - if (!IsBracketComplete(query.Search)) { return false; diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs b/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs index f4e2090e7..85db0c2cd 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs @@ -11,7 +11,7 @@ internal static partial class MainRegexHelper [GeneratedRegex(@"^(ceil|floor|exp|pi|e|max|min|det|abs|log|ln|sqrt|sin|cos|tan|arcsin|arccos|arctan|eigval|eigvec|eig|sum|polar|plot|round|sort|real|zeta|bin2dec|hex2dec|oct2dec|factorial|sign|isprime|isinfty|==|~=|&&|\|\||(?:\<|\>)=?|[ei]|[0-9]|0x[\da-fA-F]+|[\+\%\-\*\/\^\., ""]|[\(\)\|\!\[\]])+$", RegexOptions.Compiled)] public static partial Regex GetRegValidExpressChar(); - [GeneratedRegex(@"[\d\.,]+", RegexOptions.Compiled)] + [GeneratedRegex(@"-?[\d\.,]+", RegexOptions.Compiled)] public static partial Regex GetNumberRegex(); [GeneratedRegex(@"\B(?=(\d{3})+(?!\d))", RegexOptions.Compiled)] From 103d3832a087a6a9d7bc341898d9291367fdd158 Mon Sep 17 00:00:00 2001 From: dcog989 Date: Fri, 12 Sep 2025 19:30:07 +0100 Subject: [PATCH 10/75] dead code, improve messages, group separator fix? --- .../Flow.Launcher.Plugin.Calculator/Main.cs | 18 +++++++++++------- .../MainRegexHelper.cs | 3 --- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs index d2e1ed821..85cd8a6fd 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs @@ -115,16 +115,15 @@ namespace Flow.Launcher.Plugin.Calculator }; } } - catch (Exception e) + catch (Exception) { + // Mages engine can throw various exceptions, for simplicity we catch them all and show a generic message. return new List { new Result { - Title = e.Message, - SubTitle = "Calculator Exception", - IcoPath = "Images/calculator.png", - Score = 300 + Title = Localize.flowlauncher_plugin_calculator_expression_not_complete(), + IcoPath = "Images/calculator.png" } }; } @@ -201,14 +200,19 @@ namespace Flow.Launcher.Plugin.Calculator private string GetGroupSeparator(string decimalSeparator) { + if (_settings.DecimalSeparator == DecimalSeparator.UseSystemLocale) + { + return CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator; + } + // This logic is now independent of the system's group separator - // to ensure consistent output for unit testing. + // to ensure consistent output when a specific separator is chosen. return decimalSeparator == Dot ? Comma : Dot; } private bool CanCalculate(Query query) { - if (query.Search.Length < 2) + if (string.IsNullOrWhiteSpace(query.Search)) { return false; } diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs b/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs index 85db0c2cd..2e0353614 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs @@ -8,9 +8,6 @@ internal static partial class MainRegexHelper [GeneratedRegex(@"[\(\)\[\]]", RegexOptions.Compiled)] public static partial Regex GetRegBrackets(); - [GeneratedRegex(@"^(ceil|floor|exp|pi|e|max|min|det|abs|log|ln|sqrt|sin|cos|tan|arcsin|arccos|arctan|eigval|eigvec|eig|sum|polar|plot|round|sort|real|zeta|bin2dec|hex2dec|oct2dec|factorial|sign|isprime|isinfty|==|~=|&&|\|\||(?:\<|\>)=?|[ei]|[0-9]|0x[\da-fA-F]+|[\+\%\-\*\/\^\., ""]|[\(\)\|\!\[\]])+$", RegexOptions.Compiled)] - public static partial Regex GetRegValidExpressChar(); - [GeneratedRegex(@"-?[\d\.,]+", RegexOptions.Compiled)] public static partial Regex GetNumberRegex(); From 190e0e179f28ba12ad240347971cb5aec7454e07 Mon Sep 17 00:00:00 2001 From: dcog989 Date: Fri, 12 Sep 2025 20:01:55 +0100 Subject: [PATCH 11/75] Fix 'German' number formatting --- Plugins/Flow.Launcher.Plugin.Calculator/Main.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs index 85cd8a6fd..c81eb9b1c 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs @@ -139,6 +139,7 @@ namespace Flow.Launcher.Plugin.Calculator { var culture = CultureInfo.CurrentCulture; var groupSep = culture.NumberFormat.NumberGroupSeparator; + var decimalSep = culture.NumberFormat.NumberDecimalSeparator; // If the string contains the group separator, check if it's used correctly. if (!string.IsNullOrEmpty(groupSep) && numberStr.Contains(groupSep)) @@ -164,14 +165,11 @@ namespace Flow.Launcher.Plugin.Calculator } } - // At this point, any group separators are in valid positions (or there are none). - // We can safely parse with the user's culture. - if (decimal.TryParse(numberStr, NumberStyles.Any, culture, out var number)) - { - return number.ToString(CultureInfo.InvariantCulture); - } + // If validation passes, we can assume the separators are used correctly for numbers. + string processedStr = numberStr.Replace(groupSep, ""); + processedStr = processedStr.Replace(decimalSep, "."); - return numberStr; + return processedStr; } private string FormatResult(decimal roundedResult) From bd186e7fe1bf046d54311175767b648fd8913969 Mon Sep 17 00:00:00 2001 From: dcog989 Date: Fri, 12 Sep 2025 20:02:34 +0100 Subject: [PATCH 12/75] correct + extend description --- Plugins/Flow.Launcher.Plugin.Calculator/plugin.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json b/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json index c9435e043..7b4b53cdb 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json +++ b/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json @@ -2,7 +2,7 @@ "ID": "CEA0FDFC6D3B4085823D60DC76F28855", "ActionKeyword": "*", "Name": "Calculator", - "Description": "Perform mathematical calculations (including hexadecimal values). Use ',' or '.' as thousand separator or decimal place.", + "Description": "Perform mathematical calculations, including hex values and advanced math functions, such as 'min(1,2,3)', 'sqrt(123)', 'cos(123)', etc.. User locale determines thousand separator and decimal place.", "Author": "cxfksword, dcog989", "Version": "1.0.0", "Language": "csharp", From 15f31a16983237d371fc015ea5721e1fde4ab3f8 Mon Sep 17 00:00:00 2001 From: dcog989 Date: Fri, 12 Sep 2025 22:34:03 +0100 Subject: [PATCH 13/75] Bookmark plugin quick fix Catch an exception for empty / corrupted favicons. --- .../Helper/FaviconHelper.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Helper/FaviconHelper.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Helper/FaviconHelper.cs index 1820a7836..82b089033 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Helper/FaviconHelper.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Helper/FaviconHelper.cs @@ -106,12 +106,13 @@ public static class FaviconHelper { try { - using (var image = SKImage.FromBitmap(bitmap)) - using (var webp = image.Encode(SKEncodedImageFormat.Webp, 65)) - { - if (webp != null) - return webp.ToArray(); - } + using var image = SKImage.FromBitmap(bitmap); + if (image is null) + return null; + + using var webp = image.Encode(SKEncodedImageFormat.Webp, 65); + if (webp != null) + return webp.ToArray(); } finally { From 29b675b26a0e1ea090137f2ebdfdbd8e93ada436 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sat, 13 Sep 2025 14:14:59 +0800 Subject: [PATCH 14/75] Upgrade nuget packages --- Flow.Launcher.Core/packages.lock.json | 16 +- .../Flow.Launcher.Infrastructure.csproj | 6 +- .../packages.lock.json | 20 +- .../Flow.Launcher.Plugin.csproj | 2 +- Flow.Launcher.Plugin/packages.lock.json | 6 +- Flow.Launcher/Flow.Launcher.csproj | 46 +-- Flow.Launcher/packages.lock.json | 324 +++++++++--------- .../Flow.Launcher.Plugin.Explorer.csproj | 2 +- .../Flow.Launcher.Plugin.ProcessKiller.csproj | 2 +- .../Flow.Launcher.Plugin.Program.csproj | 6 +- .../Flow.Launcher.Plugin.Sys.csproj | 2 +- 11 files changed, 197 insertions(+), 235 deletions(-) diff --git a/Flow.Launcher.Core/packages.lock.json b/Flow.Launcher.Core/packages.lock.json index 487c3c5a2..b7a00d94d 100644 --- a/Flow.Launcher.Core/packages.lock.json +++ b/Flow.Launcher.Core/packages.lock.json @@ -199,15 +199,15 @@ }, "NLog": { "type": "Transitive", - "resolved": "6.0.3", - "contentHash": "5RMrpvadysflvDOi5ozD7aK1P+YL2DyZbQSxzE8qBKkw2pxPNOQA6vJtumcT6SuzE9qxhwGkQwMkLLaKnALwiw==" + "resolved": "6.0.4", + "contentHash": "Xr+lIk1ZlTTFXEqnxQVLxrDqZlt2tm5X+/AhJbaY2emb/dVtGDiU5QuEtj3gHtwV/SWlP/rJ922I/BPuOJXlRw==" }, "NLog.OutputDebugString": { "type": "Transitive", - "resolved": "6.0.3", - "contentHash": "0qojvaBMAruTDIbjRXMwft3hdkg8tPl0BMD8+tR8TpK78a8DrgKAq/h5LcHPQ/0xERZ66y+00bsn0n1VeJjlmg==", + "resolved": "6.0.4", + "contentHash": "TOP2Ap9BbE98B/l/TglnguowOD0rXo8B/20xAgvj9shO/kf6IJ5M4QMhVxq72mrneJ/ANhHY7Jcd+xJbzuI5PA==", "dependencies": { - "NLog": "6.0.3" + "NLog": "6.0.4" } }, "SharpVectors.Wpf": { @@ -254,13 +254,13 @@ "Ben.Demystifier": "[0.4.1, )", "BitFaster.Caching": "[2.5.4, )", "CommunityToolkit.Mvvm": "[8.4.0, )", - "Flow.Launcher.Plugin": "[4.7.0, )", + "Flow.Launcher.Plugin": "[5.0.0, )", "InputSimulator": "[1.0.4, )", "MemoryPack": "[1.21.4, )", "Microsoft.VisualStudio.Threading": "[17.14.15, )", "NHotkey.Wpf": "[3.0.0, )", - "NLog": "[6.0.3, )", - "NLog.OutputDebugString": "[6.0.3, )", + "NLog": "[6.0.4, )", + "NLog.OutputDebugString": "[6.0.4, )", "SharpVectors.Wpf": "[1.8.5, )", "System.Drawing.Common": "[7.0.0, )", "ToolGood.Words.Pinyin": "[3.1.0.3, )" diff --git a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj index 9aa8f9577..5b4eaf893 100644 --- a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj +++ b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj @@ -63,13 +63,13 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all diff --git a/Flow.Launcher.Infrastructure/packages.lock.json b/Flow.Launcher.Infrastructure/packages.lock.json index b1e416738..47c94d5f6 100644 --- a/Flow.Launcher.Infrastructure/packages.lock.json +++ b/Flow.Launcher.Infrastructure/packages.lock.json @@ -58,9 +58,9 @@ }, "Microsoft.Windows.CsWin32": { "type": "Direct", - "requested": "[0.3.183, )", - "resolved": "0.3.183", - "contentHash": "Ze3aE2y7xgzKxEWtNb4SH0CExXpCHr3sbmwnvMiWMzJhWDX/G4Rs5wgg2UNs3VN+qVHh/DkDWLCPaVQv/b//Nw==", + "requested": "[0.3.205, )", + "resolved": "0.3.205", + "contentHash": "U5wGAnyKd7/I2YMd43nogm81VMtjiKzZ9dsLMVI4eAB7jtv5IEj0gprj0q/F3iRmAIaGv5omOf8iSYx2+nE6BQ==", "dependencies": { "Microsoft.Windows.SDK.Win32Docs": "0.1.42-alpha", "Microsoft.Windows.SDK.Win32Metadata": "61.0.15-preview", @@ -78,17 +78,17 @@ }, "NLog": { "type": "Direct", - "requested": "[6.0.3, )", - "resolved": "6.0.3", - "contentHash": "5RMrpvadysflvDOi5ozD7aK1P+YL2DyZbQSxzE8qBKkw2pxPNOQA6vJtumcT6SuzE9qxhwGkQwMkLLaKnALwiw==" + "requested": "[6.0.4, )", + "resolved": "6.0.4", + "contentHash": "Xr+lIk1ZlTTFXEqnxQVLxrDqZlt2tm5X+/AhJbaY2emb/dVtGDiU5QuEtj3gHtwV/SWlP/rJ922I/BPuOJXlRw==" }, "NLog.OutputDebugString": { "type": "Direct", - "requested": "[6.0.3, )", - "resolved": "6.0.3", - "contentHash": "0qojvaBMAruTDIbjRXMwft3hdkg8tPl0BMD8+tR8TpK78a8DrgKAq/h5LcHPQ/0xERZ66y+00bsn0n1VeJjlmg==", + "requested": "[6.0.4, )", + "resolved": "6.0.4", + "contentHash": "TOP2Ap9BbE98B/l/TglnguowOD0rXo8B/20xAgvj9shO/kf6IJ5M4QMhVxq72mrneJ/ANhHY7Jcd+xJbzuI5PA==", "dependencies": { - "NLog": "6.0.3" + "NLog": "6.0.4" } }, "PropertyChanged.Fody": { diff --git a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj index 77113584d..1ae0b1f58 100644 --- a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj +++ b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj @@ -74,7 +74,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Flow.Launcher.Plugin/packages.lock.json b/Flow.Launcher.Plugin/packages.lock.json index 10ca667ff..70f71f20d 100644 --- a/Flow.Launcher.Plugin/packages.lock.json +++ b/Flow.Launcher.Plugin/packages.lock.json @@ -26,9 +26,9 @@ }, "Microsoft.Windows.CsWin32": { "type": "Direct", - "requested": "[0.3.183, )", - "resolved": "0.3.183", - "contentHash": "Ze3aE2y7xgzKxEWtNb4SH0CExXpCHr3sbmwnvMiWMzJhWDX/G4Rs5wgg2UNs3VN+qVHh/DkDWLCPaVQv/b//Nw==", + "requested": "[0.3.205, )", + "resolved": "0.3.205", + "contentHash": "U5wGAnyKd7/I2YMd43nogm81VMtjiKzZ9dsLMVI4eAB7jtv5IEj0gprj0q/F3iRmAIaGv5omOf8iSYx2+nE6BQ==", "dependencies": { "Microsoft.Windows.SDK.Win32Docs": "0.1.42-alpha", "Microsoft.Windows.SDK.Win32Metadata": "61.0.15-preview", diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj index 6bc9c8cfe..a99d4d8c2 100644 --- a/Flow.Launcher/Flow.Launcher.csproj +++ b/Flow.Launcher/Flow.Launcher.csproj @@ -40,49 +40,11 @@ - + - + @@ -141,8 +103,8 @@ - - + + diff --git a/Flow.Launcher/packages.lock.json b/Flow.Launcher/packages.lock.json index 5d1117627..c90db6b0c 100644 --- a/Flow.Launcher/packages.lock.json +++ b/Flow.Launcher/packages.lock.json @@ -71,41 +71,41 @@ }, "Microsoft.Extensions.DependencyInjection": { "type": "Direct", - "requested": "[9.0.8, )", - "resolved": "9.0.8", - "contentHash": "JJjI2Fa+QtZcUyuNjbKn04OjIUX5IgFGFu/Xc+qvzh1rXdZHLcnqqVXhR4093bGirTwacRlHiVg1XYI9xum6QQ==", + "requested": "[9.0.9, )", + "resolved": "9.0.9", + "contentHash": "zQV2WOSP+3z1EuK91ULxfGgo2Y75bTRnmJHp08+w/YXAyekZutX/qCd88/HOMNh35MDW9mJJJxPpMPS+1Rww8A==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8" + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.9" } }, "Microsoft.Extensions.Hosting": { "type": "Direct", - "requested": "[9.0.8, )", - "resolved": "9.0.8", - "contentHash": "O2VlzORrBbS2it203k5FOHrudDdmdrJovA73P/shdRGeLzvet4e4yXhGx52V2PNjYBQ0IO5M4xiNcL+6xIX6Bg==", + "requested": "[9.0.9, )", + "resolved": "9.0.9", + "contentHash": "DmRsWH3g8yZGho/pLQ79hxhM2ctE1eDTZ/HbAnrD/uw8m+P2pRRJOoBVxlrhbhMP3/y3oAJoy0yITasfmilbTg==", "dependencies": { - "Microsoft.Extensions.Configuration": "9.0.8", - "Microsoft.Extensions.Configuration.Abstractions": "9.0.8", - "Microsoft.Extensions.Configuration.Binder": "9.0.8", - "Microsoft.Extensions.Configuration.CommandLine": "9.0.8", - "Microsoft.Extensions.Configuration.EnvironmentVariables": "9.0.8", - "Microsoft.Extensions.Configuration.FileExtensions": "9.0.8", - "Microsoft.Extensions.Configuration.Json": "9.0.8", - "Microsoft.Extensions.Configuration.UserSecrets": "9.0.8", - "Microsoft.Extensions.DependencyInjection": "9.0.8", - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", - "Microsoft.Extensions.Diagnostics": "9.0.8", - "Microsoft.Extensions.FileProviders.Abstractions": "9.0.8", - "Microsoft.Extensions.FileProviders.Physical": "9.0.8", - "Microsoft.Extensions.Hosting.Abstractions": "9.0.8", - "Microsoft.Extensions.Logging": "9.0.8", - "Microsoft.Extensions.Logging.Abstractions": "9.0.8", - "Microsoft.Extensions.Logging.Configuration": "9.0.8", - "Microsoft.Extensions.Logging.Console": "9.0.8", - "Microsoft.Extensions.Logging.Debug": "9.0.8", - "Microsoft.Extensions.Logging.EventLog": "9.0.8", - "Microsoft.Extensions.Logging.EventSource": "9.0.8", - "Microsoft.Extensions.Options": "9.0.8" + "Microsoft.Extensions.Configuration": "9.0.9", + "Microsoft.Extensions.Configuration.Abstractions": "9.0.9", + "Microsoft.Extensions.Configuration.Binder": "9.0.9", + "Microsoft.Extensions.Configuration.CommandLine": "9.0.9", + "Microsoft.Extensions.Configuration.EnvironmentVariables": "9.0.9", + "Microsoft.Extensions.Configuration.FileExtensions": "9.0.9", + "Microsoft.Extensions.Configuration.Json": "9.0.9", + "Microsoft.Extensions.Configuration.UserSecrets": "9.0.9", + "Microsoft.Extensions.DependencyInjection": "9.0.9", + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.9", + "Microsoft.Extensions.Diagnostics": "9.0.9", + "Microsoft.Extensions.FileProviders.Abstractions": "9.0.9", + "Microsoft.Extensions.FileProviders.Physical": "9.0.9", + "Microsoft.Extensions.Hosting.Abstractions": "9.0.9", + "Microsoft.Extensions.Logging": "9.0.9", + "Microsoft.Extensions.Logging.Abstractions": "9.0.9", + "Microsoft.Extensions.Logging.Configuration": "9.0.9", + "Microsoft.Extensions.Logging.Console": "9.0.9", + "Microsoft.Extensions.Logging.Debug": "9.0.9", + "Microsoft.Extensions.Logging.EventLog": "9.0.9", + "Microsoft.Extensions.Logging.EventSource": "9.0.9", + "Microsoft.Extensions.Options": "9.0.9" } }, "Microsoft.Toolkit.Uwp.Notifications": { @@ -254,244 +254,244 @@ }, "Microsoft.Extensions.Configuration": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "6m+8Xgmf8UWL0p/oGqBM+0KbHE5/ePXbV1hKXgC59zEv0aa0DW5oiiyxDbK5kH5j4gIvyD5uWL0+HadKBJngvQ==", + "resolved": "9.0.9", + "contentHash": "w87wF/90/VI0ZQBhf4rbMEeyEy0vi2WKjFmACsNAKNaorY+ZlVz7ddyXkbADvaWouMKffNmR0yQOGcrvSSvKGg==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "9.0.8", - "Microsoft.Extensions.Primitives": "9.0.8" + "Microsoft.Extensions.Configuration.Abstractions": "9.0.9", + "Microsoft.Extensions.Primitives": "9.0.9" } }, "Microsoft.Extensions.Configuration.Abstractions": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "yNou2KM35RvzOh4vUFtl2l33rWPvOCoba+nzEDJ+BgD8aOL/jew4WPCibQvntRfOJ2pJU8ARygSMD+pdjvDHuA==", + "resolved": "9.0.9", + "contentHash": "p5RKAY9POvs3axwA/AQRuJeM8AHuE8h4qbP1NxQeGm0ep46aXz1oCLAp/oOYxX1GsjStgdhHrN3XXLLXr0+b3w==", "dependencies": { - "Microsoft.Extensions.Primitives": "9.0.8" + "Microsoft.Extensions.Primitives": "9.0.9" } }, "Microsoft.Extensions.Configuration.Binder": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "0vK9DnYrYChdiH3yRZWkkp4x4LbrfkWEdBc5HOsQ8t/0CLOWKXKkkhOE8A1shlex0hGydbGrhObeypxz/QTm+w==", + "resolved": "9.0.9", + "contentHash": "6SIp/6Bngk4jm2W36JekZbiIbFPdE/eMUtrJEqIqHGpd1zar3jvgnwxnpWQfzUiGrkyY8q8s6V82zkkEZozghA==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "9.0.8" + "Microsoft.Extensions.Configuration.Abstractions": "9.0.9" } }, "Microsoft.Extensions.Configuration.CommandLine": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "vB6eDQ5prED5jHBqmSDNYzlCXsTSylYY7co9c7guhnz0zhx+jZ8BTHgO7y/Wl1dV2jAO15mKNWuyHRIRtWwGQg==", + "resolved": "9.0.9", + "contentHash": "9bzGOcHoTi8ijrj0MHh5qUY6n9CuittZUqEOj5iE0ZJoSCfG0BI9nhcpd8MC9bOOgjZW5OeizKO8rgta9lSVyA==", "dependencies": { - "Microsoft.Extensions.Configuration": "9.0.8", - "Microsoft.Extensions.Configuration.Abstractions": "9.0.8" + "Microsoft.Extensions.Configuration": "9.0.9", + "Microsoft.Extensions.Configuration.Abstractions": "9.0.9" } }, "Microsoft.Extensions.Configuration.EnvironmentVariables": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "9qileEYXDodlPN9DfPd5sHSfU2nSrI1r5BHVqLaLyb/7mPi335cy4ar/0ix4tXb2Aer/Pu4e5/zdwxt7lrtSyQ==", + "resolved": "9.0.9", + "contentHash": "AB8suTh4STAMGDkPer5vL0YNp09eplvbkIbOfFJ1z8D1zOiFF8Hipk9FhCLU4Ea6TosWmGrK30ZIUO9KvAeFcg==", "dependencies": { - "Microsoft.Extensions.Configuration": "9.0.8", - "Microsoft.Extensions.Configuration.Abstractions": "9.0.8" + "Microsoft.Extensions.Configuration": "9.0.9", + "Microsoft.Extensions.Configuration.Abstractions": "9.0.9" } }, "Microsoft.Extensions.Configuration.FileExtensions": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "2jgx58Jpk3oKT7KRn8x/cFf3QDTjQP+KUbyBnynAcB2iBx1Eq9EdNMCu0QEbYuaZOaQru/Kwdffary+hn58Wwg==", + "resolved": "9.0.9", + "contentHash": "fvgubCs++wTowHWuQ5TAyZV0S6ldA59U+tBVqFr4/WLd0oEf6ESbdBN2CFaVdn4sZqnarqMnl2O3++RG/Jrf/w==", "dependencies": { - "Microsoft.Extensions.Configuration": "9.0.8", - "Microsoft.Extensions.Configuration.Abstractions": "9.0.8", - "Microsoft.Extensions.FileProviders.Abstractions": "9.0.8", - "Microsoft.Extensions.FileProviders.Physical": "9.0.8", - "Microsoft.Extensions.Primitives": "9.0.8" + "Microsoft.Extensions.Configuration": "9.0.9", + "Microsoft.Extensions.Configuration.Abstractions": "9.0.9", + "Microsoft.Extensions.FileProviders.Abstractions": "9.0.9", + "Microsoft.Extensions.FileProviders.Physical": "9.0.9", + "Microsoft.Extensions.Primitives": "9.0.9" } }, "Microsoft.Extensions.Configuration.Json": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "vjxzcnL7ul322+kpvELisXaZl8/5MYs6JfI9DZLQWsao1nA/4FL48yPwDK986hbJTWc64JxOOaMym0SQ/dy32w==", + "resolved": "9.0.9", + "contentHash": "PiPYo1GTinR2ECM80zYdZUIFmde6jj5DryXUcOJg3yIjh+KQMQr42e+COD03QUsUiqNkJk511wVTnVpTm2AVZA==", "dependencies": { - "Microsoft.Extensions.Configuration": "9.0.8", - "Microsoft.Extensions.Configuration.Abstractions": "9.0.8", - "Microsoft.Extensions.Configuration.FileExtensions": "9.0.8", - "Microsoft.Extensions.FileProviders.Abstractions": "9.0.8" + "Microsoft.Extensions.Configuration": "9.0.9", + "Microsoft.Extensions.Configuration.Abstractions": "9.0.9", + "Microsoft.Extensions.Configuration.FileExtensions": "9.0.9", + "Microsoft.Extensions.FileProviders.Abstractions": "9.0.9" } }, "Microsoft.Extensions.Configuration.UserSecrets": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "UgH18nQkuMJgxjn1539I83N6LhnKQlLhQm3ppe+PGsFpYsC6eGpF/1KvDRm/bmqsrg0NXhurrv4k2r0e8vWX/Q==", + "resolved": "9.0.9", + "contentHash": "bFaNxfU8gQJX3K/Dd6XT0YIJ5ZVihdAY6Z02p2nVTUHjUsaWflLIucZOgB/ecSNnN3zbbBEf1oFC7q5NHTZIHw==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "9.0.8", - "Microsoft.Extensions.Configuration.Json": "9.0.8", - "Microsoft.Extensions.FileProviders.Abstractions": "9.0.8", - "Microsoft.Extensions.FileProviders.Physical": "9.0.8" + "Microsoft.Extensions.Configuration.Abstractions": "9.0.9", + "Microsoft.Extensions.Configuration.Json": "9.0.9", + "Microsoft.Extensions.FileProviders.Abstractions": "9.0.9", + "Microsoft.Extensions.FileProviders.Physical": "9.0.9" } }, "Microsoft.Extensions.DependencyInjection.Abstractions": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "xY3lTjj4+ZYmiKIkyWitddrp1uL5uYiweQjqo4BKBw01ZC4HhcfgLghDpPZcUlppgWAFqFy9SgkiYWOMx365pw==" + "resolved": "9.0.9", + "contentHash": "/hymojfWbE9AlDOa0mczR44m00Jj+T3+HZO0ZnVTI032fVycI0ZbNOVFP6kqZMcXiLSYXzR2ilcwaRi6dzeGyA==" }, "Microsoft.Extensions.Diagnostics": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "BKkLCFXzJvNmdngeYBf72VXoZqTJSb1orvjdzDLaGobicoGFBPW8ug2ru1nnEewMEwJzMgnsjHQY8EaKWmVhKg==", + "resolved": "9.0.9", + "contentHash": "gtzl9SD6CvFYOb92qEF41Z9rICzYniM342TWbbJwN3eLS6a5fCLFvO1pQGtpMSnP3h1zHXupMEeKSA9musWYCQ==", "dependencies": { - "Microsoft.Extensions.Configuration": "9.0.8", - "Microsoft.Extensions.Diagnostics.Abstractions": "9.0.8", - "Microsoft.Extensions.Options.ConfigurationExtensions": "9.0.8" + "Microsoft.Extensions.Configuration": "9.0.9", + "Microsoft.Extensions.Diagnostics.Abstractions": "9.0.9", + "Microsoft.Extensions.Options.ConfigurationExtensions": "9.0.9" } }, "Microsoft.Extensions.Diagnostics.Abstractions": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "UDY7blv4DCyIJ/8CkNrQKLaAZFypXQavRZ2DWf/2zi1mxYYKKw2t8AOCBWxNntyPZHPGhtEmL3snFM98ADZqTw==", + "resolved": "9.0.9", + "contentHash": "YHGmxccrVZ2Ar3eI+/NdbOHkd1/HzrHvmQ5yBsp0Gl7jTyBe6qcXNYjUt9v9JIO+Z14la44+YYEe63JSqs1fYg==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", - "Microsoft.Extensions.Options": "9.0.8" + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.9", + "Microsoft.Extensions.Options": "9.0.9" } }, "Microsoft.Extensions.FileProviders.Abstractions": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "4zZbQ4w+hCMm9J+z5NOj3giIPT2MhZxx05HX/MGuAmDBbjOuXlYIIRN+t4V6OLxy5nXZIcXO+dQMB/OWubuDkw==", + "resolved": "9.0.9", + "contentHash": "M1ZhL9QkBQ/k6l/Wjgcli5zrV86HzytQ+gQiNtk9vs9Ge1fb17KKZil9T6jd15p2x/BGfXpup7Hg55CC0kkfig==", "dependencies": { - "Microsoft.Extensions.Primitives": "9.0.8" + "Microsoft.Extensions.Primitives": "9.0.9" } }, "Microsoft.Extensions.FileProviders.Physical": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "FlOe2i7UUIfY0l0ChaIYtlXjdWWutR4DMRKZaGD6z4G1uVTteFkbBfxUIoi1uGmrZQxXe/yv/cfwiT0tK2xyXA==", + "resolved": "9.0.9", + "contentHash": "sRrPtEwbK23OCFOQ36Xn6ofiB0/nl54/BOdR7lJ/Vwg3XlyvUdmyXvFUS1EU5ltn+sQtbcPuy1l0hsysO8++SQ==", "dependencies": { - "Microsoft.Extensions.FileProviders.Abstractions": "9.0.8", - "Microsoft.Extensions.FileSystemGlobbing": "9.0.8", - "Microsoft.Extensions.Primitives": "9.0.8" + "Microsoft.Extensions.FileProviders.Abstractions": "9.0.9", + "Microsoft.Extensions.FileSystemGlobbing": "9.0.9", + "Microsoft.Extensions.Primitives": "9.0.9" } }, "Microsoft.Extensions.FileSystemGlobbing": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "96Ub5LmwYfIGVoXkbe4kjs+ivK6fLBTwKJAOMfUNV0R+AkZRItlgROFqXEWMUlXBTPM1/kKu26Ueu5As6RDzJA==" + "resolved": "9.0.9", + "contentHash": "iQAgORaVIlkhcpxFnVEfjqNWfQCwBEEH7x2IanTwGafA6Tb4xiBoDWySTxUo3MV2NUV/PmwS/8OhT/elPnJCnw==" }, "Microsoft.Extensions.Hosting.Abstractions": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "WNrad20tySNCPe9aJUK7Wfwh+RiyLF+id02FKW8Qfc+HAzNQHazcqMXAbwG/kmbS89uvan/nKK1MufkRahjrJA==", + "resolved": "9.0.9", + "contentHash": "ORA4dICNz7cuwupPkjXpSuoiK6GMg0aygInBIQCCFEimwoHntRKdJqB59faxq2HHJuTPW3NsZm5EjN5P5Zh6nQ==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "9.0.8", - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", - "Microsoft.Extensions.Diagnostics.Abstractions": "9.0.8", - "Microsoft.Extensions.FileProviders.Abstractions": "9.0.8", - "Microsoft.Extensions.Logging.Abstractions": "9.0.8" + "Microsoft.Extensions.Configuration.Abstractions": "9.0.9", + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.9", + "Microsoft.Extensions.Diagnostics.Abstractions": "9.0.9", + "Microsoft.Extensions.FileProviders.Abstractions": "9.0.9", + "Microsoft.Extensions.Logging.Abstractions": "9.0.9" } }, "Microsoft.Extensions.Logging": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "Z/7ze+0iheT7FJeZPqJKARYvyC2bmwu3whbm/48BJjdlGVvgDguoCqJIkI/67NkroTYobd5geai1WheNQvWrgA==", + "resolved": "9.0.9", + "contentHash": "MaCB0Y9hNDs4YLu3HCJbo199WnJT8xSgajG1JYGANz9FkseQ5f3v/llu3HxLI6mjDlu7pa7ps9BLPWjKzsAAzQ==", "dependencies": { - "Microsoft.Extensions.DependencyInjection": "9.0.8", - "Microsoft.Extensions.Logging.Abstractions": "9.0.8", - "Microsoft.Extensions.Options": "9.0.8" + "Microsoft.Extensions.DependencyInjection": "9.0.9", + "Microsoft.Extensions.Logging.Abstractions": "9.0.9", + "Microsoft.Extensions.Options": "9.0.9" } }, "Microsoft.Extensions.Logging.Abstractions": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "pYnAffJL7ARD/HCnnPvnFKSIHnTSmWz84WIlT9tPeQ4lHNiu0Az7N/8itihWvcF8sT+VVD5lq8V+ckMzu4SbOw==", + "resolved": "9.0.9", + "contentHash": "FEgpSF+Z9StMvrsSViaybOBwR0f0ZZxDm8xV5cSOFiXN/t+ys+rwAlTd/6yG7Ld1gfppgvLcMasZry3GsI9lGA==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8" + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.9" } }, "Microsoft.Extensions.Logging.Configuration": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "Us4evDN3lbp1beVgrpxkSXKrbntVGAK+YbSo9P9driiU9PK05+ShhgesJ3aj7SuDfr3mqqcEgrMJ87Vu8t5dhw==", + "resolved": "9.0.9", + "contentHash": "Abuo+S0Sg+Ke6vzSh5Ell+lwJJM+CEIqg1ImtWnnqF6a/ibJkQnmFJi4/ekEw/0uAcdFKJXtGV7w6cFN0nyXeg==", "dependencies": { - "Microsoft.Extensions.Configuration": "9.0.8", - "Microsoft.Extensions.Configuration.Abstractions": "9.0.8", - "Microsoft.Extensions.Configuration.Binder": "9.0.8", - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", - "Microsoft.Extensions.Logging": "9.0.8", - "Microsoft.Extensions.Logging.Abstractions": "9.0.8", - "Microsoft.Extensions.Options": "9.0.8", - "Microsoft.Extensions.Options.ConfigurationExtensions": "9.0.8" + "Microsoft.Extensions.Configuration": "9.0.9", + "Microsoft.Extensions.Configuration.Abstractions": "9.0.9", + "Microsoft.Extensions.Configuration.Binder": "9.0.9", + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.9", + "Microsoft.Extensions.Logging": "9.0.9", + "Microsoft.Extensions.Logging.Abstractions": "9.0.9", + "Microsoft.Extensions.Options": "9.0.9", + "Microsoft.Extensions.Options.ConfigurationExtensions": "9.0.9" } }, "Microsoft.Extensions.Logging.Console": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "mPp9xB9MjiPuodh9z/+6zEGNj2kSVeXQtdbIBHlhUYqxX22gzJkx0ycPY42q4/OT/SzFV/TJ989Pa3sA/8ZBeA==", + "resolved": "9.0.9", + "contentHash": "x3+W7IfW9Tg3sV+sU9N1039M4CqklaAecwhz9qNtjOCBdmg7h96JaL+NAvhYgZgweVJTJaxAvuO8I+ZZehE7Pg==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", - "Microsoft.Extensions.Logging": "9.0.8", - "Microsoft.Extensions.Logging.Abstractions": "9.0.8", - "Microsoft.Extensions.Logging.Configuration": "9.0.8", - "Microsoft.Extensions.Options": "9.0.8" + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.9", + "Microsoft.Extensions.Logging": "9.0.9", + "Microsoft.Extensions.Logging.Abstractions": "9.0.9", + "Microsoft.Extensions.Logging.Configuration": "9.0.9", + "Microsoft.Extensions.Options": "9.0.9" } }, "Microsoft.Extensions.Logging.Debug": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "OwHQFVITsONEoizShc1yNYTUvMq0kT9j/LhwAKMsA7OZqtrBXuqjosbSvzkJZ9o+KWAozDh5Y1Vtpe5p/8/1qA==", + "resolved": "9.0.9", + "contentHash": "q8IbjIzTjfaGfuf9LAuG3X9BytAWj2hWhLU61rEkit847oaSSbcdx/yybY3yL9RgVG1u9ctk7kbCv18M+7Fi6Q==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", - "Microsoft.Extensions.Logging": "9.0.8", - "Microsoft.Extensions.Logging.Abstractions": "9.0.8" + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.9", + "Microsoft.Extensions.Logging": "9.0.9", + "Microsoft.Extensions.Logging.Abstractions": "9.0.9" } }, "Microsoft.Extensions.Logging.EventLog": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "/gMwlll21UJcaXlitUqd+rs9jH36EJz5BpFVPshyOqz5u0qyV1pFnTWm5vhyx+g6gwVYENSLgpazR1urNv83xw==", + "resolved": "9.0.9", + "contentHash": "1SX5+mv16SBb5NrtLNxIvUt8PHbdvDloZazQdxz1CNM39jG7yeF6olH3sceQ4ONF0oVD5mVUsTag0iVX4xgyog==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", - "Microsoft.Extensions.Logging": "9.0.8", - "Microsoft.Extensions.Logging.Abstractions": "9.0.8", - "Microsoft.Extensions.Options": "9.0.8", - "System.Diagnostics.EventLog": "9.0.8" + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.9", + "Microsoft.Extensions.Logging": "9.0.9", + "Microsoft.Extensions.Logging.Abstractions": "9.0.9", + "Microsoft.Extensions.Options": "9.0.9", + "System.Diagnostics.EventLog": "9.0.9" } }, "Microsoft.Extensions.Logging.EventSource": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "aGMFc/1P+315d07iyxSe6lEoZ0JjOPJ+Mfv9rrV2PvR2DFu1/pSi/SItHw1iChJOZgslNKJE97g1a9nLX3qQYA==", + "resolved": "9.0.9", + "contentHash": "rGQi5mImot7tTFxj1tQWknWjOBHX1+gsX1WLmQNl5WHr4Sx1kXUBGDuRUjfx4c8pe/hcYHdalAmgk7RdusW6Jw==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", - "Microsoft.Extensions.Logging": "9.0.8", - "Microsoft.Extensions.Logging.Abstractions": "9.0.8", - "Microsoft.Extensions.Options": "9.0.8", - "Microsoft.Extensions.Primitives": "9.0.8" + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.9", + "Microsoft.Extensions.Logging": "9.0.9", + "Microsoft.Extensions.Logging.Abstractions": "9.0.9", + "Microsoft.Extensions.Options": "9.0.9", + "Microsoft.Extensions.Primitives": "9.0.9" } }, "Microsoft.Extensions.Options": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "OmTaQ0v4gxGQkehpwWIqPoEiwsPuG/u4HUsbOFoWGx4DKET2AXzopnFe/fE608FIhzc/kcg2p8JdyMRCCUzitQ==", + "resolved": "9.0.9", + "contentHash": "loxGGHE1FC2AefwPHzrjPq7X92LQm64qnU/whKfo6oWaceewPUVYQJBJs3S3E2qlWwnCpeZ+dGCPTX+5dgVAuQ==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", - "Microsoft.Extensions.Primitives": "9.0.8" + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.9", + "Microsoft.Extensions.Primitives": "9.0.9" } }, "Microsoft.Extensions.Options.ConfigurationExtensions": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "eW2s6n06x0w6w4nsX+SvpgsFYkl+Y0CttYAt6DKUXeqprX+hzNqjSfOh637fwNJBg7wRBrOIRHe49gKiTgJxzQ==", + "resolved": "9.0.9", + "contentHash": "n4DCdnn2qs6V5U06Sx62FySEAZsJiJJgOzrPHDh9hPK7c2W8hEabC76F3Re3tGPjpiKa02RvB6FxZyxo8iICzg==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "9.0.8", - "Microsoft.Extensions.Configuration.Binder": "9.0.8", - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", - "Microsoft.Extensions.Options": "9.0.8", - "Microsoft.Extensions.Primitives": "9.0.8" + "Microsoft.Extensions.Configuration.Abstractions": "9.0.9", + "Microsoft.Extensions.Configuration.Binder": "9.0.9", + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.9", + "Microsoft.Extensions.Options": "9.0.9", + "Microsoft.Extensions.Primitives": "9.0.9" } }, "Microsoft.Extensions.Primitives": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "tizSIOEsIgSNSSh+hKeUVPK7xmTIjR8s+mJWOu1KXV3htvNQiPMFRMO17OdI1y/4ZApdBVk49u/08QGC9yvLug==" + "resolved": "9.0.9", + "contentHash": "z4pyMePOrl733ltTowbN565PxBw1oAr8IHmIXNDiDqd22nFpYltX9KhrNC/qBWAG1/Zx5MHX+cOYhWJQYCO/iw==" }, "Microsoft.IO.RecyclableMemoryStream": { "type": "Transitive", @@ -590,15 +590,15 @@ }, "NLog": { "type": "Transitive", - "resolved": "6.0.3", - "contentHash": "5RMrpvadysflvDOi5ozD7aK1P+YL2DyZbQSxzE8qBKkw2pxPNOQA6vJtumcT6SuzE9qxhwGkQwMkLLaKnALwiw==" + "resolved": "6.0.4", + "contentHash": "Xr+lIk1ZlTTFXEqnxQVLxrDqZlt2tm5X+/AhJbaY2emb/dVtGDiU5QuEtj3gHtwV/SWlP/rJ922I/BPuOJXlRw==" }, "NLog.OutputDebugString": { "type": "Transitive", - "resolved": "6.0.3", - "contentHash": "0qojvaBMAruTDIbjRXMwft3hdkg8tPl0BMD8+tR8TpK78a8DrgKAq/h5LcHPQ/0xERZ66y+00bsn0n1VeJjlmg==", + "resolved": "6.0.4", + "contentHash": "TOP2Ap9BbE98B/l/TglnguowOD0rXo8B/20xAgvj9shO/kf6IJ5M4QMhVxq72mrneJ/ANhHY7Jcd+xJbzuI5PA==", "dependencies": { - "NLog": "6.0.3" + "NLog": "6.0.4" } }, "runtime.osx.10.10-x64.CoreCompat.System.Drawing": { @@ -672,8 +672,8 @@ }, "System.Diagnostics.EventLog": { "type": "Transitive", - "resolved": "9.0.8", - "contentHash": "gebRF3JLLJ76jz1CQpvwezNapZUjFq20JQsaGHzBH0DzlkHBLpdhwkOei9usiOkIGMwU/L0ALWpNe1JE+5/itw==" + "resolved": "9.0.9", + "contentHash": "wpsUfnyv8E5K4WQaok6weewvAbQhcLwXFcHBm5U0gdEaBs85N//ssuYvRPFWwz2rO/9/DFP3A1sGMzUFBj8y3w==" }, "System.Drawing.Common": { "type": "Transitive", @@ -840,7 +840,7 @@ "Droplex": "[1.7.0, )", "FSharp.Core": "[9.0.303, )", "Flow.Launcher.Infrastructure": "[1.0.0, )", - "Flow.Launcher.Plugin": "[4.7.0, )", + "Flow.Launcher.Plugin": "[5.0.0, )", "Meziantou.Framework.Win32.Jobs": "[3.4.4, )", "Microsoft.IO.RecyclableMemoryStream": "[3.0.1, )", "SemanticVersioning": "[3.0.0, )", @@ -854,13 +854,13 @@ "Ben.Demystifier": "[0.4.1, )", "BitFaster.Caching": "[2.5.4, )", "CommunityToolkit.Mvvm": "[8.4.0, )", - "Flow.Launcher.Plugin": "[4.7.0, )", + "Flow.Launcher.Plugin": "[5.0.0, )", "InputSimulator": "[1.0.4, )", "MemoryPack": "[1.21.4, )", "Microsoft.VisualStudio.Threading": "[17.14.15, )", "NHotkey.Wpf": "[3.0.0, )", - "NLog": "[6.0.3, )", - "NLog.OutputDebugString": "[6.0.3, )", + "NLog": "[6.0.4, )", + "NLog.OutputDebugString": "[6.0.4, )", "SharpVectors.Wpf": "[1.8.5, )", "System.Drawing.Common": "[7.0.0, )", "ToolGood.Words.Pinyin": "[3.1.0.3, )" diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj index da1dd55b9..b7c54e578 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj @@ -49,7 +49,7 @@ - + diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Flow.Launcher.Plugin.ProcessKiller.csproj b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Flow.Launcher.Plugin.ProcessKiller.csproj index 2da97ebbd..0a7a02a45 100644 --- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Flow.Launcher.Plugin.ProcessKiller.csproj +++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Flow.Launcher.Plugin.ProcessKiller.csproj @@ -52,7 +52,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj b/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj index c33a26300..e9515fab4 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj +++ b/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj @@ -64,12 +64,12 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + \ No newline at end of file diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj b/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj index 8e54e1894..44fc9a8cf 100644 --- a/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj +++ b/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj @@ -58,7 +58,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 110f571b40840e798237c304216b2435d9845796 Mon Sep 17 00:00:00 2001 From: dcog989 Date: Sat, 13 Sep 2025 13:17:08 +0100 Subject: [PATCH 15/75] Rework solution for nested Mages Previous solution missed e.g. `pow(min(2,3), 4)` --- .../Flow.Launcher.Plugin.Calculator/Main.cs | 89 +++++++++++++++---- 1 file changed, 72 insertions(+), 17 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs index c81eb9b1c..99f0f8395 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs @@ -16,6 +16,8 @@ namespace Flow.Launcher.Plugin.Calculator private static readonly Regex RegBrackets = MainRegexHelper.GetRegBrackets(); private static readonly Regex ThousandGroupRegex = MainRegexHelper.GetThousandGroupRegex(); private static readonly Regex NumberRegex = MainRegexHelper.GetNumberRegex(); + private static readonly Regex PowRegex = new(@"\bpow(\((?:[^()\[\]]|\((?)|\)(?<-Depth>)|\[(?)|\](?<-Depth>))*(?(Depth)(?!))\))", RegexOptions.Compiled | RegexOptions.RightToLeft); + private static Engine MagesEngine; private const string Comma = ","; @@ -43,11 +45,23 @@ namespace Flow.Launcher.Plugin.Calculator public List Query(Query query) { - if (!CanCalculate(query)) + if (string.IsNullOrWhiteSpace(query.Search)) { return new List(); } + if (!IsBracketComplete(query.Search)) + { + return new List + { + new Result + { + Title = Localize.flowlauncher_plugin_calculator_expression_not_complete(), + IcoPath = "Images/calculator.png" + } + }; + } + try { var expression = NumberRegex.Replace(query.Search, m => NormalizeNumber(m.Value)); @@ -60,7 +74,7 @@ namespace Flow.Launcher.Plugin.Calculator do { previous = expression; - expression = Regex.Replace(previous, @"\bpow\s*\(\s*([^,]+?)\s*,\s*([^)]+?)\s*\)", "($1^$2)"); + expression = PowRegex.Replace(previous, PowMatchEvaluator); } while (previous != expression); // WORKAROUND END @@ -131,6 +145,57 @@ namespace Flow.Launcher.Plugin.Calculator return new List(); } + private static string PowMatchEvaluator(Match m) + { + // m.Groups[1].Value will be `(...)` with parens + var contentWithParen = m.Groups[1].Value; + // remove outer parens. `(min(2,3), 4)` becomes `min(2,3), 4` + var argsContent = contentWithParen.Substring(1, contentWithParen.Length - 2); + + var bracketCount = 0; + var splitIndex = -1; + + // Find the top-level comma that separates the two arguments of pow. + for (var i = 0; i < argsContent.Length; i++) + { + switch (argsContent[i]) + { + case '(': + case '[': + bracketCount++; + break; + case ')': + case ']': + bracketCount--; + break; + case ',' when bracketCount == 0: + splitIndex = i; + break; + } + + if (splitIndex != -1) + break; + } + + if (splitIndex == -1) + { + // This indicates malformed arguments for pow, e.g., pow(5) or pow(). + // Return original string to let Mages handle the error. + return m.Value; + } + + var arg1 = argsContent.Substring(0, splitIndex).Trim(); + var arg2 = argsContent.Substring(splitIndex + 1).Trim(); + + // Check for empty arguments which can happen with stray commas, e.g., pow(,5) + if (string.IsNullOrEmpty(arg1) || string.IsNullOrEmpty(arg2)) + { + return m.Value; + } + + return $"({arg1}^{arg2})"; + } + /// /// Parses a string representation of a number using the system's current culture. /// @@ -208,21 +273,6 @@ namespace Flow.Launcher.Plugin.Calculator return decimalSeparator == Dot ? Comma : Dot; } - private bool CanCalculate(Query query) - { - if (string.IsNullOrWhiteSpace(query.Search)) - { - return false; - } - - if (!IsBracketComplete(query.Search)) - { - return false; - } - - return true; - } - private string GetDecimalSeparator() { string systemDecimalSeparator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator; @@ -249,6 +299,11 @@ namespace Flow.Launcher.Plugin.Calculator { leftBracketCount--; } + + if (leftBracketCount < 0) + { + return false; + } } return leftBracketCount == 0; From e63c4f3b6efac32c2eb2c12b2b19af776f91d7b5 Mon Sep 17 00:00:00 2001 From: dcog989 Date: Sat, 13 Sep 2025 16:30:13 +0100 Subject: [PATCH 16/75] Catch scary exception, print friendly log Rather than showing the user `EXCEPTION OCCURS: System.Threading.Tasks.TaskCanceledException...`, print not scary log msg --- Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs b/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs index 6f3b23e11..4ec6f142b 100644 --- a/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs +++ b/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs @@ -73,6 +73,11 @@ namespace Flow.Launcher.Core.ExternalPlugins return null; } } + catch (OperationCanceledException) + { + API.LogInfo(ClassName, $"Fetching from {ManifestFileUrl} was cancelled. That is most likely OK."); + return null; + } catch (Exception e) { if (e is HttpRequestException or WebException or SocketException || e.InnerException is TimeoutException) From f3998a190c2cb985c4e5ef92052ae29603197cca Mon Sep 17 00:00:00 2001 From: dcog989 Date: Sat, 13 Sep 2025 17:04:32 +0100 Subject: [PATCH 17/75] explicit exception logging --- .../ExternalPlugins/CommunityPluginSource.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs b/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs index 4ec6f142b..2ff51ff73 100644 --- a/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs +++ b/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs @@ -73,9 +73,15 @@ namespace Flow.Launcher.Core.ExternalPlugins return null; } } - catch (OperationCanceledException) + catch (OperationCanceledException) when (token.IsCancellationRequested) { - API.LogInfo(ClassName, $"Fetching from {ManifestFileUrl} was cancelled. That is most likely OK."); + API.LogInfo(ClassName, $"Fetching from {ManifestFileUrl} was cancelled by caller."); + return null; + } + catch (TaskCanceledException) + { + // Likely an HttpClient timeout or external cancellation not requested by our token + API.LogWarn(ClassName, $"Fetching from {ManifestFileUrl} timed out."); return null; } catch (Exception e) From d4a757be49dc3b69f25306d2cae9f850f0a03010 Mon Sep 17 00:00:00 2001 From: dcog989 Date: Sat, 13 Sep 2025 19:57:54 +0100 Subject: [PATCH 18/75] Enhanced logging User can now choose None, Error, Info, or Debug. --- Flow.Launcher.Infrastructure/Logger/Log.cs | 42 +++++++++---------- .../UserSettings/Settings.cs | 2 +- Flow.Launcher/Languages/en.xaml | 8 ++-- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Logger/Log.cs b/Flow.Launcher.Infrastructure/Logger/Log.cs index 09eb98f46..409e4cf6e 100644 --- a/Flow.Launcher.Infrastructure/Logger/Log.cs +++ b/Flow.Launcher.Infrastructure/Logger/Log.cs @@ -16,7 +16,7 @@ namespace Flow.Launcher.Infrastructure.Logger public static string CurrentLogDirectory { get; } - static Log() +static Log() { CurrentLogDirectory = DataLocation.VersionLogDirectory; if (!Directory.Exists(CurrentLogDirectory)) @@ -34,7 +34,7 @@ namespace Flow.Launcher.Infrastructure.Logger var fileTarget = new FileTarget { - FileName = CurrentLogDirectory.Replace(@"\", "/") + "/${shortdate}.txt", + FileName = CurrentLogDirectory.Replace(@"\", "/") + "/Flow.Launcher.${date:format=yyyyMMdd}.log", Layout = layout }; @@ -45,6 +45,8 @@ namespace Flow.Launcher.Infrastructure.Logger Layout = layout }; + + configuration.AddTarget("file", fileTargetASyncWrapper); configuration.AddTarget("debug", debugTarget); @@ -65,26 +67,22 @@ namespace Flow.Launcher.Infrastructure.Logger public static void SetLogLevel(LOGLEVEL level) { - switch (level) + var rule = LogManager.Configuration.FindRuleByName("file"); + + var nlogLevel = level switch { - case LOGLEVEL.DEBUG: - UseDebugLogLevel(); - break; - default: - UseInfoLogLevel(); - break; - } - Info(nameof(Logger), $"Using log level: {level}."); - } + LOGLEVEL.None => LogLevel.Off, + LOGLEVEL.Error => LogLevel.Error, + LOGLEVEL.Debug => LogLevel.Debug, + _ => LogLevel.Info + }; - private static void UseDebugLogLevel() - { - LogManager.Configuration.FindRuleByName("file").SetLoggingLevels(LogLevel.Debug, LogLevel.Fatal); - } + rule.SetLoggingLevels(nlogLevel, LogLevel.Fatal); - private static void UseInfoLogLevel() - { - LogManager.Configuration.FindRuleByName("file").SetLoggingLevels(LogLevel.Info, LogLevel.Fatal); + LogManager.ReconfigExistingLoggers(); + + // We can't log Info when level is set to Error or None, so we use Debug + Debug(nameof(Logger), $"Using log level: {level}."); } private static void LogFaultyFormat(string message) @@ -169,7 +167,9 @@ namespace Flow.Launcher.Infrastructure.Logger public enum LOGLEVEL { - DEBUG, - INFO + None, + Error, + Info, + Debug } } diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index 0c3402050..8ac900cf6 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -340,7 +340,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings public DialogJumpFileResultBehaviours DialogJumpFileResultBehaviour { get; set; } = DialogJumpFileResultBehaviours.FullPath; [JsonConverter(typeof(JsonStringEnumConverter))] - public LOGLEVEL LogLevel { get; set; } = LOGLEVEL.INFO; + public LOGLEVEL LogLevel { get; set; } = LOGLEVEL.Info; /// /// when false Alphabet static service will always return empty results diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index d2f78e1f6..2d6810197 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -459,11 +459,13 @@ Wizard User Data Location User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not. - Open Folder +Open Folder Advanced Log Level - Debug - Info + None + Error + Info + Debug Setting Window Font From 2ae57ae34c996f2575ded75d3758f41c9105cbd2 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sun, 14 Sep 2025 12:20:00 +0800 Subject: [PATCH 19/75] Format & Improve string resources & Rename enums --- Flow.Launcher.Infrastructure/Logger/Log.cs | 18 ++++++++---------- .../UserSettings/Settings.cs | 4 ++-- Flow.Launcher/Languages/en.xaml | 10 +++++----- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Logger/Log.cs b/Flow.Launcher.Infrastructure/Logger/Log.cs index 409e4cf6e..b728ce988 100644 --- a/Flow.Launcher.Infrastructure/Logger/Log.cs +++ b/Flow.Launcher.Infrastructure/Logger/Log.cs @@ -16,7 +16,7 @@ namespace Flow.Launcher.Infrastructure.Logger public static string CurrentLogDirectory { get; } -static Log() + static Log() { CurrentLogDirectory = DataLocation.VersionLogDirectory; if (!Directory.Exists(CurrentLogDirectory)) @@ -45,8 +45,6 @@ static Log() Layout = layout }; - - configuration.AddTarget("file", fileTargetASyncWrapper); configuration.AddTarget("debug", debugTarget); @@ -71,9 +69,9 @@ static Log() var nlogLevel = level switch { - LOGLEVEL.None => LogLevel.Off, - LOGLEVEL.Error => LogLevel.Error, - LOGLEVEL.Debug => LogLevel.Debug, + LOGLEVEL.NONE => LogLevel.Off, + LOGLEVEL.ERROR => LogLevel.Error, + LOGLEVEL.DEBUG => LogLevel.Debug, _ => LogLevel.Info }; @@ -167,9 +165,9 @@ static Log() public enum LOGLEVEL { - None, - Error, - Info, - Debug + NONE, + ERROR, + INFO, + DEBUG } } diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index 8ac900cf6..23f9047fe 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Collections.ObjectModel; using System.Text.Json.Serialization; using System.Windows; @@ -340,7 +340,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings public DialogJumpFileResultBehaviours DialogJumpFileResultBehaviour { get; set; } = DialogJumpFileResultBehaviours.FullPath; [JsonConverter(typeof(JsonStringEnumConverter))] - public LOGLEVEL LogLevel { get; set; } = LOGLEVEL.Info; + public LOGLEVEL LogLevel { get; set; } = LOGLEVEL.INFO; /// /// when false Alphabet static service will always return empty results diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 2d6810197..f7fd0c8e5 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -459,13 +459,13 @@ Wizard User Data Location User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not. -Open Folder + Open Folder Advanced Log Level - None - Error - Info - Debug + Silent + Error + Info + Debug Setting Window Font From c2fcf648e064b7c92d47b4698c023090605ed3f6 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sun, 14 Sep 2025 12:25:54 +0800 Subject: [PATCH 20/75] Improve log file format --- Flow.Launcher.Infrastructure/Logger/Log.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Infrastructure/Logger/Log.cs b/Flow.Launcher.Infrastructure/Logger/Log.cs index b728ce988..2a5b826a9 100644 --- a/Flow.Launcher.Infrastructure/Logger/Log.cs +++ b/Flow.Launcher.Infrastructure/Logger/Log.cs @@ -34,7 +34,7 @@ namespace Flow.Launcher.Infrastructure.Logger var fileTarget = new FileTarget { - FileName = CurrentLogDirectory.Replace(@"\", "/") + "/Flow.Launcher.${date:format=yyyyMMdd}.log", + FileName = CurrentLogDirectory.Replace(@"\", "/") + "/Flow.Launcher.${date:format=yyyy-MM-dd}.log", Layout = layout }; From 11f5ea5074be16e3b712a05f4484b1c91e3bfa28 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sun, 14 Sep 2025 12:33:46 +0800 Subject: [PATCH 21/75] Improve code quality --- Plugins/Flow.Launcher.Plugin.Calculator/Main.cs | 6 ++---- Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs | 4 +++- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs index 99f0f8395..0fd32555f 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Globalization; -using System.Linq; using System.Runtime.InteropServices; using System.Text.RegularExpressions; using System.Windows.Controls; @@ -16,8 +15,7 @@ namespace Flow.Launcher.Plugin.Calculator private static readonly Regex RegBrackets = MainRegexHelper.GetRegBrackets(); private static readonly Regex ThousandGroupRegex = MainRegexHelper.GetThousandGroupRegex(); private static readonly Regex NumberRegex = MainRegexHelper.GetNumberRegex(); - private static readonly Regex PowRegex = new(@"\bpow(\((?:[^()\[\]]|\((?)|\)(?<-Depth>)|\[(?)|\](?<-Depth>))*(?(Depth)(?!))\))", RegexOptions.Compiled | RegexOptions.RightToLeft); - + private static readonly Regex PowRegex = MainRegexHelper.GetPowRegex(); private static Engine MagesEngine; private const string Comma = ","; @@ -200,7 +198,7 @@ namespace Flow.Launcher.Plugin.Calculator /// Parses a string representation of a number using the system's current culture. /// /// A normalized number string with '.' as the decimal separator for the Mages engine. - private string NormalizeNumber(string numberStr) + private static string NormalizeNumber(string numberStr) { var culture = CultureInfo.CurrentCulture; var groupSep = culture.NumberFormat.NumberGroupSeparator; diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs b/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs index 2e0353614..d8c2795dc 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs @@ -4,7 +4,6 @@ namespace Flow.Launcher.Plugin.Calculator; internal static partial class MainRegexHelper { - [GeneratedRegex(@"[\(\)\[\]]", RegexOptions.Compiled)] public static partial Regex GetRegBrackets(); @@ -13,4 +12,7 @@ internal static partial class MainRegexHelper [GeneratedRegex(@"\B(?=(\d{3})+(?!\d))", RegexOptions.Compiled)] public static partial Regex GetThousandGroupRegex(); + + [GeneratedRegex(@"\bpow(\((?:[^()\[\]]|\((?)|\)(?<-Depth>)|\[(?)|\](?<-Depth>))*(?(Depth)(?!))\))", RegexOptions.Compiled | RegexOptions.RightToLeft)] + public static partial Regex GetPowRegex(); } From 495ace124687f86fd9828439ddaab2436079972d Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sun, 14 Sep 2025 12:39:11 +0800 Subject: [PATCH 22/75] Improve plugin description --- Plugins/Flow.Launcher.Plugin.Calculator/Languages/en.xaml | 2 +- Plugins/Flow.Launcher.Plugin.Calculator/plugin.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Calculator/Languages/en.xaml index b71e5d8a0..29a0ed26f 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Languages/en.xaml +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Languages/en.xaml @@ -4,7 +4,7 @@ xmlns:system="clr-namespace:System;assembly=mscorlib"> Calculator - Perform mathematical calculations (including hexadecimal values). Use ',' or '.' as thousand separator or decimal place. + Perform mathematical calculations, including hex values and advanced functions such as 'min(1,2,3)', 'sqrt(123)' and 'cos(123)'. Not a number (NaN) Expression wrong or incomplete (Did you forget some parentheses?) Copy this number to the clipboard diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json b/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json index 7b4b53cdb..93df9ec72 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json +++ b/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json @@ -2,7 +2,7 @@ "ID": "CEA0FDFC6D3B4085823D60DC76F28855", "ActionKeyword": "*", "Name": "Calculator", - "Description": "Perform mathematical calculations, including hex values and advanced math functions, such as 'min(1,2,3)', 'sqrt(123)', 'cos(123)', etc.. User locale determines thousand separator and decimal place.", + "Description": "Perform mathematical calculations, including hex values and advanced functions such as 'min(1,2,3)', 'sqrt(123)' and 'cos(123)'.", "Author": "cxfksword, dcog989", "Version": "1.0.0", "Language": "csharp", From daf35a49725fab9107104238a81e72295ef7965f Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sun, 14 Sep 2025 15:54:35 +0800 Subject: [PATCH 23/75] Do not check bracket complete --- .../Flow.Launcher.Plugin.Calculator/Main.cs | 36 ------------------- 1 file changed, 36 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs index 0fd32555f..d19dbc9c2 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs @@ -48,18 +48,6 @@ namespace Flow.Launcher.Plugin.Calculator return new List(); } - if (!IsBracketComplete(query.Search)) - { - return new List - { - new Result - { - Title = Localize.flowlauncher_plugin_calculator_expression_not_complete(), - IcoPath = "Images/calculator.png" - } - }; - } - try { var expression = NumberRegex.Replace(query.Search, m => NormalizeNumber(m.Value)); @@ -283,30 +271,6 @@ namespace Flow.Launcher.Plugin.Calculator }; } - private static bool IsBracketComplete(string query) - { - var matchs = RegBrackets.Matches(query); - var leftBracketCount = 0; - foreach (Match match in matchs) - { - if (match.Value == "(" || match.Value == "[") - { - leftBracketCount++; - } - else - { - leftBracketCount--; - } - - if (leftBracketCount < 0) - { - return false; - } - } - - return leftBracketCount == 0; - } - public string GetTranslatedPluginTitle() { return Localize.flowlauncher_plugin_calculator_plugin_name(); From 336e51d1047f085b83fb5bb9b886b3b11b4dd0ed Mon Sep 17 00:00:00 2001 From: dcog989 Date: Sun, 14 Sep 2025 17:08:37 +0100 Subject: [PATCH 24/75] IcoPath to const string --- Plugins/Flow.Launcher.Plugin.Calculator/Main.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs index d19dbc9c2..54ac61ffb 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs @@ -20,6 +20,7 @@ namespace Flow.Launcher.Plugin.Calculator private static Engine MagesEngine; private const string Comma = ","; private const string Dot = "."; + private const string IcoPath = "Images/calculator.png"; internal static PluginInitContext Context { get; set; } = null!; @@ -73,7 +74,7 @@ namespace Flow.Launcher.Plugin.Calculator new Result { Title = Localize.flowlauncher_plugin_calculator_expression_not_complete(), - IcoPath = "Images/calculator.png" + IcoPath = IcoPath } }; } @@ -94,7 +95,7 @@ namespace Flow.Launcher.Plugin.Calculator new Result { Title = newResult, - IcoPath = "Images/calculator.png", + IcoPath = IcoPath, Score = 300, SubTitle = Localize.flowlauncher_plugin_calculator_copy_number_to_clipboard(), CopyText = newResult, @@ -123,7 +124,7 @@ namespace Flow.Launcher.Plugin.Calculator new Result { Title = Localize.flowlauncher_plugin_calculator_expression_not_complete(), - IcoPath = "Images/calculator.png" + IcoPath = IcoPath } }; } From e990e0ff5b38ead1cc1f9851a573aac7802951a8 Mon Sep 17 00:00:00 2001 From: dcog989 Date: Sun, 14 Sep 2025 19:39:06 +0100 Subject: [PATCH 25/75] Handle misplaced separators, Mages edge cases Allow for e.g. `25,00` when `,` used as digit grouping. Exclude Mages function from the above relaxed logic. --- .../Flow.Launcher.Plugin.Calculator/Main.cs | 132 +++++++++++++----- .../MainRegexHelper.cs | 6 +- 2 files changed, 103 insertions(+), 35 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs index 54ac61ffb..a15420a63 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.Linq; using System.Runtime.InteropServices; using System.Text.RegularExpressions; using System.Windows.Controls; @@ -12,10 +13,10 @@ namespace Flow.Launcher.Plugin.Calculator { public class Main : IPlugin, IPluginI18n, ISettingProvider { - private static readonly Regex RegBrackets = MainRegexHelper.GetRegBrackets(); private static readonly Regex ThousandGroupRegex = MainRegexHelper.GetThousandGroupRegex(); private static readonly Regex NumberRegex = MainRegexHelper.GetNumberRegex(); private static readonly Regex PowRegex = MainRegexHelper.GetPowRegex(); + private static readonly Regex FunctionRegex = MainRegexHelper.GetFunctionRegex(); private static Engine MagesEngine; private const string Comma = ","; @@ -51,7 +52,8 @@ namespace Flow.Launcher.Plugin.Calculator try { - var expression = NumberRegex.Replace(query.Search, m => NormalizeNumber(m.Value)); + bool isFunctionPresent = FunctionRegex.IsMatch(query.Search); + var expression = NumberRegex.Replace(query.Search, m => NormalizeNumber(m.Value, isFunctionPresent)); // WORKAROUND START: The 'pow' function in Mages v3.0.0 is broken. // https://github.com/FlorianRappl/Mages/issues/132 @@ -183,47 +185,104 @@ namespace Flow.Launcher.Plugin.Calculator return $"({arg1}^{arg2})"; } - /// - /// Parses a string representation of a number using the system's current culture. - /// - /// A normalized number string with '.' as the decimal separator for the Mages engine. - private static string NormalizeNumber(string numberStr) + private static string NormalizeNumber(string numberStr, bool isFunctionPresent) { var culture = CultureInfo.CurrentCulture; var groupSep = culture.NumberFormat.NumberGroupSeparator; var decimalSep = culture.NumberFormat.NumberDecimalSeparator; - // If the string contains the group separator, check if it's used correctly. - if (!string.IsNullOrEmpty(groupSep) && numberStr.Contains(groupSep)) + if (isFunctionPresent) { - var parts = numberStr.Split(groupSep); - // If any part after the first (excluding a possible last part with a decimal) - // does not have 3 digits, then it's not a valid use of a thousand separator. - for (int i = 1; i < parts.Length; i++) + // STRICT MODE: When functions are present, ',' is ALWAYS an argument separator. + // It must not be normalized. + if (numberStr.Contains(',')) { - var part = parts[i]; - // The last part might contain a decimal separator. - if (i == parts.Length - 1 && part.Contains(culture.NumberFormat.NumberDecimalSeparator)) - { - part = part.Split(culture.NumberFormat.NumberDecimalSeparator)[0]; - } + return numberStr; + } - if (part.Length != 3) + // The string has no commas. It could have a '.' group separator (e.g. in de-DE) + // or a '.' decimal separator (e.g. in en-US). + // Since Mages' decimal separator is '.', we only need to strip the group separator. + if (groupSep == ".") + { + var parts = numberStr.Split('.'); + // A number with a dot group separator, e.g., "1.234" + if (parts.Length > 1) { - // This is not a number with valid thousand separators, - // so it must be arguments to a function. Return it unmodified. - return numberStr; + // Check if the parts after the first dot have the correct group length (usually 3). + for (int i = 1; i < parts.Length; i++) + { + if (parts[i].Length != 3) + { + // Malformed grouping, e.g., "1.23". This is likely a decimal number. + // Return as is and let Mages handle it. + return numberStr; + } + } + // Correct grouping, e.g., "1.234" or "1.234.567". Strip separators. + return numberStr.Replace(".", ""); } } + + // For any other case (e.g. en-US culture where group sep is ',' which was already handled), + // return the string as is. + return numberStr; + } + else + { + // LENIENT MODE: No functions are present, so we can be flexible. + string processedStr = numberStr; + if (!string.IsNullOrEmpty(groupSep)) + { + processedStr = processedStr.Replace(groupSep, ""); + } + processedStr = processedStr.Replace(decimalSep, "."); + return processedStr; + } + } + + private static bool IsValidGrouping(string[] parts, int[] groupSizes) + { + if (parts.Length <= 1) return true; + + if (groupSizes is null || groupSizes.Length == 0 || groupSizes[0] == 0) + return false; // has groups, but culture defines none. + + var firstPart = parts[0]; + if (firstPart.StartsWith("-")) firstPart = firstPart.Substring(1); + if (firstPart.Length == 0) return false; // e.g. ",123" + + if (firstPart.Length > groupSizes[0]) return false; + + var lastGroupSize = groupSizes.Last(); + var canRepeatLastGroup = lastGroupSize != 0; + + int groupIndex = 0; + for (int i = parts.Length - 1; i > 0; i--) + { + int expectedSize; + if (groupIndex < groupSizes.Length) + { + expectedSize = groupSizes[groupIndex]; + } + else if(canRepeatLastGroup) + { + expectedSize = lastGroupSize; + } + else + { + return false; + } + + if (parts[i].Length != expectedSize) return false; + + groupIndex++; } - // If validation passes, we can assume the separators are used correctly for numbers. - string processedStr = numberStr.Replace(groupSep, ""); - processedStr = processedStr.Replace(decimalSep, "."); - - return processedStr; + return true; } + private string FormatResult(decimal roundedResult) { string decimalSeparator = GetDecimalSeparator(); @@ -250,14 +309,23 @@ namespace Flow.Launcher.Plugin.Calculator private string GetGroupSeparator(string decimalSeparator) { + var culture = CultureInfo.CurrentCulture; + var systemGroupSeparator = culture.NumberFormat.NumberGroupSeparator; + if (_settings.DecimalSeparator == DecimalSeparator.UseSystemLocale) { - return CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator; + return systemGroupSeparator; } - // This logic is now independent of the system's group separator - // to ensure consistent output when a specific separator is chosen. - return decimalSeparator == Dot ? Comma : Dot; + // When a custom decimal separator is used, + // use the system's group separator unless it conflicts with the custom decimal separator. + if (decimalSeparator == systemGroupSeparator) + { + // Conflict: use the opposite of the decimal separator as a fallback. + return decimalSeparator == Dot ? Comma : Dot; + } + + return systemGroupSeparator; } private string GetDecimalSeparator() diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs b/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs index d8c2795dc..5c2c19cf4 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs @@ -4,9 +4,6 @@ namespace Flow.Launcher.Plugin.Calculator; internal static partial class MainRegexHelper { - [GeneratedRegex(@"[\(\)\[\]]", RegexOptions.Compiled)] - public static partial Regex GetRegBrackets(); - [GeneratedRegex(@"-?[\d\.,]+", RegexOptions.Compiled)] public static partial Regex GetNumberRegex(); @@ -15,4 +12,7 @@ internal static partial class MainRegexHelper [GeneratedRegex(@"\bpow(\((?:[^()\[\]]|\((?)|\)(?<-Depth>)|\[(?)|\](?<-Depth>))*(?(Depth)(?!))\))", RegexOptions.Compiled | RegexOptions.RightToLeft)] public static partial Regex GetPowRegex(); + + [GeneratedRegex(@"\b(sqrt|pow|factorial|abs|sign|ceil|floor|round|exp|log|log2|log10|min|max|lt|eq|gt|sin|cos|tan|arcsin|arccos|arctan|isnan|isint|isprime|isinfty|rand|randi|type|is|as|length|throw|catch|eval|map|clamp|lerp|regex|shuffle)\s*\(", RegexOptions.Compiled | RegexOptions.IgnoreCase)] + public static partial Regex GetFunctionRegex(); } From edc76faeb4c8860c3f676e5addb7da948a33b3ef Mon Sep 17 00:00:00 2001 From: dcog989 Date: Sun, 14 Sep 2025 21:51:47 +0100 Subject: [PATCH 26/75] Review feedback, case insensitive, consistent separators --- .../Flow.Launcher.Plugin.Calculator/Main.cs | 72 ++++++++++++------- .../MainRegexHelper.cs | 2 +- 2 files changed, 46 insertions(+), 28 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs index a15420a63..545f343f2 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs @@ -52,8 +52,15 @@ namespace Flow.Launcher.Plugin.Calculator try { - bool isFunctionPresent = FunctionRegex.IsMatch(query.Search); - var expression = NumberRegex.Replace(query.Search, m => NormalizeNumber(m.Value, isFunctionPresent)); + var search = query.Search; + bool isFunctionPresent = FunctionRegex.IsMatch(search); + + // Mages is case sensitive, so we need to convert all function names to lower case. + search = FunctionRegex.Replace(search, m => m.Value.ToLowerInvariant()); + + var decimalSep = GetDecimalSeparator(); + var groupSep = GetGroupSeparator(decimalSep); + var expression = NumberRegex.Replace(search, m => NormalizeNumber(m.Value, isFunctionPresent, decimalSep, groupSep)); // WORKAROUND START: The 'pow' function in Mages v3.0.0 is broken. // https://github.com/FlorianRappl/Mages/issues/132 @@ -185,48 +192,56 @@ namespace Flow.Launcher.Plugin.Calculator return $"({arg1}^{arg2})"; } - private static string NormalizeNumber(string numberStr, bool isFunctionPresent) + private static string NormalizeNumber(string numberStr, bool isFunctionPresent, string decimalSep, string groupSep) { - var culture = CultureInfo.CurrentCulture; - var groupSep = culture.NumberFormat.NumberGroupSeparator; - var decimalSep = culture.NumberFormat.NumberDecimalSeparator; - if (isFunctionPresent) { // STRICT MODE: When functions are present, ',' is ALWAYS an argument separator. - // It must not be normalized. if (numberStr.Contains(',')) { return numberStr; } - // The string has no commas. It could have a '.' group separator (e.g. in de-DE) - // or a '.' decimal separator (e.g. in en-US). - // Since Mages' decimal separator is '.', we only need to strip the group separator. - if (groupSep == ".") + string processedStr = numberStr; + + // Handle group separator, with special care for ambiguous dot. + if (!string.IsNullOrEmpty(groupSep)) { - var parts = numberStr.Split('.'); - // A number with a dot group separator, e.g., "1.234" - if (parts.Length > 1) + if (groupSep == ".") { - // Check if the parts after the first dot have the correct group length (usually 3). - for (int i = 1; i < parts.Length; i++) + var parts = processedStr.Split('.'); + if (parts.Length > 1) { - if (parts[i].Length != 3) + bool isGrouped = true; + for (var i = 1; i < parts.Length; i++) { - // Malformed grouping, e.g., "1.23". This is likely a decimal number. - // Return as is and let Mages handle it. - return numberStr; + if (parts[i].Length != 3) + { + isGrouped = false; + break; + } } + + if (isGrouped) + { + processedStr = processedStr.Replace(groupSep, ""); + } + // If not grouped, it's likely a decimal number, so we don't strip dots. } - // Correct grouping, e.g., "1.234" or "1.234.567". Strip separators. - return numberStr.Replace(".", ""); + } + else + { + processedStr = processedStr.Replace(groupSep, ""); } } + + // Handle decimal separator. + if (decimalSep != ".") + { + processedStr = processedStr.Replace(decimalSep, "."); + } - // For any other case (e.g. en-US culture where group sep is ',' which was already handled), - // return the string as is. - return numberStr; + return processedStr; } else { @@ -236,7 +251,10 @@ namespace Flow.Launcher.Plugin.Calculator { processedStr = processedStr.Replace(groupSep, ""); } - processedStr = processedStr.Replace(decimalSep, "."); + if (decimalSep != ".") + { + processedStr = processedStr.Replace(decimalSep, "."); + } return processedStr; } } diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs b/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs index 5c2c19cf4..dacc249d9 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs @@ -10,7 +10,7 @@ internal static partial class MainRegexHelper [GeneratedRegex(@"\B(?=(\d{3})+(?!\d))", RegexOptions.Compiled)] public static partial Regex GetThousandGroupRegex(); - [GeneratedRegex(@"\bpow(\((?:[^()\[\]]|\((?)|\)(?<-Depth>)|\[(?)|\](?<-Depth>))*(?(Depth)(?!))\))", RegexOptions.Compiled | RegexOptions.RightToLeft)] + [GeneratedRegex(@"\bpow(\((?:[^()\[\]]|\((?)|\)(?<-Depth>)|\[(?)|\](?<-Depth>))*(?(Depth)(?!))\))", RegexOptions.Compiled | RegexOptions.RightToLeft | RegexOptions.IgnoreCase)] public static partial Regex GetPowRegex(); [GeneratedRegex(@"\b(sqrt|pow|factorial|abs|sign|ceil|floor|round|exp|log|log2|log10|min|max|lt|eq|gt|sin|cos|tan|arcsin|arccos|arctan|isnan|isint|isprime|isinfty|rand|randi|type|is|as|length|throw|catch|eval|map|clamp|lerp|regex|shuffle)\s*\(", RegexOptions.Compiled | RegexOptions.IgnoreCase)] From 9be8b71f0992d16bc235efe7be8ed1b781a22131 Mon Sep 17 00:00:00 2001 From: dcog989 Date: Sun, 14 Sep 2025 22:28:37 +0100 Subject: [PATCH 27/75] review feedback, CultureInvariant, mild refactor --- Plugins/Flow.Launcher.Plugin.Calculator/Main.cs | 14 ++------------ .../MainRegexHelper.cs | 6 +++--- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs index 545f343f2..a4c01fc21 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs @@ -212,17 +212,8 @@ namespace Flow.Launcher.Plugin.Calculator var parts = processedStr.Split('.'); if (parts.Length > 1) { - bool isGrouped = true; - for (var i = 1; i < parts.Length; i++) - { - if (parts[i].Length != 3) - { - isGrouped = false; - break; - } - } - - if (isGrouped) + var culture = CultureInfo.CurrentCulture; + if (IsValidGrouping(parts, culture.NumberFormat.NumberGroupSizes)) { processedStr = processedStr.Replace(groupSep, ""); } @@ -300,7 +291,6 @@ namespace Flow.Launcher.Plugin.Calculator return true; } - private string FormatResult(decimal roundedResult) { string decimalSeparator = GetDecimalSeparator(); diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs b/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs index dacc249d9..0746e4556 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs @@ -4,15 +4,15 @@ namespace Flow.Launcher.Plugin.Calculator; internal static partial class MainRegexHelper { - [GeneratedRegex(@"-?[\d\.,]+", RegexOptions.Compiled)] + [GeneratedRegex(@"-?[\d\.,'\u00A0\u202F]+", RegexOptions.Compiled | RegexOptions.CultureInvariant)] public static partial Regex GetNumberRegex(); [GeneratedRegex(@"\B(?=(\d{3})+(?!\d))", RegexOptions.Compiled)] public static partial Regex GetThousandGroupRegex(); - [GeneratedRegex(@"\bpow(\((?:[^()\[\]]|\((?)|\)(?<-Depth>)|\[(?)|\](?<-Depth>))*(?(Depth)(?!))\))", RegexOptions.Compiled | RegexOptions.RightToLeft | RegexOptions.IgnoreCase)] + [GeneratedRegex(@"\bpow(\((?:[^()\[\]]|\((?)|\)(?<-Depth>)|\[(?)|\](?<-Depth>))*(?(Depth)(?!))\))", RegexOptions.Compiled | RegexOptions.RightToLeft | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)] public static partial Regex GetPowRegex(); - [GeneratedRegex(@"\b(sqrt|pow|factorial|abs|sign|ceil|floor|round|exp|log|log2|log10|min|max|lt|eq|gt|sin|cos|tan|arcsin|arccos|arctan|isnan|isint|isprime|isinfty|rand|randi|type|is|as|length|throw|catch|eval|map|clamp|lerp|regex|shuffle)\s*\(", RegexOptions.Compiled | RegexOptions.IgnoreCase)] + [GeneratedRegex(@"\b(sqrt|pow|factorial|abs|sign|ceil|floor|round|exp|log|log2|log10|min|max|lt|eq|gt|sin|cos|tan|arcsin|arccos|arctan|isnan|isint|isprime|isinfty|rand|randi|type|is|as|length|throw|catch|eval|map|clamp|lerp|regex|shuffle)\s*\(", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)] public static partial Regex GetFunctionRegex(); } From b07420a193c8c51468d404155a4680fe7253d5aa Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Mon, 15 Sep 2025 12:51:31 +0800 Subject: [PATCH 28/75] Use EmptyResults to improve code quality --- Plugins/Flow.Launcher.Plugin.Calculator/Main.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs index a4c01fc21..cd54a2155 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs @@ -22,6 +22,7 @@ namespace Flow.Launcher.Plugin.Calculator private const string Comma = ","; private const string Dot = "."; private const string IcoPath = "Images/calculator.png"; + private static readonly List EmptyResults = []; internal static PluginInitContext Context { get; set; } = null!; @@ -47,7 +48,7 @@ namespace Flow.Launcher.Plugin.Calculator { if (string.IsNullOrWhiteSpace(query.Search)) { - return new List(); + return EmptyResults; } try @@ -138,7 +139,7 @@ namespace Flow.Launcher.Plugin.Calculator }; } - return new List(); + return EmptyResults; } private static string PowMatchEvaluator(Match m) From cea1402dde4bddf71fef55ebbc01007089c8315f Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Mon, 15 Sep 2025 12:53:17 +0800 Subject: [PATCH 29/75] Improve code quality --- Plugins/Flow.Launcher.Plugin.Calculator/Main.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs index cd54a2155..5b04ae7e8 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs @@ -181,8 +181,8 @@ namespace Flow.Launcher.Plugin.Calculator return m.Value; } - var arg1 = argsContent.Substring(0, splitIndex).Trim(); - var arg2 = argsContent.Substring(splitIndex + 1).Trim(); + var arg1 = argsContent[..splitIndex].Trim(); + var arg2 = argsContent[(splitIndex + 1)..].Trim(); // Check for empty arguments which can happen with stray commas, e.g., pow(,5) if (string.IsNullOrEmpty(arg1) || string.IsNullOrEmpty(arg2)) @@ -259,7 +259,7 @@ namespace Flow.Launcher.Plugin.Calculator return false; // has groups, but culture defines none. var firstPart = parts[0]; - if (firstPart.StartsWith("-")) firstPart = firstPart.Substring(1); + if (firstPart.StartsWith('-')) firstPart = firstPart[1..]; if (firstPart.Length == 0) return false; // e.g. ",123" if (firstPart.Length > groupSizes[0]) return false; From 1906d6854177b0960f0a861582254c31fe836439 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Mon, 15 Sep 2025 12:57:25 +0800 Subject: [PATCH 30/75] Add ShowErrorMessage setting --- .../Flow.Launcher.Plugin.Calculator/Languages/en.xaml | 1 + Plugins/Flow.Launcher.Plugin.Calculator/Main.cs | 6 ++++++ Plugins/Flow.Launcher.Plugin.Calculator/Settings.cs | 5 ++++- .../Views/CalculatorSettings.xaml | 10 ++++++++++ 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Calculator/Languages/en.xaml index 29a0ed26f..b12972b1b 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Languages/en.xaml +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Languages/en.xaml @@ -15,4 +15,5 @@ Dot (.) Max. decimal places Copy failed, please try later + Show error message when calculation fails \ No newline at end of file diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs index 5b04ae7e8..429b04979 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs @@ -79,6 +79,7 @@ namespace Flow.Launcher.Plugin.Calculator if (result == null || string.IsNullOrEmpty(result.ToString())) { + if (!_settings.ShowErrorMessage) return EmptyResults; return new List { new Result @@ -90,10 +91,14 @@ namespace Flow.Launcher.Plugin.Calculator } if (result.ToString() == "NaN") + { result = Localize.flowlauncher_plugin_calculator_not_a_number(); + } if (result is Function) + { result = Localize.flowlauncher_plugin_calculator_expression_not_complete(); + } if (!string.IsNullOrEmpty(result.ToString())) { @@ -129,6 +134,7 @@ namespace Flow.Launcher.Plugin.Calculator catch (Exception) { // Mages engine can throw various exceptions, for simplicity we catch them all and show a generic message. + if (!_settings.ShowErrorMessage) return EmptyResults; return new List { new Result diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Settings.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Settings.cs index 8354863b8..0f32b09a9 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Settings.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Settings.cs @@ -4,6 +4,9 @@ namespace Flow.Launcher.Plugin.Calculator public class Settings { public DecimalSeparator DecimalSeparator { get; set; } = DecimalSeparator.UseSystemLocale; - public int MaxDecimalPlaces { get; set; } = 10; + + public int MaxDecimalPlaces { get; set; } = 10; + + public bool ShowErrorMessage { get; set; } = false; } } diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml b/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml index 8d240ef39..9e7549b2d 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml @@ -15,6 +15,7 @@ + @@ -58,5 +59,14 @@ ItemsSource="{Binding MaxDecimalPlacesRange}" SelectedItem="{Binding Settings.MaxDecimalPlaces}" /> + From f9facda5216369e393bb3f126b5f7fdc543fef12 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Mon, 15 Sep 2025 13:02:42 +0800 Subject: [PATCH 31/75] Improve code quality --- .../Flow.Launcher.Plugin.Calculator/Main.cs | 20 +++++------ .../Settings.cs | 13 ++++--- .../ViewModels/SettingsViewModel.cs | 36 ++++++++----------- .../Views/CalculatorSettings.xaml.cs | 26 ++++++-------- 4 files changed, 41 insertions(+), 54 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs index 429b04979..17b4a85a4 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs @@ -80,14 +80,14 @@ namespace Flow.Launcher.Plugin.Calculator if (result == null || string.IsNullOrEmpty(result.ToString())) { if (!_settings.ShowErrorMessage) return EmptyResults; - return new List - { + return + [ new Result { Title = Localize.flowlauncher_plugin_calculator_expression_not_complete(), IcoPath = IcoPath } - }; + ]; } if (result.ToString() == "NaN") @@ -105,8 +105,8 @@ namespace Flow.Launcher.Plugin.Calculator decimal roundedResult = Math.Round(Convert.ToDecimal(result), _settings.MaxDecimalPlaces, MidpointRounding.AwayFromZero); string newResult = FormatResult(roundedResult); - return new List - { + return + [ new Result { Title = newResult, @@ -128,21 +128,21 @@ namespace Flow.Launcher.Plugin.Calculator } } } - }; + ]; } } catch (Exception) { // Mages engine can throw various exceptions, for simplicity we catch them all and show a generic message. if (!_settings.ShowErrorMessage) return EmptyResults; - return new List - { + return + [ new Result { Title = Localize.flowlauncher_plugin_calculator_expression_not_complete(), IcoPath = IcoPath } - }; + ]; } return EmptyResults; @@ -153,7 +153,7 @@ namespace Flow.Launcher.Plugin.Calculator // m.Groups[1].Value will be `(...)` with parens var contentWithParen = m.Groups[1].Value; // remove outer parens. `(min(2,3), 4)` becomes `min(2,3), 4` - var argsContent = contentWithParen.Substring(1, contentWithParen.Length - 2); + var argsContent = contentWithParen[1..^1]; var bracketCount = 0; var splitIndex = -1; diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Settings.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Settings.cs index 0f32b09a9..cac0f3080 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Settings.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Settings.cs @@ -1,12 +1,11 @@  -namespace Flow.Launcher.Plugin.Calculator +namespace Flow.Launcher.Plugin.Calculator; + +public class Settings { - public class Settings - { - public DecimalSeparator DecimalSeparator { get; set; } = DecimalSeparator.UseSystemLocale; + public DecimalSeparator DecimalSeparator { get; set; } = DecimalSeparator.UseSystemLocale; - public int MaxDecimalPlaces { get; set; } = 10; + public int MaxDecimalPlaces { get; set; } = 10; - public bool ShowErrorMessage { get; set; } = false; - } + public bool ShowErrorMessage { get; set; } = false; } diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Calculator/ViewModels/SettingsViewModel.cs index 87ae72fb6..36c277f15 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/ViewModels/SettingsViewModel.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/ViewModels/SettingsViewModel.cs @@ -1,31 +1,25 @@ using System.Collections.Generic; using System.Linq; -namespace Flow.Launcher.Plugin.Calculator.ViewModels +namespace Flow.Launcher.Plugin.Calculator.ViewModels; + +public class SettingsViewModel(Settings settings) : BaseModel { - public class SettingsViewModel : BaseModel + public Settings Settings { get; init; } = settings; + + public static IEnumerable MaxDecimalPlacesRange => Enumerable.Range(1, 20); + + public List AllDecimalSeparator { get; } = DecimalSeparatorLocalized.GetValues(); + + public DecimalSeparator SelectedDecimalSeparator { - public SettingsViewModel(Settings settings) + get => Settings.DecimalSeparator; + set { - Settings = settings; - } - - public Settings Settings { get; init; } - - public static IEnumerable MaxDecimalPlacesRange => Enumerable.Range(1, 20); - - public List AllDecimalSeparator { get; } = DecimalSeparatorLocalized.GetValues(); - - public DecimalSeparator SelectedDecimalSeparator - { - get => Settings.DecimalSeparator; - set + if (Settings.DecimalSeparator != value) { - if (Settings.DecimalSeparator != value) - { - Settings.DecimalSeparator = value; - OnPropertyChanged(); - } + Settings.DecimalSeparator = value; + OnPropertyChanged(); } } } diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml.cs index 7bc307d11..9e75e7bfb 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml.cs @@ -1,22 +1,16 @@ using System.Windows.Controls; using Flow.Launcher.Plugin.Calculator.ViewModels; -namespace Flow.Launcher.Plugin.Calculator.Views -{ - /// - /// Interaction logic for CalculatorSettings.xaml - /// - public partial class CalculatorSettings : UserControl - { - private readonly SettingsViewModel _viewModel; - private readonly Settings _settings; +namespace Flow.Launcher.Plugin.Calculator.Views; - public CalculatorSettings(Settings settings) - { - _viewModel = new SettingsViewModel(settings); - _settings = _viewModel.Settings; - DataContext = _viewModel; - InitializeComponent(); - } +public partial class CalculatorSettings : UserControl +{ + private readonly SettingsViewModel _viewModel; + + public CalculatorSettings(Settings settings) + { + _viewModel = new SettingsViewModel(settings); + DataContext = _viewModel; + InitializeComponent(); } } From 684fafdfddca9acfdaf6372a0a4546bc59e705e0 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Mon, 15 Sep 2025 15:18:42 +0800 Subject: [PATCH 32/75] Improve code quality --- .../ViewModels/SettingsViewModel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Calculator/ViewModels/SettingsViewModel.cs index 36c277f15..79236bdf8 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/ViewModels/SettingsViewModel.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/ViewModels/SettingsViewModel.cs @@ -5,7 +5,7 @@ namespace Flow.Launcher.Plugin.Calculator.ViewModels; public class SettingsViewModel(Settings settings) : BaseModel { - public Settings Settings { get; init; } = settings; + public Settings Settings { get; } = settings; public static IEnumerable MaxDecimalPlacesRange => Enumerable.Range(1, 20); From 9321a7df140ce303fbd21f44eb7c09bdfea31225 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Mon, 15 Sep 2025 15:40:49 +0800 Subject: [PATCH 33/75] Fix program lock issue --- Plugins/Flow.Launcher.Plugin.Program/Main.cs | 62 ++++++++++++------- .../Views/Commands/ProgramSettingDisplay.cs | 52 +++++++++++----- 2 files changed, 79 insertions(+), 35 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs index 7c30c0c96..0eb1fd403 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs @@ -31,7 +31,7 @@ namespace Flow.Launcher.Plugin.Program internal static PluginInitContext Context { get; private set; } - private static readonly List emptyResults = new(); + private static readonly List emptyResults = []; private static readonly MemoryCacheOptions cacheOptions = new() { SizeLimit = 1560 }; private static MemoryCache cache = new(cacheOptions); @@ -84,7 +84,6 @@ namespace Flow.Launcher.Plugin.Program { await _win32sLock.WaitAsync(token); await _uwpsLock.WaitAsync(token); - try { // Collect all UWP Windows app directories @@ -117,7 +116,7 @@ namespace Flow.Launcher.Plugin.Program } }, token); - resultList = resultList.Any() ? resultList : emptyResults; + resultList = resultList.Count != 0 ? resultList : emptyResults; entry.SetSize(resultList.Count); entry.SetSlidingExpiration(TimeSpan.FromHours(8)); @@ -250,14 +249,26 @@ namespace Flow.Launcher.Plugin.Program } await _win32sLock.WaitAsync(); - _win32s = await context.API.LoadCacheBinaryStorageAsync(Win32CacheName, pluginCacheDirectory, new List()); - _win32sCount = _win32s.Count; - _win32sLock.Release(); + try + { + _win32s = await context.API.LoadCacheBinaryStorageAsync(Win32CacheName, pluginCacheDirectory, new List()); + _win32sCount = _win32s.Count; + } + finally + { + _win32sLock.Release(); + } await _uwpsLock.WaitAsync(); - _uwps = await context.API.LoadCacheBinaryStorageAsync(UwpCacheName, pluginCacheDirectory, new List()); - _uwpsCount = _uwps.Count; - _uwpsLock.Release(); + try + { + _uwps = await context.API.LoadCacheBinaryStorageAsync(UwpCacheName, pluginCacheDirectory, new List()); + _uwpsCount = _uwps.Count; + } + finally + { + _uwpsLock.Release(); + } }); Context.API.LogInfo(ClassName, $"Number of preload win32 programs <{_win32sCount}>"); Context.API.LogInfo(ClassName, $"Number of preload uwps <{_uwpsCount}>"); @@ -408,38 +419,47 @@ namespace Flow.Launcher.Plugin.Program return; await _uwpsLock.WaitAsync(); - if (_uwps.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier)) + var reindexUwps = true; + try { + reindexUwps = _uwps.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier); var program = _uwps.First(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier); program.Enabled = false; _settings.DisabledProgramSources.Add(new ProgramSource(program)); + } + finally + { _uwpsLock.Release(); + } - // Reindex UWP programs + // Reindex UWP programs + if (reindexUwps) + { _ = Task.Run(IndexUwpProgramsAsync); return; } - else - { - _uwpsLock.Release(); - } await _win32sLock.WaitAsync(); - if (_win32s.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier)) + var reindexWin32s = true; + try { + reindexWin32s = _win32s.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier); var program = _win32s.First(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier); program.Enabled = false; _settings.DisabledProgramSources.Add(new ProgramSource(program)); _win32sLock.Release(); - - // Reindex Win32 programs - _ = Task.Run(IndexWin32ProgramsAsync); - return; } - else + finally { _win32sLock.Release(); } + + // Reindex Win32 programs + if (reindexWin32s) + { + _ = Task.Run(IndexWin32ProgramsAsync); + return; + } } public static void StartProcess(Func runProcess, ProcessStartInfo info) diff --git a/Plugins/Flow.Launcher.Plugin.Program/Views/Commands/ProgramSettingDisplay.cs b/Plugins/Flow.Launcher.Plugin.Program/Views/Commands/ProgramSettingDisplay.cs index b89a2a6ba..2a6a3e987 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Views/Commands/ProgramSettingDisplay.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Views/Commands/ProgramSettingDisplay.cs @@ -19,18 +19,30 @@ namespace Flow.Launcher.Plugin.Program.Views.Commands internal static async Task DisplayAllProgramsAsync() { await Main._win32sLock.WaitAsync(); - var win32 = Main._win32s + try + { + var win32 = Main._win32s .Where(t1 => !ProgramSetting.ProgramSettingDisplayList.Any(x => x.UniqueIdentifier == t1.UniqueIdentifier)) .Select(x => new ProgramSource(x)); - ProgramSetting.ProgramSettingDisplayList.AddRange(win32); - Main._win32sLock.Release(); + ProgramSetting.ProgramSettingDisplayList.AddRange(win32); + } + finally + { + Main._win32sLock.Release(); + } await Main._uwpsLock.WaitAsync(); - var uwp = Main._uwps + try + { + var uwp = Main._uwps .Where(t1 => !ProgramSetting.ProgramSettingDisplayList.Any(x => x.UniqueIdentifier == t1.UniqueIdentifier)) .Select(x => new ProgramSource(x)); - ProgramSetting.ProgramSettingDisplayList.AddRange(uwp); - Main._uwpsLock.Release(); + ProgramSetting.ProgramSettingDisplayList.AddRange(uwp); + } + finally + { + Main._uwpsLock.Release(); + } } internal static async Task SetProgramSourcesStatusAsync(List selectedProgramSourcesToDisable, bool status) @@ -44,24 +56,36 @@ namespace Flow.Launcher.Plugin.Program.Views.Commands } await Main._win32sLock.WaitAsync(); - foreach (var program in Main._win32s) + try { - if (selectedProgramSourcesToDisable.Any(x => x.UniqueIdentifier == program.UniqueIdentifier && program.Enabled != status)) + foreach (var program in Main._win32s) { - program.Enabled = status; + if (selectedProgramSourcesToDisable.Any(x => x.UniqueIdentifier == program.UniqueIdentifier && program.Enabled != status)) + { + program.Enabled = status; + } } } - Main._win32sLock.Release(); + finally + { + Main._win32sLock.Release(); + } await Main._uwpsLock.WaitAsync(); - foreach (var program in Main._uwps) + try { - if (selectedProgramSourcesToDisable.Any(x => x.UniqueIdentifier == program.UniqueIdentifier && program.Enabled != status)) + foreach (var program in Main._uwps) { - program.Enabled = status; + if (selectedProgramSourcesToDisable.Any(x => x.UniqueIdentifier == program.UniqueIdentifier && program.Enabled != status)) + { + program.Enabled = status; + } } } - Main._uwpsLock.Release(); + finally + { + Main._uwpsLock.Release(); + } } internal static void StoreDisabledInSettings() From ef69e329fc1d28b3e1352f3a04f94bb33da8afc6 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Mon, 15 Sep 2025 15:50:22 +0800 Subject: [PATCH 34/75] Fix release --- Plugins/Flow.Launcher.Plugin.Program/Main.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs index 0eb1fd403..0258a10d2 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs @@ -447,7 +447,6 @@ namespace Flow.Launcher.Plugin.Program var program = _win32s.First(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier); program.Enabled = false; _settings.DisabledProgramSources.Add(new ProgramSource(program)); - _win32sLock.Release(); } finally { From b5c860db1d98ab3b15f1c3bf1d8b9343eaad3d7c Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Mon, 15 Sep 2025 18:27:19 +0800 Subject: [PATCH 35/75] Add max width constrain --- .../Plugin/JsonRPCPluginSettings.cs | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs index 435d97ab7..598c2debb 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs @@ -27,6 +27,7 @@ namespace Flow.Launcher.Core.Plugin private JsonStorage> _storage = null!; + private static readonly double MainGridColumn0MaxWidthRatio = 0.6; private static readonly Thickness SettingPanelMargin = (Thickness)Application.Current.FindResource("SettingPanelMargin"); private static readonly Thickness SettingPanelItemLeftMargin = (Thickness)Application.Current.FindResource("SettingPanelItemLeftMargin"); private static readonly Thickness SettingPanelItemTopBottomMargin = (Thickness)Application.Current.FindResource("SettingPanelItemTopBottomMargin"); @@ -156,11 +157,12 @@ namespace Flow.Launcher.Core.Plugin { if (!NeedCreateSettingPanel()) return null!; - // Create main grid with two columns (Column 1: Auto, Column 2: *) + // Create main grid with two columns (Column 0: Auto, Column 1: *) var mainPanel = new Grid { Margin = SettingPanelMargin, VerticalAlignment = VerticalAlignment.Center }; mainPanel.ColumnDefinitions.Add(new ColumnDefinition() { - Width = new GridLength(0, GridUnitType.Auto) + Width = new GridLength(0, GridUnitType.Auto), + MaxWidth = MainGridColumn0MaxWidthRatio * 560 // 560 is the default available width }); mainPanel.ColumnDefinitions.Add(new ColumnDefinition() { @@ -488,6 +490,8 @@ namespace Flow.Launcher.Core.Plugin rowCount++; } + mainPanel.SizeChanged += MainPanel_SizeChanged; + // Wrap the main grid in a user control return new UserControl() { @@ -495,6 +499,18 @@ namespace Flow.Launcher.Core.Plugin }; } + private void MainPanel_SizeChanged(object sender, SizeChangedEventArgs e) + { + if (sender is not Grid grid) return; + + var workingWidth = + (int)(grid.ActualWidth - SystemParameters.VerticalScrollBarWidth); // take into account vertical scrollbar + + if (workingWidth <= 0) return; + + grid.ColumnDefinitions[0].MaxWidth = MainGridColumn0MaxWidthRatio * workingWidth; + } + private static bool NeedSaveInSettings(string type) { return type != "textBlock" && type != "separator" && type != "hyperlink"; From 44ca9c348093bd75e815be0830c8e6dbfba76fc0 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Mon, 15 Sep 2025 18:40:16 +0800 Subject: [PATCH 36/75] Use wrap text warpping & set max width of all children --- .../Plugin/JsonRPCPluginSettings.cs | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs index 598c2debb..0306bb29e 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs @@ -202,7 +202,7 @@ namespace Flow.Launcher.Core.Plugin { Text = attributes.Label, VerticalAlignment = VerticalAlignment.Center, - TextWrapping = TextWrapping.WrapWithOverflow + TextWrapping = TextWrapping.Wrap }; // Create a text block for description @@ -213,7 +213,7 @@ namespace Flow.Launcher.Core.Plugin { Text = attributes.Description, VerticalAlignment = VerticalAlignment.Center, - TextWrapping = TextWrapping.WrapWithOverflow + TextWrapping = TextWrapping.Wrap }; desc.SetResourceReference(TextBlock.StyleProperty, "SettingPanelTextBlockDescriptionStyle"); // for theme change @@ -249,7 +249,8 @@ namespace Flow.Launcher.Core.Plugin VerticalAlignment = VerticalAlignment.Center, Margin = SettingPanelItemLeftTopBottomMargin, Text = Settings[attributes.Name] as string ?? string.Empty, - ToolTip = attributes.Description + ToolTip = attributes.Description, + TextWrapping = TextWrapping.Wrap }; textBox.TextChanged += (_, _) => @@ -271,7 +272,8 @@ namespace Flow.Launcher.Core.Plugin VerticalAlignment = VerticalAlignment.Center, Margin = SettingPanelItemLeftMargin, Text = Settings[attributes.Name] as string ?? string.Empty, - ToolTip = attributes.Description + ToolTip = attributes.Description, + TextWrapping = TextWrapping.Wrap }; textBox.TextChanged += (_, _) => @@ -335,7 +337,7 @@ namespace Flow.Launcher.Core.Plugin HorizontalAlignment = HorizontalAlignment.Stretch, VerticalAlignment = VerticalAlignment.Center, Margin = SettingPanelItemLeftTopBottomMargin, - TextWrapping = TextWrapping.WrapWithOverflow, + TextWrapping = TextWrapping.Wrap, AcceptsReturn = true, Text = Settings[attributes.Name] as string ?? string.Empty, ToolTip = attributes.Description @@ -508,7 +510,21 @@ namespace Flow.Launcher.Core.Plugin if (workingWidth <= 0) return; - grid.ColumnDefinitions[0].MaxWidth = MainGridColumn0MaxWidthRatio * workingWidth; + var constrainedWidth = MainGridColumn0MaxWidthRatio * workingWidth; + + // Set MaxWidth of column 0 and its childrens + // We must set MaxWidth of its childrens to make text wrapping work correctly + grid.ColumnDefinitions[0].MaxWidth = constrainedWidth; + foreach (var child in grid.Children) + { + if (child is FrameworkElement element && Grid.GetColumn(element) == 0 && Grid.GetColumnSpan(element) == 1) + { + if (element.MaxWidth < constrainedWidth) + continue; + + element.MaxWidth = constrainedWidth; + } + } } private static bool NeedSaveInSettings(string type) From 5695200940bd3a9be104661731d2dd1ee4584bff Mon Sep 17 00:00:00 2001 From: Jack Ye <1160210343@qq.com> Date: Mon, 15 Sep 2025 18:46:05 +0800 Subject: [PATCH 37/75] Fix typos Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs index 0306bb29e..c9abe00f9 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs @@ -512,8 +512,8 @@ namespace Flow.Launcher.Core.Plugin var constrainedWidth = MainGridColumn0MaxWidthRatio * workingWidth; - // Set MaxWidth of column 0 and its childrens - // We must set MaxWidth of its childrens to make text wrapping work correctly + // Set MaxWidth of column 0 and its children + // We must set MaxWidth of its children to make text wrapping work correctly grid.ColumnDefinitions[0].MaxWidth = constrainedWidth; foreach (var child in grid.Children) { From f3cb85ea5917a998f91414578c0c07dc869f9f42 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Mon, 15 Sep 2025 18:46:47 +0800 Subject: [PATCH 38/75] Remove unnecessary check --- Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs index 0306bb29e..f96486947 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs @@ -519,9 +519,6 @@ namespace Flow.Launcher.Core.Plugin { if (child is FrameworkElement element && Grid.GetColumn(element) == 0 && Grid.GetColumnSpan(element) == 1) { - if (element.MaxWidth < constrainedWidth) - continue; - element.MaxWidth = constrainedWidth; } } From e571204a84ff57747a21a3cf82a45a0cefc8b1f1 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Mon, 15 Sep 2025 18:48:09 +0800 Subject: [PATCH 39/75] No need to initialize max width --- Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs index 39c208bfe..43ea6a508 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs @@ -161,8 +161,7 @@ namespace Flow.Launcher.Core.Plugin var mainPanel = new Grid { Margin = SettingPanelMargin, VerticalAlignment = VerticalAlignment.Center }; mainPanel.ColumnDefinitions.Add(new ColumnDefinition() { - Width = new GridLength(0, GridUnitType.Auto), - MaxWidth = MainGridColumn0MaxWidthRatio * 560 // 560 is the default available width + Width = new GridLength(0, GridUnitType.Auto) }); mainPanel.ColumnDefinitions.Add(new ColumnDefinition() { From 55f9857dec3db0ed5e406f23415305030aa1ca79 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Mon, 15 Sep 2025 18:59:01 +0800 Subject: [PATCH 40/75] Remove SystemParameters.VerticalScrollBarWidth --- Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs index 43ea6a508..9212dada6 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs @@ -504,8 +504,7 @@ namespace Flow.Launcher.Core.Plugin { if (sender is not Grid grid) return; - var workingWidth = - (int)(grid.ActualWidth - SystemParameters.VerticalScrollBarWidth); // take into account vertical scrollbar + var workingWidth = grid.ActualWidth; if (workingWidth <= 0) return; From e204daa8443aad283feba9dabeed576e16d13c7e Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Mon, 15 Sep 2025 21:33:21 +0800 Subject: [PATCH 41/75] Catch exception when creating setting panel --- Flow.Launcher/ViewModel/PluginViewModel.cs | 36 +++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs index d889bdd52..36c509902 100644 --- a/Flow.Launcher/ViewModel/PluginViewModel.cs +++ b/Flow.Launcher/ViewModel/PluginViewModel.cs @@ -131,11 +131,45 @@ namespace Flow.Launcher.ViewModel => IsExpanded ? _settingControl ??= HasSettingControl - ? ((ISettingProvider)PluginPair.Plugin).CreateSettingPanel() + ? TryCreateSettingPanel(PluginPair) : null : null; private ImageSource _image = ImageLoader.MissingImage; + private static readonly Thickness SettingPanelMargin = (Thickness)Application.Current.FindResource("SettingPanelMargin"); + private static readonly Thickness SettingPanelItemTopBottomMargin = (Thickness)Application.Current.FindResource("SettingPanelItemTopBottomMargin"); + private static Control TryCreateSettingPanel(PluginPair pair) + { + try + { + // We can safely cast here as we already check this in HasSettingControl + return ((ISettingProvider)pair.Plugin).CreateSettingPanel(); + } + catch (System.Exception e) + { + var errorMsg = $"Error creating setting panel for plugin {pair.Metadata}\n{e.Message}"; + var grid = new Grid() + { + Margin = SettingPanelMargin + }; + var textBox = new TextBox + { + Text = errorMsg, + IsReadOnly = true, + HorizontalAlignment = HorizontalAlignment.Stretch, + VerticalAlignment = VerticalAlignment.Top, + TextWrapping = TextWrapping.Wrap, + Margin = SettingPanelItemTopBottomMargin + }; + textBox.SetResourceReference(TextBlock.ForegroundProperty, "Color04B"); + grid.Children.Add(textBox); + return new UserControl + { + Content = grid + }; + } + } + public Visibility ActionKeywordsVisibility => PluginPair.Metadata.HideActionKeywordPanel ? Visibility.Collapsed : Visibility.Visible; public string InitializeTime => PluginPair.Metadata.InitTime + "ms"; From 0355993b009b3e29b399a3fdbc02fba481337303 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Mon, 15 Sep 2025 21:38:53 +0800 Subject: [PATCH 42/75] Use translation --- Flow.Launcher/Languages/en.xaml | 1 + Flow.Launcher/ViewModel/PluginViewModel.cs | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index f7fd0c8e5..e97bd6cf5 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -219,6 +219,7 @@ Fail to uninstall {0} Unable to find plugin.json from the extracted zip file, or this path {0} does not exist A plugin with the same ID and version already exists, or the version is greater than this downloaded plugin + Error creating setting panel for plugin {0}:{1}{2} Plugin Store diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs index 36c509902..4de1ae661 100644 --- a/Flow.Launcher/ViewModel/PluginViewModel.cs +++ b/Flow.Launcher/ViewModel/PluginViewModel.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Media; @@ -145,9 +146,10 @@ namespace Flow.Launcher.ViewModel // We can safely cast here as we already check this in HasSettingControl return ((ISettingProvider)pair.Plugin).CreateSettingPanel(); } - catch (System.Exception e) + catch (Exception e) { - var errorMsg = $"Error creating setting panel for plugin {pair.Metadata}\n{e.Message}"; + var errorMsg = string.Format(App.API.GetTranslation("errorCreatingSettingPanel"), + pair.Metadata.Name, Environment.NewLine, e.Message); var grid = new Grid() { Margin = SettingPanelMargin From 18c8a04cbcc5fe062730abef62af7c0760682eae Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Mon, 15 Sep 2025 21:46:03 +0800 Subject: [PATCH 43/75] Log exception --- Flow.Launcher/ViewModel/PluginViewModel.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs index 4de1ae661..59bb53a4a 100644 --- a/Flow.Launcher/ViewModel/PluginViewModel.cs +++ b/Flow.Launcher/ViewModel/PluginViewModel.cs @@ -15,6 +15,8 @@ namespace Flow.Launcher.ViewModel { public partial class PluginViewModel : BaseModel { + private static readonly string ClassName = nameof(PluginViewModel); + private static readonly Settings Settings = Ioc.Default.GetRequiredService(); private readonly PluginPair _pluginPair; @@ -148,6 +150,10 @@ namespace Flow.Launcher.ViewModel } catch (Exception e) { + // Log exception + App.API.LogException(ClassName, $"Failed to create setting panel for {pair.Metadata.Name}", e); + + // Show error message in UI var errorMsg = string.Format(App.API.GetTranslation("errorCreatingSettingPanel"), pair.Metadata.Name, Environment.NewLine, e.Message); var grid = new Grid() From 6841ad5410fd44c3402362a56723f4289cf1b7a0 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Tue, 16 Sep 2025 16:08:17 +0800 Subject: [PATCH 44/75] Add calculator unit testing --- Flow.Launcher.Test/Flow.Launcher.Test.csproj | 1 + Flow.Launcher.Test/Plugins/CalculatorTest.cs | 86 +++++++++++++++++++ .../Flow.Launcher.Plugin.Calculator/Main.cs | 3 +- 3 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 Flow.Launcher.Test/Plugins/CalculatorTest.cs diff --git a/Flow.Launcher.Test/Flow.Launcher.Test.csproj b/Flow.Launcher.Test/Flow.Launcher.Test.csproj index 1164e5ebe..11ccff05b 100644 --- a/Flow.Launcher.Test/Flow.Launcher.Test.csproj +++ b/Flow.Launcher.Test/Flow.Launcher.Test.csproj @@ -39,6 +39,7 @@ + diff --git a/Flow.Launcher.Test/Plugins/CalculatorTest.cs b/Flow.Launcher.Test/Plugins/CalculatorTest.cs new file mode 100644 index 000000000..3f403b24e --- /dev/null +++ b/Flow.Launcher.Test/Plugins/CalculatorTest.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using Flow.Launcher.Plugin.Calculator; +using Mages.Core; +using NUnit.Framework; +using NUnit.Framework.Legacy; + +namespace Flow.Launcher.Test.Plugins +{ + [TestFixture] + public class CalculatorPluginTest + { + private readonly Main _plugin; + + public CalculatorPluginTest() + { + _plugin = new Main(); + + var settingField = typeof(Main).GetField("_settings", BindingFlags.NonPublic | BindingFlags.Instance); + if (settingField == null) + Assert.Fail("Could not find field '_settings' on Flow.Launcher.Plugin.Calculator.Main"); + settingField.SetValue(_plugin, new Settings + { + ShowErrorMessage = false // Make sure we return the empty results when error occurs + }); + + var engineField = typeof(Main).GetField("MagesEngine", BindingFlags.NonPublic | BindingFlags.Static); + if (engineField == null) + Assert.Fail("Could not find static field 'MagesEngine' on Flow.Launcher.Plugin.Calculator.Main"); + engineField.SetValue(null, new Engine(new Configuration + { + Scope = new Dictionary + { + { "e", Math.E }, // e is not contained in the default mages engine + } + })); + } + + // Basic operations + [TestCase(@"1+1", "2")] + [TestCase(@"2-1", "1")] + [TestCase(@"2*2", "4")] + [TestCase(@"4/2", "2")] + [TestCase(@"2^3", "8")] + // Decimal places + [TestCase(@"10/3", "3.3333333333")] + // Parentheses + [TestCase(@"(1+2)*3", "9")] + [TestCase(@"2^(1+2)", "8")] + // Functions + [TestCase(@"pow(2,3)", "8")] + [TestCase(@"min(1,-1,-2)", "-2")] + [TestCase(@"max(1,-1,-2)", "1")] + [TestCase(@"sqrt(16)", "4")] + [TestCase(@"sin(pi)", "0")] + [TestCase(@"cos(0)", "1")] + [TestCase(@"tan(0)", "0")] + [TestCase(@"log(100)", "2")] + [TestCase(@"ln(e)", "1")] + [TestCase(@"abs(-5)", "5")] + // Constants + [TestCase(@"pi", "3.1415926536")] + // Complex expressions + [TestCase(@"(2+3)*sqrt(16)-log(100)/ln(e)", "19")] + [TestCase(@"sin(pi/2)+cos(0)+tan(0)", "2")] + // Error handling (should return empty result) + [TestCase(@"10/0", "")] + [TestCase(@"sqrt(-1)", "")] + [TestCase(@"log(0)", "")] + [TestCase(@"invalid_expression", "")] + public void CalculatorTest(string expression, string result) + { + ClassicAssert.AreEqual(GetCalculationResult(expression), result); + } + + private string GetCalculationResult(string expression) + { + var results = _plugin.Query(new Plugin.Query() + { + Search = expression + }); + return results.Count > 0 ? results[0].Title : string.Empty; + } + } +} diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs index 17b4a85a4..42cbafb43 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs @@ -112,7 +112,8 @@ namespace Flow.Launcher.Plugin.Calculator Title = newResult, IcoPath = IcoPath, Score = 300, - SubTitle = Localize.flowlauncher_plugin_calculator_copy_number_to_clipboard(), + // Check context nullability for unit testing + SubTitle = Context == null ? string.Empty : Localize.flowlauncher_plugin_calculator_copy_number_to_clipboard(), CopyText = newResult, Action = c => { From e10b9254ed6211ba8a8fdcc1047d9fe25724e7c4 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Tue, 16 Sep 2025 16:31:06 +0800 Subject: [PATCH 45/75] Add workaround for log & ln function --- Flow.Launcher.Test/Plugins/CalculatorTest.cs | 4 +- .../Flow.Launcher.Plugin.Calculator/Main.cs | 63 +++++++++++++++++-- .../MainRegexHelper.cs | 6 ++ 3 files changed, 67 insertions(+), 6 deletions(-) diff --git a/Flow.Launcher.Test/Plugins/CalculatorTest.cs b/Flow.Launcher.Test/Plugins/CalculatorTest.cs index 3f403b24e..146552323 100644 --- a/Flow.Launcher.Test/Plugins/CalculatorTest.cs +++ b/Flow.Launcher.Test/Plugins/CalculatorTest.cs @@ -53,10 +53,12 @@ namespace Flow.Launcher.Test.Plugins [TestCase(@"min(1,-1,-2)", "-2")] [TestCase(@"max(1,-1,-2)", "1")] [TestCase(@"sqrt(16)", "4")] - [TestCase(@"sin(pi)", "0")] + [TestCase(@"sin(pi)", "0.0000000000")] [TestCase(@"cos(0)", "1")] [TestCase(@"tan(0)", "0")] + [TestCase(@"log10(100)", "2")] [TestCase(@"log(100)", "2")] + [TestCase(@"log2(8)", "3")] [TestCase(@"ln(e)", "1")] [TestCase(@"abs(-5)", "5")] // Constants diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs index 42cbafb43..9d5e4700f 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs @@ -16,6 +16,8 @@ namespace Flow.Launcher.Plugin.Calculator private static readonly Regex ThousandGroupRegex = MainRegexHelper.GetThousandGroupRegex(); private static readonly Regex NumberRegex = MainRegexHelper.GetNumberRegex(); private static readonly Regex PowRegex = MainRegexHelper.GetPowRegex(); + private static readonly Regex LogRegex = MainRegexHelper.GetLogRegex(); + private static readonly Regex LnRegex = MainRegexHelper.GetLnRegex(); private static readonly Regex FunctionRegex = MainRegexHelper.GetFunctionRegex(); private static Engine MagesEngine; @@ -67,12 +69,36 @@ namespace Flow.Launcher.Plugin.Calculator // https://github.com/FlorianRappl/Mages/issues/132 // We bypass it by rewriting any pow(x,y) expression to the equivalent (x^y) expression // before the engine sees it. This loop handles nested calls. - string previous; - do { - previous = expression; - expression = PowRegex.Replace(previous, PowMatchEvaluator); - } while (previous != expression); + string previous; + do + { + previous = expression; + expression = PowRegex.Replace(previous, PowMatchEvaluator); + } while (previous != expression); + } + // WORKAROUND END + + // WORKAROUND START: The 'log' & 'ln' function in Mages v3.0.0 are broken. + // https://github.com/FlorianRappl/Mages/issues/137 + // We bypass it by rewriting any log & ln expression to the equivalent (log10 & log) expression + // before the engine sees it. This loop handles nested calls. + { + string previous; + do + { + previous = expression; + expression = LogRegex.Replace(previous, LogMatchEvaluator); + } while (previous != expression); + } + { + string previous; + do + { + previous = expression; + expression = LnRegex.Replace(previous, LnMatchEvaluator); + } while (previous != expression); + } // WORKAROUND END var result = MagesEngine.Interpret(expression); @@ -200,6 +226,33 @@ namespace Flow.Launcher.Plugin.Calculator return $"({arg1}^{arg2})"; } + private static string LogMatchEvaluator(Match m) + { + // m.Groups[1].Value will be `(...)` with parens + var contentWithParen = m.Groups[1].Value; + var argsContent = contentWithParen[1..^1]; + + // log is unary — if malformed, return original to let Mages handle it + var arg = argsContent.Trim(); + if (string.IsNullOrEmpty(arg)) return m.Value; + + // log(x) -> log10(x) (natural log) + return $"(log10({arg}))"; + } + + private static string LnMatchEvaluator(Match m) + { + // m.Groups[1].Value will be `(...)` with parens + var contentWithParen = m.Groups[1].Value; + var argsContent = contentWithParen[1..^1]; + + // ln is unary — if malformed, return original to let Mages handle it + var arg = argsContent.Trim(); + if (string.IsNullOrEmpty(arg)) return m.Value; + + // ln(x) -> log(x) (natural log) + return $"(log({arg}))"; + } private static string NormalizeNumber(string numberStr, bool isFunctionPresent, string decimalSep, string groupSep) { if (isFunctionPresent) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs b/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs index 0746e4556..a8b582ccc 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs @@ -13,6 +13,12 @@ internal static partial class MainRegexHelper [GeneratedRegex(@"\bpow(\((?:[^()\[\]]|\((?)|\)(?<-Depth>)|\[(?)|\](?<-Depth>))*(?(Depth)(?!))\))", RegexOptions.Compiled | RegexOptions.RightToLeft | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)] public static partial Regex GetPowRegex(); + [GeneratedRegex(@"\blog(\((?:[^()\[\]]|\((?)|\)(?<-Depth>)|\[(?)|\](?<-Depth>))*(?(Depth)(?!))\))", RegexOptions.Compiled | RegexOptions.RightToLeft | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)] + public static partial Regex GetLogRegex(); + + [GeneratedRegex(@"\bln(\((?:[^()\[\]]|\((?)|\)(?<-Depth>)|\[(?)|\](?<-Depth>))*(?(Depth)(?!))\))", RegexOptions.Compiled | RegexOptions.RightToLeft | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)] + public static partial Regex GetLnRegex(); + [GeneratedRegex(@"\b(sqrt|pow|factorial|abs|sign|ceil|floor|round|exp|log|log2|log10|min|max|lt|eq|gt|sin|cos|tan|arcsin|arccos|arctan|isnan|isint|isprime|isinfty|rand|randi|type|is|as|length|throw|catch|eval|map|clamp|lerp|regex|shuffle)\s*\(", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)] public static partial Regex GetFunctionRegex(); } From 552b6547db09301c7ab57c0a1f000eb5ee5daf44 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Tue, 16 Sep 2025 16:40:36 +0800 Subject: [PATCH 46/75] Fix unit test result issue --- Flow.Launcher.Test/Plugins/CalculatorTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Test/Plugins/CalculatorTest.cs b/Flow.Launcher.Test/Plugins/CalculatorTest.cs index 146552323..c58800002 100644 --- a/Flow.Launcher.Test/Plugins/CalculatorTest.cs +++ b/Flow.Launcher.Test/Plugins/CalculatorTest.cs @@ -64,7 +64,7 @@ namespace Flow.Launcher.Test.Plugins // Constants [TestCase(@"pi", "3.1415926536")] // Complex expressions - [TestCase(@"(2+3)*sqrt(16)-log(100)/ln(e)", "19")] + [TestCase(@"(2+3)*sqrt(16)-log(100)/ln(e)", "18")] [TestCase(@"sin(pi/2)+cos(0)+tan(0)", "2")] // Error handling (should return empty result) [TestCase(@"10/0", "")] From 8321e400c1a6608c541a3e617967ece77df0860b Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Tue, 16 Sep 2025 21:04:56 +0800 Subject: [PATCH 47/75] Fix test setting & Add instances to private fields --- Flow.Launcher.Test/Plugins/CalculatorTest.cs | 26 +++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/Flow.Launcher.Test/Plugins/CalculatorTest.cs b/Flow.Launcher.Test/Plugins/CalculatorTest.cs index c58800002..b075813db 100644 --- a/Flow.Launcher.Test/Plugins/CalculatorTest.cs +++ b/Flow.Launcher.Test/Plugins/CalculatorTest.cs @@ -12,6 +12,19 @@ namespace Flow.Launcher.Test.Plugins public class CalculatorPluginTest { private readonly Main _plugin; + private readonly Settings _settings = new() + { + DecimalSeparator = DecimalSeparator.UseSystemLocale, + MaxDecimalPlaces = 10, + ShowErrorMessage = false // Make sure we return the empty results when error occurs + }; + private readonly Engine _engine = new(new Configuration + { + Scope = new Dictionary + { + { "e", Math.E }, // e is not contained in the default mages engine + } + }); public CalculatorPluginTest() { @@ -20,21 +33,12 @@ namespace Flow.Launcher.Test.Plugins var settingField = typeof(Main).GetField("_settings", BindingFlags.NonPublic | BindingFlags.Instance); if (settingField == null) Assert.Fail("Could not find field '_settings' on Flow.Launcher.Plugin.Calculator.Main"); - settingField.SetValue(_plugin, new Settings - { - ShowErrorMessage = false // Make sure we return the empty results when error occurs - }); + settingField.SetValue(_plugin, _settings); var engineField = typeof(Main).GetField("MagesEngine", BindingFlags.NonPublic | BindingFlags.Static); if (engineField == null) Assert.Fail("Could not find static field 'MagesEngine' on Flow.Launcher.Plugin.Calculator.Main"); - engineField.SetValue(null, new Engine(new Configuration - { - Scope = new Dictionary - { - { "e", Math.E }, // e is not contained in the default mages engine - } - })); + engineField.SetValue(null, _engine); } // Basic operations From 23d0b73e20bb0963d5a11a6c910edc04035b52af Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 17 Sep 2025 17:30:03 +0800 Subject: [PATCH 48/75] Fix AllEverythingSortOptions issue --- .../ViewModels/SettingsViewModel.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs index 7292697ce..ae2235c5c 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs @@ -577,8 +577,8 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels } } - public int MaxResultLowerLimit => 1; - public int MaxResultUpperLimit => 100000; + public int MaxResultLowerLimit { get; } = 1; + public int MaxResultUpperLimit { get; } = 100000; public int MaxResult { @@ -592,7 +592,7 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels #region Everything FastSortWarning - public List AllEverythingSortOptions = EverythingSortOptionLocalized.GetValues(); + public List AllEverythingSortOptions { get; } = EverythingSortOptionLocalized.GetValues(); public EverythingSortOption SelectedEverythingSortOption { From 80c283a370fa7a9a2cb74778b97e55b2829069a0 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 17 Sep 2025 19:15:46 +0800 Subject: [PATCH 49/75] Improve code quality --- Flow.Launcher/Helper/WallpaperPathRetrieval.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs index 93b9a8aaa..c16e1170d 100644 --- a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs +++ b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading; using System.Windows; using System.Windows.Media; using System.Windows.Media.Imaging; @@ -16,7 +17,7 @@ public static class WallpaperPathRetrieval private const int MaxCacheSize = 3; private static readonly Dictionary<(string, DateTime), ImageBrush> WallpaperCache = new(); - private static readonly object CacheLock = new(); + private static readonly Lock CacheLock = new(); public static Brush GetWallpaperBrush() { @@ -56,7 +57,7 @@ public static class WallpaperPathRetrieval if (originalWidth == 0 || originalHeight == 0) { - App.API.LogInfo(ClassName, $"Failed to load bitmap: Width={originalWidth}, Height={originalHeight}"); + App.API.LogError(ClassName, $"Failed to load bitmap: Width={originalWidth}, Height={originalHeight}"); return new SolidColorBrush(Colors.Transparent); } @@ -104,13 +105,13 @@ public static class WallpaperPathRetrieval private static Color GetWallpaperColor() { - RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Colors", false); + using var key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Colors", false); var result = key?.GetValue("Background", null); if (result is string strResult) { try { - var parts = strResult.Trim().Split(new[] { ' ' }, 3).Select(byte.Parse).ToList(); + var parts = strResult.Trim().Split([' '], 3).Select(byte.Parse).ToList(); return Color.FromRgb(parts[0], parts[1], parts[2]); } catch (Exception ex) From 5c16b86edfde80d6b07c08da6a59fddc3ee61880 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 17 Sep 2025 19:16:09 +0800 Subject: [PATCH 50/75] Fix file lock during file stream --- Flow.Launcher/Helper/WallpaperPathRetrieval.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs index c16e1170d..be35b8f69 100644 --- a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs +++ b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs @@ -48,12 +48,15 @@ public static class WallpaperPathRetrieval return cachedWallpaper; } } - - using var fileStream = File.OpenRead(wallpaperPath); - var decoder = BitmapDecoder.Create(fileStream, BitmapCreateOptions.DelayCreation, BitmapCacheOption.None); - var frame = decoder.Frames[0]; - var originalWidth = frame.PixelWidth; - var originalHeight = frame.PixelHeight; + + int originalWidth, originalHeight; + using (var fileStream = File.OpenRead(wallpaperPath)) + { + var decoder = BitmapDecoder.Create(fileStream, BitmapCreateOptions.DelayCreation, BitmapCacheOption.None); + var frame = decoder.Frames[0]; + originalWidth = frame.PixelWidth; + originalHeight = frame.PixelHeight; + } if (originalWidth == 0 || originalHeight == 0) { From 83f02f5c9144cf49c387a0e408fa92c43e0f7c9f Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 17 Sep 2025 19:16:58 +0800 Subject: [PATCH 51/75] Use log error & Improve returned color --- Flow.Launcher/Helper/WallpaperPathRetrieval.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs index be35b8f69..aa41c9998 100644 --- a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs +++ b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs @@ -32,7 +32,7 @@ public static class WallpaperPathRetrieval var wallpaperPath = Win32Helper.GetWallpaperPath(); if (string.IsNullOrEmpty(wallpaperPath) || !File.Exists(wallpaperPath)) { - App.API.LogInfo(ClassName, $"Wallpaper path is invalid: {wallpaperPath}"); + App.API.LogError(ClassName, $"Wallpaper path is invalid: {wallpaperPath}"); var wallpaperColor = GetWallpaperColor(); return new SolidColorBrush(wallpaperColor); } @@ -61,7 +61,8 @@ public static class WallpaperPathRetrieval if (originalWidth == 0 || originalHeight == 0) { App.API.LogError(ClassName, $"Failed to load bitmap: Width={originalWidth}, Height={originalHeight}"); - return new SolidColorBrush(Colors.Transparent); + var wallpaperColor = GetWallpaperColor(); + return new SolidColorBrush(wallpaperColor); } // Calculate the scaling factor to fit the image within 800x600 while preserving aspect ratio From 60ec9b5c497c7a30e58dc29b0d5d602fb50a8adc Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 17 Sep 2025 19:24:32 +0800 Subject: [PATCH 52/75] Use OnLoaded to ensure the wallpaper file is not locked --- Flow.Launcher/Helper/WallpaperPathRetrieval.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs index aa41c9998..57c1bbe8d 100644 --- a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs +++ b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs @@ -75,7 +75,9 @@ public static class WallpaperPathRetrieval // Set DecodePixelWidth and DecodePixelHeight to resize the image while preserving aspect ratio var bitmap = new BitmapImage(); bitmap.BeginInit(); + bitmap.CacheOption = BitmapCacheOption.OnLoad; // Use OnLoaded to ensure the wallpaper file is not locked bitmap.UriSource = new Uri(wallpaperPath); + bitmap.CreateOptions = BitmapCreateOptions.IgnoreColorProfile; bitmap.DecodePixelWidth = decodedPixelWidth; bitmap.DecodePixelHeight = decodedPixelHeight; bitmap.EndInit(); From 354b04bea449091efa5bd61e182d133552367391 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 17 Sep 2025 19:29:36 +0800 Subject: [PATCH 53/75] Add code comments --- Flow.Launcher/Helper/WallpaperPathRetrieval.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs index 57c1bbe8d..67618d760 100644 --- a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs +++ b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs @@ -50,6 +50,7 @@ public static class WallpaperPathRetrieval } int originalWidth, originalHeight; + // Use `using ()` instead of `using var` sentence here to ensure the wallpaper file is not locked using (var fileStream = File.OpenRead(wallpaperPath)) { var decoder = BitmapDecoder.Create(fileStream, BitmapCreateOptions.DelayCreation, BitmapCacheOption.None); From e50a2772f82392234eb1389e3fad8b01dfae3e3d Mon Sep 17 00:00:00 2001 From: Jack Ye <1160210343@qq.com> Date: Wed, 17 Sep 2025 19:33:46 +0800 Subject: [PATCH 54/75] Update code comments Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- Flow.Launcher/Helper/WallpaperPathRetrieval.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs index 67618d760..fd04b3e88 100644 --- a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs +++ b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs @@ -76,7 +76,7 @@ public static class WallpaperPathRetrieval // Set DecodePixelWidth and DecodePixelHeight to resize the image while preserving aspect ratio var bitmap = new BitmapImage(); bitmap.BeginInit(); - bitmap.CacheOption = BitmapCacheOption.OnLoad; // Use OnLoaded to ensure the wallpaper file is not locked + bitmap.CacheOption = BitmapCacheOption.OnLoad; // Use OnLoad to ensure the wallpaper file is not locked bitmap.UriSource = new Uri(wallpaperPath); bitmap.CreateOptions = BitmapCreateOptions.IgnoreColorProfile; bitmap.DecodePixelWidth = decodedPixelWidth; From 1fea8edb747470b076376b76473d52f9c8253f51 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 18 Sep 2025 11:46:09 +0800 Subject: [PATCH 55/75] Add translation for default items & new profile item for explorer & browser window --- .../UserSettings/CustomBrowserViewModel.cs | 17 +++++++++++++---- .../UserSettings/CustomExplorerViewModel.cs | 15 ++++++++++++++- Flow.Launcher/Languages/en.xaml | 3 +++ Flow.Launcher/SelectBrowserWindow.xaml | 2 +- Flow.Launcher/SelectBrowserWindow.xaml.cs | 12 +++++++++++- Flow.Launcher/SelectFileManagerWindow.xaml | 2 +- .../ViewModels/SettingsPaneGeneralViewModel.cs | 4 +++- .../SettingPages/Views/SettingsPaneGeneral.xaml | 4 ++-- .../ViewModel/SelectBrowserViewModel.cs | 12 +----------- 9 files changed, 49 insertions(+), 22 deletions(-) diff --git a/Flow.Launcher.Infrastructure/UserSettings/CustomBrowserViewModel.cs b/Flow.Launcher.Infrastructure/UserSettings/CustomBrowserViewModel.cs index 24584115d..9c795f952 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/CustomBrowserViewModel.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/CustomBrowserViewModel.cs @@ -1,11 +1,18 @@ +using System.Text.Json.Serialization; +using CommunityToolkit.Mvvm.DependencyInjection; using Flow.Launcher.Plugin; -using System.Text.Json.Serialization; namespace Flow.Launcher.Infrastructure.UserSettings { public class CustomBrowserViewModel : BaseModel { + // 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(); + public string Name { get; set; } + [JsonIgnore] + public string DisplayName => Name == "Default" ? API.GetTranslation("defaultBrowser_default") : Name; public string Path { get; set; } public string PrivateArg { get; set; } public bool EnablePrivate { get; set; } @@ -26,8 +33,10 @@ namespace Flow.Launcher.Infrastructure.UserSettings Editable = Editable }; } + + public void OnDisplayNameChanged() + { + OnPropertyChanged(nameof(DisplayName)); + } } } - - - diff --git a/Flow.Launcher.Infrastructure/UserSettings/CustomExplorerViewModel.cs b/Flow.Launcher.Infrastructure/UserSettings/CustomExplorerViewModel.cs index c54c30478..5727f0735 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/CustomExplorerViewModel.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/CustomExplorerViewModel.cs @@ -1,10 +1,18 @@ -using Flow.Launcher.Plugin; +using System.Text.Json.Serialization; +using CommunityToolkit.Mvvm.DependencyInjection; +using Flow.Launcher.Plugin; namespace Flow.Launcher.ViewModel { public class CustomExplorerViewModel : BaseModel { + // 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(); + public string Name { get; set; } + [JsonIgnore] + public string DisplayName => Name == "Explorer" ? API.GetTranslation("fileManagerExplorer") : Name; public string Path { get; set; } public string FileArgument { get; set; } = "\"%d\""; public string DirectoryArgument { get; set; } = "\"%d\""; @@ -21,5 +29,10 @@ namespace Flow.Launcher.ViewModel Editable = Editable }; } + + public void OnDisplayNameChanged() + { + OnPropertyChanged(nameof(DisplayName)); + } } } diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index f7fd0c8e5..b38fe8aab 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -487,6 +487,7 @@ Arg For File The file manager '{0}' could not be located at '{1}'. Would you like to continue? File Manager Path Error + File Explorer Default Web Browser @@ -497,6 +498,8 @@ New Window New Tab Private Mode + Default + New Profile Change Priority diff --git a/Flow.Launcher/SelectBrowserWindow.xaml b/Flow.Launcher/SelectBrowserWindow.xaml index d51d597b7..67c22b07d 100644 --- a/Flow.Launcher/SelectBrowserWindow.xaml +++ b/Flow.Launcher/SelectBrowserWindow.xaml @@ -92,7 +92,7 @@ SelectedIndex="{Binding SelectedCustomBrowserIndex}"> - + diff --git a/Flow.Launcher/SelectBrowserWindow.xaml.cs b/Flow.Launcher/SelectBrowserWindow.xaml.cs index 565b4cbc3..8ef50ca75 100644 --- a/Flow.Launcher/SelectBrowserWindow.xaml.cs +++ b/Flow.Launcher/SelectBrowserWindow.xaml.cs @@ -31,7 +31,7 @@ namespace Flow.Launcher private void btnBrowseFile_Click(object sender, RoutedEventArgs e) { - var selectedFilePath = _viewModel.SelectFile(); + var selectedFilePath = SelectFile(); if (!string.IsNullOrEmpty(selectedFilePath)) { @@ -41,5 +41,15 @@ namespace Flow.Launcher ((Button)sender).Focus(); } } + + private static string SelectFile() + { + var dlg = new Microsoft.Win32.OpenFileDialog(); + var result = dlg.ShowDialog(); + if (result == true) + return dlg.FileName; + + return string.Empty; + } } } diff --git a/Flow.Launcher/SelectFileManagerWindow.xaml b/Flow.Launcher/SelectFileManagerWindow.xaml index b3b219d1c..cd4bec424 100644 --- a/Flow.Launcher/SelectFileManagerWindow.xaml +++ b/Flow.Launcher/SelectFileManagerWindow.xaml @@ -102,7 +102,7 @@ SelectedIndex="{Binding SelectedCustomExplorerIndex}"> - + diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs index ec75ddf90..b47b53654 100644 --- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs +++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; @@ -219,6 +219,8 @@ public partial class SettingsPaneGeneralViewModel : BaseModel DropdownDataGeneric.UpdateLabels(DialogJumpFileResultBehaviours); // Since we are using Binding instead of DynamicResource, we need to manually trigger the update OnPropertyChanged(nameof(AlwaysPreviewToolTip)); + Settings.CustomExplorer.OnDisplayNameChanged(); + Settings.CustomBrowser.OnDisplayNameChanged(); } public string Language diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml index 81e15df69..07cc7b6a7 100644 --- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml +++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml @@ -403,7 +403,7 @@ MaxWidth="250" Margin="10 0 0 0" Command="{Binding SelectFileManagerCommand}" - Content="{Binding Settings.CustomExplorer.Name}" /> + Content="{Binding Settings.CustomExplorer.DisplayName}" /> + Content="{Binding Settings.CustomBrowser.DisplayName}" /> diff --git a/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs b/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs index 67bbbd930..bcc6f1489 100644 --- a/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs +++ b/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs @@ -40,22 +40,12 @@ public partial class SelectBrowserViewModel : BaseModel return true; } - internal string SelectFile() - { - var dlg = new Microsoft.Win32.OpenFileDialog(); - var result = dlg.ShowDialog(); - if (result == true) - return dlg.FileName; - - return string.Empty; - } - [RelayCommand] private void Add() { CustomBrowsers.Add(new() { - Name = "New Profile" + Name = App.API.GetTranslation("defaultBrowser_new_profile") }); SelectedCustomBrowserIndex = CustomBrowsers.Count - 1; } From 647c55eaf7e60a525f7e9c4ffa3a1c5809e39d66 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 18 Sep 2025 11:47:18 +0800 Subject: [PATCH 56/75] Add property changed check --- Flow.Launcher/ViewModel/SelectBrowserViewModel.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs b/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs index bcc6f1489..f75a0ef8b 100644 --- a/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs +++ b/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs @@ -17,8 +17,11 @@ public partial class SelectBrowserViewModel : BaseModel get => selectedCustomBrowserIndex; set { - selectedCustomBrowserIndex = value; - OnPropertyChanged(nameof(CustomBrowser)); + if (selectedCustomBrowserIndex != value) + { + selectedCustomBrowserIndex = value; + OnPropertyChanged(nameof(CustomBrowser)); + } } } From dd07baff59756db8b83e0a1ca362c136cd51b2d6 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 18 Sep 2025 11:58:38 +0800 Subject: [PATCH 57/75] Add SelectFile helper method & Improve code quality --- Flow.Launcher.Infrastructure/Win32Helper.cs | 16 +++++++++++++++- Flow.Launcher/SelectBrowserWindow.xaml.cs | 13 ++----------- Flow.Launcher/SelectFileManagerWindow.xaml.cs | 5 +++-- .../ViewModel/SelectFileManagerViewModel.cs | 15 --------------- 4 files changed, 20 insertions(+), 29 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs index 811733925..5d30b740d 100644 --- a/Flow.Launcher.Infrastructure/Win32Helper.cs +++ b/Flow.Launcher.Infrastructure/Win32Helper.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; @@ -904,5 +904,19 @@ namespace Flow.Launcher.Infrastructure } #endregion + + #region File / Folder Dialog + + public static string SelectFile() + { + var dlg = new OpenFileDialog(); + var result = dlg.ShowDialog(); + if (result == true) + return dlg.FileName; + + return string.Empty; + } + + #endregion } } diff --git a/Flow.Launcher/SelectBrowserWindow.xaml.cs b/Flow.Launcher/SelectBrowserWindow.xaml.cs index 8ef50ca75..290712aad 100644 --- a/Flow.Launcher/SelectBrowserWindow.xaml.cs +++ b/Flow.Launcher/SelectBrowserWindow.xaml.cs @@ -1,6 +1,7 @@ using System.Windows; using System.Windows.Controls; using CommunityToolkit.Mvvm.DependencyInjection; +using Flow.Launcher.Infrastructure; using Flow.Launcher.ViewModel; namespace Flow.Launcher @@ -31,7 +32,7 @@ namespace Flow.Launcher private void btnBrowseFile_Click(object sender, RoutedEventArgs e) { - var selectedFilePath = SelectFile(); + var selectedFilePath = Win32Helper.SelectFile(); if (!string.IsNullOrEmpty(selectedFilePath)) { @@ -41,15 +42,5 @@ namespace Flow.Launcher ((Button)sender).Focus(); } } - - private static string SelectFile() - { - var dlg = new Microsoft.Win32.OpenFileDialog(); - var result = dlg.ShowDialog(); - if (result == true) - return dlg.FileName; - - return string.Empty; - } } } diff --git a/Flow.Launcher/SelectFileManagerWindow.xaml.cs b/Flow.Launcher/SelectFileManagerWindow.xaml.cs index d9c672aff..5143f9a56 100644 --- a/Flow.Launcher/SelectFileManagerWindow.xaml.cs +++ b/Flow.Launcher/SelectFileManagerWindow.xaml.cs @@ -2,6 +2,7 @@ using System.Windows.Controls; using System.Windows.Navigation; using CommunityToolkit.Mvvm.DependencyInjection; +using Flow.Launcher.Infrastructure; using Flow.Launcher.ViewModel; namespace Flow.Launcher @@ -32,13 +33,13 @@ namespace Flow.Launcher private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e) { - _viewModel.OpenUrl(e.Uri.AbsoluteUri); + App.API.OpenUrl(e.Uri.AbsoluteUri); e.Handled = true; } private void btnBrowseFile_Click(object sender, RoutedEventArgs e) { - var selectedFilePath = _viewModel.SelectFile(); + var selectedFilePath = Win32Helper.SelectFile(); if (!string.IsNullOrEmpty(selectedFilePath)) { diff --git a/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs b/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs index 77f004980..253f74b47 100644 --- a/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs +++ b/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs @@ -98,21 +98,6 @@ public partial class SelectFileManagerViewModel : BaseModel } } - internal void OpenUrl(string absoluteUri) - { - App.API.OpenUrl(absoluteUri); - } - - internal string SelectFile() - { - var dlg = new Microsoft.Win32.OpenFileDialog(); - var result = dlg.ShowDialog(); - if (result == true) - return dlg.FileName; - - return string.Empty; - } - [RelayCommand] private void Add() { From a03f62832ad52362cefc06f23f5130e1d78c82af Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 18 Sep 2025 12:08:49 +0800 Subject: [PATCH 58/75] Ignore index change for -1 --- Flow.Launcher/ViewModel/SelectBrowserViewModel.cs | 2 ++ Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs b/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs index f75a0ef8b..e3a0e4e44 100644 --- a/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs +++ b/Flow.Launcher/ViewModel/SelectBrowserViewModel.cs @@ -17,6 +17,8 @@ public partial class SelectBrowserViewModel : BaseModel get => selectedCustomBrowserIndex; set { + // When one custom browser is selected and removed, the index will become -1, so we need to ignore this change + if (value < 0) return; if (selectedCustomBrowserIndex != value) { selectedCustomBrowserIndex = value; diff --git a/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs b/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs index 253f74b47..b0851b90c 100644 --- a/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs +++ b/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs @@ -21,6 +21,8 @@ public partial class SelectFileManagerViewModel : BaseModel get => selectedCustomExplorerIndex; set { + // When one custom file manager is selected and removed, the index will become -1, so we need to ignore this change + if (value < 0) return; if (selectedCustomExplorerIndex != value) { selectedCustomExplorerIndex = value; From 256ae5c4b0a49b24f37326ef6a25218581d68aec Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 18 Sep 2025 12:15:33 +0800 Subject: [PATCH 59/75] Fill missing translation --- Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs b/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs index b0851b90c..f6a32e3fe 100644 --- a/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs +++ b/Flow.Launcher/ViewModel/SelectFileManagerViewModel.cs @@ -105,7 +105,7 @@ public partial class SelectFileManagerViewModel : BaseModel { CustomExplorers.Add(new() { - Name = "New Profile" + Name = App.API.GetTranslation("defaultBrowser_new_profile") }); SelectedCustomExplorerIndex = CustomExplorers.Count - 1; } From 101750115389e169a491f42c3ece4310165eec3d Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 18 Sep 2025 12:36:40 +0800 Subject: [PATCH 60/75] Fix namespace issue --- .../UserSettings/CustomExplorerViewModel.cs | 2 +- Flow.Launcher.Infrastructure/UserSettings/Settings.cs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Flow.Launcher.Infrastructure/UserSettings/CustomExplorerViewModel.cs b/Flow.Launcher.Infrastructure/UserSettings/CustomExplorerViewModel.cs index 5727f0735..2af0bb0e5 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/CustomExplorerViewModel.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/CustomExplorerViewModel.cs @@ -2,7 +2,7 @@ using CommunityToolkit.Mvvm.DependencyInjection; using Flow.Launcher.Plugin; -namespace Flow.Launcher.ViewModel +namespace Flow.Launcher.Infrastructure.UserSettings { public class CustomExplorerViewModel : BaseModel { diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index 23f9047fe..f70c4559b 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -9,7 +9,6 @@ using Flow.Launcher.Infrastructure.Logger; using Flow.Launcher.Infrastructure.Storage; using Flow.Launcher.Plugin; using Flow.Launcher.Plugin.SharedModels; -using Flow.Launcher.ViewModel; namespace Flow.Launcher.Infrastructure.UserSettings { From b05c2c1e1af62d07a8bd27dc2e9ae409a362df0f Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 18 Sep 2025 16:25:21 +0800 Subject: [PATCH 61/75] Remove old dictionaries references to fix possible memory leak --- Flow.Launcher.Core/Resource/Internationalization.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs index 8261feab3..e8711819c 100644 --- a/Flow.Launcher.Core/Resource/Internationalization.cs +++ b/Flow.Launcher.Core/Resource/Internationalization.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Globalization; using System.IO; @@ -256,6 +256,7 @@ namespace Flow.Launcher.Core.Resource foreach (var r in _oldResources) { dicts.Remove(r); + _oldResources.Remove(r); } } From 6c695f09e71ef88571c40494747cb08f95e14979 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 18 Sep 2025 17:55:06 +0800 Subject: [PATCH 62/75] Use clear function --- Flow.Launcher.Core/Resource/Internationalization.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs index e8711819c..6df2a28c6 100644 --- a/Flow.Launcher.Core/Resource/Internationalization.cs +++ b/Flow.Launcher.Core/Resource/Internationalization.cs @@ -256,8 +256,8 @@ namespace Flow.Launcher.Core.Resource foreach (var r in _oldResources) { dicts.Remove(r); - _oldResources.Remove(r); } + _oldResources.Clear(); } private void LoadLanguage(Language language) From 330e6c09e7d8321ca268147de4a6490331d92bc0 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 18 Sep 2025 18:07:18 +0800 Subject: [PATCH 63/75] Add language change lock --- .../Resource/Internationalization.cs | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs index 6df2a28c6..c1fa2ea16 100644 --- a/Flow.Launcher.Core/Resource/Internationalization.cs +++ b/Flow.Launcher.Core/Resource/Internationalization.cs @@ -30,6 +30,7 @@ namespace Flow.Launcher.Core.Resource private readonly List _languageDirectories = []; private readonly List _oldResources = []; private static string SystemLanguageCode; + private readonly SemaphoreSlim _langChangeLock = new(1, 1); public Internationalization(Settings settings) { @@ -185,20 +186,29 @@ namespace Flow.Launcher.Core.Resource private async Task ChangeLanguageAsync(Language language, bool updateMetadata = true) { - // Remove old language files and load language - RemoveOldLanguageFiles(); - if (language != AvailableLanguages.English) + await _langChangeLock.WaitAsync(); + + try { - LoadLanguage(language); + // Remove old language files and load language + RemoveOldLanguageFiles(); + if (language != AvailableLanguages.English) + { + LoadLanguage(language); + } + + // Change culture info + ChangeCultureInfo(language.LanguageCode); + + if (updateMetadata) + { + // Raise event for plugins after culture is set + await Task.Run(UpdatePluginMetadataTranslations); + } } - - // Change culture info - ChangeCultureInfo(language.LanguageCode); - - if (updateMetadata) + finally { - // Raise event for plugins after culture is set - await Task.Run(UpdatePluginMetadataTranslations); + _langChangeLock.Release(); } } From 86581e6a00f0d7806a3e910fa39283c03c0f498b Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 18 Sep 2025 18:17:27 +0800 Subject: [PATCH 64/75] Add disposable for internalization --- Flow.Launcher.Core/Resource/Internationalization.cs | 12 +++++++++++- Flow.Launcher/App.xaml.cs | 5 ++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs index c1fa2ea16..2e270a20b 100644 --- a/Flow.Launcher.Core/Resource/Internationalization.cs +++ b/Flow.Launcher.Core/Resource/Internationalization.cs @@ -14,7 +14,7 @@ using Flow.Launcher.Plugin; namespace Flow.Launcher.Core.Resource { - public class Internationalization + public class Internationalization : IDisposable { private static readonly string ClassName = nameof(Internationalization); @@ -379,5 +379,15 @@ namespace Flow.Launcher.Core.Resource } #endregion + + #region IDisposable + + public void Dispose() + { + RemoveOldLanguageFiles(); + _langChangeLock.Dispose(); + } + + #endregion } } diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs index 0360c761e..8ec11e5ff 100644 --- a/Flow.Launcher/App.xaml.cs +++ b/Flow.Launcher/App.xaml.cs @@ -45,6 +45,7 @@ namespace Flow.Launcher private static Settings _settings; private static MainWindow _mainWindow; private readonly MainViewModel _mainVM; + private readonly Internationalization _internationalization; // To prevent two disposals running at the same time. private static readonly object _disposingLock = new(); @@ -107,6 +108,7 @@ namespace Flow.Launcher API = Ioc.Default.GetRequiredService(); _settings.Initialize(); _mainVM = Ioc.Default.GetRequiredService(); + _internationalization = Ioc.Default.GetRequiredService(); } catch (Exception e) { @@ -193,7 +195,7 @@ namespace Flow.Launcher Win32Helper.EnableWin32DarkMode(_settings.ColorScheme); // Initialize language before portable clean up since it needs translations - await Ioc.Default.GetRequiredService().InitializeLanguageAsync(); + await _internationalization.InitializeLanguageAsync(); Ioc.Default.GetRequiredService().PreStartCleanUpAfterPortabilityUpdate(); @@ -421,6 +423,7 @@ namespace Flow.Launcher _mainWindow?.Dispatcher.Invoke(_mainWindow.Dispose); _mainVM?.Dispose(); DialogJump.Dispose(); + _internationalization.Dispose(); } API.LogInfo(ClassName, "End Flow Launcher dispose ----------------------------------------------------"); From 0f6245a072f8ad7c7b7fa93b4915d2505c880f0f Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 18 Sep 2025 18:18:02 +0800 Subject: [PATCH 65/75] Handle exceptions inside ChangeLanguageAsync to avoid unobserved task crashes --- Flow.Launcher.Core/Resource/Internationalization.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs index 2e270a20b..983f8b234 100644 --- a/Flow.Launcher.Core/Resource/Internationalization.cs +++ b/Flow.Launcher.Core/Resource/Internationalization.cs @@ -206,6 +206,10 @@ namespace Flow.Launcher.Core.Resource await Task.Run(UpdatePluginMetadataTranslations); } } + catch (Exception e) + { + API.LogException(ClassName, $"Failed to change language to <{language.LanguageCode}>", e); + } finally { _langChangeLock.Release(); From fc2e3fec630f98c532ae4525b8a99eddbf3e1314 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 18 Sep 2025 18:29:45 +0800 Subject: [PATCH 66/75] Improve ImageLoader performance --- Flow.Launcher.Infrastructure/Image/ImageLoader.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs index 64d323de6..598347fd2 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs @@ -22,7 +22,7 @@ namespace Flow.Launcher.Infrastructure.Image private static Lock storageLock { get; } = new(); private static BinaryStorage> _storage; private static readonly ConcurrentDictionary GuidToKey = new(); - private static IImageHashGenerator _hashGenerator; + private static ImageHashGenerator _hashGenerator; private static readonly bool EnableImageHash = true; public static ImageSource Image => ImageCache[Constant.ImageIcon, false]; public static ImageSource MissingImage => ImageCache[Constant.MissingImgIcon, false]; @@ -31,7 +31,7 @@ namespace Flow.Launcher.Infrastructure.Image public const int FullIconSize = 256; public const int FullImageSize = 320; - private static readonly string[] ImageExtensions = { ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".ico" }; + private static readonly string[] ImageExtensions = [".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".ico"]; private static readonly string SvgExtension = ".svg"; public static async Task InitializeAsync() @@ -327,7 +327,7 @@ namespace Flow.Launcher.Infrastructure.Image return img; } - private static ImageSource LoadFullImage(string path) + private static BitmapImage LoadFullImage(string path) { BitmapImage image = new BitmapImage(); image.BeginInit(); @@ -364,7 +364,7 @@ namespace Flow.Launcher.Infrastructure.Image return image; } - private static ImageSource LoadSvgImage(string path, bool loadFullImage = false) + private static RenderTargetBitmap LoadSvgImage(string path, bool loadFullImage = false) { // Set up drawing settings var desiredHeight = loadFullImage ? FullImageSize : SmallIconSize; From 9a597f2b4d1e3928c849b28de3d0b1b6cd7d84c8 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 18 Sep 2025 18:32:13 +0800 Subject: [PATCH 67/75] Disable cache feature --- Flow.Launcher/Helper/WallpaperPathRetrieval.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs index fd04b3e88..fe0ff39ad 100644 --- a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs +++ b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs @@ -15,8 +15,9 @@ public static class WallpaperPathRetrieval { private static readonly string ClassName = nameof(WallpaperPathRetrieval); - private const int MaxCacheSize = 3; - private static readonly Dictionary<(string, DateTime), ImageBrush> WallpaperCache = new(); + // Disable cache feature because some wallpaper applications (like Wallpaper Engine) may change wallpaper frequently + private const int MaxCacheSize = 0;//3; + private static readonly Dictionary<(string, DateTime), ImageBrush> WallpaperCache = []; private static readonly Lock CacheLock = new(); public static Brush GetWallpaperBrush() From 35a5e27e2d10f19b1f689e989d4efbf92d28a78f Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 18 Sep 2025 19:15:22 +0800 Subject: [PATCH 68/75] Fix DirectoryNotFoundException when deleting cache twice --- .../ViewModels/SettingsPaneAboutViewModel.cs | 59 ++++++++++--------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs index 1efc89972..5e24b9dc8 100644 --- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs +++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs @@ -231,36 +231,41 @@ public partial class SettingsPaneAboutViewModel : BaseModel } }); - // Firstly, delete plugin cache directories - pluginCacheDirectory.EnumerateDirectories("*", SearchOption.TopDirectoryOnly) - .ToList() - .ForEach(dir => + // Check if plugin cache directory exists before attempting to delete + // Or it will throw DirectoryNotFoundException in `pluginCacheDirectory.EnumerateDirectories` + if (pluginCacheDirectory.Exists) + { + // Firstly, delete plugin cache directories + pluginCacheDirectory.EnumerateDirectories("*", SearchOption.TopDirectoryOnly) + .ToList() + .ForEach(dir => + { + try + { + // Plugin may create directories in its cache directory + dir.Delete(recursive: true); + } + catch (Exception e) + { + App.API.LogException(ClassName, $"Failed to delete cache directory: {dir.Name}", e); + success = false; + } + }); + + // Then, delete plugin directory + var dir = pluginCacheDirectory; + try { - try - { - // Plugin may create directories in its cache directory - dir.Delete(recursive: true); - } - catch (Exception e) - { - App.API.LogException(ClassName, $"Failed to delete cache directory: {dir.Name}", e); - success = false; - } - }); + dir.Delete(recursive: false); + } + catch (Exception e) + { + App.API.LogException(ClassName, $"Failed to delete cache directory: {dir.Name}", e); + success = false; + } - // Then, delete plugin directory - var dir = GetPluginCacheDir(); - try - { - dir.Delete(recursive: false); + OnPropertyChanged(nameof(CacheFolderSize)); } - catch (Exception e) - { - App.API.LogException(ClassName, $"Failed to delete cache directory: {dir.Name}", e); - success = false; - } - - OnPropertyChanged(nameof(CacheFolderSize)); return success; } From ec182ade398544605da0a90bc7afadf65ef575be Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 18 Sep 2025 19:18:11 +0800 Subject: [PATCH 69/75] Fix property changed event --- .../SettingPages/ViewModels/SettingsPaneAboutViewModel.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs index 5e24b9dc8..7a6a1d91b 100644 --- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs +++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs @@ -263,10 +263,10 @@ public partial class SettingsPaneAboutViewModel : BaseModel App.API.LogException(ClassName, $"Failed to delete cache directory: {dir.Name}", e); success = false; } - - OnPropertyChanged(nameof(CacheFolderSize)); } + OnPropertyChanged(nameof(CacheFolderSize)); + return success; } From 4bea4101a1c5a7e13f8befa7ef33b0bafe98e1e7 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Thu, 18 Sep 2025 21:40:37 +1000 Subject: [PATCH 70/75] add comment for cache folder size refresh event --- .../SettingPages/ViewModels/SettingsPaneAboutViewModel.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs index 7a6a1d91b..647b36701 100644 --- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs +++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs @@ -265,6 +265,7 @@ public partial class SettingsPaneAboutViewModel : BaseModel } } + // Raise regardless to cover scenario where size needs to be recalculated if the folder is manually removed on disk. OnPropertyChanged(nameof(CacheFolderSize)); return success; From 7a5e55e5f0b5f96a29e67cefab6a6dec63463ba6 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 18 Sep 2025 21:06:18 +0800 Subject: [PATCH 71/75] Use Debug instead of Info --- Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs b/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs index 2ff51ff73..841099dd1 100644 --- a/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs +++ b/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs @@ -75,7 +75,7 @@ namespace Flow.Launcher.Core.ExternalPlugins } catch (OperationCanceledException) when (token.IsCancellationRequested) { - API.LogInfo(ClassName, $"Fetching from {ManifestFileUrl} was cancelled by caller."); + API.LogDebug(ClassName, $"Fetching from {ManifestFileUrl} was cancelled by caller."); return null; } catch (TaskCanceledException) From 245c492906aad3cd138b501363e9cdee914c484d Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 18 Sep 2025 21:13:12 +0800 Subject: [PATCH 72/75] Improve code quality --- Flow.Launcher/ViewModel/PluginViewModel.cs | 48 ++++++++++++---------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs index 59bb53a4a..c42791e8f 100644 --- a/Flow.Launcher/ViewModel/PluginViewModel.cs +++ b/Flow.Launcher/ViewModel/PluginViewModel.cs @@ -19,6 +19,9 @@ namespace Flow.Launcher.ViewModel private static readonly Settings Settings = Ioc.Default.GetRequiredService(); + private static readonly Thickness SettingPanelMargin = (Thickness)Application.Current.FindResource("SettingPanelMargin"); + private static readonly Thickness SettingPanelItemTopBottomMargin = (Thickness)Application.Current.FindResource("SettingPanelItemTopBottomMargin"); + private readonly PluginPair _pluginPair; public PluginPair PluginPair { @@ -139,8 +142,6 @@ namespace Flow.Launcher.ViewModel : null; private ImageSource _image = ImageLoader.MissingImage; - private static readonly Thickness SettingPanelMargin = (Thickness)Application.Current.FindResource("SettingPanelMargin"); - private static readonly Thickness SettingPanelItemTopBottomMargin = (Thickness)Application.Current.FindResource("SettingPanelItemTopBottomMargin"); private static Control TryCreateSettingPanel(PluginPair pair) { try @@ -156,25 +157,7 @@ namespace Flow.Launcher.ViewModel // Show error message in UI var errorMsg = string.Format(App.API.GetTranslation("errorCreatingSettingPanel"), pair.Metadata.Name, Environment.NewLine, e.Message); - var grid = new Grid() - { - Margin = SettingPanelMargin - }; - var textBox = new TextBox - { - Text = errorMsg, - IsReadOnly = true, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Top, - TextWrapping = TextWrapping.Wrap, - Margin = SettingPanelItemTopBottomMargin - }; - textBox.SetResourceReference(TextBlock.ForegroundProperty, "Color04B"); - grid.Children.Add(textBox); - return new UserControl - { - Content = grid - }; + return CreateErrorSettingPanel(errorMsg); } } @@ -228,5 +211,28 @@ namespace Flow.Launcher.ViewModel var changeKeywordsWindow = new ActionKeywords(this); changeKeywordsWindow.ShowDialog(); } + + private static UserControl CreateErrorSettingPanel(string text) + { + var grid = new Grid() + { + Margin = SettingPanelMargin + }; + var textBox = new TextBox + { + Text = text, + IsReadOnly = true, + HorizontalAlignment = HorizontalAlignment.Stretch, + VerticalAlignment = VerticalAlignment.Top, + TextWrapping = TextWrapping.Wrap, + Margin = SettingPanelItemTopBottomMargin + }; + textBox.SetResourceReference(TextBlock.ForegroundProperty, "Color04B"); + grid.Children.Add(textBox); + return new UserControl + { + Content = grid + }; + } } } From 72dae631fe8c3fd8e9cd7c466c3481be8ae3da7a Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 18 Sep 2025 21:19:49 +0800 Subject: [PATCH 73/75] Use TextBox.ForegroundProperty --- Flow.Launcher/ViewModel/PluginViewModel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs index c42791e8f..29f2b9b43 100644 --- a/Flow.Launcher/ViewModel/PluginViewModel.cs +++ b/Flow.Launcher/ViewModel/PluginViewModel.cs @@ -227,7 +227,7 @@ namespace Flow.Launcher.ViewModel TextWrapping = TextWrapping.Wrap, Margin = SettingPanelItemTopBottomMargin }; - textBox.SetResourceReference(TextBlock.ForegroundProperty, "Color04B"); + textBox.SetResourceReference(TextBox.ForegroundProperty, "Color04B"); grid.Children.Add(textBox); return new UserControl { From bbc12ec04123b7006b902001e860d9c78da4ef0d Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 18 Sep 2025 21:45:24 +0800 Subject: [PATCH 74/75] Revert "Disable cache feature" This reverts commit 9a597f2b4d1e3928c849b28de3d0b1b6cd7d84c8. --- Flow.Launcher/Helper/WallpaperPathRetrieval.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs index fe0ff39ad..fd04b3e88 100644 --- a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs +++ b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs @@ -15,9 +15,8 @@ public static class WallpaperPathRetrieval { private static readonly string ClassName = nameof(WallpaperPathRetrieval); - // Disable cache feature because some wallpaper applications (like Wallpaper Engine) may change wallpaper frequently - private const int MaxCacheSize = 0;//3; - private static readonly Dictionary<(string, DateTime), ImageBrush> WallpaperCache = []; + private const int MaxCacheSize = 3; + private static readonly Dictionary<(string, DateTime), ImageBrush> WallpaperCache = new(); private static readonly Lock CacheLock = new(); public static Brush GetWallpaperBrush() From 78e5bf2a601e30c41a7aaaf4428bfd7822f36a93 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sun, 21 Sep 2025 11:50:51 +0800 Subject: [PATCH 75/75] Use Flow.Launcher.Localization to improve code quality --- ...low.Launcher.Plugin.BrowserBookmark.csproj | 2 +- .../Flow.Launcher.Plugin.Calculator.csproj | 2 +- .../ContextMenu.cs | 114 ++++++++---------- .../Flow.Launcher.Plugin.Explorer.csproj | 2 +- .../Languages/en.xaml | 1 + Plugins/Flow.Launcher.Plugin.Explorer/Main.cs | 4 +- .../Everything/EverythingDownloadHelper.cs | 15 ++- .../Everything/EverythingSearchManager.cs | 14 +-- .../Search/ResultManager.cs | 29 ++--- .../Search/SearchManager.cs | 4 +- .../WindowsIndex/WindowsIndexSearchManager.cs | 4 +- .../Flow.Launcher.Plugin.Explorer/Settings.cs | 9 +- .../ViewModels/SettingsViewModel.cs | 12 +- .../Views/ActionKeywordSetting.xaml.cs | 12 +- .../Views/PreviewPanel.xaml.cs | 59 +++++---- .../Views/QuickAccessLinkSettings.xaml.cs | 4 +- 16 files changed, 134 insertions(+), 153 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj index 9cb2469d9..e3233f73d 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj @@ -104,7 +104,7 @@ - + diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj b/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj index b3cee425d..20a0ec4f0 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj @@ -63,7 +63,7 @@ - + diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs index 3802c701b..90db87966 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs @@ -66,8 +66,8 @@ namespace Flow.Launcher.Plugin.Explorer { contextMenus.Add(new Result { - Title = Context.API.GetTranslation("plugin_explorer_add_to_quickaccess_title"), - SubTitle = Context.API.GetTranslation("plugin_explorer_add_to_quickaccess_subtitle"), + Title = Localize.plugin_explorer_add_to_quickaccess_title(), + SubTitle = Localize.plugin_explorer_add_to_quickaccess_subtitle(), Action = (context) => { Settings.QuickAccessLinks.Add(new AccessLink @@ -77,16 +77,14 @@ namespace Flow.Launcher.Plugin.Explorer Type = record.Type }); - Context.API.ShowMsg(Context.API.GetTranslation("plugin_explorer_addfilefoldersuccess"), - Context.API.GetTranslation("plugin_explorer_addfilefoldersuccess_detail"), - Constants.ExplorerIconImageFullPath); - - + Context.API.ShowMsg(Localize.plugin_explorer_addfilefoldersuccess(), + Localize.plugin_explorer_addfilefoldersuccess_detail(), + Constants.ExplorerIconImageFullPath); return true; }, - SubTitleToolTip = Context.API.GetTranslation("plugin_explorer_contextmenu_titletooltip"), - TitleToolTip = Context.API.GetTranslation("plugin_explorer_contextmenu_titletooltip"), + SubTitleToolTip = Localize.plugin_explorer_contextmenu_titletooltip(), + TitleToolTip = Localize.plugin_explorer_contextmenu_titletooltip(), IcoPath = Constants.QuickAccessImagePath, Glyph = new GlyphInfo(FontFamily: "/Resources/#Segoe Fluent Icons", Glyph: "\ue718"), }); @@ -95,22 +93,20 @@ namespace Flow.Launcher.Plugin.Explorer { contextMenus.Add(new Result { - Title = Context.API.GetTranslation("plugin_explorer_remove_from_quickaccess_title"), - SubTitle = Context.API.GetTranslation("plugin_explorer_remove_from_quickaccess_subtitle"), + Title = Localize.plugin_explorer_remove_from_quickaccess_title(), + SubTitle = Localize.plugin_explorer_remove_from_quickaccess_subtitle(), Action = (context) => { Settings.QuickAccessLinks.Remove(Settings.QuickAccessLinks.FirstOrDefault(x => string.Equals(x.Path, record.FullPath, StringComparison.OrdinalIgnoreCase))); - Context.API.ShowMsg(Context.API.GetTranslation("plugin_explorer_removefilefoldersuccess"), - Context.API.GetTranslation("plugin_explorer_removefilefoldersuccess_detail"), - Constants.ExplorerIconImageFullPath); - - + Context.API.ShowMsg(Localize.plugin_explorer_removefilefoldersuccess(), + Localize.plugin_explorer_removefilefoldersuccess_detail(), + Constants.ExplorerIconImageFullPath); return true; }, - SubTitleToolTip = Context.API.GetTranslation("plugin_explorer_contextmenu_remove_titletooltip"), - TitleToolTip = Context.API.GetTranslation("plugin_explorer_contextmenu_remove_titletooltip"), + SubTitleToolTip = Localize.plugin_explorer_contextmenu_remove_titletooltip(), + TitleToolTip = Localize.plugin_explorer_contextmenu_remove_titletooltip(), IcoPath = Constants.RemoveQuickAccessImagePath, Glyph = new GlyphInfo(FontFamily: "/Resources/#Segoe Fluent Icons", Glyph: "\uecc9") }); @@ -118,8 +114,8 @@ namespace Flow.Launcher.Plugin.Explorer contextMenus.Add(new Result { - Title = Context.API.GetTranslation("plugin_explorer_copypath"), - SubTitle = Context.API.GetTranslation("plugin_explorer_copypath_subtitle"), + Title = Localize.plugin_explorer_copypath(), + SubTitle = Localize.plugin_explorer_copypath_subtitle(), Action = _ => { try @@ -130,7 +126,7 @@ namespace Flow.Launcher.Plugin.Explorer catch (Exception e) { LogException("Fail to set text in clipboard", e); - Context.API.ShowMsgError(Context.API.GetTranslation("plugin_explorer_fail_to_set_text")); + Context.API.ShowMsgError(Localize.plugin_explorer_fail_to_set_text()); return false; } }, @@ -140,8 +136,8 @@ namespace Flow.Launcher.Plugin.Explorer contextMenus.Add(new Result { - Title = Context.API.GetTranslation("plugin_explorer_copyname"), - SubTitle = Context.API.GetTranslation("plugin_explorer_copyname_subtitle"), + Title = Localize.plugin_explorer_copyname(), + SubTitle = Localize.plugin_explorer_copyname_subtitle(), Action = _ => { try @@ -152,7 +148,7 @@ namespace Flow.Launcher.Plugin.Explorer catch (Exception e) { LogException("Fail to set text in clipboard", e); - Context.API.ShowMsgError(Context.API.GetTranslation("plugin_explorer_fail_to_set_text")); + Context.API.ShowMsgError(Localize.plugin_explorer_fail_to_set_text()); return false; } }, @@ -162,8 +158,8 @@ namespace Flow.Launcher.Plugin.Explorer contextMenus.Add(new Result { - Title = Context.API.GetTranslation("plugin_explorer_copyfilefolder"), - SubTitle = isFile ? Context.API.GetTranslation("plugin_explorer_copyfile_subtitle") : Context.API.GetTranslation("plugin_explorer_copyfolder_subtitle"), + Title = Localize.plugin_explorer_copyfilefolder(), + SubTitle = isFile ? Localize.plugin_explorer_copyfile_subtitle(): Localize.plugin_explorer_copyfolder_subtitle(), Action = _ => { try @@ -174,28 +170,26 @@ namespace Flow.Launcher.Plugin.Explorer catch (Exception e) { LogException($"Fail to set file/folder in clipboard", e); - Context.API.ShowMsgError(Context.API.GetTranslation("plugin_explorer_fail_to_set_files")); + Context.API.ShowMsgError(Localize.plugin_explorer_fail_to_set_files()); return false; } - }, IcoPath = icoPath, Glyph = new GlyphInfo(FontFamily: "/Resources/#Segoe Fluent Icons", Glyph: "\uf12b") }); - if (record.Type is ResultType.File or ResultType.Folder) contextMenus.Add(new Result { - Title = Context.API.GetTranslation("plugin_explorer_deletefilefolder"), - SubTitle = isFile ? Context.API.GetTranslation("plugin_explorer_deletefile_subtitle") : Context.API.GetTranslation("plugin_explorer_deletefolder_subtitle"), + Title = Localize.plugin_explorer_deletefilefolder(), + SubTitle = isFile ? Localize.plugin_explorer_deletefile_subtitle(): Localize.plugin_explorer_deletefolder_subtitle(), Action = (context) => { try { if (Context.API.ShowMsgBox( - string.Format(Context.API.GetTranslation("plugin_explorer_delete_folder_link"), record.FullPath), - Context.API.GetTranslation("plugin_explorer_deletefilefolder"), + Localize.plugin_explorer_delete_folder_link(record.FullPath), + Localize.plugin_explorer_deletefilefolder(), MessageBoxButton.OKCancel, MessageBoxImage.Warning) == MessageBoxResult.Cancel) @@ -208,15 +202,15 @@ namespace Flow.Launcher.Plugin.Explorer _ = Task.Run(() => { - Context.API.ShowMsg(Context.API.GetTranslation("plugin_explorer_deletefilefoldersuccess"), - string.Format(Context.API.GetTranslation("plugin_explorer_deletefilefoldersuccess_detail"), record.FullPath), + Context.API.ShowMsg(Localize.plugin_explorer_deletefilefoldersuccess(), + Localize.plugin_explorer_deletefilefoldersuccess_detail(record.FullPath), Constants.ExplorerIconImageFullPath); }); } catch (Exception e) { LogException($"Fail to delete {record.FullPath}", e); - Context.API.ShowMsgError(string.Format(Context.API.GetTranslation("plugin_explorer_fail_to_delete"), record.FullPath)); + Context.API.ShowMsgError(Localize.plugin_explorer_fail_to_delete(record.FullPath)); return false; } @@ -230,7 +224,7 @@ namespace Flow.Launcher.Plugin.Explorer { contextMenus.Add(new Result() { - Title = Context.API.GetTranslation("plugin_explorer_show_contextmenu_title"), + Title = Localize.plugin_explorer_show_contextmenu_title(), IcoPath = Constants.ShowContextMenuImagePath, Glyph = new GlyphInfo(FontFamily: "/Resources/#Segoe Fluent Icons", Glyph: "\ue700"), Action = _ => @@ -248,8 +242,8 @@ namespace Flow.Launcher.Plugin.Explorer if (record.Type == ResultType.File && CanRunAsDifferentUser(record.FullPath)) contextMenus.Add(new Result { - Title = Context.API.GetTranslation("plugin_explorer_runasdifferentuser"), - SubTitle = Context.API.GetTranslation("plugin_explorer_runasdifferentuser_subtitle"), + Title = Localize.plugin_explorer_runasdifferentuser(), + SubTitle = Localize.plugin_explorer_runasdifferentuser_subtitle(), Action = (context) => { try @@ -259,8 +253,8 @@ namespace Flow.Launcher.Plugin.Explorer catch (FileNotFoundException e) { Context.API.ShowMsgError( - Context.API.GetTranslation("plugin_explorer_plugin_name"), - string.Format(Context.API.GetTranslation("plugin_explorer_file_not_found"), e.Message)); + Localize.plugin_explorer_plugin_name(), + Localize.plugin_explorer_file_not_found(e.Message)); return false; } @@ -317,8 +311,8 @@ namespace Flow.Launcher.Plugin.Explorer { return new Result { - Title = Context.API.GetTranslation("plugin_explorer_opencontainingfolder"), - SubTitle = Context.API.GetTranslation("plugin_explorer_opencontainingfolder_subtitle"), + Title = Localize.plugin_explorer_opencontainingfolder(), + SubTitle = Localize.plugin_explorer_opencontainingfolder_subtitle(), Action = _ => { try @@ -328,7 +322,7 @@ namespace Flow.Launcher.Plugin.Explorer catch (Exception e) { LogException($"Fail to open file at {record.FullPath}", e); - Context.API.ShowMsgError(string.Format(Context.API.GetTranslation("plugin_explorer_fail_to_open"), record.FullPath)); + Context.API.ShowMsgError(Localize.plugin_explorer_fail_to_open(record.FullPath)); return false; } @@ -339,11 +333,9 @@ namespace Flow.Launcher.Plugin.Explorer }; } - - private Result CreateOpenWithEditorResult(SearchResult record, string editorPath) { - var name = $"{Context.API.GetTranslation("plugin_explorer_openwitheditor")} {Path.GetFileNameWithoutExtension(editorPath)}"; + var name = $"{Localize.plugin_explorer_openwitheditor()} {Path.GetFileNameWithoutExtension(editorPath)}"; return new Result { @@ -361,8 +353,7 @@ namespace Flow.Launcher.Plugin.Explorer } catch (Exception e) { - var raw_message = Context.API.GetTranslation("plugin_explorer_openwitheditor_error"); - var message = string.Format(raw_message, record.FullPath, Path.GetFileNameWithoutExtension(editorPath), editorPath); + var message = Localize.plugin_explorer_openwitheditor_error(record.FullPath, Path.GetFileNameWithoutExtension(editorPath), editorPath); LogException(message, e); Context.API.ShowMsgError(message); return false; @@ -377,7 +368,7 @@ namespace Flow.Launcher.Plugin.Explorer { string shellPath = Settings.ShellPath; - var name = $"{Context.API.GetTranslation("plugin_explorer_openwithshell")} {Path.GetFileNameWithoutExtension(shellPath)}"; + var name = $"{Localize.plugin_explorer_openwithshell()} {Path.GetFileNameWithoutExtension(shellPath)}"; return new Result { @@ -394,8 +385,7 @@ namespace Flow.Launcher.Plugin.Explorer } catch (Exception e) { - var raw_message = Context.API.GetTranslation("plugin_explorer_openwithshell_error"); - var message = string.Format(raw_message, record.FullPath, Path.GetFileNameWithoutExtension(shellPath), shellPath); + var message = Localize.plugin_explorer_openwithshell_error(record.FullPath, Path.GetFileNameWithoutExtension(shellPath), shellPath); LogException(message, e); Context.API.ShowMsgError(message); return false; @@ -410,8 +400,8 @@ namespace Flow.Launcher.Plugin.Explorer { return new Result { - Title = Context.API.GetTranslation("plugin_explorer_excludefromindexsearch"), - SubTitle = Context.API.GetTranslation("plugin_explorer_path") + " " + record.FullPath, + Title = Localize.plugin_explorer_excludefromindexsearch(), + SubTitle = Localize.plugin_explorer_path()+ " " + record.FullPath, Action = c_ => { if (!Settings.IndexSearchExcludedSubdirectoryPaths.Any(x => string.Equals(x.Path, record.FullPath, StringComparison.OrdinalIgnoreCase))) @@ -422,8 +412,8 @@ namespace Flow.Launcher.Plugin.Explorer _ = Task.Run(() => { - Context.API.ShowMsg(Context.API.GetTranslation("plugin_explorer_excludedfromindexsearch_msg"), - Context.API.GetTranslation("plugin_explorer_path") + + Context.API.ShowMsg(Localize.plugin_explorer_excludedfromindexsearch_msg(), + Localize.plugin_explorer_path()+ " " + record.FullPath, Constants.ExplorerIconImageFullPath); // so the new path can be persisted to storage and not wait till next ViewModel save. @@ -441,8 +431,8 @@ namespace Flow.Launcher.Plugin.Explorer { return new Result { - Title = Context.API.GetTranslation("plugin_explorer_openindexingoptions"), - SubTitle = Context.API.GetTranslation("plugin_explorer_openindexingoptions_subtitle"), + Title = Localize.plugin_explorer_openindexingoptions(), + SubTitle = Localize.plugin_explorer_openindexingoptions_subtitle(), Action = _ => { try @@ -459,7 +449,7 @@ namespace Flow.Launcher.Plugin.Explorer } catch (Exception e) { - var message = Context.API.GetTranslation("plugin_explorer_openindexingoptions_errormsg"); + var message = Localize.plugin_explorer_openindexingoptions_errormsg(); LogException(message, e); Context.API.ShowMsgError(message); return false; @@ -470,12 +460,12 @@ namespace Flow.Launcher.Plugin.Explorer }; } - private Result CreateOpenWithMenu(SearchResult record) + private static Result CreateOpenWithMenu(SearchResult record) { return new Result { - Title = Context.API.GetTranslation("plugin_explorer_openwith"), - SubTitle = Context.API.GetTranslation("plugin_explorer_openwith_subtitle"), + Title = Localize.plugin_explorer_openwith(), + SubTitle = Localize.plugin_explorer_openwith_subtitle(), Action = _ => { Process.Start("rundll32.exe", $"{Path.Combine(Environment.SystemDirectory, "shell32.dll")},OpenAs_RunDLL {record.FullPath}"); diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj index b7c54e578..a837a49b4 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj @@ -48,7 +48,7 @@ - + diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml index 16ef037cc..c40040df5 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml @@ -24,6 +24,7 @@ Error occurred during search: {0} Could not open folder Could not open file + This new action keyword is already assigned to another plugin, please choose a different one Delete diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs index d93c6c77b..f5b8b9325 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs @@ -90,12 +90,12 @@ namespace Flow.Launcher.Plugin.Explorer public string GetTranslatedPluginTitle() { - return Context.API.GetTranslation("plugin_explorer_plugin_name"); + return Localize.plugin_explorer_plugin_name(); } public string GetTranslatedPluginDescription() { - return Context.API.GetTranslation("plugin_explorer_plugin_description"); + return Localize.plugin_explorer_plugin_description(); } public void OnCultureInfoChanged(CultureInfo newCulture) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingDownloadHelper.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingDownloadHelper.cs index c8bd68279..13d988f1a 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingDownloadHelper.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingDownloadHelper.cs @@ -21,9 +21,9 @@ public static class EverythingDownloadHelper if (string.IsNullOrEmpty(installedLocation)) { if (api.ShowMsgBox( - string.Format(api.GetTranslation("flowlauncher_plugin_everything_installing_select"), Environment.NewLine), - api.GetTranslation("flowlauncher_plugin_everything_installing_title"), - MessageBoxButton.YesNo) == MessageBoxResult.Yes) + Localize.flowlauncher_plugin_everything_installing_select(Environment.NewLine), + Localize.flowlauncher_plugin_everything_installing_title(), + MessageBoxButton.YesNo) == MessageBoxResult.Yes) { var dlg = new System.Windows.Forms.OpenFileDialog { @@ -41,13 +41,13 @@ public static class EverythingDownloadHelper return installedLocation; } - api.ShowMsg(api.GetTranslation("flowlauncher_plugin_everything_installing_title"), - api.GetTranslation("flowlauncher_plugin_everything_installing_subtitle"), "", useMainWindowAsOwner: false); + api.ShowMsg(Localize.flowlauncher_plugin_everything_installing_title(), + Localize.flowlauncher_plugin_everything_installing_subtitle(), "", useMainWindowAsOwner: false); await DroplexPackage.Drop(App.Everything1_4_1_1009).ConfigureAwait(false); - api.ShowMsg(api.GetTranslation("flowlauncher_plugin_everything_installing_title"), - api.GetTranslation("flowlauncher_plugin_everything_installationsuccess_subtitle"), "", useMainWindowAsOwner: false); + api.ShowMsg(Localize.flowlauncher_plugin_everything_installing_title(), + Localize.flowlauncher_plugin_everything_installationsuccess_subtitle(), "", useMainWindowAsOwner: false); installedLocation = "C:\\Program Files\\Everything\\Everything.exe"; @@ -83,6 +83,5 @@ public static class EverythingDownloadHelper var scoopInstalledPath = Environment.ExpandEnvironmentVariables(@"%userprofile%\scoop\apps\everything\current\Everything.exe"); return File.Exists(scoopInstalledPath) ? scoopInstalledPath : string.Empty; - } } diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingSearchManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingSearchManager.cs index ce71c94ba..eb994a6f9 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingSearchManager.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingSearchManager.cs @@ -27,8 +27,8 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything if (!await EverythingApi.IsEverythingRunningAsync(token)) throw new EngineNotAvailableException( Enum.GetName(Settings.IndexSearchEngineOption.Everything)!, - Main.Context.API.GetTranslation("flowlauncher_plugin_everything_click_to_launch_or_install"), - Main.Context.API.GetTranslation("flowlauncher_plugin_everything_is_not_running"), + Localize.flowlauncher_plugin_everything_click_to_launch_or_install(), + Localize.flowlauncher_plugin_everything_is_not_running(), Constants.EverythingErrorImagePath, ClickToInstallEverythingAsync); } @@ -38,7 +38,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything Enum.GetName(Settings.IndexSearchEngineOption.Everything)!, "Please check whether your system is x86 or x64", Constants.GeneralSearchErrorImagePath, - Main.Context.API.GetTranslation("flowlauncher_plugin_everything_sdk_issue")); + Localize.flowlauncher_plugin_everything_sdk_issue()); } } @@ -50,7 +50,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything if (installedPath == null) { - Main.Context.API.ShowMsgError(Main.Context.API.GetTranslation("flowlauncher_plugin_everything_not_found")); + Main.Context.API.ShowMsgError(Localize.flowlauncher_plugin_everything_not_found()); Main.Context.API.LogError(ClassName, "Unable to find Everything.exe"); return false; @@ -65,7 +65,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything // Just let the user know that Everything is not installed properly and ask them to install it manually catch (Exception e) { - Main.Context.API.ShowMsgError(Main.Context.API.GetTranslation("flowlauncher_plugin_everything_install_issue")); + Main.Context.API.ShowMsgError(Localize.flowlauncher_plugin_everything_install_issue()); Main.Context.API.LogException(ClassName, "Failed to install Everything", e); return false; @@ -97,8 +97,8 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything if (!Settings.EnableEverythingContentSearch) { throw new EngineNotAvailableException(Enum.GetName(Settings.IndexSearchEngineOption.Everything)!, - Main.Context.API.GetTranslation("flowlauncher_plugin_everything_enable_content_search"), - Main.Context.API.GetTranslation("flowlauncher_plugin_everything_enable_content_search_tips"), + Localize.flowlauncher_plugin_everything_enable_content_search(), + Localize.flowlauncher_plugin_everything_enable_content_search_tips(), Constants.EverythingErrorImagePath, _ => { diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs index dfa2c8d43..18eb168b9 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Linq; using System.Threading.Tasks; @@ -124,7 +124,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search } catch (Exception ex) { - Context.API.ShowMsgBox(ex.Message, Context.API.GetTranslation("plugin_explorer_opendir_error")); + Context.API.ShowMsgBox(ex.Message, Localize.plugin_explorer_opendir_error()); return false; } } @@ -138,7 +138,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search } catch (Exception ex) { - Context.API.ShowMsgBox(ex.Message, Context.API.GetTranslation("plugin_explorer_opendir_error")); + Context.API.ShowMsgBox(ex.Message, Localize.plugin_explorer_opendir_error()); return false; } } @@ -153,7 +153,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search } catch (Exception ex) { - Context.API.ShowMsgBox(ex.Message, Context.API.GetTranslation("plugin_explorer_opendir_error")); + Context.API.ShowMsgBox(ex.Message, Localize.plugin_explorer_opendir_error()); return false; } } @@ -166,7 +166,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search return false; }, Score = score, - TitleToolTip = Main.Context.API.GetTranslation("plugin_explorer_plugin_ToolTipOpenDirectory"), + TitleToolTip = Localize.plugin_explorer_plugin_ToolTipOpenDirectory(), SubTitleToolTip = Settings.DisplayMoreInformationInToolTip ? GetFolderMoreInfoTooltip(path) : path, ContextData = new SearchResult { Type = ResultType.Folder, FullPath = path, WindowsIndexed = windowsIndexed } }; @@ -190,7 +190,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search DriveInfo drv = new DriveInfo(driveLetter); var freespace = ToReadableSize(drv.AvailableFreeSpace, 2); var totalspace = ToReadableSize(drv.TotalSize, 2); - var subtitle = string.Format(Context.API.GetTranslation("plugin_explorer_diskfreespace"), freespace, totalspace); + var subtitle = Localize.plugin_explorer_diskfreespace(freespace, totalspace); double usingSize = (Convert.ToDouble(drv.TotalSize) - Convert.ToDouble(drv.AvailableFreeSpace)) / Convert.ToDouble(drv.TotalSize) * 100; int? progressValue = Convert.ToInt32(usingSize); @@ -262,8 +262,8 @@ namespace Flow.Launcher.Plugin.Explorer.Search return new Result { - Title = Context.API.GetTranslation("plugin_explorer_openresultfolder"), - SubTitle = Context.API.GetTranslation("plugin_explorer_openresultfolder_subtitle"), + Title = Localize.plugin_explorer_openresultfolder(), + SubTitle = Localize.plugin_explorer_openresultfolder_subtitle(), AutoCompleteText = GetPathWithActionKeyword(folderPath, ResultType.Folder, actionKeyword), IcoPath = folderPath, Score = 500, @@ -330,12 +330,12 @@ namespace Flow.Launcher.Plugin.Explorer.Search } catch (Exception ex) { - Context.API.ShowMsgBox(ex.Message, Context.API.GetTranslation("plugin_explorer_openfile_error")); + Context.API.ShowMsgBox(ex.Message, Localize.plugin_explorer_openfile_error()); } return true; }, - TitleToolTip = Main.Context.API.GetTranslation("plugin_explorer_plugin_ToolTipOpenContainingFolder"), + TitleToolTip = Localize.plugin_explorer_plugin_ToolTipOpenContainingFolder(), SubTitleToolTip = Settings.DisplayMoreInformationInToolTip ? GetFileMoreInfoTooltip(filePath) : filePath, ContextData = new SearchResult { Type = ResultType.File, FullPath = filePath, WindowsIndexed = windowsIndexed } }; @@ -374,8 +374,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search var fileSize = PreviewPanel.GetFileSize(filePath); var fileCreatedAt = PreviewPanel.GetFileCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel); var fileModifiedAt = PreviewPanel.GetFileLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel); - return string.Format(Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info"), - filePath, fileSize, fileCreatedAt, fileModifiedAt, Environment.NewLine); + return Localize.plugin_explorer_plugin_tooltip_more_info(filePath, fileSize, fileCreatedAt, fileModifiedAt, Environment.NewLine); } catch (Exception e) { @@ -391,8 +390,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search var folderSize = PreviewPanel.GetFolderSize(folderPath); var folderCreatedAt = PreviewPanel.GetFolderCreatedAt(folderPath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel); var folderModifiedAt = PreviewPanel.GetFolderLastModifiedAt(folderPath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel); - return string.Format(Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info"), - folderPath, folderSize, folderCreatedAt, folderModifiedAt, Environment.NewLine); + return Localize.plugin_explorer_plugin_tooltip_more_info(folderPath, folderSize, folderCreatedAt, folderModifiedAt, Environment.NewLine); } catch (Exception e) { @@ -403,8 +401,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search private static string GetVolumeMoreInfoTooltip(string volumePath, string freespace, string totalspace) { - return string.Format(Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_volume"), - volumePath, freespace, totalspace, Environment.NewLine); + return Localize.plugin_explorer_plugin_tooltip_more_info_volume(volumePath, freespace, totalspace, Environment.NewLine); } private static readonly string[] MediaExtensions = diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs index f4f87d4d4..f9d8963e6 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs @@ -161,8 +161,8 @@ namespace Flow.Launcher.Plugin.Explorer.Search { new() { - Title = Context.API.GetTranslation("flowlauncher_plugin_everything_enable_content_search"), - SubTitle = Context.API.GetTranslation("flowlauncher_plugin_everything_enable_content_search_tips"), + Title = Localize.flowlauncher_plugin_everything_enable_content_search(), + SubTitle = Localize.flowlauncher_plugin_everything_enable_content_search_tips(), IcoPath = "Images/index_error.png", Action = c => { diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/WindowsIndexSearchManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/WindowsIndexSearchManager.cs index 3d69a1ee6..eeb5c2c4a 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/WindowsIndexSearchManager.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/WindowsIndexSearchManager.cs @@ -105,8 +105,8 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex throw new EngineNotAvailableException( "Windows Index", - Main.Context.API.GetTranslation("plugin_explorer_windowsSearchServiceFix"), - Main.Context.API.GetTranslation("plugin_explorer_windowsSearchServiceNotRunning"), + Localize.plugin_explorer_windowsSearchServiceFix(), + Localize.plugin_explorer_windowsSearchServiceNotRunning(), Constants.WindowsIndexErrorImagePath, c => { diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs index 672e81d03..8d62531cd 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs @@ -14,9 +14,9 @@ namespace Flow.Launcher.Plugin.Explorer { public int MaxResult { get; set; } = 100; - public ObservableCollection QuickAccessLinks { get; set; } = new(); + public ObservableCollection QuickAccessLinks { get; set; } = []; - public ObservableCollection IndexSearchExcludedSubdirectoryPaths { get; set; } = new ObservableCollection(); + public ObservableCollection IndexSearchExcludedSubdirectoryPaths { get; set; } = []; public string EditorPath { get; set; } = ""; @@ -58,7 +58,6 @@ namespace Flow.Launcher.Plugin.Explorer public bool QuickAccessKeywordEnabled { get; set; } - public bool WarnWindowsSearchServiceOff { get; set; } = true; public bool ShowFileSizeInPreviewPanel { get; set; } = true; @@ -69,7 +68,6 @@ namespace Flow.Launcher.Plugin.Explorer public bool ShowFileAgeInPreviewPanel { get; set; } = false; - public string PreviewPanelDateFormat { get; set; } = "yyyy-MM-dd"; public string PreviewPanelTimeFormat { get; set; } = "HH:mm"; @@ -82,8 +80,8 @@ namespace Flow.Launcher.Plugin.Explorer private EverythingSearchManager EverythingManagerInstance => _everythingManagerInstance ??= new EverythingSearchManager(this); private WindowsIndexSearchManager WindowsIndexSearchManager => _windowsIndexSearchManager ??= new WindowsIndexSearchManager(this); - public IndexSearchEngineOption IndexSearchEngine { get; set; } = IndexSearchEngineOption.WindowsIndex; + [JsonIgnore] public IIndexProvider IndexProvider => IndexSearchEngine switch { @@ -139,7 +137,6 @@ namespace Flow.Launcher.Plugin.Explorer #endregion - #region Everything Settings public string EverythingInstalledPath { get; set; } diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs index ae2235c5c..2d46c6307 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs @@ -296,7 +296,7 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels return; } - var actionKeywordWindow = new ActionKeywordSetting(actionKeyword, Context.API); + var actionKeywordWindow = new ActionKeywordSetting(actionKeyword); if (!(actionKeywordWindow.ShowDialog() ?? false)) { @@ -432,8 +432,8 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels case "QuickAccessLink": if (SelectedQuickAccessLink == null) return; if (Context.API.ShowMsgBox( - Context.API.GetTranslation("plugin_explorer_delete_quick_access_link"), - Context.API.GetTranslation("plugin_explorer_delete"), + Localize.plugin_explorer_delete_quick_access_link(), + Localize.plugin_explorer_delete(), MessageBoxButton.OKCancel, MessageBoxImage.Warning) == MessageBoxResult.Cancel) @@ -443,8 +443,8 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels case "IndexSearchExcludedPaths": if (SelectedIndexSearchExcludedPath == null) return; if (Context.API.ShowMsgBox( - Context.API.GetTranslation("plugin_explorer_delete_index_search_excluded_path"), - Context.API.GetTranslation("plugin_explorer_delete"), + Localize.plugin_explorer_delete_index_search_excluded_path(), + Localize.plugin_explorer_delete(), MessageBoxButton.OKCancel, MessageBoxImage.Warning) == MessageBoxResult.Cancel) @@ -457,7 +457,7 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels private void ShowUnselectedMessage() { - var warning = Context.API.GetTranslation("plugin_explorer_make_selection_warning"); + var warning = Localize.plugin_explorer_make_selection_warning(); Context.API.ShowMsgBox(warning); } diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs index 829a2feed..562170062 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs @@ -29,13 +29,11 @@ namespace Flow.Launcher.Plugin.Explorer.Views } private string actionKeyword; - private readonly IPublicAPI _api; private bool _keywordEnabled; - public ActionKeywordSetting(ActionKeywordModel selectedActionKeyword, IPublicAPI api) + public ActionKeywordSetting(ActionKeywordModel selectedActionKeyword) { CurrentActionKeyword = selectedActionKeyword; - _api = api; ActionKeyword = selectedActionKeyword.Keyword; KeywordEnabled = selectedActionKeyword.Enabled; @@ -60,14 +58,14 @@ namespace Flow.Launcher.Plugin.Explorer.Views switch (CurrentActionKeyword.KeywordProperty, KeywordEnabled) { case (Settings.ActionKeyword.FileContentSearchActionKeyword, true): - _api.ShowMsgBox(_api.GetTranslation("plugin_explorer_globalActionKeywordInvalid")); + Main.Context.API.ShowMsgBox(Localize.plugin_explorer_globalActionKeywordInvalid()); return; case (Settings.ActionKeyword.QuickAccessActionKeyword, true): - _api.ShowMsgBox(_api.GetTranslation("plugin_explorer_quickaccess_globalActionKeywordInvalid")); + Main.Context.API.ShowMsgBox(Localize.plugin_explorer_quickaccess_globalActionKeywordInvalid()); return; } - if (!KeywordEnabled || !_api.ActionKeywordAssigned(ActionKeyword)) + if (!KeywordEnabled || !Main.Context.API.ActionKeywordAssigned(ActionKeyword)) { DialogResult = true; Close(); @@ -75,7 +73,7 @@ namespace Flow.Launcher.Plugin.Explorer.Views } // The keyword is not valid, so show message - _api.ShowMsgBox(_api.GetTranslation("newActionKeywordsHasBeenAssigned")); + Main.Context.API.ShowMsgBox(Localize.plugin_explorer_new_action_keyword_assigned()); } private void BtnCancel_OnClick(object sender, RoutedEventArgs e) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs index 4dd0588ee..3c627cc06 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs @@ -25,7 +25,7 @@ public partial class PreviewPanel : UserControl public string FileName { get; } [ObservableProperty] - private string _fileSize = Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown"); + private string _fileSize = Localize.plugin_explorer_plugin_tooltip_more_info_unknown(); [ObservableProperty] private string _createdAt = ""; @@ -111,17 +111,17 @@ public partial class PreviewPanel : UserControl catch (FileNotFoundException) { Main.Context.API.LogError(ClassName, $"File not found: {filePath}"); - return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown"); + return Localize.plugin_explorer_plugin_tooltip_more_info_unknown(); } catch (UnauthorizedAccessException) { Main.Context.API.LogError(ClassName, $"Access denied to file: {filePath}"); - return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown"); + return Localize.plugin_explorer_plugin_tooltip_more_info_unknown(); } catch (Exception e) { Main.Context.API.LogException(ClassName, $"Failed to get file size for {filePath}", e); - return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown"); + return Localize.plugin_explorer_plugin_tooltip_more_info_unknown(); } } @@ -142,17 +142,17 @@ public partial class PreviewPanel : UserControl catch (FileNotFoundException) { Main.Context.API.LogError(ClassName, $"File not found: {filePath}"); - return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown"); + return Localize.plugin_explorer_plugin_tooltip_more_info_unknown(); } catch (UnauthorizedAccessException) { Main.Context.API.LogError(ClassName, $"Access denied to file: {filePath}"); - return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown"); + return Localize.plugin_explorer_plugin_tooltip_more_info_unknown(); } catch (Exception e) { Main.Context.API.LogException(ClassName, $"Failed to get file created date for {filePath}", e); - return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown"); + return Localize.plugin_explorer_plugin_tooltip_more_info_unknown(); } } @@ -173,17 +173,17 @@ public partial class PreviewPanel : UserControl catch (FileNotFoundException) { Main.Context.API.LogError(ClassName, $"File not found: {filePath}"); - return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown"); + return Localize.plugin_explorer_plugin_tooltip_more_info_unknown(); } catch (UnauthorizedAccessException) { Main.Context.API.LogError(ClassName, $"Access denied to file: {filePath}"); - return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown"); + return Localize.plugin_explorer_plugin_tooltip_more_info_unknown(); } catch (Exception e) { Main.Context.API.LogException(ClassName, $"Failed to get file modified date for {filePath}", e); - return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown"); + return Localize.plugin_explorer_plugin_tooltip_more_info_unknown(); } } @@ -205,17 +205,17 @@ public partial class PreviewPanel : UserControl catch (FileNotFoundException) { Main.Context.API.LogError(ClassName, $"Folder not found: {folderPath}"); - return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown"); + return Localize.plugin_explorer_plugin_tooltip_more_info_unknown(); } catch (UnauthorizedAccessException) { Main.Context.API.LogError(ClassName, $"Access denied to folder: {folderPath}"); - return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown"); + return Localize.plugin_explorer_plugin_tooltip_more_info_unknown(); } catch (OperationCanceledException) { Main.Context.API.LogError(ClassName, $"Operation timed out while calculating folder size for {folderPath}"); - return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown"); + return Localize.plugin_explorer_plugin_tooltip_more_info_unknown(); } // For parallel operations, AggregateException may be thrown if any of the tasks fail catch (AggregateException ae) @@ -224,22 +224,22 @@ public partial class PreviewPanel : UserControl { case FileNotFoundException: Main.Context.API.LogError(ClassName, $"Folder not found: {folderPath}"); - return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown"); + return Localize.plugin_explorer_plugin_tooltip_more_info_unknown(); case UnauthorizedAccessException: Main.Context.API.LogError(ClassName, $"Access denied to folder: {folderPath}"); - return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown"); + return Localize.plugin_explorer_plugin_tooltip_more_info_unknown(); case OperationCanceledException: Main.Context.API.LogError(ClassName, $"Operation timed out while calculating folder size for {folderPath}"); - return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown"); + return Localize.plugin_explorer_plugin_tooltip_more_info_unknown(); default: Main.Context.API.LogException(ClassName, $"Failed to get folder size for {folderPath}", ae); - return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown"); + return Localize.plugin_explorer_plugin_tooltip_more_info_unknown(); } } catch (Exception e) { Main.Context.API.LogException(ClassName, $"Failed to get folder size for {folderPath}", e); - return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown"); + return Localize.plugin_explorer_plugin_tooltip_more_info_unknown(); } } @@ -260,17 +260,17 @@ public partial class PreviewPanel : UserControl catch (FileNotFoundException) { Main.Context.API.LogError(ClassName, $"Folder not found: {folderPath}"); - return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown"); + return Localize.plugin_explorer_plugin_tooltip_more_info_unknown(); } catch (UnauthorizedAccessException) { Main.Context.API.LogError(ClassName, $"Access denied to folder: {folderPath}"); - return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown"); + return Localize.plugin_explorer_plugin_tooltip_more_info_unknown(); } catch (Exception e) { Main.Context.API.LogException(ClassName, $"Failed to get folder created date for {folderPath}", e); - return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown"); + return Localize.plugin_explorer_plugin_tooltip_more_info_unknown(); } } @@ -291,17 +291,17 @@ public partial class PreviewPanel : UserControl catch (FileNotFoundException) { Main.Context.API.LogError(ClassName, $"Folder not found: {folderPath}"); - return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown"); + return Localize.plugin_explorer_plugin_tooltip_more_info_unknown(); } catch (UnauthorizedAccessException) { Main.Context.API.LogError(ClassName, $"Access denied to folder: {folderPath}"); - return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown"); + return Localize.plugin_explorer_plugin_tooltip_more_info_unknown(); } catch (Exception e) { Main.Context.API.LogException(ClassName, $"Failed to get folder modified date for {folderPath}", e); - return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown"); + return Localize.plugin_explorer_plugin_tooltip_more_info_unknown(); } } @@ -311,21 +311,20 @@ public partial class PreviewPanel : UserControl var difference = now - fileDateTime; if (difference.TotalDays < 1) - return Main.Context.API.GetTranslation("Today"); + return Localize.Today(); if (difference.TotalDays < 30) - return string.Format(Main.Context.API.GetTranslation("DaysAgo"), (int)difference.TotalDays); + return Localize.DaysAgo((int)difference.TotalDays); var monthsDiff = (now.Year - fileDateTime.Year) * 12 + now.Month - fileDateTime.Month; if (monthsDiff == 1) - return Main.Context.API.GetTranslation("OneMonthAgo"); + return Localize.OneMonthAgo(); if (monthsDiff < 12) - return string.Format(Main.Context.API.GetTranslation("MonthsAgo"), monthsDiff); + return Localize.MonthsAgo(monthsDiff); var yearsDiff = now.Year - fileDateTime.Year; if (now.Month < fileDateTime.Month || (now.Month == fileDateTime.Month && now.Day < fileDateTime.Day)) yearsDiff--; - return yearsDiff == 1 ? Main.Context.API.GetTranslation("OneYearAgo") : - string.Format(Main.Context.API.GetTranslation("YearsAgo"), yearsDiff); + return yearsDiff == 1 ? Localize.OneYearAgo(): Localize.YearsAgo(yearsDiff); } } diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs index e6294b98b..f8929549b 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs @@ -97,7 +97,7 @@ public partial class QuickAccessLinkSettings // Validate the input before proceeding if (string.IsNullOrEmpty(SelectedName) || string.IsNullOrEmpty(SelectedPath)) { - var warning = Main.Context.API.GetTranslation("plugin_explorer_quick_access_link_no_folder_selected"); + var warning = Localize.plugin_explorer_quick_access_link_no_folder_selected(); Main.Context.API.ShowMsgBox(warning); return; } @@ -107,7 +107,7 @@ public partial class QuickAccessLinkSettings x.Path.Equals(SelectedPath, StringComparison.OrdinalIgnoreCase) && x.Name.Equals(SelectedName, StringComparison.OrdinalIgnoreCase))) { - var warning = Main.Context.API.GetTranslation("plugin_explorer_quick_access_link_path_already_exists"); + var warning = Localize.plugin_explorer_quick_access_link_path_already_exists(); Main.Context.API.ShowMsgBox(warning); return; }