This commit is contained in:
Robert Muehsig
2017-10-18 22:35:49 +02:00
16 changed files with 791 additions and 20 deletions

View File

@@ -0,0 +1,9 @@
namespace ElectronNET.API
{
public class DisplayBalloonOptions
{
public string Icon { get; set; }
public string Title { get; set; }
public string Content { get; set; }
}
}

View File

@@ -0,0 +1,20 @@
namespace ElectronNET.API.Entities
{
public enum HighlightMode
{
/// <summary>
/// Highlight the tray icon when it is clicked and also when its context menu is open. This is the default.
/// </summary>
selection,
/// <summary>
/// Always highlight the tray icon.
/// </summary>
always,
/// <summary>
/// Never highlight the tray icon.
/// </summary>
never
}
}

View File

@@ -0,0 +1,15 @@
namespace ElectronNET.API.Entities
{
public class NotificationAction
{
/// <summary>
/// The label for the given action.
/// </summary>
public string Text { get; set; }
/// <summary>
/// The type of action, can be button.
/// </summary>
public string Type { get; set; }
}
}

View File

@@ -1,4 +1,7 @@
namespace ElectronNET.API.Entities
using Newtonsoft.Json;
using System;
namespace ElectronNET.API.Entities
{
public class NotificationOptions
{
@@ -44,6 +47,63 @@
/// </summary>
public string Sound { get; set; }
/// <summary>
/// Actions to add to the notification. Please read the available actions and
/// limitations in the NotificationAction documentation
/// </summary>
public NotificationAction Actions { get; set; }
/// <summary>
/// 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.
/// </summary>
[JsonIgnore]
public Action OnShow { get; set; }
[JsonProperty]
internal string ShowID { get; set; }
/// <summary>
/// Emitted when the notification is clicked by the user.
/// </summary>
[JsonIgnore]
public Action OnClick { get; set; }
[JsonProperty]
internal string ClickID { get; set; }
/// <summary>
/// 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.
/// </summary>
[JsonIgnore]
public Action OnClose { get; set; }
[JsonProperty]
internal string CloseID { get; set; }
/// <summary>
/// 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
/// </summary>
[JsonIgnore]
public Action<string> OnReply { get; set; }
[JsonProperty]
internal string ReplyID { get; set; }
/// <summary>
/// macOS only - The index of the action that was activated
/// </summary>
[JsonIgnore]
public Action<string> OnAction { get; set; }
[JsonProperty]
internal string ActionID { get; set; }
public NotificationOptions(string title, string body)
{
Title = title;

View File

@@ -0,0 +1,10 @@
namespace ElectronNET.API
{
public class TrayClickEventArgs
{
public bool AltKey { get; set; }
public bool ShiftKey { get; set; }
public bool CtrlKey { get; set; }
public bool MetaKey { get; set; }
}
}

View File

@@ -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> _notificationOptions = new List<NotificationOptions>();
/// <summary>
/// Create OS desktop notifications
/// </summary>
/// <param name="notificationOptions"></param>
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<string[]>();
_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<string[]>();
_notificationOptions.Single(x => x.ReplyID == arguments[0].ToString()).OnAction(arguments[1].ToString());
});
}
if (isActionDefined)
{
_notificationOptions.Add(notificationOptions);
}
}
/// <summary>
/// Whether or not desktop notifications are supported on the current system.
/// </summary>
/// <returns></returns>
public Task<bool> IsSupportedAsync()
{
var taskCompletionSource = new TaskCompletionSource<bool>();
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(),

View File

@@ -3,12 +3,182 @@ using ElectronNET.API.Extensions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace ElectronNET.API
{
public sealed class Tray
{
/// <summary>
/// Emitted when the tray icon is clicked.
/// </summary>
public event Action<TrayClickEventArgs, Rectangle> OnClick
{
add
{
if (_click == null)
{
BridgeConnector.Socket.On("tray-click-event", (result) =>
{
var args = ((JArray)result).ToObject<object[]>();
var trayClickEventArgs = ((JObject)args[0]).ToObject<TrayClickEventArgs>();
var bounds = ((JObject)args[1]).ToObject<Rectangle>();
_click(trayClickEventArgs, bounds);
});
BridgeConnector.Socket.Emit("register-tray-click");
}
_click += value;
}
remove
{
_click -= value;
}
}
private event Action<TrayClickEventArgs, Rectangle> _click;
/// <summary>
/// macOS, Windows: Emitted when the tray icon is right clicked.
/// </summary>
public event Action<TrayClickEventArgs, Rectangle> OnRightClick
{
add
{
if (_rightClick == null)
{
BridgeConnector.Socket.On("tray-right-click-event", (result) =>
{
var args = ((JArray)result).ToObject<object[]>();
var trayClickEventArgs = ((JObject)args[0]).ToObject<TrayClickEventArgs>();
var bounds = ((JObject)args[1]).ToObject<Rectangle>();
_rightClick(trayClickEventArgs, bounds);
});
BridgeConnector.Socket.Emit("register-tray-right-click");
}
_rightClick += value;
}
remove
{
_rightClick -= value;
}
}
private event Action<TrayClickEventArgs, Rectangle> _rightClick;
/// <summary>
/// macOS, Windows: Emitted when the tray icon is double clicked.
/// </summary>
public event Action<TrayClickEventArgs, Rectangle> OnDoubleClick
{
add
{
if (_doubleClick == null)
{
BridgeConnector.Socket.On("tray-double-click-event", (result) =>
{
var args = ((JArray)result).ToObject<object[]>();
var trayClickEventArgs = ((JObject)args[0]).ToObject<TrayClickEventArgs>();
var bounds = ((JObject)args[1]).ToObject<Rectangle>();
_doubleClick(trayClickEventArgs, bounds);
});
BridgeConnector.Socket.Emit("register-tray-double-click");
}
_doubleClick += value;
}
remove
{
_doubleClick -= value;
}
}
private event Action<TrayClickEventArgs, Rectangle> _doubleClick;
/// <summary>
/// Windows: Emitted when the tray balloon shows.
/// </summary>
public event Action OnBalloonShow
{
add
{
if (_balloonShow == null)
{
BridgeConnector.Socket.On("tray-balloon-show-event", () =>
{
_balloonShow();
});
BridgeConnector.Socket.Emit("register-tray-balloon-show");
}
_balloonShow += value;
}
remove
{
_balloonShow -= value;
}
}
private event Action _balloonShow;
/// <summary>
/// Windows: Emitted when the tray balloon is clicked.
/// </summary>
public event Action OnBalloonClick
{
add
{
if (_balloonClick == null)
{
BridgeConnector.Socket.On("tray-balloon-click-event", () =>
{
_balloonClick();
});
BridgeConnector.Socket.Emit("register-tray-balloon-click");
}
_balloonClick += value;
}
remove
{
_balloonClick -= value;
}
}
private event Action _balloonClick;
/// <summary>
/// Windows: Emitted when the tray balloon is closed
/// because of timeout or user manually closes it.
/// </summary>
public event Action OnBalloonClosed
{
add
{
if (_balloonClosed == null)
{
BridgeConnector.Socket.On("tray-balloon-closed-event", () =>
{
_balloonClosed();
});
BridgeConnector.Socket.Emit("register-tray-balloon-closed");
}
_balloonClosed += value;
}
remove
{
_balloonClosed -= value;
}
}
private event Action _balloonClosed;
// TODO: Implement macOS Events
private static Tray _tray;
internal Tray() { }
@@ -42,6 +212,91 @@ namespace ElectronNET.API
});
}
/// <summary>
/// Destroys the tray icon immediately.
/// </summary>
public void Destroy()
{
BridgeConnector.Socket.Emit("tray-destroy");
}
/// <summary>
/// Sets the image associated with this tray icon.
/// </summary>
/// <param name="image"></param>
public void SetImage(string image)
{
BridgeConnector.Socket.Emit("tray-setImage", image);
}
/// <summary>
/// Sets the image associated with this tray icon when pressed on macOS.
/// </summary>
/// <param name="image"></param>
public void SetPressedImage(string image)
{
BridgeConnector.Socket.Emit("tray-setPressedImage", image);
}
/// <summary>
/// Sets the hover text for this tray icon.
/// </summary>
/// <param name="toolTip"></param>
public void SetToolTip(string toolTip)
{
BridgeConnector.Socket.Emit("tray-setToolTip", toolTip);
}
/// <summary>
/// macOS: Sets the title displayed aside of the tray icon in the status bar.
/// </summary>
/// <param name="title"></param>
public void SetTitle(string title)
{
BridgeConnector.Socket.Emit("tray-setTitle", title);
}
/// <summary>
/// macOS: Sets when the trays icon background becomes highlighted (in blue).
///
/// Note: You can use highlightMode with a BrowserWindow by toggling between
/// 'never' and 'always' modes when the window visibility changes.
/// </summary>
/// <param name="highlightMode"></param>
public void SetHighlightMode(HighlightMode highlightMode)
{
BridgeConnector.Socket.Emit("tray-setHighlightMode", highlightMode.ToString());
}
/// <summary>
/// Windows: Displays a tray balloon.
/// </summary>
/// <param name="options"></param>
public void DisplayBalloon(DisplayBalloonOptions options)
{
BridgeConnector.Socket.Emit("tray-displayBalloon", JObject.FromObject(options, _jsonSerializer));
}
/// <summary>
/// Whether the tray icon is destroyed.
/// </summary>
/// <returns></returns>
public Task<bool> IsDestroyedAsync()
{
var taskCompletionSource = new TaskCompletionSource<bool>();
BridgeConnector.Socket.On("tray-isDestroyedCompleted", (isDestroyed) =>
{
BridgeConnector.Socket.Off("tray-isDestroyedCompleted");
taskCompletionSource.SetResult((bool)isDestroyed);
});
BridgeConnector.Socket.Emit("tray-isDestroyed");
return taskCompletionSource.Task;
}
private JsonSerializer _jsonSerializer = new JsonSerializer()
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),