Skip to content

Commit de57daa

Browse files
authored
Merge pull request #1498 from MichMich/develop
Release 2.6.0.
2 parents 6db61b4 + e70e011 commit de57daa

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+2836
-1602
lines changed

CHANGELOG.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,46 @@ All notable changes to this project will be documented in this file.
44
This project adheres to [Semantic Versioning](http://semver.org/).
55

66
---
7+
8+
## [2.6.0] - 2019-01-01
9+
10+
ℹ️ **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.
11+
12+
### ✨ Experimental ✨
13+
- 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).
14+
15+
### Added
16+
- Possibility to add classes to the cell of symbol, title and time of the events of calendar.
17+
- Font-awesome 5, still has 4 for backwards compatibility.
18+
- Missing `showEnd` in calendar documentation
19+
- Screenshot for the new feed module
20+
- Screenshot for the compliments module
21+
- Screenshot for the clock module
22+
- Screenshot for the current weather
23+
- Screenshot for the weather forecast module
24+
- Portuguese translation for "Feels"
25+
- Croatian translation
26+
- Fading for dateheaders timeFormat in Calendar [#1464](https://github.com/MichMich/MagicMirror/issues/1464)
27+
- Documentation for the existing `scale` option in the Weather Forecast module.
28+
29+
### Fixed
30+
- Allow to parse recurring calendar events where the start date is before 1900
31+
- Fixed Polish translation for Single Update Info
32+
- Ignore entries with unparseable details in the calendar module
33+
- Bug showing FullDayEvents one day too long in calendar fixed
34+
- Bug in newsfeed when `removeStartTags` is used on the description [#1478](https://github.com/MichMich/MagicMirror/issues/1478)
35+
36+
### Updated
37+
- The default calendar setting `showEnd` is changed to `false`.
38+
39+
### Changed
40+
- The Weather Forecast module by default displays the ° symbol after every numeric value to be consistent with the Current Weather module.
41+
42+
743
## [2.5.0] - 2018-10-01
844

945
### Added
46+
- Romanian translation for "Feels"
1047
- Support multi-line compliments
1148
- Simplified Chinese translation for "Feels"
1249
- Polish translate for "Feels"

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ MagicMirror² focuses on a modular plugin system and uses [Electron](http://elec
3838

3939
*Electron*, the app wrapper around MagicMirror², only supports the Raspberry Pi 2/3. The Raspberry Pi 0/1 is currently **not** supported. If you want to run this on a Raspberry Pi 1, use the [server only](#server-only) feature and setup a fullscreen browser yourself. (Yes, people have managed to run MM² also on a Pi0, so if you insist, search in the forums.)
4040

41-
Note that you will need to install the lastest full version of Raspbian, **don't use the Lite version**.
41+
Note that you will need to install the latest full version of Raspbian, **don't use the Lite version**.
4242

4343
Execute the following command on your Raspberry Pi to install MagicMirror²:
4444

@@ -140,7 +140,7 @@ The following properties can be configured:
140140
| `timeFormat` | The form of time notation that will be used. Possible values are `12` or `24`. The default is `24`. |
141141
| `units` | The units that will be used in the default weather modules. Possible values are `metric` or `imperial`. The default is `metric`. |
142142
| `modules` | An array of active modules. **The array must contain objects. See the next table below for more information.** |
143-
| `electronOptions` | An optional array of Electron (browser) options. This allows configuration of e.g. the browser screen size and position (example: `electronOptions: { fullscreen: false, width: 800, height: 600 }`). Kiosk mode can be enabled by setting `kiosk = true`, `autoHideMenuBar = false` and `fullscreen = false`. More options can be found [here](https://github.com/electron/electron/blob/master/docs/api/browser-window.md). |
143+
| `electronOptions` | An optional array of Electron (browser) options. This allows configuration of e.g. the browser screen size and position (example: `electronOptions: { fullscreen: false, width: 800, height: 600 }`). Kiosk mode can be enabled by setting `kiosk: true`, `autoHideMenuBar: false` and `fullscreen: false`. More options can be found [here](https://github.com/electron/electron/blob/master/docs/api/browser-window.md). |
144144
| `customCss` | The path of the `custom.css` stylesheet. The default is `css/custom.css`. |
145145

146146
Module configuration:

config/config.js.sample

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ var config = {
4444
config: {
4545
calendars: [
4646
{
47-
symbol: "calendar-check-o ",
47+
symbol: "calendar-check",
4848
url: "webcal://www.calendarlabs.com/templates/ical/US-Holidays.ics"
4949
}
5050
]
@@ -69,7 +69,7 @@ var config = {
6969
header: "Weather Forecast",
7070
config: {
7171
location: "New York",
72-
locationID: "5128581", //ID from http://www.openweathermap.org/help/city_list.txt
72+
locationID: "5128581", //ID from https://openweathermap.org/city
7373
appid: "YOUR_OPENWEATHER_API_KEY"
7474
}
7575
},

modules/default/calendar/README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# Module: Calendar
22
The `calendar` module is one of the default modules of the MagicMirror.
33
This module displays events from a public .ical calendar. It can combine multiple calendars.
4-
Note that calendars may not contain any entry before 1st January 1970, otherwise the calendar won't be displayed and the module will crash.
54

65
## Using the module
76

@@ -42,8 +41,11 @@ The following properties can be configured:
4241
| `titleReplace` | An object of textual replacements applied to the tile of the event. This allow to remove or replace certains words in the title. <br><br> **Example:** `{'Birthday of ' : '', 'foo':'bar'}` <br> **Default value:** `{ "De verjaardag van ": "", "'s birthday": "" }`
4342
| `displayRepeatingCountTitle` | Show count title for yearly repeating events (e.g. "X. Birthday", "X. Anniversary") <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
4443
| `dateFormat` | Format to use for the date of events (when using absolute dates) <br><br> **Possible values:** See [Moment.js formats](http://momentjs.com/docs/#/parsing/string-format/) <br> **Default value:** `MMM Do` (e.g. Jan 18th)
44+
| `dateEndFormat` | Format to use for the end time of events <br><br> **Possible values:** See [Moment.js formats](http://momentjs.com/docs/#/parsing/string-format/) <br> **Default value:** `HH:mm` (e.g. 16:30)
45+
| `showEnd` | Show end time of events <br><br> **Possible values:** `true` or `false` <br> **Default value:** `true`
4546
| `fullDayEventDateFormat` | Format to use for the date of full day events (when using absolute dates) <br><br> **Possible values:** See [Moment.js formats](http://momentjs.com/docs/#/parsing/string-format/) <br> **Default value:** `MMM Do` (e.g. Jan 18th)
4647
| `timeFormat` | Display event times as absolute dates, or relative time, or using absolute date headers with times for each event next to it <br><br> **Possible values:** `absolute` or `relative` or `dateheaders` <br> **Default value:** `relative`
48+
| `showEnd` | Display the end of a date as well <br><br> **Possible values:** `true` or `false` <br> **Default value:** `true`
4749
| `getRelative` | How much time (in hours) should be left until calendar events start getting relative? <br><br> **Possible values:** `0` (events stay absolute) - `48` (48 hours before the event starts) <br> **Default value:** `6`
4850
| `urgency` | When using a timeFormat of `absolute`, the `urgency` setting allows you to display events within a specific time frame as `relative`. This allows events within a certain time frame to be displayed as relative (in xx days) while others are displayed as absolute dates <br><br> **Possible values:** a positive integer representing the number of days for which you want a relative date, for example `7` (for 7 days) <br><br> **Default value:** `7`
4951
| `broadcastEvents` | If this property is set to true, the calendar will broadcast all the events to all other modules with the notification message: `CALENDAR_EVENTS`. The event objects are stored in an array and contain the following fields: `title`, `startDate`, `endDate`, `fullDayEvent`, `location` and `geo`. <br><br> **Possible values:** `true`, `false` <br><br> **Default value:** `true`
@@ -86,6 +88,9 @@ config: {
8688
| `maximumEntries` | The maximum number of events shown. Overrides global setting. **Possible values:** `0` - `100`
8789
| `maximumNumberOfDays` | The maximum number of days in the future. Overrides global setting
8890
| `auth` | The object containing options for authentication against the calendar.
91+
| `symbolClass` | Add a class to the cell of symbol.
92+
| `titleClass` | Add a class to the title's cell.
93+
| `timeClass` | Add a class to the time's cell.
8994

9095

9196
#### Calendar authentication options:

modules/default/calendar/calendar.js

Lines changed: 85 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Module.register("calendar", {
2727
dateFormat: "MMM Do",
2828
dateEndFormat: "HH:mm",
2929
fullDayEventDateFormat: "MMM Do",
30-
showEnd: true,
30+
showEnd: false,
3131
getRelative: 6,
3232
fadePoint: 0.25, // Start on 1/4th of the list.
3333
hidePrivate: false,
@@ -51,7 +51,7 @@ Module.register("calendar", {
5151

5252
// Define required scripts.
5353
getStyles: function () {
54-
return ["calendar.css", "font-awesome.css"];
54+
return ["calendar.css", "font-awesome5.css", "font-awesome5.v4shims.css"];
5555
},
5656

5757
// Define required scripts.
@@ -82,6 +82,15 @@ Module.register("calendar", {
8282
maximumEntries: calendar.maximumEntries,
8383
maximumNumberOfDays: calendar.maximumNumberOfDays
8484
};
85+
if (calendar.symbolClass === "undefined" || calendar.symbolClass === null) {
86+
calendarConfig.symbolClass = "";
87+
}
88+
if (calendar.titleClass === "undefined" || calendar.titleClass === null) {
89+
calendarConfig.titleClass = "";
90+
}
91+
if (calendar.timeClass === "undefined" || calendar.timeClass === null) {
92+
calendarConfig.timeClass = "";
93+
}
8594

8695
// we check user and password here for backwards compatibility with old configs
8796
if(calendar.user && calendar.pass) {
@@ -135,6 +144,15 @@ Module.register("calendar", {
135144
return wrapper;
136145
}
137146

147+
if (this.config.fade && this.config.fadePoint < 1) {
148+
if (this.config.fadePoint < 0) {
149+
this.config.fadePoint = 0;
150+
}
151+
var startFade = events.length * this.config.fadePoint;
152+
var fadeSteps = events.length - startFade;
153+
}
154+
155+
var currentFadeStep = 0;
138156
var lastSeenDate = "";
139157

140158
for (var e in events) {
@@ -143,14 +161,18 @@ Module.register("calendar", {
143161
if(this.config.timeFormat === "dateheaders"){
144162
if(lastSeenDate !== dateAsString){
145163
var dateRow = document.createElement("tr");
146-
dateRow.className = "normal"
164+
dateRow.className = "normal";
147165
var dateCell = document.createElement("td");
148166

149167
dateCell.colSpan = "3";
150168
dateCell.innerHTML = dateAsString;
151169
dateRow.appendChild(dateCell);
152170
wrapper.appendChild(dateRow);
153171

172+
if (e >= startFade) { //fading
173+
currentFadeStep = e - startFade;
174+
dateRow.style.opacity = 1 - (1 / fadeSteps * currentFadeStep);
175+
}
154176

155177
lastSeenDate = dateAsString;
156178
}
@@ -172,7 +194,9 @@ Module.register("calendar", {
172194
symbolWrapper.style.cssText = "color:" + this.colorForUrl(event.url);
173195
}
174196

175-
symbolWrapper.className = "symbol align-right";
197+
var symbolClass = this.symbolClassForUrl(event.url);
198+
symbolWrapper.className = "symbol align-right " + symbolClass;
199+
176200
var symbols = this.symbolsForUrl(event.url);
177201
if(typeof symbols === "string") {
178202
symbols = [symbols];
@@ -189,7 +213,7 @@ Module.register("calendar", {
189213
eventWrapper.appendChild(symbolWrapper);
190214
}else if(this.config.timeFormat === "dateheaders"){
191215
var blankCell = document.createElement("td");
192-
blankCell.innerHTML = "&nbsp;&nbsp;&nbsp;"
216+
blankCell.innerHTML = "&nbsp;&nbsp;&nbsp;";
193217
eventWrapper.appendChild(blankCell);
194218
}
195219

@@ -210,10 +234,12 @@ Module.register("calendar", {
210234

211235
titleWrapper.innerHTML = this.titleTransform(event.title) + repeatingCountTitle;
212236

237+
var titleClass = this.titleClassForUrl(event.url);
238+
213239
if (!this.config.colored) {
214-
titleWrapper.className = "title bright";
240+
titleWrapper.className = "title bright " + titleClass;
215241
} else {
216-
titleWrapper.className = "title";
242+
titleWrapper.className = "title " + titleClass;
217243
}
218244

219245
if(this.config.timeFormat === "dateheaders"){
@@ -223,26 +249,13 @@ Module.register("calendar", {
223249
titleWrapper.align = "left";
224250

225251
}else{
252+
253+
var timeClass = this.timeClassForUrl(event.url);
226254
var timeWrapper = document.createElement("td");
227-
timeWrapper.className = "time light";
255+
timeWrapper.className = "time light " + timeClass;
228256
timeWrapper.align = "left";
229257
timeWrapper.style.paddingLeft = "2px";
230-
var timeFormatString = "";
231-
switch (config.timeFormat) {
232-
case 12: {
233-
timeFormatString = "h:mm A";
234-
break;
235-
}
236-
case 24: {
237-
timeFormatString = "HH:mm";
238-
break;
239-
}
240-
default: {
241-
timeFormatString = "HH:mm";
242-
break;
243-
}
244-
}
245-
timeWrapper.innerHTML = moment(event.startDate, "x").format(timeFormatString);
258+
timeWrapper.innerHTML = moment(event.startDate, "x").format("LT");
246259
eventWrapper.appendChild(timeWrapper);
247260
titleWrapper.align = "right";
248261
}
@@ -260,6 +273,8 @@ Module.register("calendar", {
260273
var oneHour = oneMinute * 60;
261274
var oneDay = oneHour * 24;
262275
if (event.fullDayEvent) {
276+
//subtract one second so that fullDayEvents end at 23:59:59, and not at 0:00:00 one the next day
277+
event.endDate -= oneSecond;
263278
if (event.today) {
264279
timeWrapper.innerHTML = this.capFirst(this.translate("TODAY"));
265280
} else if (event.startDate - now < oneDay && event.startDate - now > 0) {
@@ -343,23 +358,17 @@ Module.register("calendar", {
343358
}
344359
//timeWrapper.innerHTML += ' - '+ moment(event.startDate,'x').format('lll');
345360
//console.log(event);
346-
timeWrapper.className = "time light";
361+
var timeClass = this.timeClassForUrl(event.url);
362+
timeWrapper.className = "time light " + timeClass;
347363
eventWrapper.appendChild(timeWrapper);
348364
}
349365

350366
wrapper.appendChild(eventWrapper);
351367

352368
// Create fade effect.
353-
if (this.config.fade && this.config.fadePoint < 1) {
354-
if (this.config.fadePoint < 0) {
355-
this.config.fadePoint = 0;
356-
}
357-
var startingPoint = events.length * this.config.fadePoint;
358-
var steps = events.length - startingPoint;
359-
if (e >= startingPoint) {
360-
var currentStep = e - startingPoint;
361-
eventWrapper.style.opacity = 1 - (1 / steps * currentStep);
362-
}
369+
if (e >= startFade) {
370+
currentFadeStep = e - startFade;
371+
eventWrapper.style.opacity = 1 - (1 / fadeSteps * currentFadeStep);
363372
}
364373
}
365374

@@ -472,11 +481,15 @@ Module.register("calendar", {
472481
maximumEntries: calendarConfig.maximumEntries || this.config.maximumEntries,
473482
maximumNumberOfDays: calendarConfig.maximumNumberOfDays || this.config.maximumNumberOfDays,
474483
fetchInterval: this.config.fetchInterval,
484+
symbolClass: calendarConfig.symbolClass,
485+
titleClass: calendarConfig.titleClass,
486+
timeClass: calendarConfig.timeClass,
475487
auth: auth
476488
});
477489
},
478490

479-
/* symbolsForUrl(url)
491+
/**
492+
* symbolsForUrl(url)
480493
* Retrieves the symbols for a specific url.
481494
*
482495
* argument url string - Url to look for.
@@ -487,6 +500,42 @@ Module.register("calendar", {
487500
return this.getCalendarProperty(url, "symbol", this.config.defaultSymbol);
488501
},
489502

503+
/**
504+
* symbolClassForUrl(url)
505+
* Retrieves the symbolClass for a specific url.
506+
*
507+
* @param url string - Url to look for.
508+
*
509+
* @returns string
510+
*/
511+
symbolClassForUrl: function (url) {
512+
return this.getCalendarProperty(url, "symbolClass", "");
513+
},
514+
515+
/**
516+
* titleClassForUrl(url)
517+
* Retrieves the titleClass for a specific url.
518+
*
519+
* @param url string - Url to look for.
520+
*
521+
* @returns string
522+
*/
523+
titleClassForUrl: function (url) {
524+
return this.getCalendarProperty(url, "titleClass", "");
525+
},
526+
527+
/**
528+
* timeClassForUrl(url)
529+
* Retrieves the timeClass for a specific url.
530+
*
531+
* @param url string - Url to look for.
532+
*
533+
* @returns string
534+
*/
535+
timeClassForUrl: function (url) {
536+
return this.getCalendarProperty(url, "timeClass", "");
537+
},
538+
490539
/* colorForUrl(url)
491540
* Retrieves the color for a specific url.
492541
*

modules/default/calendar/calendarfetcher.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,16 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri
171171
var geo = event.geo || false;
172172
var description = event.description || false;
173173

174-
if (typeof event.rrule != "undefined" && !isFacebookBirthday) {
174+
if (typeof event.rrule != "undefined" && event.rrule != null && !isFacebookBirthday) {
175175
var rule = event.rrule;
176+
177+
// can cause problems with e.g. birthdays before 1900
178+
if(rule.origOptions && rule.origOptions.dtstart && rule.origOptions.dtstart.getFullYear() < 1900 ||
179+
rule.options && rule.options.dtstart && rule.options.dtstart.getFullYear() < 1900){
180+
rule.origOptions.dtstart.setYear(1900);
181+
rule.options.dtstart.setYear(1900);
182+
}
183+
176184
var dates = rule.between(today, future, true, limitFunction);
177185

178186
for (var d in dates) {

modules/default/calendar/vendor/ical.js/node-ical.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,13 @@ ical.objectHandlers['END'] = function(val, params, curr, stack){
4444
rule += ' EXDATE:' + curr.exdates[i].toISOString().replace(/[-:]/g, '');
4545
rule = rule.replace(/\.[0-9]{3}/, '');
4646
}
47-
curr.rrule = rrulestr(rule);
47+
try {
48+
curr.rrule = rrulestr(rule);
49+
}
50+
catch(err) {
51+
console.log("Unrecognised element in calendar feed, ignoring: " + rule);
52+
curr.rrule = null;
53+
}
4854
}
4955
return originalEnd.call(this, val, params, curr, stack);
5056
}

modules/default/clock/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
The `clock` module is one of the default modules of the MagicMirror.
33
This module displays the current date and time. The information will be updated realtime.
44

5+
## Screenshot
6+
7+
- Current time
8+
![Current time](clock_screenshot.png)
9+
510
## Using the module
611

712
To use this module, add it to the modules array in the `config/config.js` file:
29.8 KB
Loading

0 commit comments

Comments
 (0)