Conform more of the codebase to strictNullChecks (#10672)
* Conform more of the codebase to `strictNullChecks` * Iterate * Iterate * Iterate * Iterate * Conform more of the codebase to `strictNullChecks` * Iterate * Update record key
This commit is contained in:
parent
792a39a39b
commit
be5928cb64
34 changed files with 143 additions and 115 deletions
|
@ -883,6 +883,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
|
|||
|
||||
const existingReceipts = receiptsByEvent.get(lastShownEventId) || [];
|
||||
const newReceipts = this.getReadReceiptsForEvent(event);
|
||||
if (!newReceipts) continue;
|
||||
receiptsByEvent.set(lastShownEventId, existingReceipts.concat(newReceipts));
|
||||
|
||||
// Record these receipts along with their last shown event ID for
|
||||
|
@ -1218,7 +1219,7 @@ class CreationGrouper extends BaseGrouper {
|
|||
key="roomcreationsummary"
|
||||
events={this.events}
|
||||
onToggle={panel.onHeightChanged} // Update scroll state
|
||||
summaryMembers={[ev.sender]}
|
||||
summaryMembers={ev.sender ? [ev.sender] : undefined}
|
||||
summaryText={summaryText}
|
||||
layout={this.panel.props.layout}
|
||||
>
|
||||
|
|
|
@ -627,7 +627,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
|||
mainSplitContentType: room ? this.getMainSplitContentType(room) : undefined,
|
||||
initialEventId: undefined, // default to clearing this, will get set later in the method if needed
|
||||
showRightPanel: this.context.rightPanelStore.isOpenForRoom(roomId),
|
||||
activeCall: CallStore.instance.getActiveCall(roomId),
|
||||
activeCall: roomId ? CallStore.instance.getActiveCall(roomId) : null,
|
||||
};
|
||||
|
||||
if (
|
||||
|
@ -1071,6 +1071,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
|||
};
|
||||
|
||||
private onAction = async (payload: ActionPayload): Promise<void> => {
|
||||
if (!this.context.client) return;
|
||||
switch (payload.action) {
|
||||
case "message_sent":
|
||||
this.checkDesktopNotifications();
|
||||
|
@ -1228,7 +1229,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
|||
this.handleEffects(ev);
|
||||
}
|
||||
|
||||
if (ev.getSender() !== this.context.client.getSafeUserId()) {
|
||||
if (this.context.client && ev.getSender() !== this.context.client.getSafeUserId()) {
|
||||
// update unread count when scrolled up
|
||||
if (!this.state.search && this.state.atEndOfLiveTimeline) {
|
||||
// no change
|
||||
|
@ -1469,7 +1470,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
|||
};
|
||||
|
||||
private updatePermissions(room: Room): void {
|
||||
if (room) {
|
||||
if (room && this.context.client) {
|
||||
const me = this.context.client.getSafeUserId();
|
||||
const canReact =
|
||||
room.getMyMembership() === "join" && room.currentState.maySendEvent(EventType.Reaction, me);
|
||||
|
@ -1956,6 +1957,8 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
|||
}
|
||||
|
||||
public render(): React.ReactNode {
|
||||
if (!this.context.client) return null;
|
||||
|
||||
if (this.state.room instanceof LocalRoom) {
|
||||
if (this.state.room.state === LocalRoomState.CREATING) {
|
||||
return this.renderLocalRoomCreateLoader(this.state.room);
|
||||
|
@ -2064,7 +2067,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
|||
const inviteEvent = myMember ? myMember.events.member : null;
|
||||
let inviterName = _t("Unknown");
|
||||
if (inviteEvent) {
|
||||
inviterName = inviteEvent.sender?.name ?? inviteEvent.getSender();
|
||||
inviterName = inviteEvent.sender?.name ?? inviteEvent.getSender()!;
|
||||
}
|
||||
|
||||
// We deliberately don't try to peek into invites, even if we have permission to peek
|
||||
|
|
|
@ -786,7 +786,7 @@ export default class ScrollPanel extends React.Component<IProps> {
|
|||
const scrollState = this.scrollState;
|
||||
const trackedNode = scrollState.trackedNode;
|
||||
|
||||
if (!trackedNode?.parentElement) {
|
||||
if (!trackedNode?.parentElement && this.itemlist.current) {
|
||||
let node: HTMLElement | undefined = undefined;
|
||||
const messages = this.itemlist.current.children;
|
||||
const scrollToken = scrollState.trackedScrollToken;
|
||||
|
@ -890,7 +890,7 @@ export default class ScrollPanel extends React.Component<IProps> {
|
|||
public clearPreventShrinking = (): void => {
|
||||
const messageList = this.itemlist.current;
|
||||
const balanceElement = messageList && messageList.parentElement;
|
||||
if (balanceElement) balanceElement.style.paddingBottom = null;
|
||||
if (balanceElement) balanceElement.style.removeProperty("paddingBottom");
|
||||
this.preventShrinkingState = null;
|
||||
debuglog("prevent shrinking cleared");
|
||||
};
|
||||
|
@ -904,7 +904,7 @@ export default class ScrollPanel extends React.Component<IProps> {
|
|||
what it was when marking.
|
||||
*/
|
||||
public updatePreventShrinking = (): void => {
|
||||
if (this.preventShrinkingState) {
|
||||
if (this.preventShrinkingState && this.itemlist.current) {
|
||||
const sn = this.getScrollNode();
|
||||
const scrollState = this.scrollState;
|
||||
const messageList = this.itemlist.current;
|
||||
|
@ -922,7 +922,7 @@ export default class ScrollPanel extends React.Component<IProps> {
|
|||
if (!shouldClear) {
|
||||
const currentOffset = messageList.clientHeight - (offsetNode.offsetTop + offsetNode.clientHeight);
|
||||
const offsetDiff = offsetFromBottom - currentOffset;
|
||||
if (offsetDiff > 0) {
|
||||
if (offsetDiff > 0 && balanceElement) {
|
||||
balanceElement.style.paddingBottom = `${offsetDiff}px`;
|
||||
debuglog("update prevent shrinking ", offsetDiff, "px from bottom");
|
||||
} else if (offsetDiff < 0) {
|
||||
|
|
|
@ -79,7 +79,8 @@ export default class UserView extends React.Component<IProps, IState> {
|
|||
return;
|
||||
}
|
||||
const fakeEvent = new MatrixEvent({ type: "m.room.member", content: profileInfo });
|
||||
const member = new RoomMember(null, this.props.userId);
|
||||
// We pass an empty string room ID here, this is slight abuse of the class to simplify code
|
||||
const member = new RoomMember("", this.props.userId);
|
||||
member.setMembershipEvent(fakeEvent);
|
||||
this.setState({ member, loading: false });
|
||||
}
|
||||
|
|
|
@ -169,8 +169,8 @@ const RoomContextMenu: React.FC<IProps> = ({ room, onFinished, ...props }) => {
|
|||
);
|
||||
|
||||
const echoChamber = EchoChamber.forRoom(room);
|
||||
let notificationLabel: string;
|
||||
let iconClassName: string;
|
||||
let notificationLabel: string | undefined;
|
||||
let iconClassName: string | undefined;
|
||||
switch (echoChamber.notificationVolume) {
|
||||
case RoomNotifState.AllMessages:
|
||||
notificationLabel = _t("Default");
|
||||
|
@ -337,7 +337,7 @@ const RoomContextMenu: React.FC<IProps> = ({ room, onFinished, ...props }) => {
|
|||
const isApplied = RoomListStore.instance.getTagsForRoom(room).includes(tagId);
|
||||
const removeTag = isApplied ? tagId : inverseTag;
|
||||
const addTag = isApplied ? null : tagId;
|
||||
dis.dispatch(RoomListActions.tagRoom(cli, room, removeTag, addTag, undefined, 0));
|
||||
dis.dispatch(RoomListActions.tagRoom(cli, room, removeTag, addTag, 0));
|
||||
} else {
|
||||
logger.warn(`Unexpected tag ${tagId} applied to ${room.roomId}`);
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ export const RoomGeneralContextMenu: React.FC<RoomGeneralContextMenuProps> = ({
|
|||
const isApplied = RoomListStore.instance.getTagsForRoom(room).includes(tagId);
|
||||
const removeTag = isApplied ? tagId : inverseTag;
|
||||
const addTag = isApplied ? null : tagId;
|
||||
dis.dispatch(RoomListActions.tagRoom(cli, room, removeTag, addTag, undefined, 0));
|
||||
dis.dispatch(RoomListActions.tagRoom(cli, room, removeTag, addTag, 0));
|
||||
} else {
|
||||
logger.warn(`Unexpected tag ${tagId} applied to ${room.roomId}`);
|
||||
}
|
||||
|
|
|
@ -260,7 +260,7 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
|
|||
|
||||
// if the user should also be ignored, do that
|
||||
if (this.state.ignoreUserToo) {
|
||||
await client.setIgnoredUsers([...client.getIgnoredUsers(), ev.getSender()]);
|
||||
await client.setIgnoredUsers([...client.getIgnoredUsers(), ev.getSender()!]);
|
||||
}
|
||||
|
||||
this.props.onFinished(true);
|
||||
|
@ -309,8 +309,8 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
|
|||
// Display report-to-moderator dialog.
|
||||
// We let the user pick a nature.
|
||||
const client = MatrixClientPeg.get();
|
||||
const homeServerName = SdkConfig.get("validated_server_config").hsName;
|
||||
let subtitle;
|
||||
const homeServerName = SdkConfig.get("validated_server_config")!.hsName;
|
||||
let subtitle: string;
|
||||
switch (this.state.nature) {
|
||||
case Nature.Disagreement:
|
||||
subtitle = _t(
|
||||
|
|
|
@ -130,7 +130,7 @@ export default class AccessSecretStorageDialog extends React.PureComponent<IProp
|
|||
|
||||
// also clear the file upload control so that the user can upload the same file
|
||||
// the did before (otherwise the onchange wouldn't fire)
|
||||
if (this.fileUpload.current) this.fileUpload.current.value = null;
|
||||
if (this.fileUpload.current) this.fileUpload.current.value = "";
|
||||
|
||||
// We don't use Field's validation here because a) we want it in a separate place rather
|
||||
// than in a tooltip and b) we want it to display feedback based on the uploaded file
|
||||
|
|
|
@ -324,7 +324,10 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
details = _t("Fetching keys from server…");
|
||||
} else if (this.state.progress.stage === ProgressState.LoadKeys) {
|
||||
const { total, successes, failures } = this.state.progress;
|
||||
details = _t("%(completed)s of %(total)s keys restored", { total, completed: successes + failures });
|
||||
details = _t("%(completed)s of %(total)s keys restored", {
|
||||
total,
|
||||
completed: (successes ?? 0) + (failures ?? 0),
|
||||
});
|
||||
} else if (this.state.progress.stage === ProgressState.PreFetch) {
|
||||
details = _t("Fetching keys from server…");
|
||||
}
|
||||
|
|
|
@ -65,11 +65,11 @@ export const OverflowMenuContext = createContext<OverflowMenuCloser | null>(null
|
|||
|
||||
const MessageComposerButtons: React.FC<IProps> = (props: IProps) => {
|
||||
const matrixClient = useContext(MatrixClientContext);
|
||||
const { room, roomId, narrow } = useContext(RoomContext);
|
||||
const { room, narrow } = useContext(RoomContext);
|
||||
|
||||
const isWysiwygLabEnabled = useSettingValue<boolean>("feature_wysiwyg_composer");
|
||||
|
||||
if (props.haveRecording) {
|
||||
if (!matrixClient || !room || props.haveRecording) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ const MessageComposerButtons: React.FC<IProps> = (props: IProps) => {
|
|||
voiceRecordingButton(props, narrow),
|
||||
startVoiceBroadcastButton(props),
|
||||
props.showPollsButton ? pollButton(room, props.relation) : null,
|
||||
showLocationButton(props, room, roomId, matrixClient),
|
||||
showLocationButton(props, room, matrixClient),
|
||||
];
|
||||
} else {
|
||||
mainButtons = [
|
||||
|
@ -113,7 +113,7 @@ const MessageComposerButtons: React.FC<IProps> = (props: IProps) => {
|
|||
voiceRecordingButton(props, narrow),
|
||||
startVoiceBroadcastButton(props),
|
||||
props.showPollsButton ? pollButton(room, props.relation) : null,
|
||||
showLocationButton(props, room, roomId, matrixClient),
|
||||
showLocationButton(props, room, matrixClient),
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -127,7 +127,7 @@ const MessageComposerButtons: React.FC<IProps> = (props: IProps) => {
|
|||
});
|
||||
|
||||
return (
|
||||
<UploadButtonContextProvider roomId={roomId} relation={props.relation}>
|
||||
<UploadButtonContextProvider roomId={room.roomId} relation={props.relation}>
|
||||
{mainButtons}
|
||||
{moreButtons.length > 0 && (
|
||||
<AccessibleTooltipButton
|
||||
|
@ -346,18 +346,13 @@ class PollButton extends React.PureComponent<IPollButtonProps> {
|
|||
}
|
||||
}
|
||||
|
||||
function showLocationButton(
|
||||
props: IProps,
|
||||
room: Room,
|
||||
roomId: string,
|
||||
matrixClient: MatrixClient,
|
||||
): ReactElement | null {
|
||||
const sender = room.getMember(matrixClient.getUserId()!);
|
||||
function showLocationButton(props: IProps, room: Room, matrixClient: MatrixClient): ReactElement | null {
|
||||
const sender = room.getMember(matrixClient.getSafeUserId());
|
||||
|
||||
return props.showLocationButton && sender ? (
|
||||
<LocationButton
|
||||
key="location"
|
||||
roomId={roomId}
|
||||
roomId={room.roomId}
|
||||
relation={props.relation}
|
||||
sender={sender}
|
||||
menuPosition={props.menuPosition}
|
||||
|
|
|
@ -151,7 +151,7 @@ export default class RoomPreviewBar extends React.Component<IProps, IState> {
|
|||
const result = await MatrixClientPeg.get().lookupThreePid(
|
||||
"email",
|
||||
this.props.invitedEmail,
|
||||
identityAccessToken,
|
||||
identityAccessToken!,
|
||||
);
|
||||
this.setState({ invitedEmailMxid: result.mxid });
|
||||
} catch (err) {
|
||||
|
@ -243,8 +243,8 @@ export default class RoomPreviewBar extends React.Component<IProps, IState> {
|
|||
if (!inviteEvent) {
|
||||
return null;
|
||||
}
|
||||
const inviterUserId = inviteEvent.events.member.getSender();
|
||||
return room.currentState.getMember(inviterUserId);
|
||||
const inviterUserId = inviteEvent.events.member?.getSender();
|
||||
return inviterUserId ? room.currentState.getMember(inviterUserId) : null;
|
||||
}
|
||||
|
||||
private isDMInvite(): boolean {
|
||||
|
@ -252,8 +252,8 @@ export default class RoomPreviewBar extends React.Component<IProps, IState> {
|
|||
if (!myMember) {
|
||||
return false;
|
||||
}
|
||||
const memberContent = myMember.events.member.getContent();
|
||||
return memberContent.membership === "invite" && memberContent.is_direct;
|
||||
const memberContent = myMember.events.member?.getContent();
|
||||
return memberContent?.membership === "invite" && memberContent.is_direct;
|
||||
}
|
||||
|
||||
private makeScreenAfterLogin(): { screen: string; params: Record<string, any> } {
|
||||
|
|
|
@ -64,7 +64,7 @@ export default class SearchResultTile extends React.Component<IProps> {
|
|||
const eventId = resultEvent.getId();
|
||||
|
||||
const ts1 = resultEvent.getTs();
|
||||
const ret = [<DateSeparator key={ts1 + "-search"} roomId={resultEvent.getRoomId()} ts={ts1} />];
|
||||
const ret = [<DateSeparator key={ts1 + "-search"} roomId={resultEvent.getRoomId()!} ts={ts1} />];
|
||||
const layout = SettingsStore.getValue("layout");
|
||||
const isTwelveHour = SettingsStore.getValue("showTwelveHourTimestamps");
|
||||
const alwaysShowTimestamps = SettingsStore.getValue("alwaysShowTimestamps");
|
||||
|
|
|
@ -372,7 +372,10 @@ export class SendMessageComposer extends React.Component<ISendMessageComposerPro
|
|||
return false;
|
||||
}
|
||||
this.currentlyComposedEditorState = this.model.serializeParts();
|
||||
} else if (this.sendHistoryManager.currentIndex + delta === this.sendHistoryManager.history.length) {
|
||||
} else if (
|
||||
this.currentlyComposedEditorState &&
|
||||
this.sendHistoryManager.currentIndex + delta === this.sendHistoryManager.history.length
|
||||
) {
|
||||
// True when we return to the message being composed currently
|
||||
this.model.reset(this.currentlyComposedEditorState);
|
||||
this.sendHistoryManager.currentIndex = this.sendHistoryManager.history.length;
|
||||
|
@ -393,6 +396,7 @@ export class SendMessageComposer extends React.Component<ISendMessageComposerPro
|
|||
|
||||
private sendQuickReaction(): void {
|
||||
const timeline = this.context.liveTimeline;
|
||||
if (!timeline) return;
|
||||
const events = timeline.getEvents();
|
||||
const reaction = this.model.parts[1].text;
|
||||
for (let i = events.length - 1; i >= 0; i--) {
|
||||
|
@ -443,8 +447,8 @@ export class SendMessageComposer extends React.Component<ISendMessageComposerPro
|
|||
isReply: !!this.props.replyToEvent,
|
||||
inThread: this.props.relation?.rel_type === THREAD_RELATION_TYPE.name,
|
||||
};
|
||||
if (posthogEvent.inThread) {
|
||||
const threadRoot = this.props.room.findEventById(this.props.relation.event_id);
|
||||
if (posthogEvent.inThread && this.props.relation!.event_id) {
|
||||
const threadRoot = this.props.room.findEventById(this.props.relation!.event_id);
|
||||
posthogEvent.startsThread = threadRoot?.getThread()?.events.length === 1;
|
||||
}
|
||||
PosthogAnalytics.instance.trackEvent<ComposerEvent>(posthogEvent);
|
||||
|
@ -480,7 +484,7 @@ export class SendMessageComposer extends React.Component<ISendMessageComposerPro
|
|||
return; // errored
|
||||
}
|
||||
|
||||
if (cmd.category === CommandCategories.messages || cmd.category === CommandCategories.effects) {
|
||||
if (content && [CommandCategories.messages, CommandCategories.effects].includes(cmd.category)) {
|
||||
// Attach any mentions which might be contained in the command content.
|
||||
attachMentions(this.props.mxClient.getSafeUserId(), content, model, replyToEvent);
|
||||
attachRelation(content, this.props.relation);
|
||||
|
|
|
@ -86,7 +86,7 @@ export default class AdvancedRoomSettingsTab extends React.Component<IProps, ISt
|
|||
|
||||
private upgradeRoom = (): void => {
|
||||
const room = MatrixClientPeg.get().getRoom(this.props.roomId);
|
||||
Modal.createDialog(RoomUpgradeDialog, { room });
|
||||
if (room) Modal.createDialog(RoomUpgradeDialog, { room });
|
||||
};
|
||||
|
||||
private onOldRoomClicked = (e: ButtonEvent): void => {
|
||||
|
|
|
@ -66,13 +66,20 @@ interface IState {
|
|||
haveIdServer: boolean;
|
||||
serverSupportsSeparateAddAndBind?: boolean;
|
||||
idServerHasUnsignedTerms: boolean;
|
||||
requiredPolicyInfo: {
|
||||
// This object is passed along to a component for handling
|
||||
hasTerms: boolean;
|
||||
policiesAndServices: ServicePolicyPair[] | null; // From the startTermsFlow callback
|
||||
agreedUrls: string[] | null; // From the startTermsFlow callback
|
||||
resolve: ((values: string[]) => void) | null; // Promise resolve function for startTermsFlow callback
|
||||
};
|
||||
requiredPolicyInfo:
|
||||
| {
|
||||
// This object is passed along to a component for handling
|
||||
hasTerms: false;
|
||||
policiesAndServices: null; // From the startTermsFlow callback
|
||||
agreedUrls: null; // From the startTermsFlow callback
|
||||
resolve: null; // Promise resolve function for startTermsFlow callback
|
||||
}
|
||||
| {
|
||||
hasTerms: boolean;
|
||||
policiesAndServices: ServicePolicyPair[];
|
||||
agreedUrls: string[];
|
||||
resolve: (values: string[]) => void;
|
||||
};
|
||||
emails: IThreepid[];
|
||||
msisdns: IThreepid[];
|
||||
loading3pids: boolean; // whether or not the emails and msisdns have been loaded
|
||||
|
@ -191,19 +198,19 @@ export default class GeneralUserSettingsTab extends React.Component<IProps, ISta
|
|||
}
|
||||
|
||||
private async checkTerms(): Promise<void> {
|
||||
if (!this.state.haveIdServer) {
|
||||
// By starting the terms flow we get the logic for checking which terms the user has signed
|
||||
// for free. So we might as well use that for our own purposes.
|
||||
const idServerUrl = MatrixClientPeg.get().getIdentityServerUrl();
|
||||
if (!this.state.haveIdServer || !idServerUrl) {
|
||||
this.setState({ idServerHasUnsignedTerms: false });
|
||||
return;
|
||||
}
|
||||
|
||||
// By starting the terms flow we get the logic for checking which terms the user has signed
|
||||
// for free. So we might as well use that for our own purposes.
|
||||
const idServerUrl = MatrixClientPeg.get().getIdentityServerUrl();
|
||||
const authClient = new IdentityAuthClient();
|
||||
try {
|
||||
const idAccessToken = await authClient.getAccessToken({ check: false });
|
||||
await startTermsFlow(
|
||||
[new Service(SERVICE_TYPES.IS, idServerUrl, idAccessToken)],
|
||||
[new Service(SERVICE_TYPES.IS, idServerUrl, idAccessToken!)],
|
||||
(policiesAndServices, agreedUrls, extraClassNames) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.setState({
|
||||
|
|
|
@ -62,7 +62,7 @@ export default class AudioFeed extends React.Component<IProps, IState> {
|
|||
// it fails.
|
||||
// It seems reliable if you set the sink ID after setting the srcObject and then set the sink ID
|
||||
// back to the default after the call is over - Dave
|
||||
element.setSinkId(audioOutput);
|
||||
element!.setSinkId(audioOutput);
|
||||
} catch (e) {
|
||||
logger.error("Couldn't set requested audio output device: using default", e);
|
||||
logger.warn("Couldn't set requested audio output device: using default", e);
|
||||
|
@ -103,7 +103,7 @@ export default class AudioFeed extends React.Component<IProps, IState> {
|
|||
if (!element) return;
|
||||
|
||||
element.pause();
|
||||
element.src = null;
|
||||
element.removeAttribute("src");
|
||||
|
||||
// As per comment in componentDidMount, setting the sink ID back to the
|
||||
// default once the call is over makes setSinkId work reliably. - Dave
|
||||
|
|
|
@ -339,16 +339,17 @@ export default class LegacyCallView extends React.Component<IProps, IState> {
|
|||
|
||||
private onCallResumeClick = (): void => {
|
||||
const userFacingRoomId = LegacyCallHandler.instance.roomIdForCall(this.props.call);
|
||||
LegacyCallHandler.instance.setActiveCallRoomId(userFacingRoomId);
|
||||
if (userFacingRoomId) LegacyCallHandler.instance.setActiveCallRoomId(userFacingRoomId);
|
||||
};
|
||||
|
||||
private onTransferClick = (): void => {
|
||||
const transfereeCall = LegacyCallHandler.instance.getTransfereeForCallId(this.props.call.callId);
|
||||
this.props.call.transferToCall(transfereeCall);
|
||||
if (transfereeCall) this.props.call.transferToCall(transfereeCall);
|
||||
};
|
||||
|
||||
private onHangupClick = (): void => {
|
||||
LegacyCallHandler.instance.hangupOrReject(LegacyCallHandler.instance.roomIdForCall(this.props.call));
|
||||
const roomId = LegacyCallHandler.instance.roomIdForCall(this.props.call);
|
||||
if (roomId) LegacyCallHandler.instance.hangupOrReject(roomId);
|
||||
};
|
||||
|
||||
private onToggleSidebar = (): void => {
|
||||
|
@ -451,13 +452,12 @@ export default class LegacyCallView extends React.Component<IProps, IState> {
|
|||
|
||||
let holdTransferContent: React.ReactNode;
|
||||
if (transfereeCall) {
|
||||
const transferTargetRoom = MatrixClientPeg.get().getRoom(
|
||||
LegacyCallHandler.instance.roomIdForCall(call),
|
||||
);
|
||||
const cli = MatrixClientPeg.get();
|
||||
const callRoomId = LegacyCallHandler.instance.roomIdForCall(call);
|
||||
const transferTargetRoom = callRoomId ? cli.getRoom(callRoomId) : null;
|
||||
const transferTargetName = transferTargetRoom ? transferTargetRoom.name : _t("unknown person");
|
||||
const transfereeRoom = MatrixClientPeg.get().getRoom(
|
||||
LegacyCallHandler.instance.roomIdForCall(transfereeCall),
|
||||
);
|
||||
const transfereeCallRoomId = LegacyCallHandler.instance.roomIdForCall(transfereeCall);
|
||||
const transfereeRoom = transfereeCallRoomId ? cli.getRoom(transfereeCallRoomId) : null;
|
||||
const transfereeName = transfereeRoom ? transfereeRoom.name : _t("unknown person");
|
||||
|
||||
holdTransferContent = (
|
||||
|
@ -579,6 +579,8 @@ export default class LegacyCallView extends React.Component<IProps, IState> {
|
|||
const callRoomId = LegacyCallHandler.instance.roomIdForCall(call);
|
||||
const secondaryCallRoomId = LegacyCallHandler.instance.roomIdForCall(secondaryCall);
|
||||
const callRoom = callRoomId ? client.getRoom(callRoomId) : null;
|
||||
if (!callRoom) return null;
|
||||
|
||||
const secCallRoom = secondaryCallRoomId ? client.getRoom(secondaryCallRoomId) : null;
|
||||
|
||||
const callViewClasses = classNames({
|
||||
|
|
|
@ -150,7 +150,7 @@ export default class VideoFeed extends React.PureComponent<IProps, IState> {
|
|||
if (!element) return;
|
||||
|
||||
element.pause();
|
||||
element.src = null;
|
||||
element.removeAttribute("src");
|
||||
|
||||
// As per comment in componentDidMount, setting the sink ID back to the
|
||||
// default once the call is over makes setSinkId work reliably. - Dave
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue