fix(client): localise calendar to user's current timezone (#38217)

* fix: localise Heatmap to user's timezone

Rather than using ISO formatted date strings, this uses Date objects
for simplicity and to ensure that the heatmap is correct for the
timezone it is viewed in. It should also match the timeline which is
also localised to the viewing computer's timezone.

* test: update snapshot
pull/38220/head
Oliver Eyton-Williams 2020-02-14 19:59:41 +01:00 committed by GitHub
parent cc79999a31
commit 3fff454872
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 48 deletions

View File

@ -5,7 +5,7 @@ import ReactTooltip from 'react-tooltip';
import addDays from 'date-fns/add_days';
import addMonths from 'date-fns/add_months';
import startOfDay from 'date-fns/start_of_day';
import format from 'date-fns/format';
import isEqual from 'date-fns/is_equal';
import FullWidthRow from '../../helpers/FullWidthRow';
import Spacer from '../../helpers/Spacer';
@ -22,33 +22,17 @@ const propTypes = {
};
function HeatMap({ calendar, streak }) {
// an issue with react-calendar-heatmap makes the days off by one
// see this https://github.com/kevinsqi/react-calendar-heatmap/issues/112
// I have added one day in the marked places to account for the offset
// this logic adds a day to all the timestamps (remove if issue gets fixed)
let tempCalendar = {};
const secondsInADay = 60 * 60 * 24;
for (let timestamp of Object.keys(calendar)) {
tempCalendar[parseInt(timestamp, 10) + secondsInADay] = 1;
}
calendar = tempCalendar;
// the addDays of 1 to startOfToday (remove if issue gets fixed)
const startOfToday = addDays(startOfDay(Date.now()), 1);
const sixMonthsAgo = addMonths(startOfToday, -6);
const startOfCalendar = format(addDays(sixMonthsAgo, -1), 'YYYY-MM-DD');
const endOfCalendar = format(startOfToday, 'YYYY-MM-DD');
const endOfCalendar = startOfDay(Date.now());
const startOfCalendar = addMonths(endOfCalendar, -6);
let calendarData = [];
let dayCounter = sixMonthsAgo;
let dayCounter = startOfCalendar;
// create a data point for each day of the calendar period (six months)
while (dayCounter <= startOfToday) {
while (dayCounter <= endOfCalendar) {
// this is the format needed for react-calendar-heatmap
const newDay = {
date: format(dayCounter, 'YYYY-MM-DD'),
date: startOfDay(dayCounter),
count: 0
};
@ -56,13 +40,11 @@ function HeatMap({ calendar, streak }) {
dayCounter = addDays(dayCounter, 1);
}
// this adds one to the count of the day for each timestamp
for (let timestamp of Object.keys(calendar)) {
timestamp = Number(timestamp * 1000) || null;
if (timestamp) {
const startOfTimestampDay = format(startOfDay(timestamp), 'YYYY-MM-DD');
const index = calendarData.findIndex(
day => day.date === startOfTimestampDay
const index = calendarData.findIndex(day =>
isEqual(day.date, startOfDay(timestamp))
);
if (index >= 0) {
@ -93,14 +75,16 @@ function HeatMap({ calendar, streak }) {
} else {
valueCount = 'No points';
}
const dateFormatted = value.date
? 'on ' +
value.date.toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric'
})
: '';
return {
'data-tip': `<b>${valueCount}</b> on ${new Date(
value.date
).toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric'
})}`
'data-tip': `<b>${valueCount}</b> ${dateFormatted}`
};
}}
values={calendarData}

View File

@ -2168,9 +2168,9 @@ exports[`<HeatMap/> renders correctly 1`] = `
<title />
</rect>
<rect
class="color-empty"
class="color-scale-1"
currentItem="false"
data-tip="<b>No points</b> on Jan 30, 2020"
data-tip="<b>2 points</b> on Jan 30, 2020"
height="10"
width="10"
x="0"
@ -2179,9 +2179,9 @@ exports[`<HeatMap/> renders correctly 1`] = `
<title />
</rect>
<rect
class="color-scale-1"
class="color-empty"
currentItem="false"
data-tip="<b>2 points</b> on Jan 31, 2020"
data-tip="<b>No points</b> on Jan 31, 2020"
height="10"
width="10"
x="0"
@ -2227,17 +2227,6 @@ exports[`<HeatMap/> renders correctly 1`] = `
>
<title />
</rect>
<rect
class="color-empty"
currentItem="false"
data-tip="<b>No points</b> on Feb 4, 2020"
height="10"
width="10"
x="0"
y="22"
>
<title />
</rect>
</g>
</g>
<g