Skip to content

Commit 6f2e8f5

Browse files
authored
Merge branch 'dev' into windowsSettingtranslationWarning
2 parents 26c4650 + 961e182 commit 6f2e8f5

File tree

169 files changed

+686
-528
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

169 files changed

+686
-528
lines changed

.github/workflows/stale.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# For more information, see:
2+
# https://github.com/actions/stale
3+
name: Mark stale issues and pull requests
4+
5+
on:
6+
schedule:
7+
- cron: '30 1 * * *'
8+
9+
jobs:
10+
stale:
11+
runs-on: ubuntu-latest
12+
permissions:
13+
issues: write
14+
pull-requests: write
15+
steps:
16+
- uses: actions/stale@v4
17+
with:
18+
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.'
19+
days-before-stale: 30
20+
days-before-close: 5
21+
days-before-pr-close: -1
22+
exempt-all-milestones: true
23+
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.'

Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
using Flow.Launcher.Infrastructure.Logger;
33
using System;
44
using System.Collections.Generic;
5+
using System.Net;
6+
using System.Net.Http;
57
using System.Text.Json;
68
using System.Threading;
79
using System.Threading.Tasks;
@@ -10,43 +12,43 @@ namespace Flow.Launcher.Core.ExternalPlugins
1012
{
1113
public static class PluginsManifest
1214
{
13-
static PluginsManifest()
14-
{
15-
UpdateTask = UpdateManifestAsync();
16-
}
17-
18-
public static List<UserPlugin> UserPlugins { get; private set; } = new List<UserPlugin>();
19-
20-
public static Task UpdateTask { get; private set; }
15+
private const string manifestFileUrl = "https://cdn.jsdelivr.net/gh/Flow-Launcher/Flow.Launcher.PluginsManifest@plugin_api_v2/plugins.json";
2116

2217
private static readonly SemaphoreSlim manifestUpdateLock = new(1);
2318

24-
public static Task UpdateManifestAsync()
25-
{
26-
if (manifestUpdateLock.CurrentCount == 0)
27-
{
28-
return UpdateTask;
29-
}
19+
private static string latestEtag = "";
3020

31-
return UpdateTask = DownloadManifestAsync();
32-
}
21+
public static List<UserPlugin> UserPlugins { get; private set; } = new List<UserPlugin>();
3322

34-
private static async Task DownloadManifestAsync()
23+
public static async Task UpdateManifestAsync(CancellationToken token = default)
3524
{
3625
try
3726
{
38-
await manifestUpdateLock.WaitAsync().ConfigureAwait(false);
27+
await manifestUpdateLock.WaitAsync(token).ConfigureAwait(false);
28+
29+
var request = new HttpRequestMessage(HttpMethod.Get, manifestFileUrl);
30+
request.Headers.Add("If-None-Match", latestEtag);
31+
32+
var response = await Http.SendAsync(request, token).ConfigureAwait(false);
3933

40-
await using var jsonStream = await Http.GetStreamAsync("https://raw.githubusercontent.com/Flow-Launcher/Flow.Launcher.PluginsManifest/plugin_api_v2/plugins.json")
41-
.ConfigureAwait(false);
34+
if (response.StatusCode == HttpStatusCode.OK)
35+
{
36+
Log.Info($"|PluginsManifest.{nameof(UpdateManifestAsync)}|Fetched plugins from manifest repo");
4237

43-
UserPlugins = await JsonSerializer.DeserializeAsync<List<UserPlugin>>(jsonStream).ConfigureAwait(false);
38+
var json = await response.Content.ReadAsStreamAsync(token).ConfigureAwait(false);
39+
40+
UserPlugins = await JsonSerializer.DeserializeAsync<List<UserPlugin>>(json, cancellationToken: token).ConfigureAwait(false);
41+
42+
latestEtag = response.Headers.ETag.Tag;
43+
}
44+
else if (response.StatusCode != HttpStatusCode.NotModified)
45+
{
46+
Log.Warn($"|PluginsManifest.{nameof(UpdateManifestAsync)}|Http response for manifest file was {response.StatusCode}");
47+
}
4448
}
4549
catch (Exception e)
4650
{
47-
Log.Exception("|PluginManagement.GetManifest|Encountered error trying to download plugins manifest", e);
48-
49-
UserPlugins = new List<UserPlugin>();
51+
Log.Exception($"|PluginsManifest.{nameof(UpdateManifestAsync)}|Http request failed", e);
5052
}
5153
finally
5254
{

Flow.Launcher.Core/Flow.Launcher.Core.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net5.0-windows</TargetFramework>
4+
<TargetFramework>net6.0-windows</TargetFramework>
55
<UseWpf>true</UseWpf>
66
<UseWindowsForms>true</UseWindowsForms>
77
<OutputType>Library</OutputType>
@@ -53,7 +53,7 @@
5353
</ItemGroup>
5454

5555
<ItemGroup>
56-
<PackageReference Include="Droplex" Version="1.4.0" />
56+
<PackageReference Include="Droplex" Version="1.4.1" />
5757
<PackageReference Include="FSharp.Core" Version="5.0.2" />
5858
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="2.1.3" />
5959
<PackageReference Include="squirrel.windows" Version="1.5.2" />

Flow.Launcher.Core/Plugin/PluginAssemblyLoader.cs

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,6 @@ internal class PluginAssemblyLoader : AssemblyLoadContext
1515

1616
private readonly AssemblyName assemblyName;
1717

18-
private static readonly ConcurrentDictionary<string, byte> loadedAssembly;
19-
20-
static PluginAssemblyLoader()
21-
{
22-
var currentAssemblies = AppDomain.CurrentDomain.GetAssemblies();
23-
loadedAssembly = new ConcurrentDictionary<string, byte>(
24-
currentAssemblies.Select(x => new KeyValuePair<string, byte>(x.FullName, default)));
25-
26-
AppDomain.CurrentDomain.AssemblyLoad += (sender, args) =>
27-
{
28-
loadedAssembly[args.LoadedAssembly.FullName] = default;
29-
};
30-
}
31-
3218
internal PluginAssemblyLoader(string assemblyFilePath)
3319
{
3420
dependencyResolver = new AssemblyDependencyResolver(assemblyFilePath);
@@ -47,21 +33,15 @@ protected override Assembly Load(AssemblyName assemblyName)
4733
// When resolving dependencies, ignore assembly depenedencies that already exits with Flow.Launcher
4834
// Otherwise duplicate assembly will be loaded and some weird behavior will occur, such as WinRT.Runtime.dll
4935
// will fail due to loading multiple versions in process, each with their own static instance of registration state
50-
if (assemblyPath == null || ExistsInReferencedPackage(assemblyName))
51-
return null;
36+
var existAssembly = Default.Assemblies.FirstOrDefault(x => x.FullName == assemblyName.FullName);
5237

53-
return LoadFromAssemblyPath(assemblyPath);
38+
return existAssembly ?? (assemblyPath == null ? null : LoadFromAssemblyPath(assemblyPath));
5439
}
5540

5641
internal Type FromAssemblyGetTypeOfInterface(Assembly assembly, Type type)
5742
{
5843
var allTypes = assembly.ExportedTypes;
5944
return allTypes.First(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Any(t => t == type));
6045
}
61-
62-
internal bool ExistsInReferencedPackage(AssemblyName assemblyName)
63-
{
64-
return loadedAssembly.ContainsKey(assemblyName.FullName);
65-
}
6646
}
6747
}

Flow.Launcher.Core/Resource/AvailableLanguages.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ internal static class AvailableLanguages
1919
public static Language Serbian = new Language("sr", "Srpski");
2020
public static Language Portuguese_Portugal = new Language("pt-pt", "Português");
2121
public static Language Portuguese_Brazil = new Language("pt-br", "Português (Brasil)");
22+
public static Language Spanish = new Language("es", "Spanish");
23+
public static Language Spanish_LatinAmerica = new Language("es-419", "Spanish (Latin America)");
2224
public static Language Italian = new Language("it", "Italiano");
2325
public static Language Norwegian_Bokmal = new Language("nb-NO", "Norsk Bokmål");
2426
public static Language Slovak = new Language("sk", "Slovenský");
@@ -43,6 +45,8 @@ public static List<Language> GetAvailableLanguages()
4345
Serbian,
4446
Portuguese_Portugal,
4547
Portuguese_Brazil,
48+
Spanish,
49+
Spanish_LatinAmerica,
4650
Italian,
4751
Norwegian_Bokmal,
4852
Slovak,

Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net5.0-windows</TargetFramework>
4+
<TargetFramework>net6.0-windows</TargetFramework>
55
<ProjectGuid>{4FD29318-A8AB-4D8F-AA47-60BC241B8DA3}</ProjectGuid>
66
<OutputType>Library</OutputType>
77
<UseWpf>true</UseWpf>

Flow.Launcher.Infrastructure/Http/Http.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,5 +153,13 @@ public static async Task<Stream> GetStreamAsync([NotNull] string url, Cancellati
153153
var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token);
154154
return await response.Content.ReadAsStreamAsync();
155155
}
156+
157+
/// <summary>
158+
/// Asynchrously send an HTTP request.
159+
/// </summary>
160+
public static async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken token = default)
161+
{
162+
return await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token);
163+
}
156164
}
157165
}

Flow.Launcher.Infrastructure/Image/ImageCache.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ async void SliceExtra()
7474
// To delete the images from the data dictionary based on the resizing of the Usage Dictionary
7575
// Double Check to avoid concurrent remove
7676
if (Data.Count > permissibleFactor * MaxCached)
77-
foreach (var key in Data.OrderBy(x => x.Value.usage).Take(Data.Count - MaxCached).Select(x => x.Key).ToArray())
77+
foreach (var key in Data.OrderBy(x => x.Value.usage).Take(Data.Count - MaxCached).Select(x => x.Key))
7878
Data.TryRemove(key, out _);
7979
semaphore.Release();
8080
}

Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net5.0-windows</TargetFramework>
4+
<TargetFramework>net6.0-windows</TargetFramework>
55
<ProjectGuid>{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}</ProjectGuid>
66
<UseWPF>true</UseWPF>
77
<OutputType>Library</OutputType>
@@ -14,10 +14,10 @@
1414
</PropertyGroup>
1515

1616
<PropertyGroup>
17-
<Version>2.1.1</Version>
18-
<PackageVersion>2.1.1</PackageVersion>
19-
<AssemblyVersion>2.1.1</AssemblyVersion>
20-
<FileVersion>2.1.1</FileVersion>
17+
<Version>3.0.0</Version>
18+
<PackageVersion>3.0.0</PackageVersion>
19+
<AssemblyVersion>3.0.0</AssemblyVersion>
20+
<FileVersion>3.0.0</FileVersion>
2121
<PackageId>Flow.Launcher.Plugin</PackageId>
2222
<Authors>Flow-Launcher</Authors>
2323
<PackageLicenseExpression>MIT</PackageLicenseExpression>

Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,27 @@ public interface IPublicAPI
228228
public void OpenDirectory(string DirectoryPath, string FileName = null);
229229

230230
/// <summary>
231-
/// Opens the url. The browser and mode used is based on what's configured in Flow's default browser settings.
231+
/// Opens the URL with the given Uri object.
232+
/// The browser and mode used is based on what's configured in Flow's default browser settings.
233+
/// </summary>
234+
public void OpenUrl(Uri url, bool? inPrivate = null);
235+
236+
/// <summary>
237+
/// Opens the URL with the given string.
238+
/// The browser and mode used is based on what's configured in Flow's default browser settings.
239+
/// Non-C# plugins should use this method.
232240
/// </summary>
233241
public void OpenUrl(string url, bool? inPrivate = null);
242+
243+
/// <summary>
244+
/// Opens the application URI with the given Uri object, e.g. obsidian://search-query-example
245+
/// </summary>
246+
public void OpenAppUri(Uri appUri);
247+
248+
/// <summary>
249+
/// Opens the application URI with the given string, e.g. obsidian://search-query-example
250+
/// Non-C# plugins should use this method
251+
/// </summary>
252+
public void OpenAppUri(string appUri);
234253
}
235254
}

0 commit comments

Comments
 (0)