Enable @typescript-eslint/explicit-function-return-type in /src (#9788)

* Enable `@typescript-eslint/explicit-member-accessibility` on /src

* Prettier

* Enable `@typescript-eslint/explicit-function-return-type` in /src

* Fix types

* tsc strict fixes

* Delint

* Fix test

* Fix bad merge
This commit is contained in:
Michael Telatynski 2023-01-12 13:25:14 +00:00 committed by GitHub
parent 7a36ba0fde
commit 030b7e90bf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
683 changed files with 3459 additions and 3013 deletions

View file

@ -72,7 +72,7 @@ export default class DateSeparator extends React.Component<IProps, IState> {
);
}
public componentWillUnmount() {
public componentWillUnmount(): void {
SettingsStore.unwatchSetting(this.settingWatcherRef);
}
@ -218,7 +218,7 @@ export default class DateSeparator extends React.Component<IProps, IState> {
);
}
public render() {
public render(): JSX.Element {
const label = this.getLabel();
let dateHeaderContent;

View file

@ -31,7 +31,7 @@ interface IProps {
}
export default class DisambiguatedProfile extends React.Component<IProps> {
public render() {
public render(): JSX.Element {
const { fallbackName, member, colored, emphasizeDisplayName, onClick } = this.props;
const rawDisplayName = member?.rawDisplayName || fallbackName;
const mxid = member?.userId;

View file

@ -52,7 +52,7 @@ export default class DownloadActionButton extends React.PureComponent<IProps, IS
};
}
private onDownloadClick = async () => {
private onDownloadClick = async (): Promise<void> => {
if (this.state.loading) return;
if (this.props.mediaEventHelperGet().media.isEncrypted) {
@ -71,7 +71,7 @@ export default class DownloadActionButton extends React.PureComponent<IProps, IS
await this.doDownload();
};
private async doDownload() {
private async doDownload(): Promise<void> {
await this.downloader.download({
blob: this.state.blob,
name: this.props.mediaEventHelperGet().fileName,
@ -79,7 +79,7 @@ export default class DownloadActionButton extends React.PureComponent<IProps, IS
this.setState({ loading: false });
}
public render() {
public render(): JSX.Element {
let spinner: JSX.Element;
if (this.state.loading) {
spinner = <Spinner w={18} h={18} />;

View file

@ -15,7 +15,7 @@ limitations under the License.
*/
import React, { createRef } from "react";
import { EventStatus, MatrixEvent, MatrixEventEvent } from "matrix-js-sdk/src/models/event";
import { EventStatus, IContent, MatrixEvent, MatrixEventEvent } from "matrix-js-sdk/src/models/event";
import classNames from "classnames";
import * as HtmlUtils from "../../../HtmlUtils";
@ -32,7 +32,7 @@ import ConfirmAndWaitRedactDialog from "../dialogs/ConfirmAndWaitRedactDialog";
import ViewSource from "../../structures/ViewSource";
import SettingsStore from "../../../settings/SettingsStore";
function getReplacedContent(event) {
function getReplacedContent(event: MatrixEvent): IContent {
const originalContent = event.getOriginalContent();
return originalContent["m.new_content"] || originalContent;
}

View file

@ -35,7 +35,7 @@ const JumpToDatePicker: React.FC<IProps> = ({ ts, onDatePicked }: IProps) => {
const [dateValue, setDateValue] = useState(dateDefaultValue);
const [onFocus, isActive, ref] = useRovingTabIndex<HTMLInputElement>();
const onDateValueInput = (ev: React.ChangeEvent<HTMLInputElement>) => setDateValue(ev.target.value);
const onDateValueInput = (ev: React.ChangeEvent<HTMLInputElement>): void => setDateValue(ev.target.value);
const onJumpToDateSubmit = (ev: FormEvent): void => {
ev.preventDefault();
onDatePicked(dateValue);

View file

@ -61,7 +61,7 @@ export default class LegacyCallEvent extends React.PureComponent<IProps, IState>
};
}
public componentDidMount() {
public componentDidMount(): void {
this.props.callEventGrouper.addListener(LegacyCallEventGrouperEvent.StateChanged, this.onStateChanged);
this.props.callEventGrouper.addListener(LegacyCallEventGrouperEvent.SilencedChanged, this.onSilencedChanged);
this.props.callEventGrouper.addListener(LegacyCallEventGrouperEvent.LengthChanged, this.onLengthChanged);
@ -70,7 +70,7 @@ export default class LegacyCallEvent extends React.PureComponent<IProps, IState>
this.wrapperElement.current && this.resizeObserver.observe(this.wrapperElement.current);
}
public componentWillUnmount() {
public componentWillUnmount(): void {
this.props.callEventGrouper.removeListener(LegacyCallEventGrouperEvent.StateChanged, this.onStateChanged);
this.props.callEventGrouper.removeListener(LegacyCallEventGrouperEvent.SilencedChanged, this.onSilencedChanged);
this.props.callEventGrouper.removeListener(LegacyCallEventGrouperEvent.LengthChanged, this.onLengthChanged);
@ -89,11 +89,11 @@ export default class LegacyCallEvent extends React.PureComponent<IProps, IState>
this.setState({ narrow: wrapperElementEntry.contentRect.width < MAX_NON_NARROW_WIDTH });
};
private onSilencedChanged = (newState) => {
private onSilencedChanged = (newState: boolean): void => {
this.setState({ silenced: newState });
};
private onStateChanged = (newState: CallState) => {
private onStateChanged = (newState: CallState): void => {
this.setState({ callState: newState });
};

View file

@ -45,7 +45,7 @@ export default class MAudioBody extends React.PureComponent<IBodyProps, IState>
this.state = {};
}
public async componentDidMount() {
public async componentDidMount(): Promise<void> {
let buffer: ArrayBuffer;
try {
@ -81,7 +81,7 @@ export default class MAudioBody extends React.PureComponent<IBodyProps, IState>
// Note: the components later on will handle preparing the Playback class for us.
}
public componentWillUnmount() {
public componentWillUnmount(): void {
this.state.playback?.destroy();
}
@ -93,7 +93,7 @@ export default class MAudioBody extends React.PureComponent<IBodyProps, IState>
);
}
public render() {
public render(): JSX.Element {
if (this.state.error) {
return (
<MediaProcessingError className="mx_MAudioBody">

View file

@ -152,7 +152,7 @@ const MBeaconBody: React.FC<IBodyProps> = React.forwardRef(({ mxEvent, getRelati
useHandleBeaconRedaction(mxEvent, matrixClient, getRelationsForEvent);
const onClick = () => {
const onClick = (): void => {
if (displayStatus !== BeaconDisplayStatus.Active) {
return;
}

View file

@ -32,7 +32,7 @@ import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContex
export let DOWNLOAD_ICON_URL; // cached copy of the download.svg asset for the sandboxed iframe later on
async function cacheDownloadIcon() {
async function cacheDownloadIcon(): Promise<void> {
if (DOWNLOAD_ICON_URL) return; // cached already
// eslint-disable-next-line @typescript-eslint/no-var-requires
const svg = await fetch(require("../../../../res/img/download.svg").default).then((r) => r.text());
@ -78,7 +78,7 @@ cacheDownloadIcon();
* @param {HTMLElement} element The element to get the current style of.
* @return {string} The CSS style encoded as a string.
*/
export function computedStyle(element: HTMLElement) {
export function computedStyle(element: HTMLElement): string {
if (!element) {
return "";
}
@ -141,7 +141,7 @@ export default class MFileBody extends React.Component<IProps, IState> {
return presentableTextForFile(this.content);
}
private downloadFile(fileName: string, text: string) {
private downloadFile(fileName: string, text: string): void {
this.fileDownloader.download({
blob: this.state.decryptedBlob,
name: fileName,
@ -155,7 +155,7 @@ export default class MFileBody extends React.Component<IProps, IState> {
});
}
public componentDidUpdate(prevProps, prevState) {
public componentDidUpdate(prevProps, prevState): void {
if (this.props.onHeightChanged && !prevState.decryptedBlob && this.state.decryptedBlob) {
this.props.onHeightChanged();
}
@ -179,7 +179,7 @@ export default class MFileBody extends React.Component<IProps, IState> {
}
};
private onPlaceholderClick = async () => {
private onPlaceholderClick = async (): Promise<void> => {
const mediaHelper = this.props.mediaEventHelper;
if (mediaHelper?.media.isEncrypted) {
await this.decryptFile();
@ -194,7 +194,7 @@ export default class MFileBody extends React.Component<IProps, IState> {
}
};
public render() {
public render(): JSX.Element {
const isEncrypted = this.props.mediaEventHelper?.media.isEncrypted;
const contentUrl = this.getContentUrl();
const fileSize = this.content.info ? this.content.info.size : null;

View file

@ -150,7 +150,7 @@ export default class MImageBody extends React.Component<IBodyProps, IState> {
imgElement.src = this.state.thumbUrl ?? this.state.contentUrl;
};
private clearError = () => {
private clearError = (): void => {
MatrixClientPeg.get().off(ClientEvent.Sync, this.reconnectedListener);
this.setState({ imgError: false });
};
@ -239,7 +239,7 @@ export default class MImageBody extends React.Component<IBodyProps, IState> {
return media.srcHttp;
}
private async downloadImage() {
private async downloadImage(): Promise<void> {
if (this.state.contentUrl) return; // already downloaded
let thumbUrl: string;
@ -318,14 +318,14 @@ export default class MImageBody extends React.Component<IBodyProps, IState> {
});
}
private clearBlurhashTimeout() {
private clearBlurhashTimeout(): void {
if (this.timeout) {
clearTimeout(this.timeout);
this.timeout = undefined;
}
}
public componentDidMount() {
public componentDidMount(): void {
this.unmounted = false;
const showImage =
@ -354,7 +354,7 @@ export default class MImageBody extends React.Component<IBodyProps, IState> {
});
}
public componentWillUnmount() {
public componentWillUnmount(): void {
this.unmounted = true;
MatrixClientPeg.get().off(ClientEvent.Sync, this.reconnectedListener);
this.clearBlurhashTimeout();
@ -562,7 +562,7 @@ export default class MImageBody extends React.Component<IBodyProps, IState> {
}
}
public render() {
public render(): JSX.Element {
const content = this.props.mxEvent.getContent<IMediaEventContent>();
if (this.state.error) {
@ -605,7 +605,7 @@ interface PlaceholderIProps {
}
export class HiddenImagePlaceholder extends React.PureComponent<PlaceholderIProps> {
public render() {
public render(): JSX.Element {
const maxWidth = this.props.maxWidth ? this.props.maxWidth + "px" : null;
let className = "mx_HiddenImagePlaceholder";
if (this.props.hover) className += " mx_HiddenImagePlaceholder_hover";

View file

@ -30,7 +30,7 @@ export default class MImageReplyBody extends MImageBody {
return children;
}
public render() {
public render(): JSX.Element {
if (this.state.error) {
return super.render();
}

View file

@ -33,7 +33,7 @@ export default class MJitsiWidgetEvent extends React.PureComponent<IProps> {
super(props);
}
public render() {
public render(): JSX.Element {
const url = this.props.mxEvent.getContent()["url"];
const prevUrl = this.props.mxEvent.getPrevContent()["url"];
const senderName = this.props.mxEvent.sender?.name || this.props.mxEvent.getSender();

View file

@ -33,21 +33,21 @@ interface IProps {
}
export default class MKeyVerificationRequest extends React.Component<IProps> {
public componentDidMount() {
public componentDidMount(): void {
const request = this.props.mxEvent.verificationRequest;
if (request) {
request.on(VerificationRequestEvent.Change, this.onRequestChanged);
}
}
public componentWillUnmount() {
public componentWillUnmount(): void {
const request = this.props.mxEvent.verificationRequest;
if (request) {
request.off(VerificationRequestEvent.Change, this.onRequestChanged);
}
}
private openRequest = () => {
private openRequest = (): void => {
const { verificationRequest } = this.props.mxEvent;
const member = MatrixClientPeg.get().getUser(verificationRequest.otherUserId);
RightPanelStore.instance.setCards([
@ -57,11 +57,11 @@ export default class MKeyVerificationRequest extends React.Component<IProps> {
]);
};
private onRequestChanged = () => {
private onRequestChanged = (): void => {
this.forceUpdate();
};
private onAcceptClicked = async () => {
private onAcceptClicked = async (): Promise<void> => {
const request = this.props.mxEvent.verificationRequest;
if (request) {
try {
@ -73,7 +73,7 @@ export default class MKeyVerificationRequest extends React.Component<IProps> {
}
};
private onRejectClicked = async () => {
private onRejectClicked = async (): Promise<void> => {
const request = this.props.mxEvent.verificationRequest;
if (request) {
try {
@ -84,7 +84,7 @@ export default class MKeyVerificationRequest extends React.Component<IProps> {
}
};
private acceptedLabel(userId: string) {
private acceptedLabel(userId: string): string {
const client = MatrixClientPeg.get();
const myUserId = client.getUserId();
if (userId === myUserId) {
@ -94,7 +94,7 @@ export default class MKeyVerificationRequest extends React.Component<IProps> {
}
}
private cancelledLabel(userId: string) {
private cancelledLabel(userId: string): string {
const client = MatrixClientPeg.get();
const myUserId = client.getUserId();
const { cancellationCode } = this.props.mxEvent.verificationRequest;
@ -114,7 +114,7 @@ export default class MKeyVerificationRequest extends React.Component<IProps> {
}
}
public render() {
public render(): JSX.Element {
const { mxEvent } = this.props;
const request = mxEvent.verificationRequest;

View file

@ -61,7 +61,7 @@ export default class MLocationBody extends React.Component<IBodyProps, IState> {
};
}
private onClick = () => {
private onClick = (): void => {
Modal.createDialog(
LocationViewDialog,
{
@ -74,12 +74,12 @@ export default class MLocationBody extends React.Component<IBodyProps, IState> {
);
};
private clearError = () => {
private clearError = (): void => {
this.context.off(ClientEvent.Sync, this.reconnectedListener);
this.setState({ error: undefined });
};
private onError = (error: Error) => {
private onError = (error: Error): void => {
this.setState({ error });
this.context.on(ClientEvent.Sync, this.reconnectedListener);
};

View file

@ -49,7 +49,7 @@ interface IState {
endRelations: RelatedRelations; // Poll end events
}
export function createVoteRelations(getRelationsForEvent: GetRelationsForEvent, eventId: string) {
export function createVoteRelations(getRelationsForEvent: GetRelationsForEvent, eventId: string): RelatedRelations {
const relationsList: Relations[] = [];
const pollResponseRelations = getRelationsForEvent(eventId, "m.reference", M_POLL_RESPONSE.name);
@ -89,7 +89,7 @@ export function findTopAnswer(
return "";
}
const findAnswerText = (answerId: string) => {
const findAnswerText = (answerId: string): string => {
return poll.answers.find((a) => a.id === answerId)?.text ?? "";
};
@ -156,7 +156,7 @@ export function isPollEnded(
}
const roomCurrentState = matrixClient.getRoom(roomId)?.currentState;
function userCanRedact(endEvent: MatrixEvent) {
function userCanRedact(endEvent: MatrixEvent): boolean {
const endEventSender = endEvent.getSender();
return (
endEventSender && roomCurrentState && roomCurrentState.maySendRedactionForEvent(pollEvent, endEventSender)
@ -237,12 +237,12 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
this.props.mxEvent.on(MatrixEventEvent.RelationsCreated, this.onRelationsCreated);
}
public componentWillUnmount() {
public componentWillUnmount(): void {
this.props.mxEvent.off(MatrixEventEvent.RelationsCreated, this.onRelationsCreated);
this.removeListeners(this.state.voteRelations, this.state.endRelations);
}
private addListeners(voteRelations?: RelatedRelations, endRelations?: RelatedRelations) {
private addListeners(voteRelations?: RelatedRelations, endRelations?: RelatedRelations): void {
if (voteRelations) {
voteRelations.on(RelationsEvent.Add, this.onRelationsChange);
voteRelations.on(RelationsEvent.Remove, this.onRelationsChange);
@ -255,7 +255,7 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
}
}
private removeListeners(voteRelations?: RelatedRelations, endRelations?: RelatedRelations) {
private removeListeners(voteRelations?: RelatedRelations, endRelations?: RelatedRelations): void {
if (voteRelations) {
voteRelations.off(RelationsEvent.Add, this.onRelationsChange);
voteRelations.off(RelationsEvent.Remove, this.onRelationsChange);
@ -268,7 +268,7 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
}
}
private onRelationsCreated = (relationType: string, eventType: string) => {
private onRelationsCreated = (relationType: string, eventType: string): void => {
if (relationType !== "m.reference") {
return;
}
@ -292,7 +292,7 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
}
};
private onRelationsChange = () => {
private onRelationsChange = (): void => {
// We hold Relations in our state, and they changed under us.
// Check whether we should delete our selection, and then
// re-render.
@ -300,7 +300,7 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
this.unselectIfNewEventFromMe();
};
private selectOption(answerId: string) {
private selectOption(answerId: string): void {
if (this.isEnded()) {
return;
}
@ -384,7 +384,7 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
* Either way, calls setState to update our list of events we
* have already seen.
*/
private unselectIfNewEventFromMe() {
private unselectIfNewEventFromMe(): void {
const newEvents: MatrixEvent[] = this.state.voteRelations
.getRelations()
.filter(isPollResponse)
@ -415,7 +415,7 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
return isPollEnded(this.props.mxEvent, this.context, this.props.getRelationsForEvent);
}
public render() {
public render(): JSX.Element {
const poll = this.props.mxEvent.unstableExtensibleEvent as PollStartEvent;
if (!poll?.isEquivalentTo(M_POLL_START)) return null; // invalid
@ -511,7 +511,7 @@ interface IEndedPollOptionProps {
votesText: string;
}
function EndedPollOption(props: IEndedPollOptionProps) {
function EndedPollOption(props: IEndedPollOptionProps): JSX.Element {
const cls = classNames({
mx_MPollBody_endedOption: true,
mx_MPollBody_endedOptionWinner: props.checked,
@ -534,7 +534,7 @@ interface ILivePollOptionProps {
onOptionSelected: (e: React.FormEvent<HTMLInputElement>) => void;
}
function LivePollOption(props: ILivePollOptionProps) {
function LivePollOption(props: ILivePollOptionProps): JSX.Element {
return (
<StyledRadioButton
className="mx_MPollBody_live-option"
@ -603,7 +603,7 @@ export function pollEndTs(
}
const roomCurrentState = matrixClient.getRoom(pollEvent.getRoomId()).currentState;
function userCanRedact(endEvent: MatrixEvent) {
function userCanRedact(endEvent: MatrixEvent): boolean {
return roomCurrentState.maySendRedactionForEvent(pollEvent, endEvent.getSender());
}

View file

@ -23,7 +23,7 @@ import { IMediaEventContent } from "../../../customisations/models/IMediaEventCo
export default class MStickerBody extends MImageBody {
// Mostly empty to prevent default behaviour of MImageBody
protected onClick = (ev: React.MouseEvent) => {
protected onClick = (ev: React.MouseEvent): void => {
ev.preventDefault();
if (!this.state.showImage) {
this.showImage();
@ -74,7 +74,7 @@ export default class MStickerBody extends MImageBody {
}
// Don't show "Download this_file.png ..."
protected getFileBody() {
protected getFileBody(): JSX.Element {
return null;
}

View file

@ -96,7 +96,7 @@ export default class MVideoBody extends React.PureComponent<IBodyProps, IState>
}
}
private loadBlurhash() {
private loadBlurhash(): void {
const info = this.props.mxEvent.getContent()?.info;
if (!info[BLURHASH_FIELD]) return;
@ -132,7 +132,7 @@ export default class MVideoBody extends React.PureComponent<IBodyProps, IState>
}
}
public async componentDidMount() {
public async componentDidMount(): Promise<void> {
this.sizeWatcher = SettingsStore.watchSetting("Images.size", null, () => {
this.forceUpdate(); // we don't really have a reliable thing to update, so just update the whole thing
});
@ -186,11 +186,11 @@ export default class MVideoBody extends React.PureComponent<IBodyProps, IState>
}
}
public componentWillUnmount() {
public componentWillUnmount(): void {
SettingsStore.unwatchSetting(this.sizeWatcher);
}
private videoOnPlay = async () => {
private videoOnPlay = async (): Promise<void> => {
if (this.hasContentUrl() || this.state.fetchingData || this.state.error) {
// We have the file, we are fetching the file, or there is an error.
return;
@ -227,12 +227,12 @@ export default class MVideoBody extends React.PureComponent<IBodyProps, IState>
);
}
private getFileBody = () => {
private getFileBody = (): JSX.Element => {
if (this.props.forExport) return null;
return this.showFileBody && <MFileBody {...this.props} showGenericPlaceholder={false} />;
};
public render() {
public render(): JSX.Element {
const content = this.props.mxEvent.getContent();
const autoplay = SettingsStore.getValue("autoplayVideo");

View file

@ -25,7 +25,7 @@ import MediaProcessingError from "./shared/MediaProcessingError";
export default class MVoiceMessageBody extends MAudioBody {
// A voice message is an audio file but rendered in a special way.
public render() {
public render(): JSX.Element {
if (this.state.error) {
return (
<MediaProcessingError className="mx_MVoiceMessageBody">

View file

@ -22,7 +22,7 @@ import { IBodyProps } from "./IBodyProps";
import { isVoiceMessage } from "../../../utils/EventUtils";
export default class MVoiceOrAudioBody extends React.PureComponent<IBodyProps> {
public render() {
public render(): JSX.Element {
if (!this.props.forExport && isVoiceMessage(this.props.mxEvent)) {
return <MVoiceMessageBody {...this.props} />;
} else {

View file

@ -199,7 +199,7 @@ interface IReplyInThreadButton {
mxEvent: MatrixEvent;
}
const ReplyInThreadButton = ({ mxEvent }: IReplyInThreadButton) => {
const ReplyInThreadButton: React.FC<IReplyInThreadButton> = ({ mxEvent }) => {
const context = useContext(CardContext);
const relationType = mxEvent?.getRelation()?.rel_type;
@ -276,7 +276,7 @@ interface IFavouriteButtonProp {
mxEvent: MatrixEvent;
}
const FavouriteButton = ({ mxEvent }: IFavouriteButtonProp) => {
const FavouriteButton: React.FC<IFavouriteButtonProp> = ({ mxEvent }) => {
const { isFavourite, toggleFavourite } = useFavouriteMessages();
const eventId = mxEvent.getId();

View file

@ -100,12 +100,12 @@ export default class MessageEvent extends React.Component<IProps> implements IMe
this.props.mxEvent.addListener(MatrixEventEvent.Decrypted, this.onDecrypted);
}
public componentWillUnmount() {
public componentWillUnmount(): void {
this.props.mxEvent.removeListener(MatrixEventEvent.Decrypted, this.onDecrypted);
this.mediaHelper?.destroy();
}
public componentDidUpdate(prevProps: Readonly<IProps>) {
public componentDidUpdate(prevProps: Readonly<IProps>): void {
if (this.props.mxEvent !== prevProps.mxEvent && MediaEventHelper.isEligible(this.props.mxEvent)) {
this.mediaHelper?.destroy();
this.mediaHelper = new MediaEventHelper(this.props.mxEvent);
@ -114,7 +114,7 @@ export default class MessageEvent extends React.Component<IProps> implements IMe
this.updateComponentMaps();
}
private updateComponentMaps() {
private updateComponentMaps(): void {
this.bodyTypes = new Map<string, typeof React.Component>(baseBodyTypes.entries());
for (const [bodyType, bodyComponent] of Object.entries(this.props.overrideBodyTypes ?? {})) {
this.bodyTypes.set(bodyType, bodyComponent);
@ -126,11 +126,11 @@ export default class MessageEvent extends React.Component<IProps> implements IMe
}
}
public getEventTileOps = () => {
public getEventTileOps = (): IEventTileOps | null => {
return (this.body.current as IOperableEventTile)?.getEventTileOps?.() || null;
};
public getMediaHelper() {
public getMediaHelper(): MediaEventHelper {
return this.mediaHelper;
}
@ -142,11 +142,11 @@ export default class MessageEvent extends React.Component<IProps> implements IMe
}
};
private onTileUpdate = () => {
private onTileUpdate = (): void => {
this.forceUpdate();
};
public render() {
public render(): JSX.Element {
const content = this.props.mxEvent.getContent();
const type = this.props.mxEvent.getType();
const msgtype = content.msgtype;

View file

@ -28,7 +28,7 @@ interface IProps {
}
export default class MessageTimestamp extends React.Component<IProps> {
public render() {
public render(): JSX.Element {
const date = new Date(this.props.ts);
let timestamp;
if (this.props.showRelative) {

View file

@ -31,7 +31,7 @@ import AccessibleButton from "../elements/AccessibleButton";
// The maximum number of reactions to initially show on a message.
const MAX_ITEMS_WHEN_LIMITED = 8;
const ReactButton = ({ mxEvent, reactions }: IProps) => {
const ReactButton: React.FC<IProps> = ({ mxEvent, reactions }) => {
const [menuDisplayed, button, openMenu, closeMenu] = useContextMenu();
let contextMenu;
@ -91,7 +91,7 @@ export default class ReactionsRow extends React.PureComponent<IProps, IState> {
};
}
public componentDidMount() {
public componentDidMount(): void {
const { mxEvent, reactions } = this.props;
if (mxEvent.isBeingDecrypted() || mxEvent.shouldAttemptDecryption()) {
@ -105,7 +105,7 @@ export default class ReactionsRow extends React.PureComponent<IProps, IState> {
}
}
public componentWillUnmount() {
public componentWillUnmount(): void {
const { mxEvent, reactions } = this.props;
mxEvent.off(MatrixEventEvent.Decrypted, this.onDecrypted);
@ -117,7 +117,7 @@ export default class ReactionsRow extends React.PureComponent<IProps, IState> {
}
}
public componentDidUpdate(prevProps: IProps) {
public componentDidUpdate(prevProps: IProps): void {
if (this.props.reactions && prevProps.reactions !== this.props.reactions) {
this.props.reactions.on(RelationsEvent.Add, this.onReactionsChange);
this.props.reactions.on(RelationsEvent.Remove, this.onReactionsChange);
@ -126,12 +126,12 @@ export default class ReactionsRow extends React.PureComponent<IProps, IState> {
}
}
private onDecrypted = () => {
private onDecrypted = (): void => {
// Decryption changes whether the event is actionable
this.forceUpdate();
};
private onReactionsChange = () => {
private onReactionsChange = (): void => {
// TODO: Call `onHeightChanged` as needed
this.setState({
myReactions: this.getMyReactions(),
@ -142,7 +142,7 @@ export default class ReactionsRow extends React.PureComponent<IProps, IState> {
this.forceUpdate();
};
private getMyReactions() {
private getMyReactions(): MatrixEvent[] {
const reactions = this.props.reactions;
if (!reactions) {
return null;
@ -155,13 +155,13 @@ export default class ReactionsRow extends React.PureComponent<IProps, IState> {
return [...myReactions.values()];
}
private onShowAllClick = () => {
private onShowAllClick = (): void => {
this.setState({
showAll: true,
});
};
public render() {
public render(): JSX.Element {
const { mxEvent, reactions } = this.props;
const { myReactions, showAll } = this.state;

View file

@ -54,7 +54,7 @@ export default class ReactionsRowButton extends React.PureComponent<IProps, ISta
tooltipVisible: false,
};
public onClick = () => {
public onClick = (): void => {
const { mxEvent, myReactionEvent, content } = this.props;
if (myReactionEvent) {
this.context.redactEvent(mxEvent.getRoomId(), myReactionEvent.getId());
@ -70,7 +70,7 @@ export default class ReactionsRowButton extends React.PureComponent<IProps, ISta
}
};
public onMouseOver = () => {
public onMouseOver = (): void => {
this.setState({
// To avoid littering the DOM with a tooltip for every reaction,
// only render it on first use.
@ -79,13 +79,13 @@ export default class ReactionsRowButton extends React.PureComponent<IProps, ISta
});
};
public onMouseLeave = () => {
public onMouseLeave = (): void => {
this.setState({
tooltipVisible: false,
});
};
public render() {
public render(): JSX.Element {
const { mxEvent, content, count, reactionEvents, myReactionEvent } = this.props;
const classes = classNames({

View file

@ -36,7 +36,7 @@ interface IProps {
export default class ReactionsRowButtonTooltip extends React.PureComponent<IProps> {
public static contextType = MatrixClientContext;
public render() {
public render(): JSX.Element {
const { content, reactionEvents, mxEvent, visible } = this.props;
const room = this.context.getRoom(mxEvent.getRoomId());

View file

@ -26,7 +26,7 @@ interface IProps {
onClick?(): void;
}
export default function SenderProfile({ mxEvent, onClick }: IProps) {
export default function SenderProfile({ mxEvent, onClick }: IProps): JSX.Element {
const member = useRoomMemberProfile({
userId: mxEvent.getSender(),
member: mxEvent.sender,

View file

@ -48,6 +48,7 @@ import AccessibleButton from "../elements/AccessibleButton";
import { options as linkifyOpts } from "../../../linkify-matrix";
import { getParentEventId } from "../../../utils/Reply";
import { EditWysiwygComposer } from "../rooms/wysiwyg_composer";
import { IEventTileOps } from "../rooms/EventTile";
const MAX_HIGHLIGHT_LENGTH = 4096;
@ -78,7 +79,7 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
};
}
public componentDidMount() {
public componentDidMount(): void {
if (!this.props.editState) {
this.applyFormatting();
}
@ -161,7 +162,7 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
button.className += "mx_EventTile_collapseButton";
}
button.onclick = async () => {
button.onclick = async (): Promise<void> => {
button.className = "mx_EventTile_button ";
if (pre.className == "mx_EventTile_collapsedCodeBlock") {
pre.className = "";
@ -187,7 +188,7 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
const expansionButtonExists = div.getElementsByClassName("mx_EventTile_button");
if (expansionButtonExists.length > 0) button.className += "mx_EventTile_buttonBottom";
button.onclick = async () => {
button.onclick = async (): Promise<void> => {
const copyCode = button.parentElement.getElementsByTagName("code")[0];
const successful = await copyPlaintext(copyCode.textContent);
@ -280,7 +281,7 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
}
}
public componentDidUpdate(prevProps) {
public componentDidUpdate(prevProps: Readonly<IBodyProps>): void {
if (!this.props.editState) {
const stoppedEditing = prevProps.editState && !this.props.editState;
const messageWasEdited = prevProps.replacingEventId !== this.props.replacingEventId;
@ -290,13 +291,13 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
}
}
public componentWillUnmount() {
public componentWillUnmount(): void {
this.unmounted = true;
unmountPills(this.pills);
unmountTooltips(this.tooltips);
}
public shouldComponentUpdate(nextProps, nextState) {
public shouldComponentUpdate(nextProps: Readonly<IBodyProps>, nextState: Readonly<IState>): boolean {
//console.info("shouldComponentUpdate: ShowUrlPreview for %s is %s", this.props.mxEvent.getId(), this.props.showUrlPreview);
// exploit that events are immutable :)
@ -450,7 +451,7 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
}
};
public getEventTileOps = () => ({
public getEventTileOps = (): IEventTileOps => ({
isWidgetHidden: () => {
return this.state.widgetHidden;
},
@ -517,7 +518,7 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
Modal.createDialog(MessageEditHistoryDialog, { mxEvent: this.props.mxEvent });
};
private renderEditedMarker() {
private renderEditedMarker(): JSX.Element {
const date = this.props.mxEvent.replacingEventDate();
const dateString = date && formatDate(date);
@ -544,7 +545,7 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
* Render a marker informing the user that, while they can see the message,
* it is hidden for other users.
*/
private renderPendingModerationMarker() {
private renderPendingModerationMarker(): JSX.Element {
let text;
const visibility = this.props.mxEvent.messageVisibility();
switch (visibility.visible) {
@ -561,7 +562,7 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
return <span className="mx_EventTile_pendingModeration">{`(${text})`}</span>;
}
public render() {
public render(): JSX.Element {
if (this.props.editState) {
const isWysiwygComposerEnabled = SettingsStore.getValue("feature_wysiwyg_composer");
return isWysiwygComposerEnabled ? (

View file

@ -27,7 +27,7 @@ interface IProps {
export default class TextualEvent extends React.Component<IProps> {
public static contextType = RoomContext;
public render() {
public render(): JSX.Element {
const text = TextForEvent.textForEvent(this.props.mxEvent, true, this.context?.showHiddenEvents);
if (!text) return null;
return <div className="mx_TextualEvent">{text}</div>;

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from "react";
import React, { ReactNode } from "react";
import classNames from "classnames";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
@ -68,7 +68,7 @@ export default class TileErrorBoundary extends React.Component<IProps, IState> {
);
};
public render() {
public render(): ReactNode {
if (this.state.error) {
const { mxEvent } = this.props;
const classes = {

View file

@ -50,7 +50,7 @@ export default class ViewSourceEvent extends React.PureComponent<IProps, IState>
}
}
private onToggle = (ev: React.MouseEvent) => {
private onToggle = (ev: React.MouseEvent): void => {
ev.preventDefault();
const { expanded } = this.state;
this.setState({