Skip to content

Commit b4fbc23

Browse files
committed
enhance: show commit info tip when hover SHA in conflict view
Signed-off-by: leo <[email protected]>
1 parent 2b2f070 commit b4fbc23

File tree

5 files changed

+176
-92
lines changed

5 files changed

+176
-92
lines changed

src/ViewModels/Conflict.cs

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
11
namespace SourceGit.ViewModels
22
{
3+
public class ConflictSourceBranch
4+
{
5+
public string Name { get; private set; }
6+
public string Head { get; private set; }
7+
public Models.Commit Revision { get; private set; }
8+
9+
public ConflictSourceBranch(string name, string head, Models.Commit revision)
10+
{
11+
Name = name;
12+
Head = head;
13+
Revision = revision;
14+
}
15+
16+
public ConflictSourceBranch(Repository repo, Models.Branch branch)
17+
{
18+
Name = branch.Name;
19+
Head = branch.Head;
20+
Revision = new Commands.QuerySingleCommit(repo.FullPath, branch.Head).Result() ?? new Models.Commit() { SHA = branch.Head };
21+
}
22+
}
23+
324
public class Conflict
425
{
526
public object Theirs
@@ -31,28 +52,32 @@ public Conflict(Repository repo, WorkingCopy wc, Models.Change change)
3152
if (context is CherryPickInProgress cherryPick)
3253
{
3354
Theirs = cherryPick.Head;
34-
Mine = repo.CurrentBranch;
55+
Mine = new ConflictSourceBranch(repo, repo.CurrentBranch);
3556
}
3657
else if (context is RebaseInProgress rebase)
3758
{
3859
var b = repo.Branches.Find(x => x.IsLocal && x.Name == rebase.HeadName);
39-
Theirs = (object)b ?? rebase.StoppedAt;
60+
if (b != null)
61+
Theirs = new ConflictSourceBranch(b.Name, b.Head, rebase.StoppedAt);
62+
else
63+
Theirs = new ConflictSourceBranch(rebase.HeadName, rebase.StoppedAt?.SHA ?? "----------", rebase.StoppedAt);
64+
4065
Mine = rebase.Onto;
4166
}
4267
else if (context is RevertInProgress revert)
4368
{
4469
Theirs = revert.Head;
45-
Mine = repo.CurrentBranch;
70+
Mine = new ConflictSourceBranch(repo, repo.CurrentBranch);
4671
}
4772
else if (context is MergeInProgress merge)
4873
{
4974
Theirs = merge.Source;
50-
Mine = repo.CurrentBranch;
75+
Mine = new ConflictSourceBranch(repo, repo.CurrentBranch);
5176
}
5277
else
5378
{
5479
Theirs = "Stash or Patch";
55-
Mine = repo.CurrentBranch;
80+
Mine = new ConflictSourceBranch(repo, repo.CurrentBranch);
5681
}
5782
}
5883

src/Views/Conflict.axaml

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
<UserControl xmlns="https://github.com/avaloniaui"
2+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
3+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
4+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
5+
xmlns:m="using:SourceGit.Models"
6+
xmlns:v="using:SourceGit.Views"
7+
xmlns:vm="using:SourceGit.ViewModels"
8+
xmlns:c="using:SourceGit.Converters"
9+
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
10+
x:Class="SourceGit.Views.Conflict"
11+
x:DataType="vm:Conflict">
12+
<Border Background="{DynamicResource Brush.Window}" BorderThickness="1" BorderBrush="{DynamicResource Brush.Border2}">
13+
<Grid VerticalAlignment="Center">
14+
<StackPanel Orientation="Vertical" IsVisible="{Binding !IsResolved}">
15+
<StackPanel.DataTemplates>
16+
<DataTemplate DataType="vm:ConflictSourceBranch">
17+
<StackPanel Orientation="Horizontal">
18+
<Path Width="12" Height="12" Data="{StaticResource Icons.Branch}"/>
19+
<TextBlock Margin="4,0,0,0" Text="{Binding Name}"/>
20+
<TextBlock Margin="4,0,0,0"
21+
Text="{Binding Head, Converter={x:Static c:StringConverters.ToShortSHA}}"
22+
Foreground="DarkOrange"
23+
TextDecorations="Underline"
24+
Cursor="Hand"
25+
PointerPressed="OnPressedSHA"
26+
ToolTip.Tip="{Binding Revision}"
27+
ToolTip.ShowDelay="0">
28+
<TextBlock.DataTemplates>
29+
<DataTemplate DataType="m:Commit">
30+
<StackPanel MinWidth="400" Orientation="Vertical">
31+
<Grid ColumnDefinitions="Auto,*,Auto">
32+
<v:Avatar Grid.Column="0" Width="16" Height="16" VerticalAlignment="Center" IsHitTestVisible="False" User="{Binding Author}"/>
33+
<TextBlock Grid.Column="1" Classes="primary" Text="{Binding Author.Name}" Margin="8,0,0,0"/>
34+
<TextBlock Grid.Column="2" Classes="primary" Text="{Binding CommitterTimeStr}" Foreground="{DynamicResource Brush.FG2}" Margin="8,0,0,0"/>
35+
</Grid>
36+
37+
<TextBlock Classes="primary" Margin="0,8,0,0" Text="{Binding Subject}" TextWrapping="Wrap"/>
38+
</StackPanel>
39+
</DataTemplate>
40+
</TextBlock.DataTemplates>
41+
</TextBlock>
42+
</StackPanel>
43+
</DataTemplate>
44+
45+
<DataTemplate DataType="m:Commit">
46+
<StackPanel Orientation="Horizontal">
47+
<Path Width="12" Height="12" Data="{StaticResource Icons.Commit}"/>
48+
<v:CommitRefsPresenter Margin="8,0,0,0"
49+
TagBackground="{DynamicResource Brush.DecoratorTag}"
50+
Foreground="{DynamicResource Brush.FG1}"
51+
FontFamily="{DynamicResource Fonts.Primary}"
52+
FontSize="11"
53+
VerticalAlignment="Center"
54+
UseGraphColor="False"/>
55+
<TextBlock Margin="4,0,0,0"
56+
Text="{Binding SHA, Converter={x:Static c:StringConverters.ToShortSHA}}"
57+
Foreground="DarkOrange"
58+
TextDecorations="Underline"
59+
Cursor="Hand"
60+
PointerPressed="OnPressedSHA"
61+
ToolTip.Tip="{Binding}"
62+
ToolTip.ShowDelay="0">
63+
<TextBlock.DataTemplates>
64+
<DataTemplate DataType="m:Commit">
65+
<StackPanel MinWidth="400" Orientation="Vertical">
66+
<Grid ColumnDefinitions="Auto,*,Auto">
67+
<v:Avatar Grid.Column="0" Width="16" Height="16" VerticalAlignment="Center" IsHitTestVisible="False" User="{Binding Author}"/>
68+
<TextBlock Grid.Column="1" Classes="primary" Text="{Binding Author.Name}" Margin="8,0,0,0"/>
69+
<TextBlock Grid.Column="2" Classes="primary" Text="{Binding CommitterTimeStr}" Foreground="{DynamicResource Brush.FG2}" Margin="8,0,0,0"/>
70+
</Grid>
71+
72+
<TextBlock Classes="primary" Margin="0,8,0,0" Text="{Binding Subject}" TextWrapping="Wrap"/>
73+
</StackPanel>
74+
</DataTemplate>
75+
</TextBlock.DataTemplates>
76+
</TextBlock>
77+
<TextBlock Margin="4,0,0,0" Text="{Binding Subject}"/>
78+
</StackPanel>
79+
</DataTemplate>
80+
81+
<DataTemplate DataType="x:String">
82+
<StackPanel Orientation="Horizontal">
83+
<Path Width="12" Height="12" Data="{StaticResource Icons.Changes}"/>
84+
<TextBlock Margin="4,0,0,0" Text="{Binding}"/>
85+
</StackPanel>
86+
</DataTemplate>
87+
</StackPanel.DataTemplates>
88+
89+
<Path Width="64" Height="64" Data="{StaticResource Icons.Conflict}" Fill="{DynamicResource Brush.FG2}" HorizontalAlignment="Center"/>
90+
<TextBlock Margin="0,16" FontSize="20" FontWeight="Bold" Text="{DynamicResource Text.WorkingCopy.Conflicts}" Foreground="{DynamicResource Brush.FG2}" HorizontalAlignment="Center"/>
91+
92+
<Border Margin="16,0" Padding="8" CornerRadius="4" BorderThickness="1" BorderBrush="{DynamicResource Brush.Border2}">
93+
<Border.IsVisible>
94+
<MultiBinding Converter="{x:Static BoolConverters.And}">
95+
<Binding Path="Theirs" Converter="{x:Static ObjectConverters.IsNotNull}"/>
96+
<Binding Path="Mine" Converter="{x:Static ObjectConverters.IsNotNull}"/>
97+
</MultiBinding>
98+
</Border.IsVisible>
99+
100+
<Grid Margin="8,0,0,0" RowDefinitions="32,32" ColumnDefinitions="Auto,*">
101+
<TextBlock Grid.Row="0" Grid.Column="0" Classes="info_label" Text="THEIRS"/>
102+
<ContentControl Grid.Row="0" Grid.Column="1" Margin="16,0,0,0" Content="{Binding Theirs}"/>
103+
<TextBlock Grid.Row="1" Grid.Column="0" Classes="info_label" Text="MINE"/>
104+
<ContentControl Grid.Row="1" Grid.Column="1" Margin="16,0,0,0" Content="{Binding Mine}"/>
105+
</Grid>
106+
</Border>
107+
108+
<StackPanel Margin="0,8,0,0" Orientation="Horizontal" HorizontalAlignment="Center">
109+
<Button Classes="flat" Content="USE THEIRS" Command="{Binding UseTheirs}"/>
110+
<Button Classes="flat" Margin="8,0,0,0" Content="USE MINE" Command="{Binding UseMine}"/>
111+
<Button Classes="flat" Margin="8,0,0,0" Content="OPEN EXTERNAL MERGETOOL" Command="{Binding OpenExternalMergeTool}"/>
112+
</StackPanel>
113+
</StackPanel>
114+
115+
<StackPanel Orientation="Vertical" IsVisible="{Binding IsResolved}">
116+
<Path Width="64" Height="64" Data="{StaticResource Icons.Check}" Fill="Green"/>
117+
<TextBlock Margin="0,16,0,8" FontSize="20" FontWeight="Bold" Text="{DynamicResource Text.WorkingCopy.Conflicts.Resolved}" Foreground="{DynamicResource Brush.FG2}" HorizontalAlignment="Center"/>
118+
<TextBlock Text="{DynamicResource Text.WorkingCopy.CanStageTip}" Foreground="{DynamicResource Brush.FG2}" HorizontalAlignment="Center"/>
119+
</StackPanel>
120+
</Grid>
121+
</Border>
122+
</UserControl>

src/Views/Conflict.axaml.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using Avalonia.Controls;
2+
using Avalonia.Input;
3+
using Avalonia.VisualTree;
4+
5+
namespace SourceGit.Views
6+
{
7+
public partial class Conflict : UserControl
8+
{
9+
public Conflict()
10+
{
11+
InitializeComponent();
12+
}
13+
14+
private void OnPressedSHA(object sender, PointerPressedEventArgs e)
15+
{
16+
var repoView = this.FindAncestorOfType<Repository>();
17+
if (repoView is { DataContext: ViewModels.Repository repo } && sender is TextBlock text)
18+
repo.NavigateToCommit(text.Text);
19+
20+
e.Handled = true;
21+
}
22+
}
23+
}

src/Views/WorkingCopy.axaml

Lines changed: 1 addition & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -203,84 +203,7 @@
203203
<ContentControl Content="{Binding DetailContext}">
204204
<ContentControl.DataTemplates>
205205
<DataTemplate DataType="vm:Conflict">
206-
<Border Background="{DynamicResource Brush.Window}" BorderThickness="1" BorderBrush="{DynamicResource Brush.Border2}">
207-
<Grid VerticalAlignment="Center">
208-
<StackPanel Orientation="Vertical" IsVisible="{Binding !IsResolved}">
209-
<StackPanel.DataTemplates>
210-
<DataTemplate DataType="m:Branch">
211-
<StackPanel Orientation="Horizontal">
212-
<Path Width="12" Height="12" Data="{StaticResource Icons.Branch}"/>
213-
<TextBlock Margin="4,0,0,0" Text="{Binding FriendlyName}"/>
214-
<TextBlock Margin="4,0,0,0"
215-
Text="{Binding Head, Converter={x:Static c:StringConverters.ToShortSHA}}"
216-
Foreground="DarkOrange"
217-
TextDecorations="Underline"
218-
Cursor="Hand"
219-
PointerPressed="OnPressedSHA"/>
220-
</StackPanel>
221-
</DataTemplate>
222-
223-
<DataTemplate DataType="m:Commit">
224-
<StackPanel Orientation="Horizontal">
225-
<Path Width="12" Height="12" Data="{StaticResource Icons.Commit}"/>
226-
<v:CommitRefsPresenter Margin="8,0,0,0"
227-
TagBackground="{DynamicResource Brush.DecoratorTag}"
228-
Foreground="{DynamicResource Brush.FG1}"
229-
FontFamily="{DynamicResource Fonts.Primary}"
230-
FontSize="11"
231-
VerticalAlignment="Center"
232-
UseGraphColor="False"/>
233-
<TextBlock Margin="4,0,0,0"
234-
Text="{Binding SHA, Converter={x:Static c:StringConverters.ToShortSHA}}"
235-
Foreground="DarkOrange"
236-
TextDecorations="Underline"
237-
Cursor="Hand"
238-
PointerPressed="OnPressedSHA"/>
239-
<TextBlock Margin="4,0,0,0" Text="{Binding Subject}"/>
240-
</StackPanel>
241-
</DataTemplate>
242-
243-
<DataTemplate DataType="x:String">
244-
<StackPanel Orientation="Horizontal">
245-
<Path Width="12" Height="12" Data="{StaticResource Icons.Changes}"/>
246-
<TextBlock Margin="4,0,0,0" Text="{Binding}"/>
247-
</StackPanel>
248-
</DataTemplate>
249-
</StackPanel.DataTemplates>
250-
251-
<Path Width="64" Height="64" Data="{StaticResource Icons.Conflict}" Fill="{DynamicResource Brush.FG2}" HorizontalAlignment="Center"/>
252-
<TextBlock Margin="0,16" FontSize="20" FontWeight="Bold" Text="{DynamicResource Text.WorkingCopy.Conflicts}" Foreground="{DynamicResource Brush.FG2}" HorizontalAlignment="Center"/>
253-
254-
<Border Margin="16,0" Padding="8" CornerRadius="4" BorderThickness="1" BorderBrush="{DynamicResource Brush.Border2}">
255-
<Border.IsVisible>
256-
<MultiBinding Converter="{x:Static BoolConverters.And}">
257-
<Binding Path="Theirs" Converter="{x:Static ObjectConverters.IsNotNull}"/>
258-
<Binding Path="Mine" Converter="{x:Static ObjectConverters.IsNotNull}"/>
259-
</MultiBinding>
260-
</Border.IsVisible>
261-
262-
<Grid Margin="8,0,0,0" RowDefinitions="32,32" ColumnDefinitions="Auto,*">
263-
<TextBlock Grid.Row="0" Grid.Column="0" Classes="info_label" Text="THEIRS"/>
264-
<ContentControl Grid.Row="0" Grid.Column="1" Margin="16,0,0,0" Content="{Binding Theirs}"/>
265-
<TextBlock Grid.Row="1" Grid.Column="0" Classes="info_label" Text="MINE"/>
266-
<ContentControl Grid.Row="1" Grid.Column="1" Margin="16,0,0,0" Content="{Binding Mine}"/>
267-
</Grid>
268-
</Border>
269-
270-
<StackPanel Margin="0,8,0,0" Orientation="Horizontal" HorizontalAlignment="Center">
271-
<Button Classes="flat" Content="USE THEIRS" Command="{Binding UseTheirs}"/>
272-
<Button Classes="flat" Margin="8,0,0,0" Content="USE MINE" Command="{Binding UseMine}"/>
273-
<Button Classes="flat" Margin="8,0,0,0" Content="OPEN EXTERNAL MERGETOOL" Command="{Binding OpenExternalMergeTool}"/>
274-
</StackPanel>
275-
</StackPanel>
276-
277-
<StackPanel Orientation="Vertical" IsVisible="{Binding IsResolved}">
278-
<Path Width="64" Height="64" Data="{StaticResource Icons.Check}" Fill="Green"/>
279-
<TextBlock Margin="0,16,0,8" FontSize="20" FontWeight="Bold" Text="{DynamicResource Text.WorkingCopy.Conflicts.Resolved}" Foreground="{DynamicResource Brush.FG2}" HorizontalAlignment="Center"/>
280-
<TextBlock Text="{DynamicResource Text.WorkingCopy.CanStageTip}" Foreground="{DynamicResource Brush.FG2}" HorizontalAlignment="Center"/>
281-
</StackPanel>
282-
</Grid>
283-
</Border>
206+
<v:Conflict/>
284207
</DataTemplate>
285208

286209
<DataTemplate DataType="vm:DiffContext">

src/Views/WorkingCopy.axaml.cs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -160,14 +160,5 @@ private void OnOpenConventionalCommitHelper(object _, RoutedEventArgs e)
160160

161161
e.Handled = true;
162162
}
163-
164-
private void OnPressedSHA(object sender, PointerPressedEventArgs e)
165-
{
166-
var repoView = this.FindAncestorOfType<Repository>();
167-
if (repoView is { DataContext: ViewModels.Repository repo } && sender is TextBlock text)
168-
repo.NavigateToCommit(text.Text);
169-
170-
e.Handled = true;
171-
}
172163
}
173164
}

0 commit comments

Comments
 (0)