Skip to content

Commit b36562a

Browse files
authored
Merge pull request #3494 from Flow-Launcher/plugin_filters
Support filtering dotnet, python, node.js, executable plugins
2 parents 9de0eb2 + d0b4485 commit b36562a

File tree

5 files changed

+225
-70
lines changed

5 files changed

+225
-70
lines changed

Flow.Launcher.Plugin/AllowedLanguage.cs

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,42 @@ public static class AllowedLanguage
6565
public static bool IsDotNet(string language)
6666
{
6767
return language.Equals(CSharp, StringComparison.OrdinalIgnoreCase)
68-
|| language.Equals(FSharp, StringComparison.OrdinalIgnoreCase);
68+
|| language.Equals(FSharp, StringComparison.OrdinalIgnoreCase);
69+
}
70+
71+
/// <summary>
72+
/// Determines if this language is a Python language
73+
/// </summary>
74+
/// <param name="language"></param>
75+
/// <returns></returns>
76+
public static bool IsPython(string language)
77+
{
78+
return language.Equals(Python, StringComparison.OrdinalIgnoreCase)
79+
|| language.Equals(PythonV2, StringComparison.OrdinalIgnoreCase);
80+
}
81+
82+
/// <summary>
83+
/// Determines if this language is a Node.js language
84+
/// </summary>
85+
/// <param name="language"></param>
86+
/// <returns></returns>
87+
public static bool IsNodeJs(string language)
88+
{
89+
return language.Equals(TypeScript, StringComparison.OrdinalIgnoreCase)
90+
|| language.Equals(TypeScriptV2, StringComparison.OrdinalIgnoreCase)
91+
|| language.Equals(JavaScript, StringComparison.OrdinalIgnoreCase)
92+
|| language.Equals(JavaScriptV2, StringComparison.OrdinalIgnoreCase);
93+
}
94+
95+
/// <summary>
96+
/// Determines if this language is a executable language
97+
/// </summary>
98+
/// <param name="language"></param>
99+
/// <returns></returns>
100+
public static bool IsExecutable(string language)
101+
{
102+
return language.Equals(Executable, StringComparison.OrdinalIgnoreCase)
103+
|| language.Equals(ExecutableV2, StringComparison.OrdinalIgnoreCase);
69104
}
70105

71106
/// <summary>
@@ -76,15 +111,9 @@ public static bool IsDotNet(string language)
76111
public static bool IsAllowed(string language)
77112
{
78113
return IsDotNet(language)
79-
|| language.Equals(Python, StringComparison.OrdinalIgnoreCase)
80-
|| language.Equals(PythonV2, StringComparison.OrdinalIgnoreCase)
81-
|| language.Equals(Executable, StringComparison.OrdinalIgnoreCase)
82-
|| language.Equals(TypeScript, StringComparison.OrdinalIgnoreCase)
83-
|| language.Equals(JavaScript, StringComparison.OrdinalIgnoreCase)
84-
|| language.Equals(ExecutableV2, StringComparison.OrdinalIgnoreCase)
85-
|| language.Equals(TypeScriptV2, StringComparison.OrdinalIgnoreCase)
86-
|| language.Equals(JavaScriptV2, StringComparison.OrdinalIgnoreCase);
87-
;
114+
|| IsPython(language)
115+
|| IsNodeJs(language)
116+
|| IsExecutable(language);
88117
}
89118
}
90119
}

Flow.Launcher/Images/EXE.png

-2.12 KB
Binary file not shown.

Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs

Lines changed: 92 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,75 @@ namespace Flow.Launcher.SettingPages.ViewModels;
99

1010
public partial class SettingsPanePluginStoreViewModel : BaseModel
1111
{
12-
public string FilterText { get; set; } = string.Empty;
12+
private string filterText = string.Empty;
13+
public string FilterText
14+
{
15+
get => filterText;
16+
set
17+
{
18+
if (filterText != value)
19+
{
20+
filterText = value;
21+
OnPropertyChanged();
22+
}
23+
}
24+
}
25+
26+
private bool showDotNet = true;
27+
public bool ShowDotNet
28+
{
29+
get => showDotNet;
30+
set
31+
{
32+
if (showDotNet != value)
33+
{
34+
showDotNet = value;
35+
OnPropertyChanged();
36+
}
37+
}
38+
}
39+
40+
private bool showPython = true;
41+
public bool ShowPython
42+
{
43+
get => showPython;
44+
set
45+
{
46+
if (showPython != value)
47+
{
48+
showPython = value;
49+
OnPropertyChanged();
50+
}
51+
}
52+
}
53+
54+
private bool showNodeJs = true;
55+
public bool ShowNodeJs
56+
{
57+
get => showNodeJs;
58+
set
59+
{
60+
if (showNodeJs != value)
61+
{
62+
showNodeJs = value;
63+
OnPropertyChanged();
64+
}
65+
}
66+
}
67+
68+
private bool showExecutable = true;
69+
public bool ShowExecutable
70+
{
71+
get => showExecutable;
72+
set
73+
{
74+
if (showExecutable != value)
75+
{
76+
showExecutable = value;
77+
OnPropertyChanged();
78+
}
79+
}
80+
}
1381

1482
public IList<PluginStoreItemViewModel> ExternalPlugins =>
1583
App.API.GetPluginManifest()?.Select(p => new PluginStoreItemViewModel(p))
@@ -30,8 +98,29 @@ private async Task RefreshExternalPluginsAsync()
3098

3199
public bool SatisfiesFilter(PluginStoreItemViewModel plugin)
32100
{
101+
// Check plugin language
102+
var pluginShown = false;
103+
if (AllowedLanguage.IsDotNet(plugin.Language))
104+
{
105+
pluginShown = ShowDotNet;
106+
}
107+
else if (AllowedLanguage.IsPython(plugin.Language))
108+
{
109+
pluginShown = ShowPython;
110+
}
111+
else if (AllowedLanguage.IsNodeJs(plugin.Language))
112+
{
113+
pluginShown = ShowNodeJs;
114+
}
115+
else if (AllowedLanguage.IsExecutable(plugin.Language))
116+
{
117+
pluginShown = ShowExecutable;
118+
}
119+
if (!pluginShown) return false;
120+
121+
// Check plugin name & description
33122
return string.IsNullOrEmpty(FilterText) ||
34-
App.API.FuzzySearch(FilterText, plugin.Name).IsSearchPrecisionScoreMet() ||
35-
App.API.FuzzySearch(FilterText, plugin.Description).IsSearchPrecisionScoreMet();
123+
App.API.FuzzySearch(FilterText, plugin.Name).IsSearchPrecisionScoreMet() ||
124+
App.API.FuzzySearch(FilterText, plugin.Description).IsSearchPrecisionScoreMet();
36125
}
37126
}

Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml

Lines changed: 86 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
</ui:Page.Resources>
2828
<Grid>
2929
<Grid.ColumnDefinitions>
30-
<ColumnDefinition />
31-
<ColumnDefinition />
30+
<ColumnDefinition Width="Auto" />
31+
<ColumnDefinition Width="*" />
3232
</Grid.ColumnDefinitions>
3333
<Grid.RowDefinitions>
3434
<RowDefinition Height="72" />
@@ -51,60 +51,93 @@
5151
Grid.Column="1"
5252
Margin="5 24 0 0">
5353

54-
<TextBox
55-
Name="PluginStoreFilterTextbox"
56-
Width="150"
57-
Height="34"
58-
Margin="0 0 26 0"
59-
HorizontalAlignment="Right"
60-
ContextMenu="{StaticResource TextBoxContextMenu}"
61-
DockPanel.Dock="Right"
62-
FontSize="14"
63-
Text="{Binding FilterText, UpdateSourceTrigger=PropertyChanged}"
64-
TextAlignment="Left"
65-
ToolTip="{DynamicResource searchpluginToolTip}"
66-
ToolTipService.InitialShowDelay="200"
67-
ToolTipService.Placement="Top">
68-
<TextBox.Style>
69-
<Style BasedOn="{StaticResource DefaultTextBoxStyle}" TargetType="TextBox">
70-
<Style.Resources>
71-
<VisualBrush
72-
x:Key="CueBannerBrush"
73-
AlignmentX="Left"
74-
AlignmentY="Center"
75-
Stretch="None">
76-
<VisualBrush.Visual>
77-
<Label
78-
Padding="10 0 0 0"
79-
Content="{DynamicResource searchplugin}"
80-
Foreground="{DynamicResource CustomContextDisabled}" />
81-
</VisualBrush.Visual>
82-
</VisualBrush>
83-
</Style.Resources>
84-
<Style.Triggers>
85-
<Trigger Property="Text" Value="{x:Static sys:String.Empty}">
86-
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
87-
</Trigger>
88-
<Trigger Property="Text" Value="{x:Null}">
89-
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
90-
</Trigger>
91-
<Trigger Property="IsKeyboardFocused" Value="True">
92-
<Setter Property="Background" Value="{DynamicResource Color02B}" />
93-
</Trigger>
94-
</Style.Triggers>
95-
</Style>
96-
</TextBox.Style>
97-
</TextBox>
98-
<Button
99-
Height="34"
100-
Margin="0 5 10 5"
101-
Padding="12 4"
54+
<StackPanel
10255
HorizontalAlignment="Right"
10356
VerticalAlignment="Center"
104-
Command="{Binding RefreshExternalPluginsCommand}"
105-
Content="{DynamicResource refresh}"
10657
DockPanel.Dock="Right"
107-
FontSize="13" />
58+
Orientation="Horizontal">
59+
<Button
60+
Height="34"
61+
Margin="0 5 10 5"
62+
Padding="12 4"
63+
HorizontalAlignment="Right"
64+
VerticalAlignment="Center"
65+
Command="{Binding RefreshExternalPluginsCommand}"
66+
Content="{DynamicResource refresh}"
67+
FontSize="13" />
68+
<Button Height="34" Margin="0 0 10 0">
69+
<ui:FontIcon FontSize="14" Glyph="&#xe71c;" />
70+
<ui:FlyoutService.Flyout>
71+
<ui:MenuFlyout x:Name="FilterFlyout" Placement="Bottom">
72+
<MenuItem
73+
Header=".Net"
74+
IsCheckable="True"
75+
IsChecked="{Binding ShowDotNet, Mode=TwoWay}"
76+
StaysOpenOnClick="True" />
77+
<MenuItem
78+
Header="Python"
79+
IsCheckable="True"
80+
IsChecked="{Binding ShowPython, Mode=TwoWay}"
81+
StaysOpenOnClick="True" />
82+
<MenuItem
83+
Header="Node.js"
84+
IsCheckable="True"
85+
IsChecked="{Binding ShowNodeJs, Mode=TwoWay}"
86+
StaysOpenOnClick="True" />
87+
<MenuItem
88+
Header="Exe"
89+
IsCheckable="True"
90+
IsChecked="{Binding ShowExecutable, Mode=TwoWay}"
91+
StaysOpenOnClick="True" />
92+
</ui:MenuFlyout>
93+
</ui:FlyoutService.Flyout>
94+
</Button>
95+
<TextBox
96+
Name="PluginStoreFilterTextbox"
97+
Width="150"
98+
Height="34"
99+
Margin="0 0 26 0"
100+
HorizontalAlignment="Right"
101+
ContextMenu="{StaticResource TextBoxContextMenu}"
102+
DockPanel.Dock="Right"
103+
FontSize="14"
104+
Text="{Binding FilterText, UpdateSourceTrigger=PropertyChanged}"
105+
TextAlignment="Left"
106+
ToolTip="{DynamicResource searchpluginToolTip}"
107+
ToolTipService.InitialShowDelay="200"
108+
ToolTipService.Placement="Top">
109+
<TextBox.Style>
110+
<Style BasedOn="{StaticResource DefaultTextBoxStyle}" TargetType="TextBox">
111+
<Style.Resources>
112+
<VisualBrush
113+
x:Key="CueBannerBrush"
114+
AlignmentX="Left"
115+
AlignmentY="Center"
116+
Stretch="None">
117+
<VisualBrush.Visual>
118+
<Label
119+
Padding="10 0 0 0"
120+
Content="{DynamicResource searchplugin}"
121+
Foreground="{DynamicResource CustomContextDisabled}" />
122+
</VisualBrush.Visual>
123+
</VisualBrush>
124+
</Style.Resources>
125+
<Style.Triggers>
126+
<Trigger Property="Text" Value="{x:Static sys:String.Empty}">
127+
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
128+
</Trigger>
129+
<Trigger Property="Text" Value="{x:Null}">
130+
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
131+
</Trigger>
132+
<Trigger Property="IsKeyboardFocused" Value="True">
133+
<Setter Property="Background" Value="{DynamicResource Color02B}" />
134+
</Trigger>
135+
</Style.Triggers>
136+
</Style>
137+
</TextBox.Style>
138+
</TextBox>
139+
</StackPanel>
140+
108141
</DockPanel>
109142
<ListView
110143
x:Name="StoreListBox"
@@ -343,9 +376,7 @@
343376
Text="{Binding Description, Mode=OneWay}"
344377
TextTrimming="WordEllipsis"
345378
TextWrapping="Wrap" />
346-
347379
</StackPanel>
348-
349380
</Grid>
350381
</Button>
351382
</DataTemplate>

Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,15 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
2626

2727
private void ViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
2828
{
29-
if (e.PropertyName == nameof(SettingsPanePluginStoreViewModel.FilterText))
29+
switch (e.PropertyName)
3030
{
31-
((CollectionViewSource)FindResource("PluginStoreCollectionView")).View.Refresh();
31+
case nameof(SettingsPanePluginStoreViewModel.FilterText):
32+
case nameof(SettingsPanePluginStoreViewModel.ShowDotNet):
33+
case nameof(SettingsPanePluginStoreViewModel.ShowPython):
34+
case nameof(SettingsPanePluginStoreViewModel.ShowNodeJs):
35+
case nameof(SettingsPanePluginStoreViewModel.ShowExecutable):
36+
((CollectionViewSource)FindResource("PluginStoreCollectionView")).View.Refresh();
37+
break;
3238
}
3339
}
3440

0 commit comments

Comments
 (0)