Gitfed
bastien-mrq/gitfed / cmd / gitfed-ctl / keys.go
package main

import tea "github.com/charmbracelet/bubbletea"

func (m model) handleKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
	switch msg.String() {
	case "ctrl+c":
		m.cancel()
		m.quitting = true
		return m, tea.Quit
	}

	switch m.screen {
	case screenDashboard:
		return m.handleDashboardKey(msg)
	case screenUpdatesCheck:
		return m.handleUpdatesCheckKey(msg)
	case screenUpdatesAckBreaking:
		return m.handleAckBreakingKey(msg)
	case screenUpdatesConfirm:
		return m.handleConfirmKey(msg)
	case screenUpdatesRunning:
		return m.handleRunningKey(msg)
	case screenUpdatesSuccess:
		return m.handleSuccessKey(msg)
	}
	return m, nil
}

func (m model) handleDashboardKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
	switch msg.String() {
	case "q":
		m.quitting = true
		return m, tea.Quit
	case "r":
		if !m.healthChecking {
			m.healthChecking = true
			return m, tea.Batch(m.cmdCheckHealth(), listen(m.msgCh))
		}
	case "f":
		if !m.kubectlOK && m.k3sYAMLPresent && !m.fixing {
			m.fixing = true
			m.fixErr = nil
			return m, tea.Batch(m.cmdFixKubeconfig(), listen(m.msgCh))
		}
	case "enter":
		m.screen = screenUpdatesCheck
		m.checking = true
		m.checked = false
		m.checkErr = nil
		return m, tea.Batch(m.cmdCheckUpdates(), listen(m.msgCh))
	}
	return m, nil
}

func (m model) handleUpdatesCheckKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
	switch msg.String() {
	case "q", "esc":
		m.screen = screenDashboard
		return m, nil
	case "r":
		if m.checked && m.checkErr != nil {
			m.checking = true
			m.checked = false
			return m, tea.Batch(m.cmdCheckUpdates(), listen(m.msgCh))
		}
	case "enter":
		if m.checked && m.checkErr == nil && m.upToDate {
			m.screen = screenDashboard
		}
	}
	return m, nil
}

func (m model) handleAckBreakingKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
	switch msg.String() {
	case "q", "esc":
		m.screen = screenDashboard
		return m, nil
	case "up", "k":
		if m.ackCursor > 0 {
			m.ackCursor--
		}
	case "down", "j":
		if m.ackCursor < len(m.ackChecklist)-1 {
			m.ackCursor++
		}
	case " ", "x":
		if m.ackCursor < len(m.ackChecklist) {
			m.ackChecklist[m.ackCursor] = !m.ackChecklist[m.ackCursor]
		}
	case "enter":
		if allAcked(m.ackChecklist) {
			m.screen = screenUpdatesConfirm
		}
	}
	return m, nil
}

func allAcked(checklist []bool) bool {
	if len(checklist) == 0 {
		return false
	}
	for _, ok := range checklist {
		if !ok {
			return false
		}
	}
	return true
}

func (m model) handleConfirmKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
	switch msg.String() {
	case "q", "esc":
		m.screen = screenDashboard
		return m, nil
	case " ", "b":
		m.backupToggle = !m.backupToggle
	case "enter":
		m.screen = screenUpdatesRunning
		m.backupStep = pipelineStepStatus{}
		m.pullStep = pipelineStepStatus{}
		m.buildStep = pipelineStepStatus{}
		m.importStep = pipelineStepStatus{}
		m.applyStep = pipelineStepStatus{}
		m.rolloutStep = pipelineStepStatus{}
		m.stepLogs = make(map[string][]string)
		m.pipelineErr = nil
		return m, tea.Batch(m.cmdRunPipeline(), listen(m.msgCh))
	}
	return m, nil
}

func (m model) handleRunningKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
	if msg.String() == "q" && m.pipelineErr != nil {
		m.quitting = true
		return m, tea.Quit
	}
	return m, nil
}

func (m model) handleSuccessKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
	switch msg.String() {
	case "enter":
		m.screen = screenDashboard
		m.healthChecking = true
		m.checked = false
		return m, tea.Batch(m.cmdCheckHealth(), listen(m.msgCh))
	case "q":
		m.quitting = true
		return m, tea.Quit
	}
	return m, nil
}