mirror of
https://github.com/netbirdio/netbird.git
synced 2026-08-04 11:45:09 -04:00
102 lines
3.2 KiB
Go
102 lines
3.2 KiB
Go
//go:build !android && !ios && !freebsd && !js
|
|
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"sync/atomic"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
"github.com/wailsapp/wails/v3/pkg/application"
|
|
"github.com/wailsapp/wails/v3/pkg/services/notifications"
|
|
)
|
|
|
|
var errNotificationsUnavailable = errors.New("notifications unavailable")
|
|
|
|
// Notifier wraps the Wails notification service so an unavailable backend
|
|
// disables notifications instead of aborting the app. Startup fails for
|
|
// environment reasons (a bare unbundled binary on macOS has no bundle
|
|
// identifier, a headless Linux session has no D-Bus session bus), and Wails
|
|
// treats a service startup error as fatal. After a failed startup every call
|
|
// is a no-op: on macOS, touching UNUserNotificationCenter without a bundle
|
|
// identifier raises an Objective-C exception that recover() cannot catch.
|
|
type Notifier struct {
|
|
inner *notifications.NotificationService
|
|
available atomic.Bool
|
|
}
|
|
|
|
func newNotifier() *Notifier {
|
|
return &Notifier{inner: notifications.New()}
|
|
}
|
|
|
|
// ServiceName implements the Wails service-name hook for startup logs.
|
|
func (n *Notifier) ServiceName() string {
|
|
return n.inner.ServiceName()
|
|
}
|
|
|
|
// ServiceStartup starts the platform notifier, downgrading failure to a
|
|
// warning so the app keeps running without notifications.
|
|
func (n *Notifier) ServiceStartup(ctx context.Context, options application.ServiceOptions) error {
|
|
if err := n.inner.ServiceStartup(ctx, options); err != nil {
|
|
log.Warnf("notifications disabled: %v", err)
|
|
return nil
|
|
}
|
|
n.available.Store(true)
|
|
return nil
|
|
}
|
|
|
|
func (n *Notifier) ServiceShutdown() error {
|
|
if !n.available.Load() {
|
|
return nil
|
|
}
|
|
return n.inner.ServiceShutdown()
|
|
}
|
|
|
|
func (n *Notifier) CheckNotificationAuthorization() (bool, error) {
|
|
if !n.available.Load() {
|
|
return false, errNotificationsUnavailable
|
|
}
|
|
return n.inner.CheckNotificationAuthorization()
|
|
}
|
|
|
|
func (n *Notifier) RequestNotificationAuthorization() (bool, error) {
|
|
if !n.available.Load() {
|
|
return false, errNotificationsUnavailable
|
|
}
|
|
return n.inner.RequestNotificationAuthorization()
|
|
}
|
|
|
|
// SendNotification delivers a notification, silently dropping it when the
|
|
// backend never started (notifications are best-effort everywhere).
|
|
func (n *Notifier) SendNotification(options notifications.NotificationOptions) error {
|
|
if !n.available.Load() {
|
|
log.Debugf("notifications disabled, dropping %q", options.ID)
|
|
return nil
|
|
}
|
|
return n.inner.SendNotification(options)
|
|
}
|
|
|
|
func (n *Notifier) SendNotificationWithActions(options notifications.NotificationOptions) error {
|
|
if !n.available.Load() {
|
|
log.Debugf("notifications disabled, dropping %q", options.ID)
|
|
return nil
|
|
}
|
|
return n.inner.SendNotificationWithActions(options)
|
|
}
|
|
|
|
func (n *Notifier) RegisterNotificationCategory(category notifications.NotificationCategory) error {
|
|
if !n.available.Load() {
|
|
return nil
|
|
}
|
|
return n.inner.RegisterNotificationCategory(category)
|
|
}
|
|
|
|
// OnNotificationResponse registers the response callback. Pure Go state, so
|
|
// it is safe (and simply inert) when the backend never started.
|
|
//
|
|
//wails:ignore
|
|
func (n *Notifier) OnNotificationResponse(callback func(result notifications.NotificationResult)) {
|
|
n.inner.OnNotificationResponse(callback)
|
|
}
|