allow only one notification service per app

This commit is contained in:
popaprozac 2025-03-19 21:40:26 -07:00
commit 25256f747f
4 changed files with 30 additions and 24 deletions

View file

@ -26,8 +26,11 @@ type Service struct {
callbackLock sync.RWMutex
}
var NotificationService *Service
var notificationServiceLock sync.RWMutex
var (
notificationServiceOnce sync.Once
NotificationService *Service
notificationServiceLock sync.RWMutex
)
// NotificationAction represents an action button for a notification
type NotificationAction = struct {
@ -109,6 +112,7 @@ func (ns *Service) handleNotificationResult(result NotificationResult) {
}
}
// validateNotificationOptions validates an ID and Title are provided for notifications
func validateNotificationOptions(options NotificationOptions) error {
if options.ID == "" {
return fmt.Errorf("notification ID cannot be empty")

View file

@ -33,21 +33,21 @@ const AppleDefaultActionIdentifier = "com.apple.UNNotificationDefaultActionIdent
// Creates a new Notifications Service.
// Your app must be packaged and signed for this feature to work.
func New() *Service {
if !CheckBundleIdentifier() {
panic("\nError: Cannot use the notification API in development mode on macOS.\n" +
"Notifications require the app to be properly bundled with a bundle identifier and signed.\n" +
"To use the notification API on macOS:\n" +
" 1. Build and package your app using 'wails3 package'\n" +
" 2. Sign the packaged .app\n" +
" 3. Run the signed .app bundle")
}
notificationServiceOnce.Do(func() {
if !CheckBundleIdentifier() {
panic("\nError: Cannot use the notification API in development mode on macOS.\n" +
"Notifications require the app to be properly bundled with a bundle identifier and signed.\n" +
"To use the notification API on macOS:\n" +
" 1. Build and package your app using 'wails3 package'\n" +
" 2. Sign the packaged .app\n" +
" 3. Run the signed .app bundle")
}
notificationServiceLock.Lock()
defer notificationServiceLock.Unlock()
if NotificationService == nil {
NotificationService = &Service{}
}
})
if NotificationService == nil {
NotificationService = &Service{}
}
return NotificationService
}
@ -70,7 +70,7 @@ func (ns *Service) RequestNotificationAuthorization() (bool, error) {
return result.Success, result.Error
case <-ctx.Done():
cleanupChannel(id)
return false, fmt.Errorf("notification authorization timed out after 15s: %w", ctx.Err())
return false, fmt.Errorf("notification authorization timed out after 15 minutes: %w", ctx.Err())
}
}

View file

@ -81,9 +81,11 @@ var notifier *internalNotifier
// New creates a new Notifications Service
func New() *Service {
if NotificationService == nil {
NotificationService = &Service{}
}
notificationServiceOnce.Do(func() {
if NotificationService == nil {
NotificationService = &Service{}
}
})
return NotificationService
}

View file

@ -42,12 +42,12 @@ type NotificationPayload struct {
// Creates a new Notifications Service.
func New() *Service {
notificationServiceLock.Lock()
defer notificationServiceLock.Unlock()
notificationServiceOnce.Do(func() {
if NotificationService == nil {
NotificationService = &Service{}
}
})
if NotificationService == nil {
NotificationService = &Service{}
}
return NotificationService
}