Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 5 additions & 9 deletions src/components/structures/MessagePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ import { logger } from "matrix-js-sdk/src/logger";
import { RoomStateEvent } from "matrix-js-sdk/src/models/room-state";
import { M_BEACON_INFO } from "matrix-js-sdk/src/@types/beacon";
import { isSupportedReceiptType } from "matrix-js-sdk/src/utils";
import { ReadReceipt } from "matrix-js-sdk/src/models/read-receipt";
import { ListenerMap } from "matrix-js-sdk/src/models/typed-event-emitter";

import shouldHideEvent from "../../shouldHideEvent";
import { wantsDateSeparator } from "../../DateUtils";
Expand Down Expand Up @@ -543,7 +541,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
return null;
}

private collectGhostReadMarker = (node: HTMLElement): void => {
private collectGhostReadMarker = (node: HTMLElement | null): void => {
if (node) {
// now the element has appeared, change the style which will trigger the CSS transition
requestAnimationFrame(() => {
Expand Down Expand Up @@ -788,13 +786,13 @@ export default class MessagePanel extends React.Component<IProps, IState> {
continuation={continuation}
isRedacted={mxEv.isRedacted()}
replacingEventId={mxEv.replacingEventId()}
editState={isEditing && this.props.editState}
editState={isEditing ? this.props.editState : undefined}
onHeightChanged={this.onHeightChanged}
readReceipts={readReceipts}
readReceiptMap={this.readReceiptMap}
showUrlPreview={this.props.showUrlPreview}
checkUnmounting={this.isUnmounting}
eventSendStatus={mxEv.getAssociatedStatus()}
eventSendStatus={mxEv.getAssociatedStatus() ?? undefined}
isTwelveHour={this.props.isTwelveHour}
permalinkCreator={this.props.permalinkCreator}
last={last}
Expand Down Expand Up @@ -836,9 +834,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
return null;
}

const receiptDestination: ReadReceipt<string, ListenerMap<string>> = this.context.threadId
? room.getThread(this.context.threadId)
: room;
const receiptDestination = this.context.threadId ? room.getThread(this.context.threadId) : room;

const receipts: IReadReceiptProps[] = [];

Expand Down Expand Up @@ -1215,7 +1211,7 @@ class CreationGrouper extends BaseGrouper {

let summaryText: string;
const roomId = ev.getRoomId();
const creator = ev.sender ? ev.sender.name : ev.getSender();
const creator = ev.sender?.name ?? ev.getSender();
if (DMRoomMap.shared().getUserIdForRoomId(roomId)) {
summaryText = _t("%(creator)s created this DM.", { creator });
} else {
Expand Down
26 changes: 13 additions & 13 deletions src/components/structures/RoomView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {

private roomView = createRef<HTMLElement>();
private searchResultsPanel = createRef<ScrollPanel>();
private messagePanel?: TimelinePanel;
private messagePanel: TimelinePanel | null = null;
private roomViewBody = createRef<HTMLDivElement>();

public static contextType = SDKContext;
Expand Down Expand Up @@ -611,11 +611,11 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {

const newState: Partial<IRoomState> = {
roomId: roomId ?? undefined,
roomAlias: this.context.roomViewStore.getRoomAlias(),
roomAlias: this.context.roomViewStore.getRoomAlias() ?? undefined,
roomLoading: this.context.roomViewStore.isRoomLoading(),
roomLoadError: this.context.roomViewStore.getRoomLoadError(),
roomLoadError: this.context.roomViewStore.getRoomLoadError() ?? undefined,
joining: this.context.roomViewStore.isJoining(),
replyToEvent: this.context.roomViewStore.getQuotingEvent(),
replyToEvent: this.context.roomViewStore.getQuotingEvent() ?? undefined,
// we should only peek once we have a ready client
shouldPeek: this.state.matrixClientIsReady && this.context.roomViewStore.shouldPeek(),
showReadReceipts: SettingsStore.getValue("showReadReceipts", roomId),
Expand Down Expand Up @@ -654,7 +654,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
// and the root event.
// The rest will be lost for now, until the aggregation API on the server
// becomes available to fetch a whole thread
if (!initialEvent) {
if (!initialEvent && this.context.client) {
initialEvent = (await fetchInitialEvent(this.context.client, roomId, initialEventId)) ?? undefined;
}

Expand Down Expand Up @@ -848,7 +848,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
isPeeking: true, // this will change to false if peeking fails
});
this.context.client
.peekInRoom(roomId)
?.peekInRoom(roomId)
.then((room) => {
if (this.unmounted) {
return;
Expand Down Expand Up @@ -883,7 +883,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
});
} else if (room) {
// Stop peeking because we have joined this room previously
this.context.client.stopPeeking();
this.context.client?.stopPeeking();
this.setState({ isPeeking: false });
}
}
Expand All @@ -909,9 +909,9 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
this.onRoomViewStoreUpdate(true);

const call = this.getCallForRoom();
const callState = call ? call.state : null;
const callState = call?.state;
this.setState({
callState: callState,
callState,
});

this.context.legacyCallHandler.on(LegacyCallHandlerEvent.CallState, this.onCallState);
Expand Down Expand Up @@ -959,7 +959,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
}

if (this.state.shouldPeek) {
this.context.client.stopPeeking();
this.context.client?.stopPeeking();
}

// stop tracking room changes to format permalinks
Expand Down Expand Up @@ -1010,7 +1010,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {

if (this.viewsLocalRoom) {
// clean up if this was a local room
this.context.client.store.removeRoom(this.state.room.roomId);
this.context.client?.store.removeRoom(this.state.room.roomId);
}
}

Expand Down Expand Up @@ -1469,7 +1469,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {

private updatePermissions(room: Room): void {
if (room) {
const me = this.context.client.getUserId();
const me = this.context.client.getSafeUserId();
const canReact =
room.getMyMembership() === "join" && room.currentState.maySendEvent(EventType.Reaction, me);
const canSendMessages = room.maySendMessage();
Expand Down Expand Up @@ -1866,7 +1866,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {

// this has to be a proper method rather than an unnamed function,
// otherwise react calls it with null on each update.
private gatherTimelinePanelRef = (r?: TimelinePanel): void => {
private gatherTimelinePanelRef = (r: TimelinePanel | null): void => {
this.messagePanel = r;
};

Expand Down
14 changes: 8 additions & 6 deletions src/components/structures/ThreadView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export default class ThreadView extends React.Component<IProps, IState> {
if (payload.event && !payload.event.getThread()) return;
this.setState(
{
editState: payload.event ? new EditorStateTransfer(payload.event) : null,
editState: payload.event ? new EditorStateTransfer(payload.event) : undefined,
},
() => {
if (payload.event) {
Expand Down Expand Up @@ -213,9 +213,11 @@ export default class ThreadView extends React.Component<IProps, IState> {
};

private get threadLastReply(): MatrixEvent | undefined {
return this.state.thread?.lastReply((ev: MatrixEvent) => {
return ev.isRelation(THREAD_RELATION_TYPE.name) && !ev.status;
});
return (
this.state.thread?.lastReply((ev: MatrixEvent) => {
return ev.isRelation(THREAD_RELATION_TYPE.name) && !ev.status;
}) ?? undefined
);
}

private updateThread = (thread?: Thread): void => {
Expand Down Expand Up @@ -245,7 +247,7 @@ export default class ThreadView extends React.Component<IProps, IState> {

private setupThreadListeners(thread?: Thread | undefined, oldThread?: Thread | undefined): void {
if (oldThread) {
this.state.thread.off(ThreadEvent.NewReply, this.updateThreadRelation);
this.state.thread?.off(ThreadEvent.NewReply, this.updateThreadRelation);
this.props.room.off(RoomEvent.LocalEchoUpdated, this.updateThreadRelation);
}
if (thread) {
Expand Down Expand Up @@ -344,7 +346,7 @@ export default class ThreadView extends React.Component<IProps, IState> {
};

public render(): React.ReactNode {
const highlightedEventId = this.props.isInitialEventHighlighted ? this.props.initialEvent?.getId() : null;
const highlightedEventId = this.props.isInitialEventHighlighted ? this.props.initialEvent?.getId() : undefined;

const threadRelation = this.threadRelation;

Expand Down
2 changes: 1 addition & 1 deletion src/components/structures/TimelinePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ interface IProps {
// representing. This may or may not have a room, depending on what it's
// a timeline representing. If it has a room, we maintain RRs etc for
// that room.
timelineSet?: EventTimelineSet;
timelineSet: EventTimelineSet;
// overlay events from a second timelineset on the main timeline
// added to support virtual rooms
// events from the overlay timeline set will be added by localTimestamp
Expand Down
1 change: 1 addition & 0 deletions src/components/views/dialogs/BetaFeedbackDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ interface IProps {

const BetaFeedbackDialog: React.FC<IProps> = ({ featureId, onFinished }) => {
const info = SettingsStore.getBetaInfo(featureId);
if (!info) return null;

return (
<GenericFeatureFeedbackDialog
Expand Down
4 changes: 2 additions & 2 deletions src/components/views/dialogs/BulkRedactDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const BulkRedactDialog: React.FC<Props> = (props) => {
const { matrixClient: cli, room, member, onFinished } = props;
const [keepStateEvents, setKeepStateEvents] = useState(true);

let timeline = room.getLiveTimeline();
let timeline: EventTimeline | null = room.getLiveTimeline();
let eventsToRedact: MatrixEvent[] = [];
while (timeline) {
eventsToRedact = [
Expand Down Expand Up @@ -93,7 +93,7 @@ const BulkRedactDialog: React.FC<Props> = (props) => {
await Promise.all(
eventsToRedact.reverse().map(async (event): Promise<void> => {
try {
await cli.redactEvent(room.roomId, event.getId());
await cli.redactEvent(room.roomId, event.getId()!);
} catch (err) {
// log and swallow errors
logger.error("Could not redact", event.getId());
Expand Down
2 changes: 1 addition & 1 deletion src/components/views/dialogs/DevtoolsDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ interface IProps {
type ToolInfo = [label: string, tool: Tool];

const DevtoolsDialog: React.FC<IProps> = ({ roomId, onFinished }) => {
const [tool, setTool] = useState<ToolInfo>(null);
const [tool, setTool] = useState<ToolInfo | null>(null);

let body: JSX.Element;
let onBack: () => void;
Expand Down
5 changes: 3 additions & 2 deletions src/components/views/dialogs/ForwardDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import { ButtonEvent } from "../elements/AccessibleButton";
import { isLocationEvent } from "../../../utils/EventUtils";
import { isSelfLocation, locationEventGeoUri } from "../../../utils/location";
import { RoomContextDetails } from "../rooms/RoomContextDetails";
import { filterBoolean } from "../../../utils/arrays";

const AVATAR_SIZE = 30;

Expand Down Expand Up @@ -194,7 +195,7 @@ const transformEvent = (event: MatrixEvent): { type: string; content: IContent }
};

const ForwardDialog: React.FC<IProps> = ({ matrixClient: cli, event, permalinkCreator, onFinished }) => {
const userId = cli.getUserId();
const userId = cli.getSafeUserId();
const [profileInfo, setProfileInfo] = useState<any>({});
useEffect(() => {
cli.getProfileInfo(userId).then((info) => setProfileInfo(info));
Expand Down Expand Up @@ -242,7 +243,7 @@ const ForwardDialog: React.FC<IProps> = ({ matrixClient: cli, event, permalinkCr
if (lcQuery) {
rooms = new QueryMatcher<Room>(rooms, {
keys: ["name"],
funcs: [(r) => [r.getCanonicalAlias(), ...r.getAltAliases()].filter(Boolean)],
funcs: [(r) => filterBoolean([r.getCanonicalAlias(), ...r.getAltAliases()])],
shouldMatchWordsOnly: false,
}).match(lcQuery);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const RegistrationEmailPromptDialog: React.FC<IProps> = ({ onFinished }) => {

const onSubmit = async (e: SyntheticEvent): Promise<void> => {
e.preventDefault();
if (!fieldRef.current) return;
if (email) {
const valid = await fieldRef.current.validate({});

Expand Down
2 changes: 1 addition & 1 deletion src/components/views/dialogs/ServerPickerDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export default class ServerPickerDialog extends React.PureComponent<IProps, ISta
return !error;
},
invalid: function ({ error }) {
return error;
return error ?? null;
},
},
],
Expand Down
8 changes: 4 additions & 4 deletions src/components/views/dialogs/TermsDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ interface ITermsDialogProps {
/**
* urls that the user has already agreed to
*/
agreedUrls?: string[];
agreedUrls: string[];

/**
* Called with:
Expand Down Expand Up @@ -127,16 +127,16 @@ export default class TermsDialog extends React.PureComponent<ITermsDialogProps,
};

public render(): React.ReactNode {
const rows = [];
const rows: JSX.Element[] = [];
for (const policiesAndService of this.props.policiesAndServicePairs) {
const parsedBaseUrl = url.parse(policiesAndService.service.baseUrl);

const policyValues = Object.values(policiesAndService.policies);
for (let i = 0; i < policyValues.length; ++i) {
const termDoc = policyValues[i];
const termsLang = pickBestLanguage(Object.keys(termDoc).filter((k) => k !== "version"));
let serviceName;
let summary;
let serviceName: JSX.Element | undefined;
let summary: JSX.Element | undefined;
if (i === 0) {
serviceName = this.nameForServiceType(policiesAndService.service.serviceType, parsedBaseUrl.host);
summary = this.summaryForServiceType(policiesAndService.service.serviceType);
Expand Down
2 changes: 1 addition & 1 deletion src/components/views/dialogs/TextInputDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export default class TextInputDialog extends React.Component<IProps, IState> {
};

private onValidate = async (fieldState: IFieldState): Promise<IValidationResult> => {
const result = await this.props.validator(fieldState);
const result = await this.props.validator!(fieldState);
this.setState({
valid: !!result.valid,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export function RoomResultContextMenus({ room }: Props): JSX.Element {
const [generalMenuPosition, setGeneralMenuPosition] = useState<DOMRect | null>(null);
const [notificationMenuPosition, setNotificationMenuPosition] = useState<DOMRect | null>(null);

let generalMenu: JSX.Element;
let generalMenu: JSX.Element | undefined;
if (generalMenuPosition !== null) {
if (room.isSpaceRoom()) {
generalMenu = (
Expand All @@ -59,7 +59,7 @@ export function RoomResultContextMenus({ room }: Props): JSX.Element {
}
}

let notificationMenu: JSX.Element;
let notificationMenu: JSX.Element | undefined;
if (notificationMenuPosition !== null) {
notificationMenu = (
<RoomNotificationContextMenu
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n

// Sort results by most recent activity

const myUserId = cli.getUserId();
const myUserId = cli.getSafeUserId();
for (const resultArray of Object.values(results)) {
resultArray.sort((a: Result, b: Result) => {
if (isRoomResult(a) || isRoomResult(b)) {
Expand Down
20 changes: 10 additions & 10 deletions src/components/views/elements/EditableText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,17 @@ enum Phases {

interface IProps {
onValueChanged?: (value: string, shouldSubmit: boolean) => void;
initialValue?: string;
label?: string;
placeholder?: string;
className?: string;
initialValue: string;
label: string;
placeholder: string;
className: string;
labelClassName?: string;
placeholderClassName?: string;
placeholderClassName: string;
// Overrides blurToSubmit if true
blurToCancel?: boolean;
// Will cause onValueChanged(value, true) to fire on blur
blurToSubmit?: boolean;
editable?: boolean;
blurToSubmit: boolean;
editable: boolean;
}

interface IState {
Expand Down Expand Up @@ -109,11 +109,11 @@ export default class EditableText extends React.Component<IProps, IState> {
this.value = this.props.initialValue;
this.showPlaceholder(!this.value);
this.onValueChanged(false);
this.editableDiv.current.blur();
this.editableDiv.current?.blur();
};

private onValueChanged = (shouldSubmit: boolean): void => {
this.props.onValueChanged(this.value, shouldSubmit);
this.props.onValueChanged?.(this.value, shouldSubmit);
};

private onKeyDown = (ev: React.KeyboardEvent<HTMLDivElement>): void => {
Expand Down Expand Up @@ -171,7 +171,7 @@ export default class EditableText extends React.Component<IProps, IState> {

private onFinish = (
ev: React.KeyboardEvent<HTMLDivElement> | React.FocusEvent<HTMLDivElement>,
shouldSubmit?: boolean,
shouldSubmit = false,
): void => {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const self = this;
Expand Down
Loading