From 85a9f141785f521270de2427de7178cc3f4afcde Mon Sep 17 00:00:00 2001 From: Johan Date: Tue, 11 Oct 2022 21:05:11 +0200 Subject: [PATCH] Added css class names "today" and "tomorrow" for calendar (#2939) Added class names "today" and "tomorrow" on the calendar module tr elements (i.e. calendar items). This way you can for example color your events today and/or tomorrow to more easily see what's happening in the near future. Implemented by adding an event.tomorrow variable (similar to event.today) that can be used for other things in the future. Also replaced a few hardcoded values (hours, seconds etc.) with constants to make the code more consistent. Edit: tested with normal events, split day events and events with locations. --- CHANGELOG.md | 1 + modules/default/calendar/calendar.js | 46 ++++++++++++++++++---------- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c2c0484e..9361b2da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ Special thanks to: @rejas, @sdetweil - Added test for remoteFile option in compliments module - Added hourlyWeather functionality to Weather.gov weather provider - Removed weatherEndpoint definition from weathergov.js (not used) +- Added css class names "today" and "tomorrow" for default calendar ### Removed diff --git a/modules/default/calendar/calendar.js b/modules/default/calendar/calendar.js index 134a84ce..b19dc62b 100644 --- a/modules/default/calendar/calendar.js +++ b/modules/default/calendar/calendar.js @@ -163,11 +163,10 @@ Module.register("calendar", { // Override dom generator. 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; + const ONE_SECOND = 1000; // 1,000 milliseconds + const ONE_MINUTE = ONE_SECOND * 60; + const ONE_HOUR = ONE_MINUTE * 60; + const ONE_DAY = ONE_HOUR * 24; const events = this.createEventList(true); const wrapper = document.createElement("table"); @@ -205,6 +204,8 @@ Module.register("calendar", { if (lastSeenDate !== dateAsString) { const dateRow = document.createElement("tr"); dateRow.className = "normal"; + if (event.today) dateRow.className += " today"; + else if (event.tomorrow) dateRow.className += " tomorrow"; const dateCell = document.createElement("td"); dateCell.colSpan = "3"; @@ -230,6 +231,8 @@ Module.register("calendar", { } eventWrapper.className = "normal event"; + if (event.today) eventWrapper.className += " today"; + else if (event.tomorrow) eventWrapper.className += " tomorrow"; const symbolWrapper = document.createElement("td"); @@ -338,7 +341,7 @@ Module.register("calendar", { // For full day events we use the fullDayEventDateFormat if (event.fullDayEvent) { //subtract one second so that fullDayEvents end at 23:59:59, and not at 0:00:00 one the next day - event.endDate -= oneSecond; + event.endDate -= ONE_SECOND; timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").format(this.config.fullDayEventDateFormat)); } else if (this.config.getRelative > 0 && event.startDate < now) { // Ongoing and getRelative is set @@ -348,7 +351,7 @@ Module.register("calendar", { timeUntilEnd: moment(event.endDate, "x").fromNow(true) }) ); - } else if (this.config.urgency > 0 && event.startDate - now < this.config.urgency * oneDay) { + } else if (this.config.urgency > 0 && event.startDate - now < this.config.urgency * ONE_DAY) { // Within urgency days timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow()); } @@ -356,9 +359,9 @@ Module.register("calendar", { // 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) { + } else if (event.startDate - now < ONE_DAY && event.startDate - now > 0) { timeWrapper.innerHTML = this.capFirst(this.translate("TOMORROW")); - } else if (event.startDate - now < 2 * oneDay && event.startDate - now > 0) { + } else if (event.startDate - now < 2 * ONE_DAY && event.startDate - now > 0) { if (this.translate("DAYAFTERTOMORROW") !== "DAYAFTERTOMORROW") { timeWrapper.innerHTML = this.capFirst(this.translate("DAYAFTERTOMORROW")); } @@ -367,7 +370,7 @@ Module.register("calendar", { } else { // Show relative times if (event.startDate >= now || (event.fullDayEvent && event.today)) { - // Use relative time + // Use relative time if (!this.config.hideTime && !event.fullDayEvent) { timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").calendar(null, { sameElse: this.config.dateFormat })); } else { @@ -384,14 +387,14 @@ Module.register("calendar", { // 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) { + } else if (event.startDate - now < ONE_DAY && event.startDate - now > 0) { timeWrapper.innerHTML = this.capFirst(this.translate("TOMORROW")); - } else if (event.startDate - now < 2 * oneDay && event.startDate - now > 0) { + } else if (event.startDate - now < 2 * ONE_DAY && event.startDate - now > 0) { if (this.translate("DAYAFTERTOMORROW") !== "DAYAFTERTOMORROW") { timeWrapper.innerHTML = this.capFirst(this.translate("DAYAFTERTOMORROW")); } } - } else if (event.startDate - now < this.config.getRelative * oneHour) { + } else if (event.startDate - now < this.config.getRelative * ONE_HOUR) { // If event is within getRelative hours, display 'in xxx' time format or moment.fromNow() timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow()); } @@ -421,6 +424,8 @@ Module.register("calendar", { if (event.location !== false) { const locationRow = document.createElement("tr"); locationRow.className = "normal xsmall light"; + if (event.today) locationRow.className += " today"; + else if (event.tomorrow) locationRow.className += " tomorrow"; if (this.config.displaySymbol) { const symbolCell = document.createElement("td"); @@ -491,6 +496,11 @@ Module.register("calendar", { * @returns {object[]} Array with events. */ createEventList: function (limitNumberOfEntries) { + const ONE_SECOND = 1000; // 1,000 milliseconds + const ONE_MINUTE = ONE_SECOND * 60; + const ONE_HOUR = ONE_MINUTE * 60; + const ONE_DAY = ONE_HOUR * 24; + const now = new Date(); const today = moment().startOf("day"); const future = moment().startOf("day").add(this.config.maximumNumberOfDays, "days").toDate(); @@ -521,19 +531,21 @@ Module.register("calendar", { } } event.url = calendarUrl; - event.today = event.startDate >= today && event.startDate < today + 24 * 60 * 60 * 1000; + event.today = event.startDate >= today && event.startDate < today + ONE_DAY; + event.tomorrow = !event.today && event.startDate >= today + ONE_DAY && event.startDate < today + 2 * ONE_DAY; /* if sliceMultiDayEvents is set to true, multiday events (events exceeding at least one midnight) are sliced into days, * otherwise, esp. in dateheaders mode it is not clear how long these events are. */ - const maxCount = Math.ceil((event.endDate - 1 - moment(event.startDate, "x").endOf("day").format("x")) / (1000 * 60 * 60 * 24)) + 1; + const maxCount = Math.ceil((event.endDate - 1 - moment(event.startDate, "x").endOf("day").format("x")) / ONE_DAY) + 1; if (this.config.sliceMultiDayEvents && maxCount > 1) { const splitEvents = []; let midnight = moment(event.startDate, "x").clone().startOf("day").add(1, "day").format("x"); let count = 1; while (event.endDate > midnight) { const thisEvent = JSON.parse(JSON.stringify(event)); // clone object - thisEvent.today = thisEvent.startDate >= today && thisEvent.startDate < today + 24 * 60 * 60 * 1000; + thisEvent.today = thisEvent.startDate >= today && thisEvent.startDate < today + ONE_DAY; + thisEvent.tomorrow = !thisEvent.today && thisEvent.startDate >= today + ONE_DAY && thisEvent.startDate < today + 2 * ONE_DAY; thisEvent.endDate = midnight; thisEvent.title += " (" + count + "/" + maxCount + ")"; splitEvents.push(thisEvent); @@ -544,6 +556,8 @@ Module.register("calendar", { } // Last day event.title += " (" + count + "/" + maxCount + ")"; + event.today += event.startDate >= today && event.startDate < today + ONE_DAY; + event.tomorrow = !event.today && event.startDate >= today + ONE_DAY && event.startDate < today + 2 * ONE_DAY; splitEvents.push(event); for (let splitEvent of splitEvents) {