Files
2026-10-31 18:32:28 +01:00

176 lines
4.0 KiB
Go

package ui
import (
"strings"
"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
)
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
// 1. Manejo especial cuando el Registry está caído (StateRegistryDown)
if m.state == StateRegistryDown {
if keyMsg, ok := msg.(tea.KeyMsg); ok {
switch keyMsg.String() {
case "enter", "L", "l":
m.state = StateLoading
m.mode = ModeLocal
m.statusMsg = ""
return m, fetchLocalImagesCmd(m.client)
case "q", "ctrl+c", "CTRL+C":
return m, tea.Quit
}
}
return m, nil
}
switch msg := msg.(type) {
case tea.KeyMsg:
if m.state == StateNewTag {
switch msg.String() {
case "esc":
m.state = StateMainTable
m.textInput.Reset()
return m, nil
case "enter":
inputVal := m.textInput.Value()
if inputVal != "" {
lastColon := strings.LastIndex(inputVal, ":")
var destRepo, destTag string
if lastColon != -1 {
destRepo = inputVal[:lastColon]
destTag = inputVal[lastColon+1:]
} else {
destRepo = inputVal
destTag = "latest"
}
if destRepo != "" && destTag != "" {
selectedRow := m.rows[m.cursor]
m.state = StateLoading
m.textInput.Reset()
if m.mode == ModeLocal {
return m, tagLocalImageCmd(m.client, selectedRow.RepoName, selectedRow.Tag, destRepo, destTag)
}
return m, copyImageCmd(m.client, selectedRow.RepoName, selectedRow.Tag, destRepo, destTag)
}
}
return m, nil
}
var cmd tea.Cmd
m.textInput, cmd = m.textInput.Update(msg)
return m, cmd
}
switch msg.String() {
case "ctrl+c", "q":
if m.state == StateConfirmDelete {
m.state = StateMainTable
return m, nil
}
return m, tea.Quit
case "up", "k":
if m.cursor > 0 {
m.cursor--
}
case "down", "j":
if m.cursor < len(m.rows)-1 {
m.cursor++
}
case "r":
if m.state == StateMainTable && m.mode != ModeRegistry {
m.state = StateLoading
m.cursor = 0
m.statusMsg = ""
m.mode = ModeRegistry
return m, fetchRegistryImagesCmd(m.client)
}
case "l":
if m.state == StateMainTable && m.mode != ModeLocal {
m.state = StateLoading
m.cursor = 0
m.statusMsg = ""
m.mode = ModeLocal
return m, fetchLocalImagesCmd(m.client)
}
case "d":
if m.state == StateMainTable && len(m.rows) > 0 {
m.state = StateConfirmDelete
}
case "t":
if m.state == StateMainTable && len(m.rows) > 0 {
m.state = StateNewTag
m.textInput.Focus()
return m, textinput.Blink
}
case "p":
if m.state == StateMainTable && m.mode == ModeLocal && len(m.rows) > 0 {
selectedRow := m.rows[m.cursor]
m.state = StateLoading
return m, pushImageCmd(m.client, selectedRow.RepoName, selectedRow.Tag)
}
case "y":
if m.state == StateConfirmDelete {
selectedRow := m.rows[m.cursor]
m.state = StateLoading
if m.mode == ModeLocal {
return m, deleteLocalImageCmd(m.client, selectedRow.RepoName, selectedRow.Tag)
}
return m, deleteTagCmd(m.client, selectedRow.RepoName, selectedRow.Tag)
}
case "n":
if m.state == StateConfirmDelete {
m.state = StateMainTable
}
}
case imagesMsg:
m.rows = msg.rows
if msg.mode == ModeRegistry {
m.registryRows = msg.rows
} else {
m.localRows = msg.rows
}
m.state = StateMainTable
m.cursor = 0
case successMsg:
m.statusMsg = string(msg)
m.state = StateLoading
if m.mode == ModeRegistry {
return m, fetchRegistryImagesCmd(m.client)
} else {
return m, fetchLocalImagesCmd(m.client)
}
case errorMsg:
errVal := error(msg)
errMsgStr := errVal.Error()
// Comprobamos si el error es de conexión con el registro
if strings.Contains(errMsgStr, "connection refused") ||
strings.Contains(errMsgStr, "dial tcp") ||
strings.Contains(errMsgStr, "Get \"http://localhost:5000") {
m.state = StateRegistryDown
m.statusMsg = errMsgStr
return m, nil
}
// Error estándar para otros casos
m.err = errVal
m.state = StateError
return m, nil
}
return m, nil
}