mirror of
https://github.com/sourcegit-scm/sourcegit
synced 2025-06-01 01:14:59 +00:00
feature: simple implementation for generating commit message by OpenAI (#456)
This commit is contained in:
parent
a63450f73f
commit
16f8e2fd0b
16 changed files with 496 additions and 30 deletions
60
src/Views/AIAssistant.axaml
Normal file
60
src/Views/AIAssistant.axaml
Normal file
|
@ -0,0 +1,60 @@
|
|||
<v:ChromelessWindow xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:v="using:SourceGit.Views"
|
||||
xmlns:vm="using:SourceGit.ViewModels"
|
||||
xmlns:c="using:SourceGit.Converters"
|
||||
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="120"
|
||||
x:Class="SourceGit.Views.AIAssistant"
|
||||
x:DataType="vm:WorkingCopy"
|
||||
x:Name="ThisControl"
|
||||
Icon="/App.ico"
|
||||
Title="{DynamicResource Text.AIAssistant}"
|
||||
Width="400" Height="120"
|
||||
CanResize="False"
|
||||
WindowStartupLocation="CenterOwner">
|
||||
<Grid RowDefinitions="Auto,Auto,Auto">
|
||||
<!-- TitleBar -->
|
||||
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto" Height="30" IsVisible="{Binding !#ThisControl.UseSystemWindowFrame}">
|
||||
<Border Grid.Column="0" Grid.ColumnSpan="3"
|
||||
Background="{DynamicResource Brush.TitleBar}"
|
||||
BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}"
|
||||
PointerPressed="BeginMoveWindow"/>
|
||||
|
||||
<Path Grid.Column="0"
|
||||
Width="14" Height="14"
|
||||
Margin="10,0,0,0"
|
||||
Data="{StaticResource Icons.AIAssist}"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
|
||||
<v:CaptionButtonsMacOS Grid.Column="0"
|
||||
Margin="0,2,0,0"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform False, macOS=True}"/>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.ColumnSpan="3"
|
||||
Classes="bold"
|
||||
Text="{DynamicResource Text.AIAssistant}"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
IsHitTestVisible="False"/>
|
||||
|
||||
<v:CaptionButtons Grid.Column="2"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
</Grid>
|
||||
|
||||
<!-- Animated Icon -->
|
||||
<v:LoadingIcon Grid.Row="1"
|
||||
Width="24" Height="24"
|
||||
Margin="0,16,0,0"/>
|
||||
|
||||
<!-- Message -->
|
||||
<TextBlock Grid.Row="2"
|
||||
x:Name="ProgressMessage"
|
||||
Margin="16"
|
||||
FontSize="{Binding Source={x:Static vm:Preference.Instance}, Path=DefaultFontSize, Converter={x:Static c:DoubleConverters.Decrease}}"
|
||||
HorizontalAlignment="Center"
|
||||
TextTrimming="CharacterEllipsis"/>
|
||||
</Grid>
|
||||
</v:ChromelessWindow>
|
61
src/Views/AIAssistant.axaml.cs
Normal file
61
src/Views/AIAssistant.axaml.cs
Normal file
|
@ -0,0 +1,61 @@
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Threading;
|
||||
|
||||
namespace SourceGit.Views
|
||||
{
|
||||
public partial class AIAssistant : ChromelessWindow
|
||||
{
|
||||
public AIAssistant()
|
||||
{
|
||||
_cancel = new CancellationTokenSource();
|
||||
InitializeComponent();
|
||||
ProgressMessage.Text = "Generating commit message... Please wait!";
|
||||
}
|
||||
|
||||
public void GenerateCommitMessage()
|
||||
{
|
||||
if (DataContext is ViewModels.WorkingCopy vm)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
var message = new Commands.GenerateCommitMessage(vm.RepoPath, vm.Staged, _cancel.Token, SetDescription).Result();
|
||||
if (_cancel.IsCancellationRequested)
|
||||
return;
|
||||
|
||||
Dispatcher.UIThread.Invoke(() =>
|
||||
{
|
||||
if (DataContext is ViewModels.WorkingCopy wc)
|
||||
wc.CommitMessage = message;
|
||||
|
||||
Close();
|
||||
});
|
||||
}, _cancel.Token);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnClosing(WindowClosingEventArgs e)
|
||||
{
|
||||
base.OnClosing(e);
|
||||
_cancel.Cancel();
|
||||
}
|
||||
|
||||
private void BeginMoveWindow(object _, PointerPressedEventArgs e)
|
||||
{
|
||||
BeginMoveDrag(e);
|
||||
}
|
||||
|
||||
private void SetDescription(string message)
|
||||
{
|
||||
Dispatcher.UIThread.Invoke(() =>
|
||||
{
|
||||
ProgressMessage.Text = message;
|
||||
});
|
||||
}
|
||||
|
||||
private CancellationTokenSource _cancel;
|
||||
}
|
||||
}
|
|
@ -348,6 +348,41 @@
|
|||
</Grid>
|
||||
</TabItem>
|
||||
|
||||
<TabItem>
|
||||
<TabItem.Header>
|
||||
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Preference.AI}"/>
|
||||
</TabItem.Header>
|
||||
|
||||
<Grid Margin="8" RowDefinitions="32,32,32" ColumnDefinitions="Auto,*">
|
||||
<TextBlock Grid.Row="0" Grid.Column="0"
|
||||
Text="{DynamicResource Text.Preference.AI.Server}"
|
||||
HorizontalAlignment="Right"
|
||||
Margin="0,0,16,0"/>
|
||||
<TextBox Grid.Row="0" Grid.Column="1"
|
||||
Height="28"
|
||||
CornerRadius="3"
|
||||
Text="{Binding OpenAIServer, Mode=TwoWay}"/>
|
||||
|
||||
<TextBlock Grid.Row="1" Grid.Column="0"
|
||||
Text="{DynamicResource Text.Preference.AI.ApiKey}"
|
||||
HorizontalAlignment="Right"
|
||||
Margin="0,0,16,0"/>
|
||||
<TextBox Grid.Row="1" Grid.Column="1"
|
||||
Height="28"
|
||||
CornerRadius="3"
|
||||
Text="{Binding OpenAIApiKey, Mode=TwoWay}"/>
|
||||
|
||||
<TextBlock Grid.Row="2" Grid.Column="0"
|
||||
Text="{DynamicResource Text.Preference.AI.Model}"
|
||||
HorizontalAlignment="Right"
|
||||
Margin="0,0,16,0"/>
|
||||
<TextBox Grid.Row="2" Grid.Column="1"
|
||||
Height="28"
|
||||
CornerRadius="3"
|
||||
Text="{Binding OpenAIModel, Mode=TwoWay}"/>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
|
||||
<TabItem>
|
||||
<TabItem.Header>
|
||||
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Preference.GPG}"/>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
xmlns:vm="using:SourceGit.ViewModels"
|
||||
xmlns:v="using:SourceGit.Views"
|
||||
xmlns:c="using:SourceGit.Converters"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="600"
|
||||
x:Class="SourceGit.Views.WorkingCopy"
|
||||
x:DataType="vm:WorkingCopy">
|
||||
<Grid>
|
||||
|
@ -173,34 +173,41 @@
|
|||
<v:CommitMessageTextBox Grid.Row="2" Text="{Binding CommitMessage, Mode=TwoWay}"/>
|
||||
|
||||
<!-- Commit Options -->
|
||||
<Grid Grid.Row="3" Margin="0,6,0,0" ColumnDefinitions="Auto,Auto,Auto,*,Auto,Auto,Auto">
|
||||
<Grid Grid.Row="3" Margin="0,6,0,0" ColumnDefinitions="Auto,Auto,Auto,Auto,*,Auto,Auto,Auto">
|
||||
<Button Grid.Column="0"
|
||||
Classes="no_border"
|
||||
Classes="icon_button"
|
||||
Margin="4,0,0,0" Padding="0"
|
||||
Click="OnOpenCommitMessagePicker">
|
||||
<Grid ColumnDefinitions="Auto,*">
|
||||
<Path Grid.Column="0" Width="12" Height="12" Data="{StaticResource Icons.Menu}"/>
|
||||
<TextBlock Grid.Column="1" Margin="8,0,0,0" Text="{DynamicResource Text.WorkingCopy.CommitMessageHelper}"/>
|
||||
</Grid>
|
||||
Click="OnOpenCommitMessagePicker"
|
||||
ToolTip.Tip="{DynamicResource Text.WorkingCopy.CommitMessageHelper}">
|
||||
<Path Grid.Column="0" Width="12" Height="12" Data="{StaticResource Icons.Menu}"/>
|
||||
</Button>
|
||||
|
||||
<CheckBox Grid.Column="1"
|
||||
<Button Grid.Column="1"
|
||||
Classes="icon_button"
|
||||
Width="32"
|
||||
Margin="4,0,0,0"
|
||||
Click="OnOpenAIAssist"
|
||||
ToolTip.Tip="{DynamicResource Text.AIAssistant.Tip}">
|
||||
<Path Width="14" Height="14" Data="{StaticResource Icons.AIAssist}"/>
|
||||
</Button>
|
||||
|
||||
<CheckBox Grid.Column="2"
|
||||
Height="24"
|
||||
Margin="12,0,0,0"
|
||||
Margin="8,0,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
IsChecked="{Binding AutoStageBeforeCommit, Mode=TwoWay}"
|
||||
Content="{DynamicResource Text.WorkingCopy.AutoStage}"/>
|
||||
|
||||
<CheckBox Grid.Column="2"
|
||||
<CheckBox Grid.Column="3"
|
||||
Height="24"
|
||||
Margin="12,0,0,0"
|
||||
Margin="8,0,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
IsChecked="{Binding UseAmend, Mode=TwoWay}"
|
||||
Content="{DynamicResource Text.WorkingCopy.Amend}"/>
|
||||
|
||||
<v:LoadingIcon Grid.Column="4" Width="18" Height="18" IsVisible="{Binding IsCommitting}"/>
|
||||
<v:LoadingIcon Grid.Column="5" Width="18" Height="18" IsVisible="{Binding IsCommitting}"/>
|
||||
|
||||
<Button Grid.Column="5"
|
||||
<Button Grid.Column="6"
|
||||
Classes="flat primary"
|
||||
Content="{DynamicResource Text.WorkingCopy.Commit}"
|
||||
Height="28"
|
||||
|
@ -210,7 +217,7 @@
|
|||
HotKey="{OnPlatform Ctrl+Enter, macOS=⌘+Enter}"
|
||||
ToolTip.Tip="{OnPlatform Ctrl+Enter, macOS=⌘+Enter}"/>
|
||||
|
||||
<Button Grid.Column="6"
|
||||
<Button Grid.Column="7"
|
||||
Classes="flat"
|
||||
Content="{DynamicResource Text.WorkingCopy.CommitAndPush}"
|
||||
Height="28"
|
||||
|
|
|
@ -88,5 +88,23 @@ namespace SourceGit.Views
|
|||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnOpenAIAssist(object _, RoutedEventArgs e)
|
||||
{
|
||||
if (!Models.OpenAI.IsValid)
|
||||
{
|
||||
App.RaiseException(null, $"Bad configuration for OpenAI");
|
||||
return;
|
||||
}
|
||||
|
||||
if (DataContext is ViewModels.WorkingCopy vm && vm.Staged is { Count: > 0 })
|
||||
{
|
||||
var dialog = new AIAssistant() { DataContext = vm };
|
||||
dialog.GenerateCommitMessage();
|
||||
App.OpenDialog(dialog);
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue