Convert MemberStatusMessageAvatar to TS

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
This commit is contained in:
Šimon Brandner 2021-09-14 18:53:31 +02:00
parent ac0ba2d597
commit 5baaa6b77e
No known key found for this signature in database
GPG key ID: 55C211A1226CB17D
2 changed files with 33 additions and 28 deletions

View file

@ -15,43 +15,48 @@ limitations under the License.
*/ */
import React, { createRef } from 'react'; import React, { createRef } from 'react';
import PropTypes from 'prop-types';
import { MatrixClientPeg } from '../../../MatrixClientPeg'; import { MatrixClientPeg } from '../../../MatrixClientPeg';
import { _t } from "../../../languageHandler"; import { _t } from "../../../languageHandler";
import MemberAvatar from '../avatars/MemberAvatar'; import MemberAvatar from '../avatars/MemberAvatar';
import classNames from 'classnames'; import classNames from 'classnames';
import StatusMessageContextMenu from "../context_menus/StatusMessageContextMenu"; import StatusMessageContextMenu from "../context_menus/StatusMessageContextMenu";
import SettingsStore from "../../../settings/SettingsStore"; import SettingsStore from "../../../settings/SettingsStore";
import { ContextMenu, ContextMenuButton } from "../../structures/ContextMenu"; import { ChevronFace, ContextMenu, ContextMenuButton } from "../../structures/ContextMenu";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import { ResizeMethod } from "matrix-js-sdk/src/@types/partials";
interface IProps {
member: RoomMember;
width?: number;
height?: number;
resizeMethod?: ResizeMethod;
}
interface IState {
hasStatus: boolean;
menuDisplayed: boolean;
}
@replaceableComponent("views.avatars.MemberStatusMessageAvatar") @replaceableComponent("views.avatars.MemberStatusMessageAvatar")
export default class MemberStatusMessageAvatar extends React.Component { export default class MemberStatusMessageAvatar extends React.Component<IProps, IState> {
static propTypes = { public static defaultProps: Partial<IProps> = {
member: PropTypes.object.isRequired,
width: PropTypes.number,
height: PropTypes.number,
resizeMethod: PropTypes.string,
};
static defaultProps = {
width: 40, width: 40,
height: 40, height: 40,
resizeMethod: 'crop', resizeMethod: 'crop',
}; };
private button = createRef<HTMLDivElement>();
constructor(props) { constructor(props: IProps) {
super(props); super(props);
this.state = { this.state = {
hasStatus: this.hasStatus, hasStatus: this.hasStatus,
menuDisplayed: false, menuDisplayed: false,
}; };
this._button = createRef();
} }
componentDidMount() { public componentDidMount(): void {
if (this.props.member.userId !== MatrixClientPeg.get().getUserId()) { if (this.props.member.userId !== MatrixClientPeg.get().getUserId()) {
throw new Error("Cannot use MemberStatusMessageAvatar on anyone but the logged in user"); throw new Error("Cannot use MemberStatusMessageAvatar on anyone but the logged in user");
} }
@ -62,44 +67,44 @@ export default class MemberStatusMessageAvatar extends React.Component {
if (!user) { if (!user) {
return; return;
} }
user.on("User._unstable_statusMessage", this._onStatusMessageCommitted); user.on("User._unstable_statusMessage", this.onStatusMessageCommitted);
} }
componentWillUnmount() { public componentWillUnmount(): void {
const { user } = this.props.member; const { user } = this.props.member;
if (!user) { if (!user) {
return; return;
} }
user.removeListener( user.removeListener(
"User._unstable_statusMessage", "User._unstable_statusMessage",
this._onStatusMessageCommitted, this.onStatusMessageCommitted,
); );
} }
get hasStatus() { private get hasStatus(): boolean {
const { user } = this.props.member; const { user } = this.props.member;
if (!user) { if (!user) {
return false; return false;
} }
return !!user._unstable_statusMessage; return !!user.unstable_statusMessage;
} }
_onStatusMessageCommitted = () => { private onStatusMessageCommitted = (): void => {
// The `User` object has observed a status message change. // The `User` object has observed a status message change.
this.setState({ this.setState({
hasStatus: this.hasStatus, hasStatus: this.hasStatus,
}); });
}; };
openMenu = () => { private openMenu = (): void => {
this.setState({ menuDisplayed: true }); this.setState({ menuDisplayed: true });
}; };
closeMenu = () => { private closeMenu = (): void => {
this.setState({ menuDisplayed: false }); this.setState({ menuDisplayed: false });
}; };
render() { public render(): JSX.Element {
const avatar = <MemberAvatar const avatar = <MemberAvatar
member={this.props.member} member={this.props.member}
width={this.props.width} width={this.props.width}
@ -118,7 +123,7 @@ export default class MemberStatusMessageAvatar extends React.Component {
let contextMenu; let contextMenu;
if (this.state.menuDisplayed) { if (this.state.menuDisplayed) {
const elementRect = this._button.current.getBoundingClientRect(); const elementRect = this.button.current.getBoundingClientRect();
const chevronWidth = 16; // See .mx_ContextualMenu_chevron_bottom const chevronWidth = 16; // See .mx_ContextualMenu_chevron_bottom
const chevronMargin = 1; // Add some spacing away from target const chevronMargin = 1; // Add some spacing away from target
@ -126,7 +131,7 @@ export default class MemberStatusMessageAvatar extends React.Component {
contextMenu = ( contextMenu = (
<ContextMenu <ContextMenu
chevronOffset={(elementRect.width - chevronWidth) / 2} chevronOffset={(elementRect.width - chevronWidth) / 2}
chevronFace="bottom" chevronFace={ChevronFace.Bottom}
left={elementRect.left + window.pageXOffset} left={elementRect.left + window.pageXOffset}
top={elementRect.top + window.pageYOffset - chevronMargin} top={elementRect.top + window.pageYOffset - chevronMargin}
menuWidth={226} menuWidth={226}
@ -140,7 +145,7 @@ export default class MemberStatusMessageAvatar extends React.Component {
return <React.Fragment> return <React.Fragment>
<ContextMenuButton <ContextMenuButton
className={classes} className={classes}
inputRef={this._button} inputRef={this.button}
onClick={this.openMenu} onClick={this.openMenu}
isExpanded={this.state.menuDisplayed} isExpanded={this.state.menuDisplayed}
label={_t("User Status")} label={_t("User Status")}

View file

@ -56,7 +56,7 @@ let instanceCount = 0;
const NARROW_MODE_BREAKPOINT = 500; const NARROW_MODE_BREAKPOINT = 500;
interface IComposerAvatarProps { interface IComposerAvatarProps {
me: object; me: RoomMember;
} }
function ComposerAvatar(props: IComposerAvatarProps) { function ComposerAvatar(props: IComposerAvatarProps) {