Convert to Typescript and move from ClientPeg to Context

This commit is contained in:
Michael Telatynski 2021-05-13 14:13:00 +01:00
parent 87ae47bd61
commit 76afc1100a
4 changed files with 87 additions and 77 deletions

View file

@ -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 {

View file

@ -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())) {

View file

@ -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}

View file

@ -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 = [];