diff --git a/ElectronNET.API/AutoUpdater.cs b/ElectronNET.API/AutoUpdater.cs index 7a44162..f464c36 100644 --- a/ElectronNET.API/AutoUpdater.cs +++ b/ElectronNET.API/AutoUpdater.cs @@ -1,9 +1,6 @@ using ElectronNET.API.Entities; using Newtonsoft.Json.Linq; using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; using System.Threading.Tasks; namespace ElectronNET.API @@ -13,6 +10,181 @@ namespace ElectronNET.API /// public sealed class AutoUpdater { + /// + /// Emitted when there is an error while updating. + /// + public event Action OnError + { + add + { + if (_error == null) + { + BridgeConnector.Socket.On("autoUpdater-error" + GetHashCode(), (message) => + { + _error(message.ToString()); + }); + + BridgeConnector.Socket.Emit("register-autoUpdater-error-event", GetHashCode()); + } + _error += value; + } + remove + { + _error -= value; + + if (_error == null) + BridgeConnector.Socket.Off("autoUpdater-error" + GetHashCode()); + } + } + + private event Action _error; + + /// + /// Emitted when checking if an update has started. + /// + public event Action OnCheckingForUpdate + { + add + { + if (_checkingForUpdate == null) + { + BridgeConnector.Socket.On("autoUpdater-checking-for-update" + GetHashCode(), () => + { + _checkingForUpdate(); + }); + + BridgeConnector.Socket.Emit("register-autoUpdater-checking-for-update-event", GetHashCode()); + } + _checkingForUpdate += value; + } + remove + { + _checkingForUpdate -= value; + + if (_checkingForUpdate == null) + BridgeConnector.Socket.Off("autoUpdater-checking-for-update" + GetHashCode()); + } + } + + private event Action _checkingForUpdate; + + /// + /// Emitted when there is an available update. + /// The update is downloaded automatically if AutoDownload is true. + /// + public event Action OnUpdateAvailable + { + add + { + if (_updateAvailable == null) + { + BridgeConnector.Socket.On("autoUpdater-update-available" + GetHashCode(), (updateInfo) => + { + _updateAvailable(JObject.Parse(updateInfo.ToString()).ToObject()); + }); + + BridgeConnector.Socket.Emit("register-autoUpdater-update-available-event", GetHashCode()); + } + _updateAvailable += value; + } + remove + { + _updateAvailable -= value; + + if (_updateAvailable == null) + BridgeConnector.Socket.Off("autoUpdater-update-available" + GetHashCode()); + } + } + + private event Action _updateAvailable; + + /// + /// Emitted when there is no available update. + /// + public event Action OnUpdateNotAvailable + { + add + { + if (_updateNotAvailable == null) + { + BridgeConnector.Socket.On("autoUpdater-update-not-available" + GetHashCode(), (updateInfo) => + { + _updateNotAvailable(JObject.Parse(updateInfo.ToString()).ToObject()); + }); + + BridgeConnector.Socket.Emit("register-autoUpdater-update-not-available-event", GetHashCode()); + } + _updateNotAvailable += value; + } + remove + { + _updateNotAvailable -= value; + + if (_updateNotAvailable == null) + BridgeConnector.Socket.Off("autoUpdater-update-not-available" + GetHashCode()); + } + } + + private event Action _updateNotAvailable; + + /// + /// Emitted on download progress. + /// + public event Action OnDownloadProgress + { + add + { + if (_downloadProgress == null) + { + BridgeConnector.Socket.On("autoUpdater-download-progress" + GetHashCode(), (progressInfo) => + { + _downloadProgress(JObject.Parse(progressInfo.ToString()).ToObject()); + }); + + BridgeConnector.Socket.Emit("register-autoUpdater-download-progress-event", GetHashCode()); + } + _downloadProgress += value; + } + remove + { + _downloadProgress -= value; + + if (_downloadProgress == null) + BridgeConnector.Socket.Off("autoUpdater-download-progress" + GetHashCode()); + } + } + + private event Action _downloadProgress; + + /// + /// Emitted on download complete. + /// + public event Action OnUpdateDownloaded + { + add + { + if (_updateDownloaded == null) + { + BridgeConnector.Socket.On("autoUpdater-update-downloaded" + GetHashCode(), (updateInfo) => + { + _updateDownloaded(JObject.Parse(updateInfo.ToString()).ToObject()); + }); + + BridgeConnector.Socket.Emit("register-autoUpdater-update-downloaded-event", GetHashCode()); + } + _updateDownloaded += value; + } + remove + { + _updateDownloaded -= value; + + if (_updateDownloaded == null) + BridgeConnector.Socket.Off("autoUpdater-update-downloaded" + GetHashCode()); + } + } + + private event Action _updateDownloaded; + private static AutoUpdater _autoUpdater; private static object _syncRoot = new object(); diff --git a/ElectronNET.API/Entities/ProgressInfo.cs b/ElectronNET.API/Entities/ProgressInfo.cs new file mode 100644 index 0000000..fe6ea3d --- /dev/null +++ b/ElectronNET.API/Entities/ProgressInfo.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ElectronNET.API.Entities +{ + /// + /// + /// + public class ProgressInfo + { + /// + /// + /// + public string Progress { get; set; } + + /// + /// + /// + public string BytesPerSecond { get; set; } + + /// + /// + /// + public string Percent { get; set; } + + /// + /// + /// + public string Total { get; set; } + + /// + /// + /// + public string Transferred { get; set; } + } +} diff --git a/ElectronNET.Host/api/autoUpdater.js b/ElectronNET.Host/api/autoUpdater.js index 8c97fe7..e44e791 100644 --- a/ElectronNET.Host/api/autoUpdater.js +++ b/ElectronNET.Host/api/autoUpdater.js @@ -12,6 +12,38 @@ const path = require('path'); let electronSocket; module.exports = (socket) => { electronSocket = socket; + // Events ******** + socket.on('register-autoUpdater-error-event', (id) => { + electron_updater_1.autoUpdater.on('error', (error) => { + electronSocket.emit('autoUpdater-error' + id, error.message); + }); + }); + socket.on('register-autoUpdater-checking-for-update-event', (id) => { + electron_updater_1.autoUpdater.on('checking-for-update', () => { + electronSocket.emit('autoUpdater-checking-for-update' + id); + }); + }); + socket.on('register-autoUpdater-update-available-event', (id) => { + electron_updater_1.autoUpdater.on('update-available', (updateInfo) => { + electronSocket.emit('autoUpdater-update-available' + id, updateInfo); + }); + }); + socket.on('register-autoUpdater-update-not-available-event', (id) => { + electron_updater_1.autoUpdater.on('update-not-available', (updateInfo) => { + electronSocket.emit('autoUpdater-update-not-available' + id, updateInfo); + }); + }); + socket.on('register-autoUpdater-download-progress-event', (id) => { + electron_updater_1.autoUpdater.on('download-progress', (progressInfo) => { + electronSocket.emit('autoUpdater-download-progress' + id, progressInfo); + }); + }); + socket.on('register-autoUpdater-update-downloaded-event', (id) => { + electron_updater_1.autoUpdater.on('update-downloaded', (updateInfo) => { + electronSocket.emit('autoUpdater-update-downloaded' + id, updateInfo); + }); + }); + // Methods ******** socket.on('autoUpdaterCheckForUpdatesAndNotify', (guid) => __awaiter(this, void 0, void 0, function* () { const updateCheckResult = yield electron_updater_1.autoUpdater.checkForUpdatesAndNotify(); electronSocket.emit('autoUpdaterCheckForUpdatesAndNotifyComplete' + guid, updateCheckResult); diff --git a/ElectronNET.Host/api/autoUpdater.js.map b/ElectronNET.Host/api/autoUpdater.js.map index 6529890..ba92a20 100644 --- a/ElectronNET.Host/api/autoUpdater.js.map +++ b/ElectronNET.Host/api/autoUpdater.js.map @@ -1 +1 @@ -{"version":3,"file":"autoUpdater.js","sourceRoot":"","sources":["autoUpdater.ts"],"names":[],"mappings":";;;;;;;;;AAAA,uDAA+C;AAC/C,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAC7B,IAAI,cAAc,CAAC;AAEnB,iBAAS,CAAC,MAAuB,EAAE,EAAE;IACjC,cAAc,GAAG,MAAM,CAAC;IAExB,MAAM,CAAC,EAAE,CAAC,qCAAqC,EAAE,CAAO,IAAI,EAAE,EAAE;QAC5D,MAAM,iBAAiB,GAAG,MAAM,8BAAW,CAAC,wBAAwB,EAAE,CAAC;QACvE,cAAc,CAAC,IAAI,CAAC,6CAA6C,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC;IACjG,CAAC,CAAA,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,4BAA4B,EAAE,CAAO,IAAI,EAAE,EAAE;QACnD,6EAA6E;QAC7E,MAAM,iBAAiB,GAAG,MAAM,8BAAW,CAAC,eAAe,EAAE,CAAC;QAC9D,cAAc,CAAC,IAAI,CAAC,oCAAoC,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC;IACxF,CAAC,CAAA,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,2BAA2B,EAAE,CAAO,QAAQ,EAAE,eAAe,EAAE,EAAE;QACvE,8BAAW,CAAC,cAAc,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IAC1D,CAAC,CAAA,CAAC,CAAC;AACP,CAAC,CAAC"} \ No newline at end of file +{"version":3,"file":"autoUpdater.js","sourceRoot":"","sources":["autoUpdater.ts"],"names":[],"mappings":";;;;;;;;;AAAA,uDAA+C;AAC/C,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAC7B,IAAI,cAAc,CAAC;AAEnB,iBAAS,CAAC,MAAuB,EAAE,EAAE;IACjC,cAAc,GAAG,MAAM,CAAC;IAExB,kBAAkB;IAElB,MAAM,CAAC,EAAE,CAAC,kCAAkC,EAAE,CAAC,EAAE,EAAE,EAAE;QACjD,8BAAW,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAC9B,cAAc,CAAC,IAAI,CAAC,mBAAmB,GAAG,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,gDAAgD,EAAE,CAAC,EAAE,EAAE,EAAE;QAC/D,8BAAW,CAAC,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;YACvC,cAAc,CAAC,IAAI,CAAC,iCAAiC,GAAG,EAAE,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,6CAA6C,EAAE,CAAC,EAAE,EAAE,EAAE;QAC5D,8BAAW,CAAC,EAAE,CAAC,kBAAkB,EAAE,CAAC,UAAU,EAAE,EAAE;YAC9C,cAAc,CAAC,IAAI,CAAC,8BAA8B,GAAG,EAAE,EAAE,UAAU,CAAC,CAAC;QACzE,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,iDAAiD,EAAE,CAAC,EAAE,EAAE,EAAE;QAChE,8BAAW,CAAC,EAAE,CAAC,sBAAsB,EAAE,CAAC,UAAU,EAAE,EAAE;YAClD,cAAc,CAAC,IAAI,CAAC,kCAAkC,GAAG,EAAE,EAAE,UAAU,CAAC,CAAC;QAC7E,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,8CAA8C,EAAE,CAAC,EAAE,EAAE,EAAE;QAC7D,8BAAW,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,YAAY,EAAE,EAAE;YACjD,cAAc,CAAC,IAAI,CAAC,+BAA+B,GAAG,EAAE,EAAE,YAAY,CAAC,CAAC;QAC5E,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,8CAA8C,EAAE,CAAC,EAAE,EAAE,EAAE;QAC7D,8BAAW,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,UAAU,EAAE,EAAE;YAC/C,cAAc,CAAC,IAAI,CAAC,+BAA+B,GAAG,EAAE,EAAE,UAAU,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,mBAAmB;IAEnB,MAAM,CAAC,EAAE,CAAC,qCAAqC,EAAE,CAAO,IAAI,EAAE,EAAE;QAC5D,MAAM,iBAAiB,GAAG,MAAM,8BAAW,CAAC,wBAAwB,EAAE,CAAC;QACvE,cAAc,CAAC,IAAI,CAAC,6CAA6C,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC;IACjG,CAAC,CAAA,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,4BAA4B,EAAE,CAAO,IAAI,EAAE,EAAE;QACnD,6EAA6E;QAC7E,MAAM,iBAAiB,GAAG,MAAM,8BAAW,CAAC,eAAe,EAAE,CAAC;QAC9D,cAAc,CAAC,IAAI,CAAC,oCAAoC,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC;IACxF,CAAC,CAAA,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,2BAA2B,EAAE,CAAO,QAAQ,EAAE,eAAe,EAAE,EAAE;QACvE,8BAAW,CAAC,cAAc,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IAC1D,CAAC,CAAA,CAAC,CAAC;AACP,CAAC,CAAC"} \ No newline at end of file diff --git a/ElectronNET.Host/api/autoUpdater.ts b/ElectronNET.Host/api/autoUpdater.ts index a3f3c07..3e99dc7 100644 --- a/ElectronNET.Host/api/autoUpdater.ts +++ b/ElectronNET.Host/api/autoUpdater.ts @@ -5,6 +5,46 @@ let electronSocket; export = (socket: SocketIO.Socket) => { electronSocket = socket; + // Events ******** + + socket.on('register-autoUpdater-error-event', (id) => { + autoUpdater.on('error', (error) => { + electronSocket.emit('autoUpdater-error' + id, error.message); + }); + }); + + socket.on('register-autoUpdater-checking-for-update-event', (id) => { + autoUpdater.on('checking-for-update', () => { + electronSocket.emit('autoUpdater-checking-for-update' + id); + }); + }); + + socket.on('register-autoUpdater-update-available-event', (id) => { + autoUpdater.on('update-available', (updateInfo) => { + electronSocket.emit('autoUpdater-update-available' + id, updateInfo); + }); + }); + + socket.on('register-autoUpdater-update-not-available-event', (id) => { + autoUpdater.on('update-not-available', (updateInfo) => { + electronSocket.emit('autoUpdater-update-not-available' + id, updateInfo); + }); + }); + + socket.on('register-autoUpdater-download-progress-event', (id) => { + autoUpdater.on('download-progress', (progressInfo) => { + electronSocket.emit('autoUpdater-download-progress' + id, progressInfo); + }); + }); + + socket.on('register-autoUpdater-update-downloaded-event', (id) => { + autoUpdater.on('update-downloaded', (updateInfo) => { + electronSocket.emit('autoUpdater-update-downloaded' + id, updateInfo); + }); + }); + + // Methods ******** + socket.on('autoUpdaterCheckForUpdatesAndNotify', async (guid) => { const updateCheckResult = await autoUpdater.checkForUpdatesAndNotify(); electronSocket.emit('autoUpdaterCheckForUpdatesAndNotifyComplete' + guid, updateCheckResult); diff --git a/ElectronNET.WebApp/Controllers/UpdateController.cs b/ElectronNET.WebApp/Controllers/UpdateController.cs index fdb75ee..1f2c891 100644 --- a/ElectronNET.WebApp/Controllers/UpdateController.cs +++ b/ElectronNET.WebApp/Controllers/UpdateController.cs @@ -10,6 +10,23 @@ namespace ElectronNET.WebApp.Controllers { if (HybridSupport.IsElectronActive) { + Electron.AutoUpdater.OnError += (message) => Electron.Dialog.ShowErrorBox("Error", message); + Electron.AutoUpdater.OnCheckingForUpdate += async () => await Electron.Dialog.ShowMessageBoxAsync("Checking for Update"); + Electron.AutoUpdater.OnUpdateNotAvailable += async (info) => await Electron.Dialog.ShowMessageBoxAsync("Update not available"); + Electron.AutoUpdater.OnUpdateAvailable += async (info) => await Electron.Dialog.ShowMessageBoxAsync("Update available" + info.Version); + Electron.AutoUpdater.OnDownloadProgress += (info) => + { + var message1 = "Download speed: " + info.BytesPerSecond + "\n
"; + var message2 = "Downloaded " + info.Percent + "%" + "\n
"; + var message3 = $"({info.Transferred}/{info.Total})" + "\n
"; + var message4 = "Progress: " + info.Progress + "\n
"; + var information = message1 + message2 + message3 + message4; + + var mainWindow = Electron.WindowManager.BrowserWindows.First(); + Electron.IpcMain.Send(mainWindow, "auto-update-reply", information); + }; + Electron.AutoUpdater.OnUpdateDownloaded += async (info) => await Electron.Dialog.ShowMessageBoxAsync("Update complete!" + info.Version); + Electron.IpcMain.On("auto-update", async (args) => { // Electron.NET CLI Command for deploy: