From 05162ebd59996201150459ac9215546b0d5b540c Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Thu, 31 Mar 2016 14:20:43 +0200 Subject: [PATCH 1/7] Update todo. --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e1a937d7..873c0339 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,8 @@ This version of the Magic Mirror software focusses on a modular plugin system. B ##Todo Things that still have to be implemented or changed. -####Loader -- Loading of module uses `eval()`. We might want to look into a better solution. [loader.js#L112](https://github.com/MichMich/MagicMirror/blob/v2-beta/js/loader.js#L112). - +####Documentation +- Write all the documentation. :) ##Modules From c698d27a29aa4121ccb5b4dc3e1a28c815e96f26 Mon Sep 17 00:00:00 2001 From: Domi-G Date: Thu, 31 Mar 2016 15:07:55 +0200 Subject: [PATCH 2/7] Fixed layout for Firefox --- css/main.css | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/css/main.css b/css/main.css index 6492d8a8..61577936 100644 --- a/css/main.css +++ b/css/main.css @@ -1,7 +1,9 @@ body { cursor: none; margin: 60px; - position: relative; + position: absolute; + height: calc(100% - 120px); + width: calc(100% - 120px); background: #000; color: #aaa; font-family: 'roboto_condensedregular', arial; From ccff5c59218130229e42fd4af3fcd1ccc0a1519f Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Thu, 31 Mar 2016 17:05:35 +0200 Subject: [PATCH 3/7] Magic module selection. --- js/loader.js | 3 +- js/main.js | 168 +++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 150 insertions(+), 21 deletions(-) diff --git a/js/loader.js b/js/loader.js index edfe3106..a35c013c 100644 --- a/js/loader.js +++ b/js/loader.js @@ -87,7 +87,8 @@ var Loader = (function() { file: module + '.js', position: moduleData.position, header: moduleData.header, - config: moduleData.config + config: moduleData.config, + classes: (typeof moduleData.classes !== 'undefined') ? moduleData.classes + ' ' + module : module }); diff --git a/js/main.js b/js/main.js index 2325f9e0..7e12a9c2 100644 --- a/js/main.js +++ b/js/main.js @@ -21,22 +21,35 @@ var MM = (function() { var createDomObjects = function() { for (var m in modules) { var module = modules[m]; - if (module.data.position) { + + if (typeof module.data.position === 'string') { var wrapper = selectWrapper(module.data.position); - if (typeof module.data.header !== 'undefined' && module.data.header !== '') { - var header = document.createElement("header"); - header.innerHTML = module.data.header; - wrapper.appendChild(header); - } - var dom = document.createElement("div"); dom.id = module.identifier; dom.className = module.name; + + if (typeof module.data.classes === 'string') { + dom.className = dom.className + ' ' + module.data.classes; + } + + dom.opacity = 0; wrapper.appendChild(dom); - dom.appendChild(module.getDom()); + if (typeof module.data.header !== 'undefined' && module.data.header !== '') { + var moduleHeader = document.createElement("header"); + moduleHeader.innerHTML = module.data.header; + dom.appendChild(moduleHeader); + } + + var moduleContent = document.createElement("div"); + moduleContent.className = "module-content"; + dom.appendChild(moduleContent); + + + + updateDom(module, 500); } } @@ -82,32 +95,33 @@ var MM = (function() { * argument speed Number - The number of microseconds for the animation. (optional) */ var updateDom = function(module, speed) { - var wrapper = document.getElementById(module.identifier); + var moduleWrapper = document.getElementById(module.identifier); + var contentWrapper = moduleWrapper.getElementsByClassName('module-content')[0]; var newContent = module.getDom(); var tempWrapper = document.createElement('div'); tempWrapper.appendChild(newContent); - if (tempWrapper.innerHTML === wrapper.innerHTML) { + if (tempWrapper.innerHTML === contentWrapper.innerHTML) { // Content did not change. Abort update. return; } if (!speed) { - wrapper.innerHTML = null; - wrapper.appendChild(newContent); + contentWrapper.innerHTML = null; + contentWrapper.appendChild(newContent); return; } - wrapper.style.opacity = 1; - wrapper.style.transition = "opacity " + speed / 2 / 1000 + "s"; - wrapper.style.opacity = 0; + moduleWrapper.style.opacity = 1; + moduleWrapper.style.transition = "opacity " + speed / 2 / 1000 + "s"; + moduleWrapper.style.opacity = 0; setTimeout(function() { - wrapper.innerHTML = null; - wrapper.appendChild(newContent); + contentWrapper.innerHTML = null; + contentWrapper.appendChild(newContent); - wrapper.style.opacity = 1; + moduleWrapper.style.opacity = 1; }, speed / 2); }; @@ -125,9 +139,119 @@ var MM = (function() { config = Object.assign(defaults, config); }; + /* setSelectionMethodsForModules() + * Adds special selectors on a collection of modules. + * + * argument modules array - Array of modules. + */ + var setSelectionMethodsForModules = function(modules) { + + /* withClass(className) + * filters a collection of modules based on classname(s). + * + * argument className string/array - one or multiple classnames. (array or space devided) + * + * return array - Filtered collection of modules. + */ + var withClass = function(className) { + var newModules = []; + + var searchClasses = className; + if (typeof className === 'string') { + searchClasses = className.split(' '); + } + + for (var m in modules) { + var module = modules[m]; + var classes = module.data.classes.toLowerCase().split(' '); + + for (var c in searchClasses) { + var searchClass = searchClasses[c]; + if (classes.indexOf(searchClass.toLowerCase()) !== -1) { + newModules.push(module); + } + } + } + + setSelectionMethodsForModules(newModules); + return newModules; + }; + + /* exceptWithClass(className) + * filters a collection of modules based on classname(s). (NOT) + * + * argument className string/array - one or multiple classnames. (array or space devided) + * + * return array - Filtered collection of modules. + */ + var exceptWithClass = function(className) { + var newModules = []; + + var searchClasses = className; + if (typeof className === 'string') { + searchClasses = className.split(' '); + } + + for (var m in modules) { + var module = modules[m]; + var classes = module.data.classes.toLowerCase().split(' '); + var foundClass = false; + for (var c in searchClasses) { + var searchClass = searchClasses[c]; + if (classes.indexOf(searchClass.toLowerCase()) !== -1) { + foundClass = true; + break; + } + } + if (!foundClass) { + newModules.push(module); + } + } + + setSelectionMethodsForModules(newModules); + return newModules; + }; + + /* exceptModule(module) + * Removes a module instance from the collection. + * + * argument module Module object - The module instance to remove from the collection. + * + * return array - Filtered collection of modules. + */ + var exceptModule = function(module) { + var newModules = []; + + for (var m in modules) { + var mod = modules[m]; + if (mod.identifier !== module.identifier) { + newModules.push(mod); + } + } + + setSelectionMethodsForModules(newModules); + return newModules; + }; + + /* enumerate(callback) + * Walks thru a collection of modules and executes the callback with the module as an argument. + * + * argument callback function - The function to execute with the module as an argument. + */ + var enumerate = function(callback) { + for (var m in modules) { + var module = modules[m]; + callback(module); + } + }; + + Object.defineProperty(modules, 'withClass', {value: withClass, enumerable: false}); + Object.defineProperty(modules, 'exceptWithClass', {value: exceptWithClass, enumerable: false}); + Object.defineProperty(modules, 'exceptModule', {value: exceptModule, enumerable: false}); + Object.defineProperty(modules, 'enumerate', {value: enumerate, enumerable: false}); + }; return { - /* Public Methods */ /* init() @@ -198,8 +322,12 @@ var MM = (function() { // Further implementation is done in the private method. updateDom(module, speed); + }, + + getModules: function() { + setSelectionMethodsForModules(modules); + return modules; } - }; })(); From e5351c573beb8a58c6e779be246d2032db052be6 Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Thu, 31 Mar 2016 17:06:39 +0200 Subject: [PATCH 4/7] Add comments. --- js/main.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/js/main.js b/js/main.js index 7e12a9c2..65ad2d78 100644 --- a/js/main.js +++ b/js/main.js @@ -324,6 +324,11 @@ var MM = (function() { updateDom(module, speed); }, + /* getModules(module, speed) + * Returns a collection of all modules currently active. + * + * return array - A collection of all modules currently active. + */ getModules: function() { setSelectionMethodsForModules(modules); return modules; From d601919dc419935b11d975d4cfc450b752ff26a7 Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Thu, 31 Mar 2016 17:07:21 +0200 Subject: [PATCH 5/7] Minor visual changes. --- css/main.css | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/css/main.css b/css/main.css index 61577936..aa676d7f 100644 --- a/css/main.css +++ b/css/main.css @@ -35,7 +35,7 @@ body { header { - margin-top: 40px; + margin-top: 30px; text-transform: uppercase; font-size: 15px; font-family: 'roboto_condensedregular'; @@ -46,10 +46,6 @@ header { color: #666; } -header:first-child { - margin-top: 0px; -} - sup { font-size: 50%; line-height: 50%; From 584a12e1f5d4bf0e4660e3d4c8399f5dbbf8fbdb Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Thu, 31 Mar 2016 19:15:58 +0200 Subject: [PATCH 6/7] Method to hide/show modules. --- js/main.js | 144 ++++++++++++++++++++++++++++++++++++++++++--------- js/module.js | 21 ++++++++ 2 files changed, 141 insertions(+), 24 deletions(-) diff --git a/js/main.js b/js/main.js index 65ad2d78..667afcc8 100644 --- a/js/main.js +++ b/js/main.js @@ -95,35 +95,100 @@ var MM = (function() { * argument speed Number - The number of microseconds for the animation. (optional) */ var updateDom = function(module, speed) { + var newContent = module.getDom(); + + if (!module.hidden) { + + + if (!moduleNeedsUpdate(module, newContent)) { + return; + } + + if (!speed) { + updateModuleContent(module, newContent); + return; + } + + hideModule(module, speed / 2, function() { + updateModuleContent(module, newContent); + if (!module.hidden) { + showModule(module, speed / 2); + } + }); + } else { + updateModuleContent(module, newContent); + } + }; + + + /* moduleNeedsUpdate(module, newContent) + * Check if the content has changed. + * + * argument module Module - The module to check. + * argument newContent Domobject - The new content that is generated. + * + * return bool - Does the module need an update? + */ + var moduleNeedsUpdate = function(module, newContent) { var moduleWrapper = document.getElementById(module.identifier); var contentWrapper = moduleWrapper.getElementsByClassName('module-content')[0]; - var newContent = module.getDom(); var tempWrapper = document.createElement('div'); tempWrapper.appendChild(newContent); - if (tempWrapper.innerHTML === contentWrapper.innerHTML) { - // Content did not change. Abort update. - return; + return tempWrapper.innerHTML !== contentWrapper.innerHTML; + }; + + /* moduleNeedsUpdate(module, newContent) + * Update the content of a module on screen. + * + * argument module Module - The module to check. + * argument newContent Domobject - The new content that is generated. + */ + var updateModuleContent = function(module, content) { + var moduleWrapper = document.getElementById(module.identifier); + var contentWrapper = moduleWrapper.getElementsByClassName('module-content')[0]; + + contentWrapper.innerHTML = null; + contentWrapper.appendChild(content); + }; + + /* hideModule(module, speed, callback) + * Hide the module. + * + * argument module Module - The module to hide. + * argument speed Number - The speed of the hide animation. + * argument callback function - Called when the animation is done. + */ + var hideModule = function(module, speed, callback) { + var moduleWrapper = document.getElementById(module.identifier); + if (moduleWrapper !== null) { + moduleWrapper.style.transition = "opacity " + speed / 1000 + "s"; + moduleWrapper.style.opacity = 0; + + setTimeout(function() { + if (typeof callback === 'function') { callback(); } + }, speed); } + }; - if (!speed) { - contentWrapper.innerHTML = null; - contentWrapper.appendChild(newContent); - return; + /* showModule(module, speed, callback) + * Show the module. + * + * argument module Module - The module to show. + * argument speed Number - The speed of the show animation. + * argument callback function - Called when the animation is done. + */ + var showModule = function(module, speed, callback) { + var moduleWrapper = document.getElementById(module.identifier); + if (moduleWrapper !== null) { + moduleWrapper.style.transition = "opacity " + speed / 1000 + "s"; + moduleWrapper.style.opacity = 1; + + setTimeout(function() { + if (typeof callback === 'function') { callback(); } + }, speed); } - - moduleWrapper.style.opacity = 1; - moduleWrapper.style.transition = "opacity " + speed / 2 / 1000 + "s"; - moduleWrapper.style.opacity = 0; - - setTimeout(function() { - contentWrapper.innerHTML = null; - contentWrapper.appendChild(newContent); - - moduleWrapper.style.opacity = 1; - }, speed / 2); - }; /* loadConfig() @@ -245,11 +310,16 @@ var MM = (function() { } }; - Object.defineProperty(modules, 'withClass', {value: withClass, enumerable: false}); - Object.defineProperty(modules, 'exceptWithClass', {value: exceptWithClass, enumerable: false}); - Object.defineProperty(modules, 'exceptModule', {value: exceptModule, enumerable: false}); - Object.defineProperty(modules, 'enumerate', {value: enumerate, enumerable: false}); + + + if (typeof modules.withClass === 'undefined') { Object.defineProperty(modules, 'withClass', {value: withClass, enumerable: false}); } + if (typeof modules.exceptWithClass === 'undefined') { Object.defineProperty(modules, 'exceptWithClass', {value: exceptWithClass, enumerable: false}); } + if (typeof modules.exceptModule === 'undefined') { Object.defineProperty(modules, 'exceptModule', {value: exceptModule, enumerable: false}); } + if (typeof modules.enumerate === 'undefined') { Object.defineProperty(modules, 'enumerate', {value: enumerate, enumerable: false}); } }; + + + return { /* Public Methods */ @@ -332,6 +402,32 @@ var MM = (function() { getModules: function() { setSelectionMethodsForModules(modules); return modules; + }, + + /* hideModule(module, speed, callback) + * Hide the module. + * + * argument module Module - The module hide. + * argument speed Number - The speed of the hide animation. + * argument callback function - Called when the animation is done. + */ + hideModule: function(module, speed, callback) { + hideModule(module, speed, function() { + module.hidden = true; + callback(); + }); + }, + + /* showModule(module, speed, callback) + * Show the module. + * + * argument module Module - The module show. + * argument speed Number - The speed of the show animation. + * argument callback function - Called when the animation is done. + */ + showModule: function(module, speed, callback) { + module.hidden = false; + showModule(module, speed, callback); } }; diff --git a/js/module.js b/js/module.js index f77f288a..20609b54 100644 --- a/js/module.js +++ b/js/module.js @@ -113,6 +113,7 @@ var Module = Class.extend({ this.data = data; this.name = data.name; this.identifier = data.identifier; + this.hidden = false; this.setConfig(data.config); }, @@ -229,6 +230,26 @@ var Module = Class.extend({ */ sendSocketNotification: function(notification, payload) { this.socket().sendNotification(notification, payload); + }, + + /* hideModule(module, speed, callback) + * Hide this module. + * + * argument speed Number - The speed of the hide animation. + * argument callback function - Called when the animation is done. + */ + hide: function(speed, callback) { + MM.hideModule(this, speed, callback); + }, + + /* showModule(module, speed, callback) + * Show this module. + * + * argument speed Number - The speed of the show animation. + * argument callback function - Called when the animation is done. + */ + show: function(speed, callback) { + MM.showModule(this, speed, callback); } }); From 38e42cf71e07b9c96f95adbc2e7c1ea34dd92035 Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Thu, 31 Mar 2016 19:25:53 +0200 Subject: [PATCH 7/7] Type check. --- js/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/main.js b/js/main.js index 667afcc8..fb1411e9 100644 --- a/js/main.js +++ b/js/main.js @@ -414,7 +414,7 @@ var MM = (function() { hideModule: function(module, speed, callback) { hideModule(module, speed, function() { module.hidden = true; - callback(); + if (typeof callback === 'function') { callback(); } }); },