Skip to content

Commit

Permalink
Merge pull request #68 from whereby/nandor/pan-269-clean-up-event-lis…
Browse files Browse the repository at this point in the history
…teners

Clean up event listeners
  • Loading branch information
thyal authored Sep 12, 2023
2 parents 19daff2 + d171488 commit e7069ce
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 110 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@whereby.com/browser-sdk",
"version": "2.0.0-alpha18",
"version": "2.0.0-alpha19",
"description": "Modules for integration Whereby video in web apps",
"author": "Whereby AS",
"license": "MIT",
Expand Down
70 changes: 41 additions & 29 deletions src/lib/RoomConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,81 +67,83 @@ export type StreamingState = {
startedAt: number | null;
};

type RoomJoinedEvent = {
export type RoomJoinedEvent = {
localParticipant: LocalParticipant;
remoteParticipants: RemoteParticipant[];
waitingParticipants: WaitingParticipant[];
};

type RoomConnectionStatusChangedEvent = {
export type RoomConnectionStatusChangedEvent = {
roomConnectionStatus: RoomConnectionStatus;
};

type ParticipantJoinedEvent = {
export type ParticipantJoinedEvent = {
remoteParticipant: RemoteParticipant;
};

type ParticipantLeftEvent = {
export type ParticipantLeftEvent = {
participantId: string;
};

type ParticipantStreamAddedEvent = {
export type ParticipantStreamAddedEvent = {
participantId: string;
stream: MediaStream;
};

type ParticipantAudioEnabledEvent = {
export type ParticipantAudioEnabledEvent = {
participantId: string;
isAudioEnabled: boolean;
};

type ParticipantVideoEnabledEvent = {
export type ParticipantVideoEnabledEvent = {
participantId: string;
isVideoEnabled: boolean;
};

type ParticipantMetadataChangedEvent = {
export type ParticipantMetadataChangedEvent = {
participantId: string;
displayName: string;
};

type ScreenshareStartedEvent = {
export type ScreenshareStartedEvent = {
participantId: string;
id: string;
hasAudioTrack: boolean;
stream: MediaStream;
};

type ScreenshareStoppedEvent = {
export type ScreenshareStoppedEvent = {
participantId: string;
id: string;
};

type WaitingParticipantJoinedEvent = {
export type WaitingParticipantJoinedEvent = {
participantId: string;
displayName: string | null;
};

type WaitingParticipantLeftEvent = {
export type WaitingParticipantLeftEvent = {
participantId: string;
};

interface RoomEventsMap {
chat_message: CustomEvent<ChatMessage>;
cloud_recording_started: CustomEvent<CloudRecordingState>;
participant_audio_enabled: CustomEvent<ParticipantAudioEnabledEvent>;
participant_joined: CustomEvent<ParticipantJoinedEvent>;
participant_left: CustomEvent<ParticipantLeftEvent>;
participant_metadata_changed: CustomEvent<ParticipantMetadataChangedEvent>;
participant_stream_added: CustomEvent<ParticipantStreamAddedEvent>;
participant_video_enabled: CustomEvent<ParticipantVideoEnabledEvent>;
room_connection_status_changed: CustomEvent<RoomConnectionStatusChangedEvent>;
room_joined: CustomEvent<RoomJoinedEvent>;
screenshare_started: CustomEvent<ScreenshareStartedEvent>;
screenshare_stopped: CustomEvent<ScreenshareStoppedEvent>;
streaming_started: CustomEvent<StreamingState>;
waiting_participant_joined: CustomEvent<WaitingParticipantJoinedEvent>;
waiting_participant_left: CustomEvent<WaitingParticipantLeftEvent>;
export interface RoomEventsMap {
chat_message: (e: CustomEvent<ChatMessage>) => void;
cloud_recording_started: (e: CustomEvent<CloudRecordingState>) => void;
cloud_recording_stopped: (e: CustomEvent<CloudRecordingState>) => void;
participant_audio_enabled: (e: CustomEvent<ParticipantAudioEnabledEvent>) => void;
participant_joined: (e: CustomEvent<ParticipantJoinedEvent>) => void;
participant_left: (e: CustomEvent<ParticipantLeftEvent>) => void;
participant_metadata_changed: (e: CustomEvent<ParticipantMetadataChangedEvent>) => void;
participant_stream_added: (e: CustomEvent<ParticipantStreamAddedEvent>) => void;
participant_video_enabled: (e: CustomEvent<ParticipantVideoEnabledEvent>) => void;
room_connection_status_changed: (e: CustomEvent<RoomConnectionStatusChangedEvent>) => void;
room_joined: (e: CustomEvent<RoomJoinedEvent>) => void;
screenshare_started: (e: CustomEvent<ScreenshareStartedEvent>) => void;
screenshare_stopped: (e: CustomEvent<ScreenshareStoppedEvent>) => void;
streaming_started: (e: CustomEvent<StreamingState>) => void;
streaming_stopped: (e: CustomEvent<StreamingState>) => void;
waiting_participant_joined: (e: CustomEvent<WaitingParticipantJoinedEvent>) => void;
waiting_participant_left: (e: CustomEvent<WaitingParticipantLeftEvent>) => void;
}

const API_BASE_URL = process.env["REACT_APP_API_BASE_URL"] || "https://api.whereby.dev";
Expand Down Expand Up @@ -177,14 +179,24 @@ function createSocket() {
interface RoomEventTarget extends EventTarget {
addEventListener<K extends keyof RoomEventsMap>(
type: K,
listener: (ev: RoomEventsMap[K]) => void,
listener: RoomEventsMap[K],
options?: boolean | AddEventListenerOptions
): void;
addEventListener(
type: string,
callback: EventListenerOrEventListenerObject | null,
options?: EventListenerOptions | boolean
): void;
removeEventListener<K extends keyof RoomEventsMap>(
type: K,
listener: RoomEventsMap[K],
options?: boolean | EventListenerOptions
): void;
removeEventListener(
type: string,
callback: EventListenerOrEventListenerObject | null,
options?: EventListenerOptions | boolean
): void;
}

const noop = () => {
Expand Down
184 changes: 104 additions & 80 deletions src/lib/react/useRoomConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import RoomConnection, {
CloudRecordingState,
RoomConnectionOptions,
RoomConnectionStatus,
RoomEventsMap,
StreamingState,
} from "../RoomConnection";
import { LocalParticipant, RemoteParticipant, Screenshare, WaitingParticipant } from "../RoomParticipant";
Expand Down Expand Up @@ -354,94 +355,117 @@ export default function useRoomConnection(
);
const [state, dispatch] = useReducer(reducer, initialState);

useEffect(() => {
roomConnection.addEventListener("chat_message", (e) => {
const chatMessage = e.detail;
dispatch({ type: "CHAT_MESSAGE", payload: chatMessage });
});

roomConnection.addEventListener("cloud_recording_started", (e) => {
const { status, startedAt } = e.detail;
dispatch({ type: "CLOUD_RECORDING_STARTED", payload: { status, startedAt } });
});

roomConnection.addEventListener("cloud_recording_stopped", () => {
dispatch({ type: "CLOUD_RECORDING_STOPPED" });
});

roomConnection.addEventListener("participant_audio_enabled", (e) => {
const { participantId, isAudioEnabled } = e.detail;
dispatch({ type: "PARTICIPANT_AUDIO_ENABLED", payload: { participantId, isAudioEnabled } });
});

roomConnection.addEventListener("participant_joined", (e) => {
const { remoteParticipant } = e.detail;
dispatch({ type: "PARTICIPANT_JOINED", payload: { paritipant: remoteParticipant } });
});

roomConnection.addEventListener("participant_left", (e) => {
const { participantId } = e.detail;
dispatch({ type: "PARTICIPANT_LEFT", payload: { participantId } });
});

roomConnection.addEventListener("participant_stream_added", (e) => {
const { participantId, stream } = e.detail;
dispatch({ type: "PARTICIPANT_STREAM_ADDED", payload: { participantId, stream } });
});

roomConnection.addEventListener("room_connection_status_changed", (e) => {
const { roomConnectionStatus } = e.detail;
dispatch({ type: "ROOM_CONNECTION_STATUS_CHANGED", payload: { roomConnectionStatus } });
});

roomConnection.addEventListener("room_joined", (e) => {
const { localParticipant, remoteParticipants, waitingParticipants } = e.detail;
dispatch({ type: "ROOM_JOINED", payload: { localParticipant, remoteParticipants, waitingParticipants } });
});

roomConnection.addEventListener("participant_video_enabled", (e) => {
const { participantId, isVideoEnabled } = e.detail;
dispatch({ type: "PARTICIPANT_VIDEO_ENABLED", payload: { participantId, isVideoEnabled } });
});

roomConnection.addEventListener("participant_metadata_changed", (e) => {
const { participantId, displayName } = e.detail;
dispatch({ type: "PARTICIPANT_METADATA_CHANGED", payload: { participantId, displayName } });
});

roomConnection.addEventListener("screenshare_started", (e) => {
const { participantId, id, hasAudioTrack, stream } = e.detail;

dispatch({ type: "SCREENSHARE_STARTED", payload: { participantId, id, hasAudioTrack, stream } });
});

roomConnection.addEventListener("screenshare_stopped", (e) => {
const { participantId, id } = e.detail;
dispatch({ type: "SCREENSHARE_STOPPED", payload: { participantId, id } });
});

roomConnection.addEventListener("streaming_started", (e) => {
const { status, startedAt } = e.detail;
dispatch({ type: "STREAMING_STARTED", payload: { status, startedAt } });
});
type EventListener<K extends keyof RoomEventsMap> = {
eventName: K;
listener: RoomEventsMap[K];
options?: boolean | AddEventListenerOptions;
};

roomConnection.addEventListener("streaming_stopped", () => {
dispatch({ type: "STREAMING_STOPPED" });
});
function createEventListener<K extends keyof RoomEventsMap>(
eventName: K,
listener: RoomEventsMap[K],
options?: boolean | AddEventListenerOptions
): EventListener<K> {
return {
eventName,
listener,
options,
};
}

roomConnection.addEventListener("waiting_participant_joined", (e) => {
const { participantId, displayName } = e.detail;
dispatch({ type: "WAITING_PARTICIPANT_JOINED", payload: { participantId, displayName } });
});
const eventListeners = React.useMemo(
(): EventListener<keyof RoomEventsMap>[] => [
createEventListener("chat_message", (e) => {
dispatch({ type: "CHAT_MESSAGE", payload: e.detail });
}),
createEventListener("cloud_recording_started", (e) => {
const { status, startedAt } = e.detail;
dispatch({ type: "CLOUD_RECORDING_STARTED", payload: { status, startedAt } });
}),
createEventListener("cloud_recording_stopped", () => {
dispatch({ type: "CLOUD_RECORDING_STOPPED" });
}),
createEventListener("participant_audio_enabled", (e) => {
const { participantId, isAudioEnabled } = e.detail;
dispatch({ type: "PARTICIPANT_AUDIO_ENABLED", payload: { participantId, isAudioEnabled } });
}),
createEventListener("participant_joined", (e) => {
const { remoteParticipant } = e.detail;
dispatch({ type: "PARTICIPANT_JOINED", payload: { paritipant: remoteParticipant } });
}),
createEventListener("participant_left", (e) => {
const { participantId } = e.detail;
dispatch({ type: "PARTICIPANT_LEFT", payload: { participantId } });
}),
createEventListener("participant_metadata_changed", (e) => {
const { participantId, displayName } = e.detail;
dispatch({ type: "PARTICIPANT_METADATA_CHANGED", payload: { participantId, displayName } });
}),
createEventListener("participant_stream_added", (e) => {
const { participantId, stream } = e.detail;
dispatch({ type: "PARTICIPANT_STREAM_ADDED", payload: { participantId, stream } });
}),
createEventListener("participant_video_enabled", (e) => {
const { participantId, isVideoEnabled } = e.detail;
dispatch({ type: "PARTICIPANT_VIDEO_ENABLED", payload: { participantId, isVideoEnabled } });
}),
createEventListener("room_connection_status_changed", (e) => {
const { roomConnectionStatus } = e.detail;
dispatch({
type: "ROOM_CONNECTION_STATUS_CHANGED",
payload: { roomConnectionStatus },
});
}),
createEventListener("room_joined", (e) => {
const { localParticipant, remoteParticipants, waitingParticipants } = e.detail;
dispatch({
type: "ROOM_JOINED",
payload: { localParticipant, remoteParticipants, waitingParticipants },
});
}),
createEventListener("screenshare_started", (e) => {
const { participantId, stream, id, hasAudioTrack } = e.detail;
dispatch({
type: "SCREENSHARE_STARTED",
payload: { participantId, stream, id, hasAudioTrack },
});
}),
createEventListener("screenshare_stopped", (e) => {
const { participantId, id } = e.detail;
dispatch({
type: "SCREENSHARE_STOPPED",
payload: { participantId, id },
});
}),
createEventListener("streaming_started", (e) => {
const { status, startedAt } = e.detail;
dispatch({ type: "STREAMING_STARTED", payload: { status, startedAt } });
}),
createEventListener("streaming_stopped", () => {
dispatch({ type: "STREAMING_STOPPED" });
}),
createEventListener("waiting_participant_joined", (e) => {
const { participantId, displayName } = e.detail;
dispatch({
type: "WAITING_PARTICIPANT_JOINED",
payload: { participantId, displayName },
});
}),
],
[]
);

roomConnection.addEventListener("waiting_participant_left", (e) => {
const { participantId } = e.detail;
dispatch({ type: "WAITING_PARTICIPANT_LEFT", payload: { participantId } });
useEffect(() => {
eventListeners.forEach(({ eventName, listener }) => {
roomConnection.addEventListener(eventName, listener);
});

roomConnection.join();

return () => {
eventListeners.forEach(({ eventName, listener }) => {
roomConnection.removeEventListener(eventName, listener);
});
roomConnection.leave();
};
}, []);
Expand Down

0 comments on commit e7069ce

Please sign in to comment.