From 25a53d990bdea26142e9145c06e278d031c4c3bf Mon Sep 17 00:00:00 2001 From: swanadiva Date: Wed, 24 Jun 2026 11:30:54 +0700 Subject: [PATCH] fix: SFTP default to Local pane + fixed border height - Default active pane changed from Remote to Local on SFTP init - renderPane now takes maxH parameter for fixed border height - paneStyle.Height(maxH) prevents border from shrinking/growing on scroll - Stacked mode: maxH = t.height - 6; Side-by-side: t.height - 5 --- CHANGELOG.md | 4 ++++ PROJECT_STATE.md | 5 ++++- pkg/tui/sftp_browser_tab.go | 31 +++++++++++++++++++++---------- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fd9b68..5c17ee9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,10 @@ - Added pane indicator bar: `[Local] Remote` with active pane highlighted - Side-by-side mode (≥50 cols) unchanged — both panes remain visible - Tab key now visually switches between panes on narrow terminals +- Default active pane: Local (was Remote) +- Border height fix: pane uses fixed `Height(maxH)` — border no longer shrinks/grows when scrolling +- `renderPane` now takes `maxH` parameter to control content area height +- Stacked: `maxH = t.height - 6`; Side-by-side: `maxH = t.height - 5` - Breakpoints: compact (<60), medium (60–100), wide (≥100) ## v1.0.0 (2025-01-30) diff --git a/PROJECT_STATE.md b/PROJECT_STATE.md index 7904a9a..0c12d04 100644 --- a/PROJECT_STATE.md +++ b/PROJECT_STATE.md @@ -68,7 +68,10 @@ ✅ Stacked mode (<50 cols): render cuma ACTIVE pane (bukan 2 pane) ✅ Pane indicator bar: `[Local] Remote` — active disorot hijau (StatusBarStyle) ✅ Side-by-side mode (>=50 cols): tidak diubah, tetap 2 pane -✅ `maxDisplay` tidak diubah (cuma 1 pane, full height) +✅ Default active pane: Local (bukan Remote) +✅ Border height fix: `renderPane` sekarang terima `maxH` parameter, `paneStyle.Height(maxH)` → border selalu konsisten tingginya, tidak naik-turun sesuai scroll +✅ Stacked mode: `maxH = t.height - 6` (title + indicator + border + footer) +✅ Side-by-side mode: `maxH = t.height - 5` (title + border + footer) --- diff --git a/pkg/tui/sftp_browser_tab.go b/pkg/tui/sftp_browser_tab.go index 47a9bba..2d1753d 100644 --- a/pkg/tui/sftp_browser_tab.go +++ b/pkg/tui/sftp_browser_tab.go @@ -79,7 +79,7 @@ func NewSFTPBrowserTab(host *models.Host, dataDir string) *SFTPBrowserTab { return &SFTPBrowserTab{ host: host, dataDir: dataDir, - active: paneRemote, + active: paneLocal, left: sftpPane{ cwd: home, localRoot: home, @@ -565,10 +565,16 @@ func (t *SFTPBrowserTab) View() string { } indicator = lipgloss.JoinHorizontal(lipgloss.Top, indicatorParts[0], SubtitleStyle.Render(" "), indicatorParts[1]) + // Height: t.height - 1(title) - 1(indicator) - 2(border) - 2(footer) = t.height - 6 + paneH := t.height - 6 + if paneH < 5 { + paneH = 5 + } + if t.active == paneLocal { - leftView = t.renderPane(&t.left, paneLocal, paneW) + leftView = t.renderPane(&t.left, paneLocal, paneW, paneH) } else { - leftView = t.renderPane(&t.right, paneRemote, paneW) + leftView = t.renderPane(&t.right, paneRemote, paneW, paneH) } } else { // Side by side — reserve 2 chars border per pane @@ -576,8 +582,13 @@ func (t *SFTPBrowserTab) View() string { if halfW < 20 { halfW = 20 } - leftView = t.renderPane(&t.left, paneLocal, halfW) - rightView = t.renderPane(&t.right, paneRemote, halfW) + // Height: t.height - 1(title) - 2(border) - 2(footer) = t.height - 5 + paneH := t.height - 5 + if paneH < 5 { + paneH = 5 + } + leftView = t.renderPane(&t.left, paneLocal, halfW, paneH) + rightView = t.renderPane(&t.right, paneRemote, halfW, paneH) } var b strings.Builder @@ -614,7 +625,7 @@ func (t *SFTPBrowserTab) View() string { return b.String() } -func (t *SFTPBrowserTab) renderPane(p *sftpPane, pt paneType, maxW int) string { +func (t *SFTPBrowserTab) renderPane(p *sftpPane, pt paneType, maxW, maxH int) string { isActive := t.active == pt title := "Local" @@ -668,9 +679,9 @@ func (t *SFTPBrowserTab) renderPane(p *sftpPane, pt paneType, maxW int) string { if len(visible) == 0 { content.WriteString(SubtitleStyle.Render(" (empty)")) } else { - maxDisplay := t.height - 6 - if maxDisplay < 5 { - maxDisplay = 5 + maxDisplay := maxH - 4 + if maxDisplay < 1 { + maxDisplay = 1 } start := 0 if p.selIdx >= maxDisplay { @@ -724,7 +735,7 @@ func (t *SFTPBrowserTab) renderPane(p *sftpPane, pt paneType, maxW int) string { } inner := titleBar + "\n" + content.String() - return paneStyle.Width(maxW).Render(inner) + return paneStyle.Width(maxW).Height(maxH).Render(inner) } func (t *SFTPBrowserTab) Close() {