Remove toggling reaction dimensions

This removes the v1 Reactions UX which only allowed you to choose only one emoji
out of each pair. It is replaced by a different UX inside a tooltip and without
these constraints.

Part of https://github.com/vector-im/riot-web/issues/9753
pull/21833/head
J. Ryan Stinnett 2019-06-25 16:17:02 +01:00
parent 088bbbfb91
commit c1821fabd3
5 changed files with 0 additions and 238 deletions

View File

@ -117,7 +117,6 @@
@import "./views/messages/_MTextBody.scss";
@import "./views/messages/_MessageActionBar.scss";
@import "./views/messages/_MessageTimestamp.scss";
@import "./views/messages/_ReactionDimension.scss";
@import "./views/messages/_ReactionQuickTooltip.scss";
@import "./views/messages/_ReactionTooltipButton.scss";
@import "./views/messages/_ReactionsRow.scss";

View File

@ -1,25 +0,0 @@
/*
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;
}

View File

@ -146,45 +146,13 @@ export default class MessageActionBar extends React.PureComponent {
/>;
}
renderAgreeDimension() {
if (!this.isReactionsEnabled()) {
return null;
}
const ReactionDimension = sdk.getComponent('messages.ReactionDimension');
return <ReactionDimension
title={_t("Agree or Disagree")}
options={["👍", "👎"]}
reactions={this.props.reactions}
mxEvent={this.props.mxEvent}
/>;
}
renderLikeDimension() {
if (!this.isReactionsEnabled()) {
return null;
}
const ReactionDimension = sdk.getComponent('messages.ReactionDimension');
return <ReactionDimension
title={_t("Like or Dislike")}
options={["🙂", "😔"]}
reactions={this.props.reactions}
mxEvent={this.props.mxEvent}
/>;
}
render() {
let reactButton;
let agreeDimensionReactionButtons;
let likeDimensionReactionButtons;
let replyButton;
let editButton;
if (isContentActionable(this.props.mxEvent)) {
reactButton = this.renderReactButton();
agreeDimensionReactionButtons = this.renderAgreeDimension();
likeDimensionReactionButtons = this.renderLikeDimension();
replyButton = <span className="mx_MessageActionBar_maskButton mx_MessageActionBar_replyButton"
title={_t("Reply")}
onClick={this.onReplyClick}
@ -199,8 +167,6 @@ export default class MessageActionBar extends React.PureComponent {
return <div className="mx_MessageActionBar">
{reactButton}
{agreeDimensionReactionButtons}
{likeDimensionReactionButtons}
{replyButton}
{editButton}
<span className="mx_MessageActionBar_maskButton mx_MessageActionBar_optionsButton"

View File

@ -1,176 +0,0 @@
/*
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';
import MatrixClientPeg from '../../../MatrixClientPeg';
export default class ReactionDimension extends React.PureComponent {
static propTypes = {
mxEvent: PropTypes.object.isRequired,
// Array of strings containing the emoji for each option
options: PropTypes.array.isRequired,
title: PropTypes.string,
// The Relations model from the JS SDK for reactions
reactions: PropTypes.object,
};
constructor(props) {
super(props);
this.state = this.getSelection();
if (props.reactions) {
props.reactions.on("Relations.add", this.onReactionsChange);
props.reactions.on("Relations.remove", this.onReactionsChange);
props.reactions.on("Relations.redaction", this.onReactionsChange);
}
}
componentDidUpdate(prevProps) {
if (prevProps.reactions !== this.props.reactions) {
this.props.reactions.on("Relations.add", this.onReactionsChange);
this.props.reactions.on("Relations.remove", this.onReactionsChange);
this.props.reactions.on("Relations.redaction", this.onReactionsChange);
this.onReactionsChange();
}
}
componentWillUnmount() {
if (this.props.reactions) {
this.props.reactions.removeListener(
"Relations.add",
this.onReactionsChange,
);
this.props.reactions.removeListener(
"Relations.remove",
this.onReactionsChange,
);
this.props.reactions.removeListener(
"Relations.redaction",
this.onReactionsChange,
);
}
}
onReactionsChange = () => {
this.setState(this.getSelection());
}
getSelection() {
const myReactions = this.getMyReactions();
if (!myReactions) {
return {
selectedOption: null,
selectedReactionEvent: null,
};
}
const { options } = this.props;
let selectedOption = null;
let selectedReactionEvent = null;
for (const option of options) {
const reactionForOption = myReactions.find(mxEvent => {
if (mxEvent.isRedacted()) {
return false;
}
return mxEvent.getRelation().key === option;
});
if (!reactionForOption) {
continue;
}
if (selectedOption) {
// If there are multiple selected values (only expected to occur via
// non-Riot clients), then act as if none are selected.
return {
selectedOption: null,
selectedReactionEvent: null,
};
}
selectedOption = option;
selectedReactionEvent = reactionForOption;
}
return { selectedOption, selectedReactionEvent };
}
getMyReactions() {
const reactions = this.props.reactions;
if (!reactions) {
return null;
}
const userId = MatrixClientPeg.get().getUserId();
const myReactions = reactions.getAnnotationsBySender()[userId];
if (!myReactions) {
return null;
}
return [...myReactions.values()];
}
onOptionClick = (ev) => {
const { key } = ev.target.dataset;
this.toggleDimension(key);
}
toggleDimension(key) {
const { selectedOption, selectedReactionEvent } = this.state;
const newSelectedOption = selectedOption !== key ? key : null;
this.setState({
selectedOption: newSelectedOption,
});
if (selectedReactionEvent) {
MatrixClientPeg.get().redactEvent(
this.props.mxEvent.getRoomId(),
selectedReactionEvent.getId(),
);
}
if (newSelectedOption) {
MatrixClientPeg.get().sendEvent(this.props.mxEvent.getRoomId(), "m.reaction", {
"m.relates_to": {
"rel_type": "m.annotation",
"event_id": this.props.mxEvent.getId(),
"key": newSelectedOption,
},
});
}
}
render() {
const { selectedOption } = this.state;
const { options } = this.props;
const items = options.map(option => {
const disabled = selectedOption && selectedOption !== option;
const classes = classNames({
mx_ReactionDimension_disabled: disabled,
});
return <span key={option}
data-key={option}
className={classes}
onClick={this.onOptionClick}
>
{option}
</span>;
});
return <span className="mx_ReactionDimension"
title={this.props.title}
aria-hidden={true}
>
{items}
</span>;
}
}

View File

@ -928,8 +928,6 @@
"Today": "Today",
"Yesterday": "Yesterday",
"Error decrypting audio": "Error decrypting audio",
"Agree or Disagree": "Agree or Disagree",
"Like or Dislike": "Like or Dislike",
"Reply": "Reply",
"Edit": "Edit",
"Options": "Options",