diff --git a/cmd/root.go b/cmd/root.go index b42e1a2..b72c41a 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -40,6 +40,7 @@ func init() { // initConfig reads and/or initializes the configuration file. func initConfig() { viper.SetDefault("averageSalary", 150000) + viper.SetDefault("currencySymbol", "$") // Find home directory. home, err := homedir.Dir() diff --git a/cmd/run.go b/cmd/run.go index 3a5b67f..b11b7d5 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -32,8 +32,11 @@ var runCmd = &cobra.Command{ manual = true } + var config tui.Config + config.SetFromViperConfig(manual) + var scraper scrape.Scraper - if !manual { + if !config.GetManualMode() { // Checking optional force_jitsi flag first switch { case forceJitsi || strings.Contains(url, "meet.jit.si"): @@ -49,7 +52,7 @@ var runCmd = &cobra.Command{ // `scrape` packages. var data tui.Data - if !manual { + if !config.GetManualMode() { log.Println("Initializing playwright to scrape participant count.") pw, err := scrape.InitializePlaywright() if err != nil { @@ -66,7 +69,7 @@ var runCmd = &cobra.Command{ }() } - tui.Start(manual, &data) + tui.Start(&data, &config) log.Info("Clockwise has been stopped.") return nil diff --git a/cmd/set.go b/cmd/set.go index 0d655ce..b5e021c 100644 --- a/cmd/set.go +++ b/cmd/set.go @@ -12,39 +12,58 @@ import ( // setCmd represents the set command. var setCmd = &cobra.Command{ Use: "set", - Short: "Set the average annual salary of meeting participants", + Short: "Set the average annual salary of meeting participants and currency representation", Long: `Set the average annual salary of meeting participants. This does not need to be an exact number.`, PreRun: toggleDebug, RunE: func(cmd *cobra.Command, args []string) error { - averageSalary := viper.GetViper().GetInt("averageSalary") + // Fetch currently set values from config or default values + averageSalaryPrev := viper.GetViper().GetInt("averageSalary") + currencySymbolPrev := viper.GetViper().GetString("currencySymbol") - q := &survey.Question{ - Prompt: &survey.Input{ - Message: "Set average annual salary of meeting participants:", - Default: strconv.Itoa(averageSalary), - }, - Validate: func(val interface{}) error { - if _, err := strconv.Atoi(val.(string)); err != nil { - return err - } + q := []*survey.Question{ + { + Name: "averageSalary", + Prompt: &survey.Input{ + Message: "Set average annual salary of meeting participants:", + Default: strconv.Itoa(averageSalaryPrev), + }, + Validate: func(val interface{}) error { + if _, err := strconv.Atoi(val.(string)); err != nil { + return err + } - return nil + return nil + }, + }, + { + Name: "currencySymbol", + Prompt: &survey.Input{ + Message: "Set symbol or abbreviation of your local currency:", + Default: currencySymbolPrev, + }, }, } - err := survey.AskOne(q.Prompt, &averageSalary, survey.WithValidator(q.Validate)) + answers := struct { + AverageSalary int + CurrencySymbol string + }{} + + err := survey.Ask(q, &answers) if err != nil { return err } - viper.GetViper().Set("averageSalary", averageSalary) + viper.GetViper().Set("averageSalary", answers.AverageSalary) + viper.GetViper().Set("currencySymbol", answers.CurrencySymbol) if err := viper.WriteConfig(); err != nil { return err } log.Printf( - "The average annual salary of meeting participants has been updated to %v in the configuration file.", - averageSalary, + "The average annual salary of meeting participants has been updated to %s%v in the configuration file.", + answers.CurrencySymbol, + answers.AverageSalary, ) return nil diff --git a/internal/tui/config.go b/internal/tui/config.go new file mode 100644 index 0000000..4c1aaeb --- /dev/null +++ b/internal/tui/config.go @@ -0,0 +1,49 @@ +package tui + +import ( + "github.com/spf13/viper" +) + +// Static configuration variables, enumerated at the start of the application +type Config struct { + manualMode bool + averageSalary int + currencySymbol string +} + +// Receive configuration values from Viper +func (c *Config) SetFromViperConfig(manualMode bool) { + c.manualMode = manualMode + c.averageSalary = viper.GetViper().GetInt("averageSalary") + c.currencySymbol = viper.GetViper().GetString("currencySymbol") +} + +// Set manual mode +func (c *Config) SetManualMode(value bool) { + c.manualMode = value +} + +// Get manual mode +func (c *Config) GetManualMode() bool { + return c.manualMode +} + +// Set average salary +func (c *Config) SetAverageSalary(value int) { + c.averageSalary = value +} + +// Get average salary +func (c *Config) GetAverageSalary() int { + return c.averageSalary +} + +// Set currency symbol +func (c *Config) SetCurrencySymbol(value string) { + c.currencySymbol = value +} + +// Get currency symbol +func (c *Config) GetCurrencySymbol() string { + return c.currencySymbol +} diff --git a/internal/tui/tui.go b/internal/tui/tui.go index f90d149..26492ab 100644 --- a/internal/tui/tui.go +++ b/internal/tui/tui.go @@ -10,7 +10,6 @@ import ( "unicode" log "github.com/sirupsen/logrus" - "github.com/spf13/viper" "github.com/gdamore/tcell/v2" "github.com/mattn/go-runewidth" @@ -38,7 +37,7 @@ func initScreen() (tcell.Screen, error) { return s, nil } -func Start(manual bool, data *Data) { +func Start(data *Data, config *Config) { // var data Data s, err := initScreen() @@ -46,16 +45,14 @@ func Start(manual bool, data *Data) { log.Fatal(err) } - averageSalary := viper.GetViper().GetInt("averageSalary") - // Start cost calculation goroutine. go func() { - calculateCost(data, averageSalary) + calculateCost(data, config.GetAverageSalary()) }() // Start cost file generation subroutine. go func() { - writeCostFile(data) + writeCostFile(data, config) }() quit := make(chan struct{}) @@ -75,10 +72,10 @@ func Start(manual bool, data *Data) { } case *tcell.EventResize: s.Sync() - draw(s, data, manual) + draw(s, data, config) } - if manual { + if config.GetManualMode() { switch ev := ev.(type) { case *tcell.EventKey: switch ev.Key() { @@ -118,16 +115,16 @@ func Start(manual bool, data *Data) { } // Render TUI after processing input. - draw(s, data, manual) + draw(s, data, config) } } } }() - tick(s, data, manual, quit) + tick(s, data, config, quit) s.Fini() - log.Infof("Total cost: $%.2f", data.getCost()) + log.Infof("Total cost: %s%.2f", config.GetCurrencySymbol(), data.getCost()) } // data stores variables passed around between the various goRoutines. @@ -184,7 +181,7 @@ func (data *Data) setInput(input string) { } // tick configures the goroutine for the scheduled calculateCost update. -func tick(s tcell.Screen, data *Data, manual bool, quit <-chan struct{}) { +func tick(s tcell.Screen, data *Data, config *Config, quit <-chan struct{}) { t := time.NewTicker(refreshInterval) for { @@ -192,7 +189,7 @@ func tick(s tcell.Screen, data *Data, manual bool, quit <-chan struct{}) { case <-quit: return case <-t.C: - draw(s, data, manual) + draw(s, data, config) } } } @@ -215,19 +212,19 @@ func emitStr(s tcell.Screen, x, y int, style tcell.Style, str string) { } // draw renders the TUI. -func draw(s tcell.Screen, data *Data, manual bool) { +func draw(s tcell.Screen, data *Data, config *Config) { s.Clear() style := tcell.StyleDefault.Foreground(tcell.ColorCornflowerBlue) emitStr(s, 0, 0, style, "Clockwise") - costString := fmt.Sprintf("Total cost: $%.2f", data.getCost()) + costString := fmt.Sprintf("Total cost: %s%.2f", config.GetCurrencySymbol(), data.getCost()) emitStr(s, 0, 1, tcell.StyleDefault, costString) countString := fmt.Sprintf("Participant count: %s", strconv.Itoa((data.GetCount()))) emitStr(s, 0, 2, tcell.StyleDefault, countString) - if manual { + if config.GetManualMode() { faded := tcell.StyleDefault.Foreground(tcell.ColorDimGray) inputString := fmt.Sprintf("Input: %s", data.getInput()) emitStr(s, 0, 3, tcell.StyleDefault, inputString) @@ -241,7 +238,7 @@ func draw(s tcell.Screen, data *Data, manual bool) { } // writeCostFile outputs the cost that gets consumed by OBS. -func writeCostFile(data *Data) { +func writeCostFile(data *Data, config *Config) { home, err := os.UserHomeDir() if err != nil { log.Fatal(err) @@ -252,7 +249,7 @@ func writeCostFile(data *Data) { outputFile := outputFolder + "clockwise.txt" for { - costString := fmt.Sprintf("Total cost: $%.2f\n", data.getCost()) + costString := fmt.Sprintf("Total cost: %s%.2f\n", config.GetCurrencySymbol(), data.getCost()) if err := ioutil.WriteFile(outputFile, []byte(costString), 0600); err != nil { log.Fatal(err)