Convert to Typescript and move from ClientPeg to Context
This commit is contained in:
parent
87ae47bd61
commit
76afc1100a
4 changed files with 87 additions and 77 deletions
|
@ -62,7 +62,7 @@ limitations under the License.
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
|
||||||
&:link, &:visited {
|
&:link, &:visited {
|
||||||
color: $tertiary-fg-color
|
color: $tertiary-fg-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2019 New Vector Ltd
|
Copyright 2019, 2021 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -14,29 +14,30 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from "react";
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { EventType } from "matrix-js-sdk/src/@types/event";
|
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
|
import { EventType } from "matrix-js-sdk/src/@types/event";
|
||||||
|
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
|
import { Relations } from "matrix-js-sdk/src/models/relations";
|
||||||
|
|
||||||
import * as sdk from '../../../index';
|
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import { isContentActionable } from '../../../utils/EventUtils';
|
import { isContentActionable } from '../../../utils/EventUtils';
|
||||||
import {MatrixClientPeg} from '../../../MatrixClientPeg';
|
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
import { ContextMenuTooltipButton } from "../../../accessibility/context_menu/ContextMenuTooltipButton";
|
||||||
import {ContextMenuTooltipButton} from "../../../accessibility/context_menu/ContextMenuTooltipButton";
|
import { aboveLeftOf, ContextMenu, useContextMenu } from "../../structures/ContextMenu";
|
||||||
import {aboveLeftOf, ContextMenu, useContextMenu} from "../../structures/ContextMenu";
|
import ReactionPicker from "../emojipicker/ReactionPicker";
|
||||||
|
import ReactionsRowButton from "./ReactionsRowButton";
|
||||||
|
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||||
|
|
||||||
// The maximum number of reactions to initially show on a message.
|
// The maximum number of reactions to initially show on a message.
|
||||||
const MAX_ITEMS_WHEN_LIMITED = 8;
|
const MAX_ITEMS_WHEN_LIMITED = 8;
|
||||||
|
|
||||||
const ReactButton = ({ mxEvent, reactions }) => {
|
const ReactButton = ({ mxEvent, reactions }: IProps) => {
|
||||||
const [menuDisplayed, button, openMenu, closeMenu] = useContextMenu();
|
const [menuDisplayed, button, openMenu, closeMenu] = useContextMenu();
|
||||||
|
|
||||||
let contextMenu;
|
let contextMenu;
|
||||||
if (menuDisplayed) {
|
if (menuDisplayed) {
|
||||||
const buttonRect = button.current.getBoundingClientRect();
|
const buttonRect = button.current.getBoundingClientRect();
|
||||||
const ReactionPicker = sdk.getComponent('emojipicker.ReactionPicker');
|
|
||||||
contextMenu = <ContextMenu {...aboveLeftOf(buttonRect)} onFinished={closeMenu} managed={false}>
|
contextMenu = <ContextMenu {...aboveLeftOf(buttonRect)} onFinished={closeMenu} managed={false}>
|
||||||
<ReactionPicker mxEvent={mxEvent} reactions={reactions} onFinished={closeMenu} />
|
<ReactionPicker mxEvent={mxEvent} reactions={reactions} onFinished={closeMenu} />
|
||||||
</ContextMenu>;
|
</ContextMenu>;
|
||||||
|
@ -57,17 +58,24 @@ const ReactButton = ({ mxEvent, reactions }) => {
|
||||||
</React.Fragment>;
|
</React.Fragment>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@replaceableComponent("views.messages.ReactionsRow")
|
interface IProps {
|
||||||
export default class ReactionsRow extends React.PureComponent {
|
|
||||||
static propTypes = {
|
|
||||||
// The event we're displaying reactions for
|
// The event we're displaying reactions for
|
||||||
mxEvent: PropTypes.object.isRequired,
|
mxEvent: MatrixEvent;
|
||||||
// The Relations model from the JS SDK for reactions to `mxEvent`
|
// The Relations model from the JS SDK for reactions to `mxEvent`
|
||||||
reactions: PropTypes.object,
|
reactions?: Relations;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
interface IState {
|
||||||
super(props);
|
myReactions: MatrixEvent[];
|
||||||
|
showAll: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@replaceableComponent("views.messages.ReactionsRow")
|
||||||
|
export default class ReactionsRow extends React.PureComponent<IProps, IState> {
|
||||||
|
static contextType = MatrixClientContext;
|
||||||
|
|
||||||
|
constructor(props, context) {
|
||||||
|
super(props, context);
|
||||||
|
|
||||||
if (props.reactions) {
|
if (props.reactions) {
|
||||||
props.reactions.on("Relations.add", this.onReactionsChange);
|
props.reactions.on("Relations.add", this.onReactionsChange);
|
||||||
|
@ -123,7 +131,7 @@ export default class ReactionsRow extends React.PureComponent {
|
||||||
if (!reactions) {
|
if (!reactions) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const userId = MatrixClientPeg.get().getUserId();
|
const userId = this.context.getUserId();
|
||||||
const myReactions = reactions.getAnnotationsBySender()[userId];
|
const myReactions = reactions.getAnnotationsBySender()[userId];
|
||||||
if (!myReactions) {
|
if (!myReactions) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -145,7 +153,6 @@ export default class ReactionsRow extends React.PureComponent {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ReactionsRowButton = sdk.getComponent('messages.ReactionsRowButton');
|
|
||||||
let items = reactions.getSortedAnnotationsByKey().map(([content, events]) => {
|
let items = reactions.getSortedAnnotationsByKey().map(([content, events]) => {
|
||||||
const count = events.size;
|
const count = events.size;
|
||||||
if (!count) {
|
if (!count) {
|
||||||
|
@ -182,7 +189,7 @@ export default class ReactionsRow extends React.PureComponent {
|
||||||
</a>;
|
</a>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = this.context;
|
||||||
|
|
||||||
let addReactionButton;
|
let addReactionButton;
|
||||||
if (cli.getRoom(mxEvent.getRoomId()).currentState.maySendEvent(EventType.Reaction, cli.getUserId())) {
|
if (cli.getRoom(mxEvent.getRoomId()).currentState.maySendEvent(EventType.Reaction, cli.getUserId())) {
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2019 New Vector Ltd
|
Copyright 2019, 2021 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -14,49 +14,54 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from "react";
|
||||||
import PropTypes from 'prop-types';
|
import classNames from "classnames";
|
||||||
import classNames from 'classnames';
|
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
|
|
||||||
import {MatrixClientPeg} from '../../../MatrixClientPeg';
|
|
||||||
import * as sdk from '../../../index';
|
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import { formatCommaSeparatedList } from '../../../utils/FormattingUtils';
|
import { formatCommaSeparatedList } from '../../../utils/FormattingUtils';
|
||||||
import dis from "../../../dispatcher/dispatcher";
|
import dis from "../../../dispatcher/dispatcher";
|
||||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||||
|
import ReactionsRowButtonTooltip from "./ReactionsRowButtonTooltip";
|
||||||
|
import AccessibleButton from "../elements/AccessibleButton";
|
||||||
|
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||||
|
|
||||||
|
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 Set of Martix reaction events for this key
|
||||||
|
reactionEvents: Set<MatrixEvent>;
|
||||||
|
// A possible Matrix event if the current user has voted for this type
|
||||||
|
myReactionEvent?: MatrixEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IState {
|
||||||
|
tooltipRendered: boolean;
|
||||||
|
tooltipVisible: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
@replaceableComponent("views.messages.ReactionsRowButton")
|
@replaceableComponent("views.messages.ReactionsRowButton")
|
||||||
export default class ReactionsRowButton extends React.PureComponent {
|
export default class ReactionsRowButton extends React.PureComponent<IProps, IState> {
|
||||||
static propTypes = {
|
static contextType = MatrixClientContext;
|
||||||
// The event we're displaying reactions for
|
|
||||||
mxEvent: PropTypes.object.isRequired,
|
|
||||||
// The reaction content / key / emoji
|
|
||||||
content: PropTypes.string.isRequired,
|
|
||||||
// The count of votes for this key
|
|
||||||
count: PropTypes.number.isRequired,
|
|
||||||
// A Set of Martix reaction events for this key
|
|
||||||
reactionEvents: PropTypes.object.isRequired,
|
|
||||||
// A possible Matrix event if the current user has voted for this type
|
|
||||||
myReactionEvent: PropTypes.object,
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(props) {
|
state = {
|
||||||
super(props);
|
tooltipRendered: false,
|
||||||
|
|
||||||
this.state = {
|
|
||||||
tooltipVisible: false,
|
tooltipVisible: false,
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
onClick = (ev) => {
|
onClick = () => {
|
||||||
const { mxEvent, myReactionEvent, content } = this.props;
|
const { mxEvent, myReactionEvent, content } = this.props;
|
||||||
if (myReactionEvent) {
|
if (myReactionEvent) {
|
||||||
MatrixClientPeg.get().redactEvent(
|
this.context.redactEvent(
|
||||||
mxEvent.getRoomId(),
|
mxEvent.getRoomId(),
|
||||||
myReactionEvent.getId(),
|
myReactionEvent.getId(),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
MatrixClientPeg.get().sendEvent(mxEvent.getRoomId(), "m.reaction", {
|
this.context.sendEvent(mxEvent.getRoomId(), "m.reaction", {
|
||||||
"m.relates_to": {
|
"m.relates_to": {
|
||||||
"rel_type": "m.annotation",
|
"rel_type": "m.annotation",
|
||||||
"event_id": mxEvent.getId(),
|
"event_id": mxEvent.getId(),
|
||||||
|
@ -83,8 +88,6 @@ export default class ReactionsRowButton extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const ReactionsRowButtonTooltip =
|
|
||||||
sdk.getComponent('messages.ReactionsRowButtonTooltip');
|
|
||||||
const { mxEvent, content, count, reactionEvents, myReactionEvent } = this.props;
|
const { mxEvent, content, count, reactionEvents, myReactionEvent } = this.props;
|
||||||
|
|
||||||
const classes = classNames({
|
const classes = classNames({
|
||||||
|
@ -102,7 +105,7 @@ export default class ReactionsRowButton extends React.PureComponent {
|
||||||
/>;
|
/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const room = MatrixClientPeg.get().getRoom(mxEvent.getRoomId());
|
const room = this.context.getRoom(mxEvent.getRoomId());
|
||||||
let label;
|
let label;
|
||||||
if (room) {
|
if (room) {
|
||||||
const senders = [];
|
const senders = [];
|
||||||
|
@ -130,7 +133,6 @@ export default class ReactionsRowButton extends React.PureComponent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const isPeeking = room.getMyMembership() !== "join";
|
const isPeeking = room.getMyMembership() !== "join";
|
||||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
|
||||||
return <AccessibleButton
|
return <AccessibleButton
|
||||||
className={classes}
|
className={classes}
|
||||||
aria-label={label}
|
aria-label={label}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
Copyright 2019, 2021 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -14,33 +14,34 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from "react";
|
||||||
import PropTypes from 'prop-types';
|
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
|
|
||||||
import {MatrixClientPeg} from '../../../MatrixClientPeg';
|
|
||||||
import * as sdk from '../../../index';
|
|
||||||
import { unicodeToShortcode } from '../../../HtmlUtils';
|
import { unicodeToShortcode } from '../../../HtmlUtils';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import { formatCommaSeparatedList } from '../../../utils/FormattingUtils';
|
import { formatCommaSeparatedList } from '../../../utils/FormattingUtils';
|
||||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||||
|
import Tooltip from "../elements/Tooltip";
|
||||||
|
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
// The event we're displaying reactions for
|
||||||
|
mxEvent: MatrixEvent;
|
||||||
|
// The reaction content / key / emoji
|
||||||
|
content: string;
|
||||||
|
// A Set of Martix reaction events for this key
|
||||||
|
reactionEvents: Set<MatrixEvent>;
|
||||||
|
visible: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
@replaceableComponent("views.messages.ReactionsRowButtonTooltip")
|
@replaceableComponent("views.messages.ReactionsRowButtonTooltip")
|
||||||
export default class ReactionsRowButtonTooltip extends React.PureComponent {
|
export default class ReactionsRowButtonTooltip extends React.PureComponent<IProps> {
|
||||||
static propTypes = {
|
static contextType = MatrixClientContext;
|
||||||
// The event we're displaying reactions for
|
|
||||||
mxEvent: PropTypes.object.isRequired,
|
|
||||||
// The reaction content / key / emoji
|
|
||||||
content: PropTypes.string.isRequired,
|
|
||||||
// A Set of Martix reaction events for this key
|
|
||||||
reactionEvents: PropTypes.object.isRequired,
|
|
||||||
visible: PropTypes.bool.isRequired,
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const Tooltip = sdk.getComponent('elements.Tooltip');
|
|
||||||
const { content, reactionEvents, mxEvent, visible } = this.props;
|
const { content, reactionEvents, mxEvent, visible } = this.props;
|
||||||
|
|
||||||
const room = MatrixClientPeg.get().getRoom(mxEvent.getRoomId());
|
const room = this.context.getRoom(mxEvent.getRoomId());
|
||||||
let tooltipLabel;
|
let tooltipLabel;
|
||||||
if (room) {
|
if (room) {
|
||||||
const senders = [];
|
const senders = [];
|
Loading…
Reference in a new issue