mirror of
https://github.com/vector-im/element-web.git
synced 2024-11-15 20:54:59 +08:00
Conform more code to strictNullChecks
(#10383
* Update matrix-widget-api * Conform more code to `strictNullChecks` * Iterate
This commit is contained in:
parent
aae9dfbb7d
commit
9c816bb720
@ -97,7 +97,7 @@
|
||||
"matrix-encrypt-attachment": "^1.0.3",
|
||||
"matrix-events-sdk": "0.0.1",
|
||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
|
||||
"matrix-widget-api": "^1.1.1",
|
||||
"matrix-widget-api": "^1.2.0",
|
||||
"minimist": "^1.2.5",
|
||||
"opus-recorder": "^8.0.3",
|
||||
"pako": "^2.0.3",
|
||||
|
@ -259,7 +259,7 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||
isItemCollapsed: (domNode) => {
|
||||
return domNode.classList.contains("mx_LeftPanel_minimized");
|
||||
},
|
||||
handler: this.resizeHandler.current,
|
||||
handler: this.resizeHandler.current ?? undefined,
|
||||
};
|
||||
const resizer = new Resizer(this._resizeContainer.current, CollapseDistributor, collapseConfig);
|
||||
resizer.setClassNames({
|
||||
|
@ -90,7 +90,7 @@ export default class RightPanel extends React.Component<IProps, IState> {
|
||||
}
|
||||
|
||||
public static getDerivedStateFromProps(props: IProps): Partial<IState> {
|
||||
let currentCard: IRightPanelCard;
|
||||
let currentCard: IRightPanelCard | undefined;
|
||||
if (props.room) {
|
||||
currentCard = RightPanelStore.instance.currentCardForRoom(props.room.roomId);
|
||||
}
|
||||
@ -111,7 +111,7 @@ export default class RightPanel extends React.Component<IProps, IState> {
|
||||
this.delayedUpdate();
|
||||
} else if (
|
||||
this.state.phase === RightPanelPhases.RoomMemberInfo &&
|
||||
member.userId === this.state.cardState.member.userId
|
||||
member.userId === this.state.cardState.member?.userId
|
||||
) {
|
||||
// refresh the member info (e.g. new power level)
|
||||
this.delayedUpdate();
|
||||
@ -136,7 +136,7 @@ export default class RightPanel extends React.Component<IProps, IState> {
|
||||
});
|
||||
} else if (
|
||||
this.state.phase === RightPanelPhases.EncryptionPanel &&
|
||||
this.state.cardState.verificationRequest?.pending
|
||||
this.state.cardState?.verificationRequest?.pending
|
||||
) {
|
||||
// When the user clicks close on the encryption panel cancel the pending request first if any
|
||||
this.state.cardState.verificationRequest.cancel();
|
||||
@ -171,8 +171,8 @@ export default class RightPanel extends React.Component<IProps, IState> {
|
||||
case RightPanelPhases.SpaceMemberList:
|
||||
card = (
|
||||
<MemberList
|
||||
roomId={cardState.spaceId ? cardState.spaceId : roomId}
|
||||
key={cardState.spaceId ? cardState.spaceId : roomId}
|
||||
roomId={cardState?.spaceId ?? roomId}
|
||||
key={cardState?.spaceId ?? roomId}
|
||||
onClose={this.onClose}
|
||||
searchQuery={this.state.searchQuery}
|
||||
onSearchQueryChanged={this.onSearchQueryChanged}
|
||||
@ -183,23 +183,23 @@ export default class RightPanel extends React.Component<IProps, IState> {
|
||||
case RightPanelPhases.RoomMemberInfo:
|
||||
case RightPanelPhases.SpaceMemberInfo:
|
||||
case RightPanelPhases.EncryptionPanel: {
|
||||
const roomMember = cardState.member instanceof RoomMember ? cardState.member : undefined;
|
||||
const roomMember = cardState?.member instanceof RoomMember ? cardState.member : undefined;
|
||||
card = (
|
||||
<UserInfo
|
||||
user={cardState.member}
|
||||
user={cardState?.member}
|
||||
room={this.context.getRoom(roomMember?.roomId) ?? this.props.room}
|
||||
key={roomId || cardState.member.userId}
|
||||
key={roomId ?? cardState?.member?.userId}
|
||||
onClose={this.onClose}
|
||||
phase={phase}
|
||||
verificationRequest={cardState.verificationRequest}
|
||||
verificationRequestPromise={cardState.verificationRequestPromise}
|
||||
verificationRequest={cardState?.verificationRequest}
|
||||
verificationRequestPromise={cardState?.verificationRequestPromise}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
}
|
||||
case RightPanelPhases.Room3pidMemberInfo:
|
||||
case RightPanelPhases.Space3pidMemberInfo:
|
||||
card = <ThirdPartyMemberInfo event={cardState.memberInfoEvent} key={roomId} />;
|
||||
card = <ThirdPartyMemberInfo event={cardState?.memberInfoEvent} key={roomId} />;
|
||||
break;
|
||||
|
||||
case RightPanelPhases.NotificationPanel:
|
||||
@ -240,10 +240,10 @@ export default class RightPanel extends React.Component<IProps, IState> {
|
||||
room={this.props.room}
|
||||
resizeNotifier={this.props.resizeNotifier}
|
||||
onClose={this.onClose}
|
||||
mxEvent={cardState.threadHeadEvent}
|
||||
initialEvent={cardState.initialEvent}
|
||||
isInitialEventHighlighted={cardState.isInitialEventHighlighted}
|
||||
initialEventScrollIntoView={cardState.initialEventScrollIntoView}
|
||||
mxEvent={cardState?.threadHeadEvent}
|
||||
initialEvent={cardState?.initialEvent}
|
||||
isInitialEventHighlighted={cardState?.isInitialEventHighlighted}
|
||||
initialEventScrollIntoView={cardState?.initialEventScrollIntoView}
|
||||
permalinkCreator={this.props.permalinkCreator}
|
||||
e2eStatus={this.props.e2eStatus}
|
||||
/>
|
||||
@ -273,7 +273,7 @@ export default class RightPanel extends React.Component<IProps, IState> {
|
||||
break;
|
||||
|
||||
case RightPanelPhases.Widget:
|
||||
card = <WidgetCard room={this.props.room} widgetId={cardState.widgetId} onClose={this.onClose} />;
|
||||
card = <WidgetCard room={this.props.room} widgetId={cardState?.widgetId} onClose={this.onClose} />;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@ if (DEBUG) {
|
||||
}
|
||||
|
||||
interface IRoomProps {
|
||||
threepidInvite: IThreepidInvite;
|
||||
threepidInvite?: IThreepidInvite;
|
||||
oobData?: IOOBData;
|
||||
|
||||
resizeNotifier: ResizeNotifier;
|
||||
@ -606,11 +606,11 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
return;
|
||||
}
|
||||
|
||||
const roomId = this.context.roomViewStore.getRoomId();
|
||||
const room = this.context.client.getRoom(roomId);
|
||||
const roomId = this.context.roomViewStore.getRoomId() ?? null;
|
||||
const room = this.context.client?.getRoom(roomId ?? undefined) ?? undefined;
|
||||
|
||||
const newState: Partial<IRoomState> = {
|
||||
roomId,
|
||||
roomId: roomId ?? undefined,
|
||||
roomAlias: this.context.roomViewStore.getRoomAlias(),
|
||||
roomLoading: this.context.roomViewStore.isRoomLoading(),
|
||||
roomLoadError: this.context.roomViewStore.getRoomLoadError(),
|
||||
@ -624,8 +624,8 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
showAvatarChanges: SettingsStore.getValue("showAvatarChanges", roomId),
|
||||
showDisplaynameChanges: SettingsStore.getValue("showDisplaynameChanges", roomId),
|
||||
wasContextSwitch: this.context.roomViewStore.getWasContextSwitch(),
|
||||
mainSplitContentType: room === null ? undefined : this.getMainSplitContentType(room),
|
||||
initialEventId: null, // default to clearing this, will get set later in the method if needed
|
||||
mainSplitContentType: room ? this.getMainSplitContentType(room) : undefined,
|
||||
initialEventId: undefined, // default to clearing this, will get set later in the method if needed
|
||||
showRightPanel: this.context.rightPanelStore.isOpenForRoom(roomId),
|
||||
activeCall: CallStore.instance.getActiveCall(roomId),
|
||||
};
|
||||
@ -655,12 +655,11 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
// The rest will be lost for now, until the aggregation API on the server
|
||||
// becomes available to fetch a whole thread
|
||||
if (!initialEvent) {
|
||||
initialEvent = await fetchInitialEvent(this.context.client, roomId, initialEventId);
|
||||
initialEvent = (await fetchInitialEvent(this.context.client, roomId, initialEventId)) ?? undefined;
|
||||
}
|
||||
|
||||
// If we have an initial event, we want to reset the event pixel offset to ensure it ends up
|
||||
// visible
|
||||
newState.initialEventPixelOffset = null;
|
||||
// If we have an initial event, we want to reset the event pixel offset to ensure it ends up visible
|
||||
newState.initialEventPixelOffset = undefined;
|
||||
|
||||
const thread = initialEvent?.getThread();
|
||||
if (thread && !initialEvent?.isThreadRoot) {
|
||||
@ -709,7 +708,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
|
||||
if (!initial && this.state.shouldPeek && !newState.shouldPeek) {
|
||||
// Stop peeking because we have joined this room now
|
||||
this.context.client.stopPeeking();
|
||||
this.context.client?.stopPeeking();
|
||||
}
|
||||
|
||||
// Temporary logging to diagnose https://github.com/vector-im/element-web/issues/4307
|
||||
@ -825,7 +824,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
}
|
||||
}
|
||||
|
||||
private setupRoom(room: Room, roomId: string, joining: boolean, shouldPeek: boolean): void {
|
||||
private setupRoom(room: Room | undefined, roomId: string | undefined, joining: boolean, shouldPeek: boolean): void {
|
||||
// if this is an unknown room then we're in one of three states:
|
||||
// - This is a room we can peek into (search engine) (we can /peek)
|
||||
// - This is a room we can publicly join or were invited to. (we can /join)
|
||||
@ -1504,7 +1503,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
|
||||
private updateDMState(): void {
|
||||
const room = this.state.room;
|
||||
if (room.getMyMembership() != "join") {
|
||||
if (room?.getMyMembership() !== "join") {
|
||||
return;
|
||||
}
|
||||
const dmInviter = room.getDMInviter();
|
||||
@ -1564,7 +1563,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
);
|
||||
|
||||
private onMessageListScroll = (): void => {
|
||||
if (this.messagePanel.isAtEndOfLiveTimeline()) {
|
||||
if (this.messagePanel?.isAtEndOfLiveTimeline()) {
|
||||
this.setState({
|
||||
numUnreadMessages: 0,
|
||||
atEndOfLiveTimeline: true,
|
||||
@ -1740,7 +1739,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
this.setState(
|
||||
{
|
||||
timelineRenderingType: TimelineRenderingType.Room,
|
||||
search: null,
|
||||
search: undefined,
|
||||
},
|
||||
resolve,
|
||||
);
|
||||
@ -1760,20 +1759,20 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
});
|
||||
} else {
|
||||
// Otherwise we have to jump manually
|
||||
this.messagePanel.jumpToLiveTimeline();
|
||||
this.messagePanel?.jumpToLiveTimeline();
|
||||
dis.fire(Action.FocusSendMessageComposer);
|
||||
}
|
||||
};
|
||||
|
||||
// jump up to wherever our read marker is
|
||||
private jumpToReadMarker = (): void => {
|
||||
this.messagePanel.jumpToReadMarker();
|
||||
this.messagePanel?.jumpToReadMarker();
|
||||
};
|
||||
|
||||
// update the read marker to match the read-receipt
|
||||
private forgetReadMarker = (ev: ButtonEvent): void => {
|
||||
ev.stopPropagation();
|
||||
this.messagePanel.forgetReadMarker();
|
||||
this.messagePanel?.forgetReadMarker();
|
||||
};
|
||||
|
||||
// decide whether or not the top 'unread messages' bar should be shown
|
||||
@ -1791,7 +1790,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
// get the current scroll position of the room, so that it can be
|
||||
// restored when we switch back to it.
|
||||
//
|
||||
private getScrollState(): ScrollState {
|
||||
private getScrollState(): ScrollState | null {
|
||||
const messagePanel = this.messagePanel;
|
||||
if (!messagePanel) return null;
|
||||
|
||||
@ -1845,7 +1844,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
* We pass it down to the scroll panel.
|
||||
*/
|
||||
public handleScrollKey = (ev: React.KeyboardEvent | KeyboardEvent): void => {
|
||||
let panel: ScrollPanel | TimelinePanel;
|
||||
let panel: ScrollPanel | TimelinePanel | undefined;
|
||||
if (this.searchResultsPanel.current) {
|
||||
panel = this.searchResultsPanel.current;
|
||||
} else if (this.messagePanel) {
|
||||
@ -1858,7 +1857,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
/**
|
||||
* get any current call for this room
|
||||
*/
|
||||
private getCallForRoom(): MatrixCall {
|
||||
private getCallForRoom(): MatrixCall | null {
|
||||
if (!this.state.room) {
|
||||
return null;
|
||||
}
|
||||
@ -1920,7 +1919,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
}
|
||||
|
||||
private renderLocalRoomCreateLoader(localRoom: LocalRoom): ReactElement {
|
||||
const names = this.state.room.getDefaultRoomName(this.context.client.getUserId());
|
||||
const names = this.state.room.getDefaultRoomName(this.context.client.getSafeUserId());
|
||||
return (
|
||||
<RoomContext.Provider value={this.state}>
|
||||
<LocalRoomCreateLoader localRoom={localRoom} names={names} resizeNotifier={this.props.resizeNotifier} />
|
||||
@ -1992,7 +1991,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
let inviterName = undefined;
|
||||
let inviterName: string | undefined;
|
||||
if (this.props.oobData) {
|
||||
inviterName = this.props.oobData.inviterName;
|
||||
}
|
||||
@ -2058,12 +2057,12 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
</ErrorBoundary>
|
||||
);
|
||||
} else {
|
||||
const myUserId = this.context.client.credentials.userId;
|
||||
const myUserId = this.context.client.getSafeUserId();
|
||||
const myMember = this.state.room.getMember(myUserId);
|
||||
const inviteEvent = myMember ? myMember.events.member : null;
|
||||
let inviterName = _t("Unknown");
|
||||
if (inviteEvent) {
|
||||
inviterName = inviteEvent.sender ? inviteEvent.sender.name : inviteEvent.getSender();
|
||||
inviterName = inviteEvent.sender?.name ?? inviteEvent.getSender();
|
||||
}
|
||||
|
||||
// We deliberately don't try to peek into invites, even if we have permission to peek
|
||||
@ -2140,7 +2139,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
const showRoomUpgradeBar =
|
||||
roomVersionRecommendation &&
|
||||
roomVersionRecommendation.needsUpgrade &&
|
||||
this.state.room.userMayUpgradeRoom(this.context.client.credentials.userId);
|
||||
this.state.room.userMayUpgradeRoom(this.context.client.getSafeUserId());
|
||||
|
||||
const hiddenHighlightCount = this.getHiddenHighlightCount();
|
||||
|
||||
@ -2160,7 +2159,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
} else if (myMembership !== "join") {
|
||||
// We do have a room object for this room, but we're not currently in it.
|
||||
// We may have a 3rd party invite to it.
|
||||
let inviterName = undefined;
|
||||
let inviterName: string | undefined;
|
||||
if (this.props.oobData) {
|
||||
inviterName = this.props.oobData.inviterName;
|
||||
}
|
||||
@ -2207,6 +2206,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
space={this.state.room}
|
||||
justCreatedOpts={this.props.justCreatedOpts}
|
||||
resizeNotifier={this.props.resizeNotifier}
|
||||
permalinkCreator={this.permalinkCreator}
|
||||
onJoinButtonClicked={this.onJoinButtonClicked}
|
||||
onRejectButtonClicked={
|
||||
this.props.threepidInvite
|
||||
@ -2220,7 +2220,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
const auxPanel = (
|
||||
<AuxPanel
|
||||
room={this.state.room}
|
||||
userId={this.context.client.credentials.userId}
|
||||
userId={this.context.client.getSafeUserId()}
|
||||
showApps={this.state.showApps}
|
||||
resizeNotifier={this.props.resizeNotifier}
|
||||
>
|
||||
@ -2330,7 +2330,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
permalinkCreator={this.permalinkCreator}
|
||||
e2eStatus={this.state.e2eStatus}
|
||||
/>
|
||||
) : null;
|
||||
) : undefined;
|
||||
|
||||
const timelineClasses = classNames("mx_RoomView_timeline", {
|
||||
mx_RoomView_timeline_rr_enabled: this.state.showReadReceipts,
|
||||
@ -2344,14 +2344,16 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
const showChatEffects = SettingsStore.getValue("showChatEffects");
|
||||
|
||||
let mainSplitBody: JSX.Element | undefined;
|
||||
let mainSplitContentClassName: string;
|
||||
let mainSplitContentClassName: string | undefined;
|
||||
// Decide what to show in the main split
|
||||
switch (this.state.mainSplitContentType) {
|
||||
case MainSplitContentType.Timeline:
|
||||
mainSplitContentClassName = "mx_MainSplit_timeline";
|
||||
mainSplitBody = (
|
||||
<>
|
||||
<Measured sensor={this.roomViewBody.current} onMeasurement={this.onMeasurement} />
|
||||
{this.roomViewBody.current && (
|
||||
<Measured sensor={this.roomViewBody.current} onMeasurement={this.onMeasurement} />
|
||||
)}
|
||||
{auxPanel}
|
||||
<div className={timelineClasses}>
|
||||
<FileDropTarget parent={this.roomView.current} onFileDrop={this.onFileDrop} />
|
||||
@ -2372,7 +2374,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
<>
|
||||
<AppsDrawer
|
||||
room={this.state.room}
|
||||
userId={this.context.client.credentials.userId}
|
||||
userId={this.context.client.getSafeUserId()}
|
||||
resizeNotifier={this.props.resizeNotifier}
|
||||
showApps={true}
|
||||
/>
|
||||
@ -2426,7 +2428,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
onAppsClick = null;
|
||||
onForgetClick = null;
|
||||
onSearchClick = null;
|
||||
if (this.state.room.canInvite(this.context.client.credentials.userId)) {
|
||||
if (this.state.room.canInvite(this.context.client.getSafeUserId())) {
|
||||
onInviteClick = this.onInviteClick;
|
||||
}
|
||||
viewingCall = true;
|
||||
|
@ -18,7 +18,7 @@ import { EventType, RoomType } from "matrix-js-sdk/src/@types/event";
|
||||
import { JoinRule, Preset } from "matrix-js-sdk/src/@types/partials";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { Room, RoomEvent } from "matrix-js-sdk/src/models/room";
|
||||
import React, { RefObject, useCallback, useContext, useRef, useState } from "react";
|
||||
import React, { MutableRefObject, useCallback, useContext, useRef, useState } from "react";
|
||||
|
||||
import MatrixClientContext from "../../contexts/MatrixClientContext";
|
||||
import createRoom, { IOpts } from "../../createRoom";
|
||||
@ -77,11 +77,13 @@ import { ChevronFace, ContextMenuButton, useContextMenu } from "./ContextMenu";
|
||||
import MainSplit from "./MainSplit";
|
||||
import RightPanel from "./RightPanel";
|
||||
import SpaceHierarchy, { showRoom } from "./SpaceHierarchy";
|
||||
import { RoomPermalinkCreator } from "../../utils/permalinks/Permalinks";
|
||||
|
||||
interface IProps {
|
||||
space: Room;
|
||||
justCreatedOpts?: IOpts;
|
||||
resizeNotifier: ResizeNotifier;
|
||||
permalinkCreator: RoomPermalinkCreator;
|
||||
onJoinButtonClicked(): void;
|
||||
onRejectButtonClicked(): void;
|
||||
}
|
||||
@ -112,7 +114,7 @@ const SpaceLandingAddButton: React.FC<{ space: Room }> = ({ space }) => {
|
||||
|
||||
let contextMenu: JSX.Element | null = null;
|
||||
if (menuDisplayed) {
|
||||
const rect = handle.current.getBoundingClientRect();
|
||||
const rect = handle.current!.getBoundingClientRect();
|
||||
contextMenu = (
|
||||
<IconizedContextMenu
|
||||
left={rect.left + window.scrollX + 0}
|
||||
@ -213,7 +215,7 @@ const SpaceLandingAddButton: React.FC<{ space: Room }> = ({ space }) => {
|
||||
const SpaceLanding: React.FC<{ space: Room }> = ({ space }) => {
|
||||
const cli = useContext(MatrixClientContext);
|
||||
const myMembership = useMyRoomMembership(space);
|
||||
const userId = cli.getUserId();
|
||||
const userId = cli.getSafeUserId();
|
||||
|
||||
const storeIsShowingSpaceMembers = useCallback(
|
||||
() =>
|
||||
@ -458,7 +460,7 @@ const SpaceSetupPublicShare: React.FC<ISpaceSetupPublicShareProps> = ({
|
||||
|
||||
const SpaceSetupPrivateScope: React.FC<{
|
||||
space: Room;
|
||||
justCreatedOpts: IOpts;
|
||||
justCreatedOpts?: IOpts;
|
||||
onFinished(createRooms: boolean): void;
|
||||
}> = ({ space, justCreatedOpts, onFinished }) => {
|
||||
return (
|
||||
@ -509,7 +511,7 @@ const SpaceSetupPrivateInvite: React.FC<{
|
||||
const [busy, setBusy] = useState(false);
|
||||
const [error, setError] = useState("");
|
||||
const numFields = 3;
|
||||
const fieldRefs: RefObject<Field>[] = [useRef(), useRef(), useRef()];
|
||||
const fieldRefs: MutableRefObject<Field | undefined>[] = [useRef(), useRef(), useRef()];
|
||||
const [emailAddresses, setEmailAddress] = useStateArray(numFields, "");
|
||||
const fields = new Array(numFields).fill(0).map((x, i) => {
|
||||
const name = "emailAddress" + i;
|
||||
@ -647,7 +649,7 @@ export default class SpaceRoomView extends React.PureComponent<IProps, IState> {
|
||||
|
||||
if (showSetup) {
|
||||
phase =
|
||||
this.props.justCreatedOpts.createOpts.preset === Preset.PublicChat
|
||||
this.props.justCreatedOpts!.createOpts?.preset === Preset.PublicChat
|
||||
? Phase.PublicCreateRooms
|
||||
: Phase.PrivateScope;
|
||||
}
|
||||
@ -817,8 +819,12 @@ export default class SpaceRoomView extends React.PureComponent<IProps, IState> {
|
||||
public render(): React.ReactNode {
|
||||
const rightPanel =
|
||||
this.state.showRightPanel && this.state.phase === Phase.Landing ? (
|
||||
<RightPanel room={this.props.space} resizeNotifier={this.props.resizeNotifier} />
|
||||
) : null;
|
||||
<RightPanel
|
||||
room={this.props.space}
|
||||
resizeNotifier={this.props.resizeNotifier}
|
||||
permalinkCreator={this.props.permalinkCreator}
|
||||
/>
|
||||
) : undefined;
|
||||
|
||||
return (
|
||||
<main className="mx_SpaceRoomView">
|
||||
|
@ -103,11 +103,11 @@ export const usePublicRoomDirectory = (): {
|
||||
if (query || roomTypes) {
|
||||
opts.filter = {
|
||||
generic_search_term: query,
|
||||
room_types: (await MatrixClientPeg.get().doesServerSupportUnstableFeature(
|
||||
"org.matrix.msc3827.stable",
|
||||
))
|
||||
? Array.from<RoomType | null>(roomTypes)
|
||||
: undefined,
|
||||
room_types:
|
||||
roomTypes &&
|
||||
(await MatrixClientPeg.get().doesServerSupportUnstableFeature("org.matrix.msc3827.stable"))
|
||||
? Array.from<RoomType | null>(roomTypes)
|
||||
: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -189,8 +189,11 @@ export default class DMRoomMap {
|
||||
if (!this.roomToUser) return {}; // No rooms means no map.
|
||||
return Object.keys(this.roomToUser)
|
||||
.map((r) => ({ userId: this.getUserIdForRoomId(r), room: this.matrixClient.getRoom(r) }))
|
||||
.filter((r) => r.userId && r.room && r.room.getInvitedAndJoinedMemberCount() === 2)
|
||||
.reduce((obj, r) => (obj[r.userId] = r.room) && obj, {} as Record<string, Room>);
|
||||
.filter((r) => r.userId && r.room?.getInvitedAndJoinedMemberCount() === 2)
|
||||
.reduce((obj, r) => {
|
||||
obj[r.userId] = r.room;
|
||||
return obj;
|
||||
}, {} as Record<string, Room>);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -141,8 +141,8 @@ export default class MultiInviter {
|
||||
return this.completionStates[addr];
|
||||
}
|
||||
|
||||
public getErrorText(addr: string): string {
|
||||
return this.errors[addr] ? this.errors[addr].errorText : null;
|
||||
public getErrorText(addr: string): string | null {
|
||||
return this.errors[addr]?.errorText ?? null;
|
||||
}
|
||||
|
||||
private async inviteToRoom(roomId: string, addr: string, ignoreProfile = false): Promise<{}> {
|
||||
|
@ -37,7 +37,7 @@ export function abbreviateUrl(u: string): string {
|
||||
return u;
|
||||
}
|
||||
|
||||
export function unabbreviateUrl(u: string): string {
|
||||
export function unabbreviateUrl(u?: string): string {
|
||||
if (!u) return "";
|
||||
|
||||
let longUrl = u;
|
||||
|
@ -450,7 +450,7 @@ export default class WidgetUtils {
|
||||
oobRoomName?: string,
|
||||
): Promise<void> {
|
||||
const domain = Jitsi.getInstance().preferredDomain;
|
||||
const auth = await Jitsi.getInstance().getJitsiAuth();
|
||||
const auth = (await Jitsi.getInstance().getJitsiAuth()) ?? undefined;
|
||||
const widgetId = randomString(24); // Must be globally unique
|
||||
|
||||
let confId;
|
||||
|
@ -29,14 +29,11 @@ import { findDMForUser } from "./findDMForUser";
|
||||
*/
|
||||
export function findDMRoom(client: MatrixClient, targets: Member[]): Room | null {
|
||||
const targetIds = targets.map((t) => t.userId);
|
||||
let existingRoom: Room | undefined;
|
||||
let existingRoom: Room | null;
|
||||
if (targetIds.length === 1) {
|
||||
existingRoom = findDMForUser(client, targetIds[0]);
|
||||
existingRoom = findDMForUser(client, targetIds[0]) ?? null;
|
||||
} else {
|
||||
existingRoom = DMRoomMap.shared().getDMRoomForIdentifiers(targetIds);
|
||||
}
|
||||
if (existingRoom) {
|
||||
return existingRoom;
|
||||
}
|
||||
return null;
|
||||
return existingRoom;
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ export default abstract class Exporter {
|
||||
let limit: number;
|
||||
switch (this.exportType) {
|
||||
case ExportType.LastNMessages:
|
||||
limit = this.exportOptions.numberOfMessages;
|
||||
limit = this.exportOptions.numberOfMessages!;
|
||||
break;
|
||||
case ExportType.Timeline:
|
||||
limit = 40;
|
||||
@ -221,11 +221,11 @@ export default abstract class Exporter {
|
||||
return events;
|
||||
}
|
||||
|
||||
protected async getMediaBlob(event: MatrixEvent): Promise<Blob> {
|
||||
let blob: Blob;
|
||||
protected async getMediaBlob(event: MatrixEvent): Promise<Blob | undefined> {
|
||||
let blob: Blob | undefined;
|
||||
try {
|
||||
const isEncrypted = event.isEncrypted();
|
||||
const content: IMediaEventContent = event.getContent();
|
||||
const content = event.getContent<IMediaEventContent>();
|
||||
const shouldDecrypt = isEncrypted && content.hasOwnProperty("file") && event.getType() !== "m.sticker";
|
||||
if (shouldDecrypt) {
|
||||
blob = await decryptFile(content.file);
|
||||
|
@ -45,7 +45,7 @@ export default class JSONExporter extends Exporter {
|
||||
protected createJSONString(): string {
|
||||
const exportDate = formatFullDateNoDayNoTime(new Date());
|
||||
const creator = this.room.currentState.getStateEvents(EventType.RoomCreate, "")?.getSender();
|
||||
const creatorName = this.room?.getMember(creator)?.rawDisplayName || creator;
|
||||
const creatorName = (creator && this.room?.getMember(creator)?.rawDisplayName) || creator;
|
||||
const topic = this.room.currentState.getStateEvents(EventType.RoomTopic, "")?.getContent()?.topic || "";
|
||||
const exporter = this.client.getUserId()!;
|
||||
const exporterName = this.room?.getMember(exporter)?.rawDisplayName || exporter;
|
||||
|
@ -19,6 +19,7 @@ import React, { ReactNode } from "react";
|
||||
import { EventStatus } from "matrix-js-sdk/src/models/event-status";
|
||||
import { MatrixEventEvent } from "matrix-js-sdk/src/models/event";
|
||||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
import { MatrixError } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import Modal, { IHandle } from "../Modal";
|
||||
import Spinner from "../components/views/elements/Spinner";
|
||||
@ -87,7 +88,7 @@ export async function leaveRoomBehaviour(roomId: string, retry = true, spinner =
|
||||
),
|
||||
);
|
||||
|
||||
let results: { [roomId: string]: Error & { errcode?: string; message: string; data?: Record<string, any> } } = {};
|
||||
let results: { [roomId: string]: Error | MatrixError | null } = {};
|
||||
if (!leavingAllVersions) {
|
||||
try {
|
||||
await cli.leave(roomId);
|
||||
@ -104,7 +105,9 @@ export async function leaveRoomBehaviour(roomId: string, retry = true, spinner =
|
||||
}
|
||||
|
||||
if (retry) {
|
||||
const limitExceededError = Object.values(results).find((e) => e?.errcode === "M_LIMIT_EXCEEDED");
|
||||
const limitExceededError = Object.values(results).find(
|
||||
(e) => (e as MatrixError)?.errcode === "M_LIMIT_EXCEEDED",
|
||||
) as MatrixError;
|
||||
if (limitExceededError) {
|
||||
await sleep(limitExceededError.data.retry_after_ms ?? 100);
|
||||
return leaveRoomBehaviour(roomId, false, false);
|
||||
@ -117,9 +120,9 @@ export async function leaveRoomBehaviour(roomId: string, retry = true, spinner =
|
||||
if (errors.length > 0) {
|
||||
const messages: ReactNode[] = [];
|
||||
for (const roomErr of errors) {
|
||||
const err = roomErr[1]; // [0] is the roomId
|
||||
const err = roomErr[1] as MatrixError; // [0] is the roomId
|
||||
let message = _t("Unexpected server error trying to leave the room");
|
||||
if (err.errcode && err.message) {
|
||||
if (err?.errcode && err.message) {
|
||||
if (err.errcode === "M_CANNOT_LEAVE_SERVER_NOTICE_ROOM") {
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: _t("Can't leave Server Notices room"),
|
||||
@ -130,7 +133,7 @@ export async function leaveRoomBehaviour(roomId: string, retry = true, spinner =
|
||||
});
|
||||
return;
|
||||
}
|
||||
message = results[roomId].message;
|
||||
message = results[roomId]!.message;
|
||||
}
|
||||
messages.push(message, React.createElement("BR")); // createElement to avoid using a tsx file in utils
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ export const makeMapSiteLink = (coords: GeolocationCoordinates): string => {
|
||||
);
|
||||
};
|
||||
|
||||
export const createMapSiteLinkFromEvent = (event: MatrixEvent): string => {
|
||||
export const createMapSiteLinkFromEvent = (event: MatrixEvent): string | null => {
|
||||
const content = event.getContent();
|
||||
const mLocation = content[M_LOCATION.name];
|
||||
if (mLocation !== undefined) {
|
||||
|
@ -192,7 +192,7 @@ export class RoomPermalinkCreator {
|
||||
isHostInRegex(domain, this.allowedHostsRegexps)
|
||||
);
|
||||
});
|
||||
const maxEntry = allowedEntries.reduce(
|
||||
const maxEntry = allowedEntries.reduce<[string | null, number]>(
|
||||
(max, entry) => {
|
||||
return entry[1] > max[1] ? entry : max;
|
||||
},
|
||||
@ -329,7 +329,7 @@ export function tryTransformEntityToPermalink(entity: string): string | null {
|
||||
if (permalinkParts.roomIdOrAlias) {
|
||||
const eventIdPart = permalinkParts.eventId ? `/${permalinkParts.eventId}` : "";
|
||||
let pl = matrixtoBaseUrl + `/#/${permalinkParts.roomIdOrAlias}${eventIdPart}`;
|
||||
if (permalinkParts.viaServers.length > 0) {
|
||||
if (permalinkParts.viaServers?.length) {
|
||||
pl += new MatrixToPermalinkConstructor().encodeServerCandidates(permalinkParts.viaServers);
|
||||
}
|
||||
return pl;
|
||||
@ -376,7 +376,7 @@ export function tryTransformPermalinkToLocalHref(permalink: string): string {
|
||||
if (permalinkParts.roomIdOrAlias) {
|
||||
const eventIdPart = permalinkParts.eventId ? `/${permalinkParts.eventId}` : "";
|
||||
permalink = `#/room/${permalinkParts.roomIdOrAlias}${eventIdPart}`;
|
||||
if (permalinkParts.viaServers.length > 0) {
|
||||
if (permalinkParts.viaServers?.length) {
|
||||
permalink += new MatrixToPermalinkConstructor().encodeServerCandidates(permalinkParts.viaServers);
|
||||
}
|
||||
} else if (permalinkParts.userId) {
|
||||
@ -475,7 +475,7 @@ function isHostnameIpAddress(hostname: string): boolean {
|
||||
return isIp(hostname);
|
||||
}
|
||||
|
||||
export const calculateRoomVia = (room: Room): string[] => {
|
||||
export const calculateRoomVia = (room: Room): string[] | undefined => {
|
||||
const permalinkCreator = new RoomPermalinkCreator(room);
|
||||
permalinkCreator.load();
|
||||
return permalinkCreator.serverCandidates;
|
||||
|
@ -84,7 +84,7 @@ export const showCreateNewRoom = async (space: Room, type?: RoomType): Promise<b
|
||||
if (shouldCreate) {
|
||||
await createRoom(opts);
|
||||
}
|
||||
return shouldCreate;
|
||||
return !!shouldCreate;
|
||||
};
|
||||
|
||||
export const shouldShowSpaceInvite = (space: Room): boolean =>
|
||||
|
10
yarn.lock
10
yarn.lock
@ -6493,7 +6493,7 @@ matrix-web-i18n@^1.3.0:
|
||||
"@babel/traverse" "^7.18.5"
|
||||
walk "^2.3.15"
|
||||
|
||||
matrix-widget-api@^1.0.0, matrix-widget-api@^1.1.1:
|
||||
matrix-widget-api@^1.0.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/matrix-widget-api/-/matrix-widget-api-1.1.1.tgz#d3fec45033d0cbc14387a38ba92dac4dbb1be962"
|
||||
integrity sha512-gNSgmgSwvOsOcWK9k2+tOhEMYBiIMwX95vMZu0JqY7apkM02xrOzUBuPRProzN8CnbIALH7e3GAhatF6QCNvtA==
|
||||
@ -6501,6 +6501,14 @@ matrix-widget-api@^1.0.0, matrix-widget-api@^1.1.1:
|
||||
"@types/events" "^3.0.0"
|
||||
events "^3.2.0"
|
||||
|
||||
matrix-widget-api@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/matrix-widget-api/-/matrix-widget-api-1.2.0.tgz#ad98796f9879c1db1ef04301f6680ba01b15a6b5"
|
||||
integrity sha512-BkBTREtXjCUM3Kx4UBgDmKoz39w7AXfIjBIC/jISBdcJkg8upFUhpIy+zUrSCIrmfO2Ke8LOsSoFoQkOyhqGxQ==
|
||||
dependencies:
|
||||
"@types/events" "^3.0.0"
|
||||
events "^3.2.0"
|
||||
|
||||
md5@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f"
|
||||
|
Loading…
Reference in New Issue
Block a user