2022-01-26 23:05:26 +00:00
|
|
|
// Copyright 2019-2022 Signal Messenger, LLC
|
2020-10-30 20:34:04 +00:00
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
2021-10-26 19:15:33 +00:00
|
|
|
import type { RefObject } from 'react';
|
|
|
|
import React from 'react';
|
2019-03-20 17:42:28 +00:00
|
|
|
import { connect } from 'react-redux';
|
2019-08-09 00:46:49 +00:00
|
|
|
|
2019-03-20 17:42:28 +00:00
|
|
|
import { mapDispatchToProps } from '../actions';
|
2021-10-26 19:15:33 +00:00
|
|
|
import type { StateType } from '../reducer';
|
2019-03-20 17:42:28 +00:00
|
|
|
|
2019-08-09 00:46:49 +00:00
|
|
|
import { TimelineItem } from '../../components/conversation/TimelineItem';
|
2021-11-17 21:11:46 +00:00
|
|
|
import { getPreferredBadgeSelector } from '../selectors/badges';
|
2021-03-24 22:06:12 +00:00
|
|
|
import { getIntl, getInteractionMode, getTheme } from '../selectors/user';
|
2019-11-07 21:36:16 +00:00
|
|
|
import {
|
2021-05-28 16:15:17 +00:00
|
|
|
getConversationSelector,
|
2019-11-07 21:36:16 +00:00
|
|
|
getMessageSelector,
|
|
|
|
getSelectedMessage,
|
|
|
|
} from '../selectors/conversations';
|
2022-03-28 22:55:12 +00:00
|
|
|
import {
|
|
|
|
areMessagesInSameGroup,
|
|
|
|
shouldCurrentMessageHideMetadata,
|
|
|
|
UnreadIndicatorPlacement,
|
|
|
|
} from '../../util/timelineUtil';
|
2019-03-20 17:42:28 +00:00
|
|
|
|
2020-09-09 02:25:05 +00:00
|
|
|
import { SmartContactName } from './ContactName';
|
2021-06-01 20:45:43 +00:00
|
|
|
import { SmartUniversalTimerNotification } from './UniversalTimerNotification';
|
2022-03-28 22:55:12 +00:00
|
|
|
import { isSameDay } from '../../util/timestamp';
|
2020-09-09 02:25:05 +00:00
|
|
|
|
2019-03-20 17:42:28 +00:00
|
|
|
type ExternalProps = {
|
2021-08-20 19:36:27 +00:00
|
|
|
containerElementRef: RefObject<HTMLElement>;
|
2021-09-10 23:59:41 +00:00
|
|
|
conversationId: string;
|
2022-01-26 23:05:26 +00:00
|
|
|
isOldestTimelineItem: boolean;
|
2021-09-10 23:59:41 +00:00
|
|
|
messageId: string;
|
|
|
|
nextMessageId: undefined | string;
|
|
|
|
previousMessageId: undefined | string;
|
2022-03-08 14:32:42 +00:00
|
|
|
unreadIndicatorPlacement: undefined | UnreadIndicatorPlacement;
|
2019-03-20 17:42:28 +00:00
|
|
|
};
|
|
|
|
|
2020-09-09 02:25:05 +00:00
|
|
|
function renderContact(conversationId: string): JSX.Element {
|
2021-11-01 19:13:35 +00:00
|
|
|
return <SmartContactName conversationId={conversationId} />;
|
2020-09-09 02:25:05 +00:00
|
|
|
}
|
|
|
|
|
2021-06-01 20:45:43 +00:00
|
|
|
function renderUniversalTimerNotification(): JSX.Element {
|
|
|
|
return <SmartUniversalTimerNotification />;
|
|
|
|
}
|
|
|
|
|
2019-03-20 17:42:28 +00:00
|
|
|
const mapStateToProps = (state: StateType, props: ExternalProps) => {
|
2021-09-10 23:59:41 +00:00
|
|
|
const {
|
|
|
|
containerElementRef,
|
|
|
|
conversationId,
|
2022-01-26 23:05:26 +00:00
|
|
|
isOldestTimelineItem,
|
2021-09-10 23:59:41 +00:00
|
|
|
messageId,
|
|
|
|
nextMessageId,
|
|
|
|
previousMessageId,
|
2022-03-08 14:32:42 +00:00
|
|
|
unreadIndicatorPlacement,
|
2021-09-10 23:59:41 +00:00
|
|
|
} = props;
|
2019-03-20 17:42:28 +00:00
|
|
|
|
|
|
|
const messageSelector = getMessageSelector(state);
|
2021-09-10 23:59:41 +00:00
|
|
|
|
|
|
|
const item = messageSelector(messageId);
|
|
|
|
const previousItem = previousMessageId
|
|
|
|
? messageSelector(previousMessageId)
|
|
|
|
: undefined;
|
|
|
|
const nextItem = nextMessageId ? messageSelector(nextMessageId) : undefined;
|
2019-03-20 17:42:28 +00:00
|
|
|
|
2019-11-07 21:36:16 +00:00
|
|
|
const selectedMessage = getSelectedMessage(state);
|
2021-09-10 23:59:41 +00:00
|
|
|
const isSelected = Boolean(
|
|
|
|
selectedMessage && messageId === selectedMessage.id
|
|
|
|
);
|
2019-11-07 21:36:16 +00:00
|
|
|
|
2021-05-28 16:15:17 +00:00
|
|
|
const conversation = getConversationSelector(state)(conversationId);
|
|
|
|
|
2022-03-28 22:55:12 +00:00
|
|
|
const isNextItemCallingNotification = nextItem?.type === 'callHistory';
|
|
|
|
|
|
|
|
const shouldCollapseAbove = areMessagesInSameGroup(
|
|
|
|
previousItem,
|
|
|
|
unreadIndicatorPlacement === UnreadIndicatorPlacement.JustAbove,
|
|
|
|
item
|
|
|
|
);
|
|
|
|
const shouldCollapseBelow = areMessagesInSameGroup(
|
|
|
|
item,
|
|
|
|
unreadIndicatorPlacement === UnreadIndicatorPlacement.JustBelow,
|
|
|
|
nextItem
|
|
|
|
);
|
|
|
|
const shouldHideMetadata = shouldCurrentMessageHideMetadata(
|
|
|
|
shouldCollapseBelow,
|
|
|
|
item,
|
|
|
|
nextItem
|
|
|
|
);
|
|
|
|
const shouldRenderDateHeader =
|
|
|
|
isOldestTimelineItem ||
|
|
|
|
Boolean(
|
|
|
|
item &&
|
|
|
|
previousItem &&
|
|
|
|
// This comparison avoids strange header behavior for out-of-order messages.
|
|
|
|
item.timestamp > previousItem.timestamp &&
|
|
|
|
!isSameDay(previousItem.timestamp, item.timestamp)
|
|
|
|
);
|
|
|
|
|
2019-03-20 17:42:28 +00:00
|
|
|
return {
|
2019-05-31 22:42:01 +00:00
|
|
|
item,
|
2021-09-10 23:59:41 +00:00
|
|
|
id: messageId,
|
2021-08-20 19:36:27 +00:00
|
|
|
containerElementRef,
|
2019-11-07 21:36:16 +00:00
|
|
|
conversationId,
|
2022-05-11 20:59:58 +00:00
|
|
|
conversationColor: conversation.conversationColor,
|
|
|
|
customColor: conversation.customColor,
|
2021-11-17 21:11:46 +00:00
|
|
|
getPreferredBadge: getPreferredBadgeSelector(state),
|
2022-03-28 22:55:12 +00:00
|
|
|
isNextItemCallingNotification,
|
2019-11-07 21:36:16 +00:00
|
|
|
isSelected,
|
2020-09-09 02:25:05 +00:00
|
|
|
renderContact,
|
2021-06-01 20:45:43 +00:00
|
|
|
renderUniversalTimerNotification,
|
2022-03-28 22:55:12 +00:00
|
|
|
shouldCollapseAbove,
|
|
|
|
shouldCollapseBelow,
|
|
|
|
shouldHideMetadata,
|
|
|
|
shouldRenderDateHeader,
|
2019-03-20 17:42:28 +00:00
|
|
|
i18n: getIntl(state),
|
2021-03-24 22:06:12 +00:00
|
|
|
interactionMode: getInteractionMode(state),
|
2021-02-12 01:50:11 +00:00
|
|
|
theme: getTheme(state),
|
2019-03-20 17:42:28 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
const smart = connect(mapStateToProps, mapDispatchToProps);
|
|
|
|
|
|
|
|
export const SmartTimelineItem = smart(TimelineItem);
|