okami.mom/albedo

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

dawntui: sessions and folders fuzzy filter, shared confirm and footers10e0f66

main
3.0 KiB62 linesraw
1// The folder picker in every state a person sees, for the shot gallery. A
2// plain test run draws each state and writes nothing.
3package tui
4
5import (
6	"errors"
7
8	"albedo/cli/internal/daemon"
9
10	tea "charm.land/bubbletea/v2"
11)
12
13const shotHere = "/Users/dawn/proj/albedo"
14
15func init() {
16	session := daemon.Session{ID: "a", Workspace: shotHere}
17	right := tea.KeyPressMsg{Code: tea.KeyRight}
18	registerShots("folders",
19		shotState{"browse", folderShot(func() FolderPicker { return NewFolderBrowser(remoteFolders("ready", ""), shotHere, "") }, "", nil)},
20		shotState{"move-session", folderShot(func() FolderPicker { return NewFolderPicker(remoteFolders("ready", ""), session, nil) }, "", nil)},
21		shotState{"retry-missing", folderShot(func() FolderPicker {
22			return NewFolderPicker(remoteFolders("ready", ""), session, &WorkspaceRetry{Missing: "/Users/dawn/proj/gone", Prompt: "fix the bug"})
23		}, "", nil)},
24		shotState{"listing-host", folderShot(func() FolderPicker { return NewFolderBrowser(remoteFolders("ready", ""), shotHere, "") }, "chernobog:", nil)},
25		shotState{"hosts", folderShot(func() FolderPicker { return NewFolderBrowser(remoteFolders("ready", ""), shotHere, "") }, "@", nil)},
26		shotState{"listing-failed", folderShot(func() FolderPicker { return NewFolderBrowser(remoteFolders("ready", ""), shotHere, "") }, "/nowhere/", nil)},
27		shotState{"host-warming", folderShot(func() FolderPicker { return NewFolderBrowser(remoteFolders("warming", ""), shotHere, "") }, "cher", nil)},
28		shotState{"host-needs-sign-in", folderShot(func() FolderPicker {
29			return NewFolderBrowser(remoteFolders("needs_auth", "Permission denied (publickey)"), shotHere, "")
30		}, "cher", nil)},
31		shotState{"host-unreachable", folderShot(func() FolderPicker {
32			return NewFolderBrowser(remoteFolders("unreachable", "no route to host"), shotHere, "")
33		}, "cher", nil)},
34		shotState{"sessions-stepped", folderShot(func() FolderPicker { return NewFolderBrowser(remoteFolders("ready", ""), shotHere, "") }, "", func(m *FolderPicker) {
35			*m, _ = m.Update(right)
36		})},
37		shotState{"sessions-failed", folderShot(func() FolderPicker { return NewFolderBrowser(remoteFolders("ready", ""), shotHere, "") }, "", func(m *FolderPicker) {
38			m.sessionsError = "daemon did not answer"
39		})},
40		shotState{"notice", folderShot(func() FolderPicker { return NewFolderBrowser(remoteFolders("ready", ""), shotHere, "") }, "", func(m *FolderPicker) {
41			m.Refused(errors.New("chernobog: connection refused"))
42		})},
43		shotState{"moving", folderShot(func() FolderPicker { return NewFolderPicker(remoteFolders("ready", ""), session, nil) }, "", func(m *FolderPicker) {
44			m.moving = true
45		})},
46	)
47}
48
49// folderShot draws the picker built by build, after the first listing has
50// settled, then typed query, then setup.
51func folderShot(build func() FolderPicker, query string, setup func(*FolderPicker)) func(width, height int) string {
52	return func(width, height int) string {
53		m := build()
54		m.SetSize(width, height)
55		m = drainPicker(m, m.Init())
56		m = typeText(m, query)
57		if setup != nil {
58			setup(&m)
59		}
60		return m.View()
61	}
62}