Convert EntityTile to TS

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
This commit is contained in:
Šimon Brandner 2021-06-23 17:27:53 +02:00
parent f0ad70f0e7
commit d5acfc6cf4
No known key found for this signature in database
GPG key ID: 9760693FDD98A790

View file

@ -16,14 +16,19 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import React from 'react'; import React, { createRef } from 'react';
import PropTypes from 'prop-types';
import * as sdk from '../../../index';
import AccessibleButton from '../elements/AccessibleButton'; import AccessibleButton from '../elements/AccessibleButton';
import { _t } from '../../../languageHandler'; import { _td } from '../../../languageHandler';
import classNames from "classnames"; import classNames from "classnames";
import E2EIcon from './E2EIcon'; import E2EIcon from './E2EIcon';
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import BaseAvatar from '../avatars/BaseAvatar';
import PresenceLabel from "./PresenceLabel";
const PowerLabel: Record<string, string> = {
"admin": _td("Admin"),
"moderator": _td("Mod"),
}
const PRESENCE_CLASS = { const PRESENCE_CLASS = {
"offline": "mx_EntityTile_offline", "offline": "mx_EntityTile_offline",
@ -31,14 +36,14 @@ const PRESENCE_CLASS = {
"unavailable": "mx_EntityTile_unavailable", "unavailable": "mx_EntityTile_unavailable",
}; };
function presenceClassForMember(presenceState, lastActiveAgo, showPresence) { function presenceClassForMember(presenceState: string, lastActiveAgo: number, showPresence: boolean) {
if (showPresence === false) { if (showPresence === false) {
return 'mx_EntityTile_online_beenactive'; return 'mx_EntityTile_online_beenactive';
} }
// offline is split into two categories depending on whether we have // offline is split into two categories depending on whether we have
// a last_active_ago for them. // a last_active_ago for them.
if (presenceState == 'offline') { if (presenceState === 'offline') {
if (lastActiveAgo) { if (lastActiveAgo) {
return PRESENCE_CLASS['offline'] + '_beenactive'; return PRESENCE_CLASS['offline'] + '_beenactive';
} else { } else {
@ -51,29 +56,34 @@ function presenceClassForMember(presenceState, lastActiveAgo, showPresence) {
} }
} }
@replaceableComponent("views.rooms.EntityTile") interface IProps {
class EntityTile extends React.Component { name?: string,
static propTypes = { title?: string,
name: PropTypes.string, avatarJsx?: JSX.Element, // <BaseAvatar />
title: PropTypes.string, className?: string,
avatarJsx: PropTypes.any, // <BaseAvatar /> presenceState?: string,
className: PropTypes.string, presenceLastActiveAgo?: number,
presenceState: PropTypes.string, presenceLastTs?: number,
presenceLastActiveAgo: PropTypes.number, presenceCurrentlyActive?: boolean,
presenceLastTs: PropTypes.number, showInviteButton?: boolean,
presenceCurrentlyActive: PropTypes.bool, shouldComponentUpdate?(nextProps: IProps, nextState: IState): boolean,
showInviteButton: PropTypes.bool, onClick?(): void,
shouldComponentUpdate: PropTypes.func, suppressOnHover?: boolean,
onClick: PropTypes.func, showPresence?: boolean,
suppressOnHover: PropTypes.bool, subtextLabel?: string,
showPresence: PropTypes.bool, e2eStatus?: string,
subtextLabel: PropTypes.string, powerStatus?: string,
e2eStatus: PropTypes.string, }
};
interface IState {
hover: boolean;
}
@replaceableComponent("views.rooms.EntityTile")
export default class EntityTile extends React.Component<IProps, IState> {
static defaultProps = { static defaultProps = {
shouldComponentUpdate: function(nextProps, nextState) { return true; }, shouldComponentUpdate: (nextProps: IProps, nextState: IState) => { return true; },
onClick: function() {}, onClick: () => {},
presenceState: "offline", presenceState: "offline",
presenceLastActiveAgo: 0, presenceLastActiveAgo: 0,
presenceLastTs: 0, presenceLastTs: 0,
@ -81,12 +91,17 @@ class EntityTile extends React.Component {
suppressOnHover: false, suppressOnHover: false,
showPresence: true, showPresence: true,
}; };
private container = createRef<HTMLDivElement>();
state = { constructor(props: IProps) {
super(props);
this.state = {
hover: false, hover: false,
}; };
}
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps: IProps, nextState: IState) {
if (this.state.hover !== nextState.hover) return true; if (this.state.hover !== nextState.hover) return true;
return this.props.shouldComponentUpdate(nextProps, nextState); return this.props.shouldComponentUpdate(nextProps, nextState);
} }
@ -110,7 +125,6 @@ class EntityTile extends React.Component {
const activeAgo = this.props.presenceLastActiveAgo ? const activeAgo = this.props.presenceLastActiveAgo ?
(Date.now() - (this.props.presenceLastTs - this.props.presenceLastActiveAgo)) : -1; (Date.now() - (this.props.presenceLastTs - this.props.presenceLastActiveAgo)) : -1;
const PresenceLabel = sdk.getComponent("rooms.PresenceLabel");
let presenceLabel = null; let presenceLabel = null;
if (this.props.showPresence) { if (this.props.showPresence) {
presenceLabel = <PresenceLabel activeAgo={activeAgo} presenceLabel = <PresenceLabel activeAgo={activeAgo}
@ -155,10 +169,7 @@ class EntityTile extends React.Component {
let powerLabel; let powerLabel;
const powerStatus = this.props.powerStatus; const powerStatus = this.props.powerStatus;
if (powerStatus) { if (powerStatus) {
const powerText = { const powerText = PowerLabel[powerStatus];
[EntityTile.POWER_STATUS_MODERATOR]: _t("Mod"),
[EntityTile.POWER_STATUS_ADMIN]: _t("Admin"),
}[powerStatus];
powerLabel = <div className="mx_EntityTile_power">{powerText}</div>; powerLabel = <div className="mx_EntityTile_power">{powerText}</div>;
} }
@ -168,14 +179,12 @@ class EntityTile extends React.Component {
e2eIcon = <E2EIcon status={e2eStatus} isUser={true} bordered={true} />; e2eIcon = <E2EIcon status={e2eStatus} isUser={true} bordered={true} />;
} }
const BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
const av = this.props.avatarJsx || const av = this.props.avatarJsx ||
<BaseAvatar name={this.props.name} width={36} height={36} aria-hidden="true" />; <BaseAvatar name={this.props.name} width={36} height={36} aria-hidden="true" />;
// The wrapping div is required to make the magic mouse listener work, for some reason. // The wrapping div is required to make the magic mouse listener work, for some reason.
return ( return (
<div ref={(c) => this.container = c} > <div ref={this.container} >
<AccessibleButton <AccessibleButton
className={classNames(mainClassNames)} className={classNames(mainClassNames)}
title={this.props.title} title={this.props.title}
@ -193,8 +202,3 @@ class EntityTile extends React.Component {
); );
} }
} }
EntityTile.POWER_STATUS_MODERATOR = "moderator";
EntityTile.POWER_STATUS_ADMIN = "admin";
export default EntityTile;