From 5c92f8ab256de473de57bbd8597749ca6cad652a Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 10 Dec 2019 00:08:45 +0000 Subject: [PATCH] Fix RoomTile right click context menu Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/RoomTile.js | 55 ++++++++++++++++---------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/src/components/views/rooms/RoomTile.js b/src/components/views/rooms/RoomTile.js index 313f013de4..817ada9706 100644 --- a/src/components/views/rooms/RoomTile.js +++ b/src/components/views/rooms/RoomTile.js @@ -17,7 +17,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React, {createRef} from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; import createReactClass from 'create-react-class'; import classNames from 'classnames'; @@ -59,7 +59,7 @@ module.exports = createReactClass({ return ({ hover: false, badgeHover: false, - menuDisplayed: false, + contextMenuPosition: null, // DOM bounding box, null if non-shown roomName: this.props.room.name, notifState: RoomNotifs.getRoomNotifsState(this.props.room.roomId), notificationCount: this.props.room.getUnreadNotificationCount(), @@ -145,8 +145,6 @@ module.exports = createReactClass({ }, componentDidMount: function() { - this._contextMenuButton = createRef(); - const cli = MatrixClientPeg.get(); cli.on("accountData", this.onAccountData); cli.on("Room.name", this.onRoomName); @@ -241,16 +239,12 @@ module.exports = createReactClass({ this.setState( { badgeHover: false } ); }, - openMenu: function(e) { + _showContextMenu: function(boundingClientRect) { // Only allow non-guests to access the context menu if (MatrixClientPeg.get().isGuest()) return; - // Prevent the RoomTile onClick event firing as well - e.stopPropagation(); - e.preventDefault(); - const state = { - menuDisplayed: true, + contextMenuPosition: boundingClientRect, }; // If the badge is clicked, then no longer show tooltip @@ -261,9 +255,28 @@ module.exports = createReactClass({ this.setState(state); }, + onContextMenuButtonClick: function(e) { + // Prevent the RoomTile onClick event firing as well + e.stopPropagation(); + e.preventDefault(); + + this._showContextMenu(e.target.getBoundingClientRect()); + }, + + onContextMenu: function(e) { + // Prevent the native context menu + e.preventDefault(); + + this._showContextMenu({ + right: e.clientX, + top: e.clientY, + height: 0, + }); + }, + closeMenu: function() { this.setState({ - menuDisplayed: false, + contextMenuPosition: null, }); this.props.refreshSubList(); }, @@ -282,6 +295,8 @@ module.exports = createReactClass({ subtext = this.state.statusMessage; } + const isMenuDisplayed = Boolean(this.state.contextMenuPosition); + const classes = classNames({ 'mx_RoomTile': true, 'mx_RoomTile_selected': this.state.selected, @@ -289,7 +304,7 @@ module.exports = createReactClass({ 'mx_RoomTile_unreadNotify': notifBadges, 'mx_RoomTile_highlight': mentionBadges, 'mx_RoomTile_invited': isInvite, - 'mx_RoomTile_menuDisplayed': this.state.menuDisplayed, + 'mx_RoomTile_menuDisplayed': isMenuDisplayed, 'mx_RoomTile_noBadges': !badges, 'mx_RoomTile_transparent': this.props.transparent, 'mx_RoomTile_hasSubtext': subtext && !this.props.collapsed, @@ -301,7 +316,7 @@ module.exports = createReactClass({ const badgeClasses = classNames({ 'mx_RoomTile_badge': true, - 'mx_RoomTile_badgeButton': this.state.badgeHover || this.state.menuDisplayed, + 'mx_RoomTile_badgeButton': this.state.badgeHover || isMenuDisplayed, }); let name = this.state.roomName; @@ -323,7 +338,7 @@ module.exports = createReactClass({ const nameClasses = classNames({ 'mx_RoomTile_name': true, 'mx_RoomTile_invite': this.props.isInvite, - 'mx_RoomTile_badgeShown': badges || this.state.badgeHover || this.state.menuDisplayed, + 'mx_RoomTile_badgeShown': badges || this.state.badgeHover || isMenuDisplayed, }); subtextLabel = subtext ? { subtext } : null; @@ -346,10 +361,9 @@ module.exports = createReactClass({ contextMenuButton = ( + isExpanded={isMenuDisplayed} + onClick={this.onContextMenuButtonClick} /> ); } @@ -382,11 +396,10 @@ module.exports = createReactClass({ } let contextMenu; - if (this.state.menuDisplayed && this._contextMenuButton.current) { - const elementRect = this._contextMenuButton.current.getBoundingClientRect(); + if (isMenuDisplayed) { const RoomTileContextMenu = sdk.getComponent('context_menus.RoomTileContextMenu'); contextMenu = ( - + ); @@ -399,7 +412,7 @@ module.exports = createReactClass({ onClick={this.onClick} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave} - onContextMenu={this.openMenu} + onContextMenu={this.onContextMenu} aria-label={ariaLabel} aria-selected={this.state.selected} role="treeitem"