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.
*