diff options
| author | nsfisis <nsfisis@gmail.com> | 2025-10-27 06:08:21 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2025-10-27 06:08:21 +0900 |
| commit | 79c9870704df5ce77cb852bccec7dc780a248b2e (patch) | |
| tree | b597ebd73abaa68d78de73e3973d253b73984871 | |
| parent | 531820f3d60a301751c41d0aac5bbf5615f677b1 (diff) | |
| download | term-clock-79c9870704df5ce77cb852bccec7dc780a248b2e.tar.gz term-clock-79c9870704df5ce77cb852bccec7dc780a248b2e.tar.zst term-clock-79c9870704df5ce77cb852bccec7dc780a248b2e.zip | |
| -rw-r--r-- | README.md | 20 | ||||
| -rw-r--r-- | cmd/countdown.go | 105 | ||||
| -rw-r--r-- | cmd/root.go | 1 |
3 files changed, 123 insertions, 3 deletions
@@ -4,9 +4,10 @@ A digital clock that runs in your terminal, providing clock, alarm and timer. ## Features -- **Clock Mode**: Digital display of current time (24-hour format) -- **Alarm Mode**: Screen flashes at the specified time -- **Timer Mode**: Countdown timer (up to 99 minutes) +- Clock Mode: Digital display of current time (24-hour format) +- Alarm Mode: Screen flashes at the specified time +- Timer Mode: Countdown timer (up to 99 minutes) +- Countdown Mode: Countdown from a specified duration to zero ## Installation @@ -49,6 +50,19 @@ $ term-clock timer 90s # 90-second timer $ term-clock timer 1h30m # 1 hour 30 minutes timer (note: maximum 99 minutes) ``` +### Countdown Mode + +Counts down from the specified number of seconds to zero, displaying the remaining seconds. +The screen flashes when the countdown reaches zero. + +```bash +$ term-clock countdown 10 # Countdown from 10 seconds +$ term-clock countdown 600 # Countdown from 600 seconds +$ term-clock countdown 9999 # Countdown from 9999 seconds +``` + +Note: Maximum supported duration is 9999 seconds. + ## How to Exit Press `Ctrl+C` or type `q` to exit. diff --git a/cmd/countdown.go b/cmd/countdown.go new file mode 100644 index 0000000..61cd929 --- /dev/null +++ b/cmd/countdown.go @@ -0,0 +1,105 @@ +package cmd + +import ( + "log" + "math" + "strconv" + "time" + + "github.com/spf13/cobra" + + "github.com/nsfisis/term-clock/internal/term" +) + +func drawCountdown(scr *term.Screen, leftSeconds int, bgStyle, fgStyle term.Style) { + if leftSeconds <= 0 { + if int(math.Abs(float64(leftSeconds)))%2 == 0 { + bgStyle, fgStyle = fgStyle, bgStyle + } + leftSeconds = 0 + } + + // Clear the entire screen. + scr.Clear(bgStyle) + + // Calculate number of digits needed + numDigits := 1 + if leftSeconds > 0 { + n := leftSeconds + numDigits = 0 + for n > 0 { + numDigits++ + n /= 10 + } + } + + scrW, scrH := scr.Size() + // Calculate square size based on number of digits + squareW := scrW / (numDigits*4 + 2) + squareH := min(scrH/(5+2), squareW) + if squareW > squareH*3/2 { + squareW = squareH * 3 / 2 + } + xOffset := (scrW - squareW*numDigits*4) / 2 + yOffset := (scrH - squareH*5) / 2 + + // Extract and display each digit + n := leftSeconds + for i := numDigits - 1; i >= 0; i-- { + digit := n % 10 + term.DrawNumber(scr, digit, xOffset+squareW*i*4, yOffset, squareW, squareH, fgStyle) + n /= 10 + } +} + +func cmdCountdown(cmd *cobra.Command, args []string) { + totalSeconds, err := strconv.Atoi(args[0]) + if err != nil { + log.Fatalf("%+v", err) + } + + if totalSeconds > 9999 { + log.Fatal("Duration over 9999 seconds is not supported.") + } + + scr, err := term.NewScreen() + if err != nil { + log.Fatalf("%+v", err) + } + defer scr.Close() + + startTime := time.Now() + + calcLeftSeconds := func(t time.Time) int { + elapsed := int(t.Sub(startTime).Seconds()) + return totalSeconds - elapsed + } + + drawCountdown(scr, calcLeftSeconds(time.Now()), term.BgStyle, term.FgStyle) + + scr.OnResize(func() bool { + drawCountdown(scr, calcLeftSeconds(time.Now()), term.BgStyle, term.FgStyle) + return false + }) + go scr.DoEventLoop() + + t := time.NewTicker(1 * time.Second) + defer t.Stop() + + for { + select { + case <-scr.QuitC: + return + case now := <-t.C: + drawCountdown(scr, calcLeftSeconds(now), term.BgStyle, term.FgStyle) + scr.Show() + } + } +} + +var countdownCmd = &cobra.Command{ + Use: "countdown", + Short: "Countdown mode", + Run: cmdCountdown, + Args: cobra.ExactArgs(1), +} diff --git a/cmd/root.go b/cmd/root.go index 5a91eae..e3aa309 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -16,6 +16,7 @@ var rootCmd = &cobra.Command{ func init() { rootCmd.AddCommand(alarmCmd) rootCmd.AddCommand(clockCmd) + rootCmd.AddCommand(countdownCmd) rootCmd.AddCommand(timerCmd) } |
