fix: auto-navigating to first change sometimes does not work (#1952)

Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
leo
2025-12-04 10:52:48 +08:00
parent e2feac3624
commit f318ecaacc
4 changed files with 35 additions and 117 deletions

View File

@@ -3,6 +3,14 @@ using CommunityToolkit.Mvvm.ComponentModel;
namespace SourceGit.ViewModels
{
public enum BlockNavigationDirection
{
First = 0,
Prev,
Next,
Last
}
public class BlockNavigation : ObservableObject
{
public record Block(int Start, int End)
@@ -67,7 +75,7 @@ namespace SourceGit.ViewModels
_blocks.AddRange(blocks);
if (gotoFirst)
GotoFirst();
Goto(BlockNavigationDirection.First);
}
public Block GetCurrentBlock()
@@ -78,48 +86,20 @@ namespace SourceGit.ViewModels
return null;
}
public Block GotoFirst()
public Block Goto(BlockNavigationDirection direction)
{
if (_blocks.Count == 0)
return null;
_current = 0;
OnPropertyChanged(nameof(Indicator));
return _blocks[_current];
}
_current = direction switch
{
BlockNavigationDirection.First => 0,
BlockNavigationDirection.Prev => _current <= 0 ? 0 : _current - 1,
BlockNavigationDirection.Next => _current >= _blocks.Count - 1 ? _blocks.Count - 1 : _current + 1,
BlockNavigationDirection.Last => _blocks.Count - 1,
_ => _current
};
public Block GotoPrev()
{
if (_blocks.Count == 0)
return null;
if (_current == -1)
_current = 0;
else if (_current > 0)
_current--;
OnPropertyChanged(nameof(Indicator));
return _blocks[_current];
}
public Block GotoNext()
{
if (_blocks.Count == 0)
return null;
if (_current < _blocks.Count - 1)
_current++;
OnPropertyChanged(nameof(Indicator));
return _blocks[_current];
}
public Block GotoLast()
{
if (_blocks.Count == 0)
return null;
_current = _blocks.Count - 1;
OnPropertyChanged(nameof(Indicator));
return _blocks[_current];
}

View File

@@ -135,10 +135,7 @@ namespace SourceGit.ViewModels
}
if (ctx.IsSideBySide() != UseSideBySide)
{
ctx = ctx.SwitchMode();
Content = ctx;
}
Content = ctx.SwitchMode();
}
}

View File

@@ -21,25 +21,25 @@ namespace SourceGit.Views
private void OnGotoFirstChange(object _, RoutedEventArgs e)
{
this.FindDescendantOfType<ThemedTextDiffPresenter>()?.GotoFirstChange();
this.FindDescendantOfType<ThemedTextDiffPresenter>()?.GotoChange(ViewModels.BlockNavigationDirection.First);
e.Handled = true;
}
private void OnGotoPrevChange(object _, RoutedEventArgs e)
{
this.FindDescendantOfType<ThemedTextDiffPresenter>()?.GotoPrevChange();
this.FindDescendantOfType<ThemedTextDiffPresenter>()?.GotoChange(ViewModels.BlockNavigationDirection.Prev);
e.Handled = true;
}
private void OnGotoNextChange(object _, RoutedEventArgs e)
{
this.FindDescendantOfType<ThemedTextDiffPresenter>()?.GotoNextChange();
this.FindDescendantOfType<ThemedTextDiffPresenter>()?.GotoChange(ViewModels.BlockNavigationDirection.Next);
e.Handled = true;
}
private void OnGotoLastChange(object _, RoutedEventArgs e)
{
this.FindDescendantOfType<ThemedTextDiffPresenter>()?.GotoLastChange();
this.FindDescendantOfType<ThemedTextDiffPresenter>()?.GotoChange(ViewModels.BlockNavigationDirection.Last);
e.Handled = true;
}
}

View File

@@ -487,43 +487,16 @@ namespace SourceGit.Views
{
}
public virtual void GotoFirstChange()
public void GotoChange(ViewModels.BlockNavigationDirection direction)
{
var first = BlockNavigation.GotoFirst();
if (first != null)
{
TextArea.Caret.Line = first.Start;
ScrollToLine(first.Start);
}
}
if (DataContext is not ViewModels.TextDiffContext ctx)
return;
public virtual void GotoPrevChange()
{
var prev = BlockNavigation.GotoPrev();
if (prev != null)
var block = BlockNavigation.Goto(direction);
if (block != null)
{
TextArea.Caret.Line = prev.Start;
ScrollToLine(prev.Start);
}
}
public virtual void GotoNextChange()
{
var next = BlockNavigation.GotoNext();
if (next != null)
{
TextArea.Caret.Line = next.Start;
ScrollToLine(next.Start);
}
}
public virtual void GotoLastChange()
{
var next = BlockNavigation.GotoLast();
if (next != null)
{
TextArea.Caret.Line = next.Start;
ScrollToLine(next.Start);
TextArea.Caret.Line = block.Start;
ScrollToLine(block.Start);
}
}
@@ -618,9 +591,9 @@ namespace SourceGit.Views
}
}
protected override void OnDataContextBeginUpdate()
protected override void OnDataContextChanged(EventArgs e)
{
base.OnDataContextBeginUpdate();
base.OnDataContextChanged(e);
AutoScrollToFirstChange();
}
@@ -805,9 +778,6 @@ namespace SourceGit.Views
if (DataContext is not ViewModels.TextDiffContext ctx)
return;
if (ctx.IsSideBySide() && !IsOld)
return;
var curBlock = ctx.BlockNavigation.GetCurrentBlock();
if (curBlock == null)
return;
@@ -819,8 +789,9 @@ namespace SourceGit.Views
var scroller = this.FindDescendantOfType<ScrollViewer>();
if (scroller != null)
{
ctx.ScrollOffset = new Vector(0, vOffset);
scroller.Offset = ctx.ScrollOffset;
var scrollOffset = new Vector(0, vOffset);
scroller.Offset = scrollOffset;
ctx.ScrollOffset = scrollOffset;
}
}
}
@@ -1098,30 +1069,6 @@ namespace SourceGit.Views
return [];
}
public override void GotoFirstChange()
{
base.GotoFirstChange();
SyncScrollOffset();
}
public override void GotoPrevChange()
{
base.GotoPrevChange();
SyncScrollOffset();
}
public override void GotoNextChange()
{
base.GotoNextChange();
SyncScrollOffset();
}
public override void GotoLastChange()
{
base.GotoLastChange();
SyncScrollOffset();
}
public override void UpdateSelectedChunk(double y)
{
if (DataContext is not ViewModels.TwoSideTextDiff diff)
@@ -1318,12 +1265,6 @@ namespace SourceGit.Views
TextArea?.TextView?.Redraw();
}
private void SyncScrollOffset()
{
if (_scrollViewer is not null && DataContext is ViewModels.TwoSideTextDiff diff)
diff.ScrollOffset = _scrollViewer.Offset;
}
private ScrollViewer _scrollViewer = null;
}