fix: SFTP stacked mode — render only active pane + indicator bar

Stacked mode (<50 cols) now shows only the active pane (Local/Remote)
with a visual indicator bar. Tab switches between panes. Side-by-side
mode (>=50 cols) unchanged.
This commit is contained in:
swanadiva
2026-06-24 11:22:21 +07:00
parent c114b2435c
commit 2e10308c75
3 changed files with 37 additions and 20 deletions
+6
View File
@@ -27,6 +27,12 @@
- Fixed: key_list_tab & snippet_list_tab were dropping last data row (off-by-one in `rows[:len(rows)-1]`)
- Fixed: SFTP pane width — lipgloss `Width(n)` renders `n+2` chars (border extra). halfW now `t.width/2-2` to compensate. File names truncate to `…` within inner text area. Filter line also truncated.
- Verified: zero overflow at 80, 60, 50 (side-by-side), 40, 30 cols (stacked)
### SFTP Stacked Mode Fix (Done)
- Stacked mode (<50 cols) now renders only the active pane (Local or Remote)
- 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
- Breakpoints: compact (<60), medium (60100), wide (≥100)
## v1.0.0 (2025-01-30)
+6 -16
View File
@@ -63,22 +63,12 @@
✅ Fixed bug: key_list_tab.go & snippet_list_tab.go dropped last row (`rows[:len(rows)-1]` excluded real data)
✅ Breakpoints: compact (<60 cols / mobile), medium (60100 / tablet), wide (≥100 / desktop)
### Next: SFTP Stacked Mode Fix
**File**: `pkg/tui/sftp_browser_tab.go`
**Masalah**: Stacked mode (<50 cols) render 2 pane vertikal, masing-masing
`t.height-6` entries. Total 2x tinggi terminal. Pane kedua menutupi pane pertama.
Tab switch bekerja tapi tidak terlihat karena cuma 1 pane visible.
**Solusi**:
- Stacked mode: render cuma ACTIVE pane (bukan 2 pane)
- Tambah pane indicator bar: `[Local] Remote` (active disorot hijau)
- Side-by-side mode (>=50 cols): TIDAK DIUBAH, tetap 2 pane
**Detail implementasi**:
1. Di `View()`, ganti blok `if t.width < 50`:
- Render cuma `t.renderPane(activePane, paneW)` bukan keduanya
- Tambah indicator bar sebelum pane: active pane disorot `StatusBarStyle`, inactive `SubtitleStyle`
2. `maxDisplay` tidak perlu diubah (cuma 1 pane, full height)
3. Footer tetap sama (sudah wrapped)
**Prioritas**: HIGH
### Done: SFTP Stacked Mode Fix
**File**: `pkg/tui/sftp_browser_tab.go`
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)
---
+25 -4
View File
@@ -543,14 +543,33 @@ func (t *SFTPBrowserTab) View() string {
// Responsive pane layout: stack vertically on narrow terminals
// Each pane renders at maxW+2 total (maxW content + 2 border chars)
var leftView, rightView string
var indicator string
if t.width < 50 {
// Stack vertically — each pane gets full width minus border
// Only show active pane in stacked mode — Tab switches between them
paneW := t.width - 2
if paneW < 20 {
paneW = 20
}
leftView = t.renderPane(&t.left, paneLocal, paneW)
rightView = t.renderPane(&t.right, paneRemote, paneW)
// Pane indicator: [Local] Remote or Local [Remote]
var indicatorParts []string
for _, name := range []string{"Local", "Remote"} {
pt := paneLocal
if name == "Remote" {
pt = paneRemote
}
if t.active == pt {
indicatorParts = append(indicatorParts, StatusBarStyle.Render(" "+name+" "))
} else {
indicatorParts = append(indicatorParts, SubtitleStyle.Render(" "+name+" "))
}
}
indicator = lipgloss.JoinHorizontal(lipgloss.Top, indicatorParts[0], SubtitleStyle.Render(" "), indicatorParts[1])
if t.active == paneLocal {
leftView = t.renderPane(&t.left, paneLocal, paneW)
} else {
leftView = t.renderPane(&t.right, paneRemote, paneW)
}
} else {
// Side by side — reserve 2 chars border per pane
halfW := t.width/2 - 2
@@ -568,7 +587,9 @@ func (t *SFTPBrowserTab) View() string {
b.WriteString("\n")
if t.width < 50 {
b.WriteString(lipgloss.JoinVertical(lipgloss.Left, leftView, rightView))
b.WriteString(lipgloss.PlaceHorizontal(t.width, lipgloss.Center, indicator))
b.WriteString("\n")
b.WriteString(leftView)
} else {
b.WriteString(lipgloss.JoinHorizontal(lipgloss.Top, leftView, rightView))
}