diff --git a/src/Models/OpenAI.cs b/src/Models/OpenAI.cs
index 516a9423..df67ff66 100644
--- a/src/Models/OpenAI.cs
+++ b/src/Models/OpenAI.cs
@@ -175,7 +175,7 @@ namespace SourceGit.Models
var body = reader.Result;
if (!rsp.IsSuccessStatusCode)
{
- throw new Exception($"AI service returns error code {rsp.StatusCode}. Body: {body??string.Empty}");
+ throw new Exception($"AI service returns error code {rsp.StatusCode}. Body: {body ?? string.Empty}");
}
return JsonSerializer.Deserialize(reader.Result, JsonCodeGen.Default.OpenAIChatResponse);
diff --git a/src/Views/CommitBaseInfo.axaml b/src/Views/CommitBaseInfo.axaml
index fdccbf99..d850932c 100644
--- a/src/Views/CommitBaseInfo.axaml
+++ b/src/Views/CommitBaseInfo.axaml
@@ -211,6 +211,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Views/CommitMessagePresenter.cs b/src/Views/CommitMessagePresenter.cs
index a022ae99..59543af8 100644
--- a/src/Views/CommitMessagePresenter.cs
+++ b/src/Views/CommitMessagePresenter.cs
@@ -1,12 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
+using System.Threading.Tasks;
using Avalonia;
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Controls.Documents;
using Avalonia.Input;
+using Avalonia.Threading;
using Avalonia.VisualTree;
namespace SourceGit.Views
@@ -43,7 +45,9 @@ namespace SourceGit.Views
if (change.Property == MessageProperty || change.Property == IssueTrackerRulesProperty)
{
Inlines!.Clear();
+ _inlineCommits.Clear();
_matches = null;
+ _lastHover = null;
ClearHoveredIssueLink();
var message = Message;
@@ -154,6 +158,10 @@ namespace SourceGit.Views
ToolTip.SetTip(this, match.Link);
ToolTip.SetIsOpen(this, true);
}
+ else
+ {
+ ProcessHoverCommitLink(match);
+ }
return;
}
@@ -256,6 +264,52 @@ namespace SourceGit.Views
ClearHoveredIssueLink();
}
+ private void ProcessHoverCommitLink(Models.Hyperlink link)
+ {
+ var sha = link.Link;
+
+ // If we have already queried this SHA, just use it.
+ if (_inlineCommits.TryGetValue(sha, out var exist))
+ {
+ if (exist != null)
+ {
+ ToolTip.SetTip(this, exist);
+ ToolTip.SetIsOpen(this, true);
+ }
+
+ return;
+ }
+
+ var parentView = this.FindAncestorOfType();
+ if (parentView is { DataContext: ViewModels.CommitDetail detail })
+ {
+ // Record the SHA of current viewing commit in the CommitDetail panel to determine if it is changed after
+ // asynchronous queries.
+ var lastDetailCommit = detail.Commit.SHA;
+ Task.Run(() =>
+ {
+ var c = detail.GetParent(sha);
+ Dispatcher.UIThread.Invoke(() =>
+ {
+ // Make sure the DataContext of CommitBaseInfo is not changed.
+ var currentParent = this.FindAncestorOfType();
+ if (currentParent is { DataContext: ViewModels.CommitDetail currentDetail } &&
+ currentDetail.Commit.SHA == lastDetailCommit)
+ {
+ _inlineCommits.Add(sha, c);
+
+ // Make sure user still hovers the target SHA.
+ if (_lastHover == link)
+ {
+ ToolTip.SetTip(this, c);
+ ToolTip.SetIsOpen(this, true);
+ }
+ }
+ });
+ });
+ }
+ }
+
private void ClearHoveredIssueLink()
{
if (_lastHover != null)
@@ -268,5 +322,6 @@ namespace SourceGit.Views
private List _matches = null;
private Models.Hyperlink _lastHover = null;
+ private Dictionary _inlineCommits = new();
}
}
diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs
index 544453f5..da2d9ed1 100644
--- a/src/Views/TextDiffView.axaml.cs
+++ b/src/Views/TextDiffView.axaml.cs
@@ -476,7 +476,7 @@ namespace SourceGit.Views
get => GetValue(SelectedChunkProperty);
set => SetValue(SelectedChunkProperty, value);
}
-
+
public static readonly StyledProperty DisplayRangeProperty =
AvaloniaProperty.Register(nameof(DisplayRange), new TextDiffViewRange(0, 0));
@@ -523,7 +523,7 @@ namespace SourceGit.Views
var firstLineIdx = DisplayRange.StartIdx;
if (firstLineIdx <= 1)
return;
-
+
var lines = GetLines();
var firstLineType = lines[firstLineIdx].Type;
var prevLineType = lines[firstLineIdx - 1].Type;
@@ -761,7 +761,7 @@ namespace SourceGit.Views
if (start > index)
start = index;
}
-
+
SetCurrentValue(DisplayRangeProperty, new TextDiffViewRange(start, start + count));
}
@@ -1313,9 +1313,9 @@ namespace SourceGit.Views
private ScrollViewer _scrollViewer = null;
}
-
+
public class TextDiffViewMinimap : Control
- {
+ {
public static readonly StyledProperty AddedLineBrushProperty =
AvaloniaProperty.Register(nameof(AddedLineBrush), new SolidColorBrush(Color.FromArgb(60, 0, 255, 0)));
@@ -1333,7 +1333,7 @@ namespace SourceGit.Views
get => GetValue(DeletedLineBrushProperty);
set => SetValue(DeletedLineBrushProperty, value);
}
-
+
public static readonly StyledProperty DisplayRangeProperty =
AvaloniaProperty.Register(nameof(DisplayRange), new TextDiffViewRange(0, 0));
@@ -1342,7 +1342,7 @@ namespace SourceGit.Views
get => GetValue(DisplayRangeProperty);
set => SetValue(DisplayRangeProperty, value);
}
-
+
public static readonly StyledProperty DisplayRangeColorProperty =
AvaloniaProperty.Register(nameof(DisplayRangeColor), Colors.RoyalBlue);
@@ -1376,7 +1376,7 @@ namespace SourceGit.Views
total = diff.Lines.Count;
RenderSingleSide(context, diff.Lines, 0, Bounds.Width);
}
-
+
var range = DisplayRange;
if (range.EndIdx == 0)
return;
@@ -1416,7 +1416,7 @@ namespace SourceGit.Views
lastLineTypeStart = i;
}
}
-
+
RenderBlock(context, lastLineType, lastLineTypeStart, total - lastLineTypeStart, total, x, width);
}
@@ -1431,7 +1431,7 @@ namespace SourceGit.Views
}
}
}
-
+
public partial class TextDiffView : UserControl
{
public static readonly StyledProperty UseSideBySideDiffProperty =