Skip to content

Commit e28bf0f

Browse files
committed
Add end call function, ammend styling and fix bugs
1 parent 31579dc commit e28bf0f

File tree

2 files changed

+101
-13
lines changed

2 files changed

+101
-13
lines changed

apps/frontend/src/components/VideoPanel/VideoPanel.tsx

Lines changed: 99 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,12 @@ const VideoPanel = () => {
2323
const [callInstance, setCallInstance] = useState<MediaConnection | null>(
2424
null
2525
);
26+
const [remoteCallInstance, setRemoteCallInstance] =
27+
useState<MediaConnection | null>(null);
2628
const [userStream, setUserStream] = useState<MediaStream | null>(null);
2729
const [videoOn, setVideoOn] = useState<boolean>(true);
2830
const [muteOn, setMuteOn] = useState<boolean>(false);
31+
const [isCalling, setIsCalling] = useState<boolean>(false);
2932

3033
const handleCall = () => {
3134
navigator.mediaDevices
@@ -37,6 +40,7 @@ const VideoPanel = () => {
3740
if (peerInstance) {
3841
const call = peerInstance?.call(partnerId, stream);
3942
setCallInstance(call);
43+
setIsCalling(true); // Set isCalling as true since it is the initiator
4044
if (call) {
4145
call.on("stream", (userVideoStream: MediaStream) => {
4246
if (remoteVideoRef.current) {
@@ -100,6 +104,8 @@ const VideoPanel = () => {
100104

101105
peer.on("call", (call) => {
102106
call.answer(stream);
107+
setIsCalling(true); // When a peer initiates call, on answer, set the calling state to true
108+
setRemoteCallInstance(call); // Set remote call instance media connection
103109
call.on("stream", (userVideoStream) => {
104110
if (remoteVideoRef.current) {
105111
remoteVideoRef.current.srcObject = userVideoStream;
@@ -116,6 +122,17 @@ const VideoPanel = () => {
116122
}
117123
}, []);
118124

125+
// When remote peer initiates end call, we set isCalling to false
126+
useEffect(() => {
127+
remoteCallInstance?.on("close", () => {
128+
setIsCalling(false);
129+
});
130+
131+
callInstance?.on("close", () => {
132+
setIsCalling(false);
133+
});
134+
}, [remoteCallInstance?.open, callInstance?.open]);
135+
119136
const toggleVideo = () => {
120137
if (userStream) {
121138
const videoTrack = userStream.getVideoTracks()[0];
@@ -126,8 +143,10 @@ const VideoPanel = () => {
126143
videoTrack.enabled = false;
127144

128145
setVideoOn(false);
129-
if (callInstance) {
130-
const sender = callInstance.peerConnection
146+
if (callInstance && remoteCallInstance?.open) {
147+
const sender = (
148+
callInstance.peerConnection || remoteCallInstance.peerConnection
149+
)
131150
.getSenders()
132151
.find((s) => {
133152
if (s.track) {
@@ -147,6 +166,18 @@ const VideoPanel = () => {
147166
}
148167
};
149168

169+
const handleCloseConnection = () => {
170+
if (callInstance && callInstance.open) {
171+
callInstance.close();
172+
setIsCalling(false);
173+
}
174+
175+
if (remoteCallInstance && remoteCallInstance.open) {
176+
remoteCallInstance.close();
177+
setIsCalling(false);
178+
}
179+
};
180+
150181
const toggleMute = () => {
151182
if (userStream) {
152183
const audioTrack = userStream.getAudioTracks()[0];
@@ -161,8 +192,10 @@ const VideoPanel = () => {
161192
audioTrack.enabled = false;
162193
setMuteOn(true);
163194

164-
if (callInstance) {
165-
const sender = callInstance.peerConnection
195+
if (callInstance && remoteCallInstance?.open) {
196+
const sender = (
197+
callInstance.peerConnection || remoteCallInstance.peerConnection
198+
)
166199
.getSenders()
167200
.find((s) => {
168201
if (s.track) {
@@ -186,6 +219,7 @@ const VideoPanel = () => {
186219
playsInline
187220
ref={currentUserVideoRef}
188221
autoPlay
222+
muted
189223
/>
190224
<div className="buttons-container">
191225
<Button
@@ -232,17 +266,70 @@ const VideoPanel = () => {
232266
>
233267
{muteOn ? "On Mic" : "Off Mic"}
234268
</Button>
235-
<Button onClick={handleCall} icon={<ApiOutlined />} type="primary">
236-
Call
269+
<Button
270+
onClick={isCalling ? handleCloseConnection : handleCall}
271+
icon={
272+
isCalling ? (
273+
<div className="icon-padding">
274+
<svg
275+
xmlns="http://www.w3.org/2000/svg"
276+
width="1.2em"
277+
height="1.2em"
278+
viewBox="0 0 24 24"
279+
>
280+
<g fill="none">
281+
<path
282+
stroke="currentColor"
283+
strokeLinecap="round"
284+
strokeWidth={2}
285+
d="m20 4l-4 4m0-4l4 4"
286+
></path>
287+
<path
288+
fill="currentColor"
289+
d="m15.1 15.027l-.543-.516zm.456-.48l.544.517zm2.417-.335l-.374.65zm1.91 1.1l-.374.65zm.539 3.446l.543.517zm-1.42 1.496l-.545-.517zm-1.326.71l.074.745zm-9.86-4.489l.543-.516zm-4.813-9.51l-.749.041zm6.475 1.538l.543.517zm.156-2.81l.613-.433zM8.374 3.91l-.613.433zM5.26 3.609l.544.516zM3.691 5.26l-.543-.516zm7.372 7.795l.544-.517zm4.582 2.488l.455-.48l-1.088-1.033l-.455.48zm1.954-.682l1.91 1.1l.749-1.3l-1.911-1.1zm2.279 3.38l-1.42 1.495l1.087 1.034l1.42-1.496zm-2.275 1.975c-1.435.141-5.18.02-9.244-4.258l-1.087 1.033c4.429 4.663 8.654 4.898 10.478 4.717zm-9.244-4.258c-3.876-4.081-4.526-7.523-4.607-9.033l-1.498.08c.1 1.85.884 5.634 5.018 9.986zm1.376-6.637l.286-.302l-1.087-1.033l-.287.302zm.512-4.062L8.986 3.477l-1.225.866l1.26 1.783zm-5.53-2.168L3.149 4.745l1.088 1.033l1.57-1.653zm4.474 5.713a38 38 0 0 0-.545-.515l-.002.002l-.003.003l-.05.058a1.6 1.6 0 0 0-.23.427c-.098.275-.15.639-.084 1.093c.13.892.715 2.091 2.242 3.7l1.088-1.034c-1.428-1.503-1.78-2.428-1.846-2.884c-.032-.22 0-.335.013-.372l.008-.019l-.028.037l-.018.02s-.002 0-.545-.516m1.328 4.767c1.523 1.604 2.673 2.234 3.55 2.377c.451.073.816.014 1.092-.095a1.5 1.5 0 0 0 .421-.25l.036-.034l.014-.014l.007-.006l.003-.003l.001-.002s.002-.001-.542-.518c-.544-.516-.543-.517-.543-.518l.002-.001l.002-.003l.005-.005l.01-.01l.037-.032q.015-.008-.004.001c-.02.008-.11.04-.3.009c-.402-.066-1.27-.42-2.703-1.929zM8.986 3.477C7.972 2.043 5.944 1.8 4.718 3.092l1.087 1.033c.523-.55 1.444-.507 1.956.218zM3.752 6.926c-.022-.4.152-.8.484-1.148L3.148 4.745c-.536.564-.943 1.347-.894 2.261zm14.705 12.811c-.279.294-.57.452-.854.48l.147 1.492c.747-.073 1.352-.472 1.795-.939zM10.021 9.02c.968-1.019 1.036-2.613.226-3.76l-1.225.866c.422.597.357 1.392-.088 1.86zm9.488 6.942c.821.473.982 1.635.369 2.28l1.087 1.033c1.305-1.374.925-3.673-.707-4.613zm-3.409-.898c.385-.406.986-.497 1.499-.202l.748-1.3c-1.099-.632-2.46-.45-3.335.47z"
290+
></path>
291+
</g>
292+
</svg>
293+
</div>
294+
) : (
295+
<div className="icon-padding">
296+
<svg
297+
xmlns="http://www.w3.org/2000/svg"
298+
width="1.2em"
299+
height="1.2em"
300+
viewBox="0 0 24 24"
301+
>
302+
<g fill="none">
303+
<path
304+
stroke="currentColor"
305+
strokeLinecap="round"
306+
strokeWidth={2}
307+
d="M13.5 2s2.334.212 5.303 3.182c2.97 2.97 3.182 5.303 3.182 5.303m-7.778-4.949s.99.282 2.475 1.767s1.768 2.475 1.768 2.475"
308+
></path>
309+
<path
310+
fill="currentColor"
311+
d="m15.1 15.027l-.543-.516zm.456-.48l.544.517zm2.417-.335l-.374.65zm1.91 1.1l-.374.65zm.539 3.446l.543.517zm-1.42 1.496l-.545-.517zm-1.326.71l.074.745zm-9.86-4.489l.543-.516zm-4.813-9.51l-.749.041zm6.475 1.538l.543.517zm.156-2.81l.613-.433zM8.374 3.91l-.613.433zM5.26 3.609l.544.516zM3.691 5.26l-.543-.516zm7.372 7.795l.544-.517zm4.582 2.488l.455-.48l-1.088-1.033l-.455.48zm1.954-.682l1.91 1.1l.749-1.3l-1.911-1.1zm2.279 3.38l-1.42 1.495l1.087 1.034l1.42-1.496zm-2.275 1.975c-1.435.141-5.18.02-9.244-4.258l-1.087 1.033c4.429 4.663 8.654 4.898 10.478 4.717zm-9.244-4.258c-3.876-4.081-4.526-7.523-4.607-9.033l-1.498.08c.1 1.85.884 5.634 5.018 9.986zm1.376-6.637l.286-.302l-1.087-1.033l-.287.302zm.512-4.062L8.986 3.477l-1.225.866l1.26 1.783zm-5.53-2.168L3.149 4.745l1.088 1.033l1.57-1.653zm4.474 5.713a38 38 0 0 0-.545-.515l-.002.002l-.003.003l-.05.058a1.6 1.6 0 0 0-.23.427c-.098.275-.15.639-.084 1.093c.13.892.715 2.091 2.242 3.7l1.088-1.034c-1.428-1.503-1.78-2.428-1.846-2.884c-.032-.22 0-.335.013-.372l.008-.019l-.028.037l-.018.02s-.002 0-.545-.516m1.328 4.767c1.523 1.604 2.673 2.234 3.55 2.377c.451.073.816.014 1.092-.095a1.5 1.5 0 0 0 .421-.25l.036-.034l.014-.014l.007-.006l.003-.003l.001-.002s.002-.001-.542-.518c-.544-.516-.543-.517-.543-.518l.002-.001l.002-.003l.005-.005l.01-.01l.037-.032q.015-.008-.004.001c-.02.008-.11.04-.3.009c-.402-.066-1.27-.42-2.703-1.929zM8.986 3.477C7.972 2.043 5.944 1.8 4.718 3.092l1.087 1.033c.523-.55 1.444-.507 1.956.218zM3.752 6.926c-.022-.4.152-.8.484-1.148L3.148 4.745c-.536.564-.943 1.347-.894 2.261zm14.705 12.811c-.279.294-.57.452-.854.48l.147 1.492c.747-.073 1.352-.472 1.795-.939zM10.021 9.02c.968-1.019 1.036-2.613.226-3.76l-1.225.866c.422.597.357 1.392-.088 1.86zm9.488 6.942c.821.473.982 1.635.369 2.28l1.087 1.033c1.305-1.374.925-3.673-.707-4.613zm-3.409-.898c.385-.406.986-.497 1.499-.202l.748-1.3c-1.099-.632-2.46-.45-3.335.47z"
312+
></path>
313+
</g>
314+
</svg>
315+
</div>
316+
)
317+
}
318+
type="primary"
319+
danger={isCalling}
320+
>
321+
{isCalling ? "End" : "Call"}
237322
</Button>
238323
</div>
239324
{/* <p className="header-tag">Video Feed for: {matchedUsername}</p> */}
240-
<video
241-
className="matched-user-video"
242-
playsInline
243-
ref={remoteVideoRef}
244-
autoPlay
245-
/>
325+
{isCalling && (
326+
<video
327+
className="matched-user-video"
328+
playsInline
329+
ref={remoteVideoRef}
330+
autoPlay
331+
/>
332+
)}
246333
</div>
247334
);
248335
};

apps/frontend/src/components/VideoPanel/styles.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55

66
.user-video,
77
.matched-user-video {
8+
margin-top: 4px;
89
width: 100%;
9-
margin: 4px 0px 0px;
10+
max-height: 40%; // Set the max height to 40%
1011
}
1112

1213
.header-tag {

0 commit comments

Comments
 (0)