diff --git a/stylesheets/components/MessageBody.scss b/stylesheets/components/MessageBody.scss index a3ab52702b..c589daa86e 100644 --- a/stylesheets/components/MessageBody.scss +++ b/stylesheets/components/MessageBody.scss @@ -54,4 +54,8 @@ background-color: $color-black-alpha-40; } } + + &__author { + @include font-body-2-bold; + } } diff --git a/ts/components/conversation/MessageBody.tsx b/ts/components/conversation/MessageBody.tsx index 960245ce59..8311d590b4 100644 --- a/ts/components/conversation/MessageBody.tsx +++ b/ts/components/conversation/MessageBody.tsx @@ -27,6 +27,7 @@ type OpenConversationActionType = ( export type Props = { direction?: 'incoming' | 'outgoing'; text: string; + author?: string; textAttachment?: Pick; /** If set, all emoji will be the same size. Otherwise, just one emoji will be large. */ disableJumbomoji?: boolean; @@ -74,6 +75,7 @@ export function MessageBody({ onIncreaseTextLength, openConversation, text, + author, textAttachment, kickOffBodyDownload, }: Props): JSX.Element { @@ -144,6 +146,20 @@ export function MessageBody({ return ( + {author && ( + <> + + {renderEmoji({ + i18n, + text: author, + sizeClass, + key: 0, + renderNonEmoji: renderNewLines, + })} + + :{' '} + + )} {disableLinks ? ( renderEmoji({ i18n, diff --git a/ts/components/conversationList/ConversationListItem.tsx b/ts/components/conversationList/ConversationListItem.tsx index 5d8f2560cf..ec09f35463 100644 --- a/ts/components/conversationList/ConversationListItem.tsx +++ b/ts/components/conversationList/ConversationListItem.tsx @@ -148,6 +148,7 @@ export const ConversationListItem: FunctionComponent = React.memo( messageText = ( { this.set({ lastMessage: null, + lastMessageAuthor: null, timestamp: null, active_at: null, pendingUniversalTimer: undefined, diff --git a/ts/models/messages.ts b/ts/models/messages.ts index cf1a8e1fa8..813e6c1260 100644 --- a/ts/models/messages.ts +++ b/ts/models/messages.ts @@ -833,6 +833,17 @@ export class MessageModel extends window.Backbone.Model { return body; } + getAuthorText(): string | undefined { + // if it's outgoing, it must be self-authored + const selfAuthor = isOutgoing(this.attributes) + ? window.i18n('you') + : undefined; + + // if it's not selfAuthor and there's no incoming contact, + // it might be a group notification, so we return undefined + return selfAuthor ?? this.getIncomingContact()?.getTitle(); + } + getNotificationText(): string { const { text, emoji } = this.getNotificationData(); const { attributes } = this; @@ -1258,12 +1269,12 @@ export class MessageModel extends window.Backbone.Model { if (!isIncoming(this.attributes)) { return null; } - const source = this.get('source'); - if (!source) { + const sourceUuid = this.get('sourceUuid'); + if (!sourceUuid) { return null; } - return window.ConversationController.getOrCreate(source, 'private'); + return window.ConversationController.getOrCreate(sourceUuid, 'private'); } async retrySend(): Promise { @@ -2723,6 +2734,7 @@ export class MessageModel extends window.Backbone.Model { ) { conversation.set({ lastMessage: message.getNotificationText(), + lastMessageAuthor: message.getAuthorText(), timestamp: message.get('sent_at'), }); } diff --git a/ts/state/ducks/conversations.ts b/ts/state/ducks/conversations.ts index d5946f8fa5..60c0866499 100644 --- a/ts/state/ducks/conversations.ts +++ b/ts/state/ducks/conversations.ts @@ -150,6 +150,7 @@ export type ConversationType = { | { status?: LastMessageStatus; text: string; + author?: string; deletedForEveryone: false; } | { deletedForEveryone: true }; diff --git a/ts/test-mock/benchmarks/group_send_bench.ts b/ts/test-mock/benchmarks/group_send_bench.ts index b5dd3e9bbf..aa3426eea3 100644 --- a/ts/test-mock/benchmarks/group_send_bench.ts +++ b/ts/test-mock/benchmarks/group_send_bench.ts @@ -124,8 +124,8 @@ const LAST_MESSAGE = 'start sending messages now'; const item = leftPane.locator( '_react=BaseConversationListItem' + - `[title = ${JSON.stringify(group.title)}]` + - `>> ${JSON.stringify(LAST_MESSAGE)}` + `[title = ${JSON.stringify(group.title)}] ` + + `>> text=${LAST_MESSAGE}` ); await item.click(); }