Run prettier over ALL files once

No other changes done in this commit
This commit is contained in:
Veeck 2020-05-11 22:22:32 +02:00
parent 3a5a29efc0
commit abb5dc5739
160 changed files with 2369 additions and 2210 deletions

View file

@ -1,5 +1,4 @@
Contribution Policy for MagicMirror² # Contribution Policy for MagicMirror²
====================================
Thanks for contributing to MagicMirror²! Thanks for contributing to MagicMirror²!
@ -30,7 +29,7 @@ Problems installing or configuring your MagicMirror? Check out: [https://forum.m
When submitting a new issue, please supply the following information: When submitting a new issue, please supply the following information:
**Platform**: Place your platform here... give us your web browser/Electron version *and* your hardware (Raspberry Pi 2/3, Windows, Mac, Linux, System V UNIX). **Platform**: Place your platform here... give us your web browser/Electron version _and_ your hardware (Raspberry Pi 2/3, Windows, Mac, Linux, System V UNIX).
**Node Version**: Make sure it's version 0.12.13 or later. **Node Version**: Make sure it's version 0.12.13 or later.

View file

@ -1,24 +1,29 @@
## I'm not sure if this is a bug ## I'm not sure if this is a bug
If you're not sure if it's a real bug or if it's just you, please open a topic on the forum: [https://forum.magicmirror.builders/category/15/bug-hunt](https://forum.magicmirror.builders/category/15/bug-hunt) If you're not sure if it's a real bug or if it's just you, please open a topic on the forum: [https://forum.magicmirror.builders/category/15/bug-hunt](https://forum.magicmirror.builders/category/15/bug-hunt)
## I'm having troubles installing or configuring MagicMirror ## I'm having troubles installing or configuring MagicMirror
Problems installing or configuring your MagicMirror? Check out: [https://forum.magicmirror.builders/category/10/troubleshooting](https://forum.magicmirror.builders/category/10/troubleshooting) Problems installing or configuring your MagicMirror? Check out: [https://forum.magicmirror.builders/category/10/troubleshooting](https://forum.magicmirror.builders/category/10/troubleshooting)
## I found a bug in the MagicMirror installer ## I found a bug in the MagicMirror installer
If you are facing an issue or found a bug while trying to install MagicMirror via the installer please report it in the respective GitHub repository: If you are facing an issue or found a bug while trying to install MagicMirror via the installer please report it in the respective GitHub repository:
[https://github.com/sdetweil/MagicMirror_scripts](https://github.com/sdetweil/MagicMirror_scripts) [https://github.com/sdetweil/MagicMirror_scripts](https://github.com/sdetweil/MagicMirror_scripts)
## I found a bug in the MagicMirror Docker image ## I found a bug in the MagicMirror Docker image
If you are facing an issue or found a bug while running MagicMirror inside a Docker container please create an issue in the GitHub repository of the MagicMirror Docker image: If you are facing an issue or found a bug while running MagicMirror inside a Docker container please create an issue in the GitHub repository of the MagicMirror Docker image:
[https://github.com/bastilimbach/docker-MagicMirror](https://github.com/bastilimbach/docker-MagicMirror) [https://github.com/bastilimbach/docker-MagicMirror](https://github.com/bastilimbach/docker-MagicMirror)
--- ---
## I found a bug in MagicMirror ## I found a bug in MagicMirror
Please make sure to only submit reproducible issues. You can safely remove everything above the dividing line. Please make sure to only submit reproducible issues. You can safely remove everything above the dividing line.
When submitting a new issue, please supply the following information: When submitting a new issue, please supply the following information:
**Platform**: Place your platform here... give us your web browser/Electron version *and* your hardware (Raspberry Pi 2/3, Windows, Mac, Linux, System V UNIX). **Platform**: Place your platform here... give us your web browser/Electron version _and_ your hardware (Raspberry Pi 2/3, Windows, Mac, Linux, System V UNIX).
**Node Version**: Make sure it's version 8 or later. **Node Version**: Make sure it's version 8 or later.

View file

@ -7,8 +7,7 @@ pull request to send us your changes. This makes everyone's lives
easier (including yours) and helps us out on the development team. easier (including yours) and helps us out on the development team.
Thanks! Thanks!
- Does the pull request solve a **related** issue?
* Does the pull request solve a **related** issue? - If so, can you reference the issue?
* If so, can you reference the issue? - What does the pull request accomplish? Use a list if needed.
* What does the pull request accomplish? Use a list if needed. - If it includes major visual changes please add screenshots.
* If it includes major visual changes please add screenshots.

View file

@ -7,13 +7,14 @@ This project adheres to [Semantic Versioning](https://semver.org/).
## [2.12.0] - Unreleased (Develop Branch) ## [2.12.0] - Unreleased (Develop Branch)
*This release is scheduled to be released on 2020-07-01.* _This release is scheduled to be released on 2020-07-01._
### Added ### Added
- Added prettier for an even cleaner codebase - Added prettier for an even cleaner codebase
### Updated ### Updated
- Cleaned up alert module code - Cleaned up alert module code
- Cleaned up check_config code - Cleaned up check_config code
- Replaced grunt-based linters with their non-grunt equivalents - Replaced grunt-based linters with their non-grunt equivalents
@ -22,9 +23,11 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- Cleaned up all "no-undef" warnings from eslint - Cleaned up all "no-undef" warnings from eslint
### Deleted ### Deleted
- Removed truetype (ttf) fonts - Removed truetype (ttf) fonts
### Fixed ### Fixed
- The broken modules due to Socket.io change from last release [#1973](https://github.com/MichMich/MagicMirror/issues/1973) - The broken modules due to Socket.io change from last release [#1973](https://github.com/MichMich/MagicMirror/issues/1973)
- Add backward compatibility for old module code in socketclient.js [#1973](https://github.com/MichMich/MagicMirror/issues/1973) - Add backward compatibility for old module code in socketclient.js [#1973](https://github.com/MichMich/MagicMirror/issues/1973)
@ -37,11 +40,13 @@ In the past years the project has grown a lot. This came with a huge downside: p
For more information regarding this major change, please check issue [#1860](https://github.com/MichMich/MagicMirror/issues/1860). For more information regarding this major change, please check issue [#1860](https://github.com/MichMich/MagicMirror/issues/1860).
### Deleted ### Deleted
- Remove installers. - Remove installers.
- Remove externalized scripts. - Remove externalized scripts.
- Remove jshint dependency, instead eslint checks your config file now - Remove jshint dependency, instead eslint checks your config file now
### Added ### Added
- Brazilian translation for "FEELS". - Brazilian translation for "FEELS".
- Ukrainian translation. - Ukrainian translation.
- Finnish translation for "PRECIP", "UPDATE_INFO_MULTIPLE" and "UPDATE_INFO_SINGLE". - Finnish translation for "PRECIP", "UPDATE_INFO_MULTIPLE" and "UPDATE_INFO_SINGLE".
@ -56,6 +61,7 @@ For more information regarding this major change, please check issue [#1860](htt
- Add HTTPS support for clientonly-mode. - Add HTTPS support for clientonly-mode.
### Fixed ### Fixed
- Force declaration of public ip address in config file (ISSUE #1852) - Force declaration of public ip address in config file (ISSUE #1852)
- Fixes `run-start.sh`: If running in docker-container, don't check the environment, just start electron (ISSUE #1859) - Fixes `run-start.sh`: If running in docker-container, don't check the environment, just start electron (ISSUE #1859)
- Fix calendar time offset for recurring events crossing Daylight Savings Time (ISSUE #1798) - Fix calendar time offset for recurring events crossing Daylight Savings Time (ISSUE #1798)
@ -66,6 +72,7 @@ For more information regarding this major change, please check issue [#1860](htt
- Fix update checking skipping 3rd party modules the first time - Fix update checking skipping 3rd party modules the first time
### Changed ### Changed
- Remove documentation from core repository and link to new dedicated docs site: [docs.magicmirror.builders](https://docs.magicmirror.builders). - Remove documentation from core repository and link to new dedicated docs site: [docs.magicmirror.builders](https://docs.magicmirror.builders).
- Updated config.js.sample: Corrected some grammar on `config.js.sample` comment section. - Updated config.js.sample: Corrected some grammar on `config.js.sample` comment section.
- Removed `run-start.sh` script and update start commands: - Removed `run-start.sh` script and update start commands:
@ -79,6 +86,7 @@ For more information regarding this major change, please check issue [#1860](htt
## [2.10.1] - 2020-01-10 ## [2.10.1] - 2020-01-10
### Changed ### Changed
- Updated README.md: Added links to the official documentation website and remove links to broken installer. - Updated README.md: Added links to the official documentation website and remove links to broken installer.
## [2.10.0] - 2020-01-01 ## [2.10.0] - 2020-01-01
@ -88,12 +96,14 @@ Special thanks to @sdetweil for all his great contributions!
**Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`. **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`.
### Added ### Added
- Timestamps in log output. - Timestamps in log output.
- Padding in dateheader mode of the calendar module. - Padding in dateheader mode of the calendar module.
- New upgrade script to help users consume regular updates installers/upgrade-script.sh. - New upgrade script to help users consume regular updates installers/upgrade-script.sh.
- New script to help setup pm2, without install installers/fixuppm2.sh. - New script to help setup pm2, without install installers/fixuppm2.sh.
### Updated ### Updated
- Updated lower bound of `lodash` and `helmet` dependencies for security patches. - Updated lower bound of `lodash` and `helmet` dependencies for security patches.
- Updated compliments.js to handle newline in text, as textfields to not interpolate contents. - Updated compliments.js to handle newline in text, as textfields to not interpolate contents.
- Updated raspberry.sh installer script to handle new platform issues, split node/npm, pm2, and screen saver changes. - Updated raspberry.sh installer script to handle new platform issues, split node/npm, pm2, and screen saver changes.
@ -102,6 +112,7 @@ Special thanks to @sdetweil for all his great contributions!
- Only check for xwindows running if not on macOS. - Only check for xwindows running if not on macOS.
### Fixed ### Fixed
- Fixed issue in weatherforecast module where predicted amount of rain was not using the decimal symbol specified in config.js. - Fixed issue in weatherforecast module where predicted amount of rain was not using the decimal symbol specified in config.js.
- Module header now updates correctly, if a module need to dynamically show/hide its header based on a condition. - Module header now updates correctly, if a module need to dynamically show/hide its header based on a condition.
- Fix handling of config.js for serverOnly mode commented out. - Fix handling of config.js for serverOnly mode commented out.
@ -114,18 +125,21 @@ Special thanks to @sdetweil for all his great contributions!
**Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`. If you are having issues running Electron, make sure your [Raspbian is up to date](https://www.raspberrypi.org/documentation/raspbian/updating.md). **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`. If you are having issues running Electron, make sure your [Raspbian is up to date](https://www.raspberrypi.org/documentation/raspbian/updating.md).
### Added ### Added
- Spanish translation for "PRECIP". - Spanish translation for "PRECIP".
- Adding a Malay (Malaysian) translation for MagicMirror². - Adding a Malay (Malaysian) translation for MagicMirror².
- Add test check URLs of vendors 200 and 404 HTTP CODE. - Add test check URLs of vendors 200 and 404 HTTP CODE.
- Add tests for new weather module and helper to stub ajax requests. - Add tests for new weather module and helper to stub ajax requests.
### Updated ### Updated
- Updatenotification module: Display update notification for a limited (configurable) time. - Updatenotification module: Display update notification for a limited (configurable) time.
- Enabled e2e/vendor_spec.js tests. - Enabled e2e/vendor_spec.js tests.
- The css/custom.css will be renamed after the next release. We've added into `run-start.sh` an instruction by GIT to ignore with `--skip-worktree` and `rm --cached`. [#1540](https://github.com/MichMich/MagicMirror/issues/1540) - The css/custom.css will be renamed after the next release. We've added into `run-start.sh` an instruction by GIT to ignore with `--skip-worktree` and `rm --cached`. [#1540](https://github.com/MichMich/MagicMirror/issues/1540)
- Disable sending of notification CLOCK_SECOND when displaySeconds is false. - Disable sending of notification CLOCK_SECOND when displaySeconds is false.
### Fixed ### Fixed
- Updatenotification module: Properly handle race conditions, prevent crash. - Updatenotification module: Properly handle race conditions, prevent crash.
- Send `NEWS_FEED` notification also for the first news messages which are shown. - Send `NEWS_FEED` notification also for the first news messages which are shown.
- Fixed issue where weather module would not refresh data after a network or API outage. [#1722](https://github.com/MichMich/MagicMirror/issues/1722) - Fixed issue where weather module would not refresh data after a network or API outage. [#1722](https://github.com/MichMich/MagicMirror/issues/1722)
@ -137,6 +151,7 @@ Special thanks to @sdetweil for all his great contributions!
**Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`. If you are having issues running Electron, make sure your [Raspbian is up to date](https://www.raspberrypi.org/documentation/raspbian/updating.md). **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`. If you are having issues running Electron, make sure your [Raspbian is up to date](https://www.raspberrypi.org/documentation/raspbian/updating.md).
### Added ### Added
- Option to show event location in calendar - Option to show event location in calendar
- Finnish translation for "Feels" and "Weeks" - Finnish translation for "Feels" and "Weeks"
- Russian translation for “Feels” - Russian translation for “Feels”
@ -156,6 +171,7 @@ Special thanks to @sdetweil for all his great contributions!
- Added to `newsfeed.js`: in order to design the news article better with css, three more class-names were introduced: newsfeed-desc, newsfeed-desc, newsfeed-desc - Added to `newsfeed.js`: in order to design the news article better with css, three more class-names were introduced: newsfeed-desc, newsfeed-desc, newsfeed-desc
### Updated ### Updated
- English translation for "Feels" to "Feels like" - English translation for "Feels" to "Feels like"
- Fixed the example calendar url in `config.js.sample` - Fixed the example calendar url in `config.js.sample`
- Update `ical.js` to solve various calendar issues. - Update `ical.js` to solve various calendar issues.
@ -163,6 +179,7 @@ Special thanks to @sdetweil for all his great contributions!
- Only update clock once per minute when seconds aren't shown - Only update clock once per minute when seconds aren't shown
### Fixed ### Fixed
- Fixed uncaught exception, race condition on module update - Fixed uncaught exception, race condition on module update
- Fixed issue [#1696](https://github.com/MichMich/MagicMirror/issues/1696), some ical files start date to not parse to date type - Fixed issue [#1696](https://github.com/MichMich/MagicMirror/issues/1696), some ical files start date to not parse to date type
- Allowance HTML5 autoplay-policy (policy is changed from Chrome 66 updates) - Allowance HTML5 autoplay-policy (policy is changed from Chrome 66 updates)
@ -174,6 +191,7 @@ Special thanks to @sdetweil for all his great contributions!
- Updated the fetchedLocationName variable in currentweather.js so that city shows up in the header - Updated the fetchedLocationName variable in currentweather.js so that city shows up in the header
### Updated installer ### Updated installer
- give non-pi2+ users (pi0, odroid, jetson nano, mac, windows, ...) option to continue install - give non-pi2+ users (pi0, odroid, jetson nano, mac, windows, ...) option to continue install
- use current username vs hardcoded 'pi' to support non-pi install - use current username vs hardcoded 'pi' to support non-pi install
- check for npm installed. node install doesn't do npm anymore - check for npm installed. node install doesn't do npm anymore
@ -190,6 +208,7 @@ Fixed `package.json` version number.
**Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`. If you are having issues running Electron, make sure your [Raspbian is up to date](https://www.raspberrypi.org/documentation/raspbian/updating.md). **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`. If you are having issues running Electron, make sure your [Raspbian is up to date](https://www.raspberrypi.org/documentation/raspbian/updating.md).
### Added ### Added
- Italian translation for "Feels" - Italian translation for "Feels"
- Basic Klingon (tlhIngan Hol) translations - Basic Klingon (tlhIngan Hol) translations
- Disabled the screensaver on raspbian with installation script - Disabled the screensaver on raspbian with installation script
@ -203,12 +222,14 @@ Fixed `package.json` version number.
- Add `name` config option for calendars to be sent along with event broadcasts - Add `name` config option for calendars to be sent along with event broadcasts
### Updated ### Updated
- Bumped the Electron dependency to v3.0.13 to support the most recent Raspbian. [#1500](https://github.com/MichMich/MagicMirror/issues/1500) - Bumped the Electron dependency to v3.0.13 to support the most recent Raspbian. [#1500](https://github.com/MichMich/MagicMirror/issues/1500)
- Updated modernizr code in alert module, fixed a small typo there too - Updated modernizr code in alert module, fixed a small typo there too
- More verbose error message on console if the config is malformed - More verbose error message on console if the config is malformed
- Updated installer script to install Node.js version 10.x - Updated installer script to install Node.js version 10.x
### Fixed ### Fixed
- Fixed temperature displays in currentweather and weatherforecast modules [#1503](https://github.com/MichMich/MagicMirror/issues/1503), [#1511](https://github.com/MichMich/MagicMirror/issues/1511). - Fixed temperature displays in currentweather and weatherforecast modules [#1503](https://github.com/MichMich/MagicMirror/issues/1503), [#1511](https://github.com/MichMich/MagicMirror/issues/1511).
- Fixed unhandled error on bad git data in updatenotification module [#1285](https://github.com/MichMich/MagicMirror/issues/1285). - Fixed unhandled error on bad git data in updatenotification module [#1285](https://github.com/MichMich/MagicMirror/issues/1285).
- Weather forecast now works with openweathermap in new weather module. Daily data are displayed, see issue [#1504](https://github.com/MichMich/MagicMirror/issues/1504). - Weather forecast now works with openweathermap in new weather module. Daily data are displayed, see issue [#1504](https://github.com/MichMich/MagicMirror/issues/1504).
@ -226,6 +247,7 @@ Fixed `package.json` version number.
- Fix documentation of `useKMPHwind` option in currentweather - Fix documentation of `useKMPHwind` option in currentweather
### New weather module ### New weather module
- Fixed weather forecast table display [#1499](https://github.com/MichMich/MagicMirror/issues/1499). - Fixed weather forecast table display [#1499](https://github.com/MichMich/MagicMirror/issues/1499).
- Dimmed loading indicator for weather forecast. - Dimmed loading indicator for weather forecast.
- Implemented config option `decimalSymbol` [#1499](https://github.com/MichMich/MagicMirror/issues/1499). - Implemented config option `decimalSymbol` [#1499](https://github.com/MichMich/MagicMirror/issues/1499).
@ -243,11 +265,13 @@ Fixed `package.json` version number.
**Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`. If you are having issues updating, make sure you are running the latest version of Node. **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`. If you are having issues updating, make sure you are running the latest version of Node.
### ✨ Experimental ✨ ### ✨ Experimental ✨
- New default [module weather](modules/default/weather). This module will eventually replace the current `currentweather` and `weatherforecast` modules. The new module is still pretty experimental, but it's included so you can give it a try and help us improve this module. Please give us you feedback using [this forum post](https://forum.magicmirror.builders/topic/9335/default-weather-module-refactoring). - New default [module weather](modules/default/weather). This module will eventually replace the current `currentweather` and `weatherforecast` modules. The new module is still pretty experimental, but it's included so you can give it a try and help us improve this module. Please give us you feedback using [this forum post](https://forum.magicmirror.builders/topic/9335/default-weather-module-refactoring).
A huge, huge, huge thanks to user @fewieden for all his hard work on the new `weather` module! A huge, huge, huge thanks to user @fewieden for all his hard work on the new `weather` module!
### Added ### Added
- Possibility to add classes to the cell of symbol, title and time of the events of calendar. - Possibility to add classes to the cell of symbol, title and time of the events of calendar.
- Font-awesome 5, still has 4 for backwards compatibility. - Font-awesome 5, still has 4 for backwards compatibility.
- Missing `showEnd` in calendar documentation - Missing `showEnd` in calendar documentation
@ -262,6 +286,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Documentation for the existing `scale` option in the Weather Forecast module. - Documentation for the existing `scale` option in the Weather Forecast module.
### Fixed ### Fixed
- Allow parsing recurring calendar events where the start date is before 1900 - Allow parsing recurring calendar events where the start date is before 1900
- Fixed Polish translation for Single Update Info - Fixed Polish translation for Single Update Info
- Ignore entries with unparseable details in the calendar module - Ignore entries with unparseable details in the calendar module
@ -269,15 +294,17 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Bug in newsfeed when `removeStartTags` is used on the description [#1478](https://github.com/MichMich/MagicMirror/issues/1478) - Bug in newsfeed when `removeStartTags` is used on the description [#1478](https://github.com/MichMich/MagicMirror/issues/1478)
### Updated ### Updated
- The default calendar setting `showEnd` is changed to `false`. - The default calendar setting `showEnd` is changed to `false`.
### Changed ### Changed
- The Weather Forecast module by default displays the ° symbol after every numeric value to be consistent with the Current Weather module.
- The Weather Forecast module by default displays the ° symbol after every numeric value to be consistent with the Current Weather module.
## [2.5.0] - 2018-10-01 ## [2.5.0] - 2018-10-01
### Added ### Added
- Romanian translation for "Feels" - Romanian translation for "Feels"
- Support multi-line compliments - Support multi-line compliments
- Simplified Chinese translation for "Feels" - Simplified Chinese translation for "Feels"
@ -292,6 +319,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Support for showing end of events through config parameters showEnd and dateEndFormat - Support for showing end of events through config parameters showEnd and dateEndFormat
### Fixed ### Fixed
- Fixed gzip encoded calendar loading issue #1400. - Fixed gzip encoded calendar loading issue #1400.
- Mixup between german and spanish translation for newsfeed. - Mixup between german and spanish translation for newsfeed.
- Fixed close dates to be absolute, if no configured in the config.js - module Calendar - Fixed close dates to be absolute, if no configured in the config.js - module Calendar
@ -337,11 +365,13 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Add update translations for Português Brasileiro - Add update translations for Português Brasileiro
### Changed ### Changed
- Upgrade to Electron 2.0.0. - Upgrade to Electron 2.0.0.
- Remove yarn-or-npm which breaks production builds. - Remove yarn-or-npm which breaks production builds.
- Invoke module suspend even if no dom content. [#1308](https://github.com/MichMich/MagicMirror/issues/1308) - Invoke module suspend even if no dom content. [#1308](https://github.com/MichMich/MagicMirror/issues/1308)
### Fixed ### Fixed
- Fixed issue where wind chill could not be displayed in Fahrenheit. [#1247](https://github.com/MichMich/MagicMirror/issues/1247) - Fixed issue where wind chill could not be displayed in Fahrenheit. [#1247](https://github.com/MichMich/MagicMirror/issues/1247)
- Fixed issues where a module crashes when it tries to dismiss a non existing alert. [#1240](https://github.com/MichMich/MagicMirror/issues/1240) - Fixed issues where a module crashes when it tries to dismiss a non existing alert. [#1240](https://github.com/MichMich/MagicMirror/issues/1240)
- In default module currentWeather/currentWeather.js line 296, 300, self.config.animationSpeed can not be found because the notificationReceived function does not have "self" variable. - In default module currentWeather/currentWeather.js line 296, 300, self.config.animationSpeed can not be found because the notificationReceived function does not have "self" variable.
@ -354,6 +384,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Fixed issue where heat index and wind chill were reporting incorrect values in Kelvin. [#1263](https://github.com/MichMich/MagicMirror/issues/1263) - Fixed issue where heat index and wind chill were reporting incorrect values in Kelvin. [#1263](https://github.com/MichMich/MagicMirror/issues/1263)
### Updated ### Updated
- Updated Italian translation - Updated Italian translation
- Updated German translation - Updated German translation
- Updated Dutch translation - Updated Dutch translation
@ -361,6 +392,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
## [2.3.1] - 2018-04-01 ## [2.3.1] - 2018-04-01
### Fixed ### Fixed
- Downgrade electron to 1.4.15 to solve the black screen issue.[#1243](https://github.com/MichMich/MagicMirror/issues/1243) - Downgrade electron to 1.4.15 to solve the black screen issue.[#1243](https://github.com/MichMich/MagicMirror/issues/1243)
## [2.3.0] - 2018-04-01 ## [2.3.0] - 2018-04-01
@ -381,6 +413,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Add dc:date to parsing in newsfeed module, which allows parsing of more rss feeds. - Add dc:date to parsing in newsfeed module, which allows parsing of more rss feeds.
### Changed ### Changed
- Add link to GitHub repository which contains the respective Dockerfile. - Add link to GitHub repository which contains the respective Dockerfile.
- Optimized automated unit tests cloneObject, cmpVersions - Optimized automated unit tests cloneObject, cmpVersions
- Update notifications use now translation templates instead of normal strings. - Update notifications use now translation templates instead of normal strings.
@ -388,6 +421,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Changed Electron dependency to v1.7.13. - Changed Electron dependency to v1.7.13.
### Fixed ### Fixed
- News article in fullscreen (iframe) is now shown in front of modules. - News article in fullscreen (iframe) is now shown in front of modules.
- Forecast respects maxNumberOfDays regardless of endpoint. - Forecast respects maxNumberOfDays regardless of endpoint.
- Fix exception on translation of objects. - Fix exception on translation of objects.
@ -405,6 +439,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
## [2.2.1] - 2018-01-01 ## [2.2.1] - 2018-01-01
### Fixed ### Fixed
- Fixed linting errors. - Fixed linting errors.
## [2.2.0] - 2018-01-01 ## [2.2.0] - 2018-01-01
@ -412,10 +447,12 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
**Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install` **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`
### Changed ### Changed
- Calendar week is now handled with a variable translation in order to move number language specific. - Calendar week is now handled with a variable translation in order to move number language specific.
- Reverted the Electron dependency back to 1.4.15 since newer version don't seem to work on the Raspberry Pi very well. - Reverted the Electron dependency back to 1.4.15 since newer version don't seem to work on the Raspberry Pi very well.
### Added ### Added
- Add option to use [Nunjucks](https://mozilla.github.io/nunjucks/) templates in modules. (See `helloworld` module as an example.) - Add option to use [Nunjucks](https://mozilla.github.io/nunjucks/) templates in modules. (See `helloworld` module as an example.)
- Add Bulgarian translations for MagicMirror² and Alert module. - Add Bulgarian translations for MagicMirror² and Alert module.
- Add graceful shutdown of modules by calling `stop` function of each `node_helper` on SIGINT before exiting. - Add graceful shutdown of modules by calling `stop` function of each `node_helper` on SIGINT before exiting.
@ -429,6 +466,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Add option for decimal symbols other than the decimal point for temperature values in both default weather modules: WeatherForecast and CurrentWeather. - Add option for decimal symbols other than the decimal point for temperature values in both default weather modules: WeatherForecast and CurrentWeather.
### Fixed ### Fixed
- Fixed issue with calendar module showing more than `maximumEntries` allows - Fixed issue with calendar module showing more than `maximumEntries` allows
- WeatherForecast and CurrentWeather are now using HTTPS instead of HTTP - WeatherForecast and CurrentWeather are now using HTTPS instead of HTTP
- Correcting translation for Indonesian language - Correcting translation for Indonesian language
@ -439,9 +477,11 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
**Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install` **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`
### Changed ### Changed
- Remove Roboto fonts files inside `fonts` and these are installed by npm install command. - Remove Roboto fonts files inside `fonts` and these are installed by npm install command.
### Added ### Added
- Add `clientonly` script to start only the electron client for a remote server. - Add `clientonly` script to start only the electron client for a remote server.
- Add symbol and color properties of event when `CALENDAR_EVENTS` notification is broadcasted from `default/calendar` module. - Add symbol and color properties of event when `CALENDAR_EVENTS` notification is broadcasted from `default/calendar` module.
- Add `.vscode/` folder to `.gitignore` to keep custom Visual Studio Code config out of git. - Add `.vscode/` folder to `.gitignore` to keep custom Visual Studio Code config out of git.
@ -458,6 +498,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Add Slack badge to Readme. - Add Slack badge to Readme.
### Updated ### Updated
- Changed 'default.js' - listen on all attached interfaces by default. - Changed 'default.js' - listen on all attached interfaces by default.
- Add execution of `npm list` after the test are ran in Travis CI. - Add execution of `npm list` after the test are ran in Travis CI.
- Change hooks for the vendors e2e tests. - Change hooks for the vendors e2e tests.
@ -466,6 +507,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Set version of the `express-ipfilter` on 0.3.1. - Set version of the `express-ipfilter` on 0.3.1.
### Fixed ### Fixed
- Fixed issue with incorrect alignment of analog clock when displayed in the center column of the MM. - Fixed issue with incorrect alignment of analog clock when displayed in the center column of the MM.
- Fixed ipWhitelist behaviour to make empty whitelist ([]) allow any and all hosts access to the MM. - Fixed ipWhitelist behaviour to make empty whitelist ([]) allow any and all hosts access to the MM.
- Fixed issue with calendar module where 'excludedEvents' count towards 'maximumEntries'. - Fixed issue with calendar module where 'excludedEvents' count towards 'maximumEntries'.
@ -476,11 +518,13 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
## [2.1.2] - 2017-07-01 ## [2.1.2] - 2017-07-01
### Changed ### Changed
- Revert Docker related changes in favor of [docker-MagicMirror](https://github.com/bastilimbach/docker-MagicMirror). All Docker images are outsourced. ([#856](https://github.com/MichMich/MagicMirror/pull/856)) - Revert Docker related changes in favor of [docker-MagicMirror](https://github.com/bastilimbach/docker-MagicMirror). All Docker images are outsourced. ([#856](https://github.com/MichMich/MagicMirror/pull/856))
- Change Docker base image (Debian + Node) to an arm based distro (AlpineARM + Node) ([#846](https://github.com/MichMich/MagicMirror/pull/846)) - Change Docker base image (Debian + Node) to an arm based distro (AlpineARM + Node) ([#846](https://github.com/MichMich/MagicMirror/pull/846))
- Fix the dockerfile to have it running from the first time. - Fix the dockerfile to have it running from the first time.
### Added ### Added
- Add in option to wrap long calendar events to multiple lines using `wrapEvents` configuration option. - Add in option to wrap long calendar events to multiple lines using `wrapEvents` configuration option.
- Add test e2e `show title newsfeed` for newsfeed module. - Add test e2e `show title newsfeed` for newsfeed module.
- Add task to check configuration file. - Add task to check configuration file.
@ -499,11 +543,13 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Added Romanian translation. - Added Romanian translation.
### Updated ### Updated
- Added missing keys to Polish translation. - Added missing keys to Polish translation.
- Added missing key to German translation. - Added missing key to German translation.
- Added better translation with flexible word order to Finnish translation. - Added better translation with flexible word order to Finnish translation.
### Fixed ### Fixed
- Fix instruction in README for using automatically installer script. - Fix instruction in README for using automatically installer script.
- Bug of duplicated compliments as described in [here](https://forum.magicmirror.builders/topic/2381/compliments-module-stops-cycling-compliments). - Bug of duplicated compliments as described in [here](https://forum.magicmirror.builders/topic/2381/compliments-module-stops-cycling-compliments).
- Fix double message about port when server is starting - Fix double message about port when server is starting
@ -517,6 +563,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
**Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install` **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`
### Changed ### Changed
- Add `anytime` group for Compliments module. - Add `anytime` group for Compliments module.
- Compliments module can use remoteFile without default daytime arrays defined. - Compliments module can use remoteFile without default daytime arrays defined.
- Installer: Use init config.js from config.js.sample. - Installer: Use init config.js from config.js.sample.
@ -532,6 +579,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Restructured Test Suite. - Restructured Test Suite.
### Added ### Added
- Added Docker support (Pull Request [#673](https://github.com/MichMich/MagicMirror/pull/673)). - Added Docker support (Pull Request [#673](https://github.com/MichMich/MagicMirror/pull/673)).
- Calendar-specific support for `maximumEntries`, and `maximumNumberOfDays`. - Calendar-specific support for `maximumEntries`, and `maximumNumberOfDays`.
- Add loaded function to modules, providing an async callback. - Add loaded function to modules, providing an async callback.
@ -574,6 +622,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Added a configurable Week section to the clock module. - Added a configurable Week section to the clock module.
### Fixed ### Fixed
- Update .gitignore to not ignore default modules folder. - Update .gitignore to not ignore default modules folder.
- Remove white flash on boot up. - Remove white flash on boot up.
- Added `update` in Raspberry Pi installation script. - Added `update` in Raspberry Pi installation script.
@ -590,6 +639,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
**Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install` **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`
### Added ### Added
- Finnish translation. - Finnish translation.
- Danish translation. - Danish translation.
- Turkish translation. - Turkish translation.
@ -620,6 +670,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Add root_path for global vars - Add root_path for global vars
### Updated ### Updated
- Modified translations for Frysk. - Modified translations for Frysk.
- Modified core English translations. - Modified core English translations.
- Updated package.json as a result of Snyk security update. - Updated package.json as a result of Snyk security update.
@ -630,6 +681,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Modules are now secure, and Helmet is now used to prevent abuse of the Mirror's API. - Modules are now secure, and Helmet is now used to prevent abuse of the Mirror's API.
### Fixed ### Fixed
- Solve an issue where module margins would appear when the first module of a section was hidden. - Solve an issue where module margins would appear when the first module of a section was hidden.
- Solved visual display errors on chrome, if all modules in one of the right sections are hidden. - Solved visual display errors on chrome, if all modules in one of the right sections are hidden.
- Global and Module default config values are no longer modified when setting config values. - Global and Module default config values are no longer modified when setting config values.
@ -640,6 +692,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
## [2.0.5] - 2016-09-20 ## [2.0.5] - 2016-09-20
### Added ### Added
- Added ability to remove tags from the beginning or end of newsfeed items in 'newsfeed.js'. - Added ability to remove tags from the beginning or end of newsfeed items in 'newsfeed.js'.
- Added ability to define "the day after tomorrow" for calendar events (Definition for German and Dutch already included). - Added ability to define "the day after tomorrow" for calendar events (Definition for German and Dutch already included).
- Added CII Badge (we are compliant with the CII Best Practices) - Added CII Badge (we are compliant with the CII Best Practices)
@ -647,11 +700,13 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Add the ability to turn off and on the date display in the Clock Module - Add the ability to turn off and on the date display in the Clock Module
### Fixed ### Fixed
- Fix typo in installer. - Fix typo in installer.
- Add message to unsupported Pi error to mention that Pi Zeros must use server only mode, as ARMv6 is unsupported. Closes #374. - Add message to unsupported Pi error to mention that Pi Zeros must use server only mode, as ARMv6 is unsupported. Closes #374.
- Fix API url for weather API. - Fix API url for weather API.
### Updated ### Updated
- Force fullscreen when kioskmode is active. - Force fullscreen when kioskmode is active.
- Update the .github templates and information with more modern information. - Update the .github templates and information with more modern information.
- Update the Gruntfile with a more functional StyleLint implementation. - Update the Gruntfile with a more functional StyleLint implementation.
@ -659,6 +714,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
## [2.0.4] - 2016-08-07 ## [2.0.4] - 2016-08-07
### Added ### Added
- Brazilian Portuguese Translation. - Brazilian Portuguese Translation.
- Option to enable Kiosk mode. - Option to enable Kiosk mode.
- Added ability to start the app with Dev Tools. - Added ability to start the app with Dev Tools.
@ -666,6 +722,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Greek Translation - Greek Translation
### Fixed ### Fixed
- Prevent `getModules()` selectors from returning duplicate entries. - Prevent `getModules()` selectors from returning duplicate entries.
- Append endpoints of weather modules with `/` to retrieve the correct data. (Issue [#337](https://github.com/MichMich/MagicMirror/issues/337)) - Append endpoints of weather modules with `/` to retrieve the correct data. (Issue [#337](https://github.com/MichMich/MagicMirror/issues/337))
- Corrected grammar in `module.js` from 'suspend' to 'suspended'. - Corrected grammar in `module.js` from 'suspend' to 'suspended'.
@ -674,55 +731,72 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Fix issue where translation loading prevented the UI start-up when the language was set to 'en'. (Issue [#388](https://github.com/MichMich/MagicMirror/issues/388)) - Fix issue where translation loading prevented the UI start-up when the language was set to 'en'. (Issue [#388](https://github.com/MichMich/MagicMirror/issues/388))
### Updated ### Updated
- Updated package.json to fix possible vulnerabilities. (Using Snyk) - Updated package.json to fix possible vulnerabilities. (Using Snyk)
- Updated weathericons - Updated weathericons
- Updated default weatherforecast to work with the new icons. - Updated default weatherforecast to work with the new icons.
- More detailed error message in case config file couldn't be loaded. - More detailed error message in case config file couldn't be loaded.
## [2.0.3] - 2016-07-12 ## [2.0.3] - 2016-07-12
### Added ### Added
- Add max newsitems parameter to the newsfeed module. - Add max newsitems parameter to the newsfeed module.
- Translations for Simplified Chinese, Traditional Chinese and Japanese. - Translations for Simplified Chinese, Traditional Chinese and Japanese.
- Polish Translation - Polish Translation
- Add an analog clock in addition to the digital one. - Add an analog clock in addition to the digital one.
### Fixed ### Fixed
- Edit Alert Module to display title & message if they are provided in the notification (Issue [#300](https://github.com/MichMich/MagicMirror/issues/300)) - Edit Alert Module to display title & message if they are provided in the notification (Issue [#300](https://github.com/MichMich/MagicMirror/issues/300))
- Removed 'null' reference from updateModuleContent(). This fixes recent Edge and Internet Explorer browser displays (Issue [#319](https://github.com/MichMich/MagicMirror/issues/319)) - Removed 'null' reference from updateModuleContent(). This fixes recent Edge and Internet Explorer browser displays (Issue [#319](https://github.com/MichMich/MagicMirror/issues/319))
### Changed ### Changed
- Added default string to calendar titleReplace. - Added default string to calendar titleReplace.
## [2.0.2] - 2016-06-05 ## [2.0.2] - 2016-06-05
### Added ### Added
- Norwegian Translations (nb and nn) - Norwegian Translations (nb and nn)
- Portuguese Translation - Portuguese Translation
- Swedish Translation - Swedish Translation
### Fixed ### Fixed
- Added reference to Italian Translation. - Added reference to Italian Translation.
- Added the missing NE translation to all languages. [#344](https://github.com/MichMich/MagicMirror/issues/344) - Added the missing NE translation to all languages. [#344](https://github.com/MichMich/MagicMirror/issues/344)
- Added proper User-Agent string to calendar call. - Added proper User-Agent string to calendar call.
### Changed ### Changed
- Add option to use locationID in weather modules. - Add option to use locationID in weather modules.
## [2.0.1] - 2016-05-18 ## [2.0.1] - 2016-05-18
### Added ### Added
- Changelog - Changelog
- Italian Translation - Italian Translation
### Changed ### Changed
- Improve the installer by fetching the latest Node.js without any 3rd party interferences. - Improve the installer by fetching the latest Node.js without any 3rd party interferences.
## [2.0.0] - 2016-05-03 ## [2.0.0] - 2016-05-03
### Initial release of MagicMirror² ### Initial release of MagicMirror²
It includes (but is not limited to) the following features: It includes (but is not limited to) the following features:
- Modular system allowing 3rd party plugins. - Modular system allowing 3rd party plugins.
- An Node/Electron based application taking away the need for external servers or browsers. - An Node/Electron based application taking away the need for external servers or browsers.
- A complete development API documentation. - A complete development API documentation.
- Small cute fairies that kiss you while you sleep. - Small cute fairies that kiss you while you sleep.
## [1.0.0] - 2014-02-16 ## [1.0.0] - 2014-02-16
### Initial release of MagicMirror. ### Initial release of MagicMirror.
This was part of the blogpost: [https://michaelteeuw.nl/post/83916869600/magic-mirror-part-vi-production-of-the](https://michaelteeuw.nl/post/83916869600/magic-mirror-part-vi-production-of-the) This was part of the blogpost: [https://michaelteeuw.nl/post/83916869600/magic-mirror-part-vi-production-of-the](https://michaelteeuw.nl/post/83916869600/magic-mirror-part-vi-production-of-the)

View file

@ -1,5 +1,4 @@
The MIT License (MIT) # The MIT License (MIT)
=====================
Copyright © 2016-2019 Michael Teeuw Copyright © 2016-2019 Michael Teeuw

View file

@ -14,9 +14,11 @@
MagicMirror² focuses on a modular plugin system and uses [Electron](https://www.electronjs.org/) as an application wrapper. So no more web server or browser installs necessary! MagicMirror² focuses on a modular plugin system and uses [Electron](https://www.electronjs.org/) as an application wrapper. So no more web server or browser installs necessary!
## Documentation ## Documentation
For the full documentation including **[installation instructions](https://docs.magicmirror.builders/getting-started/installation.html)**, please visit our dedicated documentation website: [https://docs.magicmirror.builders](https://docs.magicmirror.builders). For the full documentation including **[installation instructions](https://docs.magicmirror.builders/getting-started/installation.html)**, please visit our dedicated documentation website: [https://docs.magicmirror.builders](https://docs.magicmirror.builders).
## Links ## Links
- Website: [https://magicmirror.builders](https://magicmirror.builders) - Website: [https://magicmirror.builders](https://magicmirror.builders)
- Documentation: [https://docs.magicmirror.builders](https://docs.magicmirror.builders) - Documentation: [https://docs.magicmirror.builders](https://docs.magicmirror.builders)
- Forum: [https://forum.magicmirror.builders](https://forum.magicmirror.builders) - Forum: [https://forum.magicmirror.builders](https://forum.magicmirror.builders)
@ -28,7 +30,6 @@ For the full documentation including **[installation instructions](https://docs.
Contributions of all kinds are welcome, not only in the form of code but also with regards bug reports and documentation. For the full contribution guidelines, check out: [https://docs.magicmirror.builders/getting-started/contributing.html](https://docs.magicmirror.builders/getting-started/contributing.html) Contributions of all kinds are welcome, not only in the form of code but also with regards bug reports and documentation. For the full contribution guidelines, check out: [https://docs.magicmirror.builders/getting-started/contributing.html](https://docs.magicmirror.builders/getting-started/contributing.html)
## Enjoying MagicMirror? Consider a donation! ## Enjoying MagicMirror? Consider a donation!
MagicMirror² is opensource and free. That doesn't mean we don't need any money. MagicMirror² is opensource and free. That doesn't mean we don't need any money.

View file

@ -96,7 +96,6 @@
console.log(`There something wrong. The clientonly is not running code ${code}`); console.log(`There something wrong. The clientonly is not running code ${code}`);
} }
}); });
}) })
.catch(function (reason) { .catch(function (reason) {
fail(`Unable to connect to server: (${reason})`); fail(`Unable to connect to server: (${reason})`);
@ -104,4 +103,4 @@
} else { } else {
fail(); fail();
} }
}()); })();

View file

@ -2,21 +2,14 @@
font-family: Roboto; font-family: Roboto;
font-style: normal; font-style: normal;
font-weight: 100; font-weight: 100;
src: src: local("Roboto Thin"), local("Roboto-Thin"), url("node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.woff2") format("woff2"), url("node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.woff") format("woff");
local("Roboto Thin"),
local("Roboto-Thin"),
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.woff2") format("woff2"),
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.woff") format("woff");
} }
@font-face { @font-face {
font-family: "Roboto Condensed"; font-family: "Roboto Condensed";
font-style: normal; font-style: normal;
font-weight: 300; font-weight: 300;
src: src: local("Roboto Condensed Light"), local("RobotoCondensed-Light"), url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Light.woff2") format("woff2"),
local("Roboto Condensed Light"),
local("RobotoCondensed-Light"),
url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Light.woff2") format("woff2"),
url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Light.woff") format("woff"); url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Light.woff") format("woff");
} }
@ -24,10 +17,7 @@
font-family: "Roboto Condensed"; font-family: "Roboto Condensed";
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
src: src: local("Roboto Condensed"), local("RobotoCondensed-Regular"), url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Regular.woff2") format("woff2"),
local("Roboto Condensed"),
local("RobotoCondensed-Regular"),
url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Regular.woff2") format("woff2"),
url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Regular.woff") format("woff"); url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Regular.woff") format("woff");
} }
@ -35,10 +25,7 @@
font-family: "Roboto Condensed"; font-family: "Roboto Condensed";
font-style: normal; font-style: normal;
font-weight: 700; font-weight: 700;
src: src: local("Roboto Condensed Bold"), local("RobotoCondensed-Bold"), url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Bold.woff2") format("woff2"),
local("Roboto Condensed Bold"),
local("RobotoCondensed-Bold"),
url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Bold.woff2") format("woff2"),
url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Bold.woff") format("woff"); url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Bold.woff") format("woff");
} }
@ -46,42 +33,26 @@
font-family: Roboto; font-family: Roboto;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
src: src: local("Roboto"), local("Roboto-Regular"), url("node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff2") format("woff2"), url("node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff") format("woff");
local("Roboto"),
local("Roboto-Regular"),
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff2") format("woff2"),
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff") format("woff");
} }
@font-face { @font-face {
font-family: Roboto; font-family: Roboto;
font-style: normal; font-style: normal;
font-weight: 500; font-weight: 500;
src: src: local("Roboto Medium"), local("Roboto-Medium"), url("node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff2") format("woff2"), url("node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff") format("woff");
local("Roboto Medium"),
local("Roboto-Medium"),
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff2") format("woff2"),
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff") format("woff");
} }
@font-face { @font-face {
font-family: Roboto; font-family: Roboto;
font-style: normal; font-style: normal;
font-weight: 700; font-weight: 700;
src: src: local("Roboto Bold"), local("Roboto-Bold"), url("node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff2") format("woff2"), url("node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff") format("woff");
local("Roboto Bold"),
local("Roboto-Bold"),
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff2") format("woff2"),
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff") format("woff");
} }
@font-face { @font-face {
font-family: Roboto; font-family: Roboto;
font-style: normal; font-style: normal;
font-weight: 300; font-weight: 300;
src: src: local("Roboto Light"), local("Roboto-Light"), url("node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff2") format("woff2"), url("node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff") format("woff");
local("Roboto Light"),
local("Roboto-Light"),
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff2") format("woff2"),
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff") format("woff");
} }

View file

@ -60,7 +60,7 @@ var App = function() {
// For this check proposed to TestSuite // For this check proposed to TestSuite
// https://forum.magicmirror.builders/topic/1456/test-suite-for-magicmirror/8 // https://forum.magicmirror.builders/topic/1456/test-suite-for-magicmirror/8
var configFilename = path.resolve(global.root_path + "/config/config.js"); var configFilename = path.resolve(global.root_path + "/config/config.js");
if (typeof(global.configuration_file) !== "undefined") { if (typeof global.configuration_file !== "undefined") {
configFilename = path.resolve(global.configuration_file); configFilename = path.resolve(global.configuration_file);
} }
@ -94,11 +94,7 @@ var App = function() {
} }
}); });
if (usedDeprecated.length > 0) { if (usedDeprecated.length > 0) {
console.warn(Utils.colors.warn( console.warn(Utils.colors.warn("WARNING! Your config is using deprecated options: " + usedDeprecated.join(", ") + ". Check README and CHANGELOG for more up-to-date ways of getting the same functionality."));
"WARNING! Your config is using deprecated options: " +
usedDeprecated.join(", ") +
". Check README and CHANGELOG for more up-to-date ways of getting the same functionality.")
);
} }
}; };
@ -108,7 +104,6 @@ var App = function() {
* argument module string - The name of the module (including subpath). * argument module string - The name of the module (including subpath).
*/ */
var loadModule = function (module, callback) { var loadModule = function (module, callback) {
var elements = module.split("/"); var elements = module.split("/");
var moduleName = elements[elements.length - 1]; var moduleName = elements[elements.length - 1];
var moduleFolder = __dirname + "/../modules/" + module; var moduleFolder = __dirname + "/../modules/" + module;
@ -206,7 +201,6 @@ var App = function() {
* argument callback function - The callback function. * argument callback function - The callback function.
*/ */
this.start = function (callback) { this.start = function (callback) {
loadConfig(function (c) { loadConfig(function (c) {
config = c; config = c;
@ -262,7 +256,9 @@ var App = function() {
*/ */
process.on("SIGINT", () => { process.on("SIGINT", () => {
console.log("[SIGINT] Received. Shutting down server..."); console.log("[SIGINT] Received. Shutting down server...");
setTimeout(() => { process.exit(0); }, 3000); // Force quit after 3 seconds setTimeout(() => {
process.exit(0);
}, 3000); // Force quit after 3 seconds
this.stop(); this.stop();
process.exit(0); process.exit(0);
}); });
@ -271,7 +267,9 @@ var App = function() {
*/ */
process.on("SIGTERM", () => { process.on("SIGTERM", () => {
console.log("[SIGTERM] Received. Shutting down server..."); console.log("[SIGTERM] Received. Shutting down server...");
setTimeout(() => { process.exit(0); }, 3000); // Force quit after 3 seconds setTimeout(() => {
process.exit(0);
}, 3000); // Force quit after 3 seconds
this.stop(); this.stop();
process.exit(0); process.exit(0);
}); });

View file

@ -53,13 +53,15 @@ function checkConfigFile() {
console.info(Utils.colors.info("Checking file... "), configFileName); console.info(Utils.colors.info("Checking file... "), configFileName);
// I'm not sure if all ever is utf-8 // I'm not sure if all ever is utf-8
fs.readFile(configFileName, "utf-8", function (err, data) { fs.readFile(configFileName, "utf-8", function (err, data) {
if (err) { throw err; } if (err) {
throw err;
}
const messages = linter.verify(data, config); const messages = linter.verify(data, config);
if (messages.length === 0) { if (messages.length === 0) {
console.log("Your configuration file doesn't contain syntax errors :)"); console.log("Your configuration file doesn't contain syntax errors :)");
return true; return true;
} else { } else {
messages.forEach(error => { messages.forEach((error) => {
console.log("Line", error.line, "col", error.column, error.message); console.log("Line", error.line, "col", error.column, error.message);
}); });
} }

View file

@ -9,7 +9,11 @@
*/ */
(function () { (function () {
var initializing = false; var initializing = false;
var fnTest = /xyz/.test(function () { xyz; }) ? /\b_super\b/ : /.*/; var fnTest = /xyz/.test(function () {
xyz;
})
? /\b_super\b/
: /.*/;
// The base Class implementation (does nothing) // The base Class implementation (does nothing)
this.Class = function () {}; this.Class = function () {};
@ -32,8 +36,9 @@
// Copy the properties over onto the new prototype // Copy the properties over onto the new prototype
for (var name in prop) { for (var name in prop) {
// Check if we're overwriting an existing function // Check if we're overwriting an existing function
prototype[name] = typeof prop[name] === "function" && prototype[name] =
typeof _super[name] === "function" && fnTest.test(prop[name]) ? (function (name, fn) { typeof prop[name] === "function" && typeof _super[name] === "function" && fnTest.test(prop[name])
? (function (name, fn) {
return function () { return function () {
var tmp = this._super; var tmp = this._super;
@ -48,7 +53,8 @@
return ret; return ret;
}; };
})(name, prop[name]) : prop[name]; })(name, prop[name])
: prop[name];
} }
// The dummy class constructor // The dummy class constructor

View file

@ -8,7 +8,7 @@
*/ */
var address = "localhost"; var address = "localhost";
var port = 8080; var port = 8080;
if (typeof(mmPort) !== "undefined") { if (typeof mmPort !== "undefined") {
port = mmPort; port = mmPort;
} }
var defaults = { var defaults = {
@ -68,14 +68,16 @@ var defaults = {
config: { config: {
text: "www.michaelteeuw.nl" text: "www.michaelteeuw.nl"
} }
}, }
], ],
paths: { paths: {
modules: "modules", modules: "modules",
vendor: "vendor" vendor: "vendor"
}, }
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = defaults;} if (typeof module !== "undefined") {
module.exports = defaults;
}

View file

@ -7,8 +7,10 @@
*/ */
var deprecated = { var deprecated = {
configs: ["kioskmode"], configs: ["kioskmode"]
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = deprecated;} if (typeof module !== "undefined") {
module.exports = deprecated;
}

View file

@ -112,7 +112,9 @@ app.on("activate", function() {
app.on("before-quit", (event) => { app.on("before-quit", (event) => {
console.log("Shutting down server..."); console.log("Shutting down server...");
event.preventDefault(); event.preventDefault();
setTimeout(() => { process.exit(0); }, 3000); // Force-quit after 3 seconds. setTimeout(() => {
process.exit(0);
}, 3000); // Force-quit after 3 seconds.
core.stop(); core.stop();
process.exit(0); process.exit(0);
}); });

View file

@ -7,7 +7,6 @@
* MIT Licensed. * MIT Licensed.
*/ */
var Loader = (function () { var Loader = (function () {
/* Create helper variables */ /* Create helper variables */
var loadedModuleFiles = []; var loadedModuleFiles = [];
@ -20,7 +19,6 @@ var Loader = (function() {
* Loops thru all modules and requests load for every module. * Loops thru all modules and requests load for every module.
*/ */
var loadModules = function () { var loadModules = function () {
var moduleData = getModuleData(); var moduleData = getModuleData();
var loadNextModule = function () { var loadNextModule = function () {
@ -39,7 +37,6 @@ var Loader = (function() {
// custom.css loaded. Start all modules. // custom.css loaded. Start all modules.
startModules(); startModules();
}); });
} }
}; };
@ -102,7 +99,7 @@ var Loader = (function() {
position: moduleData.position, position: moduleData.position,
header: moduleData.header, header: moduleData.header,
config: moduleData.config, config: moduleData.config,
classes: (typeof moduleData.classes !== "undefined") ? moduleData.classes + " " + module : module classes: typeof moduleData.classes !== "undefined" ? moduleData.classes + " " + module : module
}); });
} }
@ -171,7 +168,6 @@ var Loader = (function() {
* argument callback function - Function called when done. * argument callback function - Function called when done.
*/ */
var loadFile = function (fileName, callback) { var loadFile = function (fileName, callback) {
var extension = fileName.slice((Math.max(0, fileName.lastIndexOf(".")) || Infinity) + 1); var extension = fileName.slice((Math.max(0, fileName.lastIndexOf(".")) || Infinity) + 1);
switch (extension.toLowerCase()) { switch (extension.toLowerCase()) {
@ -181,11 +177,15 @@ var Loader = (function() {
script.type = "text/javascript"; script.type = "text/javascript";
script.src = fileName; script.src = fileName;
script.onload = function () { script.onload = function () {
if (typeof callback === "function") {callback();} if (typeof callback === "function") {
callback();
}
}; };
script.onerror = function () { script.onerror = function () {
console.error("Error on loading script:", fileName); console.error("Error on loading script:", fileName);
if (typeof callback === "function") {callback();} if (typeof callback === "function") {
callback();
}
}; };
document.getElementsByTagName("body")[0].appendChild(script); document.getElementsByTagName("body")[0].appendChild(script);
@ -197,11 +197,15 @@ var Loader = (function() {
stylesheet.type = "text/css"; stylesheet.type = "text/css";
stylesheet.href = fileName; stylesheet.href = fileName;
stylesheet.onload = function () { stylesheet.onload = function () {
if (typeof callback === "function") {callback();} if (typeof callback === "function") {
callback();
}
}; };
stylesheet.onerror = function () { stylesheet.onerror = function () {
console.error("Error on loading stylesheet:", fileName); console.error("Error on loading stylesheet:", fileName);
if (typeof callback === "function") {callback();} if (typeof callback === "function") {
callback();
}
}; };
document.getElementsByTagName("head")[0].appendChild(stylesheet); document.getElementsByTagName("head")[0].appendChild(stylesheet);
@ -211,7 +215,6 @@ var Loader = (function() {
/* Public Methods */ /* Public Methods */
return { return {
/* loadModules() /* loadModules()
* Load all modules as defined in the config. * Load all modules as defined in the config.
*/ */
@ -228,7 +231,6 @@ var Loader = (function() {
* argument callback function - Function called when done. * argument callback function - Function called when done.
*/ */
loadFile: function (fileName, module, callback) { loadFile: function (fileName, module, callback) {
if (loadedFiles.indexOf(fileName.toLowerCase()) !== -1) { if (loadedFiles.indexOf(fileName.toLowerCase()) !== -1) {
Log.log("File already loaded: " + fileName); Log.log("File already loaded: " + fileName);
callback(); callback();

View file

@ -7,7 +7,6 @@
* MIT Licensed. * MIT Licensed.
*/ */
var MM = (function () { var MM = (function () {
var modules = []; var modules = [];
/* Private Methods */ /* Private Methods */
@ -52,9 +51,11 @@ var MM = (function() {
var domCreationPromise = updateDom(module, 0); var domCreationPromise = updateDom(module, 0);
domCreationPromises.push(domCreationPromise); domCreationPromises.push(domCreationPromise);
domCreationPromise.then(function() { domCreationPromise
.then(function () {
sendNotification("MODULE_DOM_CREATED", null, null, module); sendNotification("MODULE_DOM_CREATED", null, null, module);
}).catch(Log.error); })
.catch(Log.error);
}); });
updateWrapperStates(); updateWrapperStates();
@ -115,11 +116,13 @@ var MM = (function() {
newContentPromise = Promise.resolve(newContentPromise); newContentPromise = Promise.resolve(newContentPromise);
} }
newContentPromise.then(function(newContent) { newContentPromise
.then(function (newContent) {
var updatePromise = updateDomWithContent(module, speed, newHeader, newContent); var updatePromise = updateDomWithContent(module, speed, newHeader, newContent);
updatePromise.then(resolve).catch(Log.error); updatePromise.then(resolve).catch(Log.error);
}).catch(Log.error); })
.catch(Log.error);
}); });
}; };
@ -203,7 +206,9 @@ var MM = (function() {
*/ */
var updateModuleContent = function (module, newHeader, newContent) { var updateModuleContent = function (module, newHeader, newContent) {
var moduleWrapper = document.getElementById(module.identifier); var moduleWrapper = document.getElementById(module.identifier);
if (moduleWrapper === null) {return;} if (moduleWrapper === null) {
return;
}
var headerWrapper = moduleWrapper.getElementsByClassName("module-header"); var headerWrapper = moduleWrapper.getElementsByClassName("module-header");
var contentWrapper = moduleWrapper.getElementsByClassName("module-content"); var contentWrapper = moduleWrapper.getElementsByClassName("module-content");
@ -247,11 +252,15 @@ var MM = (function() {
updateWrapperStates(); updateWrapperStates();
if (typeof callback === "function") { callback(); } if (typeof callback === "function") {
callback();
}
}, speed); }, speed);
} else { } else {
// invoke callback even if no content, issue 1308 // invoke callback even if no content, issue 1308
if (typeof callback === "function") { callback(); } if (typeof callback === "function") {
callback();
}
} }
}; };
@ -302,11 +311,15 @@ var MM = (function() {
clearTimeout(module.showHideTimer); clearTimeout(module.showHideTimer);
module.showHideTimer = setTimeout(function () { module.showHideTimer = setTimeout(function () {
if (typeof callback === "function") { callback(); } if (typeof callback === "function") {
callback();
}
}, speed); }, speed);
} else { } else {
// invoke callback // invoke callback
if (typeof callback === "function") { callback(); } if (typeof callback === "function") {
callback();
}
} }
}; };
@ -361,7 +374,6 @@ var MM = (function() {
* argument modules array - Array of modules. * argument modules array - Array of modules.
*/ */
var setSelectionMethodsForModules = function (modules) { var setSelectionMethodsForModules = function (modules) {
/* withClass(className) /* withClass(className)
* calls modulesByClass to filter modules with the specified classes. * calls modulesByClass to filter modules with the specified classes.
* *
@ -442,10 +454,18 @@ var MM = (function() {
}); });
}; };
if (typeof modules.withClass === "undefined") { Object.defineProperty(modules, "withClass", {value: withClass, enumerable: false}); } if (typeof modules.withClass === "undefined") {
if (typeof modules.exceptWithClass === "undefined") { Object.defineProperty(modules, "exceptWithClass", {value: exceptWithClass, enumerable: false}); } Object.defineProperty(modules, "withClass", { value: withClass, 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}); } 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 { return {
@ -558,7 +578,6 @@ var MM = (function() {
showModule(module, speed, callback, options); showModule(module, speed, callback, options);
} }
}; };
})(); })();
// Add polyfill for Object.assign. // Add polyfill for Object.assign.

View file

@ -7,7 +7,6 @@
* MIT Licensed. * MIT Licensed.
*/ */
var Module = Class.extend({ var Module = Class.extend({
/********************************************************* /*********************************************************
* All methods (and properties) below can be subclassed. * * All methods (and properties) below can be subclassed. *
*********************************************************/ *********************************************************/
@ -126,7 +125,7 @@ var Module = Class.extend({
* return string - The template string of filename. * return string - The template string of filename.
*/ */
getTemplate: function () { getTemplate: function () {
return "<div class=\"normal\">" + this.name + "</div><div class=\"small dimmed\">" + this.identifier + "</div>"; return '<div class="normal">' + this.name + '</div><div class="small dimmed">' + this.identifier + "</div>";
}, },
/* getTemplateData() /* getTemplateData()
@ -313,7 +312,9 @@ var Module = Class.extend({
// The variable `first` will contain the first // The variable `first` will contain the first
// defined translation after the following line. // defined translation after the following line.
for (var first in translations) { break; } for (var first in translations) {
break;
}
if (translations) { if (translations) {
var translationFile = translations[lang] || undefined; var translationFile = translations[lang] || undefined;
@ -393,10 +394,15 @@ var Module = Class.extend({
options = options || {}; options = options || {};
var self = this; var self = this;
MM.hideModule(self, speed, function () { MM.hideModule(
self,
speed,
function () {
self.suspend(); self.suspend();
callback(); callback();
}, options); },
options
);
}, },
/* showModule(module, speed, callback) /* showModule(module, speed, callback)
@ -416,17 +422,21 @@ var Module = Class.extend({
options = options || {}; options = options || {};
var self = this; var self = this;
MM.showModule(this, speed, function () { MM.showModule(
this,
speed,
function () {
self.resume(); self.resume();
callback; callback;
}, options); },
options
);
} }
}); });
Module.definitions = {}; Module.definitions = {};
Module.create = function (name) { Module.create = function (name) {
// Make sure module definition is available. // Make sure module definition is available.
if (!Module.definitions[name]) { if (!Module.definitions[name]) {
return; return;
@ -464,7 +474,6 @@ function cmpVersions(a, b) {
} }
Module.register = function (name, moduleDefinition) { Module.register = function (name, moduleDefinition) {
if (moduleDefinition.requiresVersion) { if (moduleDefinition.requiresVersion) {
Log.log("Check MagicMirror version for module '" + name + "' - Minimum version: " + moduleDefinition.requiresVersion + " - Current version: " + window.version); Log.log("Check MagicMirror version for module '" + name + "' - Minimum version: " + moduleDefinition.requiresVersion + " - Current version: " + window.version);
if (cmpVersions(window.version, moduleDefinition.requiresVersion) >= 0) { if (cmpVersions(window.version, moduleDefinition.requiresVersion) >= 0) {

View file

@ -120,4 +120,6 @@ NodeHelper.create = function(moduleDefinition) {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = NodeHelper;} if (typeof module !== "undefined") {
module.exports = NodeHelper;
}

View file

@ -14,7 +14,6 @@ var helmet = require("helmet");
var Utils = require(__dirname + "/utils.js"); var Utils = require(__dirname + "/utils.js");
var Server = function (config, callback) { var Server = function (config, callback) {
var port = config.port; var port = config.port;
if (process.env.MM_PORT) { if (process.env.MM_PORT) {
port = process.env.MM_PORT; port = process.env.MM_PORT;
@ -72,7 +71,7 @@ var Server = function(config, callback) {
html = html.replace("#VERSION#", global.version); html = html.replace("#VERSION#", global.version);
var configFile = "config/config.js"; var configFile = "config/config.js";
if (typeof(global.configuration_file) !== "undefined") { if (typeof global.configuration_file !== "undefined") {
configFile = global.configuration_file; configFile = global.configuration_file;
} }
html = html.replace("#CONFIG_FILE#", configFile); html = html.replace("#CONFIG_FILE#", configFile);

View file

@ -17,7 +17,7 @@ var MMSocket = function(moduleName) {
// Private Methods // Private Methods
var base = "/"; var base = "/";
if ((typeof config !== "undefined") && (typeof config.basePath !== "undefined")) { if (typeof config !== "undefined" && typeof config.basePath !== "undefined") {
base = config.basePath; base = config.basePath;
} }
self.socket = io("/" + self.moduleName, { self.socket = io("/" + self.moduleName, {

View file

@ -7,7 +7,6 @@
* MIT Licensed. * MIT Licensed.
*/ */
var Translator = (function () { var Translator = (function () {
/* loadJSON(file, callback) /* loadJSON(file, callback)
* Load a JSON file via XHR. * Load a JSON file via XHR.
* *
@ -62,7 +61,7 @@ var Translator = (function() {
currentChar = str[i]; currentChar = str[i];
nextChar = str[i + 1]; nextChar = str[i + 1];
if (!insideComment && currentChar === "\"") { if (!insideComment && currentChar === '"') {
var escaped = str[i - 1] === "\\" && str[i - 2] !== "\\"; var escaped = str[i - 1] === "\\" && str[i - 2] !== "\\";
if (!escaped) { if (!escaped) {
insideString = !insideString; insideString = !insideString;
@ -220,7 +219,9 @@ var Translator = (function() {
// The variable `first` will contain the first // The variable `first` will contain the first
// defined translation after the following line. // defined translation after the following line.
for (var first in translations) {break;} for (var first in translations) {
break;
}
if (first) { if (first) {
Log.log("Loading core translation fallback file: " + translations[first]); Log.log("Loading core translation fallback file: " + translations[first]);
@ -228,6 +229,6 @@ var Translator = (function() {
self.coreTranslationsFallback = translations; self.coreTranslationsFallback = translations;
}); });
} }
}, }
}; };
})(); })();

View file

@ -14,4 +14,6 @@ var Utils = {
} }
}; };
if (typeof module !== "undefined") {module.exports = Utils;} if (typeof module !== "undefined") {
module.exports = Utils;
}

View file

@ -6,8 +6,5 @@
"module": "commonjs", "module": "commonjs",
"allowSyntheticDefaultImports": true "allowSyntheticDefaultImports": true
}, },
"exclude": [ "exclude": ["modules", "node_modules"]
"modules",
"node_modules"
]
} }

View file

@ -1,4 +1,5 @@
# Module: Alert # Module: Alert
The alert module is one of the default modules of the MagicMirror. This module displays notifications from other modules. The alert module is one of the default modules of the MagicMirror. This module displays notifications from other modules.
For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/alert.html). For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/alert.html).

View file

@ -17,7 +17,7 @@ Module.register("alert",{
//Position //Position
position: "center", position: "center",
//shown at startup //shown at startup
welcome_message: false, welcome_message: false
}, },
getScripts: function () { getScripts: function () {
return ["notificationFx.js"]; return ["notificationFx.js"];
@ -30,11 +30,13 @@ Module.register("alert",{
return { return {
en: "translations/en.json", en: "translations/en.json",
de: "translations/de.json", de: "translations/de.json",
nl: "translations/nl.json", nl: "translations/nl.json"
}; };
}, },
show_notification: function (message) { show_notification: function (message) {
if (this.config.effect === "slide") {this.config.effect = this.config.effect + "-" + this.config.position;} if (this.config.effect === "slide") {
this.config.effect = this.config.effect + "-" + this.config.position;
}
let msg = ""; let msg = "";
if (message.title) { if (message.title) {
msg += "<span class='thin dimmed medium'>" + message.title + "</span>"; msg += "<span class='thin dimmed medium'>" + message.title + "</span>";
@ -56,19 +58,23 @@ Module.register("alert",{
show_alert: function (params, sender) { show_alert: function (params, sender) {
let image = ""; let image = "";
//Set standard params if not provided by module //Set standard params if not provided by module
if (typeof params.timer === "undefined") { params.timer = null; } if (typeof params.timer === "undefined") {
if (typeof params.imageHeight === "undefined") { params.imageHeight = "80px"; } params.timer = null;
}
if (typeof params.imageHeight === "undefined") {
params.imageHeight = "80px";
}
if (typeof params.imageUrl === "undefined" && typeof params.imageFA === "undefined") { if (typeof params.imageUrl === "undefined" && typeof params.imageFA === "undefined") {
params.imageUrl = null; params.imageUrl = null;
} else if (typeof params.imageFA === "undefined") { } else if (typeof params.imageFA === "undefined") {
image = "<img src='" + (params.imageUrl).toString() + "' height='" + (params.imageHeight).toString() + "' style='margin-bottom: 10px;'/><br />"; image = "<img src='" + params.imageUrl.toString() + "' height='" + params.imageHeight.toString() + "' style='margin-bottom: 10px;'/><br />";
} else if (typeof params.imageUrl === "undefined") { } else if (typeof params.imageUrl === "undefined") {
image = "<span class='bright " + "fa fa-" + params.imageFA + "' style='margin-bottom: 10px;font-size:" + (params.imageHeight).toString() + ";'/></span><br />"; image = "<span class='bright " + "fa fa-" + params.imageFA + "' style='margin-bottom: 10px;font-size:" + params.imageHeight.toString() + ";'/></span><br />";
} }
//Create overlay //Create overlay
const overlay = document.createElement("div"); const overlay = document.createElement("div");
overlay.id = "overlay"; overlay.id = "overlay";
overlay.innerHTML += "<div class=\"black_overlay\"></div>"; overlay.innerHTML += '<div class="black_overlay"></div>';
document.body.insertBefore(overlay, document.body.firstChild); document.body.insertBefore(overlay, document.body.firstChild);
//If module already has an open alert close it //If module already has an open alert close it
@ -104,7 +110,6 @@ Module.register("alert",{
this.hide_alert(sender); this.hide_alert(sender);
}, params.timer); }, params.timer);
} }
}, },
hide_alert: function (sender) { hide_alert: function (sender) {
//Dismiss alert and remove from this.alerts //Dismiss alert and remove from this.alerts
@ -119,15 +124,22 @@ Module.register("alert",{
setPosition: function (pos) { setPosition: function (pos) {
//Add css to body depending on the set position for notifications //Add css to body depending on the set position for notifications
const sheet = document.createElement("style"); const sheet = document.createElement("style");
if (pos === "center") {sheet.innerHTML = ".ns-box {margin-left: auto; margin-right: auto;text-align: center;}";} if (pos === "center") {
if (pos === "right") {sheet.innerHTML = ".ns-box {margin-left: auto;text-align: right;}";} sheet.innerHTML = ".ns-box {margin-left: auto; margin-right: auto;text-align: center;}";
if (pos === "left") {sheet.innerHTML = ".ns-box {margin-right: auto;text-align: left;}";} }
if (pos === "right") {
sheet.innerHTML = ".ns-box {margin-left: auto;text-align: right;}";
}
if (pos === "left") {
sheet.innerHTML = ".ns-box {margin-right: auto;text-align: left;}";
}
document.body.appendChild(sheet); document.body.appendChild(sheet);
}, },
notificationReceived: function (notification, payload, sender) { notificationReceived: function (notification, payload, sender) {
if (notification === "SHOW_ALERT") { if (notification === "SHOW_ALERT") {
if (typeof payload.type === "undefined") { payload.type = "alert"; } if (typeof payload.type === "undefined") {
payload.type = "alert";
}
if (payload.type === "alert") { if (payload.type === "alert") {
this.show_alert(payload, sender); this.show_alert(payload, sender);
} else if (payload.type === "notification") { } else if (payload.type === "notification") {
@ -143,8 +155,7 @@ Module.register("alert",{
if (this.config.welcome_message) { if (this.config.welcome_message) {
if (this.config.welcome_message === true) { if (this.config.welcome_message === true) {
this.show_notification({ title: this.translate("sysTitle"), message: this.translate("welcome") }); this.show_notification({ title: this.translate("sysTitle"), message: this.translate("welcome") });
} } else {
else{
this.show_notification({ title: this.translate("sysTitle"), message: this.config.welcome_message }); this.show_notification({ title: this.translate("sysTitle"), message: this.config.welcome_message });
} }
} }

View file

@ -235,8 +235,12 @@
} }
@keyframes animFade { @keyframes animFade {
0% { opacity: 0; } 0% {
100% { opacity: 1; } opacity: 0;
}
100% {
opacity: 1;
}
} }
@keyframes animJelly { @keyframes animJelly {

View file

@ -11,7 +11,6 @@
* https://tympanus.net/codrops/ * https://tympanus.net/codrops/
*/ */
(function (window) { (function (window) {
/** /**
* extend obj function * extend obj function
*/ */
@ -58,8 +57,12 @@
ttl: 6000, ttl: 6000,
al_no: "ns-box", al_no: "ns-box",
// callbacks // callbacks
onClose: function() { return false; }, onClose: function () {
onOpen: function() { return false; } return false;
},
onOpen: function () {
return false;
}
}; };
/** /**
@ -70,7 +73,7 @@
// create HTML structure // create HTML structure
this.ntf = document.createElement("div"); this.ntf = document.createElement("div");
this.ntf.className = this.options.al_no + " ns-" + this.options.layout + " ns-effect-" + this.options.effect + " ns-type-" + this.options.type; this.ntf.className = this.options.al_no + " ns-" + this.options.layout + " ns-effect-" + this.options.effect + " ns-type-" + this.options.type;
let strinner = "<div class=\"ns-box-inner\">"; let strinner = '<div class="ns-box-inner">';
strinner += this.options.message; strinner += this.options.message;
strinner += "</div>"; strinner += "</div>";
this.ntf.innerHTML = strinner; this.ntf.innerHTML = strinner;
@ -96,7 +99,9 @@
*/ */
NotificationFx.prototype._initEvents = function () { NotificationFx.prototype._initEvents = function () {
// dismiss notification by tapping on it if someone has a touchscreen // dismiss notification by tapping on it if someone has a touchscreen
this.ntf.querySelector(".ns-box-inner").addEventListener("click", () => { this.dismiss(); }); this.ntf.querySelector(".ns-box-inner").addEventListener("click", () => {
this.dismiss();
});
}; };
/** /**
@ -125,7 +130,9 @@
// after animation ends remove ntf from the DOM // after animation ends remove ntf from the DOM
const onEndAnimationFn = (ev) => { const onEndAnimationFn = (ev) => {
if (ev.target !== this.ntf) {return false;} if (ev.target !== this.ntf) {
return false;
}
this.ntf.removeEventListener("animationend", onEndAnimationFn); this.ntf.removeEventListener("animationend", onEndAnimationFn);
if (ev.target.parentNode === this.options.wrapper) { if (ev.target.parentNode === this.options.wrapper) {
@ -140,5 +147,4 @@
* add to global namespace * add to global namespace
*/ */
window.NotificationFx = NotificationFx; window.NotificationFx = NotificationFx;
})(window); })(window);

View file

@ -1,4 +1,5 @@
# Module: Calendar # Module: Calendar
The `calendar` module is one of the default modules of the MagicMirror. The `calendar` module is one of the default modules of the MagicMirror.
This module displays events from a public .ical calendar. It can combine multiple calendars. This module displays events from a public .ical calendar. It can combine multiple calendars.

View file

@ -7,7 +7,6 @@
* MIT Licensed. * MIT Licensed.
*/ */
Module.register("calendar", { Module.register("calendar", {
// Define module defaults // Define module defaults
defaults: { defaults: {
maximumEntries: 10, // Total Maximum Entries maximumEntries: 10, // Total Maximum Entries
@ -39,8 +38,8 @@ Module.register("calendar", {
calendars: [ calendars: [
{ {
symbol: "calendar", symbol: "calendar",
url: "https://www.calendarlabs.com/templates/ical/US-Holidays.ics", url: "https://www.calendarlabs.com/templates/ical/US-Holidays.ics"
}, }
], ],
titleReplace: { titleReplace: {
"De verjaardag van ": "", "De verjaardag van ": "",
@ -85,7 +84,7 @@ Module.register("calendar", {
var calendarConfig = { var calendarConfig = {
maximumEntries: calendar.maximumEntries, maximumEntries: calendar.maximumEntries,
maximumNumberOfDays: calendar.maximumNumberOfDays, maximumNumberOfDays: calendar.maximumNumberOfDays,
broadcastPastEvents: calendar.broadcastPastEvents, broadcastPastEvents: calendar.broadcastPastEvents
}; };
if (calendar.symbolClass === "undefined" || calendar.symbolClass === null) { if (calendar.symbolClass === "undefined" || calendar.symbolClass === null) {
calendarConfig.symbolClass = ""; calendarConfig.symbolClass = "";
@ -144,13 +143,12 @@ Module.register("calendar", {
// Override dom generator. // Override dom generator.
getDom: function () { getDom: function () {
var events = this.createEventList(); var events = this.createEventList();
var wrapper = document.createElement("table"); var wrapper = document.createElement("table");
wrapper.className = this.config.tableClass; wrapper.className = this.config.tableClass;
if (events.length === 0) { if (events.length === 0) {
wrapper.innerHTML = (this.loaded) ? this.translate("EMPTY") : this.translate("LOADING"); wrapper.innerHTML = this.loaded ? this.translate("EMPTY") : this.translate("LOADING");
wrapper.className = this.config.tableClass + " dimmed"; wrapper.className = this.config.tableClass + " dimmed";
return wrapper; return wrapper;
} }
@ -181,9 +179,10 @@ Module.register("calendar", {
dateRow.appendChild(dateCell); dateRow.appendChild(dateCell);
wrapper.appendChild(dateRow); wrapper.appendChild(dateRow);
if (e >= startFade) { //fading if (e >= startFade) {
//fading
currentFadeStep = e - startFade; currentFadeStep = e - startFade;
dateRow.style.opacity = 1 - (1 / fadeSteps * currentFadeStep); dateRow.style.opacity = 1 - (1 / fadeSteps) * currentFadeStep;
} }
lastSeenDate = dateAsString; lastSeenDate = dateAsString;
@ -232,7 +231,6 @@ Module.register("calendar", {
repeatingCountTitle = ""; repeatingCountTitle = "";
if (this.config.displayRepeatingCountTitle && event.firstYear !== undefined) { if (this.config.displayRepeatingCountTitle && event.firstYear !== undefined) {
repeatingCountTitle = this.countTitleForUrl(event.url); repeatingCountTitle = this.countTitleForUrl(event.url);
if (repeatingCountTitle !== "") { if (repeatingCountTitle !== "") {
@ -256,11 +254,9 @@ Module.register("calendar", {
var timeWrapper; var timeWrapper;
if (this.config.timeFormat === "dateheaders") { if (this.config.timeFormat === "dateheaders") {
if (event.fullDayEvent) { if (event.fullDayEvent) {
titleWrapper.colSpan = "2"; titleWrapper.colSpan = "2";
titleWrapper.align = "left"; titleWrapper.align = "left";
} else { } else {
timeWrapper = document.createElement("td"); timeWrapper = document.createElement("td");
timeWrapper.className = "time light " + this.timeClassForUrl(event.url); timeWrapper.className = "time light " + this.timeClassForUrl(event.url);
@ -305,7 +301,7 @@ Module.register("calendar", {
* Note: this needs to be put in its own function, as the whole thing repeats again verbatim * Note: this needs to be put in its own function, as the whole thing repeats again verbatim
*/ */
if (this.config.timeFormat === "absolute") { if (this.config.timeFormat === "absolute") {
if ((this.config.urgency > 1) && (event.startDate - now < (this.config.urgency * oneDay))) { if (this.config.urgency > 1 && event.startDate - now < this.config.urgency * oneDay) {
// This event falls within the config.urgency period that the user has set // This event falls within the config.urgency period that the user has set
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").from(moment().format("YYYYMMDD"))); timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").from(moment().format("YYYYMMDD")));
} else { } else {
@ -343,7 +339,7 @@ Module.register("calendar", {
* Note: this needs to be put in its own function, as the whole thing repeats again verbatim * Note: this needs to be put in its own function, as the whole thing repeats again verbatim
*/ */
if (this.config.timeFormat === "absolute") { if (this.config.timeFormat === "absolute") {
if ((this.config.urgency > 1) && (event.startDate - now < (this.config.urgency * oneDay))) { if (this.config.urgency > 1 && event.startDate - now < this.config.urgency * oneDay) {
// This event falls within the config.urgency period that the user has set // This event falls within the config.urgency period that the user has set
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow()); timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
} else { } else {
@ -364,7 +360,6 @@ Module.register("calendar", {
if (this.config.showEnd) { if (this.config.showEnd) {
timeWrapper.innerHTML += "-"; timeWrapper.innerHTML += "-";
timeWrapper.innerHTML += this.capFirst(moment(event.endDate, "x").format(this.config.dateEndFormat)); timeWrapper.innerHTML += this.capFirst(moment(event.endDate, "x").format(this.config.dateEndFormat));
} }
} }
//timeWrapper.innerHTML += ' - '+ moment(event.startDate,'x').format('lll'); //timeWrapper.innerHTML += ' - '+ moment(event.startDate,'x').format('lll');
@ -378,7 +373,7 @@ Module.register("calendar", {
// Create fade effect. // Create fade effect.
if (e >= startFade) { if (e >= startFade) {
currentFadeStep = e - startFade; currentFadeStep = e - startFade;
eventWrapper.style.opacity = 1 - (1 / fadeSteps * currentFadeStep); eventWrapper.style.opacity = 1 - (1 / fadeSteps) * currentFadeStep;
} }
if (this.config.showLocation) { if (this.config.showLocation) {
@ -401,7 +396,7 @@ Module.register("calendar", {
if (e >= startFade) { if (e >= startFade) {
currentFadeStep = e - startFade; currentFadeStep = e - startFade;
locationRow.style.opacity = 1 - (1 / fadeSteps * currentFadeStep); locationRow.style.opacity = 1 - (1 / fadeSteps) * currentFadeStep;
} }
} }
} }
@ -482,19 +477,19 @@ Module.register("calendar", {
continue; continue;
} }
event.url = c; event.url = c;
event.today = event.startDate >= today && event.startDate < (today + 24 * 60 * 60 * 1000); event.today = event.startDate >= today && event.startDate < today + 24 * 60 * 60 * 1000;
/* if sliceMultiDayEvents is set to true, multiday events (events exceeding at least one midnight) are sliced into days, /* if sliceMultiDayEvents is set to true, multiday events (events exceeding at least one midnight) are sliced into days,
* otherwise, esp. in dateheaders mode it is not clear how long these events are. * otherwise, esp. in dateheaders mode it is not clear how long these events are.
*/ */
var maxCount = Math.ceil(((event.endDate - 1) - moment(event.startDate, "x").endOf("day").format("x"))/(1000*60*60*24)) + 1; var maxCount = Math.ceil((event.endDate - 1 - moment(event.startDate, "x").endOf("day").format("x")) / (1000 * 60 * 60 * 24)) + 1;
if (this.config.sliceMultiDayEvents && maxCount > 1) { if (this.config.sliceMultiDayEvents && maxCount > 1) {
var splitEvents = []; var splitEvents = [];
var midnight = moment(event.startDate, "x").clone().startOf("day").add(1, "day").format("x"); var midnight = moment(event.startDate, "x").clone().startOf("day").add(1, "day").format("x");
var count = 1; var count = 1;
while (event.endDate > midnight) { while (event.endDate > midnight) {
var thisEvent = JSON.parse(JSON.stringify(event)); // clone object var thisEvent = JSON.parse(JSON.stringify(event)); // clone object
thisEvent.today = thisEvent.startDate >= today && thisEvent.startDate < (today + 24 * 60 * 60 * 1000); thisEvent.today = thisEvent.startDate >= today && thisEvent.startDate < today + 24 * 60 * 60 * 1000;
thisEvent.endDate = midnight; thisEvent.endDate = midnight;
thisEvent.title += " (" + count + "/" + maxCount + ")"; thisEvent.title += " (" + count + "/" + maxCount + ")";
splitEvents.push(thisEvent); splitEvents.push(thisEvent);
@ -508,7 +503,7 @@ Module.register("calendar", {
splitEvents.push(event); splitEvents.push(event);
for (event of splitEvents) { for (event of splitEvents) {
if ((event.endDate > now) && (event.endDate <= future)) { if (event.endDate > now && event.endDate <= future) {
events.push(event); events.push(event);
} }
} }
@ -549,7 +544,7 @@ Module.register("calendar", {
titleClass: calendarConfig.titleClass, titleClass: calendarConfig.titleClass,
timeClass: calendarConfig.timeClass, timeClass: calendarConfig.timeClass,
auth: auth, auth: auth,
broadcastPastEvents: calendarConfig.broadcastPastEvents || this.config.broadcastPastEvents, broadcastPastEvents: calendarConfig.broadcastPastEvents || this.config.broadcastPastEvents
}); });
}, },
@ -676,8 +671,9 @@ Module.register("calendar", {
for (var i = 0; i < words.length; i++) { for (var i = 0; i < words.length; i++) {
var word = words[i]; var word = words[i];
if (currentLine.length + word.length < (typeof maxLength === "number" ? maxLength : 25) - 1) { // max - 1 to account for a space if (currentLine.length + word.length < (typeof maxLength === "number" ? maxLength : 25) - 1) {
currentLine += (word + " "); // max - 1 to account for a space
currentLine += word + " ";
} else { } else {
line++; line++;
if (line > maxTitleLines - 1) { if (line > maxTitleLines - 1) {
@ -688,9 +684,9 @@ Module.register("calendar", {
} }
if (currentLine.length > 0) { if (currentLine.length > 0) {
temp += (currentLine + "<br>" + word + " "); temp += currentLine + "<br>" + word + " ";
} else { } else {
temp += (word + "<br>"); temp += word + "<br>";
} }
currentLine = ""; currentLine = "";
} }
@ -763,6 +759,5 @@ Module.register("calendar", {
}); });
this.sendNotification("CALENDAR_EVENTS", eventList); this.sendNotification("CALENDAR_EVENTS", eventList);
} }
}); });

View file

@ -21,7 +21,6 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri
* Initiates calendar fetch. * Initiates calendar fetch.
*/ */
var fetchCalendar = function () { var fetchCalendar = function () {
clearTimeout(reloadTimer); clearTimeout(reloadTimer);
reloadTimer = null; reloadTimer = null;
@ -38,7 +37,6 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri
opts.auth = { opts.auth = {
bearer: auth.pass bearer: auth.pass
}; };
} else { } else {
opts.auth = { opts.auth = {
user: auth.user, user: auth.user,
@ -64,10 +62,12 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri
var newEvents = []; var newEvents = [];
// limitFunction doesn't do much limiting, see comment re: the dates array in rrule section below as to why we need to do the filtering ourselves // limitFunction doesn't do much limiting, see comment re: the dates array in rrule section below as to why we need to do the filtering ourselves
var limitFunction = function(date, i) {return true;}; var limitFunction = function (date, i) {
return true;
};
var eventDate = function (event, time) { var eventDate = function (event, time) {
return (event[time].length === 8) ? moment(event[time], "YYYYMMDD") : moment(new Date(event[time])); return event[time].length === 8 ? moment(event[time], "YYYYMMDD") : moment(new Date(event[time]));
}; };
for (var e in data) { for (var e in data) {
@ -91,7 +91,6 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri
} }
if (event.type === "VEVENT") { if (event.type === "VEVENT") {
var startDate = eventDate(event, "start"); var startDate = eventDate(event, "start");
var endDate; var endDate;
if (typeof event.end !== "undefined") { if (typeof event.end !== "undefined") {
@ -175,8 +174,7 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri
var addedEvents = 0; var addedEvents = 0;
// can cause problems with e.g. birthdays before 1900 // can cause problems with e.g. birthdays before 1900
if(rule.options && rule.origOptions && rule.origOptions.dtstart && rule.origOptions.dtstart.getFullYear() < 1900 || if ((rule.options && rule.origOptions && rule.origOptions.dtstart && rule.origOptions.dtstart.getFullYear() < 1900) || (rule.options && rule.options.dtstart && rule.options.dtstart.getFullYear() < 1900)) {
rule.options && rule.options.dtstart && rule.options.dtstart.getFullYear() < 1900){
rule.origOptions.dtstart.setYear(1900); rule.origOptions.dtstart.setYear(1900);
rule.options.dtstart.setYear(1900); rule.options.dtstart.setYear(1900);
} }
@ -199,17 +197,14 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri
// because the logic below will filter out any recurrences that don"t actually belong within // because the logic below will filter out any recurrences that don"t actually belong within
// our display range. // our display range.
// Would be great if there was a better way to handle this. // Would be great if there was a better way to handle this.
if (event.recurrences !== undefined) if (event.recurrences !== undefined) {
{
var pastMoment = moment(past); var pastMoment = moment(past);
var futureMoment = moment(future); var futureMoment = moment(future);
for (var r in event.recurrences) for (var r in event.recurrences) {
{
// Only add dates that weren't already in the range we added from the rrule so that // Only add dates that weren't already in the range we added from the rrule so that
// we don"t double-add those events. // we don"t double-add those events.
if (moment(new Date(r)).isBetween(pastMoment, futureMoment) !== true) if (moment(new Date(r)).isBetween(pastMoment, futureMoment) !== true) {
{
dates.push(new Date(r)); dates.push(new Date(r));
} }
} }
@ -234,16 +229,14 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri
startDate = moment(date); startDate = moment(date);
// For each date that we"re checking, it"s possible that there is a recurrence override for that one day. // For each date that we"re checking, it"s possible that there is a recurrence override for that one day.
if ((curEvent.recurrences !== undefined) && (curEvent.recurrences[dateKey] !== undefined)) if (curEvent.recurrences !== undefined && curEvent.recurrences[dateKey] !== undefined) {
{
// We found an override, so for this recurrence, use a potentially different title, start date, and duration. // We found an override, so for this recurrence, use a potentially different title, start date, and duration.
curEvent = curEvent.recurrences[dateKey]; curEvent = curEvent.recurrences[dateKey];
startDate = moment(curEvent.start); startDate = moment(curEvent.start);
duration = parseInt(moment(curEvent.end).format("x")) - parseInt(startDate.format("x")); duration = parseInt(moment(curEvent.end).format("x")) - parseInt(startDate.format("x"));
} }
// If there"s no recurrence override, check for an exception date. Exception dates represent exceptions to the rule. // If there"s no recurrence override, check for an exception date. Exception dates represent exceptions to the rule.
else if ((curEvent.exdate !== undefined) && (curEvent.exdate[dateKey] !== undefined)) else if (curEvent.exdate !== undefined && curEvent.exdate[dateKey] !== undefined) {
{
// This date is an exception date, which means we should skip it in the recurrence pattern. // This date is an exception date, which means we should skip it in the recurrence pattern.
showRecurrence = false; showRecurrence = false;
} }
@ -265,7 +258,7 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri
showRecurrence = false; showRecurrence = false;
} }
if ((showRecurrence === true) && (addedEvents < maximumEntries)) { if (showRecurrence === true && addedEvents < maximumEntries) {
addedEvents++; addedEvents++;
newEvents.push({ newEvents.push({
title: recurrenceTitle, title: recurrenceTitle,
@ -284,7 +277,7 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri
} else { } else {
// console.log("Single event ..."); // console.log("Single event ...");
// Single event. // Single event.
var fullDayEvent = (isFacebookBirthday) ? true : isFullDayEvent(event); var fullDayEvent = isFacebookBirthday ? true : isFullDayEvent(event);
if (includePastEvents) { if (includePastEvents) {
if (endDate < past) { if (endDate < past) {
@ -329,7 +322,6 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri
geo: geo, geo: geo,
description: description description: description
}); });
} }
} }
} }
@ -373,7 +365,7 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri
var start = event.start || 0; var start = event.start || 0;
var startDate = new Date(start); var startDate = new Date(start);
var end = event.end || 0; var end = event.end || 0;
if (((end - start) % (24 * 60 * 60 * 1000)) === 0 && startDate.getHours() === 0 && startDate.getMinutes() === 0) { if ((end - start) % (24 * 60 * 60 * 1000) === 0 && startDate.getHours() === 0 && startDate.getMinutes() === 0) {
// Is 24 hours, and starts on the middle of the night. // Is 24 hours, and starts on the middle of the night.
return true; return true;
} }
@ -413,7 +405,7 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri
var getTitleFromEvent = function (event) { var getTitleFromEvent = function (event) {
var title = "Event"; var title = "Event";
if (event.summary) { if (event.summary) {
title = (typeof event.summary.val !== "undefined") ? event.summary.val : event.summary; title = typeof event.summary.val !== "undefined" ? event.summary.val : event.summary;
} else if (event.description) { } else if (event.description) {
title = event.description; title = event.description;
} }

View file

@ -17,7 +17,6 @@ module.exports = NodeHelper.create({
this.fetchers = []; this.fetchers = [];
console.log("Starting node helper for: " + this.name); console.log("Starting node helper for: " + this.name);
}, },
// Override socketNotificationReceived method. // Override socketNotificationReceived method.

View file

@ -1,4 +1,5 @@
# Module: Clock # Module: Clock
The `clock` module is one of the default modules of the MagicMirror. The `clock` module is one of the default modules of the MagicMirror.
This module displays the current date and time. The information will be updated realtime. This module displays the current date and time. The information will be updated realtime.

View file

@ -31,7 +31,7 @@ Module.register("clock",{
showSunTimes: false, showSunTimes: false,
showMoonTimes: false, showMoonTimes: false,
lat: 47.630539, lat: 47.630539,
lon: -122.344147, lon: -122.344147
}, },
// Define required scripts. // Define required scripts.
getScripts: function () { getScripts: function () {
@ -55,7 +55,7 @@ Module.register("clock",{
if (self.config.displaySeconds) { if (self.config.displaySeconds) {
return 1000 - moment().milliseconds(); return 1000 - moment().milliseconds();
} else { } else {
return ((60 - reducedSeconds) * 1000) - moment().milliseconds(); return (60 - reducedSeconds) * 1000 - moment().milliseconds();
} }
}; };
@ -84,11 +84,9 @@ Module.register("clock",{
// Set locale. // Set locale.
moment.locale(config.language); moment.locale(config.language);
}, },
// Override dom generator. // Override dom generator.
getDom: function () { getDom: function () {
var wrapper = document.createElement("div"); var wrapper = document.createElement("div");
/************************************ /************************************
@ -127,7 +125,7 @@ Module.register("clock",{
} }
if (this.config.clockBold === true) { if (this.config.clockBold === true) {
timeString = now.format(hourSymbol + "[<span class=\"bold\">]mm[</span>]"); timeString = now.format(hourSymbol + '[<span class="bold">]mm[</span>]');
} else { } else {
timeString = now.format(hourSymbol + ":mm"); timeString = now.format(hourSymbol + ":mm");
} }
@ -173,9 +171,18 @@ Module.register("clock",{
} }
const untilNextEvent = moment.duration(moment(nextEvent).diff(now)); const untilNextEvent = moment.duration(moment(nextEvent).diff(now));
const untilNextEventString = untilNextEvent.hours() + "h " + untilNextEvent.minutes() + "m"; const untilNextEventString = untilNextEvent.hours() + "h " + untilNextEvent.minutes() + "m";
sunWrapper.innerHTML = "<span class=\"" + (isVisible ? "bright" : "") + "\"><i class=\"fa fa-sun-o\" aria-hidden=\"true\"></i> " + untilNextEventString + "</span>" + sunWrapper.innerHTML =
"<span><i class=\"fa fa-arrow-up\" aria-hidden=\"true\"></i>" + formatTime(this.config, sunTimes.sunrise) + "</span>" + '<span class="' +
"<span><i class=\"fa fa-arrow-down\" aria-hidden=\"true\"></i>" + formatTime(this.config, sunTimes.sunset) + "</span>"; (isVisible ? "bright" : "") +
'"><i class="fa fa-sun-o" aria-hidden="true"></i> ' +
untilNextEventString +
"</span>" +
'<span><i class="fa fa-arrow-up" aria-hidden="true"></i>' +
formatTime(this.config, sunTimes.sunrise) +
"</span>" +
'<span><i class="fa fa-arrow-down" aria-hidden="true"></i>' +
formatTime(this.config, sunTimes.sunset) +
"</span>";
} }
if (this.config.showMoonTimes) { if (this.config.showMoonTimes) {
const moonIllumination = SunCalc.getMoonIllumination(now.toDate()); const moonIllumination = SunCalc.getMoonIllumination(now.toDate());
@ -190,9 +197,18 @@ Module.register("clock",{
} }
const isVisible = now.isBetween(moonRise, moonSet) || moonTimes.alwaysUp === true; const isVisible = now.isBetween(moonRise, moonSet) || moonTimes.alwaysUp === true;
const illuminatedFractionString = Math.round(moonIllumination.fraction * 100) + "%"; const illuminatedFractionString = Math.round(moonIllumination.fraction * 100) + "%";
moonWrapper.innerHTML = "<span class=\"" + (isVisible ? "bright" : "") + "\"><i class=\"fa fa-moon-o\" aria-hidden=\"true\"></i> " + illuminatedFractionString + "</span>" + moonWrapper.innerHTML =
"<span><i class=\"fa fa-arrow-up\" aria-hidden=\"true\"></i> " + (moonRise ? formatTime(this.config, moonRise) : "...") + "</span>"+ '<span class="' +
"<span><i class=\"fa fa-arrow-down\" aria-hidden=\"true\"></i> " + (moonSet ? formatTime(this.config, moonSet) : "...") + "</span>"; (isVisible ? "bright" : "") +
'"><i class="fa fa-moon-o" aria-hidden="true"></i> ' +
illuminatedFractionString +
"</span>" +
'<span><i class="fa fa-arrow-up" aria-hidden="true"></i> ' +
(moonRise ? formatTime(this.config, moonRise) : "...") +
"</span>" +
'<span><i class="fa fa-arrow-down" aria-hidden="true"></i> ' +
(moonSet ? formatTime(this.config, moonSet) : "...") +
"</span>";
} }
/**************************************************************** /****************************************************************
@ -223,7 +239,6 @@ Module.register("clock",{
// The following line solves issue: https://github.com/MichMich/MagicMirror/issues/611 // The following line solves issue: https://github.com/MichMich/MagicMirror/issues/611
// clockCircle.style.border = "1px solid black"; // clockCircle.style.border = "1px solid black";
clockCircle.style.border = "rgba(0, 0, 0, 0.1)"; //Updated fix for Issue 611 where non-black backgrounds are used clockCircle.style.border = "rgba(0, 0, 0, 0.1)"; //Updated fix for Issue 611 where non-black backgrounds are used
} else if (this.config.analogFace !== "none") { } else if (this.config.analogFace !== "none") {
clockCircle.style.border = "2px solid white"; clockCircle.style.border = "2px solid white";
} }
@ -305,7 +320,7 @@ Module.register("clock",{
var appendClocks = function (condition, pos1, pos2) { var appendClocks = function (condition, pos1, pos2) {
var padding = [0, 0, 0, 0]; var padding = [0, 0, 0, 0];
padding[(placement === condition) ? pos1 : pos2] = "20px"; padding[placement === condition ? pos1 : pos2] = "20px";
analogWrapper.style.padding = padding.join(" "); analogWrapper.style.padding = padding.join(" ");
if (placement === condition) { if (placement === condition) {
wrapper.appendChild(analogWrapper); wrapper.appendChild(analogWrapper);

View file

@ -1,4 +1,5 @@
# Module: Compliments # Module: Compliments
The `compliments` module is one of the default modules of the MagicMirror. The `compliments` module is one of the default modules of the MagicMirror.
This module displays a random compliment. This module displays a random compliment.

View file

@ -5,31 +5,14 @@
* MIT Licensed. * MIT Licensed.
*/ */
Module.register("compliments", { Module.register("compliments", {
// Module config defaults. // Module config defaults.
defaults: { defaults: {
compliments: { compliments: {
anytime: [ anytime: ["Hey there sexy!"],
"Hey there sexy!" morning: ["Good morning, handsome!", "Enjoy your day!", "How was your sleep?"],
], afternoon: ["Hello, beauty!", "You look sexy!", "Looking good today!"],
morning: [ evening: ["Wow, you look hot!", "You look nice!", "Hi, sexy!"],
"Good morning, handsome!", "....-01-01": ["Happy new year!"]
"Enjoy your day!",
"How was your sleep?"
],
afternoon: [
"Hello, beauty!",
"You look sexy!",
"Looking good today!"
],
evening: [
"Wow, you look hot!",
"You look nice!",
"Hi, sexy!"
],
"....-01-01": [
"Happy new year!"
]
}, },
updateInterval: 30000, updateInterval: 30000,
remoteFile: null, remoteFile: null,
@ -165,11 +148,10 @@ Module.register("compliments", {
if (this.config.random) { if (this.config.random) {
// yes // yes
index = this.randomIndex(compliments); index = this.randomIndex(compliments);
} } else {
else{
// no, sequential // no, sequential
// if doing sequential, don't fall off the end // if doing sequential, don't fall off the end
index = (this.lastIndexUsed >= (compliments.length-1))?0: ++this.lastIndexUsed; index = this.lastIndexUsed >= compliments.length - 1 ? 0 : ++this.lastIndexUsed;
} }
return compliments[index] || ""; return compliments[index] || "";
@ -229,6 +211,5 @@ Module.register("compliments", {
if (notification === "CURRENTWEATHER_DATA") { if (notification === "CURRENTWEATHER_DATA") {
this.setCurrentWeatherType(payload.data); this.setCurrentWeatherType(payload.data);
} }
}, }
}); });

View file

@ -1,4 +1,5 @@
# Module: Current Weather # Module: Current Weather
The `currentweather` module is one of the default modules of the MagicMirror. The `currentweather` module is one of the default modules of the MagicMirror.
This module displays the current weather, including the windspeed, the sunset or sunrise time, the temperature and an icon to display the current conditions. This module displays the current weather, including the windspeed, the sunset or sunrise time, the temperature and an icon to display the current conditions.

View file

@ -5,7 +5,6 @@
* MIT Licensed. * MIT Licensed.
*/ */
Module.register("currentweather", { Module.register("currentweather", {
// Default module config. // Default module config.
defaults: { defaults: {
location: false, location: false,
@ -63,7 +62,7 @@ Module.register("currentweather",{
"11n": "wi-night-thunderstorm", "11n": "wi-night-thunderstorm",
"13n": "wi-night-snow", "13n": "wi-night-snow",
"50n": "wi-night-alt-cloudy-windy" "50n": "wi-night-alt-cloudy-windy"
}, }
}, },
// create a variable for the first upcoming calendar event. Used if no location is specified. // create a variable for the first upcoming calendar event. Used if no location is specified.
@ -109,13 +108,11 @@ Module.register("currentweather",{
this.feelsLike = null; this.feelsLike = null;
this.loaded = false; this.loaded = false;
this.scheduleUpdate(this.config.initialLoadDelay); this.scheduleUpdate(this.config.initialLoadDelay);
}, },
// add extra information of current weather // add extra information of current weather
// windDirection, humidity, sunrise and sunset // windDirection, humidity, sunrise and sunset
addExtraInfoWeather: function (wrapper) { addExtraInfoWeather: function (wrapper) {
var small = document.createElement("div"); var small = document.createElement("div");
small.className = "normal medium"; small.className = "normal medium";
@ -131,7 +128,7 @@ Module.register("currentweather",{
var windDirection = document.createElement("sup"); var windDirection = document.createElement("sup");
if (this.config.showWindDirectionAsArrow) { if (this.config.showWindDirectionAsArrow) {
if (this.windDeg !== null) { if (this.windDeg !== null) {
windDirection.innerHTML = " &nbsp;<i class=\"fa fa-long-arrow-down\" style=\"transform:rotate("+this.windDeg+"deg);\"></i>&nbsp;"; windDirection.innerHTML = ' &nbsp;<i class="fa fa-long-arrow-down" style="transform:rotate(' + this.windDeg + 'deg);"></i>&nbsp;';
} }
} else { } else {
windDirection.innerHTML = " " + this.translate(this.windDirection); windDirection.innerHTML = " " + this.translate(this.windDirection);
@ -340,7 +337,7 @@ Module.register("currentweather",{
} }
if (retry) { if (retry) {
self.scheduleUpdate((self.loaded) ? -1 : self.config.retryDelay); self.scheduleUpdate(self.loaded ? -1 : self.config.retryDelay);
} }
} }
}; };
@ -380,7 +377,6 @@ Module.register("currentweather",{
* argument data object - Weather information received form openweather.org. * argument data object - Weather information received form openweather.org.
*/ */
processWeather: function (data) { processWeather: function (data) {
if (!data || !data.main || typeof data.main.temp === "undefined") { if (!data || !data.main || typeof data.main.temp === "undefined") {
// Did not receive usable new data. // Did not receive usable new data.
// Maybe this needs a better check? // Maybe this needs a better check?
@ -405,9 +401,11 @@ Module.register("currentweather",{
var tempInF = 0; var tempInF = 0;
switch (this.config.units) { switch (this.config.units) {
case "metric": tempInF = 1.8 * this.temperature + 32; case "metric":
tempInF = 1.8 * this.temperature + 32;
break; break;
case "imperial": tempInF = this.temperature; case "imperial":
tempInF = this.temperature;
break; break;
case "default": case "default":
tempInF = 1.8 * (this.temperature - 273.15) + 32; tempInF = 1.8 * (this.temperature - 273.15) + 32;
@ -421,28 +419,35 @@ Module.register("currentweather",{
// this.feelsLike = windChillInC.toFixed(0); // this.feelsLike = windChillInC.toFixed(0);
switch (this.config.units) { switch (this.config.units) {
case "metric": this.feelsLike = windChillInC.toFixed(0); case "metric":
this.feelsLike = windChillInC.toFixed(0);
break; break;
case "imperial": this.feelsLike = windChillInF.toFixed(0); case "imperial":
this.feelsLike = windChillInF.toFixed(0);
break; break;
case "default": case "default":
this.feelsLike = (windChillInC + 273.15).toFixed(0); this.feelsLike = (windChillInC + 273.15).toFixed(0);
break; break;
} }
} else if (tempInF > 80 && this.humidity > 40) { } else if (tempInF > 80 && this.humidity > 40) {
// heat index // heat index
var Hindex = -42.379 + 2.04901523*tempInF + 10.14333127*this.humidity var Hindex =
- 0.22475541*tempInF*this.humidity - 6.83783*Math.pow(10,-3)*tempInF*tempInF -42.379 +
- 5.481717*Math.pow(10,-2)*this.humidity*this.humidity 2.04901523 * tempInF +
+ 1.22874*Math.pow(10,-3)*tempInF*tempInF*this.humidity 10.14333127 * this.humidity -
+ 8.5282*Math.pow(10,-4)*tempInF*this.humidity*this.humidity 0.22475541 * tempInF * this.humidity -
- 1.99*Math.pow(10,-6)*tempInF*tempInF*this.humidity*this.humidity; 6.83783 * Math.pow(10, -3) * tempInF * tempInF -
5.481717 * Math.pow(10, -2) * this.humidity * this.humidity +
1.22874 * Math.pow(10, -3) * tempInF * tempInF * this.humidity +
8.5282 * Math.pow(10, -4) * tempInF * this.humidity * this.humidity -
1.99 * Math.pow(10, -6) * tempInF * tempInF * this.humidity * this.humidity;
switch (this.config.units) { switch (this.config.units) {
case "metric": this.feelsLike = parseFloat((Hindex - 32) / 1.8).toFixed(0); case "metric":
this.feelsLike = parseFloat((Hindex - 32) / 1.8).toFixed(0);
break; break;
case "imperial": this.feelsLike = Hindex.toFixed(0); case "imperial":
this.feelsLike = Hindex.toFixed(0);
break; break;
case "default": case "default":
var tc = parseFloat((Hindex - 32) / 1.8) + 273.15; var tc = parseFloat((Hindex - 32) / 1.8) + 273.15;
@ -464,7 +469,7 @@ Module.register("currentweather",{
// The moment().format('h') method has a bug on the Raspberry Pi. // The moment().format('h') method has a bug on the Raspberry Pi.
// So we need to generate the timestring manually. // So we need to generate the timestring manually.
// See issue: https://github.com/MichMich/MagicMirror/issues/181 // See issue: https://github.com/MichMich/MagicMirror/issues/181
var sunriseSunsetDateObject = (sunrise < now && sunset > now) ? sunset : sunrise; var sunriseSunsetDateObject = sunrise < now && sunset > now ? sunset : sunrise;
var timeString = moment(sunriseSunsetDateObject).format("HH:mm"); var timeString = moment(sunriseSunsetDateObject).format("HH:mm");
if (this.config.timeFormat !== 24) { if (this.config.timeFormat !== 24) {
//var hours = sunriseSunsetDateObject.getHours() % 12 || 12; //var hours = sunriseSunsetDateObject.getHours() % 12 || 12;
@ -483,7 +488,7 @@ Module.register("currentweather",{
} }
this.sunriseSunsetTime = timeString; this.sunriseSunsetTime = timeString;
this.sunriseSunsetIcon = (sunrise < now && sunset > now) ? "wi-sunset" : "wi-sunrise"; this.sunriseSunsetIcon = sunrise < now && sunset > now ? "wi-sunset" : "wi-sunrise";
this.show(this.config.animationSpeed, { lockString: this.identifier }); this.show(this.config.animationSpeed, { lockString: this.identifier });
this.loaded = true; this.loaded = true;
@ -520,7 +525,7 @@ Module.register("currentweather",{
* return number - Windspeed in beaufort. * return number - Windspeed in beaufort.
*/ */
ms2Beaufort: function (ms) { ms2Beaufort: function (ms) {
var kmh = ms * 60 * 60 / 1000; var kmh = (ms * 60 * 60) / 1000;
var speeds = [1, 5, 11, 19, 28, 38, 49, 61, 74, 88, 102, 117, 1000]; var speeds = [1, 5, 11, 19, 28, 38, 49, 61, 74, 88, 102, 117, 1000];
for (var beaufort in speeds) { for (var beaufort in speeds) {
var speed = speeds[beaufort]; var speed = speeds[beaufort];
@ -578,5 +583,4 @@ Module.register("currentweather",{
var decimals = this.config.roundTemp ? 0 : 1; var decimals = this.config.roundTemp ? 0 : 1;
return parseFloat(temperature).toFixed(decimals); return parseFloat(temperature).toFixed(decimals);
} }
}); });

View file

@ -7,18 +7,9 @@
// Modules listed below can be loaded without the 'default/' prefix. Omitting the default folder name. // Modules listed below can be loaded without the 'default/' prefix. Omitting the default folder name.
var defaultModules = [ var defaultModules = ["alert", "calendar", "clock", "compliments", "currentweather", "helloworld", "newsfeed", "weatherforecast", "updatenotification", "weather"];
"alert",
"calendar",
"clock",
"compliments",
"currentweather",
"helloworld",
"newsfeed",
"weatherforecast",
"updatenotification",
"weather"
];
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = defaultModules;} if (typeof module !== "undefined") {
module.exports = defaultModules;
}

View file

@ -1,4 +1,5 @@
# Module: Hello World # Module: Hello World
The `helloworld` module is one of the default modules of the MagicMirror. It is a simple way to display a static text on the mirror. The `helloworld` module is one of the default modules of the MagicMirror. It is a simple way to display a static text on the mirror.
For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/helloworld.html). For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/helloworld.html).

View file

@ -5,7 +5,6 @@
* MIT Licensed. * MIT Licensed.
*/ */
Module.register("helloworld", { Module.register("helloworld", {
// Default module config. // Default module config.
defaults: { defaults: {
text: "Hello World!" text: "Hello World!"

View file

@ -1,5 +1,6 @@
# Module: News Feed # Module: News Feed
The `newsfeed` module is one of the default modules of the MagicMirror. The `newsfeed` module is one of the default modules of the MagicMirror.
This module displays news headlines based on an RSS feed. Scrolling through news headlines happens time-based (````updateInterval````), but can also be controlled by sending news feed specific notifications to the module. This module displays news headlines based on an RSS feed. Scrolling through news headlines happens time-based (`updateInterval`), but can also be controlled by sending news feed specific notifications to the module.
For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/newsfeed.html). For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/newsfeed.html).

View file

@ -43,24 +43,21 @@ var Fetcher = function(url, reloadInterval, encoding, logFeedWarnings) {
var parser = new FeedMe(); var parser = new FeedMe();
parser.on("item", function (item) { parser.on("item", function (item) {
var title = item.title; var title = item.title;
var description = item.description || item.summary || item.content || ""; var description = item.description || item.summary || item.content || "";
var pubdate = item.pubdate || item.published || item.updated || item["dc:date"]; var pubdate = item.pubdate || item.published || item.updated || item["dc:date"];
var url = item.url || item.link || ""; var url = item.url || item.link || "";
if (title && pubdate) { if (title && pubdate) {
var regex = /(<([^>]+)>)/gi;
var regex = /(<([^>]+)>)/ig;
description = description.toString().replace(regex, ""); description = description.toString().replace(regex, "");
items.push({ items.push({
title: title, title: title,
description: description, description: description,
pubdate: pubdate, pubdate: pubdate,
url: url, url: url
}); });
} else if (logFeedWarnings) { } else if (logFeedWarnings) {
console.log("Can't parse feed item:"); console.log("Can't parse feed item:");
console.log(item); console.log(item);
@ -82,17 +79,15 @@ var Fetcher = function(url, reloadInterval, encoding, logFeedWarnings) {
}); });
var nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]); var nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]);
var headers = {"User-Agent": "Mozilla/5.0 (Node.js "+ nodeVersion + ") MagicMirror/" + global.version + " (https://github.com/MichMich/MagicMirror/)", var headers = { "User-Agent": "Mozilla/5.0 (Node.js " + nodeVersion + ") MagicMirror/" + global.version + " (https://github.com/MichMich/MagicMirror/)", "Cache-Control": "max-age=0, no-cache, no-store, must-revalidate", Pragma: "no-cache" };
"Cache-Control": "max-age=0, no-cache, no-store, must-revalidate",
"Pragma": "no-cache"};
request({ uri: url, encoding: null, headers: headers }) request({ uri: url, encoding: null, headers: headers })
.on("error", function (error) { .on("error", function (error) {
fetchFailedCallback(self, error); fetchFailedCallback(self, error);
scheduleTimer(); scheduleTimer();
}) })
.pipe(iconv.decodeStream(encoding)).pipe(parser); .pipe(iconv.decodeStream(encoding))
.pipe(parser);
}; };
/* scheduleTimer() /* scheduleTimer()

View file

@ -5,7 +5,6 @@
* MIT Licensed. * MIT Licensed.
*/ */
Module.register("newsfeed", { Module.register("newsfeed", {
// Default module config. // Default module config.
defaults: { defaults: {
feeds: [ feeds: [
@ -98,7 +97,6 @@ Module.register("newsfeed",{
} }
if (this.newsItems.length > 0) { if (this.newsItems.length > 0) {
// this.config.showFullArticle is a run-time configuration, triggered by optional notifications // this.config.showFullArticle is a run-time configuration, triggered by optional notifications
if (!this.config.showFullArticle && (this.config.showSourceTitle || this.config.showPublishDate)) { if (!this.config.showFullArticle && (this.config.showSourceTitle || this.config.showPublishDate)) {
var sourceAndTimestamp = document.createElement("div"); var sourceAndTimestamp = document.createElement("div");
@ -113,7 +111,7 @@ Module.register("newsfeed",{
if (this.config.showPublishDate) { if (this.config.showPublishDate) {
sourceAndTimestamp.innerHTML += moment(new Date(this.newsItems[this.activeItem].pubdate)).fromNow(); sourceAndTimestamp.innerHTML += moment(new Date(this.newsItems[this.activeItem].pubdate)).fromNow();
} }
if (this.config.showSourceTitle && this.newsItems[this.activeItem].sourceTitle !== "" || this.config.showPublishDate) { if ((this.config.showSourceTitle && this.newsItems[this.activeItem].sourceTitle !== "") || this.config.showPublishDate) {
sourceAndTimestamp.innerHTML += ":"; sourceAndTimestamp.innerHTML += ":";
} }
@ -123,17 +121,14 @@ Module.register("newsfeed",{
//Remove selected tags from the beginning of rss feed items (title or description) //Remove selected tags from the beginning of rss feed items (title or description)
if (this.config.removeStartTags === "title" || this.config.removeStartTags === "both") { if (this.config.removeStartTags === "title" || this.config.removeStartTags === "both") {
for (let f = 0; f < this.config.startTags.length; f++) { for (let f = 0; f < this.config.startTags.length; f++) {
if (this.newsItems[this.activeItem].title.slice(0, this.config.startTags[f].length) === this.config.startTags[f]) { if (this.newsItems[this.activeItem].title.slice(0, this.config.startTags[f].length) === this.config.startTags[f]) {
this.newsItems[this.activeItem].title = this.newsItems[this.activeItem].title.slice(this.config.startTags[f].length, this.newsItems[this.activeItem].title.length); this.newsItems[this.activeItem].title = this.newsItems[this.activeItem].title.slice(this.config.startTags[f].length, this.newsItems[this.activeItem].title.length);
} }
} }
} }
if (this.config.removeStartTags === "description" || this.config.removeStartTags === "both") { if (this.config.removeStartTags === "description" || this.config.removeStartTags === "both") {
if (this.isShowingDescription) { if (this.isShowingDescription) {
for (let f = 0; f < this.config.startTags.length; f++) { for (let f = 0; f < this.config.startTags.length; f++) {
if (this.newsItems[this.activeItem].description.slice(0, this.config.startTags[f].length) === this.config.startTags[f]) { if (this.newsItems[this.activeItem].description.slice(0, this.config.startTags[f].length) === this.config.startTags[f]) {
@ -141,7 +136,6 @@ Module.register("newsfeed",{
} }
} }
} }
} }
//Remove selected tags from the end of rss feed items (title or description) //Remove selected tags from the end of rss feed items (title or description)
@ -160,7 +154,6 @@ Module.register("newsfeed",{
} }
} }
} }
} }
if (!this.config.showFullArticle) { if (!this.config.showFullArticle) {
@ -174,7 +167,7 @@ Module.register("newsfeed",{
var description = document.createElement("div"); var description = document.createElement("div");
description.className = "newsfeed-desc small light" + (!this.config.wrapDescription ? " no-wrap" : ""); description.className = "newsfeed-desc small light" + (!this.config.wrapDescription ? " no-wrap" : "");
var txtDesc = this.newsItems[this.activeItem].description; var txtDesc = this.newsItems[this.activeItem].description;
description.innerHTML = (this.config.truncDescription ? (txtDesc.length > this.config.lengthDescription ? txtDesc.substring(0, this.config.lengthDescription) + "..." : txtDesc) : txtDesc); description.innerHTML = this.config.truncDescription ? (txtDesc.length > this.config.lengthDescription ? txtDesc.substring(0, this.config.lengthDescription) + "..." : txtDesc) : txtDesc;
wrapper.appendChild(description); wrapper.appendChild(description);
} }
@ -196,7 +189,6 @@ Module.register("newsfeed",{
if (this.config.hideLoading) { if (this.config.hideLoading) {
this.show(); this.show();
} }
} else { } else {
if (this.config.hideLoading) { if (this.config.hideLoading) {
this.hide(); this.hide();
@ -239,7 +231,7 @@ Module.register("newsfeed",{
for (var i in feedItems) { for (var i in feedItems) {
var item = feedItems[i]; var item = feedItems[i];
item.sourceTitle = this.titleForFeed(feed); item.sourceTitle = this.titleForFeed(feed);
if (!(this.config.ignoreOldItems && ((Date.now() - new Date(item.pubdate)) > this.config.ignoreOlderThan))) { if (!(this.config.ignoreOldItems && Date.now() - new Date(item.pubdate) > this.config.ignoreOlderThan)) {
newsItems.push(item); newsItems.push(item);
} }
} }
@ -267,8 +259,8 @@ Module.register("newsfeed",{
// get updated news items and broadcast them // get updated news items and broadcast them
var updatedItems = []; var updatedItems = [];
newsItems.forEach(value => { newsItems.forEach((value) => {
if (this.newsItems.findIndex(value1 => value1 === value) === -1) { if (this.newsItems.findIndex((value1) => value1 === value) === -1) {
// Add item to updated items list // Add item to updated items list
updatedItems.push(value); updatedItems.push(value);
} }
@ -390,8 +382,7 @@ Module.register("newsfeed",{
window.scrollTo(0, this.scrollPosition); window.scrollTo(0, this.scrollPosition);
Log.info(this.name + " - scrolling down"); Log.info(this.name + " - scrolling down");
Log.info(this.name + " - ARTICLE_MORE_DETAILS, scroll position: " + this.config.scrollLength); Log.info(this.name + " - ARTICLE_MORE_DETAILS, scroll position: " + this.config.scrollLength);
} } else {
else {
this.showFullArticle(); this.showFullArticle();
} }
} else if (notification === "ARTICLE_SCROLL_UP") { } else if (notification === "ARTICLE_SCROLL_UP") {

View file

@ -1,4 +1,5 @@
# Module: Update Notification # Module: Update Notification
The `updatenotification` module is one of the default modules of the MagicMirror. The `updatenotification` module is one of the default modules of the MagicMirror.
This will display a message whenever a new version of the MagicMirror application is available. This will display a message whenever a new version of the MagicMirror application is available.

View file

@ -6,21 +6,18 @@ var defaultModules = require(__dirname + "/../defaultmodules.js");
var NodeHelper = require("node_helper"); var NodeHelper = require("node_helper");
module.exports = NodeHelper.create({ module.exports = NodeHelper.create({
config: {}, config: {},
updateTimer: null, updateTimer: null,
updateProcessStarted: false, updateProcessStarted: false,
start: function () { start: function () {},
},
configureModules: function (modules) { configureModules: function (modules) {
// Push MagicMirror itself , biggest chance it'll show up last in UI and isn't overwritten // Push MagicMirror itself , biggest chance it'll show up last in UI and isn't overwritten
// others will be added in front // others will be added in front
// this method returns promises so we can't wait for every one to resolve before continuing // this method returns promises so we can't wait for every one to resolve before continuing
simpleGits.push({"module": "default", "git": SimpleGit(path.normalize(__dirname + "/../../../"))}); simpleGits.push({ module: "default", git: SimpleGit(path.normalize(__dirname + "/../../../")) });
var promises = []; var promises = [];
@ -65,7 +62,7 @@ module.exports = NodeHelper.create({
return resolve(); return resolve();
} }
// Folder has .git and has at least one git remote, watch this folder // Folder has .git and has at least one git remote, watch this folder
simpleGits.unshift({"module": moduleName, "git": git}); simpleGits.unshift({ module: moduleName, git: git });
resolve(); resolve();
}); });
}); });
@ -116,5 +113,4 @@ module.exports = NodeHelper.create({
// The rest of the modules that passes should check for updates // The rest of the modules that passes should check for updates
return false; return false;
} }
}); });

View file

@ -5,7 +5,6 @@
* MIT Licensed. * MIT Licensed.
*/ */
Module.register("updatenotification", { Module.register("updatenotification", {
defaults: { defaults: {
updateInterval: 10 * 60 * 1000, // every 10 minutes updateInterval: 10 * 60 * 1000, // every 10 minutes
refreshInterval: 24 * 60 * 60 * 1000, // one day refreshInterval: 24 * 60 * 60 * 1000, // one day
@ -18,7 +17,10 @@ Module.register("updatenotification", {
start: function () { start: function () {
var self = this; var self = this;
Log.log("Start updatenotification"); Log.log("Start updatenotification");
setInterval( () => { self.moduleList = {};self.updateDom(2); } , self.config.refreshInterval); setInterval(() => {
self.moduleList = {};
self.updateDom(2);
}, self.config.refreshInterval);
}, },
notificationReceived: function (notification, payload, sender) { notificationReceived: function (notification, payload, sender) {
@ -45,7 +47,6 @@ Module.register("updatenotification", {
self.updateDom(2); self.updateDom(2);
} }
//self.show(1000, { lockString: self.identifier }); //self.show(1000, { lockString: self.identifier });
} else if (payload && payload.behind === 0) { } else if (payload && payload.behind === 0) {
// if the module WAS in the list, but shouldn't be // if the module WAS in the list, but shouldn't be
if (this.moduleList[payload.module] !== undefined) { if (this.moduleList[payload.module] !== undefined) {
@ -59,12 +60,7 @@ Module.register("updatenotification", {
diffLink: function (module, text) { diffLink: function (module, text) {
var localRef = module.hash; var localRef = module.hash;
var remoteRef = module.tracking.replace(/.*\//, ""); var remoteRef = module.tracking.replace(/.*\//, "");
return "<a href=\"https://github.com/MichMich/MagicMirror/compare/"+localRef+"..."+remoteRef+"\" "+ return '<a href="https://github.com/MichMich/MagicMirror/compare/' + localRef + "..." + remoteRef + '" ' + 'class="xsmall dimmed" ' + 'style="text-decoration: none;" ' + 'target="_blank" >' + text + "</a>";
"class=\"xsmall dimmed\" "+
"style=\"text-decoration: none;\" "+
"target=\"_blank\" >" +
text +
"</a>";
}, },
// Override dom generator. // Override dom generator.

View file

@ -15,7 +15,7 @@ Table of Contents:
This is the script in which the weather provider will be defined. In its most simple form, the weather provider must implement the following: This is the script in which the weather provider will be defined. In its most simple form, the weather provider must implement the following:
````javascript ```javascript
WeatherProvider.register("yourprovider", { WeatherProvider.register("yourprovider", {
providerName: "YourProvider", providerName: "YourProvider",
@ -23,7 +23,7 @@ WeatherProvider.register("yourprovider", {
fetchWeatherForecast() {} fetchWeatherForecast() {}
}); });
```` ```
### Weather provider methods to implement ### Weather provider methods to implement
@ -90,7 +90,7 @@ A convenience function to make requests. It returns a promise.
### WeatherObject ### WeatherObject
| Property | Type | Value/Unit | | Property | Type | Value/Unit |
| --- | --- | --- | | -------------- | -------- | --------------------------------------------------------------------------------------------------------------- |
| units | `string` | Gets initialized with the constructor. <br> Possible values: `metric`, `imperial` | | units | `string` | Gets initialized with the constructor. <br> Possible values: `metric`, `imperial` |
| tempUnits | `string` | Gets initialized with the constructor. <br> Possible values: `metric`, `imperial` | | tempUnits | `string` | Gets initialized with the constructor. <br> Possible values: `metric`, `imperial` |
| windUnits | `string` | Gets initialized with the constructor. <br> Possible values: `metric`, `imperial` | | windUnits | `string` | Gets initialized with the constructor. <br> Possible values: `metric`, `imperial` |

View file

@ -22,7 +22,7 @@ WeatherProvider.register("darksky", {
fetchCurrentWeather() { fetchCurrentWeather() {
this.fetchData(this.getUrl()) this.fetchData(this.getUrl())
.then(data => { .then((data) => {
if (!data || !data.currently || typeof data.currently.temperature === "undefined") { if (!data || !data.currently || typeof data.currently.temperature === "undefined") {
// No usable data? // No usable data?
return; return;
@ -30,7 +30,8 @@ WeatherProvider.register("darksky", {
const currentWeather = this.generateWeatherDayFromCurrentWeather(data); const currentWeather = this.generateWeatherDayFromCurrentWeather(data);
this.setCurrentWeather(currentWeather); this.setCurrentWeather(currentWeather);
}).catch(function(request) { })
.catch(function (request) {
Log.error("Could not load data ... ", request); Log.error("Could not load data ... ", request);
}) })
.finally(() => this.updateAvailable()); .finally(() => this.updateAvailable());
@ -38,7 +39,7 @@ WeatherProvider.register("darksky", {
fetchWeatherForecast() { fetchWeatherForecast() {
this.fetchData(this.getUrl()) this.fetchData(this.getUrl())
.then(data => { .then((data) => {
if (!data || !data.daily || !data.daily.data.length) { if (!data || !data.daily || !data.daily.data.length) {
// No usable data? // No usable data?
return; return;
@ -46,7 +47,8 @@ WeatherProvider.register("darksky", {
const forecast = this.generateWeatherObjectsFromForecast(data.daily.data); const forecast = this.generateWeatherObjectsFromForecast(data.daily.data);
this.setWeatherForecast(forecast); this.setWeatherForecast(forecast);
}).catch(function(request) { })
.catch(function (request) {
Log.error("Could not load data ... ", request); Log.error("Could not load data ... ", request);
}) })
.finally(() => this.updateAvailable()); .finally(() => this.updateAvailable());
@ -109,12 +111,12 @@ WeatherProvider.register("darksky", {
const weatherTypes = { const weatherTypes = {
"clear-day": "day-sunny", "clear-day": "day-sunny",
"clear-night": "night-clear", "clear-night": "night-clear",
"rain": "rain", rain: "rain",
"snow": "snow", snow: "snow",
"sleet": "snow", sleet: "snow",
"wind": "wind", wind: "wind",
"fog": "fog", fog: "fog",
"cloudy": "cloudy", cloudy: "cloudy",
"partly-cloudy-day": "day-cloudy", "partly-cloudy-day": "day-cloudy",
"partly-cloudy-night": "night-cloudy" "partly-cloudy-night": "night-cloudy"
}; };

View file

@ -9,7 +9,6 @@
* This class is the blueprint for a weather provider. * This class is the blueprint for a weather provider.
*/ */
WeatherProvider.register("openweathermap", { WeatherProvider.register("openweathermap", {
// Set the name of the provider. // Set the name of the provider.
// This isn't strictly necessary, since it will fallback to the provider identifier // This isn't strictly necessary, since it will fallback to the provider identifier
// But for debugging (and future alerts) it would be nice to have the real name. // But for debugging (and future alerts) it would be nice to have the real name.
@ -18,7 +17,7 @@ WeatherProvider.register("openweathermap", {
// Overwrite the fetchCurrentWeather method. // Overwrite the fetchCurrentWeather method.
fetchCurrentWeather() { fetchCurrentWeather() {
this.fetchData(this.getUrl()) this.fetchData(this.getUrl())
.then(data => { .then((data) => {
if (!data || !data.main || typeof data.main.temp === "undefined") { if (!data || !data.main || typeof data.main.temp === "undefined") {
// Did not receive usable new data. // Did not receive usable new data.
// Maybe this needs a better check? // Maybe this needs a better check?
@ -39,7 +38,7 @@ WeatherProvider.register("openweathermap", {
// Overwrite the fetchCurrentWeather method. // Overwrite the fetchCurrentWeather method.
fetchWeatherForecast() { fetchWeatherForecast() {
this.fetchData(this.getUrl()) this.fetchData(this.getUrl())
.then(data => { .then((data) => {
if (!data || !data.list || !data.list.length) { if (!data || !data.list || !data.list.length) {
// Did not receive usable new data. // Did not receive usable new data.
// Maybe this needs a better check? // Maybe this needs a better check?
@ -86,7 +85,6 @@ WeatherProvider.register("openweathermap", {
* Generate WeatherObjects based on forecast information * Generate WeatherObjects based on forecast information
*/ */
generateWeatherObjectsFromForecast(forecasts) { generateWeatherObjectsFromForecast(forecasts) {
if (this.config.weatherEndpoint === "/forecast") { if (this.config.weatherEndpoint === "/forecast") {
return this.fetchForecastHourly(forecasts); return this.fetchForecastHourly(forecasts);
} else if (this.config.weatherEndpoint === "/forecast/daily") { } else if (this.config.weatherEndpoint === "/forecast/daily") {
@ -113,7 +111,6 @@ WeatherProvider.register("openweathermap", {
let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
for (const forecast of forecasts) { for (const forecast of forecasts) {
if (date !== moment(forecast.dt, "X").format("YYYY-MM-DD")) { if (date !== moment(forecast.dt, "X").format("YYYY-MM-DD")) {
// calculate minimum/maximum temperature, specify rain amount // calculate minimum/maximum temperature, specify rain amount
weather.minTemperature = Math.min.apply(null, minTemp); weather.minTemperature = Math.min.apply(null, minTemp);
@ -139,7 +136,6 @@ WeatherProvider.register("openweathermap", {
// If the first value of today is later than 17:00, we have an icon at least! // If the first value of today is later than 17:00, we have an icon at least!
weather.weatherType = this.convertWeatherType(forecast.weather[0].icon); weather.weatherType = this.convertWeatherType(forecast.weather[0].icon);
} }
if (moment(forecast.dt, "X").format("H") >= 8 && moment(forecast.dt, "X").format("H") <= 17) { if (moment(forecast.dt, "X").format("H") >= 8 && moment(forecast.dt, "X").format("H") <= 17) {

View file

@ -9,7 +9,6 @@
* This class is a provider for UK Met Office Datapoint. * This class is a provider for UK Met Office Datapoint.
*/ */
WeatherProvider.register("ukmetoffice", { WeatherProvider.register("ukmetoffice", {
// Set the name of the provider. // Set the name of the provider.
// This isn't strictly necessary, since it will fallback to the provider identifier // This isn't strictly necessary, since it will fallback to the provider identifier
// But for debugging (and future alerts) it would be nice to have the real name. // But for debugging (and future alerts) it would be nice to have the real name.
@ -23,7 +22,7 @@ WeatherProvider.register("ukmetoffice", {
// Overwrite the fetchCurrentWeather method. // Overwrite the fetchCurrentWeather method.
fetchCurrentWeather() { fetchCurrentWeather() {
this.fetchData(this.getUrl("3hourly")) this.fetchData(this.getUrl("3hourly"))
.then(data => { .then((data) => {
if (!data || !data.SiteRep || !data.SiteRep.DV || !data.SiteRep.DV.Location || !data.SiteRep.DV.Location.Period || data.SiteRep.DV.Location.Period.length === 0) { if (!data || !data.SiteRep || !data.SiteRep.DV || !data.SiteRep.DV.Location || !data.SiteRep.DV.Location.Period || data.SiteRep.DV.Location.Period.length === 0) {
// Did not receive usable new data. // Did not receive usable new data.
// Maybe this needs a better check? // Maybe this needs a better check?
@ -44,7 +43,7 @@ WeatherProvider.register("ukmetoffice", {
// Overwrite the fetchCurrentWeather method. // Overwrite the fetchCurrentWeather method.
fetchWeatherForecast() { fetchWeatherForecast() {
this.fetchData(this.getUrl("daily")) this.fetchData(this.getUrl("daily"))
.then(data => { .then((data) => {
if (!data || !data.SiteRep || !data.SiteRep.DV || !data.SiteRep.DV.Location || !data.SiteRep.DV.Location.Period || data.SiteRep.DV.Location.Period.length === 0) { if (!data || !data.SiteRep || !data.SiteRep.DV || !data.SiteRep.DV.Location || !data.SiteRep.DV.Location.Period || data.SiteRep.DV.Location.Period.length === 0) {
// Did not receive usable new data. // Did not receive usable new data.
// Maybe this needs a better check? // Maybe this needs a better check?
@ -87,7 +86,6 @@ WeatherProvider.register("ukmetoffice", {
// ignore if period is before today // ignore if period is before today
if (periodDate.isSameOrAfter(moment.utc().startOf("day"))) { if (periodDate.isSameOrAfter(moment.utc().startOf("day"))) {
// check this is the period we want, after today the diff will be -ve // check this is the period we want, after today the diff will be -ve
if (moment().diff(periodDate, "minutes") > 0) { if (moment().diff(periodDate, "minutes") > 0) {
// loop round the reports looking for the one we are in // loop round the reports looking for the one we are in
@ -121,7 +119,6 @@ WeatherProvider.register("ukmetoffice", {
* Generate WeatherObjects based on forecast information * Generate WeatherObjects based on forecast information
*/ */
generateWeatherObjectsFromForecast(forecasts) { generateWeatherObjectsFromForecast(forecasts) {
const days = []; const days = [];
// loop round the (5) periods getting the data // loop round the (5) periods getting the data
@ -207,7 +204,7 @@ WeatherProvider.register("ukmetoffice", {
* Convert temp (from degrees C) if required * Convert temp (from degrees C) if required
*/ */
convertTemp(tempInC) { convertTemp(tempInC) {
return this.tempUnits === "imperial" ? tempInC * 9 / 5 + 32 : tempInC; return this.tempUnits === "imperial" ? (tempInC * 9) / 5 + 32 : tempInC;
}, },
/* /*
@ -222,22 +219,22 @@ WeatherProvider.register("ukmetoffice", {
*/ */
convertWindDirection(windDirection) { convertWindDirection(windDirection) {
const windCardinals = { const windCardinals = {
"N": 0, N: 0,
"NNE": 22, NNE: 22,
"NE": 45, NE: 45,
"ENE": 67, ENE: 67,
"E": 90, E: 90,
"ESE": 112, ESE: 112,
"SE": 135, SE: 135,
"SSE": 157, SSE: 157,
"S": 180, S: 180,
"SSW": 202, SSW: 202,
"SW": 225, SW: 225,
"WSW": 247, WSW: 247,
"W": 270, W: 270,
"WNW": 292, WNW: 292,
"NW": 315, NW: 315,
"NNW": 337 NNW: 337
}; };
return windCardinals.hasOwnProperty(windDirection) ? windCardinals[windDirection] : null; return windCardinals.hasOwnProperty(windDirection) ? windCardinals[windDirection] : null;

View file

@ -12,7 +12,6 @@
* Since it is free, there are some items missing - like sunrise, sunset, humidity, etc. * Since it is free, there are some items missing - like sunrise, sunset, humidity, etc.
*/ */
WeatherProvider.register("weathergov", { WeatherProvider.register("weathergov", {
// Set the name of the provider. // Set the name of the provider.
// This isn't strictly necessary, since it will fallback to the provider identifier // This isn't strictly necessary, since it will fallback to the provider identifier
// But for debugging (and future alerts) it would be nice to have the real name. // But for debugging (and future alerts) it would be nice to have the real name.
@ -21,7 +20,7 @@ WeatherProvider.register("weathergov", {
// Overwrite the fetchCurrentWeather method. // Overwrite the fetchCurrentWeather method.
fetchCurrentWeather() { fetchCurrentWeather() {
this.fetchData(this.getUrl()) this.fetchData(this.getUrl())
.then(data => { .then((data) => {
if (!data || !data.properties || !data.properties.periods || !data.properties.periods.length) { if (!data || !data.properties || !data.properties.periods || !data.properties.periods.length) {
// Did not receive usable new data. // Did not receive usable new data.
// Maybe this needs a better check? // Maybe this needs a better check?
@ -40,7 +39,7 @@ WeatherProvider.register("weathergov", {
// Overwrite the fetchCurrentWeather method. // Overwrite the fetchCurrentWeather method.
fetchWeatherForecast() { fetchWeatherForecast() {
this.fetchData(this.getUrl()) this.fetchData(this.getUrl())
.then(data => { .then((data) => {
if (!data || !data.properties || !data.properties.periods || !data.properties.periods.length) { if (!data || !data.properties || !data.properties.periods || !data.properties.periods.length) {
// Did not receive usable new data. // Did not receive usable new data.
// Maybe this needs a better check? // Maybe this needs a better check?
@ -105,9 +104,7 @@ WeatherProvider.register("weathergov", {
weather.precipitation = 0; weather.precipitation = 0;
for (const forecast of forecasts) { for (const forecast of forecasts) {
if (date !== moment(forecast.startTime).format("YYYY-MM-DD")) { if (date !== moment(forecast.startTime).format("YYYY-MM-DD")) {
// calculate minimum/maximum temperature, specify rain amount // calculate minimum/maximum temperature, specify rain amount
weather.minTemperature = Math.min.apply(null, minTemp); weather.minTemperature = Math.min.apply(null, minTemp);
weather.maxTemperature = Math.max.apply(null, maxTemp); weather.maxTemperature = Math.max.apply(null, maxTemp);
@ -240,22 +237,22 @@ WeatherProvider.register("weathergov", {
*/ */
convertWindDirection(windDirection) { convertWindDirection(windDirection) {
const windCardinals = { const windCardinals = {
"N": 0, N: 0,
"NNE": 22, NNE: 22,
"NE": 45, NE: 45,
"ENE": 67, ENE: 67,
"E": 90, E: 90,
"ESE": 112, ESE: 112,
"SE": 135, SE: 135,
"SSE": 157, SSE: 157,
"S": 180, S: 180,
"SSW": 202, SSW: 202,
"SW": 225, SW: 225,
"WSW": 247, WSW: 247,
"W": 270, W: 270,
"WNW": 292, WNW: 292,
"NW": 315, NW: 315,
"NNW": 337 NNW: 337
}; };
return windCardinals.hasOwnProperty(windDirection) ? windCardinals[windDirection] : null; return windCardinals.hasOwnProperty(windDirection) ? windCardinals[windDirection] : null;

View file

@ -66,13 +66,7 @@ Module.register("weather",{
// Return the scripts that are necessary for the weather module. // Return the scripts that are necessary for the weather module.
getScripts: function () { getScripts: function () {
return [ return ["moment.js", "weatherprovider.js", "weatherobject.js", "suncalc.js", this.file("providers/" + this.config.weatherProvider.toLowerCase() + ".js")];
"moment.js",
"weatherprovider.js",
"weatherobject.js",
"suncalc.js",
this.file("providers/" + this.config.weatherProvider.toLowerCase() + ".js")
];
}, },
// Override getHeader method. // Override getHeader method.
@ -172,7 +166,9 @@ Module.register("weather",{
}, },
addFilters() { addFilters() {
this.nunjucksEnvironment().addFilter("formatTime", function(date) { this.nunjucksEnvironment().addFilter(
"formatTime",
function (date) {
date = moment(date); date = moment(date);
if (this.config.timeFormat !== 24) { if (this.config.timeFormat !== 24) {
@ -188,9 +184,12 @@ Module.register("weather",{
} }
return date.format("HH:mm"); return date.format("HH:mm");
}.bind(this)); }.bind(this)
);
this.nunjucksEnvironment().addFilter("unit", function (value, type) { this.nunjucksEnvironment().addFilter(
"unit",
function (value, type) {
if (type === "temperature") { if (type === "temperature") {
if (this.config.tempUnits === "metric" || this.config.tempUnits === "imperial") { if (this.config.tempUnits === "metric" || this.config.tempUnits === "imperial") {
value += "°"; value += "°";
@ -219,21 +218,33 @@ Module.register("weather",{
} }
return value; return value;
}.bind(this)); }.bind(this)
);
this.nunjucksEnvironment().addFilter("roundValue", function(value) { this.nunjucksEnvironment().addFilter(
"roundValue",
function (value) {
return this.roundValue(value); return this.roundValue(value);
}.bind(this)); }.bind(this)
);
this.nunjucksEnvironment().addFilter("decimalSymbol", function(value) { this.nunjucksEnvironment().addFilter(
"decimalSymbol",
function (value) {
return value.toString().replace(/\./g, this.config.decimalSymbol); return value.toString().replace(/\./g, this.config.decimalSymbol);
}.bind(this)); }.bind(this)
);
this.nunjucksEnvironment().addFilter("calcNumSteps", function(forecast) { this.nunjucksEnvironment().addFilter(
"calcNumSteps",
function (forecast) {
return Math.min(forecast.length, this.config.maxNumberOfDays); return Math.min(forecast.length, this.config.maxNumberOfDays);
}.bind(this)); }.bind(this)
);
this.nunjucksEnvironment().addFilter("opacity", function(currentStep, numSteps) { this.nunjucksEnvironment().addFilter(
"opacity",
function (currentStep, numSteps) {
if (this.config.fade && this.config.fadePoint < 1) { if (this.config.fade && this.config.fadePoint < 1) {
if (this.config.fadePoint < 0) { if (this.config.fadePoint < 0) {
this.config.fadePoint = 0; this.config.fadePoint = 0;
@ -248,6 +259,7 @@ Module.register("weather",{
} else { } else {
return 1; return 1;
} }
}.bind(this)); }.bind(this)
);
} }
}); });

View file

@ -11,7 +11,6 @@
*/ */
class WeatherObject { class WeatherObject {
constructor(units, tempUnits, windUnits) { constructor(units, tempUnits, windUnits) {
this.units = units; this.units = units;
this.tempUnits = tempUnits; this.tempUnits = tempUnits;
this.windUnits = windUnits; this.windUnits = windUnits;
@ -29,7 +28,6 @@ class WeatherObject {
this.snow = null; this.snow = null;
this.precipitation = null; this.precipitation = null;
this.feelsLikeTemp = null; this.feelsLikeTemp = null;
} }
cardinalWindDirection() { cardinalWindDirection() {
@ -69,7 +67,7 @@ class WeatherObject {
} }
beaufortWindSpeed() { beaufortWindSpeed() {
const windInKmh = (this.windUnits === "imperial") ? this.windSpeed * 1.609344 : this.windSpeed * 60 * 60 / 1000; const windInKmh = this.windUnits === "imperial" ? this.windSpeed * 1.609344 : (this.windSpeed * 60 * 60) / 1000;
const speeds = [1, 5, 11, 19, 28, 38, 49, 61, 74, 88, 102, 117, 1000]; const speeds = [1, 5, 11, 19, 28, 38, 49, 61, 74, 88, 102, 117, 1000];
for (const [index, speed] of speeds.entries()) { for (const [index, speed] of speeds.entries()) {
if (speed > windInKmh) { if (speed > windInKmh) {
@ -87,21 +85,25 @@ class WeatherObject {
if (this.feelsLikeTemp) { if (this.feelsLikeTemp) {
return this.feelsLikeTemp; return this.feelsLikeTemp;
} }
const windInMph = (this.windUnits === "imperial") ? this.windSpeed : this.windSpeed * 2.23694; const windInMph = this.windUnits === "imperial" ? this.windSpeed : this.windSpeed * 2.23694;
const tempInF = this.tempUnits === "imperial" ? this.temperature : this.temperature * 9 / 5 + 32; const tempInF = this.tempUnits === "imperial" ? this.temperature : (this.temperature * 9) / 5 + 32;
let feelsLike = tempInF; let feelsLike = tempInF;
if (windInMph > 3 && tempInF < 50) { if (windInMph > 3 && tempInF < 50) {
feelsLike = Math.round(35.74 + 0.6215 * tempInF - 35.75 * Math.pow(windInMph, 0.16) + 0.4275 * tempInF * Math.pow(windInMph, 0.16)); feelsLike = Math.round(35.74 + 0.6215 * tempInF - 35.75 * Math.pow(windInMph, 0.16) + 0.4275 * tempInF * Math.pow(windInMph, 0.16));
} else if (tempInF > 80 && this.humidity > 40) { } else if (tempInF > 80 && this.humidity > 40) {
feelsLike = -42.379 + 2.04901523 * tempInF + 10.14333127 * this.humidity feelsLike =
- 0.22475541 * tempInF * this.humidity - 6.83783 * Math.pow(10, -3) * tempInF * tempInF -42.379 +
- 5.481717 * Math.pow(10, -2) * this.humidity * this.humidity 2.04901523 * tempInF +
+ 1.22874 * Math.pow(10, -3) * tempInF * tempInF * this.humidity 10.14333127 * this.humidity -
+ 8.5282 * Math.pow(10, -4) * tempInF * this.humidity * this.humidity 0.22475541 * tempInF * this.humidity -
- 1.99 * Math.pow(10, -6) * tempInF * tempInF * this.humidity * this.humidity; 6.83783 * Math.pow(10, -3) * tempInF * tempInF -
5.481717 * Math.pow(10, -2) * this.humidity * this.humidity +
1.22874 * Math.pow(10, -3) * tempInF * tempInF * this.humidity +
8.5282 * Math.pow(10, -4) * tempInF * this.humidity * this.humidity -
1.99 * Math.pow(10, -6) * tempInF * tempInF * this.humidity * this.humidity;
} }
return this.tempUnits === "imperial" ? feelsLike : (feelsLike - 32) * 5 / 9; return this.tempUnits === "imperial" ? feelsLike : ((feelsLike - 32) * 5) / 9;
} }
} }

View file

@ -1,4 +1,5 @@
# Module: Weather Forecast # Module: Weather Forecast
The `weatherforecast` module is one of the default modules of the MagicMirror. The `weatherforecast` module is one of the default modules of the MagicMirror.
This module displays the weather forecast for the coming week, including an an icon to display the current conditions, the minimum temperature and the maximum temperature. This module displays the weather forecast for the coming week, including an an icon to display the current conditions, the minimum temperature and the maximum temperature.

View file

@ -5,7 +5,6 @@
* MIT Licensed. * MIT Licensed.
*/ */
Module.register("weatherforecast", { Module.register("weatherforecast", {
// Default module config. // Default module config.
defaults: { defaults: {
location: false, location: false,
@ -56,7 +55,7 @@ Module.register("weatherforecast",{
"11n": "wi-night-thunderstorm", "11n": "wi-night-thunderstorm",
"13n": "wi-night-snow", "13n": "wi-night-snow",
"50n": "wi-night-alt-cloudy-windy" "50n": "wi-night-alt-cloudy-windy"
}, }
}, },
// create a variable for the first upcoming calendar event. Used if no location is specified. // create a variable for the first upcoming calendar event. Used if no location is specified.
@ -95,7 +94,6 @@ Module.register("weatherforecast",{
this.scheduleUpdate(this.config.initialLoadDelay); this.scheduleUpdate(this.config.initialLoadDelay);
this.updateTimer = null; this.updateTimer = null;
}, },
// Override dom generator. // Override dom generator.
@ -194,7 +192,7 @@ Module.register("weatherforecast",{
var steps = this.forecast.length - startingPoint; var steps = this.forecast.length - startingPoint;
if (f >= startingPoint) { if (f >= startingPoint) {
var currentStep = f - startingPoint; var currentStep = f - startingPoint;
row.style.opacity = 1 - (1 / steps * currentStep); row.style.opacity = 1 - (1 / steps) * currentStep;
} }
} }
} }
@ -269,7 +267,7 @@ Module.register("weatherforecast",{
} }
if (retry) { if (retry) {
self.scheduleUpdate((self.loaded) ? -1 : self.config.retryDelay); self.scheduleUpdate(self.loaded ? -1 : self.config.retryDelay);
} }
} }
}; };
@ -312,7 +310,7 @@ Module.register("weatherforecast",{
*/ */
parserDataWeather: function (data) { parserDataWeather: function (data) {
if (data.hasOwnProperty("main")) { if (data.hasOwnProperty("main")) {
data["temp"] = {"min": data.main.temp_min, "max": data.main.temp_max}; data["temp"] = { min: data.main.temp_min, max: data.main.temp_max };
} }
return data; return data;
}, },
@ -330,7 +328,6 @@ Module.register("weatherforecast",{
var forecastData = {}; var forecastData = {};
for (var i = 0, count = data.list.length; i < count; i++) { for (var i = 0, count = data.list.length; i < count; i++) {
var forecast = data.list[i]; var forecast = data.list[i];
this.parserDataWeather(forecast); // hack issue #1017 this.parserDataWeather(forecast); // hack issue #1017
@ -410,7 +407,7 @@ Module.register("weatherforecast",{
* return number - Windspeed in beaufort. * return number - Windspeed in beaufort.
*/ */
ms2Beaufort: function (ms) { ms2Beaufort: function (ms) {
var kmh = ms * 60 * 60 / 1000; var kmh = (ms * 60 * 60) / 1000;
var speeds = [1, 5, 11, 19, 28, 38, 49, 61, 74, 88, 102, 117, 1000]; var speeds = [1, 5, 11, 19, 28, 38, 49, 61, 74, 88, 102, 117, 1000];
for (var beaufort in speeds) { for (var beaufort in speeds) {
var speed = speeds[beaufort]; var speed = speeds[beaufort];
@ -447,9 +444,9 @@ Module.register("weatherforecast",{
} }
//Find all forecasts that is for the same day //Find all forecasts that is for the same day
var checkDateTime = (forecast.dt_txt) ? moment(forecast.dt_txt, "YYYY-MM-DD hh:mm:ss") : moment(forecast.dt, "X"); var checkDateTime = forecast.dt_txt ? moment(forecast.dt_txt, "YYYY-MM-DD hh:mm:ss") : moment(forecast.dt, "X");
var daysForecasts = allForecasts.filter(function (item) { var daysForecasts = allForecasts.filter(function (item) {
var itemDateTime = (item.dt_txt) ? moment(item.dt_txt, "YYYY-MM-DD hh:mm:ss") : moment(item.dt, "X"); var itemDateTime = item.dt_txt ? moment(item.dt_txt, "YYYY-MM-DD hh:mm:ss") : moment(item.dt, "X");
return itemDateTime.isSame(checkDateTime, "day") && item.rain instanceof Object; return itemDateTime.isSame(checkDateTime, "day") && item.rain instanceof Object;
}); });
@ -459,9 +456,11 @@ Module.register("weatherforecast",{
} }
//Summarize all the rain from the matching days //Summarize all the rain from the matching days
return daysForecasts.map(function(item) { return daysForecasts
.map(function (item) {
return Object.values(item.rain)[0]; return Object.values(item.rain)[0];
}).reduce(function(a, b) { })
.reduce(function (a, b) {
return a + b; return a + b;
}, 0); }, 0);
} }

View file

@ -13,13 +13,14 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: []
]
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -13,13 +13,14 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: []
]
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -13,8 +13,8 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -38,4 +38,6 @@ var config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -13,8 +13,8 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -39,4 +39,6 @@ var config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -13,8 +13,8 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -34,4 +34,6 @@ var config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -15,8 +15,8 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -41,4 +41,6 @@ var config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -13,8 +13,8 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -36,4 +36,6 @@ var config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -13,8 +13,8 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -26,4 +26,6 @@ var config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -13,8 +13,8 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -26,4 +26,6 @@ var config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -13,8 +13,8 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -29,4 +29,6 @@ var config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -13,8 +13,8 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -29,4 +29,6 @@ var config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -13,8 +13,8 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -29,4 +29,6 @@ var config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -13,8 +13,8 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -26,4 +26,6 @@ var config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -13,8 +13,8 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -26,4 +26,6 @@ var config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -13,8 +13,8 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -29,4 +29,6 @@ var config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -16,8 +16,8 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -32,4 +32,6 @@ var config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -13,8 +13,8 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -27,7 +27,6 @@ var config = {
afternoon: [], afternoon: [],
evening: [], evening: [],
anytime: ["Anytime here"] anytime: ["Anytime here"]
} }
} }
} }
@ -35,4 +34,6 @@ var config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -14,8 +14,8 @@ let config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -28,9 +28,7 @@ let config = {
morning: [], morning: [],
afternoon: [], afternoon: [],
evening: [], evening: [],
"....-01-01": [ "....-01-01": ["Happy new year!"]
"Happy new year!"
]
} }
} }
} }
@ -38,4 +36,6 @@ let config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -13,8 +13,8 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -24,7 +24,6 @@ var config = {
config: { config: {
compliments: { compliments: {
anytime: ["Anytime here"] anytime: ["Anytime here"]
} }
} }
} }
@ -32,4 +31,6 @@ var config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -13,8 +13,8 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -23,15 +23,9 @@ var config = {
position: "middle_center", position: "middle_center",
config: { config: {
compliments: { compliments: {
morning: [ morning: ["Hi", "Good Morning", "Morning test"],
"Hi", "Good Morning", "Morning test" afternoon: ["Hello", "Good Afternoon", "Afternoon test"],
], evening: ["Hello There", "Good Evening", "Evening test"]
afternoon: [
"Hello", "Good Afternoon", "Afternoon test"
],
evening: [
"Hello There", "Good Evening", "Evening test"
]
} }
} }
} }
@ -39,4 +33,6 @@ var config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -13,8 +13,8 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -29,4 +29,6 @@ var config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -13,8 +13,8 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -26,4 +26,6 @@ var config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -13,13 +13,12 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
{ {
module: "newsfeed", module: "newsfeed",
position: "bottom_bar", position: "bottom_bar",
config: { config: {
@ -27,7 +26,7 @@ var config = {
{ {
title: "Rodrigo Ramirez Blog", title: "Rodrigo Ramirez Blog",
url: "http://localhost:8080/tests/configs/data/feed_test_rodrigoramirez.xml" url: "http://localhost:8080/tests/configs/data/feed_test_rodrigoramirez.xml"
}, }
] ]
} }
} }
@ -35,4 +34,6 @@ var config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -15,16 +15,14 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: modules:
// Using exotic content. This is why dont accept go to JSON configuration file // Using exotic content. This is why dont accept go to JSON configuration file
(function () { (function () {
var positions = ["top_bar", "top_left", "top_center", "top_right", "upper_third", var positions = ["top_bar", "top_left", "top_center", "top_right", "upper_third", "middle_center", "lower_third", "bottom_left", "bottom_center", "bottom_right", "bottom_bar", "fullscreen_above", "fullscreen_below"];
"middle_center", "lower_third", "bottom_left", "bottom_center", "bottom_right",
"bottom_bar", "fullscreen_above", "fullscreen_below"];
var modules = Array(); var modules = Array();
for (var idx in positions) { for (var idx in positions) {
modules.push({ modules.push({
@ -36,7 +34,9 @@ var config = {
}); });
} }
return modules; return modules;
})(), })()
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -14,8 +14,8 @@ let config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -32,4 +32,6 @@ let config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -14,8 +14,8 @@ let config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -37,4 +37,6 @@ let config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -14,8 +14,8 @@ let config = {
units: "imperial", units: "imperial",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -34,4 +34,6 @@ let config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -14,8 +14,8 @@ let config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -34,4 +34,6 @@ let config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -14,8 +14,8 @@ let config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: [
@ -37,4 +37,6 @@ let config = {
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -13,13 +13,14 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: []
]
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -13,13 +13,14 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
}, },
modules: [ modules: []
]
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -13,11 +13,12 @@ var config = {
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true
}, }
} }
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;} if (typeof module !== "undefined") {
module.exports = config;
}

View file

@ -32,7 +32,8 @@ describe("Electron app environment", function() {
}); });
it("should open a browserwindow", function () { it("should open a browserwindow", function () {
return app.client return (
app.client
.waitUntilWindowLoaded() .waitUntilWindowLoaded()
// .browserWindow.focus() // .browserWindow.focus()
.getWindowCount() .getWindowCount()
@ -48,7 +49,8 @@ describe("Electron app environment", function() {
.should.eventually.have.property("height") .should.eventually.have.property("height")
.and.be.above(0) .and.be.above(0)
.browserWindow.getTitle() .browserWindow.getTitle()
.should.eventually.equal("MagicMirror²"); .should.eventually.equal("MagicMirror²")
);
}); });
it("get request from http://localhost:8080 should return 200", function (done) { it("get request from http://localhost:8080 should return 200", function (done) {

View file

@ -13,9 +13,13 @@ describe("ipWhitelist directive configuration", function () {
var app = null; var app = null;
beforeEach(function () { beforeEach(function () {
return helpers.startApplication({ return helpers
.startApplication({
args: ["js/electron.js"] args: ["js/electron.js"]
}).then(function (startedApp) { app = startedApp; }); })
.then(function (startedApp) {
app = startedApp;
});
}); });
afterEach(function () { afterEach(function () {
@ -47,5 +51,4 @@ describe("ipWhitelist directive configuration", function () {
}); });
}); });
}); });
}); });

View file

@ -78,8 +78,7 @@ describe("Clock set to spanish language module", function() {
it("shows week with correct format", function () { it("shows week with correct format", function () {
const weekRegex = /^Semana [0-9]{1,2}$/; const weekRegex = /^Semana [0-9]{1,2}$/;
return app.client.waitUntilWindowLoaded() return app.client.waitUntilWindowLoaded().getText(".clock .week").should.eventually.match(weekRegex);
.getText(".clock .week").should.eventually.match(weekRegex);
}); });
}); });
}); });

View file

@ -35,7 +35,10 @@ describe("Compliments module", function() {
var hour = new Date().getHours(); var hour = new Date().getHours();
if (hour >= 3 && hour < 12) { if (hour >= 3 && hour < 12) {
// if morning check // if morning check
return app.client.waitUntilWindowLoaded().getText(".compliments").then(function(text) { return app.client
.waitUntilWindowLoaded()
.getText(".compliments")
.then(function (text) {
expect(text).to.be.oneOf(["Hi", "Good Morning", "Morning test"]); expect(text).to.be.oneOf(["Hi", "Good Morning", "Morning test"]);
}); });
} }
@ -45,7 +48,10 @@ describe("Compliments module", function() {
var hour = new Date().getHours(); var hour = new Date().getHours();
if (hour >= 12 && hour < 17) { if (hour >= 12 && hour < 17) {
// if morning check // if morning check
return app.client.waitUntilWindowLoaded().getText(".compliments").then(function(text) { return app.client
.waitUntilWindowLoaded()
.getText(".compliments")
.then(function (text) {
expect(text).to.be.oneOf(["Hello", "Good Afternoon", "Afternoon test"]); expect(text).to.be.oneOf(["Hello", "Good Afternoon", "Afternoon test"]);
}); });
} }
@ -55,7 +61,10 @@ describe("Compliments module", function() {
var hour = new Date().getHours(); var hour = new Date().getHours();
if (!(hour >= 3 && hour < 12) && !(hour >= 12 && hour < 17)) { if (!(hour >= 3 && hour < 12) && !(hour >= 12 && hour < 17)) {
// if evening check // if evening check
return app.client.waitUntilWindowLoaded().getText(".compliments").then(function(text) { return app.client
.waitUntilWindowLoaded()
.getText(".compliments")
.then(function (text) {
expect(text).to.be.oneOf(["Hello There", "Good Evening", "Evening test"]); expect(text).to.be.oneOf(["Hello There", "Good Evening", "Evening test"]);
}); });
} }
@ -70,7 +79,10 @@ describe("Compliments module", function() {
}); });
it("Show anytime because if configure empty parts of day compliments and set anytime compliments", function () { it("Show anytime because if configure empty parts of day compliments and set anytime compliments", function () {
return app.client.waitUntilWindowLoaded().getText(".compliments").then(function(text) { return app.client
.waitUntilWindowLoaded()
.getText(".compliments")
.then(function (text) {
expect(text).to.be.oneOf(["Anytime here"]); expect(text).to.be.oneOf(["Anytime here"]);
}); });
}); });
@ -83,7 +95,10 @@ describe("Compliments module", function() {
}); });
it("Show anytime compliments", function () { it("Show anytime compliments", function () {
return app.client.waitUntilWindowLoaded().getText(".compliments").then(function(text) { return app.client
.waitUntilWindowLoaded()
.getText(".compliments")
.then(function (text) {
expect(text).to.be.oneOf(["Anytime here"]); expect(text).to.be.oneOf(["Anytime here"]);
}); });
}); });
@ -98,7 +113,10 @@ describe("Compliments module", function() {
}); });
it("Show happy new year compliment on new years day", function () { it("Show happy new year compliment on new years day", function () {
return app.client.waitUntilWindowLoaded().getText(".compliments").then(function(text) { return app.client
.waitUntilWindowLoaded()
.getText(".compliments")
.then(function (text) {
expect(text).to.be.oneOf(["Happy new year!"]); expect(text).to.be.oneOf(["Happy new year!"]);
}); });
}); });

View file

@ -31,8 +31,7 @@ describe("Test helloworld module", function() {
}); });
it("Test message helloworld module", function () { it("Test message helloworld module", function () {
return app.client.waitUntilWindowLoaded() return app.client.waitUntilWindowLoaded().getText(".helloworld").should.eventually.equal("Test HelloWorld Module");
.getText(".helloworld").should.eventually.equal("Test HelloWorld Module");
}); });
}); });
@ -43,8 +42,7 @@ describe("Test helloworld module", function() {
}); });
it("Test message helloworld module", function () { it("Test message helloworld module", function () {
return app.client.waitUntilWindowLoaded() return app.client.waitUntilWindowLoaded().getText(".helloworld").should.eventually.equal("Hello World!");
.getText(".helloworld").should.eventually.equal("Hello World!");
}); });
}); });
}); });

View file

@ -1,7 +1,10 @@
const _ = require("lodash"); const _ = require("lodash");
function generateWeather(extendedData = {}) { function generateWeather(extendedData = {}) {
return JSON.stringify(_.merge({}, { return JSON.stringify(
_.merge(
{},
{
coord: { coord: {
lon: 11.58, lon: 11.58,
lat: 48.14 lat: 48.14
@ -48,7 +51,10 @@ function generateWeather(extendedData = {}) {
id: 2867714, id: 2867714,
name: "Munich", name: "Munich",
cod: 200 cod: 200
}, extendedData)); },
extendedData
)
);
} }
module.exports = generateWeather; module.exports = generateWeather;

View file

@ -1,97 +1,111 @@
const _ = require("lodash"); const _ = require("lodash");
function generateWeatherForecast(extendedData = {}) { function generateWeatherForecast(extendedData = {}) {
return JSON.stringify(_.merge({}, { return JSON.stringify(
"city": { _.merge(
"id": 2867714, {},
"name": "Munich", {
"coord": {"lon": 11.5754, "lat": 48.1371}, city: {
"country": "DE", id: 2867714,
"population": 1260391, name: "Munich",
"timezone": 7200 coord: { lon: 11.5754, lat: 48.1371 },
country: "DE",
population: 1260391,
timezone: 7200
}, },
"cod": "200", cod: "200",
"message": 0.9653487, message: 0.9653487,
"cnt": 7, cnt: 7,
"list": [{ list: [
"dt": 1568372400, {
"sunrise": 1568350044, dt: 1568372400,
"sunset": 1568395948, sunrise: 1568350044,
"temp": {"day": 24.44, "min": 15.35, "max": 24.44, "night": 15.35, "eve": 18, "morn": 23.03}, sunset: 1568395948,
"pressure": 1031.65, temp: { day: 24.44, min: 15.35, max: 24.44, night: 15.35, eve: 18, morn: 23.03 },
"humidity": 70, pressure: 1031.65,
"weather": [{"id": 801, "main": "Clouds", "description": "few clouds", "icon": "02d"}], humidity: 70,
"speed": 3.35, weather: [{ id: 801, main: "Clouds", description: "few clouds", icon: "02d" }],
"deg": 314, speed: 3.35,
"clouds": 21 deg: 314,
}, { clouds: 21
"dt": 1568458800, },
"sunrise": 1568436525, {
"sunset": 1568482223, dt: 1568458800,
"temp": {"day": 20.81, "min": 13.56, "max": 21.02, "night": 13.56, "eve": 16.6, "morn": 15.88}, sunrise: 1568436525,
"pressure": 1028.81, sunset: 1568482223,
"humidity": 72, temp: { day: 20.81, min: 13.56, max: 21.02, night: 13.56, eve: 16.6, morn: 15.88 },
"weather": [{"id": 500, "main": "Rain", "description": "light rain", "icon": "10d"}], pressure: 1028.81,
"speed": 2.21, humidity: 72,
"deg": 81, weather: [{ id: 500, main: "Rain", description: "light rain", icon: "10d" }],
"clouds": 100 speed: 2.21,
}, { deg: 81,
"dt": 1568545200, clouds: 100
"sunrise": 1568523007, },
"sunset": 1568568497, {
"temp": {"day": 22.65, "min": 13.76, "max": 22.88, "night": 15.27, "eve": 17.45, "morn": 13.76}, dt: 1568545200,
"pressure": 1023.75, sunrise: 1568523007,
"humidity": 64, sunset: 1568568497,
"weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}], temp: { day: 22.65, min: 13.76, max: 22.88, night: 15.27, eve: 17.45, morn: 13.76 },
"speed": 1.15, pressure: 1023.75,
"deg": 7, humidity: 64,
"clouds": 0 weather: [{ id: 800, main: "Clear", description: "sky is clear", icon: "01d" }],
}, { speed: 1.15,
"dt": 1568631600, deg: 7,
"sunrise": 1568609489, clouds: 0
"sunset": 1568654771, },
"temp": {"day": 23.45, "min": 13.95, "max": 23.45, "night": 13.95, "eve": 17.75, "morn": 15.21}, {
"pressure": 1020.41, dt: 1568631600,
"humidity": 64, sunrise: 1568609489,
"weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}], sunset: 1568654771,
"speed": 3.07, temp: { day: 23.45, min: 13.95, max: 23.45, night: 13.95, eve: 17.75, morn: 15.21 },
"deg": 298, pressure: 1020.41,
"clouds": 7 humidity: 64,
}, { weather: [{ id: 800, main: "Clear", description: "sky is clear", icon: "01d" }],
"dt": 1568718000, speed: 3.07,
"sunrise": 1568695970, deg: 298,
"sunset": 1568741045, clouds: 7
"temp": {"day": 20.55, "min": 10.95, "max": 20.55, "night": 10.95, "eve": 14.82, "morn": 13.24}, },
"pressure": 1019.4, {
"humidity": 66, dt: 1568718000,
"weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}], sunrise: 1568695970,
"speed": 2.8, sunset: 1568741045,
"deg": 333, temp: { day: 20.55, min: 10.95, max: 20.55, night: 10.95, eve: 14.82, morn: 13.24 },
"clouds": 2 pressure: 1019.4,
}, { humidity: 66,
"dt": 1568804400, weather: [{ id: 800, main: "Clear", description: "sky is clear", icon: "01d" }],
"sunrise": 1568782452, speed: 2.8,
"sunset": 1568827319, deg: 333,
"temp": {"day": 18.15, "min": 7.75, "max": 18.15, "night": 7.75, "eve": 12.45, "morn": 9.41}, clouds: 2
"pressure": 1017.56, },
"humidity": 52, {
"weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}], dt: 1568804400,
"speed": 2.92, sunrise: 1568782452,
"deg": 34, sunset: 1568827319,
"clouds": 0 temp: { day: 18.15, min: 7.75, max: 18.15, night: 7.75, eve: 12.45, morn: 9.41 },
}, { pressure: 1017.56,
"dt": 1568890800, humidity: 52,
"sunrise": 1568868934, weather: [{ id: 800, main: "Clear", description: "sky is clear", icon: "01d" }],
"sunset": 1568913593, speed: 2.92,
"temp": {"day": 14.85, "min": 5.56, "max": 15.05, "night": 5.56, "eve": 9.56, "morn": 6.25}, deg: 34,
"pressure": 1022.7, clouds: 0
"humidity": 59, },
"weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}], {
"speed": 2.89, dt: 1568890800,
"deg": 51, sunrise: 1568868934,
"clouds": 1 sunset: 1568913593,
}] temp: { day: 14.85, min: 5.56, max: 15.05, night: 5.56, eve: 9.56, morn: 6.25 },
}, extendedData)); pressure: 1022.7,
humidity: 59,
weather: [{ id: 800, main: "Clear", description: "sky is clear", icon: "01d" }],
speed: 2.89,
deg: 51,
clouds: 1
}
]
},
extendedData
)
);
} }
module.exports = generateWeatherForecast; module.exports = generateWeatherForecast;

View file

@ -9,7 +9,6 @@ const helpers = require("../global-setup");
const { generateWeather, generateWeatherForecast } = require("./mocks"); const { generateWeather, generateWeatherForecast } = require("./mocks");
describe("Weather module", function () { describe("Weather module", function () {
let app; let app;
helpers.setupTimeout(this); helpers.setupTimeout(this);
@ -136,13 +135,13 @@ describe("Weather module", function() {
it("should render imperial units", async function () { it("should render imperial units", async function () {
const weather = generateWeather({ const weather = generateWeather({
main: { main: {
temp: 1.49 * 9 / 5 + 32, temp: (1.49 * 9) / 5 + 32,
temp_min: 1 * 9 / 5 + 32, temp_min: (1 * 9) / 5 + 32,
temp_max: 2 * 9 / 5 + 32 temp_max: (2 * 9) / 5 + 32
}, },
wind: { wind: {
speed: 11.8 * 2.23694 speed: 11.8 * 2.23694
}, }
}); });
await setup({ template, data: weather }); await setup({ template, data: weather });
@ -154,13 +153,13 @@ describe("Weather module", function() {
it("should render decimalSymbol = ','", async function () { it("should render decimalSymbol = ','", async function () {
const weather = generateWeather({ const weather = generateWeather({
main: { main: {
temp: 1.49 * 9 / 5 + 32, temp: (1.49 * 9) / 5 + 32,
temp_min: 1 * 9 / 5 + 32, temp_min: (1 * 9) / 5 + 32,
temp_max: 2 * 9 / 5 + 32 temp_max: (2 * 9) / 5 + 32
}, },
wind: { wind: {
speed: 11.8 * 2.23694 speed: 11.8 * 2.23694
}, }
}); });
await setup({ template, data: weather }); await setup({ template, data: weather });

View file

@ -9,7 +9,6 @@ describe("Position of modules", function () {
var app = null; var app = null;
describe("Using helloworld", function () { describe("Using helloworld", function () {
after(function () { after(function () {
return helpers.stopApplication(app); return helpers.stopApplication(app);
}); });
@ -17,14 +16,16 @@ describe("Position of modules", function () {
before(function () { before(function () {
// Set config sample for use in test // Set config sample for use in test
process.env.MM_CONFIG_FILE = "tests/configs/modules/positions.js"; process.env.MM_CONFIG_FILE = "tests/configs/modules/positions.js";
return helpers.startApplication({ return helpers
.startApplication({
args: ["js/electron.js"] args: ["js/electron.js"]
}).then(function (startedApp) { app = startedApp; }); })
.then(function (startedApp) {
app = startedApp;
});
}); });
var positions = ["top_bar", "top_left", "top_center", "top_right", "upper_third", var positions = ["top_bar", "top_left", "top_center", "top_right", "upper_third", "middle_center", "lower_third", "bottom_left", "bottom_center", "bottom_right", "bottom_bar", "fullscreen_above", "fullscreen_below"];
"middle_center", "lower_third", "bottom_left", "bottom_center", "bottom_right",
"bottom_bar", "fullscreen_above", "fullscreen_below"];
var position; var position;
var className; var className;
@ -32,8 +33,10 @@ describe("Position of modules", function () {
position = positions[idx]; position = positions[idx];
className = position.replace("_", "."); className = position.replace("_", ".");
it("show text in " + position, function () { it("show text in " + position, function () {
return app.client.waitUntilWindowLoaded() return app.client
.getText("." + className).should.eventually.equal("Text in " + position); .waitUntilWindowLoaded()
.getText("." + className)
.should.eventually.equal("Text in " + position);
}); });
} }
}); });

View file

@ -13,9 +13,13 @@ describe("port directive configuration", function () {
var app = null; var app = null;
beforeEach(function () { beforeEach(function () {
return helpers.startApplication({ return helpers
.startApplication({
args: ["js/electron.js"] args: ["js/electron.js"]
}).then(function (startedApp) { app = startedApp; }); })
.then(function (startedApp) {
app = startedApp;
});
}); });
afterEach(function () { afterEach(function () {

View file

@ -44,9 +44,11 @@ describe("Translations", function() {
describe("Parsing language files through the Translator class", function () { describe("Parsing language files through the Translator class", function () {
for (let language in translations) { for (let language in translations) {
it(`should parse ${language}`, function (done) { it(`should parse ${language}`, function (done) {
const dom = new JSDOM(`<script>var translations = ${JSON.stringify(translations)}; var Log = {log: function(){}};</script>\ const dom = new JSDOM(
<script src="${path.join(__dirname, "..", "..", "js", "translator.js")}">`, { runScripts: "dangerously", `<script>var translations = ${JSON.stringify(translations)}; var Log = {log: function(){}};</script>\
resources: "usable" }); <script src="${path.join(__dirname, "..", "..", "js", "translator.js")}">`,
{ runScripts: "dangerously", resources: "usable" }
);
dom.window.onload = function () { dom.window.onload = function () {
const { Translator } = dom.window; const { Translator } = dom.window;
@ -64,9 +66,11 @@ describe("Translations", function() {
let base; let base;
before(function (done) { before(function (done) {
const dom = new JSDOM(`<script>var translations = ${JSON.stringify(translations)}; var Log = {log: function(){}};</script>\ const dom = new JSDOM(
<script src="${path.join(__dirname, "..", "..", "js", "translator.js")}">`, { runScripts: "dangerously", `<script>var translations = ${JSON.stringify(translations)}; var Log = {log: function(){}};</script>\
resources: "usable" }); <script src="${path.join(__dirname, "..", "..", "js", "translator.js")}">`,
{ runScripts: "dangerously", resources: "usable" }
);
dom.window.onload = function () { dom.window.onload = function () {
const { Translator } = dom.window; const { Translator } = dom.window;
@ -86,9 +90,11 @@ describe("Translations", function() {
let keys; let keys;
before(function (done) { before(function (done) {
const dom = new JSDOM(`<script>var translations = ${JSON.stringify(translations)}; var Log = {log: function(){}};</script>\ const dom = new JSDOM(
<script src="${path.join(__dirname, "..", "..", "js", "translator.js")}">`, { runScripts: "dangerously", `<script>var translations = ${JSON.stringify(translations)}; var Log = {log: function(){}};</script>\
resources: "usable" }); <script src="${path.join(__dirname, "..", "..", "js", "translator.js")}">`,
{ runScripts: "dangerously", resources: "usable" }
);
dom.window.onload = function () { dom.window.onload = function () {
const { Translator } = dom.window; const { Translator } = dom.window;
@ -114,7 +120,7 @@ describe("Translations", function() {
expect(keys).to.deep.equal(base); expect(keys).to.deep.equal(base);
} catch (e) { } catch (e) {
if (e instanceof chai.AssertionError) { if (e instanceof chai.AssertionError) {
const diff = base.filter(key => !keys.includes(key)); const diff = base.filter((key) => !keys.includes(key));
mlog.pending(`Missing Translations for language ${language}: ${diff}`); mlog.pending(`Missing Translations for language ${language}: ${diff}`);
this.skip(); this.skip();
} else { } else {

View file

@ -8,16 +8,19 @@ const before = global.before;
const after = global.after; const after = global.after;
describe("Vendors", function () { describe("Vendors", function () {
helpers.setupTimeout(this); helpers.setupTimeout(this);
var app = null; var app = null;
before(function () { before(function () {
process.env.MM_CONFIG_FILE = "tests/configs/env.js"; process.env.MM_CONFIG_FILE = "tests/configs/env.js";
return helpers.startApplication({ return helpers
.startApplication({
args: ["js/electron.js"] args: ["js/electron.js"]
}).then(function (startedApp) { app = startedApp; }); })
.then(function (startedApp) {
app = startedApp;
});
}); });
after(function () { after(function () {
@ -25,9 +28,8 @@ describe("Vendors", function () {
}); });
describe("Get list vendors", function () { describe("Get list vendors", function () {
var vendors = require(__dirname + "/../../vendor/vendor.js"); var vendors = require(__dirname + "/../../vendor/vendor.js");
Object.keys(vendors).forEach(vendor => { Object.keys(vendors).forEach((vendor) => {
it(`should return 200 HTTP code for vendor "${vendor}"`, function () { it(`should return 200 HTTP code for vendor "${vendor}"`, function () {
var urlVendor = "http://localhost:8080/vendor/" + vendors[vendor]; var urlVendor = "http://localhost:8080/vendor/" + vendors[vendor];
request.get(urlVendor, function (err, res, body) { request.get(urlVendor, function (err, res, body) {
@ -36,7 +38,7 @@ describe("Vendors", function () {
}); });
}); });
Object.keys(vendors).forEach(vendor => { Object.keys(vendors).forEach((vendor) => {
it(`should return 404 HTTP code for vendor https://localhost/"${vendor}"`, function () { it(`should return 404 HTTP code for vendor https://localhost/"${vendor}"`, function () {
var urlVendor = "http://localhost:8080/" + vendors[vendor]; var urlVendor = "http://localhost:8080/" + vendors[vendor];
request.get(urlVendor, function (err, res, body) { request.get(urlVendor, function (err, res, body) {

View file

@ -11,9 +11,13 @@ describe("Check configuration without modules", function () {
var app = null; var app = null;
beforeEach(function () { beforeEach(function () {
return helpers.startApplication({ return helpers
.startApplication({
args: ["js/electron.js"] args: ["js/electron.js"]
}).then(function (startedApp) { app = startedApp; }); })
.then(function (startedApp) {
app = startedApp;
});
}); });
afterEach(function () { afterEach(function () {
@ -26,13 +30,10 @@ describe("Check configuration without modules", function () {
}); });
it("Show the message MagicMirror title", function () { it("Show the message MagicMirror title", function () {
return app.client.waitUntilWindowLoaded() return app.client.waitUntilWindowLoaded().getText("#module_1_helloworld .module-content").should.eventually.equal("Magic Mirror2");
.getText("#module_1_helloworld .module-content").should.eventually.equal("Magic Mirror2");
}); });
it("Show the text Michael's website", function () { it("Show the text Michael's website", function () {
return app.client.waitUntilWindowLoaded() return app.client.waitUntilWindowLoaded().getText("#module_5_helloworld .module-content").should.eventually.equal("www.michaelteeuw.nl");
.getText("#module_5_helloworld .module-content").should.eventually.equal("www.michaelteeuw.nl");
}); });
}); });

Some files were not shown because too many files have changed in this diff Show more