update to latest major version of react-contexify

pull/1381/head
Audric Ackermann 4 years ago
parent efa45f7cbe
commit d729e49840
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -109,7 +109,7 @@
"protobufjs": "^6.9.0", "protobufjs": "^6.9.0",
"rc-slider": "^8.7.1", "rc-slider": "^8.7.1",
"react": "^16.13.1", "react": "^16.13.1",
"react-contexify": "^4.1.1", "react-contexify": "5.0.0",
"react-dom": "16.8.3", "react-dom": "16.8.3",
"react-emoji": "^0.5.0", "react-emoji": "^0.5.0",
"react-emoji-render": "^1.2.4", "react-emoji-render": "^1.2.4",

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { isEmpty } from 'lodash'; import { isEmpty } from 'lodash';
import { MenuProvider } from 'react-contexify'; import { contextMenu } from 'react-contexify';
import { Avatar } from './Avatar'; import { Avatar } from './Avatar';
import { MessageBody } from './conversation/MessageBody'; import { MessageBody } from './conversation/MessageBody';
@ -19,6 +19,7 @@ import {
ConversationListItemContextMenu, ConversationListItemContextMenu,
PropsContextConversationItem, PropsContextConversationItem,
} from './session/menu/ConversationListItemContextMenu'; } from './session/menu/ConversationListItemContextMenu';
import { createPortal } from 'react-dom';
export type PropsData = { export type PropsData = {
id: string; id: string;
@ -70,6 +71,10 @@ type PropsHousekeeping = {
type Props = PropsData & PropsHousekeeping; type Props = PropsData & PropsHousekeeping;
const Portal = ({ children }: { children: any }) => {
return createPortal(children, document.querySelector('.inbox.index') as Element);
}
class ConversationListItem extends React.PureComponent<Props> { class ConversationListItem extends React.PureComponent<Props> {
public constructor(props: Props) { public constructor(props: Props) {
super(props); super(props);
@ -103,7 +108,6 @@ class ConversationListItem extends React.PureComponent<Props> {
public renderHeader() { public renderHeader() {
const { unreadCount, mentionedUs, i18n, isMe, lastUpdated } = this.props; const { unreadCount, mentionedUs, i18n, isMe, lastUpdated } = this.props;
const {} = this.props;
let atSymbol = null; let atSymbol = null;
let unreadCountDiv = null; let unreadCountDiv = null;
@ -184,14 +188,14 @@ class ConversationListItem extends React.PureComponent<Props> {
{isTyping ? ( {isTyping ? (
<TypingAnimation i18n={i18n} /> <TypingAnimation i18n={i18n} />
) : ( ) : (
<MessageBody <MessageBody
isGroup={true} isGroup={true}
text={text} text={text}
disableJumbomoji={true} disableJumbomoji={true}
disableLinks={true} disableLinks={true}
i18n={i18n} i18n={i18n}
/> />
)} )}
</div> </div>
{lastMessage && lastMessage.status ? ( {lastMessage && lastMessage.status ? (
<div <div
@ -221,35 +225,41 @@ class ConversationListItem extends React.PureComponent<Props> {
return ( return (
<div key={key}> <div key={key}>
<MenuProvider id={triggerId}> <div
<div role="button"
role="button" onClick={() => {
onClick={() => { if (onClick) {
if (onClick) { onClick(id);
onClick(id); }
} }}
}} onContextMenu={(e: any) => {
style={style} contextMenu.show({
className={classNames( id: triggerId,
'module-conversation-list-item', event: e,
unreadCount > 0 });
? 'module-conversation-list-item--has-unread' }}
: null, style={style}
unreadCount > 0 && mentionedUs className={classNames(
? 'module-conversation-list-item--mentioned-us' 'module-conversation-list-item',
: null, unreadCount > 0
isSelected ? 'module-conversation-list-item--is-selected' : null, ? 'module-conversation-list-item--has-unread'
isBlocked ? 'module-conversation-list-item--is-blocked' : null : null,
)} unreadCount > 0 && mentionedUs
> ? 'module-conversation-list-item--mentioned-us'
{this.renderAvatar()} : null,
<div className="module-conversation-list-item__content"> isSelected ? 'module-conversation-list-item--is-selected' : null,
{this.renderHeader()} isBlocked ? 'module-conversation-list-item--is-blocked' : null
{this.renderMessage()} )}
</div> >
{this.renderAvatar()}
<div className="module-conversation-list-item__content">
{this.renderHeader()}
{this.renderMessage()}
</div> </div>
</MenuProvider> </div>
<ConversationListItemContextMenu {...this.getMenuProps(triggerId)} /> <Portal>
<ConversationListItemContextMenu {...this.getMenuProps(triggerId)} />
</Portal>
</div> </div>
); );
} }

@ -17,11 +17,11 @@ import {
ConversationAvatar, ConversationAvatar,
usingClosedConversationDetails, usingClosedConversationDetails,
} from '../session/usingClosedConversationDetails'; } from '../session/usingClosedConversationDetails';
import { MenuProvider } from 'react-contexify';
import { import {
ConversationHeaderMenu, ConversationHeaderMenu,
PropsConversationHeaderMenu, PropsConversationHeaderMenu,
} from '../session/menu/ConversationHeaderMenu'; } from '../session/menu/ConversationHeaderMenu';
import { contextMenu } from 'react-contexify';
export interface TimerOption { export interface TimerOption {
name: string; name: string;
@ -309,12 +309,20 @@ class ConversationHeader extends React.Component<Props> {
return <></>; return <></>;
} }
return ( return (
<MenuProvider id={triggerId} event="onClick"> <div
role="button"
onClick={(e: any) => {
contextMenu.show({
id: triggerId,
event: e,
});
}}
>
<SessionIconButton <SessionIconButton
iconType={SessionIconType.Ellipses} iconType={SessionIconType.Ellipses}
iconSize={SessionIconSize.Medium} iconSize={SessionIconSize.Medium}
/> />
</MenuProvider> </div>
); );
} }
} }

@ -291,15 +291,15 @@ export class Message extends React.PureComponent<Props, State> {
{window.i18n('sendFailed')} {window.i18n('sendFailed')}
</span> </span>
) : ( ) : (
<Timestamp <Timestamp
i18n={window.i18n} i18n={window.i18n}
timestamp={serverTimestamp || timestamp} timestamp={serverTimestamp || timestamp}
extended={true} extended={true}
direction={direction} direction={direction}
withImageNoCaption={withImageNoCaption} withImageNoCaption={withImageNoCaption}
module="module-message__metadata__date" module="module-message__metadata__date"
/> />
)} )}
{this.renderMetadataBadges()} {this.renderMetadataBadges()}
{expirationLength && expirationTimestamp ? ( {expirationLength && expirationTimestamp ? (
<ExpireTimer <ExpireTimer
@ -473,30 +473,30 @@ export class Message extends React.PureComponent<Props, State> {
<Spinner size="small" direction={direction} /> <Spinner size="small" direction={direction} />
</div> </div>
) : ( ) : (
<div className="module-message__generic-attachment__icon-container"> <div className="module-message__generic-attachment__icon-container">
<div <div
role="button" role="button"
className="module-message__generic-attachment__icon" className="module-message__generic-attachment__icon"
onClick={(e: any) => { onClick={(e: any) => {
if (this.props?.onDownload) { if (this.props?.onDownload) {
e.stopPropagation(); e.stopPropagation();
this.props.onDownload(firstAttachment); this.props.onDownload(firstAttachment);
} }
}} }}
> >
{extension ? ( {extension ? (
<div className="module-message__generic-attachment__icon__extension"> <div className="module-message__generic-attachment__icon__extension">
{extension} {extension}
</div>
) : null}
</div>
{isDangerous ? (
<div className="module-message__generic-attachment__icon-dangerous-container">
<div className="module-message__generic-attachment__icon-dangerous" />
</div> </div>
) : null} ) : null}
</div> </div>
{isDangerous ? ( )}
<div className="module-message__generic-attachment__icon-dangerous-container">
<div className="module-message__generic-attachment__icon-dangerous" />
</div>
) : null}
</div>
)}
<div className="module-message__generic-attachment__text"> <div className="module-message__generic-attachment__text">
<div <div
className={classNames( className={classNames(
@ -840,20 +840,8 @@ export class Message extends React.PureComponent<Props, State> {
} = this.props; } = this.props;
const showRetry = status === 'error' && direction === 'outgoing'; 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; 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<any>) => (e: any) => {
e.event.stopPropagation();
if (f) {
f(...args);
}
};
const onContextMenuShown = () => { const onContextMenuShown = () => {
window.contextMenuShown = true; window.contextMenuShown = true;
}; };
@ -880,7 +868,6 @@ export class Message extends React.PureComponent<Props, State> {
{!multipleAttachments && attachments && attachments[0] ? ( {!multipleAttachments && attachments && attachments[0] ? (
<Item <Item
onClick={(e: any) => { onClick={(e: any) => {
e.event.stopPropagation();
if (onDownload) { if (onDownload) {
onDownload(attachments[0]); onDownload(attachments[0]);
} }
@ -890,15 +877,13 @@ export class Message extends React.PureComponent<Props, State> {
</Item> </Item>
) : null} ) : null}
<Item onClick={wrap(onCopyText)}>{window.i18n('copyMessage')}</Item> <Item onClick={onCopyText}>{window.i18n('copyMessage')}</Item>
<Item onClick={this.onReplyPrivate}> <Item onClick={this.onReplyPrivate}>
{window.i18n('replyToMessage')} {window.i18n('replyToMessage')}
</Item> </Item>
<Item onClick={wrap(onShowDetail)}> <Item onClick={onShowDetail}>{window.i18n('moreInformation')}</Item>
{window.i18n('moreInformation')}
</Item>
{showRetry ? ( {showRetry ? (
<Item onClick={wrap(onRetrySend)}>{window.i18n('resend')}</Item> <Item onClick={onRetrySend}>{window.i18n('resend')}</Item>
) : null} ) : null}
{isDeletable ? ( {isDeletable ? (
<> <>
@ -919,7 +904,7 @@ export class Message extends React.PureComponent<Props, State> {
</> </>
) : null} ) : null}
{isModerator && isPublic ? ( {isModerator && isPublic ? (
<Item onClick={wrap(onBanUser)}>{window.i18n('banUser')}</Item> <Item onClick={onBanUser}>{window.i18n('banUser')}</Item>
) : null} ) : null}
</Menu> </Menu>
); );
@ -1189,8 +1174,6 @@ export class Message extends React.PureComponent<Props, State> {
} }
private onReplyPrivate(e: any) { private onReplyPrivate(e: any) {
e.event.stopPropagation();
e.event.preventDefault();
if (this.props && this.props.onReply) { if (this.props && this.props.onReply) {
this.props.onReply(this.props.timestamp); this.props.onReply(this.props.timestamp);
} }

@ -1,5 +1,5 @@
import React from 'react'; 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'; import { SessionIconButton, SessionIconSize, SessionIconType } from './icon';
interface Props { interface Props {
@ -21,20 +21,26 @@ export class SessionSearchInput extends React.Component<Props> {
return ( return (
<> <>
<MenuProvider id={triggerId}> <div
<div className="session-search-input"> className="session-search-input"
<SessionIconButton onContextMenu={(e: any) => {
iconSize={SessionIconSize.Medium} contextMenu.show({
iconType={SessionIconType.Search} id: triggerId,
/> event: e,
<input });
value={searchString} }}
onChange={e => this.props.onChange(e.target.value)} >
onKeyDown={this.handleKeyDown} <SessionIconButton
placeholder={this.props.placeholder} iconSize={SessionIconSize.Medium}
/> iconType={SessionIconType.Search}
</div> />
</MenuProvider> <input
value={searchString}
onChange={e => this.props.onChange(e.target.value)}
onKeyDown={this.handleKeyDown}
placeholder={this.props.placeholder}
/>
</div>
<Menu id={triggerId} animation={animation.fade}> <Menu id={triggerId} animation={animation.fade}>
<Item onClick={() => document.execCommand('undo')}> <Item onClick={() => document.execCommand('undo')}>
{window.i18n('editMenuUndo')} {window.i18n('editMenuUndo')}

@ -2253,6 +2253,11 @@ clone@^1.0.2:
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= 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: co@^4.6.0:
version "4.6.0" version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" 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" resolved "https://registry.yarnpkg.com/react-codemirror2/-/react-codemirror2-4.3.0.tgz#e79aedca4da60d22402d2cd74f2885a3e5c009fd"
integrity sha512-tC0n9CHgrQYc976pUlKOaVJYEHAAYTVMers04gNy6jbkFf4rbPlw72y7bbOAfkHHvu6COG5S629Fek30bvHe8w== integrity sha512-tC0n9CHgrQYc976pUlKOaVJYEHAAYTVMers04gNy6jbkFf4rbPlw72y7bbOAfkHHvu6COG5S629Fek30bvHe8w==
react-contexify@^4.1.1: react-contexify@5.0.0:
version "4.1.1" version "5.0.0"
resolved "https://registry.yarnpkg.com/react-contexify/-/react-contexify-4.1.1.tgz#f5eba1ad82a923c033c91d0abcea1da0a71ebaa1" resolved "https://registry.yarnpkg.com/react-contexify/-/react-contexify-5.0.0.tgz#11b477550a0ee5a9a144399bc17c7c56bbc60057"
integrity sha512-WJeRI4ohHEOmNiH0xb62a/eV+5ae168FB7H6pfbeEVJkf0UN7D5H99l6b89poc2LHKN1gOimFjREyY8quGVsXA== integrity sha512-2FIp7lxJ6dtfGr8EZ4uVV5p5TQjd0n2h/JU7PrejNIMiCeZWvSVPFh4lj1ZvjXosglBvP7q5JQQ8yUCdSaMSaw==
dependencies: dependencies:
classnames "^2.2.6" clsx "^1.1.1"
prop-types "^15.6.2"
react-dev-utils@^5.0.0: react-dev-utils@^5.0.0:
version "5.0.3" version "5.0.3"

Loading…
Cancel
Save