diff --git a/niotify_android.go b/niotify_android.go new file mode 100644 index 0000000..94fa0ca --- /dev/null +++ b/niotify_android.go @@ -0,0 +1,31 @@ +package niotify + +import ( + "git.sr.ht/~whereswaldon/niotify/android" +) + +type androidManager struct { + channel *android.NotificationChannel +} + +var _ managerInterface = &androidManager{} + +func newManager() (Manager, error) { + channel, err := android.NewChannel(android.ImportanceDefault, "DEFAULT", "niotify", "background notifications") + if err != nil { + return Manager{}, err + } + return Manager{ + &androidManager{ + channel: channel, + }, + }, nil +} + +func (a *androidManager) CreateNotification(title, text string) (*Notification, error) { + notification, err := a.channel.Send(title, text) + if err != nil { + return nil, err + } + return &Notification{notification}, nil +} diff --git a/niotify_linux.go b/niotify_linux.go new file mode 100644 index 0000000..6e6d1d5 --- /dev/null +++ b/niotify_linux.go @@ -0,0 +1,55 @@ +package niotify + +import ( + "fmt" + + "github.com/esiqveland/notify" + dbus "github.com/godbus/dbus/v5" +) + +type linuxManager struct { + notify.Notifier +} + +var _ managerInterface = &linuxManager{} + +func newManager() (Manager, error) { + conn, err := dbus.SessionBus() + if err != nil { + return Manager{}, fmt.Errorf("failed connecting to dbus: %w", err) + } + notifier, err := notify.New(conn) + if err != nil { + return Manager{}, fmt.Errorf("failed creating notifier: %w", err) + } + return Manager{ + impl: &linuxManager{ + Notifier: notifier, + }, + }, nil +} + +type linuxNotification struct { + id uint32 + *linuxManager +} + +var _ notificationInterface = linuxNotification{} + +func (l *linuxManager) CreateNotification(title, text string) (*Notification, error) { + id, err := l.Notifier.SendNotification(notify.Notification{}) + if err != nil { + return nil, err + } + return &Notification{ + linuxNotification{ + id: id, + linuxManager: l, + }, + }, nil +} + +func (l linuxNotification) Cancel() error { + _, err := l.linuxManager.CloseNotification(l.id) + return err +} diff --git a/niotify_unsupported.go b/niotify_unsupported.go new file mode 100644 index 0000000..c64952c --- /dev/null +++ b/niotify_unsupported.go @@ -0,0 +1,19 @@ +//+build !linux,!android + +package niotify + +type unsupportedManager struct{} + +func newManager() (Manager, error) { + return Manager{unsupportedManager{}}, nil +} + +func (u unsupportedManager) CreateNotification(title, text string) (*Notification, error) { + return &Notification{unsupportedNotification{}}, nil +} + +type unsupportedNotification struct{} + +func (u unsupportedNotification) Cancel() error { + return nil +} diff --git a/notification_manager.go b/notification_manager.go new file mode 100644 index 0000000..d42afe2 --- /dev/null +++ b/notification_manager.go @@ -0,0 +1,56 @@ +/* +Package niotify provides cross-platform notifications for Gio applications. https://gioui.org + +It aims to eventually support all Gio target platforms, but currently only supports +android and linux. + +Sending a notification is easy: + + // NOTE: error handling omitted + // construct a manager + manager, _ := NewManager() + // send notification + notification, _ := manager.CreateNotification("hello!", "I was sent from Gio!") + + // you can also cancel notifications + notification.Cancel() +*/ +package niotify + +// Manager provides methods for creating and managing notifications. +type Manager struct { + impl managerInterface +} + +// NewManager creates a new Manager tailored to the current operating system. +func NewManager() (Manager, error) { + return newManager() +} + +// CreateNotification creates and sends a notification on the current platform. +// NOTE: it currently only supports Android and Linux. All other platforms are a +// no-op. +func (m Manager) CreateNotification(title, text string) (*Notification, error) { + return m.impl.CreateNotification(title, text) +} + +// managerInterface is the set of methods required for a cross-platform notification manager. +type managerInterface interface { + CreateNotification(title, text string) (*Notification, error) +} + +// notificationInterface is the set of methods required for a cross-platform notification. +type notificationInterface interface { + Cancel() error +} + +// Notification provides a cross-platform set of methods to manage a sent Notification. +type Notification struct { + impl notificationInterface +} + +// Cancel attempts to remove a previously-created notification from view on the current +// platform. +func (n *Notification) Cancel() error { + return n.impl.Cancel() +}