Apply strictNullChecks to src/components/views/context_menus/* (#10367)

This commit is contained in:
Michael Telatynski 2023-03-14 09:29:35 +00:00 committed by GitHub
parent 4c2b5df1f2
commit 7c2511a592
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 32 additions and 29 deletions

View file

@ -54,7 +54,7 @@ const DeviceContextMenuSection: React.FC<IDeviceContextMenuSectionProps> = ({ de
useEffect(() => {
const getDevices = async (): Promise<void> => {
return setDevices((await MediaDeviceHandler.getDevices())[deviceKind]);
return setDevices((await MediaDeviceHandler.getDevices())?.[deviceKind] ?? []);
};
getDevices();
}, [deviceKind]);

View file

@ -48,7 +48,7 @@ export const KebabContextMenu: React.FC<KebabContextMenuProps> = ({ options, tit
compact
rightAligned
closeOnInteraction
{...contextMenuBelow(button.current.getBoundingClientRect())}
{...contextMenuBelow(button.current!.getBoundingClientRect())}
>
<IconizedContextMenuOptionList>{options}</IconizedContextMenuOptionList>
</IconizedContextMenu>

View file

@ -73,7 +73,7 @@ const ReplyInThreadButton: React.FC<IReplyInThreadButton> = ({ mxEvent, closeMen
if (mxEvent.getThread() && !mxEvent.isThreadRoot) {
dis.dispatch<ShowThreadPayload>({
action: Action.ShowThread,
rootEvent: mxEvent.getThread().rootEvent,
rootEvent: mxEvent.getThread()!.rootEvent!,
initialEvent: mxEvent,
scroll_into_view: true,
highlighted: true,
@ -163,12 +163,12 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
// to obliterate the room - https://github.com/matrix-org/synapse/issues/4042
// Similarly for encryption events, since redacting them "breaks everything"
const canRedact =
room.currentState.maySendRedactionForEvent(this.props.mxEvent, cli.credentials.userId) &&
!!room?.currentState.maySendRedactionForEvent(this.props.mxEvent, cli.getSafeUserId()) &&
this.props.mxEvent.getType() !== EventType.RoomServerAcl &&
this.props.mxEvent.getType() !== EventType.RoomEncryption;
let canPin =
room.currentState.mayClientSendStateEvent(EventType.RoomPinnedEvents, cli) &&
!!room?.currentState.mayClientSendStateEvent(EventType.RoomPinnedEvents, cli) &&
canPinEvent(this.props.mxEvent);
// HACK: Intentionally say we can't pin if the user doesn't want to use the functionality
@ -249,9 +249,10 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
private onPinClick = (): void => {
const cli = MatrixClientPeg.get();
const room = cli.getRoom(this.props.mxEvent.getRoomId());
if (!room) return;
const eventId = this.props.mxEvent.getId();
const pinnedIds = room?.currentState?.getStateEvents(EventType.RoomPinnedEvents, "")?.getContent().pinned || [];
const pinnedIds = room.currentState?.getStateEvents(EventType.RoomPinnedEvents, "")?.getContent().pinned || [];
if (pinnedIds.includes(eventId)) {
pinnedIds.splice(pinnedIds.indexOf(eventId), 1);
@ -261,7 +262,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
event_ids: [...(room.getAccountData(ReadPinsEventId)?.getContent()?.event_ids || []), eventId],
});
}
cli.sendStateEvent(this.props.mxEvent.getRoomId(), EventType.RoomPinnedEvents, { pinned: pinnedIds }, "");
cli.sendStateEvent(room.roomId, EventType.RoomPinnedEvents, { pinned: pinnedIds }, "");
this.closeMenu();
};
@ -294,12 +295,13 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
private onCopyLinkClick = (e: ButtonEvent): void => {
e.preventDefault(); // So that we don't open the permalink
if (!this.props.link) return;
copyPlaintext(this.props.link);
this.closeMenu();
};
private onCollapseReplyChainClick = (): void => {
this.props.collapseReplyChain();
this.props.collapseReplyChain?.();
this.closeMenu();
};
@ -349,10 +351,12 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
const cli = MatrixClientPeg.get();
const room = cli.getRoom(this.props.mxEvent.getRoomId());
const eventId = this.props.mxEvent.getId();
return room.getPendingEvents().filter((e) => {
const relation = e.getRelation();
return relation?.rel_type === RelationType.Annotation && relation.event_id === eventId && filter(e);
});
return (
room?.getPendingEvents().filter((e) => {
const relation = e.getRelation();
return relation?.rel_type === RelationType.Annotation && relation.event_id === eventId && filter(e);
}) ?? []
);
}
private getUnsentReactions(): MatrixEvent[] {
@ -380,7 +384,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
const eventStatus = mxEvent.status;
const unsentReactionsCount = this.getUnsentReactions().length;
const contentActionable = isContentActionable(mxEvent);
const permalink = this.props.permalinkCreator?.forEvent(this.props.mxEvent.getId());
const permalink = this.props.permalinkCreator?.forEvent(this.props.mxEvent.getId()!);
// status is SENT before remote-echo, null after
const isSent = !eventStatus || eventStatus === EventStatus.SENT;
const { timelineRenderingType, canReact, canSendMessages } = this.context;

View file

@ -399,7 +399,7 @@ const RoomContextMenu: React.FC<IProps> = ({ room, onFinished, ...props }) => {
Modal.createDialog(
DevtoolsDialog,
{
roomId: SdkContextClass.instance.roomViewStore.getRoomId(),
roomId: room.roomId,
},
"mx_DevtoolsDialog_wrapper",
);

View file

@ -72,7 +72,7 @@ const ThreadListContextMenu: React.FC<ThreadListContextMenuProps> = ({
if (permalinkCreator) {
evt?.preventDefault();
evt?.stopPropagation();
const matrixToUrl = permalinkCreator.forEvent(mxEvent.getId());
const matrixToUrl = permalinkCreator.forEvent(mxEvent.getId()!);
await copyPlaintext(matrixToUrl);
closeThreadOptions();
}
@ -84,9 +84,8 @@ const ThreadListContextMenu: React.FC<ThreadListContextMenuProps> = ({
onMenuToggle?.(menuDisplayed);
}, [menuDisplayed, onMenuToggle]);
const isMainSplitTimelineShown = !WidgetLayoutStore.instance.hasMaximisedWidget(
MatrixClientPeg.get().getRoom(mxEvent.getRoomId()),
);
const room = MatrixClientPeg.get().getRoom(mxEvent.getRoomId());
const isMainSplitTimelineShown = !!room && !WidgetLayoutStore.instance.hasMaximisedWidget(room);
return (
<React.Fragment>
<ContextMenuTooltipButton
@ -104,7 +103,7 @@ const ThreadListContextMenu: React.FC<ThreadListContextMenuProps> = ({
className="mx_RoomTile_contextMenu"
compact
rightAligned
{...contextMenuBelow(button.current.getBoundingClientRect())}
{...contextMenuBelow(button.current!.getBoundingClientRect())}
>
<IconizedContextMenuOptionList>
{isMainSplitTimelineShown && (

View file

@ -63,8 +63,8 @@ export const WidgetContextMenu: React.FC<IProps> = ({
const widgetMessaging = WidgetMessagingStore.instance.getMessagingForUid(WidgetUtils.getWidgetUid(app));
const canModify = userWidget || WidgetUtils.canUserModifyWidgets(roomId);
let streamAudioStreamButton;
if (getConfigLivestreamUrl() && WidgetType.JITSI.matches(app.type)) {
let streamAudioStreamButton: JSX.Element | undefined;
if (roomId && getConfigLivestreamUrl() && WidgetType.JITSI.matches(app.type)) {
const onStreamAudioClick = async (): Promise<void> => {
try {
await startJitsiAudioLivestream(widgetMessaging!, roomId);
@ -87,12 +87,12 @@ export const WidgetContextMenu: React.FC<IProps> = ({
const pinnedWidgets = room ? WidgetLayoutStore.instance.getContainerWidgets(room, Container.Top) : [];
const widgetIndex = pinnedWidgets.findIndex((widget) => widget.id === app.id);
let editButton;
let editButton: JSX.Element | undefined;
if (canModify && WidgetUtils.isManagedByManager(app)) {
const _onEditClick = (): void => {
if (onEditClick) {
onEditClick();
} else {
} else if (room) {
WidgetUtils.editWidget(room, app);
}
onFinished();
@ -101,7 +101,7 @@ export const WidgetContextMenu: React.FC<IProps> = ({
editButton = <IconizedContextMenuOption onClick={_onEditClick} label={_t("Edit")} />;
}
let snapshotButton;
let snapshotButton: JSX.Element | undefined;
const screenshotsEnabled = SettingsStore.getValue("enableWidgetScreenshots");
if (screenshotsEnabled && widgetMessaging?.hasCapability(MatrixCapabilities.Screenshots)) {
const onSnapshotClick = (): void => {
@ -122,12 +122,12 @@ export const WidgetContextMenu: React.FC<IProps> = ({
snapshotButton = <IconizedContextMenuOption onClick={onSnapshotClick} label={_t("Take a picture")} />;
}
let deleteButton;
let deleteButton: JSX.Element | undefined;
if (onDeleteClick || canModify) {
const _onDeleteClick = (): void => {
if (onDeleteClick) {
onDeleteClick();
} else {
} else if (roomId) {
// Show delete confirmation dialog
Modal.createDialog(QuestionDialog, {
title: _t("Delete Widget"),
@ -159,7 +159,7 @@ export const WidgetContextMenu: React.FC<IProps> = ({
app.creatorUserId === cli.getUserId();
const isLocalWidget = WidgetType.JITSI.matches(app.type);
let revokeButton;
let revokeButton: JSX.Element | undefined;
if (!userWidget && !isLocalWidget && isAllowedWidget) {
const opts: ApprovalOpts = { approved: undefined };
ModuleRunner.instance.invoke(WidgetLifecycle.PreLoadRequest, opts, new ElementWidget(app));
@ -182,7 +182,7 @@ export const WidgetContextMenu: React.FC<IProps> = ({
}
}
let moveLeftButton;
let moveLeftButton: JSX.Element | undefined;
if (showUnpin && widgetIndex > 0) {
const onClick = (): void => {
if (!room) throw new Error("room must be defined");
@ -193,7 +193,7 @@ export const WidgetContextMenu: React.FC<IProps> = ({
moveLeftButton = <IconizedContextMenuOption onClick={onClick} label={_t("Move left")} />;
}
let moveRightButton;
let moveRightButton: JSX.Element | undefined;
if (showUnpin && widgetIndex < pinnedWidgets.length - 1) {
const onClick = (): void => {
if (!room) throw new Error("room must be defined");