repos / pico

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

pico / tui / notifications
Eric Bower · 29 Nov 24

notifications.go

  1package notifications
  2
  3import (
  4	"fmt"
  5
  6	"github.com/charmbracelet/bubbles/viewport"
  7	tea "github.com/charmbracelet/bubbletea"
  8	"github.com/charmbracelet/glamour"
  9	"github.com/picosh/pico/db"
 10	"github.com/picosh/pico/tui/common"
 11	"github.com/picosh/pico/tui/pages"
 12)
 13
 14func NotificationsView(dbpool db.DB, userID string, w int) string {
 15	pass, err := dbpool.UpsertToken(userID, "pico-rss")
 16	if err != nil {
 17		return err.Error()
 18	}
 19	url := fmt.Sprintf("https://auth.pico.sh/rss/%s", pass)
 20	md := fmt.Sprintf(`We provide a special RSS feed for all pico users where we can send
 21user-specific notifications. This is where we will send pico+
 22expiration notices, among other alerts. To be clear, this is
 23optional but **highly** recommended.
 24
 25Add this URL to your RSS feed reader:
 26
 27%s
 28
 29## Using our [rss-to-email](https://pico.sh/feeds) service
 30
 31Create a feeds file (e.g. pico.txt):`, url)
 32
 33	md += "\n```\n"
 34	md += fmt.Sprintf(`=: email rss@myemail.com
 35=: digest_interval 1day
 36=> %s
 37`, url)
 38	md += "\n```\n"
 39	md += "Then copy the file to us:\n"
 40	md += "```\nrsync pico.txt feeds.pico.sh:/\n```"
 41
 42	r, _ := glamour.NewTermRenderer(
 43		// detect background color and pick either the default dark or light theme
 44		glamour.WithAutoStyle(),
 45		glamour.WithWordWrap(w-20),
 46	)
 47	out, err := r.Render(md)
 48	if err != nil {
 49		return err.Error()
 50	}
 51	return out
 52}
 53
 54// Model holds the state of the username UI.
 55type Model struct {
 56	shared *common.SharedModel
 57
 58	Done bool // true when it's time to exit this view
 59	Quit bool // true when the user wants to quit the whole program
 60
 61	viewport viewport.Model
 62}
 63
 64func headerHeight(shrd *common.SharedModel) int {
 65	return shrd.HeaderHeight
 66}
 67
 68func headerWidth(w int) int {
 69	return w - 2
 70}
 71
 72func NewModel(shared *common.SharedModel) Model {
 73	hh := headerHeight(shared)
 74	ww := headerWidth(shared.Width)
 75	viewport := viewport.New(ww, shared.Height-hh)
 76	viewport.YPosition = hh
 77	if shared.User != nil {
 78		viewport.SetContent(NotificationsView(shared.Dbpool, shared.User.ID, ww))
 79	}
 80
 81	return Model{
 82		shared: shared,
 83
 84		Done:     false,
 85		Quit:     false,
 86		viewport: viewport,
 87	}
 88}
 89
 90func (m Model) Init() tea.Cmd {
 91	return nil
 92}
 93
 94func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 95	switch msg := msg.(type) {
 96	case tea.WindowSizeMsg:
 97		m.viewport.Width = headerWidth(msg.Width)
 98		hh := headerHeight(m.shared)
 99		m.viewport.Height = msg.Height - hh
100
101	case tea.KeyMsg:
102		switch msg.String() {
103		case "q", "esc":
104			return m, pages.Navigate(pages.MenuPage)
105		}
106	}
107
108	var cmd tea.Cmd
109	m.viewport, cmd = m.viewport.Update(msg)
110	return m, cmd
111}
112
113func (m Model) View() string {
114	return m.viewport.View()
115}