native.go

 1package notification
 2
 3import (
 4	"log/slog"
 5
 6	tea "charm.land/bubbletea/v2"
 7	"github.com/gen2brain/beeep"
 8)
 9
10// NativeBackend sends desktop notifications using the native OS notification
11// system via beeep.
12type NativeBackend struct {
13	// icon is the notification icon data (PNG bytes).
14	icon []byte
15	// notifyFunc is the function used to send notifications (swappable for testing).
16	notifyFunc func(title, message string, icon any) error
17}
18
19// NewNativeBackend creates a new native notification backend.
20func NewNativeBackend(icon []byte) *NativeBackend {
21	beeep.AppName = "Crush"
22	return &NativeBackend{
23		icon:       icon,
24		notifyFunc: beeep.Notify,
25	}
26}
27
28// Send returns a command that sends a desktop notification using the native
29// OS notification system.
30func (b *NativeBackend) Send(n Notification) tea.Cmd {
31	return func() tea.Msg {
32		slog.Debug("Sending native notification", "title", n.Title, "message", n.Message)
33
34		if err := b.notifyFunc(n.Title, n.Message, b.icon); err != nil {
35			slog.Error("Failed to send notification", "error", err)
36		} else {
37			slog.Debug("Notification sent successfully")
38		}
39
40		return nil
41	}
42}
43
44// SetNotifyFunc allows replacing the notification function for testing.
45func (b *NativeBackend) SetNotifyFunc(fn func(title, message string, icon any) error) {
46	b.notifyFunc = fn
47}
48
49// ResetNotifyFunc resets the notification function to the default.
50func (b *NativeBackend) ResetNotifyFunc() {
51	b.notifyFunc = beeep.Notify
52}