Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 2e86d53

Browse files
authored
Merge pull request #6027 from matrix-org/t3chguy/fix/i80
Encourage more diverse reactions to content
2 parents 712bdba + a41d76b commit 2e86d53

File tree

9 files changed

+178
-91
lines changed

9 files changed

+178
-91
lines changed

res/css/views/messages/_MessageActionBar.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ limitations under the License.
8585
left: 0;
8686
height: 100%;
8787
width: 100%;
88+
mask-size: 18px;
8889
mask-repeat: no-repeat;
8990
mask-position: center;
9091
background-color: $message-action-bar-fg-color;

res/css/views/messages/_ReactionsRow.scss

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,55 @@ limitations under the License.
1717
.mx_ReactionsRow {
1818
margin: 6px 0;
1919
color: $primary-fg-color;
20+
21+
.mx_ReactionsRow_addReactionButton {
22+
position: relative;
23+
display: none; // show on hover of the .mx_EventTile
24+
width: 24px;
25+
height: 24px;
26+
vertical-align: middle;
27+
margin-left: 4px;
28+
29+
&::before {
30+
content: '';
31+
position: absolute;
32+
height: 100%;
33+
width: 100%;
34+
mask-size: 16px;
35+
mask-repeat: no-repeat;
36+
mask-position: center;
37+
background-color: $tertiary-fg-color;
38+
mask-image: url('$(res)/img/element-icons/room/message-bar/emoji.svg');
39+
}
40+
41+
&.mx_ReactionsRow_addReactionButton_active {
42+
display: inline-block; // keep showing whilst the context menu is shown
43+
}
44+
45+
&:hover, &.mx_ReactionsRow_addReactionButton_active {
46+
&::before {
47+
background-color: $primary-fg-color;
48+
}
49+
}
50+
}
51+
}
52+
53+
.mx_EventTile:hover .mx_ReactionsRow_addReactionButton {
54+
display: inline-block;
2055
}
2156

2257
.mx_ReactionsRow_showAll {
2358
text-decoration: none;
24-
font-size: $font-10px;
25-
font-weight: 600;
26-
margin-left: 6px;
27-
vertical-align: top;
28-
29-
&:hover,
30-
&:link,
31-
&:visited {
32-
color: $accent-color;
59+
font-size: $font-12px;
60+
line-height: $font-20px;
61+
margin-left: 4px;
62+
vertical-align: middle;
63+
64+
&:link, &:visited {
65+
color: $tertiary-fg-color;
66+
}
67+
68+
&:hover {
69+
color: $primary-fg-color;
3370
}
3471
}

res/css/views/messages/_ReactionsRowButton.scss

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ limitations under the License.
1616

1717
.mx_ReactionsRowButton {
1818
display: inline-flex;
19-
line-height: $font-21px;
19+
line-height: $font-20px;
2020
margin-right: 6px;
21-
padding: 0 6px;
21+
padding: 1px 6px;
2222
border: 1px solid $reaction-row-button-border-color;
2323
border-radius: 10px;
2424
background-color: $reaction-row-button-bg-color;
2525
cursor: pointer;
2626
user-select: none;
27+
vertical-align: middle;
2728

2829
&:hover {
2930
border-color: $reaction-row-button-hover-border-color;
Lines changed: 5 additions & 5 deletions
Loading
Lines changed: 2 additions & 4 deletions
Loading

src/components/views/messages/ReactionsRow.js renamed to src/components/views/messages/ReactionsRow.tsx

Lines changed: 65 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright 2019 New Vector Ltd
2+
Copyright 2019, 2021 The Matrix.org Foundation C.I.C.
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
@@ -14,29 +14,68 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
import React from 'react';
18-
import PropTypes from 'prop-types';
17+
import React from "react";
18+
import classNames from "classnames";
19+
import { EventType } from "matrix-js-sdk/src/@types/event";
20+
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
21+
import { Relations } from "matrix-js-sdk/src/models/relations";
1922

20-
import * as sdk from '../../../index';
2123
import { _t } from '../../../languageHandler';
2224
import { isContentActionable } from '../../../utils/EventUtils';
23-
import {MatrixClientPeg} from '../../../MatrixClientPeg';
24-
import {replaceableComponent} from "../../../utils/replaceableComponent";
25+
import { replaceableComponent } from "../../../utils/replaceableComponent";
26+
import { ContextMenuTooltipButton } from "../../../accessibility/context_menu/ContextMenuTooltipButton";
27+
import { aboveLeftOf, ContextMenu, useContextMenu } from "../../structures/ContextMenu";
28+
import ReactionPicker from "../emojipicker/ReactionPicker";
29+
import ReactionsRowButton from "./ReactionsRowButton";
30+
import MatrixClientContext from "../../../contexts/MatrixClientContext";
2531

2632
// The maximum number of reactions to initially show on a message.
2733
const MAX_ITEMS_WHEN_LIMITED = 8;
2834

29-
@replaceableComponent("views.messages.ReactionsRow")
30-
export default class ReactionsRow extends React.PureComponent {
31-
static propTypes = {
32-
// The event we're displaying reactions for
33-
mxEvent: PropTypes.object.isRequired,
34-
// The Relations model from the JS SDK for reactions to `mxEvent`
35-
reactions: PropTypes.object,
35+
const ReactButton = ({ mxEvent, reactions }: IProps) => {
36+
const [menuDisplayed, button, openMenu, closeMenu] = useContextMenu();
37+
38+
let contextMenu;
39+
if (menuDisplayed) {
40+
const buttonRect = button.current.getBoundingClientRect();
41+
contextMenu = <ContextMenu {...aboveLeftOf(buttonRect)} onFinished={closeMenu} managed={false}>
42+
<ReactionPicker mxEvent={mxEvent} reactions={reactions} onFinished={closeMenu} />
43+
</ContextMenu>;
3644
}
3745

38-
constructor(props) {
39-
super(props);
46+
return <React.Fragment>
47+
<ContextMenuTooltipButton
48+
className={classNames("mx_ReactionsRow_addReactionButton", {
49+
mx_ReactionsRow_addReactionButton_active: menuDisplayed,
50+
})}
51+
title={_t("Add reaction")}
52+
onClick={openMenu}
53+
isExpanded={menuDisplayed}
54+
inputRef={button}
55+
/>
56+
57+
{ contextMenu }
58+
</React.Fragment>;
59+
};
60+
61+
interface IProps {
62+
// The event we're displaying reactions for
63+
mxEvent: MatrixEvent;
64+
// The Relations model from the JS SDK for reactions to `mxEvent`
65+
reactions?: Relations;
66+
}
67+
68+
interface IState {
69+
myReactions: MatrixEvent[];
70+
showAll: boolean;
71+
}
72+
73+
@replaceableComponent("views.messages.ReactionsRow")
74+
export default class ReactionsRow extends React.PureComponent<IProps, IState> {
75+
static contextType = MatrixClientContext;
76+
77+
constructor(props, context) {
78+
super(props, context);
4079

4180
if (props.reactions) {
4281
props.reactions.on("Relations.add", this.onReactionsChange);
@@ -92,7 +131,7 @@ export default class ReactionsRow extends React.PureComponent {
92131
if (!reactions) {
93132
return null;
94133
}
95-
const userId = MatrixClientPeg.get().getUserId();
134+
const userId = this.context.getUserId();
96135
const myReactions = reactions.getAnnotationsBySender()[userId];
97136
if (!myReactions) {
98137
return null;
@@ -114,7 +153,6 @@ export default class ReactionsRow extends React.PureComponent {
114153
return null;
115154
}
116155

117-
const ReactionsRowButton = sdk.getComponent('messages.ReactionsRowButton');
118156
let items = reactions.getSortedAnnotationsByKey().map(([content, events]) => {
119157
const count = events.size;
120158
if (!count) {
@@ -151,13 +189,21 @@ export default class ReactionsRow extends React.PureComponent {
151189
</a>;
152190
}
153191

192+
const cli = this.context;
193+
194+
let addReactionButton;
195+
if (cli.getRoom(mxEvent.getRoomId()).currentState.maySendEvent(EventType.Reaction, cli.getUserId())) {
196+
addReactionButton = <ReactButton mxEvent={mxEvent} reactions={reactions} />;
197+
}
198+
154199
return <div
155200
className="mx_ReactionsRow"
156201
role="toolbar"
157202
aria-label={_t("Reactions")}
158203
>
159-
{items}
160-
{showAllButton}
204+
{ items }
205+
{ showAllButton }
206+
{ addReactionButton }
161207
</div>;
162208
}
163209
}

0 commit comments

Comments
 (0)