From 3fff454872a3fdfb829510c3a3f77d4db664ccfa Mon Sep 17 00:00:00 2001 From: Oliver Eyton-Williams Date: Fri, 14 Feb 2020 19:59:41 +0100 Subject: [PATCH] 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 --- .../components/profile/components/HeatMap.js | 50 +++++++------------ .../__snapshots__/HeatMap.test.js.snap | 19 ++----- 2 files changed, 21 insertions(+), 48 deletions(-) diff --git a/client/src/components/profile/components/HeatMap.js b/client/src/components/profile/components/HeatMap.js index a9d5f8af1ba..166b82f074b 100644 --- a/client/src/components/profile/components/HeatMap.js +++ b/client/src/components/profile/components/HeatMap.js @@ -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': `${valueCount} on ${new Date( - value.date - ).toLocaleDateString('en-US', { - year: 'numeric', - month: 'short', - day: 'numeric' - })}` + 'data-tip': `${valueCount} ${dateFormatted}` }; }} values={calendarData} diff --git a/client/src/components/profile/components/__snapshots__/HeatMap.test.js.snap b/client/src/components/profile/components/__snapshots__/HeatMap.test.js.snap index 4f6db267d9a..af7e0b2ce3b 100644 --- a/client/src/components/profile/components/__snapshots__/HeatMap.test.js.snap +++ b/client/src/components/profile/components/__snapshots__/HeatMap.test.js.snap @@ -2168,9 +2168,9 @@ exports[` renders correctly 1`] = ` </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