{ e.preventDefault(); e.stopPropagation(); if (multiSelectMode && id) { this.props.onSelectMessage(id); return; } const { authorPhoneNumber, messageId: quoteId, referencedMessageNotFound } = quote; quote?.onClick({ quoteAuthor: authorPhoneNumber, quoteId, referencedMessageNotFound, }); }} text={quote.text} attachment={quote.attachment} isIncoming={direction === 'incoming'} conversationType={conversationType} convoId={convoId} isPublic={isPublic} authorPhoneNumber={displayedPubkey} authorProfileName={quote.authorProfileName} authorName={quote.authorName} referencedMessageNotFound={quote.referencedMessageNotFound} isFromMe={quote.isFromMe} withContentAbove={withContentAbove} /> ); } public renderAvatar() { const { authorAvatarPath, authorName, authorPhoneNumber, authorProfileName, collapseMetadata, isAdmin, conversationType, direction, isPublic, onShowUserDetails, firstMessageOfSeries, } = this.props; if (collapseMetadata || conversationType !== 'group' || direction === 'outgoing') { return; } const userName = authorName || authorProfileName || authorPhoneNumber; if (!firstMessageOfSeries) { return ; } return (); } public renderText() { const { text, direction, status, conversationType, convoId, multiSelectMode } = this.props; const contents = direction === 'incoming' && status === 'error' ? window.i18n('incomingError') : text; if (!contents) { return null; } return ({ onShowUserDetails(authorPhoneNumber); }} pubkey={authorPhoneNumber} /> {isPublic && isAdmin && ( )}); } public renderError(isCorrectSide: boolean) { const { status, direction } = this.props; if (!isCorrectSide || status !== 'error') { return null; } return (; const mentionMe = mentions && mentions.some(m => UserUtils.isUsFromCache(m.slice(1))); const isIncoming = direction === 'incoming'; const shouldHightlight = mentionMe && isIncoming && isPublic; const shouldMarkReadWhenVisible = isIncoming && isUnread; const divClasses = ['session-message-wrapper']; if (shouldHightlight) { //divClasses.push('message-highlighted'); } if (selected) { divClasses.push('message-selected'); } if (conversationType === 'group') { divClasses.push('public-chat-message-wrapper'); } if (this.props.isQuotedMessageToAnimate) { divClasses.push('flash-green-once'); } const onVisible = (inView: boolean) => { if (inView && shouldMarkReadWhenVisible) { // mark the message as read. // this will trigger the expire timer. void markRead(Date.now()); } }; return ( {this.renderAvatar()} ); } private handleContextMenu(e: any) { e.preventDefault(); e.stopPropagation(); const { multiSelectMode, isKickedFromGroup } = this.props; const enableContextMenu = !multiSelectMode && !isKickedFromGroup; if (enableContextMenu) { // Don't forget to pass the id and the event and voila! contextMenu.hideAll(); contextMenu.show({ id: this.ctxMenuID, event: e, }); } } private renderAuthor() { const { authorName, authorPhoneNumber, authorProfileName, conversationType, direction, isPublic, } = this.props; const title = authorName ? authorName : authorPhoneNumber; if (direction !== 'incoming' || conversationType !== 'group' || !title) { return null; } const shortenedPubkey = PubKey.shorten(authorPhoneNumber); const displayedPubkey = authorProfileName ? shortenedPubkey : authorPhoneNumber; return ({ const selection = window.getSelection(); // Text is being selected if (selection && selection.type === 'Range') { return; } // User clicked on message body const target = event.target as HTMLDivElement; if ( (!multiSelectMode && target.className === 'text-selectable') || window.contextMenuShown ) { return; } if (id) { this.props.onSelectMessage(id); } }} > {this.renderError(isIncoming)}{ const selection = window.getSelection(); // Text is being selected if (selection && selection.type === 'Range') { return; } // User clicked on message body const target = event.target as HTMLDivElement; if (target.className === 'text-selectable' || window.contextMenuShown) { return; } if (id) { this.props.onSelectMessage(id); } }} > {this.renderAuthor()} {this.renderQuote()} {this.renderAttachment()} {this.renderPreview()} {this.renderText()}{this.renderError(!isIncoming)} {this.renderContextMenu()}