mirror of https://github.com/vector-im/riot-web
Conform more of the codebase to strictNullChecks (#10800)
parent
adb29b38a3
commit
456c66db5b
|
@ -652,9 +652,9 @@ export default class LegacyCallHandler extends EventEmitter {
|
|||
}
|
||||
|
||||
private onCallStateChanged = (newState: CallState, oldState: CallState | null, call: MatrixCall): void => {
|
||||
if (!this.matchesCallForThisRoom(call)) return;
|
||||
|
||||
const mappedRoomId = this.roomIdForCall(call);
|
||||
if (!mappedRoomId || !this.matchesCallForThisRoom(call)) return;
|
||||
|
||||
this.setCallState(call, newState);
|
||||
dis.dispatch({
|
||||
action: "call_state",
|
||||
|
|
|
@ -60,7 +60,7 @@ export class PlaybackClock implements IDestroyable {
|
|||
private stopped = true;
|
||||
private lastCheck = 0;
|
||||
private observable = new SimpleObservable<number[]>();
|
||||
private timerId: number;
|
||||
private timerId?: number;
|
||||
private clipDuration = 0;
|
||||
private placeholderDuration = 0;
|
||||
|
||||
|
|
|
@ -33,9 +33,9 @@ export interface IUpload {
|
|||
* This class can be used to record a single voice message.
|
||||
*/
|
||||
export class VoiceMessageRecording implements IDestroyable {
|
||||
private lastUpload: IUpload;
|
||||
private lastUpload?: IUpload;
|
||||
private buffer = new Uint8Array(0); // use this.audioBuffer to access
|
||||
private playback: Playback;
|
||||
private playback?: Playback;
|
||||
|
||||
public constructor(private matrixClient: MatrixClient, private voiceRecording: VoiceRecording) {
|
||||
this.voiceRecording.onDataAvailable = this.onDataAvailable;
|
||||
|
|
|
@ -243,7 +243,7 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
|
|||
return;
|
||||
}
|
||||
|
||||
const secondsLeft = TARGET_MAX_LENGTH - this.recorderSeconds;
|
||||
const secondsLeft = TARGET_MAX_LENGTH - this.recorderSeconds!;
|
||||
if (secondsLeft < 0) {
|
||||
// go over to make sure we definitely capture that last frame
|
||||
// noinspection JSIgnoredPromiseFromCall - we aren't concerned with it overlapping
|
||||
|
@ -259,7 +259,8 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
|
|||
/**
|
||||
* {@link https://github.com/chris-rudmin/opus-recorder#instance-fields ref for recorderSeconds}
|
||||
*/
|
||||
public get recorderSeconds(): number {
|
||||
public get recorderSeconds(): number | undefined {
|
||||
if (!this.recorder) return undefined;
|
||||
return this.recorder.encodedSamplePosition / 48000;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ export default class IndicatorScrollbar<T extends keyof JSX.IntrinsicElements> e
|
|||
IState
|
||||
> {
|
||||
private autoHideScrollbar = createRef<AutoHideScrollbar<any>>();
|
||||
private scrollElement: HTMLDivElement;
|
||||
private scrollElement?: HTMLDivElement;
|
||||
private likelyTrackpadUser: boolean | null = null;
|
||||
private checkAgainForTrackpad = 0; // ts in milliseconds to recheck this._likelyTrackpadUser
|
||||
|
||||
|
@ -85,6 +85,7 @@ export default class IndicatorScrollbar<T extends keyof JSX.IntrinsicElements> e
|
|||
}
|
||||
|
||||
private checkOverflow = (): void => {
|
||||
if (!this.scrollElement) return;
|
||||
const hasTopOverflow = this.scrollElement.scrollTop > 0;
|
||||
const hasBottomOverflow =
|
||||
this.scrollElement.scrollHeight > this.scrollElement.scrollTop + this.scrollElement.clientHeight;
|
||||
|
|
|
@ -73,7 +73,7 @@ export function buildLegacyCallEventGroupers(
|
|||
export default class LegacyCallEventGrouper extends EventEmitter {
|
||||
private events: Set<MatrixEvent> = new Set<MatrixEvent>();
|
||||
private call: MatrixCall | null = null;
|
||||
public state: CallState | CustomCallState;
|
||||
public state?: CallState | CustomCallState;
|
||||
|
||||
public constructor() {
|
||||
super();
|
||||
|
|
|
@ -96,10 +96,10 @@ interface IProps {
|
|||
autoJoin?: boolean;
|
||||
threepidInvite?: IThreepidInvite;
|
||||
roomOobData?: IOOBData;
|
||||
currentRoomId: string;
|
||||
currentRoomId: string | null;
|
||||
collapseLhs: boolean;
|
||||
config: ConfigOptions;
|
||||
currentUserId: string;
|
||||
currentUserId: string | null;
|
||||
justRegistered?: boolean;
|
||||
roomJustCreatedOpts?: IOpts;
|
||||
forceTimeline?: boolean; // see props on MatrixChat
|
||||
|
@ -131,10 +131,10 @@ class LoggedInView extends React.Component<IProps, IState> {
|
|||
protected readonly _roomView: React.RefObject<RoomViewType>;
|
||||
protected readonly _resizeContainer: React.RefObject<HTMLDivElement>;
|
||||
protected readonly resizeHandler: React.RefObject<HTMLDivElement>;
|
||||
protected layoutWatcherRef: string;
|
||||
protected compactLayoutWatcherRef: string;
|
||||
protected backgroundImageWatcherRef: string;
|
||||
protected resizer: Resizer;
|
||||
protected layoutWatcherRef?: string;
|
||||
protected compactLayoutWatcherRef?: string;
|
||||
protected backgroundImageWatcherRef?: string;
|
||||
protected resizer?: Resizer;
|
||||
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
@ -200,10 +200,10 @@ class LoggedInView extends React.Component<IProps, IState> {
|
|||
this._matrixClient.removeListener(ClientEvent.Sync, this.onSync);
|
||||
this._matrixClient.removeListener(RoomStateEvent.Events, this.onRoomStateEvents);
|
||||
OwnProfileStore.instance.off(UPDATE_EVENT, this.refreshBackgroundImage);
|
||||
SettingsStore.unwatchSetting(this.layoutWatcherRef);
|
||||
SettingsStore.unwatchSetting(this.compactLayoutWatcherRef);
|
||||
SettingsStore.unwatchSetting(this.backgroundImageWatcherRef);
|
||||
this.resizer.detach();
|
||||
if (this.layoutWatcherRef) SettingsStore.unwatchSetting(this.layoutWatcherRef);
|
||||
if (this.compactLayoutWatcherRef) SettingsStore.unwatchSetting(this.compactLayoutWatcherRef);
|
||||
if (this.backgroundImageWatcherRef) SettingsStore.unwatchSetting(this.backgroundImageWatcherRef);
|
||||
this.resizer?.detach();
|
||||
}
|
||||
|
||||
private onCallState = (): void => {
|
||||
|
@ -274,7 +274,7 @@ class LoggedInView extends React.Component<IProps, IState> {
|
|||
if (isNaN(lhsSize)) {
|
||||
lhsSize = 350;
|
||||
}
|
||||
this.resizer.forHandleWithId("lp-resizer")?.resize(lhsSize);
|
||||
this.resizer?.forHandleWithId("lp-resizer")?.resize(lhsSize);
|
||||
}
|
||||
|
||||
private onAccountData = (event: MatrixEvent): void => {
|
||||
|
@ -645,7 +645,11 @@ class LoggedInView extends React.Component<IProps, IState> {
|
|||
break;
|
||||
|
||||
case PageTypes.UserView:
|
||||
pageElement = <UserView userId={this.props.currentUserId} resizeNotifier={this.props.resizeNotifier} />;
|
||||
if (!!this.props.currentUserId) {
|
||||
pageElement = (
|
||||
<UserView userId={this.props.currentUserId} resizeNotifier={this.props.resizeNotifier} />
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -231,7 +231,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
|||
private focusComposer: boolean;
|
||||
private subTitleStatus: string;
|
||||
private prevWindowWidth: number;
|
||||
private voiceBroadcastResumer: VoiceBroadcastResumer;
|
||||
private voiceBroadcastResumer?: VoiceBroadcastResumer;
|
||||
|
||||
private readonly loggedInView: React.RefObject<LoggedInViewType>;
|
||||
private readonly dispatcherRef: string;
|
||||
|
@ -441,7 +441,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
|||
window.removeEventListener("resize", this.onWindowResized);
|
||||
|
||||
this.stores.accountPasswordStore.clearPassword();
|
||||
if (this.voiceBroadcastResumer) this.voiceBroadcastResumer.destroy();
|
||||
this.voiceBroadcastResumer?.destroy();
|
||||
}
|
||||
|
||||
private onWindowResized = (): void => {
|
||||
|
@ -1935,7 +1935,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
|||
private setPageSubtitle(subtitle = ""): void {
|
||||
if (this.state.currentRoomId) {
|
||||
const client = MatrixClientPeg.get();
|
||||
const room = client && client.getRoom(this.state.currentRoomId);
|
||||
const room = client?.getRoom(this.state.currentRoomId);
|
||||
if (room) {
|
||||
subtitle = `${this.subTitleStatus} | ${room.name} ${subtitle}`;
|
||||
}
|
||||
|
|
|
@ -179,7 +179,7 @@ export default class ScrollPanel extends React.Component<IProps> {
|
|||
};
|
||||
private readonly itemlist = createRef<HTMLOListElement>();
|
||||
private unmounted = false;
|
||||
private scrollTimeout: Timer;
|
||||
private scrollTimeout?: Timer;
|
||||
// Are we currently trying to backfill?
|
||||
private isFilling: boolean;
|
||||
// Is the current fill request caused by a props update?
|
||||
|
@ -189,8 +189,8 @@ export default class ScrollPanel extends React.Component<IProps> {
|
|||
// Is that next fill request scheduled because of a props update?
|
||||
private pendingFillDueToPropsUpdate: boolean;
|
||||
private scrollState: IScrollState;
|
||||
private preventShrinkingState: IPreventShrinkingState | null;
|
||||
private unfillDebouncer: number | null;
|
||||
private preventShrinkingState: IPreventShrinkingState | null = null;
|
||||
private unfillDebouncer: number | null = null;
|
||||
private bottomGrowth: number;
|
||||
private minListHeight: number;
|
||||
private heightUpdateInProgress: boolean;
|
||||
|
@ -234,7 +234,7 @@ export default class ScrollPanel extends React.Component<IProps> {
|
|||
// skip scroll events caused by resizing
|
||||
if (this.props.resizeNotifier && this.props.resizeNotifier.isResizing) return;
|
||||
debuglog("onScroll called past resize gate; scroll node top:", this.getScrollNode().scrollTop);
|
||||
this.scrollTimeout.restart();
|
||||
this.scrollTimeout?.restart();
|
||||
this.saveScrollState();
|
||||
this.updatePreventShrinking();
|
||||
this.props.onScroll?.(ev);
|
||||
|
@ -725,7 +725,7 @@ export default class ScrollPanel extends React.Component<IProps> {
|
|||
// need a better name that also indicates this will change scrollTop? Rebalance height? Reveal content?
|
||||
private async updateHeight(): Promise<void> {
|
||||
// wait until user has stopped scrolling
|
||||
if (this.scrollTimeout.isRunning()) {
|
||||
if (this.scrollTimeout?.isRunning()) {
|
||||
debuglog("updateHeight waiting for scrolling to end ... ");
|
||||
await this.scrollTimeout.finished();
|
||||
debuglog("updateHeight actually running now");
|
||||
|
|
|
@ -88,9 +88,9 @@ export default class UserMenu extends React.Component<IProps, IState> {
|
|||
public static contextType = SDKContext;
|
||||
public context!: React.ContextType<typeof SDKContext>;
|
||||
|
||||
private dispatcherRef: string;
|
||||
private themeWatcherRef: string;
|
||||
private readonly dndWatcherRef: string;
|
||||
private dispatcherRef?: string;
|
||||
private themeWatcherRef?: string;
|
||||
private readonly dndWatcherRef?: string;
|
||||
private buttonRef: React.RefObject<HTMLButtonElement> = createRef();
|
||||
|
||||
public constructor(props: IProps, context: React.ContextType<typeof SDKContext>) {
|
||||
|
|
|
@ -125,7 +125,7 @@ interface IState {
|
|||
export default class Registration extends React.Component<IProps, IState> {
|
||||
private readonly loginLogic: Login;
|
||||
// `replaceClient` tracks latest serverConfig to spot when it changes under the async method which fetches flows
|
||||
private latestServerConfig: ValidatedServerConfig;
|
||||
private latestServerConfig?: ValidatedServerConfig;
|
||||
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
|
|
@ -556,8 +556,8 @@ export class MsisdnAuthEntry extends React.Component<IMsisdnAuthEntryProps, IMsi
|
|||
public static LOGIN_TYPE = AuthType.Msisdn;
|
||||
|
||||
private submitUrl?: string;
|
||||
private sid: string;
|
||||
private msisdn: string;
|
||||
private sid?: string;
|
||||
private msisdn?: string;
|
||||
|
||||
public constructor(props: IMsisdnAuthEntryProps) {
|
||||
super(props);
|
||||
|
@ -615,8 +615,8 @@ export class MsisdnAuthEntry extends React.Component<IMsisdnAuthEntryProps, IMsi
|
|||
});
|
||||
|
||||
try {
|
||||
let result;
|
||||
if (this.submitUrl) {
|
||||
let result: { success: boolean };
|
||||
if (this.submitUrl && this.sid) {
|
||||
result = await this.props.matrixClient.submitMsisdnTokenOtherUrl(
|
||||
this.submitUrl,
|
||||
this.sid,
|
||||
|
|
|
@ -19,7 +19,7 @@ import React, { ChangeEvent } from "react";
|
|||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
import { _t } from "../../../languageHandler";
|
||||
import { _t, UserFriendlyError } from "../../../languageHandler";
|
||||
import { ensureDMExists } from "../../../createRoom";
|
||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
import SdkConfig from "../../../SdkConfig";
|
||||
|
@ -245,6 +245,10 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
|
|||
// Report to moderators through to the dedicated bot,
|
||||
// as configured in the room's state events.
|
||||
const dmRoomId = await ensureDMExists(client, this.moderation.moderationBotUserId);
|
||||
if (!dmRoomId) {
|
||||
throw new UserFriendlyError("Unable to create room with moderation bot");
|
||||
}
|
||||
|
||||
await client.sendEvent(dmRoomId, ABUSE_EVENT_TYPE, {
|
||||
event_id: ev.getId(),
|
||||
room_id: ev.getRoomId(),
|
||||
|
|
|
@ -62,7 +62,7 @@ interface IState {
|
|||
}
|
||||
|
||||
class RoomSettingsDialog extends React.Component<IProps, IState> {
|
||||
private dispatcherRef: string;
|
||||
private dispatcherRef?: string;
|
||||
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
|
|
@ -35,7 +35,7 @@ interface IState {
|
|||
}
|
||||
|
||||
export default class RoomUpgradeDialog extends React.Component<IProps, IState> {
|
||||
private targetVersion: string;
|
||||
private targetVersion?: string;
|
||||
|
||||
public state = {
|
||||
busy: true,
|
||||
|
@ -53,7 +53,7 @@ export default class RoomUpgradeDialog extends React.Component<IProps, IState> {
|
|||
|
||||
private onUpgradeClick = (): void => {
|
||||
this.setState({ busy: true });
|
||||
upgradeRoom(this.props.room, this.targetVersion, false, false)
|
||||
upgradeRoom(this.props.room, this.targetVersion!, false, false)
|
||||
.then(() => {
|
||||
this.props.onFinished(true);
|
||||
})
|
||||
|
@ -69,7 +69,7 @@ export default class RoomUpgradeDialog extends React.Component<IProps, IState> {
|
|||
};
|
||||
|
||||
public render(): React.ReactNode {
|
||||
let buttons;
|
||||
let buttons: JSX.Element;
|
||||
if (this.state.busy) {
|
||||
buttons = <Spinner />;
|
||||
} else {
|
||||
|
|
|
@ -44,7 +44,7 @@ interface IState {
|
|||
export default class ServerPickerDialog extends React.PureComponent<IProps, IState> {
|
||||
private readonly defaultServer: ValidatedServerConfig;
|
||||
private readonly fieldRef = createRef<Field>();
|
||||
private validatedConf: ValidatedServerConfig;
|
||||
private validatedConf?: ValidatedServerConfig;
|
||||
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
@ -85,7 +85,7 @@ export default class ServerPickerDialog extends React.PureComponent<IProps, ISta
|
|||
// find their homeserver without demanding they use "https://matrix.org"
|
||||
private validate = withValidation<this, { error?: string }>({
|
||||
deriveData: async ({ value }): Promise<{ error?: string }> => {
|
||||
let hsUrl = value.trim(); // trim to account for random whitespace
|
||||
let hsUrl = (value ?? "").trim(); // trim to account for random whitespace
|
||||
|
||||
// if the URL has no protocol, try validate it as a serverName via well-known
|
||||
if (!hsUrl.includes("://")) {
|
||||
|
|
|
@ -45,7 +45,7 @@ interface IState {
|
|||
* On success, `onFinished(true)` is called.
|
||||
*/
|
||||
export default class SetEmailDialog extends React.Component<IProps, IState> {
|
||||
private addThreepid: AddThreepid;
|
||||
private addThreepid?: AddThreepid;
|
||||
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
@ -109,7 +109,7 @@ export default class SetEmailDialog extends React.Component<IProps, IState> {
|
|||
};
|
||||
|
||||
private verifyEmailAddress(): void {
|
||||
this.addThreepid.checkEmailLinkClicked().then(
|
||||
this.addThreepid?.checkEmailLinkClicked().then(
|
||||
() => {
|
||||
this.props.onFinished(true);
|
||||
},
|
||||
|
|
|
@ -121,11 +121,11 @@ export default class AppTile extends React.Component<IProps, IState> {
|
|||
};
|
||||
|
||||
private contextMenuButton = createRef<any>();
|
||||
private iframe: HTMLIFrameElement; // ref to the iframe (callback style)
|
||||
private allowedWidgetsWatchRef: string;
|
||||
private iframe?: HTMLIFrameElement; // ref to the iframe (callback style)
|
||||
private allowedWidgetsWatchRef?: string;
|
||||
private persistKey: string;
|
||||
private sgWidget: StopGapWidget | null;
|
||||
private dispatcherRef: string;
|
||||
private dispatcherRef?: string;
|
||||
private unmounted: boolean;
|
||||
|
||||
public constructor(props: IProps) {
|
||||
|
@ -305,7 +305,7 @@ export default class AppTile extends React.Component<IProps, IState> {
|
|||
this.context.off(RoomEvent.MyMembership, this.onMyMembership);
|
||||
}
|
||||
|
||||
SettingsStore.unwatchSetting(this.allowedWidgetsWatchRef);
|
||||
if (this.allowedWidgetsWatchRef) SettingsStore.unwatchSetting(this.allowedWidgetsWatchRef);
|
||||
OwnProfileStore.instance.removeListener(UPDATE_EVENT, this.onUserReady);
|
||||
}
|
||||
|
||||
|
@ -344,7 +344,7 @@ export default class AppTile extends React.Component<IProps, IState> {
|
|||
|
||||
private startMessaging(): void {
|
||||
try {
|
||||
this.sgWidget?.startMessaging(this.iframe);
|
||||
this.sgWidget?.startMessaging(this.iframe!);
|
||||
} catch (e) {
|
||||
logger.error("Failed to start widget", e);
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ export interface PickerIProps {
|
|||
type TabId = "screen" | "window";
|
||||
|
||||
export default class DesktopCapturerSourcePicker extends React.Component<PickerIProps, PickerIState> {
|
||||
public interval: number;
|
||||
public interval?: number;
|
||||
|
||||
public constructor(props: PickerIProps) {
|
||||
super(props);
|
||||
|
|
|
@ -75,8 +75,8 @@ interface IProps {
|
|||
export default class PersistedElement extends React.Component<IProps> {
|
||||
private resizeObserver: ResizeObserver;
|
||||
private dispatcherRef: string;
|
||||
private childContainer: HTMLDivElement;
|
||||
private child: HTMLDivElement;
|
||||
private childContainer?: HTMLDivElement;
|
||||
private child?: HTMLDivElement;
|
||||
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
@ -172,12 +172,12 @@ export default class PersistedElement extends React.Component<IProps> {
|
|||
ReactDOM.render(content, getOrCreateContainer("mx_persistedElement_" + this.props.persistKey));
|
||||
}
|
||||
|
||||
private updateChildVisibility(child: HTMLDivElement, visible: boolean): void {
|
||||
private updateChildVisibility(child?: HTMLDivElement, visible = false): void {
|
||||
if (!child) return;
|
||||
child.style.display = visible ? "block" : "none";
|
||||
}
|
||||
|
||||
private updateChildPosition(child: HTMLDivElement, parent: HTMLDivElement): void {
|
||||
private updateChildPosition(child?: HTMLDivElement, parent?: HTMLDivElement): void {
|
||||
if (!child || !parent) return;
|
||||
|
||||
const parentRect = parent.getBoundingClientRect();
|
||||
|
|
|
@ -17,5 +17,5 @@ limitations under the License.
|
|||
import { MediaEventHelper } from "../../../utils/MediaEventHelper";
|
||||
|
||||
export interface IMediaBody {
|
||||
getMediaHelper(): MediaEventHelper;
|
||||
getMediaHelper(): MediaEventHelper | undefined;
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ interface IState {
|
|||
|
||||
export default class LegacyCallEvent extends React.PureComponent<IProps, IState> {
|
||||
private wrapperElement = createRef<HTMLDivElement>();
|
||||
private resizeObserver: ResizeObserver;
|
||||
private resizeObserver?: ResizeObserver;
|
||||
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
@ -75,7 +75,7 @@ export default class LegacyCallEvent extends React.PureComponent<IProps, IState>
|
|||
this.props.callEventGrouper.removeListener(LegacyCallEventGrouperEvent.SilencedChanged, this.onSilencedChanged);
|
||||
this.props.callEventGrouper.removeListener(LegacyCallEventGrouperEvent.LengthChanged, this.onLengthChanged);
|
||||
|
||||
this.resizeObserver.disconnect();
|
||||
this.resizeObserver?.disconnect();
|
||||
}
|
||||
|
||||
private onLengthChanged = (length: number): void => {
|
||||
|
|
|
@ -69,7 +69,7 @@ export default class MImageBody extends React.Component<IBodyProps, IState> {
|
|||
private unmounted = true;
|
||||
private image = createRef<HTMLImageElement>();
|
||||
private timeout?: number;
|
||||
private sizeWatcher: string;
|
||||
private sizeWatcher?: string;
|
||||
private reconnectedListener: ClientEventHandlerMap[ClientEvent.Sync];
|
||||
|
||||
public constructor(props: IBodyProps) {
|
||||
|
@ -367,7 +367,7 @@ export default class MImageBody extends React.Component<IBodyProps, IState> {
|
|||
this.unmounted = true;
|
||||
MatrixClientPeg.get().off(ClientEvent.Sync, this.reconnectedListener);
|
||||
this.clearBlurhashTimeout();
|
||||
SettingsStore.unwatchSetting(this.sizeWatcher);
|
||||
if (this.sizeWatcher) SettingsStore.unwatchSetting(this.sizeWatcher);
|
||||
if (this.state.isAnimated && this.state.thumbUrl) {
|
||||
URL.revokeObjectURL(this.state.thumbUrl);
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ export default class MVideoBody extends React.PureComponent<IBodyProps, IState>
|
|||
public context!: React.ContextType<typeof RoomContext>;
|
||||
|
||||
private videoRef = React.createRef<HTMLVideoElement>();
|
||||
private sizeWatcher: string;
|
||||
private sizeWatcher?: string;
|
||||
|
||||
public constructor(props: IBodyProps) {
|
||||
super(props);
|
||||
|
@ -187,7 +187,7 @@ export default class MVideoBody extends React.PureComponent<IBodyProps, IState>
|
|||
}
|
||||
|
||||
public componentWillUnmount(): void {
|
||||
SettingsStore.unwatchSetting(this.sizeWatcher);
|
||||
if (this.sizeWatcher) SettingsStore.unwatchSetting(this.sizeWatcher);
|
||||
}
|
||||
|
||||
private videoOnPlay = async (): Promise<void> => {
|
||||
|
|
|
@ -82,7 +82,7 @@ const baseEvTypes = new Map<string, React.ComponentType<Partial<IBodyProps>>>([
|
|||
|
||||
export default class MessageEvent extends React.Component<IProps> implements IMediaBody, IOperableEventTile {
|
||||
private body: React.RefObject<React.Component | IOperableEventTile> = createRef();
|
||||
private mediaHelper: MediaEventHelper;
|
||||
private mediaHelper?: MediaEventHelper;
|
||||
private bodyTypes = new Map<string, typeof React.Component>(baseBodyTypes.entries());
|
||||
private evTypes = new Map<string, React.ComponentType<Partial<IBodyProps>>>(baseEvTypes.entries());
|
||||
|
||||
|
@ -133,7 +133,7 @@ export default class MessageEvent extends React.Component<IProps> implements IMe
|
|||
return (this.body.current as IOperableEventTile)?.getEventTileOps?.() || null;
|
||||
};
|
||||
|
||||
public getMediaHelper(): MediaEventHelper {
|
||||
public getMediaHelper(): MediaEventHelper | undefined {
|
||||
return this.mediaHelper;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,9 +57,9 @@ interface IState {
|
|||
|
||||
export default class AppsDrawer extends React.Component<IProps, IState> {
|
||||
private unmounted = false;
|
||||
private resizeContainer: HTMLDivElement;
|
||||
private resizeContainer?: HTMLDivElement;
|
||||
private resizer: Resizer;
|
||||
private dispatcherRef: string;
|
||||
private dispatcherRef?: string;
|
||||
public static defaultProps: Partial<IProps> = {
|
||||
showApps: true,
|
||||
};
|
||||
|
@ -113,11 +113,11 @@ export default class AppsDrawer extends React.Component<IProps, IState> {
|
|||
};
|
||||
const collapseConfig = {
|
||||
onResizeStart: () => {
|
||||
this.resizeContainer.classList.add("mx_AppsDrawer_resizing");
|
||||
this.resizeContainer?.classList.add("mx_AppsDrawer_resizing");
|
||||
this.setState({ resizingHorizontal: true });
|
||||
},
|
||||
onResizeStop: () => {
|
||||
this.resizeContainer.classList.remove("mx_AppsDrawer_resizing");
|
||||
this.resizeContainer?.classList.remove("mx_AppsDrawer_resizing");
|
||||
WidgetLayoutStore.instance.setResizerDistributions(
|
||||
this.props.room,
|
||||
Container.Top,
|
||||
|
|
|
@ -133,9 +133,9 @@ export default class Autocomplete extends React.PureComponent<IProps, IState> {
|
|||
});
|
||||
}
|
||||
|
||||
private processQuery(query: string, selection: ISelectionRange): Promise<void> {
|
||||
private async processQuery(query: string, selection: ISelectionRange): Promise<void> {
|
||||
return this.autocompleter
|
||||
.getCompletions(query, selection, this.state.forceComplete, MAX_PROVIDER_MATCHES)
|
||||
?.getCompletions(query, selection, this.state.forceComplete, MAX_PROVIDER_MATCHES)
|
||||
.then((completions) => {
|
||||
// Only ever process the completions for the most recent query being processed
|
||||
if (query !== this.queryRequested) {
|
||||
|
|
|
@ -129,7 +129,7 @@ class EditMessageComposer extends React.Component<IEditMessageComposerProps, ISt
|
|||
private readonly editorRef = createRef<BasicMessageComposer>();
|
||||
private readonly dispatcherRef: string;
|
||||
private readonly replyToEvent?: MatrixEvent;
|
||||
private model: EditorModel;
|
||||
private model!: EditorModel;
|
||||
|
||||
public constructor(props: IEditMessageComposerProps, context: React.ContextType<typeof RoomContext>) {
|
||||
super(props);
|
||||
|
|
|
@ -46,8 +46,8 @@ interface IState {
|
|||
}
|
||||
|
||||
export default class MemberTile extends React.Component<IProps, IState> {
|
||||
private userLastModifiedTime: number;
|
||||
private memberLastModifiedTime: number;
|
||||
private userLastModifiedTime?: number;
|
||||
private memberLastModifiedTime?: number;
|
||||
|
||||
public static defaultProps = {
|
||||
showPresence: true,
|
||||
|
|
|
@ -443,7 +443,7 @@ const TAG_AESTHETICS: TagAestheticsMap = {
|
|||
export default class RoomList extends React.PureComponent<IProps, IState> {
|
||||
private dispatcherRef?: string;
|
||||
private treeRef = createRef<HTMLDivElement>();
|
||||
private favouriteMessageWatcher: string;
|
||||
private favouriteMessageWatcher?: string;
|
||||
|
||||
public static contextType = MatrixClientContext;
|
||||
public context!: React.ContextType<typeof MatrixClientContext>;
|
||||
|
@ -476,7 +476,7 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
|
|||
public componentWillUnmount(): void {
|
||||
SpaceStore.instance.off(UPDATE_SUGGESTED_ROOMS, this.updateSuggestedRooms);
|
||||
RoomListStore.instance.off(LISTS_UPDATE_EVENT, this.updateLists);
|
||||
SettingsStore.unwatchSetting(this.favouriteMessageWatcher);
|
||||
if (this.favouriteMessageWatcher) SettingsStore.unwatchSetting(this.favouriteMessageWatcher);
|
||||
if (this.dispatcherRef) defaultDispatcher.unregister(this.dispatcherRef);
|
||||
SdkContextClass.instance.roomViewStore.off(UPDATE_EVENT, this.onRoomViewStoreUpdate);
|
||||
}
|
||||
|
|
|
@ -215,8 +215,10 @@ export default class RoomPreviewBar extends React.Component<IProps, IState> {
|
|||
if (!myMember) {
|
||||
return {};
|
||||
}
|
||||
const kickerMember = this.props.room?.currentState.getMember(myMember.events.member.getSender());
|
||||
const memberName = kickerMember?.name ?? myMember.events.member?.getSender();
|
||||
|
||||
const kickerUserId = myMember.events.member?.getSender();
|
||||
const kickerMember = kickerUserId ? this.props.room?.currentState.getMember(kickerUserId) : undefined;
|
||||
const memberName = kickerMember?.name ?? kickerUserId;
|
||||
const reason = myMember.events.member?.getContent().reason;
|
||||
return { memberName, reason };
|
||||
}
|
||||
|
@ -559,7 +561,7 @@ export default class RoomPreviewBar extends React.Component<IProps, IState> {
|
|||
"%(errcode)s was returned while trying to access the room or space. " +
|
||||
"If you think you're seeing this message in error, please " +
|
||||
"<issueLink>submit a bug report</issueLink>.",
|
||||
{ errcode: this.props.error.errcode },
|
||||
{ errcode: String(this.props.error?.errcode) },
|
||||
{
|
||||
issueLink: (label) => (
|
||||
<a
|
||||
|
|
|
@ -110,7 +110,7 @@ export default class RoomSublist extends React.Component<IProps, IState> {
|
|||
private headerButton = createRef<HTMLDivElement>();
|
||||
private sublistRef = createRef<HTMLDivElement>();
|
||||
private tilesRef = createRef<HTMLDivElement>();
|
||||
private dispatcherRef: string;
|
||||
private dispatcherRef?: string;
|
||||
private layout: ListLayout;
|
||||
private heightAtStart: number;
|
||||
private notificationState: ListNotificationState;
|
||||
|
@ -257,7 +257,7 @@ export default class RoomSublist extends React.Component<IProps, IState> {
|
|||
}
|
||||
|
||||
public componentWillUnmount(): void {
|
||||
defaultDispatcher.unregister(this.dispatcherRef);
|
||||
if (this.dispatcherRef) defaultDispatcher.unregister(this.dispatcherRef);
|
||||
RoomListStore.instance.off(LISTS_UPDATE_EVENT, this.onListsUpdated);
|
||||
RoomListStore.instance.off(LISTS_LOADING_EVENT, this.onListsLoading);
|
||||
this.tilesRef.current?.removeEventListener("scroll", this.onScrollPrevent);
|
||||
|
|
|
@ -23,7 +23,7 @@ import AppTile from "../elements/AppTile";
|
|||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
import dis from "../../../dispatcher/dispatcher";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import WidgetUtils, { IWidgetEvent } from "../../../utils/WidgetUtils";
|
||||
import WidgetUtils, { UserWidget } from "../../../utils/WidgetUtils";
|
||||
import PersistedElement from "../elements/PersistedElement";
|
||||
import { IntegrationManagers } from "../../../integrations/IntegrationManagers";
|
||||
import ContextMenu, { ChevronFace } from "../../structures/ContextMenu";
|
||||
|
@ -53,7 +53,7 @@ interface IProps {
|
|||
|
||||
interface IState {
|
||||
imError: string | null;
|
||||
stickerpickerWidget: IWidgetEvent | null;
|
||||
stickerpickerWidget: UserWidget | null;
|
||||
widgetId: string | null;
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ export default class Stickerpicker extends React.PureComponent<IProps, IState> {
|
|||
threadId: null,
|
||||
};
|
||||
|
||||
public static currentWidget?: IWidgetEvent;
|
||||
public static currentWidget?: UserWidget;
|
||||
|
||||
private dispatcherRef?: string;
|
||||
|
||||
|
@ -252,14 +252,14 @@ export default class Stickerpicker extends React.PureComponent<IProps, IState> {
|
|||
// Render content from multiple stickerpack sources, each within their
|
||||
// own iframe, within the stickerpicker UI element.
|
||||
const stickerpickerWidget = this.state.stickerpickerWidget;
|
||||
let stickersContent;
|
||||
let stickersContent: JSX.Element | undefined;
|
||||
|
||||
// Use a separate ReactDOM tree to render the AppTile separately so that it persists and does
|
||||
// not unmount when we (a) close the sticker picker (b) switch rooms. It's properties are still
|
||||
// updated.
|
||||
|
||||
// Load stickerpack content
|
||||
if (stickerpickerWidget && stickerpickerWidget.content && stickerpickerWidget.content.url) {
|
||||
if (!!stickerpickerWidget?.content?.url) {
|
||||
// Set default name
|
||||
stickerpickerWidget.content.name = stickerpickerWidget.content.name || _t("Stickerpack");
|
||||
|
||||
|
|
|
@ -69,9 +69,9 @@ interface IState {
|
|||
}
|
||||
|
||||
export default class ChangePassword extends React.Component<IProps, IState> {
|
||||
private [FIELD_OLD_PASSWORD]: Field | null;
|
||||
private [FIELD_NEW_PASSWORD]: Field | null;
|
||||
private [FIELD_NEW_PASSWORD_CONFIRM]: Field | null;
|
||||
private [FIELD_OLD_PASSWORD]: Field | null = null;
|
||||
private [FIELD_NEW_PASSWORD]: Field | null = null;
|
||||
private [FIELD_NEW_PASSWORD_CONFIRM]: Field | null = null;
|
||||
|
||||
public static defaultProps: Partial<IProps> = {
|
||||
onFinished() {},
|
||||
|
|
|
@ -43,7 +43,7 @@ interface IState {
|
|||
}
|
||||
|
||||
export default class IntegrationManager extends React.Component<IProps, IState> {
|
||||
private dispatcherRef: string;
|
||||
private dispatcherRef?: string;
|
||||
|
||||
public static defaultProps: Partial<IProps> = {
|
||||
connected: true,
|
||||
|
@ -60,7 +60,7 @@ export default class IntegrationManager extends React.Component<IProps, IState>
|
|||
}
|
||||
|
||||
public componentWillUnmount(): void {
|
||||
dis.unregister(this.dispatcherRef);
|
||||
if (this.dispatcherRef) dis.unregister(this.dispatcherRef);
|
||||
document.removeEventListener("keydown", this.onKeyDown);
|
||||
}
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ interface IState {
|
|||
}
|
||||
|
||||
export default class SetIdServer extends React.Component<IProps, IState> {
|
||||
private dispatcherRef: string;
|
||||
private dispatcherRef?: string;
|
||||
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
@ -108,7 +108,7 @@ export default class SetIdServer extends React.Component<IProps, IState> {
|
|||
}
|
||||
|
||||
public componentWillUnmount(): void {
|
||||
dis.unregister(this.dispatcherRef);
|
||||
if (this.dispatcherRef) dis.unregister(this.dispatcherRef);
|
||||
}
|
||||
|
||||
private onAction = (payload: ActionPayload): void => {
|
||||
|
|
|
@ -20,6 +20,7 @@ import { Optional } from "matrix-events-sdk";
|
|||
|
||||
import { MatrixClientPeg } from "../MatrixClientPeg";
|
||||
import { IMediaEventContent, IPreparedMedia, prepEventContentAsMedia } from "./models/IMediaEventContent";
|
||||
import { UserFriendlyError } from "../languageHandler";
|
||||
|
||||
// Populate this class with the details of your customisations when copying it.
|
||||
|
||||
|
@ -141,7 +142,11 @@ export class Media {
|
|||
* @returns {Promise<Response>} Resolves to the server's response for chaining.
|
||||
*/
|
||||
public downloadSource(): Promise<Response> {
|
||||
return fetch(this.srcHttp);
|
||||
const src = this.srcHttp;
|
||||
if (!src) {
|
||||
throw new UserFriendlyError("Failed to download source media, no source url was found");
|
||||
}
|
||||
return fetch(src);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1130,6 +1130,7 @@
|
|||
"You can use <code>/help</code> to list available commands. Did you mean to send this as a message?": "You can use <code>/help</code> to list available commands. Did you mean to send this as a message?",
|
||||
"Hint: Begin your message with <code>//</code> to start it with a slash.": "Hint: Begin your message with <code>//</code> to start it with a slash.",
|
||||
"Send as message": "Send as message",
|
||||
"Failed to download source media, no source url was found": "Failed to download source media, no source url was found",
|
||||
"Audio devices": "Audio devices",
|
||||
"Mute microphone": "Mute microphone",
|
||||
"Unmute microphone": "Unmute microphone",
|
||||
|
@ -2975,6 +2976,7 @@
|
|||
"Just a heads up, if you don't add an email and forget your password, you could <b>permanently lose access to your account</b>.": "Just a heads up, if you don't add an email and forget your password, you could <b>permanently lose access to your account</b>.",
|
||||
"Email (optional)": "Email (optional)",
|
||||
"Please fill why you're reporting.": "Please fill why you're reporting.",
|
||||
"Unable to create room with moderation bot": "Unable to create room with moderation bot",
|
||||
"Ignore user": "Ignore user",
|
||||
"Check if you want to hide all current and future messages from this user.": "Check if you want to hide all current and future messages from this user.",
|
||||
"What this user is writing is wrong.\nThis will be reported to the room moderators.": "What this user is writing is wrong.\nThis will be reported to the room moderators.",
|
||||
|
|
|
@ -150,8 +150,8 @@ export class RoomViewStore extends EventEmitter {
|
|||
// another RVS via INITIAL_STATE as they share the same underlying object. Mostly relevant for tests.
|
||||
private state = utils.deepCopy(INITIAL_STATE);
|
||||
|
||||
private dis: MatrixDispatcher;
|
||||
private dispatchToken: string;
|
||||
private dis?: MatrixDispatcher;
|
||||
private dispatchToken?: string;
|
||||
|
||||
public constructor(dis: MatrixDispatcher, private readonly stores: SdkContextClass) {
|
||||
super();
|
||||
|
@ -217,7 +217,7 @@ export class RoomViewStore extends EventEmitter {
|
|||
|
||||
// Fired so we can reduce dependency on event emitters to this store, which is relatively
|
||||
// central to the application and can easily cause import cycles.
|
||||
this.dis.dispatch<ActiveRoomChangedPayload>({
|
||||
this.dis?.dispatch<ActiveRoomChangedPayload>({
|
||||
action: Action.ActiveRoomChanged,
|
||||
oldRoomId: lastRoomId,
|
||||
newRoomId: this.state.roomId,
|
||||
|
@ -343,7 +343,7 @@ export class RoomViewStore extends EventEmitter {
|
|||
// can happen when performing a search across all rooms. Persist the data from this event for both
|
||||
// room and search timeline rendering types, search will get auto-closed by RoomView at this time.
|
||||
if (payload.event && payload.event.getRoomId() !== this.state.roomId) {
|
||||
this.dis.dispatch<ViewRoomPayload>({
|
||||
this.dis?.dispatch<ViewRoomPayload>({
|
||||
action: Action.ViewRoom,
|
||||
room_id: payload.event.getRoomId(),
|
||||
replyingToEvent: payload.event,
|
||||
|
@ -414,7 +414,7 @@ export class RoomViewStore extends EventEmitter {
|
|||
return;
|
||||
}
|
||||
// Re-fire the payload: we won't re-process it because the prev room ID == payload room ID now
|
||||
this.dis.dispatch({
|
||||
this.dis?.dispatch({
|
||||
...payload,
|
||||
});
|
||||
return;
|
||||
|
@ -455,7 +455,7 @@ export class RoomViewStore extends EventEmitter {
|
|||
this.setState(newState);
|
||||
|
||||
if (payload.auto_join) {
|
||||
this.dis.dispatch<JoinRoomPayload>({
|
||||
this.dis?.dispatch<JoinRoomPayload>({
|
||||
...payload,
|
||||
action: Action.JoinRoom,
|
||||
roomId: payload.room_id,
|
||||
|
@ -493,7 +493,7 @@ export class RoomViewStore extends EventEmitter {
|
|||
roomId = result.room_id;
|
||||
} catch (err) {
|
||||
logger.error("RVS failed to get room id for alias: ", err);
|
||||
this.dis.dispatch<ViewRoomErrorPayload>({
|
||||
this.dis?.dispatch<ViewRoomErrorPayload>({
|
||||
action: Action.ViewRoomError,
|
||||
room_id: null,
|
||||
room_alias: payload.room_alias,
|
||||
|
@ -504,7 +504,7 @@ export class RoomViewStore extends EventEmitter {
|
|||
}
|
||||
|
||||
// Re-fire the payload with the newly found room_id
|
||||
this.dis.dispatch({
|
||||
this.dis?.dispatch({
|
||||
...payload,
|
||||
room_id: roomId,
|
||||
});
|
||||
|
@ -553,13 +553,13 @@ export class RoomViewStore extends EventEmitter {
|
|||
// We do *not* clear the 'joining' flag because the Room object and/or our 'joined' member event may not
|
||||
// have come down the sync stream yet, and that's the point at which we'd consider the user joined to the
|
||||
// room.
|
||||
this.dis.dispatch<JoinRoomReadyPayload>({
|
||||
this.dis?.dispatch<JoinRoomReadyPayload>({
|
||||
action: Action.JoinRoomReady,
|
||||
roomId: roomId!,
|
||||
metricsTrigger: payload.metricsTrigger,
|
||||
});
|
||||
} catch (err) {
|
||||
this.dis.dispatch({
|
||||
this.dis?.dispatch({
|
||||
action: Action.JoinRoomError,
|
||||
roomId,
|
||||
err,
|
||||
|
@ -648,7 +648,7 @@ export class RoomViewStore extends EventEmitter {
|
|||
*/
|
||||
public resetDispatcher(dis: MatrixDispatcher): void {
|
||||
if (this.dispatchToken) {
|
||||
this.dis.unregister(this.dispatchToken);
|
||||
this.dis?.unregister(this.dispatchToken);
|
||||
}
|
||||
this.dis = dis;
|
||||
if (dis) {
|
||||
|
|
|
@ -44,7 +44,7 @@ export enum Phase {
|
|||
}
|
||||
|
||||
export class SetupEncryptionStore extends EventEmitter {
|
||||
private started: boolean;
|
||||
private started?: boolean;
|
||||
public phase: Phase;
|
||||
public verificationRequest: VerificationRequest | null = null;
|
||||
public backupInfo: IKeyBackupInfo | null = null;
|
||||
|
@ -52,7 +52,7 @@ export class SetupEncryptionStore extends EventEmitter {
|
|||
public keyId: string | null = null;
|
||||
// Descriptor of the key that the secrets we want are encrypted with
|
||||
public keyInfo: ISecretStorageKeyInfo | null = null;
|
||||
public hasDevicesToVerifyAgainst: boolean;
|
||||
public hasDevicesToVerifyAgainst?: boolean;
|
||||
|
||||
public static sharedInstance(): SetupEncryptionStore {
|
||||
if (!window.mxSetupEncryptionStore) window.mxSetupEncryptionStore = new SetupEncryptionStore();
|
||||
|
|
|
@ -32,7 +32,7 @@ export default class TypingStore {
|
|||
userTimer: Timer;
|
||||
serverTimer: Timer;
|
||||
};
|
||||
};
|
||||
} = {};
|
||||
|
||||
public constructor(private readonly context: SdkContextClass) {
|
||||
this.reset();
|
||||
|
@ -68,7 +68,7 @@ export default class TypingStore {
|
|||
if (threadId) return;
|
||||
|
||||
let currentTyping = this.typingStates[roomId];
|
||||
if ((!isTyping && !currentTyping) || (currentTyping && currentTyping.isTyping === isTyping)) {
|
||||
if ((!isTyping && !currentTyping) || currentTyping?.isTyping === isTyping) {
|
||||
// No change in state, so don't do anything. We'll let the timer run its course.
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -157,9 +157,9 @@ export class ElementWidget extends Widget {
|
|||
|
||||
export class StopGapWidget extends EventEmitter {
|
||||
private client: MatrixClient;
|
||||
private messaging: ClientWidgetApi | null;
|
||||
private messaging: ClientWidgetApi | null = null;
|
||||
private mockWidget: ElementWidget;
|
||||
private scalarToken: string;
|
||||
private scalarToken?: string;
|
||||
private roomId?: string;
|
||||
private kind: WidgetKind;
|
||||
private readonly virtual: boolean;
|
||||
|
|
|
@ -39,7 +39,7 @@ export default class DMRoomMap {
|
|||
private roomToUser: { [key: string]: string } | null = null;
|
||||
private userToRooms: { [key: string]: string[] } | null = null;
|
||||
private hasSentOutPatchDirectAccountDataPatch: boolean;
|
||||
private mDirectEvent: { [key: string]: string[] };
|
||||
private mDirectEvent!: { [key: string]: string[] };
|
||||
|
||||
public constructor(private readonly matrixClient: MatrixClient) {
|
||||
// see onAccountData
|
||||
|
|
|
@ -47,7 +47,11 @@ export interface IWidgetEvent {
|
|||
sender: string;
|
||||
// eslint-disable-next-line camelcase
|
||||
state_key: string;
|
||||
content: Partial<IApp>;
|
||||
content: IApp;
|
||||
}
|
||||
|
||||
export interface UserWidget extends Omit<IWidgetEvent, "content"> {
|
||||
content: IWidget & Partial<IApp>;
|
||||
}
|
||||
|
||||
export default class WidgetUtils {
|
||||
|
@ -254,6 +258,7 @@ export default class WidgetUtils {
|
|||
const userId = client.getSafeUserId();
|
||||
|
||||
const content = {
|
||||
id: widgetId,
|
||||
type: widgetType.preferred,
|
||||
url: widgetUrl,
|
||||
name: widgetName,
|
||||
|
@ -354,7 +359,7 @@ export default class WidgetUtils {
|
|||
* Get user specific widgets (not linked to a specific room)
|
||||
* @return {object} Event content object containing current / active user widgets
|
||||
*/
|
||||
public static getUserWidgets(): Record<string, IWidgetEvent> {
|
||||
public static getUserWidgets(): Record<string, UserWidget> {
|
||||
const client = MatrixClientPeg.get();
|
||||
if (!client) {
|
||||
throw new Error("User not logged in");
|
||||
|
@ -370,7 +375,7 @@ export default class WidgetUtils {
|
|||
* Get user specific widgets (not linked to a specific room) as an array
|
||||
* @return {[object]} Array containing current / active user widgets
|
||||
*/
|
||||
public static getUserWidgetsArray(): IWidgetEvent[] {
|
||||
public static getUserWidgetsArray(): UserWidget[] {
|
||||
return Object.values(WidgetUtils.getUserWidgets());
|
||||
}
|
||||
|
||||
|
@ -378,18 +383,18 @@ export default class WidgetUtils {
|
|||
* Get active stickerpicker widgets (stickerpickers are user widgets by nature)
|
||||
* @return {[object]} Array containing current / active stickerpicker widgets
|
||||
*/
|
||||
public static getStickerpickerWidgets(): IWidgetEvent[] {
|
||||
public static getStickerpickerWidgets(): UserWidget[] {
|
||||
const widgets = WidgetUtils.getUserWidgetsArray();
|
||||
return widgets.filter((widget) => widget.content && widget.content.type === "m.stickerpicker");
|
||||
return widgets.filter((widget) => widget.content?.type === "m.stickerpicker");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all integration manager widgets for this user.
|
||||
* @returns {Object[]} An array of integration manager user widgets.
|
||||
*/
|
||||
public static getIntegrationManagerWidgets(): IWidgetEvent[] {
|
||||
public static getIntegrationManagerWidgets(): UserWidget[] {
|
||||
const widgets = WidgetUtils.getUserWidgetsArray();
|
||||
return widgets.filter((w) => w.content && w.content.type === "m.integration_manager");
|
||||
return widgets.filter((w) => w.content?.type === "m.integration_manager");
|
||||
}
|
||||
|
||||
public static getRoomWidgetsOfType(room: Room, type: WidgetType): MatrixEvent[] {
|
||||
|
|
|
@ -126,7 +126,7 @@ export class VoiceBroadcastRecorder
|
|||
return;
|
||||
}
|
||||
|
||||
this.setCurrentChunkLength(this.voiceRecording.recorderSeconds - this.previousChunkEndTimePosition);
|
||||
this.setCurrentChunkLength(this.voiceRecording.recorderSeconds! - this.previousChunkEndTimePosition);
|
||||
this.handleData(dataArray);
|
||||
};
|
||||
|
||||
|
@ -154,7 +154,7 @@ export class VoiceBroadcastRecorder
|
|||
return null;
|
||||
}
|
||||
|
||||
const currentRecorderTime = this.voiceRecording.recorderSeconds;
|
||||
const currentRecorderTime = this.voiceRecording.recorderSeconds!;
|
||||
const payload: ChunkRecordedPayload = {
|
||||
buffer: concat(this.opusHead!, this.opusTags!, this.chunkBuffer),
|
||||
length: this.getCurrentChunkLength(),
|
||||
|
|
|
@ -21,8 +21,8 @@ import { SettingLevel } from "../../../src/settings/SettingLevel";
|
|||
function makeMatchMedia(values: any) {
|
||||
class FakeMediaQueryList {
|
||||
matches: false;
|
||||
media: null;
|
||||
onchange: null;
|
||||
media?: null;
|
||||
onchange?: null;
|
||||
addListener() {}
|
||||
removeListener() {}
|
||||
addEventListener() {}
|
||||
|
|
Loading…
Reference in New Issue