summaryrefslogtreecommitdiff
path: root/menu/model.go
blob: ceeb86183207b65ab0a29a9cbb6e8e70a3f1b23c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package menu

import (
	tea "github.com/charmbracelet/bubbletea"
	"pik/model"
	"pik/spool"
)

type Model struct {
	*model.HydratedState
	Index         int
	Indices       map[int]model.HydratedTarget
	SourceIndices map[int]*model.HydratedSource
}

func (m *Model) Init() tea.Cmd {
	return nil
}

func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
	var err error
	var result tea.Cmd
	switch mt := msg.(type) {
	case tea.KeyMsg:
		result, err = m.HandleInput(mt)
	case tea.Cmd:
		result, err = m.HandleSignal(mt)
	}
	if err != nil {
		spool.Warn("%v\n", err)
	}
	return m, result
}

func (m *Model) HandleInput(msg tea.KeyMsg) (tea.Cmd, error) {
	var cmd tea.Cmd
	switch msg.String() {
	case "up", "k":
		m.Index--
	case "down", "j":
		m.Index++
	case "q", "esc":
		cmd = tea.Quit
	case "space", " ", "enter":
		cmd = tea.Quit
	}

	m.Validate()

	return cmd, nil
}

func (m *Model) HandleSignal(cmd tea.Cmd) (tea.Cmd, error) {
	return nil, nil
}

func (m *Model) View() string {
	return m.State(m.HydratedState)
}

func (m *Model) Result() (*model.HydratedSource, model.HydratedTarget) {
	return m.SourceIndices[m.Index], m.Indices[m.Index]
}

func (m *Model) Validate() {
	if m.Index < 0 {
		m.Index = 0
	}
	if m.Index > len(m.Indices)-1 {
		m.Index = len(m.Indices) - 1
	}
}

func NewModel(st *model.State, hydrators []model.Hydrator) *Model {
	m := &Model{
		HydratedState: Hydrate(st, hydrators),
		Index:         0,
		Indices:       make(map[int]model.HydratedTarget),
		SourceIndices: make(map[int]*model.HydratedSource),
	}
	idx := 0
	for _, src := range st.Sources {
		hydSrc := src.Hydrate(hydrators)
		for _, target := range src.Targets {

			if !target.Visible() {
				continue
			}

			hydTarget, err := target.Hydrate(src)
			m.Indices[idx] = hydTarget
			if err != nil {
				spool.Warn("%v\n", err)
			}
			m.SourceIndices[idx] = hydSrc

			idx++
		}
	}
	return m
}