diff --git a/ts/components/ConversationList.stories.tsx b/ts/components/ConversationList.stories.tsx index 9d4009bcee..86fd64f6c5 100644 --- a/ts/components/ConversationList.stories.tsx +++ b/ts/components/ConversationList.stories.tsx @@ -230,6 +230,7 @@ story.add('Contact checkboxes: disabled', () => ( MessageStatuses.reduce((m, s) => ({ ...m, [s]: s }), {}), 'read' ), + deletedForEveryone: false, }, lastUpdated: date( 'lastUpdated', @@ -264,6 +265,7 @@ story.add('Contact checkboxes: disabled', () => ( lastMessage: { text: 'Just a second', status: 'read', + deletedForEveryone: false, }, name: 'Myself', title: 'Myself', @@ -277,7 +279,7 @@ story.add('Contact checkboxes: disabled', () => ( MessageStatuses.map(status => ({ type: RowType.Conversation, conversation: createConversation({ - lastMessage: { text: status, status }, + lastMessage: { text: status, status, deletedForEveryone: false }, }), })) )} @@ -302,11 +304,7 @@ story.add('Contact checkboxes: disabled', () => ( story.add('Conversation: Deleted for everyone', () => renderConversation({ - lastMessage: { - status: 'sent', - text: 'You should not see this!', - deletedForEveryone: true, - }, + lastMessage: { deletedForEveryone: true }, }) ); @@ -316,6 +314,7 @@ story.add('Contact checkboxes: disabled', () => ( lastMessage: { text: 'A Message', status: 'delivered', + deletedForEveryone: false, }, }) ); @@ -326,7 +325,11 @@ story.add('Contact checkboxes: disabled', () => ( [4, 10, 250].map(unreadCount => ({ type: RowType.Conversation, conversation: createConversation({ - lastMessage: { text: 'Hey there!', status: 'delivered' }, + lastMessage: { + text: 'Hey there!', + status: 'delivered', + deletedForEveryone: false, + }, unreadCount, }), })) @@ -343,6 +346,7 @@ story.add('Contact checkboxes: disabled', () => ( lastMessage: { text: 'Hey there!', status: 'read', + deletedForEveryone: false, }, isSelected: true, }) @@ -353,6 +357,7 @@ story.add('Contact checkboxes: disabled', () => ( lastMessage: { text: '🔥', status: 'read', + deletedForEveryone: false, }, }) ); @@ -362,6 +367,7 @@ story.add('Contact checkboxes: disabled', () => ( lastMessage: { text: 'Download at http://signal.org', status: 'read', + deletedForEveryone: false, }, }) ); @@ -394,6 +400,7 @@ Line 4, well.`, lastMessage: { text: messageText, status: 'read', + deletedForEveryone: false, }, }), })) @@ -420,6 +427,7 @@ Line 4, well.`, lastMessage: { text: messageText, status: 'read', + deletedForEveryone: false, }, }), })) @@ -449,9 +457,9 @@ Line 4, well.`, story.add('Conversation: Missing Text', () => renderConversation({ lastMessage: { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - text: undefined as any, + text: '', status: 'sent', + deletedForEveryone: false, }, }) ); @@ -469,6 +477,7 @@ Line 4, well.`, lastMessage: { text: '@Leia Organa I know', status: 'read', + deletedForEveryone: false, }, }) ); diff --git a/ts/components/conversationList/ConversationListItem.tsx b/ts/components/conversationList/ConversationListItem.tsx index 3b7c16bae0..5fb45cc1ec 100644 --- a/ts/components/conversationList/ConversationListItem.tsx +++ b/ts/components/conversationList/ConversationListItem.tsx @@ -97,60 +97,44 @@ export const ConversationListItem: FunctionComponent = React.memo( let messageText: ReactNode = null; let messageStatusIcon: ReactNode = null; - if (lastMessage || typingContact) { - const messageBody = lastMessage ? lastMessage.text : ''; - const showingDraft = shouldShowDraft && draftPreview; - const deletedForEveryone = Boolean( - lastMessage && lastMessage.deletedForEveryone + if (!acceptedMessageRequest) { + messageText = ( + + {i18n('ConversationListItem--message-request')} + ); - - /* eslint-disable no-nested-ternary */ + } else if (typingContact) { + messageText = ; + } else if (shouldShowDraft && draftPreview) { messageText = ( <> - {muteExpiresAt && Date.now() < muteExpiresAt ? ( - - ) : null} - {!acceptedMessageRequest ? ( - - {i18n('ConversationListItem--message-request')} - - ) : typingContact ? ( - - ) : ( - <> - {showingDraft ? ( - <> - - {i18n('ConversationListItem--draft-prefix')} - - - - ) : deletedForEveryone ? ( - - {i18n('message--deletedForEveryone')} - - ) : ( - - )} - - )} + + {i18n('ConversationListItem--draft-prefix')} + + ); - /* eslint-enable no-nested-ternary */ - - if (!showingDraft && lastMessage && lastMessage.status) { + } else if (lastMessage?.deletedForEveryone) { + messageText = ( + + {i18n('message--deletedForEveryone')} + + ); + } else if (lastMessage) { + messageText = ( + + ); + if (lastMessage.status) { messageStatusIcon = (
= React.memo( } } + const isMuted = Boolean(muteExpiresAt && Date.now() < muteExpiresAt); + if (isMuted) { + messageText = ( + <> + + {messageText} + + ); + } + const onClickItem = useCallback(() => onClick(id), [onClick, id]); return ( diff --git a/ts/models/conversations.ts b/ts/models/conversations.ts index c32b046585..0a81eae18c 100644 --- a/ts/models/conversations.ts +++ b/ts/models/conversations.ts @@ -7,6 +7,7 @@ import { compact } from 'lodash'; import { ConversationAttributesType, ConversationModelCollectionType, + LastMessageStatus, MessageAttributesType, MessageModelCollectionType, QuotedMessageType, @@ -50,6 +51,7 @@ import { BodyRangesType } from '../types/Util'; import { getTextWithMentions } from '../util'; import { migrateColor } from '../util/migrateColor'; import { isNotNil } from '../util/isNotNil'; +import { dropNull } from '../util/dropNull'; import { ourProfileKeyService } from '../services/ourProfileKey'; import { getSendOptions } from '../util/getSendOptions'; import { isConversationAccepted } from '../util/isConversationAccepted'; @@ -1348,6 +1350,28 @@ export class ConversationModel extends window.Backbone // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const color = this.getColor()!; + let lastMessage: + | undefined + | { + status?: LastMessageStatus; + text: string; + deletedForEveryone: false; + } + | { deletedForEveryone: true }; + + if (this.get('lastMessageDeletedForEveryone')) { + lastMessage = { deletedForEveryone: true }; + } else { + const lastMessageText = this.get('lastMessage'); + if (lastMessageText) { + lastMessage = { + status: dropNull(this.get('lastMessageStatus')), + text: lastMessageText, + deletedForEveryone: false, + }; + } + } + const typingValues = window._.values(this.contactTypingTimers || {}); const typingMostRecent = window._.first( window._.sortBy(typingValues, 'timestamp') @@ -1440,11 +1464,7 @@ export class ConversationModel extends window.Backbone isUntrusted: this.isUntrusted(), isVerified: this.isVerified(), isFetchingUUID: this.isFetchingUUID, - lastMessage: { - status: this.get('lastMessageStatus')!, - text: this.get('lastMessage')!, - deletedForEveryone: this.get('lastMessageDeletedForEveryone')!, - }, + lastMessage, lastUpdated: this.get('timestamp')!, left: Boolean(this.get('left')), markedUnread: this.get('markedUnread')!, diff --git a/ts/state/ducks/conversations.ts b/ts/state/ducks/conversations.ts index a0b73b3ee8..78f11a8a24 100644 --- a/ts/state/ducks/conversations.ts +++ b/ts/state/ducks/conversations.ts @@ -116,11 +116,13 @@ export type ConversationType = { timestamp?: number; inboxPosition?: number; left?: boolean; - lastMessage?: { - status: LastMessageStatus; - text: string; - deletedForEveryone?: boolean; - }; + lastMessage?: + | { + status?: LastMessageStatus; + text: string; + deletedForEveryone: false; + } + | { deletedForEveryone: true }; markedUnread?: boolean; phoneNumber?: string; membersCount?: number;