From d729e498404504c51b52ddad3dd0bad6066346d6 Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Tue, 1 Dec 2020 10:32:56 +1100 Subject: [PATCH] update to latest major version of react-contexify --- package.json | 2 +- ts/components/ConversationListItem.tsx | 86 +++++++++++-------- .../conversation/ConversationHeader.tsx | 14 ++- ts/components/conversation/Message.tsx | 85 ++++++++---------- ts/components/session/SessionSearchInput.tsx | 36 ++++---- yarn.lock | 16 ++-- 6 files changed, 125 insertions(+), 114 deletions(-) diff --git a/package.json b/package.json index 4aa78d1b6..fcce35627 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,7 @@ "protobufjs": "^6.9.0", "rc-slider": "^8.7.1", "react": "^16.13.1", - "react-contexify": "^4.1.1", + "react-contexify": "5.0.0", "react-dom": "16.8.3", "react-emoji": "^0.5.0", "react-emoji-render": "^1.2.4", diff --git a/ts/components/ConversationListItem.tsx b/ts/components/ConversationListItem.tsx index 2c2197440..a30f7d9cc 100644 --- a/ts/components/ConversationListItem.tsx +++ b/ts/components/ConversationListItem.tsx @@ -1,7 +1,7 @@ import React from 'react'; import classNames from 'classnames'; import { isEmpty } from 'lodash'; -import { MenuProvider } from 'react-contexify'; +import { contextMenu } from 'react-contexify'; import { Avatar } from './Avatar'; import { MessageBody } from './conversation/MessageBody'; @@ -19,6 +19,7 @@ import { ConversationListItemContextMenu, PropsContextConversationItem, } from './session/menu/ConversationListItemContextMenu'; +import { createPortal } from 'react-dom'; export type PropsData = { id: string; @@ -70,6 +71,10 @@ type PropsHousekeeping = { type Props = PropsData & PropsHousekeeping; +const Portal = ({ children }: { children: any }) => { + return createPortal(children, document.querySelector('.inbox.index') as Element); +} + class ConversationListItem extends React.PureComponent { public constructor(props: Props) { super(props); @@ -103,7 +108,6 @@ class ConversationListItem extends React.PureComponent { public renderHeader() { const { unreadCount, mentionedUs, i18n, isMe, lastUpdated } = this.props; - const {} = this.props; let atSymbol = null; let unreadCountDiv = null; @@ -184,14 +188,14 @@ class ConversationListItem extends React.PureComponent { {isTyping ? ( ) : ( - - )} + + )} {lastMessage && lastMessage.status ? (
{ return (
- -
{ - if (onClick) { - onClick(id); - } - }} - style={style} - className={classNames( - 'module-conversation-list-item', - unreadCount > 0 - ? 'module-conversation-list-item--has-unread' - : null, - unreadCount > 0 && mentionedUs - ? 'module-conversation-list-item--mentioned-us' - : null, - isSelected ? 'module-conversation-list-item--is-selected' : null, - isBlocked ? 'module-conversation-list-item--is-blocked' : null - )} - > - {this.renderAvatar()} -
- {this.renderHeader()} - {this.renderMessage()} -
+
{ + if (onClick) { + onClick(id); + } + }} + onContextMenu={(e: any) => { + contextMenu.show({ + id: triggerId, + event: e, + }); + }} + style={style} + className={classNames( + 'module-conversation-list-item', + unreadCount > 0 + ? 'module-conversation-list-item--has-unread' + : null, + unreadCount > 0 && mentionedUs + ? 'module-conversation-list-item--mentioned-us' + : null, + isSelected ? 'module-conversation-list-item--is-selected' : null, + isBlocked ? 'module-conversation-list-item--is-blocked' : null + )} + > + {this.renderAvatar()} +
+ {this.renderHeader()} + {this.renderMessage()}
- - +
+ + +
); } diff --git a/ts/components/conversation/ConversationHeader.tsx b/ts/components/conversation/ConversationHeader.tsx index cb807604d..30b237edb 100644 --- a/ts/components/conversation/ConversationHeader.tsx +++ b/ts/components/conversation/ConversationHeader.tsx @@ -17,11 +17,11 @@ import { ConversationAvatar, usingClosedConversationDetails, } from '../session/usingClosedConversationDetails'; -import { MenuProvider } from 'react-contexify'; import { ConversationHeaderMenu, PropsConversationHeaderMenu, } from '../session/menu/ConversationHeaderMenu'; +import { contextMenu } from 'react-contexify'; export interface TimerOption { name: string; @@ -309,12 +309,20 @@ class ConversationHeader extends React.Component { return <>; } return ( - +
{ + contextMenu.show({ + id: triggerId, + event: e, + }); + }} + > - +
); } } diff --git a/ts/components/conversation/Message.tsx b/ts/components/conversation/Message.tsx index 59e240d98..50ac56da5 100644 --- a/ts/components/conversation/Message.tsx +++ b/ts/components/conversation/Message.tsx @@ -291,15 +291,15 @@ export class Message extends React.PureComponent { {window.i18n('sendFailed')} ) : ( - - )} + + )} {this.renderMetadataBadges()} {expirationLength && expirationTimestamp ? ( {
) : ( -
-
{ - if (this.props?.onDownload) { - e.stopPropagation(); - this.props.onDownload(firstAttachment); - } - }} - > - {extension ? ( -
- {extension} +
+
{ + if (this.props?.onDownload) { + e.stopPropagation(); + this.props.onDownload(firstAttachment); + } + }} + > + {extension ? ( +
+ {extension} +
+ ) : null} +
+ {isDangerous ? ( +
+
) : null}
- {isDangerous ? ( -
-
-
- ) : null} -
- )} + )}
{ } = this.props; const showRetry = status === 'error' && direction === 'outgoing'; - const fileName = - attachments && attachments[0] ? attachments[0].fileName : null; - const isDangerous = isFileDangerous(fileName || ''); const multipleAttachments = attachments && attachments.length > 1; - // Wraps a function to prevent event propagation, thus preventing - // message selection whenever any of the menu buttons are pressed. - const wrap = (f: any, ...args: Array) => (e: any) => { - e.event.stopPropagation(); - if (f) { - f(...args); - } - }; - const onContextMenuShown = () => { window.contextMenuShown = true; }; @@ -880,7 +868,6 @@ export class Message extends React.PureComponent { {!multipleAttachments && attachments && attachments[0] ? ( { - e.event.stopPropagation(); if (onDownload) { onDownload(attachments[0]); } @@ -890,15 +877,13 @@ export class Message extends React.PureComponent { ) : null} - {window.i18n('copyMessage')} + {window.i18n('copyMessage')} {window.i18n('replyToMessage')} - - {window.i18n('moreInformation')} - + {window.i18n('moreInformation')} {showRetry ? ( - {window.i18n('resend')} + {window.i18n('resend')} ) : null} {isDeletable ? ( <> @@ -919,7 +904,7 @@ export class Message extends React.PureComponent { ) : null} {isModerator && isPublic ? ( - {window.i18n('banUser')} + {window.i18n('banUser')} ) : null} ); @@ -1189,8 +1174,6 @@ export class Message extends React.PureComponent { } private onReplyPrivate(e: any) { - e.event.stopPropagation(); - e.event.preventDefault(); if (this.props && this.props.onReply) { this.props.onReply(this.props.timestamp); } diff --git a/ts/components/session/SessionSearchInput.tsx b/ts/components/session/SessionSearchInput.tsx index 1b084c706..a84f2bf19 100644 --- a/ts/components/session/SessionSearchInput.tsx +++ b/ts/components/session/SessionSearchInput.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { animation, Item, Menu, MenuProvider } from 'react-contexify'; +import { animation, contextMenu, Item, Menu } from 'react-contexify'; import { SessionIconButton, SessionIconSize, SessionIconType } from './icon'; interface Props { @@ -21,20 +21,26 @@ export class SessionSearchInput extends React.Component { return ( <> - -
- - this.props.onChange(e.target.value)} - onKeyDown={this.handleKeyDown} - placeholder={this.props.placeholder} - /> -
-
+
{ + contextMenu.show({ + id: triggerId, + event: e, + }); + }} + > + + this.props.onChange(e.target.value)} + onKeyDown={this.handleKeyDown} + placeholder={this.props.placeholder} + /> +
document.execCommand('undo')}> {window.i18n('editMenuUndo')} diff --git a/yarn.lock b/yarn.lock index c61c47361..ca182ac06 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2253,6 +2253,11 @@ clone@^1.0.2: resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= +clsx@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188" + integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA== + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -8724,13 +8729,12 @@ react-codemirror2@^4.2.1: resolved "https://registry.yarnpkg.com/react-codemirror2/-/react-codemirror2-4.3.0.tgz#e79aedca4da60d22402d2cd74f2885a3e5c009fd" integrity sha512-tC0n9CHgrQYc976pUlKOaVJYEHAAYTVMers04gNy6jbkFf4rbPlw72y7bbOAfkHHvu6COG5S629Fek30bvHe8w== -react-contexify@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/react-contexify/-/react-contexify-4.1.1.tgz#f5eba1ad82a923c033c91d0abcea1da0a71ebaa1" - integrity sha512-WJeRI4ohHEOmNiH0xb62a/eV+5ae168FB7H6pfbeEVJkf0UN7D5H99l6b89poc2LHKN1gOimFjREyY8quGVsXA== +react-contexify@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/react-contexify/-/react-contexify-5.0.0.tgz#11b477550a0ee5a9a144399bc17c7c56bbc60057" + integrity sha512-2FIp7lxJ6dtfGr8EZ4uVV5p5TQjd0n2h/JU7PrejNIMiCeZWvSVPFh4lj1ZvjXosglBvP7q5JQQ8yUCdSaMSaw== dependencies: - classnames "^2.2.6" - prop-types "^15.6.2" + clsx "^1.1.1" react-dev-utils@^5.0.0: version "5.0.3"