From b0b7932f5fc6960262bdbd3b54bf0d1e119a6677 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 12 Dec 2018 22:26:39 -0700 Subject: [PATCH] Move status context menu to its own component This fixes a lot of the state bugs such as buttons not updating, etc. This commit also adds the border around the avatar to indicate a status is set. --- res/css/_components.scss | 1 + .../avatars/_MemberStatusMessageAvatar.scss | 37 +------- .../_StatusMessageContextMenu.scss | 51 +++++++++++ .../avatars/MemberStatusMessageAvatar.js | 61 +------------- .../context_menus/StatusMessageContextMenu.js | 84 +++++++++++++++++++ 5 files changed, 143 insertions(+), 91 deletions(-) create mode 100644 res/css/views/context_menus/_StatusMessageContextMenu.scss create mode 100644 src/components/views/context_menus/StatusMessageContextMenu.js diff --git a/res/css/_components.scss b/res/css/_components.scss index 7975a71e4f..7271038444 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -27,6 +27,7 @@ @import "./views/avatars/_MemberStatusMessageAvatar.scss"; @import "./views/context_menus/_MessageContextMenu.scss"; @import "./views/context_menus/_RoomTileContextMenu.scss"; +@import "./views/context_menus/_StatusMessageContextMenu.scss"; @import "./views/context_menus/_TagTileContextMenu.scss"; @import "./views/dialogs/_BugReportDialog.scss"; @import "./views/dialogs/_ChangelogDialog.scss"; diff --git a/res/css/views/avatars/_MemberStatusMessageAvatar.scss b/res/css/views/avatars/_MemberStatusMessageAvatar.scss index 4027bfa514..c857b9807b 100644 --- a/res/css/views/avatars/_MemberStatusMessageAvatar.scss +++ b/res/css/views/avatars/_MemberStatusMessageAvatar.scss @@ -14,38 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -.mx_MemberStatusMessageAvatar_contextMenu_message { - display: inline-block; - border-radius: 3px 0 0 3px; - border: 1px solid $input-border-color; - font-size: 13px; - padding: 7px 7px 7px 9px; - width: 135px; - background-color: $primary-bg-color !important; -} - -.mx_MemberStatusMessageAvatar_contextMenu_submit { - display: inline-block; -} - -.mx_MemberStatusMessageAvatar_contextMenu_submit img { - vertical-align: middle; - margin-left: 8px; -} - -.mx_MemberStatusMessageAvatar_contextMenu hr { - border: 0.5px solid $menu-border-color; -} - -.mx_MemberStatusMessageAvatar_contextMenu_clearIcon { - margin: 5px 15px 5px 5px; - vertical-align: middle; -} - -.mx_MemberStatusMessageAvatar_contextMenu_clear { - padding: 2px; -} - -.mx_MemberStatusMessageAvatar_contextMenu_hasStatus .mx_MemberStatusMessageAvatar_contextMenu_clear { - color: $warning-color; +.mx_MemberStatusMessageAvatar_hasStatus { + border: 2px solid $accent-color; + border-radius: 40px; } diff --git a/res/css/views/context_menus/_StatusMessageContextMenu.scss b/res/css/views/context_menus/_StatusMessageContextMenu.scss new file mode 100644 index 0000000000..465f1b53e4 --- /dev/null +++ b/res/css/views/context_menus/_StatusMessageContextMenu.scss @@ -0,0 +1,51 @@ +/* +Copyright 2018 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_StatusMessageContextMenu_message { + display: inline-block; + border-radius: 3px 0 0 3px; + border: 1px solid $input-border-color; + font-size: 13px; + padding: 7px 7px 7px 9px; + width: 135px; + background-color: $primary-bg-color !important; +} + +.mx_StatusMessageContextMenu_submit { + display: inline-block; +} + +.mx_StatusMessageContextMenu_submit img { + vertical-align: middle; + margin-left: 8px; +} + +.mx_StatusMessageContextMenu hr { + border: 0.5px solid $menu-border-color; +} + +.mx_StatusMessageContextMenu_clearIcon { + margin: 5px 15px 5px 5px; + vertical-align: middle; +} + +.mx_StatusMessageContextMenu_clear { + padding: 2px; +} + +.mx_StatusMessageContextMenu_hasStatus .mx_StatusMessageContextMenu_clear { + color: $warning-color; +} diff --git a/src/components/views/avatars/MemberStatusMessageAvatar.js b/src/components/views/avatars/MemberStatusMessageAvatar.js index 66122f9eee..00b25b3c73 100644 --- a/src/components/views/avatars/MemberStatusMessageAvatar.js +++ b/src/components/views/avatars/MemberStatusMessageAvatar.js @@ -16,22 +16,18 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; -import { _t } from '../../../languageHandler'; import MatrixClientPeg from '../../../MatrixClientPeg'; import AccessibleButton from '../elements/AccessibleButton'; import MemberAvatar from '../avatars/MemberAvatar'; import classNames from 'classnames'; import * as ContextualMenu from "../../structures/ContextualMenu"; -import GenericElementContextMenu from "../context_menus/GenericElementContextMenu"; +import StatusMessageContextMenu from "../context_menus/StatusMessageContextMenu"; export default class MemberStatusMessageAvatar extends React.Component { constructor(props, context) { super(props, context); this._onRoomStateEvents = this._onRoomStateEvents.bind(this); this._onClick = this._onClick.bind(this); - this._onClearClick = this._onClearClick.bind(this); - this._onSubmit = this._onSubmit.bind(this); - this._onStatusChange = this._onStatusChange.bind(this); } componentWillMount() { @@ -75,64 +71,16 @@ export default class MemberStatusMessageAvatar extends React.Component { let y = elementRect.top + (elementRect.height / 2) + window.pageYOffset; y = y - (chevronOffset + 4); // where 4 is 1/4 the height of the chevron - const contextMenu = this._renderContextMenu(); - - ContextualMenu.createMenu(GenericElementContextMenu, { + ContextualMenu.createMenu(StatusMessageContextMenu, { chevronOffset: chevronOffset, chevronFace: 'bottom', left: x, top: y, menuWidth: 190, - element: contextMenu, + user: this.props.member.user, }); } - async _onClearClick(e) { - await MatrixClientPeg.get().setStatusMessage(""); - this.setState({message: ""}); - } - - _onSubmit(e) { - e.preventDefault(); - MatrixClientPeg.get().setStatusMessage(this.state.message); - } - - _onStatusChange(e) { - this.setState({message: e.target.value}); - } - - _renderContextMenu() { - const form =
- - - - -
; - - const clearIcon = this.state.message ? "img/cancel-red.svg" : "img/cancel.svg"; - const clearButton = - {_t('Clear - {_t("Clear status")} - ; - - const menuClasses = classNames({ - "mx_MemberStatusMessageAvatar_contextMenu": true, - "mx_MemberStatusMessageAvatar_contextMenu_hasStatus": this.state.message, - }); - - return
- { form } -
- { clearButton } -
; - } - render() { const hasStatus = this.props.member.user ? !!this.props.member.user.statusMessage : false; @@ -145,8 +93,7 @@ export default class MemberStatusMessageAvatar extends React.Component { + resizeMethod={this.props.resizeMethod} /> ; } } diff --git a/src/components/views/context_menus/StatusMessageContextMenu.js b/src/components/views/context_menus/StatusMessageContextMenu.js new file mode 100644 index 0000000000..f77669329f --- /dev/null +++ b/src/components/views/context_menus/StatusMessageContextMenu.js @@ -0,0 +1,84 @@ +/* +Copyright 2018 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import React from 'react'; +import PropTypes from 'prop-types'; +import { _t } from '../../../languageHandler'; +import MatrixClientPeg from '../../../MatrixClientPeg'; +import AccessibleButton from '../elements/AccessibleButton'; +import classNames from 'classnames'; + +export default class StatusMessageContextMenu extends React.Component { + constructor(props, context) { + super(props, context); + this._onClearClick = this._onClearClick.bind(this); + this._onSubmit = this._onSubmit.bind(this); + this._onStatusChange = this._onStatusChange.bind(this); + + this.state = { + message: props.user ? props.user.statusMessage : "", + }; + } + + async _onClearClick(e) { + await MatrixClientPeg.get().setStatusMessage(""); + this.setState({message: ""}); + } + + _onSubmit(e) { + e.preventDefault(); + MatrixClientPeg.get().setStatusMessage(this.state.message); + } + + _onStatusChange(e) { + this.setState({message: e.target.value}); + } + + render() { + const form =
+ + + + +
; + + const clearIcon = this.state.message ? "img/cancel-red.svg" : "img/cancel.svg"; + const clearButton = + {_t('Clear + {_t("Clear status")} + ; + + const menuClasses = classNames({ + "mx_StatusMessageContextMenu": true, + "mx_StatusMessageContextMenu_hasStatus": this.state.message, + }); + + return
+ { form } +
+ { clearButton } +
; + } +} + +StatusMessageContextMenu.propTypes = { + // js-sdk User object. Not required because it might not exist. + user: PropTypes.object, +};