You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
2.3 KiB
119 lines
2.3 KiB
package main |
|
|
|
import ( |
|
"flag" |
|
"fmt" |
|
"io/ioutil" |
|
"log" |
|
"os" |
|
|
|
|
|
tea "github.com/charmbracelet/bubbletea" |
|
"github.com/charmbracelet/bubbles/spinner" |
|
"github.com/charmbracelet/lipgloss" |
|
"github.com/mattn/go-isatty" |
|
"github.com/muesli/reflow/indent" |
|
|
|
"samhofi.us/x/keybase/v2" |
|
"samhofi.us/x/keybase/v2/types/chat1" |
|
) |
|
|
|
var ( |
|
helpStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("241")).Render |
|
k = keybase.NewKeybase() |
|
mainModel *model |
|
) |
|
|
|
func main() { |
|
var ( |
|
daemonMode bool |
|
showHelp bool |
|
opts []tea.ProgramOption |
|
) |
|
|
|
flag.BoolVar(&daemonMode, "d", false, "run as a daemon") |
|
flag.BoolVar(&showHelp, "h", false, "show help") |
|
flag.Parse() |
|
|
|
if showHelp { |
|
flag.Usage() |
|
os.Exit(0) |
|
} |
|
|
|
if daemonMode || !isatty.IsTerminal(os.Stdout.Fd()) { |
|
// If we're in daemon mode don't render the TUI |
|
opts = []tea.ProgramOption{tea.WithoutRenderer()} |
|
} else { |
|
// If we're in TUI mode, discard log output |
|
log.SetOutput(ioutil.Discard) |
|
} |
|
m1 := newModel() |
|
mainModel = &m1 |
|
chatHandler := handleChat |
|
handlers := keybase.Handlers{ |
|
ChatHandler: &chatHandler, |
|
} |
|
go k.Run(handlers, &keybase.RunOptions{}) |
|
p := tea.NewProgram(mainModel, opts...) |
|
if err := p.Start(); err != nil { |
|
fmt.Println("Error starting Bubble Tea program:", err) |
|
os.Exit(1) |
|
} |
|
} |
|
|
|
func newModel() model { |
|
sp := spinner.New() |
|
sp.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("206")) |
|
|
|
return model{ |
|
spinner: sp, |
|
} |
|
} |
|
|
|
func (m model) Init() tea.Cmd { |
|
log.Println("Starting work...") |
|
return tea.Batch( |
|
spinner.Tick, |
|
) |
|
} |
|
|
|
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { |
|
switch msg := msg.(type) { |
|
case tea.KeyMsg: |
|
if msg.String() == "ctrl+c" { |
|
m.quitting= true |
|
return m, tea.Quit |
|
} else { |
|
return m, nil |
|
} |
|
case spinner.TickMsg: |
|
var cmd tea.Cmd |
|
m.spinner, cmd = m.spinner.Update(msg) |
|
return m, cmd |
|
case chat1.MsgSummary: |
|
log.Println("chat1.MsgSummary passed to m.Update()") |
|
var cmd tea.Cmd |
|
return m, cmd |
|
default: |
|
return m, nil |
|
} |
|
} |
|
|
|
func (m model) View() string { |
|
s := "\n" |
|
|
|
for _, res := range mainModel.chat { |
|
log.Println(res) |
|
if res.Content.TypeName == "text" { |
|
s += fmt.Sprintf("%+v: %+v\n", res.Sender.Username, res.Content.Text.Body) |
|
} |
|
} |
|
|
|
s += helpStyle("\nCtrl+C to exit\n") |
|
|
|
if m.quitting { |
|
s += "\n" |
|
} |
|
|
|
return indent.String(s, 1) |
|
} |