feat: responsive TUI layout — mobile/tablet/desktop support

- NEW responsive.go: wrapFooter, adaptiveSidePad, clampWidth, truncateStr
- Footer auto-wraps to multi-line on narrow terminals (full labels preserved)
- Box width clamped to terminal width across all tabs
- Host/key/snippet rows truncated with ellipsis; compact format <35 cols
- SFTP panes stack vertically when terminal < 50 cols
- Tab bar truncates names on overflow
- Form contentW minimum lowered 50->30 for mobile
- Fixed: key_list_tab & snippet_list_tab dropped last data row (off-by-one bug)
This commit is contained in:
swanadiva
2026-06-23 19:08:44 +07:00
parent d359688b75
commit d75621e9b4
11 changed files with 302 additions and 113 deletions
+25 -9
View File
@@ -540,21 +540,33 @@ func (t *SFTPBrowserTab) View() string {
SubtitleStyle.Render(fmt.Sprintf("Connecting SFTP to %s...", t.host.Name)))
}
halfW := t.width / 2
if halfW < 20 {
halfW = 20
// Responsive pane layout: stack vertically on narrow terminals
var leftView, rightView string
if t.width < 50 {
// Stack vertically — each pane gets full width
leftView = t.renderPane(&t.left, paneLocal, t.width)
rightView = t.renderPane(&t.right, paneRemote, t.width)
} else {
// Side by side — each pane gets half width
halfW := t.width / 2
if halfW < 20 {
halfW = 20
}
leftView = t.renderPane(&t.left, paneLocal, halfW)
rightView = t.renderPane(&t.right, paneRemote, halfW)
}
leftView := t.renderPane(&t.left, paneLocal, halfW)
rightView := t.renderPane(&t.right, paneRemote, halfW)
var b strings.Builder
b.WriteString(lipgloss.PlaceHorizontal(t.width, lipgloss.Center,
AppTitleStyle.Render(fmt.Sprintf("SFTP: %s@%s", t.host.Username, t.host.Hostname))))
b.WriteString("\n")
b.WriteString(lipgloss.JoinHorizontal(lipgloss.Top, leftView, rightView))
if t.width < 50 {
b.WriteString(lipgloss.JoinVertical(lipgloss.Left, leftView, rightView))
} else {
b.WriteString(lipgloss.JoinHorizontal(lipgloss.Top, leftView, rightView))
}
if t.err != nil {
b.WriteString("\n" + lipgloss.PlaceHorizontal(t.width, lipgloss.Center,
@@ -566,8 +578,12 @@ func (t *SFTPBrowserTab) View() string {
InfoStyle.Render(t.transferMsg)))
}
b.WriteString("\n" + lipgloss.PlaceHorizontal(t.width, lipgloss.Center,
SubtitleStyle.Render("Ctrl+Tab:switch Ctrl+Q:close Tab:pane ↑↓:nav Enter/→:open ←/Backspace:up /:filter C:copy D:delete N:mkdir R:refresh Esc:close")))
// Footer (wrapped to terminal width)
footerText := "Ctrl+Tab:switch Ctrl+Q:close Tab:pane ↑↓:nav Enter/→:open ←/Backspace:up /:filter C:copy D:delete N:mkdir R:refresh Esc:close"
footerWrapped := wrapFooter(footerText, t.width)
for _, line := range strings.Split(footerWrapped, "\n") {
b.WriteString("\n" + lipgloss.PlaceHorizontal(t.width, lipgloss.Center, SubtitleStyle.Render(line)))
}
return b.String()
}