Merge branch 'dev' into filewatcher

This commit is contained in:
Jeremy 2022-01-27 20:50:54 +11:00
commit 2b538d9cb6
126 changed files with 353 additions and 283 deletions

View file

@ -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<UserPlugin> UserPlugins { get; private set; } = new List<UserPlugin>();
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<UserPlugin> UserPlugins { get; private set; } = new List<UserPlugin>();
private static async 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<List<UserPlugin>>(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<List<UserPlugin>>(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<UserPlugin>();
Log.Exception($"|PluginsManifest.{nameof(UpdateManifestAsync)}|Http request failed", e);
}
finally
{

View file

@ -153,5 +153,13 @@ namespace Flow.Launcher.Infrastructure.Http
var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token);
return await response.Content.ReadAsStreamAsync();
}
/// <summary>
/// Asynchrously send an HTTP request.
/// </summary>
public static async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken token = default)
{
return await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token);
}
}
}

View file

@ -29,6 +29,13 @@ namespace Flow.Launcher.Plugin
/// </summary>
public string ActionKeywordAssigned { get; set; }
/// <summary>
/// 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.
/// </summary>
public string CopyText { get; set; } = string.Empty;
/// <summary>
/// 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

View file

@ -153,7 +153,6 @@ namespace Flow.Launcher
DispatcherUnhandledException += ErrorReporting.DispatcherUnhandledException;
}
/// <summary>
/// let exception throw as normal is better for Debug
/// </summary>
@ -179,4 +178,4 @@ namespace Flow.Launcher
Current.MainWindow.Show();
}
}
}
}

View file

@ -88,6 +88,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="InputSimulator" Version="1.0.4" />
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.2" />
<PackageReference Include="ModernWpfUI" Version="0.9.4" />
<PackageReference Include="NHotkey.Wpf" Version="2.1.0" />
<PackageReference Include="NuGet.CommandLine" Version="5.4.0">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 873 B

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 774 B

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 796 B

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 597 B

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 530 B

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 752 B

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 501 B

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 506 B

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 290 B

After

Width:  |  Height:  |  Size: 339 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 468 B

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 634 B

After

Width:  |  Height:  |  Size: 687 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 759 B

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 674 B

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 792 B

After

Width:  |  Height:  |  Size: 752 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 B

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 436 B

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 760 B

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 470 B

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 794 B

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -126,8 +126,8 @@
<system:String x:Key="update_flowlauncher_update">Opdater</system:String>
<system:String x:Key="update_flowlauncher_update_cancel">Annuler</system:String>
<system:String x:Key="update_flowlauncher_update_restart_flowlauncher_tip">Denne opdatering vil genstarte Flow Launcher</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_files">Følgende filer bliver opdateret</system:String>
<system:String x:Key="update_flowlauncher_update_update_files">Følgende filer bliver opdateret</system:String>
<system:String x:Key="update_flowlauncher_update_files">Opdatereringsfiler</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_description">Opdateringsbeskrivelse</system:String>
<system:String x:Key="update_flowlauncher_update_update_description">Opdateringsbeskrivelse</system:String>
</ResourceDictionary>

View file

@ -126,8 +126,8 @@
<system:String x:Key="update_flowlauncher_update">Aktualisieren</system:String>
<system:String x:Key="update_flowlauncher_update_cancel">Abbrechen</system:String>
<system:String x:Key="update_flowlauncher_update_restart_flowlauncher_tip">Diese Aktualisierung wird Flow Launcher neu starten</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_files">Folgende Dateien werden aktualisiert</system:String>
<system:String x:Key="update_flowlauncher_update_update_files">Folgende Dateien werden aktualisiert</system:String>
<system:String x:Key="update_flowlauncher_update_files">Aktualisiere Dateien</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_description">Aktualisierungbeschreibung</system:String>
<system:String x:Key="update_flowlauncher_update_update_description">Aktualisierungbeschreibung</system:String>
</ResourceDictionary>

View file

@ -18,6 +18,9 @@
<system:String x:Key="copy">Copy</system:String>
<system:String x:Key="cut">Cut</system:String>
<system:String x:Key="paste">Paste</system:String>
<system:String x:Key="fileTitle">File</system:String>
<system:String x:Key="folderTitle">Folder</system:String>
<system:String x:Key="textTitle">Text</system:String>
<system:String x:Key="GameMode">Game Mode</system:String>
<system:String x:Key="GameModeToolTip">Suspend the use of Hotkeys.</system:String>
@ -244,9 +247,9 @@
<system:String x:Key="update_flowlauncher_fail">Update Failed</system:String>
<system:String x:Key="update_flowlauncher_check_connection">Check your connection and try updating proxy settings to github-cloud.s3.amazonaws.com.</system:String>
<system:String x:Key="update_flowlauncher_update_restart_flowlauncher_tip">This upgrade will restart Flow Launcher</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_files">Following files will be updated</system:String>
<system:String x:Key="update_flowlauncher_update_update_files">Following files will be updated</system:String>
<system:String x:Key="update_flowlauncher_update_files">Update files</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_description">Update description</system:String>
<system:String x:Key="update_flowlauncher_update_update_description">Update description</system:String>
<!-- Welcome Window -->
<system:String x:Key="Skip">Skip</system:String>
@ -281,7 +284,7 @@
<system:String x:Key="RecommendShell">&gt; ping 8.8.8.8</system:String>
<system:String x:Key="RecommendShellDesc">Shell Command</system:String>
<system:String x:Key="RecommendBluetooth">Bluetooth</system:String>
<system:String x:Key="RecommendBluetoothDesc">Bluetooth in Windows Setting</system:String>
<system:String x:Key="RecommendBluetoothDesc">Bluetooth in Windows Settings</system:String>
<system:String x:Key="RecommendAcronyms">sn</system:String>
<system:String x:Key="RecommendAcronymsDesc">Sticky Notes</system:String>

View file

@ -132,8 +132,8 @@
<system:String x:Key="update_flowlauncher_update">Mettre à jour</system:String>
<system:String x:Key="update_flowlauncher_update_cancel">Annuler</system:String>
<system:String x:Key="update_flowlauncher_update_restart_flowlauncher_tip">Flow Launcher doit redémarrer pour installer cette mise à jour</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_files">Les fichiers suivants seront mis à jour</system:String>
<system:String x:Key="update_flowlauncher_update_update_files">Les fichiers suivants seront mis à jour</system:String>
<system:String x:Key="update_flowlauncher_update_files">Fichiers mis à jour</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_description">Description de la mise à jour</system:String>
<system:String x:Key="update_flowlauncher_update_update_description">Description de la mise à jour</system:String>
</ResourceDictionary>

View file

@ -135,8 +135,8 @@
<system:String x:Key="update_flowlauncher_update">Aggiorna</system:String>
<system:String x:Key="update_flowlauncher_update_cancel">Annulla</system:String>
<system:String x:Key="update_flowlauncher_update_restart_flowlauncher_tip">Questo aggiornamento riavvierà Flow Launcher</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_files">I seguenti file saranno aggiornati</system:String>
<system:String x:Key="update_flowlauncher_update_update_files">I seguenti file saranno aggiornati</system:String>
<system:String x:Key="update_flowlauncher_update_files">File aggiornati</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_description">Descrizione aggiornamento</system:String>
<system:String x:Key="update_flowlauncher_update_update_description">Descrizione aggiornamento</system:String>
</ResourceDictionary>

View file

@ -138,8 +138,8 @@
<system:String x:Key="update_flowlauncher_update">アップデート</system:String>
<system:String x:Key="update_flowlauncher_update_cancel">キャンセル</system:String>
<system:String x:Key="update_flowlauncher_update_restart_flowlauncher_tip">このアップデートでは、Flow Launcherの再起動が必要です</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_files">次のファイルがアップデートされます</system:String>
<system:String x:Key="update_flowlauncher_update_update_files">次のファイルがアップデートされます</system:String>
<system:String x:Key="update_flowlauncher_update_files">更新ファイル一覧</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_description">アップデートの詳細</system:String>
<system:String x:Key="update_flowlauncher_update_update_description">アップデートの詳細</system:String>
</ResourceDictionary>

View file

@ -241,9 +241,9 @@
<system:String x:Key="update_flowlauncher_fail">업데이트 실패</system:String>
<system:String x:Key="update_flowlauncher_check_connection">Check your connection and try updating proxy settings to github-cloud.s3.amazonaws.com.</system:String>
<system:String x:Key="update_flowlauncher_update_restart_flowlauncher_tip">업데이트를 위해 Flow Launcher를 재시작합니다.</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_files">아래 파일들이 업데이트됩니다.</system:String>
<system:String x:Key="update_flowlauncher_update_update_files">아래 파일들이 업데이트됩니다.</system:String>
<system:String x:Key="update_flowlauncher_update_files">업데이트 파일</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_description">업데이트 설명</system:String>
<system:String x:Key="update_flowlauncher_update_update_description">업데이트 설명</system:String>
<!-- Welcome Window -->

View file

@ -135,8 +135,8 @@
<system:String x:Key="update_flowlauncher_update">Oppdater</system:String>
<system:String x:Key="update_flowlauncher_update_cancel">Avbryt</system:String>
<system:String x:Key="update_flowlauncher_update_restart_flowlauncher_tip">Denne opgraderingen vil starte Flow Launcher på nytt</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_files">Følgende filer vil bli oppdatert</system:String>
<system:String x:Key="update_flowlauncher_update_update_files">Følgende filer vil bli oppdatert</system:String>
<system:String x:Key="update_flowlauncher_update_files">Oppdateringsfiler</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_description">Oppdateringsbeskrivelse</system:String>
<system:String x:Key="update_flowlauncher_update_update_description">Oppdateringsbeskrivelse</system:String>
</ResourceDictionary>

View file

@ -126,8 +126,8 @@
<system:String x:Key="update_flowlauncher_update">Update</system:String>
<system:String x:Key="update_flowlauncher_update_cancel">Annuleer</system:String>
<system:String x:Key="update_flowlauncher_update_restart_flowlauncher_tip">Deze upgrade zal Flow Launcher opnieuw opstarten</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_files">Volgende bestanden zullen worden geüpdatet</system:String>
<system:String x:Key="update_flowlauncher_update_update_files">Volgende bestanden zullen worden geüpdatet</system:String>
<system:String x:Key="update_flowlauncher_update_files">Update bestanden</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_description">Update beschrijving</system:String>
<system:String x:Key="update_flowlauncher_update_update_description">Update beschrijving</system:String>
</ResourceDictionary>

View file

@ -126,8 +126,8 @@
<system:String x:Key="update_flowlauncher_update">Aktualizuj</system:String>
<system:String x:Key="update_flowlauncher_update_cancel">Anuluj</system:String>
<system:String x:Key="update_flowlauncher_update_restart_flowlauncher_tip">Aby dokończyć proces aktualizacji Flow Launcher musi zostać zresetowany</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_files">Następujące pliki zostaną zaktualizowane</system:String>
<system:String x:Key="update_flowlauncher_update_update_files">Następujące pliki zostaną zaktualizowane</system:String>
<system:String x:Key="update_flowlauncher_update_files">Aktualizuj pliki</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_description">Opis aktualizacji</system:String>
<system:String x:Key="update_flowlauncher_update_update_description">Opis aktualizacji</system:String>
</ResourceDictionary>

View file

@ -135,8 +135,8 @@
<system:String x:Key="update_flowlauncher_update">Atualizar</system:String>
<system:String x:Key="update_flowlauncher_update_cancel">Cancelar</system:String>
<system:String x:Key="update_flowlauncher_update_restart_flowlauncher_tip">Essa atualização reiniciará o Flow Launcher</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_files">Os seguintes arquivos serão atualizados</system:String>
<system:String x:Key="update_flowlauncher_update_update_files">Os seguintes arquivos serão atualizados</system:String>
<system:String x:Key="update_flowlauncher_update_files">Atualizar arquivos</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_description">Atualizar descrição</system:String>
<system:String x:Key="update_flowlauncher_update_update_description">Atualizar descrição</system:String>
</ResourceDictionary>

View file

@ -244,9 +244,9 @@
<system:String x:Key="update_flowlauncher_fail">Falha ao atualizar</system:String>
<system:String x:Key="update_flowlauncher_check_connection">Verifique a sua ligação e as definições do proxy estabelecidas para github-cloud.s3.amazonaws.com</system:String>
<system:String x:Key="update_flowlauncher_update_restart_flowlauncher_tip">Esta atualização irá reiniciar o Flow Launcher</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_files">Os seguintes ficheiros serão atualizados</system:String>
<system:String x:Key="update_flowlauncher_update_update_files">Os seguintes ficheiros serão atualizados</system:String>
<system:String x:Key="update_flowlauncher_update_files">Atualizar ficheiros</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_description">Atualizar descrição</system:String>
<system:String x:Key="update_flowlauncher_update_update_description">Atualizar descrição</system:String>
<!-- Welcome Window -->
<system:String x:Key="Skip">Ignorar</system:String>

View file

@ -126,8 +126,8 @@
<system:String x:Key="update_flowlauncher_update">Обновить</system:String>
<system:String x:Key="update_flowlauncher_update_cancel">Отмена</system:String>
<system:String x:Key="update_flowlauncher_update_restart_flowlauncher_tip">Это обновление перезапустит Flow Launcher</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_files">Следующие файлы будут обновлены</system:String>
<system:String x:Key="update_flowlauncher_update_update_files">Следующие файлы будут обновлены</system:String>
<system:String x:Key="update_flowlauncher_update_files">Обновить файлы</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_description">Описание обновления</system:String>
<system:String x:Key="update_flowlauncher_update_update_description">Описание обновления</system:String>
</ResourceDictionary>

View file

@ -242,9 +242,9 @@
<system:String x:Key="update_flowlauncher_fail">Aktualizácia zlyhala</system:String>
<system:String x:Key="update_flowlauncher_check_connection">Skontrolujte pripojenie a skúste aktualizovať nastavenia servera proxy k github-cloud.s3.amazonaws.com.</system:String>
<system:String x:Key="update_flowlauncher_update_restart_flowlauncher_tip">Tento upgrade reštartuje Flow Launcher</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_files">Nasledujúce súbory budú aktualizované</system:String>
<system:String x:Key="update_flowlauncher_update_update_files">Nasledujúce súbory budú aktualizované</system:String>
<system:String x:Key="update_flowlauncher_update_files">Aktualizovať súbory</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_description">Aktualizovať popis</system:String>
<system:String x:Key="update_flowlauncher_update_update_description">Aktualizovať popis</system:String>
<!-- Welcome Window -->
<system:String x:Key="Skip">Preskočiť</system:String>

View file

@ -135,8 +135,8 @@
<system:String x:Key="update_flowlauncher_update">Ažuriraj</system:String>
<system:String x:Key="update_flowlauncher_update_cancel">Otkaži</system:String>
<system:String x:Key="update_flowlauncher_update_restart_flowlauncher_tip">Ova nadogradnja će ponovo pokrenuti Flow Launcher</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_files">Sledeće datoteke će biti ažurirane</system:String>
<system:String x:Key="update_flowlauncher_update_update_files">Sledeće datoteke će biti ažurirane</system:String>
<system:String x:Key="update_flowlauncher_update_files">Ažuriraj datoteke</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_description">Opis ažuriranja</system:String>
<system:String x:Key="update_flowlauncher_update_update_description">Opis ažuriranja</system:String>
</ResourceDictionary>

View file

@ -139,8 +139,8 @@
<system:String x:Key="update_flowlauncher_update">Güncelle</system:String>
<system:String x:Key="update_flowlauncher_update_cancel">İptal</system:String>
<system:String x:Key="update_flowlauncher_update_restart_flowlauncher_tip">Bu güncelleme Flow Launcher'u yeniden başlatacaktır</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_files">Aşağıdaki dosyalar güncelleştirilecektir</system:String>
<system:String x:Key="update_flowlauncher_update_update_files">Aşağıdaki dosyalar güncelleştirilecektir</system:String>
<system:String x:Key="update_flowlauncher_update_files">Güncellenecek dosyalar</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_description">Güncelleme açıklaması</system:String>
<system:String x:Key="update_flowlauncher_update_update_description">Güncelleme açıklaması</system:String>
</ResourceDictionary>

View file

@ -126,8 +126,8 @@
<system:String x:Key="update_flowlauncher_update">Оновити</system:String>
<system:String x:Key="update_flowlauncher_update_cancel">Скасувати</system:String>
<system:String x:Key="update_flowlauncher_update_restart_flowlauncher_tip">Це оновлення перезавантажить Flow Launcher</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_files">Ці файли будуть оновлені</system:String>
<system:String x:Key="update_flowlauncher_update_update_files">Ці файли будуть оновлені</system:String>
<system:String x:Key="update_flowlauncher_update_files">Оновити файли</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_description">Опис оновлення</system:String>
<system:String x:Key="update_flowlauncher_update_update_description">Опис оновлення</system:String>
</ResourceDictionary>

View file

@ -226,9 +226,9 @@
<system:String x:Key="update_flowlauncher_fail">更新失败</system:String>
<system:String x:Key="update_flowlauncher_check_connection">检查网络是否可以连接至github-cloud.s3.amazonaws.com.</system:String>
<system:String x:Key="update_flowlauncher_update_restart_flowlauncher_tip">此次更新需要重启Flow Launcher</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_files">下列文件会被更新</system:String>
<system:String x:Key="update_flowlauncher_update_update_files">下列文件会被更新</system:String>
<system:String x:Key="update_flowlauncher_update_files">更新文件</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_description">更新日志</system:String>
<system:String x:Key="update_flowlauncher_update_update_description">更新日志</system:String>
<!-- Welcome Window -->
<system:String x:Key="Skip">跳过</system:String>

View file

@ -126,8 +126,8 @@
<system:String x:Key="update_flowlauncher_update">更新</system:String>
<system:String x:Key="update_flowlauncher_update_cancel">取消</system:String>
<system:String x:Key="update_flowlauncher_update_restart_flowlauncher_tip">此更新需要重新啟動 Flow Launcher</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_files">下列檔案會被更新</system:String>
<system:String x:Key="update_flowlauncher_update_update_files">下列檔案會被更新</system:String>
<system:String x:Key="update_flowlauncher_update_files">更新檔案</system:String>
<system:String x:Key="update_flowlauncher_update_upadte_description">更新日誌</system:String>
<system:String x:Key="update_flowlauncher_update_update_description">更新日誌</system:String>
</ResourceDictionary>

View file

@ -175,6 +175,9 @@
Style="{DynamicResource QueryBoxStyle}"
Text="{Binding QueryText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Visibility="Visible">
<TextBox.CommandBindings>
<CommandBinding Command="ApplicationCommands.Copy" Executed="OnCopy" />
</TextBox.CommandBindings>
<TextBox.ContextMenu>
<ContextMenu>
<MenuItem Command="ApplicationCommands.Cut" Header="{DynamicResource cut}" />

View file

@ -18,6 +18,8 @@ using KeyEventArgs = System.Windows.Input.KeyEventArgs;
using NotifyIcon = System.Windows.Forms.NotifyIcon;
using Flow.Launcher.Infrastructure;
using System.Windows.Media;
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher
{
@ -50,7 +52,18 @@ namespace Flow.Launcher
{
InitializeComponent();
}
private void OnCopy(object sender, ExecutedRoutedEventArgs e)
{
if (QueryTextBox.SelectionLength == 0)
{
_viewModel.ResultCopy(string.Empty);
}
else if (!string.IsNullOrEmpty(QueryTextBox.Text))
{
_viewModel.ResultCopy(QueryTextBox.SelectedText);
}
}
private async void OnClosing(object sender, CancelEventArgs e)
{
_settings.WindowTop = Top;
@ -59,6 +72,7 @@ namespace Flow.Launcher
_viewModel.Save();
e.Cancel = true;
await PluginManager.DisposePluginsAsync();
Notification.Uninstall();
Environment.Exit(0);
}
@ -498,6 +512,24 @@ namespace Flow.Launcher
e.Handled = true;
}
break;
case Key.Back:
var specialKeyState = GlobalHotkey.CheckModifiers();
if (specialKeyState.CtrlPressed)
{
if (_viewModel.SelectedIsFromQueryResults()
&& QueryTextBox.CaretIndex == QueryTextBox.Text.Length)
{
var queryWithoutActionKeyword =
QueryBuilder.Build(QueryTextBox.Text.Trim(), PluginManager.NonGlobalPlugins).Search;
if (FilesFolders.IsLocationPathString(queryWithoutActionKeyword))
{
_viewModel.BackspaceCommand.Execute(null);
e.Handled = true;
}
}
}
break;
default:
break;

View file

@ -1,4 +1,5 @@
using Flow.Launcher.Infrastructure;
using Microsoft.Toolkit.Uwp.Notifications;
using System;
using System.IO;
using Windows.Data.Xml.Dom;
@ -8,10 +9,17 @@ namespace Flow.Launcher
{
internal static class Notification
{
internal static bool legacy = Environment.OSVersion.Version.Build < 19041;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>")]
internal static void Uninstall()
{
if (!legacy)
ToastNotificationManagerCompat.Uninstall();
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>")]
public static void Show(string title, string subTitle, string iconPath)
{
var legacy = Environment.OSVersion.Version.Build < 19041;
// Handle notification for win7/8/early win10
if (legacy)
{
@ -24,13 +32,11 @@ namespace Flow.Launcher
? Path.Combine(Constant.ProgramDirectory, "Images\\app.png")
: iconPath;
var xml = $"<?xml version=\"1.0\"?><toast><visual><binding template=\"ToastImageAndText04\"><image id=\"1\" src=\"{Icon}\" alt=\"meziantou\"/><text id=\"1\">{title}</text>" +
$"<text id=\"2\">{subTitle}</text></binding></visual></toast>";
var toastXml = new XmlDocument();
toastXml.LoadXml(xml);
var toast = new ToastNotification(toastXml);
ToastNotificationManager.CreateToastNotifier("Flow Launcher").Show(toast);
new ToastContentBuilder()
.AddText(title, hintMaxLines: 1)
.AddText(subTitle)
.AddAppLogoOverride(new Uri(Icon))
.Show();
}
private static void LegacyShow(string title, string subTitle, string iconPath)

View file

@ -2514,6 +2514,18 @@
Margin="14,14,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
FontSize="12"
Foreground="{DynamicResource Color15B}"
TextWrapping="WrapWithOverflow">
<Hyperlink NavigateUri="https://icons8.com" RequestNavigate="OnRequestNavigate">
<Run Text="Icons by icons8.com" />
</Hyperlink>
</TextBlock>
<TextBlock
Margin="14,4,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
DockPanel.Dock="Bottom"
FontSize="12"
Foreground="{DynamicResource Color15B}"

View file

@ -13,12 +13,14 @@ using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.Storage;
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
{
@ -229,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;
@ -252,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())
@ -398,6 +412,7 @@ namespace Flow.Launcher.ViewModel
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; }
@ -410,6 +425,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; }
@ -662,7 +680,7 @@ namespace Flow.Launcher.ViewModel
Action = _ =>
{
_topMostRecord.Remove(result);
App.API.ShowMsg("Success");
App.API.ShowMsg(InternationalizationManager.Instance.GetTranslation("success"));
return false;
}
};
@ -706,7 +724,11 @@ namespace Flow.Launcher.ViewModel
IcoPath = icon,
SubTitle = subtitle,
PluginDirectory = metadata.PluginDirectory,
Action = _ => false
Action = _ =>
{
App.API.OpenUrl(metadata.Website);
return true;
}
};
return menu;
}
@ -853,6 +875,52 @@ namespace Flow.Launcher.ViewModel
Results.AddResults(resultsForUpdates, token);
}
/// <summary>
/// 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
/// </summary>
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
}
}

View file

@ -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<string, string> 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
{

View file

@ -310,4 +310,4 @@ namespace Flow.Launcher.ViewModel
}
}
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View file

@ -4,7 +4,7 @@
"Name": "Browser Bookmarks",
"Description": "Search your browser bookmarks",
"Author": "qianlifeng, Ioannis G.",
"Version": "1.6.2",
"Version": "1.6.3",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.BrowserBookmark.dll",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 597 B

After

Width:  |  Height:  |  Size: 3.2 KiB

View file

@ -1,7 +0,0 @@
<?xml version="1.0"?>
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:system="clr-namespace:System;assembly=mscorlib">
<system:String x:Key="flowlauncher_plugin_controlpanel_plugin_name">제어판</system:String>
<system:String x:Key="flowlauncher_plugin_controlpanel_plugin_description">제어판 항목을 검색합니다.</system:String>
</ResourceDictionary>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 501 B

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 290 B

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 468 B

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View file

@ -10,7 +10,7 @@
"Name": "Explorer",
"Description": "Search and manage files and folders. Explorer utilises Windows Index Search",
"Author": "Jeremy Wu",
"Version": "1.11.1",
"Version": "1.11.2",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.Explorer.dll",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 B

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -25,6 +25,7 @@ namespace Flow.Launcher.Plugin.PluginIndicator
SubTitle = $"Activate {metadata.Name} plugin",
Score = 100,
IcoPath = metadata.IcoPath,
AutoCompleteText = $"{keyword}{Plugin.Query.TermSeparator}",
Action = c =>
{
context.API.ChangeQuery($"{keyword}{Plugin.Query.TermSeparator}");

View file

@ -4,7 +4,7 @@
"Name": "Plugin Indicator",
"Description": "Provide plugin actionword suggestion",
"Author": "qianlifeng",
"Version": "1.1.3",
"Version": "1.1.4",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.PluginIndicator.dll",

View file

@ -2,7 +2,7 @@
using Flow.Launcher.Infrastructure.UserSettings;
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace Flow.Launcher.Plugin.PluginsManager
{
@ -53,8 +53,8 @@ namespace Flow.Launcher.Plugin.PluginsManager
{
// standard UrlSourceCode format in PluginsManifest's plugins.json file: https://github.com/jjw24/Flow.Launcher.Plugin.Putty/tree/master
var link = pluginManifestInfo.UrlSourceCode.StartsWith("https://github.com")
? pluginManifestInfo.UrlSourceCode.Replace("/tree/master", "/issues/new/choose")
: pluginManifestInfo.UrlSourceCode;
? Regex.Replace(pluginManifestInfo.UrlSourceCode, @"\/tree\/\w+$", "") + "/issues/new/choose"
: pluginManifestInfo.UrlSourceCode;
Context.API.OpenUrl(link);
return true;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 484 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -12,7 +12,7 @@ using System.Windows;
namespace Flow.Launcher.Plugin.PluginsManager
{
public class Main : ISettingProvider, IAsyncPlugin, IContextMenu, IPluginI18n, IAsyncReloadable
public class Main : ISettingProvider, IAsyncPlugin, IContextMenu, IPluginI18n
{
internal PluginInitContext Context { get; set; }
@ -24,28 +24,20 @@ namespace Flow.Launcher.Plugin.PluginsManager
internal PluginsManager pluginManager;
private DateTime lastUpdateTime = DateTime.MinValue;
public Control CreateSettingPanel()
{
return new PluginsManagerSettings(viewModel);
}
public Task InitAsync(PluginInitContext context)
public async Task InitAsync(PluginInitContext context)
{
Context = context;
Settings = context.API.LoadSettingJsonStorage<Settings>();
viewModel = new SettingsViewModel(context, Settings);
contextMenu = new ContextMenu(Context);
pluginManager = new PluginsManager(Context, Settings);
_manifestUpdateTask = pluginManager
.UpdateManifestAsync(true)
.ContinueWith(_ =>
{
lastUpdateTime = DateTime.Now;
}, TaskContinuationOptions.OnlyOnRanToCompletion);
return Task.CompletedTask;
await pluginManager.UpdateManifestAsync();
}
public List<Result> LoadContextMenus(Result selectedResult)
@ -53,35 +45,20 @@ namespace Flow.Launcher.Plugin.PluginsManager
return contextMenu.LoadContextMenus(selectedResult);
}
private Task _manifestUpdateTask = Task.CompletedTask;
public async Task<List<Result>> QueryAsync(Query query, CancellationToken token)
{
var search = query.Search;
if (string.IsNullOrWhiteSpace(search))
if (string.IsNullOrWhiteSpace(query.Search))
return pluginManager.GetDefaultHotKeys();
if ((DateTime.Now - lastUpdateTime).TotalHours > 12 && _manifestUpdateTask.IsCompleted) // 12 hours
{
_manifestUpdateTask = pluginManager.UpdateManifestAsync().ContinueWith(t =>
{
lastUpdateTime = DateTime.Now;
}, TaskContinuationOptions.OnlyOnRanToCompletion);
}
return search switch
return query.FirstSearch.ToLower() switch
{
//search could be url, no need ToLower() when passed in
var s when s.StartsWith(Settings.HotKeyInstall, StringComparison.OrdinalIgnoreCase)
=> await pluginManager.RequestInstallOrUpdate(search, token),
var s when s.StartsWith(Settings.HotkeyUninstall, StringComparison.OrdinalIgnoreCase)
=> pluginManager.RequestUninstall(search),
var s when s.StartsWith(Settings.HotkeyUpdate, StringComparison.OrdinalIgnoreCase)
=> await pluginManager.RequestUpdate(search, token),
Settings.InstallCommand => await pluginManager.RequestInstallOrUpdate(query.SecondToEndSearch, token),
Settings.UninstallCommand => pluginManager.RequestUninstall(query.SecondToEndSearch),
Settings.UpdateCommand => await pluginManager.RequestUpdate(query.SecondToEndSearch, token),
_ => pluginManager.GetDefaultHotKeys().Where(hotkey =>
{
hotkey.Score = StringMatcher.FuzzySearch(search, hotkey.Title).Score;
hotkey.Score = StringMatcher.FuzzySearch(query.Search, hotkey.Title).Score;
return hotkey.Score > 0;
}).ToList()
};
@ -96,11 +73,5 @@ namespace Flow.Launcher.Plugin.PluginsManager
{
return Context.API.GetTranslation("plugin_pluginsmanager_plugin_description");
}
public async Task ReloadDataAsync()
{
await pluginManager.UpdateManifestAsync();
lastUpdateTime = DateTime.Now;
}
}
}

View file

@ -51,7 +51,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
private Task _downloadManifestTask = Task.CompletedTask;
internal Task UpdateManifestAsync(bool silent = false)
internal Task UpdateManifestAsync(CancellationToken token = default, bool silent = false)
{
if (_downloadManifestTask.Status == TaskStatus.Running)
{
@ -59,7 +59,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
}
else
{
_downloadManifestTask = PluginsManifest.UpdateTask;
_downloadManifestTask = PluginsManifest.UpdateManifestAsync(token);
if (!silent)
_downloadManifestTask.ContinueWith(_ =>
Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_failed_title"),
@ -75,31 +75,34 @@ namespace Flow.Launcher.Plugin.PluginsManager
{
new Result()
{
Title = Settings.HotKeyInstall,
Title = Settings.InstallCommand,
IcoPath = icoPath,
AutoCompleteText = $"{Context.CurrentPluginMetadata.ActionKeyword} {Settings.InstallCommand} ",
Action = _ =>
{
Context.API.ChangeQuery("pm install ");
Context.API.ChangeQuery($"{Context.CurrentPluginMetadata.ActionKeyword} {Settings.InstallCommand} ");
return false;
}
},
new Result()
{
Title = Settings.HotkeyUninstall,
Title = Settings.UninstallCommand,
IcoPath = icoPath,
AutoCompleteText = $"{Context.CurrentPluginMetadata.ActionKeyword} {Settings.UninstallCommand} ",
Action = _ =>
{
Context.API.ChangeQuery("pm uninstall ");
Context.API.ChangeQuery($"{Context.CurrentPluginMetadata.ActionKeyword} {Settings.UninstallCommand} ");
return false;
}
},
new Result()
{
Title = Settings.HotkeyUpdate,
Title = Settings.UpdateCommand,
IcoPath = icoPath,
AutoCompleteText = $"{Context.CurrentPluginMetadata.ActionKeyword} {Settings.UpdateCommand} ",
Action = _ =>
{
Context.API.ChangeQuery("pm update ");
Context.API.ChangeQuery($"{Context.CurrentPluginMetadata.ActionKeyword} {Settings.UpdateCommand} ");
return false;
}
}
@ -119,7 +122,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
Context
.API
.ChangeQuery(
$"{Context.CurrentPluginMetadata.ActionKeywords.FirstOrDefault()} {Settings.HotkeyUpdate} {plugin.Name}");
$"{Context.CurrentPluginMetadata.ActionKeywords.FirstOrDefault()} {Settings.UpdateCommand} {plugin.Name}");
var mainWindow = Application.Current.MainWindow;
mainWindow.Show();
@ -181,22 +184,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
internal async ValueTask<List<Result>> RequestUpdate(string search, CancellationToken token)
{
if (!PluginsManifest.UserPlugins.Any())
{
await UpdateManifestAsync();
}
token.ThrowIfCancellationRequested();
var autocompletedResults = AutoCompleteReturnAllResults(search,
Settings.HotkeyUpdate,
"Update",
"Select a plugin to update");
if (autocompletedResults.Any())
return autocompletedResults;
var uninstallSearch = search.Replace(Settings.HotkeyUpdate, string.Empty, StringComparison.OrdinalIgnoreCase).TrimStart();
await UpdateManifestAsync(token);
var resultsForUpdate =
from existingPlugin in Context.API.GetAllPlugins()
@ -285,7 +273,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
}
});
return Search(results, uninstallSearch);
return Search(results, search);
}
internal bool PluginExists(string id)
@ -369,20 +357,13 @@ namespace Flow.Launcher.Plugin.PluginsManager
return url.StartsWith(acceptedSource) && Context.API.GetAllPlugins().Any(x => x.Metadata.Website.StartsWith(contructedUrlPart));
}
internal async ValueTask<List<Result>> RequestInstallOrUpdate(string searchName, CancellationToken token)
internal async ValueTask<List<Result>> RequestInstallOrUpdate(string search, CancellationToken token)
{
if (!PluginsManifest.UserPlugins.Any())
{
await UpdateManifestAsync();
}
await UpdateManifestAsync(token);
token.ThrowIfCancellationRequested();
var searchNameWithoutKeyword = searchName.Replace(Settings.HotKeyInstall, string.Empty, StringComparison.OrdinalIgnoreCase).Trim();
if (Uri.IsWellFormedUriString(searchNameWithoutKeyword, UriKind.Absolute)
&& searchNameWithoutKeyword.Split('.').Last() == zip)
return InstallFromWeb(searchNameWithoutKeyword);
if (Uri.IsWellFormedUriString(search, UriKind.Absolute)
&& search.Split('.').Last() == zip)
return InstallFromWeb(search);
var results =
PluginsManifest
@ -408,7 +389,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
ContextData = x
});
return Search(results, searchNameWithoutKeyword);
return Search(results, search);
}
private void Install(UserPlugin plugin, string downloadedFilePath)
@ -468,16 +449,6 @@ namespace Flow.Launcher.Plugin.PluginsManager
internal List<Result> RequestUninstall(string search)
{
var autocompletedResults = AutoCompleteReturnAllResults(search,
Settings.HotkeyUninstall,
"Uninstall",
"Select a plugin to uninstall");
if (autocompletedResults.Any())
return autocompletedResults;
var uninstallSearch = search.Replace(Settings.HotkeyUninstall, string.Empty, StringComparison.OrdinalIgnoreCase).TrimStart();
var results = Context.API
.GetAllPlugins()
.Select(x =>
@ -508,7 +479,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
}
});
return Search(results, uninstallSearch);
return Search(results, search);
}
private void Uninstall(PluginMetadata plugin, bool removedSetting = true)
@ -523,36 +494,6 @@ namespace Flow.Launcher.Plugin.PluginsManager
using var _ = File.CreateText(Path.Combine(plugin.PluginDirectory, "NeedDelete.txt"));
}
private List<Result> AutoCompleteReturnAllResults(string search, string hotkey, string title, string subtitle)
{
if (!string.IsNullOrEmpty(search)
&& hotkey.StartsWith(search)
&& (hotkey != search || !search.StartsWith(hotkey)))
{
return
new List<Result>
{
new Result
{
Title = title,
IcoPath = icoPath,
SubTitle = subtitle,
Action = e =>
{
Context
.API
.ChangeQuery(
$"{Context.CurrentPluginMetadata.ActionKeywords.FirstOrDefault()} {hotkey} ");
return false;
}
}
};
}
return new List<Result>();
}
private bool SameOrLesserPluginVersionExists(string metadataPath)
{
var newMetadata = JsonSerializer.Deserialize<PluginMetadata>(File.ReadAllText(metadataPath));

View file

@ -6,11 +6,11 @@ namespace Flow.Launcher.Plugin.PluginsManager
{
internal class Settings
{
internal string HotKeyInstall { get; set; } = "install";
internal const string InstallCommand = "install";
internal string HotkeyUninstall { get; set; } = "uninstall";
internal const string UninstallCommand = "uninstall";
internal string HotkeyUpdate { get; set; } = "update";
internal const string UpdateCommand = "update";
public bool WarnFromUnknownSource { get; set; } = true;
}

View file

@ -6,7 +6,7 @@
"Name": "Plugins Manager",
"Description": "Management of installing, uninstalling or updating Flow Launcher plugins",
"Author": "Jeremy Wu",
"Version": "1.11.2",
"Version": "1.12.1",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.PluginsManager.dll",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -88,6 +88,7 @@ namespace Flow.Launcher.Plugin.ProcessKiller
TitleHighlightData = StringMatcher.FuzzySearch(termToSearch, p.ProcessName).MatchData,
Score = pr.Score,
ContextData = p.ProcessName,
AutoCompleteText = $"{_context.CurrentPluginMetadata.ActionKeyword}{Plugin.Query.TermSeparator}{p.ProcessName}",
Action = (c) =>
{
processHelper.TryKill(p);

View file

@ -4,7 +4,7 @@
"Name":"Process Killer",
"Description":"Kill running processes from Flow",
"Author":"Flow-Launcher",
"Version":"1.2.4",
"Version":"1.2.6",
"Language":"csharp",
"Website":"https://github.com/Flow-Launcher/Flow.Launcher.Plugin.ProcessKiller",
"IcoPath":"Images\\app.png",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 752 B

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 468 B

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 774 B

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View file

@ -4,7 +4,7 @@
"Name": "Program",
"Description": "Search programs in Flow.Launcher",
"Author": "qianlifeng",
"Version": "1.8.1",
"Version": "1.8.2",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.Program.dll",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 752 B

After

Width:  |  Height:  |  Size: 2.5 KiB

Some files were not shown because too many files have changed in this diff Show more