diff --git a/modules/default/calendar/README.md b/modules/default/calendar/README.md old mode 100644 new mode 100755 index 65c4741e..7d8d3fa2 --- a/modules/default/calendar/README.md +++ b/modules/default/calendar/README.md @@ -41,7 +41,7 @@ The following properties can be configured: | `displayRepeatingCountTitle` | Show count title for yearly repeating events (e.g. "X. Birthday", "X. Anniversary")

**Possible values:** `true` or `false`
**Default value:** `false` | `dateFormat` | Format to use for the date of events (when using absolute dates)

**Possible values:** See [Moment.js formats](http://momentjs.com/docs/#/parsing/string-format/)
**Default value:** `MMM Do` (e.g. Jan 18th) | `fullDayEventDateFormat` | Format to use for the date of full day events (when using absolute dates)

**Possible values:** See [Moment.js formats](http://momentjs.com/docs/#/parsing/string-format/)
**Default value:** `MMM Do` (e.g. Jan 18th) -| `timeFormat` | Display event times as absolute dates, or relative time

**Possible values:** `absolute` or `relative`
**Default value:** `relative` +| `timeFormat` | Display event times as absolute dates, or relative time, or using absolute date headers with times for each event next to it

**Possible values:** `absolute` or `relative` or `dateheader`
**Default value:** `relative` | `getRelative` | How much time (in hours) should be left until calendar events start getting relative?

**Possible values:** `0` (events stay absolute) - `48` (48 hours before the event starts)
**Default value:** `6` | `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

**Possible values:** a positive integer representing the number of days for which you want a relative date, for example `7` (for 7 days)

**Default value:** `7` | `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`.

**Possible values:** `true`, `false`

**Default value:** `true` diff --git a/modules/default/calendar/calendar.js b/modules/default/calendar/calendar.js old mode 100644 new mode 100755 index 79571fa9..3f9d3071 --- a/modules/default/calendar/calendar.js +++ b/modules/default/calendar/calendar.js @@ -132,8 +132,29 @@ Module.register("calendar", { return wrapper; } + var lastSeenDate = ''; + for (var e in events) { var event = events[e]; + var dateAsString = moment(event.startDate, "x").format(this.config.dateFormat); + if(this.config.timeFormat === "dateheaders"){ + if(lastSeenDate !== dateAsString){ + var dateRow = document.createElement("tr"); + dateRow.className = "normal" + var dateCell = document.createElement("td"); + + dateCell.colSpan = "3"; + dateCell.innerHTML = dateAsString; + dateRow.appendChild(dateCell); + wrapper.appendChild(dateRow); + + + lastSeenDate = dateAsString; + } + } + + + var eventWrapper = document.createElement("tr"); if (this.config.colored && !this.config.coloredSymbolOnly) { @@ -164,6 +185,10 @@ Module.register("calendar", { symbolWrapper.appendChild(symbol); } eventWrapper.appendChild(symbolWrapper); + }else if(this.config.timeFormat === "dateheaders"){ + var blankCell = document.createElement("td"); + blankCell.innerHTML = "   " + eventWrapper.appendChild(blankCell); } var titleWrapper = document.createElement("td"), @@ -189,89 +214,123 @@ Module.register("calendar", { titleWrapper.className = "title"; } - eventWrapper.appendChild(titleWrapper); - - var timeWrapper = document.createElement("td"); - //console.log(event.today); - var now = new Date(); - // Define second, minute, hour, and day variables - var oneSecond = 1000; // 1,000 milliseconds - var oneMinute = oneSecond * 60; - var oneHour = oneMinute * 60; - var oneDay = oneHour * 24; - if (event.fullDayEvent) { - if (event.today) { - timeWrapper.innerHTML = this.capFirst(this.translate("TODAY")); - } else if (event.startDate - now < oneDay && event.startDate - now > 0) { - timeWrapper.innerHTML = this.capFirst(this.translate("TOMORROW")); - } else if (event.startDate - now < 2 * oneDay && event.startDate - now > 0) { - if (this.translate("DAYAFTERTOMORROW") !== "DAYAFTERTOMORROW") { - timeWrapper.innerHTML = this.capFirst(this.translate("DAYAFTERTOMORROW")); - } else { - timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow()); - } - } else { - /* Check to see if the user displays absolute or relative dates with their events - * Also check to see if an event is happening within an 'urgency' time frameElement - * For example, if the user set an .urgency of 7 days, those events that fall within that - * time frame will be displayed with 'in xxx' time format or moment.fromNow() - * - * 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.urgency > 1) && (event.startDate - now < (this.config.urgency * oneDay))) { - // This event falls within the config.urgency period that the user has set - timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow()); - } else { - timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").format(this.config.fullDayEventDateFormat)); + if(this.config.timeFormat === "dateheaders"){ + + if (event.fullDayEvent) { + titleWrapper.colSpan = "2"; + titleWrapper.align = "left"; + + }else{ + var timeWrapper = document.createElement("td"); + timeWrapper.className = "time light"; + timeWrapper.align = "left"; + timeWrapper.style.paddingLeft = "2px"; + var timeFormatString = ""; + switch (config.timeFormat) { + case 12: { + timeFormatString = "h:mm A"; + break; + } + case 24: { + timeFormatString = "HH:mm"; + break; + } + default: { + timeFormatString = "HH:mm"; + break; } - } else { - timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow()); } + timeWrapper.innerHTML = moment(event.startDate, "x").format(timeFormatString); + eventWrapper.appendChild(timeWrapper); + titleWrapper.align = "right"; } - } else { - if (event.startDate >= new Date()) { - if (event.startDate - now < 2 * oneDay) { - // This event is within the next 48 hours (2 days) - if (event.startDate - now < this.config.getRelative * oneHour) { - // If event is within 6 hour, display 'in xxx' time format or moment.fromNow() - timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow()); + + eventWrapper.appendChild(titleWrapper); + }else{ + var timeWrapper = document.createElement("td"); + + eventWrapper.appendChild(titleWrapper); + //console.log(event.today); + var now = new Date(); + // Define second, minute, hour, and day variables + var oneSecond = 1000; // 1,000 milliseconds + var oneMinute = oneSecond * 60; + var oneHour = oneMinute * 60; + var oneDay = oneHour * 24; + if (event.fullDayEvent) { + if (event.today) { + timeWrapper.innerHTML = this.capFirst(this.translate("TODAY")); + } else if (event.startDate - now < oneDay && event.startDate - now > 0) { + timeWrapper.innerHTML = this.capFirst(this.translate("TOMORROW")); + } else if (event.startDate - now < 2 * oneDay && event.startDate - now > 0) { + if (this.translate("DAYAFTERTOMORROW") !== "DAYAFTERTOMORROW") { + timeWrapper.innerHTML = this.capFirst(this.translate("DAYAFTERTOMORROW")); } else { - // Otherwise just say 'Today/Tomorrow at such-n-such time' - timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").calendar()); + timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow()); } } else { /* Check to see if the user displays absolute or relative dates with their events - * Also check to see if an event is happening within an 'urgency' time frameElement - * For example, if the user set an .urgency of 7 days, those events that fall within that - * time frame will be displayed with 'in xxx' time format or moment.fromNow() - * - * Note: this needs to be put in its own function, as the whole thing repeats again verbatim - */ + * Also check to see if an event is happening within an 'urgency' time frameElement + * For example, if the user set an .urgency of 7 days, those events that fall within that + * time frame will be displayed with 'in xxx' time format or moment.fromNow() + * + * 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.urgency > 1) && (event.startDate - now < (this.config.urgency * oneDay))) { // This event falls within the config.urgency period that the user has set timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow()); } else { - timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").format(this.config.dateFormat)); + timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").format(this.config.fullDayEventDateFormat)); } } else { timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow()); } } } else { - timeWrapper.innerHTML = this.capFirst( - this.translate("RUNNING", { - fallback: this.translate("RUNNING") + " {timeUntilEnd}", - timeUntilEnd: moment(event.endDate, "x").fromNow(true) - }) - ); + if (event.startDate >= new Date()) { + if (event.startDate - now < 2 * oneDay) { + // This event is within the next 48 hours (2 days) + if (event.startDate - now < this.config.getRelative * oneHour) { + // If event is within 6 hour, display 'in xxx' time format or moment.fromNow() + timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow()); + } else { + // Otherwise just say 'Today/Tomorrow at such-n-such time' + timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").calendar()); + } + } else { + /* Check to see if the user displays absolute or relative dates with their events + * Also check to see if an event is happening within an 'urgency' time frameElement + * For example, if the user set an .urgency of 7 days, those events that fall within that + * time frame will be displayed with 'in xxx' time format or moment.fromNow() + * + * 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.urgency > 1) && (event.startDate - now < (this.config.urgency * oneDay))) { + // This event falls within the config.urgency period that the user has set + timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow()); + } else { + timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").format(this.config.dateFormat)); + } + } else { + timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow()); + } + } + } else { + timeWrapper.innerHTML = this.capFirst( + this.translate("RUNNING", { + fallback: this.translate("RUNNING") + " {timeUntilEnd}", + timeUntilEnd: moment(event.endDate, "x").fromNow(true) + }) + ); + } } + //timeWrapper.innerHTML += ' - '+ moment(event.startDate,'x').format('lll'); + //console.log(event); + timeWrapper.className = "time light"; + eventWrapper.appendChild(timeWrapper); } - //timeWrapper.innerHTML += ' - '+ moment(event.startDate,'x').format('lll'); - //console.log(event); - timeWrapper.className = "time light"; - eventWrapper.appendChild(timeWrapper); wrapper.appendChild(eventWrapper); @@ -359,6 +418,9 @@ Module.register("calendar", { continue; } } + if(this.listContainsEvent(events,event)){ + continue; + } event.url = c; event.today = event.startDate >= today && event.startDate < (today + 24 * 60 * 60 * 1000); events.push(event); @@ -372,6 +434,17 @@ Module.register("calendar", { return events.slice(0, this.config.maximumEntries); }, + + listContainsEvent: function(eventList, event){ + for(let evt of eventList){ + if(evt.title === event.title && parseInt(evt.startDate) === parseInt(event.startDate)){ + return true; + } + } + return false; + + }, + /* createEventList(url) * Requests node helper to add calendar url. *