mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-20 19:09:29 +08:00
windows impl
This commit is contained in:
parent
91f1704f68
commit
01fa3071f1
@ -3,6 +3,7 @@ module github.com/wailsapp/wails/v3
|
|||||||
go 1.24.0
|
go 1.24.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
git.sr.ht/~jackmordaunt/go-toast v1.1.2
|
||||||
github.com/Masterminds/semver v1.5.0
|
github.com/Masterminds/semver v1.5.0
|
||||||
github.com/adrg/xdg v0.5.3
|
github.com/adrg/xdg v0.5.3
|
||||||
github.com/atterpac/refresh v0.8.4
|
github.com/atterpac/refresh v0.8.4
|
||||||
|
@ -8,6 +8,8 @@ atomicgo.dev/schedule v0.1.0 h1:nTthAbhZS5YZmgYbb2+DH8uQIZcTlIrd4eYr3UQxEjs=
|
|||||||
atomicgo.dev/schedule v0.1.0/go.mod h1:xeUa3oAkiuHYh8bKiQBRojqAMq3PXXbJujjb0hw8pEU=
|
atomicgo.dev/schedule v0.1.0/go.mod h1:xeUa3oAkiuHYh8bKiQBRojqAMq3PXXbJujjb0hw8pEU=
|
||||||
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
||||||
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||||
|
git.sr.ht/~jackmordaunt/go-toast v1.1.2 h1:/yrfI55LRt1M7H1vkaw+NaH1+L1CDxrqDltwm5euVuE=
|
||||||
|
git.sr.ht/~jackmordaunt/go-toast v1.1.2/go.mod h1:jA4OqHKTQ4AFBdwrSnwnskUIIS3HYzlJSgdzCKqfavo=
|
||||||
github.com/AlekSi/pointer v1.2.0 h1:glcy/gc4h8HnG2Z3ZECSzZ1IX1x2JxRVuDzaJwQE0+w=
|
github.com/AlekSi/pointer v1.2.0 h1:glcy/gc4h8HnG2Z3ZECSzZ1IX1x2JxRVuDzaJwQE0+w=
|
||||||
github.com/AlekSi/pointer v1.2.0/go.mod h1:gZGfd3dpW4vEc/UlyfKKi1roIqcCgwOIvb0tSNSBle0=
|
github.com/AlekSi/pointer v1.2.0/go.mod h1:gZGfd3dpW4vEc/UlyfKKi1roIqcCgwOIvb0tSNSBle0=
|
||||||
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
||||||
|
@ -1,22 +1,5 @@
|
|||||||
//go:build darwin
|
|
||||||
|
|
||||||
package notifications
|
package notifications
|
||||||
|
|
||||||
/*
|
|
||||||
#cgo CFLAGS: -mmacosx-version-min=10.14 -x objective-c
|
|
||||||
#cgo LDFLAGS: -framework Cocoa -mmacosx-version-min=10.14 -framework UserNotifications
|
|
||||||
#import "./notifications_darwin.h"
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v3/pkg/application"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,158 +30,18 @@ type NotificationOptions = struct {
|
|||||||
Data map[string]interface{} `json:"data,omitempty"`
|
Data map[string]interface{} `json:"data,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func New() *Service {
|
type NotificationResponseData = struct {
|
||||||
return &Service{}
|
ID string `json:"id,omitempty"`
|
||||||
|
ActionIdentifier string `json:"actionIdentifier,omitempty"`
|
||||||
|
CategoryID string `json:"categoryIdentifier,omitempty"`
|
||||||
|
Title string `json:"title,omitempty"`
|
||||||
|
Subtitle string `json:"subtitle,omitempty"`
|
||||||
|
Body string `json:"body,omitempty"`
|
||||||
|
UserText string `json:"userText,omitempty"`
|
||||||
|
UserInfo map[string]interface{} `json:"userInfo,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckBundleIdentifier() bool {
|
type NotificationResponse = struct {
|
||||||
return bool(C.checkBundleIdentifier())
|
Name string `json:"name"`
|
||||||
}
|
Data NotificationResponseData `json:"data"`
|
||||||
|
|
||||||
// ServiceName returns the name of the service
|
|
||||||
func (ns *Service) ServiceName() string {
|
|
||||||
return "github.com/wailsapp/wails/v3/services/notifications"
|
|
||||||
}
|
|
||||||
|
|
||||||
// ServiceStartup is called when the service is loaded
|
|
||||||
func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error {
|
|
||||||
if !CheckBundleIdentifier() {
|
|
||||||
return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ServiceShutdown is called when the service is unloaded
|
|
||||||
func (ns *Service) ServiceShutdown() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RequestUserNotificationAuthorization requests permission for notifications.
|
|
||||||
func (ns *Service) RequestUserNotificationAuthorization() (bool, error) {
|
|
||||||
if !CheckBundleIdentifier() {
|
|
||||||
return false, fmt.Errorf("Notifications require a bundled application with a unique bundle identifier")
|
|
||||||
}
|
|
||||||
result := C.requestUserNotificationAuthorization(nil)
|
|
||||||
return result == true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CheckNotificationAuthorization checks current permission status
|
|
||||||
func (ns *Service) CheckNotificationAuthorization() (bool, error) {
|
|
||||||
if !CheckBundleIdentifier() {
|
|
||||||
return false, fmt.Errorf("Notifications require a bundled application with a unique bundle identifier")
|
|
||||||
}
|
|
||||||
return bool(C.checkNotificationAuthorization()), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendNotification sends a notification with the given identifier, title, subtitle, and body.
|
|
||||||
func (ns *Service) SendNotification(identifier, title, subtitle, body string) error {
|
|
||||||
if !CheckBundleIdentifier() {
|
|
||||||
return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier")
|
|
||||||
}
|
|
||||||
cIdentifier := C.CString(identifier)
|
|
||||||
cTitle := C.CString(title)
|
|
||||||
cSubtitle := C.CString(subtitle)
|
|
||||||
cBody := C.CString(body)
|
|
||||||
defer C.free(unsafe.Pointer(cIdentifier))
|
|
||||||
defer C.free(unsafe.Pointer(cTitle))
|
|
||||||
defer C.free(unsafe.Pointer(cSubtitle))
|
|
||||||
defer C.free(unsafe.Pointer(cBody))
|
|
||||||
|
|
||||||
C.sendNotification(cIdentifier, cTitle, cSubtitle, cBody, nil)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendNotificationWithActions sends a notification with the specified actions
|
|
||||||
func (ns *Service) SendNotificationWithActions(options NotificationOptions) error {
|
|
||||||
if !CheckBundleIdentifier() {
|
|
||||||
return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier")
|
|
||||||
}
|
|
||||||
cIdentifier := C.CString(options.ID)
|
|
||||||
cTitle := C.CString(options.Title)
|
|
||||||
cSubtitle := C.CString(options.Subtitle)
|
|
||||||
cBody := C.CString(options.Body)
|
|
||||||
cCategoryID := C.CString(options.CategoryID)
|
|
||||||
defer C.free(unsafe.Pointer(cIdentifier))
|
|
||||||
defer C.free(unsafe.Pointer(cTitle))
|
|
||||||
defer C.free(unsafe.Pointer(cSubtitle))
|
|
||||||
defer C.free(unsafe.Pointer(cBody))
|
|
||||||
defer C.free(unsafe.Pointer(cCategoryID))
|
|
||||||
|
|
||||||
var cActionsJSON *C.char
|
|
||||||
if options.Data != nil {
|
|
||||||
jsonData, err := json.Marshal(options.Data)
|
|
||||||
if err == nil {
|
|
||||||
cActionsJSON = C.CString(string(jsonData))
|
|
||||||
defer C.free(unsafe.Pointer(cActionsJSON))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
C.sendNotificationWithActions(cIdentifier, cTitle, cSubtitle, cBody, cCategoryID, cActionsJSON, nil)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegisterNotificationCategory registers a category with actions and optional reply field
|
|
||||||
func (ns *Service) RegisterNotificationCategory(category NotificationCategory) error {
|
|
||||||
if !CheckBundleIdentifier() {
|
|
||||||
return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier")
|
|
||||||
}
|
|
||||||
cCategoryID := C.CString(category.ID)
|
|
||||||
defer C.free(unsafe.Pointer(cCategoryID))
|
|
||||||
|
|
||||||
actionsJSON, err := json.Marshal(category.Actions)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
cActionsJSON := C.CString(string(actionsJSON))
|
|
||||||
defer C.free(unsafe.Pointer(cActionsJSON))
|
|
||||||
|
|
||||||
var cReplyPlaceholder, cReplyButtonTitle *C.char
|
|
||||||
if category.HasReplyField {
|
|
||||||
cReplyPlaceholder = C.CString(category.ReplyPlaceholder)
|
|
||||||
cReplyButtonTitle = C.CString(category.ReplyButtonTitle)
|
|
||||||
defer C.free(unsafe.Pointer(cReplyPlaceholder))
|
|
||||||
defer C.free(unsafe.Pointer(cReplyButtonTitle))
|
|
||||||
}
|
|
||||||
|
|
||||||
C.registerNotificationCategory(cCategoryID, cActionsJSON, C.bool(category.HasReplyField),
|
|
||||||
cReplyPlaceholder, cReplyButtonTitle)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveAllPendingNotifications removes all pending notifications
|
|
||||||
func (ns *Service) RemoveAllPendingNotifications() error {
|
|
||||||
if !CheckBundleIdentifier() {
|
|
||||||
return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier")
|
|
||||||
}
|
|
||||||
C.removeAllPendingNotifications()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemovePendingNotification removes a specific pending notification
|
|
||||||
func (ns *Service) RemovePendingNotification(identifier string) error {
|
|
||||||
if !CheckBundleIdentifier() {
|
|
||||||
return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier")
|
|
||||||
}
|
|
||||||
cIdentifier := C.CString(identifier)
|
|
||||||
defer C.free(unsafe.Pointer(cIdentifier))
|
|
||||||
C.removePendingNotification(cIdentifier)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ns *Service) RemoveAllDeliveredNotifications() error {
|
|
||||||
if !CheckBundleIdentifier() {
|
|
||||||
return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier")
|
|
||||||
}
|
|
||||||
C.removeAllDeliveredNotifications()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ns *Service) RemoveDeliveredNotification(identifier string) error {
|
|
||||||
if !CheckBundleIdentifier() {
|
|
||||||
return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier")
|
|
||||||
}
|
|
||||||
cIdentifier := C.CString(identifier)
|
|
||||||
defer C.free(unsafe.Pointer(cIdentifier))
|
|
||||||
C.removeDeliveredNotification(cIdentifier)
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
176
v3/pkg/services/notifications/notifications_darwin.go
Normal file
176
v3/pkg/services/notifications/notifications_darwin.go
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
//go:build darwin
|
||||||
|
|
||||||
|
package notifications
|
||||||
|
|
||||||
|
/*
|
||||||
|
#cgo CFLAGS: -mmacosx-version-min=10.14 -x objective-c
|
||||||
|
#cgo LDFLAGS: -framework Cocoa -mmacosx-version-min=10.14 -framework UserNotifications
|
||||||
|
#import "./notifications_darwin.h"
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/wailsapp/wails/v3/pkg/application"
|
||||||
|
)
|
||||||
|
|
||||||
|
func New() *Service {
|
||||||
|
return &Service{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServiceName returns the name of the service
|
||||||
|
func (ns *Service) ServiceName() string {
|
||||||
|
return "github.com/wailsapp/wails/v3/services/notifications"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServiceStartup is called when the service is loaded
|
||||||
|
func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error {
|
||||||
|
if !CheckBundleIdentifier() {
|
||||||
|
return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServiceShutdown is called when the service is unloaded
|
||||||
|
func (ns *Service) ServiceShutdown() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckBundleIdentifier() bool {
|
||||||
|
return bool(C.checkBundleIdentifier())
|
||||||
|
}
|
||||||
|
|
||||||
|
// RequestUserNotificationAuthorization requests permission for notifications.
|
||||||
|
func (ns *Service) RequestUserNotificationAuthorization() (bool, error) {
|
||||||
|
if !CheckBundleIdentifier() {
|
||||||
|
return false, fmt.Errorf("Notifications require a bundled application with a unique bundle identifier")
|
||||||
|
}
|
||||||
|
result := C.requestUserNotificationAuthorization(nil)
|
||||||
|
return result == true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckNotificationAuthorization checks current permission status
|
||||||
|
func (ns *Service) CheckNotificationAuthorization() (bool, error) {
|
||||||
|
if !CheckBundleIdentifier() {
|
||||||
|
return false, fmt.Errorf("Notifications require a bundled application with a unique bundle identifier")
|
||||||
|
}
|
||||||
|
return bool(C.checkNotificationAuthorization()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendNotification sends a notification with the given identifier, title, subtitle, and body.
|
||||||
|
func (ns *Service) SendNotification(identifier, title, subtitle, body string) error {
|
||||||
|
if !CheckBundleIdentifier() {
|
||||||
|
return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier")
|
||||||
|
}
|
||||||
|
cIdentifier := C.CString(identifier)
|
||||||
|
cTitle := C.CString(title)
|
||||||
|
cSubtitle := C.CString(subtitle)
|
||||||
|
cBody := C.CString(body)
|
||||||
|
defer C.free(unsafe.Pointer(cIdentifier))
|
||||||
|
defer C.free(unsafe.Pointer(cTitle))
|
||||||
|
defer C.free(unsafe.Pointer(cSubtitle))
|
||||||
|
defer C.free(unsafe.Pointer(cBody))
|
||||||
|
|
||||||
|
C.sendNotification(cIdentifier, cTitle, cSubtitle, cBody, nil)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendNotificationWithActions sends a notification with the specified actions
|
||||||
|
func (ns *Service) SendNotificationWithActions(options NotificationOptions) error {
|
||||||
|
if !CheckBundleIdentifier() {
|
||||||
|
return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier")
|
||||||
|
}
|
||||||
|
cIdentifier := C.CString(options.ID)
|
||||||
|
cTitle := C.CString(options.Title)
|
||||||
|
cSubtitle := C.CString(options.Subtitle)
|
||||||
|
cBody := C.CString(options.Body)
|
||||||
|
cCategoryID := C.CString(options.CategoryID)
|
||||||
|
defer C.free(unsafe.Pointer(cIdentifier))
|
||||||
|
defer C.free(unsafe.Pointer(cTitle))
|
||||||
|
defer C.free(unsafe.Pointer(cSubtitle))
|
||||||
|
defer C.free(unsafe.Pointer(cBody))
|
||||||
|
defer C.free(unsafe.Pointer(cCategoryID))
|
||||||
|
|
||||||
|
var cActionsJSON *C.char
|
||||||
|
if options.Data != nil {
|
||||||
|
jsonData, err := json.Marshal(options.Data)
|
||||||
|
if err == nil {
|
||||||
|
cActionsJSON = C.CString(string(jsonData))
|
||||||
|
defer C.free(unsafe.Pointer(cActionsJSON))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
C.sendNotificationWithActions(cIdentifier, cTitle, cSubtitle, cBody, cCategoryID, cActionsJSON, nil)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterNotificationCategory registers a category with actions and optional reply field
|
||||||
|
func (ns *Service) RegisterNotificationCategory(category NotificationCategory) error {
|
||||||
|
if !CheckBundleIdentifier() {
|
||||||
|
return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier")
|
||||||
|
}
|
||||||
|
cCategoryID := C.CString(category.ID)
|
||||||
|
defer C.free(unsafe.Pointer(cCategoryID))
|
||||||
|
|
||||||
|
actionsJSON, err := json.Marshal(category.Actions)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cActionsJSON := C.CString(string(actionsJSON))
|
||||||
|
defer C.free(unsafe.Pointer(cActionsJSON))
|
||||||
|
|
||||||
|
var cReplyPlaceholder, cReplyButtonTitle *C.char
|
||||||
|
if category.HasReplyField {
|
||||||
|
cReplyPlaceholder = C.CString(category.ReplyPlaceholder)
|
||||||
|
cReplyButtonTitle = C.CString(category.ReplyButtonTitle)
|
||||||
|
defer C.free(unsafe.Pointer(cReplyPlaceholder))
|
||||||
|
defer C.free(unsafe.Pointer(cReplyButtonTitle))
|
||||||
|
}
|
||||||
|
|
||||||
|
C.registerNotificationCategory(cCategoryID, cActionsJSON, C.bool(category.HasReplyField),
|
||||||
|
cReplyPlaceholder, cReplyButtonTitle)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveAllPendingNotifications removes all pending notifications
|
||||||
|
func (ns *Service) RemoveAllPendingNotifications() error {
|
||||||
|
if !CheckBundleIdentifier() {
|
||||||
|
return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier")
|
||||||
|
}
|
||||||
|
C.removeAllPendingNotifications()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemovePendingNotification removes a specific pending notification
|
||||||
|
func (ns *Service) RemovePendingNotification(identifier string) error {
|
||||||
|
if !CheckBundleIdentifier() {
|
||||||
|
return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier")
|
||||||
|
}
|
||||||
|
cIdentifier := C.CString(identifier)
|
||||||
|
defer C.free(unsafe.Pointer(cIdentifier))
|
||||||
|
C.removePendingNotification(cIdentifier)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveAllDeliveredNotifications removes all delivered notifications
|
||||||
|
func (ns *Service) RemoveAllDeliveredNotifications() error {
|
||||||
|
if !CheckBundleIdentifier() {
|
||||||
|
return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier")
|
||||||
|
}
|
||||||
|
C.removeAllDeliveredNotifications()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveDeliveredNotification removes a specific delivered notification
|
||||||
|
func (ns *Service) RemoveDeliveredNotification(identifier string) error {
|
||||||
|
if !CheckBundleIdentifier() {
|
||||||
|
return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier")
|
||||||
|
}
|
||||||
|
cIdentifier := C.CString(identifier)
|
||||||
|
defer C.free(unsafe.Pointer(cIdentifier))
|
||||||
|
C.removeDeliveredNotification(cIdentifier)
|
||||||
|
return nil
|
||||||
|
}
|
@ -34,6 +34,10 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
|
|||||||
if (response.notification.request.content.categoryIdentifier) {
|
if (response.notification.request.content.categoryIdentifier) {
|
||||||
[payload setObject:response.notification.request.content.categoryIdentifier forKey:@"categoryIdentifier"];
|
[payload setObject:response.notification.request.content.categoryIdentifier forKey:@"categoryIdentifier"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (response.notification.request.content.subtitle) {
|
||||||
|
[payload setObject:response.notification.request.content.subtitle forKey:@"subtitle"];
|
||||||
|
}
|
||||||
|
|
||||||
if (response.notification.request.content.userInfo) {
|
if (response.notification.request.content.userInfo) {
|
||||||
[payload setObject:response.notification.request.content.userInfo forKey:@"userInfo"];
|
[payload setObject:response.notification.request.content.userInfo forKey:@"userInfo"];
|
||||||
|
150
v3/pkg/services/notifications/notifications_windows.go
Normal file
150
v3/pkg/services/notifications/notifications_windows.go
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
//go:build windows
|
||||||
|
|
||||||
|
package notifications
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"git.sr.ht/~jackmordaunt/go-toast"
|
||||||
|
"github.com/wailsapp/wails/v3/pkg/application"
|
||||||
|
)
|
||||||
|
|
||||||
|
var NotificationCategories map[string]NotificationCategory = make(map[string]NotificationCategory)
|
||||||
|
|
||||||
|
func New() *Service {
|
||||||
|
return &Service{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServiceName returns the name of the service
|
||||||
|
func (ns *Service) ServiceName() string {
|
||||||
|
return "github.com/wailsapp/wails/v3/services/notifications"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServiceStartup is called when the service is loaded
|
||||||
|
func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error {
|
||||||
|
toast.SetActivationCallback(func(args string, data []toast.UserData) {
|
||||||
|
response := NotificationResponse{
|
||||||
|
Name: "notification",
|
||||||
|
Data: NotificationResponseData{
|
||||||
|
ActionIdentifier: args,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if userText, found := getUserText(data); found {
|
||||||
|
response.Data.UserText = userText
|
||||||
|
}
|
||||||
|
|
||||||
|
application.Get().EmitEvent("notificationResponse", response)
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServiceShutdown is called when the service is unloaded
|
||||||
|
func (ns *Service) ServiceShutdown() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// On Windows this does not apply, return true
|
||||||
|
func CheckBundleIdentifier() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// On Windows this does not apply, return true
|
||||||
|
func (ns *Service) RequestUserNotificationAuthorization() (bool, error) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// On Windows this does not apply, return true
|
||||||
|
func (ns *Service) CheckNotificationAuthorization() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ns *Service) SendNotification(identifier, title, _, body string) error {
|
||||||
|
n := toast.Notification{
|
||||||
|
AppID: identifier,
|
||||||
|
Title: title,
|
||||||
|
Body: body,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := n.Push()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ns *Service) SendNotificationWithActions(options NotificationOptions) error {
|
||||||
|
nCategory := NotificationCategories[options.CategoryID]
|
||||||
|
|
||||||
|
n := toast.Notification{
|
||||||
|
AppID: options.ID,
|
||||||
|
Title: options.Title,
|
||||||
|
Body: options.Body,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, action := range nCategory.Actions {
|
||||||
|
n.Actions = append(n.Actions, toast.Action{
|
||||||
|
Content: action.Title,
|
||||||
|
Arguments: action.ID,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if nCategory.HasReplyField {
|
||||||
|
n.Inputs = append(n.Inputs, toast.Input{
|
||||||
|
ID: "userText",
|
||||||
|
Title: nCategory.ReplyButtonTitle,
|
||||||
|
Placeholder: nCategory.ReplyPlaceholder,
|
||||||
|
})
|
||||||
|
|
||||||
|
n.Actions = append(n.Actions, toast.Action{
|
||||||
|
Content: nCategory.ReplyButtonTitle,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
err := n.Push()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ns *Service) RegisterNotificationCategory(category NotificationCategory) error {
|
||||||
|
NotificationCategories[category.ID] = NotificationCategory{
|
||||||
|
ID: category.ID,
|
||||||
|
Actions: category.Actions,
|
||||||
|
HasReplyField: bool(category.HasReplyField),
|
||||||
|
ReplyPlaceholder: category.ReplyPlaceholder,
|
||||||
|
ReplyButtonTitle: category.ReplyButtonTitle,
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveAllPendingNotifications removes all pending notifications
|
||||||
|
func (ns *Service) RemoveAllPendingNotifications() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemovePendingNotification removes a specific pending notification
|
||||||
|
func (ns *Service) RemovePendingNotification(_ string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveAllDeliveredNotifications removes all delivered notifications
|
||||||
|
func (ns *Service) RemoveAllDeliveredNotifications() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveDeliveredNotification removes a specific delivered notification
|
||||||
|
func (ns *Service) RemoveDeliveredNotification(_ string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getUserText(data []toast.UserData) (string, bool) {
|
||||||
|
for _, d := range data {
|
||||||
|
if d.Key == "userText" {
|
||||||
|
return d.Value, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", false
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user