diff options
author | Samuel Newman <mozzius@protonmail.com> | 2024-10-03 18:19:38 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-03 18:19:38 +0300 |
commit | 7e79c7f768e40ef192decfeac0dfac63c3d37468 (patch) | |
tree | 95f36a2d83f639589cbdf3adef3df239a3765c72 /src/components/dms/MessageItem.tsx | |
parent | 523a9a48c21ac1aade3d703703f0e59ffeac482e (diff) | |
download | voidsky-7e79c7f768e40ef192decfeac0dfac63c3d37468.tar.zst |
[🐴] Reduce amount that message sent date is shown (#4228)
Diffstat (limited to 'src/components/dms/MessageItem.tsx')
-rw-r--r-- | src/components/dms/MessageItem.tsx | 178 |
1 files changed, 88 insertions, 90 deletions
diff --git a/src/components/dms/MessageItem.tsx b/src/components/dms/MessageItem.tsx index c5c472cf0..52220e2ca 100644 --- a/src/components/dms/MessageItem.tsx +++ b/src/components/dms/MessageItem.tsx @@ -17,13 +17,15 @@ import {useLingui} from '@lingui/react' import {ConvoItem} from '#/state/messages/convo/types' import {useSession} from '#/state/session' -import {TimeElapsed} from 'view/com/util/TimeElapsed' +import {TimeElapsed} from '#/view/com/util/TimeElapsed' import {atoms as a, useTheme} from '#/alf' import {ActionsWrapper} from '#/components/dms/ActionsWrapper' import {InlineLinkText} from '#/components/Link' import {Text} from '#/components/Typography' import {isOnlyEmoji, RichText} from '../RichText' +import {DateDivider} from './DateDivider' import {MessageItemEmbed} from './MessageItemEmbed' +import {localDateString} from './util' let MessageItem = ({ item, @@ -33,14 +35,37 @@ let MessageItem = ({ const t = useTheme() const {currentAccount} = useSession() - const {message, nextMessage} = item + const {message, nextMessage, prevMessage} = item const isPending = item.type === 'pending-message' const isFromSelf = message.sender?.did === currentAccount?.did + const nextIsMessage = ChatBskyConvoDefs.isMessageView(nextMessage) + const isNextFromSelf = - ChatBskyConvoDefs.isMessageView(nextMessage) && - nextMessage.sender?.did === currentAccount?.did + nextIsMessage && nextMessage.sender?.did === currentAccount?.did + + const isNextFromSameSender = isNextFromSelf === isFromSelf + + const isNewDay = useMemo(() => { + if (!prevMessage) return true + + const thisDate = new Date(message.sentAt) + const prevDate = new Date(prevMessage.sentAt) + + return localDateString(thisDate) !== localDateString(prevDate) + }, [message, prevMessage]) + + const isLastMessageOfDay = useMemo(() => { + if (!nextMessage || !nextIsMessage) return true + + const thisDate = new Date(message.sentAt) + const prevDate = new Date(nextMessage.sentAt) + + return localDateString(thisDate) !== localDateString(prevDate) + }, [message.sentAt, nextIsMessage, nextMessage]) + + const needsTail = isLastMessageOfDay || !isNextFromSameSender const isLastInGroup = useMemo(() => { // if this message is pending, it means the next message is pending too @@ -48,24 +73,19 @@ let MessageItem = ({ return false } - // if the next message is from a different sender, then it's the last in the group - if (isFromSelf ? !isNextFromSelf : isNextFromSelf) { - return true - } - - // or, if there's a 3 minute gap between this message and the next + // or, if there's a 5 minute gap between this message and the next if (ChatBskyConvoDefs.isMessageView(nextMessage)) { const thisDate = new Date(message.sentAt) const nextDate = new Date(nextMessage.sentAt) const diff = nextDate.getTime() - thisDate.getTime() - // 3 minutes - return diff > 3 * 60 * 1000 + // 5 minutes + return diff > 5 * 60 * 1000 } return true - }, [message, nextMessage, isFromSelf, isNextFromSelf, isPending]) + }, [message, nextMessage, isPending]) const lastInGroupRef = useRef(isLastInGroup) if (lastInGroupRef.current !== isLastInGroup) { @@ -80,52 +100,59 @@ let MessageItem = ({ }, [message.text, message.facets]) return ( - <View style={[isFromSelf ? a.mr_md : a.ml_md]}> - <ActionsWrapper isFromSelf={isFromSelf} message={message}> - {AppBskyEmbedRecord.isView(message.embed) && ( - <MessageItemEmbed embed={message.embed} /> - )} - {rt.text.length > 0 && ( - <View - style={ - !isOnlyEmoji(message.text) && [ - a.py_sm, - a.my_2xs, - a.rounded_md, - { - paddingLeft: 14, - paddingRight: 14, - backgroundColor: isFromSelf - ? isPending - ? pendingColor - : t.palette.primary_500 - : t.palette.contrast_50, - borderRadius: 17, - }, - isFromSelf ? a.self_end : a.self_start, - isFromSelf - ? {borderBottomRightRadius: isLastInGroup ? 2 : 17} - : {borderBottomLeftRadius: isLastInGroup ? 2 : 17}, - ] - }> - <RichText - value={rt} - style={[a.text_md, isFromSelf && {color: t.palette.white}]} - interactiveStyle={a.underline} - enableTags - emojiMultiplier={3} - /> - </View> - )} - </ActionsWrapper> + <> + {isNewDay && <DateDivider date={message.sentAt} />} + <View + style={[ + isFromSelf ? a.mr_md : a.ml_md, + nextIsMessage && !isNextFromSameSender && a.mb_md, + ]}> + <ActionsWrapper isFromSelf={isFromSelf} message={message}> + {AppBskyEmbedRecord.isView(message.embed) && ( + <MessageItemEmbed embed={message.embed} /> + )} + {rt.text.length > 0 && ( + <View + style={ + !isOnlyEmoji(message.text) && [ + a.py_sm, + a.my_2xs, + a.rounded_md, + { + paddingLeft: 14, + paddingRight: 14, + backgroundColor: isFromSelf + ? isPending + ? pendingColor + : t.palette.primary_500 + : t.palette.contrast_50, + borderRadius: 17, + }, + isFromSelf ? a.self_end : a.self_start, + isFromSelf + ? {borderBottomRightRadius: needsTail ? 2 : 17} + : {borderBottomLeftRadius: needsTail ? 2 : 17}, + ] + }> + <RichText + value={rt} + style={[a.text_md, isFromSelf && {color: t.palette.white}]} + interactiveStyle={a.underline} + enableTags + emojiMultiplier={3} + /> + </View> + )} + </ActionsWrapper> - {isLastInGroup && ( - <MessageItemMetadata - item={item} - style={isFromSelf ? a.text_right : a.text_left} - /> - )} - </View> + {isLastInGroup && ( + <MessageItemMetadata + item={item} + style={isFromSelf ? a.text_right : a.text_left} + /> + )} + </View> + </> ) } MessageItem = React.memo(MessageItem) @@ -165,31 +192,12 @@ let MessageItemMetadata = ({ const diff = now.getTime() - date.getTime() - // if under 1 minute - if (diff < 1000 * 60) { + // if under 30 seconds + if (diff < 1000 * 30) { return _(msg`Now`) } - // if in the last day - if (localDateString(now) === localDateString(date)) { - return time - } - - // if yesterday - const yesterday = new Date(now) - yesterday.setDate(yesterday.getDate() - 1) - - if (localDateString(yesterday) === localDateString(date)) { - return _(msg`Yesterday, ${time}`) - } - - return i18n.date(date, { - hour: 'numeric', - minute: 'numeric', - day: 'numeric', - month: 'numeric', - year: 'numeric', - }) + return time }, [_], ) @@ -242,15 +250,5 @@ let MessageItemMetadata = ({ </Text> ) } - MessageItemMetadata = React.memo(MessageItemMetadata) export {MessageItemMetadata} - -function localDateString(date: Date) { - // can't use toISOString because it should be in local time - const mm = date.getMonth() - const dd = date.getDate() - const yyyy = date.getFullYear() - // not padding with 0s because it's not necessary, it's just used for comparison - return `${yyyy}-${mm}-${dd}` -} |