From 356c761c8fa5b56a5ef638a6093c1780c82a448c Mon Sep 17 00:00:00 2001 From: malmen237 Date: Fri, 13 Dec 2024 13:35:34 +0100 Subject: [PATCH] feat: moved symphony-connection-items into own component and added variables to global state --- .../landing-page/join-production.tsx | 3 + .../production-line/production-line.tsx | 44 +++++------ .../symphony-rtc-connection-component.tsx | 75 +++++++++++++++++++ src/global-state/types.ts | 3 + 4 files changed, 104 insertions(+), 21 deletions(-) create mode 100644 src/components/production-line/symphony-rtc-connection-component.tsx diff --git a/src/components/landing-page/join-production.tsx b/src/components/landing-page/join-production.tsx index 27e4162f..e4204875 100644 --- a/src/components/landing-page/join-production.tsx +++ b/src/components/landing-page/join-production.tsx @@ -157,6 +157,9 @@ export const JoinProduction = ({ mediaStreamInput: null, dominantSpeaker: null, audioLevelAboveThreshold: false, + connectionState: null, + audioElements: null, + sessionId: null, }, }, }); diff --git a/src/components/production-line/production-line.tsx b/src/components/production-line/production-line.tsx index 90ae13ca..037a5023 100644 --- a/src/components/production-line/production-line.tsx +++ b/src/components/production-line/production-line.tsx @@ -3,8 +3,6 @@ import { useCallback, useEffect, useState } from "react"; import { useParams } from "react-router-dom"; import { useGlobalState } from "../../global-state/context-provider.tsx"; import { useAudioInput } from "./use-audio-input.ts"; -import { useRtcConnection } from "./use-rtc-connection.ts"; -import { useEstablishSession } from "./use-establish-session.ts"; import { SecondaryButton } from "../landing-page/form-elements.tsx"; import { UserList } from "./user-list.tsx"; import { @@ -17,7 +15,6 @@ import { import { Spinner } from "../loader/loader.tsx"; import { DisplayContainerHeader } from "../landing-page/display-container-header.tsx"; import { DisplayContainer, FlexContainer } from "../generic-components.ts"; -import { useHeartbeat } from "./use-heartbeat.ts"; import { useDeviceLabels } from "./use-device-labels.ts"; import { isMobile } from "../../bowser.ts"; import { useLineHotkeys, useSpeakerHotkeys } from "./use-line-hotkeys.ts"; @@ -34,6 +31,7 @@ import { ExitCallButton } from "./exit-call-button.tsx"; import { Modal } from "../modal/modal.tsx"; import { VerifyDecision } from "../verify-decision/verify-decision.tsx"; import { ModalConfirmationText } from "../modal/modal-confirmation-text.ts"; +import { SymphonyRtcConnectionComponent } from "./symphony-rtc-connection-component.tsx"; const TempDiv = styled.div` padding: 0 0 2rem 0; @@ -136,6 +134,7 @@ export const ProductionLine = ({ }: TProductionLine) => { const { productionId: paramProductionId, lineId: paramLineId } = useParams(); const [, dispatch] = useGlobalState(); + const [connectionActive, setConnectionActive] = useState(true); const [isInputMuted, setIsInputMuted] = useState(true); const [isOutputMuted, setIsOutputMuted] = useState(false); const [isSettingsModalOpen, setIsSettingsModalOpen] = useState(false); @@ -150,8 +149,14 @@ export const ProductionLine = ({ speakerHotkey: "n", pressToTalkHotkey: "t", }); - const { joinProductionOptions, dominantSpeaker, audioLevelAboveThreshold } = - callState; + const { + joinProductionOptions, + dominantSpeaker, + audioLevelAboveThreshold, + connectionState, + audioElements, + sessionId, + } = callState; const inputAudioStream = useAudioInput({ inputId: joinProductionOptions?.audioinput ?? null, @@ -173,6 +178,7 @@ export const ProductionLine = ({ const { playEnterSound, playExitSound } = useAudioCue(); const exit = useCallback(() => { + setConnectionActive(false); playExitSound(); dispatch({ type: "REMOVE_CALL", @@ -187,20 +193,6 @@ export const ProductionLine = ({ customKeyPress: savedHotkeys.pressToTalkHotkey, }); - const { sessionId, sdpOffer } = useEstablishSession({ - joinProductionOptions, - callId: id, - dispatch, - }); - - const { connectionState, audioElements } = useRtcConnection({ - inputAudioStream, - sdpOffer, - joinProductionOptions, - sessionId, - callId: id, - }); - useEffect(() => { if (connectionState === "connected") { playEnterSound(); @@ -208,6 +200,8 @@ export const ProductionLine = ({ }, [connectionState, playEnterSound]); const muteOutput = useCallback(() => { + if (!audioElements) return; + audioElements.forEach((singleElement: HTMLAudioElement) => { // eslint-disable-next-line no-param-reassign singleElement.muted = !isOutputMuted; @@ -245,8 +239,6 @@ export const ProductionLine = ({ const { loading, connectionError } = useIsLoading({ connectionState }); - useHeartbeat({ sessionId }); - const deviceLabels = useDeviceLabels({ joinProductionOptions }); useCheckBadLineData({ @@ -288,6 +280,7 @@ export const ProductionLine = ({ )} )} + {!loading && production && line && ( Production: {production.name}{" "} @@ -296,6 +289,15 @@ export const ProductionLine = ({ )} + {connectionActive && ( + + )} + {joinProductionOptions && connectionState && ( diff --git a/src/components/production-line/symphony-rtc-connection-component.tsx b/src/components/production-line/symphony-rtc-connection-component.tsx new file mode 100644 index 00000000..2f93b2e3 --- /dev/null +++ b/src/components/production-line/symphony-rtc-connection-component.tsx @@ -0,0 +1,75 @@ +import { useEffect } from "react"; +import { TJoinProductionOptions } from "./types"; +import { TGlobalStateAction } from "../../global-state/global-state-actions"; +import { useEstablishSession } from "./use-establish-session"; +import { useRtcConnection } from "./use-rtc-connection"; +import { useHeartbeat } from "./use-heartbeat"; +import { TUseAudioInputValues } from "./use-audio-input"; + +type SymphonyRtcConnectionComponentProps = { + joinProductionOptions: TJoinProductionOptions | null; + inputAudioStream: TUseAudioInputValues; + callId: string; + dispatch: React.Dispatch; +}; + +export const SymphonyRtcConnectionComponent = ({ + joinProductionOptions, + inputAudioStream, + callId, + dispatch, +}: SymphonyRtcConnectionComponentProps) => { + const { sessionId, sdpOffer } = useEstablishSession({ + joinProductionOptions, + callId, + dispatch, + }); + + const { connectionState, audioElements } = useRtcConnection({ + inputAudioStream, + sdpOffer, + joinProductionOptions, + sessionId, + callId, + }); + + useHeartbeat({ sessionId }); + + useEffect(() => { + dispatch({ + type: "UPDATE_CALL", + payload: { + id: callId, + updates: { + connectionState, + }, + }, + }); + }, [callId, connectionState, dispatch]); + + useEffect(() => { + dispatch({ + type: "UPDATE_CALL", + payload: { + id: callId, + updates: { + audioElements, + }, + }, + }); + }, [audioElements, callId, dispatch]); + + useEffect(() => { + dispatch({ + type: "UPDATE_CALL", + payload: { + id: callId, + updates: { + sessionId, + }, + }, + }); + }, [sessionId, callId, dispatch]); + + return null; +}; diff --git a/src/global-state/types.ts b/src/global-state/types.ts index a5a0686f..053a99ba 100644 --- a/src/global-state/types.ts +++ b/src/global-state/types.ts @@ -16,6 +16,9 @@ export interface CallState { mediaStreamInput: MediaStream | null; dominantSpeaker: string | null; audioLevelAboveThreshold: boolean; + connectionState: RTCPeerConnectionState | null; + audioElements: HTMLAudioElement[] | null; + sessionId: string | null; } export type TGlobalState = {