From 24b94a25dfaf5113ffcc17bd886cf8cb9a22255d Mon Sep 17 00:00:00 2001 From: dillon Date: Wed, 12 Aug 2015 14:52:03 -0700 Subject: [PATCH] fix(message-list): show relative time if email is less than 22 hours ago. fixes T2308. Summary: refactored existing code and rewrite come tests to make the logic simpler Test Plan: new tests to test final outcome rather than intermediate formats, which i figured was more useful Reviewers: bengotow Reviewed By: bengotow Maniphest Tasks: T3219, T2308 Differential Revision: https://phab.nylas.com/D1876 --- .../message-list/lib/message-timestamp.cjsx | 39 ++++++------ .../spec/message-timestamp-spec.cjsx | 60 +++++++++---------- 2 files changed, 47 insertions(+), 52 deletions(-) diff --git a/internal_packages/message-list/lib/message-timestamp.cjsx b/internal_packages/message-list/lib/message-timestamp.cjsx index 7effc51a8..1a769b532 100644 --- a/internal_packages/message-list/lib/message-timestamp.cjsx +++ b/internal_packages/message-list/lib/message-timestamp.cjsx @@ -15,29 +15,28 @@ class MessageTimestamp extends React.Component +nextProps.date isnt +@props.date or nextProps.isDetailed isnt @props.isDetailed render: => + msgDate = moment.tz(@props.date, Utils.timeZone) + nowDate = @_today() + formattedDate = @_formattedDate(nowDate, msgDate, @props.isDetailed)
{@_formattedDate()}
+ onClick={@props.onClick}>{formattedDate} - _formattedDate: => - moment.tz(@props.date, Utils.timeZone).format(@_timeFormat()) - - _timeFormat: => - if @props.isDetailed - return "MMMM D, YYYY [at] h:mm A" + _formattedDate: (msgDate, now, isDetailed) => + if isDetailed + return msgDate.format "MMMM D, YYYY [at] h:mm A" else - today = moment(@_today()) - dayOfEra = today.dayOfYear() + today.year() * 365 - msgDate = moment(@props.date) - msgDayOfEra = msgDate.dayOfYear() + msgDate.year() * 365 - diff = dayOfEra - msgDayOfEra - if diff < 1 - return "h:mm a" - if diff < 4 - return "MMM D" - else if diff > 1 and diff <= 365 - return "MMM D" - else - return "MMM D YYYY" + diff = now.diff(msgDate, 'days', true) + isSameDay = now.isSame(msgDate, 'days') + if diff < 1 and isSameDay + return msgDate.format "h:mm a" + if diff < 1.5 and not isSameDay + timeAgo = msgDate.from now + monthAndDay = msgDate.format "h:mm a" + return monthAndDay + " (" + timeAgo + ")" + if diff >= 1.5 and diff < 365 + return msgDate.format "MMM D" + if diff >= 365 + return msgDate.format "MMM D, YYYY" # Stubbable for testing. Returns a `moment` _today: -> moment.tz(Utils.timeZone) diff --git a/internal_packages/message-list/spec/message-timestamp-spec.cjsx b/internal_packages/message-list/spec/message-timestamp-spec.cjsx index 87b99cb43..9dbc948c7 100644 --- a/internal_packages/message-list/spec/message-timestamp-spec.cjsx +++ b/internal_packages/message-list/spec/message-timestamp-spec.cjsx @@ -3,43 +3,39 @@ React = require 'react/addons' TestUtils = React.addons.TestUtils MessageTimestamp = require '../lib/message-timestamp' -testDate = -> - moment([2010, 1, 14, 15, 25, 50, 125]) +msgTime = -> + moment([2010, 1, 14, 15, 25, 50, 125]) # Feb 14, 2010 at 3:25pm describe "MessageTimestamp", -> beforeEach -> @item = TestUtils.renderIntoDocument( - + ) - # test messsage time is 1415814587 - it "displays the time from messages LONG ago", -> - spyOn(@item, "_today").andCallFake -> testDate().add(2, 'years') - expect(@item._timeFormat()).toBe "MMM D YYYY" - - it "displays the time and date from a while ago", -> - spyOn(@item, "_today").andCallFake -> testDate().add(7, 'days') - expect(@item._timeFormat()).toBe "MMM D" - - it "displays the time and date from messages a couple days ago", -> - spyOn(@item, "_today").andCallFake -> testDate().add(2, 'days') - expect(@item._timeFormat()).toBe "MMM D" - - it "displays the time and date messages exactly a day ago", -> - spyOn(@item, "_today").andCallFake -> testDate().add(1, 'day') - expect(@item._timeFormat()).toBe "MMM D" - - it "displays the time from messages yesterday with the day, even though it's less than 24 hours ago", -> - spyOn(@item, "_today").andCallFake -> moment([2010, 1, 15, 2, 25, 50, 125]) - expect(@item._timeFormat()).toBe "MMM D" - - it "displays the time from messages recently", -> - spyOn(@item, "_today").andCallFake -> testDate().add(2, 'hours') - expect(@item._timeFormat()).toBe "h:mm a" + it "still processes one day, even if it crosses a month divider", -> + # this should be tested in moment.js, but we add a test here for our own sanity too + feb28 = moment([2015, 1, 28]) + mar01 = moment([2015, 2, 1]) + expect(mar01.diff(feb28, 'days')).toBe 1 it "displays the full time when in detailed timestamp mode", -> - itemDetailed = TestUtils.renderIntoDocument( - - ) - spyOn(itemDetailed, "_today").andCallFake -> testDate() - expect(itemDetailed._timeFormat()).toBe "MMMM D, YYYY [at] h:mm A" + expect(@item._formattedDate(msgTime(), null, true)).toBe "February 14, 2010 at 3:25 PM" + + it "displays the time from messages shown today", -> + now = msgTime().add(2, 'hours') + expect(@item._formattedDate(msgTime(), now)).toBe "3:25 pm" + + it "displays the time from messages yesterday with the relative time if it's less than 36 hours ago", -> + now = msgTime().add(21, 'hours') + expect(@item._formattedDate(msgTime(), now)).toBe "3:25 pm (21 hours ago)" + + now = msgTime().add(30, 'hours') + expect(@item._formattedDate(msgTime(), now)).toBe "3:25 pm (a day ago)" + + it "displays month, day for messages less than a year ago, but more than 24 hours ago", -> + now = msgTime().add(2, 'months') + expect(@item._formattedDate(msgTime(), now)).toBe "Feb 14" + + it "displays month, day, and year for messages over a year ago", -> + now = msgTime().add(2, 'years') + expect(@item._formattedDate(msgTime(), now)).toBe "Feb 14, 2010" \ No newline at end of file