Enable lint rules for Promise handling to discourage misuse of them. (#2607)

* Enable lint rules for Promise handling to discourage misuse of them.
Squashed all of Hugh's commits into one.

---------

Co-authored-by: Hugh Nimmo-Smith <hughns@element.io>
This commit is contained in:
Timo
2024-09-10 09:49:35 +02:00
committed by GitHub
parent c30c8ac7d6
commit c3edd3e25e
35 changed files with 369 additions and 241 deletions

View File

@@ -138,11 +138,7 @@ export const GroupCallView: FC<Props> = ({
if (audioInput === null) {
latestMuteStates.current!.audio.setEnabled?.(false);
} else {
const deviceId = await findDeviceByName(
audioInput,
"audioinput",
devices,
);
const deviceId = findDeviceByName(audioInput, "audioinput", devices);
if (!deviceId) {
logger.warn("Unknown audio input: " + audioInput);
latestMuteStates.current!.audio.setEnabled?.(false);
@@ -158,11 +154,7 @@ export const GroupCallView: FC<Props> = ({
if (videoInput === null) {
latestMuteStates.current!.video.setEnabled?.(false);
} else {
const deviceId = await findDeviceByName(
videoInput,
"videoinput",
devices,
);
const deviceId = findDeviceByName(videoInput, "videoinput", devices);
if (!deviceId) {
logger.warn("Unknown video input: " + videoInput);
latestMuteStates.current!.video.setEnabled?.(false);
@@ -178,24 +170,27 @@ export const GroupCallView: FC<Props> = ({
if (widget && preload && skipLobby) {
// In preload mode without lobby we wait for a join action before entering
const onJoin = async (
ev: CustomEvent<IWidgetApiRequest>,
): Promise<void> => {
await defaultDeviceSetup(ev.detail.data as unknown as JoinCallData);
await enterRTCSession(rtcSession, perParticipantE2EE);
await widget!.api.transport.reply(ev.detail, {});
const onJoin = (ev: CustomEvent<IWidgetApiRequest>): void => {
(async (): Promise<void> => {
await defaultDeviceSetup(ev.detail.data as unknown as JoinCallData);
await enterRTCSession(rtcSession, perParticipantE2EE);
widget!.api.transport.reply(ev.detail, {});
})().catch((e) => {
logger.error("Error joining RTC session", e);
});
};
widget.lazyActions.on(ElementWidgetActions.JoinCall, onJoin);
return (): void => {
widget!.lazyActions.off(ElementWidgetActions.JoinCall, onJoin);
};
} else if (widget && !preload && skipLobby) {
const join = async (): Promise<void> => {
// No lobby and no preload: we enter the rtc session right away
(async (): Promise<void> => {
await defaultDeviceSetup({ audioInput: null, videoInput: null });
await enterRTCSession(rtcSession, perParticipantE2EE);
};
// No lobby and no preload: we enter the RTC Session right away.
join();
})().catch((e) => {
logger.error("Error joining RTC session", e);
});
}
}, [rtcSession, preload, skipLobby, perParticipantE2EE]);
@@ -204,7 +199,7 @@ export const GroupCallView: FC<Props> = ({
const history = useHistory();
const onLeave = useCallback(
async (leaveError?: Error) => {
(leaveError?: Error): void => {
setLeaveError(leaveError);
setLeft(true);
@@ -218,15 +213,19 @@ export const GroupCallView: FC<Props> = ({
);
// Only sends matrix leave event. The Livekit session will disconnect once the ActiveCall-view unmounts.
await leaveRTCSession(rtcSession);
if (
!isPasswordlessUser &&
!confineToRoom &&
!PosthogAnalytics.instance.isEnabled()
) {
history.push("/");
}
leaveRTCSession(rtcSession)
.then(() => {
if (
!isPasswordlessUser &&
!confineToRoom &&
!PosthogAnalytics.instance.isEnabled()
) {
history.push("/");
}
})
.catch((e) => {
logger.error("Error leaving RTC session", e);
});
},
[rtcSession, isPasswordlessUser, confineToRoom, history],
);
@@ -234,14 +233,16 @@ export const GroupCallView: FC<Props> = ({
useEffect(() => {
if (widget && isJoined) {
// set widget to sticky once joined.
widget!.api.setAlwaysOnScreen(true);
widget!.api.setAlwaysOnScreen(true).catch((e) => {
logger.error("Error calling setAlwaysOnScreen(true)", e);
});
const onHangup = async (
ev: CustomEvent<IWidgetApiRequest>,
): Promise<void> => {
const onHangup = (ev: CustomEvent<IWidgetApiRequest>): void => {
widget!.api.transport.reply(ev.detail, {});
// Only sends matrix leave event. The Livekit session will disconnect once the ActiveCall-view unmounts.
await leaveRTCSession(rtcSession);
leaveRTCSession(rtcSession).catch((e) => {
logger.error("Failed to leave RTC session", e);
});
};
widget.lazyActions.once(ElementWidgetActions.HangupCall, onHangup);
return (): void => {
@@ -253,7 +254,9 @@ export const GroupCallView: FC<Props> = ({
const onReconnect = useCallback(() => {
setLeft(false);
setLeaveError(undefined);
enterRTCSession(rtcSession, perParticipantE2EE);
enterRTCSession(rtcSession, perParticipantE2EE).catch((e) => {
logger.error("Error re-entering RTC session on reconnect", e);
});
}, [rtcSession, perParticipantE2EE]);
const joinRule = useJoinRule(rtcSession.room);

View File

@@ -29,6 +29,7 @@ import { MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc/MatrixRTCSession";
import classNames from "classnames";
import { BehaviorSubject, of } from "rxjs";
import { useObservableEagerState } from "observable-hooks";
import { logger } from "matrix-js-sdk/src/logger";
import LogoMark from "../icons/LogoMark.svg?react";
import LogoType from "../icons/LogoType.svg?react";
@@ -100,7 +101,9 @@ export const ActiveCall: FC<ActiveCallProps> = (props) => {
useEffect(() => {
return (): void => {
livekitRoom?.disconnect();
livekitRoom?.disconnect().catch((e) => {
logger.error("Failed to disconnect from livekit room", e);
});
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
@@ -296,12 +299,16 @@ export const InCallView: FC<InCallViewProps> = ({
);
useEffect(() => {
widget?.api.transport.send(
gridMode === "grid"
? ElementWidgetActions.TileLayout
: ElementWidgetActions.SpotlightLayout,
{},
);
widget?.api.transport
.send(
gridMode === "grid"
? ElementWidgetActions.TileLayout
: ElementWidgetActions.SpotlightLayout,
{},
)
.catch((e) => {
logger.error("Failed to send layout change to widget API", e);
});
}, [gridMode]);
useEffect(() => {
@@ -461,13 +468,15 @@ export const InCallView: FC<InCallViewProps> = ({
rtcSession.room.roomId,
);
const toggleScreensharing = useCallback(async () => {
await localParticipant.setScreenShareEnabled(!isScreenShareEnabled, {
audio: true,
selfBrowserSurface: "include",
surfaceSwitching: "include",
systemAudio: "include",
});
const toggleScreensharing = useCallback(() => {
localParticipant
.setScreenShareEnabled(!isScreenShareEnabled, {
audio: true,
selfBrowserSurface: "include",
surfaceSwitching: "include",
systemAudio: "include",
})
.catch(logger.error);
}, [localParticipant, isScreenShareEnabled]);
let footer: JSX.Element | null;

View File

@@ -13,6 +13,7 @@ import {
useMemo,
} from "react";
import { IWidgetApiRequest } from "matrix-widget-api";
import { logger } from "matrix-js-sdk/src/logger";
import { MediaDevice, useMediaDevices } from "../livekit/MediaDevicesContext";
import { useReactiveState } from "../useReactiveState";
@@ -74,10 +75,14 @@ export function useMuteStates(): MuteStates {
const video = useMuteState(devices.videoInput, () => true);
useEffect(() => {
widget?.api.transport.send(ElementWidgetActions.DeviceMute, {
audio_enabled: audio.enabled,
video_enabled: video.enabled,
});
widget?.api.transport
.send(ElementWidgetActions.DeviceMute, {
audio_enabled: audio.enabled,
video_enabled: video.enabled,
})
.catch((e) =>
logger.warn("Could not send DeviceMute action to widget", e),
);
}, [audio, video]);
const onMuteStateChangeRequest = useCallback(

View File

@@ -59,9 +59,13 @@ export const RoomPage: FC = () => {
// a URL param, automatically register a passwordless user
if (!loading && !authenticated && displayName && !widget) {
setIsRegistering(true);
registerPasswordlessUser(displayName).finally(() => {
setIsRegistering(false);
});
registerPasswordlessUser(displayName)
.catch((e) => {
logger.error("Failed to register passwordless user", e);
})
.finally(() => {
setIsRegistering(false);
});
}
}, [
loading,

View File

@@ -150,23 +150,22 @@ export const useLoadGroupCall = (
viaServers: string[],
onKnockSent: () => void,
): Promise<Room> => {
let joinedRoom: Room | null = null;
await client.knockRoom(roomId, { viaServers });
onKnockSent();
const invitePromise = new Promise<void>((resolve, reject) => {
return await new Promise<Room>((resolve, reject) => {
client.on(
RoomEvent.MyMembership,
async (room, membership, prevMembership) => {
(room, membership, prevMembership): void => {
if (roomId !== room.roomId) return;
activeRoom.current = room;
if (
membership === KnownMembership.Invite &&
prevMembership === KnownMembership.Knock
) {
await client.joinRoom(room.roomId, { viaServers });
joinedRoom = room;
logger.log("Auto-joined %s", room.roomId);
resolve();
client.joinRoom(room.roomId, { viaServers }).then((room) => {
logger.log("Auto-joined %s", room.roomId);
resolve(room);
}, reject);
}
if (membership === KnownMembership.Ban) reject(bannedError());
if (membership === KnownMembership.Leave)
@@ -174,11 +173,6 @@ export const useLoadGroupCall = (
},
);
});
await invitePromise;
if (!joinedRoom) {
throw new Error("Failed to join room after knocking.");
}
return joinedRoom;
};
const fetchOrCreateRoom = async (): Promise<Room> => {
@@ -308,7 +302,7 @@ export const useLoadGroupCall = (
const observeMyMembership = async (): Promise<void> => {
await new Promise((_, reject) => {
client.on(RoomEvent.MyMembership, async (_, membership) => {
client.on(RoomEvent.MyMembership, (_, membership) => {
if (membership === KnownMembership.Leave) reject(removeNoticeError());
if (membership === KnownMembership.Ban) reject(bannedError());
});