From 8d0e453666b7416ef34cfaac7ba761439e8bf1e1 Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Mon, 1 Jan 2018 12:59:28 +0100 Subject: [PATCH 1/8] Preparation for v2.3.0 release. --- CHANGELOG.md | 11 +++++++++++ package.json | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2495e21..e32ada02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,17 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [2.3.0] - Unreleased + +*This release is scheduled to be released on 2018-04-01.* + +### Changed +- Changed Electron dependency to v1.7.10. + +### Added + +### Fixed + ## [2.2.0] - 2018-01-01 **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install` diff --git a/package.json b/package.json index 977bb544..4c42c44c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "magicmirror", - "version": "2.2.0", + "version": "2.3.0-dev", "description": "The open source modular smart mirror platform.", "main": "js/electron.js", "scripts": { @@ -54,7 +54,7 @@ "dependencies": { "body-parser": "^1.18.2", "colors": "^1.1.2", - "electron": "1.4.15", + "electron": "^1.7.10", "express": "^4.16.2", "express-ipfilter": "0.3.1", "feedme": "latest", From 538a2acbf515be9cc476805c7efc352728a4e4a4 Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Mon, 1 Jan 2018 13:38:07 +0100 Subject: [PATCH 2/8] Fix linting errors. --- css/main.css | 15 ++++++--------- .../default/weatherforecast/weatherforecast.js | 4 ++-- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/css/main.css b/css/main.css index 49bfe611..db1fb428 100644 --- a/css/main.css +++ b/css/main.css @@ -95,7 +95,7 @@ body { header { text-transform: uppercase; font-size: 15px; - font-family: "Roboto Condensed"; + font-family: "Roboto Condensed", Arial, Helvetica, sans-serif; font-weight: 400; border-bottom: 1px solid #666; line-height: 15px; @@ -151,6 +151,7 @@ sup { .region.right { right: 0; + text-align: right; } .region.top { @@ -161,6 +162,10 @@ sup { margin-bottom: 25px; } +.region.bottom .container { + margin-top: 25px; +} + .region.top .container:empty { margin-bottom: 0; } @@ -185,10 +190,6 @@ sup { bottom: 0; } -.region.bottom .container { - margin-top: 25px; -} - .region.bottom .container:empty { margin-top: 0; } @@ -231,10 +232,6 @@ sup { text-align: left; } -.region.right { - text-align: right; -} - .region table { width: 100%; border-spacing: 0; diff --git a/modules/default/weatherforecast/weatherforecast.js b/modules/default/weatherforecast/weatherforecast.js index 8c3a4595..22322bf3 100644 --- a/modules/default/weatherforecast/weatherforecast.js +++ b/modules/default/weatherforecast/weatherforecast.js @@ -161,12 +161,12 @@ Module.register("weatherforecast",{ } var maxTempCell = document.createElement("td"); - maxTempCell.innerHTML = forecast.maxTemp.replace(".", this.config.decimalSymbol) + degreeLabel; + maxTempCell.innerHTML = forecast.maxTemp.replace(".", this.config.decimalSymbol) + degreeLabel; maxTempCell.className = "align-right bright max-temp"; row.appendChild(maxTempCell); var minTempCell = document.createElement("td"); - minTempCell.innerHTML = forecast.minTemp.replace(".", this.config.decimalSymbol) + degreeLabel; + minTempCell.innerHTML = forecast.minTemp.replace(".", this.config.decimalSymbol) + degreeLabel; minTempCell.className = "align-right min-temp"; row.appendChild(minTempCell); From 4a1bee769ba33c1e60884970a3ebecb1ba55df81 Mon Sep 17 00:00:00 2001 From: Connor Christie Date: Mon, 1 Jan 2018 09:42:34 -0600 Subject: [PATCH 3/8] Add true module dom creation events --- js/main.js | 36 +++++++++++++++++++++++++++++++----- js/module.js | 43 +++++++++++++++++++++---------------------- 2 files changed, 52 insertions(+), 27 deletions(-) diff --git a/js/main.js b/js/main.js index f499da62..242be5a8 100644 --- a/js/main.js +++ b/js/main.js @@ -96,17 +96,44 @@ var MM = (function() { * argument speed Number - The number of microseconds for the animation. (optional) */ var updateDom = function(module, speed) { - var newContent = module.getDom(); + var newContentPromise = module.getDom(); var newHeader = module.getHeader(); - if (!module.hidden) { + if (!(newContentPromise instanceof Promise)) { + // convert to a promise if not already one to avoid if/else's everywhere + newContentPromise = Promise.resolve(newContentPromise); + } + + newContentPromise.then((newContent) => { + var updatePromise = updateDomWithContent(module, speed, newHeader, newContent); + + updatePromise.then(() => { + // dom has been updated + sendNotification("MODULE_DOM_CREATED", { module: module.name }); + }).catch((err) => { + Log.error(err); + }); + }).catch((err) => { + Log.error(err); + }); + }; + + var updateDomWithContent = function(module, speed, newHeader, newContent) { + return new Promise((resolve) => { + if (module.hidden || !speed) { + updateModuleContent(module, newHeader, newContent); + resolve(); + return; + } if (!moduleNeedsUpdate(module, newHeader, newContent)) { + resolve(); return; } if (!speed) { updateModuleContent(module, newHeader, newContent); + resolve(); return; } @@ -115,10 +142,9 @@ var MM = (function() { if (!module.hidden) { showModule(module, speed / 2); } + resolve(); }); - } else { - updateModuleContent(module, newHeader, newContent); - } + }); }; /* moduleNeedsUpdate(module, newContent) diff --git a/js/module.js b/js/module.js index 464509ee..dbcfe91f 100644 --- a/js/module.js +++ b/js/module.js @@ -81,31 +81,30 @@ var Module = Class.extend({ * return domobject - The dom to display. */ getDom: function () { - var div = document.createElement("div"); - var template = this.getTemplate(); - var templateData = this.getTemplateData(); + return new Promise((resolve) => { + var div = document.createElement("div"); + var template = this.getTemplate(); + var templateData = this.getTemplateData(); + + // Check to see if we need to render a template string or a file. + if (/^.*((\.html)|(\.njk))$/.test(template)) { + // the template is a filename + this.nunjucksEnvironment().render(template, templateData, function (err, res) { + if (err) { + Log.error(err) + } - // Check to see if we need to render a template string or a file. - if (/^.*((\.html)|(\.njk))$/.test(template)) { - // the template is a filename - this.nunjucksEnvironment().render(template, templateData, function (err, res) { - if (err) { - Log.error(err) - } + div.innerHTML = res; - // The inner content of the div will be set after the template is received. - // This isn't the most optimal way, but since it's near instant - // it probably won't be an issue. - // If it gives problems, we can always add a way to pre fetch the templates. - // Let's not over optimise this ... KISS! :) - div.innerHTML = res; - }); - } else { - // the template is a template string. - div.innerHTML = this.nunjucksEnvironment().renderString(template, templateData); - } + resolve(div); + }); + } else { + // the template is a template string. + div.innerHTML = this.nunjucksEnvironment().renderString(template, templateData); - return div; + resolve(div); + } + }); }, /* getHeader() From 80b84212cc99c4e0596e3b5592ce87b2bfaa53f6 Mon Sep 17 00:00:00 2001 From: Connor Christie Date: Mon, 1 Jan 2018 10:23:15 -0600 Subject: [PATCH 4/8] Add notification for module dom creation with async support --- js/main.js | 103 +++++++++++++++++++++++++---------------------------- 1 file changed, 49 insertions(+), 54 deletions(-) diff --git a/js/main.js b/js/main.js index 242be5a8..e3412e14 100644 --- a/js/main.js +++ b/js/main.js @@ -19,38 +19,39 @@ var MM = (function() { * are configured for a specific position. */ var createDomObjects = function() { - for (var m in modules) { - var module = modules[m]; - - if (typeof module.data.position === "string") { - - var wrapper = selectWrapper(module.data.position); - - var dom = document.createElement("div"); - dom.id = module.identifier; - dom.className = module.name; - - if (typeof module.data.classes === "string") { - dom.className = "module " + dom.className + " " + module.data.classes; - } - - dom.opacity = 0; - wrapper.appendChild(dom); - - if (typeof module.data.header !== "undefined" && module.data.header !== "") { - var moduleHeader = document.createElement("header"); - moduleHeader.innerHTML = module.data.header; - moduleHeader.className = "module-header"; - dom.appendChild(moduleHeader); - } - - var moduleContent = document.createElement("div"); - moduleContent.className = "module-content"; - dom.appendChild(moduleContent); - - updateDom(module, 0); + modules.forEach(module => { + if (typeof module.data.position !== "string") { + return; } - } + + var wrapper = selectWrapper(module.data.position); + + var dom = document.createElement("div"); + dom.id = module.identifier; + dom.className = module.name; + + if (typeof module.data.classes === "string") { + dom.className = "module " + dom.className + " " + module.data.classes; + } + + dom.opacity = 0; + wrapper.appendChild(dom); + + if (typeof module.data.header !== "undefined" && module.data.header !== "") { + var moduleHeader = document.createElement("header"); + moduleHeader.innerHTML = module.data.header; + moduleHeader.className = "module-header"; + dom.appendChild(moduleHeader); + } + + var moduleContent = document.createElement("div"); + moduleContent.className = "module-content"; + dom.appendChild(moduleContent); + + updateDom(module, 0).then(() => { + sendNotification("MODULE_DOM_CREATED", null, null, module); + }).catch(Log.error); + }); updateWrapperStates(); @@ -80,10 +81,9 @@ var MM = (function() { * argument payload mixed - The payload of the notification. * argument sender Module - The module that sent the notification. */ - var sendNotification = function(notification, payload, sender) { - for (var m in modules) { - var module = modules[m]; - if (module !== sender) { + var sendNotification = function(notification, payload, sender, sendTo) { + for (var module of modules) { + if (module !== sender && (!sendTo || module === sendTo)) { module.notificationReceived(notification, payload, sender); } } @@ -96,25 +96,20 @@ var MM = (function() { * argument speed Number - The number of microseconds for the animation. (optional) */ var updateDom = function(module, speed) { - var newContentPromise = module.getDom(); - var newHeader = module.getHeader(); - - if (!(newContentPromise instanceof Promise)) { - // convert to a promise if not already one to avoid if/else's everywhere - newContentPromise = Promise.resolve(newContentPromise); - } - - newContentPromise.then((newContent) => { - var updatePromise = updateDomWithContent(module, speed, newHeader, newContent); - - updatePromise.then(() => { - // dom has been updated - sendNotification("MODULE_DOM_CREATED", { module: module.name }); - }).catch((err) => { - Log.error(err); - }); - }).catch((err) => { - Log.error(err); + return new Promise((resolve) => { + var newContentPromise = module.getDom(); + var newHeader = module.getHeader(); + + if (!(newContentPromise instanceof Promise)) { + // convert to a promise if not already one to avoid if/else's everywhere + newContentPromise = Promise.resolve(newContentPromise); + } + + newContentPromise.then((newContent) => { + var updatePromise = updateDomWithContent(module, speed, newHeader, newContent); + + updatePromise.then(resolve).catch(Log.error); + }).catch(Log.error); }); }; From 7bb11d6436a70e0e2ab80e4bf27aaf22463285e6 Mon Sep 17 00:00:00 2001 From: Connor Christie Date: Mon, 1 Jan 2018 10:38:00 -0600 Subject: [PATCH 5/8] Add documentation regarding updates --- js/main.js | 15 +++++++++++++++ modules/README.md | 3 ++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/js/main.js b/js/main.js index e3412e14..782b6863 100644 --- a/js/main.js +++ b/js/main.js @@ -80,6 +80,7 @@ var MM = (function() { * argument notification string - The identifier of the notification. * argument payload mixed - The payload of the notification. * argument sender Module - The module that sent the notification. + * argument sendTo Module - The module to send the notification to. (optional) */ var sendNotification = function(notification, payload, sender, sendTo) { for (var module of modules) { @@ -94,6 +95,8 @@ var MM = (function() { * * argument module Module - The module that needs an update. * argument speed Number - The number of microseconds for the animation. (optional) + * + * return Promise - Resolved when the dom is fully updated. */ var updateDom = function(module, speed) { return new Promise((resolve) => { @@ -113,6 +116,16 @@ var MM = (function() { }); }; + /* updateDomWithContent(module, speed, newHeader, newContent) + * Update the dom with the specified content + * + * argument module Module - The module that needs an update. + * argument speed Number - The number of microseconds for the animation. (optional) + * argument newHeader String - The new header that is generated. + * argument newContent Domobject - The new content that is generated. + * + * return Promise - Resolved when the module dom has been updated. + */ var updateDomWithContent = function(module, speed, newHeader, newContent) { return new Promise((resolve) => { if (module.hidden || !speed) { @@ -146,6 +159,7 @@ var MM = (function() { * Check if the content has changed. * * argument module Module - The module to check. + * argument newHeader String - The new header that is generated. * argument newContent Domobject - The new content that is generated. * * return bool - Does the module need an update? @@ -173,6 +187,7 @@ var MM = (function() { * Update the content of a module on screen. * * argument module Module - The module to check. + * argument newHeader String - The new header that is generated. * argument newContent Domobject - The new content that is generated. */ var updateModuleContent = function(module, newHeader, newContent) { diff --git a/modules/README.md b/modules/README.md index 76973996..0b5c2d7c 100644 --- a/modules/README.md +++ b/modules/README.md @@ -230,11 +230,12 @@ notificationReceived: function(notification, payload, sender) { } ```` -**Note:** the system sends two notifications when starting up. These notifications could come in handy! +**Note:** the system sends three notifications when starting up. These notifications could come in handy! - `ALL_MODULES_STARTED` - All modules are started. You can now send notifications to other modules. - `DOM_OBJECTS_CREATED` - All dom objects are created. The system is now ready to perform visual changes. +- `MODULE_DOM_CREATED` - This module's dom has been fully loaded. You can now access your module's dom objects. #### `socketNotificationReceived: function(notification, payload)` From e2df5739f0d82b25de2372f6fe67f595b54d060e Mon Sep 17 00:00:00 2001 From: Connor Christie Date: Mon, 1 Jan 2018 10:40:52 -0600 Subject: [PATCH 6/8] Update module docs --- js/module.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/module.js b/js/module.js index dbcfe91f..71a14827 100644 --- a/js/module.js +++ b/js/module.js @@ -78,7 +78,7 @@ var Module = Class.extend({ * This method can to be subclassed if the module wants to display info on the mirror. * Alternatively, the getTemplete method could be subclassed. * - * return domobject - The dom to display. + * return DomObject | Promise - The dom or a promise with the dom to display. */ getDom: function () { return new Promise((resolve) => { From be3d7036923b8804904eb1e897e20eae2adcf587 Mon Sep 17 00:00:00 2001 From: Connor Christie Date: Mon, 1 Jan 2018 10:55:39 -0600 Subject: [PATCH 7/8] Fix linter errors --- js/main.js | 12 ++++++------ js/module.js | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/js/main.js b/js/main.js index 782b6863..0e1e5239 100644 --- a/js/main.js +++ b/js/main.js @@ -95,22 +95,22 @@ var MM = (function() { * * argument module Module - The module that needs an update. * argument speed Number - The number of microseconds for the animation. (optional) - * + * * return Promise - Resolved when the dom is fully updated. */ var updateDom = function(module, speed) { return new Promise((resolve) => { var newContentPromise = module.getDom(); var newHeader = module.getHeader(); - + if (!(newContentPromise instanceof Promise)) { // convert to a promise if not already one to avoid if/else's everywhere newContentPromise = Promise.resolve(newContentPromise); } - + newContentPromise.then((newContent) => { var updatePromise = updateDomWithContent(module, speed, newHeader, newContent); - + updatePromise.then(resolve).catch(Log.error); }).catch(Log.error); }); @@ -118,12 +118,12 @@ var MM = (function() { /* updateDomWithContent(module, speed, newHeader, newContent) * Update the dom with the specified content - * + * * argument module Module - The module that needs an update. * argument speed Number - The number of microseconds for the animation. (optional) * argument newHeader String - The new header that is generated. * argument newContent Domobject - The new content that is generated. - * + * * return Promise - Resolved when the module dom has been updated. */ var updateDomWithContent = function(module, speed, newHeader, newContent) { diff --git a/js/module.js b/js/module.js index 71a14827..57bdde4f 100644 --- a/js/module.js +++ b/js/module.js @@ -85,7 +85,7 @@ var Module = Class.extend({ var div = document.createElement("div"); var template = this.getTemplate(); var templateData = this.getTemplateData(); - + // Check to see if we need to render a template string or a file. if (/^.*((\.html)|(\.njk))$/.test(template)) { // the template is a filename From 9e83234df147e7d9e2d25eaeb3352f009c2bb521 Mon Sep 17 00:00:00 2001 From: Connor Christie Date: Tue, 2 Jan 2018 18:06:21 -0600 Subject: [PATCH 8/8] Update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad3cfd9e..8d65fc3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [2.2.3] - 2018-01-03 + +### Added + +- Add system notification `MODULE_DOM_CREATED` for notifying each module when their Dom has been fully loaded. + ## [2.2.2] - 2018-01-02 ### Added