-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Notification support #1788
Comments
I don't know if there is a plan for notifications, but beeep is a good package for native notifications IMO: |
Added to Roadmap 👍 |
As @leaanthony suggested, I'm trying to put together an API proposal and I'm looking at the notification capabilities of Windows, macOs and linux. Windows has the most extensive functionality, linux and macOS has a "simpler" API. My question would be, what is the goal, a common API with functions that work everywhere, or one where each OS can have its own settings, or some form of hybrid from the two with an override style solution. Case one:
We may lose some functionality on windows, but when you create a notification it would behave the same way on every OS. Case two: One would have to configure every notification for each OS they want to support, probably the only common options for a notification would be the title and a message (and maybe action buttons). Case three: The main API would work as described in the first case with the basic functionality, but has OS specific options like timing, sound, position, or for windows status/download bars, etc. |
Awesome @lyimmi ! As far as API goes, it's ok to have a single struct of options for all platforms where options are ignored if not supported 👍 |
Here is my first draft of the Notification API. I think if we want to have more than a title, message and an icon, we need to have OS specific options. As far as I can tell Electron only supports these three options as default. Even the timeout is different on each os, on linux it's set in milliseconds, on windows it's a dateTime, on macOs its not available. Handling the actions / buttons is totally different as well. Maybe the click on the notification could be handled commonly too. It is more of a conversation starter than a complete API. // LinuxActionInvokedHandler handles signals returned by activating actions
type LinuxActionInvokedHandler func(signal *LinuxNotificationActionInvokedSignal, options ...interface{})
// LinuxNotificationAction represents a Notification action for a notification
type LinuxNotificationAction struct {
// Key is the actions's identifier
Key string
// Label is shown on the notification
Label string
}
// LinuxNotificationActionInvokedSignal holds data from any signal received regarding Actions invoked
type LinuxNotificationActionInvokedSignal struct {
// ID of the Notification the action was invoked for
NotificationID uint32
// Key from the activated action
ActionKey string
}
type LinuxNotificationOptions struct {
// ReplacesID is used to replace an existing notification.
ReplacesID uint32
// Actions to be shown.
Actions []LinuxNotificationAction
// OnAction handles the activated action's signal.
OnAction LinuxActionInvokedHandler
// Timeout of the notification
Timeout time.Duration
}
// NotificationProgressBar shows a progress bar. (Windows only)
type NotificationProgressBar struct {
// Gets or sets an optional title string. Supports data binding.
Title string
// Gets or sets the value of the progress bar. Supports data binding.
// Defaults to 0. Can either be a double between 0.0 and 1.0, AdaptiveProgressBarValue.
// Indeterminate, or new BindableProgressBarValue("myProgressValue").
Value float32
// Gets or sets an optional string to be displayed instead of the default percentage string.
// If this isn't provided, something like "70%" will be displayed.
ValueStringOverride string
// Gets or sets a status string (required), which is displayed underneath the progress bar on the left.
// This string should reflect the status of the operation, like "Downloading..." or "Installing..."
Status string
}
// NotificationHeroImage A featured "hero" image that is displayed on the toast and within Action Center. (Windows only)
type NotificationHeroImage struct {
// The URL to the image. ms-appx, ms-appdata, and http are supported.
// Http images must be 200 KB or less in size.
Source string
// Alternate text describing the image, used for accessibility purposes.
AlternateText string
// Set to "true" to allow Windows to append a query string to the image URL
// supplied in the toast notification. Use this attribute if your server hosts
// images and can handle query strings, either by retrieving an image
// variant based on the query strings or by ignoring the query string and
// returning the image as specified without the query string.
//
// This query string specifies scale, contrast setting, and language; for instance,
// a value of "www.website.com/images/hello.png" given in the notification becomes
// "www.website.com/images/hello.png?ms-scale=100&ms-contrast=standard&ms-lang=en-us"
AddImageQuery bool
}
type WindowsNotificationOptions struct {
// HeroImage shows a full size image.
HeroImage *NotificationHeroImage
// ProgressBar shows a progress bar style notification.
ProgressBar *NotificationProgressBar
// ExpirationTime sets the expiration time for the notification.
ExpirationTime time.Time
}
// NotificationOptions sets up a notification to be sent.
type NotificationOptions struct {
// Applications identifier.
AppID string
// AppIcon used to show an icon on the notification. Absolute path to the icon.
AppIcon string
// Title is a summary for the notification.
Title string
// Message is the notification's message.
Message string
// LinuxOptions holds the linux specific options for a notification.
LinuxOptions *LinuxNotificationOptions
// WindowsOptions holds the windows specific options for a notification.
WindowsOptions *WindowsNotificationOptions
// Timeout is the duration for how long a notification is shown.
Timeout time.Duration
} Usage would look something like this: no := NotificationOptions{
AppID: "Wails test",
AppIcon: "/wails/build/appicon.png",
Title: "wails test",
Message: name,
LinuxOptions: &LinuxNotificationOptions{
ReplacesID: 0,
Actions: []LinuxNotificationAction{
{Key: "btn-1", Label: "Button 1"},
{Key: "btn-2", Label: "Button 2"},
},
OnAction: func(signal *LinuxNotificationActionInvokedSignal, options ...interface{}) {
fmt.Printf("key: %v, label: %v", signal.NotificationID, signal.ActionKey)
},
Timeout: time.Second * 10,
},
WindowsOptions: &WindowsNotificationOptions{
HeroImage: &NotificationHeroImage{
Source: "/path/to/image.jpg",
AlternateText: "alternate text",
AddImageQuery: false,
},
ProgressBar: &NotificationProgressBar{
Title: "title",
Value: 0.5,
ValueStringOverride: "10 out of a 100",
Status: "progress...",
},
ExpirationTime: time.Now().Add(24 * time.Hour),
},
}
runtime.SendNotification(ctx, no) |
For a work side project, I needed something to send notifications on macOS. All of the existing libraries I found were either deprecated or no longer maintained (and so features didn't work on recent versions of macOS), or the beeep one suggested earlier in this issue would cause script manager to launch when used, which isn't nice UX. However I found a library / binary (written in Objective-C) that is maintained and fairly feature complete but needed a Go library to work with it. So I created one that I'm using. https://github.com/willdot/gomacosnotify It does require the Alterer binary to be embedded and then installed into a temp location on the users machine, however I'm sure there's a way to stop that so that it's opt in (ie you want notifications and so the binary then gets used), possibly via build tags? Happy to work together to get something working for notifications working (on macOS) using the library I've created and open to API changes etc. |
Hi, @leaanthony, @stffabi, @willdot I started implementing the notification support on this branch: https://github.com/Lyimmi/wails/tree/feature/1788_notification_support It is still in early stages and currently only supports linux/dbus (started the nofiy-send and kdialog fallbacks but with a minimal functionality). Should I make a draft pull request, or wait for a more complete stage? It would be nice if someone else looked at it. Whether it's going in the right direction at all. Thanks! Edit: Made some changes to the API, currently this is how it looks like. res, err := runtime.SendNotification(a.ctx, runtime.NotificationOptions{
AppIcon: "/wailst/build/appicon.png",
Title: "This is a title",
Message: "This is a message",
Timeout: 60 * time.Second,
LinuxOptions: &runtime.LinuxNotificationOptions{
Actions: []runtime.LinuxNotificationAction{
{
Key: "maximize",
Label: "Maximize",
OnAction: func(signal *runtime.LinuxNotificationActionInvokedSignal) {
runtime.WindowMaximise(a.ctx)
},
},
{
Key: "minimize",
Label: "Minimize",
OnAction: func(signal *runtime.LinuxNotificationActionInvokedSignal) {
runtime.WindowMinimise(a.ctx)
},
},
},
},
}) |
Thanks for the work on this @lyimmi! I'm happy for you to push on with this. One question: is the path to the icon something that'll work at runtime or should we be using a |
@leaanthony all supported OSes are using absolute paths as default and all of them have some optional unique way too. This is one of my pain points as well, because we cannot use embedded resources. One way could be to use []byte as input and save the images to tmp if its not supported and then point to it? |
I think there's no option because how does it work from a distribution point of view? |
Well, yes. But it raises a few of questions.
Another advantage of the []byte route is that we could create a standard api for showing images via http. |
Another subject. The documentation is rather confusing to me. As a simple drop in for windows I used this https://github.com/martinlindhe/notify, but this package only handles opening other applications and web pages. |
Hey there 👋 Regarding the Q's, My approach would be to generate a random filename prefix at startup so icons are unique to the process. Before issuing the notification just write the file again. It sounds inefficient but notifications will be few and far between and the cost of writing a 32k icon will be miniscule vs the overhead of reading, hashing and potentially writing anyway, plus writing and testing code for all that. We can defer a delete but it's not even critical to do that as temp files will be vacuumed at some point by the OS. Regarding file type, the approach I've been taking is to use PNGs as source and generate OS appropriate file types from that if needed. I wouldn't bother with file limit unless you are required to by the OS. I can probably sort out the windows side. Managed to get in the zone over the last 6 months. |
Hi @leaanthony, it was a good idea, works nicely on Windows and linux as well. |
Hi, am at a stage where Windows, macOS and Linux can show notifications. Windows and macOS needs more work. Linux is almost there I think. I wrote the docs that represent the current state of things.
|
This is awesome! I may be able to help with the MacOS notification icons by implementing it in Objective-C. I'll be moving to mac in the next week or so to do tray menus so can fit this in at the same time 👍 |
@lyimmi amazing work, I had the same issue trying to work for actually listening to toast events for Windows. While it's cool.. the actual underlying API for toasts doesn't seem very thought out in terms of other apps, other than uwp using toast notifications. The few times I did get the listener working for the notification, (which I had to do with c# mind you) it was almost impossible to get the related action data. Like what button was clicked. What text was entered, what radio button was selected.. I think it's crucial to get events from notifications but in terms of a alpha feature.. don't focus too much on getting the events working. It'll only give you headaches. I'm willing to help, but my knowledge of windows apis, and c++/c in general is very very limited.. |
It might be worth actually contacting a Microsoft developer about this. It doesn't seem like even their website explains how to get data from toasts/receive events? Here's a developer support email: premdevinfo@microsoft.com |
For OSX it is possible to schedule and cancel notifications: |
Hey folks :) Do you have any news about this feature? Is it still on-going? |
No updates. I believe it's pretty difficult beyond very basic notifications. I'm hoping we can get a basic plugin working for v3 |
I found this function that should work at least in Mac, although it just uses the wails/v2/pkg/mac/notification_darwin.go Line 14 in 12d6336
I'm guessing the difficult part to come up with a more-or-less uniform API across systems? |
any updates on the progress of this? looks like this is the only blocker for v3 |
Maybe this can be postponed to v3.1 |
How do I open, the app back again with the context, after clicking notification? |
I'd like to see this feature too. |
As things look currently this is probably better off being a plugin for wails rather than a core feature. Notifications vary between platforms and is likely to change often. |
Windows Notification Feasible Solution: ShellNotifyIcon + SetCurrentProcessExplicitAppUserModelID or .rc Can anyone provide elegant solutions for Linux and macOS? Let's expedite the arrival of wails3! |
Is your feature request related to a problem? Please describe.
We want to show a notification toast to hint information to users, but it seems no such function in Wails and its roadmap.
Describe the solution you'd like
Notification should be added.
Describe alternatives you've considered
Toast function which is similiar to Android Toas.
Additional context
No response
The text was updated successfully, but these errors were encountered: