From 1f7602bb1590b4ff357d3a758528ff5c921b293c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim=20D=C3=BCsterhus?= Date: Wed, 26 Apr 2023 11:54:31 +0200 Subject: [PATCH] =?utf8?q?Fix=20=E2=80=9Ctoday=20or=20yesterday=E2=80=9D?= =?utf8?q?=20rendering=20for=20languages=20that=20do=20not=20put=20the=20w?= =?utf8?q?eekday=20first?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The previous version was broken, because it just returned the name of the weekday (`value`), but the time was missing entirely. The code was refactored to move the “weekday first” check into refresh(), allowing languages that put the weekday first to proceed as previously without any visual changes and other languages to just use the absolute date + time. The diff likely looks larger than it is for that reason. Rendering was verified with de, en_US, en_GB, ar, he, el, ru, ja. --- .../WebComponent/woltlab-core-date-time.ts | 45 ++++++++++++------- .../files/js/WoltLabSuite/WebComponent.js | 38 +++++++++------- 2 files changed, 51 insertions(+), 32 deletions(-) diff --git a/ts/WoltLabSuite/WebComponent/woltlab-core-date-time.ts b/ts/WoltLabSuite/WebComponent/woltlab-core-date-time.ts index 3c660bdf1c..f35498fdfa 100644 --- a/ts/WoltLabSuite/WebComponent/woltlab-core-date-time.ts +++ b/ts/WoltLabSuite/WebComponent/woltlab-core-date-time.ts @@ -162,12 +162,24 @@ } else if (difference < TimePeriod.OneHour) { const minutes = Math.trunc(difference / TimePeriod.OneMinute); value = DateFormatter.Minutes.format(minutes * -1, "minute"); - } else if (date.getTime() > todayDayStart) { - value = this.#formatTodayOrYesterday(date, TodayOrYesterday.Today); - } else if (date.getTime() > yesterdayDayStart) { - value = this.#formatTodayOrYesterday(date, TodayOrYesterday.Yesterday); } else if (difference < TimePeriod.OneWeek) { - value = DateFormatter.DayOfWeekAndTime.format(date); + const dateParts = DateFormatter.DayOfWeekAndTime.formatToParts(date); + const weekdayFirst = dateParts[0].type === "weekday"; + + if (weekdayFirst) { + // If the weekday comes first, we can be reasonably sure that + // "Today" and "Yesterday" can be inserted correctly. + if (date.getTime() > todayDayStart) { + value = this.#formatTodayOrYesterday(dateParts, TodayOrYesterday.Today); + } else if (date.getTime() > yesterdayDayStart) { + value = this.#formatTodayOrYesterday(dateParts, TodayOrYesterday.Yesterday); + } else { + value = dateParts.map((part) => part.value).join(""); + } + } else { + // If the weekday does not come first, use absolute dates + times. + value = DateFormatter.DateAndTime.format(date); + } } else { value = DateFormatter.Date.format(date); } @@ -183,22 +195,21 @@ * the “date” portion as a relative value such as “today” or * “tomorrow” _along_ with the time. * - * This workaround will generate the date using the day of week + * This workaround will take the date using the day of week * and the time, but replace the day of week with the relative * value. */ - #formatTodayOrYesterday(date: Date, dayOffset: TodayOrYesterday): string { - // This will generate the localized value of “today” or “tomorrow”. - let value = DateFormatter.TodayOrYesterday.format(dayOffset, "day"); - - const dateParts = DateFormatter.DayOfWeekAndTime.formatToParts(date); - if (dateParts[0].type === "weekday") { - const datePartsWithoutDayOfWeek: string[] = dateParts.slice(1).map((part) => part.value); - datePartsWithoutDayOfWeek.unshift(value); - value = datePartsWithoutDayOfWeek.join(""); - } + #formatTodayOrYesterday(dateParts: Intl.DateTimeFormatPart[], dayOffset: TodayOrYesterday): string { + const datePartsWithReplacedWeekday: string[] = dateParts.map((part) => { + if (part.type === "weekday") { + // This will return the localized value of “today” or “tomorrow”. + return DateFormatter.TodayOrYesterday.format(dayOffset, "day"); + } else { + return part.value; + } + }); - return value; + return datePartsWithReplacedWeekday.join(""); } } diff --git a/wcfsetup/install/files/js/WoltLabSuite/WebComponent.js b/wcfsetup/install/files/js/WoltLabSuite/WebComponent.js index 89e025a2c8..27f9584717 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/WebComponent.js +++ b/wcfsetup/install/files/js/WoltLabSuite/WebComponent.js @@ -1331,12 +1331,20 @@ } else if (difference < 3600 /* OneHour */) { const minutes = Math.trunc(difference / 60 /* OneMinute */); value = DateFormatter.Minutes.format(minutes * -1, "minute"); - } else if (date.getTime() > todayDayStart) { - value = this.#formatTodayOrYesterday(date, 0 /* Today */); - } else if (date.getTime() > yesterdayDayStart) { - value = this.#formatTodayOrYesterday(date, -1 /* Yesterday */); } else if (difference < 604800 /* OneWeek */) { - value = DateFormatter.DayOfWeekAndTime.format(date); + const dateParts = DateFormatter.DayOfWeekAndTime.formatToParts(date); + const weekdayFirst = dateParts[0].type === "weekday"; + if (weekdayFirst) { + if (date.getTime() > todayDayStart) { + value = this.#formatTodayOrYesterday(dateParts, 0 /* Today */); + } else if (date.getTime() > yesterdayDayStart) { + value = this.#formatTodayOrYesterday(dateParts, -1 /* Yesterday */); + } else { + value = dateParts.map((part) => part.value).join(""); + } + } else { + value = DateFormatter.DateAndTime.format(date); + } } else { value = DateFormatter.Date.format(date); } @@ -1349,19 +1357,19 @@ * the “date” portion as a relative value such as “today” or * “tomorrow” _along_ with the time. * - * This workaround will generate the date using the day of week + * This workaround will take the date using the day of week * and the time, but replace the day of week with the relative * value. */ - #formatTodayOrYesterday(date, dayOffset) { - let value = DateFormatter.TodayOrYesterday.format(dayOffset, "day"); - const dateParts = DateFormatter.DayOfWeekAndTime.formatToParts(date); - if (dateParts[0].type === "weekday") { - const datePartsWithoutDayOfWeek = dateParts.slice(1).map((part) => part.value); - datePartsWithoutDayOfWeek.unshift(value); - value = datePartsWithoutDayOfWeek.join(""); - } - return value; + #formatTodayOrYesterday(dateParts, dayOffset) { + const datePartsWithReplacedWeekday = dateParts.map((part) => { + if (part.type === "weekday") { + return DateFormatter.TodayOrYesterday.format(dayOffset, "day"); + } else { + return part.value; + } + }); + return datePartsWithReplacedWeekday.join(""); } } window.customElements.define("woltlab-core-date-time", WoltlabCoreDateTimeElement); -- 2.20.1