Use compound tooltip in `ReactionRowButton`

pull/28217/head
Florian Duros 2024-05-22 11:27:01 +02:00
parent 67c7514dcd
commit a6907a033e
No known key found for this signature in database
GPG Key ID: A5BBB4041B493F15
4 changed files with 31 additions and 87 deletions

View File

@ -44,20 +44,10 @@ export interface IProps {
customReactionImagesEnabled?: boolean;
}
interface IState {
tooltipRendered: boolean;
tooltipVisible: boolean;
}
export default class ReactionsRowButton extends React.PureComponent<IProps, IState> {
export default class ReactionsRowButton extends React.PureComponent<IProps> {
public static contextType = MatrixClientContext;
public context!: React.ContextType<typeof MatrixClientContext>;
public state = {
tooltipRendered: false,
tooltipVisible: false,
};
public onClick = (): void => {
const { mxEvent, myReactionEvent, content } = this.props;
if (myReactionEvent) {
@ -74,21 +64,6 @@ export default class ReactionsRowButton extends React.PureComponent<IProps, ISta
}
};
public onMouseOver = (): void => {
this.setState({
// To avoid littering the DOM with a tooltip for every reaction,
// only render it on first use.
tooltipRendered: true,
tooltipVisible: true,
});
};
public onMouseLeave = (): void => {
this.setState({
tooltipVisible: false,
});
};
public render(): React.ReactNode {
const { mxEvent, content, count, reactionEvents, myReactionEvent } = this.props;
@ -97,19 +72,6 @@ export default class ReactionsRowButton extends React.PureComponent<IProps, ISta
mx_ReactionsRowButton_selected: !!myReactionEvent,
});
let tooltip: JSX.Element | undefined;
if (this.state.tooltipRendered) {
tooltip = (
<ReactionsRowButtonTooltip
mxEvent={this.props.mxEvent}
content={content}
reactionEvents={reactionEvents}
visible={this.state.tooltipVisible}
customReactionImagesEnabled={this.props.customReactionImagesEnabled}
/>
);
}
const room = this.context.getRoom(mxEvent.getRoomId());
let label: string | undefined;
let customReactionName: string | undefined;
@ -156,20 +118,24 @@ export default class ReactionsRowButton extends React.PureComponent<IProps, ISta
}
return (
<ReactionsRowButtonTooltip
mxEvent={this.props.mxEvent}
content={content}
reactionEvents={reactionEvents}
customReactionImagesEnabled={this.props.customReactionImagesEnabled}
>
<AccessibleButton
className={classes}
aria-label={label}
onClick={this.onClick}
disabled={this.props.disabled}
onMouseOver={this.onMouseOver}
onMouseLeave={this.onMouseLeave}
>
{reactionContent}
<span className="mx_ReactionsRowButton_count" aria-hidden="true">
{count}
</span>
{tooltip}
</AccessibleButton>
</ReactionsRowButtonTooltip>
);
}
}

View File

@ -14,13 +14,13 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from "react";
import React, { PropsWithChildren } from "react";
import { MatrixEvent } from "matrix-js-sdk/src/matrix";
import { Tooltip } from "@vector-im/compound-web";
import { unicodeToShortcode } from "../../../HtmlUtils";
import { _t } from "../../../languageHandler";
import { formatList } from "../../../utils/FormattingUtils";
import Tooltip from "../elements/Tooltip";
import MatrixClientContext from "../../../contexts/MatrixClientContext";
import { REACTION_SHORTCODE_KEY } from "./ReactionsRow";
interface IProps {
@ -30,20 +30,18 @@ interface IProps {
content: string;
// A list of Matrix reaction events for this key
reactionEvents: MatrixEvent[];
visible: boolean;
// Whether to render custom image reactions
customReactionImagesEnabled?: boolean;
}
export default class ReactionsRowButtonTooltip extends React.PureComponent<IProps> {
export default class ReactionsRowButtonTooltip extends React.PureComponent<PropsWithChildren<IProps>> {
public static contextType = MatrixClientContext;
public context!: React.ContextType<typeof MatrixClientContext>;
public render(): React.ReactNode {
const { content, reactionEvents, mxEvent, visible } = this.props;
const { content, reactionEvents, mxEvent, children } = this.props;
const room = this.context.getRoom(mxEvent.getRoomId());
let tooltipLabel: JSX.Element | undefined;
if (room) {
const senders: string[] = [];
let customReactionName: string | undefined;
@ -57,34 +55,16 @@ export default class ReactionsRowButtonTooltip extends React.PureComponent<IProp
undefined;
}
const shortName = unicodeToShortcode(content) || customReactionName;
tooltipLabel = (
<div>
{_t(
"timeline|reactions|tooltip",
{
shortName,
},
{
reactors: () => {
return <div className="mx_Tooltip_title">{formatList(senders, 6)}</div>;
},
reactedWith: (sub) => {
if (!shortName) {
return null;
}
return <div className="mx_Tooltip_sub">{sub}</div>;
},
},
)}
</div>
const formattedSenders = formatList(senders, 6);
const caption = shortName ? _t("timeline|reactions|tooltip_caption", { shortName }) : undefined;
return (
<Tooltip label={formattedSenders} caption={caption} placement="right">
{children}
</Tooltip>
);
}
let tooltip: JSX.Element | undefined;
if (tooltipLabel) {
tooltip = <Tooltip visible={visible} label={tooltipLabel} />;
}
return tooltip;
return children;
}
}

View File

@ -3483,7 +3483,7 @@
"add_reaction_prompt": "Add reaction",
"custom_reaction_fallback_label": "Custom reaction",
"label": "%(reactors)s reacted with %(content)s",
"tooltip": "<reactors/><reactedWith>reacted with %(shortName)s</reactedWith>"
"tooltip_caption": "reacted with %(shortName)s"
},
"read_receipt_title": {
"one": "Seen by %(count)s person",

View File

@ -46,7 +46,6 @@ exports[`ReactionsRowButton renders reaction row button custom image reactions c
>
2
</span>
<div />
</div>
</DocumentFragment>
`;
@ -95,7 +94,6 @@ exports[`ReactionsRowButton renders reaction row button emojis correctly 2`] = `
>
2
</span>
<div />
</div>
</DocumentFragment>
`;