diff options
Diffstat (limited to 'internal/cli/timer.go')
| -rw-r--r-- | internal/cli/timer.go | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/internal/cli/timer.go b/internal/cli/timer.go new file mode 100644 index 0000000..aafcda0 --- /dev/null +++ b/internal/cli/timer.go @@ -0,0 +1,209 @@ +package cli + +import ( + "errors" + "fmt" + "math/rand/v2" + "strconv" + "strings" + + "codeberg.org/snonux/timr/internal/ascii" + "codeberg.org/snonux/timr/internal/live" + timrTimer "codeberg.org/snonux/timr/internal/timer" + tea "github.com/charmbracelet/bubbletea" + "github.com/spf13/cobra" +) + +func newTimerCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "timer", + Short: "Stopwatch timer operations", + } + + cmd.AddCommand(newTimerStartCmd()) + cmd.AddCommand(newTimerStopCmd()) + cmd.AddCommand(newTimerContinueCmd()) + cmd.AddCommand(newTimerResetCmd()) + cmd.AddCommand(newTimerStatusCmd()) + cmd.AddCommand(newTimerPromptCmd()) + cmd.AddCommand(newTimerTrackCmd()) + cmd.AddCommand(newTimerLiveCmd()) + + return cmd +} + +func newTimerStartCmd() *cobra.Command { + return &cobra.Command{ + Use: "start", + Short: "Start the timer", + RunE: func(cmd *cobra.Command, args []string) error { + rawStatus, err := timrTimer.GetRawStatus() + if err != nil { + return err + } + status, err := strconv.ParseFloat(rawStatus, 64) + if err != nil { + return err + } + + output, err := timrTimer.StartTimer(status > 0) + if err != nil { + return err + } + return printOutput(cmd, output) + }, + } +} + +func newTimerStopCmd() *cobra.Command { + return &cobra.Command{ + Use: "stop", + Short: "Stop the timer", + RunE: func(cmd *cobra.Command, args []string) error { + output, err := timrTimer.StopTimer() + if err != nil { + return err + } + return printOutput(cmd, output) + }, + } +} + +func newTimerContinueCmd() *cobra.Command { + return &cobra.Command{ + Use: "continue", + Short: "Continue a stopped timer", + RunE: func(cmd *cobra.Command, args []string) error { + rawStatus, err := timrTimer.GetRawStatus() + if err != nil { + return err + } + status, err := strconv.ParseFloat(rawStatus, 64) + if err != nil { + return err + } + + output := "Timer is at 0, cannot continue." + if status > 0 { + output, err = timrTimer.StartTimer(true) + if err != nil { + return err + } + } + + return printOutput(cmd, output) + }, + } +} + +func newTimerResetCmd() *cobra.Command { + return &cobra.Command{ + Use: "reset", + Short: "Reset the timer", + RunE: func(cmd *cobra.Command, args []string) error { + output, err := timrTimer.ResetTimer() + if err != nil { + return err + } + return printOutput(cmd, output) + }, + } +} + +func newTimerStatusCmd() *cobra.Command { + var raw bool + var rawMinutes bool + + cmd := &cobra.Command{ + Use: "status", + Short: "Show timer status", + RunE: func(cmd *cobra.Command, args []string) error { + if raw && rawMinutes { + return errors.New("only one of --raw or --raw-minutes can be set") + } + + var ( + output string + err error + ) + + switch { + case raw: + output, err = timrTimer.GetRawStatus() + case rawMinutes: + output, err = timrTimer.GetRawMinutesStatus() + default: + output, err = timrTimer.GetStatus() + } + if err != nil { + return err + } + + return printOutput(cmd, output) + }, + } + + cmd.Flags().BoolVar(&raw, "raw", false, "Show elapsed time in seconds") + cmd.Flags().BoolVar(&rawMinutes, "raw-minutes", false, "Show elapsed time in minutes") + return cmd +} + +func newTimerPromptCmd() *cobra.Command { + return &cobra.Command{ + Use: "prompt", + Short: "Show prompt-friendly timer status", + RunE: func(cmd *cobra.Command, args []string) error { + output, err := timrTimer.GetPromptStatus() + if err != nil { + return err + } + return printOutput(cmd, output) + }, + } +} + +func newTimerTrackCmd() *cobra.Command { + return &cobra.Command{ + Use: "track <description>", + Short: "Track elapsed time to Taskwarrior and reset timer", + Args: cobra.MinimumNArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + description := strings.Join(args, " ") + output, err := timrTimer.TrackTime(description) + if err != nil { + return err + } + return printOutput(cmd, output) + }, + } +} + +func newTimerLiveCmd() *cobra.Command { + var font string + + cmd := &cobra.Command{ + Use: "live", + Short: "Launch interactive live timer view", + RunE: func(cmd *cobra.Command, args []string) error { + selectedFont := strings.TrimSpace(font) + if selectedFont == "" { + selectedFont = ascii.AllFonts[rand.IntN(len(ascii.AllFonts))] + } + + program := tea.NewProgram(live.NewModel(selectedFont)) + return program.Start() + }, + } + + cmd.Flags().StringVarP(&font, "font", "f", "", "Font for live timer (doom, mono12, rebel, ansi, ansiShadow)") + return cmd +} + +func printOutput(cmd *cobra.Command, output string) error { + if output == "" { + return nil + } + + _, err := fmt.Fprintln(cmd.OutOrStdout(), output) + return err +} |
