refactor: improved status buffer message logic

This commit is contained in:
decentral1se 2023-07-23 13:51:30 +02:00
parent 6bcdf35223
commit c1df444ce2
Signed by: decentral1se
GPG Key ID: 03789458B3D0C410
3 changed files with 56 additions and 26 deletions

View File

@ -74,7 +74,7 @@ func connInit(m *model) tea.Msg {
return errMsg{Err: fmt.Errorf("unable to initialise torrc builder: %s", err)}
}
m.statusBuffer <- "initialising Tor ACN..."
m.sendStatus("initialising Tor ACN...")
acn, err := tor.NewTorACNWithAuth(
path.Join(m.userDir, "/.tor"),
@ -89,7 +89,7 @@ func connInit(m *model) tea.Msg {
return errMsg{Err: fmt.Errorf("unable to bootstrap tor: %s", err)}
}
m.statusBuffer <- "waiting for Tor ACN to bootstrap..."
m.sendStatus("waiting for Tor ACN to bootstrap...")
if err := acn.WaitTillBootstrapped(); err != nil {
return errMsg{Err: fmt.Errorf("unable to initialise tor: %s", err)}
@ -104,13 +104,10 @@ func connInit(m *model) tea.Msg {
gSettings.DownloadPath = "./"
settingsFile.WriteGlobalSettings(gSettings)
m.statusBuffer <- "creating new Cwtch application"
app := app.NewApp(acn, m.userDir, settingsFile)
app.InstallEngineHooks(connections.DefaultEngineHooks{})
m.statusBuffer <- "the Tor ACN is up"
m.sendStatus("the Tor ACN is up")
return appInitialisedMsg{
app: app,

View File

@ -5,7 +5,9 @@ import (
"git.openprivacy.ca/openprivacy/connectivity"
)
type statusMsg struct{ msg string }
type sendStatusMsg struct{ lines []string }
type renderStatusMsg struct{ msg string }
type errMsg struct{ Err error }

View File

@ -51,14 +51,32 @@ func newModel(username, homeDir string) model {
}
}
func (m model) handleStatusMessage() tea.Msg {
return statusMsg{msg: <-m.statusBuffer}
func (m model) receiveStatusCmd() tea.Msg {
return renderStatusMsg{msg: <-m.statusBuffer}
}
// sendStatusCmd delivers a tea.Msg to bubbletea for rendering lines from the
// statusbuffer. Unlinke sendStatus, this method is an actual tea.Cmd.
func (m model) sendStatusCmd(lines ...string) tea.Cmd {
return func() tea.Msg {
return sendStatusMsg{lines: lines}
}
}
// sendStatus appends messages to the models status buffer directly. This
// method should only be called from within a tea.Cmd as it is blocking and
// does not return a tea.Msg. We need this for message passing in tea.Cmd when
// we want to render messages to the status buffer but still have work to do.
func (m model) sendStatus(lines ...string) {
for _, line := range lines {
m.statusBuffer <- line
}
}
func (m model) Init() tea.Cmd {
return tea.Batch(
textinput.Blink,
m.handleStatusMessage,
m.receiveStatusCmd,
)
}
@ -105,15 +123,15 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case cmdMsg:
m.input.Reset()
m.statusBuffer <- msg.output
cmds = append(cmds, m.sendStatusCmd(msg.output))
case offlineMsg:
m.input.Reset()
m.statusBuffer <- "conn: currently offline"
cmds = append(cmds, m.sendStatusCmd("conn: currently offline"))
case stillConnectingMsg:
m.input.Reset()
m.statusBuffer <- "conn: initialising, please hold"
cmds = append(cmds, m.sendStatusCmd("conn: initialising, please hold"))
case shutdownMsg:
m.input.Reset()
@ -124,9 +142,11 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.input.Reset()
m.app.CreateProfile(msg.name, msg.password, false)
m.statusBuffer <- fmt.Sprintf("created new profile: %s", msg.name)
cmds = append(cmds, m.sendStatusCmd(
fmt.Sprintf("created new profile: %s", msg.name),
))
profiles := m.app.ListProfiles() // TODO
profiles := m.app.ListProfiles()
m.profiles = append(m.profiles, profile{
name: msg.name,
onion: profiles[len(profiles)-1],
@ -143,7 +163,9 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
profiles := unlockProfiles(m, msg.password)
if len(profiles) > 0 {
m.statusBuffer <- fmt.Sprintf("unlocked profile(s): %s", profiles.names())
cmds = append(cmds, m.sendStatusCmd(
fmt.Sprintf("unlocked profile(s): %s", profiles.names()),
))
}
m.profiles = profiles
@ -156,18 +178,28 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
if len(m.profiles) == 0 {
m.statusBuffer <- "no profiles loaded"
cmds = append(cmds, m.sendStatusCmd("no profiles loaded"))
break
}
profile := m.profiles[m.profileState]
m.statusBuffer <- fmt.Sprintf("profile onion: %s", profile.onion)
cmds = append(cmds, m.sendStatusCmd(
fmt.Sprintf("profile onion: %s", profile.onion),
))
case statusMsg:
case sendStatusMsg:
cmds = append(cmds, func() tea.Msg {
for _, line := range msg.lines {
m.statusBuffer <- line
}
return nil
})
case renderStatusMsg:
existing := m.viewport.View()
m.viewport.SetContent(existing + "\n" + msg.msg)
m.viewport.GotoBottom()
cmds = append(cmds, m.handleStatusMessage)
cmds = append(cmds, m.receiveStatusCmd)
case clearMsg:
m.input.Reset()
@ -184,14 +216,13 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.app = msg.app
m.acn = msg.acn
m.connState = connected
cmds = append(cmds, func() tea.Msg {
m.statusBuffer <- "create or unlock a profile to get started"
m.statusBuffer <- "run /help to see the command listing"
return nil
})
cmds = append(cmds, m.sendStatusCmd(
"create or unlock a profile to get started",
"run /help to see the command listing",
))
case errMsg:
m.statusBuffer <- msg.Error()
cmds = append(cmds, m.sendStatusCmd(msg.Error()))
}
return m, tea.Batch(cmds...)