using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using ElectronNET.API.Entities; using ElectronNET.API.Extensions; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Serialization; namespace ElectronNET.API { /// /// Control your app in the macOS dock. /// public sealed class Dock { private static Dock _dock; private static object _syncRoot = new object(); internal Dock() { } internal static Dock Instance { get { if (_dock == null) { lock (_syncRoot) { if (_dock == null) { _dock = new Dock(); } } } return _dock; } } /// /// When is passed, the dock icon will bounce until either the application becomes /// active or the request is canceled. When is passed, the dock icon will bounce /// for one second. However, the request remains active until either the application becomes active or the request is canceled. /// /// Note: This method can only be used while the app is not focused; when the app is focused it will return -1. /// /// Can be critical or informational. The default is informational. /// The cancellation token. /// Return an ID representing the request. public async Task BounceAsync(DockBounceType type, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); var taskCompletionSource = new TaskCompletionSource(); using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled())) { BridgeConnector.Socket.On("dock-bounce-completed", (id) => { BridgeConnector.Socket.Off("dock-bounce-completed"); taskCompletionSource.SetResult((int) id); }); BridgeConnector.Socket.Emit("dock-bounce", type.GetDescription()); return await taskCompletionSource.Task .ConfigureAwait(false); } } /// /// Cancel the bounce of id. /// /// Id of the request. public void CancelBounce(int id) { BridgeConnector.Socket.Emit("dock-cancelBounce", id); } /// /// Bounces the Downloads stack if the filePath is inside the Downloads folder. /// /// public void DownloadFinished(string filePath) { BridgeConnector.Socket.Emit("dock-downloadFinished", filePath); } /// /// Sets the string to be displayed in the dock’s badging area. /// /// public void SetBadge(string text) { BridgeConnector.Socket.Emit("dock-setBadge", text); } /// /// Gets the string to be displayed in the dock’s badging area. /// /// The cancellation token. /// The badge string of the dock. public async Task GetBadgeAsync(CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); var taskCompletionSource = new TaskCompletionSource(); using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled())) { BridgeConnector.Socket.On("dock-getBadge-completed", (text) => { BridgeConnector.Socket.Off("dock-getBadge-completed"); taskCompletionSource.SetResult((string) text); }); BridgeConnector.Socket.Emit("dock-getBadge"); return await taskCompletionSource.Task .ConfigureAwait(false); } } /// /// Hides the dock icon. /// public void Hide() { BridgeConnector.Socket.Emit("dock-hide"); } /// /// Shows the dock icon. /// public void Show() { BridgeConnector.Socket.Emit("dock-show"); } /// /// Whether the dock icon is visible. The app.dock.show() call is asynchronous /// so this method might not return true immediately after that call. /// /// The cancellation token. /// Whether the dock icon is visible. public async Task IsVisibleAsync(CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); var taskCompletionSource = new TaskCompletionSource(); using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled())) { BridgeConnector.Socket.On("dock-isVisible-completed", (isVisible) => { BridgeConnector.Socket.Off("dock-isVisible-completed"); taskCompletionSource.SetResult((bool) isVisible); }); BridgeConnector.Socket.Emit("dock-isVisible"); return await taskCompletionSource.Task .ConfigureAwait(false); } } /// /// Gets the dock menu items. /// /// /// The menu items. /// public IReadOnlyCollection MenuItems { get { return _items.AsReadOnly(); } } private List _items = new List(); /// /// Sets the application's dock menu. /// public void SetMenu(MenuItem[] menuItems) { menuItems.AddMenuItemsId(); BridgeConnector.Socket.Emit("dock-setMenu", JArray.FromObject(menuItems, _jsonSerializer)); _items.AddRange(menuItems); BridgeConnector.Socket.Off("dockMenuItemClicked"); BridgeConnector.Socket.On("dockMenuItemClicked", (id) => { MenuItem menuItem = _items.GetMenuItem(id.ToString()); menuItem?.Click(); }); } /// /// TODO: Menu (macOS) still to be implemented /// Gets the application's dock menu. /// public async Task GetMenu(CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); var taskCompletionSource = new TaskCompletionSource(); using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled())) { BridgeConnector.Socket.On("dock-getMenu-completed", (menu) => { BridgeConnector.Socket.Off("dock-getMenu-completed"); taskCompletionSource.SetResult(((JObject)menu).ToObject()); }); BridgeConnector.Socket.Emit("dock-getMenu"); return await taskCompletionSource.Task .ConfigureAwait(false); } } /// /// Sets the image associated with this dock icon. /// /// public void SetIcon(string image) { BridgeConnector.Socket.Emit("dock-setIcon", image); } private JsonSerializer _jsonSerializer = new JsonSerializer() { ContractResolver = new CamelCasePropertyNamesContractResolver(), NullValueHandling = NullValueHandling.Ignore }; } }