FEATURE: Omit showing day when 'to' day is same as 'from' day (#18500)

Essentially,

Saturday at 2:50 PM -> Saturday at 4:38 PM becomes
Saturday at 2:50 PM -> 4:38 PM (Singapore)

Also, the displayed dates are shortened when the standalone date
is within two days. So despite the 'from' and 'to' date being the
same day, it may show 'Saturday' for 'from', and the specific date
for the 'to'. This corrects the behaviour.

(so if the current date and time is Thursday 5PM, the 'from' date
below is within 2 days, but the 'to' date is not)
Saturday at 2:50 PM -> 8 October 2022 at 9:38 PM becomes
Saturday at 2:50 PM -> 9:38 PM
This commit is contained in:
Natalie Tay 2022-10-07 09:39:41 +08:00 committed by GitHub
parent cb26d52d33
commit 7d8cda9858
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 61 additions and 7 deletions

View File

@ -21,10 +21,22 @@ export function applyLocalDates(dates, siteSettings) {
const currentUserTZ = moment.tz.guess();
dates.forEach((element) => {
dates.forEach((element, index, arr) => {
const opts = buildOptionsFromElement(element, siteSettings);
if (
element.attributes["data-range"]?.value === "to" &&
index !== 0 &&
arr[index - 1].attributes["data-range"]?.value === "from"
) {
const fromElement = arr[index - 1];
if (_rangeIsSameLocalDay(fromElement, element)) {
opts.sameLocalDayAsFrom = true;
}
}
const localDateBuilder = new LocalDateBuilder(opts, currentUserTZ).build();
element.innerText = "";
element.insertAdjacentHTML(
"beforeend",
@ -45,6 +57,17 @@ export function applyLocalDates(dates, siteSettings) {
});
}
function _rangeIsSameLocalDay(fromElement, toElement) {
const timezone = fromElement.attributes["data-timezone"].value;
const from = moment(_getDateFromElement(fromElement)).tz(timezone);
const to = moment(_getDateFromElement(toElement)).tz(timezone);
return from.isSame(to, "day");
}
function _getDateFromElement(element) {
return `${element.attributes["data-date"].value}T${element.attributes["data-time"].value}`;
}
function buildOptionsFromElement(element, siteSettings) {
const opts = {};
const dataset = element.dataset;
@ -85,6 +108,7 @@ function buildOptionsFromMarkdownTag(element) {
opts.displayedTimezone = element.attributes["data-displayed-timezone"];
opts.format = element.attributes["data-format"];
opts.countdown = element.attributes["data-countdown"];
opts.range = element.attributes["data-range"];
return opts;
}
@ -189,7 +213,11 @@ function initializeDiscourseLocalDates(api) {
this.metadata.discourseLocalDateStartRangeOpts = null;
return "";
}
if (this.element.attributes["data-range"] === "true") {
if (
this.element.attributes["data-range"] === "true" ||
this.element.attributes["data-range"] === "from" ||
this.element.attributes["data-range"] === "to"
) {
this.metadata.discourseLocalDateStartRangeOpts =
buildOptionsFromMarkdownTag(this.element);
return "";

View File

@ -47,7 +47,7 @@ function addSingleLocalDate(buffer, state, config) {
]);
}
if (config.range) {
token.attrs.push(["data-range", true]);
token.attrs.push(["data-range", config.range]);
}
if (
@ -152,12 +152,12 @@ function addLocalRange(buffer, matches, state) {
config.timezones = parsed.attrs.timezones;
config.displayedTimezone = parsed.attrs.displayedTimezone;
config.countdown = parsed.attrs.countdown;
config.range = parsed.attrs.from && parsed.attrs.to;
if (parsed.attrs.from) {
[date, time] = parsed.attrs.from.split("T");
config.date = date;
config.time = time;
config.range = "from";
addSingleLocalDate(buffer, state, config);
}
if (config.range) {
@ -167,6 +167,7 @@ function addLocalRange(buffer, matches, state) {
[date, time] = parsed.attrs.to.split("T");
config.date = date;
config.time = time;
config.range = "to";
addSingleLocalDate(buffer, state, config);
}
}

View File

@ -16,6 +16,7 @@ export default class LocalDateBuilder {
this.time = params.time;
this.date = params.date;
this.recurring = params.recurring;
this.sameLocalDayAsFrom = params.sameLocalDayAsFrom;
this.timezones = Array.from(
new Set((params.timezones || []).filter(Boolean))
);
@ -233,6 +234,10 @@ export default class LocalDateBuilder {
localDate.add(1, "day").datetime.endOf("day")
);
if (this.sameLocalDayAsFrom) {
return this._timeOnlyFormat(localDate, displayedTimezone);
}
if (inCalendarRange && sameTimezone) {
const date = localDate.datetimeWithZone(this.localTimezone);
@ -293,4 +298,8 @@ export default class LocalDateBuilder {
.format(format);
return `${formatted} (${this._zoneWithoutPrefix(displayedTimezone)})`;
}
_timeOnlyFormat(localTime, displayedTimezone) {
return this._formatWithZone(localTime, displayedTimezone, "LT");
}
}

View File

@ -91,7 +91,8 @@ RSpec.describe "Local Dates" do
cooked = Fabricate(:post, raw: raw).cooked
expect(cooked).to include('data-date="2022-01-06')
expect(cooked).to include('data-range="true"')
expect(cooked).to include('data-range="from"')
expect(cooked).to include('data-range="to"')
expect(cooked).not_to include('data-time=')
end
@ -100,7 +101,8 @@ RSpec.describe "Local Dates" do
cooked = Fabricate(:post, raw: raw).cooked
expect(cooked).to include('data-date="2022-01-06')
expect(cooked).to include('data-range="true"')
expect(cooked).to include('data-range="to"')
expect(cooked).to include('data-range="from"')
expect(cooked).to include('data-time="13:00"')
expect(cooked).to include('data-timezone="Australia/Sydney"')
end
@ -111,7 +113,7 @@ RSpec.describe "Local Dates" do
expect(cooked).to include('data-date="2022-01-06')
expect(cooked).to include('data-time="13:00"')
expect(cooked).not_to include('data-range=')
expect(cooked).not_to include('data-range="to"')
end
end
end

View File

@ -86,6 +86,20 @@ module("lib:local-date-builder", function () {
);
});
test("time", function (assert) {
assert.buildsCorrectDate(
{
"time": "12:22:00",
"date": "2022-10-07",
"timezone": "Asia/Singapore",
"localTimezone": "Asia/Singapore",
"sameLocalDayAsFrom": true
},
{ formatted: "12:22 PM (Singapore)" },
"it displays the time only as the date is the same local day as 'from'"
);
});
test("option[format]", function (assert) {
freezeTime({ date: "2020-03-11" }, () => {
assert.buildsCorrectDate(