diff --git a/web/chat/composed-message.react.js b/web/chat/composed-message.react.js index 5df829046..c96fc719e 100644 --- a/web/chat/composed-message.react.js +++ b/web/chat/composed-message.react.js @@ -1,259 +1,258 @@ // @flow import classNames from 'classnames'; import * as React from 'react'; import { Circle as CircleIcon, CheckCircle as CheckCircleIcon, XCircle as XCircleIcon, } from 'react-feather'; import { useStringForUser } from 'lib/hooks/ens-cache.js'; import { type ChatMessageInfoItem } from 'lib/selectors/chat-selectors.js'; import { getMessageLabel } from 'lib/shared/edit-messages-utils.js'; import { assertComposableMessageType } from 'lib/types/message-types.js'; import type { MinimallyEncodedThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js'; import { type ThreadInfo } from 'lib/types/thread-types.js'; import { getComposedMessageID } from './chat-constants.js'; import css from './chat-message-list.css'; import FailedSend from './failed-send.react.js'; import InlineEngagement from './inline-engagement.react.js'; import UserAvatar from '../avatars/user-avatar.react.js'; import CommIcon from '../CommIcon.react.js'; import { type InputState, InputStateContext } from '../input/input-state.js'; import { usePushUserProfileModal } from '../modals/user-profile/user-profile-utils.js'; import { useMessageTooltip } from '../utils/tooltip-action-utils.js'; import { tooltipPositions } from '../utils/tooltip-utils.js'; export type ComposedMessageID = string; const availableTooltipPositionsForViewerMessage = [ tooltipPositions.LEFT, tooltipPositions.LEFT_BOTTOM, tooltipPositions.LEFT_TOP, tooltipPositions.RIGHT, tooltipPositions.RIGHT_BOTTOM, tooltipPositions.RIGHT_TOP, tooltipPositions.BOTTOM, tooltipPositions.TOP, ]; const availableTooltipPositionsForNonViewerMessage = [ tooltipPositions.RIGHT, tooltipPositions.RIGHT_BOTTOM, tooltipPositions.RIGHT_TOP, tooltipPositions.LEFT, tooltipPositions.LEFT_BOTTOM, tooltipPositions.LEFT_TOP, tooltipPositions.BOTTOM, tooltipPositions.TOP, ]; type BaseProps = { +item: ChatMessageInfoItem, +threadInfo: ThreadInfo | MinimallyEncodedThreadInfo, +shouldDisplayPinIndicator: boolean, +sendFailed: boolean, +children: React.Node, +fixedWidth?: boolean, +borderRadius: number, }; -type BaseConfig = React.Config; +type DefaultProps = { +borderRadius: number }; +type BaseConfig = React.Config; type Props = { ...BaseProps, // withInputState +inputState: ?InputState, +onMouseLeave: ?() => mixed, +onMouseEnter: (event: SyntheticEvent) => mixed, +containsInlineEngagement: boolean, +stringForUser: ?string, +onClickUser: () => mixed, }; class ComposedMessage extends React.PureComponent { - static defaultProps: { +borderRadius: number } = { - borderRadius: 8, - }; + static defaultProps: DefaultProps = { borderRadius: 8 }; render(): React.Node { assertComposableMessageType(this.props.item.messageInfo.type); const { borderRadius, item, threadInfo, shouldDisplayPinIndicator } = this.props; const { hasBeenEdited, isPinned } = item; const { id, creator } = item.messageInfo; const threadColor = threadInfo.color; const { isViewer } = creator; const contentClassName = classNames({ [css.content]: true, [css.viewerContent]: isViewer, [css.nonViewerContent]: !isViewer, }); const messageBoxContainerClassName = classNames({ [css.messageBoxContainer]: true, [css.fixedWidthMessageBoxContainer]: this.props.fixedWidth, }); const messageBoxClassName = classNames({ [css.messageBox]: true, [css.fixedWidthMessageBox]: this.props.fixedWidth, }); const messageBoxStyle = { borderTopRightRadius: isViewer && !item.startsCluster ? 0 : borderRadius, borderBottomRightRadius: isViewer && !item.endsCluster ? 0 : borderRadius, borderTopLeftRadius: !isViewer && !item.startsCluster ? 0 : borderRadius, borderBottomLeftRadius: !isViewer && !item.endsCluster ? 0 : borderRadius, }; let authorName = null; const { stringForUser } = this.props; if (stringForUser) { authorName = ( {stringForUser} ); } let deliveryIcon = null; let failedSendInfo = null; if (isViewer) { let deliveryIconSpan; let deliveryIconColor = threadColor; if (id !== null && id !== undefined) { deliveryIconSpan = ; } else if (this.props.sendFailed) { deliveryIconSpan = ; deliveryIconColor = 'FF0000'; failedSendInfo = ; } else { deliveryIconSpan = ; } deliveryIcon = (
{deliveryIconSpan}
); } let inlineEngagement = null; const label = getMessageLabel(hasBeenEdited, threadInfo.id); if ( (this.props.containsInlineEngagement && item.threadCreatedFromMessage) || Object.keys(item.reactions).length > 0 || label ) { const positioning = isViewer ? 'right' : 'left'; inlineEngagement = (
); } let avatar; if (!isViewer && item.endsCluster) { avatar = (
); } else if (!isViewer) { avatar =
; } const pinIconPositioning = isViewer ? 'left' : 'right'; const pinIconName = pinIconPositioning === 'left' ? 'pin-mirror' : 'pin'; const pinIconContainerClassName = classNames({ [css.pinIconContainer]: true, [css.pinIconLeft]: pinIconPositioning === 'left', [css.pinIconRight]: pinIconPositioning === 'right', }); let pinIcon; if (isPinned && shouldDisplayPinIndicator) { pinIcon = (
); } return ( {authorName}
{avatar}
{pinIcon}
{this.props.children}
{deliveryIcon}
{failedSendInfo} {inlineEngagement}
); } } type ConnectedConfig = React.Config< BaseProps, typeof ComposedMessage.defaultProps, >; const ConnectedComposedMessage: React.ComponentType = React.memo(function ConnectedComposedMessage(props) { const { item, threadInfo } = props; const inputState = React.useContext(InputStateContext); const { creator } = props.item.messageInfo; const { isViewer } = creator; const availablePositions = isViewer ? availableTooltipPositionsForViewerMessage : availableTooltipPositionsForNonViewerMessage; const containsInlineEngagement = !!item.threadCreatedFromMessage; const { onMouseLeave, onMouseEnter } = useMessageTooltip({ item, threadInfo, availablePositions, }); const shouldShowUsername = !isViewer && item.startsCluster; const stringForUser = useStringForUser(shouldShowUsername ? creator : null); const pushUserProfileModal = usePushUserProfileModal(creator.id); return ( ); }); export default ConnectedComposedMessage;