diff --git a/presenter-app/package.json b/presenter-app/package.json index 6eda8ee..583d3d3 100644 --- a/presenter-app/package.json +++ b/presenter-app/package.json @@ -1,9 +1,13 @@ { "name": "plodo", - "version": "0.3.0", + "version": "0.4.0", "description": "Use plodo to get immediate feedback from your audience while you present", "author": "Lars Baunwall (https://www.plodo.io/)", "homepage": "https://www.plodo.io", + "os": [ + "win32", + "darwin" + ], "repository": { "type": "git", "url": "https://github.com/larsbaunwall/plodo.git" @@ -24,7 +28,9 @@ "axios": "^0.19.0", "bootstrap-vue": "^2.10.1", "core-js": "^3.6.4", + "electron-log": "^4.1.1", "electron-promise-ipc": "^2.1.0", + "electron-updater": "^4.2.5", "eventsource": "^1.0.7", "flatpickr": "^4.5.1", "nouislider": "^14.2.0", diff --git a/presenter-app/src/background.js b/presenter-app/src/background.js index 2ead067..d8de1ee 100644 --- a/presenter-app/src/background.js +++ b/presenter-app/src/background.js @@ -3,8 +3,15 @@ import { app, protocol, screen, ipcMain } from "electron"; import manager from "./common/WindowManager"; import store from "./store"; +import logging from "./common/Logging"; +import { autoUpdater } from "electron-updater"; -let DEBUG = process.env.NODE_ENV !== "production"; +const DEBUG = process.env.NODE_ENV !== "production"; + +logging.init(); + +autoUpdater.logger = logging.log; +autoUpdater.logger.transports.file.level = "info"; // Keep a global reference of the window object, if you don't, the window will // be closed automatically when the JavaScript object is garbage collected. @@ -72,6 +79,8 @@ app.on("ready", async () => { win = manager.createAppWindow(450, 650, "", false, true); tray = manager.createTray(win); celebrationWin = manager.createCelebrationWindow(screen.getPrimaryDisplay()); + + autoUpdater.checkForUpdatesAndNotify(); }); app.on("before-quit", async () => { diff --git a/presenter-app/src/common/Logging.js b/presenter-app/src/common/Logging.js new file mode 100644 index 0000000..8d2ba31 --- /dev/null +++ b/presenter-app/src/common/Logging.js @@ -0,0 +1,18 @@ +import log from "electron-log"; +console.log = log.log; + +const DEBUG = process.env.NODE_ENV !== "production"; + +const init = () => { + if(DEBUG){ + log.transports.file.level = "silly"; + } else { + log.transports.file.level = "warn"; + } + + process.on("uncaughtException", (err, origin) => { + log.error(`Caught exception: ${err}, origin: ${origin}`); + }); +}; + +export default { init, log }; \ No newline at end of file diff --git a/presenter-app/src/common/WindowManager.js b/presenter-app/src/common/WindowManager.js index b5d4239..93029af 100644 --- a/presenter-app/src/common/WindowManager.js +++ b/presenter-app/src/common/WindowManager.js @@ -1,20 +1,56 @@ "use strict"; /* global __static */ -import { app, BrowserWindow, screen, Tray, Menu } from "electron"; +import { app, BrowserWindow, dialog, screen, Tray, Menu } from "electron"; import path from "path"; import { createProtocol, installVueDevtools } from "vue-cli-plugin-electron-builder/lib"; +import { autoUpdater } from "electron-updater"; +import log from "electron-log"; +autoUpdater.logger = log; const DEBUG = process.env.NODE_ENV !== "production"; +let createdAppProtocol = false; let tray; +const showUpdateDialog = async (mainWindow) => { + + try { + const result = await autoUpdater.checkForUpdates(); + + const message = `${result.updateInfo.version} is the latest version.\nYour version is ${app.getVersion()}.\n\nDo you want to update?`; + + const clicked = await dialog.showMessageBox(mainWindow, { + type: "info", + title: "Update plodo", + buttons: ["Yes, quit and update now", "Later"], + cancelId: 1, + message : message + }); + + if(clicked === 0) + await autoUpdater.quitAndInstall(); + } catch (err) { + await dialog.showMessageBox(mainWindow, { + type: "error", + title: "Error looking for update", + message : err.message + }); + } +}; + const createTray = mainWindow => { const menu = Menu.buildFromTemplate([ { label: "Open plodo", - click() { + click: () => { toggleWindow(mainWindow); }, }, + { + label: "Check for updates", + click: async () => { + await showUpdateDialog(mainWindow); + }, + }, { type: "separator" }, { role: "quit" // "role": system prepared action menu @@ -93,7 +129,7 @@ const createAppWindow = (width, height, urlPath, hideOnBlur = false, hideOnClose // Load the url of the dev server if in development mode win.loadURL(`${process.env.WEBPACK_DEV_SERVER_URL}${urlPath}`); } else { - createProtocol("plodo"); + ensurePlodoProtocol(); // Load the index.html when not in development win.loadURL(`plodo://./index.html${urlPath}`); } @@ -137,7 +173,7 @@ const createCelebrationWindow = (display = screen.getPrimaryDisplay()) => { }); win.setMenu(null); - win.setAlwaysOnTop(true, "screen-saver", 1); + win.setAlwaysOnTop(true, "screen-saver"); win.setIgnoreMouseEvents(true); @@ -145,7 +181,7 @@ const createCelebrationWindow = (display = screen.getPrimaryDisplay()) => { // Load the url of the dev server if in development mode win.loadURL(`${process.env.WEBPACK_DEV_SERVER_URL}#/celebrate`); } else { - createProtocol("plodo"); + ensurePlodoProtocol(); // Load the index.html when not in development win.loadURL("plodo://./index.html/#/celebrate"); } @@ -153,4 +189,12 @@ const createCelebrationWindow = (display = screen.getPrimaryDisplay()) => { return win; }; +const ensurePlodoProtocol = () => { + if(!createdAppProtocol) + { + createProtocol("plodo"); + createdAppProtocol = true; + } +}; + export default { createAppWindow, createCelebrationWindow, createTray }; diff --git a/presenter-app/vue.config.js b/presenter-app/vue.config.js index 59da387..9e3cb52 100644 --- a/presenter-app/vue.config.js +++ b/presenter-app/vue.config.js @@ -14,7 +14,10 @@ module.exports = { }, pluginOptions: { electronBuilder: { - customFileProtocol: "plodo://./" // Make sure to add "./" to the end of the protocol + customFileProtocol: "plodo://./", // Make sure to add "./" to the end of the protocol + builderOptions: { + publish: ["github"] + } } }, configureWebpack: { diff --git a/presenter-app/yarn.lock b/presenter-app/yarn.lock index 7ab02d7..1ecdd7c 100644 --- a/presenter-app/yarn.lock +++ b/presenter-app/yarn.lock @@ -1282,6 +1282,13 @@ resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== +"@types/semver@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.1.0.tgz#c8c630d4c18cd326beff77404887596f96408408" + integrity sha512-pOKLaubrAEMUItGNpgwl0HMFPrSAFic8oSVIvfu1UwcgGNmNyK9gyhBHKmBnUTwwVvpZfkzUC0GaMgnL6P86uA== + dependencies: + "@types/node" "*" + "@vue/babel-helper-vue-jsx-merge-props@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.0.0.tgz#048fe579958da408fb7a8b2a3ec050b50a661040" @@ -2512,6 +2519,14 @@ builder-util-runtime@8.3.0: debug "^4.1.1" sax "^1.2.4" +builder-util-runtime@8.6.2: + version "8.6.2" + resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-8.6.2.tgz#8270e15b012d8d3b110f3e327b0fd8b0e07b1686" + integrity sha512-9QnIBISfhgQ2BxtRLidVqf/v5HD73vSKZDllpUmGd2L6VORGQk7cZAPmPtw4HQM3gPBelyVJ5yIjMNZ8xjmd1A== + dependencies: + debug "^4.1.1" + sax "^1.2.4" + builder-util@21.2.0, builder-util@~21.2.0: version "21.2.0" resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-21.2.0.tgz#aba721190e4e841009d9fb4b88f1130ed616522f" @@ -4026,6 +4041,11 @@ electron-icon-builder@^1.0.1: icon-gen "^2.0.0" jimp "^0.9.3" +electron-log@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/electron-log/-/electron-log-4.1.1.tgz#c57e3d833f723742eb430dc2cdaa6f97d8dbcaff" + integrity sha512-vkK3rNBOciRiinxrsdgg8hyUia+ct8ZMjBblvKjgNk4uHEDjjSyn313NOwv75xOMVIKlfmYzxaN8kR/oGC33aQ== + electron-promise-ipc@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/electron-promise-ipc/-/electron-promise-ipc-2.1.0.tgz#23503c397f067b228246be4f5418e38186a686d7" @@ -4061,6 +4081,20 @@ electron-to-chromium@^1.3.390: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.398.tgz#4c01e29091bf39e578ac3f66c1f157d92fa5725d" integrity sha512-BJjxuWLKFbM5axH3vES7HKMQgAknq9PZHBkMK/rEXUQG9i1Iw5R+6hGkm6GtsQSANjSUrh/a6m32nzCNDNo/+w== +electron-updater@^4.2.5: + version "4.2.5" + resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-4.2.5.tgz#dbced8da6f8c6fc2dc662f2776131f5a49ce018d" + integrity sha512-ir8SI3capF5pN4LTQY79bP7oqiBKjgtdDW378xVId5VcGUZ+Toei2j+fgx1mq3y4Qg19z4HqLxEZ9FqMD0T0RA== + dependencies: + "@types/semver" "^7.1.0" + builder-util-runtime "8.6.2" + fs-extra "^8.1.0" + js-yaml "^3.13.1" + lazy-val "^1.0.4" + lodash.isequal "^4.5.0" + pako "^1.0.11" + semver "^7.1.3" + electron@^8.2.1: version "8.2.1" resolved "https://registry.yarnpkg.com/electron/-/electron-8.2.1.tgz#0341ea01272a69f4f3a2bd4cb41521adb1e4ddcf" @@ -6716,6 +6750,11 @@ lodash.defaultsdeep@^4.6.1: resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6" integrity sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA== +lodash.isequal@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= + lodash.kebabcase@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" @@ -7808,7 +7847,7 @@ package-json@^6.3.0: registry-url "^5.0.0" semver "^6.2.0" -pako@^1.0.5, pako@~1.0.2, pako@~1.0.5: +pako@^1.0.11, pako@^1.0.5, pako@~1.0.2, pako@~1.0.5: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== @@ -9319,6 +9358,11 @@ semver@^7.1.2: resolved "https://registry.yarnpkg.com/semver/-/semver-7.2.1.tgz#d997aa36bdbb00b501ae4ac4c7d17e9f7a587ae5" integrity sha512-aHhm1pD02jXXkyIpq25qBZjr3CQgg8KST8uX0OWXch3xE6jw+1bfbWnCjzMwojsTquroUmKFHNzU6x26mEiRxw== +semver@^7.1.3: + version "7.3.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" + integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== + semver@~5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"