Conform more of the code base to strict null checking (#10147)

* Conform more of the code base to strict null checking

* More strict fixes

* More strict work

* Fix missing optional type

* Iterate
This commit is contained in:
Michael Telatynski 2023-02-13 17:01:43 +00:00 committed by GitHub
parent fa036a5080
commit da7aa4055e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
380 changed files with 682 additions and 694 deletions

View file

@ -74,7 +74,7 @@ export default class AsyncWrapper extends React.Component<IProps, IState> {
this.props.onFinished(false); this.props.onFinished(false);
}; };
public render(): JSX.Element { public render(): React.ReactNode {
if (this.state.component) { if (this.state.component) {
const Component = this.state.component; const Component = this.state.component;
return <Component {...this.props} />; return <Component {...this.props} />;

View file

@ -138,7 +138,7 @@ export function getInitialLetter(name: string): string | undefined {
} }
export function avatarUrlForRoom( export function avatarUrlForRoom(
room: Room, room: Room | null,
width: number, width: number,
height: number, height: number,
resizeMethod?: ResizeMethod, resizeMethod?: ResizeMethod,

View file

@ -204,7 +204,7 @@ const transformTags: IExtendedSanitizeOptions["transformTags"] = {
attribs.style += "height: 100%;"; attribs.style += "height: 100%;";
} }
attribs.src = mediaFromMxc(src).getThumbnailOfSourceHttp(width, height); attribs.src = mediaFromMxc(src).getThumbnailOfSourceHttp(width, height)!;
return { tagName, attribs }; return { tagName, attribs };
}, },
"code": function (tagName: string, attribs: sanitizeHtml.Attributes) { "code": function (tagName: string, attribs: sanitizeHtml.Attributes) {
@ -352,7 +352,7 @@ const topicSanitizeHtmlParams: IExtendedSanitizeOptions = {
}; };
abstract class BaseHighlighter<T extends React.ReactNode> { abstract class BaseHighlighter<T extends React.ReactNode> {
public constructor(public highlightClass: string, public highlightLink: string) {} public constructor(public highlightClass: string, public highlightLink?: string) {}
/** /**
* apply the highlights to a section of text * apply the highlights to a section of text
@ -504,7 +504,7 @@ function formatEmojis(message: string, isHtmlMessage: boolean): (JSX.Element | s
export function bodyToHtml(content: IContent, highlights: Optional<string[]>, opts: IOptsReturnString): string; export function bodyToHtml(content: IContent, highlights: Optional<string[]>, opts: IOptsReturnString): string;
export function bodyToHtml(content: IContent, highlights: Optional<string[]>, opts: IOptsReturnNode): ReactNode; export function bodyToHtml(content: IContent, highlights: Optional<string[]>, opts: IOptsReturnNode): ReactNode;
export function bodyToHtml(content: IContent, highlights: Optional<string[]>, opts: IOpts = {}): ReactNode | string { export function bodyToHtml(content: IContent, highlights: Optional<string[]>, opts: IOpts = {}): ReactNode | string {
const isFormattedBody = content.format === "org.matrix.custom.html" && !!content.formatted_body; const isFormattedBody = content.format === "org.matrix.custom.html" && typeof content.formatted_body === "string";
let bodyHasEmoji = false; let bodyHasEmoji = false;
let isHtmlMessage = false; let isHtmlMessage = false;
@ -514,7 +514,7 @@ export function bodyToHtml(content: IContent, highlights: Optional<string[]>, op
} }
let strippedBody: string; let strippedBody: string;
let safeBody: string; // safe, sanitised HTML, preferred over `strippedBody` which is fully plaintext let safeBody: string | undefined; // safe, sanitised HTML, preferred over `strippedBody` which is fully plaintext
try { try {
// sanitizeHtml can hang if an unclosed HTML tag is thrown at it // sanitizeHtml can hang if an unclosed HTML tag is thrown at it
@ -529,7 +529,7 @@ export function bodyToHtml(content: IContent, highlights: Optional<string[]>, op
if (opts.stripReplyFallback && formattedBody) formattedBody = stripHTMLReply(formattedBody); if (opts.stripReplyFallback && formattedBody) formattedBody = stripHTMLReply(formattedBody);
strippedBody = opts.stripReplyFallback ? stripPlainReply(plainBody) : plainBody; strippedBody = opts.stripReplyFallback ? stripPlainReply(plainBody) : plainBody;
bodyHasEmoji = mightContainEmoji(isFormattedBody ? formattedBody : plainBody); bodyHasEmoji = mightContainEmoji(isFormattedBody ? formattedBody! : plainBody);
const highlighter = safeHighlights?.length const highlighter = safeHighlights?.length
? new HtmlHighlighter("mx_EventTile_searchHighlight", opts.highlightLink) ? new HtmlHighlighter("mx_EventTile_searchHighlight", opts.highlightLink)
@ -543,11 +543,11 @@ export function bodyToHtml(content: IContent, highlights: Optional<string[]>, op
// by an attempt to search for 'foobar'. Then again, the search query probably wouldn't work either // by an attempt to search for 'foobar'. Then again, the search query probably wouldn't work either
// XXX: hacky bodge to temporarily apply a textFilter to the sanitizeParams structure. // XXX: hacky bodge to temporarily apply a textFilter to the sanitizeParams structure.
sanitizeParams.textFilter = function (safeText) { sanitizeParams.textFilter = function (safeText) {
return highlighter.applyHighlights(safeText, safeHighlights).join(""); return highlighter.applyHighlights(safeText, safeHighlights!).join("");
}; };
} }
safeBody = sanitizeHtml(formattedBody, sanitizeParams); safeBody = sanitizeHtml(formattedBody!, sanitizeParams);
const phtml = cheerio.load(safeBody, { const phtml = cheerio.load(safeBody, {
// @ts-ignore: The `_useHtmlParser2` internal option is the // @ts-ignore: The `_useHtmlParser2` internal option is the
// simplest way to both parse and render using `htmlparser2`. // simplest way to both parse and render using `htmlparser2`.
@ -574,7 +574,7 @@ export function bodyToHtml(content: IContent, highlights: Optional<string[]>, op
safeBody = formatEmojis(safeBody, true).join(""); safeBody = formatEmojis(safeBody, true).join("");
} }
} else if (highlighter) { } else if (highlighter) {
safeBody = highlighter.applyHighlights(plainBody, safeHighlights).join(""); safeBody = highlighter.applyHighlights(plainBody, safeHighlights!).join("");
} }
} finally { } finally {
delete sanitizeParams.textFilter; delete sanitizeParams.textFilter;
@ -597,9 +597,7 @@ export function bodyToHtml(content: IContent, highlights: Optional<string[]>, op
const match = BIGEMOJI_REGEX.exec(contentBodyTrimmed); const match = BIGEMOJI_REGEX.exec(contentBodyTrimmed);
emojiBody = emojiBody =
match && match?.[0]?.length === contentBodyTrimmed.length &&
match[0] &&
match[0].length === contentBodyTrimmed.length &&
// Prevent user pills expanding for users with only emoji in // Prevent user pills expanding for users with only emoji in
// their username. Permalinks (links in pills) can be any URL // their username. Permalinks (links in pills) can be any URL
// now, so we just check for an HTTP-looking thing. // now, so we just check for an HTTP-looking thing.
@ -614,7 +612,7 @@ export function bodyToHtml(content: IContent, highlights: Optional<string[]>, op
"markdown-body": isHtmlMessage && !emojiBody, "markdown-body": isHtmlMessage && !emojiBody,
}); });
let emojiBodyElements: JSX.Element[]; let emojiBodyElements: JSX.Element[] | undefined;
if (!safeBody && bodyHasEmoji) { if (!safeBody && bodyHasEmoji) {
emojiBodyElements = formatEmojis(strippedBody, false) as JSX.Element[]; emojiBodyElements = formatEmojis(strippedBody, false) as JSX.Element[];
} }
@ -649,7 +647,7 @@ export function topicToHtml(
allowExtendedHtml = false, allowExtendedHtml = false,
): ReactNode { ): ReactNode {
if (!SettingsStore.getValue("feature_html_topic")) { if (!SettingsStore.getValue("feature_html_topic")) {
htmlTopic = null; htmlTopic = undefined;
} }
let isFormattedTopic = !!htmlTopic; let isFormattedTopic = !!htmlTopic;
@ -657,10 +655,10 @@ export function topicToHtml(
let safeTopic = ""; let safeTopic = "";
try { try {
topicHasEmoji = mightContainEmoji(isFormattedTopic ? htmlTopic : topic); topicHasEmoji = mightContainEmoji(isFormattedTopic ? htmlTopic! : topic);
if (isFormattedTopic) { if (isFormattedTopic) {
safeTopic = sanitizeHtml(htmlTopic, allowExtendedHtml ? sanitizeHtmlParams : topicSanitizeHtmlParams); safeTopic = sanitizeHtml(htmlTopic!, allowExtendedHtml ? sanitizeHtmlParams : topicSanitizeHtmlParams);
if (topicHasEmoji) { if (topicHasEmoji) {
safeTopic = formatEmojis(safeTopic, true).join(""); safeTopic = formatEmojis(safeTopic, true).join("");
} }
@ -669,7 +667,7 @@ export function topicToHtml(
isFormattedTopic = false; // Fall back to plain-text topic isFormattedTopic = false; // Fall back to plain-text topic
} }
let emojiBodyElements: ReturnType<typeof formatEmojis>; let emojiBodyElements: ReturnType<typeof formatEmojis> | undefined;
if (!isFormattedTopic && topicHasEmoji) { if (!isFormattedTopic && topicHasEmoji) {
emojiBodyElements = formatEmojis(topic, false); emojiBodyElements = formatEmojis(topic, false);
} }

View file

@ -139,7 +139,7 @@ export default class Markdown {
*/ */
private repairLinks(parsed: commonmark.Node): commonmark.Node { private repairLinks(parsed: commonmark.Node): commonmark.Node {
const walker = parsed.walker(); const walker = parsed.walker();
let event: commonmark.NodeWalkingStep = null; let event: commonmark.NodeWalkingStep | null = null;
let text = ""; let text = "";
let isInPara = false; let isInPara = false;
let previousNode: commonmark.Node | null = null; let previousNode: commonmark.Node | null = null;
@ -287,7 +287,7 @@ export default class Markdown {
// However, if it's a blockquote, adds a p tag anyway // However, if it's a blockquote, adds a p tag anyway
// in order to avoid deviation to commonmark and unexpected // in order to avoid deviation to commonmark and unexpected
// results when parsing the formatted HTML. // results when parsing the formatted HTML.
if (node.parent.type === "block_quote" || isMultiLine(node)) { if (node.parent?.type === "block_quote" || isMultiLine(node)) {
realParagraph.call(this, node, entering); realParagraph.call(this, node, entering);
} }
}; };

View file

@ -120,7 +120,7 @@ export default class NodeAnimator extends React.Component<IProps> {
this.nodes[k] = node; this.nodes[k] = node;
} }
public render(): JSX.Element { public render(): React.ReactNode {
return <>{Object.values(this.children)}</>; return <>{Object.values(this.children)}</>;
} }
} }

View file

@ -120,7 +120,7 @@ export class PosthogScreenTracker extends PureComponent<{ screenName: ScreenName
PosthogTrackers.instance.clearOverride(this.props.screenName); PosthogTrackers.instance.clearOverride(this.props.screenName);
} }
public render(): JSX.Element { public render(): React.ReactNode {
return null; // no need to render anything, we just need to hook into the React lifecycle return null; // no need to render anything, we just need to hook into the React lifecycle
} }
} }

View file

@ -33,9 +33,9 @@ enum State {
} }
class Presence { class Presence {
private unavailableTimer: Timer = null; private unavailableTimer: Timer | null = null;
private dispatcherRef: string = null; private dispatcherRef: string | null = null;
private state: State = null; private state: State | null = null;
/** /**
* Start listening the user activity to evaluate his presence state. * Start listening the user activity to evaluate his presence state.
@ -73,14 +73,14 @@ class Presence {
* Get the current presence state. * Get the current presence state.
* @returns {string} the presence state (see PRESENCE enum) * @returns {string} the presence state (see PRESENCE enum)
*/ */
public getState(): State { public getState(): State | null {
return this.state; return this.state;
} }
private onAction = (payload: ActionPayload): void => { private onAction = (payload: ActionPayload): void => {
if (payload.action === "user_activity") { if (payload.action === "user_activity") {
this.setState(State.Online); this.setState(State.Online);
this.unavailableTimer.restart(); this.unavailableTimer?.restart();
} }
}; };

View file

@ -46,7 +46,7 @@ export default class Resend {
} }
public static resend(event: MatrixEvent): Promise<void> { public static resend(event: MatrixEvent): Promise<void> {
const room = MatrixClientPeg.get().getRoom(event.getRoomId()); const room = MatrixClientPeg.get().getRoom(event.getRoomId())!;
return MatrixClientPeg.get() return MatrixClientPeg.get()
.resendEvent(event, room) .resendEvent(event, room)
.then( .then(

View file

@ -30,6 +30,6 @@ export function storeRoomAliasInCache(alias: string, id: string): void {
aliasToIDMap.set(alias, id); aliasToIDMap.set(alias, id);
} }
export function getCachedRoomIDForAlias(alias: string): string { export function getCachedRoomIDForAlias(alias: string): string | undefined {
return aliasToIDMap.get(alias); return aliasToIDMap.get(alias);
} }

View file

@ -112,7 +112,7 @@ export function inviteUsersToRoom(
): Promise<void> { ): Promise<void> {
return inviteMultipleToRoom(roomId, userIds, sendSharedHistoryKeys, progressCallback) return inviteMultipleToRoom(roomId, userIds, sendSharedHistoryKeys, progressCallback)
.then((result) => { .then((result) => {
const room = MatrixClientPeg.get().getRoom(roomId); const room = MatrixClientPeg.get().getRoom(roomId)!;
showAnyInviteErrors(result.states, room, result.inviter); showAnyInviteErrors(result.states, room, result.inviter);
}) })
.catch((err) => { .catch((err) => {
@ -175,14 +175,14 @@ export function showAnyInviteErrors(
<BaseAvatar <BaseAvatar
url={avatarUrl ? mediaFromMxc(avatarUrl).getSquareThumbnailHttp(24) : null} url={avatarUrl ? mediaFromMxc(avatarUrl).getSquareThumbnailHttp(24) : null}
name={name} name={name}
idName={user.userId} idName={user?.userId}
width={36} width={36}
height={36} height={36}
/> />
</div> </div>
<div className="mx_InviteDialog_tile_nameStack"> <div className="mx_InviteDialog_tile_nameStack">
<span className="mx_InviteDialog_tile_nameStack_name">{name}</span> <span className="mx_InviteDialog_tile_nameStack_name">{name}</span>
<span className="mx_InviteDialog_tile_nameStack_userId">{user.userId}</span> <span className="mx_InviteDialog_tile_nameStack_userId">{user?.userId}</span>
</div> </div>
<div className="mx_InviteDialog_tile--inviterError_errorText"> <div className="mx_InviteDialog_tile--inviterError_errorText">
{inviter.getErrorText(addr)} {inviter.getErrorText(addr)}

View file

@ -46,7 +46,7 @@ export function getRoomNotifsState(client: MatrixClient, roomId: string): RoomNo
} }
// for everything else, look at the room rule. // for everything else, look at the room rule.
let roomRule = null; let roomRule: IPushRule | undefined;
try { try {
roomRule = client.getRoomPushRule("global", roomId); roomRule = client.getRoomPushRule("global", roomId);
} catch (err) { } catch (err) {
@ -106,7 +106,7 @@ export function getUnreadNotificationCount(room: Room, type: NotificationCountTy
function setRoomNotifsStateMuted(roomId: string): Promise<any> { function setRoomNotifsStateMuted(roomId: string): Promise<any> {
const cli = MatrixClientPeg.get(); const cli = MatrixClientPeg.get();
const promises = []; const promises: Promise<unknown>[] = [];
// delete the room rule // delete the room rule
const roomRule = cli.getRoomPushRule("global", roomId); const roomRule = cli.getRoomPushRule("global", roomId);
@ -137,7 +137,7 @@ function setRoomNotifsStateMuted(roomId: string): Promise<any> {
function setRoomNotifsStateUnmuted(roomId: string, newState: RoomNotifState): Promise<any> { function setRoomNotifsStateUnmuted(roomId: string, newState: RoomNotifState): Promise<any> {
const cli = MatrixClientPeg.get(); const cli = MatrixClientPeg.get();
const promises = []; const promises: Promise<unknown>[] = [];
const overrideMuteRule = findOverrideMuteRule(roomId); const overrideMuteRule = findOverrideMuteRule(roomId);
if (overrideMuteRule) { if (overrideMuteRule) {

View file

@ -29,13 +29,13 @@ import AliasCustomisations from "./customisations/Alias";
* @param {Object} room The room object * @param {Object} room The room object
* @returns {string} A display alias for the given room * @returns {string} A display alias for the given room
*/ */
export function getDisplayAliasForRoom(room: Room): string | undefined { export function getDisplayAliasForRoom(room: Room): string | null {
return getDisplayAliasForAliasSet(room.getCanonicalAlias(), room.getAltAliases()); return getDisplayAliasForAliasSet(room.getCanonicalAlias(), room.getAltAliases());
} }
// The various display alias getters should all feed through this one path so // The various display alias getters should all feed through this one path so
// there's a single place to change the logic. // there's a single place to change the logic.
export function getDisplayAliasForAliasSet(canonicalAlias: string, altAliases: string[]): string { export function getDisplayAliasForAliasSet(canonicalAlias: string | null, altAliases: string[]): string | null {
if (AliasCustomisations.getDisplayAliasForAliasSet) { if (AliasCustomisations.getDisplayAliasForAliasSet) {
return AliasCustomisations.getDisplayAliasForAliasSet(canonicalAlias, altAliases); return AliasCustomisations.getDisplayAliasForAliasSet(canonicalAlias, altAliases);
} }
@ -45,7 +45,7 @@ export function getDisplayAliasForAliasSet(canonicalAlias: string, altAliases: s
export function guessAndSetDMRoom(room: Room, isDirect: boolean): Promise<void> { export function guessAndSetDMRoom(room: Room, isDirect: boolean): Promise<void> {
let newTarget; let newTarget;
if (isDirect) { if (isDirect) {
const guessedUserId = guessDMRoomTargetId(room, MatrixClientPeg.get().getUserId()); const guessedUserId = guessDMRoomTargetId(room, MatrixClientPeg.get().getUserId()!);
newTarget = guessedUserId; newTarget = guessedUserId;
} else { } else {
newTarget = null; newTarget = null;
@ -118,7 +118,7 @@ function guessDMRoomTargetId(room: Room, myUserId: string): string {
if (oldestTs === undefined || (user.events.member && user.events.member.getTs() < oldestTs)) { if (oldestTs === undefined || (user.events.member && user.events.member.getTs() < oldestTs)) {
oldestUser = user; oldestUser = user;
oldestTs = user.events.member.getTs(); oldestTs = user.events.member?.getTs();
} }
} }
if (oldestUser) return oldestUser.userId; if (oldestUser) return oldestUser.userId;
@ -129,7 +129,7 @@ function guessDMRoomTargetId(room: Room, myUserId: string): string {
if (oldestTs === undefined || (user.events.member && user.events.member.getTs() < oldestTs)) { if (oldestTs === undefined || (user.events.member && user.events.member.getTs() < oldestTs)) {
oldestUser = user; oldestUser = user;
oldestTs = user.events.member.getTs(); oldestTs = user.events.member?.getTs();
} }
} }

View file

@ -72,9 +72,9 @@ export default class VoipUserMapper {
* Gets the ID of the virtual room for a room, or null if the room has no * Gets the ID of the virtual room for a room, or null if the room has no
* virtual room * virtual room
*/ */
public async getVirtualRoomForRoom(roomId: string): Promise<Room | null> { public async getVirtualRoomForRoom(roomId: string): Promise<Room | undefined> {
const virtualUser = await this.getVirtualUserForRoom(roomId); const virtualUser = await this.getVirtualUserForRoom(roomId);
if (!virtualUser) return null; if (!virtualUser) return undefined;
return findDMForUser(MatrixClientPeg.get(), virtualUser); return findDMForUser(MatrixClientPeg.get(), virtualUser);
} }
@ -145,7 +145,6 @@ export default class VoipUserMapper {
// (possibly we should only join if we've also joined the native room, then we'd also have // (possibly we should only join if we've also joined the native room, then we'd also have
// to make sure we joined virtual rooms on joining a native one) // to make sure we joined virtual rooms on joining a native one)
MatrixClientPeg.get().joinRoom(invitedRoom.roomId); MatrixClientPeg.get().joinRoom(invitedRoom.roomId);
}
// also put this room in the virtual room ID cache so isVirtualRoom return the right answer // also put this room in the virtual room ID cache so isVirtualRoom return the right answer
// in however long it takes for the echo of setAccountData to come down the sync // in however long it takes for the echo of setAccountData to come down the sync
@ -153,3 +152,4 @@ export default class VoipUserMapper {
} }
} }
} }
}

View file

@ -143,7 +143,7 @@ export default class ManageEventIndexDialog extends React.Component<IProps, ISta
SettingsStore.setValue("crawlerSleepTime", null, SettingLevel.DEVICE, e.target.value); SettingsStore.setValue("crawlerSleepTime", null, SettingLevel.DEVICE, e.target.value);
}; };
public render(): JSX.Element { public render(): React.ReactNode {
const brand = SdkConfig.get().brand; const brand = SdkConfig.get().brand;
let crawlerState; let crawlerState;

View file

@ -459,7 +459,7 @@ export default class CreateKeyBackupDialog extends React.PureComponent<IProps, I
} }
} }
public render(): JSX.Element { public render(): React.ReactNode {
let content; let content;
if (this.state.error) { if (this.state.error) {
content = ( content = (

View file

@ -842,7 +842,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent<IProp
} }
} }
public render(): JSX.Element { public render(): React.ReactNode {
let content; let content;
if (this.state.error) { if (this.state.error) {
content = ( content = (

View file

@ -127,7 +127,7 @@ export default class ExportE2eKeysDialog extends React.Component<IProps, IState>
} as Pick<IState, AnyPassphrase>); } as Pick<IState, AnyPassphrase>);
}; };
public render(): JSX.Element { public render(): React.ReactNode {
const disableForm = this.state.phase === Phase.Exporting; const disableForm = this.state.phase === Phase.Exporting;
return ( return (

View file

@ -127,7 +127,7 @@ export default class ImportE2eKeysDialog extends React.Component<IProps, IState>
return false; return false;
}; };
public render(): JSX.Element { public render(): React.ReactNode {
const disableForm = this.state.phase !== Phase.Edit; const disableForm = this.state.phase !== Phase.Edit;
return ( return (

View file

@ -48,13 +48,13 @@ export default class NewRecoveryMethodDialog extends React.PureComponent<IProps>
{ {
onFinished: this.props.onFinished, onFinished: this.props.onFinished,
}, },
null, undefined,
/* priority = */ false, /* priority = */ false,
/* static = */ true, /* static = */ true,
); );
}; };
public render(): JSX.Element { public render(): React.ReactNode {
const title = <span className="mx_KeyBackupFailedDialog_title">{_t("New Recovery Method")}</span>; const title = <span className="mx_KeyBackupFailedDialog_title">{_t("New Recovery Method")}</span>;
const newMethodDetected = <p>{_t("A new Security Phrase and key for Secure Messages have been detected.")}</p>; const newMethodDetected = <p>{_t("A new Security Phrase and key for Secure Messages have been detected.")}</p>;

View file

@ -37,14 +37,14 @@ export default class RecoveryMethodRemovedDialog extends React.PureComponent<IPr
this.props.onFinished(); this.props.onFinished();
Modal.createDialogAsync( Modal.createDialogAsync(
import("./CreateKeyBackupDialog") as unknown as Promise<ComponentType<{}>>, import("./CreateKeyBackupDialog") as unknown as Promise<ComponentType<{}>>,
null, undefined,
null, null,
/* priority = */ false, /* priority = */ false,
/* static = */ true, /* static = */ true,
); );
}; };
public render(): JSX.Element { public render(): React.ReactNode {
const title = <span className="mx_KeyBackupFailedDialog_title">{_t("Recovery Method Removed")}</span>; const title = <span className="mx_KeyBackupFailedDialog_title">{_t("Recovery Method Removed")}</span>;
return ( return (

View file

@ -91,7 +91,7 @@ export class PlaybackQueue {
public unsortedEnqueue(mxEvent: MatrixEvent, playback: Playback): void { public unsortedEnqueue(mxEvent: MatrixEvent, playback: Playback): void {
// We don't ever detach our listeners: we expect the Playback to clean up for us // We don't ever detach our listeners: we expect the Playback to clean up for us
this.playbacks.set(mxEvent.getId(), playback); this.playbacks.set(mxEvent.getId()!, playback);
playback.on(UPDATE_EVENT, (state) => this.onPlaybackStateChange(playback, mxEvent, state)); playback.on(UPDATE_EVENT, (state) => this.onPlaybackStateChange(playback, mxEvent, state));
playback.clockInfo.liveData.onUpdate((clock) => this.onPlaybackClock(playback, mxEvent, clock)); playback.clockInfo.liveData.onUpdate((clock) => this.onPlaybackClock(playback, mxEvent, clock));
} }
@ -99,12 +99,12 @@ export class PlaybackQueue {
private onPlaybackStateChange(playback: Playback, mxEvent: MatrixEvent, newState: PlaybackState): void { private onPlaybackStateChange(playback: Playback, mxEvent: MatrixEvent, newState: PlaybackState): void {
// Remember where the user got to in playback // Remember where the user got to in playback
const wasLastPlaying = this.currentPlaybackId === mxEvent.getId(); const wasLastPlaying = this.currentPlaybackId === mxEvent.getId();
if (newState === PlaybackState.Stopped && this.clockStates.has(mxEvent.getId()) && !wasLastPlaying) { if (newState === PlaybackState.Stopped && this.clockStates.has(mxEvent.getId()!) && !wasLastPlaying) {
// noinspection JSIgnoredPromiseFromCall // noinspection JSIgnoredPromiseFromCall
playback.skipTo(this.clockStates.get(mxEvent.getId())!); playback.skipTo(this.clockStates.get(mxEvent.getId()!)!);
} else if (newState === PlaybackState.Stopped) { } else if (newState === PlaybackState.Stopped) {
// Remove the now-useless clock for some space savings // Remove the now-useless clock for some space savings
this.clockStates.delete(mxEvent.getId()); this.clockStates.delete(mxEvent.getId()!);
if (wasLastPlaying) { if (wasLastPlaying) {
this.recentFullPlays.add(this.currentPlaybackId); this.recentFullPlays.add(this.currentPlaybackId);
@ -133,7 +133,7 @@ export class PlaybackQueue {
// timeline is already most recent last, so we can iterate down that. // timeline is already most recent last, so we can iterate down that.
const timeline = arrayFastClone(this.room.getLiveTimeline().getEvents()); const timeline = arrayFastClone(this.room.getLiveTimeline().getEvents());
let scanForVoiceMessage = false; let scanForVoiceMessage = false;
let nextEv: MatrixEvent; let nextEv: MatrixEvent | undefined;
for (const event of timeline) { for (const event of timeline) {
if (event.getId() === mxEvent.getId()) { if (event.getId() === mxEvent.getId()) {
scanForVoiceMessage = true; scanForVoiceMessage = true;
@ -149,8 +149,8 @@ export class PlaybackQueue {
break; // Stop automatic playback: next useful event is not a voice message break; // Stop automatic playback: next useful event is not a voice message
} }
const havePlayback = this.playbacks.has(event.getId()); const havePlayback = this.playbacks.has(event.getId()!);
const isRecentlyCompleted = this.recentFullPlays.has(event.getId()); const isRecentlyCompleted = this.recentFullPlays.has(event.getId()!);
if (havePlayback && !isRecentlyCompleted) { if (havePlayback && !isRecentlyCompleted) {
nextEv = event; nextEv = event;
break; break;
@ -164,7 +164,7 @@ export class PlaybackQueue {
} else { } else {
this.playbackIdOrder = orderClone; this.playbackIdOrder = orderClone;
const instance = this.playbacks.get(nextEv.getId()); const instance = this.playbacks.get(nextEv.getId()!);
PlaybackManager.instance.pauseAllExcept(instance); PlaybackManager.instance.pauseAllExcept(instance);
// This should cause a Play event, which will re-populate our playback order // This should cause a Play event, which will re-populate our playback order
@ -196,7 +196,7 @@ export class PlaybackQueue {
} }
} }
this.currentPlaybackId = mxEvent.getId(); this.currentPlaybackId = mxEvent.getId()!;
if (order.length === 0 || order[order.length - 1] !== this.currentPlaybackId) { if (order.length === 0 || order[order.length - 1] !== this.currentPlaybackId) {
order.push(this.currentPlaybackId); order.push(this.currentPlaybackId);
} }
@ -214,7 +214,7 @@ export class PlaybackQueue {
if (playback.currentState === PlaybackState.Decoding) return; // ignore pre-ready values if (playback.currentState === PlaybackState.Decoding) return; // ignore pre-ready values
if (playback.currentState !== PlaybackState.Stopped) { if (playback.currentState !== PlaybackState.Stopped) {
this.clockStates.set(mxEvent.getId(), clocks[0]); // [0] is the current seek position this.clockStates.set(mxEvent.getId()!, clocks[0]); // [0] is the current seek position
} }
} }
} }

View file

@ -77,7 +77,7 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
private targetMaxLength: number | null = TARGET_MAX_LENGTH; private targetMaxLength: number | null = TARGET_MAX_LENGTH;
public amplitudes: number[] = []; // at each second mark, generated public amplitudes: number[] = []; // at each second mark, generated
private liveWaveform = new FixedRollingArray(RECORDING_PLAYBACK_SAMPLES, 0); private liveWaveform = new FixedRollingArray(RECORDING_PLAYBACK_SAMPLES, 0);
public onDataAvailable: (data: ArrayBuffer) => void; public onDataAvailable?: (data: ArrayBuffer) => void;
public get contentType(): string { public get contentType(): string {
return "audio/ogg"; return "audio/ogg";
@ -181,7 +181,7 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
}); });
// not using EventEmitter here because it leads to detached bufferes // not using EventEmitter here because it leads to detached bufferes
this.recorder.ondataavailable = (data: ArrayBuffer) => this?.onDataAvailable(data); this.recorder.ondataavailable = (data: ArrayBuffer) => this.onDataAvailable?.(data);
} catch (e) { } catch (e) {
logger.error("Error starting recording: ", e); logger.error("Error starting recording: ", e);
if (e instanceof DOMException) { if (e instanceof DOMException) {

View file

@ -70,7 +70,7 @@ export default abstract class AutocompleteProvider {
* @param {boolean} force True if the user is forcing completion * @param {boolean} force True if the user is forcing completion
* @return {object} { command, range } where both objects fields are null if no match * @return {object} { command, range } where both objects fields are null if no match
*/ */
public getCurrentCommand(query: string, selection: ISelectionRange, force = false): ICommand | null { public getCurrentCommand(query: string, selection: ISelectionRange, force = false): Partial<ICommand> {
let commandRegex = this.commandRegex; let commandRegex = this.commandRegex;
if (force && this.shouldForceComplete()) { if (force && this.shouldForceComplete()) {
@ -78,7 +78,7 @@ export default abstract class AutocompleteProvider {
} }
if (!commandRegex) { if (!commandRegex) {
return null; return {};
} }
commandRegex.lastIndex = 0; commandRegex.lastIndex = 0;

View file

@ -95,7 +95,7 @@ export default class CommandProvider extends AutocompleteProvider {
description={_t(result.description)} description={_t(result.description)}
/> />
), ),
range, range: range!,
}; };
}); });
} }

View file

@ -94,7 +94,7 @@ export default class EmojiProvider extends AutocompleteProvider {
shouldMatchWordsOnly: true, shouldMatchWordsOnly: true,
}); });
this.recentlyUsed = Array.from(new Set(recent.get().map(getEmojiFromUnicode).filter(Boolean))); this.recentlyUsed = Array.from(new Set(recent.get().map(getEmojiFromUnicode).filter(Boolean))) as IEmoji[];
} }
public async getCompletions( public async getCompletions(
@ -152,7 +152,7 @@ export default class EmojiProvider extends AutocompleteProvider {
<span>{c.emoji.unicode}</span> <span>{c.emoji.unicode}</span>
</PillCompletion> </PillCompletion>
), ),
range, range: range!,
})); }));
} }
return []; return [];

View file

@ -40,12 +40,13 @@ export default class NotifProvider extends AutocompleteProvider {
): Promise<ICompletion[]> { ): Promise<ICompletion[]> {
const client = MatrixClientPeg.get(); const client = MatrixClientPeg.get();
if (!this.room.currentState.mayTriggerNotifOfType("room", client.credentials.userId)) return []; if (!this.room.currentState.mayTriggerNotifOfType("room", client.credentials.userId!)) return [];
const { command, range } = this.getCurrentCommand(query, selection, force); const { command, range } = this.getCurrentCommand(query, selection, force);
if ( if (
command?.[0].length > 1 && command?.[0] &&
["@room", "@channel", "@everyone", "@here"].some((c) => c.startsWith(command[0])) command[0].length > 1 &&
["@room", "@channel", "@everyone", "@here"].some((c) => c.startsWith(command![0]))
) { ) {
return [ return [
{ {
@ -58,7 +59,7 @@ export default class NotifProvider extends AutocompleteProvider {
<RoomAvatar width={24} height={24} room={this.room} /> <RoomAvatar width={24} height={24} room={this.room} />
</PillCompletion> </PillCompletion>
), ),
range, range: range!,
}, },
]; ];
} }

View file

@ -88,7 +88,7 @@ export default class QueryMatcher<T extends {}> {
if (!this._items.has(key)) { if (!this._items.has(key)) {
this._items.set(key, []); this._items.set(key, []);
} }
this._items.get(key).push({ this._items.get(key)!.push({
keyWeight: Number(index), keyWeight: Number(index),
object, object,
}); });
@ -104,7 +104,11 @@ export default class QueryMatcher<T extends {}> {
if (query.length === 0) { if (query.length === 0) {
return []; return [];
} }
const matches = []; const matches: {
index: number;
object: T;
keyWeight: number;
}[] = [];
// Iterate through the map & check each key. // Iterate through the map & check each key.
// ES6 Map iteration order is defined to be insertion order, so results // ES6 Map iteration order is defined to be insertion order, so results
// here will come out in the order they were put in. // here will come out in the order they were put in.

View file

@ -39,12 +39,12 @@ function canonicalScore(displayedAlias: string, room: Room): number {
function matcherObject( function matcherObject(
room: Room, room: Room,
displayedAlias: string | null, displayedAlias: string,
matchName = "", matchName = "",
): { ): {
room: Room; room: Room;
matchName: string; matchName: string;
displayedAlias: string | null; displayedAlias: string;
} { } {
return { return {
room, room,
@ -81,7 +81,7 @@ export default class RoomProvider extends AutocompleteProvider {
// the only reason we need to do this is because Fuse only matches on properties // the only reason we need to do this is because Fuse only matches on properties
let matcherObjects = this.getRooms().reduce<ReturnType<typeof matcherObject>[]>((aliases, room) => { let matcherObjects = this.getRooms().reduce<ReturnType<typeof matcherObject>[]>((aliases, room) => {
if (room.getCanonicalAlias()) { if (room.getCanonicalAlias()) {
aliases = aliases.concat(matcherObject(room, room.getCanonicalAlias(), room.name)); aliases = aliases.concat(matcherObject(room, room.getCanonicalAlias()!, room.name));
} }
if (room.getAltAliases().length) { if (room.getAltAliases().length) {
const altAliases = room.getAltAliases().map((alias) => matcherObject(room, alias)); const altAliases = room.getAltAliases().map((alias) => matcherObject(room, alias));
@ -122,7 +122,7 @@ export default class RoomProvider extends AutocompleteProvider {
<RoomAvatar width={24} height={24} room={room.room} /> <RoomAvatar width={24} height={24} room={room.room} />
</PillCompletion> </PillCompletion>
), ),
range, range: range!,
}), }),
) )
.filter((completion) => !!completion.completion && completion.completion.length > 0); .filter((completion) => !!completion.completion && completion.completion.length > 0);

View file

@ -44,7 +44,7 @@ const FORCED_USER_REGEX = /[^/,:; \t\n]\S*/g;
export default class UserProvider extends AutocompleteProvider { export default class UserProvider extends AutocompleteProvider {
public matcher: QueryMatcher<RoomMember>; public matcher: QueryMatcher<RoomMember>;
public users: RoomMember[]; public users: RoomMember[] | null;
public room: Room; public room: Room;
public constructor(room: Room, renderingType?: TimelineRenderingType) { public constructor(room: Room, renderingType?: TimelineRenderingType) {
@ -54,7 +54,7 @@ export default class UserProvider extends AutocompleteProvider {
renderingType, renderingType,
}); });
this.room = room; this.room = room;
this.matcher = new QueryMatcher([], { this.matcher = new QueryMatcher<RoomMember>([], {
keys: ["name"], keys: ["name"],
funcs: [(obj) => obj.userId.slice(1)], // index by user id minus the leading '@' funcs: [(obj) => obj.userId.slice(1)], // index by user id minus the leading '@'
shouldMatchWordsOnly: false, shouldMatchWordsOnly: false,
@ -73,7 +73,7 @@ export default class UserProvider extends AutocompleteProvider {
private onRoomTimeline = ( private onRoomTimeline = (
ev: MatrixEvent, ev: MatrixEvent,
room: Room | null, room: Room | undefined,
toStartOfTimeline: boolean, toStartOfTimeline: boolean,
removed: boolean, removed: boolean,
data: IRoomTimelineData, data: IRoomTimelineData,
@ -118,7 +118,7 @@ export default class UserProvider extends AutocompleteProvider {
// Don't include the '@' in our search query - it's only used as a way to trigger completion // Don't include the '@' in our search query - it's only used as a way to trigger completion
const query = fullMatch.startsWith("@") ? fullMatch.substring(1) : fullMatch; const query = fullMatch.startsWith("@") ? fullMatch.substring(1) : fullMatch;
return this.matcher.match(query, limit).map((user) => { return this.matcher.match(query, limit).map((user) => {
const description = UserIdentifierCustomisations.getDisplayUserIdentifier(user.userId, { const description = UserIdentifierCustomisations.getDisplayUserIdentifier?.(user.userId, {
roomId: this.room.roomId, roomId: this.room.roomId,
withDisplayName: true, withDisplayName: true,
}); });
@ -129,14 +129,14 @@ export default class UserProvider extends AutocompleteProvider {
completion: user.rawDisplayName, completion: user.rawDisplayName,
completionId: user.userId, completionId: user.userId,
type: "user", type: "user",
suffix: selection.beginning && range.start === 0 ? ": " : " ", suffix: selection.beginning && range!.start === 0 ? ": " : " ",
href: makeUserPermalink(user.userId), href: makeUserPermalink(user.userId),
component: ( component: (
<PillCompletion title={displayName} description={description}> <PillCompletion title={displayName} description={description}>
<MemberAvatar member={user} width={24} height={24} /> <MemberAvatar member={user} width={24} height={24} />
</PillCompletion> </PillCompletion>
), ),
range, range: range!,
}; };
}); });
} }
@ -152,7 +152,7 @@ export default class UserProvider extends AutocompleteProvider {
const lastSpoken: Record<string, number> = {}; const lastSpoken: Record<string, number> = {};
for (const event of events) { for (const event of events) {
lastSpoken[event.getSender()] = event.getTs(); lastSpoken[event.getSender()!] = event.getTs();
} }
const currentUserId = MatrixClientPeg.get().credentials.userId; const currentUserId = MatrixClientPeg.get().credentials.userId;
@ -164,7 +164,7 @@ export default class UserProvider extends AutocompleteProvider {
this.matcher.setObjects(this.users); this.matcher.setObjects(this.users);
} }
public onUserSpoke(user: RoomMember): void { public onUserSpoke(user: RoomMember | null): void {
if (!this.users) return; if (!this.users) return;
if (!user) return; if (!user) return;
if (user.userId === MatrixClientPeg.get().credentials.userId) return; if (user.userId === MatrixClientPeg.get().credentials.userId) return;

View file

@ -55,7 +55,7 @@ export default class AutoHideScrollbar<T extends keyof JSX.IntrinsicElements> ex
} }
} }
public render(): JSX.Element { public render(): React.ReactNode {
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
const { element, className, onScroll, tabIndex, wrappedRef, children, ...otherProps } = this.props; const { element, className, onScroll, tabIndex, wrappedRef, children, ...otherProps } = this.props;

View file

@ -118,7 +118,7 @@ export default class EmbeddedPage extends React.PureComponent<IProps, IState> {
} }
}; };
public render(): JSX.Element { public render(): React.ReactNode {
// HACK: Workaround for the context's MatrixClient not updating. // HACK: Workaround for the context's MatrixClient not updating.
const client = this.context || MatrixClientPeg.get(); const client = this.context || MatrixClientPeg.get();
const isGuest = client ? client.isGuest() : true; const isGuest = client ? client.isGuest() : true;

View file

@ -223,7 +223,7 @@ class FilePanel extends React.Component<IProps, IState> {
} }
} }
public render(): JSX.Element { public render(): React.ReactNode {
if (MatrixClientPeg.get().isGuest()) { if (MatrixClientPeg.get().isGuest()) {
return ( return (
<BaseCard className="mx_FilePanel mx_RoomView_messageListWrapper" onClose={this.props.onClose}> <BaseCard className="mx_FilePanel mx_RoomView_messageListWrapper" onClose={this.props.onClose}>

View file

@ -22,7 +22,7 @@ interface IProps {
} }
export default class GenericErrorPage extends React.PureComponent<IProps> { export default class GenericErrorPage extends React.PureComponent<IProps> {
public render(): JSX.Element { public render(): React.ReactNode {
return ( return (
<div className="mx_GenericErrorPage"> <div className="mx_GenericErrorPage">
<div className="mx_GenericErrorPage_box"> <div className="mx_GenericErrorPage_box">

View file

@ -177,7 +177,7 @@ export default class IndicatorScrollbar<T extends keyof JSX.IntrinsicElements> e
} }
}; };
public render(): JSX.Element { public render(): React.ReactNode {
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
const { children, trackHorizontalOverflow, verticalScrollsHorizontally, ...otherProps } = this.props; const { children, trackHorizontalOverflow, verticalScrollsHorizontally, ...otherProps } = this.props;

View file

@ -249,7 +249,7 @@ export default class InteractiveAuthComponent extends React.Component<IProps, IS
this.authLogic.setEmailSid(sid); this.authLogic.setEmailSid(sid);
}; };
public render(): JSX.Element { public render(): React.ReactNode {
const stage = this.state.authStage; const stage = this.state.authStage;
if (!stage) { if (!stage) {
if (this.state.busy) { if (this.state.busy) {

View file

@ -619,7 +619,7 @@ class LoggedInView extends React.Component<IProps, IState> {
this._roomView.current?.handleScrollKey(ev); this._roomView.current?.handleScrollKey(ev);
}; };
public render(): JSX.Element { public render(): React.ReactNode {
let pageElement; let pageElement;
switch (this.props.page_type) { switch (this.props.page_type) {

View file

@ -47,7 +47,7 @@ export default class MainSplit extends React.Component<IProps> {
}; };
private loadSidePanelSize(): { height: string | number; width: number } { private loadSidePanelSize(): { height: string | number; width: number } {
let rhsSize = parseInt(window.localStorage.getItem("mx_rhs_size"), 10); let rhsSize = parseInt(window.localStorage.getItem("mx_rhs_size")!, 10);
if (isNaN(rhsSize)) { if (isNaN(rhsSize)) {
rhsSize = 350; rhsSize = 350;
@ -59,7 +59,7 @@ export default class MainSplit extends React.Component<IProps> {
}; };
} }
public render(): JSX.Element { public render(): React.ReactNode {
const bodyView = React.Children.only(this.props.children); const bodyView = React.Children.only(this.props.children);
const panelView = this.props.panel; const panelView = this.props.panel;

View file

@ -2021,7 +2021,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
return fragmentAfterLogin; return fragmentAfterLogin;
} }
public render(): JSX.Element { public render(): React.ReactNode {
const fragmentAfterLogin = this.getFragmentAfterLogin(); const fragmentAfterLogin = this.getFragmentAfterLogin();
let view = null; let view = null;

View file

@ -982,7 +982,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
} }
} }
public render(): JSX.Element { public render(): React.ReactNode {
let topSpinner; let topSpinner;
let bottomSpinner; let bottomSpinner;
if (this.props.backPaginating) { if (this.props.backPaginating) {

View file

@ -45,7 +45,7 @@ export default class NonUrgentToastContainer extends React.PureComponent<IProps,
this.setState({ toasts: NonUrgentToastStore.instance.components }); this.setState({ toasts: NonUrgentToastStore.instance.components });
}; };
public render(): JSX.Element { public render(): React.ReactNode {
const toasts = this.state.toasts.map((t, i) => { const toasts = this.state.toasts.map((t, i) => {
return ( return (
<div className="mx_NonUrgentToastContainer_toast" key={`toast-${i}`}> <div className="mx_NonUrgentToastContainer_toast" key={`toast-${i}`}>

View file

@ -55,7 +55,7 @@ export default class NotificationPanel extends React.PureComponent<IProps, IStat
this.setState({ narrow }); this.setState({ narrow });
}; };
public render(): JSX.Element { public render(): React.ReactNode {
const emptyState = ( const emptyState = (
<div className="mx_RightPanel_empty mx_NotificationPanel_empty"> <div className="mx_RightPanel_empty mx_NotificationPanel_empty">
<h2>{_t("You're all caught up")}</h2> <h2>{_t("You're all caught up")}</h2>

View file

@ -245,7 +245,7 @@ export default class PictureInPictureDragger extends React.Component<IProps> {
} }
}; };
public render(): JSX.Element { public render(): React.ReactNode {
const style = { const style = {
transform: `translateX(${this.translationX}px) translateY(${this.translationY}px)`, transform: `translateX(${this.translationX}px) translateY(${this.translationY}px)`,
}; };

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import React, { MutableRefObject, useContext, useRef } from "react"; import React, { MutableRefObject, ReactNode, useContext, useRef } from "react";
import { CallEvent, CallState, MatrixCall } from "matrix-js-sdk/src/webrtc/call"; import { CallEvent, CallState, MatrixCall } from "matrix-js-sdk/src/webrtc/call";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import { Optional } from "matrix-events-sdk"; import { Optional } from "matrix-events-sdk";
@ -288,7 +288,7 @@ class PipContainerInner extends React.Component<IProps, IState> {
); );
} }
public render(): JSX.Element { public render(): ReactNode {
const pipMode = true; const pipMode = true;
let pipContent: Array<CreatePipChildren> = []; let pipContent: Array<CreatePipChildren> = [];

View file

@ -149,7 +149,7 @@ export default class RightPanel extends React.Component<IProps, IState> {
this.setState({ searchQuery }); this.setState({ searchQuery });
}; };
public render(): JSX.Element { public render(): React.ReactNode {
let card = <div />; let card = <div />;
const roomId = this.props.room?.roomId; const roomId = this.props.room?.roomId;
const phase = this.props.overwriteCard?.phase ?? this.state.phase; const phase = this.props.overwriteCard?.phase ?? this.state.phase;

View file

@ -111,11 +111,11 @@ export const RoomSearchView = forwardRef<ScrollPanel, Props>(
); );
if (!bundledRelationship || event.getThread()) continue; if (!bundledRelationship || event.getThread()) continue;
const room = client.getRoom(event.getRoomId()); const room = client.getRoom(event.getRoomId());
const thread = room.findThreadForEvent(event); const thread = room?.findThreadForEvent(event);
if (thread) { if (thread) {
event.setThread(thread); event.setThread(thread);
} else { } else {
room.createThread(event.getId(), event, [], true); room?.createThread(event.getId()!, event, [], true);
} }
} }
} }
@ -214,7 +214,7 @@ export const RoomSearchView = forwardRef<ScrollPanel, Props>(
scrollPanel?.checkScroll(); scrollPanel?.checkScroll();
}; };
let lastRoomId: string; let lastRoomId: string | undefined;
let mergedTimeline: MatrixEvent[] = []; let mergedTimeline: MatrixEvent[] = [];
let ourEventsIndexes: number[] = []; let ourEventsIndexes: number[] = [];

View file

@ -213,7 +213,7 @@ export default class RoomStatusBar extends React.PureComponent<IProps, IState> {
{}, {},
{ {
consentLink: (sub) => ( consentLink: (sub) => (
<a href={consentError.data && consentError.data.consent_uri} target="_blank"> <a href={consentError!.data?.consent_uri} target="_blank">
{sub} {sub}
</a> </a>
), ),
@ -272,7 +272,7 @@ export default class RoomStatusBar extends React.PureComponent<IProps, IState> {
); );
} }
public render(): JSX.Element { public render(): React.ReactNode {
if (this.shouldShowConnectionError()) { if (this.shouldShowConnectionError()) {
return ( return (
<div className="mx_RoomStatusBar"> <div className="mx_RoomStatusBar">

View file

@ -1879,7 +1879,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
); );
} }
public render(): JSX.Element { public render(): React.ReactNode {
if (this.state.room instanceof LocalRoom) { if (this.state.room instanceof LocalRoom) {
if (this.state.room.state === LocalRoomState.CREATING) { if (this.state.room.state === LocalRoomState.CREATING) {
return this.renderLocalRoomCreateLoader(); return this.renderLocalRoomCreateLoader();

View file

@ -24,7 +24,7 @@ import { getKeyBindingsManager } from "../../KeyBindingsManager";
import { KeyBindingAction } from "../../accessibility/KeyboardShortcuts"; import { KeyBindingAction } from "../../accessibility/KeyboardShortcuts";
interface IProps extends HTMLProps<HTMLInputElement> { interface IProps extends HTMLProps<HTMLInputElement> {
onSearch?: (query: string) => void; onSearch: (query: string) => void;
onCleared?: (source?: string) => void; onCleared?: (source?: string) => void;
onKeyDown?: (ev: React.KeyboardEvent) => void; onKeyDown?: (ev: React.KeyboardEvent) => void;
onFocus?: (ev: React.FocusEvent) => void; onFocus?: (ev: React.FocusEvent) => void;
@ -62,7 +62,7 @@ export default class SearchBox extends React.Component<IProps, IState> {
private onSearch = throttle( private onSearch = throttle(
(): void => { (): void => {
this.props.onSearch(this.search.current.value); this.props.onSearch(this.search.current?.value);
}, },
200, 200,
{ trailing: true, leading: true }, { trailing: true, leading: true },
@ -101,7 +101,7 @@ export default class SearchBox extends React.Component<IProps, IState> {
} }
} }
public render(): JSX.Element { public render(): React.ReactNode {
/* eslint @typescript-eslint/no-unused-vars: ["error", { "ignoreRestSiblings": true }] */ /* eslint @typescript-eslint/no-unused-vars: ["error", { "ignoreRestSiblings": true }] */
const { const {
onSearch, onSearch,

View file

@ -814,7 +814,7 @@ export default class SpaceRoomView extends React.PureComponent<IProps, IState> {
} }
} }
public render(): JSX.Element { public render(): React.ReactNode {
const rightPanel = const rightPanel =
this.state.showRightPanel && this.state.phase === Phase.Landing ? ( this.state.showRightPanel && this.state.phase === Phase.Landing ? (
<RightPanel room={this.props.space} resizeNotifier={this.props.resizeNotifier} /> <RightPanel room={this.props.space} resizeNotifier={this.props.resizeNotifier} />

View file

@ -343,7 +343,7 @@ export default class ThreadView extends React.Component<IProps, IState> {
); );
}; };
public render(): JSX.Element { public render(): React.ReactNode {
const highlightedEventId = this.props.isInitialEventHighlighted ? this.props.initialEvent?.getId() : null; const highlightedEventId = this.props.isInitialEventHighlighted ? this.props.initialEvent?.getId() : null;
const threadRelation = this.threadRelation; const threadRelation = this.threadRelation;

View file

@ -1886,7 +1886,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
this.callEventGroupers = buildLegacyCallEventGroupers(this.callEventGroupers, events); this.callEventGroupers = buildLegacyCallEventGroupers(this.callEventGroupers, events);
} }
public render(): JSX.Element { public render(): React.ReactNode {
// just show a spinner while the timeline loads. // just show a spinner while the timeline loads.
// //
// put it in a div of the right class (mx_RoomView_messagePanel) so // put it in a div of the right class (mx_RoomView_messagePanel) so

View file

@ -50,7 +50,7 @@ export default class ToastContainer extends React.Component<{}, IState> {
}); });
}; };
public render(): JSX.Element { public render(): React.ReactNode {
const totalCount = this.state.toasts.length; const totalCount = this.state.toasts.length;
const isStacked = totalCount > 1; const isStacked = totalCount > 1;
let toast; let toast;

View file

@ -103,7 +103,7 @@ export default class UploadBar extends React.PureComponent<IProps, IState> {
ContentMessages.sharedInstance().cancelUpload(this.state.currentUpload!); ContentMessages.sharedInstance().cancelUpload(this.state.currentUpload!);
}; };
public render(): JSX.Element { public render(): React.ReactNode {
if (!this.state.currentFile) { if (!this.state.currentFile) {
return null; return null;
} }

View file

@ -429,7 +429,7 @@ export default class UserMenu extends React.Component<IProps, IState> {
); );
}; };
public render(): JSX.Element { public render(): React.ReactNode {
const avatarSize = 32; // should match border-radius of the avatar const avatarSize = 32; // should match border-radius of the avatar
const userId = MatrixClientPeg.get().getUserId(); const userId = MatrixClientPeg.get().getUserId();

View file

@ -18,6 +18,7 @@ limitations under the License.
import React from "react"; import React from "react";
import { MatrixEvent } from "matrix-js-sdk/src/models/event"; import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { RoomMember } from "matrix-js-sdk/src/models/room-member"; import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import { MatrixClientPeg } from "../../MatrixClientPeg"; import { MatrixClientPeg } from "../../MatrixClientPeg";
import Modal from "../../Modal"; import Modal from "../../Modal";
@ -31,7 +32,7 @@ import { RightPanelPhases } from "../../stores/right-panel/RightPanelStorePhases
import { UserOnboardingPage } from "../views/user-onboarding/UserOnboardingPage"; import { UserOnboardingPage } from "../views/user-onboarding/UserOnboardingPage";
interface IProps { interface IProps {
userId?: string; userId: string;
resizeNotifier: ResizeNotifier; resizeNotifier: ResizeNotifier;
} }
@ -66,7 +67,7 @@ export default class UserView extends React.Component<IProps, IState> {
private async loadProfileInfo(): Promise<void> { private async loadProfileInfo(): Promise<void> {
const cli = MatrixClientPeg.get(); const cli = MatrixClientPeg.get();
this.setState({ loading: true }); this.setState({ loading: true });
let profileInfo; let profileInfo: Awaited<ReturnType<MatrixClient["getProfileInfo"]>>;
try { try {
profileInfo = await cli.getProfileInfo(this.props.userId); profileInfo = await cli.getProfileInfo(this.props.userId);
} catch (err) { } catch (err) {
@ -83,7 +84,7 @@ export default class UserView extends React.Component<IProps, IState> {
this.setState({ member, loading: false }); this.setState({ member, loading: false });
} }
public render(): JSX.Element { public render(): React.ReactNode {
if (this.state.loading) { if (this.state.loading) {
return <Spinner />; return <Spinner />;
} else if (this.state.member) { } else if (this.state.member) {

View file

@ -142,7 +142,7 @@ export default class ViewSource extends React.Component<IProps, IState> {
return room.currentState.mayClientSendStateEvent(mxEvent.getType(), cli); return room.currentState.mayClientSendStateEvent(mxEvent.getType(), cli);
} }
public render(): JSX.Element { public render(): React.ReactNode {
const mxEvent = this.props.mxEvent.replacingEvent() || this.props.mxEvent; // show the replacing event, not the original, if it is an edit const mxEvent = this.props.mxEvent.replacingEvent() || this.props.mxEvent; // show the replacing event, not the original, if it is an edit
const isEditing = this.state.isEditing; const isEditing = this.state.isEditing;

View file

@ -57,7 +57,7 @@ export default class CompleteSecurity extends React.Component<IProps, IState> {
store.stop(); store.stop();
} }
public render(): JSX.Element { public render(): React.ReactNode {
const { phase, lostKeys } = this.state; const { phase, lostKeys } = this.state;
let icon; let icon;
let title; let title;

View file

@ -27,7 +27,7 @@ interface IProps {
} }
export default class E2eSetup extends React.Component<IProps> { export default class E2eSetup extends React.Component<IProps> {
public render(): JSX.Element { public render(): React.ReactNode {
return ( return (
<AuthPage> <AuthPage>
<CompleteSecurityBody> <CompleteSecurityBody>

View file

@ -487,7 +487,7 @@ export default class ForgotPassword extends React.Component<Props, State> {
); );
} }
public render(): JSX.Element { public render(): React.ReactNode {
let resetPasswordJsx: JSX.Element; let resetPasswordJsx: JSX.Element;
switch (this.state.phase) { switch (this.state.phase) {

View file

@ -563,7 +563,7 @@ export default class LoginComponent extends React.PureComponent<IProps, IState>
); );
}; };
public render(): JSX.Element { public render(): React.ReactNode {
const loader = const loader =
this.isBusy() && !this.state.busyLoggingIn ? ( this.isBusy() && !this.state.busyLoggingIn ? (
<div className="mx_Login_loader"> <div className="mx_Login_loader">

View file

@ -573,7 +573,7 @@ export default class Registration extends React.Component<IProps, IState> {
} }
} }
public render(): JSX.Element { public render(): React.ReactNode {
let errorText; let errorText;
const err = this.state.errorText; const err = this.state.errorText;
if (err) { if (err) {

View file

@ -141,7 +141,7 @@ export default class SetupEncryptionBody extends React.Component<IProps, IState>
this.props.onFinished(); this.props.onFinished();
}; };
public render(): JSX.Element { public render(): React.ReactNode {
const { phase, lostKeys } = this.state; const { phase, lostKeys } = this.state;
if (this.state.verificationRequest) { if (this.state.verificationRequest) {

View file

@ -326,7 +326,7 @@ export default class SoftLogout extends React.Component<IProps, IState> {
); );
} }
public render(): JSX.Element { public render(): React.ReactNode {
return ( return (
<AuthPage> <AuthPage>
<AuthHeader /> <AuthHeader />

View file

@ -43,7 +43,7 @@ export default class Clock extends React.Component<Props> {
return currentFloor !== nextFloor; return currentFloor !== nextFloor;
} }
public render(): JSX.Element { public render(): React.ReactNode {
return ( return (
<span aria-live={this.props["aria-live"]} role={this.props.role} className="mx_Clock"> <span aria-live={this.props["aria-live"]} role={this.props.role} className="mx_Clock">
{this.props.formatFn(this.props.seconds)} {this.props.formatFn(this.props.seconds)}

View file

@ -48,7 +48,7 @@ export default class DurationClock extends React.PureComponent<IProps, IState> {
this.setState({ durationSeconds: time[1] }); this.setState({ durationSeconds: time[1] });
}; };
public render(): JSX.Element { public render(): React.ReactNode {
return <Clock seconds={this.state.durationSeconds} />; return <Clock seconds={this.state.durationSeconds} />;
} }
} }

View file

@ -59,7 +59,7 @@ export default class LiveRecordingClock extends React.PureComponent<IProps, ISta
}); });
} }
public render(): JSX.Element { public render(): React.ReactNode {
return <Clock seconds={this.state.seconds} aria-live="off" />; return <Clock seconds={this.state.seconds} aria-live="off" />;
} }
} }

View file

@ -63,7 +63,7 @@ export default class LiveRecordingWaveform extends React.PureComponent<IProps, I
this.setState({ waveform: this.waveform }); this.setState({ waveform: this.waveform });
} }
public render(): JSX.Element { public render(): React.ReactNode {
return <Waveform relHeights={this.state.waveform} />; return <Waveform relHeights={this.state.waveform} />;
} }
} }

View file

@ -65,7 +65,7 @@ export default class PlaybackClock extends React.PureComponent<IProps, IState> {
this.setState({ seconds: time[0], durationSeconds: time[1] }); this.setState({ seconds: time[0], durationSeconds: time[1] });
}; };
public render(): JSX.Element { public render(): React.ReactNode {
let seconds = this.state.seconds; let seconds = this.state.seconds;
if (this.state.playbackPhase === PlaybackState.Stopped) { if (this.state.playbackPhase === PlaybackState.Stopped) {
if (Number.isFinite(this.props.defaultDisplaySeconds)) { if (Number.isFinite(this.props.defaultDisplaySeconds)) {

View file

@ -61,7 +61,7 @@ export default class PlaybackWaveform extends React.PureComponent<IProps, IState
this.setState({ progress }); this.setState({ progress });
}; };
public render(): JSX.Element { public render(): React.ReactNode {
return <Waveform relHeights={this.state.heights} progress={this.state.progress} />; return <Waveform relHeights={this.state.heights} progress={this.state.progress} />;
} }
} }

View file

@ -41,7 +41,7 @@ export default class Waveform extends React.PureComponent<IProps, IState> {
progress: 1, progress: 1,
}; };
public render(): JSX.Element { public render(): React.ReactNode {
return ( return (
<div className="mx_Waveform"> <div className="mx_Waveform">
{this.props.relHeights.map((h, i) => { {this.props.relHeights.map((h, i) => {

View file

@ -122,7 +122,7 @@ export default class CaptchaForm extends React.Component<ICaptchaFormProps, ICap
} }
} }
public render(): JSX.Element { public render(): React.ReactNode {
let error = null; let error = null;
if (this.state.errorText) { if (this.state.errorText) {
error = <div className="error">{this.state.errorText}</div>; error = <div className="error">{this.state.errorText}</div>;

View file

@ -74,7 +74,7 @@ class EmailField extends PureComponent<IProps> {
return result; return result;
}; };
public render(): JSX.Element { public render(): React.ReactNode {
return ( return (
<Field <Field
id={this.props.id} id={this.props.id}

View file

@ -136,7 +136,7 @@ export class PasswordAuthEntry extends React.Component<IAuthEntryProps, IPasswor
}); });
}; };
public render(): JSX.Element { public render(): React.ReactNode {
const passwordBoxClass = classNames({ const passwordBoxClass = classNames({
error: this.props.errorText, error: this.props.errorText,
}); });
@ -207,7 +207,7 @@ export class RecaptchaAuthEntry extends React.Component<IRecaptchaAuthEntryProps
}); });
}; };
public render(): JSX.Element { public render(): React.ReactNode {
if (this.props.busy) { if (this.props.busy) {
return <Spinner />; return <Spinner />;
} }
@ -353,7 +353,7 @@ export class TermsAuthEntry extends React.Component<ITermsAuthEntryProps, ITerms
} }
}; };
public render(): JSX.Element { public render(): React.ReactNode {
if (this.props.busy) { if (this.props.busy) {
return <Spinner />; return <Spinner />;
} }
@ -442,7 +442,7 @@ export class EmailIdentityAuthEntry extends React.Component<
this.props.onPhaseChange(DEFAULT_PHASE); this.props.onPhaseChange(DEFAULT_PHASE);
} }
public render(): JSX.Element { public render(): React.ReactNode {
let errorSection; let errorSection;
// ignore the error when errcode is M_UNAUTHORIZED as we expect that error until the link is clicked. // ignore the error when errcode is M_UNAUTHORIZED as we expect that error until the link is clicked.
if (this.props.errorText && this.props.errorCode !== "M_UNAUTHORIZED") { if (this.props.errorText && this.props.errorCode !== "M_UNAUTHORIZED") {
@ -650,7 +650,7 @@ export class MsisdnAuthEntry extends React.Component<IMsisdnAuthEntryProps, IMsi
} }
}; };
public render(): JSX.Element { public render(): React.ReactNode {
if (this.state.requestingToken) { if (this.state.requestingToken) {
return <Spinner />; return <Spinner />;
} else { } else {
@ -733,7 +733,7 @@ export class RegistrationTokenAuthEntry extends React.Component<IAuthEntryProps,
}); });
}; };
public render(): JSX.Element { public render(): React.ReactNode {
const registrationTokenBoxClass = classNames({ const registrationTokenBoxClass = classNames({
error: this.props.errorText, error: this.props.errorText,
}); });
@ -857,7 +857,7 @@ export class SSOAuthEntry extends React.Component<ISSOAuthEntryProps, ISSOAuthEn
this.props.submitAuthDict({}); this.props.submitAuthDict({});
}; };
public render(): JSX.Element { public render(): React.ReactNode {
let continueButton = null; let continueButton = null;
const cancelButton = ( const cancelButton = (
<AccessibleButton <AccessibleButton
@ -952,7 +952,7 @@ export class FallbackAuthEntry extends React.Component<IAuthEntryProps> {
} }
}; };
public render(): JSX.Element { public render(): React.ReactNode {
let errorSection; let errorSection;
if (this.props.errorText) { if (this.props.errorText) {
errorSection = ( errorSection = (

View file

@ -229,7 +229,7 @@ export default class LoginWithQR extends React.Component<IProps, IState> {
} }
}; };
public render(): JSX.Element { public render(): React.ReactNode {
return ( return (
<LoginWithQRFlow <LoginWithQRFlow
onClick={this.onClick} onClick={this.onClick}

View file

@ -69,7 +69,7 @@ export default class LoginWithQRFlow extends React.Component<IProps> {
); );
}; };
public render(): JSX.Element { public render(): React.ReactNode {
let title = ""; let title = "";
let titleIcon: JSX.Element | undefined; let titleIcon: JSX.Element | undefined;
let main: JSX.Element | undefined; let main: JSX.Element | undefined;

View file

@ -65,7 +65,7 @@ class PassphraseConfirmField extends PureComponent<IProps> {
return result; return result;
}; };
public render(): JSX.Element { public render(): React.ReactNode {
return ( return (
<Field <Field
id={this.props.id} id={this.props.id}

View file

@ -102,7 +102,7 @@ class PassphraseField extends PureComponent<IProps> {
return result; return result;
}; };
public render(): JSX.Element { public render(): React.ReactNode {
return ( return (
<Field <Field
id={this.props.id} id={this.props.id}

View file

@ -367,7 +367,7 @@ export default class PasswordLogin extends React.PureComponent<IProps, IState> {
} }
} }
public render(): JSX.Element { public render(): React.ReactNode {
let forgotPasswordJsx; let forgotPasswordJsx;
if (this.props.onForgotPasswordClick) { if (this.props.onForgotPasswordClick) {

View file

@ -534,7 +534,7 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
); );
} }
public render(): JSX.Element { public render(): React.ReactNode {
const registerButton = ( const registerButton = (
<input className="mx_Login_submit" type="submit" value={_t("Register")} disabled={!this.props.canSubmit} /> <input className="mx_Login_submit" type="submit" value={_t("Register")} disabled={!this.props.canSubmit} />
); );

View file

@ -109,7 +109,7 @@ export default function MemberAvatar({
} }
export class LegacyMemberAvatar extends React.Component<IProps> { export class LegacyMemberAvatar extends React.Component<IProps> {
public render(): JSX.Element { public render(): React.ReactNode {
return <MemberAvatar {...this.props}>{this.props.children}</MemberAvatar>; return <MemberAvatar {...this.props}>{this.props.children}</MemberAvatar>;
} }
} }

View file

@ -135,7 +135,7 @@ export default class RoomAvatar extends React.Component<IProps, IState> {
return this.props.room?.roomId || this.props.oobData?.roomId; return this.props.room?.roomId || this.props.oobData?.roomId;
} }
public render(): JSX.Element { public render(): React.ReactNode {
const { room, oobData, viewAvatarOnClick, onClick, className, ...otherProps } = this.props; const { room, oobData, viewAvatarOnClick, onClick, className, ...otherProps } = this.props;
const roomName = room?.name ?? oobData.name; const roomName = room?.name ?? oobData.name;

View file

@ -91,7 +91,7 @@ const BetaCard: React.FC<IProps> = ({ title: titleOverride, featureId }) => {
); );
} }
let refreshWarning: string; let refreshWarning: string | undefined;
if (requiresRefresh) { if (requiresRefresh) {
const brand = SdkConfig.get().brand; const brand = SdkConfig.get().brand;
refreshWarning = value refreshWarning = value

View file

@ -69,7 +69,7 @@ export default class DialpadContextMenu extends React.Component<IProps, IState>
this.setState({ value: ev.target.value }); this.setState({ value: ev.target.value });
}; };
public render(): JSX.Element { public render(): React.ReactNode {
return ( return (
<ContextMenu {...this.props}> <ContextMenu {...this.props}>
<div className="mx_DialPadContextMenuWrapper"> <div className="mx_DialPadContextMenuWrapper">

View file

@ -47,7 +47,7 @@ export default class GenericElementContextMenu extends React.Component<IProps> {
} }
}; };
public render(): JSX.Element { public render(): React.ReactNode {
return <div>{this.props.element}</div>; return <div>{this.props.element}</div>;
} }
} }

View file

@ -21,7 +21,7 @@ interface IProps {
} }
export default class GenericTextContextMenu extends React.Component<IProps> { export default class GenericTextContextMenu extends React.Component<IProps> {
public render(): JSX.Element { public render(): React.ReactNode {
return ( return (
<div className="mx_Tooltip mx_Tooltip_visible" style={{ display: "block" }}> <div className="mx_Tooltip mx_Tooltip_visible" style={{ display: "block" }}>
{this.props.message} {this.props.message}

View file

@ -46,7 +46,7 @@ export default class LegacyCallContextMenu extends React.Component<IProps> {
this.props.onFinished(); this.props.onFinished();
}; };
public render(): JSX.Element { public render(): React.ReactNode {
const holdUnholdCaption = this.props.call.isRemoteOnHold() ? _t("Resume") : _t("Hold"); const holdUnholdCaption = this.props.call.isRemoteOnHold() ? _t("Resume") : _t("Hold");
const handler = this.props.call.isRemoteOnHold() ? this.onUnholdClick : this.onHoldClick; const handler = this.props.call.isRemoteOnHold() ? this.onUnholdClick : this.onHoldClick;

View file

@ -376,7 +376,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
this.closeMenu(); this.closeMenu();
}; };
public render(): JSX.Element { public render(): React.ReactNode {
const cli = MatrixClientPeg.get(); const cli = MatrixClientPeg.get();
const me = cli.getUserId(); const me = cli.getUserId();
const { mxEvent, rightClick, link, eventTileOps, reactions, collapseReplyChain, ...other } = this.props; const { mxEvent, rightClick, link, eventTileOps, reactions, collapseReplyChain, ...other } = this.props;

View file

@ -48,7 +48,7 @@ export default class AskInviteAnywayDialog extends React.Component<IProps> {
this.props.onFinished(false); this.props.onFinished(false);
}; };
public render(): JSX.Element { public render(): React.ReactNode {
const errorList = this.props.unknownProfileUsers.map((address) => ( const errorList = this.props.unknownProfileUsers.map((address) => (
<li key={address.userId}> <li key={address.userId}>
{address.userId}: {address.errorText} {address.userId}: {address.errorText}

View file

@ -115,7 +115,7 @@ export default class BaseDialog extends React.Component<IProps> {
this.props.onFinished(false); this.props.onFinished(false);
}; };
public render(): JSX.Element { public render(): React.ReactNode {
let cancelButton; let cancelButton;
if (this.props.hasCancel) { if (this.props.hasCancel) {
cancelButton = ( cancelButton = (

View file

@ -180,7 +180,7 @@ export default class BugReportDialog extends React.Component<IProps, IState> {
this.setState({ downloadProgress }); this.setState({ downloadProgress });
}; };
public render(): JSX.Element { public render(): React.ReactNode {
let error = null; let error = null;
if (this.state.err) { if (this.state.err) {
error = <div className="error">{this.state.err}</div>; error = <div className="error">{this.state.err}</div>;

View file

@ -86,7 +86,7 @@ export default class ChangelogDialog extends React.Component<IProps, State> {
); );
} }
public render(): JSX.Element { public render(): React.ReactNode {
const logs = REPOS.map((repo) => { const logs = REPOS.map((repo) => {
let content; let content;
if (this.state[repo] == null) { if (this.state[repo] == null) {

View file

@ -72,7 +72,7 @@ export default class ConfirmAndWaitRedactDialog extends React.PureComponent<IPro
} }
}; };
public render(): JSX.Element { public render(): React.ReactNode {
if (this.state.isRedacting) { if (this.state.isRedacting) {
if (this.state.redactionErrorCode) { if (this.state.redactionErrorCode) {
const code = this.state.redactionErrorCode; const code = this.state.redactionErrorCode;

View file

@ -33,7 +33,7 @@ interface IProps {
* A dialog for confirming a redaction. * A dialog for confirming a redaction.
*/ */
export default class ConfirmRedactDialog extends React.Component<IProps> { export default class ConfirmRedactDialog extends React.Component<IProps> {
public render(): JSX.Element { public render(): React.ReactNode {
return ( return (
<TextInputDialog <TextInputDialog
onFinished={this.props.onFinished} onFinished={this.props.onFinished}

View file

@ -83,7 +83,7 @@ export default class ConfirmUserActionDialog extends React.Component<IProps, ISt
}); });
}; };
public render(): JSX.Element { public render(): React.ReactNode {
const confirmButtonClass = this.props.danger ? "danger" : ""; const confirmButtonClass = this.props.danger ? "danger" : "";
let reasonBox; let reasonBox;

View file

@ -33,7 +33,7 @@ export default class ConfirmWipeDeviceDialog extends React.Component<IProps> {
this.props.onFinished(false); this.props.onFinished(false);
}; };
public render(): JSX.Element { public render(): React.ReactNode {
return ( return (
<BaseDialog <BaseDialog
className="mx_ConfirmWipeDeviceDialog" className="mx_ConfirmWipeDeviceDialog"

View file

@ -216,7 +216,7 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
], ],
}); });
public render(): JSX.Element { public render(): React.ReactNode {
const isVideoRoom = this.props.type === RoomType.ElementVideo; const isVideoRoom = this.props.type === RoomType.ElementVideo;
let aliasField: JSX.Element; let aliasField: JSX.Element;

View file

@ -182,7 +182,7 @@ export default class DeactivateAccountDialog extends React.Component<IProps, ISt
}); });
} }
public render(): JSX.Element { public render(): React.ReactNode {
let error = null; let error = null;
if (this.state.errStr) { if (this.state.errStr) {
error = <div className="error">{this.state.errStr}</div>; error = <div className="error">{this.state.errStr}</div>;

View file

@ -67,7 +67,7 @@ export default class EndPollDialog extends React.Component<IProps> {
this.props.onFinished(endPoll); this.props.onFinished(endPoll);
}; };
public render(): JSX.Element { public render(): React.ReactNode {
return ( return (
<QuestionDialog <QuestionDialog
title={_t("End Poll")} title={_t("End Poll")}

View file

@ -52,7 +52,7 @@ export default class ErrorDialog extends React.Component<IProps, IState> {
this.props.onFinished(true); this.props.onFinished(true);
}; };
public render(): JSX.Element { public render(): React.ReactNode {
return ( return (
<BaseDialog <BaseDialog
className="mx_ErrorDialog" className="mx_ErrorDialog"

View file

@ -97,7 +97,7 @@ const FeedbackDialog: React.FC<IProps> = (props: IProps) => {
); );
} }
let bugReports = null; let bugReports: JSX.Element | null = null;
if (rageshakeUrl) { if (rageshakeUrl) {
bugReports = ( bugReports = (
<p className="mx_FeedbackDialog_section_microcopy"> <p className="mx_FeedbackDialog_section_microcopy">

Some files were not shown because too many files have changed in this diff Show more