notification.go

 1package notification
 2
 3import (
 4	"context"
 5	"log/slog"
 6	"time"
 7
 8	"github.com/gen2brain/beeep"
 9)
10
11// Notifier handles sending native notifications.
12type Notifier struct {
13	enabled bool
14}
15
16// New creates a new Notifier instance.
17func New(enabled bool) *Notifier {
18	return &Notifier{
19		enabled: enabled,
20	}
21}
22
23// NotifyTaskComplete sends a notification when a task is completed.
24// It waits for the specified delay before sending the notification.
25func (n *Notifier) NotifyTaskComplete(ctx context.Context, title, message string, delay time.Duration) context.CancelFunc {
26	if !n.enabled {
27		slog.Debug("Notifications disabled, skipping completion notification")
28		return func() {}
29	}
30
31	notifyCtx, cancel := context.WithCancel(ctx)
32	go func() {
33		slog.Debug("Waiting before sending completion notification", "delay", delay)
34		timer := time.NewTimer(delay)
35		defer timer.Stop()
36		select {
37		case <-timer.C:
38			slog.Debug("Sending completion notification", "title", title, "message", message)
39			if err := beeep.Notify(title, message, ""); err != nil {
40				slog.Warn("Failed to send notification", "error", err, "title", title, "message", message)
41			} else {
42				slog.Debug("Notification sent successfully", "title", title)
43			}
44		case <-notifyCtx.Done():
45			slog.Debug("Completion notification cancelled")
46		}
47	}()
48	return cancel
49}
50
51// NotifyPermissionRequest sends a notification when a permission request needs attention.
52// It waits for the specified delay before sending the notification.
53func (n *Notifier) NotifyPermissionRequest(ctx context.Context, title, message string, delay time.Duration) context.CancelFunc {
54	if !n.enabled {
55		slog.Debug("Notifications disabled, skipping permission request notification")
56		return func() {}
57	}
58
59	notifyCtx, cancel := context.WithCancel(ctx)
60	go func() {
61		slog.Debug("Waiting before sending permission request notification", "delay", delay)
62		timer := time.NewTimer(delay)
63		defer timer.Stop()
64		select {
65		case <-timer.C:
66			slog.Debug("Sending permission request notification", "title", title, "message", message)
67			if err := beeep.Notify(title, message, ""); err != nil {
68				slog.Warn("Failed to send notification", "error", err, "title", title, "message", message)
69			} else {
70				slog.Debug("Notification sent successfully", "title", title)
71			}
72		case <-notifyCtx.Done():
73			slog.Debug("Permission request notification cancelled")
74		}
75	}()
76	return cancel
77}