diff --git a/app/client/web/src/calling/Calling.module.css b/app/client/web/src/calling/Calling.module.css index eee1d2ec..a6664e3c 100644 --- a/app/client/web/src/calling/Calling.module.css +++ b/app/client/web/src/calling/Calling.module.css @@ -37,13 +37,13 @@ .calling { height: 100%; width: 100%; + display: flex; align-items: center; justify-content: center; - display: flex; - flex-direction: column; .title { - flex: 1; + position: absolute; + top: 32px; display: flex; justify-content: center; align-items: center; @@ -54,17 +54,17 @@ } .logo { - flex: 4; - } - - .control { - flex: 2; - display: flex; - align-items: center; - justify-content: center; + position: absolute; + max-width: 50%; + height: 50%; + aspect-ratio: 1; + top: 92px; + border-radius: 16px; } .buttons { + position: absolute; + bottom: 64px; display: flex; flex-direction: row; padding: 16px; @@ -74,7 +74,8 @@ } .status { - flex: 1; + position: absolute; + bottom: 32px; display: flex; align-items: center; justify-content: center; diff --git a/app/client/web/src/calling/Calling.tsx b/app/client/web/src/calling/Calling.tsx index d9f3f26a..a52f976a 100644 --- a/app/client/web/src/calling/Calling.tsx +++ b/app/client/web/src/calling/Calling.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import classes from './Calling.module.css' import { useCalling } from './useCalling.hook'; import { Card } from '../card/Card'; @@ -15,6 +15,8 @@ export function Calling({ callCard }: { callCard: string }) { const [ignoring, setIgnoring] = useState(false); const [declining, setDeclining] = useState(false); const [accepting, setAccepting] = useState(false); + const remote = useRef(); + const local = useRef(); const { state, actions } = useCalling(); const showError = () => { @@ -148,6 +150,22 @@ export function Calling({ callCard }: { callCard: string }) { } }, [callCard]); + useEffect(() => { + if (local.current) { + local.current.srcObject = state.localStream; + local.current.load(); + local.current.play(); + } + }, [state.localStream]); + + useEffect(() => { + if (remote.current) { + remote.current.srcObject = state.remoteStream; + remote.current.load(); + remote.current.play(); + } + }, [state.remoteStream]); + const calls = state.calls.map((contact, index) => { const { callId, card } = contact; const { name, handle, node, imageUrl } = card; @@ -164,28 +182,39 @@ export function Calling({ callCard }: { callCard: string }) { return (
0 || connecting || state.calling ? classes.active : classes.inactive}> - { !state.calling && !connecting && state.calls.length > 0 && ( -
- { calls } -
- )} - { !state.calling && connecting && ( - - )} - { state.calling && ( -
-
- { state.calling.name && ( - { state.calling.name } - )} - { !state.calling.name && ( - { `${state.calling.handle}/${state.calling.node}` } - )} +
+ { !state.calling && !connecting && state.calls.length > 0 && ( +
+ { calls }
-
- -
-
+ )} + { !state.calling && connecting && ( + + )} + { state.calling && ( +
+
+ { state.calling.name && ( + { state.calling.name } + )} + { !state.calling.name && ( + { `${state.calling.handle}/${state.calling.node}` } + )} +
+
+ +
+
+ { !state.connected && ( + { state.strings.connecting } + )} +
+
+
+
+
{ state.audioEnabled && ( @@ -206,13 +235,8 @@ export function Calling({ callCard }: { callCard: string }) {
-
- { !state.connected && ( - { state.strings.connecting } - )} -
-
- )} + )} +
) } diff --git a/app/client/web/src/calling/useCalling.hook.ts b/app/client/web/src/calling/useCalling.hook.ts index 3ef83bb8..1864c0f0 100644 --- a/app/client/web/src/calling/useCalling.hook.ts +++ b/app/client/web/src/calling/useCalling.hook.ts @@ -81,15 +81,15 @@ export function useCalling() { const audioStream = await getAudioStream(null); const audioTrack = audioStream.getTracks().find((track: MediaStreamTrack) => track.kind === 'audio'); if (audioTrack) { - localAudio.current = null; + localAudio.current = audioTrack; } localVideo.current = null; - localStream.current = new MediaStream(); + localStream.current = null; remoteStream.current = new MediaStream(); if (localAudio.current) { localAudio.current.enabled = true; - await updatePeer('local_track', localAudio.current); + await updatePeer('local_track', { track: audioTrack, stream: audioStream }); } updateState({ localStream: localStream.current, remoteStream: remoteStream.current, audioEnabled: true, videoEnabled: false, localVideo: false, remoteVideo: false, connected: true }); @@ -157,11 +157,11 @@ export function useCalling() { } } - const peerTrack = async (track: MediaStreamTrack) => { + const peerTrack = async (track: MediaStreamTrack, stream: MediaStream) => { if (call.current && localStream.current) { try { const { peer } = call.current; - peer.addTrack(track, localStream.current); + peer.addTrack(track, stream); } catch (err) { console.log(err); } @@ -189,7 +189,7 @@ export function useCalling() { } } } else if (type === 'local_track') { - await peerTrack(data); + await peerTrack(data.track, data.stream); } else if (type === 'close' && call.current) { peerUpdate.current = []; const { peer, link } = call.current; @@ -339,8 +339,9 @@ export function useCalling() { const videoTrack = videoStream.getTracks().find((track: MediaStreamTrack) => track.kind === 'video'); if (videoTrack) { localVideo.current = videoTrack; - updatePeer('local_track', videoTrack); - updateState({ localVideo: true }); + localStream.current = videoStream; + updatePeer('local_track', { track: videoTrack, stream: videoStream }); + updateState({ localVideo: true, localStream: videoStream }); } } if (localVideo.current) {