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