diff --git a/babel.config.js b/babel.config.js index a9e4b5c137b..541c567770a 100644 --- a/babel.config.js +++ b/babel.config.js @@ -10,15 +10,15 @@ module.exports = { "last 2 Safari versions", "last 2 Edge versions", ], + include: ["@babel/plugin-transform-class-properties"], }, ], - "@babel/preset-typescript", + ["@babel/preset-typescript", { allowDeclareFields: true }], "@babel/preset-react", ], plugins: [ "@babel/plugin-proposal-export-default-from", "@babel/plugin-transform-numeric-separator", - "@babel/plugin-transform-class-properties", "@babel/plugin-transform-object-rest-spread", "@babel/plugin-syntax-dynamic-import", "@babel/plugin-transform-runtime", diff --git a/playwright/plugins/homeserver/dendrite/index.ts b/playwright/plugins/homeserver/dendrite/index.ts index 603bd360a8c..0ddaecc1b7d 100644 --- a/playwright/plugins/homeserver/dendrite/index.ts +++ b/playwright/plugins/homeserver/dendrite/index.ts @@ -29,7 +29,6 @@ const dendriteConfigFile = "dendrite.yaml"; // Surprisingly, Dendrite implements the same register user Admin API Synapse, so we can just extend it export class Dendrite extends Synapse implements Homeserver, HomeserverInstance { - public config: HomeserverConfig & { serverId: string }; protected image = "matrixdotorg/dendrite-monolith:main"; protected entrypoint = "/usr/bin/dendrite"; diff --git a/playwright/tsconfig.json b/playwright/tsconfig.json index 48ff1f8c02e..5f3083fd57b 100644 --- a/playwright/tsconfig.json +++ b/playwright/tsconfig.json @@ -1,8 +1,8 @@ { "compilerOptions": { - "target": "es2018", + "target": "es2022", "jsx": "react", - "lib": ["ESNext", "es2021", "dom", "dom.iterable"], + "lib": ["ESNext", "es2022", "dom", "dom.iterable"], "resolveJsonModule": true, "esModuleInterop": true, "moduleResolution": "node", diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index e42e83d58db..fab9791ada1 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -144,69 +144,14 @@ declare global { usageDetails?: { [key: string]: number }; } - // https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas - interface OffscreenCanvas { - convertToBlob(opts?: { type?: string; quality?: number }): Promise; - } - - interface HTMLAudioElement { - type?: string; - } - - interface HTMLVideoElement { - type?: string; - } - - // Add Chrome-specific `instant` ScrollBehaviour - type _ScrollBehavior = ScrollBehavior | "instant"; - - interface _ScrollOptions { - behavior?: _ScrollBehavior; - } - - interface _ScrollIntoViewOptions extends _ScrollOptions { - block?: ScrollLogicalPosition; - inline?: ScrollLogicalPosition; - } - interface Element { // Safari & IE11 only have this prefixed: we used prefixed versions // previously so let's continue to support them for now webkitRequestFullScreen(options?: FullscreenOptions): Promise; msRequestFullscreen(options?: FullscreenOptions): Promise; - scrollIntoView(arg?: boolean | _ScrollIntoViewOptions): void; - } - - interface Error { - // Standard - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause - cause?: unknown; - - // Non-standard - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/fileName - fileName?: string; - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/lineNumber - lineNumber?: number; - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/columnNumber - columnNumber?: number; - } - - // We can remove these pieces if we ever update to `target: "es2022"` in our - // TypeScript config which supports the new `cause` property, see - // https://github.com/vector-im/element-web/issues/24913 - interface ErrorOptions { - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause - cause?: unknown; - } - - interface ErrorConstructor { - new (message?: string, options?: ErrorOptions): Error; - (message?: string, options?: ErrorOptions): Error; + // scrollIntoView(arg?: boolean | _ScrollIntoViewOptions): void; } - // eslint-disable-next-line no-var - var Error: ErrorConstructor; - // https://github.com/microsoft/TypeScript/issues/28308#issuecomment-650802278 interface AudioWorkletProcessor { readonly port: MessagePort; diff --git a/src/components/structures/EmbeddedPage.tsx b/src/components/structures/EmbeddedPage.tsx index 4c36412cb62..2a37e53859a 100644 --- a/src/components/structures/EmbeddedPage.tsx +++ b/src/components/structures/EmbeddedPage.tsx @@ -45,7 +45,7 @@ interface IState { export default class EmbeddedPage extends React.PureComponent { public static contextType = MatrixClientContext; - public context!: React.ContextType; + public declare context: React.ContextType; private unmounted = false; private dispatcherRef: string | null = null; diff --git a/src/components/structures/FilePanel.tsx b/src/components/structures/FilePanel.tsx index 77448627035..86a3e1cf833 100644 --- a/src/components/structures/FilePanel.tsx +++ b/src/components/structures/FilePanel.tsx @@ -59,7 +59,7 @@ interface IState { */ class FilePanel extends React.Component { public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; // This is used to track if a decrypted event was a live event and should be // added to the timeline. diff --git a/src/components/structures/MessagePanel.tsx b/src/components/structures/MessagePanel.tsx index 3a97f27b381..07b600484ac 100644 --- a/src/components/structures/MessagePanel.tsx +++ b/src/components/structures/MessagePanel.tsx @@ -205,7 +205,7 @@ interface IReadReceiptForUser { */ export default class MessagePanel extends React.Component { public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; public static defaultProps = { disableGrouping: false, diff --git a/src/components/structures/NotificationPanel.tsx b/src/components/structures/NotificationPanel.tsx index 1f9fb4c57f6..7c8fd71b791 100644 --- a/src/components/structures/NotificationPanel.tsx +++ b/src/components/structures/NotificationPanel.tsx @@ -42,7 +42,7 @@ interface IState { */ export default class NotificationPanel extends React.PureComponent { public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; private card = React.createRef(); diff --git a/src/components/structures/RightPanel.tsx b/src/components/structures/RightPanel.tsx index 1d6bf101b6e..9e228de611b 100644 --- a/src/components/structures/RightPanel.tsx +++ b/src/components/structures/RightPanel.tsx @@ -73,7 +73,7 @@ interface IState { export default class RightPanel extends React.Component { public static contextType = MatrixClientContext; - public context!: React.ContextType; + public declare context: React.ContextType; public constructor(props: Props, context: React.ContextType) { super(props, context); diff --git a/src/components/structures/RoomStatusBar.tsx b/src/components/structures/RoomStatusBar.tsx index ce489a5019d..e98785aa7e7 100644 --- a/src/components/structures/RoomStatusBar.tsx +++ b/src/components/structures/RoomStatusBar.tsx @@ -97,11 +97,10 @@ interface IState { export default class RoomStatusBar extends React.PureComponent { private unmounted = false; public static contextType = MatrixClientContext; - public context!: React.ContextType; + public declare context: React.ContextType; public constructor(props: IProps, context: React.ContextType) { super(props, context); - this.context = context; // XXX: workaround for lack of `declare` support on `public context!:` definition this.state = { syncState: this.context.getSyncState(), diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index a0555abbf78..9c6ffb857f9 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -417,7 +417,7 @@ export class RoomView extends React.Component { private roomViewBody = createRef(); public static contextType = SDKContext; - public context!: React.ContextType; + public declare context: React.ContextType; public constructor(props: IRoomProps, context: React.ContextType) { super(props, context); diff --git a/src/components/structures/SpaceRoomView.tsx b/src/components/structures/SpaceRoomView.tsx index 4564741a290..1c188f8f73b 100644 --- a/src/components/structures/SpaceRoomView.tsx +++ b/src/components/structures/SpaceRoomView.tsx @@ -605,7 +605,7 @@ const SpaceSetupPrivateInvite: React.FC<{ export default class SpaceRoomView extends React.PureComponent { public static contextType = MatrixClientContext; - public context!: React.ContextType; + public declare context: React.ContextType; private readonly dispatcherRef: string; diff --git a/src/components/structures/ThreadView.tsx b/src/components/structures/ThreadView.tsx index dbe2c59551e..f2d775464ed 100644 --- a/src/components/structures/ThreadView.tsx +++ b/src/components/structures/ThreadView.tsx @@ -83,7 +83,7 @@ interface IState { export default class ThreadView extends React.Component { public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; private dispatcherRef: string | null = null; private readonly layoutWatcherRef: string; diff --git a/src/components/structures/TimelinePanel.tsx b/src/components/structures/TimelinePanel.tsx index b193403695c..976c00e2fdc 100644 --- a/src/components/structures/TimelinePanel.tsx +++ b/src/components/structures/TimelinePanel.tsx @@ -241,7 +241,7 @@ interface IEventIndexOpts { */ class TimelinePanel extends React.Component { public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; // a map from room id to read marker event timestamp public static roomReadMarkerTsMap: Record = {}; @@ -273,7 +273,6 @@ class TimelinePanel extends React.Component { public constructor(props: IProps, context: React.ContextType) { super(props, context); - this.context = context; debuglog("mounting"); diff --git a/src/components/structures/UserMenu.tsx b/src/components/structures/UserMenu.tsx index 6921c262645..ca949f46d08 100644 --- a/src/components/structures/UserMenu.tsx +++ b/src/components/structures/UserMenu.tsx @@ -90,7 +90,7 @@ const below = (rect: PartialDOMRect): MenuProps => { export default class UserMenu extends React.Component { public static contextType = SDKContext; - public context!: React.ContextType; + public declare context: React.ContextType; private dispatcherRef?: string; private themeWatcherRef?: string; @@ -100,7 +100,6 @@ export default class UserMenu extends React.Component { public constructor(props: IProps, context: React.ContextType) { super(props, context); - this.context = context; this.state = { contextMenuPosition: null, isDarkTheme: this.isUserOnDarkTheme(), diff --git a/src/components/structures/UserView.tsx b/src/components/structures/UserView.tsx index 4398af851a9..7aa2d92d0ca 100644 --- a/src/components/structures/UserView.tsx +++ b/src/components/structures/UserView.tsx @@ -41,7 +41,7 @@ interface IState { export default class UserView extends React.Component { public static contextType = MatrixClientContext; - public context!: React.ContextType; + public declare context: React.ContextType; public constructor(props: IProps, context: React.ContextType) { super(props, context); diff --git a/src/components/structures/auth/SoftLogout.tsx b/src/components/structures/auth/SoftLogout.tsx index f623ae7dcbb..ca34e3830aa 100644 --- a/src/components/structures/auth/SoftLogout.tsx +++ b/src/components/structures/auth/SoftLogout.tsx @@ -72,13 +72,11 @@ interface IState { export default class SoftLogout extends React.Component { public static contextType = SDKContext; - public context!: React.ContextType; + public declare context: React.ContextType; public constructor(props: IProps, context: React.ContextType) { super(props, context); - this.context = context; - this.state = { loginView: LoginView.Loading, busy: false, diff --git a/src/components/views/context_menus/MessageContextMenu.tsx b/src/components/views/context_menus/MessageContextMenu.tsx index 77fc7215ebf..801ab0b023e 100644 --- a/src/components/views/context_menus/MessageContextMenu.tsx +++ b/src/components/views/context_menus/MessageContextMenu.tsx @@ -133,7 +133,7 @@ interface IState { export default class MessageContextMenu extends React.Component { public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; private reactButtonRef = createRef(); // XXX Ref to a functional component diff --git a/src/components/views/elements/AppTile.tsx b/src/components/views/elements/AppTile.tsx index 1612154c943..6d326b09007 100644 --- a/src/components/views/elements/AppTile.tsx +++ b/src/components/views/elements/AppTile.tsx @@ -120,7 +120,7 @@ interface IState { export default class AppTile extends React.Component { public static contextType = MatrixClientContext; - public context!: ContextType; + public declare context: ContextType; public static defaultProps: Partial = { waitForIframeLoad: true, @@ -144,7 +144,6 @@ export default class AppTile extends React.Component { public constructor(props: IProps, context: ContextType) { super(props, context); - this.context = context; // XXX: workaround for lack of `declare` support on `public context!:` definition // Tiles in miniMode are floating, and therefore not docked if (!this.props.miniMode) { diff --git a/src/components/views/elements/EventListSummary.tsx b/src/components/views/elements/EventListSummary.tsx index a1270427ccd..4f5817e4c74 100644 --- a/src/components/views/elements/EventListSummary.tsx +++ b/src/components/views/elements/EventListSummary.tsx @@ -81,7 +81,7 @@ export default class EventListSummary extends React.Component< IProps & Required> > { public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; public static defaultProps = { summaryLength: 1, diff --git a/src/components/views/elements/PersistentApp.tsx b/src/components/views/elements/PersistentApp.tsx index 812d3432498..dfed54a3ba0 100644 --- a/src/components/views/elements/PersistentApp.tsx +++ b/src/components/views/elements/PersistentApp.tsx @@ -32,7 +32,7 @@ interface IProps { export default class PersistentApp extends React.Component { public static contextType = MatrixClientContext; - public context!: ContextType; + public declare context: ContextType; private room: Room; public constructor(props: IProps, context: ContextType) { diff --git a/src/components/views/elements/ReplyChain.tsx b/src/components/views/elements/ReplyChain.tsx index b7e833a629b..621a360bc54 100644 --- a/src/components/views/elements/ReplyChain.tsx +++ b/src/components/views/elements/ReplyChain.tsx @@ -73,7 +73,7 @@ interface IState { // be low as each event being loaded (after the first) is triggered by an explicit user action. export default class ReplyChain extends React.Component { public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; private unmounted = false; private room: Room; diff --git a/src/components/views/elements/RoomAliasField.tsx b/src/components/views/elements/RoomAliasField.tsx index d5353dcabc3..1ec057fff10 100644 --- a/src/components/views/elements/RoomAliasField.tsx +++ b/src/components/views/elements/RoomAliasField.tsx @@ -41,7 +41,7 @@ interface IState { // Controlled form component wrapping Field for inputting a room alias scoped to a given domain export default class RoomAliasField extends React.PureComponent { public static contextType = MatrixClientContext; - public context!: React.ContextType; + public declare context: React.ContextType; private fieldRef = createRef(); diff --git a/src/components/views/emojipicker/ReactionPicker.tsx b/src/components/views/emojipicker/ReactionPicker.tsx index 075a6e6cee7..8265331a3cd 100644 --- a/src/components/views/emojipicker/ReactionPicker.tsx +++ b/src/components/views/emojipicker/ReactionPicker.tsx @@ -37,7 +37,7 @@ interface IState { class ReactionPicker extends React.Component { public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; public constructor(props: IProps, context: React.ContextType) { super(props, context); diff --git a/src/components/views/emojipicker/Search.tsx b/src/components/views/emojipicker/Search.tsx index 33549b7489a..d7077f0591a 100644 --- a/src/components/views/emojipicker/Search.tsx +++ b/src/components/views/emojipicker/Search.tsx @@ -31,7 +31,7 @@ interface IProps { class Search extends React.PureComponent { public static contextType = RovingTabIndexContext; - public context!: React.ContextType; + public declare context: React.ContextType; private inputRef = React.createRef(); diff --git a/src/components/views/location/LocationPicker.tsx b/src/components/views/location/LocationPicker.tsx index 75437296d97..d4739935c76 100644 --- a/src/components/views/location/LocationPicker.tsx +++ b/src/components/views/location/LocationPicker.tsx @@ -50,7 +50,7 @@ const isSharingOwnLocation = (shareType: LocationShareType): boolean => class LocationPicker extends React.Component { public static contextType = MatrixClientContext; - public context!: React.ContextType; + public declare context: React.ContextType; private map?: maplibregl.Map; private geolocate?: maplibregl.GeolocateControl; private marker?: maplibregl.Marker; diff --git a/src/components/views/messages/EditHistoryMessage.tsx b/src/components/views/messages/EditHistoryMessage.tsx index bd7eccba3e9..de2ba8a1b4b 100644 --- a/src/components/views/messages/EditHistoryMessage.tsx +++ b/src/components/views/messages/EditHistoryMessage.tsx @@ -52,7 +52,7 @@ interface IState { export default class EditHistoryMessage extends React.PureComponent { public static contextType = MatrixClientContext; - public context!: React.ContextType; + public declare context: React.ContextType; private content = createRef(); private pills: Element[] = []; @@ -60,7 +60,6 @@ export default class EditHistoryMessage extends React.PureComponent) { super(props, context); - this.context = context; const cli = this.context; const userId = cli.getSafeUserId(); diff --git a/src/components/views/messages/MAudioBody.tsx b/src/components/views/messages/MAudioBody.tsx index 5e8d9f2436c..13c97d32020 100644 --- a/src/components/views/messages/MAudioBody.tsx +++ b/src/components/views/messages/MAudioBody.tsx @@ -38,7 +38,7 @@ interface IState { export default class MAudioBody extends React.PureComponent { public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; public state: IState = {}; diff --git a/src/components/views/messages/MFileBody.tsx b/src/components/views/messages/MFileBody.tsx index 1da3cafc65b..d7542b97407 100644 --- a/src/components/views/messages/MFileBody.tsx +++ b/src/components/views/messages/MFileBody.tsx @@ -106,7 +106,7 @@ interface IState { export default class MFileBody extends React.Component { public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; public state: IState = {}; diff --git a/src/components/views/messages/MImageBody.tsx b/src/components/views/messages/MImageBody.tsx index 547972cdb02..82f03519087 100644 --- a/src/components/views/messages/MImageBody.tsx +++ b/src/components/views/messages/MImageBody.tsx @@ -65,7 +65,7 @@ interface IState { export default class MImageBody extends React.Component { public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; private unmounted = true; private image = createRef(); diff --git a/src/components/views/messages/MLocationBody.tsx b/src/components/views/messages/MLocationBody.tsx index 276b22eeed7..f3f1a3d9d3a 100644 --- a/src/components/views/messages/MLocationBody.tsx +++ b/src/components/views/messages/MLocationBody.tsx @@ -38,7 +38,7 @@ interface IState { export default class MLocationBody extends React.Component { public static contextType = MatrixClientContext; - public context!: React.ContextType; + public declare context: React.ContextType; private unmounted = false; private mapId: string; diff --git a/src/components/views/messages/MPollBody.tsx b/src/components/views/messages/MPollBody.tsx index fadab6e2a5c..5fad5acd5fc 100644 --- a/src/components/views/messages/MPollBody.tsx +++ b/src/components/views/messages/MPollBody.tsx @@ -147,7 +147,7 @@ export function launchPollEditor(mxEvent: MatrixEvent, getRelationsForEvent?: Ge export default class MPollBody extends React.Component { public static contextType = MatrixClientContext; - public context!: React.ContextType; + public declare context: React.ContextType; private seenEventIds: string[] = []; // Events we have already seen public constructor(props: IBodyProps, context: React.ContextType) { diff --git a/src/components/views/messages/MVideoBody.tsx b/src/components/views/messages/MVideoBody.tsx index 143176a1550..1309a034ad2 100644 --- a/src/components/views/messages/MVideoBody.tsx +++ b/src/components/views/messages/MVideoBody.tsx @@ -42,7 +42,7 @@ interface IState { export default class MVideoBody extends React.PureComponent { public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; private videoRef = React.createRef(); private sizeWatcher?: string; diff --git a/src/components/views/messages/MessageActionBar.tsx b/src/components/views/messages/MessageActionBar.tsx index f6e01dcd100..25547c78363 100644 --- a/src/components/views/messages/MessageActionBar.tsx +++ b/src/components/views/messages/MessageActionBar.tsx @@ -261,7 +261,7 @@ interface IMessageActionBarProps { export default class MessageActionBar extends React.PureComponent { public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; public componentDidMount(): void { if (this.props.mxEvent.status && this.props.mxEvent.status !== EventStatus.SENT) { diff --git a/src/components/views/messages/MessageEvent.tsx b/src/components/views/messages/MessageEvent.tsx index db0016de7b0..fb700579bea 100644 --- a/src/components/views/messages/MessageEvent.tsx +++ b/src/components/views/messages/MessageEvent.tsx @@ -90,7 +90,7 @@ export default class MessageEvent extends React.Component implements IMe private evTypes = new Map>(baseEvTypes.entries()); public static contextType = MatrixClientContext; - public context!: React.ContextType; + public declare context: React.ContextType; public constructor(props: IProps, context: React.ContextType) { super(props, context); diff --git a/src/components/views/messages/ReactionsRow.tsx b/src/components/views/messages/ReactionsRow.tsx index e57326edd73..c5d004b12b0 100644 --- a/src/components/views/messages/ReactionsRow.tsx +++ b/src/components/views/messages/ReactionsRow.tsx @@ -83,11 +83,10 @@ interface IState { export default class ReactionsRow extends React.PureComponent { public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; public constructor(props: IProps, context: React.ContextType) { super(props, context); - this.context = context; this.state = { myReactions: this.getMyReactions(), diff --git a/src/components/views/messages/ReactionsRowButton.tsx b/src/components/views/messages/ReactionsRowButton.tsx index 1dbd1bd7bf1..7c4dcc8b3cb 100644 --- a/src/components/views/messages/ReactionsRowButton.tsx +++ b/src/components/views/messages/ReactionsRowButton.tsx @@ -46,7 +46,7 @@ export interface IProps { export default class ReactionsRowButton extends React.PureComponent { public static contextType = MatrixClientContext; - public context!: React.ContextType; + public declare context: React.ContextType; public onClick = (): void => { const { mxEvent, myReactionEvent, content } = this.props; diff --git a/src/components/views/messages/ReactionsRowButtonTooltip.tsx b/src/components/views/messages/ReactionsRowButtonTooltip.tsx index 5b4db10ed6b..f9a5c2d66f6 100644 --- a/src/components/views/messages/ReactionsRowButtonTooltip.tsx +++ b/src/components/views/messages/ReactionsRowButtonTooltip.tsx @@ -36,7 +36,7 @@ interface IProps { export default class ReactionsRowButtonTooltip extends React.PureComponent> { public static contextType = MatrixClientContext; - public context!: React.ContextType; + public declare context: React.ContextType; public render(): React.ReactNode { const { content, reactionEvents, mxEvent, children } = this.props; diff --git a/src/components/views/messages/TextualBody.tsx b/src/components/views/messages/TextualBody.tsx index 2133eb5fe82..5dba3e42b77 100644 --- a/src/components/views/messages/TextualBody.tsx +++ b/src/components/views/messages/TextualBody.tsx @@ -66,7 +66,7 @@ export default class TextualBody extends React.Component { private tooltips: Element[] = []; public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; public state = { links: [], diff --git a/src/components/views/right_panel/TimelineCard.tsx b/src/components/views/right_panel/TimelineCard.tsx index 67aca930909..97f5aabc320 100644 --- a/src/components/views/right_panel/TimelineCard.tsx +++ b/src/components/views/right_panel/TimelineCard.tsx @@ -77,7 +77,7 @@ interface IState { export default class TimelineCard extends React.Component { public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; private dispatcherRef?: string; private layoutWatcherRef?: string; diff --git a/src/components/views/room_settings/AliasSettings.tsx b/src/components/views/room_settings/AliasSettings.tsx index 3b2f294e5c1..a8fe6cdbe95 100644 --- a/src/components/views/room_settings/AliasSettings.tsx +++ b/src/components/views/room_settings/AliasSettings.tsx @@ -102,7 +102,7 @@ interface IState { export default class AliasSettings extends React.Component { public static contextType = MatrixClientContext; - public context!: ContextType; + public declare context: ContextType; public static defaultProps = { canSetAliases: false, diff --git a/src/components/views/rooms/Autocomplete.tsx b/src/components/views/rooms/Autocomplete.tsx index 840fd098da3..eb7c42ee7c8 100644 --- a/src/components/views/rooms/Autocomplete.tsx +++ b/src/components/views/rooms/Autocomplete.tsx @@ -56,7 +56,7 @@ export default class Autocomplete extends React.PureComponent { private containerRef = createRef(); public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; public constructor(props: IProps, context: React.ContextType) { super(props, context); diff --git a/src/components/views/rooms/EditMessageComposer.tsx b/src/components/views/rooms/EditMessageComposer.tsx index b379da2ea64..9b33f42914e 100644 --- a/src/components/views/rooms/EditMessageComposer.tsx +++ b/src/components/views/rooms/EditMessageComposer.tsx @@ -129,7 +129,7 @@ interface IState { class EditMessageComposer extends React.Component { public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; private readonly editorRef = createRef(); private readonly dispatcherRef: string; @@ -138,7 +138,6 @@ class EditMessageComposer extends React.Component) { super(props, context); - this.context = context; // otherwise React will only set it prior to render due to type def above const isRestored = this.createEditorModel(); const ev = this.props.editState.getEvent(); diff --git a/src/components/views/rooms/EventTile.tsx b/src/components/views/rooms/EventTile.tsx index 669e57a06a4..e0f8ab1161c 100644 --- a/src/components/views/rooms/EventTile.tsx +++ b/src/components/views/rooms/EventTile.tsx @@ -297,7 +297,7 @@ export class UnwrappedEventTile extends React.Component }; public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; private unmounted = false; diff --git a/src/components/views/rooms/LegacyRoomHeader.tsx b/src/components/views/rooms/LegacyRoomHeader.tsx index f16e324d80c..20c8357473b 100644 --- a/src/components/views/rooms/LegacyRoomHeader.tsx +++ b/src/components/views/rooms/LegacyRoomHeader.tsx @@ -493,7 +493,7 @@ export default class RoomHeader extends React.Component { }; public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; private readonly client = this.props.room.client; private readonly featureAskToJoinWatcher: string; diff --git a/src/components/views/rooms/MemberList.tsx b/src/components/views/rooms/MemberList.tsx index 1ffca0821cb..cb671035359 100644 --- a/src/components/views/rooms/MemberList.tsx +++ b/src/components/views/rooms/MemberList.tsx @@ -82,7 +82,7 @@ export default class MemberList extends React.Component { private mounted = false; public static contextType = SDKContext; - public context!: React.ContextType; + public declare context: React.ContextType; private tiles: Map = new Map(); public constructor(props: IProps, context: React.ContextType) { diff --git a/src/components/views/rooms/MessageComposer.tsx b/src/components/views/rooms/MessageComposer.tsx index d1a72a6988b..a4a73b495f1 100644 --- a/src/components/views/rooms/MessageComposer.tsx +++ b/src/components/views/rooms/MessageComposer.tsx @@ -119,7 +119,7 @@ export class MessageComposer extends React.Component { private _voiceRecording: Optional; public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; public static defaultProps = { compact: false, diff --git a/src/components/views/rooms/MessageComposerButtons.tsx b/src/components/views/rooms/MessageComposerButtons.tsx index 77d809d1f8d..dc5c14517b6 100644 --- a/src/components/views/rooms/MessageComposerButtons.tsx +++ b/src/components/views/rooms/MessageComposerButtons.tsx @@ -298,7 +298,7 @@ interface IPollButtonProps { class PollButton extends React.PureComponent { public static contextType = OverflowMenuContext; - public context!: React.ContextType; + public declare context: React.ContextType; private onCreateClick = (): void => { this.context?.(); // close overflow menu diff --git a/src/components/views/rooms/PinnedEventTile.tsx b/src/components/views/rooms/PinnedEventTile.tsx index 581583d1d5a..6c63efc3520 100644 --- a/src/components/views/rooms/PinnedEventTile.tsx +++ b/src/components/views/rooms/PinnedEventTile.tsx @@ -40,7 +40,7 @@ const AVATAR_SIZE = "24px"; export default class PinnedEventTile extends React.Component { public static contextType = MatrixClientContext; - public context!: React.ContextType; + public declare context: React.ContextType; private onTileClicked = (): void => { dis.dispatch({ diff --git a/src/components/views/rooms/ReplyPreview.tsx b/src/components/views/rooms/ReplyPreview.tsx index 009d8d21a50..431af5ce6ff 100644 --- a/src/components/views/rooms/ReplyPreview.tsx +++ b/src/components/views/rooms/ReplyPreview.tsx @@ -39,7 +39,7 @@ interface IProps { export default class ReplyPreview extends React.Component { public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; public render(): JSX.Element | null { if (!this.props.replyToEvent) return null; diff --git a/src/components/views/rooms/RoomList.tsx b/src/components/views/rooms/RoomList.tsx index 10fcca7709a..7d47748de80 100644 --- a/src/components/views/rooms/RoomList.tsx +++ b/src/components/views/rooms/RoomList.tsx @@ -432,7 +432,7 @@ export default class RoomList extends React.PureComponent { private treeRef = createRef(); public static contextType = MatrixClientContext; - public context!: React.ContextType; + public declare context: React.ContextType; public constructor(props: IProps, context: React.ContextType) { super(props, context); diff --git a/src/components/views/rooms/RoomUpgradeWarningBar.tsx b/src/components/views/rooms/RoomUpgradeWarningBar.tsx index 99ae4f7ba4b..ab374108e9d 100644 --- a/src/components/views/rooms/RoomUpgradeWarningBar.tsx +++ b/src/components/views/rooms/RoomUpgradeWarningBar.tsx @@ -33,7 +33,7 @@ interface IState { export default class RoomUpgradeWarningBar extends React.PureComponent { public static contextType = MatrixClientContext; - public context!: React.ContextType; + public declare context: React.ContextType; public constructor(props: IProps, context: React.ContextType) { super(props, context); diff --git a/src/components/views/rooms/SearchResultTile.tsx b/src/components/views/rooms/SearchResultTile.tsx index 99b5f0805c3..52977901cf9 100644 --- a/src/components/views/rooms/SearchResultTile.tsx +++ b/src/components/views/rooms/SearchResultTile.tsx @@ -44,7 +44,7 @@ interface IProps { export default class SearchResultTile extends React.Component { public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; // A map of private callEventGroupers = new Map(); diff --git a/src/components/views/rooms/SendMessageComposer.tsx b/src/components/views/rooms/SendMessageComposer.tsx index c5972ee86ac..eee2a476a7e 100644 --- a/src/components/views/rooms/SendMessageComposer.tsx +++ b/src/components/views/rooms/SendMessageComposer.tsx @@ -254,7 +254,7 @@ interface ISendMessageComposerProps extends MatrixClientProps { export class SendMessageComposer extends React.Component { public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; private readonly prepareToEncrypt?: DebouncedFunc<() => void>; private readonly editorRef = createRef(); @@ -269,7 +269,6 @@ export class SendMessageComposer extends React.Component) { super(props, context); - this.context = context; // otherwise React will only set it prior to render due to type def above if (this.props.mxClient.isCryptoEnabled() && this.props.mxClient.isRoomEncrypted(this.props.room.roomId)) { this.prepareToEncrypt = throttle( diff --git a/src/components/views/rooms/VoiceRecordComposerTile.tsx b/src/components/views/rooms/VoiceRecordComposerTile.tsx index 333bd248e10..4010adf283f 100644 --- a/src/components/views/rooms/VoiceRecordComposerTile.tsx +++ b/src/components/views/rooms/VoiceRecordComposerTile.tsx @@ -63,7 +63,7 @@ interface IState { */ export default class VoiceRecordComposerTile extends React.PureComponent { public static contextType = RoomContext; - public context!: React.ContextType; + public declare context: React.ContextType; private voiceRecordingId: string; public constructor(props: IProps, context: React.ContextType) { diff --git a/src/components/views/settings/tabs/room/BridgeSettingsTab.tsx b/src/components/views/settings/tabs/room/BridgeSettingsTab.tsx index cfe6b3ccd32..1f44f06323e 100644 --- a/src/components/views/settings/tabs/room/BridgeSettingsTab.tsx +++ b/src/components/views/settings/tabs/room/BridgeSettingsTab.tsx @@ -36,7 +36,7 @@ interface IProps { export default class BridgeSettingsTab extends React.Component { public static contextType = MatrixClientContext; - public context!: React.ContextType; + public declare context: React.ContextType; private renderBridgeCard(event: MatrixEvent, room: Room | null): ReactNode { const content = event.getContent(); diff --git a/src/components/views/settings/tabs/room/GeneralRoomSettingsTab.tsx b/src/components/views/settings/tabs/room/GeneralRoomSettingsTab.tsx index 7b260e3a7e6..97503ef50a7 100644 --- a/src/components/views/settings/tabs/room/GeneralRoomSettingsTab.tsx +++ b/src/components/views/settings/tabs/room/GeneralRoomSettingsTab.tsx @@ -42,7 +42,7 @@ interface IState { export default class GeneralRoomSettingsTab extends React.Component { public static contextType = MatrixClientContext; - public context!: ContextType; + public declare context: ContextType; public constructor(props: IProps, context: ContextType) { super(props, context); diff --git a/src/components/views/settings/tabs/room/NotificationSettingsTab.tsx b/src/components/views/settings/tabs/room/NotificationSettingsTab.tsx index 1c536ed6d64..1b0dbfdf1a9 100644 --- a/src/components/views/settings/tabs/room/NotificationSettingsTab.tsx +++ b/src/components/views/settings/tabs/room/NotificationSettingsTab.tsx @@ -50,7 +50,7 @@ export default class NotificationsSettingsTab extends React.Component(); public static contextType = MatrixClientContext; - public context!: React.ContextType; + public declare context: React.ContextType; public constructor(props: IProps, context: React.ContextType) { super(props, context); diff --git a/src/components/views/settings/tabs/room/RolesRoomSettingsTab.tsx b/src/components/views/settings/tabs/room/RolesRoomSettingsTab.tsx index 2197cad3dff..3105ba961a3 100644 --- a/src/components/views/settings/tabs/room/RolesRoomSettingsTab.tsx +++ b/src/components/views/settings/tabs/room/RolesRoomSettingsTab.tsx @@ -89,7 +89,7 @@ interface IBannedUserProps { export class BannedUser extends React.Component { public static contextType = MatrixClientContext; - public context!: React.ContextType; + public declare context: React.ContextType; private onUnbanClick = (): void => { this.context.unban(this.props.member.roomId, this.props.member.userId).catch((err) => { @@ -137,7 +137,7 @@ interface IProps { export default class RolesRoomSettingsTab extends React.Component { public static contextType = MatrixClientContext; - public context!: React.ContextType; + public declare context: React.ContextType; public componentDidMount(): void { this.context.on(RoomStateEvent.Update, this.onRoomStateUpdate); diff --git a/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx b/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx index 01fcbd1abb0..adbf1b72d96 100644 --- a/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx +++ b/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx @@ -67,7 +67,7 @@ interface IState { export default class SecurityRoomSettingsTab extends React.Component { public static contextType = MatrixClientContext; - public context!: React.ContextType; + public declare context: React.ContextType; public constructor(props: IProps, context: React.ContextType) { super(props, context); diff --git a/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx b/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx index eace2caa8de..867b986c820 100644 --- a/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx @@ -40,7 +40,7 @@ interface IState { export default class HelpUserSettingsTab extends React.Component { public static contextType = MatrixClientContext; - public context!: React.ContextType; + public declare context: React.ContextType; public constructor(props: IProps, context: React.ContextType) { super(props, context); diff --git a/src/components/views/settings/tabs/user/VoiceUserSettingsTab.tsx b/src/components/views/settings/tabs/user/VoiceUserSettingsTab.tsx index ad8de753384..c3d21205ff0 100644 --- a/src/components/views/settings/tabs/user/VoiceUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/VoiceUserSettingsTab.tsx @@ -59,7 +59,7 @@ const mapDeviceKindToHandlerValue = (deviceKind: MediaDeviceKindEnum): string | export default class VoiceUserSettingsTab extends React.Component<{}, IState> { public static contextType = MatrixClientContext; - public context!: React.ContextType; + public declare context: React.ContextType; public constructor(props: {}, context: React.ContextType) { super(props, context); diff --git a/src/models/Call.ts b/src/models/Call.ts index 7935025e5b2..658cb780487 100644 --- a/src/models/Call.ts +++ b/src/models/Call.ts @@ -126,8 +126,8 @@ interface CallEventHandlerMap { * A group call accessed through a widget. */ export abstract class Call extends TypedEventEmitter { - protected readonly widgetUid = WidgetUtils.getWidgetUid(this.widget); - protected readonly room = this.client.getRoom(this.roomId)!; + protected readonly widgetUid: string; + protected readonly room: Room; /** * The time after which device member state should be considered expired. @@ -184,6 +184,8 @@ export abstract class Call extends TypedEventEmitter; + public declare context: React.ContextType; public getTextFor(event: MatrixEvent, tagId?: TagID, isThread?: boolean): string | null { let eventContent = event.getContent(); diff --git a/src/utils/MegolmExportEncryption.ts b/src/utils/MegolmExportEncryption.ts index de6ffea5f1c..fc0958c1795 100644 --- a/src/utils/MegolmExportEncryption.ts +++ b/src/utils/MegolmExportEncryption.ts @@ -20,7 +20,7 @@ import { logger } from "matrix-js-sdk/src/logger"; import { _t } from "../languageHandler"; import SdkConfig from "../SdkConfig"; -const subtleCrypto = window.crypto.subtle || window.crypto.webkitSubtle; +const subtleCrypto = window.crypto.subtle; /** * Make an Error object which has a friendlyText property which is already diff --git a/test/TestSdkContext.ts b/test/TestSdkContext.ts index 5aad5bcfa51..154881db530 100644 --- a/test/TestSdkContext.ts +++ b/test/TestSdkContext.ts @@ -35,18 +35,18 @@ import { * replace individual stores. This is useful for tests which need to mock out stores. */ export class TestSdkContext extends SdkContextClass { - public _RightPanelStore?: RightPanelStore; - public _RoomNotificationStateStore?: RoomNotificationStateStore; - public _RoomViewStore?: RoomViewStore; - public _WidgetPermissionStore?: WidgetPermissionStore; - public _WidgetLayoutStore?: WidgetLayoutStore; - public _WidgetStore?: WidgetStore; - public _PosthogAnalytics?: PosthogAnalytics; - public _SlidingSyncManager?: SlidingSyncManager; - public _SpaceStore?: SpaceStoreClass; - public _VoiceBroadcastRecordingsStore?: VoiceBroadcastRecordingsStore; - public _VoiceBroadcastPreRecordingStore?: VoiceBroadcastPreRecordingStore; - public _VoiceBroadcastPlaybacksStore?: VoiceBroadcastPlaybacksStore; + public declare _RightPanelStore?: RightPanelStore; + public declare _RoomNotificationStateStore?: RoomNotificationStateStore; + public declare _RoomViewStore?: RoomViewStore; + public declare _WidgetPermissionStore?: WidgetPermissionStore; + public declare _WidgetLayoutStore?: WidgetLayoutStore; + public declare _WidgetStore?: WidgetStore; + public declare _PosthogAnalytics?: PosthogAnalytics; + public declare _SlidingSyncManager?: SlidingSyncManager; + public declare _SpaceStore?: SpaceStoreClass; + public declare _VoiceBroadcastRecordingsStore?: VoiceBroadcastRecordingsStore; + public declare _VoiceBroadcastPreRecordingStore?: VoiceBroadcastPreRecordingStore; + public declare _VoiceBroadcastPlaybacksStore?: VoiceBroadcastPlaybacksStore; constructor() { super(); diff --git a/test/test-utils/call.ts b/test/test-utils/call.ts index e97c7a59e9b..21672b98867 100644 --- a/test/test-utils/call.ts +++ b/test/test-utils/call.ts @@ -43,6 +43,7 @@ export class MockedCall extends Call { }, room.client, ); + this.groupCall = { creationTs: this.event.getTs() } as unknown as GroupCall; } public static get(room: Room): MockedCall | null { @@ -67,7 +68,7 @@ export class MockedCall extends Call { CallStore.instance.updateRoom(room); } - public readonly groupCall = { creationTs: this.event.getTs() } as unknown as GroupCall; + public readonly groupCall: GroupCall; public get participants(): Map> { return super.participants; diff --git a/tsconfig.json b/tsconfig.json index 3118f598c4c..55e83d95b97 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,9 +4,10 @@ "emitDecoratorMetadata": false, "resolveJsonModule": true, "esModuleInterop": true, + "useDefineForClassFields": true, "module": "es2022", "moduleResolution": "node", - "target": "es2018", + "target": "es2022", "noUnusedLocals": true, "sourceMap": false, "outDir": "./lib",