okami.mom/albedo

git clone https://git.nkp.pet/okami.mom/albedo

dawntui: replace the generic /quota page with a screen of latest limits, bars and per-limit trails8e3e173

main
4.3 KiB143 linesraw
1package tui
2
3import (
4	"albedo/cli/internal/daemon"
5
6	tea "charm.land/bubbletea/v2"
7)
8
9func (m *AppModel) initScreen() tea.Cmd {
10	switch m.State {
11	case AppStateChat:
12		return tea.Batch(m.Chat.Init(), m.loadCommandCatalogCmd(m.CatalogGen), m.recordOpenCmd(m.ActiveSession.ID))
13	case AppStateLogin:
14		return m.Login.initWithProfiles(m.Profiles)
15	case AppStateSessionPicker:
16		return tea.Batch(m.SessionPicker.Init(), m.SessionPicker.PreviewCmd())
17	}
18	return nil
19}
20
21func (m *AppModel) returnToChat() tea.Cmd {
22	if m.Chat.SessionID != m.ActiveSession.ID {
23		return tea.Batch(m.setChatSession(*m.ActiveSession, false), m.recordOpenCmd(m.ActiveSession.ID))
24	}
25	m.State = AppStateChat
26	return nil
27}
28
29func (m *AppModel) openLogin(name string) tea.Cmd {
30	previous := m.Login.Close()
31	m.Login = NewLoginModel(m.Conn, name, m.openBrowser)
32	m.Login.SetSize(m.Width, m.Height)
33	m.State = AppStateLogin
34	return tea.Batch(previous, m.Login.Init())
35}
36
37func (m *AppModel) openSessions() tea.Cmd {
38	m.State = AppStateSessionPicker
39	m.SessionGen++
40	return tea.Batch(m.SessionPicker.Init(), m.loadSessionsCmd(m.SessionGen), m.refreshSettingsCmd())
41}
42
43type screen interface {
44	SetSize(int, int)
45	Init() tea.Cmd
46}
47
48func (m *AppModel) openScreen(state AppState, s screen) tea.Cmd {
49	s.SetSize(m.Width, m.Height)
50	m.State = state
51	return s.Init()
52}
53
54func (m *AppModel) openModelPicker() tea.Cmd {
55	if m.ActiveSession == nil {
56		return nil
57	}
58	m.ModelPicker.Close()
59	m.ModelPicker = NewModelPickerModel(m.Conn, m.Profiles, m.ActiveSession.Model, m.ActiveSession.Provider, m.ActiveSession.Effort)
60	return m.openScreen(AppStateModelPicker, &m.ModelPicker)
61}
62
63func (m *AppModel) openExtensionPicker() tea.Cmd {
64	if m.ActiveSession == nil {
65		return nil
66	}
67	m.ExtensionPicker = NewExtensionPickerModel(m.Conn, m.ActiveSession.ID)
68	return m.openScreen(AppStateExtensionPicker, &m.ExtensionPicker)
69}
70
71func (m *AppModel) openTreePicker() tea.Cmd {
72	if m.ActiveSession == nil {
73		return nil
74	}
75	m.TreePicker = NewTreePickerModel(m.Conn, m.ActiveSession.ID)
76	return m.openScreen(AppStateTreePicker, &m.TreePicker)
77}
78
79func (m *AppModel) openQuota() tea.Cmd {
80	m.Quota = NewQuotaModel(m.Conn)
81	return m.openScreen(AppStateQuota, &m.Quota)
82}
83
84func (m *AppModel) openContextInspector() tea.Cmd {
85	if m.ActiveSession == nil {
86		return nil
87	}
88	m.ContextInspector = NewContextInspectorModel(m.Conn, m.ActiveSession.ID)
89	return m.openScreen(AppStateContextInspector, &m.ContextInspector)
90}
91
92// openFolderPicker offers the session another folder; a retry is the turn
93// its missing folder refused.
94func (m *AppModel) openFolderPicker(retry *WorkspaceRetry) tea.Cmd {
95	if m.ActiveSession == nil {
96		return nil
97	}
98	m.FolderPicker.Close()
99	m.FolderPicker = NewFolderPicker(daemonFolders{conn: m.Conn, condition: daemon.SessionCondition{ETag: m.ActiveSession.ETag, FamilyRevision: m.ActiveSession.FamilyRevision}}, *m.ActiveSession, retry)
100	m.folderReturn = AppStateChat
101	return m.openScreen(AppStateFolderPicker, &m.FolderPicker)
102}
103
104// openFolderBrowser lists sessions by folder, from the sessions view.
105func (m *AppModel) openFolderBrowser(query string) tea.Cmd {
106	m.FolderPicker.Close()
107	m.FolderPicker = NewFolderBrowser(daemonFolders{conn: m.Conn}, m.Workspace, query)
108	m.folderReturn = AppStateSessionPicker
109	return m.openScreen(AppStateFolderPicker, &m.FolderPicker)
110}
111
112// moved takes the daemon's answer to moving the session on screen.
113func (m *AppModel) moved(msg FolderMovedMsg) tea.Cmd {
114	if m.ActiveSession == nil || msg.SessionID != m.ActiveSession.ID {
115		return nil
116	}
117	if msg.Err != nil {
118		if m.State == AppStateFolderPicker {
119			m.FolderPicker.Refused(msg.Err)
120		} else {
121			m.AddError(operationError(msg.Err, "Could not move this session: ", "Session may have moved; check its folder before trying again."))
122		}
123		return nil
124	}
125	if msg.Session != nil && msg.Session.ETag != "" {
126		captured := *msg.Session
127		m.ActiveSession = &captured
128	}
129	m.ActiveSession.Workspace, m.ActiveSession.Location, m.Workspace = msg.Workspace, msg.Location, msg.Workspace
130	m.updateSession(*m.ActiveSession)
131	m.State = AppStateChat
132	return m.Chat.Moved(*m.ActiveSession, msg.Retry)
133}
134
135// Close releases this application's reads and subscriptions. Shared daemon
136// work and admitted mutations continue independently of the terminal.
137func (m *AppModel) Close() tea.Cmd {
138	m.Chat.Close()
139	m.Agents.Close()
140	m.ModelPicker.Close()
141	m.FolderPicker.Close()
142	return m.Login.Close()
143}