repos / pico

pico services - prose.sh, pastes.sh, imgs.sh, feeds.sh, pgs.sh
git clone https://github.com/picosh/pico.git

commit
4a82d8e
parent
50895e2
author
Eric Bower
date
2024-05-17 15:14:41 +0000 UTC
style: page titles
8 files changed,  +110, -62
M tui/common/model.go
+1, -0
1@@ -17,5 +17,6 @@ type SharedModel struct {
2 	PlusFeatureFlag *db.FeatureFlag
3 	Width           int
4 	Height          int
5+	HeaderHeight    int
6 	Styles          Styles
7 }
M tui/common/styles.go
+4, -4
 1@@ -51,6 +51,10 @@ func DefaultStyles(renderer *lipgloss.Renderer) Styles {
 2 	s.Cursor = renderer.NewStyle().Foreground(Fuschia)
 3 	s.Wrap = renderer.NewStyle().Width(58)
 4 	s.Paragraph = s.Wrap.Copy().Margin(1, 0, 0, 2)
 5+	s.Logo = renderer.NewStyle().
 6+		Foreground(Cream).
 7+		Background(Indigo).
 8+		Padding(0, 1)
 9 	s.Code = renderer.NewStyle().
10 		Foreground(Red).
11 		Background(DarkRed).
12@@ -71,10 +75,6 @@ func DefaultStyles(renderer *lipgloss.Renderer) Styles {
13 		PaddingRight(1).
14 		SetString("•")
15 	s.SelectedMenuItem = renderer.NewStyle().Foreground(Fuschia)
16-	s.Logo = renderer.NewStyle().
17-		Foreground(Cream).
18-		Background(Indigo).
19-		Padding(0, 1)
20 	s.BlurredButtonStyle = renderer.NewStyle().
21 		Foreground(Cream).
22 		Background(GreyLight).
M tui/notifications/notifications.go
+5, -7
 1@@ -17,9 +17,7 @@ func NotificationsView(dbpool db.DB, userID string) string {
 2 		return err.Error()
 3 	}
 4 	url := fmt.Sprintf("https://auth.pico.sh/rss/%s", pass)
 5-	md := fmt.Sprintf(`# Notifications
 6-
 7-We provide a special RSS feed for all pico users where we can send
 8+	md := fmt.Sprintf(`We provide a special RSS feed for all pico users where we can send
 9 user-specific notifications. This is where we will send pico+
10 expiration notices, among other alerts. To be clear, this is
11 optional but **highly** recommended.
12@@ -62,8 +60,8 @@ type Model struct {
13 	viewport viewport.Model
14 }
15 
16-func headerHeight(styles common.Styles) int {
17-	return 0
18+func headerHeight(shrd common.SharedModel) int {
19+	return shrd.HeaderHeight
20 }
21 
22 func headerWidth(w int) int {
23@@ -71,7 +69,7 @@ func headerWidth(w int) int {
24 }
25 
26 func NewModel(shared common.SharedModel) Model {
27-	hh := headerHeight(shared.Styles)
28+	hh := headerHeight(shared)
29 	viewport := viewport.New(headerWidth(shared.Width), shared.Height-hh)
30 	viewport.YPosition = hh
31 	if shared.User != nil {
32@@ -95,7 +93,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
33 	switch msg := msg.(type) {
34 	case tea.WindowSizeMsg:
35 		m.viewport.Width = headerWidth(m.shared.Width)
36-		hh := headerHeight(m.shared.Styles)
37+		hh := headerHeight(m.shared)
38 		m.viewport.Height = m.shared.Height - hh
39 
40 	case tea.KeyMsg:
M tui/pages/pages.go
+23, -0
 1@@ -22,3 +22,26 @@ func Navigate(page Page) tea.Cmd {
 2 		return NavigateMsg{page}
 3 	}
 4 }
 5+
 6+func ToTitle(page Page) string {
 7+	switch page {
 8+	case CreateAccountPage:
 9+		return "create account"
10+	case CreatePubkeyPage:
11+		return "add pubkey"
12+	case CreateTokenPage:
13+		return "new api token"
14+	case MenuPage:
15+		return "menu"
16+	case NotificationsPage:
17+		return "notifications"
18+	case PlusPage:
19+		return "pico+"
20+	case TokensPage:
21+		return "api tokens"
22+	case PubkeysPage:
23+		return "pubkeys"
24+	}
25+
26+	return ""
27+}
M tui/plus/plus.go
+5, -7
 1@@ -14,9 +14,7 @@ import (
 2 func PlusView(username string) string {
 3 	paymentLink := "https://auth.pico.sh/checkout"
 4 	url := fmt.Sprintf("%s/%s", paymentLink, url.QueryEscape(username))
 5-	md := fmt.Sprintf(`# pico+
 6-
 7-Signup to get premium access
 8+	md := fmt.Sprintf(`Signup to get premium access
 9 
10 ## $2/month (billed annually)
11 
12@@ -80,8 +78,8 @@ type Model struct {
13 	viewport viewport.Model
14 }
15 
16-func headerHeight(styles common.Styles) int {
17-	return 0
18+func headerHeight(shrd common.SharedModel) int {
19+	return shrd.HeaderHeight
20 }
21 
22 func headerWidth(w int) int {
23@@ -90,7 +88,7 @@ func headerWidth(w int) int {
24 
25 // NewModel returns a new username model in its initial state.
26 func NewModel(shared common.SharedModel) Model {
27-	hh := headerHeight(shared.Styles)
28+	hh := headerHeight(shared)
29 	viewport := viewport.New(headerWidth(shared.Width), shared.Height-hh)
30 	viewport.YPosition = hh
31 	if shared.User != nil {
32@@ -112,7 +110,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
33 	switch msg := msg.(type) {
34 	case tea.WindowSizeMsg:
35 		m.viewport.Width = headerWidth(m.shared.Width)
36-		hh := headerHeight(m.shared.Styles)
37+		hh := headerHeight(m.shared)
38 		m.viewport.Height = m.shared.Height - hh
39 	case tea.KeyMsg:
40 		switch msg.String() {
M tui/pubkeys/keyview.go
+1, -1
1@@ -93,7 +93,7 @@ func (m Model) newStyledKey(styles common.Styles, key *db.PublicKey, active bool
2 
3 	var note string
4 	if active {
5-		note = m.shared.Styles.Note.Render("• ") + m.shared.Styles.Note.Render("Current Key")
6+		note = m.shared.Styles.Note.Render("• Current Key")
7 	}
8 
9 	// Default state
M tui/ui.go
+25, -43
 1@@ -1,14 +1,13 @@
 2 package tui
 3 
 4 import (
 5-	"errors"
 6+	"fmt"
 7 
 8 	tea "github.com/charmbracelet/bubbletea"
 9+	"github.com/charmbracelet/lipgloss"
10 	"github.com/charmbracelet/wish"
11 	"github.com/muesli/reflow/wordwrap"
12 	"github.com/muesli/reflow/wrap"
13-	"github.com/picosh/pico/db"
14-	"github.com/picosh/pico/shared"
15 	"github.com/picosh/pico/tui/common"
16 	"github.com/picosh/pico/tui/createaccount"
17 	"github.com/picosh/pico/tui/createkey"
18@@ -66,6 +65,7 @@ func (m *UI) updateModels(msg tea.Msg) tea.Cmd {
19 }
20 
21 func (m *UI) Init() tea.Cmd {
22+	m.shared.HeaderHeight = lipgloss.Height(m.header())
23 	user, err := findUser(m.shared)
24 	if err != nil {
25 		wish.Errorln(m.shared.Session, err)
26@@ -146,49 +146,31 @@ func (m *UI) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
27 	return m, tea.Batch(cmds...)
28 }
29 
30-func (m *UI) View() string {
31-	w := m.shared.Width - m.shared.Styles.App.GetHorizontalFrameSize()
32-	s := m.shared.Styles.Logo.SetString("pico.sh").String() + "\n\n"
33-	if m.pages[m.activePage] != nil {
34-		s += m.pages[m.activePage].View()
35-	}
36-	str := wrap.String(wordwrap.String(s, w), w)
37-	return m.shared.Styles.App.Render(str)
38+func (m *UI) header() string {
39+	logo := m.shared.
40+		Styles.
41+		Logo.
42+		SetString("pico.sh")
43+	title := m.shared.
44+		Styles.
45+		Note.
46+		SetString(pages.ToTitle(m.activePage))
47+	div := m.shared.Styles.HelpDivider.Foreground(common.Green)
48+	s := fmt.Sprintf("%s%s%s\n\n", logo, div, title)
49+	return s
50 }
51 
52-func findUser(shrd common.SharedModel) (*db.User, error) {
53-	logger := shrd.Cfg.Logger
54-	var user *db.User
55-	usr := shrd.Session.User()
56-
57-	key, err := shared.KeyForKeyText(shrd.Session.PublicKey())
58-	if err != nil {
59-		return nil, err
60-	}
61-
62-	user, err = shrd.Dbpool.FindUserForKey(usr, key)
63-	if err != nil {
64-		logger.Error("no user found for public key", "err", err.Error())
65-		// we only want to throw an error for specific cases
66-		if errors.Is(err, &db.ErrMultiplePublicKeys{}) {
67-			return nil, err
68-		}
69-		// no user and not error indicates we need to create an account
70-		return nil, nil
71-	}
72-
73-	return user, nil
74-}
75-
76-func findPlusFeatureFlag(shrd common.SharedModel) (*db.FeatureFlag, error) {
77-	if shrd.User == nil {
78-		return nil, nil
79-	}
80+func (m *UI) View() string {
81+	s := m.header()
82 
83-	ff, err := shrd.Dbpool.FindFeatureForUser(shrd.User.ID, "plus")
84-	if err != nil {
85-		return nil, err
86+	if m.pages[m.activePage] != nil {
87+		s += m.pages[m.activePage].View()
88 	}
89 
90-	return ff, nil
91+	width := m.shared.Width - m.shared.Styles.App.GetHorizontalFrameSize()
92+	str := wrap.String(
93+		wordwrap.String(s, width),
94+		width,
95+	)
96+	return m.shared.Styles.App.Render(str)
97 }
A tui/util.go
+46, -0
 1@@ -0,0 +1,46 @@
 2+package tui
 3+
 4+import (
 5+	"errors"
 6+
 7+	"github.com/picosh/pico/db"
 8+	"github.com/picosh/pico/shared"
 9+	"github.com/picosh/pico/tui/common"
10+)
11+
12+func findUser(shrd common.SharedModel) (*db.User, error) {
13+	logger := shrd.Cfg.Logger
14+	var user *db.User
15+	usr := shrd.Session.User()
16+
17+	key, err := shared.KeyForKeyText(shrd.Session.PublicKey())
18+	if err != nil {
19+		return nil, err
20+	}
21+
22+	user, err = shrd.Dbpool.FindUserForKey(usr, key)
23+	if err != nil {
24+		logger.Error("no user found for public key", "err", err.Error())
25+		// we only want to throw an error for specific cases
26+		if errors.Is(err, &db.ErrMultiplePublicKeys{}) {
27+			return nil, err
28+		}
29+		// no user and not error indicates we need to create an account
30+		return nil, nil
31+	}
32+
33+	return user, nil
34+}
35+
36+func findPlusFeatureFlag(shrd common.SharedModel) (*db.FeatureFlag, error) {
37+	if shrd.User == nil {
38+		return nil, nil
39+	}
40+
41+	ff, err := shrd.Dbpool.FindFeatureForUser(shrd.User.ID, "plus")
42+	if err != nil {
43+		return nil, err
44+	}
45+
46+	return ff, nil
47+}