From 576241236c96728e450d8495ee9334820d63dd6f Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Wed, 8 May 2019 13:53:41 +0100 Subject: [PATCH] Extract `ReactionDimension` out of `MessageActionBar` The reactions bits were cluttering up `MessageActionBar` so they have now been extracted to a separate component. --- res/css/_components.scss | 1 + res/css/views/messages/_MessageActionBar.scss | 10 --- .../views/messages/_ReactionDimension.scss | 25 +++++++ .../views/messages/MessageActionBar.js | 74 ++----------------- .../views/messages/ReactionDimension.js | 73 ++++++++++++++++++ 5 files changed, 107 insertions(+), 76 deletions(-) create mode 100644 res/css/views/messages/_ReactionDimension.scss create mode 100644 src/components/views/messages/ReactionDimension.js diff --git a/res/css/_components.scss b/res/css/_components.scss index 36648f4982..6e681894e3 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -115,6 +115,7 @@ @import "./views/messages/_MTextBody.scss"; @import "./views/messages/_MessageActionBar.scss"; @import "./views/messages/_MessageTimestamp.scss"; +@import "./views/messages/_ReactionDimension.scss"; @import "./views/messages/_ReactionsRow.scss"; @import "./views/messages/_ReactionsRowButton.scss"; @import "./views/messages/_RoomAvatarEvent.scss"; diff --git a/res/css/views/messages/_MessageActionBar.scss b/res/css/views/messages/_MessageActionBar.scss index 877e1916fc..419542036e 100644 --- a/res/css/views/messages/_MessageActionBar.scss +++ b/res/css/views/messages/_MessageActionBar.scss @@ -72,13 +72,3 @@ limitations under the License. .mx_MessageActionBar_optionsButton::after { mask-image: url('$(res)/img/icon_context.svg'); } - -.mx_MessageActionBar_reactionDimension { - width: 42px; - display: flex; - justify-content: space-evenly; -} - -.mx_MessageActionBar_reactionDisabled { - opacity: 0.4; -} diff --git a/res/css/views/messages/_ReactionDimension.scss b/res/css/views/messages/_ReactionDimension.scss new file mode 100644 index 0000000000..9a891d05cf --- /dev/null +++ b/res/css/views/messages/_ReactionDimension.scss @@ -0,0 +1,25 @@ +/* +Copyright 2019 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_ReactionDimension { + width: 42px; + display: flex; + justify-content: space-evenly; +} + +.mx_ReactionDimension_disabled { + opacity: 0.4; +} diff --git a/src/components/views/messages/MessageActionBar.js b/src/components/views/messages/MessageActionBar.js index 74eb4165e9..9a482c9e6e 100644 --- a/src/components/views/messages/MessageActionBar.js +++ b/src/components/views/messages/MessageActionBar.js @@ -16,7 +16,6 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; -import classNames from 'classnames'; import { _t } from '../../../languageHandler'; import sdk from '../../../index'; @@ -35,15 +34,6 @@ export default class MessageActionBar extends React.PureComponent { onFocusChange: PropTypes.func, }; - constructor(props) { - super(props); - - this.state = { - agreeDimension: null, - likeDimension: null, - }; - } - onFocusChange = (focused) => { if (!this.props.onFocusChange) { return; @@ -59,31 +49,6 @@ export default class MessageActionBar extends React.PureComponent { ); } - onAgreeClick = (ev) => { - this.toggleDimensionValue("agreeDimension", "agree"); - } - - onDisagreeClick = (ev) => { - this.toggleDimensionValue("agreeDimension", "disagree"); - } - - onLikeClick = (ev) => { - this.toggleDimensionValue("likeDimension", "like"); - } - - onDislikeClick = (ev) => { - this.toggleDimensionValue("likeDimension", "dislike"); - } - - toggleDimensionValue(dimension, value) { - const state = this.state[dimension]; - const newState = state !== value ? value : null; - this.setState({ - [dimension]: newState, - }); - // TODO: Send the reaction event - } - onReplyClick = (ev) => { dis.dispatch({ action: 'reply_to_event', @@ -134,25 +99,21 @@ export default class MessageActionBar extends React.PureComponent { return null; } - const state = this.state.agreeDimension; + const ReactionDimension = sdk.getComponent('messages.ReactionDimension'); const options = [ { key: "agree", content: "👍", - onClick: this.onAgreeClick, }, { key: "disagree", content: "👎", - onClick: this.onDisagreeClick, }, ]; - - return - {this.renderReactionDimensionItems(state, options)} - ; + options={options} + />; } renderLikeDimension() { @@ -160,40 +121,21 @@ export default class MessageActionBar extends React.PureComponent { return null; } - const state = this.state.likeDimension; + const ReactionDimension = sdk.getComponent('messages.ReactionDimension'); const options = [ { key: "like", content: "🙂", - onClick: this.onLikeClick, }, { key: "dislike", content: "😔", - onClick: this.onDislikeClick, }, ]; - - return - {this.renderReactionDimensionItems(state, options)} - ; - } - - renderReactionDimensionItems(state, options) { - return options.map(option => { - const disabled = state && state !== option.key; - const classes = classNames({ - mx_MessageActionBar_reactionDisabled: disabled, - }); - return - {option.content} - ; - }); + options={options} + />; } render() { diff --git a/src/components/views/messages/ReactionDimension.js b/src/components/views/messages/ReactionDimension.js new file mode 100644 index 0000000000..3b72aabe15 --- /dev/null +++ b/src/components/views/messages/ReactionDimension.js @@ -0,0 +1,73 @@ +/* +Copyright 2019 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 classNames from 'classnames'; + +export default class ReactionDimension extends React.PureComponent { + static propTypes = { + options: PropTypes.array.isRequired, + title: PropTypes.string, + }; + + constructor(props) { + super(props); + + this.state = { + selected: null, + }; + } + + onOptionClick = (ev) => { + const { key } = ev.target.dataset; + this.toggleDimensionValue(key); + } + + toggleDimensionValue(value) { + const state = this.state.selected; + const newState = state !== value ? value : null; + this.setState({ + selected: newState, + }); + // TODO: Send the reaction event + } + + render() { + const { selected } = this.state; + const { options } = this.props; + + const items = options.map(option => { + const disabled = selected && selected !== option.key; + const classes = classNames({ + mx_ReactionDimension_disabled: disabled, + }); + return + {option.content} + ; + }); + + return + {items} + ; + } +}