@@ -18,6 +18,7 @@ import React, { SyntheticEvent } from "react";
18
18
import classNames from "classnames" ;
19
19
import { MatrixEvent , MatrixEventEvent } from "matrix-js-sdk/src/models/event" ;
20
20
import { Relations , RelationsEvent } from "matrix-js-sdk/src/models/relations" ;
21
+ import { uniqBy } from "lodash" ;
21
22
22
23
import { _t } from "../../../languageHandler" ;
23
24
import { isContentActionable } from "../../../utils/EventUtils" ;
@@ -177,6 +178,10 @@ export default class ReactionsRow extends React.PureComponent<IProps, IState> {
177
178
if ( ! count ) {
178
179
return null ;
179
180
}
181
+ // Deduplicate the events as per the spec https://spec.matrix.org/v1.7/client-server-api/#annotations-client-behaviour
182
+ // This isn't done by the underlying data model as applications may still need access to the whole list of events
183
+ // for moderation purposes.
184
+ const deduplicatedEvents = uniqBy ( [ ...events ] , ( e ) => e . getSender ( ) ) ;
180
185
const myReactionEvent = myReactions ?. find ( ( mxEvent ) => {
181
186
if ( mxEvent . isRedacted ( ) ) {
182
187
return false ;
@@ -187,9 +192,9 @@ export default class ReactionsRow extends React.PureComponent<IProps, IState> {
187
192
< ReactionsRowButton
188
193
key = { content }
189
194
content = { content }
190
- count = { count }
195
+ count = { deduplicatedEvents . length }
191
196
mxEvent = { mxEvent }
192
- reactionEvents = { events }
197
+ reactionEvents = { deduplicatedEvents }
193
198
myReactionEvent = { myReactionEvent }
194
199
disabled = {
195
200
! this . context . canReact ||
0 commit comments