From 5f3e3b3ec20603fa94828b64f47eb49681490c1c Mon Sep 17 00:00:00 2001 From: Agusti Bau Date: Sat, 25 Apr 2020 01:09:07 +0200 Subject: [PATCH 1/6] Extracted context menu from TagTile to DNDTagTile --- src/components/views/elements/DNDTagTile.js | 91 ++++++++++++++++----- src/components/views/elements/TagTile.js | 60 ++++++-------- 2 files changed, 92 insertions(+), 59 deletions(-) diff --git a/src/components/views/elements/DNDTagTile.js b/src/components/views/elements/DNDTagTile.js index 7aa642986b..3ef805992e 100644 --- a/src/components/views/elements/DNDTagTile.js +++ b/src/components/views/elements/DNDTagTile.js @@ -17,29 +17,76 @@ limitations under the License. import TagTile from './TagTile'; -import React from 'react'; +import React, {createRef} from 'react'; import { Draggable } from 'react-beautiful-dnd'; +import {ContextMenu, toRightOf} from "../../structures/ContextMenu"; +import * as sdk from '../../../index'; -export default function DNDTagTile(props) { - return
- - { (provided, snapshot) => ( -
-
- +export default class DNDTagTile extends React.Component { + constructor() { + super(); + this.state = { + menuDisplayed: false, + }; + + this.openMenu = this.openMenu.bind(this); + this.closeMenu = this.closeMenu.bind(this); + } + + componentDidMount() { + this._contextMenuButton = createRef(); + } + + openMenu() { + this.setState({ + menuDisplayed: true, + }); + } + + closeMenu() { + console.log("Closig menu"); + this.setState({ + menuDisplayed: false, + }); + } + + getContextMenu() { + const elementRect = this._contextMenuButton.current.getBoundingClientRect(); + const TagTileContextMenu = sdk.getComponent('context_menus.TagTileContextMenu'); + return ( + + + + ); + } + + render(props) { + return
+ + { (provided, snapshot) => ( +
+
+ +
+ { provided.placeholder }
- { provided.placeholder } -
- ) } - -
; + ) } + + {this.state.menuDisplayed && this.getContextMenu()} +
; + } } diff --git a/src/components/views/elements/TagTile.js b/src/components/views/elements/TagTile.js index 2f182c261e..023d9cca93 100644 --- a/src/components/views/elements/TagTile.js +++ b/src/components/views/elements/TagTile.js @@ -16,7 +16,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'; @@ -28,7 +28,6 @@ import * as FormattingUtils from '../../../utils/FormattingUtils'; import FlairStore from '../../../stores/FlairStore'; import GroupStore from '../../../stores/GroupStore'; import TagOrderStore from '../../../stores/TagOrderStore'; -import {ContextMenu, toRightOf} from "../../structures/ContextMenu"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; // A class for a child of TagPanel (possibly wrapped in a DNDTagTile) that represents @@ -43,6 +42,9 @@ export default createReactClass({ // A string tag such as "m.favourite" or a group ID such as "+groupid:domain.bla" // For now, only group IDs are handled. tag: PropTypes.string, + contextMenuButtonRef: PropTypes.object, + openMenu: PropTypes.func, + menuDisplayed: PropTypes.bool, }, statics: { @@ -55,14 +57,10 @@ export default createReactClass({ hover: false, // The profile data of the group if this.props.tag is a group ID profile: null, - // Whether or not the context menu is open - menuDisplayed: false, }; }, componentDidMount() { - this._contextMenuButton = createRef(); - this.unmounted = false; if (this.props.tag[0] === '+') { FlairStore.addListener('updateGroupProfile', this._onFlairStoreUpdated); @@ -124,17 +122,8 @@ export default createReactClass({ // Prevent the TagTile onClick event firing as well e.stopPropagation(); e.preventDefault(); - - this.setState({ - menuDisplayed: true, - hover: false, - }); - }, - - closeMenu: function() { - this.setState({ - menuDisplayed: false, - }); + this.setState({hover: false}); + this.props.openMenu(); }, render: function() { @@ -163,26 +152,25 @@ export default createReactClass({ } // FIXME: this ought to use AccessibleButton for a11y but that causes onMouseOut/onMouseOver to fire too much - const contextButton = this.state.hover || this.state.menuDisplayed ? -
+ const contextButton = this.state.hover || this.props.menuDisplayed ? +
{ "\u00B7\u00B7\u00B7" } -
:
; - - let contextMenu; - if (this.state.menuDisplayed) { - const elementRect = this._contextMenuButton.current.getBoundingClientRect(); - const TagTileContextMenu = sdk.getComponent('context_menus.TagTileContextMenu'); - contextMenu = ( - - - - ); - } +
:
; const AccessibleTooltipButton = sdk.getComponent("elements.AccessibleTooltipButton"); - return - -
+ + return
+ +
- - { contextMenu } - ; +
; }, }); From 98a949bed1aca4916f82bbbe615f90891d330b49 Mon Sep 17 00:00:00 2001 From: Agusti Bau Date: Sat, 25 Apr 2020 01:09:07 +0200 Subject: [PATCH 2/6] Refactored DNDTagTile to use useContextMenu Signed-off-by: Agusti Bau --- src/components/views/elements/DNDTagTile.js | 63 ++++++--------------- 1 file changed, 18 insertions(+), 45 deletions(-) diff --git a/src/components/views/elements/DNDTagTile.js b/src/components/views/elements/DNDTagTile.js index 3ef805992e..5a96f01d9f 100644 --- a/src/components/views/elements/DNDTagTile.js +++ b/src/components/views/elements/DNDTagTile.js @@ -17,55 +17,29 @@ limitations under the License. import TagTile from './TagTile'; -import React, {createRef} from 'react'; +import React from 'react'; import { Draggable } from 'react-beautiful-dnd'; -import {ContextMenu, toRightOf} from "../../structures/ContextMenu"; +import {ContextMenu, toRightOf, useContextMenu} from "../../structures/ContextMenu"; import * as sdk from '../../../index'; -export default class DNDTagTile extends React.Component { - constructor() { - super(); - this.state = { - menuDisplayed: false, - }; +export default function DNDTagTile(props) { + const [menuDisplayed, handle, openMenu, closeMenu] = useContextMenu(); - this.openMenu = this.openMenu.bind(this); - this.closeMenu = this.closeMenu.bind(this); - } - - componentDidMount() { - this._contextMenuButton = createRef(); - } - - openMenu() { - this.setState({ - menuDisplayed: true, - }); - } - - closeMenu() { - console.log("Closig menu"); - this.setState({ - menuDisplayed: false, - }); - } - - getContextMenu() { - const elementRect = this._contextMenuButton.current.getBoundingClientRect(); + let contextMenu = null; + if (menuDisplayed && handle.current) { + const elementRect = handle.current.getBoundingClientRect(); const TagTileContextMenu = sdk.getComponent('context_menus.TagTileContextMenu'); - return ( - - + contextMenu = ( + + ); } - - render(props) { return
{ (provided, snapshot) => ( @@ -76,17 +50,16 @@ export default class DNDTagTile extends React.Component { {...provided.dragHandleProps} >
{ provided.placeholder }
) } - {this.state.menuDisplayed && this.getContextMenu()} + {contextMenu}
; - } } From 01131a403657e0025b8506d3a3e14b819d01bd51 Mon Sep 17 00:00:00 2001 From: Agusti Bau Date: Sat, 2 May 2020 12:55:56 +0200 Subject: [PATCH 3/6] removed unnecessary divs --- src/components/views/elements/DNDTagTile.js | 4 +--- src/components/views/elements/TagTile.js | 6 ++---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/components/views/elements/DNDTagTile.js b/src/components/views/elements/DNDTagTile.js index 5a96f01d9f..2a6664d271 100644 --- a/src/components/views/elements/DNDTagTile.js +++ b/src/components/views/elements/DNDTagTile.js @@ -43,7 +43,6 @@ export default function DNDTagTile(props) { type="draggable-TagTile" > { (provided, snapshot) => ( -
-
{ provided.placeholder } -
+
) } {contextMenu} diff --git a/src/components/views/elements/TagTile.js b/src/components/views/elements/TagTile.js index 023d9cca93..848dc797a2 100644 --- a/src/components/views/elements/TagTile.js +++ b/src/components/views/elements/TagTile.js @@ -159,8 +159,7 @@ export default createReactClass({ const AccessibleTooltipButton = sdk.getComponent("elements.AccessibleTooltipButton"); - return
- - -
; + ; }, }); From fc5a5c411f41c004fae10241f3dc4d4c013e307a Mon Sep 17 00:00:00 2001 From: Agusti Bau Date: Sat, 2 May 2020 13:09:04 +0200 Subject: [PATCH 4/6] provided.placeholder has no effect --- src/components/views/elements/DNDTagTile.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/views/elements/DNDTagTile.js b/src/components/views/elements/DNDTagTile.js index 2a6664d271..b017704e70 100644 --- a/src/components/views/elements/DNDTagTile.js +++ b/src/components/views/elements/DNDTagTile.js @@ -54,7 +54,6 @@ export default function DNDTagTile(props) { menuDisplayed={menuDisplayed} openMenu={openMenu} /> - { provided.placeholder }
) }
From a84a3c4780bece5778d9e4fabcb5856ec284928b Mon Sep 17 00:00:00 2001 From: Agusti Bau Date: Sat, 2 May 2020 13:12:31 +0200 Subject: [PATCH 5/6] hide badge when context menu is open --- src/components/views/elements/TagTile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/elements/TagTile.js b/src/components/views/elements/TagTile.js index 848dc797a2..0f98971198 100644 --- a/src/components/views/elements/TagTile.js +++ b/src/components/views/elements/TagTile.js @@ -143,7 +143,7 @@ export default createReactClass({ const badge = TagOrderStore.getGroupBadge(this.props.tag); let badgeElement; - if (badge && !this.state.hover) { + if (badge && !this.state.hover && !this.props.menuDisplayed) { const badgeClasses = classNames({ "mx_TagTile_badge": true, "mx_TagTile_badgeHighlight": badge.highlight, From baa9cd8078ef277f84714beda7a4afd4336a1a3c Mon Sep 17 00:00:00 2001 From: Agusti Bau Date: Sat, 2 May 2020 13:25:18 +0200 Subject: [PATCH 6/6] formatted files --- src/components/views/elements/DNDTagTile.js | 50 ++++++++++----------- src/components/views/elements/TagTile.js | 50 ++++++++++----------- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/components/views/elements/DNDTagTile.js b/src/components/views/elements/DNDTagTile.js index b017704e70..67572d4508 100644 --- a/src/components/views/elements/DNDTagTile.js +++ b/src/components/views/elements/DNDTagTile.js @@ -19,7 +19,7 @@ import TagTile from './TagTile'; import React from 'react'; import { Draggable } from 'react-beautiful-dnd'; -import {ContextMenu, toRightOf, useContextMenu} from "../../structures/ContextMenu"; +import { ContextMenu, toRightOf, useContextMenu } from "../../structures/ContextMenu"; import * as sdk from '../../../index'; export default function DNDTagTile(props) { @@ -35,28 +35,28 @@ export default function DNDTagTile(props) { ); } - return
- - { (provided, snapshot) => ( -
- -
- ) } -
- {contextMenu} -
; + return
+ + {(provided, snapshot) => ( +
+ +
+ )} +
+ {contextMenu} +
; } diff --git a/src/components/views/elements/TagTile.js b/src/components/views/elements/TagTile.js index 0f98971198..d8983ac2ea 100644 --- a/src/components/views/elements/TagTile.js +++ b/src/components/views/elements/TagTile.js @@ -84,7 +84,7 @@ export default createReactClass({ this.props.tag, ).then((profile) => { if (this.unmounted) return; - this.setState({profile}); + this.setState({ profile }); }).catch((err) => { console.warn('Could not fetch group profile for ' + this.props.tag, err); }); @@ -111,18 +111,18 @@ export default createReactClass({ }, onMouseOver: function() { - this.setState({hover: true}); + this.setState({ hover: true }); }, onMouseOut: function() { - this.setState({hover: false}); + this.setState({ hover: false }); }, openMenu: function(e) { // Prevent the TagTile onClick event firing as well e.stopPropagation(); e.preventDefault(); - this.setState({hover: false}); + this.setState({ hover: false }); this.props.openMenu(); }, @@ -154,32 +154,32 @@ export default createReactClass({ // FIXME: this ought to use AccessibleButton for a11y but that causes onMouseOut/onMouseOver to fire too much const contextButton = this.state.hover || this.props.menuDisplayed ?
- { "\u00B7\u00B7\u00B7" } + {"\u00B7\u00B7\u00B7"}
:
; const AccessibleTooltipButton = sdk.getComponent("elements.AccessibleTooltipButton"); return +
-
- - { contextButton } - { badgeElement } -
- ; + + {contextButton} + {badgeElement} +
+
; }, });