Conform more of the codebase to strictNullChecks (#10842)

This commit is contained in:
Michael Telatynski 2023-05-11 09:56:56 +01:00 committed by GitHub
parent 5eea2c8b02
commit 82e32035fd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 126 additions and 93 deletions

View file

@ -20,7 +20,7 @@ limitations under the License.
import url from "url";
import React, { ContextType, createRef, CSSProperties, MutableRefObject, ReactNode } from "react";
import classNames from "classnames";
import { MatrixCapabilities } from "matrix-widget-api";
import { IWidget, MatrixCapabilities } from "matrix-widget-api";
import { Room, RoomEvent } from "matrix-js-sdk/src/models/room";
import { logger } from "matrix-js-sdk/src/logger";
import { ApprovalOpts, WidgetLifecycle } from "@matrix-org/react-sdk-module-api/lib/lifecycles/WidgetLifecycle";
@ -40,7 +40,7 @@ import { ElementWidget, StopGapWidget } from "../../../stores/widgets/StopGapWid
import { WidgetContextMenu } from "../context_menus/WidgetContextMenu";
import WidgetAvatar from "../avatars/WidgetAvatar";
import LegacyCallHandler from "../../../LegacyCallHandler";
import { IApp } from "../../../stores/WidgetStore";
import { IApp, isAppWidget } from "../../../stores/WidgetStore";
import { Container, WidgetLayoutStore } from "../../../stores/widgets/WidgetLayoutStore";
import { OwnProfileStore } from "../../../stores/OwnProfileStore";
import { UPDATE_EVENT } from "../../../stores/AsyncStore";
@ -54,7 +54,7 @@ import { SdkContextClass } from "../../../contexts/SDKContext";
import { ModuleRunner } from "../../../modules/ModuleRunner";
interface IProps {
app: IApp;
app: IWidget | IApp;
// If room is not specified then it is an account level widget
// which bypasses permission prompts as it was added explicitly by that user
room?: Room;
@ -133,7 +133,10 @@ export default class AppTile extends React.Component<IProps, IState> {
// Tiles in miniMode are floating, and therefore not docked
if (!this.props.miniMode) {
ActiveWidgetStore.instance.dockWidget(this.props.app.id, this.props.app.roomId);
ActiveWidgetStore.instance.dockWidget(
this.props.app.id,
isAppWidget(this.props.app) ? this.props.app.roomId : null,
);
}
// The key used for PersistedElement
@ -169,14 +172,17 @@ export default class AppTile extends React.Component<IProps, IState> {
if (opts.approved) return true;
const currentlyAllowedWidgets = SettingsStore.getValue("allowedWidgets", props.room.roomId);
const allowed = props.app.eventId !== undefined && (currentlyAllowedWidgets[props.app.eventId] ?? false);
const allowed =
isAppWidget(props.app) &&
props.app.eventId !== undefined &&
(currentlyAllowedWidgets[props.app.eventId] ?? false);
return allowed || props.userId === props.creatorUserId;
};
private onUserLeftRoom(): void {
const isActiveWidget = ActiveWidgetStore.instance.getWidgetPersistence(
this.props.app.id,
this.props.app.roomId,
isAppWidget(this.props.app) ? this.props.app.roomId : null,
);
if (isActiveWidget) {
// We just left the room that the active widget was from.
@ -188,7 +194,10 @@ export default class AppTile extends React.Component<IProps, IState> {
this.reload();
} else {
// Otherwise just cancel its persistence.
ActiveWidgetStore.instance.destroyPersistentWidget(this.props.app.id, this.props.app.roomId);
ActiveWidgetStore.instance.destroyPersistentWidget(
this.props.app.id,
isAppWidget(this.props.app) ? this.props.app.roomId : null,
);
}
}
}
@ -243,7 +252,10 @@ export default class AppTile extends React.Component<IProps, IState> {
if (this.state.hasPermissionToLoad && !hasPermissionToLoad) {
// Force the widget to be non-persistent (able to be deleted/forgotten)
ActiveWidgetStore.instance.destroyPersistentWidget(this.props.app.id, this.props.app.roomId);
ActiveWidgetStore.instance.destroyPersistentWidget(
this.props.app.id,
isAppWidget(this.props.app) ? this.props.app.roomId : null,
);
PersistedElement.destroyElement(this.persistKey);
this.sgWidget?.stopMessaging();
}
@ -288,13 +300,21 @@ export default class AppTile extends React.Component<IProps, IState> {
this.unmounted = true;
if (!this.props.miniMode) {
ActiveWidgetStore.instance.undockWidget(this.props.app.id, this.props.app.roomId);
ActiveWidgetStore.instance.undockWidget(
this.props.app.id,
isAppWidget(this.props.app) ? this.props.app.roomId : null,
);
}
// Only tear down the widget if no other component is keeping it alive,
// because we support moving widgets between containers, in which case
// another component will keep it loaded throughout the transition
if (!ActiveWidgetStore.instance.isLive(this.props.app.id, this.props.app.roomId)) {
if (
!ActiveWidgetStore.instance.isLive(
this.props.app.id,
isAppWidget(this.props.app) ? this.props.app.roomId : null,
)
) {
this.endWidgetActions();
}
@ -395,7 +415,10 @@ export default class AppTile extends React.Component<IProps, IState> {
// Delete the widget from the persisted store for good measure.
PersistedElement.destroyElement(this.persistKey);
ActiveWidgetStore.instance.destroyPersistentWidget(this.props.app.id, this.props.app.roomId);
ActiveWidgetStore.instance.destroyPersistentWidget(
this.props.app.id,
isAppWidget(this.props.app) ? this.props.app.roomId : null,
);
this.sgWidget?.stopMessaging({ forceDestroy: true });
}
@ -441,9 +464,10 @@ export default class AppTile extends React.Component<IProps, IState> {
private grantWidgetPermission = (): void => {
const roomId = this.props.room?.roomId;
logger.info("Granting permission for widget to load: " + this.props.app.eventId);
const eventId = isAppWidget(this.props.app) ? this.props.app.eventId : undefined;
logger.info("Granting permission for widget to load: " + eventId);
const current = SettingsStore.getValue("allowedWidgets", roomId);
if (this.props.app.eventId !== undefined) current[this.props.app.eventId] = true;
if (eventId !== undefined) current[eventId] = true;
const level = SettingsStore.firstSupportedLevel("allowedWidgets")!;
SettingsStore.setValue("allowedWidgets", roomId ?? null, level, current)
.then(() => {
@ -550,7 +574,7 @@ export default class AppTile extends React.Component<IProps, IState> {
};
public render(): React.ReactNode {
let appTileBody;
let appTileBody: JSX.Element;
// Note that there is advice saying allow-scripts shouldn't be used with allow-same-origin
// because that would allow the iframe to programmatically remove the sandbox attribute, but

View file

@ -47,7 +47,7 @@ interface IProps {
// the latest event in this chain of replies
parentEv: MatrixEvent;
// called when the ReplyChain contents has changed, including EventTiles thereof
onHeightChanged: () => void;
onHeightChanged?: () => void;
permalinkCreator?: RoomPermalinkCreator;
// Specifies which layout to use.
layout?: Layout;
@ -104,7 +104,7 @@ export default class ReplyChain extends React.Component<IProps, IState> {
}
public componentDidUpdate(): void {
this.props.onHeightChanged();
this.props.onHeightChanged?.();
this.trySetExpandableQuotes();
}