This commit is contained in:
1 parent
fa7446e5f7
commit
79c0027833
8 files changed
+219
-61
No files matched your search
+57
-17
@@ -8,15 +8,15 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.zb-server.de/Sebi/ssh-netbox-wrapper/internal/notes"
|
||||
"github.com/charmbracelet/bubbles/list"
|
||||
"github.com/charmbracelet/bubbles/textarea"
|
||||
"github.com/charmbracelet/bubbles/textinput"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
"charm.land/bubbles/v2/list"
|
||||
"charm.land/bubbles/v2/textarea"
|
||||
"charm.land/bubbles/v2/textinput"
|
||||
tea "charm.land/bubbletea/v2"
|
||||
"charm.land/lipgloss/v2"
|
||||
|
||||
"git.zb-server.de/Sebi/ssh-netbox-wrapper/internal/cache"
|
||||
"git.zb-server.de/Sebi/ssh-netbox-wrapper/internal/netbox"
|
||||
"git.zb-server.de/Sebi/ssh-netbox-wrapper/internal/notes"
|
||||
)
|
||||
|
||||
// SelectedHost is returned when the user confirms a host in the TUI.
|
||||
@@ -78,7 +78,7 @@ func (d compactDelegate) Render(w io.Writer, m list.Model, index int, item list.
|
||||
if index == m.Index() {
|
||||
line = lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("86")).Render("> " + strings.TrimPrefix(line, " "))
|
||||
}
|
||||
fmt.Fprintln(w, line)
|
||||
fmt.Fprint(w, line)
|
||||
}
|
||||
|
||||
// --- filter ---
|
||||
@@ -221,6 +221,7 @@ func (m *Model) loadRecent() tea.Cmd {
|
||||
}
|
||||
|
||||
func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
defer m.resizeList()
|
||||
switch msg := msg.(type) {
|
||||
case noteResultMsg:
|
||||
m.noteBusy = false
|
||||
@@ -240,18 +241,13 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
case tea.WindowSizeMsg:
|
||||
m.width = msg.Width
|
||||
m.height = msg.Height
|
||||
extraRows := 4
|
||||
if m.filterOpen {
|
||||
extraRows++
|
||||
}
|
||||
if m.editMode {
|
||||
extraRows += 2
|
||||
}
|
||||
m.list.SetSize(msg.Width, max(1, msg.Height-extraRows))
|
||||
m.input.SetWidth(max(1, msg.Width-lipgloss.Width(m.input.Prompt)))
|
||||
m.filterInput.SetWidth(max(1, msg.Width-lipgloss.Width(m.filterInput.Prompt)))
|
||||
m.editInput.SetWidth(max(1, msg.Width-lipgloss.Width("Connect as: ")))
|
||||
m.noteInput.SetWidth(max(10, msg.Width-4))
|
||||
return m, nil
|
||||
|
||||
case tea.KeyMsg:
|
||||
case tea.KeyPressMsg:
|
||||
if msg.String() == "ctrl+c" {
|
||||
return m, tea.Quit
|
||||
}
|
||||
@@ -427,10 +423,26 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
}
|
||||
|
||||
if m.noteMode {
|
||||
if m.noteBusy {
|
||||
return m, nil
|
||||
}
|
||||
var cmd tea.Cmd
|
||||
m.noteInput, cmd = m.noteInput.Update(msg)
|
||||
return m, cmd
|
||||
}
|
||||
// Paste and cursor events are separate from key presses in Bubble Tea v2.
|
||||
// Route them to the focused editor as well.
|
||||
if m.editMode {
|
||||
var cmd tea.Cmd
|
||||
m.editInput, cmd = m.editInput.Update(msg)
|
||||
return m, cmd
|
||||
}
|
||||
if m.filterOpen {
|
||||
var cmd tea.Cmd
|
||||
m.filterInput, cmd = m.filterInput.Update(msg)
|
||||
m.updateListItems(m.lastResults)
|
||||
return m, cmd
|
||||
}
|
||||
// Forward to search input and restart debounce timer.
|
||||
var cmds []tea.Cmd
|
||||
var inputCmd tea.Cmd
|
||||
@@ -449,7 +461,13 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
return m, tea.Batch(cmds...)
|
||||
}
|
||||
|
||||
func (m *Model) View() string {
|
||||
func (m *Model) View() tea.View {
|
||||
view := tea.NewView(m.viewContent())
|
||||
view.AltScreen = true
|
||||
return view
|
||||
}
|
||||
|
||||
func (m *Model) viewContent() string {
|
||||
if m.noteMode {
|
||||
target := "local"
|
||||
if m.noteRemote {
|
||||
@@ -562,6 +580,28 @@ func (m *Model) updateListItems(entries []netbox.HostEntry) {
|
||||
items[i] = hostItem{id: e.ID, name: e.Name, ip: ip, kind: e.Kind, tags: e.Tags}
|
||||
}
|
||||
m.list.SetItems(items)
|
||||
m.resizeList()
|
||||
}
|
||||
|
||||
// resizeList keeps the footer visible when the recent heading or editors change.
|
||||
func (m *Model) resizeList() {
|
||||
if m.width <= 0 || m.height <= 0 {
|
||||
return
|
||||
}
|
||||
extraRows := 5 // title, blank line, search, footer separator, footer
|
||||
if m.recentMode && m.input.Value() == "" && len(m.list.Items()) > 0 {
|
||||
extraRows++
|
||||
}
|
||||
if m.filterOpen {
|
||||
extraRows++
|
||||
}
|
||||
if m.editMode {
|
||||
extraRows++
|
||||
}
|
||||
height := max(1, m.height-extraRows)
|
||||
if m.list.Width() != m.width || m.list.Height() != height {
|
||||
m.list.SetSize(m.width, height)
|
||||
}
|
||||
}
|
||||
|
||||
// openEdit switches to edit mode for the given list item.
|
||||
|
||||
Reference in new issue
Block a user