1package notification
2
3import (
4 "log/slog"
5 "sync"
6
7 "github.com/gen2brain/beeep"
8)
9
10var (
11 isFocused = true
12 supportsFocus = false
13 focusStateLock sync.RWMutex
14)
15
16// SetFocusSupport sets whether the terminal supports focus reporting.
17func SetFocusSupport(supported bool) {
18 focusStateLock.Lock()
19 defer focusStateLock.Unlock()
20 supportsFocus = supported
21}
22
23// SetFocused sets whether the terminal window is currently focused.
24func SetFocused(focused bool) {
25 focusStateLock.Lock()
26 defer focusStateLock.Unlock()
27 isFocused = focused
28}
29
30// IsFocused returns whether the terminal window is currently focused.
31func IsFocused() bool {
32 focusStateLock.RLock()
33 defer focusStateLock.RUnlock()
34 return isFocused
35}
36
37// Send sends a desktop notification with the given title and message.
38// Notifications are only sent when the terminal window is not focused.
39// On darwin (macOS), icons are omitted due to platform limitations.
40func Send(title, message string) error {
41 focusStateLock.RLock()
42 focused := isFocused
43 supported := supportsFocus
44 focusStateLock.RUnlock()
45
46 slog.Debug("notification.Send called", "title", title, "message", message, "focused", focused, "supported", supported)
47
48 // Only skip notification if we know the window is focused.
49 // Send by default if focus reporting is not supported.
50 if supported && focused {
51 slog.Debug("skipping notification: window is focused")
52 return nil
53 }
54
55 beeep.AppName = "Crush"
56
57 err := beeep.Notify(title, message, notificationIcon)
58
59 if err != nil {
60 slog.Error("failed to send notification", "error", err)
61 } else {
62 slog.Debug("notification sent successfully")
63 }
64
65 return err
66}