refactor!: cleaning up messages
This commit is contained in:
parent
2fbc7c42aa
commit
105ee428a6
66
acn.go
66
acn.go
@ -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}
|
||||
}
|
||||
|
10
input.go
10
input.go
@ -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"}}
|
||||
|
71
message.go
71
message.go
@ -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{}
|
||||
|
90
model.go
90
model.go
@ -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...)
|
||||
|
Reference in New Issue
Block a user