1package tui
2
3import (
4 "github.com/charmbracelet/bubbles/key"
5 tea "github.com/charmbracelet/bubbletea"
6 "github.com/kujtimiihoxha/termai/internal/tui/layout"
7 "github.com/kujtimiihoxha/termai/internal/tui/page"
8)
9
10type keyMap struct {
11 Logs key.Binding
12 Back key.Binding
13 Quit key.Binding
14}
15
16var keys = keyMap{
17 Logs: key.NewBinding(
18 key.WithKeys("L"),
19 key.WithHelp("L", "logs"),
20 ),
21 Back: key.NewBinding(
22 key.WithKeys("esc"),
23 key.WithHelp("esc", "back"),
24 ),
25 Quit: key.NewBinding(
26 key.WithKeys("ctrl+c", "q"),
27 key.WithHelp("ctrl+c/q", "quit"),
28 ),
29}
30
31type appModel struct {
32 width, height int
33 currentPage page.PageID
34 previousPage page.PageID
35 pages map[page.PageID]tea.Model
36 loadedPages map[page.PageID]bool
37}
38
39func (a appModel) Init() tea.Cmd {
40 cmd := a.pages[a.currentPage].Init()
41 a.loadedPages[a.currentPage] = true
42 return cmd
43}
44
45func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
46 switch msg := msg.(type) {
47 case tea.WindowSizeMsg:
48 a.width, a.height = msg.Width, msg.Height
49 case tea.KeyMsg:
50 if key.Matches(msg, keys.Quit) {
51 return a, tea.Quit
52 }
53 if key.Matches(msg, keys.Back) {
54 if a.previousPage != "" {
55 return a, a.moveToPage(a.previousPage)
56 }
57 return a, nil
58 }
59 if key.Matches(msg, keys.Logs) {
60 return a, a.moveToPage(page.LogsPage)
61 }
62 }
63 p, cmd := a.pages[a.currentPage].Update(msg)
64 if p != nil {
65 a.pages[a.currentPage] = p
66 }
67 return a, cmd
68}
69
70func (a *appModel) moveToPage(pageID page.PageID) tea.Cmd {
71 var cmd tea.Cmd
72 if _, ok := a.loadedPages[pageID]; !ok {
73 cmd = a.pages[pageID].Init()
74 a.loadedPages[pageID] = true
75 }
76 a.previousPage = a.currentPage
77 a.currentPage = pageID
78 if sizable, ok := a.pages[a.currentPage].(layout.Sizeable); ok {
79 sizable.SetSize(a.width, a.height)
80 }
81
82 return cmd
83}
84
85func (a appModel) View() string {
86 return a.pages[a.currentPage].View()
87}
88
89func New() tea.Model {
90 return &appModel{
91 currentPage: page.ReplPage,
92 loadedPages: make(map[page.PageID]bool),
93 pages: map[page.PageID]tea.Model{
94 page.LogsPage: page.NewLogsPage(),
95 page.InitPage: page.NewInitPage(),
96 page.ReplPage: page.NewReplPage(),
97 },
98 }
99}