feature: warn when commit subject line goes beyond a certain number of characters (#201)

This commit is contained in:
leo 2024-06-23 15:45:54 +08:00
parent d3042bbe8d
commit dca8f8b39b
No known key found for this signature in database
16 changed files with 236 additions and 43 deletions

View file

@ -0,0 +1,60 @@
<UserControl 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:ae="using:AvaloniaEdit"
xmlns:c="using:SourceGit.Converters"
xmlns:vm="using:SourceGit.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.CommitMessageTextBox"
x:Name="ThisControl">
<Border Background="{DynamicResource Brush.Contents}"
BorderThickness="1"
BorderBrush="{DynamicResource Brush.Border2}"
CornerRadius="4">
<Grid RowDefinitions="*,Auto">
<Grid Grid.Row="0">
<ae:TextEditor x:Name="TextEditor"
Foreground="{DynamicResource Brush.FG1}"
Background="Transparent"
Padding="2,1"
BorderThickness="0"
WordWrap="True"
Document="{Binding #ThisControl.Document}"
TextChanged="OnTextEditorTextChanged"
LayoutUpdated="OnTextEditorLayoutUpdated"/>
<TextBlock Text="{DynamicResource Text.CommitMessageTextBox.Placeholder}"
Foreground="{DynamicResource Brush.FG2}"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="2,1"
IsVisible="{Binding #ThisControl.Text, Converter={x:Static StringConverters.IsNullOrEmpty}}"
IsHitTestVisible="False"/>
<Rectangle x:Name="SubjectGuideLine"
Height="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
IsHitTestVisible="False"
Fill="{DynamicResource Brush.Border2}"/>
</Grid>
<Border Grid.Row="1" CornerRadius="0,0,4,4" BorderThickness="0,1,0,0" BorderBrush="{DynamicResource Brush.Border2}" Background="{DynamicResource Brush.Window}" ClipToBounds="True">
<Grid ColumnDefinitions="Auto,*,Auto">
<Path Grid.Column="0" Height="12" Width="12" Margin="4,0,0,0" Data="{DynamicResource Icons.Info}" ToolTip.Tip="{DynamicResource Text.CommitMessageTextBox.Tip}"/>
<StackPanel Grid.Column="2" Orientation="Horizontal" Margin="4,2">
<TextBlock Text="Subject:" FontSize="10" Foreground="{DynamicResource Brush.FG2}"/>
<TextBlock Classes="monospace" Margin="2,0,0,0" FontSize="10" Text="{Binding #ThisControl.SubjectLength}"/>
<TextBlock Classes="monospace" FontSize="10" Text="/"/>
<TextBlock Classes="monospace" FontSize="10" Text="{Binding Source={x:Static vm:Preference.Instance}, Path=SubjectGuideLength}"/>
<Path Width="10" Height="10" Margin="4,0,0,0" Data="{StaticResource Icons.Error}" Fill="DarkGoldenrod" IsVisible="{Binding #ThisControl.SubjectLength, Converter={x:Static c:IntConverters.IsBadSubjectLength}}"/>
<TextBlock Margin="8,0,0,0" Text="Total:" FontSize="10" Foreground="{DynamicResource Brush.FG2}"/>
<TextBlock Classes="monospace" Margin="2,0,0,0" FontSize="10" Text="{Binding #ThisControl.Text.Length}"/>
</StackPanel>
</Grid>
</Border>
</Grid>
</Border>
</UserControl>

View file

@ -0,0 +1,112 @@
using System;
using Avalonia;
using Avalonia.Controls;
using AvaloniaEdit.Document;
using AvaloniaEdit.Rendering;
namespace SourceGit.Views
{
public partial class CommitMessageTextBox : UserControl
{
public static readonly StyledProperty<string> TextProperty =
AvaloniaProperty.Register<CommitMessageTextBox, string>(nameof(Text), string.Empty);
public static readonly StyledProperty<int> SubjectLengthProperty =
AvaloniaProperty.Register<CommitMessageTextBox, int>(nameof(SubjectLength));
public string Text
{
get => GetValue(TextProperty);
set => SetValue(TextProperty, value);
}
public int SubjectLength
{
get => GetValue(SubjectLengthProperty);
set => SetValue(SubjectLengthProperty, value);
}
public TextDocument Document
{
get;
private set;
}
public CommitMessageTextBox()
{
Document = new TextDocument(Text);
InitializeComponent();
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
if (change.Property == TextProperty)
{
if (!_isDocumentTextChanging)
Document.Text = Text;
}
}
private void OnTextEditorLayoutUpdated(object sender, EventArgs e)
{
var view = TextEditor.TextArea?.TextView;
if (view is { VisualLinesValid: true })
{
if (_subjectEndLineNumber == 0)
{
SubjectGuideLine.Margin = new Thickness(1, view.DefaultLineHeight + 2, 1, 0);
SubjectGuideLine.IsVisible = true;
return;
}
foreach (var line in view.VisualLines)
{
var lineNumber = line.FirstDocumentLine.LineNumber;
if (lineNumber == _subjectEndLineNumber)
{
var y = line.GetTextLineVisualYPosition(line.TextLines[^1], VisualYPosition.TextBottom) - view.VerticalOffset + 2;
SubjectGuideLine.Margin = new Thickness(1, y, 1, 0);
SubjectGuideLine.IsVisible = true;
return;
}
}
}
SubjectGuideLine.IsVisible = false;
}
private void OnTextEditorTextChanged(object sender, EventArgs e)
{
_isDocumentTextChanging = true;
SetCurrentValue(TextProperty, Document.Text);
_isDocumentTextChanging = false;
var setSubject = false;
for (int i = 0; i < Document.LineCount; i++)
{
var line = Document.Lines[i];
if (line.LineNumber > 1 && line.Length == 0)
{
var subject = Text.Substring(0, line.Offset).ReplaceLineEndings(" ").Trim();
SetCurrentValue(SubjectLengthProperty, subject.Length);
setSubject = true;
break;
}
_subjectEndLineNumber = line.LineNumber;
}
if (setSubject)
return;
SetCurrentValue(SubjectLengthProperty, Text.ReplaceLineEndings(" ").Trim().Length);
}
private bool _isDocumentTextChanging = false;
private int _subjectEndLineNumber = 0;
}
}

View file

@ -14,11 +14,11 @@
Classes="bold"
Text="{DynamicResource Text.CreateTag.Title}"/>
<Grid Margin="0,16,8,0" RowDefinitions="32,32,32,Auto,Auto,32" ColumnDefinitions="120,*">
<TextBlock Grid.Column="0"
<TextBlock Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0"
Text="{DynamicResource Text.CreateTag.BasedOn}"/>
<ContentControl Grid.Column="1" Content="{Binding BasedOn}">
<ContentControl Grid.Row="0" Grid.Column="1" Content="{Binding BasedOn}">
<ContentControl.DataTemplates>
<DataTemplate DataType="m:Branch">
<StackPanel Orientation="Horizontal">

View file

@ -163,8 +163,8 @@
</Button.Flyout>
<StackPanel Orientation="Horizontal">
<Ellipse Grid.Column="0" Width="14" Height="14" Fill="{Binding Action, Converter={x:Static c:InteractiveRebaseActionConverters.ToIconBrush}}"/>
<TextBlock Grid.Column="1" Classes="monospace" Margin="8,0" Text="{Binding Action, Converter={x:Static c:InteractiveRebaseActionConverters.ToName}}"/>
<Ellipse Width="14" Height="14" Fill="{Binding Action, Converter={x:Static c:InteractiveRebaseActionConverters.ToIconBrush}}"/>
<TextBlock Classes="monospace" Margin="8,0" Text="{Binding Action, Converter={x:Static c:InteractiveRebaseActionConverters.ToName}}"/>
</StackPanel>
</Button>
</DataTemplate>
@ -179,12 +179,7 @@
<Button.Flyout>
<Flyout Placement="BottomEdgeAlignedLeft">
<Panel Width="600" Height="120">
<TextBox Grid.Row="0"
CornerRadius="2"
AcceptsReturn="True"
VerticalContentAlignment="Top"
Text="{Binding FullMessage, Mode=TwoWay}"
v:AutoFocusBehaviour.IsEnabled="True"/>
<v:CommitMessageTextBox Text="{Binding FullMessage, Mode=TwoWay}"/>
</Panel>
</Flyout>
</Button.Flyout>

View file

@ -58,7 +58,7 @@
<TabItem.Header>
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Preference.General}"/>
</TabItem.Header>
<Grid Margin="8" RowDefinitions="32,32,32,32,32,32" ColumnDefinitions="Auto,*">
<Grid Margin="8" RowDefinitions="32,32,32,32,32,32,32" ColumnDefinitions="Auto,*">
<TextBlock Grid.Row="0" Grid.Column="0"
Text="{DynamicResource Text.Preference.General.Locale}"
HorizontalAlignment="Right"
@ -113,17 +113,45 @@
Foreground="{DynamicResource Brush.FG1}"
Text="{Binding MaxHistoryCommits}"/>
</Grid>
<TextBlock Grid.Row="3" Grid.Column="0"
Text="{DynamicResource Text.Preference.General.SubjectGuideLength}"
HorizontalAlignment="Right"
Margin="0,0,16,0"/>
<Grid Grid.Row="3" Grid.Column="1" ColumnDefinitions="*,64">
<Slider Grid.Column="0"
Minimum="50" Maximum="250"
TickPlacement="BottomRight" TickFrequency="4"
IsSnapToTickEnabled="False"
VerticalAlignment="Center"
Foreground="{DynamicResource Brush.Border1}"
Value="{Binding SubjectGuideLength, Mode=TwoWay}">
<Slider.Resources>
<Thickness x:Key="SliderTopHeaderMargin">0,0,0,4</Thickness>
<GridLength x:Key="SliderPreContentMargin">0</GridLength>
<GridLength x:Key="SliderPostContentMargin">0</GridLength>
<CornerRadius x:Key="SliderThumbCornerRadius">8</CornerRadius>
<x:Double x:Key="SliderHorizontalThumbWidth">16</x:Double>
<x:Double x:Key="SliderHorizontalThumbHeight">16</x:Double>
</Slider.Resources>
</Slider>
<CheckBox Grid.Row="3" Grid.Column="1"
<TextBlock Grid.Column="1"
HorizontalAlignment="Right" VerticalAlignment="Center"
Foreground="{DynamicResource Brush.FG1}"
Text="{Binding SubjectGuideLength}"/>
</Grid>
<CheckBox Grid.Row="4" Grid.Column="1"
Content="{DynamicResource Text.Preference.General.RestoreTabs}"
IsChecked="{Binding RestoreTabs, Mode=TwoWay}"/>
<CheckBox Grid.Row="4" Grid.Column="1"
<CheckBox Grid.Row="5" Grid.Column="1"
Height="32"
Content="{DynamicResource Text.Preference.General.UseFixedTabWidth}"
IsChecked="{Binding Source={x:Static vm:Preference.Instance}, Path=UseFixedTabWidth, Mode=TwoWay}"/>
<CheckBox Grid.Row="5" Grid.Column="1"
<CheckBox Grid.Row="6" Grid.Column="1"
Height="32"
Content="{DynamicResource Text.Preference.General.Check4UpdatesOnStartup}"
IsChecked="{Binding Source={x:Static vm:Preference.Instance}, Path=Check4UpdatesOnStartup, Mode=TwoWay}"/>

View file

@ -2,11 +2,9 @@
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:ae="using:AvaloniaEdit"
xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.RevisionFiles"
x:DataType="vm:CommitDetail">

View file

@ -105,19 +105,12 @@ namespace SourceGit.Views
set => SetValue(UseSyntaxHighlightingProperty, value);
}
/// <summary>
/// ShowHiddenSymbols StyledProperty definition
/// </summary>
public static readonly StyledProperty<bool> ShowHiddenSymbolsProperty =
AvaloniaProperty.Register<IThemedTextDiffPresenter, bool>(nameof(ShowHiddenSymbols), false);
/// <summary>
/// Gets or sets the ShowHiddenSymbols property. This StyledProperty
/// indicates that show hidden symbol like space and tab
/// </summary>
public bool ShowHiddenSymbols
{
get => this.GetValue(ShowHiddenSymbolsProperty);
get => GetValue(ShowHiddenSymbolsProperty);
set => SetValue(ShowHiddenSymbolsProperty, value);
}

View file

@ -159,19 +159,10 @@
</Grid>
<!-- Commit Message -->
<TextBox Grid.Row="1"
Height="80"
Margin="0,4" Padding="2,1"
AcceptsReturn="True" AcceptsTab="True"
TextWrapping="Wrap"
VerticalContentAlignment="Top"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto"
Background="{DynamicResource Brush.Contents}"
BorderThickness="1"
BorderBrush="{DynamicResource Brush.Border2}"
Watermark="{DynamicResource Text.WorkingCopy.CommitMessageTip}"
Text="{Binding CommitMessage, Mode=TwoWay}"/>
<v:CommitMessageTextBox Grid.Row="1"
Height="100"
Margin="0,4"
Text="{Binding CommitMessage, Mode=TwoWay}"/>
<!-- Commit Options -->
<Grid Grid.Row="2" ColumnDefinitions="Auto,Auto,*,Auto,Auto,Auto">