feat: clear screen on SSH enter/exit, host list scrolling, 'e' edit key
- tea.Batch(tea.ClearScreen, sshConnectCmd) before SSH starts so TUI output doesn't bleed into SSH terminal - tea.ClearScreen after SSH exits so SSH output doesn't ghost in TUI - Host list now paginates: only (term_height - 8) / 5 cards shown, viewport follows selectedIndex with centered scrolling - Shows 'N of M hosts' indicator when content is clipped - Added 'e' key alias for editing host (Ctrl+E or E)
This commit is contained in:
@@ -68,7 +68,7 @@ func (t *HostListTab) Update(msg tea.Msg) (Tab, tea.Cmd) {
|
|||||||
return openHostFormMsg{}
|
return openHostFormMsg{}
|
||||||
}
|
}
|
||||||
|
|
||||||
case "ctrl+e":
|
case "ctrl+e", "e":
|
||||||
if len(t.hosts) > 0 {
|
if len(t.hosts) > 0 {
|
||||||
host := t.hosts[t.selectedIndex]
|
host := t.hosts[t.selectedIndex]
|
||||||
return t, func() tea.Msg {
|
return t, func() tea.Msg {
|
||||||
@@ -139,15 +139,39 @@ func (t *HostListTab) View() string {
|
|||||||
b.WriteString(centerText(SubtitleStyle.Render("No hosts found. Add with Ctrl+N"), availW))
|
b.WriteString(centerText(SubtitleStyle.Render("No hosts found. Add with Ctrl+N"), availW))
|
||||||
b.WriteString("\n")
|
b.WriteString("\n")
|
||||||
} else {
|
} else {
|
||||||
for i, host := range t.hosts {
|
// Scrolling: show only what fits on screen
|
||||||
|
cardH := 5 // 4 lines per card + 1 blank separator
|
||||||
|
maxCards := (t.height - 8) / cardH
|
||||||
|
if maxCards < 1 {
|
||||||
|
maxCards = 1
|
||||||
|
}
|
||||||
|
if maxCards > len(t.hosts) {
|
||||||
|
maxCards = len(t.hosts)
|
||||||
|
}
|
||||||
|
|
||||||
|
start := t.selectedIndex - maxCards/2
|
||||||
|
if start < 0 {
|
||||||
|
start = 0
|
||||||
|
}
|
||||||
|
if start+maxCards > len(t.hosts) {
|
||||||
|
start = len(t.hosts) - maxCards
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := start; i < start+maxCards; i++ {
|
||||||
|
host := t.hosts[i]
|
||||||
entry := renderHostEntry(host, i == t.selectedIndex, cardW)
|
entry := renderHostEntry(host, i == t.selectedIndex, cardW)
|
||||||
// Center the card (which produces 4 lines) horizontally
|
|
||||||
for _, line := range strings.Split(entry, "\n") {
|
for _, line := range strings.Split(entry, "\n") {
|
||||||
b.WriteString(centerText(line, availW))
|
b.WriteString(centerText(line, availW))
|
||||||
b.WriteString("\n")
|
b.WriteString("\n")
|
||||||
}
|
}
|
||||||
b.WriteString("\n")
|
b.WriteString("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if maxCards < len(t.hosts) {
|
||||||
|
b.WriteString(centerText(
|
||||||
|
SubtitleStyle.Render(fmt.Sprintf("%d of %d hosts", start+1, len(t.hosts))),
|
||||||
|
availW))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.String()
|
return b.String()
|
||||||
|
|||||||
+2
-2
@@ -62,13 +62,13 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
return m, tea.Quit
|
return m, tea.Quit
|
||||||
|
|
||||||
case sshConnectToMsg:
|
case sshConnectToMsg:
|
||||||
return m, sshConnectCmd(msg.host, m.dataDir)
|
return m, tea.Batch(tea.ClearScreen, sshConnectCmd(msg.host, m.dataDir))
|
||||||
|
|
||||||
case sshExitMsg:
|
case sshExitMsg:
|
||||||
if msg.err != nil {
|
if msg.err != nil {
|
||||||
m.Error = msg.err
|
m.Error = msg.err
|
||||||
}
|
}
|
||||||
return m, nil
|
return m, tea.ClearScreen
|
||||||
|
|
||||||
case openHostFormMsg:
|
case openHostFormMsg:
|
||||||
var tab Tab
|
var tab Tab
|
||||||
|
|||||||
Reference in New Issue
Block a user