Merge pull request #740 from onesounds/PluginStore

Plugin store
This commit is contained in:
Jeremy Wu 2021-10-27 22:01:24 +11:00 committed by GitHub
commit f47de6b838
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 1499 additions and 540 deletions

View file

@ -0,0 +1,57 @@
using Flow.Launcher.Infrastructure.Http;
using Flow.Launcher.Infrastructure.Logger;
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
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 static readonly SemaphoreSlim manifestUpdateLock = new(1);
public static Task UpdateManifestAsync()
{
if (manifestUpdateLock.CurrentCount == 0)
{
return UpdateTask;
}
return UpdateTask = DownloadManifestAsync();
}
private async static Task DownloadManifestAsync()
{
try
{
await manifestUpdateLock.WaitAsync().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);
UserPlugins = await JsonSerializer.DeserializeAsync<List<UserPlugin>>(jsonStream).ConfigureAwait(false);
}
catch (Exception e)
{
Log.Exception("|PluginManagement.GetManifest|Encountered error trying to download plugins manifest", e);
UserPlugins = new List<UserPlugin>();
}
finally
{
manifestUpdateLock.Release();
}
}
}
}

View file

@ -1,7 +1,6 @@

namespace Flow.Launcher.Plugin.PluginsManager.Models
namespace Flow.Launcher.Core.ExternalPlugins
{
public class UserPlugin
public record UserPlugin
{
public string ID { get; set; }
public string Name { get; set; }
@ -12,5 +11,6 @@ namespace Flow.Launcher.Plugin.PluginsManager.Models
public string Website { get; set; }
public string UrlDownload { get; set; }
public string UrlSourceCode { get; set; }
public string IcoPath { get; set; }
}
}

View file

@ -99,8 +99,6 @@ namespace Flow.Launcher.Infrastructure.UserSettings
public bool RememberLastLaunchLocation { get; set; }
public bool IgnoreHotkeysOnFullscreen { get; set; }
public bool AutoHideScrollBar { get; set; }
public HttpProxy Proxy { get; set; } = new HttpProxy();
[JsonConverter(typeof(JsonStringEnumConverter))]

View file

@ -60,8 +60,13 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Fody" Version="6.5.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
<PackageReference Include="JetBrains.Annotations" Version="2021.2.0" />
<PackageReference Include="PropertyChanged.Fody" Version="3.4.0" />
</ItemGroup>
</Project>

View file

@ -59,6 +59,11 @@ namespace Flow.Launcher.Plugin
/// <param name="subTitle">Optional message subtitle</param>
void ShowMsgError(string title, string subTitle = "");
/// <summary>
/// Show the MainWindow when hiding
/// </summary>
void ShowMainWindow();
/// <summary>
/// Show message box
/// </summary>

View file

@ -44,7 +44,7 @@ namespace Flow.Launcher
var oldActionKeyword = plugin.Metadata.ActionKeywords[0];
var newActionKeyword = tbAction.Text.Trim();
newActionKeyword = newActionKeyword.Length > 0 ? newActionKeyword : "*";
if (!pluginViewModel.IsActionKeywordRegistered(newActionKeyword))
if (!PluginViewModel.IsActionKeywordRegistered(newActionKeyword))
{
pluginViewModel.ChangeActionKeyword(newActionKeyword, oldActionKeyword);
Close();

View file

@ -6,6 +6,227 @@
Startup="OnStartupAsync">
<Application.Resources>
<ResourceDictionary>
<!--#region Expander for Setting Window-->
<Style x:Key="ExpanderRightHeaderStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Padding="{TemplateBinding Padding}">
<Grid Background="Transparent" SnapsToDevicePixels="False">
<Grid.RowDefinitions>
<RowDefinition Height="19"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid>
<Grid.LayoutTransform>
<TransformGroup>
<TransformGroup.Children>
<TransformCollection>
<RotateTransform Angle="-90"/>
</TransformCollection>
</TransformGroup.Children>
</TransformGroup>
</Grid.LayoutTransform>
<Ellipse x:Name="circle" HorizontalAlignment="Center" Height="19" Stroke="DarkGray" VerticalAlignment="Center" Width="19"/>
<Path x:Name="arrow" Data="M 1,1.5 L 4.5,5 L 8,1.5" HorizontalAlignment="Center" SnapsToDevicePixels="false" Stroke="#666" StrokeThickness="2" VerticalAlignment="Center"/>
</Grid>
<ContentPresenter HorizontalAlignment="Center" Margin="0,4,0,0" Grid.Row="1" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Top"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Data" TargetName="arrow" Value="M 1,4.5 L 4.5,1 L 8,4.5"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Stroke" TargetName="circle" Value="#FF3C7FB1"/>
<Setter Property="Stroke" TargetName="arrow" Value="#222"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Stroke" TargetName="circle" Value="#FF526C7B"/>
<Setter Property="StrokeThickness" TargetName="circle" Value="1.5"/>
<Setter Property="Stroke" TargetName="arrow" Value="#FF003366"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ExpanderUpHeaderStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Padding="{TemplateBinding Padding}">
<Grid Background="Transparent" SnapsToDevicePixels="False">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="19"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid>
<Grid.LayoutTransform>
<TransformGroup>
<TransformGroup.Children>
<TransformCollection>
<RotateTransform Angle="180"/>
</TransformCollection>
</TransformGroup.Children>
</TransformGroup>
</Grid.LayoutTransform>
<Ellipse x:Name="circle" HorizontalAlignment="Center" Height="19" Stroke="Transparent" VerticalAlignment="Center" Width="19"/>
<Path x:Name="arrow" Data="M 1,1.5 L 4.5,5 L 8,1.5" HorizontalAlignment="Center" SnapsToDevicePixels="false" Stroke="#666" StrokeThickness="1" VerticalAlignment="Center"/>
</Grid>
<ContentPresenter Grid.Column="1" HorizontalAlignment="Left" Margin="4,0,0,0" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Center"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Data" TargetName="arrow" Value="M 1,4.5 L 4.5,1 L 8,4.5"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Stroke" TargetName="circle" Value="Transparent"/>
<Setter Property="Stroke" TargetName="arrow" Value="#222"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Stroke" TargetName="circle" Value="Transparent"/>
<Setter Property="StrokeThickness" TargetName="circle" Value="1.5"/>
<Setter Property="Stroke" TargetName="arrow" Value="#FF003366"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ExpanderLeftHeaderStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Padding="{TemplateBinding Padding}">
<Grid Background="Transparent" SnapsToDevicePixels="False">
<Grid.RowDefinitions>
<RowDefinition Height="19"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid>
<Grid.LayoutTransform>
<TransformGroup>
<TransformGroup.Children>
<TransformCollection>
<RotateTransform Angle="90"/>
</TransformCollection>
</TransformGroup.Children>
</TransformGroup>
</Grid.LayoutTransform>
<Ellipse x:Name="circle" HorizontalAlignment="Center" Height="19" Stroke="DarkGray" VerticalAlignment="Center" Width="19"/>
<Path x:Name="arrow" Data="M 1,1.5 L 4.5,5 L 8,1.5" HorizontalAlignment="Center" SnapsToDevicePixels="false" Stroke="#666" StrokeThickness="2" VerticalAlignment="Center"/>
</Grid>
<ContentPresenter HorizontalAlignment="Center" Margin="0,4,0,0" Grid.Row="1" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Top"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Data" TargetName="arrow" Value="M 1,4.5 L 4.5,1 L 8,4.5"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Stroke" TargetName="circle" Value="#FF3C7FB1"/>
<Setter Property="Stroke" TargetName="arrow" Value="#222"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Stroke" TargetName="circle" Value="#FF526C7B"/>
<Setter Property="StrokeThickness" TargetName="circle" Value="1.5"/>
<Setter Property="Stroke" TargetName="arrow" Value="#FF003366"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ExpanderHeaderFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Border>
<Rectangle Margin="0" SnapsToDevicePixels="true" Stroke="Black" StrokeThickness="1" StrokeDashArray="1 2"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ExpanderDownHeaderStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Padding="{TemplateBinding Padding}">
<Grid Background="Transparent" SnapsToDevicePixels="False">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="19"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Ellipse x:Name="circle" HorizontalAlignment="Center" Height="19" Stroke="Transparent" VerticalAlignment="Center" Width="19"/>
<Path x:Name="arrow" Data="M 1,1.5 L 4.5,5 L 8,1.5" HorizontalAlignment="Center" SnapsToDevicePixels="false" Stroke="#666" StrokeThickness="1" VerticalAlignment="Center"/>
<ContentPresenter Grid.Column="1" HorizontalAlignment="Left" Margin="4,0,0,0" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Center"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Data" TargetName="arrow" Value="M 1,4.5 L 4.5,1 L 8,4.5"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Stroke" TargetName="circle" Value="Transparent"/>
<Setter Property="Stroke" TargetName="arrow" Value="#222"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Stroke" TargetName="circle" Value="Transparent"/>
<Setter Property="StrokeThickness" TargetName="circle" Value="1.5"/>
<Setter Property="Stroke" TargetName="arrow" Value="#FF003366"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ExpanderStyle1" TargetType="{x:Type Expander}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="3" SnapsToDevicePixels="true">
<DockPanel>
<ToggleButton x:Name="HeaderSite" ContentTemplate="{TemplateBinding HeaderTemplate}" ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}" Content="{TemplateBinding Header}" DockPanel.Dock="Top" Foreground="{TemplateBinding Foreground}" FontWeight="{TemplateBinding FontWeight}" FocusVisualStyle="{StaticResource ExpanderHeaderFocusVisual}" FontStyle="{TemplateBinding FontStyle}" FontStretch="{TemplateBinding FontStretch}" FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Margin="18 0 0 0" MinWidth="0" MinHeight="0" Padding="{TemplateBinding Padding}" Style="{StaticResource ExpanderDownHeaderStyle}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<ContentPresenter x:Name="ExpandSite" DockPanel.Dock="Bottom" Focusable="false" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" Visibility="Collapsed" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</DockPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="true">
<Setter Property="Visibility" TargetName="ExpandSite" Value="Visible"/>
</Trigger>
<Trigger Property="ExpandDirection" Value="Right">
<Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Right"/>
<Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Left"/>
<Setter Property="Style" TargetName="HeaderSite" Value="{StaticResource ExpanderRightHeaderStyle}"/>
</Trigger>
<Trigger Property="ExpandDirection" Value="Up">
<Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Top"/>
<Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Bottom"/>
<Setter Property="Style" TargetName="HeaderSite" Value="{StaticResource ExpanderUpHeaderStyle}"/>
</Trigger>
<Trigger Property="ExpandDirection" Value="Left">
<Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Left"/>
<Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Right"/>
<Setter Property="Style" TargetName="HeaderSite" Value="{StaticResource ExpanderLeftHeaderStyle}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--#endregion-->
<ResourceDictionary.MergedDictionaries>
<ui:ThemeResources RequestedTheme="Light" />
<ui:XamlControlsResources />

View file

@ -83,6 +83,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Fody" Version="6.5.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="InputSimulator" Version="1.0.4" />
<PackageReference Include="ModernWpfUI" Version="0.9.4" />
<PackageReference Include="NHotkey.Wpf" Version="2.1.0" />

View file

@ -13,50 +13,59 @@
<system:String x:Key="iconTraySettings">Settings</system:String>
<system:String x:Key="iconTrayAbout">About</system:String>
<system:String x:Key="iconTrayExit">Exit</system:String>
<system:String x:Key="closeWindow">Close</system:String>
<!--Setting General-->
<system:String x:Key="flowlauncher_settings">Flow Launcher Settings</system:String>
<system:String x:Key="general">General</system:String>
<system:String x:Key="portableMode">Portable Mode</system:String>
<system:String x:Key="portableModeToolTIp">Store all settings and user data in one folder (Useful when used with removable drives or cloud services).</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">Start Flow Launcher on system startup</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">Hide Flow Launcher when focus is lost</system:String>
<system:String x:Key="dontPromptUpdateMsg">Do not show new version notifications</system:String>
<system:String x:Key="rememberLastLocation">Remember last launch location</system:String>
<system:String x:Key="language">Language</system:String>
<system:String x:Key="lastQueryMode">Last Query Style</system:String>
<system:String x:Key="lastQueryModeToolTip">Show/Hide previous results when Flow Launcher is reactivated.</system:String>
<system:String x:Key="LastQueryPreserved">Preserve Last Query</system:String>
<system:String x:Key="LastQuerySelected">Select last Query</system:String>
<system:String x:Key="LastQueryEmpty">Empty last Query</system:String>
<system:String x:Key="maxShowResults">Maximum results shown</system:String>
<system:String x:Key="ignoreHotkeysOnFullscreen">Ignore hotkeys in fullscreen mode</system:String>
<system:String x:Key="ignoreHotkeysOnFullscreenToolTip">Disable Flow Launcher activation when a full screen application is active (Recommended for games).</system:String>
<system:String x:Key="pythonDirectory">Python Directory</system:String>
<system:String x:Key="autoUpdates">Auto Update</system:String>
<system:String x:Key="autoHideScrollBar">Auto Hide Scroll Bar</system:String>
<system:String x:Key="autoHideScrollBarToolTip">Automatically hides the Settings window scroll bar and show when hover the mouse over it</system:String>
<system:String x:Key="selectPythonDirectory">Select</system:String>
<system:String x:Key="hideOnStartup">Hide Flow Launcher on startup</system:String>
<system:String x:Key="hideNotifyIcon">Hide tray icon</system:String>
<system:String x:Key="querySearchPrecision">Query Search Precision</system:String>
<system:String x:Key="querySearchPrecisionToolTip">Changes minimum match score required for results.</system:String>
<system:String x:Key="ShouldUsePinyin">Should Use Pinyin</system:String>
<system:String x:Key="ShouldUsePinyinToolTip">Allows using Pinyin to search. Pinyin is the standard system of romanized spelling for translating Chinese</system:String>
<system:String x:Key="shadowEffectNotAllowed">Shadow effect is not allowed while current theme has blur effect enabled</system:String>
<!--Setting Plugin-->
<system:String x:Key="plugin">Plugin</system:String>
<system:String x:Key="plugin">Plugins</system:String>
<system:String x:Key="browserMorePlugins">Find more plugins</system:String>
<system:String x:Key="enable">Enable</system:String>
<system:String x:Key="disable">Disable</system:String>
<system:String x:Key="actionKeywords">Action keyword:</system:String>
<system:String x:Key="enable">On</system:String>
<system:String x:Key="disable">Off</system:String>
<system:String x:Key="actionKeywords">Action keyword</system:String>
<system:String x:Key="currentActionKeywords">Current action keyword:</system:String>
<system:String x:Key="newActionKeyword">New action keyword:</system:String>
<system:String x:Key="currentPriority">Current Priority:</system:String>
<system:String x:Key="newPriority">New Priority:</system:String>
<system:String x:Key="priority">Priority:</system:String>
<system:String x:Key="priority">Priority</system:String>
<system:String x:Key="pluginDirectory">Plugin Directory</system:String>
<system:String x:Key="author">Author</system:String>
<system:String x:Key="author">Author:</system:String>
<system:String x:Key="plugin_init_time">Init time:</system:String>
<system:String x:Key="plugin_query_time">Query time:</system:String>
<!--Setting Plugin Store-->
<system:String x:Key="pluginStore">Plugin Store</system:String>
<system:String x:Key="refresh">Refresh</system:String>
<system:String x:Key="install">Install</system:String>
<!--Setting Theme-->
<system:String x:Key="theme">Theme</system:String>
<system:String x:Key="browserMoreThemes">Browse for more themes</system:String>
@ -67,12 +76,17 @@
<system:String x:Key="opacity">Opacity</system:String>
<system:String x:Key="theme_load_failure_path_not_exists">Theme {0} not exists, fallback to default theme</system:String>
<system:String x:Key="theme_load_failure_parse_error">Fail to load theme {0}, fallback to default theme</system:String>
<system:String x:Key="ThemeFolder">Theme Folder</system:String>
<system:String x:Key="OpenThemeFolder">Open Theme Folder</system:String>
<!--Setting Hotkey-->
<system:String x:Key="hotkey">Hotkey</system:String>
<system:String x:Key="flowlauncherHotkey">Flow Launcher Hotkey</system:String>
<system:String x:Key="openResultModifiers">Open Result Modifiers</system:String>
<system:String x:Key="flowlauncherHotkeyToolTip">Enter shortcut to show/hide Flow Launcher.</system:String>
<system:String x:Key="openResultModifiers">Open Result Modifier Key</system:String>
<system:String x:Key="openResultModifiersToolTip">Select a modifier key to open selected result via keyboard.</system:String>
<system:String x:Key="showOpenResultHotkey">Show Hotkey</system:String>
<system:String x:Key="showOpenResultHotkeyToolTip">Show result selection hotkey with results.</system:String>
<system:String x:Key="customQueryHotkey">Custom Query Hotkey</system:String>
<system:String x:Key="customQuery">Query</system:String>
<system:String x:Key="delete">Delete</system:String>
@ -117,6 +131,7 @@
<system:String x:Key="documentation">Usage Tips:</system:String>
<!--Priority Setting Dialog-->
<system:String x:Key="changePriorityWindow">Change Priority</system:String>
<system:String x:Key="priority_tips">Greater the number, the higher the result will be ranked. Try setting it as 5. If you want the results to be lower than any other plugin's, provide a negative number</system:String>
<system:String x:Key="invalidPriority">Please provide an valid integer for Priority!</system:String>
@ -180,4 +195,4 @@
<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>
</ResourceDictionary>
</ResourceDictionary>

View file

@ -13,55 +13,90 @@
<system:String x:Key="iconTraySettings">설정</system:String>
<system:String x:Key="iconTrayAbout">정보</system:String>
<system:String x:Key="iconTrayExit">종료</system:String>
<system:String x:Key="closeWindow">닫기</system:String>
<!--Setting General-->
<system:String x:Key="flowlauncher_settings">Flow Launcher 설정</system:String>
<system:String x:Key="general">일반</system:String>
<system:String x:Key="portableMode">포터블 모드</system:String>
<system:String x:Key="portableModeToolTIp">모든 설정이 폴더안에 들어갑니다. USB 드라이브나 클라우드로 사용 가능합니다.</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">시스템 시작 시 Flow Launcher 실행</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">포커스 잃으면 Flow Launcher 숨김</system:String>
<system:String x:Key="dontPromptUpdateMsg">새 버전 알림 끄기</system:String>
<system:String x:Key="rememberLastLocation">마지막 실행 위치 기억</system:String>
<system:String x:Key="language">언어</system:String>
<system:String x:Key="lastQueryMode">마지막 쿼리 스타일</system:String>
<system:String x:Key="lastQueryModeToolTip">쿼리박스를 열었을 때 쿼리 처리 방식</system:String>
<system:String x:Key="LastQueryPreserved">직전 쿼리에 계속 입력</system:String>
<system:String x:Key="LastQuerySelected">직전 쿼리 내용 선택</system:String>
<system:String x:Key="LastQueryEmpty">직전 쿼리 지우기</system:String>
<system:String x:Key="maxShowResults">표시할 결과 수</system:String>
<system:String x:Key="ignoreHotkeysOnFullscreen">전체화면 모드에서는 핫키 무시</system:String>
<system:String x:Key="ignoreHotkeysOnFullscreenToolTip">게이머라면 켜는 것을 추천합니다.</system:String>
<system:String x:Key="pythonDirectory">Python 디렉토리</system:String>
<system:String x:Key="autoUpdates">자동 업데이트</system:String>
<system:String x:Key="selectPythonDirectory">선택</system:String>
<system:String x:Key="hideOnStartup">시작 시 Flow Launcher 숨김</system:String>
<system:String x:Key="hideNotifyIcon">트레이 아이콘 숨기기</system:String>
<system:String x:Key="querySearchPrecision">쿼리 검색 정확도</system:String>
<system:String x:Key="querySearchPrecisionToolTip">검색 결과가 좀 더 정확해집니다.</system:String>
<system:String x:Key="ShouldUsePinyin">항상 Pinyin 사용</system:String>
<system:String x:Key="ShouldUsePinyinToolTip">Pinyin을 사용하여 검색할 수 있습니다. Pinyin(병음)은 로마자 중국어 입력 방식입니다.</system:String>
<system:String x:Key="shadowEffectNotAllowed">반투명 흐림 효과를 사용하는 경우, 그림자 효과를 쓸 수 없습니다.</system:String>
<!--Setting Plugin-->
<system:String x:Key="plugin">플러그인</system:String>
<system:String x:Key="browserMorePlugins">플러그인 더 찾아보기</system:String>
<system:String x:Key="disable">비활성화</system:String>
<system:String x:Key="enable">On</system:String>
<system:String x:Key="disable">Off</system:String>
<system:String x:Key="actionKeywords">액션 키워드</system:String>
<system:String x:Key="currentPriority">현재 중요도:</system:String>
<system:String x:Key="newPriority">새 중요도:</system:String>
<system:String x:Key="priority">중요도</system:String>
<system:String x:Key="pluginDirectory">플러그인 디렉토리</system:String>
<system:String x:Key="author">저자</system:String>
<system:String x:Key="plugin_init_time">초기화 시간:</system:String>
<system:String x:Key="plugin_query_time">쿼리 시간:</system:String>
<!--Setting Plugin Store-->
<system:String x:Key="pluginStore">플러그인 스토어</system:String>
<system:String x:Key="refresh">새로고침</system:String>
<system:String x:Key="install">설치</system:String>
<!--Setting Theme-->
<system:String x:Key="theme">테마</system:String>
<system:String x:Key="browserMoreThemes">테마 더 찾아보기</system:String>
<system:String x:Key="hiThere">Hi There</system:String>
<system:String x:Key="queryBoxFont">쿼리 상자 글꼴</system:String>
<system:String x:Key="resultItemFont">결과 항목 글꼴</system:String>
<system:String x:Key="windowMode">윈도우 모드</system:String>
<system:String x:Key="opacity">투명도</system:String>
<system:String x:Key="theme_load_failure_path_not_exists">{0} 테마가 존재하지 않습니다. 기본 테마로 변경합니다.</system:String>
<system:String x:Key="theme_load_failure_parse_error">{0} 테마 로드에 실패했습니다. 기본 테마로 변경합니다.</system:String>
<system:String x:Key="ThemeFolder">테마 폴더</system:String>
<system:String x:Key="OpenThemeFolder">테마 폴더 열기</system:String>
<!--Setting Hotkey-->
<system:String x:Key="hotkey">핫키</system:String>
<system:String x:Key="flowlauncherHotkey">Flow Launcher 핫키</system:String>
<system:String x:Key="openResultModifiers">결과 수정 자 열기</system:String>
<system:String x:Key="customQueryHotkey">사용자지정 쿼리 핫키</system:String>
<system:String x:Key="flowlauncherHotkeyToolTip">Flow Launcher를 열 때 사용할 단축키를 입력합니다.</system:String>
<system:String x:Key="openResultModifiers">결과 선택 단축키</system:String>
<system:String x:Key="openResultModifiersToolTip">결과 목록을 선택하는 단축키입니다.</system:String>
<system:String x:Key="showOpenResultHotkey">단축키 표시</system:String>
<system:String x:Key="showOpenResultHotkeyToolTip">결과창에서 결과 선택 단축키를 표시합니다.</system:String>
<system:String x:Key="customQueryHotkey">사용자지정 쿼리 핫키</system:String>
<system:String x:Key="customQuery">Query</system:String>
<system:String x:Key="delete">삭제</system:String>
<system:String x:Key="edit">편집</system:String>
<system:String x:Key="add">추가</system:String>
<system:String x:Key="pleaseSelectAnItem">항목을 선택하세요.</system:String>
<system:String x:Key="deleteCustomHotkeyWarning">{0} 플러그인 핫키를 삭제하시겠습니까?</system:String>
<system:String x:Key="queryWindowShadowEffect">그림자 효과</system:String>
<system:String x:Key="shadowEffectCPUUsage">그림자 효과는 GPU를 사용합니다. 컴퓨터 퍼포먼스가 제한적인 경우 사용을 추천하지 않습니다.</system:String>
<system:String x:Key="useGlyphUI">플루언트 아이콘 사용</system:String>
<system:String x:Key="useGlyphUIEffect">결과 및 일부 메뉴에서 플루언트 아이콘을 사용합니다.</system:String>
<!--Setting Proxy-->
<system:String x:Key="proxy">HTTP 프록시</system:String>
@ -86,8 +121,18 @@
<system:String x:Key="about_activate_times">Flow Launcher를 {0}번 실행했습니다.</system:String>
<system:String x:Key="checkUpdates">업데이트 확인</system:String>
<system:String x:Key="newVersionTips">새 버전({0})이 있습니다. Flow Launcher를 재시작하세요.</system:String>
<system:String x:Key="checkUpdatesFailed">업데이트 확인을 실패했습니다. api.github.com로의 연결 또는 프록시 설정을 확인해주세요.</system:String>
<system:String x:Key="downloadUpdatesFailed">
업데이트 다운로드에 실패했습니다. github-cloud.s3.amazonaws.com의 연결 또는 프록시 설정을 확인해주세요.
수동 다운로드를 하려면 https://github.com/Flow-Launcher/Flow.Launcher/releases 으로 방문하세요.
</system:String>
<system:String x:Key="releaseNotes">릴리즈 노트:</system:String>
<system:String x:Key="documentation">사용 팁:</system:String>
<!--Priority Setting Dialog-->
<system:String x:Key="changePriorityWindow">중요도 변경</system:String>
<system:String x:Key="priority_tips">높은 수를 넣을수록 상위 결과에 표시됩니다. 5를 시도해보세요. 다른 플러그인 보다 결과를 낮추고 싶다면, 그보다 낮은 수를 입력하세요.</system:String>
<system:String x:Key="invalidPriority">중요도에 올바른 정수를 입력하세요.</system:String>
<!--Action Keyword Setting Dialog-->
<system:String x:Key="oldActionKeywords">예전 액션 키워드</system:String>
<system:String x:Key="newActionKeywords">새 액션 키워드</system:String>
@ -97,9 +142,11 @@
<system:String x:Key="newActionKeywordsCannotBeEmpty">새 액션 키워드를 입력하세요.</system:String>
<system:String x:Key="newActionKeywordsHasBeenAssigned">새 액션 키워드가 할당된 플러그인이 이미 있습니다. 다른 액션 키워드를 입력하세요.</system:String>
<system:String x:Key="success">성공</system:String>
<system:String x:Key="completedSuccessfully">성공적으로 완료했습니다.</system:String>
<system:String x:Key="actionkeyword_tips">액션 키워드를 지정하지 않으려면 *를 사용하세요.</system:String>
<!--Custom Query Hotkey Dialog-->
<system:String x:Key="customeQueryHotkeyTitle">커스텀 플러그인 핫키</system:String>
<system:String x:Key="preview">미리보기</system:String>
<system:String x:Key="hotkeyIsNotUnavailable">핫키를 사용할 수 없습니다. 다른 핫키를 입력하세요.</system:String>
<system:String x:Key="invalidPluginHotkey">플러그인 핫키가 유효하지 않습니다.</system:String>
@ -123,12 +170,23 @@
<system:String x:Key="reportWindow_report_succeed">보고서를 정상적으로 보냈습니다.</system:String>
<system:String x:Key="reportWindow_report_failed">보고서를 보내지 못했습니다.</system:String>
<system:String x:Key="reportWindow_flowlauncher_got_an_error">Flow Launcher에 문제가 발생했습니다.</system:String>
<!--General Notice-->
<system:String x:Key="pleaseWait">잠시 기다려주세요...</system:String>
<!--update-->
<system:String x:Key="update_flowlauncher_update_check">새 업데이트 확인 중</system:String>
<system:String x:Key="update_flowlauncher_update_new_version_available">새 Flow Launcher 버전({0})을 사용할 수 있습니다.</system:String>
<system:String x:Key="update_flowlauncher_already_on_latest">이미 가장 최신 버전의 Flow Launcher를 사용중입니다.</system:String>
<system:String x:Key="update_flowlauncher_update_found">업데이트 발견</system:String>
<system:String x:Key="update_flowlauncher_updating">업데이트 중...</system:String>
<system:String x:Key="update_flowlauncher_fail_moving_portable_user_profile_data">Flow Launcher가 유저 정보 데이터를 새버전으로 옮길 수 없습니다.
프로필 데이터 폴더를 수동으로 {0} 에서 {1}로 옮겨주세요. </system:String>
<system:String x:Key="update_flowlauncher_new_update">새 업데이트</system:String>
<system:String x:Key="update_flowlauncher_update_error">소프트웨어 업데이트를 설치하는 중에 오류가 발생했습니다.</system:String>
<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_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_files">업데이트 파일</system:String>

View file

@ -31,8 +31,6 @@
<system:String x:Key="ignoreHotkeysOnFullscreen">Ignorovať klávesové skratky v režime na celú obrazovku</system:String>
<system:String x:Key="pythonDirectory">Priečinok s Pythonom</system:String>
<system:String x:Key="autoUpdates">Automatická aktualizácia</system:String>
<system:String x:Key="autoHideScrollBar">Automaticky skryť posuvník</system:String>
<system:String x:Key="autoHideScrollBarToolTip">Automaticky skrývať posuvník v okne nastavení a zobraziť ho, keď naň prejdete myšou</system:String>
<system:String x:Key="selectPythonDirectory">Vybrať</system:String>
<system:String x:Key="hideOnStartup">Schovať Flow Launcher po spustení</system:String>
<system:String x:Key="hideNotifyIcon">Schovať ikonu z oblasti oznámení</system:String>

View file

@ -92,7 +92,7 @@
<MenuItem Command="ApplicationCommands.Paste"/>
<Separator />
<MenuItem Header="{DynamicResource flowlauncher_settings}" Click="OnContextMenusForSettingsClick" />
<MenuItem Command="{Binding EscCommand}" Header="Close"/>
<MenuItem Command="{Binding EscCommand}" Header="{DynamicResource closeWindow}"/>
</ContextMenu>
</TextBox.ContextMenu>
</TextBox>

View file

@ -7,37 +7,51 @@
Loaded="PriorityChangeWindow_Loaded"
mc:Ignorable="d"
WindowStartupLocation="CenterScreen"
Title="PriorityChangeWindow" Height="250" Width="300">
Title="{DynamicResource changePriorityWindow}" Height="400" Width="350" ResizeMode="NoResize" Background="#f3f3f3">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="60"/>
<RowDefinition Height="75"/>
<RowDefinition />
<RowDefinition />
<RowDefinition Height="80"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock FontSize="14" Grid.Row="0" Grid.Column="1" VerticalAlignment="Center"
HorizontalAlignment="Left" Text="{DynamicResource currentPriority}" />
<TextBlock x:Name="OldPriority" Grid.Row="0" Grid.Column="1" Margin="170 10 10 10" FontSize="14"
VerticalAlignment="Center" HorizontalAlignment="Left" />
<TextBlock FontSize="14" Grid.Row="1" Grid.Column="1" VerticalAlignment="Center"
HorizontalAlignment="Left" Text="{DynamicResource newPriority}" />
<StackPanel Grid.Row="1" Orientation="Horizontal" Grid.Column="1">
<TextBox x:Name="tbAction" Margin="140 10 15 10" Width="105" VerticalAlignment="Center" HorizontalAlignment="Left" />
<StackPanel Grid.Row="0" VerticalAlignment="Center">
<TextBlock Grid.Column="0" FontFamily="/Resources/#Segoe Fluent Icons" FontSize="40" TextAlignment="Center"
Margin="0 0 0 0">
&#xe8d0;
</TextBlock>
</StackPanel>
<TextBlock Grid.Row="2" Grid.ColumnSpan="1" Grid.Column="1" Foreground="Gray"
Text="{DynamicResource priority_tips}" TextWrapping="Wrap"
Margin="0,0,20,0"/>
<Border Background="#ffffff" Grid.Row="1" BorderBrush="#cecece" BorderThickness="1" Margin="14 0 14 0" Padding="0 14 0 0" CornerRadius="5">
<StackPanel Orientation="Vertical" >
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Grid.Row="1">
<TextBlock FontSize="14" Grid.Column="1" VerticalAlignment="Center"
HorizontalAlignment="Left" Text="{DynamicResource currentPriority}" />
<TextBlock x:Name="OldPriority" Grid.Row="0" Grid.Column="1" Margin="14 0 10 0" FontSize="14"
VerticalAlignment="Center" HorizontalAlignment="Left" FontWeight="Bold" />
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Grid.Row="3" Grid.Column="1">
<Button x:Name="btnCancel" Click="BtnCancel_OnClick" Margin="10 0 10 0" Width="80" Height="30"
<StackPanel Orientation="Horizontal" Grid.Column="1" HorizontalAlignment="Center">
<TextBlock FontSize="14" VerticalAlignment="Center"
HorizontalAlignment="Right" Text="{DynamicResource newPriority}" />
<TextBox x:Name="tbAction" Margin="14 10 15 10" Width="105" VerticalAlignment="Center" HorizontalAlignment="Left" />
</StackPanel>
</StackPanel>
</Border>
<StackPanel Grid.Row="2" VerticalAlignment="Center">
<TextBlock Foreground="Gray"
Text="{DynamicResource priority_tips}" TextWrapping="WrapWithOverflow" TextAlignment="Center"
Margin="20,0,20,0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Grid.Row="3" Grid.Column="1">
<Button x:Name="btnCancel" Click="BtnCancel_OnClick" Margin="0 0 10 0" Width="80" Height="30"
Content="{DynamicResource cancel}" />
<Button x:Name="btnDone" Margin="10 0 10 0" Width="80" Height="30" Click="btnDone_OnClick">
<Button x:Name="btnDone" Margin="10 0 0 0" Width="80" Height="30" Click="btnDone_OnClick">
<TextBlock x:Name="lblAdd" Text="{DynamicResource done}" />
</Button>
</StackPanel>

View file

@ -68,6 +68,8 @@ namespace Flow.Launcher
public void RestarApp() => RestartApp();
public void ShowMainWindow() => _mainVM.MainWindowVisibility = Visibility.Visible;
public void CheckForNewUpdate() => _settingsVM.UpdateApp();
public void SaveAppAllSettings()

File diff suppressed because it is too large Load diff

View file

@ -13,6 +13,8 @@ using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.ViewModel;
using Flow.Launcher.Helper;
using System.Windows.Controls;
using Flow.Launcher.Core.ExternalPlugins;
namespace Flow.Launcher
{
@ -185,23 +187,20 @@ namespace Flow.Launcher
settings.PluginSettings.Plugins[id].Disabled = viewModel.SelectedPlugin.PluginPair.Metadata.Disabled;
}
private void OnPluginPriorityClick(object sender, MouseButtonEventArgs e)
private void OnPluginPriorityClick(object sender, RoutedEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
if (sender is Control { DataContext: PluginViewModel pluginViewModel })
{
PriorityChangeWindow priorityChangeWindow = new PriorityChangeWindow(viewModel.SelectedPlugin.PluginPair.Metadata.ID, settings, viewModel.SelectedPlugin);
PriorityChangeWindow priorityChangeWindow = new PriorityChangeWindow(pluginViewModel.PluginPair.Metadata.ID, settings, pluginViewModel);
priorityChangeWindow.ShowDialog();
}
}
private void OnPluginActionKeywordsClick(object sender, MouseButtonEventArgs e)
private void OnPluginActionKeywordsClick(object sender, RoutedEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
var id = viewModel.SelectedPlugin.PluginPair.Metadata.ID;
ActionKeywords changeKeywordsWindow = new ActionKeywords(id, settings, viewModel.SelectedPlugin);
changeKeywordsWindow.ShowDialog();
}
var id = viewModel.SelectedPlugin.PluginPair.Metadata.ID;
ActionKeywords changeKeywordsWindow = new ActionKeywords(id, settings, viewModel.SelectedPlugin);
changeKeywordsWindow.ShowDialog();
}
private void OnPluginNameClick(object sender, MouseButtonEventArgs e)
@ -267,5 +266,20 @@ namespace Flow.Launcher
FilesFolders.OpenPath(Path.Combine(DataLocation.DataDirectory(), Constant.Themes));
}
private void OnPluginStoreRefreshClick(object sender, RoutedEventArgs e)
{
_ = viewModel.RefreshExternalPluginsAsync();
}
private void OnExternalPluginInstallClick(object sender, RoutedEventArgs e)
{
if(sender is Button { DataContext: UserPlugin plugin })
{
var pluginsManagerPlugin = PluginManager.GetPluginForId("9f8f9b14-2518-4907-b211-35ab6290dee7");
var actionKeywrod = pluginsManagerPlugin.Metadata.ActionKeywords.Count == 0 ? "" : pluginsManagerPlugin.Metadata.ActionKeywords[0];
API.ChangeQuery($"{actionKeywrod} install {plugin.Name}");
API.ShowMainWindow();
}
}
}
}

View file

@ -3,24 +3,39 @@ using System.Windows.Media;
using Flow.Launcher.Plugin;
using Flow.Launcher.Infrastructure.Image;
using Flow.Launcher.Core.Plugin;
using System.Windows.Controls;
namespace Flow.Launcher.ViewModel
{
public class PluginViewModel : BaseModel
{
public PluginPair PluginPair { get; set; }
private readonly PluginPair _pluginPair;
public PluginPair PluginPair
{
get => _pluginPair;
init
{
_pluginPair = value;
value.Metadata.PropertyChanged += (_, args) =>
{
if (args.PropertyName == nameof(PluginPair.Metadata.AvgQueryTime))
OnPropertyChanged(nameof(QueryTime));
};
}
}
public ImageSource Image => ImageLoader.Load(PluginPair.Metadata.IcoPath);
public bool PluginState
{
get { return !PluginPair.Metadata.Disabled; }
set
{
PluginPair.Metadata.Disabled = !value;
}
get => !PluginPair.Metadata.Disabled;
set => PluginPair.Metadata.Disabled = !value;
}
private Control _settingControl;
public Control SettingControl => _settingControl ??= PluginPair.Plugin is not ISettingProvider settingProvider ? new Control() : settingProvider.CreateSettingPanel();
public Visibility ActionKeywordsVisibility => PluginPair.Metadata.ActionKeywords.Count == 1 ? Visibility.Visible : Visibility.Collapsed;
public string InitilizaTime => PluginPair.Metadata.InitTime.ToString() + "ms";
public string InitilizaTime => PluginPair.Metadata.InitTime + "ms";
public string QueryTime => PluginPair.Metadata.AvgQueryTime + "ms";
public string ActionKeywordsText => string.Join(Query.ActionKeywordSeparator, PluginPair.Metadata.ActionKeywords);
public int Priority => PluginPair.Metadata.Priority;
@ -28,7 +43,6 @@ namespace Flow.Launcher.ViewModel
public void ChangeActionKeyword(string newActionKeyword, string oldActionKeyword)
{
PluginManager.ReplaceActionKeyword(PluginPair.Metadata.ID, oldActionKeyword, newActionKeyword);
OnPropertyChanged(nameof(ActionKeywordsText));
}
@ -38,6 +52,7 @@ namespace Flow.Launcher.ViewModel
OnPropertyChanged(nameof(Priority));
}
public bool IsActionKeywordRegistered(string newActionKeyword) => PluginManager.ActionKeywordRegistered(newActionKeyword);
public static bool IsActionKeywordRegistered(string newActionKeyword) => PluginManager.ActionKeywordRegistered(newActionKeyword);
}
}
}

View file

@ -3,12 +3,14 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Flow.Launcher.Core;
using Flow.Launcher.Core.Configuration;
using Flow.Launcher.Core.ExternalPlugins;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Helper;
@ -61,12 +63,6 @@ namespace Flow.Launcher.ViewModel
}
}
public bool AutoHideScrollBar
{
get => Settings.AutoHideScrollBar;
set => Settings.AutoHideScrollBar = value;
}
// This is only required to set at startup. When portable mode enabled/disabled a restart is always required
private bool _portableMode = DataLocation.PortableDataLocationInUse();
public bool PortableMode
@ -237,6 +233,14 @@ namespace Flow.Launcher.ViewModel
}
}
public IList<UserPlugin> ExternalPlugins
{
get
{
return PluginsManifest.UserPlugins;
}
}
public Control SettingProvider
{
get
@ -256,6 +260,12 @@ namespace Flow.Launcher.ViewModel
}
}
public async Task RefreshExternalPluginsAsync()
{
await PluginsManifest.UpdateManifestAsync();
OnPropertyChanged(nameof(ExternalPlugins));
}
#endregion

View file

@ -22,12 +22,12 @@
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="{DynamicResource flowlauncher_plugin_browserbookmark_settings_openBookmarks}"
FontSize="15" Margin="10 5 0 0"/>
<RadioButton Grid.Column="1" Name="NewWindowBrowser" GroupName="OpenSearchBehaviour"
Content="{DynamicResource flowlauncher_plugin_browserbookmark_settings_newWindow}"
Click="OnNewBrowserWindowClick" />
<RadioButton Grid.Column="2" Name="NewTabInBrowser" GroupName="OpenSearchBehaviour"
Content="{DynamicResource flowlauncher_plugin_browserbookmark_settings_newTab}"
Click="OnNewTabClick" />
<RadioButton Grid.Column="1" Name="NewWindowBrowser"
IsChecked="{Binding OpenInNewBrowserWindow}"
Content="{DynamicResource flowlauncher_plugin_browserbookmark_settings_newWindow}"/>
<RadioButton Grid.Column="2" Name="NewTabInBrowser"
IsChecked="{Binding OpenInNewTab, Mode=OneTime}"
Content="{DynamicResource flowlauncher_plugin_browserbookmark_settings_newTab}"/>
</Grid>
</StackPanel>
<StackPanel Orientation="Horizontal" VerticalAlignment="Top" Grid.Row="1" Height="60" Margin="30,20,0,0">

View file

@ -3,34 +3,38 @@ using System.Windows;
using System.Windows.Controls;
using Flow.Launcher.Plugin.BrowserBookmark.Models;
using System.Windows.Input;
using System.ComponentModel;
namespace Flow.Launcher.Plugin.BrowserBookmark.Views
{
/// <summary>
/// Interaction logic for BrowserBookmark.xaml
/// </summary>
public partial class SettingsControl
public partial class SettingsControl : INotifyPropertyChanged
{
public Settings Settings { get; }
public CustomBrowser SelectedCustomBrowser { get; set; }
public bool OpenInNewBrowserWindow
{
get => Settings.OpenInNewBrowserWindow;
set
{
Settings.OpenInNewBrowserWindow = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(OpenInNewBrowserWindow)));
}
}
public bool OpenInNewTab
{
get => !OpenInNewBrowserWindow;
}
public SettingsControl(Settings settings)
{
Settings = settings;
InitializeComponent();
NewWindowBrowser.IsChecked = Settings.OpenInNewBrowserWindow;
NewTabInBrowser.IsChecked = !Settings.OpenInNewBrowserWindow;
}
private void OnNewBrowserWindowClick(object sender, RoutedEventArgs e)
{
Settings.OpenInNewBrowserWindow = true;
}
private void OnNewTabClick(object sender, RoutedEventArgs e)
{
Settings.OpenInNewBrowserWindow = false;
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnChooseClick(object sender, RoutedEventArgs e)
{
@ -61,7 +65,7 @@ namespace Flow.Launcher.Plugin.BrowserBookmark.Views
private void DeleteCustomBrowser(object sender, RoutedEventArgs e)
{
if(CustomBrowsers.SelectedItem is CustomBrowser selectedCustomBrowser)
if (CustomBrowsers.SelectedItem is CustomBrowser selectedCustomBrowser)
{
Settings.CustomChromiumBrowsers.Remove(selectedCustomBrowser);
}

View file

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

View file

@ -15,7 +15,7 @@
<core:LocalizationConverter x:Key="LocalizationConverter"/>
</UserControl.Resources>
<Grid Margin="20 50 0 0">
<Grid Margin="20 14 0 14">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>

View file

@ -1,5 +1,5 @@
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin.PluginsManager.Models;
using Flow.Launcher.Core.ExternalPlugins;
using Flow.Launcher.Infrastructure.UserSettings;
using System;
using System.Collections.Generic;
using System.Text;

View file

@ -38,7 +38,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
viewModel = new SettingsViewModel(context, Settings);
contextMenu = new ContextMenu(Context);
pluginManager = new PluginsManager(Context, Settings);
_manifestUpdateTask = pluginManager.UpdateManifest().ContinueWith(_ =>
_manifestUpdateTask = pluginManager.UpdateManifestAsync().ContinueWith(_ =>
{
lastUpdateTime = DateTime.Now;
}, TaskContinuationOptions.OnlyOnRanToCompletion);
@ -62,7 +62,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
if ((DateTime.Now - lastUpdateTime).TotalHours > 12 && _manifestUpdateTask.IsCompleted) // 12 hours
{
_manifestUpdateTask = pluginManager.UpdateManifest().ContinueWith(t =>
_manifestUpdateTask = pluginManager.UpdateManifestAsync().ContinueWith(t =>
{
lastUpdateTime = DateTime.Now;
}, TaskContinuationOptions.OnlyOnRanToCompletion);
@ -93,7 +93,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
public async Task ReloadDataAsync()
{
await pluginManager.UpdateManifest();
await pluginManager.UpdateManifestAsync();
lastUpdateTime = DateTime.Now;
}
}

View file

@ -1,31 +0,0 @@
using Flow.Launcher.Infrastructure.Http;
using Flow.Launcher.Infrastructure.Logger;
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Threading.Tasks;
namespace Flow.Launcher.Plugin.PluginsManager.Models
{
internal class PluginsManifest
{
internal List<UserPlugin> UserPlugins { get; private set; } = new List<UserPlugin>();
internal async Task DownloadManifest()
{
try
{
await using var jsonStream = await Http.GetStreamAsync("https://cdn.jsdelivr.net/gh/Flow-Launcher/Flow.Launcher.PluginsManifest/plugins.json")
.ConfigureAwait(false);
UserPlugins = await JsonSerializer.DeserializeAsync<List<UserPlugin>>(jsonStream).ConfigureAwait(false);
}
catch (Exception e)
{
Log.Exception("|PluginManagement.GetManifest|Encountered error trying to download plugins manifest", e);
UserPlugins = new List<UserPlugin>();
}
}
}
}

View file

@ -1,9 +1,9 @@
using Flow.Launcher.Core.ExternalPlugins;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Http;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin.PluginsManager.Models;
using Flow.Launcher.Plugin.SharedCommands;
using System;
using System.Collections.Generic;
@ -17,8 +17,6 @@ namespace Flow.Launcher.Plugin.PluginsManager
{
internal class PluginsManager
{
private PluginsManifest pluginsManifest;
private PluginInitContext Context { get; set; }
private Settings Settings { get; set; }
@ -43,7 +41,6 @@ namespace Flow.Launcher.Plugin.PluginsManager
internal PluginsManager(PluginInitContext context, Settings settings)
{
pluginsManifest = new PluginsManifest();
Context = context;
Settings = settings;
}
@ -51,7 +48,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
private Task _downloadManifestTask = Task.CompletedTask;
internal Task UpdateManifest()
internal Task UpdateManifestAsync()
{
if (_downloadManifestTask.Status == TaskStatus.Running)
{
@ -59,7 +56,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
}
else
{
_downloadManifestTask = pluginsManifest.DownloadManifest();
_downloadManifestTask = PluginsManifest.UpdateTask;
_downloadManifestTask.ContinueWith(_ =>
Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_failed_title"),
Context.API.GetTranslation("plugin_pluginsmanager_update_failed_subtitle"), icoPath, false),
@ -171,9 +168,9 @@ namespace Flow.Launcher.Plugin.PluginsManager
internal async ValueTask<List<Result>> RequestUpdate(string search, CancellationToken token)
{
if (!pluginsManifest.UserPlugins.Any())
if (!PluginsManifest.UserPlugins.Any())
{
await UpdateManifest();
await UpdateManifestAsync();
}
token.ThrowIfCancellationRequested();
@ -190,7 +187,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
var resultsForUpdate =
from existingPlugin in Context.API.GetAllPlugins()
join pluginFromManifest in pluginsManifest.UserPlugins
join pluginFromManifest in PluginsManifest.UserPlugins
on existingPlugin.Metadata.ID equals pluginFromManifest.ID
where existingPlugin.Metadata.Version.CompareTo(pluginFromManifest.Version) <
0 // if current version precedes manifest version
@ -307,9 +304,9 @@ namespace Flow.Launcher.Plugin.PluginsManager
internal async ValueTask<List<Result>> RequestInstallOrUpdate(string searchName, CancellationToken token)
{
if (!pluginsManifest.UserPlugins.Any())
if (!PluginsManifest.UserPlugins.Any())
{
await UpdateManifest();
await UpdateManifestAsync();
}
token.ThrowIfCancellationRequested();
@ -317,7 +314,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
var searchNameWithoutKeyword = searchName.Replace(Settings.HotKeyInstall, string.Empty).Trim();
var results =
pluginsManifest
PluginsManifest
.UserPlugins
.Select(x =>
new Result

View file

@ -6,7 +6,7 @@
mc:Ignorable="d"
Loaded="CMDSetting_OnLoaded"
d:DesignHeight="300" d:DesignWidth="300">
<Grid Margin="7,50" VerticalAlignment="Top" >
<Grid Margin="7,10" VerticalAlignment="Top" >
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>

View file

@ -4,7 +4,7 @@
"Name": "Shell",
"Description": "Provide executing commands from Flow Launcher",
"Author": "qianlifeng",
"Version": "1.4.4",
"Version": "1.4.5",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.Shell.dll",

View file

@ -11,9 +11,9 @@
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0">
<Label Content="{DynamicResource flowlauncher_plugin_url_open_search_in}" Margin="0 10 15 0" />
<RadioButton x:Name="NewWindowBrowser" GroupName="OpenSearchBehaviour"
<RadioButton x:Name="NewWindowBrowser"
Content="{DynamicResource flowlauncher_plugin_new_window}" Click="OnNewBrowserWindowClick" />
<RadioButton x:Name="NewTabInBrowser" GroupName="OpenSearchBehaviour"
<RadioButton x:Name="NewTabInBrowser"
Content="{DynamicResource flowlauncher_plugin_new_tab}" Click="OnNewTabClick" />
</StackPanel>
<StackPanel VerticalAlignment="Top" Grid.Row="1" Height="106" Margin="0 20 0 0">

View file

@ -4,7 +4,7 @@
"Name": "URL",
"Description": "Open the typed URL from Flow Launcher",
"Author": "qianlifeng",
"Version": "1.1.6",
"Version": "1.1.7",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.Url.dll",

View file

@ -32,7 +32,7 @@
</DockPanel>
</DataTemplate>
</UserControl.Resources>
<Grid Margin="15 0 0 0">
<Grid Margin="14">
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="48" />