|
1 | 1 | import React, {Fragment} from 'react'; |
2 | 2 | import PropTypes from 'prop-types'; |
| 3 | +import {ListSeparator} from '@momentum-ui/react'; |
| 4 | +import {format, isToday, isSameWeek, isYesterday} from 'date-fns'; |
3 | 5 |
|
4 | 6 | import {RoomType} from '../../adapters/RoomsAdapter'; |
5 | 7 | import {useActivityStream, useRoom} from '../hooks'; |
6 | 8 | import WebexActivity from '../WebexActivity/WebexActivity'; |
7 | 9 |
|
8 | 10 | import './WebexActivityStream.scss'; |
9 | 11 |
|
| 12 | +/** |
| 13 | + * Returns a formatted timestamp based on the given date's offset from the current time. |
| 14 | + * |
| 15 | + * Divisor for messages from today display today |
| 16 | + * Divisor for messages from dates from a previous day display as Yesterday |
| 17 | + * Divisor for messages of dates from a previous day of the week (but not yesterday) display as <day of the week> |
| 18 | + * Divisor for messages of dates older than a week from today display as M/D/YY |
| 19 | + * |
| 20 | + * @param {Date} timestamp Date instance to format |
| 21 | + * @returns {string} formattedDate |
| 22 | + */ |
| 23 | +export function formatTimeRulerText(timestamp) { |
| 24 | + let formattedDate; |
| 25 | + |
| 26 | + if (isToday(timestamp)) { |
| 27 | + formattedDate = 'today'; |
| 28 | + } else if (isYesterday(timestamp)) { |
| 29 | + // Yesterday |
| 30 | + formattedDate = 'Yesterday'; |
| 31 | + } else if (isSameWeek(timestamp, new Date())) { |
| 32 | + // Monday |
| 33 | + formattedDate = format(timestamp, 'iiii'); |
| 34 | + } else { |
| 35 | + // 1/1/2020 |
| 36 | + formattedDate = format(timestamp, 'P'); |
| 37 | + } |
| 38 | + |
| 39 | + return formattedDate; |
| 40 | +} |
| 41 | + |
10 | 42 | export function GreetingDirectSVG() { |
11 | 43 | return ( |
12 | 44 | <svg |
@@ -138,19 +170,34 @@ Greeting.propTypes = { |
138 | 170 | personName: PropTypes.string.isRequired, |
139 | 171 | }; |
140 | 172 |
|
| 173 | +export function TimeRuler({text}) { |
| 174 | + return <ListSeparator className="time-ruler" role="listitem" text={text} />; |
| 175 | +} |
| 176 | + |
| 177 | +TimeRuler.propTypes = { |
| 178 | + text: PropTypes.string.isRequired, |
| 179 | +}; |
| 180 | + |
141 | 181 | export default function WebexActivityStream(props) { |
142 | 182 | const {roomID, adapters} = props; |
143 | 183 | const {roomsAdapter, activitiesAdapter, peopleAdapter} = adapters; |
144 | 184 | const {title, roomType} = useRoom(roomID, roomsAdapter); |
145 | | - const activityIDs = useActivityStream(roomID, roomsAdapter); |
| 185 | + const activitiesData = useActivityStream(roomID, roomsAdapter); |
146 | 186 | const personName = roomType === RoomType.DIRECT ? title : ''; |
147 | | - const activities = activityIDs.map((activityID) => ( |
148 | | - <WebexActivity key={activityID} activityID={activityID} adapters={{activitiesAdapter, peopleAdapter}} /> |
149 | | - )); |
| 187 | + const activities = activitiesData.map((activity) => { |
| 188 | + // If the activity is an object with a date property, it is a time ruler |
| 189 | + const activityComponent = activity.date ? ( |
| 190 | + <TimeRuler key={activity.date.toString()} text={formatTimeRulerText(new Date(activity.date))} /> |
| 191 | + ) : ( |
| 192 | + <WebexActivity key={activity} activityID={activity} adapters={{activitiesAdapter, peopleAdapter}} /> |
| 193 | + ); |
| 194 | + |
| 195 | + return activityComponent; |
| 196 | + }); |
150 | 197 |
|
151 | 198 | return ( |
152 | 199 | <div className="activity-stream"> |
153 | | - {activityIDs.length ? <Fragment>{activities}</Fragment> : <Greeting personName={personName} />} |
| 200 | + {activities.length ? <Fragment>{activities}</Fragment> : <Greeting personName={personName} />} |
154 | 201 | </div> |
155 | 202 | ); |
156 | 203 | } |
|
0 commit comments