fix(tui): clamp diff scroll offset to last full page
The diff overlay incremented diffScrollOffset on every down-key with no upper bound; the render clamped only the displayed offset, so the stored value grew unbounded and the up-key appeared dead for N presses. Clamp the increment against a new diffMaxScroll() (len(lines) - body height), shared with the render path via diffBodyHeight().
This commit is contained in:
@@ -94,20 +94,36 @@ func (m Model) renderApproval(base string) string {
|
|||||||
return m.center(modal)
|
return m.center(modal)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m Model) diffModal() string {
|
// diffBodyHeight is the number of diff lines visible in the diff modal body.
|
||||||
t := m.theme
|
func (m Model) diffBodyHeight() int {
|
||||||
w := m.modalWidth()
|
|
||||||
h := m.height * 70 / 100
|
h := m.height * 70 / 100
|
||||||
if h < 8 {
|
if h < 8 {
|
||||||
h = 8
|
h = 8
|
||||||
}
|
}
|
||||||
bodyH := h - 6
|
return h - 6
|
||||||
|
}
|
||||||
|
|
||||||
|
// diffMaxScroll is the largest scroll offset that still fills the body with
|
||||||
|
// diff lines, keeping the last page anchored to the bottom of the modal.
|
||||||
|
func (m Model) diffMaxScroll() int {
|
||||||
|
lines := strings.Split(strings.TrimRight(m.currentDiff(), "\n"), "\n")
|
||||||
|
max := len(lines) - m.diffBodyHeight()
|
||||||
|
if max < 0 {
|
||||||
|
max = 0
|
||||||
|
}
|
||||||
|
return max
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Model) diffModal() string {
|
||||||
|
t := m.theme
|
||||||
|
w := m.modalWidth()
|
||||||
|
bodyH := m.diffBodyHeight()
|
||||||
diff := m.currentDiff()
|
diff := m.currentDiff()
|
||||||
lines := strings.Split(strings.TrimRight(diff, "\n"), "\n")
|
lines := strings.Split(strings.TrimRight(diff, "\n"), "\n")
|
||||||
|
|
||||||
off := m.diffScrollOffset
|
off := m.diffScrollOffset
|
||||||
if off > len(lines)-1 {
|
if off > m.diffMaxScroll() {
|
||||||
off = len(lines) - 1
|
off = m.diffMaxScroll()
|
||||||
}
|
}
|
||||||
if off < 0 {
|
if off < 0 {
|
||||||
off = 0
|
off = 0
|
||||||
|
|||||||
@@ -332,7 +332,9 @@ func (m Model) handleOverlayKey(k tea.KeyMsg) (tea.Model, tea.Cmd) {
|
|||||||
m.diffScrollOffset--
|
m.diffScrollOffset--
|
||||||
}
|
}
|
||||||
case k.Type == tea.KeyDown || runeIs(k, "j"):
|
case k.Type == tea.KeyDown || runeIs(k, "j"):
|
||||||
m.diffScrollOffset++
|
if m.diffScrollOffset < m.diffMaxScroll() {
|
||||||
|
m.diffScrollOffset++
|
||||||
|
}
|
||||||
case k.Type == tea.KeyCtrlX:
|
case k.Type == tea.KeyCtrlX:
|
||||||
m.overlay = OverlayNone
|
m.overlay = OverlayNone
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user