mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Merge dev
This commit is contained in:
commit
2b085dbcee
13 changed files with 73 additions and 31 deletions
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
|
|
@ -30,7 +30,7 @@ namespace Flow.Launcher.Infrastructure
|
||||||
|
|
||||||
public static string PythonPath;
|
public static string PythonPath;
|
||||||
|
|
||||||
public static readonly string QueryTextBoxIconImagePath = $"{ProgramDirectory}\\Images\\mainsearch.png";
|
public static readonly string QueryTextBoxIconImagePath = $"{ProgramDirectory}\\Images\\mainsearch.svg";
|
||||||
|
|
||||||
public const string DefaultTheme = "Darker";
|
public const string DefaultTheme = "Darker";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,23 +76,31 @@ namespace Flow.Launcher.Infrastructure.Http
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task Download([NotNull] string url, [NotNull] string filePath)
|
public static async Task DownloadAsync([NotNull] string url, [NotNull] string filePath)
|
||||||
{
|
{
|
||||||
using var response = await client.GetAsync(url);
|
try
|
||||||
if (response.StatusCode == HttpStatusCode.OK)
|
|
||||||
{
|
{
|
||||||
await using var fileStream = new FileStream(filePath, FileMode.CreateNew);
|
using var response = await client.GetAsync(url);
|
||||||
await response.Content.CopyToAsync(fileStream);
|
if (response.StatusCode == HttpStatusCode.OK)
|
||||||
|
{
|
||||||
|
await using var fileStream = new FileStream(filePath, FileMode.CreateNew);
|
||||||
|
await response.Content.CopyToAsync(fileStream);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new HttpRequestException($"Error code <{response.StatusCode}> returned from <{url}>");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
catch (HttpRequestException e)
|
||||||
{
|
{
|
||||||
throw new HttpRequestException($"Error code <{response.StatusCode}> returned from <{url}>");
|
Log.Exception("Infrastructure.Http", "Http Request Error", e, "DownloadAsync");
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Asynchrously get the result as string from url.
|
/// Asynchrously get the result as string from url.
|
||||||
/// When supposing the result is long and large, try using GetStreamAsync to avoid reading as string
|
/// When supposing the result larger than 83kb, try using GetStreamAsync to avoid reading as string
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="url"></param>
|
/// <param name="url"></param>
|
||||||
/// <returns>The Http result as string. Null if cancellation requested</returns>
|
/// <returns>The Http result as string. Null if cancellation requested</returns>
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,7 @@
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="PropertyChanged.Fody" Version="2.5.13" />
|
<PackageReference Include="PropertyChanged.Fody" Version="2.5.13" />
|
||||||
|
<PackageReference Include="SharpVectors" Version="1.7.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
10
Flow.Launcher/Images/mainsearch.svg
Normal file
10
Flow.Launcher/Images/mainsearch.svg
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||||
|
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="1200px" height="1200px" viewBox="0 0 12000 12000" preserveAspectRatio="xMidYMid meet">
|
||||||
|
<g id="layer101" fill="#000000" stroke="none">
|
||||||
|
</g>
|
||||||
|
<g id="layer102" fill="#555555" stroke="none">
|
||||||
|
<path d="M10354 10962 c-28 -11 -75 -35 -105 -55 -33 -21 -773 -754 -1879 -1861 -1004 -1004 -1829 -1826 -1834 -1826 -4 0 -38 22 -75 48 -248 179 -578 351 -869 453 -398 139 -790 198 -1232 185 -748 -20 -1407 -259 -2020 -732 -209 -161 -508 -475 -676 -709 -270 -377 -476 -847 -567 -1295 -53 -261 -67 -406 -67 -700 0 -340 26 -556 105 -861 128 -499 376 -976 715 -1374 86 -101 312 -324 410 -406 521 -434 1162 -709 1830 -784 181 -20 577 -20 758 0 657 75 1252 323 1782 744 144 114 451 426 556 566 176 233 281 404 393 635 223 465 332 947 332 1470 0 394 -50 705 -174 1082 -53 160 -62 182 -135 343 -85 186 -212 407 -332 575 -28 39 -50 73 -50 78 0 4 826 833 1835 1842 1386 1386 1843 1849 1869 1894 21 34 42 90 52 134 14 64 15 85 4 146 -28 163 -140 311 -290 383 -69 34 -83 37 -180 40 -85 3 -115 0 -156 -15z m-5669 -3912 c529 -49 1009 -241 1415 -566 109 -88 296 -275 384 -384 667 -833 762 -1990 237 -2910 -352 -619 -923 -1053 -1621 -1234 -394 -101 -878 -101 -1270 1 -382 99 -690 253 -992 496 -501 402 -828 974 -930 1627 -31 194 -31 576 0 770 40 255 120 520 225 740 326 682 944 1192 1677 1383 157 41 275 61 480 80 81 8 293 6 395 -3z"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -72,7 +72,7 @@
|
||||||
<system:String x:Key="deleteCustomHotkeyWarning">Are you sure you want to delete {0} plugin hotkey?</system:String>
|
<system:String x:Key="deleteCustomHotkeyWarning">Are you sure you want to delete {0} plugin hotkey?</system:String>
|
||||||
<system:String x:Key="queryWindowShadowEffect">Query window shadow effect</system:String>
|
<system:String x:Key="queryWindowShadowEffect">Query window shadow effect</system:String>
|
||||||
<system:String x:Key="shadowEffectCPUUsage">Shadow effect has a substantial usage of GPU.</system:String>
|
<system:String x:Key="shadowEffectCPUUsage">Shadow effect has a substantial usage of GPU.</system:String>
|
||||||
<system:String x:Key="shadowEffectPerformance">Not recommended if you computer performance is limited.</system:String>
|
<system:String x:Key="shadowEffectPerformance">Not recommended if your computer performance is limited.</system:String>
|
||||||
|
|
||||||
<!--Setting Proxy-->
|
<!--Setting Proxy-->
|
||||||
<system:String x:Key="proxy">HTTP Proxy</system:String>
|
<system:String x:Key="proxy">HTTP Proxy</system:String>
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:converters="clr-namespace:Flow.Launcher.Converters"
|
xmlns:converters="clr-namespace:Flow.Launcher.Converters"
|
||||||
|
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="Flow Launcher"
|
Title="Flow Launcher"
|
||||||
Topmost="True"
|
Topmost="True"
|
||||||
|
|
@ -92,7 +93,8 @@
|
||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
</TextBox.ContextMenu>
|
</TextBox.ContextMenu>
|
||||||
</TextBox>
|
</TextBox>
|
||||||
<Image Source="{Binding Image, IsAsync=True}" Width="48" HorizontalAlignment="Right" />
|
<svgc:SvgControl Source="{Binding Image}" HorizontalAlignment="Right" Width="48" Height="48"
|
||||||
|
Background="Transparent"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Line x:Name="ProgressBar" HorizontalAlignment="Right"
|
<Line x:Name="ProgressBar" HorizontalAlignment="Right"
|
||||||
Style="{DynamicResource PendingLineStyle}" Visibility="{Binding ProgressBarVisibility, Mode=TwoWay}"
|
Style="{DynamicResource PendingLineStyle}" Visibility="{Binding ProgressBarVisibility, Mode=TwoWay}"
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
xmlns:userSettings="clr-namespace:Flow.Launcher.Infrastructure.UserSettings;assembly=Flow.Launcher.Infrastructure"
|
xmlns:userSettings="clr-namespace:Flow.Launcher.Infrastructure.UserSettings;assembly=Flow.Launcher.Infrastructure"
|
||||||
xmlns:sys="clr-namespace:System;assembly=mscorlib"
|
xmlns:sys="clr-namespace:System;assembly=mscorlib"
|
||||||
xmlns:ui="http://schemas.modernwpf.com/2019"
|
xmlns:ui="http://schemas.modernwpf.com/2019"
|
||||||
|
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
|
||||||
x:Class="Flow.Launcher.SettingWindow"
|
x:Class="Flow.Launcher.SettingWindow"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Icon="Images\app.png"
|
Icon="Images\app.png"
|
||||||
|
|
@ -252,7 +253,8 @@
|
||||||
Text="{DynamicResource hiThere}" IsReadOnly="True"
|
Text="{DynamicResource hiThere}" IsReadOnly="True"
|
||||||
Style="{DynamicResource QueryBoxStyle}"
|
Style="{DynamicResource QueryBoxStyle}"
|
||||||
Margin="18 0 56 0" />
|
Margin="18 0 56 0" />
|
||||||
<Image Source="{Binding ThemeImage}" HorizontalAlignment="Right" />
|
<svgc:SvgControl Source="{Binding ThemeImage}" Height="48" Width="48" HorizontalAlignment="Right"
|
||||||
|
Background="Transparent" />
|
||||||
<ContentControl Grid.Row="1">
|
<ContentControl Grid.Row="1">
|
||||||
<flowlauncher:ResultListBox DataContext="{Binding PreviewResults, Mode=OneTime}" Visibility="Visible" />
|
<flowlauncher:ResultListBox DataContext="{Binding PreviewResults, Mode=OneTime}" Visibility="Visible" />
|
||||||
</ContentControl>
|
</ContentControl>
|
||||||
|
|
|
||||||
|
|
@ -285,7 +285,7 @@ namespace Flow.Launcher.ViewModel
|
||||||
|
|
||||||
public string OpenResultCommandModifiers { get; private set; }
|
public string OpenResultCommandModifiers { get; private set; }
|
||||||
|
|
||||||
public ImageSource Image => ImageLoader.Load(Constant.QueryTextBoxIconImagePath);
|
public string Image => Constant.QueryTextBoxIconImagePath;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
|
@ -12,9 +13,9 @@ namespace Flow.Launcher.ViewModel
|
||||||
{
|
{
|
||||||
public class ResultViewModel : BaseModel
|
public class ResultViewModel : BaseModel
|
||||||
{
|
{
|
||||||
public class LazyAsync<T> : Lazy<Task<T>>
|
public class LazyAsync<T> : Lazy<ValueTask<T>>
|
||||||
{
|
{
|
||||||
private T defaultValue;
|
private readonly T defaultValue;
|
||||||
|
|
||||||
private readonly Action _updateCallback;
|
private readonly Action _updateCallback;
|
||||||
public new T Value
|
public new T Value
|
||||||
|
|
@ -23,21 +24,27 @@ namespace Flow.Launcher.ViewModel
|
||||||
{
|
{
|
||||||
if (!IsValueCreated)
|
if (!IsValueCreated)
|
||||||
{
|
{
|
||||||
base.Value.ContinueWith(_ =>
|
_ = Exercute(); // manually use callback strategy
|
||||||
{
|
|
||||||
_updateCallback();
|
|
||||||
});
|
|
||||||
|
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!base.Value.IsCompleted || base.Value.IsFaulted)
|
if (!base.Value.IsCompletedSuccessfully)
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
|
|
||||||
return base.Value.Result;
|
return base.Value.Result;
|
||||||
|
|
||||||
|
// If none of the variables captured by the local function are captured by other lambdas,
|
||||||
|
// the compiler can avoid heap allocations.
|
||||||
|
async ValueTask Exercute()
|
||||||
|
{
|
||||||
|
await base.Value.ConfigureAwait(false);
|
||||||
|
_updateCallback();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public LazyAsync(Func<Task<T>> factory, T defaultValue, Action updateCallback) : base(factory)
|
public LazyAsync(Func<ValueTask<T>> factory, T defaultValue, Action updateCallback) : base(factory)
|
||||||
{
|
{
|
||||||
if (defaultValue != null)
|
if (defaultValue != null)
|
||||||
{
|
{
|
||||||
|
|
@ -55,13 +62,13 @@ namespace Flow.Launcher.ViewModel
|
||||||
Result = result;
|
Result = result;
|
||||||
|
|
||||||
Image = new LazyAsync<ImageSource>(
|
Image = new LazyAsync<ImageSource>(
|
||||||
SetImage,
|
SetImage,
|
||||||
ImageLoader.DefaultImage,
|
ImageLoader.DefaultImage,
|
||||||
() =>
|
() =>
|
||||||
{
|
{
|
||||||
OnPropertyChanged(nameof(Image));
|
OnPropertyChanged(nameof(Image));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings = settings;
|
Settings = settings;
|
||||||
}
|
}
|
||||||
|
|
@ -82,7 +89,7 @@ namespace Flow.Launcher.ViewModel
|
||||||
|
|
||||||
public LazyAsync<ImageSource> Image { get; set; }
|
public LazyAsync<ImageSource> Image { get; set; }
|
||||||
|
|
||||||
private async Task<ImageSource> SetImage()
|
private async ValueTask<ImageSource> SetImage()
|
||||||
{
|
{
|
||||||
var imagePath = Result.IcoPath;
|
var imagePath = Result.IcoPath;
|
||||||
if (string.IsNullOrEmpty(imagePath) && Result.Icon != null)
|
if (string.IsNullOrEmpty(imagePath) && Result.Icon != null)
|
||||||
|
|
@ -94,7 +101,7 @@ namespace Flow.Launcher.ViewModel
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.Exception($"|ResultViewModel.Image|IcoPath is empty and exception when calling Icon() for result <{Result.Title}> of plugin <{Result.PluginDirectory}>", e);
|
Log.Exception($"|ResultViewModel.Image|IcoPath is empty and exception when calling Icon() for result <{Result.Title}> of plugin <{Result.PluginDirectory}>", e);
|
||||||
imagePath = Constant.MissingImgIcon;
|
return ImageLoader.DefaultImage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -438,7 +438,7 @@ namespace Flow.Launcher.ViewModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImageSource ThemeImage => ImageLoader.Load(Constant.QueryTextBoxIconImagePath);
|
public string ThemeImage => Constant.QueryTextBoxIconImagePath;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
|
||||||
Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin"),
|
Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin"),
|
||||||
Context.API.GetTranslation("plugin_pluginsmanager_please_wait"));
|
Context.API.GetTranslation("plugin_pluginsmanager_please_wait"));
|
||||||
|
|
||||||
await Http.Download(plugin.UrlDownload, filePath).ConfigureAwait(false);
|
await Http.DownloadAsync(plugin.UrlDownload, filePath).ConfigureAwait(false);
|
||||||
|
|
||||||
Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin"),
|
Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin"),
|
||||||
Context.API.GetTranslation("plugin_pluginsmanager_download_success"));
|
Context.API.GetTranslation("plugin_pluginsmanager_download_success"));
|
||||||
|
|
@ -214,11 +214,23 @@ namespace Flow.Launcher.Plugin.PluginsManager
|
||||||
|
|
||||||
Task.Run(async delegate
|
Task.Run(async delegate
|
||||||
{
|
{
|
||||||
await Http.Download(x.PluginNewUserPlugin.UrlDownload, downloadToFilePath).ConfigureAwait(false);
|
Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin"),
|
||||||
|
Context.API.GetTranslation("plugin_pluginsmanager_please_wait"));
|
||||||
|
|
||||||
|
await Http.DownloadAsync(x.PluginNewUserPlugin.UrlDownload, downloadToFilePath).ConfigureAwait(false);
|
||||||
|
|
||||||
|
Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin"),
|
||||||
|
Context.API.GetTranslation("plugin_pluginsmanager_download_success"));
|
||||||
|
|
||||||
Install(x.PluginNewUserPlugin, downloadToFilePath);
|
Install(x.PluginNewUserPlugin, downloadToFilePath);
|
||||||
|
|
||||||
Context.API.RestartApp();
|
Context.API.RestartApp();
|
||||||
});
|
}).ContinueWith(t =>
|
||||||
|
{
|
||||||
|
Log.Exception("PluginsManager", $"Update failed for {x.Name}", t.Exception.InnerException, "RequestUpdate");
|
||||||
|
Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
|
||||||
|
string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"), x.Name));
|
||||||
|
}, TaskContinuationOptions.OnlyOnFaulted);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
"Name": "Plugins Manager",
|
"Name": "Plugins Manager",
|
||||||
"Description": "Management of installing, uninstalling or updating Flow Launcher plugins",
|
"Description": "Management of installing, uninstalling or updating Flow Launcher plugins",
|
||||||
"Author": "Jeremy Wu",
|
"Author": "Jeremy Wu",
|
||||||
"Version": "1.4.0",
|
"Version": "1.4.1",
|
||||||
"Language": "csharp",
|
"Language": "csharp",
|
||||||
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
|
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
|
||||||
"ExecuteFileName": "Flow.Launcher.Plugin.PluginsManager.dll",
|
"ExecuteFileName": "Flow.Launcher.Plugin.PluginsManager.dll",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue