Skip to content

Commit 5c279b4

Browse files
committed
feature: add global configuration for custom action (#1077)
Signed-off-by: leo <[email protected]>
1 parent 0f9087f commit 5c279b4

File tree

6 files changed

+182
-6
lines changed

6 files changed

+182
-6
lines changed

src/Models/RepositorySettings.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -471,11 +471,7 @@ public void RemoveIssueTracker(IssueTrackerRule rule)
471471

472472
public CustomAction AddNewCustomAction()
473473
{
474-
var act = new CustomAction()
475-
{
476-
Name = "Unnamed Custom Action",
477-
};
478-
474+
var act = new CustomAction() { Name = "Unnamed Action" };
479475
CustomActions.Add(act);
480476
return act;
481477
}

src/ViewModels/Histories.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,11 @@ public ContextMenu MakeContextMenu(ListBox list)
695695
menu.Items.Add(new MenuItem() { Header = "-" });
696696

697697
var actions = new List<Models.CustomAction>();
698+
foreach (var action in Preferences.Instance.CustomActions)
699+
{
700+
if (action.Scope == Models.CustomActionScope.Commit)
701+
actions.Add(action);
702+
}
698703
foreach (var action in _repo.Settings.CustomActions)
699704
{
700705
if (action.Scope == Models.CustomActionScope.Commit)

src/ViewModels/Preferences.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,12 @@ public List<Workspace> Workspaces
342342
set;
343343
} = [];
344344

345+
public AvaloniaList<Models.CustomAction> CustomActions
346+
{
347+
get;
348+
set;
349+
} = [];
350+
345351
public AvaloniaList<Models.OpenAIService> OpenAIServices
346352
{
347353
get;

src/ViewModels/Repository.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,6 +1444,12 @@ public ContextMenu CreateContextMenuForGitLFS()
14441444
public ContextMenu CreateContextMenuForCustomAction()
14451445
{
14461446
var actions = new List<Models.CustomAction>();
1447+
foreach (var action in Preferences.Instance.CustomActions)
1448+
{
1449+
if (action.Scope == Models.CustomActionScope.Repository)
1450+
actions.Add(action);
1451+
}
1452+
14471453
foreach (var action in _settings.CustomActions)
14481454
{
14491455
if (action.Scope == Models.CustomActionScope.Repository)
@@ -2350,6 +2356,12 @@ private BranchTreeNode FindBranchNode(List<BranchTreeNode> nodes, string path)
23502356
private void TryToAddCustomActionsToBranchContextMenu(ContextMenu menu, Models.Branch branch)
23512357
{
23522358
var actions = new List<Models.CustomAction>();
2359+
foreach (var action in Preferences.Instance.CustomActions)
2360+
{
2361+
if (action.Scope == Models.CustomActionScope.Branch)
2362+
actions.Add(action);
2363+
}
2364+
23532365
foreach (var action in Settings.CustomActions)
23542366
{
23552367
if (action.Scope == Models.CustomActionScope.Branch)

src/Views/Preferences.axaml

Lines changed: 115 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,12 +527,126 @@
527527
</StackPanel>
528528
</TabItem>
529529

530+
<TabItem>
531+
<TabItem.Header>
532+
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Configure.CustomAction}"/>
533+
</TabItem.Header>
534+
535+
<Grid MinHeight="340" Margin="0,8,0,16">
536+
<Grid.ColumnDefinitions>
537+
<ColumnDefinition Width="200"/>
538+
<ColumnDefinition Width="*" MaxWidth="400"/>
539+
</Grid.ColumnDefinitions>
540+
541+
<Border Grid.Column="0"
542+
BorderThickness="1" BorderBrush="{DynamicResource Brush.Border2}"
543+
Background="{DynamicResource Brush.Contents}">
544+
<Grid RowDefinitions="*,1,Auto">
545+
<ListBox Grid.Row="0"
546+
Background="Transparent"
547+
ItemsSource="{Binding CustomActions}"
548+
SelectedItem="{Binding #ThisControl.SelectedCustomAction, Mode=TwoWay}"
549+
SelectionMode="Single">
550+
<ListBox.Styles>
551+
<Style Selector="ListBoxItem">
552+
<Setter Property="MinHeight" Value="0"/>
553+
<Setter Property="Height" Value="26"/>
554+
<Setter Property="Padding" Value="4,2"/>
555+
</Style>
556+
</ListBox.Styles>
557+
558+
<ListBox.ItemsPanel>
559+
<ItemsPanelTemplate>
560+
<StackPanel Orientation="Vertical"/>
561+
</ItemsPanelTemplate>
562+
</ListBox.ItemsPanel>
563+
564+
<ListBox.ItemTemplate>
565+
<DataTemplate DataType="m:CustomAction">
566+
<Grid Margin="4,0" ColumnDefinitions="Auto,*">
567+
<Path Grid.Column="0" Width="12" Height="12" Data="{StaticResource Icons.Action}" Fill="{DynamicResource Brush.FG1}"/>
568+
<TextBlock Grid.Column="1" Text="{Binding Name}" Margin="6,0,0,0" TextTrimming="CharacterEllipsis"/>
569+
</Grid>
570+
</DataTemplate>
571+
</ListBox.ItemTemplate>
572+
</ListBox>
573+
574+
<Rectangle Grid.Row="1" Height="1" Fill="{DynamicResource Brush.Border2}" HorizontalAlignment="Stretch" VerticalAlignment="Bottom"/>
575+
576+
<StackPanel Grid.Row="2" Orientation="Horizontal" Background="{DynamicResource Brush.ToolBar}">
577+
<Button Classes="icon_button" Click="OnAddCustomAction">
578+
<Path Width="14" Height="14" Data="{StaticResource Icons.Plus}"/>
579+
</Button>
580+
581+
<Rectangle Width="1" Fill="{DynamicResource Brush.Border2}" HorizontalAlignment="Left" VerticalAlignment="Stretch"/>
582+
583+
<Button Classes="icon_button" Click="OnRemoveSelectedCustomAction">
584+
<Path Width="14" Height="14" Data="{StaticResource Icons.Window.Minimize}"/>
585+
</Button>
586+
587+
<Rectangle Width="1" Fill="{DynamicResource Brush.Border2}" HorizontalAlignment="Left" VerticalAlignment="Stretch"/>
588+
</StackPanel>
589+
</Grid>
590+
</Border>
591+
592+
<ContentControl Grid.Column="1" Margin="16,0,0,0">
593+
<ContentControl.Content>
594+
<Binding Path="SelectedCustomAction" ElementName="ThisControl">
595+
<Binding.TargetNullValue>
596+
<Path Width="64" Height="64"
597+
HorizontalAlignment="Center"
598+
VerticalAlignment="Center"
599+
Fill="{DynamicResource Brush.FG2}"
600+
Data="{StaticResource Icons.Empty}"/>
601+
</Binding.TargetNullValue>
602+
</Binding>
603+
</ContentControl.Content>
604+
605+
<ContentControl.DataTemplates>
606+
<DataTemplate DataType="m:CustomAction">
607+
<StackPanel Orientation="Vertical">
608+
<TextBlock Text="{DynamicResource Text.Configure.CustomAction.Name}"/>
609+
<TextBox Margin="0,4,0,0" CornerRadius="3" Height="28" Text="{Binding Name, Mode=TwoWay}"/>
610+
611+
<TextBlock Margin="0,12,0,0" Text="{DynamicResource Text.Configure.CustomAction.Scope}"/>
612+
<ComboBox Margin="0,4,0,0" Height="28" HorizontalAlignment="Stretch" SelectedIndex="{Binding Scope, Mode=TwoWay}">
613+
<ComboBoxItem Content="{DynamicResource Text.Configure.CustomAction.Scope.Repository}"/>
614+
<ComboBoxItem Content="{DynamicResource Text.Configure.CustomAction.Scope.Commit}"/>
615+
<ComboBoxItem Content="{DynamicResource Text.Configure.CustomAction.Scope.Branch}"/>
616+
</ComboBox>
617+
618+
<TextBlock Margin="0,12,0,0" Text="{DynamicResource Text.Configure.CustomAction.Executable}"/>
619+
<TextBox Margin="0,4,0,0" Height="28" CornerRadius="3" Text="{Binding Executable, Mode=TwoWay}">
620+
<TextBox.InnerRightContent>
621+
<Button Classes="icon_button" Width="30" Height="30" Click="SelectExecutableForCustomAction">
622+
<Path Data="{StaticResource Icons.Folder.Open}" Fill="{DynamicResource Brush.FG1}"/>
623+
</Button>
624+
</TextBox.InnerRightContent>
625+
</TextBox>
626+
627+
<TextBlock Margin="0,12,0,0" Text="{DynamicResource Text.Configure.CustomAction.Arguments}"/>
628+
<TextBox Margin="0,4,0,0" CornerRadius="3" Height="28" Text="{Binding Arguments, Mode=TwoWay}"/>
629+
<TextBlock Margin="0,2,0,0" TextWrapping="Wrap" Text="{DynamicResource Text.Configure.CustomAction.Arguments.Tip}" Foreground="{DynamicResource Brush.FG2}"/>
630+
631+
<CheckBox Margin="0,8,0,0" Content="{DynamicResource Text.Configure.CustomAction.WaitForExit}" IsChecked="{Binding WaitForExit, Mode=TwoWay}"/>
632+
</StackPanel>
633+
</DataTemplate>
634+
</ContentControl.DataTemplates>
635+
</ContentControl>
636+
</Grid>
637+
</TabItem>
638+
530639
<TabItem>
531640
<TabItem.Header>
532641
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Preferences.AI}"/>
533642
</TabItem.Header>
534643

535-
<Grid ColumnDefinitions="200,*" Margin="0,8,0,16" MinHeight="400">
644+
<Grid Margin="0,8,0,16" MinHeight="400">
645+
<Grid.ColumnDefinitions>
646+
<ColumnDefinition Width="200"/>
647+
<ColumnDefinition Width="*" MaxWidth="400"/>
648+
</Grid.ColumnDefinitions>
649+
536650
<Border Grid.Column="0"
537651
BorderThickness="1" BorderBrush="{DynamicResource Brush.Border2}"
538652
Background="{DynamicResource Brush.Contents}">

src/Views/Preferences.axaml.cs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,15 @@ public Models.OpenAIService SelectedOpenAIService
103103
set => SetValue(SelectedOpenAIServiceProperty, value);
104104
}
105105

106+
public static readonly StyledProperty<Models.CustomAction> SelectedCustomActionProperty =
107+
AvaloniaProperty.Register<Preferences, Models.CustomAction>(nameof(SelectedCustomAction));
108+
109+
public Models.CustomAction SelectedCustomAction
110+
{
111+
get => GetValue(SelectedCustomActionProperty);
112+
set => SetValue(SelectedCustomActionProperty, value);
113+
}
114+
106115
public Preferences()
107116
{
108117
var pref = ViewModels.Preferences.Instance;
@@ -368,6 +377,40 @@ private void OnRemoveSelectedOpenAIService(object sender, RoutedEventArgs e)
368377
e.Handled = true;
369378
}
370379

380+
private void OnAddCustomAction(object sender, RoutedEventArgs e)
381+
{
382+
var action = new Models.CustomAction() { Name = "Unnamed Action (Global)" };
383+
ViewModels.Preferences.Instance.CustomActions.Add(action);
384+
SelectedCustomAction = action;
385+
386+
e.Handled = true;
387+
}
388+
389+
private async void SelectExecutableForCustomAction(object sender, RoutedEventArgs e)
390+
{
391+
var options = new FilePickerOpenOptions()
392+
{
393+
FileTypeFilter = [new FilePickerFileType("Executable file(script)") { Patterns = ["*.*"] }],
394+
AllowMultiple = false,
395+
};
396+
397+
var selected = await StorageProvider.OpenFilePickerAsync(options);
398+
if (selected.Count == 1 && sender is Button { DataContext: Models.CustomAction action })
399+
action.Executable = selected[0].Path.LocalPath;
400+
401+
e.Handled = true;
402+
}
403+
404+
private void OnRemoveSelectedCustomAction(object sender, RoutedEventArgs e)
405+
{
406+
if (SelectedCustomAction == null)
407+
return;
408+
409+
ViewModels.Preferences.Instance.CustomActions.Remove(SelectedCustomAction);
410+
SelectedCustomAction = null;
411+
e.Handled = true;
412+
}
413+
371414
private void UpdateGitVersion()
372415
{
373416
GitVersion = Native.OS.GitVersionString;

0 commit comments

Comments
 (0)