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
}
|