diff --git a/ElectronNET.API/App.cs b/ElectronNET.API/App.cs
index 4d4c86a..e4849ad 100644
--- a/ElectronNET.API/App.cs
+++ b/ElectronNET.API/App.cs
@@ -280,12 +280,6 @@ namespace ElectronNET.API
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
- // TODO: Auslagern in eigenes Notification-API
- public void CreateNotification(NotificationOptions notificationOptions)
- {
- BridgeConnector.Socket.Emit("createNotification", JObject.FromObject(notificationOptions, _jsonSerializer));
- }
-
///
/// Try to close all windows. The before-quit event will be emitted first. If all
/// windows are successfully closed, the will-quit event will be emitted and by
diff --git a/ElectronNET.API/Dialog.cs b/ElectronNET.API/Dialog.cs
new file mode 100644
index 0000000..f47afac
--- /dev/null
+++ b/ElectronNET.API/Dialog.cs
@@ -0,0 +1,89 @@
+using ElectronNET.API.Entities;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Serialization;
+using System;
+using System.Threading.Tasks;
+
+namespace ElectronNET.API
+{
+ public sealed class Dialog
+ {
+ private static Dialog _dialog;
+
+ internal Dialog() { }
+
+ internal static Dialog Instance
+ {
+ get
+ {
+ if (_dialog == null)
+ {
+ _dialog = new Dialog();
+ }
+
+ return _dialog;
+ }
+ }
+
+ ///
+ /// Shows a message box, it will block the process until the message box is closed.
+ /// It returns the index of the clicked button. The browserWindow argument allows
+ /// the dialog to attach itself to a parent window, making it modal. If a callback
+ /// is passed, the dialog will not block the process.The API call will be
+ /// asynchronous and the result will be passed via callback(response).
+ ///
+ ///
+ /// The API call will be asynchronous and the result will be passed via MessageBoxResult.
+ public async Task ShowMessageBoxAsync(MessageBoxOptions messageBoxOptions)
+ {
+ return await ShowMessageBoxAsync(null, messageBoxOptions);
+ }
+
+ ///
+ /// Shows a message box, it will block the process until the message box is closed.
+ /// It returns the index of the clicked button. If a callback
+ /// is passed, the dialog will not block the process.
+ ///
+ /// The browserWindow argument allows the dialog to attach itself to a parent window, making it modal.
+ ///
+ /// The API call will be asynchronous and the result will be passed via MessageBoxResult.
+ public Task ShowMessageBoxAsync(BrowserWindow browserWindow, MessageBoxOptions messageBoxOptions)
+ {
+ var taskCompletionSource = new TaskCompletionSource();
+
+ BridgeConnector.Socket.On("showMessageBoxComplete", (args) =>
+ {
+ BridgeConnector.Socket.Off("showMessageBoxComplete");
+
+ var result = ((JArray)args);
+
+ taskCompletionSource.SetResult(new MessageBoxResult
+ {
+ Response = (int)result.First,
+ CheckboxChecked = (bool)result.Last
+ });
+
+ });
+
+ if (browserWindow == null)
+ {
+ BridgeConnector.Socket.Emit("showMessageBox", JObject.FromObject(messageBoxOptions, _jsonSerializer));
+ } else
+ {
+ BridgeConnector.Socket.Emit("showMessageBox",
+ JObject.FromObject(browserWindow, _jsonSerializer),
+ JObject.FromObject(messageBoxOptions, _jsonSerializer));
+ }
+
+ return taskCompletionSource.Task;
+ }
+
+ private JsonSerializer _jsonSerializer = new JsonSerializer()
+ {
+ ContractResolver = new CamelCasePropertyNamesContractResolver(),
+ NullValueHandling = NullValueHandling.Ignore,
+ DefaultValueHandling = DefaultValueHandling.Ignore
+ };
+ }
+}
diff --git a/ElectronNET.API/Electron.cs b/ElectronNET.API/Electron.cs
index 0a551b0..6002677 100644
--- a/ElectronNET.API/Electron.cs
+++ b/ElectronNET.API/Electron.cs
@@ -21,5 +21,20 @@
/// Create native application menus and context menus.
///
public static Menu Menu { get { return Menu.Instance; } }
+
+ ///
+ /// Display native system dialogs for opening and saving files, alerting, etc.
+ ///
+ public static Dialog Dialog { get { return Dialog.Instance; } }
+
+ ///
+ /// Create OS desktop notifications
+ ///
+ public static Notification Notification { get { return Notification.Instance; } }
+
+ ///
+ /// Add icons and context menus to the system’s notification area.
+ ///
+ public static Tray Tray { get { return Tray.Instance; } }
}
}
diff --git a/ElectronNET.API/Entities/MessageBoxOptions.cs b/ElectronNET.API/Entities/MessageBoxOptions.cs
new file mode 100644
index 0000000..960471c
--- /dev/null
+++ b/ElectronNET.API/Entities/MessageBoxOptions.cs
@@ -0,0 +1,84 @@
+namespace ElectronNET.API.Entities
+{
+ public class MessageBoxOptions
+ {
+ ///
+ /// Can be "none", "info", "error", "question" or "warning". On Windows, "question"
+ /// displays the same icon as "info", unless you set an icon using the "icon"
+ /// option.On macOS, both "warning" and "error" display the same warning icon.
+ ///
+ public string Type { get; set; }
+
+ ///
+ /// Array of texts for buttons. On Windows, an empty array will result in one button
+ /// labeled "OK".
+ ///
+ public string[] Buttons { get; set; }
+
+ ///
+ /// Index of the button in the buttons array which will be selected by default when
+ /// the message box opens.
+ ///
+ public int DefaultId { get; set; }
+
+ ///
+ /// Title of the message box, some platforms will not show it.
+ ///
+ public string Title { get; set; }
+
+ ///
+ /// Content of the message box.
+ ///
+ public string Message { get; set; }
+
+ ///
+ /// Extra information of the message.
+ ///
+ public string Detail { get; set; }
+
+ ///
+ /// If provided, the message box will include a checkbox with the given label. The
+ /// checkbox state can be inspected only when using callback.
+ ///
+ public string CheckboxLabel { get; set; }
+
+ ///
+ /// Initial checked state of the checkbox. false by default.
+ ///
+ public bool CheckboxChecked { get; set; }
+
+ public string Icon { get; set; }
+
+ ///
+ /// The index of the button to be used to cancel the dialog, via the Esc key. By
+ /// default this is assigned to the first button with "cancel" or "no" as the label.
+ /// If no such labeled buttons exist and this option is not set, 0 will be used as
+ /// the return value or callback response. This option is ignored on Windows.
+ ///
+ public int CancelId { get; set; }
+
+ ///
+ /// On Windows Electron will try to figure out which one of the buttons are common
+ /// buttons(like "Cancel" or "Yes"), and show the others as command links in the
+ /// dialog.This can make the dialog appear in the style of modern Windows apps. If
+ /// you don't like this behavior, you can set noLink to true.
+ ///
+ public bool NoLink { get; set; }
+
+ ///
+ /// Normalize the keyboard access keys across platforms. Default is false. Enabling
+ /// this assumes & is used in the button labels for the placement of the keyboard
+ /// shortcut access key and labels will be converted so they work correctly on each
+ /// platform, & characters are removed on macOS, converted to _ on Linux, and left
+ /// untouched on Windows.For example, a button label of Vie&w will be converted to
+ /// Vie_w on Linux and View on macOS and can be selected via Alt-W on Windows and
+ /// Linux.
+ ///
+ public bool NormalizeAccessKeys { get; set; }
+
+ public MessageBoxOptions(string message)
+ {
+ Message = message;
+ }
+ }
+}
diff --git a/ElectronNET.API/Entities/MessageBoxResult.cs b/ElectronNET.API/Entities/MessageBoxResult.cs
new file mode 100644
index 0000000..20a19b6
--- /dev/null
+++ b/ElectronNET.API/Entities/MessageBoxResult.cs
@@ -0,0 +1,9 @@
+namespace ElectronNET.API.Entities
+{
+ public class MessageBoxResult
+ {
+ public int Response { get; set; }
+
+ public bool CheckboxChecked { get; set; }
+ }
+}
diff --git a/ElectronNET.API/Entities/NotificationOptions.cs b/ElectronNET.API/Entities/NotificationOptions.cs
index b58e954..efa127f 100644
--- a/ElectronNET.API/Entities/NotificationOptions.cs
+++ b/ElectronNET.API/Entities/NotificationOptions.cs
@@ -2,7 +2,52 @@
{
public class NotificationOptions
{
+ ///
+ /// A title for the notification, which will be shown at the top of the notification
+ /// window when it is shown
+ ///
public string Title { get; set; }
+
+ ///
+ /// The body text of the notification, which will be displayed below the title or
+ /// subtitle
+ ///
public string Body { get; set; }
+
+ ///
+ /// A subtitle for the notification, which will be displayed below the title.
+ ///
+ public string Subtitle { get; set; }
+
+ ///
+ /// Whether or not to emit an OS notification noise when showing the notification
+ ///
+ public bool Silent { get; set; }
+
+ ///
+ /// An icon to use in the notification
+ ///
+ public string Icon { get; set; }
+
+ ///
+ /// Whether or not to add an inline reply option to the notification.
+ ///
+ public bool HasReply { get; set; }
+
+ ///
+ /// The placeholder to write in the inline reply input field.
+ ///
+ public string ReplyPlaceholder { get; set; }
+
+ ///
+ /// The name of the sound file to play when the notification is shown.
+ ///
+ public string Sound { get; set; }
+
+ public NotificationOptions(string title, string body)
+ {
+ Title = title;
+ Body = body;
+ }
}
}
diff --git a/ElectronNET.API/Notification.cs b/ElectronNET.API/Notification.cs
new file mode 100644
index 0000000..ad396d0
--- /dev/null
+++ b/ElectronNET.API/Notification.cs
@@ -0,0 +1,39 @@
+using ElectronNET.API.Entities;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Serialization;
+
+namespace ElectronNET.API
+{
+ public sealed class Notification
+ {
+ private static Notification _notification;
+
+ internal Notification() { }
+
+ internal static Notification Instance
+ {
+ get
+ {
+ if (_notification == null)
+ {
+ _notification = new Notification();
+ }
+
+ return _notification;
+ }
+ }
+
+ public void Show(NotificationOptions notificationOptions)
+ {
+ BridgeConnector.Socket.Emit("createNotification", JObject.FromObject(notificationOptions, _jsonSerializer));
+ }
+
+ private JsonSerializer _jsonSerializer = new JsonSerializer()
+ {
+ ContractResolver = new CamelCasePropertyNamesContractResolver(),
+ NullValueHandling = NullValueHandling.Ignore,
+ DefaultValueHandling = DefaultValueHandling.Ignore
+ };
+ }
+}
diff --git a/ElectronNET.API/Tray.cs b/ElectronNET.API/Tray.cs
new file mode 100644
index 0000000..417812e
--- /dev/null
+++ b/ElectronNET.API/Tray.cs
@@ -0,0 +1,39 @@
+using ElectronNET.API.Entities;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Serialization;
+
+namespace ElectronNET.API
+{
+ public sealed class Tray
+ {
+ private static Tray _tray;
+
+ internal Tray() { }
+
+ internal static Tray Instance
+ {
+ get
+ {
+ if (_tray == null)
+ {
+ _tray = new Tray();
+ }
+
+ return _tray;
+ }
+ }
+
+ public void Show(string image, MenuItem[] menuItems)
+ {
+ BridgeConnector.Socket.Emit("create-tray", image, JArray.FromObject(menuItems, _jsonSerializer));
+ }
+
+ private JsonSerializer _jsonSerializer = new JsonSerializer()
+ {
+ ContractResolver = new CamelCasePropertyNamesContractResolver(),
+ NullValueHandling = NullValueHandling.Ignore,
+ DefaultValueHandling = DefaultValueHandling.Ignore
+ };
+ }
+}
diff --git a/ElectronNET.CLI/Commands/BuildCommand.cs b/ElectronNET.CLI/Commands/BuildCommand.cs
index 7e3b366..66503b9 100644
--- a/ElectronNET.CLI/Commands/BuildCommand.cs
+++ b/ElectronNET.CLI/Commands/BuildCommand.cs
@@ -42,6 +42,10 @@ namespace ElectronNET.CLI.Commands
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "ipc.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "app.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "browserWindows.js", "api.");
+ EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "dialog.js", "api.");
+ EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "menu.js", "api.");
+ EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "notification.js", "api.");
+ EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "tray.js", "api.");
Console.WriteLine("Start npm install...");
ProcessHelper.CmdExecute("npm install", tempPath);
diff --git a/ElectronNET.CLI/Commands/StartElectronCommand.cs b/ElectronNET.CLI/Commands/StartElectronCommand.cs
index 8dd5159..474e1da 100644
--- a/ElectronNET.CLI/Commands/StartElectronCommand.cs
+++ b/ElectronNET.CLI/Commands/StartElectronCommand.cs
@@ -61,6 +61,10 @@ namespace ElectronNET.CLI.Commands
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "ipc.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "app.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "browserWindows.js", "api.");
+ EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "dialog.js", "api.");
+ EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "menu.js", "api.");
+ EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "notification.js", "api.");
+ EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "tray.js", "api.");
Console.WriteLine("Start npm install...");
ProcessHelper.CmdExecute("npm install", tempPath);
diff --git a/ElectronNET.CLI/ElectronNET.CLI.csproj b/ElectronNET.CLI/ElectronNET.CLI.csproj
index b530400..994d6f5 100644
--- a/ElectronNET.CLI/ElectronNET.CLI.csproj
+++ b/ElectronNET.CLI/ElectronNET.CLI.csproj
@@ -39,4 +39,11 @@
+
+
+
+
+
+
+
diff --git a/ElectronNET.Host/api/browserWindows.js b/ElectronNET.Host/api/browserWindows.js
index 85b812c..39efbb2 100644
--- a/ElectronNET.Host/api/browserWindows.js
+++ b/ElectronNET.Host/api/browserWindows.js
@@ -19,6 +19,7 @@ module.exports = function (socket) {
}
}
});
+ // TODO: IPC Lösung für mehrere Fenster finden
if (ipc == undefined) {
ipc = require('./ipc')(socket, window);
}
diff --git a/ElectronNET.Host/api/browserWindows.js.map b/ElectronNET.Host/api/browserWindows.js.map
index f1c28ff..3e67861 100644
--- a/ElectronNET.Host/api/browserWindows.js.map
+++ b/ElectronNET.Host/api/browserWindows.js.map
@@ -1 +1 @@
-{"version":3,"file":"browserWindows.js","sourceRoot":"","sources":["browserWindows.ts"],"names":[],"mappings":";;AAAA,qCAAyC;AACzC,IAAI,OAAO,GAA6B,EAAE,CAAA;AAC1C,IAAI,GAAG,CAAC;AAER,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB;IACrC,MAAM,CAAC,EAAE,CAAC,qBAAqB,EAAE,UAAC,OAAO,EAAE,OAAO;QAC9C,IAAI,MAAM,GAAG,IAAI,wBAAa,CAAC,OAAO,CAAC,CAAC;QAExC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAC,MAAM;YACvB,GAAG,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;gBAClD,IAAI,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;gBAChC,IAAI,CAAC;oBACD,UAAU,CAAC,EAAE,CAAC;gBAClB,CAAC;gBAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;oBACb,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,KAAK,2BAA2B,CAAC,CAAC,CAAC;wBAChD,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;oBAC7B,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,CAAC,GAAG,IAAI,SAAS,CAAC,CAAC,CAAC;YACnB,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC3C,CAAC;QAED,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YACV,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC5B,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrB,MAAM,CAAC,IAAI,CAAC,sBAAsB,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,wBAAwB,EAAE,UAAC,EAAE;QACnC,aAAa,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,uBAAuB,EAAU;QAC7B,GAAG,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;YAClD,IAAI,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;YAC7B,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;gBACnB,MAAM,CAAC,OAAO,CAAC;YACnB,CAAC;QACL,CAAC;IACL,CAAC;AACL,CAAC,CAAA"}
\ No newline at end of file
+{"version":3,"file":"browserWindows.js","sourceRoot":"","sources":["browserWindows.ts"],"names":[],"mappings":";;AAAA,qCAAyC;AACzC,IAAI,OAAO,GAA6B,EAAE,CAAA;AAC1C,IAAI,GAAG,CAAC;AAER,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB;IACrC,MAAM,CAAC,EAAE,CAAC,qBAAqB,EAAE,UAAC,OAAO,EAAE,OAAO;QAC9C,IAAI,MAAM,GAAG,IAAI,wBAAa,CAAC,OAAO,CAAC,CAAC;QAExC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAC,MAAM;YACvB,GAAG,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;gBAClD,IAAI,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;gBAChC,IAAI,CAAC;oBACD,UAAU,CAAC,EAAE,CAAC;gBAClB,CAAC;gBAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;oBACb,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,KAAK,2BAA2B,CAAC,CAAC,CAAC;wBAChD,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;oBAC7B,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,+CAA+C;QAC/C,EAAE,CAAC,CAAC,GAAG,IAAI,SAAS,CAAC,CAAC,CAAC;YACnB,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC3C,CAAC;QAED,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YACV,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC5B,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrB,MAAM,CAAC,IAAI,CAAC,sBAAsB,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,wBAAwB,EAAE,UAAC,EAAE;QACnC,aAAa,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,uBAAuB,EAAU;QAC7B,GAAG,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;YAClD,IAAI,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;YAC7B,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;gBACnB,MAAM,CAAC,OAAO,CAAC;YACnB,CAAC;QACL,CAAC;IACL,CAAC;AACL,CAAC,CAAA"}
\ No newline at end of file
diff --git a/ElectronNET.Host/api/dialog.js b/ElectronNET.Host/api/dialog.js
new file mode 100644
index 0000000..e3f106e
--- /dev/null
+++ b/ElectronNET.Host/api/dialog.js
@@ -0,0 +1,19 @@
+"use strict";
+exports.__esModule = true;
+var electron_1 = require("electron");
+module.exports = function (socket) {
+ socket.on('showMessageBox', function (browserWindow, options) {
+ if ("id" in browserWindow) {
+ var window = electron_1.BrowserWindow.fromId(browserWindow.id);
+ electron_1.dialog.showMessageBox(window, options, function (response, checkboxChecked) {
+ socket.emit('showMessageBoxComplete', response, checkboxChecked);
+ });
+ }
+ else {
+ electron_1.dialog.showMessageBox(browserWindow, function (response, checkboxChecked) {
+ socket.emit('showMessageBoxComplete', response, checkboxChecked);
+ });
+ }
+ });
+};
+//# sourceMappingURL=dialog.js.map
\ No newline at end of file
diff --git a/ElectronNET.Host/api/dialog.js.map b/ElectronNET.Host/api/dialog.js.map
new file mode 100644
index 0000000..f7a9d8d
--- /dev/null
+++ b/ElectronNET.Host/api/dialog.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"dialog.js","sourceRoot":"","sources":["dialog.ts"],"names":[],"mappings":";;AAAA,qCAAiD;AAEjD,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB;IACrC,MAAM,CAAC,EAAE,CAAC,gBAAgB,EAAE,UAAC,aAAa,EAAE,OAAO;QAC/C,EAAE,CAAA,CAAC,IAAI,IAAI,aAAa,CAAC,CAAC,CAAC;YACvB,IAAI,MAAM,GAAG,wBAAa,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;YAEpD,iBAAM,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,UAAC,QAAQ,EAAE,eAAe;gBAC7D,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;YACrE,CAAC,CAAC,CAAC;QACP,CAAC;QAAC,IAAI,CAAC,CAAC;YACJ,iBAAM,CAAC,cAAc,CAAC,aAAa,EAAE,UAAC,QAAQ,EAAE,eAAe;gBAC3D,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;YACrE,CAAC,CAAC,CAAC;QACP,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC,CAAA"}
\ No newline at end of file
diff --git a/ElectronNET.Host/api/dialog.ts b/ElectronNET.Host/api/dialog.ts
new file mode 100644
index 0000000..c445e51
--- /dev/null
+++ b/ElectronNET.Host/api/dialog.ts
@@ -0,0 +1,17 @@
+import { BrowserWindow, dialog } from "electron";
+
+module.exports = (socket: SocketIO.Server) => {
+ socket.on('showMessageBox', (browserWindow, options) => {
+ if("id" in browserWindow) {
+ var window = BrowserWindow.fromId(browserWindow.id);
+
+ dialog.showMessageBox(window, options, (response, checkboxChecked) => {
+ socket.emit('showMessageBoxComplete', response, checkboxChecked);
+ });
+ } else {
+ dialog.showMessageBox(browserWindow, (response, checkboxChecked) => {
+ socket.emit('showMessageBoxComplete', response, checkboxChecked);
+ });
+ }
+ });
+}
\ No newline at end of file
diff --git a/ElectronNET.Host/api/menu.js b/ElectronNET.Host/api/menu.js
new file mode 100644
index 0000000..4eb7eb3
--- /dev/null
+++ b/ElectronNET.Host/api/menu.js
@@ -0,0 +1,23 @@
+"use strict";
+exports.__esModule = true;
+var electron_1 = require("electron");
+module.exports = function (socket) {
+ socket.on('menu-setApplicationMenu', function (menuItems) {
+ var menu = electron_1.Menu.buildFromTemplate(menuItems);
+ addMenuItemClickConnector(menu.items, function (id) {
+ socket.emit("menuItemClicked", id);
+ });
+ electron_1.Menu.setApplicationMenu(menu);
+ });
+ function addMenuItemClickConnector(menuItems, callback) {
+ menuItems.forEach(function (item) {
+ if (item.submenu && item.submenu.items.length > 0) {
+ addMenuItemClickConnector(item.submenu.items, callback);
+ }
+ if ("id" in item && item.id) {
+ item.click = function () { callback(item.id); };
+ }
+ });
+ }
+};
+//# sourceMappingURL=menu.js.map
\ No newline at end of file
diff --git a/ElectronNET.Host/api/menu.js.map b/ElectronNET.Host/api/menu.js.map
new file mode 100644
index 0000000..94adcce
--- /dev/null
+++ b/ElectronNET.Host/api/menu.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"menu.js","sourceRoot":"","sources":["menu.ts"],"names":[],"mappings":";;AAAA,qCAAgC;AAEhC,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB;IACrC,MAAM,CAAC,EAAE,CAAC,yBAAyB,EAAE,UAAC,SAAS;QAC3C,IAAM,IAAI,GAAG,eAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAE/C,yBAAyB,CAAC,IAAI,CAAC,KAAK,EAAE,UAAC,EAAE;YACrC,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,eAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,mCAAmC,SAAS,EAAE,QAAQ;QAClD,SAAS,CAAC,OAAO,CAAC,UAAC,IAAI;YACnB,EAAE,CAAA,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC/C,yBAAyB,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YAC5D,CAAC;YAED,EAAE,CAAA,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBACzB,IAAI,CAAC,KAAK,GAAG,cAAQ,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9C,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;AACL,CAAC,CAAA"}
\ No newline at end of file
diff --git a/ElectronNET.Host/api/menu.ts b/ElectronNET.Host/api/menu.ts
new file mode 100644
index 0000000..1d96344
--- /dev/null
+++ b/ElectronNET.Host/api/menu.ts
@@ -0,0 +1,25 @@
+import { Menu } from "electron";
+
+module.exports = (socket: SocketIO.Server) => {
+ socket.on('menu-setApplicationMenu', (menuItems) => {
+ const menu = Menu.buildFromTemplate(menuItems);
+
+ addMenuItemClickConnector(menu.items, (id) => {
+ socket.emit("menuItemClicked", id);
+ });
+
+ Menu.setApplicationMenu(menu);
+ });
+
+ function addMenuItemClickConnector(menuItems, callback) {
+ menuItems.forEach((item) => {
+ if(item.submenu && item.submenu.items.length > 0) {
+ addMenuItemClickConnector(item.submenu.items, callback);
+ }
+
+ if("id" in item && item.id) {
+ item.click = () => { callback(item.id); };
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/ElectronNET.Host/api/notification.js b/ElectronNET.Host/api/notification.js
new file mode 100644
index 0000000..8ce83a7
--- /dev/null
+++ b/ElectronNET.Host/api/notification.js
@@ -0,0 +1,10 @@
+"use strict";
+exports.__esModule = true;
+var electron_1 = require("electron");
+module.exports = function (socket) {
+ socket.on('createNotification', function (options) {
+ var notification = new electron_1.Notification(options);
+ notification.show();
+ });
+};
+//# 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
new file mode 100644
index 0000000..b7d3ab1
--- /dev/null
+++ b/ElectronNET.Host/api/notification.js.map
@@ -0,0 +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
diff --git a/ElectronNET.Host/api/notification.ts b/ElectronNET.Host/api/notification.ts
new file mode 100644
index 0000000..2264373
--- /dev/null
+++ b/ElectronNET.Host/api/notification.ts
@@ -0,0 +1,8 @@
+import { Notification } from "electron";
+
+module.exports = (socket: SocketIO.Server) => {
+ socket.on('createNotification', (options) => {
+ const notification = new Notification(options);
+ notification.show();
+ });
+}
\ No newline at end of file
diff --git a/ElectronNET.Host/api/tray.js b/ElectronNET.Host/api/tray.js
new file mode 100644
index 0000000..8cc6e97
--- /dev/null
+++ b/ElectronNET.Host/api/tray.js
@@ -0,0 +1,14 @@
+"use strict";
+exports.__esModule = true;
+var electron_1 = require("electron");
+var path = require('path');
+var tray;
+module.exports = function (socket) {
+ socket.on('create-tray', function (image, menuItems) {
+ var menu = electron_1.Menu.buildFromTemplate(menuItems);
+ var imagePath = path.join(__dirname.replace('api', ''), 'bin', image);
+ tray = new electron_1.Tray(imagePath);
+ tray.setContextMenu(menu);
+ });
+};
+//# sourceMappingURL=tray.js.map
\ No newline at end of file
diff --git a/ElectronNET.Host/api/tray.js.map b/ElectronNET.Host/api/tray.js.map
new file mode 100644
index 0000000..6ceee68
--- /dev/null
+++ b/ElectronNET.Host/api/tray.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"tray.js","sourceRoot":"","sources":["tray.ts"],"names":[],"mappings":";;AAAA,qCAAsC;AACtC,IAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAC7B,IAAI,IAAI,CAAC;AAET,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB;IACrC,MAAM,CAAC,EAAE,CAAC,aAAa,EAAE,UAAC,KAAK,EAAE,SAAS;QACtC,IAAM,IAAI,GAAG,eAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAE/C,IAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAExE,IAAI,GAAG,IAAI,eAAI,CAAC,SAAS,CAAC,CAAC;QAC3B,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;AACP,CAAC,CAAA"}
\ No newline at end of file
diff --git a/ElectronNET.Host/api/tray.ts b/ElectronNET.Host/api/tray.ts
new file mode 100644
index 0000000..a0ec1c8
--- /dev/null
+++ b/ElectronNET.Host/api/tray.ts
@@ -0,0 +1,14 @@
+import { Menu, Tray } from "electron";
+const path = require('path');
+let tray;
+
+module.exports = (socket: SocketIO.Server) => {
+ socket.on('create-tray', (image, menuItems) => {
+ const menu = Menu.buildFromTemplate(menuItems);
+
+ const imagePath = path.join(__dirname.replace('api', ''), 'bin', image);
+
+ tray = new Tray(imagePath);
+ tray.setContextMenu(menu);
+ });
+}
\ No newline at end of file
diff --git a/ElectronNET.Host/main.js b/ElectronNET.Host/main.js
index 0fcca2e..4c01f71 100644
--- a/ElectronNET.Host/main.js
+++ b/ElectronNET.Host/main.js
@@ -1,9 +1,9 @@
-const { app, Notification, Menu } = require('electron');
+const { app } = require('electron');
const fs = require('fs');
const path = require('path');
const process = require('child_process').spawn;
const portfinder = require('detect-port');
-let io, browserWindows, apiProcess, loadURL, appApi;
+let io, browserWindows, apiProcess, loadURL, appApi, menu, dialog, notification, tray;
app.on('ready', () => {
portfinder(8000, (error, port) => {
@@ -17,36 +17,13 @@ function startSocketApiBridge(port) {
io.on('connection', (socket) => {
console.log('ASP.NET Core Application connected...');
+
appApi = require('./api/app')(socket, app);
browserWindows = require('./api/browserWindows')(socket);
-
- socket.on('menu-setApplicationMenu', (menuItems) => {
- const menu = Menu.buildFromTemplate(menuItems);
-
- addMenuItemClickConnector(menu.items, (id) => {
- socket.emit("menuItemClicked", id);
- });
-
- Menu.setApplicationMenu(menu);
- });
-
- socket.on('createNotification', (options) => {
- const notification = new Notification(options);
- notification.show();
- });
-
- });
-}
-
-function addMenuItemClickConnector(menuItems, callback) {
- menuItems.forEach((item) => {
- if(item.submenu && item.submenu.items.length > 0) {
- addMenuItemClickConnector(item.submenu.items, callback);
- }
-
- if("id" in item && item.id) {
- item.click = () => { callback(item.id); };
- }
+ menu = require('./api/menu')(socket);
+ dialog = require('./api/dialog')(socket);
+ notification = require('./api/notification')(socket);
+ tray = require('./api/tray')(socket);
});
}
diff --git a/ElectronNET.WebApp/Assets/electron.ico b/ElectronNET.WebApp/Assets/electron.ico
new file mode 100644
index 0000000..3a10449
Binary files /dev/null and b/ElectronNET.WebApp/Assets/electron.ico differ
diff --git a/ElectronNET.WebApp/Assets/electron_32x32.png b/ElectronNET.WebApp/Assets/electron_32x32.png
new file mode 100644
index 0000000..125dde6
Binary files /dev/null and b/ElectronNET.WebApp/Assets/electron_32x32.png differ
diff --git a/ElectronNET.WebApp/Controllers/HomeController.cs b/ElectronNET.WebApp/Controllers/HomeController.cs
index 3dea985..5f2146c 100644
--- a/ElectronNET.WebApp/Controllers/HomeController.cs
+++ b/ElectronNET.WebApp/Controllers/HomeController.cs
@@ -10,11 +10,7 @@ namespace ElectronNET.WebApp.Controllers
public IActionResult Index()
{
Electron.IpcMain.On("SayHello", (args) => {
- Electron.App.CreateNotification(new NotificationOptions
- {
- Title = "Hallo Robert",
- Body = "Nachricht von ASP.NET Core App"
- });
+ Electron.Notification.Show(new NotificationOptions("Hallo Robert","Nachricht von ASP.NET Core App"));
Electron.IpcMain.Send("Goodbye", "Elephant!");
});
diff --git a/ElectronNET.WebApp/ElectronNET.WebApp.csproj b/ElectronNET.WebApp/ElectronNET.WebApp.csproj
index 33d154c..afa9da2 100644
--- a/ElectronNET.WebApp/ElectronNET.WebApp.csproj
+++ b/ElectronNET.WebApp/ElectronNET.WebApp.csproj
@@ -6,6 +6,7 @@
+
@@ -24,4 +25,13 @@
+
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
diff --git a/ElectronNET.WebApp/Startup.cs b/ElectronNET.WebApp/Startup.cs
index a1648ec..8ad87aa 100644
--- a/ElectronNET.WebApp/Startup.cs
+++ b/ElectronNET.WebApp/Startup.cs
@@ -45,20 +45,40 @@ namespace ElectronNET.WebApp
{
Electron.Menu.SetApplicationMenu(new MenuItem[] {
new MenuItem {
- Label = "Datei",
+ Label = "File",
Submenu = new MenuItem[] {
new MenuItem {
- Label = "Beenden",
+ Label = "Exit",
Click = () =>
{
Electron.App.Exit();
}
}
}
+ },
+ new MenuItem
+ {
+ Label = "About",
+ Click = async () => {
+ await Electron.Dialog.ShowMessageBoxAsync(new MessageBoxOptions("(c) 2017 Gregor Biswanger & Robert Muehsig") {
+ Title = "About us...",
+ Type = "info"
+ });
+ }
}
});
var browserWindow = await Electron.WindowManager.CreateWindowAsync();
+
+ Electron.Tray.Show("/Assets/electron_32x32.png", new MenuItem[] {
+ new MenuItem {
+ Label = "Exit",
+ Click = () =>
+ {
+ Electron.App.Exit();
+ }
+ }
+ });
}
}
}
diff --git a/ElectronNET.WebApp/Views/Home/Index.cshtml b/ElectronNET.WebApp/Views/Home/Index.cshtml
index 22197ef..75b5ee5 100644
--- a/ElectronNET.WebApp/Views/Home/Index.cshtml
+++ b/ElectronNET.WebApp/Views/Home/Index.cshtml
@@ -3,7 +3,6 @@
- Home
Hello from ASP.NET Core MVC!