diff --git a/ElectronNET.API/Entities/NotificationAction.cs b/ElectronNET.API/Entities/NotificationAction.cs
new file mode 100644
index 0000000..25bee11
--- /dev/null
+++ b/ElectronNET.API/Entities/NotificationAction.cs
@@ -0,0 +1,15 @@
+namespace ElectronNET.API.Entities
+{
+ public class NotificationAction
+ {
+ ///
+ /// The label for the given action.
+ ///
+ public string Text { get; set; }
+
+ ///
+ /// The type of action, can be button.
+ ///
+ public string Type { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ElectronNET.API/Entities/NotificationOptions.cs b/ElectronNET.API/Entities/NotificationOptions.cs
index efa127f..f2fc91c 100644
--- a/ElectronNET.API/Entities/NotificationOptions.cs
+++ b/ElectronNET.API/Entities/NotificationOptions.cs
@@ -1,4 +1,7 @@
-namespace ElectronNET.API.Entities
+using Newtonsoft.Json;
+using System;
+
+namespace ElectronNET.API.Entities
{
public class NotificationOptions
{
@@ -44,6 +47,63 @@
///
public string Sound { get; set; }
+ ///
+ /// Actions to add to the notification. Please read the available actions and
+ /// limitations in the NotificationAction documentation
+ ///
+ public NotificationAction Actions { get; set; }
+
+ ///
+ /// Emitted when the notification is shown to the user,
+ /// note this could be fired multiple times as a notification
+ /// can be shown multiple times through the Show() method.
+ ///
+ [JsonIgnore]
+ public Action OnShow { get; set; }
+
+ [JsonProperty]
+ internal string ShowID { get; set; }
+
+ ///
+ /// Emitted when the notification is clicked by the user.
+ ///
+ [JsonIgnore]
+ public Action OnClick { get; set; }
+
+ [JsonProperty]
+ internal string ClickID { get; set; }
+
+ ///
+ /// Emitted when the notification is closed by manual intervention from the user.
+ ///
+ /// This event is not guarunteed to be emitted in all cases where the notification is closed.
+ ///
+ [JsonIgnore]
+ public Action OnClose { get; set; }
+
+ [JsonProperty]
+ internal string CloseID { get; set; }
+
+ ///
+ /// macOS only: Emitted when the user clicks the “Reply” button on a notification with hasReply: true.
+ ///
+ /// The string the user entered into the inline reply field
+ ///
+ [JsonIgnore]
+ public Action OnReply { get; set; }
+
+ [JsonProperty]
+ internal string ReplyID { get; set; }
+
+ ///
+ /// macOS only - The index of the action that was activated
+ ///
+ [JsonIgnore]
+ public Action OnAction { get; set; }
+
+ [JsonProperty]
+ internal string ActionID { get; set; }
+
public NotificationOptions(string title, string body)
{
Title = title;
diff --git a/ElectronNET.API/Notification.cs b/ElectronNET.API/Notification.cs
index ad396d0..b7fd081 100644
--- a/ElectronNET.API/Notification.cs
+++ b/ElectronNET.API/Notification.cs
@@ -2,6 +2,10 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
namespace ElectronNET.API
{
@@ -24,11 +28,105 @@ namespace ElectronNET.API
}
}
+ private static List _notificationOptions = new List();
+
+ ///
+ /// Create OS desktop notifications
+ ///
+ ///
public void Show(NotificationOptions notificationOptions)
{
+ GenerateIDsForDefinedActions(notificationOptions);
+
BridgeConnector.Socket.Emit("createNotification", JObject.FromObject(notificationOptions, _jsonSerializer));
}
+ private static void GenerateIDsForDefinedActions(NotificationOptions notificationOptions)
+ {
+ bool isActionDefined = false;
+
+ if (notificationOptions.OnShow != null)
+ {
+ notificationOptions.ShowID = Guid.NewGuid().ToString();
+ isActionDefined = true;
+
+ BridgeConnector.Socket.Off("NotificationEventShow");
+ BridgeConnector.Socket.On("NotificationEventShow", (id) => {
+ _notificationOptions.Single(x => x.ShowID == id.ToString()).OnShow();
+ });
+ }
+
+ if (notificationOptions.OnClick != null)
+ {
+ notificationOptions.ClickID = Guid.NewGuid().ToString();
+ isActionDefined = true;
+
+ BridgeConnector.Socket.Off("NotificationEventClick");
+ BridgeConnector.Socket.On("NotificationEventClick", (id) => {
+ _notificationOptions.Single(x => x.ClickID == id.ToString()).OnClick();
+ });
+ }
+
+ if (notificationOptions.OnClose != null)
+ {
+ notificationOptions.CloseID = Guid.NewGuid().ToString();
+ isActionDefined = true;
+
+ BridgeConnector.Socket.Off("NotificationEventClose");
+ BridgeConnector.Socket.On("NotificationEventClose", (id) => {
+ _notificationOptions.Single(x => x.CloseID == id.ToString()).OnClose();
+ });
+ }
+
+ if (notificationOptions.OnReply != null)
+ {
+ notificationOptions.ReplyID = Guid.NewGuid().ToString();
+ isActionDefined = true;
+
+ BridgeConnector.Socket.Off("NotificationEventReply");
+ BridgeConnector.Socket.On("NotificationEventReply", (args) => {
+ var arguments = ((JArray)args).ToObject();
+ _notificationOptions.Single(x => x.ReplyID == arguments[0].ToString()).OnReply(arguments[1].ToString());
+ });
+ }
+
+ if (notificationOptions.OnAction != null)
+ {
+ notificationOptions.ActionID = Guid.NewGuid().ToString();
+ isActionDefined = true;
+
+ BridgeConnector.Socket.Off("NotificationEventAction");
+ BridgeConnector.Socket.On("NotificationEventAction", (args) => {
+ var arguments = ((JArray)args).ToObject();
+ _notificationOptions.Single(x => x.ReplyID == arguments[0].ToString()).OnAction(arguments[1].ToString());
+ });
+ }
+
+ if (isActionDefined)
+ {
+ _notificationOptions.Add(notificationOptions);
+ }
+ }
+
+ ///
+ /// Whether or not desktop notifications are supported on the current system.
+ ///
+ ///
+ public Task IsSupportedAsync()
+ {
+ var taskCompletionSource = new TaskCompletionSource();
+
+ BridgeConnector.Socket.On("notificationIsSupportedComplete", (isSupported) =>
+ {
+ BridgeConnector.Socket.Off("notificationIsSupportedComplete");
+ taskCompletionSource.SetResult((bool)isSupported);
+ });
+
+ BridgeConnector.Socket.Emit("notificationIsSupported");
+
+ return taskCompletionSource.Task;
+ }
+
private JsonSerializer _jsonSerializer = new JsonSerializer()
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
diff --git a/ElectronNET.Host/api/notification.js b/ElectronNET.Host/api/notification.js
index 8ce83a7..020a153 100644
--- a/ElectronNET.Host/api/notification.js
+++ b/ElectronNET.Host/api/notification.js
@@ -1,10 +1,49 @@
"use strict";
exports.__esModule = true;
var electron_1 = require("electron");
+var notifications = [];
module.exports = function (socket) {
socket.on('createNotification', function (options) {
var notification = new electron_1.Notification(options);
+ var haveEvent = false;
+ if (options.showID) {
+ haveEvent = true;
+ notification.on('show', function () {
+ socket.emit('NotificationEventShow', options.showID);
+ });
+ }
+ if (options.clickID) {
+ haveEvent = true;
+ notification.on('click', function () {
+ socket.emit('NotificationEventClick', options.clickID);
+ });
+ }
+ if (options.closeID) {
+ haveEvent = true;
+ notification.on('close', function () {
+ socket.emit('NotificationEventClose', options.closeID);
+ });
+ }
+ if (options.replyID) {
+ haveEvent = true;
+ notification.on('reply', function (event, value) {
+ socket.emit('NotificationEventReply', [options.replyID, value]);
+ });
+ }
+ if (options.actionID) {
+ haveEvent = true;
+ notification.on('action', function (event, value) {
+ socket.emit('NotificationEventAction', [options.actionID, value]);
+ });
+ }
+ if (haveEvent) {
+ notifications.push(notification);
+ }
notification.show();
});
+ socket.on('notificationIsSupported', function (options) {
+ var isSupported = electron_1.Notification.isSupported;
+ socket.emit('notificationIsSupportedComplete', isSupported);
+ });
};
//# sourceMappingURL=notification.js.map
\ No newline at end of file
diff --git a/ElectronNET.Host/api/notification.js.map b/ElectronNET.Host/api/notification.js.map
index b7d3ab1..85c75b9 100644
--- a/ElectronNET.Host/api/notification.js.map
+++ b/ElectronNET.Host/api/notification.js.map
@@ -1 +1 @@
-{"version":3,"file":"notification.js","sourceRoot":"","sources":["notification.ts"],"names":[],"mappings":";;AAAA,qCAAwC;AAExC,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB;IACrC,MAAM,CAAC,EAAE,CAAC,oBAAoB,EAAE,UAAC,OAAO;QACpC,IAAM,YAAY,GAAG,IAAI,uBAAY,CAAC,OAAO,CAAC,CAAC;QAC/C,YAAY,CAAC,IAAI,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;AACP,CAAC,CAAA"}
\ No newline at end of file
+{"version":3,"file":"notification.js","sourceRoot":"","sources":["notification.ts"],"names":[],"mappings":";;AAAA,qCAAwC;AACxC,IAAM,aAAa,GAA4B,EAAE,CAAC;AAElD,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB;IACrC,MAAM,CAAC,EAAE,CAAC,oBAAoB,EAAE,UAAC,OAAO;QACpC,IAAM,YAAY,GAAG,IAAI,uBAAY,CAAC,OAAO,CAAC,CAAC;QAC/C,IAAI,SAAS,GAAG,KAAK,CAAC;QAEtB,EAAE,CAAA,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;YAChB,SAAS,GAAG,IAAI,CAAC;YACjB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE;gBACpB,MAAM,CAAC,IAAI,CAAC,uBAAuB,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;YACzD,CAAC,CAAC,CAAC;QACP,CAAC;QAED,EAAE,CAAA,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;YACjB,SAAS,GAAG,IAAI,CAAC;YACjB,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE;gBACrB,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;YAC3D,CAAC,CAAC,CAAC;QACP,CAAC;QAED,EAAE,CAAA,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;YACjB,SAAS,GAAG,IAAI,CAAC;YACjB,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE;gBACrB,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;YAC3D,CAAC,CAAC,CAAC;QACP,CAAC;QAED,EAAE,CAAA,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;YACjB,SAAS,GAAG,IAAI,CAAC;YACjB,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,UAAC,KAAK,EAAE,KAAK;gBAClC,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;YACpE,CAAC,CAAC,CAAC;QACP,CAAC;QAED,EAAE,CAAA,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;YAClB,SAAS,GAAG,IAAI,CAAC;YACjB,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAC,KAAK,EAAE,KAAK;gBACnC,MAAM,CAAC,IAAI,CAAC,yBAAyB,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;YACtE,CAAC,CAAC,CAAC;QACP,CAAC;QAED,EAAE,CAAA,CAAC,SAAS,CAAC,CAAC,CAAC;YACX,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACrC,CAAC;QAED,YAAY,CAAC,IAAI,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,yBAAyB,EAAE,UAAC,OAAO;QACzC,IAAM,WAAW,GAAG,uBAAY,CAAC,WAAW,CAAC;QAC7C,MAAM,CAAC,IAAI,CAAC,iCAAiC,EAAE,WAAW,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;AACP,CAAC,CAAA"}
\ No newline at end of file
diff --git a/ElectronNET.Host/api/notification.ts b/ElectronNET.Host/api/notification.ts
index 2264373..b388a4e 100644
--- a/ElectronNET.Host/api/notification.ts
+++ b/ElectronNET.Host/api/notification.ts
@@ -1,8 +1,55 @@
import { Notification } from "electron";
+const notifications: Electron.Notification[] = [];
module.exports = (socket: SocketIO.Server) => {
socket.on('createNotification', (options) => {
const notification = new Notification(options);
+ let haveEvent = false;
+
+ if(options.showID) {
+ haveEvent = true;
+ notification.on('show', () => {
+ socket.emit('NotificationEventShow', options.showID);
+ });
+ }
+
+ if(options.clickID) {
+ haveEvent = true;
+ notification.on('click', () => {
+ socket.emit('NotificationEventClick', options.clickID);
+ });
+ }
+
+ if(options.closeID) {
+ haveEvent = true;
+ notification.on('close', () => {
+ socket.emit('NotificationEventClose', options.closeID);
+ });
+ }
+
+ if(options.replyID) {
+ haveEvent = true;
+ notification.on('reply', (event, value) => {
+ socket.emit('NotificationEventReply', [options.replyID, value]);
+ });
+ }
+
+ if(options.actionID) {
+ haveEvent = true;
+ notification.on('action', (event, value) => {
+ socket.emit('NotificationEventAction', [options.actionID, value]);
+ });
+ }
+
+ if(haveEvent) {
+ notifications.push(notification);
+ }
+
notification.show();
});
+
+ socket.on('notificationIsSupported', (options) => {
+ const isSupported = Notification.isSupported;
+ socket.emit('notificationIsSupportedComplete', isSupported);
+ });
}
\ No newline at end of file
diff --git a/ElectronNET.WebApp/Controllers/HomeController.cs b/ElectronNET.WebApp/Controllers/HomeController.cs
index 12792a1..e939029 100644
--- a/ElectronNET.WebApp/Controllers/HomeController.cs
+++ b/ElectronNET.WebApp/Controllers/HomeController.cs
@@ -11,7 +11,13 @@ namespace ElectronNET.WebApp.Controllers
{
Electron.IpcMain.On("SayHello", async (args) =>
{
- Electron.Notification.Show(new NotificationOptions("Hallo Robert", "Nachricht von ASP.NET Core App"));
+ Electron.Notification.Show(new NotificationOptions("Hallo Robert", "Nachricht von ASP.NET Core App") {
+ OnClick = async () => { await Electron.Dialog.ShowMessageBoxAsync(new MessageBoxOptions("Notification clicked")); },
+ OnShow = async () => { await Electron.Dialog.ShowMessageBoxAsync(new MessageBoxOptions("Notification show")); },
+ OnClose = async () => { await Electron.Dialog.ShowMessageBoxAsync(new MessageBoxOptions("Notification closed")); },
+ OnAction = async (value) => { await Electron.Dialog.ShowMessageBoxAsync(new MessageBoxOptions("Notification Action")); },
+ OnReply = async (value) => { await Electron.Dialog.ShowMessageBoxAsync(new MessageBoxOptions("Notification Reply")); }
+ });
Electron.IpcMain.Send(Electron.WindowManager.BrowserWindows.First(), "Goodbye", "Elephant!");
var currentBrowserWindow = Electron.WindowManager.BrowserWindows.First();
@@ -28,6 +34,8 @@ namespace ElectronNET.WebApp.Controllers
Electron.IpcMain.On("GetPath", async (args) =>
{
+ Electron.Notification.Show(new NotificationOptions("test", "test2"));
+
var currentBrowserWindow = Electron.WindowManager.BrowserWindows.First();
string pathName = await Electron.App.GetPathAsync(PathName.pictures);