diff --git a/res/css/structures/_ContextualMenu.scss b/res/css/structures/_ContextualMenu.scss index fc1538a13d..b6644c1752 100644 --- a/res/css/structures/_ContextualMenu.scss +++ b/res/css/structures/_ContextualMenu.scss @@ -39,7 +39,11 @@ limitations under the License. z-index: 5001; } -.mx_ContextualMenu.mx_ContextualMenu_right { +.mx_ContextualMenu_right { + right: 0; +} + +.mx_ContextualMenu.mx_ContextualMenu_withChevron_right { right: 8px; } @@ -66,7 +70,11 @@ limitations under the License. right: 1px; } -.mx_ContextualMenu.mx_ContextualMenu_left { +.mx_ContextualMenu_left { + left: 0; +} + +.mx_ContextualMenu.mx_ContextualMenu_withChevron_left { left: 8px; } @@ -93,7 +101,11 @@ limitations under the License. left: 1px; } -.mx_ContextualMenu.mx_ContextualMenu_top { +.mx_ContextualMenu_top { + top: 0; +} + +.mx_ContextualMenu.mx_ContextualMenu_withChevron_top { top: 8px; } @@ -120,7 +132,11 @@ limitations under the License. top: 1px; } -.mx_ContextualMenu.mx_ContextualMenu_bottom { +.mx_ContextualMenu_bottom { + bottom: 0; +} + +.mx_ContextualMenu.mx_ContextualMenu_withChevron_bottom { bottom: 8px; } diff --git a/src/components/structures/ContextualMenu.js b/src/components/structures/ContextualMenu.js index 345eae2b18..edd6f79270 100644 --- a/src/components/structures/ContextualMenu.js +++ b/src/components/structures/ContextualMenu.js @@ -183,11 +183,14 @@ export default class ContextualMenu extends React.Component { const menuClasses = classNames({ 'mx_ContextualMenu': true, - 'mx_ContextualMenu_noChevron': chevronFace === 'none', - 'mx_ContextualMenu_left': chevronFace === 'left', - 'mx_ContextualMenu_right': chevronFace === 'right', - 'mx_ContextualMenu_top': chevronFace === 'top', - 'mx_ContextualMenu_bottom': chevronFace === 'bottom', + 'mx_ContextualMenu_left': !hasChevron && position.left, + 'mx_ContextualMenu_right': !hasChevron && position.right, + 'mx_ContextualMenu_top': !hasChevron && position.top, + 'mx_ContextualMenu_bottom': !hasChevron && position.bottom, + 'mx_ContextualMenu_withChevron_left': chevronFace === 'left', + 'mx_ContextualMenu_withChevron_right': chevronFace === 'right', + 'mx_ContextualMenu_withChevron_top': chevronFace === 'top', + 'mx_ContextualMenu_withChevron_bottom': chevronFace === 'bottom', }); const menuStyle = {}; diff --git a/src/components/views/messages/MessageActionBar.js b/src/components/views/messages/MessageActionBar.js index c4cca847d9..80f0ba538c 100644 --- a/src/components/views/messages/MessageActionBar.js +++ b/src/components/views/messages/MessageActionBar.js @@ -83,10 +83,6 @@ export default class MessageActionBar extends React.PureComponent { const MessageContextMenu = sdk.getComponent('context_menus.MessageContextMenu'); const buttonRect = ev.target.getBoundingClientRect(); - // The window X and Y offsets are to adjust position when zoomed in to page - const x = buttonRect.right + window.pageXOffset; - const y = (buttonRect.top + (buttonRect.height / 2) + window.pageYOffset) - 19; - const { getTile, getReplyThread } = this.props; const tile = getTile && getTile(); const replyThread = getReplyThread && getReplyThread(); @@ -96,11 +92,9 @@ export default class MessageActionBar extends React.PureComponent { e2eInfoCallback = () => this.onCryptoClicked(); } - createMenu(MessageContextMenu, { - chevronOffset: 10, + const menuOptions = { mxEvent: this.props.mxEvent, - left: x, - top: y, + chevronFace: "none", permalinkCreator: this.props.permalinkCreator, eventTileOps: tile && tile.getEventTileOps ? tile.getEventTileOps() : undefined, collapseReplyThread: replyThread && replyThread.canCollapse() ? replyThread.collapse : undefined, @@ -108,7 +102,23 @@ export default class MessageActionBar extends React.PureComponent { onFinished: () => { this.onFocusChange(false); }, - }); + }; + + // The window X and Y offsets are to adjust position when zoomed in to page + const buttonRight = buttonRect.right + window.pageXOffset; + const buttonBottom = buttonRect.bottom + window.pageYOffset; + const buttonTop = buttonRect.top + window.pageYOffset; + // Align the right edge of the menu to the right edge of the button + menuOptions.right = window.innerWidth - buttonRight; + // Align the menu vertically on whichever side of the button has more + // space available. + if (buttonBottom < window.innerHeight / 2) { + menuOptions.top = buttonBottom; + } else { + menuOptions.bottom = window.innerHeight - buttonTop; + } + + createMenu(MessageContextMenu, menuOptions); this.onFocusChange(true); }