Revised handling of timeFormat "absolute" and "relative".

Added new option "coloredEvents" which contain an array with keyword and color for coloring events matching keyword
This commit is contained in:
Johan Alvinger
2020-11-23 21:48:34 +01:00
parent a19c3a43d8
commit e86fa9d24a

View File

@@ -38,6 +38,7 @@ Module.register("calendar", {
hideOngoing: false, hideOngoing: false,
colored: false, colored: false,
coloredSymbolOnly: false, coloredSymbolOnly: false,
coloredEvents: [], // Array of Keyword/Color where Keyword is a regexp and color the color code to use when regexp matches
tableClass: "small", tableClass: "small",
calendars: [ calendars: [
{ {
@@ -155,6 +156,12 @@ Module.register("calendar", {
// Override dom generator. // Override dom generator.
getDom: function () { getDom: function () {
// Define second, minute, hour, and day constants
const oneSecond = 1000; // 1,000 milliseconds
const oneMinute = oneSecond * 60;
const oneHour = oneMinute * 60;
const oneDay = oneHour * 24;
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;
@@ -250,6 +257,17 @@ Module.register("calendar", {
} }
} }
if (this.config.coloredEvents.length > 0) {
for (var ev in this.config.coloredEvents) {
var needle = new RegExp(this.config.coloredEvents[ev].keyword, "gi");
if (needle.test(event.title)) {
eventWrapper.style.cssText = "color:" + this.config.coloredEvents[ev].color;
titleWrapper.style.cssText = "color:" + this.config.coloredEvents[ev].color;
break;
}
}
}
titleWrapper.innerHTML = this.titleTransform(event.title, this.config.titleReplace, this.config.wrapEvents, this.config.maxTitleLength, this.config.maxTitleLines) + repeatingCountTitle; titleWrapper.innerHTML = this.titleTransform(event.title, this.config.titleReplace, this.config.wrapEvents, this.config.maxTitleLength, this.config.maxTitleLines) + repeatingCountTitle;
var titleClass = this.titleClassForUrl(event.url); var titleClass = this.titleClassForUrl(event.url);
@@ -282,82 +300,56 @@ Module.register("calendar", {
eventWrapper.appendChild(titleWrapper); eventWrapper.appendChild(titleWrapper);
var now = new Date(); var now = new Date();
// Define second, minute, hour, and day variables
var oneSecond = 1000; // 1,000 milliseconds if (this.config.timeFormat === "absolute") {
var oneMinute = oneSecond * 60; // Use dateFormat
var oneHour = oneMinute * 60; timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").format(this.config.dateFormat));
var oneDay = oneHour * 24; // Add end time if showEnd
if (event.fullDayEvent) { if (this.config.showEnd) {
//subtract one second so that fullDayEvents end at 23:59:59, and not at 0:00:00 one the next day timeWrapper.innerHTML += "-";
event.endDate -= oneSecond; timeWrapper.innerHTML += this.capFirst(moment(event.endDate, "x").format(this.config.dateEndFormat));
if (event.today) { }
timeWrapper.innerHTML = this.capFirst(this.translate("TODAY")); // For full day events we use the fullDayEventDateFormat
} else if (event.startDate - now < oneDay && event.startDate - now > 0) { if (event.fullDayEvent) {
timeWrapper.innerHTML = this.capFirst(this.translate("TOMORROW")); //subtract one second so that fullDayEvents end at 23:59:59, and not at 0:00:00 one the next day
} else if (event.startDate - now < 2 * oneDay && event.startDate - now > 0) { event.endDate -= oneSecond;
if (this.translate("DAYAFTERTOMORROW") !== "DAYAFTERTOMORROW") { timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").format(this.config.fullDayEventDateFormat));
timeWrapper.innerHTML = this.capFirst(this.translate("DAYAFTERTOMORROW")); }
} else { if (this.config.getRelative > 0 && event.startDate >= now) {
// Ongoing and getRelative is set
timeWrapper.innerHTML = this.capFirst(
this.translate("RUNNING", {
fallback: this.translate("RUNNING") + " {timeUntilEnd}",
timeUntilEnd: moment(event.endDate, "x").fromNow(true)
})
);
} else if (this.config.urgency > 0 && event.startDate - now < this.config.urgency * oneDay) {
// Within urgency days
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
}
if (event.fullDayEvent && this.config.nextDaysRelative) {
// Full days events within the next two days
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 {
// Show relative times
if (event.startDate >= now) {
// Use relative time
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").calendar());
if (event.startDate - now < this.config.getRelative * oneHour) {
// If event is within getRelative hours, display 'in xxx' time format or moment.fromNow()
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow()); timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
} }
} else { } else {
/* Check to see if the user displays absolute or relative dates with their events // Ongoing event
* 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").from(moment().format("YYYYMMDD")));
} else {
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").format(this.config.fullDayEventDateFormat));
}
} else {
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").from(moment().format("YYYYMMDD")));
}
}
if (this.config.showEnd) {
timeWrapper.innerHTML += "-";
timeWrapper.innerHTML += this.capFirst(moment(event.endDate, "x").format(this.config.fullDayEventDateFormat));
}
} 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());
} else {
if (this.config.timeFormat === "absolute" && !this.config.nextDaysRelative) {
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").format(this.config.dateFormat));
} 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( timeWrapper.innerHTML = this.capFirst(
this.translate("RUNNING", { this.translate("RUNNING", {
fallback: this.translate("RUNNING") + " {timeUntilEnd}", fallback: this.translate("RUNNING") + " {timeUntilEnd}",
@@ -365,12 +357,7 @@ Module.register("calendar", {
}) })
); );
} }
if (this.config.showEnd) {
timeWrapper.innerHTML += "-";
timeWrapper.innerHTML += this.capFirst(moment(event.endDate, "x").format(this.config.dateEndFormat));
}
} }
//timeWrapper.innerHTML += ' - '+ moment(event.startDate,'x').format('lll');
timeWrapper.className = "time light " + this.timeClassForUrl(event.url); timeWrapper.className = "time light " + this.timeClassForUrl(event.url);
eventWrapper.appendChild(timeWrapper); eventWrapper.appendChild(timeWrapper);
} }
@@ -524,13 +511,31 @@ Module.register("calendar", {
return a.startDate - b.startDate; return a.startDate - b.startDate;
}); });
// Limit the number of days displayed
// If limitDays is set > 0, limit display to that number of days // If limitDays is set > 0, limit display to that number of days
if (this.config.limitDays > 0) { if (this.config.limitDays > 0) {
var newEvents = [];
var lastDate = today.clone().subtract(1, "days").format("YYYYMMDD"); var lastDate = today.clone().subtract(1, "days").format("YYYYMMDD");
var days = 0; var days = 0;
var newevents = []; for (var e of events) {
for (var e in events) { eventDate = moment(e.startDate, "x").format("YYYYMMDD");
// if date of event is later than lastdate
// check if we already are showing max unique days
if (eventDate > lastDate) {
// if the only entry in the first day is a full day event that day is not counted as unique
if (newEvents.length === 1 && days === 1 && newEvents[0].fullDayEvent) {
days--;
}
days++;
if (days > this.config.limitDays) {
continue;
} else {
lastDate = eventDate;
}
}
newEvents.push(e);
} }
events = newEvents;
} }
return events.slice(0, this.config.maximumEntries); return events.slice(0, this.config.maximumEntries);