diff --git a/src/website/public/components/MessagesList.tsx b/src/website/public/components/MessagesList.tsx index 130432fe7d..9b585043eb 100644 --- a/src/website/public/components/MessagesList.tsx +++ b/src/website/public/components/MessagesList.tsx @@ -2,10 +2,12 @@ import React from "react"; import { useSelector } from "react-redux"; import { RootState } from "../reducers"; +import DayChangeMarker from "./messages/DayChangeMarker"; import DirectMessageSentByThem from "./messages/DirectMessageSentByThem"; import GroupMessageSentByElse from "./messages/GroupMessageSentByElse"; import MessageSentByMe from "./messages/MessageSentByMe"; import RemoteMessage from "./messages/RemoteMessage"; +import * as timestamp from "../utils/timestamp"; export default MessagesList; @@ -20,52 +22,65 @@ function MessagesList() { const chat = chatsState.chats[chatsState.selectedChatIndex]; - const confirmedMessages = chat.kind === "direct" - ? chat.confirmedMessages.map(m => { - switch (m.kind) { - case "local": - const sentByMe = m.sender === myUserId; - if (sentByMe) { - const props = { - message: m.text, - timestamp: m.timestamp, - confirmed: true - }; - return ; - } else if (chat.kind === "direct") { - const props = { - message: m.text, - timestamp: m.timestamp - }; - return ; - } else { - const props = { - message: m.text, - timestamp: m.timestamp, - senderUsername: usersDictionary.hasOwnProperty(m.sender) ? usersDictionary[m.sender] : "" - }; - return ; - } + const children: JSX.Element[] = []; - case "remote": - return + if (chat.kind !== "newDirect") { + let prevDate: Date | null = null; + let prevDayString: string | null = null; + for (let i = 0; i < chat.confirmedMessages.length; i++) { + const message = chat.confirmedMessages[i]; + if (message.kind === "local") { + const date = timestamp.asDate(message.timestamp); + const dayString = date.toDateString(); + if (prevDayString === null || prevDayString !== dayString) { + children.push(); + } + + const sentByMe = message.sender === myUserId; + if (sentByMe) { + const props = { + message: message.text, + date, + confirmed: true + }; + children.push(); + } else if (chat.kind === "direct") { + const props = { + message: message.text, + date + }; + children.push(); + } else { + const props = { + message: message.text, + date, + senderUsername: usersDictionary.hasOwnProperty(message.sender) + ? usersDictionary[message.sender] + : "" + }; + children.push(); + } + prevDate = date; + prevDayString = dayString; + } else if (message.kind === "remote") { + children.push(); } - }) - : null; + } + } - const unconfirmedMessages = chat.unconfirmedMessages.map(m => { + for (let i = 0; i < chat.unconfirmedMessages.length; i++) { + const message = chat.unconfirmedMessages[i]; const props = { - message: m.text, - timestamp: m.timestamp, + message: message.text, + date: timestamp.asDate(message.timestamp), confirmed: false }; - return ; - }); + children.push(); + } return (
- {confirmedMessages} - {unconfirmedMessages} + {children}
); } diff --git a/src/website/public/components/messages/DayChangeMarker.tsx b/src/website/public/components/messages/DayChangeMarker.tsx new file mode 100644 index 0000000000..354068704b --- /dev/null +++ b/src/website/public/components/messages/DayChangeMarker.tsx @@ -0,0 +1,26 @@ +import React from "react"; + +export default DayChangeMarker; + +interface Props { + date: Date +} + +function DayChangeMarker(props : Props) { + const dayOfWeek = props.date.toLocaleDateString("en", { weekday: "long" }); + const dayOfMonth = props.date.getDate(); + const month = props.date.toLocaleDateString("en", { month: "long" }); + const ordinal = getOrdinal(dayOfMonth); + const year = props.date.getFullYear(); + + const text = `-- ${dayOfWeek} ${dayOfMonth}${ordinal} ${month} ${year} --`; + + return ( +
{text}
+ ); +} + +function getOrdinal(n: number) : string { + // Taken from https://stackoverflow.com/a/39466341 + return [,"st","nd","rd"][n/10%10^1&&n%10]||"th"; +} diff --git a/src/website/public/components/messages/DirectMessageSentByThem.tsx b/src/website/public/components/messages/DirectMessageSentByThem.tsx index 1813a657dd..6b62f311a9 100644 --- a/src/website/public/components/messages/DirectMessageSentByThem.tsx +++ b/src/website/public/components/messages/DirectMessageSentByThem.tsx @@ -1,12 +1,10 @@ import React from "react"; -import { Timestamp } from "../../model/common"; - export default DirectMessageSentByThem; -interface Props { +type Props = { message: string, - timestamp: Timestamp + date: Date } function DirectMessageSentByThem(props : Props) { diff --git a/src/website/public/components/messages/GroupMessageSentByElse.tsx b/src/website/public/components/messages/GroupMessageSentByElse.tsx index 68a1b115e0..1611fabe5a 100644 --- a/src/website/public/components/messages/GroupMessageSentByElse.tsx +++ b/src/website/public/components/messages/GroupMessageSentByElse.tsx @@ -1,10 +1,8 @@ import React from "react"; -import { Timestamp } from "../../model/common"; - interface Props { message: string, - timestamp: Timestamp, + date: Date, senderUsername: string } diff --git a/src/website/public/components/messages/MessageSentByMe.tsx b/src/website/public/components/messages/MessageSentByMe.tsx index 2eb3d51d5c..96587dbeed 100644 --- a/src/website/public/components/messages/MessageSentByMe.tsx +++ b/src/website/public/components/messages/MessageSentByMe.tsx @@ -1,12 +1,10 @@ import React from "react"; -import { Timestamp } from "../../model/common"; - export default MessageSentByMe; interface Props { message: string, - timestamp: Timestamp, + date: Date, confirmed: boolean } diff --git a/src/website/public/utils/timestamp.ts b/src/website/public/utils/timestamp.ts index ad808b7147..9b31db7f64 100644 --- a/src/website/public/utils/timestamp.ts +++ b/src/website/public/utils/timestamp.ts @@ -3,3 +3,7 @@ import { Timestamp } from "../model/common"; export function getCurrent() : Timestamp { return Date.now(); } + +export function asDate(timestamp: Timestamp) : Date { + return new Date(timestamp); +}