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:
@@ -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: 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.
|
- 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)
|
- 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 (60–100), wide (≥100)
|
- Breakpoints: compact (<60), medium (60–100), wide (≥100)
|
||||||
|
|
||||||
## v1.0.0 (2025-01-30)
|
## v1.0.0 (2025-01-30)
|
||||||
|
|||||||
+6
-16
@@ -63,22 +63,12 @@
|
|||||||
✅ Fixed bug: key_list_tab.go & snippet_list_tab.go dropped last row (`rows[:len(rows)-1]` excluded real data)
|
✅ 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 (60–100 / tablet), wide (≥100 / desktop)
|
✅ Breakpoints: compact (<60 cols / mobile), medium (60–100 / tablet), wide (≥100 / desktop)
|
||||||
|
|
||||||
### Next: SFTP Stacked Mode Fix
|
### Done: SFTP Stacked Mode Fix
|
||||||
⏳ **File**: `pkg/tui/sftp_browser_tab.go`
|
✅ **File**: `pkg/tui/sftp_browser_tab.go`
|
||||||
⏳ **Masalah**: Stacked mode (<50 cols) render 2 pane vertikal, masing-masing
|
✅ Stacked mode (<50 cols): render cuma ACTIVE pane (bukan 2 pane)
|
||||||
`t.height-6` entries. Total 2x tinggi terminal. Pane kedua menutupi pane pertama.
|
✅ Pane indicator bar: `[Local] Remote` — active disorot hijau (StatusBarStyle)
|
||||||
Tab switch bekerja tapi tidak terlihat karena cuma 1 pane visible.
|
✅ Side-by-side mode (>=50 cols): tidak diubah, tetap 2 pane
|
||||||
⏳ **Solusi**:
|
✅ `maxDisplay` tidak diubah (cuma 1 pane, full height)
|
||||||
- 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
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -543,14 +543,33 @@ func (t *SFTPBrowserTab) View() string {
|
|||||||
// Responsive pane layout: stack vertically on narrow terminals
|
// Responsive pane layout: stack vertically on narrow terminals
|
||||||
// Each pane renders at maxW+2 total (maxW content + 2 border chars)
|
// Each pane renders at maxW+2 total (maxW content + 2 border chars)
|
||||||
var leftView, rightView string
|
var leftView, rightView string
|
||||||
|
var indicator string
|
||||||
if t.width < 50 {
|
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
|
paneW := t.width - 2
|
||||||
if paneW < 20 {
|
if paneW < 20 {
|
||||||
paneW = 20
|
paneW = 20
|
||||||
}
|
}
|
||||||
leftView = t.renderPane(&t.left, paneLocal, paneW)
|
// Pane indicator: [Local] Remote or Local [Remote]
|
||||||
rightView = t.renderPane(&t.right, paneRemote, paneW)
|
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 {
|
} else {
|
||||||
// Side by side — reserve 2 chars border per pane
|
// Side by side — reserve 2 chars border per pane
|
||||||
halfW := t.width/2 - 2
|
halfW := t.width/2 - 2
|
||||||
@@ -568,7 +587,9 @@ func (t *SFTPBrowserTab) View() string {
|
|||||||
b.WriteString("\n")
|
b.WriteString("\n")
|
||||||
|
|
||||||
if t.width < 50 {
|
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 {
|
} else {
|
||||||
b.WriteString(lipgloss.JoinHorizontal(lipgloss.Top, leftView, rightView))
|
b.WriteString(lipgloss.JoinHorizontal(lipgloss.Top, leftView, rightView))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user