Remove matrix-events-sdk dependency (#31398)

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski
2025-12-04 13:24:28 +00:00
committed by GitHub
parent d1f45da51a
commit e7be9d16b9
40 changed files with 70 additions and 106 deletions

View File

@@ -79,7 +79,7 @@ Unless otherwise specified, the following applies to all code:
11. If a variable is not receiving a value on declaration, its type must be defined.
```typescript
let errorMessage: Optional<string>;
let errorMessage: string;
```
12. Objects can use shorthand declarations, including mixing of types.

View File

@@ -129,7 +129,6 @@
"lodash": "^4.17.21",
"maplibre-gl": "^5.0.0",
"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.14.0",
"memoize-one": "^6.0.0",

View File

@@ -8,8 +8,6 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
Please see LICENSE files in the repository root for full details.
*/
import { type Optional } from "matrix-events-sdk";
import { _t, getUserLanguage } from "./languageHandler";
import { getUserTimezone } from "./TimezoneHandler";
@@ -219,7 +217,7 @@ function withinCurrentYear(prevDate: Date, nextDate: Date): boolean {
return prevDate.getFullYear() === nextDate.getFullYear();
}
export function wantsDateSeparator(prevEventDate: Optional<Date>, nextEventDate: Optional<Date>): boolean {
export function wantsDateSeparator(prevEventDate: Date | undefined, nextEventDate: Date | undefined): boolean {
if (!nextEventDate || !prevEventDate) {
return false;
}

View File

@@ -15,7 +15,6 @@ import classNames from "classnames";
import katex from "katex";
import { decode } from "html-entities";
import { type IContent } from "matrix-js-sdk/src/matrix";
import { type Optional } from "matrix-events-sdk";
import escapeHtml from "escape-html";
import { getEmojiFromUnicode } from "@matrix-org/emojibase-bindings";
@@ -301,7 +300,7 @@ export interface EventRenderOpts {
linkify?: boolean;
}
function analyseEvent(content: IContent, highlights: Optional<string[]>, opts: EventRenderOpts = {}): EventAnalysis {
function analyseEvent(content: IContent, highlights?: string[], opts: EventRenderOpts = {}): EventAnalysis {
let sanitizeParams = sanitizeHtmlParams;
if (opts.forComposerQuote) {
sanitizeParams = composerSanitizeHtmlParams;
@@ -413,11 +412,7 @@ interface BodyToNodeReturn {
className: string;
}
export function bodyToNode(
content: IContent,
highlights: Optional<string[]>,
opts: EventRenderOpts = {},
): BodyToNodeReturn {
export function bodyToNode(content: IContent, highlights?: string[], opts: EventRenderOpts = {}): BodyToNodeReturn {
const eventInfo = analyseEvent(content, highlights, opts);
let emojiBody = false;
@@ -478,7 +473,7 @@ export function bodyToNode(
* opts.forComposerQuote: optional param to lessen the url rewriting done by sanitization, for quoting into composer
* opts.ref: React ref to attach to any React components returned (not compatible with opts.returnString)
*/
export function bodyToHtml(content: IContent, highlights: Optional<string[]>, opts: EventRenderOpts = {}): string {
export function bodyToHtml(content: IContent, highlights?: string[], opts: EventRenderOpts = {}): string {
const eventInfo = analyseEvent(content, highlights, opts);
let formattedBody = eventInfo.safeBody;

View File

@@ -7,7 +7,6 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
Please see LICENSE files in the repository root for full details.
*/
import { type Optional } from "matrix-events-sdk";
import { mergeWith } from "lodash";
import { SnakedObject } from "./utils/SnakedObject";
@@ -90,7 +89,7 @@ function mergeConfig(
type ObjectType<K extends keyof IConfigOptions> = IConfigOptions[K] extends object
? SnakedObject<NonNullable<IConfigOptions[K]>>
: Optional<SnakedObject<NonNullable<IConfigOptions[K]>>>;
: SnakedObject<NonNullable<IConfigOptions[K]>> | null | undefined;
export default class SdkConfig {
private static instance: DeepReadonly<IConfigOptions>;

View File

@@ -9,7 +9,6 @@ Please see LICENSE files in the repository root for full details.
import React, { type RefObject, type ReactNode, useRef } from "react";
import { CallEvent, CallState, type MatrixCall } from "matrix-js-sdk/src/webrtc/call";
import { logger } from "matrix-js-sdk/src/logger";
import { type Optional } from "matrix-events-sdk";
import LegacyCallView from "../views/voip/LegacyCallView";
import LegacyCallHandler, { LegacyCallHandlerEvent } from "../../LegacyCallHandler";
@@ -57,7 +56,7 @@ interface IState {
// (which should be a single element) of other calls.
// The primary will be the one not on hold, or an arbitrary one
// if they're all on hold)
function getPrimarySecondaryCallsForPip(roomId: Optional<string>): [MatrixCall | null, MatrixCall[]] {
function getPrimarySecondaryCallsForPip(roomId: string | null): [MatrixCall | null, MatrixCall[]] {
if (!roomId) return [null, []];
const calls = LegacyCallHandler.instance.getAllActiveCallsForPip(roomId);

View File

@@ -6,7 +6,6 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
Please see LICENSE files in the repository root for full details.
*/
import { type Optional } from "matrix-events-sdk";
import React, { useContext, useEffect, useRef, useState } from "react";
import { type EventTimelineSet, type Room, Thread } from "matrix-js-sdk/src/matrix";
import { IconButton, Tooltip } from "@vector-im/compound-web";
@@ -163,7 +162,7 @@ const ThreadPanel: React.FC<IProps> = ({ roomId, onClose, permalinkCreator }) =>
const [room, setRoom] = useState<Room | null>(null);
const [narrow, setNarrow] = useState<boolean>(false);
const timelineSet: Optional<EventTimelineSet> =
const timelineSet: EventTimelineSet | undefined =
filterOption === ThreadFilterType.My ? room?.threadsTimelineSets[1] : room?.threadsTimelineSets[0];
const hasThreads = Boolean(room?.threadsTimelineSets?.[0]?.getLiveTimeline()?.getEvents()?.length);

View File

@@ -8,7 +8,6 @@ Please see LICENSE files in the repository root for full details.
import React from "react";
import { type Room, type IEventRelation } from "matrix-js-sdk/src/matrix";
import { type Optional } from "matrix-events-sdk";
import ContentMessages from "../../ContentMessages";
import dis from "../../dispatcher/dispatcher";
@@ -45,7 +44,7 @@ function isUploadPayload(payload: ActionPayload): payload is UploadPayload {
}
export default class UploadBar extends React.PureComponent<IProps, IState> {
private dispatcherRef: Optional<string>;
private dispatcherRef?: string;
private unmounted = false;
public constructor(props: IProps) {

View File

@@ -8,7 +8,6 @@ Please see LICENSE files in the repository root for full details.
import React, { type JSX, type ChangeEvent, type SyntheticEvent } from "react";
import { logger } from "matrix-js-sdk/src/logger";
import { type Optional } from "matrix-events-sdk";
import { type LoginFlow, MatrixError, SSOAction, type SSOFlow } from "matrix-js-sdk/src/matrix";
import { _t } from "../../../languageHandler";
@@ -217,7 +216,7 @@ export default class SoftLogout extends React.Component<IProps, IState> {
});
}
private renderPasswordForm(introText: Optional<string>): JSX.Element {
private renderPasswordForm(introText?: string): JSX.Element {
let error: JSX.Element | undefined;
if (this.state.errorText) {
error = <span className="mx_Login_error">{this.state.errorText}</span>;
@@ -244,7 +243,7 @@ export default class SoftLogout extends React.Component<IProps, IState> {
);
}
private renderSsoForm(introText: Optional<string>): JSX.Element {
private renderSsoForm(introText?: string): JSX.Element {
const loginType = this.state.loginView === LoginView.CAS ? "cas" : "sso";
const flow = this.state.flows.find((flow) => flow.type === "m.login." + loginType) as SSOFlow;
@@ -284,14 +283,14 @@ export default class SoftLogout extends React.Component<IProps, IState> {
return (
<>
<p>{_t("auth|soft_logout_intro_sso")}</p>
{this.renderSsoForm(null)}
{this.renderSsoForm()}
<h2 className="mx_AuthBody_centered">
{_t("auth|sso_or_username_password", {
ssoButtons: "",
usernamePassword: "",
}).trim()}
</h2>
{this.renderPasswordForm(null)}
{this.renderPasswordForm()}
</>
);
}

View File

@@ -6,7 +6,6 @@ Please see LICENSE files in the repository root for full details.
import { type SyntheticEvent, useState } from "react";
import { EventType, type Room, type ContentHelpers } from "matrix-js-sdk/src/matrix";
import { type Optional } from "matrix-events-sdk";
import { useRoomState } from "../../../hooks/useRoomState";
import defaultDispatcher from "../../../dispatcher/dispatcher";
@@ -17,7 +16,7 @@ export interface RoomTopicState {
/**
* The topic of the room, the value is taken from the room state
*/
topic: Optional<ContentHelpers.TopicState>;
topic: ContentHelpers.TopicState | null;
/**
* Whether the topic is expanded or not
*/

View File

@@ -12,11 +12,10 @@ import { useDispatcher } from "../../../hooks/useDispatcher";
import dispatcher from "../../../dispatcher/dispatcher";
import { Action } from "../../../dispatcher/actions";
import type { Room } from "matrix-js-sdk/src/matrix";
import type { Optional } from "matrix-events-sdk";
import SpaceStore from "../../../stores/spaces/SpaceStore";
import { type RoomsResult } from "../../../stores/room-list-v3/RoomListStoreV3";
function getIndexByRoomId(rooms: Room[], roomId: Optional<string>): number | undefined {
function getIndexByRoomId(rooms: Room[], roomId: string): number | undefined {
const index = rooms.findIndex((room) => room.roomId === roomId);
return index === -1 ? undefined : index;
}
@@ -88,7 +87,7 @@ export interface StickyRoomListResult {
*/
export function useStickyRoomList(roomsResult: RoomsResult): StickyRoomListResult {
const [listState, setListState] = useState<StickyRoomListResult>({
activeIndex: getIndexByRoomId(roomsResult.rooms, SdkContextClass.instance.roomViewStore.getRoomId()),
activeIndex: getIndexByRoomId(roomsResult.rooms, SdkContextClass.instance.roomViewStore.getRoomId()!),
roomsResult: roomsResult,
});
@@ -98,7 +97,7 @@ export function useStickyRoomList(roomsResult: RoomsResult): StickyRoomListResul
(newRoomId: string | null, isRoomChange: boolean = false) => {
setListState((current) => {
const activeRoomId = newRoomId ?? SdkContextClass.instance.roomViewStore.getRoomId();
const newActiveIndex = getIndexByRoomId(roomsResult.rooms, activeRoomId);
const newActiveIndex = getIndexByRoomId(roomsResult.rooms, activeRoomId!);
const oldIndex = current.activeIndex;
const { newIndex, newRooms } = getRoomsWithStickyRoom(
roomsResult.rooms,

View File

@@ -255,7 +255,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
dis.dispatch<OpenForwardDialogPayload>({
action: Action.OpenForwardDialog,
event: forwardableEvent,
permalinkCreator: this.props.permalinkCreator,
permalinkCreator: this.props.permalinkCreator ?? null,
});
this.closeMenu();
};

View File

@@ -16,7 +16,6 @@ import {
EventType,
THREAD_RELATION_TYPE,
} from "matrix-js-sdk/src/matrix";
import { type Optional } from "matrix-events-sdk";
import { Tooltip } from "@vector-im/compound-web";
import { logger } from "matrix-js-sdk/src/logger";
import { LockOffIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
@@ -115,7 +114,7 @@ export class MessageComposer extends React.Component<IProps, IState> {
private ref = createRef<HTMLDivElement>();
private instanceId: number;
private _voiceRecording: Optional<VoiceMessageRecording>;
private _voiceRecording?: VoiceMessageRecording;
public static contextType = RoomContext;
declare public context: React.ContextType<typeof RoomContext>;
@@ -202,11 +201,11 @@ export class MessageComposer extends React.Component<IProps, IState> {
localStorage.removeItem(this.editorStateKey);
}
private get voiceRecording(): Optional<VoiceMessageRecording> {
private get voiceRecording(): VoiceMessageRecording | undefined {
return this._voiceRecording;
}
private set voiceRecording(rec: Optional<VoiceMessageRecording>) {
private set voiceRecording(rec: VoiceMessageRecording | undefined) {
if (this._voiceRecording) {
this._voiceRecording.off(RecordingState.Started, this.onRecordingStarted);
this._voiceRecording.off(RecordingState.EndingSoon, this.onRecordingEndingSoon);
@@ -328,7 +327,7 @@ export class MessageComposer extends React.Component<IProps, IState> {
window.removeEventListener("beforeunload", this.saveWysiwygEditorState);
this.saveWysiwygEditorState();
// clean up our listeners by setting our cached recording to falsy (see internal setter)
this.voiceRecording = null;
this.voiceRecording = undefined;
}
private onTombstoneClick = (ev: ButtonEvent): void => {

View File

@@ -9,7 +9,6 @@ Please see LICENSE files in the repository root for full details.
import React, { type ReactNode } from "react";
import { type Room, type IEventRelation, type MatrixEvent } from "matrix-js-sdk/src/matrix";
import { logger } from "matrix-js-sdk/src/logger";
import { type Optional } from "matrix-events-sdk";
import { _t } from "../../../languageHandler";
import { RecordingState } from "../../../audio/VoiceRecording";
@@ -216,7 +215,7 @@ export default class VoiceRecordComposerTile extends React.PureComponent<IProps,
}
};
private bindNewRecorder(recorder: Optional<VoiceMessageRecording>): void {
private bindNewRecorder(recorder: VoiceMessageRecording | null): void {
if (this.state.recorder) {
this.state.recorder.off(UPDATE_EVENT, this.onRecordingUpdate);
}

View File

@@ -8,7 +8,6 @@
import { type MatrixClient, parseErrorResponse, type ResizeMethod } from "matrix-js-sdk/src/matrix";
import { type MediaEventContent } from "matrix-js-sdk/src/types";
import { type Optional } from "matrix-events-sdk";
import type { MediaCustomisations, Media } from "@element-hq/element-web-module-api";
import { MatrixClientPeg } from "../MatrixClientPeg";
@@ -58,7 +57,7 @@ class MediaImplementation implements Media {
* The MXC URI of the thumbnail media, if a thumbnail is recorded. Null/undefined
* otherwise.
*/
public get thumbnailMxc(): Optional<string> {
public get thumbnailMxc(): string | undefined {
return this.prepared.thumbnail?.mxc;
}

View File

@@ -6,14 +6,12 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
Please see LICENSE files in the repository root for full details.
*/
import { type Optional } from "matrix-events-sdk";
import { type Action } from "../actions";
import { type ActionPayload } from "../payloads";
export interface ActiveRoomChangedPayload extends ActionPayload {
action: Action.ActiveRoomChanged;
oldRoomId: Optional<string>;
newRoomId: Optional<string>;
oldRoomId: string | null;
newRoomId: string | null;
}

View File

@@ -7,7 +7,6 @@ Please see LICENSE files in the repository root for full details.
*/
import { type MatrixEvent } from "matrix-js-sdk/src/matrix";
import { type Optional } from "matrix-events-sdk";
import { type Action } from "../actions";
import { type ActionPayload } from "../payloads";
@@ -17,5 +16,5 @@ export interface OpenForwardDialogPayload extends ActionPayload {
action: Action.OpenForwardDialog;
event: MatrixEvent;
permalinkCreator: Optional<RoomPermalinkCreator>;
permalinkCreator: RoomPermalinkCreator | null;
}

View File

@@ -6,7 +6,6 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
Please see LICENSE files in the repository root for full details.
*/
import { type Optional } from "matrix-events-sdk";
import { type MatrixCall } from "matrix-js-sdk/src/webrtc/call";
import { type ActionPayload } from "../payloads";
@@ -17,7 +16,7 @@ export interface OpenInviteDialogPayload extends ActionPayload {
action: Action.OpenInviteDialog;
kind: InviteKind;
onFinishedCallback: Optional<(results: boolean[]) => void>;
onFinishedCallback?: (results: boolean[]) => void;
call?: MatrixCall;
roomId?: string;

View File

@@ -17,7 +17,6 @@ import {
M_POLL_END,
M_POLL_START,
} from "matrix-js-sdk/src/matrix";
import { type Optional } from "matrix-events-sdk";
import { TextualEventView } from "@element-hq/web-shared-components";
import SettingsStore from "../settings/SettingsStore";
@@ -154,14 +153,14 @@ const SINGULAR_STATE_EVENTS = new Set([
* @param cli The matrix client to reference when needed.
* @param showHiddenEvents Whether hidden events should be shown.
* @param asHiddenEv When true, treat the event as always hidden.
* @returns The factory, or falsy if not possible.
* @returns The factory, or undefined if not possible.
*/
export function pickFactory(
mxEvent: MatrixEvent,
cli: MatrixClient,
showHiddenEvents: boolean,
asHiddenEv?: boolean,
): Optional<Factory> {
): Factory | undefined {
const evType = mxEvent.getType(); // cache this to reduce call stack execution hits
// Note: we avoid calling SettingsStore unless absolutely necessary - this code is on the critical path.
@@ -170,7 +169,7 @@ export function pickFactory(
return JSONEventFactory;
}
const noEventFactoryFactory: () => Optional<Factory> = () => (showHiddenEvents ? JSONEventFactory : undefined); // just don't render things that we shouldn't render
const noEventFactoryFactory: () => Factory | undefined = () => (showHiddenEvents ? JSONEventFactory : undefined); // just don't render things that we shouldn't render
// We run all the event type checks first as they might override the factory entirely.
@@ -249,15 +248,14 @@ export function pickFactory(
* Render an event as a tile
* @param renderType The render type. Used to inform properties given to the eventual component.
* @param props The properties to provide to the eventual component.
* @param showHiddenEvents Whether hidden events should be shown.
* @param cli Optional client instance to use, otherwise the default MatrixClientPeg will be used.
* @returns The tile as JSX, or falsy if unable to render.
* @returns The tile as JSX, or null if unable to render.
*/
export function renderTile(
renderType: TimelineRenderingType,
props: EventTileTypeProps,
cli?: MatrixClient,
): Optional<JSX.Element> {
): JSX.Element | null {
cli = cli ?? MatrixClientPeg.safeGet(); // because param defaults don't do the correct thing
const factory = pickFactory(props.mxEvent, cli, props.showHiddenEvents);
@@ -352,7 +350,7 @@ export function renderReplyTile(
props: EventTileTypeProps,
showHiddenEvents: boolean,
cli?: MatrixClient,
): Optional<JSX.Element> {
): JSX.Element | null {
cli = cli ?? MatrixClientPeg.safeGet(); // because param defaults don't do the correct thing
const factory = pickFactory(props.mxEvent, cli, showHiddenEvents);

View File

@@ -15,11 +15,10 @@ import {
ContentHelpers,
type MRoomTopicEventContent,
} from "matrix-js-sdk/src/matrix";
import { type Optional } from "matrix-events-sdk";
import { useTypedEventEmitter } from "../useEventEmitter";
export const getTopic = (room?: Room): Optional<ContentHelpers.TopicState> => {
export const getTopic = (room?: Room): ContentHelpers.TopicState | null => {
const content = room?.currentState?.getStateEvents(EventType.RoomTopic, "")?.getContent<MRoomTopicEventContent>();
return !!content ? ContentHelpers.parseTopicContent(content) : null;
};
@@ -29,7 +28,7 @@ export const getTopic = (room?: Room): Optional<ContentHelpers.TopicState> => {
* @param room
* @returns the raw text and an html parsion version of the room topic
*/
export function useTopic(room?: Room): Optional<ContentHelpers.TopicState> {
export function useTopic(room?: Room): ContentHelpers.TopicState | null {
const [topic, setTopic] = useState(getTopic(room));
useTypedEventEmitter(room?.currentState, RoomStateEvent.Events, (ev: MatrixEvent) => {
if (ev.getType() !== EventType.RoomTopic) return;

View File

@@ -6,7 +6,6 @@
*/
import { logger } from "matrix-js-sdk/src/logger";
import { type Optional } from "matrix-events-sdk";
import { MapWithDefault } from "matrix-js-sdk/src/utils";
import { type TranslationStringsObject } from "@matrix-org/react-sdk-module-api";
import _ from "lodash";
@@ -236,7 +235,7 @@ async function getLanguage(langPath: string): Promise<ICounterpartTranslation> {
return res.json();
}
let cachedCustomTranslations: Optional<TranslationStringsObject> = null;
let cachedCustomTranslations: TranslationStringsObject | undefined;
let cachedCustomTranslationsExpire = 0; // zero to trigger expiration right away
// This awkward class exists so the test runner can get at the function. It is
@@ -285,7 +284,7 @@ export async function registerCustomTranslations({
if (!lookupUrl) return; // easy - nothing to do
try {
let json: Optional<TranslationStringsObject>;
let json: TranslationStringsObject | undefined;
if (testOnlyIgnoreCustomTranslationsCache || Date.now() >= cachedCustomTranslationsExpire) {
json = CustomTranslationOptions.lookupFn
? CustomTranslationOptions.lookupFn(lookupUrl)

View File

@@ -11,7 +11,6 @@ import {
type TranslationStringsObject,
type PlainSubstitution,
} from "@matrix-org/react-sdk-module-api/lib/types/translations";
import { type Optional } from "matrix-events-sdk";
import { type DialogContent, type DialogProps } from "@matrix-org/react-sdk-module-api/lib/components/DialogContent";
import { type AccountAuthInfo } from "@matrix-org/react-sdk-module-api/lib/types/AccountAuthInfo";
import * as Matrix from "matrix-js-sdk/src/matrix";
@@ -40,7 +39,7 @@ import type { ViewRoomPayload } from "../dispatcher/payloads/ViewRoomPayload.ts"
* to be assigned to a single module.
*/
export class ProxiedModuleApi implements ModuleApi {
private cachedTranslations: Optional<TranslationStringsObject>;
private cachedTranslations?: TranslationStringsObject;
private overrideLoginResolve?: () => void;
@@ -57,7 +56,7 @@ export class ProxiedModuleApi implements ModuleApi {
/**
* All custom translations used by the associated module.
*/
public get translations(): Optional<TranslationStringsObject> {
public get translations(): TranslationStringsObject | undefined {
return this.cachedTranslations;
}

View File

@@ -15,7 +15,6 @@ import { KnownMembership } from "matrix-js-sdk/src/types";
import { logger } from "matrix-js-sdk/src/logger";
import { type ViewRoom as ViewRoomEvent } from "@matrix-org/analytics-events/types/typescript/ViewRoom";
import { type JoinedRoom as JoinedRoomEvent } from "@matrix-org/analytics-events/types/typescript/JoinedRoom";
import { type Optional } from "matrix-events-sdk";
import EventEmitter from "events";
import {
RoomViewLifecycle,
@@ -664,16 +663,16 @@ export class RoomViewStore extends EventEmitter {
}
// The room ID of the room currently being viewed
public getRoomId(): Optional<string> {
public getRoomId(): string | null {
return this.state.roomId;
}
public getThreadId(): Optional<string> {
public getThreadId(): string | null {
return this.state.threadId;
}
// The event to scroll to when the room is first viewed
public getInitialEventId(): Optional<string> {
public getInitialEventId(): string | null {
return this.state.initialEventId;
}
@@ -688,7 +687,7 @@ export class RoomViewStore extends EventEmitter {
}
// The room alias of the room (or null if not originally specified in view_room)
public getRoomAlias(): Optional<string> {
public getRoomAlias(): string | null {
return this.state.roomAlias;
}
@@ -698,7 +697,7 @@ export class RoomViewStore extends EventEmitter {
}
// Any error that has occurred during loading
public getRoomLoadError(): Optional<MatrixError> {
public getRoomLoadError(): MatrixError | null {
return this.state.roomLoadError;
}
@@ -730,7 +729,7 @@ export class RoomViewStore extends EventEmitter {
}
// Any error that has occurred during joining
public getJoinError(): Optional<Error> {
public getJoinError(): Error | null {
return this.state.joinError;
}

View File

@@ -6,7 +6,6 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
Please see LICENSE files in the repository root for full details.
*/
import { type Optional } from "matrix-events-sdk";
import { type Room, type IEventRelation, RelationType } from "matrix-js-sdk/src/matrix";
import { AsyncStoreWithClient } from "./AsyncStoreWithClient";
@@ -17,7 +16,7 @@ import { createVoiceMessageRecording, type VoiceMessageRecording } from "../audi
const SEPARATOR = "|";
interface IState {
[voiceRecordingId: string]: Optional<VoiceMessageRecording>;
[voiceRecordingId: string]: VoiceMessageRecording;
}
export class VoiceRecordingStore extends AsyncStoreWithClient<IState> {
@@ -51,9 +50,9 @@ export class VoiceRecordingStore extends AsyncStoreWithClient<IState> {
/**
* Gets the active recording instance, if any.
* @param {string} voiceRecordingId The room ID (with optionally the thread ID if in one) to get the recording in.
* @returns {Optional<VoiceRecording>} The recording, if any.
* @returns {VoiceRecording?} The recording, if any.
*/
public getActiveRecording(voiceRecordingId: string): Optional<VoiceMessageRecording> {
public getActiveRecording(voiceRecordingId: string): VoiceMessageRecording | undefined {
return this.state[voiceRecordingId];
}

View File

@@ -8,7 +8,6 @@ Please see LICENSE files in the repository root for full details.
import { logger } from "matrix-js-sdk/src/logger";
import { CryptoEvent } from "matrix-js-sdk/src/crypto-api";
import { type Optional } from "matrix-events-sdk";
import defaultDispatcher from "../../dispatcher/dispatcher";
import { pendingVerificationRequestForUser } from "../../verification";
@@ -58,7 +57,7 @@ export default class RightPanelStore extends ReadyWatchingStore {
private global?: IRightPanelForRoom;
private byRoom: { [roomId: string]: IRightPanelForRoom } = {};
private viewedRoomId: Optional<string>;
private viewedRoomId: string | null = null;
private constructor() {
super(defaultDispatcher);
@@ -419,7 +418,7 @@ export default class RightPanelStore extends ReadyWatchingStore {
}
};
private handleViewedRoomChange(oldRoomId: Optional<string>, newRoomId: Optional<string>): void {
private handleViewedRoomChange(oldRoomId: string | null, newRoomId: string | null): void {
if (!this.mxClient) return; // not ready, onReady will handle the first room
this.viewedRoomId = newRoomId;
// load values from byRoomCache with the viewedRoomId.

View File

@@ -7,7 +7,6 @@
*/
import { type Room, RoomStateEvent, type MatrixEvent } from "matrix-js-sdk/src/matrix";
import { type Optional } from "matrix-events-sdk";
import { MapWithDefault, recursiveMapToObject } from "matrix-js-sdk/src/utils";
import { type IWidget } from "matrix-widget-api";
import { clamp, defaultNumber, sum } from "@element-hq/web-shared-components";
@@ -316,7 +315,7 @@ export class WidgetLayoutStore extends ReadyWatchingStore {
}
}
public getContainerWidgets(room: Optional<Room>, container: Container): IWidget[] {
public getContainerWidgets(room: Room | null, container: Container): IWidget[] {
return (room && this.byRoom.get(room.roomId)?.get(container)?.ordered) || [];
}

View File

@@ -10,7 +10,6 @@ import { uniq } from "lodash";
import { type Room, type MatrixEvent, EventType, ClientEvent, type MatrixClient } from "matrix-js-sdk/src/matrix";
import { KnownMembership } from "matrix-js-sdk/src/types";
import { logger } from "matrix-js-sdk/src/logger";
import { type Optional } from "matrix-events-sdk";
import { filterValidMDirect } from "./dm/filterValidMDirect";
@@ -170,7 +169,7 @@ export default class DMRoomMap {
return joinedRooms[0];
}
public getUserIdForRoomId(roomId: string): Optional<string> {
public getUserIdForRoomId(roomId: string): string | undefined {
if (this.roomToUser == null) {
// we lazily populate roomToUser so you can use
// this class just to call getDMRoomsForUserId

View File

@@ -27,7 +27,7 @@ function getSanitizedHtmlBody(content: IContent): string {
stripReplyFallback: true,
};
if (content.format === "org.matrix.custom.html") {
return bodyToHtml(content, null, opts);
return bodyToHtml(content, undefined, opts);
} else {
// convert the string to something that can be safely
// embedded in an html document, e.g. use html entities where needed
@@ -37,7 +37,7 @@ function getSanitizedHtmlBody(content: IContent): string {
// as opposed to bodyToHtml, here we also render
// text messages with dangerouslySetInnerHTML, to unify
// the code paths and because we need html to show differences
return textToHtml(bodyToHtml(content, null, opts));
return textToHtml(bodyToHtml(content, undefined, opts));
}
}

View File

@@ -7,7 +7,6 @@ Please see LICENSE files in the repository root for full details.
*/
import { type IInvite3PID, type MatrixClient, type Room } from "matrix-js-sdk/src/matrix";
import { type Optional } from "matrix-events-sdk";
import { Action } from "../../dispatcher/actions";
import { type ViewRoomPayload } from "../../dispatcher/payloads/ViewRoomPayload";
@@ -28,7 +27,7 @@ export async function startDm(client: MatrixClient, targets: Member[], showSpinn
const targetIds = targets.map((t) => t.userId);
// Check if there is already a DM with these people and reuse it if possible.
let existingRoom: Optional<Room>;
let existingRoom: Room | undefined;
if (targetIds.length === 1) {
existingRoom = findDMForUser(client, targetIds[0]);
} else {

View File

@@ -68,7 +68,7 @@ describe("avatarUrlForRoom", () => {
});
it("should return null if the room is not a DM", () => {
mocked(dmRoomMap).getUserIdForRoomId.mockReturnValue(null);
mocked(dmRoomMap).getUserIdForRoomId.mockReturnValue(undefined);
expect(avatarUrlForRoom(room, 128, 128)).toBeNull();
expect(dmRoomMap.getUserIdForRoomId).toHaveBeenCalledWith(roomId);
});

View File

@@ -30,7 +30,7 @@ describe("RoomAvatarViewModel", () => {
room = mkStubRoom("roomId", "roomName", matrixClient);
DMRoomMap.makeShared(matrixClient);
jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue(null);
jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue(undefined);
jest.spyOn(PresenceIndicatorModule, "useDmMember").mockReturnValue(null);
jest.spyOn(PresenceIndicatorModule, "usePresence").mockReturnValue(null);

View File

@@ -56,7 +56,7 @@ describe("RoomListItemMenuViewModel", () => {
room = mkStubRoom("roomId", "roomName", matrixClient);
DMRoomMap.makeShared(matrixClient);
jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue(null);
jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue(undefined);
mocked(useUnreadNotifications).mockReturnValue({ symbol: null, count: 0, level: NotificationLevel.None });
mocked(useNotificationState).mockReturnValue([RoomNotifState.AllMessages, jest.fn()]);

View File

@@ -315,7 +315,7 @@ describe("RoomListViewModel", () => {
it("active room index becomes undefined when active room is deleted", () => {
const { rooms } = mockAndCreateRooms();
// Let's say that the room at index 5 is active
let roomId: string | undefined = rooms[5].roomId;
let roomId: string | null = rooms[5].roomId;
jest.spyOn(SdkContextClass.instance.roomViewStore, "getRoomId").mockImplementation(() => roomId);
const { result: vm } = renderHook(() => useRoomListViewModel());
@@ -323,7 +323,7 @@ describe("RoomListViewModel", () => {
// Let's remove the active room (i.e room at index 5)
rooms.splice(5, 1);
roomId = undefined;
roomId = null;
act(() => RoomListStoreV3.instance.emit(LISTS_UPDATE_EVENT));
expect(vm.current.activeIndex).toBeUndefined();
});
@@ -332,7 +332,7 @@ describe("RoomListViewModel", () => {
mockAndCreateRooms();
// Let's say that there's no active room currently
jest.spyOn(SdkContextClass.instance.roomViewStore, "getRoomId").mockImplementation(() => undefined);
jest.spyOn(SdkContextClass.instance.roomViewStore, "getRoomId").mockImplementation(() => null);
const { result: vm } = renderHook(() => useRoomListViewModel());
expect(vm.current.activeIndex).toEqual(undefined);

View File

@@ -30,7 +30,7 @@ describe("useRoomListNavigation", () => {
];
DMRoomMap.makeShared(matrixClient);
jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue(null);
jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue(undefined);
jest.spyOn(dispatcher, "dispatch");
});

View File

@@ -29,7 +29,7 @@ describe("<RoomAvatarView />", () => {
const room = mkStubRoom("roomId", "roomName", matrixClient);
DMRoomMap.makeShared(matrixClient);
jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue(null);
jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue(undefined);
let defaultValue: RoomAvatarViewState;

View File

@@ -9,7 +9,6 @@ Please see LICENSE files in the repository root for full details.
import React from "react";
import { Room, type MatrixClient } from "matrix-js-sdk/src/matrix";
import { type ClientWidgetApi, type IWidget, MatrixWidgetType } from "matrix-widget-api";
import { type Optional } from "matrix-events-sdk";
import { act, render, type RenderResult, waitForElementToBeRemoved, waitFor } from "jest-matrix-react";
import userEvent from "@testing-library/user-event";
import {
@@ -411,7 +410,7 @@ describe("AppTile", () => {
describe("for a maximised (centered) widget", () => {
beforeEach(() => {
jest.spyOn(WidgetLayoutStore.instance, "isInContainer").mockImplementation(
(room: Optional<Room>, widget: IWidget, container: Container) => {
(room: Room | null, widget: IWidget, container: Container) => {
return room === r1 && widget === app1 && container === Container.Center;
},
);

View File

@@ -37,7 +37,7 @@ describe("<RoomList />", () => {
// Needed to render a room list cell
DMRoomMap.makeShared(matrixClient);
jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue(null);
jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue(undefined);
});
it("should render a room list", () => {

View File

@@ -49,7 +49,7 @@ describe("<RoomListItemView />", () => {
room = mkRoom(matrixClient, "room1");
DMRoomMap.makeShared(matrixClient);
jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue(null);
jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue(undefined);
const notificationState = new RoomNotificationState(room, false);
jest.spyOn(notificationState, "hasAnyNotificationOrActivity", "get").mockReturnValue(true);

View File

@@ -20,7 +20,6 @@ import {
} from "matrix-js-sdk/src/matrix";
import { ClientWidgetApi, WidgetApiFromWidgetAction } from "matrix-widget-api";
import { waitFor } from "jest-matrix-react";
import { type Optional } from "matrix-events-sdk";
import { stubClient, mkRoom, mkEvent } from "../../../test-utils";
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
@@ -362,13 +361,13 @@ describe("StopGapWidget with stickyPromise", () => {
describe("StopGapWidget as an account widget", () => {
let widget: StopGapWidget;
let messaging: MockedObject<ClientWidgetApi>;
let getRoomId: MockedFunction<() => Optional<string>>;
let getRoomId: MockedFunction<() => string | null>;
beforeEach(() => {
stubClient();
// I give up, getting the return type of spyOn right is hopeless
getRoomId = jest.spyOn(SdkContextClass.instance.roomViewStore, "getRoomId") as unknown as MockedFunction<
() => Optional<string>
() => string | null
>;
getRoomId.mockReturnValue("!1:example.org");

View File

@@ -214,8 +214,7 @@ module.exports = (env, argv) => {
__dirname,
"node_modules/@matrix-org/react-sdk-module-api",
),
// and matrix-events-sdk & matrix-widget-api
"matrix-events-sdk": path.resolve(__dirname, "node_modules/matrix-events-sdk"),
// and matrix-widget-api
"matrix-widget-api": path.resolve(__dirname, "node_modules/matrix-widget-api"),
"oidc-client-ts": path.resolve(__dirname, "node_modules/oidc-client-ts"),