From edab7c7d83e6f8478d0638636bbdc44e69599e54 Mon Sep 17 00:00:00 2001 From: Scott Nonnenberg Date: Thu, 11 Nov 2021 15:45:47 -0800 Subject: [PATCH] Remember message Read More state when scrolling in virtualized container --- .../conversation/Message.stories.tsx | 1 + ts/components/conversation/Message.tsx | 8 ++ .../MessageBodyReadMore.stories.tsx | 3 + .../conversation/MessageBodyReadMore.tsx | 21 ++- ts/components/conversation/MessageDetail.tsx | 2 + ts/components/conversation/Quote.stories.tsx | 3 +- .../conversation/Timeline.stories.tsx | 1 + ts/components/conversation/Timeline.tsx | 1 + .../conversation/TimelineItem.stories.tsx | 1 + ts/state/ducks/conversations.ts | 53 ++++++- ts/state/selectors/message.ts | 135 ++++++++++-------- ts/util/lint/exceptions.json | 2 +- 12 files changed, 159 insertions(+), 72 deletions(-) diff --git a/ts/components/conversation/Message.stories.tsx b/ts/components/conversation/Message.stories.tsx index f5a1b509f..9cfb3973f 100644 --- a/ts/components/conversation/Message.stories.tsx +++ b/ts/components/conversation/Message.stories.tsx @@ -144,6 +144,7 @@ const createProps = (overrideProps: Partial = {}): Props => ({ kickOffAttachmentDownload: action('kickOffAttachmentDownload'), markAttachmentAsCorrupted: action('markAttachmentAsCorrupted'), markViewed: action('markViewed'), + messageExpanded: action('messageExpanded'), onHeightChange: action('onHeightChange'), openConversation: action('openConversation'), openLink: action('openLink'), diff --git a/ts/components/conversation/Message.tsx b/ts/components/conversation/Message.tsx index e6d6e868c..8d07ba87b 100644 --- a/ts/components/conversation/Message.tsx +++ b/ts/components/conversation/Message.tsx @@ -131,6 +131,7 @@ export type PropsData = { conversationColor: ConversationColorType; customColor?: CustomColorType; conversationId: string; + displayLimit?: number; text?: string; textPending?: boolean; isSticker?: boolean; @@ -216,6 +217,7 @@ export type PropsActions = { clearSelectedMessage: () => unknown; doubleCheckMissingQuoteReference: (messageId: string) => unknown; onHeightChange: () => unknown; + messageExpanded: (id: string, displayLimit: number) => unknown; checkForAccount: (identifier: string) => unknown; reactToMessage: ( @@ -1229,7 +1231,10 @@ export class Message extends React.PureComponent { bodyRanges, deletedForEveryone, direction, + displayLimit, i18n, + id, + messageExpanded, onHeightChange, openConversation, status, @@ -1263,7 +1268,10 @@ export class Message extends React.PureComponent { bodyRanges={bodyRanges} disableLinks={!this.areLinksEnabled()} direction={direction} + displayLimit={displayLimit} i18n={i18n} + id={id} + messageExpanded={messageExpanded} openConversation={openConversation} onHeightChange={onHeightChange} text={contents || ''} diff --git a/ts/components/conversation/MessageBodyReadMore.stories.tsx b/ts/components/conversation/MessageBodyReadMore.stories.tsx index c4fd6d3f9..2e2db7f17 100644 --- a/ts/components/conversation/MessageBodyReadMore.stories.tsx +++ b/ts/components/conversation/MessageBodyReadMore.stories.tsx @@ -19,7 +19,10 @@ const story = storiesOf('Components/Conversation/MessageBodyReadMore', module); const createProps = (overrideProps: Partial = {}): Props => ({ bodyRanges: overrideProps.bodyRanges, direction: 'incoming', + displayLimit: overrideProps.displayLimit, i18n, + id: 'some-id', + messageExpanded: action('messageExpanded'), onHeightChange: action('onHeightChange'), text: text('text', overrideProps.text || ''), }); diff --git a/ts/components/conversation/MessageBodyReadMore.tsx b/ts/components/conversation/MessageBodyReadMore.tsx index 5a58bfe34..de7a9fbbf 100644 --- a/ts/components/conversation/MessageBodyReadMore.tsx +++ b/ts/components/conversation/MessageBodyReadMore.tsx @@ -1,10 +1,11 @@ // Copyright 2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import React, { useState } from 'react'; +import React, { useEffect } from 'react'; import type { Props as MessageBodyPropsType } from './MessageBody'; import { MessageBody } from './MessageBody'; +import { usePrevious } from '../../hooks/usePrevious'; export type Props = Pick< MessageBodyPropsType, @@ -16,6 +17,9 @@ export type Props = Pick< | 'bodyRanges' | 'openConversation' > & { + id: string; + displayLimit?: number; + messageExpanded: (id: string, displayLimit: number) => unknown; onHeightChange: () => unknown; }; @@ -57,20 +61,29 @@ export function MessageBodyReadMore({ bodyRanges, direction, disableLinks, + displayLimit, i18n, + id, + messageExpanded, onHeightChange, openConversation, text, textPending, }: Props): JSX.Element { - const [maxLength, setMaxLength] = useState(INITIAL_LENGTH); + const maxLength = displayLimit || INITIAL_LENGTH; + const previousMaxLength = usePrevious(maxLength, maxLength); + + useEffect(() => { + if (previousMaxLength !== maxLength) { + onHeightChange(); + } + }, [maxLength, previousMaxLength, onHeightChange]); const { hasReadMore, text: slicedText } = graphemeAwareSlice(text, maxLength); const onIncreaseTextLength = hasReadMore ? () => { - setMaxLength(oldMaxLength => oldMaxLength + INCREMENT_COUNT); - onHeightChange(); + messageExpanded(id, maxLength + INCREMENT_COUNT); } : undefined; diff --git a/ts/components/conversation/MessageDetail.tsx b/ts/components/conversation/MessageDetail.tsx index a5a0427e7..46d6f5619 100644 --- a/ts/components/conversation/MessageDetail.tsx +++ b/ts/components/conversation/MessageDetail.tsx @@ -313,6 +313,7 @@ export class MessageDetail extends React.Component { } disableMenu disableScroll + displayLimit={Number.MAX_SAFE_INTEGER} displayTapToViewMessage={displayTapToViewMessage} downloadAttachment={() => log.warn('MessageDetail: deleteMessageForEveryone called!') @@ -323,6 +324,7 @@ export class MessageDetail extends React.Component { kickOffAttachmentDownload={kickOffAttachmentDownload} markAttachmentAsCorrupted={markAttachmentAsCorrupted} markViewed={markViewed} + messageExpanded={noop} onHeightChange={noop} openConversation={openConversation} openLink={openLink} diff --git a/ts/components/conversation/Quote.stories.tsx b/ts/components/conversation/Quote.stories.tsx index 302f01347..37a8801aa 100644 --- a/ts/components/conversation/Quote.stories.tsx +++ b/ts/components/conversation/Quote.stories.tsx @@ -63,7 +63,8 @@ const defaultMessageProps: MessagesProps = { kickOffAttachmentDownload: action('default--kickOffAttachmentDownload'), markAttachmentAsCorrupted: action('default--markAttachmentAsCorrupted'), markViewed: action('default--markViewed'), - onHeightChange: action('onHeightChange'), + messageExpanded: action('dafult--message-expanded'), + onHeightChange: action('default--onHeightChange'), openConversation: action('default--openConversation'), openLink: action('default--openLink'), previews: [], diff --git a/ts/components/conversation/Timeline.stories.tsx b/ts/components/conversation/Timeline.stories.tsx index ff9b57ac4..3aff52acd 100644 --- a/ts/components/conversation/Timeline.stories.tsx +++ b/ts/components/conversation/Timeline.stories.tsx @@ -327,6 +327,7 @@ const actions = () => ({ kickOffAttachmentDownload: action('kickOffAttachmentDownload'), markAttachmentAsCorrupted: action('markAttachmentAsCorrupted'), markViewed: action('markViewed'), + messageExpanded: action('messageExpanded'), showVisualAttachment: action('showVisualAttachment'), downloadAttachment: action('downloadAttachment'), displayTapToViewMessage: action('displayTapToViewMessage'), diff --git a/ts/components/conversation/Timeline.tsx b/ts/components/conversation/Timeline.tsx index 9dcd62612..6b4e164ce 100644 --- a/ts/components/conversation/Timeline.tsx +++ b/ts/components/conversation/Timeline.tsx @@ -269,6 +269,7 @@ const getActions = createSelector( 'showContactModal', 'kickOffAttachmentDownload', 'markAttachmentAsCorrupted', + 'messageExpanded', 'showVisualAttachment', 'downloadAttachment', 'displayTapToViewMessage', diff --git a/ts/components/conversation/TimelineItem.stories.tsx b/ts/components/conversation/TimelineItem.stories.tsx index 1624a774e..3d6b55a36 100644 --- a/ts/components/conversation/TimelineItem.stories.tsx +++ b/ts/components/conversation/TimelineItem.stories.tsx @@ -66,6 +66,7 @@ const getDefaultProps = () => ({ learnMoreAboutDeliveryIssue: action('learnMoreAboutDeliveryIssue'), markAttachmentAsCorrupted: action('markAttachmentAsCorrupted'), markViewed: action('markViewed'), + messageExpanded: action('messageExpanded'), showMessageDetail: action('showMessageDetail'), openConversation: action('openConversation'), showContactDetail: action('showContactDetail'), diff --git a/ts/state/ducks/conversations.ts b/ts/state/ducks/conversations.ts index 79494b8d5..659efc7f5 100644 --- a/ts/state/ducks/conversations.ts +++ b/ts/state/ducks/conversations.ts @@ -87,6 +87,9 @@ export type InteractionModeType = typeof InteractionModes[number]; export type MessageType = MessageAttributesType & { interactionType?: InteractionModeType; }; +export type MessageWithUIFieldsType = MessageAttributesType & { + displayLimit?: number; +}; export const ConversationTypes = ['direct', 'group'] as const; export type ConversationTypeType = typeof ConversationTypes[number]; @@ -235,7 +238,7 @@ type MessageMetricsType = { }; export type MessageLookupType = { - [key: string]: MessageAttributesType; + [key: string]: MessageWithUIFieldsType; }; export type ConversationMessageType = { heightChangeMessageIds: Array; @@ -523,6 +526,14 @@ export type MessageDeletedActionType = { conversationId: string; }; }; +export type MessageExpandedActionType = { + type: 'MESSAGE_EXPANDED'; + payload: { + id: string; + displayLimit: number; + }; +}; + type MessageSizeChangedActionType = { type: 'MESSAGE_SIZE_CHANGED'; payload: { @@ -738,6 +749,7 @@ export type ConversationActionType = | MessageStoppedByMissingVerificationActionType | MessageChangedActionType | MessageDeletedActionType + | MessageExpandedActionType | MessageSelectedActionType | MessageSizeChangedActionType | MessagesAddedActionType @@ -801,6 +813,7 @@ export const actions = { messageStoppedByMissingVerification, messageChanged, messageDeleted, + messageExpanded, messageSizeChanged, messagesAdded, messagesReset, @@ -1504,6 +1517,18 @@ function messageDeleted( }, }; } +function messageExpanded( + id: string, + displayLimit: number +): MessageExpandedActionType { + return { + type: 'MESSAGE_EXPANDED', + payload: { + id, + displayLimit, + }, + }; +} function messageSizeChanged( id: string, conversationId: string @@ -2361,7 +2386,7 @@ export function reducer( return state; } // ...and we've already loaded that message once - const existingMessage = state.messagesLookup[id]; + const existingMessage = getOwn(state.messagesLookup, id); if (!existingMessage) { return state; } @@ -2379,7 +2404,10 @@ export function reducer( ...state, messagesLookup: { ...state.messagesLookup, - [id]: data, + [id]: { + ...data, + displayLimit: existingMessage.displayLimit, + }, }, messagesByConversation: { ...state.messagesByConversation, @@ -2390,6 +2418,25 @@ export function reducer( }, }; } + if (action.type === 'MESSAGE_EXPANDED') { + const { id, displayLimit } = action.payload; + + const existingMessage = state.messagesLookup[id]; + if (!existingMessage) { + return state; + } + + return { + ...state, + messagesLookup: { + ...state.messagesLookup, + [id]: { + ...existingMessage, + displayLimit, + }, + }, + }; + } if (action.type === 'MESSAGE_SIZE_CHANGED') { const { id, conversationId } = action.payload; diff --git a/ts/state/selectors/message.ts b/ts/state/selectors/message.ts index 12888d05d..accc4c94a 100644 --- a/ts/state/selectors/message.ts +++ b/ts/state/selectors/message.ts @@ -16,7 +16,6 @@ import filesize from 'filesize'; import type { LastMessageStatus, - MessageAttributesType, MessageReactionType, ShallowChallengeError, } from '../../model-types.d'; @@ -58,7 +57,10 @@ import { isMoreRecentThan } from '../../util/timestamp'; import * as iterables from '../../util/iterables'; import { strictAssert } from '../../util/assert'; -import type { ConversationType } from '../ducks/conversations'; +import type { + ConversationType, + MessageWithUIFieldsType, +} from '../ducks/conversations'; import type { AccountSelectorType } from './accounts'; import type { CallSelectorType, CallStateType } from './calling'; @@ -114,25 +116,25 @@ export type GetPropsForBubbleOptions = Readonly<{ }>; export function isIncoming( - message: Pick + message: Pick ): boolean { return message.type === 'incoming'; } export function isOutgoing( - message: Pick + message: Pick ): boolean { return message.type === 'outgoing'; } export function hasErrors( - message: Pick + message: Pick ): boolean { return message.errors ? message.errors.length > 0 : false; } export function getSource( - message: MessageAttributesType, + message: MessageWithUIFieldsType, ourNumber: string | undefined ): string | undefined { if (isIncoming(message)) { @@ -146,7 +148,7 @@ export function getSource( } export function getSourceDevice( - message: MessageAttributesType, + message: MessageWithUIFieldsType, ourDeviceId: number ): string | number | undefined { const { sourceDevice } = message; @@ -164,7 +166,7 @@ export function getSourceDevice( } export function getSourceUuid( - message: MessageAttributesType, + message: MessageWithUIFieldsType, ourUuid: string | undefined ): string | undefined { if (isIncoming(message)) { @@ -185,7 +187,7 @@ export type GetContactOptions = Pick< >; function getContactId( - message: MessageAttributesType, + message: MessageWithUIFieldsType, { conversationSelector, ourConversationId, @@ -206,7 +208,7 @@ function getContactId( // TODO: DESKTOP-2145 export function getContact( - message: MessageAttributesType, + message: MessageWithUIFieldsType, { conversationSelector, ourConversationId, @@ -225,7 +227,7 @@ export function getContact( } export function getConversation( - message: Pick, + message: Pick, conversationSelector: GetConversationByIdType ): ConversationType { return conversationSelector(message.conversationId); @@ -237,12 +239,12 @@ export const getAttachmentsForMessage = createSelectorCreator(memoizeByRoot)( // `memoizeByRoot` requirement identity, - ({ sticker }: MessageAttributesType) => sticker, - ({ attachments }: MessageAttributesType) => attachments, + ({ sticker }: MessageWithUIFieldsType) => sticker, + ({ attachments }: MessageWithUIFieldsType) => attachments, ( - _: MessageAttributesType, - sticker: MessageAttributesType['sticker'], - attachments: MessageAttributesType['attachments'] = [] + _: MessageWithUIFieldsType, + sticker: MessageWithUIFieldsType['sticker'], + attachments: MessageWithUIFieldsType['attachments'] = [] ): Array => { if (sticker && sticker.data) { const { data } = sticker; @@ -276,7 +278,7 @@ export const processBodyRanges = createSelectorCreator(memoizeByRoot, isEqual)( identity, ( - { bodyRanges }: Pick, + { bodyRanges }: Pick, { conversationSelector }: { conversationSelector: GetConversationByIdType } ): BodyRangesType | undefined => { if (!bodyRanges) { @@ -296,7 +298,7 @@ export const processBodyRanges = createSelectorCreator(memoizeByRoot, isEqual)( }) .sort((a, b) => b.start - a.start); }, - (_: MessageAttributesType, ranges?: BodyRangesType) => ranges + (_: MessageWithUIFieldsType, ranges?: BodyRangesType) => ranges ); const getAuthorForMessage = createSelectorCreator(memoizeByRoot)( @@ -305,7 +307,10 @@ const getAuthorForMessage = createSelectorCreator(memoizeByRoot)( getContact, - (_: MessageAttributesType, convo: ConversationType): PropsData['author'] => { + ( + _: MessageWithUIFieldsType, + convo: ConversationType + ): PropsData['author'] => { const { acceptedMessageRequest, avatarPath, @@ -347,7 +352,7 @@ const getCachedAuthorForMessage = createSelectorCreator(memoizeByRoot, isEqual)( getAuthorForMessage, ( - _: MessageAttributesType, + _: MessageWithUIFieldsType, author: PropsData['author'] ): PropsData['author'] => author ); @@ -356,11 +361,11 @@ export const getPreviewsForMessage = createSelectorCreator(memoizeByRoot)( // `memoizeByRoot` requirement identity, - ({ preview }: MessageAttributesType) => preview, + ({ preview }: MessageWithUIFieldsType) => preview, ( - _: MessageAttributesType, - previews: MessageAttributesType['preview'] = [] + _: MessageWithUIFieldsType, + previews: MessageWithUIFieldsType['preview'] = [] ): Array => { return previews.map(preview => ({ ...preview, @@ -379,7 +384,7 @@ export const getReactionsForMessage = createSelectorCreator( identity, ( - { reactions = [] }: MessageAttributesType, + { reactions = [] }: MessageWithUIFieldsType, { conversationSelector }: { conversationSelector: GetConversationByIdType } ) => { const reactionBySender = new Map(); @@ -430,7 +435,7 @@ export const getReactionsForMessage = createSelectorCreator( return [...formattedReactions]; }, - (_: MessageAttributesType, reactions: PropsData['reactions']) => reactions + (_: MessageWithUIFieldsType, reactions: PropsData['reactions']) => reactions ); export const getPropsForQuote = createSelectorCreator(memoizeByRoot, isEqual)( @@ -438,7 +443,7 @@ export const getPropsForQuote = createSelectorCreator(memoizeByRoot, isEqual)( identity, ( - message: Pick, + message: Pick, { conversationSelector, ourConversationId, @@ -528,6 +533,7 @@ type ShallowPropsType = Pick< | 'customColor' | 'deletedForEveryone' | 'direction' + | 'displayLimit' | 'expirationLength' | 'expirationTimestamp' | 'id' @@ -552,7 +558,7 @@ const getShallowPropsForMessage = createSelectorCreator(memoizeByRoot, isEqual)( identity, ( - message: MessageAttributesType, + message: MessageWithUIFieldsType, { accountSelector, conversationSelector, @@ -611,6 +617,7 @@ const getShallowPropsForMessage = createSelectorCreator(memoizeByRoot, isEqual)( defaultConversationColor.customColorData?.value, deletedForEveryone: message.deletedForEveryone || false, direction: isIncoming(message) ? 'incoming' : 'outgoing', + displayLimit: message.displayLimit, expirationLength, expirationTimestamp, id: message.id, @@ -681,7 +688,7 @@ export const getBubblePropsForMessage = createSelectorCreator(memoizeByRoot)( // Top-level prop generation for the message bubble export function getPropsForBubble( - message: MessageAttributesType, + message: MessageWithUIFieldsType, options: GetPropsForBubbleOptions ): TimelineItemType { if (isUnsupportedMessage(message)) { @@ -780,7 +787,9 @@ export function getPropsForBubble( // Unsupported Message -export function isUnsupportedMessage(message: MessageAttributesType): boolean { +export function isUnsupportedMessage( + message: MessageWithUIFieldsType +): boolean { const versionAtReceive = message.supportedVersionAtReceive; const requiredVersion = message.requiredProtocolVersion; @@ -792,7 +801,7 @@ export function isUnsupportedMessage(message: MessageAttributesType): boolean { } function getPropsForUnsupportedMessage( - message: MessageAttributesType, + message: MessageWithUIFieldsType, options: GetContactOptions ): PropsForUnsupportedMessage { const CURRENT_PROTOCOL_VERSION = Proto.DataMessage.ProtocolVersion.CURRENT; @@ -812,12 +821,12 @@ function getPropsForUnsupportedMessage( // GroupV2 Change -export function isGroupV2Change(message: MessageAttributesType): boolean { +export function isGroupV2Change(message: MessageWithUIFieldsType): boolean { return Boolean(message.groupV2Change); } function getPropsForGroupV2Change( - message: MessageAttributesType, + message: MessageWithUIFieldsType, { conversationSelector, ourUuid }: GetPropsForBubbleOptions ): GroupsV2Props { const change = message.groupV2Change; @@ -837,12 +846,12 @@ function getPropsForGroupV2Change( // GroupV1 Migration -export function isGroupV1Migration(message: MessageAttributesType): boolean { +export function isGroupV1Migration(message: MessageWithUIFieldsType): boolean { return message.type === 'group-v1-migration'; } function getPropsForGroupV1Migration( - message: MessageAttributesType, + message: MessageWithUIFieldsType, { conversationSelector }: GetPropsForBubbleOptions ): GroupV1MigrationPropsType { const migration = message.groupMigration; @@ -887,7 +896,7 @@ function getPropsForGroupV1Migration( // Message History Unsynced export function isMessageHistoryUnsynced( - message: MessageAttributesType + message: MessageWithUIFieldsType ): boolean { return message.type === 'message-history-unsynced'; } @@ -897,7 +906,7 @@ export function isMessageHistoryUnsynced( // Expiration Timer Update export function isExpirationTimerUpdate( - message: Pick + message: Pick ): boolean { const flag = Proto.DataMessage.Flags.EXPIRATION_TIMER_UPDATE; // eslint-disable-next-line no-bitwise @@ -905,7 +914,7 @@ export function isExpirationTimerUpdate( } function getPropsForTimerNotification( - message: MessageAttributesType, + message: MessageWithUIFieldsType, { ourConversationId, conversationSelector }: GetPropsForBubbleOptions ): TimerNotificationProps { const timerUpdate = message.expirationTimerUpdate; @@ -951,12 +960,12 @@ function getPropsForTimerNotification( // Key Change -export function isKeyChange(message: MessageAttributesType): boolean { +export function isKeyChange(message: MessageWithUIFieldsType): boolean { return message.type === 'keychange'; } function getPropsForSafetyNumberNotification( - message: MessageAttributesType, + message: MessageWithUIFieldsType, { conversationSelector }: GetPropsForBubbleOptions ): SafetyNumberNotificationProps { const conversation = getConversation(message, conversationSelector); @@ -972,12 +981,12 @@ function getPropsForSafetyNumberNotification( // Verified Change -export function isVerifiedChange(message: MessageAttributesType): boolean { +export function isVerifiedChange(message: MessageWithUIFieldsType): boolean { return message.type === 'verified-change'; } function getPropsForVerificationNotification( - message: MessageAttributesType, + message: MessageWithUIFieldsType, { conversationSelector }: GetPropsForBubbleOptions ): VerificationNotificationProps { const type = message.verified ? 'markVerified' : 'markNotVerified'; @@ -994,13 +1003,13 @@ function getPropsForVerificationNotification( // Group Update (V1) export function isGroupUpdate( - message: Pick + message: Pick ): boolean { return Boolean(message.group_update); } function getPropsForGroupNotification( - message: MessageAttributesType, + message: MessageWithUIFieldsType, options: GetContactOptions ): GroupNotificationProps { const groupUpdate = message.group_update; @@ -1075,7 +1084,7 @@ function getPropsForGroupNotification( // End Session export function isEndSession( - message: Pick + message: Pick ): boolean { const flag = Proto.DataMessage.Flags.END_SESSION; // eslint-disable-next-line no-bitwise @@ -1084,7 +1093,7 @@ export function isEndSession( // Call History -export function isCallHistory(message: MessageAttributesType): boolean { +export function isCallHistory(message: MessageWithUIFieldsType): boolean { return message.type === 'call-history'; } @@ -1094,7 +1103,7 @@ export type GetPropsForCallHistoryOptions = Pick< >; export function getPropsForCallHistory( - message: MessageAttributesType, + message: MessageWithUIFieldsType, { conversationSelector, callSelector, @@ -1151,12 +1160,12 @@ export function getPropsForCallHistory( // Profile Change -export function isProfileChange(message: MessageAttributesType): boolean { +export function isProfileChange(message: MessageWithUIFieldsType): boolean { return message.type === 'profile-change'; } function getPropsForProfileChange( - message: MessageAttributesType, + message: MessageWithUIFieldsType, { conversationSelector }: GetPropsForBubbleOptions ): ProfileChangeNotificationPropsType { const change = message.profileChange; @@ -1178,7 +1187,7 @@ function getPropsForProfileChange( // Note: smart, so props not generated here export function isUniversalTimerNotification( - message: MessageAttributesType + message: MessageWithUIFieldsType ): boolean { return message.type === 'universal-timer-notification'; } @@ -1186,13 +1195,13 @@ export function isUniversalTimerNotification( // Change Number Notification export function isChangeNumberNotification( - message: MessageAttributesType + message: MessageWithUIFieldsType ): boolean { return message.type === 'change-number-notification'; } function getPropsForChangeNumberNotification( - message: MessageAttributesType, + message: MessageWithUIFieldsType, { conversationSelector }: GetPropsForBubbleOptions ): ChangeNumberNotificationProps { return { @@ -1204,7 +1213,7 @@ function getPropsForChangeNumberNotification( // Chat Session Refreshed export function isChatSessionRefreshed( - message: MessageAttributesType + message: MessageWithUIFieldsType ): boolean { return message.type === 'chat-session-refreshed'; } @@ -1213,12 +1222,12 @@ export function isChatSessionRefreshed( // Delivery Issue -export function isDeliveryIssue(message: MessageAttributesType): boolean { +export function isDeliveryIssue(message: MessageWithUIFieldsType): boolean { return message.type === 'delivery-issue'; } function getPropsForDeliveryIssue( - message: MessageAttributesType, + message: MessageWithUIFieldsType, { conversationSelector }: GetPropsForBubbleOptions ): DeliveryIssuePropsType { const sender = conversationSelector(message.sourceUuid); @@ -1232,7 +1241,7 @@ function getPropsForDeliveryIssue( // Other utility functions -export function isTapToView(message: MessageAttributesType): boolean { +export function isTapToView(message: MessageWithUIFieldsType): boolean { // If a message is deleted for everyone, that overrides all other styling if (message.deletedForEveryone) { return false; @@ -1259,7 +1268,7 @@ function createNonBreakingLastSeparator(text?: string): string { export function getMessagePropStatus( message: Pick< - MessageAttributesType, + MessageWithUIFieldsType, 'type' | 'errors' | 'sendStateByConversationId' >, ourConversationId: string @@ -1318,7 +1327,7 @@ export function getMessagePropStatus( } export function getPropsForEmbeddedContact( - message: MessageAttributesType, + message: MessageWithUIFieldsType, regionCode: string, accountSelector: (identifier?: string) => boolean ): EmbeddedContactType | undefined { @@ -1400,7 +1409,7 @@ function processQuoteAttachment( function canReplyOrReact( message: Pick< - MessageAttributesType, + MessageWithUIFieldsType, 'deletedForEveryone' | 'sendStateByConversationId' | 'type' >, ourConversationId: string, @@ -1445,7 +1454,7 @@ function canReplyOrReact( export function canReply( message: Pick< - MessageAttributesType, + MessageWithUIFieldsType, | 'conversationId' | 'deletedForEveryone' | 'sendStateByConversationId' @@ -1466,7 +1475,7 @@ export function canReply( export function canReact( message: Pick< - MessageAttributesType, + MessageWithUIFieldsType, | 'conversationId' | 'deletedForEveryone' | 'sendStateByConversationId' @@ -1481,7 +1490,7 @@ export function canReact( export function canDeleteForEveryone( message: Pick< - MessageAttributesType, + MessageWithUIFieldsType, 'type' | 'deletedForEveryone' | 'sent_at' | 'sendStateByConversationId' > ): boolean { @@ -1501,7 +1510,7 @@ export function canDeleteForEveryone( } export function canDownload( - message: MessageAttributesType, + message: MessageWithUIFieldsType, conversationSelector: GetConversationByIdType ): boolean { if (isOutgoing(message)) { @@ -1526,7 +1535,7 @@ export function canDownload( } export function getLastChallengeError( - message: Pick + message: Pick ): ShallowChallengeError | undefined { const { errors } = message; if (!errors) { diff --git a/ts/util/lint/exceptions.json b/ts/util/lint/exceptions.json index 3b6a1c769..bcf51e011 100644 --- a/ts/util/lint/exceptions.json +++ b/ts/util/lint/exceptions.json @@ -11994,4 +11994,4 @@ "reasonCategory": "usageTrusted", "updated": "2021-09-17T21:02:59.414Z" } -] \ No newline at end of file +]