diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 000000000..6abd850ed --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,23 @@ +# For more information, see: +# https://github.com/actions/stale +name: Mark stale issues and pull requests + +on: + schedule: + - cron: '30 1 * * *' + +jobs: + stale: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/stale@v4 + with: + stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.' + days-before-stale: 30 + days-before-close: 5 + days-before-pr-close: -1 + exempt-all-milestones: true + close-issue-message: 'This issue was closed because it has been stale for 5 days with no activity. If you feel this issue still needs attention please feel free to reopen.' \ No newline at end of file diff --git a/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs b/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs index c0cd022ea..fab1b3e8f 100644 --- a/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs +++ b/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs @@ -2,6 +2,8 @@ using Flow.Launcher.Infrastructure.Logger; using System; using System.Collections.Generic; +using System.Net; +using System.Net.Http; using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -10,43 +12,43 @@ namespace Flow.Launcher.Core.ExternalPlugins { public static class PluginsManifest { - static PluginsManifest() - { - UpdateTask = UpdateManifestAsync(); - } - - public static List UserPlugins { get; private set; } = new List(); - - public static Task UpdateTask { get; private set; } + private const string manifestFileUrl = "https://cdn.jsdelivr.net/gh/Flow-Launcher/Flow.Launcher.PluginsManifest@plugin_api_v2/plugins.json"; private static readonly SemaphoreSlim manifestUpdateLock = new(1); - public static Task UpdateManifestAsync() - { - if (manifestUpdateLock.CurrentCount == 0) - { - return UpdateTask; - } + private static string latestEtag = ""; - return UpdateTask = DownloadManifestAsync(); - } + public static List UserPlugins { get; private set; } = new List(); - private async static Task DownloadManifestAsync() + public static async Task UpdateManifestAsync(CancellationToken token = default) { try { - await manifestUpdateLock.WaitAsync().ConfigureAwait(false); + await manifestUpdateLock.WaitAsync(token).ConfigureAwait(false); - await using var jsonStream = await Http.GetStreamAsync("https://raw.githubusercontent.com/Flow-Launcher/Flow.Launcher.PluginsManifest/plugin_api_v2/plugins.json") - .ConfigureAwait(false); + var request = new HttpRequestMessage(HttpMethod.Get, manifestFileUrl); + request.Headers.Add("If-None-Match", latestEtag); - UserPlugins = await JsonSerializer.DeserializeAsync>(jsonStream).ConfigureAwait(false); + var response = await Http.SendAsync(request, token).ConfigureAwait(false); + + if (response.StatusCode == HttpStatusCode.OK) + { + Log.Info($"|PluginsManifest.{nameof(UpdateManifestAsync)}|Fetched plugins from manifest repo"); + + var json = await response.Content.ReadAsStreamAsync(token).ConfigureAwait(false); + + UserPlugins = await JsonSerializer.DeserializeAsync>(json, cancellationToken: token).ConfigureAwait(false); + + latestEtag = response.Headers.ETag.Tag; + } + else if (response.StatusCode != HttpStatusCode.NotModified) + { + Log.Warn($"|PluginsManifest.{nameof(UpdateManifestAsync)}|Http response for manifest file was {response.StatusCode}"); + } } catch (Exception e) { - Log.Exception("|PluginManagement.GetManifest|Encountered error trying to download plugins manifest", e); - - UserPlugins = new List(); + Log.Exception($"|PluginsManifest.{nameof(UpdateManifestAsync)}|Http request failed", e); } finally { diff --git a/Flow.Launcher.Core/Flow.Launcher.Core.csproj b/Flow.Launcher.Core/Flow.Launcher.Core.csproj index 60c4ec3de..fdd23a0d2 100644 --- a/Flow.Launcher.Core/Flow.Launcher.Core.csproj +++ b/Flow.Launcher.Core/Flow.Launcher.Core.csproj @@ -1,7 +1,7 @@  - net5.0-windows + net6.0-windows true true Library @@ -53,7 +53,7 @@ - + diff --git a/Flow.Launcher.Core/Plugin/ExecutablePlugin.cs b/Flow.Launcher.Core/Plugin/ExecutablePlugin.cs index 0982e4017..049d1c583 100644 --- a/Flow.Launcher.Core/Plugin/ExecutablePlugin.cs +++ b/Flow.Launcher.Core/Plugin/ExecutablePlugin.cs @@ -1,5 +1,4 @@ -using System; -using System.Diagnostics; +using System.Diagnostics; using System.IO; using System.Threading; using System.Threading.Tasks; @@ -22,18 +21,23 @@ namespace Flow.Launcher.Core.Plugin RedirectStandardOutput = true, RedirectStandardError = true }; + + // required initialisation for below request calls + _startInfo.ArgumentList.Add(string.Empty); } protected override Task RequestAsync(JsonRPCRequestModel request, CancellationToken token = default) { - _startInfo.Arguments = $"\"{request}\""; + // since this is not static, request strings will build up in ArgumentList if index is not specified + _startInfo.ArgumentList[0] = request.ToString(); return ExecuteAsync(_startInfo, token); } protected override string Request(JsonRPCRequestModel rpcRequest, CancellationToken token = default) { - _startInfo.Arguments = $"\"{rpcRequest}\""; + // since this is not static, request strings will build up in ArgumentList if index is not specified + _startInfo.ArgumentList[0] = rpcRequest.ToString(); return Execute(_startInfo); } } -} \ No newline at end of file +} diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs b/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs index 384418db9..4cfa83382 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs @@ -354,7 +354,9 @@ namespace Flow.Launcher.Core.Plugin this.context = context; await InitSettingAsync(); } - private static readonly Thickness settingControlMargin = new(10); + private static readonly Thickness settingControlMargin = new(10, 4, 10, 4); + private static readonly Thickness settingPanelMargin = new(15, 20, 15, 20); + private static readonly Thickness settingTextBlockMargin = new(10, 4, 10, 4); private JsonRpcConfigurationModel _settingsTemplate; public Control CreateSettingPanel() { @@ -363,7 +365,7 @@ namespace Flow.Launcher.Core.Plugin var settingWindow = new UserControl(); var mainPanel = new StackPanel { - Margin = settingControlMargin, + Margin = settingPanelMargin, Orientation = Orientation.Vertical }; settingWindow.Content = mainPanel; @@ -375,10 +377,13 @@ namespace Flow.Launcher.Core.Plugin Orientation = Orientation.Horizontal, Margin = settingControlMargin }; - var name = new Label() + var name = new TextBlock() { - Content = attribute.Label, - Margin = settingControlMargin + Text = attribute.Label, + Width = 120, + VerticalAlignment = VerticalAlignment.Center, + Margin = settingControlMargin, + TextWrapping = TextWrapping.WrapWithOverflow }; FrameworkElement contentControl; @@ -390,8 +395,8 @@ namespace Flow.Launcher.Core.Plugin contentControl = new TextBlock { Text = attribute.Description.Replace("\\r\\n", "\r\n"), - Margin = settingControlMargin, - MaxWidth = 400, + Margin = settingTextBlockMargin, + MaxWidth = 500, TextWrapping = TextWrapping.WrapWithOverflow }; break; diff --git a/Flow.Launcher.Core/Plugin/PluginAssemblyLoader.cs b/Flow.Launcher.Core/Plugin/PluginAssemblyLoader.cs index 515b0bedc..9d76b6be0 100644 --- a/Flow.Launcher.Core/Plugin/PluginAssemblyLoader.cs +++ b/Flow.Launcher.Core/Plugin/PluginAssemblyLoader.cs @@ -15,20 +15,6 @@ namespace Flow.Launcher.Core.Plugin private readonly AssemblyName assemblyName; - private static readonly ConcurrentDictionary loadedAssembly; - - static PluginAssemblyLoader() - { - var currentAssemblies = AppDomain.CurrentDomain.GetAssemblies(); - loadedAssembly = new ConcurrentDictionary( - currentAssemblies.Select(x => new KeyValuePair(x.FullName, default))); - - AppDomain.CurrentDomain.AssemblyLoad += (sender, args) => - { - loadedAssembly[args.LoadedAssembly.FullName] = default; - }; - } - internal PluginAssemblyLoader(string assemblyFilePath) { dependencyResolver = new AssemblyDependencyResolver(assemblyFilePath); @@ -47,10 +33,9 @@ namespace Flow.Launcher.Core.Plugin // When resolving dependencies, ignore assembly depenedencies that already exits with Flow.Launcher // Otherwise duplicate assembly will be loaded and some weird behavior will occur, such as WinRT.Runtime.dll // will fail due to loading multiple versions in process, each with their own static instance of registration state - if (assemblyPath == null || ExistsInReferencedPackage(assemblyName)) - return null; + var existAssembly = Default.Assemblies.FirstOrDefault(x => x.FullName == assemblyName.FullName); - return LoadFromAssemblyPath(assemblyPath); + return existAssembly ?? (assemblyPath == null ? null : LoadFromAssemblyPath(assemblyPath)); } internal Type FromAssemblyGetTypeOfInterface(Assembly assembly, Type type) @@ -58,10 +43,5 @@ namespace Flow.Launcher.Core.Plugin var allTypes = assembly.ExportedTypes; return allTypes.First(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Any(t => t == type)); } - - internal bool ExistsInReferencedPackage(AssemblyName assemblyName) - { - return loadedAssembly.ContainsKey(assemblyName.FullName); - } } } \ No newline at end of file diff --git a/Flow.Launcher.Core/Resource/AvailableLanguages.cs b/Flow.Launcher.Core/Resource/AvailableLanguages.cs index 0ad7ede1e..f541d3f35 100644 --- a/Flow.Launcher.Core/Resource/AvailableLanguages.cs +++ b/Flow.Launcher.Core/Resource/AvailableLanguages.cs @@ -19,6 +19,8 @@ namespace Flow.Launcher.Core.Resource public static Language Serbian = new Language("sr", "Srpski"); public static Language Portuguese_Portugal = new Language("pt-pt", "Português"); public static Language Portuguese_Brazil = new Language("pt-br", "Português (Brasil)"); + public static Language Spanish = new Language("es", "Spanish"); + public static Language Spanish_LatinAmerica = new Language("es-419", "Spanish (Latin America)"); public static Language Italian = new Language("it", "Italiano"); public static Language Norwegian_Bokmal = new Language("nb-NO", "Norsk Bokmål"); public static Language Slovak = new Language("sk", "Slovenský"); @@ -43,6 +45,8 @@ namespace Flow.Launcher.Core.Resource Serbian, Portuguese_Portugal, Portuguese_Brazil, + Spanish, + Spanish_LatinAmerica, Italian, Norwegian_Bokmal, Slovak, diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs index e09c6380c..69b537b39 100644 --- a/Flow.Launcher.Core/Updater.cs +++ b/Flow.Launcher.Core/Updater.cs @@ -91,8 +91,9 @@ namespace Flow.Launcher.Core catch (Exception e) when (e is HttpRequestException or WebException or SocketException || e.InnerException is TimeoutException) { Log.Exception($"|Updater.UpdateApp|Check your connection and proxy settings to github-cloud.s3.amazonaws.com.", e); - api.ShowMsg(api.GetTranslation("update_flowlauncher_fail"), - api.GetTranslation("update_flowlauncher_check_connection")); + if (!silentUpdate) + api.ShowMsg(api.GetTranslation("update_flowlauncher_fail"), + api.GetTranslation("update_flowlauncher_check_connection")); } finally { @@ -124,7 +125,7 @@ namespace Flow.Launcher.Core var releases = await System.Text.Json.JsonSerializer.DeserializeAsync>(jsonStream).ConfigureAwait(false); var latest = releases.Where(r => !r.Prerelease).OrderByDescending(r => r.PublishedAt).First(); var latestUrl = latest.HtmlUrl.Replace("/tag/", "/download/"); - + var client = new WebClient { Proxy = Http.WebProxy diff --git a/Flow.Launcher.Infrastructure/Constant.cs b/Flow.Launcher.Infrastructure/Constant.cs index cd49217a4..57b39e46e 100644 --- a/Flow.Launcher.Infrastructure/Constant.cs +++ b/Flow.Launcher.Infrastructure/Constant.cs @@ -21,7 +21,7 @@ namespace Flow.Launcher.Infrastructure public static readonly string PreinstalledDirectory = Path.Combine(ProgramDirectory, Plugins); public const string Issue = "https://github.com/Flow-Launcher/Flow.Launcher/issues/new"; public static readonly string Version = FileVersionInfo.GetVersionInfo(Assembly.Location.NonNull()).ProductVersion; - public const string Documentation = "https://flow-launcher.github.io/docs/#/usage-tips"; + public const string Documentation = "https://flowlauncher.com/docs/#/usage-tips"; public static readonly int ThumbnailSize = 64; private static readonly string ImagesDirectory = Path.Combine(ProgramDirectory, "Images"); @@ -43,8 +43,8 @@ namespace Flow.Launcher.Infrastructure public const string Settings = "Settings"; public const string Logs = "Logs"; - public const string Website = "https://flow-launcher.github.io"; + public const string Website = "https://flowlauncher.com"; public const string GitHub = "https://github.com/Flow-Launcher/Flow.Launcher"; - public const string Docs = "https://flow-launcher.github.io/docs"; + public const string Docs = "https://flowlauncher.com/docs"; } } diff --git a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj index 40c2cb956..930cf0b91 100644 --- a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj +++ b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj @@ -1,7 +1,7 @@  - net5.0-windows + net6.0-windows {4FD29318-A8AB-4D8F-AA47-60BC241B8DA3} Library true diff --git a/Flow.Launcher.Infrastructure/Http/Http.cs b/Flow.Launcher.Infrastructure/Http/Http.cs index b45b6adcd..9f4146b7b 100644 --- a/Flow.Launcher.Infrastructure/Http/Http.cs +++ b/Flow.Launcher.Infrastructure/Http/Http.cs @@ -153,5 +153,13 @@ namespace Flow.Launcher.Infrastructure.Http var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token); return await response.Content.ReadAsStreamAsync(); } + + /// + /// Asynchrously send an HTTP request. + /// + public static async Task SendAsync(HttpRequestMessage request, CancellationToken token = default) + { + return await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token); + } } } diff --git a/Flow.Launcher.Infrastructure/Image/ImageCache.cs b/Flow.Launcher.Infrastructure/Image/ImageCache.cs index 13277c7d9..04e11bf1a 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageCache.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageCache.cs @@ -74,7 +74,7 @@ namespace Flow.Launcher.Infrastructure.Image // To delete the images from the data dictionary based on the resizing of the Usage Dictionary // Double Check to avoid concurrent remove if (Data.Count > permissibleFactor * MaxCached) - foreach (var key in Data.OrderBy(x => x.Value.usage).Take(Data.Count - MaxCached).Select(x => x.Key).ToArray()) + foreach (var key in Data.OrderBy(x => x.Value.usage).Take(Data.Count - MaxCached).Select(x => x.Key)) Data.TryRemove(key, out _); semaphore.Release(); } diff --git a/Flow.Launcher.Infrastructure/Logger/Log.cs b/Flow.Launcher.Infrastructure/Logger/Log.cs index 26e305ace..75f208c9e 100644 --- a/Flow.Launcher.Infrastructure/Logger/Log.cs +++ b/Flow.Launcher.Infrastructure/Logger/Log.cs @@ -211,4 +211,4 @@ namespace Flow.Launcher.Infrastructure.Logger LogInternal(message, LogLevel.Warn); } } -} \ No newline at end of file +} diff --git a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj index 7ce2fc8fd..41072993c 100644 --- a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj +++ b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj @@ -1,7 +1,7 @@ - + - net5.0-windows + net6.0-windows {8451ECDD-2EA4-4966-BB0A-7BBC40138E80} true Library @@ -14,10 +14,10 @@ - 2.1.0 - 2.1.0 - 2.1.0 - 2.1.0 + 3.0.0 + 3.0.0 + 3.0.0 + 3.0.0 Flow.Launcher.Plugin Flow-Launcher MIT @@ -42,6 +42,7 @@ 4 AnyCPU false + ..\Output\Debug\Flow.Launcher.Plugin.xml diff --git a/Flow.Launcher.Plugin/GlyphInfo.cs b/Flow.Launcher.Plugin/GlyphInfo.cs index d24624d8f..730046e1d 100644 --- a/Flow.Launcher.Plugin/GlyphInfo.cs +++ b/Flow.Launcher.Plugin/GlyphInfo.cs @@ -7,5 +7,10 @@ using System.Windows.Media; namespace Flow.Launcher.Plugin { + /// + /// Text with FontFamily specified + /// + /// Font Family of this Glyph + /// Text/Unicode of the Glyph public record GlyphInfo(string FontFamily, string Glyph); } diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs index 133ad25a5..69057820e 100644 --- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs +++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs @@ -228,8 +228,27 @@ namespace Flow.Launcher.Plugin public void OpenDirectory(string DirectoryPath, string FileName = null); /// - /// Opens the url. The browser and mode used is based on what's configured in Flow's default browser settings. + /// Opens the URL with the given Uri object. + /// The browser and mode used is based on what's configured in Flow's default browser settings. + /// + public void OpenUrl(Uri url, bool? inPrivate = null); + + /// + /// Opens the URL with the given string. + /// The browser and mode used is based on what's configured in Flow's default browser settings. + /// Non-C# plugins should use this method. /// public void OpenUrl(string url, bool? inPrivate = null); + + /// + /// Opens the application URI with the given Uri object, e.g. obsidian://search-query-example + /// + public void OpenAppUri(Uri appUri); + + /// + /// Opens the application URI with the given string, e.g. obsidian://search-query-example + /// Non-C# plugins should use this method + /// + public void OpenAppUri(string appUri); } } diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs index 29f8198ab..4a5eb39af 100644 --- a/Flow.Launcher.Plugin/Result.cs +++ b/Flow.Launcher.Plugin/Result.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Windows.Media; @@ -10,11 +10,11 @@ namespace Flow.Launcher.Plugin { private string _pluginDirectory; - + private string _icoPath; /// - /// Provides the title of the result. This is always required. + /// The title of the result. This is always required. /// public string Title { get; set; } @@ -29,6 +29,13 @@ namespace Flow.Launcher.Plugin /// public string ActionKeywordAssigned { get; set; } + /// + /// This holds the text which can be provided by plugin to be copied to the + /// user's clipboard when Ctrl + C is pressed on a result. If the text is a file/directory path + /// flow will copy the actual file/folder instead of just the path text. + /// + public string CopyText { get; set; } = string.Empty; + /// /// This holds the text which can be provided by plugin to help Flow autocomplete text /// for user on the plugin result. If autocomplete action for example is tab, pressing tab will have @@ -36,6 +43,11 @@ namespace Flow.Launcher.Plugin /// public string AutoCompleteText { get; set; } + /// + /// Image Displayed on the result + /// Relative Path to the Image File + /// GlyphInfo is prioritized if not null + /// public string IcoPath { get { return _icoPath; } @@ -60,16 +72,23 @@ namespace Flow.Launcher.Plugin public IconDelegate Icon; /// - /// Information for Glyph Icon + /// Information for Glyph Icon (Prioritized than IcoPath/Icon if user enable Glyph Icons) /// - public GlyphInfo Glyph { get; init; } + public GlyphInfo Glyph { get; init; } /// - /// return true to hide flowlauncher after select result + /// Delegate. An action to take in the form of a function call when the result has been selected + /// + /// true to hide flowlauncher after select result + /// /// public Func Action { get; set; } + /// + /// Priority of the current result + /// default: 0 + /// public int Score { get; set; } /// @@ -77,13 +96,11 @@ namespace Flow.Launcher.Plugin /// public IList TitleHighlightData { get; set; } - /// - /// A list of indexes for the characters to be highlighted in SubTitle - /// + [Obsolete("Deprecated as of Flow Launcher v1.9.1. Subtitle highlighting is no longer offered")] public IList SubTitleHighlightData { get; set; } /// - /// Only results that originQuery match with current query will be displayed in the panel + /// Query information associated with the result /// internal Query OriginQuery { get; set; } @@ -103,6 +120,7 @@ namespace Flow.Launcher.Plugin } } + /// public override bool Equals(object obj) { var r = obj as Result; @@ -110,12 +128,12 @@ namespace Flow.Launcher.Plugin var equality = string.Equals(r?.Title, Title) && string.Equals(r?.SubTitle, SubTitle) && string.Equals(r?.IcoPath, IcoPath) && - TitleHighlightData == r.TitleHighlightData && - SubTitleHighlightData == r.SubTitleHighlightData; + TitleHighlightData == r.TitleHighlightData; return equality; } + /// public override int GetHashCode() { var hashcode = (Title?.GetHashCode() ?? 0) ^ @@ -123,15 +141,17 @@ namespace Flow.Launcher.Plugin return hashcode; } + /// public override string ToString() { return Title + SubTitle; } - public Result() { } - /// - /// Additional data associate with this result + /// Additional data associated with this result + /// + /// As external information for ContextMenu + /// /// public object ContextData { get; set; } diff --git a/Flow.Launcher.Plugin/SharedCommands/SearchWeb.cs b/Flow.Launcher.Plugin/SharedCommands/SearchWeb.cs index 6c4ac8ebf..6588132b9 100644 --- a/Flow.Launcher.Plugin/SharedCommands/SearchWeb.cs +++ b/Flow.Launcher.Plugin/SharedCommands/SearchWeb.cs @@ -60,7 +60,7 @@ namespace Flow.Launcher.Plugin.SharedCommands try { - Process.Start(psi); + Process.Start(psi)?.Dispose(); } catch (System.ComponentModel.Win32Exception) { @@ -100,7 +100,7 @@ namespace Flow.Launcher.Plugin.SharedCommands psi.FileName = url; } - Process.Start(psi); + Process.Start(psi)?.Dispose(); } // This error may be thrown if browser path is incorrect catch (System.ComponentModel.Win32Exception) diff --git a/Flow.Launcher.Test/Flow.Launcher.Test.csproj b/Flow.Launcher.Test/Flow.Launcher.Test.csproj index 8de0681c8..f429586ce 100644 --- a/Flow.Launcher.Test/Flow.Launcher.Test.csproj +++ b/Flow.Launcher.Test/Flow.Launcher.Test.csproj @@ -1,7 +1,7 @@  - net5.0-windows10.0.19041.0 + net6.0-windows10.0.19041.0 {FF742965-9A80-41A5-B042-D6C7D3A21708} Library Properties diff --git a/Flow.Launcher.Test/Plugins/JsonRPCPluginTest.cs b/Flow.Launcher.Test/Plugins/JsonRPCPluginTest.cs index 383650619..7231dfbe0 100644 --- a/Flow.Launcher.Test/Plugins/JsonRPCPluginTest.cs +++ b/Flow.Launcher.Test/Plugins/JsonRPCPluginTest.cs @@ -76,7 +76,7 @@ namespace Flow.Launcher.Test.Plugins [TestCaseSource(typeof(JsonRPCPluginTest), nameof(ResponseModelsSource))] public async Task GivenModel_WhenSerializeWithDifferentNamingPolicy_ThenExpectSameResult_Async(JsonRPCQueryResponseModel reference) { - var camelText = JsonSerializer.Serialize(reference, new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); + var camelText = JsonSerializer.Serialize(reference, new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); var pascalText = JsonSerializer.Serialize(reference); diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs index 9ee486b3b..4ebff16a9 100644 --- a/Flow.Launcher/App.xaml.cs +++ b/Flow.Launcher/App.xaml.cs @@ -69,8 +69,6 @@ namespace Flow.Launcher PluginManager.LoadPlugins(_settings.PluginSettings); _mainVM = new MainViewModel(_settings); - HotKeyMapper.Initialize(_mainVM); - API = new PublicAPIInstance(_settingsVM, _mainVM, _alphabet); Http.API = API; @@ -83,6 +81,8 @@ namespace Flow.Launcher Current.MainWindow = window; Current.MainWindow.Title = Constant.FlowLauncher; + + HotKeyMapper.Initialize(_mainVM); // happlebao todo temp fix for instance code logic // load plugin before change language, because plugin language also needs be changed @@ -153,7 +153,6 @@ namespace Flow.Launcher DispatcherUnhandledException += ErrorReporting.DispatcherUnhandledException; } - /// /// let exception throw as normal is better for Debug /// @@ -179,4 +178,4 @@ namespace Flow.Launcher Current.MainWindow.Show(); } } -} \ No newline at end of file +} diff --git a/Flow.Launcher/Converters/QuerySuggestionBoxConverter.cs b/Flow.Launcher/Converters/QuerySuggestionBoxConverter.cs index 08ee8571e..ecdfc5851 100644 --- a/Flow.Launcher/Converters/QuerySuggestionBoxConverter.cs +++ b/Flow.Launcher/Converters/QuerySuggestionBoxConverter.cs @@ -53,7 +53,10 @@ namespace Flow.Launcher.Converters // Check if Text will be larger then our QueryTextBox System.Windows.Media.Typeface typeface = new Typeface(QueryTextBox.FontFamily, QueryTextBox.FontStyle, QueryTextBox.FontWeight, QueryTextBox.FontStretch); System.Windows.Media.FormattedText ft = new FormattedText(QueryTextBox.Text, System.Globalization.CultureInfo.CurrentCulture, System.Windows.FlowDirection.LeftToRight, typeface, QueryTextBox.FontSize, Brushes.Black); - if (ft.Width > QueryTextBox.ActualWidth || QueryTextBox.HorizontalOffset != 0) + + var offset = QueryTextBox.Padding.Right; + + if ((ft.Width + offset) > QueryTextBox.ActualWidth || QueryTextBox.HorizontalOffset != 0) { return string.Empty; }; diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml b/Flow.Launcher/CustomQueryHotkeySetting.xaml index 2f7d28212..187f99d18 100644 --- a/Flow.Launcher/CustomQueryHotkeySetting.xaml +++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml @@ -79,20 +79,18 @@ - + - - + + - - + LastChildFill="True"> - + + - New Tab - New Window + + - + @@ -135,7 +135,7 @@ - + - + @@ -102,7 +99,7 @@ TargetType="{x:Type CheckBox}"> - + @@ -115,7 +112,12 @@ BasedOn="{StaticResource DefaultToggleSwitch}" TargetType="{x:Type ui:ToggleSwitch}"> - + + + + + + - - - + - - + + - - - - + @@ -152,7 +158,7 @@ - + @@ -160,44 +166,50 @@ - - + + - - + + - + - + @@ -249,12 +263,12 @@ - - + + - - - \ No newline at end of file diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index abf3a1d14..0531c925d 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows; -using System.Windows.Media; using System.Windows.Input; using Flow.Launcher.Core.Plugin; using Flow.Launcher.Core.Resource; @@ -20,7 +19,8 @@ using Flow.Launcher.Infrastructure.Logger; using Microsoft.VisualStudio.Threading; using System.Threading.Channels; using ISavable = Flow.Launcher.Plugin.ISavable; - +using System.IO; +using System.Collections.Specialized; namespace Flow.Launcher.ViewModel { @@ -231,7 +231,7 @@ namespace Flow.Launcher.ViewModel AutocompleteQueryCommand = new RelayCommand(_ => { var result = SelectedResults.SelectedItem?.Result; - if (result != null) // SelectedItem returns null if selection is empty. + if (result != null && SelectedIsFromQueryResults()) // SelectedItem returns null if selection is empty. { var autoCompleteText = result.Title; @@ -254,6 +254,18 @@ namespace Flow.Launcher.ViewModel } }); + BackspaceCommand = new RelayCommand(index => + { + var query = QueryBuilder.Build(QueryText.Trim(), PluginManager.NonGlobalPlugins); + + // GetPreviousExistingDirectory does not require trailing '\', otherwise will return empty string + var path = FilesFolders.GetPreviousExistingDirectory((_) => true, query.Search.TrimEnd('\\')); + + var actionKeyword = string.IsNullOrEmpty(query.ActionKeyword) ? string.Empty : $"{query.ActionKeyword} "; + + ChangeQueryText($"{actionKeyword}{path}"); + }); + LoadContextMenuCommand = new RelayCommand(_ => { if (SelectedIsFromQueryResults()) @@ -334,6 +346,9 @@ namespace Flow.Launcher.ViewModel { // re-query is done in QueryText's setter method QueryText = queryText; + // set to false so the subsequent set true triggers + // PropertyChanged and MoveQueryTextToEnd is called + QueryTextCursorMovedToEnd = false; } else if (reQuery) { @@ -393,9 +408,14 @@ namespace Flow.Launcher.ViewModel // because it is more accurate and reliable representation than using Visibility as a condition check public bool MainWindowVisibilityStatus { get; set; } = true; + public Visibility SearchIconVisibility { get; set; } + public double MainWindowWidth => _settings.WindowSize; + public string PluginIconPath { get; set; } = null; + public ICommand EscCommand { get; set; } + public ICommand BackspaceCommand { get; set; } public ICommand SelectNextItemCommand { get; set; } public ICommand SelectPrevItemCommand { get; set; } public ICommand SelectNextPageCommand { get; set; } @@ -408,6 +428,9 @@ namespace Flow.Launcher.ViewModel public ICommand OpenSettingCommand { get; set; } public ICommand ReloadPluginDataCommand { get; set; } public ICommand ClearQueryCommand { get; private set; } + + public ICommand CopyToClipboard { get; set; } + public ICommand AutocompleteQueryCommand { get; set; } public string OpenResultCommandModifiers { get; private set; } @@ -528,6 +551,8 @@ namespace Flow.Launcher.ViewModel { Results.Clear(); Results.Visbility = Visibility.Collapsed; + PluginIconPath = null; + SearchIconVisibility = Visibility.Visible; return; } @@ -556,6 +581,18 @@ namespace Flow.Launcher.ViewModel var plugins = PluginManager.ValidPluginsForQuery(query); + if (plugins.Count == 1) + { + PluginIconPath = plugins.Single().Metadata.IcoPath; + SearchIconVisibility = Visibility.Hidden; + } + else + { + PluginIconPath = null; + SearchIconVisibility = Visibility.Visible; + } + + if (query.ActionKeyword == Plugin.Query.GlobalPluginWildcardSign) { // Wait 45 millisecond for query change in global query @@ -646,7 +683,7 @@ namespace Flow.Launcher.ViewModel Action = _ => { _topMostRecord.Remove(result); - App.API.ShowMsg("Success"); + App.API.ShowMsg(InternationalizationManager.Instance.GetTranslation("success")); return false; } }; @@ -690,7 +727,11 @@ namespace Flow.Launcher.ViewModel IcoPath = icon, SubTitle = subtitle, PluginDirectory = metadata.PluginDirectory, - Action = _ => false + Action = _ => + { + App.API.OpenUrl(metadata.Website); + return true; + } }; return menu; } @@ -734,20 +775,10 @@ namespace Flow.Launcher.ViewModel public void Show() { - if (_settings.UseSound) - { - MediaPlayer media = new MediaPlayer(); - media.Open(new Uri(AppDomain.CurrentDomain.BaseDirectory + "Resources\\open.wav")); - media.Play(); - } - MainWindowVisibility = Visibility.Visible; MainWindowVisibilityStatus = true; - - if(_settings.UseAnimation) - ((MainWindow)Application.Current.MainWindow).WindowAnimator(); - + MainWindowOpacity = 1; } @@ -847,6 +878,52 @@ namespace Flow.Launcher.ViewModel Results.AddResults(resultsForUpdates, token); } + /// + /// This is the global copy method for an individual result. If no text is passed, + /// the method will work out what is to be copied based on the result, so plugin can offer the text + /// to be copied via the result model. If the text is a directory/file path, + /// then actual file/folder will be copied instead. + /// The result's subtitle text is the default text to be copied + /// + public void ResultCopy(string stringToCopy) + { + if (string.IsNullOrEmpty(stringToCopy)) + { + var result = Results.SelectedItem?.Result; + if (result != null) + { + string copyText = string.IsNullOrEmpty(result.CopyText) ? result.SubTitle : result.CopyText; + var isFile = File.Exists(copyText); + var isFolder = Directory.Exists(copyText); + if (isFile || isFolder) + { + var paths = new StringCollection(); + paths.Add(copyText); + + Clipboard.SetFileDropList(paths); + App.API.ShowMsg( + App.API.GetTranslation("copy") + +" " + + (isFile? App.API.GetTranslation("fileTitle") : App.API.GetTranslation("folderTitle")), + App.API.GetTranslation("completedSuccessfully")); + } + else + { + Clipboard.SetDataObject(copyText.ToString()); + App.API.ShowMsg( + App.API.GetTranslation("copy") + + " " + + App.API.GetTranslation("textTitle"), + App.API.GetTranslation("completedSuccessfully")); + } + } + + return; + } + + Clipboard.SetDataObject(stringToCopy); + } + #endregion } } \ No newline at end of file diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs index 864a60646..38f2421a1 100644 --- a/Flow.Launcher/ViewModel/PluginViewModel.cs +++ b/Flow.Launcher/ViewModel/PluginViewModel.cs @@ -66,4 +66,4 @@ namespace Flow.Launcher.ViewModel public static bool IsActionKeywordRegistered(string newActionKeyword) => PluginManager.ActionKeywordRegistered(newActionKeyword); } -} \ No newline at end of file +} diff --git a/Flow.Launcher/ViewModel/ResultViewModel.cs b/Flow.Launcher/ViewModel/ResultViewModel.cs index 908de0c09..4d32d792d 100644 --- a/Flow.Launcher/ViewModel/ResultViewModel.cs +++ b/Flow.Launcher/ViewModel/ResultViewModel.cs @@ -7,11 +7,16 @@ using Flow.Launcher.Infrastructure.Logger; using Flow.Launcher.Infrastructure.UserSettings; using Flow.Launcher.Plugin; using System.IO; +using System.Drawing.Text; +using System.Collections.Generic; namespace Flow.Launcher.ViewModel { public class ResultViewModel : BaseModel { + private static PrivateFontCollection fontCollection = new(); + private static Dictionary fonts = new(); + public ResultViewModel(Result result, Settings settings) { if (result != null) @@ -23,13 +28,29 @@ namespace Flow.Launcher.ViewModel // Checks if it's a system installed font, which does not require path to be provided. if (glyph.FontFamily.EndsWith(".ttf") || glyph.FontFamily.EndsWith(".otf")) { - var fontPath = Result.Glyph.FontFamily; - Glyph = Path.IsPathRooted(fontPath) - ? Result.Glyph - : Result.Glyph with + string fontFamilyPath = glyph.FontFamily; + + if (!Path.IsPathRooted(fontFamilyPath)) + { + fontFamilyPath = Path.Combine(Result.PluginDirectory, fontFamilyPath); + } + + if (fonts.ContainsKey(fontFamilyPath)) + { + Glyph = glyph with { - FontFamily = Path.Combine(Result.PluginDirectory, fontPath) + FontFamily = fonts[fontFamilyPath] }; + } + else + { + fontCollection.AddFontFile(fontFamilyPath); + fonts[fontFamilyPath] = $"{Path.GetDirectoryName(fontFamilyPath)}/#{fontCollection.Families[^1].Name}"; + Glyph = glyph with + { + FontFamily = fonts[fontFamilyPath] + }; + } } else { diff --git a/Flow.Launcher/ViewModel/ResultsViewModel.cs b/Flow.Launcher/ViewModel/ResultsViewModel.cs index 01a19d871..db24825d0 100644 --- a/Flow.Launcher/ViewModel/ResultsViewModel.cs +++ b/Flow.Launcher/ViewModel/ResultsViewModel.cs @@ -310,4 +310,4 @@ namespace Flow.Launcher.ViewModel } } } -} \ No newline at end of file +} diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs index 342c85da2..2fc6934d5 100644 --- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs +++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs @@ -273,7 +273,7 @@ namespace Flow.Launcher.ViewModel #region theme - public static string Theme => @"https://flow-launcher.github.io/docs/#/how-to-create-a-theme"; + public static string Theme => @"https://flowlauncher.com/docs/#/how-to-create-a-theme"; public string SelectedTheme { diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs index d7b412392..735530520 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs @@ -37,7 +37,8 @@ namespace Flow.Launcher.Plugin.BrowserBookmark return new(); foreach (var folder in rootElement.EnumerateObject()) { - EnumerateFolderBookmark(folder.Value, bookmarks, source); + if (folder.Value.ValueKind == JsonValueKind.Object) + EnumerateFolderBookmark(folder.Value, bookmarks, source); } return bookmarks; } @@ -64,4 +65,4 @@ namespace Flow.Launcher.Plugin.BrowserBookmark } } -} \ No newline at end of file +} 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 2a586818c..8454b11e6 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj @@ -2,7 +2,7 @@ Library - net5.0-windows + net6.0-windows true {9B130CC5-14FB-41FF-B310-0A95B6894C37} Properties diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Images/bookmark.png b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Images/bookmark.png index b8aee3564..d68cecea1 100644 Binary files a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Images/bookmark.png and b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Images/bookmark.png differ diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Images/copylink.png b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Images/copylink.png index 0dee870b6..3218c94c9 100644 Binary files a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Images/copylink.png and b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Images/copylink.png differ diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/da.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/da.xaml new file mode 100644 index 000000000..86c09730c --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/da.xaml @@ -0,0 +1,22 @@ + + + + + Browser Bookmarks + Search your browser bookmarks + + + Bookmark Data + Open bookmarks in: + New window + New tab + Set browser from path: + Choose + Copy url + Copy the bookmark's url to clipboard + Load Browser From: + Browser Name + Data Directory Path + Tilføj + Slet + diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/de.xaml new file mode 100644 index 000000000..0f8227530 --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/de.xaml @@ -0,0 +1,22 @@ + + + + + Browser-Lesezeichen + Lesezeichen durchsuchen + + + Lesezeichen-Daten + Lesezeichen öffnen in: + Neues Fenster + Neuer Tab + Browser aus Pfad festlegen: + Auswählen + Kopiere Url + Die Url des Lesezeichens in die Zwischenablage kopieren + Lade Browser-Lesezeichen aus: + Browser-Name + Pfad zum Datenverzeichnis + Hinzufügen + Löschen + diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml index af2a556c1..8f5396dd7 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml @@ -8,7 +8,7 @@ Search your browser bookmarks - Bookmmark Data + Bookmark Data Open bookmarks in: New window New tab diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/es-419.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/es-419.xaml new file mode 100644 index 000000000..b22481631 --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/es-419.xaml @@ -0,0 +1,22 @@ + + + + + Marcadores del Navegador + Busca en los marcadores de tu navegador + + + Datos de Marcadores + Abrir marcadores en: + Nueva ventana + Nueva pestaña + Establecer navegador desde ruta: + Elegir + Copiar url + Copiar la url del marcador al portapapeles + Cargar navegador desde: + Nombre del Navegador + Ruta del Directorio de Datos + Añadir + Eliminar + diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/es.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/es.xaml new file mode 100644 index 000000000..190679ea4 --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/es.xaml @@ -0,0 +1,22 @@ + + + + + Marcadores del navegador + Busca en los marcadores de tu navegador + + + Datos de marcador + Abrir marcadores en: + Nueva ventana + Nueva Pestaña + Establecer navegador desde ruta: + Elige + Copiar enlace + Copiar enlace del marcador al portapapeles + Iniciar navegador desde: + Nombre del navegador + Ruta del directorio de datos + Añadir + Eliminar + diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/fr.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/fr.xaml new file mode 100644 index 000000000..485092912 --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/fr.xaml @@ -0,0 +1,22 @@ + + + + + Browser Bookmarks + Search your browser bookmarks + + + Bookmark Data + Open bookmarks in: + New window + New tab + Set browser from path: + Choose + Copy url + Copy the bookmark's url to clipboard + Load Browser From: + Browser Name + Data Directory Path + Ajouter + Supprimer + diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/it.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/it.xaml new file mode 100644 index 000000000..f0f2d79bb --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/it.xaml @@ -0,0 +1,22 @@ + + + + + Browser Bookmarks + Search your browser bookmarks + + + Bookmark Data + Open bookmarks in: + New window + New tab + Set browser from path: + Choose + Copy url + Copy the bookmark's url to clipboard + Load Browser From: + Browser Name + Data Directory Path + Aggiungi + Cancella + diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ja.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ja.xaml new file mode 100644 index 000000000..232007a4d --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ja.xaml @@ -0,0 +1,22 @@ + + + + + Browser Bookmarks + Search your browser bookmarks + + + Bookmark Data + Open bookmarks in: + New window + New tab + Set browser from path: + Choose + Copy url + Copy the bookmark's url to clipboard + Load Browser From: + Browser Name + Data Directory Path + + 削除 + diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ko.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ko.xaml new file mode 100644 index 000000000..6f916cf54 --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ko.xaml @@ -0,0 +1,22 @@ + + + + + 브라우저 북마크 + 브라우저의 북마크 검색 + + + 북마크 데이터 + Open bookmarks in: + New window + New tab + Set browser from path: + Choose + Copy url + Copy the bookmark's url to clipboard + Load Browser From: + 브라우저 이름 + 데이터 디렉토리 위치 + + 삭제 + diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/nb.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/nb.xaml new file mode 100644 index 000000000..c5d6f77a0 --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/nb.xaml @@ -0,0 +1,22 @@ + + + + + Browser Bookmarks + Search your browser bookmarks + + + Bookmark Data + Open bookmarks in: + New window + New tab + Set browser from path: + Choose + Copy url + Copy the bookmark's url to clipboard + Load Browser From: + Browser Name + Data Directory Path + Add + Delete + diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/nl.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/nl.xaml new file mode 100644 index 000000000..d1cbaa001 --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/nl.xaml @@ -0,0 +1,22 @@ + + + + + Browser Bookmarks + Search your browser bookmarks + + + Bookmark Data + Open bookmarks in: + New window + New tab + Set browser from path: + Choose + Copy url + Copy the bookmark's url to clipboard + Load Browser From: + Browser Name + Data Directory Path + Toevoegen + Verwijder + diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pl.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pl.xaml new file mode 100644 index 000000000..024232350 --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pl.xaml @@ -0,0 +1,22 @@ + + + + + Browser Bookmarks + Search your browser bookmarks + + + Bookmark Data + Open bookmarks in: + New window + New tab + Set browser from path: + Choose + Copy url + Copy the bookmark's url to clipboard + Load Browser From: + Browser Name + Data Directory Path + Dodaj + Usu + diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pt-br.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pt-br.xaml new file mode 100644 index 000000000..db29166a0 --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pt-br.xaml @@ -0,0 +1,22 @@ + + + + + Browser Bookmarks + Search your browser bookmarks + + + Bookmark Data + Open bookmarks in: + New window + New tab + Set browser from path: + Choose + Copy url + Copy the bookmark's url to clipboard + Load Browser From: + Browser Name + Data Directory Path + Adicionar + Apagar + diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pt-pt.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pt-pt.xaml index 259f34c85..eefcc1d2e 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pt-pt.xaml +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pt-pt.xaml @@ -1,19 +1,20 @@  - - Marcadores do navegador - Pesquisar nos marcadores do navegador + + Marcadores do navegador + Pesquisar nos marcadores do navegador - + + Dados do marcador Abrir marcadores em: Nova janela Novo separador Caminho do navegador: Escolher Copiar URL - Copiar URL do marcador para área de transferência - Carregar navegador de: + Copiar URL do marcador para a área de transferência + Carregar navegador em: Nome do navegador Caminho do diretório de dados Adicionar diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ru.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ru.xaml new file mode 100644 index 000000000..545ddbf9a --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ru.xaml @@ -0,0 +1,22 @@ + + + + + Browser Bookmarks + Search your browser bookmarks + + + Bookmark Data + Open bookmarks in: + New window + New tab + Set browser from path: + Choose + Copy url + Copy the bookmark's url to clipboard + Load Browser From: + Browser Name + Data Directory Path + Добавить + Удалить + diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/sk.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/sk.xaml index 76fc24883..b45b437a8 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/sk.xaml +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/sk.xaml @@ -1,11 +1,12 @@  - - Prehliadač záložiek - Vyhľadáva záložky prehliadača + + Záložky prehliadača + Vyhľadáva záložky prehliadača - + + Nastavenia pluginu Otvoriť záložky v: Nové okno Nová karta @@ -15,7 +16,7 @@ Kopírovať URL záložky do schránky Načítať prehliadač z: Názov prehliadača - Cesta k dátovému priečinku + Umiestnenie priečinku s dátami Pridať Odstrániť diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/sr.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/sr.xaml new file mode 100644 index 000000000..d898a834c --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/sr.xaml @@ -0,0 +1,22 @@ + + + + + Browser Bookmarks + Search your browser bookmarks + + + Bookmark Data + Open bookmarks in: + New window + New tab + Set browser from path: + Choose + Copy url + Copy the bookmark's url to clipboard + Load Browser From: + Browser Name + Data Directory Path + Dodaj + Obriši + diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/tr.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/tr.xaml index dbfad64f4..3e18a245e 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/tr.xaml +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/tr.xaml @@ -1,9 +1,22 @@ - - - - Yer İşaretleri - Tarayıcılarınızdaki yer işaretlerini arayın. - - \ No newline at end of file + + + + + Yer İşaretleri + Tarayıcılarınızdaki yer işaretlerini arayın. + + + Yer İmleri Verisi + Open bookmarks in: + Yeni Pencere + Yeni Sekme + Dizin üzerinden tarayıcı seç: + Seç + Url Kopyala + Copy the bookmark's url to clipboard + Load Browser From: + Browser Name + Data Directory Path + Ekle + Sil + diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/uk-UA.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/uk-UA.xaml new file mode 100644 index 000000000..f8701ed49 --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/uk-UA.xaml @@ -0,0 +1,22 @@ + + + + + Browser Bookmarks + Search your browser bookmarks + + + Bookmark Data + Open bookmarks in: + New window + New tab + Set browser from path: + Choose + Copy url + Copy the bookmark's url to clipboard + Load Browser From: + Browser Name + Data Directory Path + Додати + Видалити + diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/zh-cn.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/zh-cn.xaml index 288e3ed94..81fa84b44 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/zh-cn.xaml +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/zh-cn.xaml @@ -1,17 +1,22 @@ - - - - 浏览器书签 - 搜索您的浏览器书签 - - - 在以下位置打开书签: - 新窗口 - 新标签 - 设置浏览器路径: - 选择 - 复制网址 - 将书签的网址复制到剪贴板 - \ No newline at end of file + + + + + 浏览器书签 + 搜索您的浏览器书签 + + + 书签数据 + 在以下位置打开书签: + 新窗口 + 新标签 + 设置浏览器路径: + 选择 + 复制网址 + 将书签的网址复制到剪贴板 + 从以下浏览器加载: + 浏览器名称 + 数据文件路径 + 增加 + 删除 + diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/zh-tw.xaml new file mode 100644 index 000000000..f9e98bb10 --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/zh-tw.xaml @@ -0,0 +1,22 @@ + + + + + 瀏覽器書籤 + 搜索你的瀏覽器書籤 + + + 書籤資料 + Open bookmarks in: + 新增視窗 + 新增分頁 + Set browser from path: + 選擇 + 複製網址 + 複製書籤網址 + Load Browser From: + 瀏覽器名稱 + Data Directory Path + 新增 + 刪除 + diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/CustomBrowserSetting.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/CustomBrowserSetting.xaml index 8a2a65f26..4d23bd060 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/CustomBrowserSetting.xaml +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/CustomBrowserSetting.xaml @@ -5,11 +5,12 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Flow.Launcher.Plugin.BrowserBookmark.Models" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - Title="{DynamicResource BookmarkDataSetting}" - Width="500" + Title="{DynamicResource flowlauncher_plugin_browserbookmark_bookmarkDataSetting}" + Width="520" Background="{DynamicResource PopuBGColor}" Foreground="{DynamicResource PopupTextColor}" KeyDown="WindowKeyDown" + ResizeMode="NoResize" SizeToContent="Height" WindowStartupLocation="CenterScreen" mc:Ignorable="d"> @@ -66,39 +67,54 @@ FontFamily="Segoe UI" FontSize="20" FontWeight="SemiBold" - Text="{DynamicResource BookmarkDataSetting}" + Text="{DynamicResource flowlauncher_plugin_browserbookmark_bookmarkDataSetting}" TextAlignment="Left" /> - - - - - - - + + + + + + + + + + + + + + + @@ -110,15 +126,13 @@