From cf93ff24d867bac93716e354bf8ed6e037b8772a Mon Sep 17 00:00:00 2001 From: decentral1se Date: Sun, 23 Jul 2023 12:24:27 +0200 Subject: [PATCH] refactor: break up huge file, structure now clear --- input.go | 104 +++++++++++++++++++++ main.go | 76 +++++++++++++++ cairde.go => model.go | 210 ------------------------------------------ msg.go | 40 ++++++++ style.go | 16 ++++ 5 files changed, 236 insertions(+), 210 deletions(-) create mode 100644 input.go create mode 100644 main.go rename cairde.go => model.go (70%) create mode 100644 msg.go create mode 100644 style.go diff --git a/input.go b/input.go new file mode 100644 index 0000000..8617a45 --- /dev/null +++ b/input.go @@ -0,0 +1,104 @@ +package main + +import ( + "strings" + + tea "github.com/charmbracelet/bubbletea" +) + +func isHelpCmd(cmds []string) bool { + if cmds[0] == "help" { + return true + } + return false +} + +func isQuitCmd(cmds []string) bool { + if cmds[0] == "quit" { + return true + } + return false +} + +func isProfileCreateCmd(cmds []string) bool { + if cmds[0] == "profile" && cmds[1] == "create" { + return true + } + return false +} + +func isProfileUnlockCmd(cmds []string) bool { + if cmds[0] == "profile" && cmds[1] == "unlock" { + return true + } + return false +} + +func isProfileInfoCmd(cmds []string) bool { + if cmds[0] == "profile" && cmds[1] == "info" { + return true + } + return false +} + +func isConnectCmd(cmds []string) bool { + if cmds[0] == "connect" { + return true + } + return false +} + +func isClearCmd(cmds []string) bool { + if cmds[0] == "clear" { + return true + } + return false +} + +func handleCommand(cmd, hiddenInput string) tea.Msg { + cmds := strings.Split(cmd, " ") + + switch { + case isHelpCmd(cmds): + return cmdMsg{output: cmdHelp} + + case isQuitCmd(cmds): + return shutdownMsg{} + + case isProfileCreateCmd(cmds): + if len(cmds) != 5 { + return cmdMsg{output: cmdHelp} + } + + passwords := strings.Split(strings.TrimSpace(hiddenInput), " ") + if passwords[0] != passwords[1] { + return cmdMsg{output: "profile create: passwords do not match?"} + } + + return createProfileMsg{ + name: cmds[2], + password: passwords[1], + } + + case isProfileUnlockCmd(cmds): + if len(cmds) != 3 { + return cmdMsg{output: cmdHelp} + } + + return profileUnlockMsg{ + password: strings.TrimSpace(hiddenInput), + } + + case isProfileInfoCmd(cmds): + return profileInfoMsg{} + + case isConnectCmd(cmds): + return connectMsg{} + + case isClearCmd(cmds): + return clearMsg{} + + default: + return cmdMsg{output: "unknown command"} + } +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..356d69f --- /dev/null +++ b/main.go @@ -0,0 +1,76 @@ +package main + +import ( + "flag" + "fmt" + "log" + "os" + "os/exec" + "os/user" + + openPrivacyLog "git.openprivacy.ca/openprivacy/log" + _ "github.com/mutecomm/go-sqlcipher/v4" + + tea "github.com/charmbracelet/bubbletea" +) + +const ( + help = `cairde [options] + +A text-based user interface for metadata resistant online chat. + +Options: + -h output help +` + cmdHelp = `/clear +/connect +/help +/profile create +/profile info +/profile unlock +/quit` +) + +func main() { + var helpFlag bool + + flag.BoolVar(&helpFlag, "h", false, "output help") + flag.Parse() + + if helpFlag { + fmt.Print(help) + os.Exit(0) + } + + // NOTE(d1): pending https://git.coopcloud.tech/decentral1se/cairde/issues/1 + _, err := exec.LookPath("tor") + if err != nil { + log.Fatal("could not find 'tor' command, is it installed?") + } + + f, err := tea.LogToFile("cairde.log", "debug") + if err != nil { + log.Fatal(err) + } + defer f.Close() + + filelogger, err := openPrivacyLog.NewFile(openPrivacyLog.LevelInfo, "cwtch.log") + if err == nil { + openPrivacyLog.SetStd(filelogger) + } + + user, err := user.Current() + if err != nil { + log.Fatalf("unable to determine current user: %s", err) + } + + p := tea.NewProgram( + newModel(user.Username, user.HomeDir), + tea.WithAltScreen(), + tea.WithMouseCellMotion(), + ) + + if err := p.Start(); err != nil { + log.Fatal(err) + } +} diff --git a/cairde.go b/model.go similarity index 70% rename from cairde.go rename to model.go index fb796f2..8b02bb9 100644 --- a/cairde.go +++ b/model.go @@ -3,13 +3,9 @@ package main import ( "crypto/rand" "encoding/base64" - "flag" "fmt" - "log" mrand "math/rand" "os" - "os/exec" - "os/user" "path" "path/filepath" "strings" @@ -22,9 +18,6 @@ import ( "cwtch.im/cwtch/settings" "git.openprivacy.ca/openprivacy/connectivity" "git.openprivacy.ca/openprivacy/connectivity/tor" - openPrivacyLog "git.openprivacy.ca/openprivacy/log" - _ "github.com/mutecomm/go-sqlcipher/v4" - "github.com/charmbracelet/bubbles/textinput" "github.com/charmbracelet/bubbles/viewport" tea "github.com/charmbracelet/bubbletea" @@ -35,78 +28,6 @@ const ( offline = iota connecting connected - - help = `cairde [options] - -A text-based user interface for metadata resistant online chat. - -Options: - -h output help -` - cmdHelp = `/clear -/connect -/help -/profile create -/profile info -/profile unlock -/quit` -) - -func main() { - var helpFlag bool - - flag.BoolVar(&helpFlag, "h", false, "output help") - flag.Parse() - - if helpFlag { - fmt.Print(help) - os.Exit(0) - } - - // NOTE(d1): pending https://git.coopcloud.tech/decentral1se/cairde/issues/1 - _, err := exec.LookPath("tor") - if err != nil { - log.Fatal("could not find 'tor' command, is it installed?") - } - - f, err := tea.LogToFile("cairde.log", "debug") - if err != nil { - log.Fatal(err) - } - defer f.Close() - - filelogger, err := openPrivacyLog.NewFile(openPrivacyLog.LevelInfo, "cwtch.log") - if err == nil { - openPrivacyLog.SetStd(filelogger) - } - - user, err := user.Current() - if err != nil { - log.Fatalf("unable to determine current user: %s", err) - } - - p := tea.NewProgram( - newModel(user.Username, user.HomeDir), - tea.WithAltScreen(), - tea.WithMouseCellMotion(), - ) - - if err := p.Start(); err != nil { - log.Fatal(err) - } -} - -var ( - mainStyle = lipgloss.NewStyle(). - BorderStyle(lipgloss.NormalBorder()) - - viewportStyle = lipgloss.NewStyle() - - profileNameButtonStyle = lipgloss.NewStyle() - - channelBarStyle = lipgloss.NewStyle() - - inputStyle = lipgloss.NewStyle() ) type profile struct { @@ -152,17 +73,6 @@ func newModel(username, homeDir string) model { } } -type errMsg struct{ Err error } - -func (e errMsg) Error() string { - return e.Err.Error() -} - -type appInitialisedMsg struct { - app app.Application - acn connectivity.ACN -} - func (m model) initApp() tea.Msg { mrand.Seed(int64(time.Now().Nanosecond())) port := mrand.Intn(1000) + 9600 @@ -235,8 +145,6 @@ func (m model) initApp() tea.Msg { } } -type statusMsg struct{ msg string } - func (m model) handleStatusMessage() tea.Msg { return statusMsg{msg: <-m.statusBuffer} } @@ -280,124 +188,6 @@ func (m model) shutdown() bool { return true } -type cmdMsg struct { - output string -} - -type shutdownMsg struct{} - -type createProfileMsg struct { - name string - password string -} - -type profileUnlockMsg struct { - password string -} - -type connectMsg struct{} - -type clearMsg struct{} - -type profileInfoMsg struct{} - -func isHelpCmd(cmds []string) bool { - if cmds[0] == "help" { - return true - } - return false -} - -func isQuitCmd(cmds []string) bool { - if cmds[0] == "quit" { - return true - } - return false -} - -func isProfileCreateCmd(cmds []string) bool { - if cmds[0] == "profile" && cmds[1] == "create" { - return true - } - return false -} - -func isProfileUnlockCmd(cmds []string) bool { - if cmds[0] == "profile" && cmds[1] == "unlock" { - return true - } - return false -} - -func isProfileInfoCmd(cmds []string) bool { - if cmds[0] == "profile" && cmds[1] == "info" { - return true - } - return false -} - -func isConnectCmd(cmds []string) bool { - if cmds[0] == "connect" { - return true - } - return false -} - -func isClearCmd(cmds []string) bool { - if cmds[0] == "clear" { - return true - } - return false -} - -func handleCommand(cmd, hiddenInput string) tea.Msg { - cmds := strings.Split(cmd, " ") - - switch { - case isHelpCmd(cmds): - return cmdMsg{output: cmdHelp} - - case isQuitCmd(cmds): - return shutdownMsg{} - - case isProfileCreateCmd(cmds): - if len(cmds) != 5 { - return cmdMsg{output: cmdHelp} - } - - passwords := strings.Split(strings.TrimSpace(hiddenInput), " ") - if passwords[0] != passwords[1] { - return cmdMsg{output: "profile create: passwords do not match?"} - } - - return createProfileMsg{ - name: cmds[2], - password: passwords[1], - } - - case isProfileUnlockCmd(cmds): - if len(cmds) != 3 { - return cmdMsg{output: cmdHelp} - } - - return profileUnlockMsg{ - password: strings.TrimSpace(hiddenInput), - } - - case isProfileInfoCmd(cmds): - return profileInfoMsg{} - - case isConnectCmd(cmds): - return connectMsg{} - - case isClearCmd(cmds): - return clearMsg{} - - default: - return cmdMsg{output: "unknown command"} - } -} - func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { var ( cmd tea.Cmd diff --git a/msg.go b/msg.go new file mode 100644 index 0000000..fc26c0b --- /dev/null +++ b/msg.go @@ -0,0 +1,40 @@ +package main + +import ( + "cwtch.im/cwtch/app" + "git.openprivacy.ca/openprivacy/connectivity" +) + +type statusMsg struct{ msg string } + +type errMsg struct{ Err error } + +func (e errMsg) Error() string { + return e.Err.Error() +} + +type appInitialisedMsg struct { + app app.Application + acn connectivity.ACN +} + +type cmdMsg struct { + output string +} + +type shutdownMsg struct{} + +type createProfileMsg struct { + name string + password string +} + +type profileUnlockMsg struct { + password string +} + +type connectMsg struct{} + +type clearMsg struct{} + +type profileInfoMsg struct{} diff --git a/style.go b/style.go new file mode 100644 index 0000000..3750c03 --- /dev/null +++ b/style.go @@ -0,0 +1,16 @@ +package main + +import "github.com/charmbracelet/lipgloss" + +var ( + mainStyle = lipgloss.NewStyle(). + BorderStyle(lipgloss.NormalBorder()) + + viewportStyle = lipgloss.NewStyle() + + profileNameButtonStyle = lipgloss.NewStyle() + + channelBarStyle = lipgloss.NewStyle() + + inputStyle = lipgloss.NewStyle() +)