Files
ThreadNet-Web/src/components/views/messages/ReactionsRowButton.tsx
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

134 lines
4.9 KiB
TypeScript
Raw Normal View History

/*
2024-09-09 14:57:16 +01:00
Copyright 2024 New Vector Ltd.
Copyright 2019-2021 The Matrix.org Foundation C.I.C.
2024-09-09 14:57:16 +01:00
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
import React from "react";
import classNames from "classnames";
2024-03-25 12:48:48 +00:00
import { EventType, MatrixEvent, RelationType } from "matrix-js-sdk/src/matrix";
2023-09-01 04:16:24 -06:00
import { mediaFromMxc } from "../../../customisations/Media";
2019-12-06 15:48:34 +01:00
import { _t } from "../../../languageHandler";
import { formatList } from "../../../utils/FormattingUtils";
import dis from "../../../dispatcher/dispatcher";
import ReactionsRowButtonTooltip from "./ReactionsRowButtonTooltip";
import AccessibleButton from "../elements/AccessibleButton";
import MatrixClientContext from "../../../contexts/MatrixClientContext";
2023-09-01 04:16:24 -06:00
import { REACTION_SHORTCODE_KEY } from "./ReactionsRow";
2024-03-25 12:48:48 +00:00
2023-09-01 04:16:24 -06:00
export interface IProps {
// The event we're displaying reactions for
mxEvent: MatrixEvent;
// The reaction content / key / emoji
content: string;
// The count of votes for this key
count: number;
// A list of Matrix reaction events for this key
reactionEvents: MatrixEvent[];
// A possible Matrix event if the current user has voted for this type
myReactionEvent?: MatrixEvent;
// Whether to prevent quick-reactions by clicking on this reaction
disabled?: boolean;
2023-09-01 04:16:24 -06:00
// Whether to render custom image reactions
customReactionImagesEnabled?: boolean;
}
2024-05-22 11:27:01 +02:00
export default class ReactionsRowButton extends React.PureComponent<IProps> {
public static contextType = MatrixClientContext;
2024-08-01 17:14:28 +01:00
public declare context: React.ContextType<typeof MatrixClientContext>;
2019-05-02 11:48:32 +01:00
public onClick = (): void => {
2019-05-09 19:11:40 +01:00
const { mxEvent, myReactionEvent, content } = this.props;
if (myReactionEvent) {
this.context.redactEvent(mxEvent.getRoomId()!, myReactionEvent.getId()!);
2019-05-09 19:11:40 +01:00
} else {
2024-03-25 12:48:48 +00:00
this.context.sendEvent(mxEvent.getRoomId()!, EventType.Reaction, {
2019-05-09 19:11:40 +01:00
"m.relates_to": {
2024-03-25 12:48:48 +00:00
rel_type: RelationType.Annotation,
event_id: mxEvent.getId()!,
2019-05-09 19:11:40 +01:00
key: content,
},
});
2021-06-29 13:11:58 +01:00
dis.dispatch({ action: "message_sent" });
2019-05-09 19:11:40 +01:00
}
2019-05-02 11:48:32 +01:00
};
public render(): React.ReactNode {
2019-12-06 15:48:34 +01:00
const { mxEvent, content, count, reactionEvents, myReactionEvent } = this.props;
2019-05-02 11:48:32 +01:00
const classes = classNames({
mx_ReactionsRowButton: true,
2019-05-09 19:11:40 +01:00
mx_ReactionsRowButton_selected: !!myReactionEvent,
2019-05-02 11:48:32 +01:00
});
const room = this.context.getRoom(mxEvent.getRoomId());
let label: string | undefined;
2023-09-01 04:16:24 -06:00
let customReactionName: string | undefined;
2019-12-06 15:48:34 +01:00
if (room) {
const senders: string[] = [];
2019-12-06 15:48:34 +01:00
for (const reactionEvent of reactionEvents) {
const member = room.getMember(reactionEvent.getSender()!);
senders.push(member?.name || reactionEvent.getSender()!);
2023-09-01 04:16:24 -06:00
customReactionName =
(this.props.customReactionImagesEnabled &&
REACTION_SHORTCODE_KEY.findIn(reactionEvent.getContent())) ||
undefined;
}
const reactors = formatList(senders, 6);
if (content) {
label = _t("timeline|reactions|label", {
2023-09-01 04:16:24 -06:00
reactors,
content: customReactionName || content,
});
} else {
label = reactors;
2019-12-06 15:48:34 +01:00
}
}
2023-09-01 04:16:24 -06:00
let reactionContent = (
<span className="mx_ReactionsRowButton_content" aria-hidden="true">
{content}
</span>
);
if (this.props.customReactionImagesEnabled && content.startsWith("mxc://")) {
const imageSrc = mediaFromMxc(content).srcHttp;
if (imageSrc) {
reactionContent = (
<img
className="mx_ReactionsRowButton_content"
alt={customReactionName || _t("timeline|reactions|custom_reaction_fallback_label")}
2023-09-01 04:16:24 -06:00
src={imageSrc}
width="16"
height="16"
/>
);
}
}
return (
2024-05-22 11:27:01 +02:00
<ReactionsRowButtonTooltip
mxEvent={this.props.mxEvent}
content={content}
reactionEvents={reactionEvents}
customReactionImagesEnabled={this.props.customReactionImagesEnabled}
2019-05-02 11:48:32 +01:00
>
2024-05-22 11:27:01 +02:00
<AccessibleButton
className={classes}
aria-label={label}
onClick={this.onClick}
disabled={this.props.disabled}
>
{reactionContent}
<span className="mx_ReactionsRowButton_count" aria-hidden="true">
{count}
</span>
</AccessibleButton>
</ReactionsRowButtonTooltip>
);
}
}