@timmy6942025/cli-timer 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/package.json +1 -1
- package/settings-ui/main.go +24 -16
- package/settings-ui/main_test.go +9 -8
- package/settings-ui/prebuilt/darwin-arm64/cli-timer-settings-ui +0 -0
- package/settings-ui/prebuilt/darwin-x64/cli-timer-settings-ui +0 -0
- package/settings-ui/prebuilt/linux-arm64/cli-timer-settings-ui +0 -0
- package/settings-ui/prebuilt/linux-x64/cli-timer-settings-ui +0 -0
- package/settings-ui/prebuilt/windows-arm64/cli-timer-settings-ui.exe +0 -0
- package/settings-ui/prebuilt/windows-x64/cli-timer-settings-ui.exe +0 -0
- package/src/index.js +23 -9
package/README.md
CHANGED
|
@@ -102,6 +102,7 @@ This launches a Bubble Tea based screen where you can change:
|
|
|
102
102
|
- Tick rate (50-1000 ms)
|
|
103
103
|
- Completion message
|
|
104
104
|
- System notification on completion (default On)
|
|
105
|
+
- Completion sound/alarm on completion (default Off)
|
|
105
106
|
- Pause key / pause alt key
|
|
106
107
|
- Restart key
|
|
107
108
|
- Exit key / exit alt key
|
package/package.json
CHANGED
package/settings-ui/main.go
CHANGED
|
@@ -39,14 +39,15 @@ var defaultKeybindings = keybindings{
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
type config struct {
|
|
42
|
-
Font
|
|
43
|
-
CenterDisplay
|
|
44
|
-
ShowHeader
|
|
45
|
-
ShowControls
|
|
46
|
-
TickRateMs
|
|
47
|
-
CompletionMessage
|
|
48
|
-
NotifyOnComplete
|
|
49
|
-
|
|
42
|
+
Font string `json:"font"`
|
|
43
|
+
CenterDisplay bool `json:"centerDisplay"`
|
|
44
|
+
ShowHeader bool `json:"showHeader"`
|
|
45
|
+
ShowControls bool `json:"showControls"`
|
|
46
|
+
TickRateMs int `json:"tickRateMs"`
|
|
47
|
+
CompletionMessage string `json:"completionMessage"`
|
|
48
|
+
NotifyOnComplete bool `json:"notifyOnComplete"`
|
|
49
|
+
PlaySoundOnComplete bool `json:"playSoundOnComplete"`
|
|
50
|
+
Keybindings keybindings `json:"keybindings"`
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
type statePayload struct {
|
|
@@ -151,6 +152,7 @@ func buildMenuItems(cfg config) []list.Item {
|
|
|
151
152
|
menuEntry{id: "tickRate", title: "Tick rate", description: fmt.Sprintf("%d ms", cfg.TickRateMs)},
|
|
152
153
|
menuEntry{id: "message", title: "Completion message", description: summarizeMessage(cfg.CompletionMessage)},
|
|
153
154
|
menuEntry{id: "notify", title: "System notification", description: boolText(cfg.NotifyOnComplete)},
|
|
155
|
+
menuEntry{id: "sound", title: "Completion sound/alarm", description: boolText(cfg.PlaySoundOnComplete)},
|
|
154
156
|
menuEntry{id: "pauseKey", title: "Pause key", description: keyTokenLabel(cfg.Keybindings.PauseKey)},
|
|
155
157
|
menuEntry{id: "pauseAltKey", title: "Pause alt key", description: keyTokenLabel(cfg.Keybindings.PauseAltKey)},
|
|
156
158
|
menuEntry{id: "restartKey", title: "Restart key", description: keyTokenLabel(cfg.Keybindings.RestartKey)},
|
|
@@ -226,14 +228,15 @@ func normalizeKeybindings(cfg keybindings) keybindings {
|
|
|
226
228
|
|
|
227
229
|
func normalizeConfig(cfg config) config {
|
|
228
230
|
result := config{
|
|
229
|
-
Font:
|
|
230
|
-
CenterDisplay:
|
|
231
|
-
ShowHeader:
|
|
232
|
-
ShowControls:
|
|
233
|
-
TickRateMs:
|
|
234
|
-
CompletionMessage:
|
|
235
|
-
NotifyOnComplete:
|
|
236
|
-
|
|
231
|
+
Font: defaultFont,
|
|
232
|
+
CenterDisplay: true,
|
|
233
|
+
ShowHeader: true,
|
|
234
|
+
ShowControls: true,
|
|
235
|
+
TickRateMs: defaultTickRateMs,
|
|
236
|
+
CompletionMessage: defaultCompletionMessage,
|
|
237
|
+
NotifyOnComplete: true,
|
|
238
|
+
PlaySoundOnComplete: false,
|
|
239
|
+
Keybindings: defaultKeybindings,
|
|
237
240
|
}
|
|
238
241
|
|
|
239
242
|
if strings.TrimSpace(cfg.Font) != "" {
|
|
@@ -249,6 +252,7 @@ func normalizeConfig(cfg config) config {
|
|
|
249
252
|
result.CompletionMessage = normalizeCompletionMessage(cfg.CompletionMessage)
|
|
250
253
|
}
|
|
251
254
|
result.NotifyOnComplete = cfg.NotifyOnComplete
|
|
255
|
+
result.PlaySoundOnComplete = cfg.PlaySoundOnComplete
|
|
252
256
|
result.Keybindings = normalizeKeybindings(cfg.Keybindings)
|
|
253
257
|
return result
|
|
254
258
|
}
|
|
@@ -462,6 +466,10 @@ func (m *model) applyMenuAction() tea.Cmd {
|
|
|
462
466
|
m.payload.Config.NotifyOnComplete = !m.payload.Config.NotifyOnComplete
|
|
463
467
|
m.refreshMenu()
|
|
464
468
|
return nil
|
|
469
|
+
case "sound":
|
|
470
|
+
m.payload.Config.PlaySoundOnComplete = !m.payload.Config.PlaySoundOnComplete
|
|
471
|
+
m.refreshMenu()
|
|
472
|
+
return nil
|
|
465
473
|
case "pauseKey":
|
|
466
474
|
m.openKeyPicker("pauseKey", "Select Pause Key")
|
|
467
475
|
return nil
|
package/settings-ui/main_test.go
CHANGED
|
@@ -10,14 +10,15 @@ func testPayload() statePayload {
|
|
|
10
10
|
return statePayload{
|
|
11
11
|
ConfigPath: "/tmp/cli-timer-test-config.json",
|
|
12
12
|
Config: config{
|
|
13
|
-
Font:
|
|
14
|
-
CenterDisplay:
|
|
15
|
-
ShowHeader:
|
|
16
|
-
ShowControls:
|
|
17
|
-
TickRateMs:
|
|
18
|
-
CompletionMessage:
|
|
19
|
-
NotifyOnComplete:
|
|
20
|
-
|
|
13
|
+
Font: "Standard",
|
|
14
|
+
CenterDisplay: true,
|
|
15
|
+
ShowHeader: true,
|
|
16
|
+
ShowControls: true,
|
|
17
|
+
TickRateMs: 100,
|
|
18
|
+
CompletionMessage: "Time is up!",
|
|
19
|
+
NotifyOnComplete: false,
|
|
20
|
+
PlaySoundOnComplete: false,
|
|
21
|
+
Keybindings: defaultKeybindings,
|
|
21
22
|
},
|
|
22
23
|
Fonts: []string{"Standard", "Big"},
|
|
23
24
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/src/index.js
CHANGED
|
@@ -39,6 +39,7 @@ const DEFAULT_CONFIG = Object.freeze({
|
|
|
39
39
|
tickRateMs: 100,
|
|
40
40
|
completionMessage: "Time is up!",
|
|
41
41
|
notifyOnComplete: true,
|
|
42
|
+
playSoundOnComplete: false,
|
|
42
43
|
keybindings: { ...DEFAULT_KEYBINDINGS }
|
|
43
44
|
});
|
|
44
45
|
|
|
@@ -203,6 +204,7 @@ function normalizeConfig(raw) {
|
|
|
203
204
|
tickRateMs: DEFAULT_CONFIG.tickRateMs,
|
|
204
205
|
completionMessage: DEFAULT_CONFIG.completionMessage,
|
|
205
206
|
notifyOnComplete: DEFAULT_CONFIG.notifyOnComplete,
|
|
207
|
+
playSoundOnComplete: DEFAULT_CONFIG.playSoundOnComplete,
|
|
206
208
|
keybindings: { ...DEFAULT_KEYBINDINGS }
|
|
207
209
|
};
|
|
208
210
|
|
|
@@ -225,6 +227,9 @@ function normalizeConfig(raw) {
|
|
|
225
227
|
if (typeof raw.notifyOnComplete === "boolean") {
|
|
226
228
|
next.notifyOnComplete = raw.notifyOnComplete;
|
|
227
229
|
}
|
|
230
|
+
if (typeof raw.playSoundOnComplete === "boolean") {
|
|
231
|
+
next.playSoundOnComplete = raw.playSoundOnComplete;
|
|
232
|
+
}
|
|
228
233
|
next.keybindings = normalizeKeybindings(raw.keybindings);
|
|
229
234
|
if (typeof raw.font === "string") {
|
|
230
235
|
const normalizedFont = normalizeFontName(raw.font);
|
|
@@ -568,19 +573,28 @@ function sendSystemNotification({ title, message }) {
|
|
|
568
573
|
return false;
|
|
569
574
|
}
|
|
570
575
|
|
|
576
|
+
function playCompletionAlarm(config) {
|
|
577
|
+
if (!config || !config.playSoundOnComplete) {
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
580
|
+
try {
|
|
581
|
+
process.stderr.write("\x07\x07\x07");
|
|
582
|
+
} catch (_error) {
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
571
586
|
function notifyTimerFinished(config, initialSeconds) {
|
|
572
|
-
if (!config
|
|
587
|
+
if (!config) {
|
|
573
588
|
return;
|
|
574
589
|
}
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
process.stderr.write("\x07");
|
|
581
|
-
} catch (_error) {
|
|
582
|
-
}
|
|
590
|
+
|
|
591
|
+
if (config.notifyOnComplete) {
|
|
592
|
+
const message = config.completionMessage || "Time is up!";
|
|
593
|
+
const title = initialSeconds ? `Timer finished (${formatHms(initialSeconds)})` : "Timer finished";
|
|
594
|
+
sendSystemNotification({ title, message });
|
|
583
595
|
}
|
|
596
|
+
|
|
597
|
+
playCompletionAlarm(config);
|
|
584
598
|
}
|
|
585
599
|
|
|
586
600
|
function runNonInteractiveTimer(initialSeconds, tickRateMs) {
|