- commit
- b3374e6
- parent
- 6886a8e
- author
- Eric Bower
- date
- 2024-12-17 16:47:02 +0000 UTC
refactor(tui): chat page to describe how it works with senpai We also notify the user that chat is pico+ only
5 files changed,
+96,
-3
+4,
-0
1@@ -270,6 +270,10 @@ services:
2 volumes:
3 - ./data/storage/data:/app/.storage
4 - ./data/pgs-ssh/data:/app/ssh_data
5+ deploy:
6+ resources:
7+ limits:
8+ memory: 3g
9 pgs-ssh:
10 networks:
11 pgs:
+84,
-0
1@@ -0,0 +1,84 @@
2+package chat
3+
4+import (
5+ tea "github.com/charmbracelet/bubbletea"
6+ "github.com/picosh/pico/tui/common"
7+ "github.com/picosh/pico/tui/pages"
8+)
9+
10+var maxWidth = 55
11+
12+type focus int
13+
14+const (
15+ focusNone = iota
16+ focusChat
17+)
18+
19+type Model struct {
20+ shared *common.SharedModel
21+ focus focus
22+}
23+
24+func NewModel(shrd *common.SharedModel) Model {
25+ return Model{
26+ shared: shrd,
27+ focus: focusChat,
28+ }
29+}
30+
31+func (m Model) Init() tea.Cmd {
32+ return nil
33+}
34+
35+func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
36+ switch msg := msg.(type) {
37+ case tea.KeyMsg:
38+ switch msg.String() {
39+ case "q", "esc":
40+ return m, pages.Navigate(pages.MenuPage)
41+ case "tab":
42+ if m.focus == focusNone {
43+ m.focus = focusChat
44+ } else {
45+ m.focus = focusNone
46+ }
47+ case "enter":
48+ if m.focus == focusChat {
49+ return m, m.gotoChat()
50+ }
51+ }
52+ }
53+ return m, nil
54+}
55+
56+func (m Model) View() string {
57+ return m.analyticsView()
58+}
59+
60+func (m Model) analyticsView() string {
61+ banner := `We provide a managed IRC bouncer for pico+ users. When you click the button we will open our TUI chat with your user authenticated automatically.
62+
63+If you haven't configured your pico+ account with our IRC bouncer, the guide is here:
64+
65+ https://pico.sh/bouncer
66+
67+If you want to quickly chat with us on IRC without pico+, go to the web chat:
68+
69+ https://web.libera.chat/gamja?autojoin=#pico.sh`
70+
71+ str := ""
72+ hasPlus := m.shared.PlusFeatureFlag != nil
73+ if hasPlus {
74+ hasFocus := m.focus == focusChat
75+ str += banner + "\n\nLet's Chat! " + common.OKButtonView(m.shared.Styles, hasFocus, true)
76+ } else {
77+ str += banner + "\n\n" + m.shared.Styles.Error.SetString("Our IRC Bouncer is only available to pico+ users.").String()
78+ }
79+
80+ return m.shared.Styles.RoundedBorder.Width(maxWidth).SetString(str).String()
81+}
82+
83+func (m Model) gotoChat() tea.Cmd {
84+ return LoadChat(m.shared)
85+}
R tui/senpai.go =>
tui/chat/senpai.go
+1,
-1
1@@ -1,4 +1,4 @@
2-package tui
3+package chat
4
5 import (
6 "io"
+3,
-0
1@@ -16,6 +16,7 @@ const (
2 SettingsPage
3 LogsPage
4 AnalyticsPage
5+ ChatPage
6 )
7
8 type NavigateMsg struct{ Page }
9@@ -50,6 +51,8 @@ func ToTitle(page Page) string {
10 return "logs"
11 case AnalyticsPage:
12 return "analytics"
13+ case ChatPage:
14+ return "chat"
15 }
16
17 return ""
+4,
-2
1@@ -9,6 +9,7 @@ import (
2 "github.com/muesli/reflow/wordwrap"
3 "github.com/muesli/reflow/wrap"
4 "github.com/picosh/pico/tui/analytics"
5+ "github.com/picosh/pico/tui/chat"
6 "github.com/picosh/pico/tui/common"
7 "github.com/picosh/pico/tui/createaccount"
8 "github.com/picosh/pico/tui/createkey"
9@@ -43,7 +44,7 @@ func NewUI(shared *common.SharedModel) *UI {
10 m := &UI{
11 shared: shared,
12 state: initState,
13- pages: make([]tea.Model, 11),
14+ pages: make([]tea.Model, 12),
15 }
16 return m
17 }
18@@ -86,6 +87,7 @@ func (m *UI) Init() tea.Cmd {
19 m.pages[pages.SettingsPage] = settings.NewModel(m.shared)
20 m.pages[pages.LogsPage] = logs.NewModel(m.shared)
21 m.pages[pages.AnalyticsPage] = analytics.NewModel(m.shared)
22+ m.pages[pages.ChatPage] = chat.NewModel(m.shared)
23 if m.shared.User == nil {
24 m.activePage = pages.CreateAccountPage
25 } else {
26@@ -153,7 +155,7 @@ func (m *UI) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
27 case menu.AnalyticsChoice:
28 m.activePage = pages.AnalyticsPage
29 case menu.ChatChoice:
30- return m, LoadChat(m.shared)
31+ m.activePage = pages.ChatPage
32 case menu.ExitChoice:
33 m.shared.Dbpool.Close()
34 return m, tea.Quit