refactor!: cleaning up messages

This commit is contained in:
decentral1se 2023-07-27 23:41:59 +02:00
parent 2fbc7c42aa
commit 105ee428a6
Signed by: decentral1se
GPG Key ID: 03789458B3D0C410
4 changed files with 126 additions and 111 deletions

66
acn.go
View File

@ -23,34 +23,29 @@ const (
connected
)
func ensureConnected(m model) (bool, tea.Msg) {
switch m.connState {
func isConnected(m model) (bool, tea.Msg) {
switch m.acnState {
case offline:
return false, offlineMsg{}
return false, acnOfflineMsg{}
case connecting:
return false, stillConnectingMsg{}
return false, acnConnectingMsg{}
default:
return true, nil
return true, acnAlreadyOnlineMsg{}
}
}
func attemptShutdown(m *model) tea.Msg {
switch m.connState {
case offline:
close(m.statusBuffer)
return shutdownMsg{quit: true}
case connecting:
return stillConnectingMsg{}
func turnAcnOn(m *model) tea.Msg {
if ok, msg := isConnected(*m); !ok {
switch msg.(type) {
case acnConnectingMsg:
return msg
case acnAlreadyOnlineMsg:
return msg
}
}
m.app.Shutdown()
m.acn.Close()
close(m.statusBuffer)
m.acnState = connecting
return shutdownMsg{quit: true}
}
func acnOn(m *model) tea.Msg {
mrand.Seed(int64(time.Now().Nanosecond()))
port := mrand.Intn(1000) + 9600
controlPort := port + 1
@ -58,15 +53,15 @@ func acnOn(m *model) tea.Msg {
key := make([]byte, 64)
_, err := rand.Read(key)
if err != nil {
return errMsg{Err: fmt.Errorf("unable to generate control port password: %s", err)}
return acnErrMsg{err: fmt.Errorf("unable to generate control port password: %s", err)}
}
if err := os.MkdirAll(path.Join(m.userDir, "/.tor", "tor"), 0700); err != nil {
return errMsg{Err: fmt.Errorf("unable to create tor directory: %s", err)}
return acnErrMsg{err: fmt.Errorf("unable to create tor directory: %s", err)}
}
if err := os.MkdirAll(path.Join(m.userDir, "profiles"), 0700); err != nil {
return errMsg{Err: fmt.Errorf("unable to create profiles directory: %s", err)}
return acnErrMsg{err: fmt.Errorf("unable to create profiles directory: %s", err)}
}
if err := tor.NewTorrc().
@ -75,7 +70,7 @@ func acnOn(m *model) tea.Msg {
WithControlPort(controlPort).
WithHashedPassword(base64.StdEncoding.EncodeToString(key)).
Build(filepath.Join(m.userDir, ".tor", "tor", "torrc")); err != nil {
return errMsg{Err: fmt.Errorf("unable to initialise torrc builder: %s", err)}
return acnErrMsg{err: fmt.Errorf("unable to initialise torrc builder: %s", err)}
}
m.sendStatus("Initialising Tor ACN...")
@ -90,18 +85,18 @@ func acnOn(m *model) tea.Msg {
},
)
if err != nil {
return errMsg{Err: fmt.Errorf("unable to bootstrap tor: %s", err)}
return acnErrMsg{err: fmt.Errorf("unable to bootstrap tor: %s", err)}
}
m.sendStatus("Waiting for ACN to bootstrap...")
if err := acn.WaitTillBootstrapped(); err != nil {
return errMsg{Err: fmt.Errorf("unable to initialise tor: %s", err)}
return acnErrMsg{err: fmt.Errorf("unable to initialise tor: %s", err)}
}
settingsFile, err := settings.InitGlobalSettingsFile(m.userDir, "")
if err != nil {
return errMsg{Err: fmt.Errorf("unable to initialise settings: %s", err)}
return acnErrMsg{err: fmt.Errorf("unable to initialise settings: %s", err)}
}
gSettings := settingsFile.ReadGlobalSettings()
gSettings.ExperimentsEnabled = false
@ -111,27 +106,24 @@ func acnOn(m *model) tea.Msg {
app := app.NewApp(acn, m.userDir, settingsFile)
app.InstallEngineHooks(connections.DefaultEngineHooks{})
m.sendStatus("Tor ACN is up and running, all engines go")
return appInitialisedMsg{
return acnOnMsg{
app: app,
acn: acn,
}
}
func acnOff(m *model) tea.Msg {
switch m.connState {
func turnAcnOff(m *model, quitProgram bool) tea.Msg {
switch m.acnState {
case offline:
return offlineMsg{}
if !quitProgram {
return acnOfflineMsg{}
}
case connecting:
return stillConnectingMsg{}
return acnConnectingMsg{}
}
m.app.Shutdown()
m.acn.Close()
return shutdownMsg{
quit: false,
status: "ACN successfully turned off",
}
return acnOffMsg{quitProgram: quitProgram}
}

View File

@ -87,10 +87,10 @@ func handleCommand(cmd, hiddenInput string) tea.Msg {
return cmdMsg{output: strings.Split(cmdHelp, "\n")}
case isQuitCmd(cmds):
return shutdownMsg{quit: true}
return turnAcnOffMsg{quitProgram: true}
case isStartCmd(cmds):
return startMsg{}
return showGettingStartedGuideMsg{}
case isProfileCreateCmd(cmds):
if len(cmds) != 5 {
@ -120,13 +120,13 @@ func handleCommand(cmd, hiddenInput string) tea.Msg {
return profileInfoMsg{}
case isAcnOnCmd(cmds):
return acnOnMsg{}
return turnAcnOnMsg{}
case isAcnOffCmd(cmds):
return acnOffMsg{}
return turnAcnOffMsg{}
case isClearCmd(cmds):
return clearMsg{}
return clearScreenMsg{}
default:
return cmdMsg{output: []string{"unknown command"}}

View File

@ -5,34 +5,50 @@ import (
"git.openprivacy.ca/openprivacy/connectivity"
)
type sendStatusMsg struct{ lines []string }
// ---------------------------------------------------------------------------
// ACN messages
// ---------------------------------------------------------------------------
type turnAcnOnMsg struct{}
type renderStatusMsg struct{ line string }
type errMsg struct{ Err error }
func (e errMsg) Error() string {
return e.Err.Error()
}
type appInitialisedMsg struct {
type acnOnMsg struct {
app app.Application
acn connectivity.ACN
}
type cmdMsg struct{ output []string }
type offlineMsg struct{}
type startMsg struct{}
type stillConnectingMsg struct{}
type shutdownMsg struct {
quit bool
status string
type turnAcnOffMsg struct {
quitProgram bool
}
type acnOffMsg struct {
quitProgram bool
}
type acnAlreadyOnlineMsg struct{}
type acnOfflineMsg struct{}
type acnConnectingMsg struct{}
type acnErrMsg struct {
err error
}
func (e acnErrMsg) Error() string {
return e.err.Error()
}
// ---------------------------------------------------------------------------
// help messages
// ---------------------------------------------------------------------------
type showGettingStartedGuideMsg struct{}
// ---------------------------------------------------------------------------
// profile messages
// ---------------------------------------------------------------------------
type profileInfoMsg struct{}
type startProfileQueuePollMsg struct{ onion string }
type createProfileMsg struct {
name string
password string
@ -42,12 +58,13 @@ type profileUnlockMsg struct {
password string
}
type acnOffMsg struct{}
// ---------------------------------------------------------------------------
// TODO: categorize messages below
// ---------------------------------------------------------------------------
type sendStatusMsg struct{ lines []string }
type acnOnMsg struct{}
type renderStatusMsg struct{ line string }
type clearMsg struct{}
type cmdMsg struct{ output []string }
type profileInfoMsg struct{}
type startProfileQueuePollMsg struct{ onion string }
type clearScreenMsg struct{}

View File

@ -58,7 +58,7 @@ type model struct {
username string
userDir string
connState int
acnState int
menuState int
menuBar []string
@ -99,7 +99,7 @@ func newModel(username, homeDir string, debug bool) model {
username: username,
userDir: path.Join(homeDir, "/.cairde/"),
connState: offline,
acnState: offline,
menuBar: []string{"STATUS"},
menuState: 0,
@ -224,7 +224,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg.String() {
case "ctrl+c":
cmds = append(cmds, func() tea.Msg {
return attemptShutdown(&m)
return turnAcnOff(&m, true)
})
case "enter":
@ -249,7 +249,9 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
case "ctrl+l":
cmds = append(cmds, func() tea.Msg { return clearMsg{} })
cmds = append(cmds, func() tea.Msg {
return clearScreenMsg{}
})
default:
hidePasswordInput(&m)
@ -259,34 +261,59 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.input.Reset()
cmds = append(cmds, m.sendStatusCmd(msg.output...))
case offlineMsg:
case turnAcnOffMsg:
m.input.Reset()
cmds = append(cmds, func() tea.Msg {
return turnAcnOff(&m, msg.quitProgram)
})
case acnOffMsg:
if msg.quitProgram {
return m, tea.Quit
}
cmds = append(cmds, m.sendStatusCmd("ACN successfully turned off"))
m.acnState = offline
case turnAcnOnMsg:
m.input.Reset()
cmds = append(cmds, func() tea.Msg {
return turnAcnOn(&m)
})
case acnOnMsg:
m.app = msg.app
m.acn = msg.acn
m.app.ActivateEngines(true, true, true)
m.acnState = connected
cmds = append(cmds, m.sendStatusCmd("ACN is up and running, all engines go"))
case acnAlreadyOnlineMsg:
m.input.Reset()
cmds = append(cmds, m.sendStatusCmd("ACN is already online"))
case acnOfflineMsg:
m.input.Reset()
cmds = append(cmds, m.sendStatusCmd("ACN is currently offline"))
case stillConnectingMsg:
case acnConnectingMsg:
m.input.Reset()
cmds = append(cmds, m.sendStatusCmd("Still initialising ACN, please hold"))
cmds = append(cmds, m.sendStatusCmd("ACN still initialising, please hold"))
case startMsg:
case acnErrMsg:
m.acnState = offline
cmds = append(cmds, m.sendStatusCmd(msg.Error()))
case showGettingStartedGuideMsg:
cmds = append(cmds, m.sendStatusCmd(
strings.Split(gettingStartedMessage, "\n")...,
))
m.input.Reset()
case shutdownMsg:
m.input.Reset()
if msg.quit {
return m, tea.Quit
}
if msg.status != "" {
cmds = append(cmds, m.sendStatusCmd(msg.status))
}
case createProfileMsg:
m.hiddenInput = ""
m.input.Reset()
if isConnected, msg := ensureConnected(m); !isConnected {
if ok, msg := isConnected(m); !ok {
cmds = append(cmds, func() tea.Msg { return msg })
break
}
@ -315,7 +342,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.hiddenInput = ""
m.input.Reset()
if isConnected, msg := ensureConnected(m); !isConnected {
if ok, msg := isConnected(m); !ok {
cmds = append(cmds, func() tea.Msg { return msg })
break
}
@ -339,7 +366,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case profileInfoMsg:
m.input.Reset()
if isConnected, msg := ensureConnected(m); !isConnected {
if ok, msg := isConnected(m); !ok {
cmds = append(cmds, func() tea.Msg { return msg })
break
}
@ -373,32 +400,11 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.statusViewport.GotoBottom()
cmds = append(cmds, m.receiveStatusCmd)
case clearMsg:
case clearScreenMsg:
m.input.Reset()
m.statusViewportLines = []string{}
m.statusViewport.SetContent("")
m.statusViewport.GotoTop()
case acnOffMsg:
m.input.Reset()
cmds = append(cmds, func() tea.Msg {
return acnOff(&m)
})
case acnOnMsg:
m.input.Reset()
cmds = append(cmds, func() tea.Msg {
return acnOn(&m)
})
case appInitialisedMsg:
m.app = msg.app
m.acn = msg.acn
m.connState = connected
m.app.ActivateEngines(true, true, true)
case errMsg:
cmds = append(cmds, m.sendStatusCmd(msg.Error()))
}
return m, tea.Batch(cmds...)