Conform more of the codebase to strictNullChecks (#10800)

This commit is contained in:
Michael Telatynski 2023-05-10 08:41:55 +01:00 committed by GitHub
parent adb29b38a3
commit 456c66db5b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
46 changed files with 147 additions and 123 deletions

View file

@ -44,7 +44,7 @@ export default class IndicatorScrollbar<T extends keyof JSX.IntrinsicElements> e
IState
> {
private autoHideScrollbar = createRef<AutoHideScrollbar<any>>();
private scrollElement: HTMLDivElement;
private scrollElement?: HTMLDivElement;
private likelyTrackpadUser: boolean | null = null;
private checkAgainForTrackpad = 0; // ts in milliseconds to recheck this._likelyTrackpadUser
@ -85,6 +85,7 @@ export default class IndicatorScrollbar<T extends keyof JSX.IntrinsicElements> e
}
private checkOverflow = (): void => {
if (!this.scrollElement) return;
const hasTopOverflow = this.scrollElement.scrollTop > 0;
const hasBottomOverflow =
this.scrollElement.scrollHeight > this.scrollElement.scrollTop + this.scrollElement.clientHeight;

View file

@ -73,7 +73,7 @@ export function buildLegacyCallEventGroupers(
export default class LegacyCallEventGrouper extends EventEmitter {
private events: Set<MatrixEvent> = new Set<MatrixEvent>();
private call: MatrixCall | null = null;
public state: CallState | CustomCallState;
public state?: CallState | CustomCallState;
public constructor() {
super();

View file

@ -96,10 +96,10 @@ interface IProps {
autoJoin?: boolean;
threepidInvite?: IThreepidInvite;
roomOobData?: IOOBData;
currentRoomId: string;
currentRoomId: string | null;
collapseLhs: boolean;
config: ConfigOptions;
currentUserId: string;
currentUserId: string | null;
justRegistered?: boolean;
roomJustCreatedOpts?: IOpts;
forceTimeline?: boolean; // see props on MatrixChat
@ -131,10 +131,10 @@ class LoggedInView extends React.Component<IProps, IState> {
protected readonly _roomView: React.RefObject<RoomViewType>;
protected readonly _resizeContainer: React.RefObject<HTMLDivElement>;
protected readonly resizeHandler: React.RefObject<HTMLDivElement>;
protected layoutWatcherRef: string;
protected compactLayoutWatcherRef: string;
protected backgroundImageWatcherRef: string;
protected resizer: Resizer;
protected layoutWatcherRef?: string;
protected compactLayoutWatcherRef?: string;
protected backgroundImageWatcherRef?: string;
protected resizer?: Resizer;
public constructor(props: IProps) {
super(props);
@ -200,10 +200,10 @@ class LoggedInView extends React.Component<IProps, IState> {
this._matrixClient.removeListener(ClientEvent.Sync, this.onSync);
this._matrixClient.removeListener(RoomStateEvent.Events, this.onRoomStateEvents);
OwnProfileStore.instance.off(UPDATE_EVENT, this.refreshBackgroundImage);
SettingsStore.unwatchSetting(this.layoutWatcherRef);
SettingsStore.unwatchSetting(this.compactLayoutWatcherRef);
SettingsStore.unwatchSetting(this.backgroundImageWatcherRef);
this.resizer.detach();
if (this.layoutWatcherRef) SettingsStore.unwatchSetting(this.layoutWatcherRef);
if (this.compactLayoutWatcherRef) SettingsStore.unwatchSetting(this.compactLayoutWatcherRef);
if (this.backgroundImageWatcherRef) SettingsStore.unwatchSetting(this.backgroundImageWatcherRef);
this.resizer?.detach();
}
private onCallState = (): void => {
@ -274,7 +274,7 @@ class LoggedInView extends React.Component<IProps, IState> {
if (isNaN(lhsSize)) {
lhsSize = 350;
}
this.resizer.forHandleWithId("lp-resizer")?.resize(lhsSize);
this.resizer?.forHandleWithId("lp-resizer")?.resize(lhsSize);
}
private onAccountData = (event: MatrixEvent): void => {
@ -645,7 +645,11 @@ class LoggedInView extends React.Component<IProps, IState> {
break;
case PageTypes.UserView:
pageElement = <UserView userId={this.props.currentUserId} resizeNotifier={this.props.resizeNotifier} />;
if (!!this.props.currentUserId) {
pageElement = (
<UserView userId={this.props.currentUserId} resizeNotifier={this.props.resizeNotifier} />
);
}
break;
}

View file

@ -231,7 +231,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
private focusComposer: boolean;
private subTitleStatus: string;
private prevWindowWidth: number;
private voiceBroadcastResumer: VoiceBroadcastResumer;
private voiceBroadcastResumer?: VoiceBroadcastResumer;
private readonly loggedInView: React.RefObject<LoggedInViewType>;
private readonly dispatcherRef: string;
@ -441,7 +441,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
window.removeEventListener("resize", this.onWindowResized);
this.stores.accountPasswordStore.clearPassword();
if (this.voiceBroadcastResumer) this.voiceBroadcastResumer.destroy();
this.voiceBroadcastResumer?.destroy();
}
private onWindowResized = (): void => {
@ -1935,7 +1935,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
private setPageSubtitle(subtitle = ""): void {
if (this.state.currentRoomId) {
const client = MatrixClientPeg.get();
const room = client && client.getRoom(this.state.currentRoomId);
const room = client?.getRoom(this.state.currentRoomId);
if (room) {
subtitle = `${this.subTitleStatus} | ${room.name} ${subtitle}`;
}

View file

@ -179,7 +179,7 @@ export default class ScrollPanel extends React.Component<IProps> {
};
private readonly itemlist = createRef<HTMLOListElement>();
private unmounted = false;
private scrollTimeout: Timer;
private scrollTimeout?: Timer;
// Are we currently trying to backfill?
private isFilling: boolean;
// Is the current fill request caused by a props update?
@ -189,8 +189,8 @@ export default class ScrollPanel extends React.Component<IProps> {
// Is that next fill request scheduled because of a props update?
private pendingFillDueToPropsUpdate: boolean;
private scrollState: IScrollState;
private preventShrinkingState: IPreventShrinkingState | null;
private unfillDebouncer: number | null;
private preventShrinkingState: IPreventShrinkingState | null = null;
private unfillDebouncer: number | null = null;
private bottomGrowth: number;
private minListHeight: number;
private heightUpdateInProgress: boolean;
@ -234,7 +234,7 @@ export default class ScrollPanel extends React.Component<IProps> {
// skip scroll events caused by resizing
if (this.props.resizeNotifier && this.props.resizeNotifier.isResizing) return;
debuglog("onScroll called past resize gate; scroll node top:", this.getScrollNode().scrollTop);
this.scrollTimeout.restart();
this.scrollTimeout?.restart();
this.saveScrollState();
this.updatePreventShrinking();
this.props.onScroll?.(ev);
@ -725,7 +725,7 @@ export default class ScrollPanel extends React.Component<IProps> {
// need a better name that also indicates this will change scrollTop? Rebalance height? Reveal content?
private async updateHeight(): Promise<void> {
// wait until user has stopped scrolling
if (this.scrollTimeout.isRunning()) {
if (this.scrollTimeout?.isRunning()) {
debuglog("updateHeight waiting for scrolling to end ... ");
await this.scrollTimeout.finished();
debuglog("updateHeight actually running now");

View file

@ -88,9 +88,9 @@ export default class UserMenu extends React.Component<IProps, IState> {
public static contextType = SDKContext;
public context!: React.ContextType<typeof SDKContext>;
private dispatcherRef: string;
private themeWatcherRef: string;
private readonly dndWatcherRef: string;
private dispatcherRef?: string;
private themeWatcherRef?: string;
private readonly dndWatcherRef?: string;
private buttonRef: React.RefObject<HTMLButtonElement> = createRef();
public constructor(props: IProps, context: React.ContextType<typeof SDKContext>) {

View file

@ -125,7 +125,7 @@ interface IState {
export default class Registration extends React.Component<IProps, IState> {
private readonly loginLogic: Login;
// `replaceClient` tracks latest serverConfig to spot when it changes under the async method which fetches flows
private latestServerConfig: ValidatedServerConfig;
private latestServerConfig?: ValidatedServerConfig;
public constructor(props: IProps) {
super(props);

View file

@ -556,8 +556,8 @@ export class MsisdnAuthEntry extends React.Component<IMsisdnAuthEntryProps, IMsi
public static LOGIN_TYPE = AuthType.Msisdn;
private submitUrl?: string;
private sid: string;
private msisdn: string;
private sid?: string;
private msisdn?: string;
public constructor(props: IMsisdnAuthEntryProps) {
super(props);
@ -615,8 +615,8 @@ export class MsisdnAuthEntry extends React.Component<IMsisdnAuthEntryProps, IMsi
});
try {
let result;
if (this.submitUrl) {
let result: { success: boolean };
if (this.submitUrl && this.sid) {
result = await this.props.matrixClient.submitMsisdnTokenOtherUrl(
this.submitUrl,
this.sid,

View file

@ -19,7 +19,7 @@ import React, { ChangeEvent } from "react";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { logger } from "matrix-js-sdk/src/logger";
import { _t } from "../../../languageHandler";
import { _t, UserFriendlyError } from "../../../languageHandler";
import { ensureDMExists } from "../../../createRoom";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
import SdkConfig from "../../../SdkConfig";
@ -245,6 +245,10 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
// Report to moderators through to the dedicated bot,
// as configured in the room's state events.
const dmRoomId = await ensureDMExists(client, this.moderation.moderationBotUserId);
if (!dmRoomId) {
throw new UserFriendlyError("Unable to create room with moderation bot");
}
await client.sendEvent(dmRoomId, ABUSE_EVENT_TYPE, {
event_id: ev.getId(),
room_id: ev.getRoomId(),

View file

@ -62,7 +62,7 @@ interface IState {
}
class RoomSettingsDialog extends React.Component<IProps, IState> {
private dispatcherRef: string;
private dispatcherRef?: string;
public constructor(props: IProps) {
super(props);

View file

@ -35,7 +35,7 @@ interface IState {
}
export default class RoomUpgradeDialog extends React.Component<IProps, IState> {
private targetVersion: string;
private targetVersion?: string;
public state = {
busy: true,
@ -53,7 +53,7 @@ export default class RoomUpgradeDialog extends React.Component<IProps, IState> {
private onUpgradeClick = (): void => {
this.setState({ busy: true });
upgradeRoom(this.props.room, this.targetVersion, false, false)
upgradeRoom(this.props.room, this.targetVersion!, false, false)
.then(() => {
this.props.onFinished(true);
})
@ -69,7 +69,7 @@ export default class RoomUpgradeDialog extends React.Component<IProps, IState> {
};
public render(): React.ReactNode {
let buttons;
let buttons: JSX.Element;
if (this.state.busy) {
buttons = <Spinner />;
} else {

View file

@ -44,7 +44,7 @@ interface IState {
export default class ServerPickerDialog extends React.PureComponent<IProps, IState> {
private readonly defaultServer: ValidatedServerConfig;
private readonly fieldRef = createRef<Field>();
private validatedConf: ValidatedServerConfig;
private validatedConf?: ValidatedServerConfig;
public constructor(props: IProps) {
super(props);
@ -85,7 +85,7 @@ export default class ServerPickerDialog extends React.PureComponent<IProps, ISta
// find their homeserver without demanding they use "https://matrix.org"
private validate = withValidation<this, { error?: string }>({
deriveData: async ({ value }): Promise<{ error?: string }> => {
let hsUrl = value.trim(); // trim to account for random whitespace
let hsUrl = (value ?? "").trim(); // trim to account for random whitespace
// if the URL has no protocol, try validate it as a serverName via well-known
if (!hsUrl.includes("://")) {

View file

@ -45,7 +45,7 @@ interface IState {
* On success, `onFinished(true)` is called.
*/
export default class SetEmailDialog extends React.Component<IProps, IState> {
private addThreepid: AddThreepid;
private addThreepid?: AddThreepid;
public constructor(props: IProps) {
super(props);
@ -109,7 +109,7 @@ export default class SetEmailDialog extends React.Component<IProps, IState> {
};
private verifyEmailAddress(): void {
this.addThreepid.checkEmailLinkClicked().then(
this.addThreepid?.checkEmailLinkClicked().then(
() => {
this.props.onFinished(true);
},

View file

@ -121,11 +121,11 @@ export default class AppTile extends React.Component<IProps, IState> {
};
private contextMenuButton = createRef<any>();
private iframe: HTMLIFrameElement; // ref to the iframe (callback style)
private allowedWidgetsWatchRef: string;
private iframe?: HTMLIFrameElement; // ref to the iframe (callback style)
private allowedWidgetsWatchRef?: string;
private persistKey: string;
private sgWidget: StopGapWidget | null;
private dispatcherRef: string;
private dispatcherRef?: string;
private unmounted: boolean;
public constructor(props: IProps) {
@ -305,7 +305,7 @@ export default class AppTile extends React.Component<IProps, IState> {
this.context.off(RoomEvent.MyMembership, this.onMyMembership);
}
SettingsStore.unwatchSetting(this.allowedWidgetsWatchRef);
if (this.allowedWidgetsWatchRef) SettingsStore.unwatchSetting(this.allowedWidgetsWatchRef);
OwnProfileStore.instance.removeListener(UPDATE_EVENT, this.onUserReady);
}
@ -344,7 +344,7 @@ export default class AppTile extends React.Component<IProps, IState> {
private startMessaging(): void {
try {
this.sgWidget?.startMessaging(this.iframe);
this.sgWidget?.startMessaging(this.iframe!);
} catch (e) {
logger.error("Failed to start widget", e);
}

View file

@ -88,7 +88,7 @@ export interface PickerIProps {
type TabId = "screen" | "window";
export default class DesktopCapturerSourcePicker extends React.Component<PickerIProps, PickerIState> {
public interval: number;
public interval?: number;
public constructor(props: PickerIProps) {
super(props);

View file

@ -75,8 +75,8 @@ interface IProps {
export default class PersistedElement extends React.Component<IProps> {
private resizeObserver: ResizeObserver;
private dispatcherRef: string;
private childContainer: HTMLDivElement;
private child: HTMLDivElement;
private childContainer?: HTMLDivElement;
private child?: HTMLDivElement;
public constructor(props: IProps) {
super(props);
@ -172,12 +172,12 @@ export default class PersistedElement extends React.Component<IProps> {
ReactDOM.render(content, getOrCreateContainer("mx_persistedElement_" + this.props.persistKey));
}
private updateChildVisibility(child: HTMLDivElement, visible: boolean): void {
private updateChildVisibility(child?: HTMLDivElement, visible = false): void {
if (!child) return;
child.style.display = visible ? "block" : "none";
}
private updateChildPosition(child: HTMLDivElement, parent: HTMLDivElement): void {
private updateChildPosition(child?: HTMLDivElement, parent?: HTMLDivElement): void {
if (!child || !parent) return;
const parentRect = parent.getBoundingClientRect();

View file

@ -17,5 +17,5 @@ limitations under the License.
import { MediaEventHelper } from "../../../utils/MediaEventHelper";
export interface IMediaBody {
getMediaHelper(): MediaEventHelper;
getMediaHelper(): MediaEventHelper | undefined;
}

View file

@ -48,7 +48,7 @@ interface IState {
export default class LegacyCallEvent extends React.PureComponent<IProps, IState> {
private wrapperElement = createRef<HTMLDivElement>();
private resizeObserver: ResizeObserver;
private resizeObserver?: ResizeObserver;
public constructor(props: IProps) {
super(props);
@ -75,7 +75,7 @@ export default class LegacyCallEvent extends React.PureComponent<IProps, IState>
this.props.callEventGrouper.removeListener(LegacyCallEventGrouperEvent.SilencedChanged, this.onSilencedChanged);
this.props.callEventGrouper.removeListener(LegacyCallEventGrouperEvent.LengthChanged, this.onLengthChanged);
this.resizeObserver.disconnect();
this.resizeObserver?.disconnect();
}
private onLengthChanged = (length: number): void => {

View file

@ -69,7 +69,7 @@ export default class MImageBody extends React.Component<IBodyProps, IState> {
private unmounted = true;
private image = createRef<HTMLImageElement>();
private timeout?: number;
private sizeWatcher: string;
private sizeWatcher?: string;
private reconnectedListener: ClientEventHandlerMap[ClientEvent.Sync];
public constructor(props: IBodyProps) {
@ -367,7 +367,7 @@ export default class MImageBody extends React.Component<IBodyProps, IState> {
this.unmounted = true;
MatrixClientPeg.get().off(ClientEvent.Sync, this.reconnectedListener);
this.clearBlurhashTimeout();
SettingsStore.unwatchSetting(this.sizeWatcher);
if (this.sizeWatcher) SettingsStore.unwatchSetting(this.sizeWatcher);
if (this.state.isAnimated && this.state.thumbUrl) {
URL.revokeObjectURL(this.state.thumbUrl);
}

View file

@ -45,7 +45,7 @@ export default class MVideoBody extends React.PureComponent<IBodyProps, IState>
public context!: React.ContextType<typeof RoomContext>;
private videoRef = React.createRef<HTMLVideoElement>();
private sizeWatcher: string;
private sizeWatcher?: string;
public constructor(props: IBodyProps) {
super(props);
@ -187,7 +187,7 @@ export default class MVideoBody extends React.PureComponent<IBodyProps, IState>
}
public componentWillUnmount(): void {
SettingsStore.unwatchSetting(this.sizeWatcher);
if (this.sizeWatcher) SettingsStore.unwatchSetting(this.sizeWatcher);
}
private videoOnPlay = async (): Promise<void> => {

View file

@ -82,7 +82,7 @@ const baseEvTypes = new Map<string, React.ComponentType<Partial<IBodyProps>>>([
export default class MessageEvent extends React.Component<IProps> implements IMediaBody, IOperableEventTile {
private body: React.RefObject<React.Component | IOperableEventTile> = createRef();
private mediaHelper: MediaEventHelper;
private mediaHelper?: MediaEventHelper;
private bodyTypes = new Map<string, typeof React.Component>(baseBodyTypes.entries());
private evTypes = new Map<string, React.ComponentType<Partial<IBodyProps>>>(baseEvTypes.entries());
@ -133,7 +133,7 @@ export default class MessageEvent extends React.Component<IProps> implements IMe
return (this.body.current as IOperableEventTile)?.getEventTileOps?.() || null;
};
public getMediaHelper(): MediaEventHelper {
public getMediaHelper(): MediaEventHelper | undefined {
return this.mediaHelper;
}

View file

@ -57,9 +57,9 @@ interface IState {
export default class AppsDrawer extends React.Component<IProps, IState> {
private unmounted = false;
private resizeContainer: HTMLDivElement;
private resizeContainer?: HTMLDivElement;
private resizer: Resizer;
private dispatcherRef: string;
private dispatcherRef?: string;
public static defaultProps: Partial<IProps> = {
showApps: true,
};
@ -113,11 +113,11 @@ export default class AppsDrawer extends React.Component<IProps, IState> {
};
const collapseConfig = {
onResizeStart: () => {
this.resizeContainer.classList.add("mx_AppsDrawer_resizing");
this.resizeContainer?.classList.add("mx_AppsDrawer_resizing");
this.setState({ resizingHorizontal: true });
},
onResizeStop: () => {
this.resizeContainer.classList.remove("mx_AppsDrawer_resizing");
this.resizeContainer?.classList.remove("mx_AppsDrawer_resizing");
WidgetLayoutStore.instance.setResizerDistributions(
this.props.room,
Container.Top,

View file

@ -133,9 +133,9 @@ export default class Autocomplete extends React.PureComponent<IProps, IState> {
});
}
private processQuery(query: string, selection: ISelectionRange): Promise<void> {
private async processQuery(query: string, selection: ISelectionRange): Promise<void> {
return this.autocompleter
.getCompletions(query, selection, this.state.forceComplete, MAX_PROVIDER_MATCHES)
?.getCompletions(query, selection, this.state.forceComplete, MAX_PROVIDER_MATCHES)
.then((completions) => {
// Only ever process the completions for the most recent query being processed
if (query !== this.queryRequested) {

View file

@ -129,7 +129,7 @@ class EditMessageComposer extends React.Component<IEditMessageComposerProps, ISt
private readonly editorRef = createRef<BasicMessageComposer>();
private readonly dispatcherRef: string;
private readonly replyToEvent?: MatrixEvent;
private model: EditorModel;
private model!: EditorModel;
public constructor(props: IEditMessageComposerProps, context: React.ContextType<typeof RoomContext>) {
super(props);

View file

@ -46,8 +46,8 @@ interface IState {
}
export default class MemberTile extends React.Component<IProps, IState> {
private userLastModifiedTime: number;
private memberLastModifiedTime: number;
private userLastModifiedTime?: number;
private memberLastModifiedTime?: number;
public static defaultProps = {
showPresence: true,

View file

@ -443,7 +443,7 @@ const TAG_AESTHETICS: TagAestheticsMap = {
export default class RoomList extends React.PureComponent<IProps, IState> {
private dispatcherRef?: string;
private treeRef = createRef<HTMLDivElement>();
private favouriteMessageWatcher: string;
private favouriteMessageWatcher?: string;
public static contextType = MatrixClientContext;
public context!: React.ContextType<typeof MatrixClientContext>;
@ -476,7 +476,7 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
public componentWillUnmount(): void {
SpaceStore.instance.off(UPDATE_SUGGESTED_ROOMS, this.updateSuggestedRooms);
RoomListStore.instance.off(LISTS_UPDATE_EVENT, this.updateLists);
SettingsStore.unwatchSetting(this.favouriteMessageWatcher);
if (this.favouriteMessageWatcher) SettingsStore.unwatchSetting(this.favouriteMessageWatcher);
if (this.dispatcherRef) defaultDispatcher.unregister(this.dispatcherRef);
SdkContextClass.instance.roomViewStore.off(UPDATE_EVENT, this.onRoomViewStoreUpdate);
}

View file

@ -215,8 +215,10 @@ export default class RoomPreviewBar extends React.Component<IProps, IState> {
if (!myMember) {
return {};
}
const kickerMember = this.props.room?.currentState.getMember(myMember.events.member.getSender());
const memberName = kickerMember?.name ?? myMember.events.member?.getSender();
const kickerUserId = myMember.events.member?.getSender();
const kickerMember = kickerUserId ? this.props.room?.currentState.getMember(kickerUserId) : undefined;
const memberName = kickerMember?.name ?? kickerUserId;
const reason = myMember.events.member?.getContent().reason;
return { memberName, reason };
}
@ -559,7 +561,7 @@ export default class RoomPreviewBar extends React.Component<IProps, IState> {
"%(errcode)s was returned while trying to access the room or space. " +
"If you think you're seeing this message in error, please " +
"<issueLink>submit a bug report</issueLink>.",
{ errcode: this.props.error.errcode },
{ errcode: String(this.props.error?.errcode) },
{
issueLink: (label) => (
<a

View file

@ -110,7 +110,7 @@ export default class RoomSublist extends React.Component<IProps, IState> {
private headerButton = createRef<HTMLDivElement>();
private sublistRef = createRef<HTMLDivElement>();
private tilesRef = createRef<HTMLDivElement>();
private dispatcherRef: string;
private dispatcherRef?: string;
private layout: ListLayout;
private heightAtStart: number;
private notificationState: ListNotificationState;
@ -257,7 +257,7 @@ export default class RoomSublist extends React.Component<IProps, IState> {
}
public componentWillUnmount(): void {
defaultDispatcher.unregister(this.dispatcherRef);
if (this.dispatcherRef) defaultDispatcher.unregister(this.dispatcherRef);
RoomListStore.instance.off(LISTS_UPDATE_EVENT, this.onListsUpdated);
RoomListStore.instance.off(LISTS_LOADING_EVENT, this.onListsLoading);
this.tilesRef.current?.removeEventListener("scroll", this.onScrollPrevent);

View file

@ -23,7 +23,7 @@ import AppTile from "../elements/AppTile";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
import dis from "../../../dispatcher/dispatcher";
import AccessibleButton from "../elements/AccessibleButton";
import WidgetUtils, { IWidgetEvent } from "../../../utils/WidgetUtils";
import WidgetUtils, { UserWidget } from "../../../utils/WidgetUtils";
import PersistedElement from "../elements/PersistedElement";
import { IntegrationManagers } from "../../../integrations/IntegrationManagers";
import ContextMenu, { ChevronFace } from "../../structures/ContextMenu";
@ -53,7 +53,7 @@ interface IProps {
interface IState {
imError: string | null;
stickerpickerWidget: IWidgetEvent | null;
stickerpickerWidget: UserWidget | null;
widgetId: string | null;
}
@ -62,7 +62,7 @@ export default class Stickerpicker extends React.PureComponent<IProps, IState> {
threadId: null,
};
public static currentWidget?: IWidgetEvent;
public static currentWidget?: UserWidget;
private dispatcherRef?: string;
@ -252,14 +252,14 @@ export default class Stickerpicker extends React.PureComponent<IProps, IState> {
// Render content from multiple stickerpack sources, each within their
// own iframe, within the stickerpicker UI element.
const stickerpickerWidget = this.state.stickerpickerWidget;
let stickersContent;
let stickersContent: JSX.Element | undefined;
// Use a separate ReactDOM tree to render the AppTile separately so that it persists and does
// not unmount when we (a) close the sticker picker (b) switch rooms. It's properties are still
// updated.
// Load stickerpack content
if (stickerpickerWidget && stickerpickerWidget.content && stickerpickerWidget.content.url) {
if (!!stickerpickerWidget?.content?.url) {
// Set default name
stickerpickerWidget.content.name = stickerpickerWidget.content.name || _t("Stickerpack");

View file

@ -69,9 +69,9 @@ interface IState {
}
export default class ChangePassword extends React.Component<IProps, IState> {
private [FIELD_OLD_PASSWORD]: Field | null;
private [FIELD_NEW_PASSWORD]: Field | null;
private [FIELD_NEW_PASSWORD_CONFIRM]: Field | null;
private [FIELD_OLD_PASSWORD]: Field | null = null;
private [FIELD_NEW_PASSWORD]: Field | null = null;
private [FIELD_NEW_PASSWORD_CONFIRM]: Field | null = null;
public static defaultProps: Partial<IProps> = {
onFinished() {},

View file

@ -43,7 +43,7 @@ interface IState {
}
export default class IntegrationManager extends React.Component<IProps, IState> {
private dispatcherRef: string;
private dispatcherRef?: string;
public static defaultProps: Partial<IProps> = {
connected: true,
@ -60,7 +60,7 @@ export default class IntegrationManager extends React.Component<IProps, IState>
}
public componentWillUnmount(): void {
dis.unregister(this.dispatcherRef);
if (this.dispatcherRef) dis.unregister(this.dispatcherRef);
document.removeEventListener("keydown", this.onKeyDown);
}

View file

@ -81,7 +81,7 @@ interface IState {
}
export default class SetIdServer extends React.Component<IProps, IState> {
private dispatcherRef: string;
private dispatcherRef?: string;
public constructor(props: IProps) {
super(props);
@ -108,7 +108,7 @@ export default class SetIdServer extends React.Component<IProps, IState> {
}
public componentWillUnmount(): void {
dis.unregister(this.dispatcherRef);
if (this.dispatcherRef) dis.unregister(this.dispatcherRef);
}
private onAction = (payload: ActionPayload): void => {