feat(04-01): add Notifier interface and FocusTimer
- Notifier interface with ExecNotifier (notify-send) and NullNotifier - FocusTimer thread-safe with Set/IsActive/Remaining - shortName helper for session display names - Full test coverage for all components
This commit is contained in:
44
notify.go
Normal file
44
notify.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Notifier sends desktop notifications.
|
||||
type Notifier interface {
|
||||
Notify(title, body string) error
|
||||
}
|
||||
|
||||
// ExecNotifier calls notify-send via os/exec.
|
||||
type ExecNotifier struct{}
|
||||
|
||||
func (n *ExecNotifier) Notify(title, body string) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
return exec.CommandContext(ctx, "notify-send",
|
||||
"--urgency=critical",
|
||||
"--app-name=vmux",
|
||||
title,
|
||||
body,
|
||||
).Run()
|
||||
}
|
||||
|
||||
// NullNotifier discards all notifications (for tests and focus mode).
|
||||
type NullNotifier struct{}
|
||||
|
||||
func (n *NullNotifier) Notify(_, _ string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// shortName returns a human-readable short name for a session.
|
||||
// Prefers Label if set, otherwise uses the last component of Cwd.
|
||||
func shortName(s SessionInfo) string {
|
||||
if s.Label != "" {
|
||||
return s.Label
|
||||
}
|
||||
return filepath.Base(s.Cwd)
|
||||
}
|
||||
Reference in New Issue
Block a user