mirror of
https://github.com/MichMich/MagicMirror.git
synced 2025-07-03 22:36:09 +00:00
commit
5e68a8200d
3
.jscsrc
3
.jscsrc
@ -4,5 +4,6 @@
|
|||||||
"validateQuoteMarks": "\"",
|
"validateQuoteMarks": "\"",
|
||||||
"maximumLineLength": 250,
|
"maximumLineLength": 250,
|
||||||
"requireCurlyBraces": [],
|
"requireCurlyBraces": [],
|
||||||
"requireCamelCaseOrUpperCaseIdentifiers": false
|
"requireCamelCaseOrUpperCaseIdentifiers": false,
|
||||||
|
"excludeFiles": [".jscsrc"],
|
||||||
}
|
}
|
@ -20,6 +20,7 @@ MagicMirror² focuses on a modular plugin system and uses [Electron](http://elec
|
|||||||
- [Configuration](#configuration)
|
- [Configuration](#configuration)
|
||||||
- [Modules](#modules)
|
- [Modules](#modules)
|
||||||
- [Known Issues](#known-issues)
|
- [Known Issues](#known-issues)
|
||||||
|
- [community](#community)
|
||||||
- [Contributing Guidelines](#contributing-guidelines)
|
- [Contributing Guidelines](#contributing-guidelines)
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@ -110,6 +111,10 @@ For more available modules, check out out the wiki page: [MagicMirror² Modules]
|
|||||||
- Electron seems to have some issues on certain Raspberry Pi 2's. See [#145](https://github.com/MichMich/MagicMirror/issues/145).
|
- Electron seems to have some issues on certain Raspberry Pi 2's. See [#145](https://github.com/MichMich/MagicMirror/issues/145).
|
||||||
- MagicMirror² (Electron) sometimes quits without an error after an extended period of use. See [#150](https://github.com/MichMich/MagicMirror/issues/150).
|
- MagicMirror² (Electron) sometimes quits without an error after an extended period of use. See [#150](https://github.com/MichMich/MagicMirror/issues/150).
|
||||||
|
|
||||||
|
## Community
|
||||||
|
|
||||||
|
The community around the MagicMirror² is constantly growing. We even have a [forum](https://forum.magicmirror.builders) now where you can share your ideas, ask questions, help others and get inspired by other builders. We would love to see you there!
|
||||||
|
|
||||||
## Contributing Guidelines
|
## Contributing Guidelines
|
||||||
|
|
||||||
Contributions of all kinds are welcome, not only in the form of code but also with regards bug reports and documentation.
|
Contributions of all kinds are welcome, not only in the form of code but also with regards bug reports and documentation.
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
|
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
|
||||||
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
|
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
|
||||||
<link rel="stylesheet" type="text/css" href="css/main.css">
|
<link rel="stylesheet" type="text/css" href="css/main.css">
|
||||||
<link rel="stylesheet" type="text/css" href="css/custom.css">
|
|
||||||
<link rel="stylesheet" type="text/css" href="fonts/roboto.css">
|
<link rel="stylesheet" type="text/css" href="fonts/roboto.css">
|
||||||
|
<!-- custom.css is loaded by the loader.js to make sure it's loaded after the module css files. -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="region fullscreen below"><div class="container"></div></div>
|
<div class="region fullscreen below"><div class="container"></div></div>
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
echo "Installing helper tools ..."
|
echo "Installing helper tools ..."
|
||||||
sudo apt-get install curl wget build-essential unzip || exit
|
sudo apt-get install curl wget build-essential unzip || exit
|
||||||
ARM=$(uname -m) # Determine which Pi is running.
|
ARM=$(uname -m) # Determine which Pi is running.
|
||||||
NODE_LATEST="v5.11.0" # Set the latest version here.
|
NODE_LATEST="v6.0.0" # Set the latest version here.
|
||||||
DOWNLOAD_URL="https://nodejs.org/dist/latest/node-$NODE_LATEST-linux-$ARM.tar.gz" # Construct the download URL.
|
DOWNLOAD_URL="https://nodejs.org/dist/latest/node-$NODE_LATEST-linux-$ARM.tar.gz" # Construct the download URL.
|
||||||
|
|
||||||
echo "Installing Latest Node.js ..."
|
echo "Installing Latest Node.js ..."
|
||||||
|
@ -38,6 +38,14 @@ var defaults = {
|
|||||||
text: "See README for more information."
|
text: "See README for more information."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
module: "helloworld",
|
||||||
|
position: "middle_center",
|
||||||
|
classes: "xsmall",
|
||||||
|
config: {
|
||||||
|
text: "If you get this message while your config file is already<br>created, your config file probably contains an error.<br>Use a JavaScript linter to validate your file."
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
module: "helloworld",
|
module: "helloworld",
|
||||||
position: "bottom_bar",
|
position: "bottom_bar",
|
||||||
|
@ -34,7 +34,15 @@ var Loader = (function() {
|
|||||||
loadNextModule();
|
loadNextModule();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
// All modules loaded. Load custom.css
|
||||||
|
// This is done after all the moduels so we can
|
||||||
|
// overwrite all the defined styls.
|
||||||
|
|
||||||
|
loadFile('css/custom.css', function() {
|
||||||
|
// custom.css loaded. Start all modules.
|
||||||
startModules();
|
startModules();
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
21
js/logger.js
21
js/logger.js
@ -21,6 +21,27 @@ var Log = (function() {
|
|||||||
},
|
},
|
||||||
error: function(message) {
|
error: function(message) {
|
||||||
console.error(message);
|
console.error(message);
|
||||||
|
},
|
||||||
|
warn: function(message) {
|
||||||
|
console.warn(message);
|
||||||
|
},
|
||||||
|
group: function(message) {
|
||||||
|
console.group(message);
|
||||||
|
},
|
||||||
|
groupCollapsed: function(message) {
|
||||||
|
console.groupCollapsed(message);
|
||||||
|
},
|
||||||
|
groupEnd: function() {
|
||||||
|
console.groupEnd();
|
||||||
|
},
|
||||||
|
time: function(message) {
|
||||||
|
console.time(message);
|
||||||
|
},
|
||||||
|
timeEnd: function(message) {
|
||||||
|
console.timeEnd(message);
|
||||||
|
},
|
||||||
|
timeStamp: function(message) {
|
||||||
|
console.timeStamp(message);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
@ -97,7 +97,7 @@ start: function() {
|
|||||||
####`getScripts()`
|
####`getScripts()`
|
||||||
**Should return: Array**
|
**Should return: Array**
|
||||||
|
|
||||||
The getScripts method is called to request any additional scripts that need to be loaded. This method should therefor return an array with strings. If you want to return a full path to a file in the module folder, use the `this.file('filename.js')` method. In all cases the loader will only load a file once. It even checks if the file is available in the default vendor folder.
|
The getScripts method is called to request any additional scripts that need to be loaded. This method should therefore return an array with strings. If you want to return a full path to a file in the module folder, use the `this.file('filename.js')` method. In all cases the loader will only load a file once. It even checks if the file is available in the default vendor folder.
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
````javascript
|
````javascript
|
||||||
@ -117,7 +117,7 @@ getScripts: function() {
|
|||||||
####`getStyles()`
|
####`getStyles()`
|
||||||
**Should return: Array**
|
**Should return: Array**
|
||||||
|
|
||||||
The getStyles method is called to request any additional scripts that need to be loaded. This method should therefor return an array with strings. If you want to return a full path to a file in the module folder, use the `this.file('filename.css')` method. In all cases the loader will only load a file once. It even checks if the file is available in the default vendor folder.
|
The getStyles method is called to request any additional stylesheets that need to be loaded. This method should therefore return an array with strings. If you want to return a full path to a file in the module folder, use the `this.file('filename.css')` method. In all cases the loader will only load a file once. It even checks if the file is available in the default vendor folder.
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
````javascript
|
````javascript
|
||||||
@ -133,6 +133,22 @@ getStyles: function() {
|
|||||||
````
|
````
|
||||||
**Note:** If a file can not be loaded, the boot up of the mirror will stall. Therefore it's advised not to use any external urls.
|
**Note:** If a file can not be loaded, the boot up of the mirror will stall. Therefore it's advised not to use any external urls.
|
||||||
|
|
||||||
|
####`getTranslations()`
|
||||||
|
**Should return: Dictionary**
|
||||||
|
|
||||||
|
The getTranslations method is called to request translation files that need to be loaded. This method should therefore return a dictionary with the files to load, identified by the country's short name.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
````javascript
|
||||||
|
getTranslations: function() {
|
||||||
|
return {
|
||||||
|
en: "translations/en.json",
|
||||||
|
de: "translations/de.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
````
|
||||||
|
|
||||||
####`getDom()`
|
####`getDom()`
|
||||||
**Should return:** Dom Object
|
**Should return:** Dom Object
|
||||||
|
|
||||||
@ -261,6 +277,25 @@ To show a module, you can call the `show(speed, callback)` method. You can call
|
|||||||
**Note 2:** If the show animation is hijacked (an other method calls show on the same module), the callback will not be called.<br>
|
**Note 2:** If the show animation is hijacked (an other method calls show on the same module), the callback will not be called.<br>
|
||||||
**Note 3:** If the dom is not yet created, the show method won't work. Wait for the `DOM_OBJECTS_CREATED` [notification](#notificationreceivednotification-payload-sender).
|
**Note 3:** If the dom is not yet created, the show method won't work. Wait for the `DOM_OBJECTS_CREATED` [notification](#notificationreceivednotification-payload-sender).
|
||||||
|
|
||||||
|
####`this.translate(identifier)`
|
||||||
|
***identifier* String** - Identifier of the string that should be translated.
|
||||||
|
|
||||||
|
The Magic Mirror contains a convenience wrapper for `l18n`. You can use this to automatically serve different translations for your modules based on the user's `language` configuration.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
````javascript
|
||||||
|
this.translate("INFO") //Will return a translated string for the identifier INFO
|
||||||
|
````
|
||||||
|
|
||||||
|
**Example json file:**
|
||||||
|
````javascript
|
||||||
|
{
|
||||||
|
"INFO": "Really important information!"
|
||||||
|
}
|
||||||
|
````
|
||||||
|
|
||||||
|
**Note:** Currently there is no fallback if a translation identifier does not exist in one language. Right now you always have to add all identifier to all your translations even if they are not translated yet (see [#191](https://github.com/MichMich/MagicMirror/issues/191)).
|
||||||
|
|
||||||
|
|
||||||
## The Node Helper: node_helper.js
|
## The Node Helper: node_helper.js
|
||||||
|
|
||||||
@ -458,4 +493,4 @@ The Magic Mirror contains a convenience wrapper for logging. Currently, this log
|
|||||||
Log.info('error');
|
Log.info('error');
|
||||||
Log.log('log');
|
Log.log('log');
|
||||||
Log.error('info');
|
Log.error('info');
|
||||||
```
|
````
|
||||||
|
@ -18,7 +18,7 @@ Module.register("alert",{
|
|||||||
//Position
|
//Position
|
||||||
position: "center",
|
position: "center",
|
||||||
//shown at startup
|
//shown at startup
|
||||||
welcome_message: true,
|
welcome_message: false,
|
||||||
},
|
},
|
||||||
getScripts: function() {
|
getScripts: function() {
|
||||||
return ["classie.js", "modernizr.custom.js", "notificationFx.js"];
|
return ["classie.js", "modernizr.custom.js", "notificationFx.js"];
|
||||||
|
@ -144,7 +144,10 @@
|
|||||||
if (ev.target !== self.ntf) return false;
|
if (ev.target !== self.ntf) return false;
|
||||||
this.removeEventListener(animEndEventName, onEndAnimationFn);
|
this.removeEventListener(animEndEventName, onEndAnimationFn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.parentNode === self.options.wrapper) {
|
||||||
self.options.wrapper.removeChild(this);
|
self.options.wrapper.removeChild(this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (support.animations) {
|
if (support.animations) {
|
||||||
|
@ -112,6 +112,14 @@ The following properties can be configured:
|
|||||||
</code>
|
</code>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>displayRepeatingCountTitle</code></td>
|
||||||
|
<td>Show count title for yearly repeating events (e.g. "X. Birthday", "X. Anniversary")<br>
|
||||||
|
|
||||||
|
<br><b>Possible values:</b> <code>true</code> or <code>false</code>
|
||||||
|
<br><b>Default value:</b> <code>false</code>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
@ -154,5 +162,12 @@ config: {
|
|||||||
<br><b>Possible values:</b> See <a href="http://fontawesome.io/icons/" target="_blank">Font Awsome</a> website.
|
<br><b>Possible values:</b> See <a href="http://fontawesome.io/icons/" target="_blank">Font Awsome</a> website.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code> repeatingCountTitle </code></td>
|
||||||
|
<td>The count title for yearly repating events in this calendar. <br>
|
||||||
|
<br><b>Example:</b> <br>
|
||||||
|
<code>'Birthday'</code>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -15,6 +15,8 @@ Module.register("calendar",{
|
|||||||
maximumNumberOfDays: 365,
|
maximumNumberOfDays: 365,
|
||||||
displaySymbol: true,
|
displaySymbol: true,
|
||||||
defaultSymbol: "calendar", // Fontawsome Symbol see http://fontawesome.io/cheatsheet/
|
defaultSymbol: "calendar", // Fontawsome Symbol see http://fontawesome.io/cheatsheet/
|
||||||
|
displayRepeatingCountTitle: false,
|
||||||
|
defaultRepeatingCountTitle: '',
|
||||||
maxTitleLength: 25,
|
maxTitleLength: 25,
|
||||||
fetchInterval: 5 * 60 * 1000, // Update every 5 minutes.
|
fetchInterval: 5 * 60 * 1000, // Update every 5 minutes.
|
||||||
animationSpeed: 2000,
|
animationSpeed: 2000,
|
||||||
@ -46,7 +48,8 @@ Module.register("calendar",{
|
|||||||
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",
|
||||||
|
fr: "translations/fr.json"
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -113,8 +116,23 @@ Module.register("calendar",{
|
|||||||
eventWrapper.appendChild(symbolWrapper);
|
eventWrapper.appendChild(symbolWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
var titleWrapper = document.createElement("td");
|
var titleWrapper = document.createElement("td"),
|
||||||
titleWrapper.innerHTML = this.titleTransform(event.title);
|
repeatingCountTitle = '';
|
||||||
|
|
||||||
|
|
||||||
|
if (this.config.displayRepeatingCountTitle) {
|
||||||
|
|
||||||
|
repeatingCountTitle = this.countTitleForUrl(event.url);
|
||||||
|
|
||||||
|
if(repeatingCountTitle !== '') {
|
||||||
|
var thisYear = new Date().getFullYear(),
|
||||||
|
yearDiff = thisYear - event.firstYear;
|
||||||
|
|
||||||
|
repeatingCountTitle = ', '+ yearDiff + '. ' + repeatingCountTitle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
titleWrapper.innerHTML = this.titleTransform(event.title) + repeatingCountTitle;
|
||||||
titleWrapper.className = "title bright";
|
titleWrapper.className = "title bright";
|
||||||
eventWrapper.appendChild(titleWrapper);
|
eventWrapper.appendChild(titleWrapper);
|
||||||
|
|
||||||
@ -239,6 +257,23 @@ Module.register("calendar",{
|
|||||||
|
|
||||||
return this.config.defaultSymbol;
|
return this.config.defaultSymbol;
|
||||||
},
|
},
|
||||||
|
/* countTitleForUrl(url)
|
||||||
|
* Retrieves the name for a specific url.
|
||||||
|
*
|
||||||
|
* argument url sting - Url to look for.
|
||||||
|
*
|
||||||
|
* return string - The Symbol
|
||||||
|
*/
|
||||||
|
countTitleForUrl: function(url) {
|
||||||
|
for (var c in this.config.calendars) {
|
||||||
|
var calendar = this.config.calendars[c];
|
||||||
|
if (calendar.url === url && typeof calendar.repeatingCountTitle === "string") {
|
||||||
|
return calendar.repeatingCountTitle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.config.defaultRepeatingCountTitle;
|
||||||
|
},
|
||||||
|
|
||||||
/* shorten(string, maxLength)
|
/* shorten(string, maxLength)
|
||||||
* Shortens a sting if it's longer than maxLenthg.
|
* Shortens a sting if it's longer than maxLenthg.
|
||||||
|
@ -55,14 +55,16 @@ var CalendarFetcher = function(url, reloadInterval, maximumEntries, maximumNumbe
|
|||||||
|
|
||||||
if (event.type === "VEVENT") {
|
if (event.type === "VEVENT") {
|
||||||
|
|
||||||
//console.log(event);
|
|
||||||
|
|
||||||
var startDate = (event.start.length === 8) ? moment(event.start, "YYYYMMDD") : moment(new Date(event.start));
|
var startDate = (event.start.length === 8) ? moment(event.start, "YYYYMMDD") : moment(new Date(event.start));
|
||||||
var endDate;
|
var endDate;
|
||||||
if (typeof event.end !== "undefined") {
|
if (typeof event.end !== "undefined") {
|
||||||
endDate = (event.end.length === 8) ? moment(event.end, "YYYYMMDD") : moment(new Date(event.end));
|
endDate = (event.end.length === 8) ? moment(event.end, "YYYYMMDD") : moment(new Date(event.end));
|
||||||
} else {
|
} else {
|
||||||
|
if (!isFacebookBirthday) {
|
||||||
endDate = startDate;
|
endDate = startDate;
|
||||||
|
} else {
|
||||||
|
endDate = moment(startDate).add(1, 'days');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate the duration f the event for use with recurring events.
|
// calculate the duration f the event for use with recurring events.
|
||||||
@ -84,14 +86,15 @@ var CalendarFetcher = function(url, reloadInterval, maximumEntries, maximumNumbe
|
|||||||
title: (typeof event.summary.val !== "undefined") ? event.summary.val : event.summary,
|
title: (typeof event.summary.val !== "undefined") ? event.summary.val : event.summary,
|
||||||
startDate: startDate.format("x"),
|
startDate: startDate.format("x"),
|
||||||
endDate: endDate.format("x"),
|
endDate: endDate.format("x"),
|
||||||
fullDayEvent: isFullDayEvent(event)
|
fullDayEvent: isFullDayEvent(event),
|
||||||
|
firstYear: event.start.getFullYear()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// console.log("Single event ...");
|
// console.log("Single event ...");
|
||||||
// Single event.
|
// Single event.
|
||||||
var fullDayEvent = isFullDayEvent(event);
|
var fullDayEvent = (isFacebookBirthday) ? true : isFullDayEvent(event);
|
||||||
var title = (typeof event.summary.val !== "undefined") ? event.summary.val : event.summary;
|
var title = (typeof event.summary.val !== "undefined") ? event.summary.val : event.summary;
|
||||||
|
|
||||||
if (!fullDayEvent && endDate < new Date()) {
|
if (!fullDayEvent && endDate < new Date()) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"TODAY": "Heute"
|
"TODAY": "Heute"
|
||||||
, "TOMORROW": "Morgen"
|
, "TOMORROW": "Morgen"
|
||||||
, "RUNNING": "Noch"
|
, "RUNNING": "noch"
|
||||||
, "LOADING": "Lade Termine …"
|
, "LOADING": "Lade Termine …"
|
||||||
, "EMPTY": "Keine Termine."
|
, "EMPTY": "Keine Termine."
|
||||||
}
|
}
|
||||||
|
7
modules/default/calendar/translations/fr.json
Normal file
7
modules/default/calendar/translations/fr.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"TODAY": "Aujourd'hui"
|
||||||
|
, "TOMORROW": "Demain"
|
||||||
|
, "RUNNING": "Se termine dans"
|
||||||
|
, "LOADING": "Chargement des RDV …"
|
||||||
|
, "EMPTY": "Aucun RDV."
|
||||||
|
}
|
@ -32,7 +32,7 @@ ical.objectHandlers['END'] = function(val, params, curr, stack){
|
|||||||
if (curr.start.length === 8) {
|
if (curr.start.length === 8) {
|
||||||
var comps = /^(\d{4})(\d{2})(\d{2})$/.exec(curr.start);
|
var comps = /^(\d{4})(\d{2})(\d{2})$/.exec(curr.start);
|
||||||
if (comps) {
|
if (comps) {
|
||||||
curr.start = new Date (comps[1], comps[2], comps[3]);
|
curr.start = new Date (comps[1], comps[2] - 1, comps[3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,14 +47,21 @@ The following properties can be configured:
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><code>showPeriod</code></td>
|
<td><code>showPeriod</code></td>
|
||||||
<td>Show the period (am/pm) with 12 hour format<br>
|
<td>Show the period (am/pm) with 12 hour format.<br>
|
||||||
<br><b>Possible values:</b> <code>true</code> or <code>false</code>
|
<br><b>Possible values:</b> <code>true</code> or <code>false</code>
|
||||||
<br><b>Default value:</b> <code>true</code>
|
<br><b>Default value:</b> <code>true</code>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><code>showPeriodUpper</code></td>
|
<td><code>showPeriodUpper</code></td>
|
||||||
<td>Show the period (AM/PM) with 12 hour format as uppercase<br>
|
<td>Show the period (AM/PM) with 12 hour format as uppercase.<br>
|
||||||
|
<br><b>Possible values:</b> <code>true</code> or <code>false</code>
|
||||||
|
<br><b>Default value:</b> <code>false</code>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>clockBold</code></td>
|
||||||
|
<td>Remove the colon and bold the minutes to make a more modern look.<br>
|
||||||
<br><b>Possible values:</b> <code>true</code> or <code>false</code>
|
<br><b>Possible values:</b> <code>true</code> or <code>false</code>
|
||||||
<br><b>Default value:</b> <code>false</code>
|
<br><b>Default value:</b> <code>false</code>
|
||||||
</td>
|
</td>
|
||||||
|
@ -1,41 +1,34 @@
|
|||||||
/* global Log, Module, moment, config */
|
/* global Log, Module, moment, config */
|
||||||
|
|
||||||
/* Magic Mirror
|
/* Magic Mirror
|
||||||
* Module: Clock
|
* Module: Clock
|
||||||
*
|
*
|
||||||
* By Michael Teeuw http://michaelteeuw.nl
|
* By Michael Teeuw http://michaelteeuw.nl
|
||||||
* MIT Licensed.
|
* MIT Licensed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Module.register("clock",{
|
Module.register("clock",{
|
||||||
|
|
||||||
// Module config defaults.
|
// Module config defaults.
|
||||||
defaults: {
|
defaults: {
|
||||||
timeFormat: config.timeFormat,
|
timeFormat: config.timeFormat,
|
||||||
displaySeconds: true,
|
displaySeconds: true,
|
||||||
showPeriod: true,
|
showPeriod: true,
|
||||||
showPeriodUpper: false,
|
showPeriodUpper: false,
|
||||||
|
clockBold: false
|
||||||
},
|
},
|
||||||
|
|
||||||
// Define required scripts.
|
// Define required scripts.
|
||||||
getScripts: function() {
|
getScripts: function() {
|
||||||
return ["moment.js"];
|
return ["moment.js"];
|
||||||
},
|
},
|
||||||
|
|
||||||
// Define start sequence.
|
// Define start sequence.
|
||||||
start: function() {
|
start: function() {
|
||||||
Log.info("Starting module: " + this.name);
|
Log.info("Starting module: " + this.name);
|
||||||
|
|
||||||
// Schedule update interval.
|
// Schedule update interval.
|
||||||
var self = this;
|
var self = this;
|
||||||
setInterval(function() {
|
setInterval(function() {
|
||||||
self.updateDom();
|
self.updateDom();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
// Set locale.
|
// Set locale.
|
||||||
moment.locale(config.language);
|
moment.locale(config.language);
|
||||||
},
|
},
|
||||||
|
|
||||||
// Override dom generator.
|
// Override dom generator.
|
||||||
getDom: function() {
|
getDom: function() {
|
||||||
// Create wrappers.
|
// Create wrappers.
|
||||||
@ -44,35 +37,36 @@ Module.register("clock",{
|
|||||||
var timeWrapper = document.createElement("div");
|
var timeWrapper = document.createElement("div");
|
||||||
var secondsWrapper = document.createElement("sup");
|
var secondsWrapper = document.createElement("sup");
|
||||||
var periodWrapper = document.createElement("span");
|
var periodWrapper = document.createElement("span");
|
||||||
|
|
||||||
// Style Wrappers
|
// Style Wrappers
|
||||||
dateWrapper.className = "date normal medium";
|
dateWrapper.className = "date normal medium";
|
||||||
timeWrapper.className = "time bright large light";
|
timeWrapper.className = "time bright large light";
|
||||||
secondsWrapper.className = "dimmed";
|
secondsWrapper.className = "dimmed";
|
||||||
|
|
||||||
// Set content of wrappers.
|
// Set content of wrappers.
|
||||||
// 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 timeString = moment().format('HH:mm');
|
if (this.config.clockBold === true) {
|
||||||
|
var timeString = moment().format("HH[<span class=\"bold\">]mm[</span>]");
|
||||||
|
} else {
|
||||||
|
var timeString = moment().format("HH:mm");
|
||||||
|
}
|
||||||
if (this.config.timeFormat !== 24) {
|
if (this.config.timeFormat !== 24) {
|
||||||
var now = new Date();
|
var now = new Date();
|
||||||
var hours = now.getHours() % 12 || 12;
|
var hours = now.getHours() % 12 || 12;
|
||||||
timeString = hours + moment().format(':mm');
|
if (this.config.clockBold === true) {
|
||||||
|
timeString = hours + moment().format("[<span class=\"bold\">]mm[</span>]");
|
||||||
|
} else {
|
||||||
|
timeString = hours + moment().format(":mm");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dateWrapper.innerHTML = moment().format("dddd, LL");
|
dateWrapper.innerHTML = moment().format("dddd, LL");
|
||||||
timeWrapper.innerHTML = timeString;
|
timeWrapper.innerHTML = timeString;
|
||||||
secondsWrapper.innerHTML = moment().format("ss");
|
secondsWrapper.innerHTML = moment().format("ss");
|
||||||
|
|
||||||
|
|
||||||
if (this.config.showPeriodUpper) {
|
if (this.config.showPeriodUpper) {
|
||||||
periodWrapper.innerHTML = moment().format('A');
|
periodWrapper.innerHTML = moment().format("A");
|
||||||
} else {
|
} else {
|
||||||
periodWrapper.innerHTML = moment().format('a');
|
periodWrapper.innerHTML = moment().format("a");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Combine wrappers.
|
// Combine wrappers.
|
||||||
wrapper.appendChild(dateWrapper);
|
wrapper.appendChild(dateWrapper);
|
||||||
wrapper.appendChild(timeWrapper);
|
wrapper.appendChild(timeWrapper);
|
||||||
@ -82,7 +76,6 @@ Module.register("clock",{
|
|||||||
if (this.config.showPeriod && this.config.timeFormat !== 24) {
|
if (this.config.showPeriod && this.config.timeFormat !== 24) {
|
||||||
timeWrapper.appendChild(periodWrapper);
|
timeWrapper.appendChild(periodWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the wrapper to the dom.
|
// Return the wrapper to the dom.
|
||||||
return wrapper;
|
return wrapper;
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,14 @@ The following properties can be configured:
|
|||||||
<br><b>Default value:</b> <code>config.units</code>
|
<br><b>Default value:</b> <code>config.units</code>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>maxNumberOfDays</code></td>
|
||||||
|
<td>How many days of forecast to return. Specified by config.js<br>
|
||||||
|
<br><b>Possible values:</b> <code>1</code> - <code>16</code>
|
||||||
|
<br><b>Default value:</b> <code>7</code> (7 days)
|
||||||
|
<br>This value is optional. By default the weatherforecast module will return 7 days.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><code>updateInterval</code></td>
|
<td><code>updateInterval</code></td>
|
||||||
<td>How often does the content needs to be fetched? (Milliseconds)<br>
|
<td>How often does the content needs to be fetched? (Milliseconds)<br>
|
||||||
|
@ -14,6 +14,7 @@ Module.register("weatherforecast",{
|
|||||||
location: "",
|
location: "",
|
||||||
appid: "",
|
appid: "",
|
||||||
units: config.units,
|
units: config.units,
|
||||||
|
maxNumberOfDays: 7,
|
||||||
updateInterval: 10 * 60 * 1000, // every 10 minutes
|
updateInterval: 10 * 60 * 1000, // every 10 minutes
|
||||||
animationSpeed: 1000,
|
animationSpeed: 1000,
|
||||||
timeFormat: config.timeFormat,
|
timeFormat: config.timeFormat,
|
||||||
@ -189,6 +190,12 @@ Module.register("weatherforecast",{
|
|||||||
params += "q=" + this.config.location;
|
params += "q=" + this.config.location;
|
||||||
params += "&units=" + this.config.units;
|
params += "&units=" + this.config.units;
|
||||||
params += "&lang=" + this.config.lang;
|
params += "&lang=" + this.config.lang;
|
||||||
|
/*
|
||||||
|
* Submit a specific number of days to forecast, between 1 to 16 days.
|
||||||
|
* The OpenWeatherMap API properly handles values outside of the 1 - 16 range and returns 7 days by default.
|
||||||
|
* This is simply being pedantic and doing it ourselves.
|
||||||
|
*/
|
||||||
|
params += "&cnt=" + (((this.config.maxNumberOfDays < 1) || (this.config.maxNumberOfDays > 16)) ? 7 : this.config.maxNumberOfDays);
|
||||||
params += "&APPID=" + this.config.appid;
|
params += "&APPID=" + this.config.appid;
|
||||||
|
|
||||||
return params;
|
return params;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user