import React, { useState } from "react";
import Twilio from "twilio-video";
import { emptyObject, processOptions, useVars } from "../../_core";
import { useMemo } from "react";
import { useCallback } from "react";
import { useEffect } from "react";
import { VideoRoomParticipant } from "./VideoRoomParticipant";
/**
* Componente que renderiza una pizarra donde el usuario puede dibujar libremente.
* En la documentacion se pueden consultar las opciones que acepta options: https://github.com/embiem/react-canvas-draw
*
* @name Reactor.Components.Media.VideoRoom
* Example
*
*
<video_room
access_token="abcd1234"
options='{
"classes": {
"classes_root": "w-full max-w-full h-screen relative bg-gray-800",
"classes_participant": "h-full w-full max-w-full max-h-full bg-gray-800 flex justify-center rounded overflow-auto relative",
"classes_video_off": "h-full w-full bg-gray-800 text-white absolute flex justify-center items-center",
"classes_mic_off": "absolute flex top-1 left-1 text-white inline-flex items-center justify-center w-8 h-8 bg-gray-800 rounded-full",
"classes_video": "h-full max-w-full max-h-full",
"classes_local_participant": "absolute h-32 flex justify-center bottom-5 right-5 shadow-2xl",
"classes_local_videoOff": "h-full w-full bg-gray-800 text-white absolute flex justify-center items-center",
"classes_localMicOff": "absolute flex top-1 left-1 text-white inline-flex items-center justify-center w-8 h-8 bg-gray-800 rounded-full",
"classes_localVideo": "h-full max-w-full max-h-full",
"classes_controls": "absolute h-32 bottom-0 right-0 w-full flex justify-center items-center gap-4",
"classes_toggleMic": "",
"classes_toggleMicDisabled": "",
"classes_toggleVideo": "",
"classes_toggleVideoDisabled": "",
"classes_disconnect": ""
},
}'
on_disconnected="Pagina"
on_local_disconneted="Pagina"
>Conectando...</video_room>
*/
const contents = {
disconnect: <svg data-v-041ad48a='' version='1.1' viewBox='0 0 24 24' ><path pid='0' d='M0 0h24v24H0V0z' fill='none'></path><path pid='1' d='M18.59 10.52c1.05.51 2.04 1.15 2.96 1.91l-1.07 1.07c-.58-.47-1.21-.89-1.88-1.27v-1.71m-13.2 0v1.7c-.65.37-1.28.79-1.87 1.27l-1.07-1.07c.91-.75 1.9-1.38 2.94-1.9M12 7C7.46 7 3.34 8.78.29 11.67c-.18.18-.29.43-.29.71s.11.53.29.7l2.48 2.48c.18.18.43.29.71.29.27 0 .52-.1.7-.28.79-.73 1.68-1.36 2.66-1.85.33-.16.56-.51.56-.9v-3.1C8.85 9.25 10.4 9 12 9s3.15.25 4.59.73v3.1c0 .4.23.74.56.9.98.49 1.88 1.11 2.67 1.85.18.17.43.28.7.28.28 0 .53-.11.71-.29l2.48-2.48c.18-.18.29-.43.29-.71s-.11-.53-.29-.71A16.971 16.971 0 0012 7z'></path></svg>,
toggleMicDisabled: <svg data-v-041ad48a='' version='1.1' viewBox='0 0 24 24' ><g fill='none'><path pid='0' d='M0 0h24v24H0z'></path><path pid='1' d='M0 0h24v24H0z'></path><path pid='2' d='M0 0h24v24H0z'></path></g><path pid='3' d='M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3z'></path><path pid='4' d='M17 11c0 2.76-2.24 5-5 5s-5-2.24-5-5H5c0 3.53 2.61 6.43 6 6.92V21h2v-3.08c3.39-.49 6-3.39 6-6.92h-2z'></path></svg>,
toggleMic: <svg data-v-041ad48a='' version='1.1' viewBox='0 0 24 24' ><path pid='0' d='M0 0h24v24H0V0z' fill='none'></path><path pid='1' d='M10.8 4.9c0-.66.54-1.2 1.2-1.2s1.2.54 1.2 1.2l-.01 3.91L15 10.6V5c0-1.66-1.34-3-3-3-1.54 0-2.79 1.16-2.96 2.65l1.76 1.76V4.9zM19 11h-1.7c0 .58-.1 1.13-.27 1.64l1.27 1.27c.44-.88.7-1.87.7-2.91zM4.41 2.86L3 4.27l6 6V11c0 1.66 1.34 3 3 3 .23 0 .44-.03.65-.08l1.66 1.66c-.71.33-1.5.52-2.31.52-2.76 0-5.3-2.1-5.3-5.1H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28a7.13 7.13 0 002.55-.9l4.2 4.2 1.41-1.41L4.41 2.86z'></path></svg>,
toggleVideoDisabled: <svg data-v-041ad48a='' version='1.1' viewBox='0 0 24 24' ><path pid='0' d='M0 0h24v24H0V0z' fill='none'></path><path pid='1' d='M15 8v8H5V8h10m1-2H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4V7c0-.55-.45-1-1-1z'></path></svg>,
toggleVideo: <svg data-v-041ad48a='' version='1.1' viewBox='0 0 24 24' ><path pid='0' d='M0 0h24v24H0V0z' fill='none'></path><path pid='1' d='M9.56 8l-2-2-4.15-4.14L2 3.27 4.73 6H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.21 0 .39-.08.55-.18L19.73 21l1.41-1.41-8.86-8.86L9.56 8zM5 16V8h1.73l8 8H5zm10-8v2.61l6 6V6.5l-4 4V7c0-.55-.45-1-1-1h-5.61l2 2H15z'></path></svg>,
micOff: <svg data-v-041ad48a='' version='1.1' viewBox='0 0 24 24' ><path pid='0' d='M0 0h24v24H0V0z' fill='none'></path><path pid='1' d='M10.8 4.9c0-.66.54-1.2 1.2-1.2s1.2.54 1.2 1.2l-.01 3.91L15 10.6V5c0-1.66-1.34-3-3-3-1.54 0-2.79 1.16-2.96 2.65l1.76 1.76V4.9zM19 11h-1.7c0 .58-.1 1.13-.27 1.64l1.27 1.27c.44-.88.7-1.87.7-2.91zM4.41 2.86L3 4.27l6 6V11c0 1.66 1.34 3 3 3 .23 0 .44-.03.65-.08l1.66 1.66c-.71.33-1.5.52-2.31.52-2.76 0-5.3-2.1-5.3-5.1H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28a7.13 7.13 0 002.55-.9l4.2 4.2 1.41-1.41L4.41 2.86z'></path></svg>,
videoOff: <svg data-v-041ad48a='' version='1.1' viewBox='0 0 24 24' ><path pid='0' d='M0 0h24v24H0V0z' fill='none'></path><path pid='1' d='M9.56 8l-2-2-4.15-4.14L2 3.27 4.73 6H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.21 0 .39-.08.55-.18L19.73 21l1.41-1.41-8.86-8.86L9.56 8zM5 16V8h1.73l8 8H5zm10-8v2.61l6 6V6.5l-4 4V7c0-.55-.45-1-1-1h-5.61l2 2H15z'></path></svg>,
}
const VideoRoom = ({access_token, options = "{}", children, context}) => {
const [varDisconnected, setvarDisconnected] = useVars({variable: "disconnected", context, storage: false, defaultValue: false});
const [varServerDisconnected, setVarServerDisconnected] = useVars({variable: "serverDisconnected", context, storage: false, defaultValue: false});
const [varRoom, setVarRoom] = useVars({variable: "room", context, storage: false, defaultValue: emptyObject});
const [room, setRoom] = useState(null);
const [isMicDisabled, setIsMicDisabled] = useState(false);
const [isVideoDisabled, setIsVideoDisabled] = useState(false);
const [participants, setParticipants] = useState([]);
const [status, setStatus] = useState("connecting");
const optionsObj = useMemo(() => processOptions(options), [options]);
const participantDisconnected = useCallback(
(participant) => {
setParticipants((prevParticipants) =>
prevParticipants.filter((p) => p !== participant)
);
},
[room]
);
useEffect(()=>{
setVarRoom({state: room?.state, sid: room?.sid});
}, [room?.state, room?.id]);
useEffect(() => {
const participantConnected = (participant) => {
setParticipants((prevParticipants) => {
if (!prevParticipants.some((part) => part.sid === participant.sid)) {
return [...prevParticipants, participant];
} else {
return [prevParticipants];
}
});
};
const disconnected = () => {
if(!!context){
setVarServerDisconnected(true);
}
}
Twilio.connect(access_token, {
video: true,
audio: true
}).then((room) => {
setRoom(room);
room.on("participantConnected", participantConnected);
room.on("participantDisconnected", participantDisconnected);
room.on("disconnected", disconnected);
room.participants.forEach(participantConnected);
setStatus("connected");
}).catch(reason => {
console.log(reason);
});
return () => {
setRoom((currentRoom) => {
if (currentRoom && currentRoom.localParticipant.state === "connected") {
currentRoom.localParticipant.tracks
.forEach(trackPublication => {
trackPublication.track.stop();
});
currentRoom.disconnect();
return null;
} else {
return currentRoom;
}
});
};
}, []); //TODO ADD HERE
const toggleMic = useCallback(() => {
if (isMicDisabled) {
room.localParticipant.audioTracks.forEach(({ track }) => {
track.enable();
});
} else {
room.localParticipant.audioTracks.forEach(({ track }) => {
track.disable();
});
}
setIsMicDisabled(!isMicDisabled);
}, [isMicDisabled, room]);
const toggleVideo = useCallback(() => {
if (isVideoDisabled) {
room.localParticipant.videoTracks.forEach(({ track }) => {
track.enable();
});
} else {
room.localParticipant.videoTracks.forEach(({ track }) => {
track.disable();
});
}
setIsVideoDisabled(!isVideoDisabled);
}, [isVideoDisabled, room]);
const handleDisconnect = useCallback(() => {
if(!!context){
setvarDisconnected(true);
}
room.disconnect();
}, [room]);
if (status === "connecting") return children;
return (
<div className={optionsObj?.classes?.root}>
{participants.map((participant) => (
<VideoRoomParticipant
participantClass={optionsObj?.classes?.participant}
participantIconsClass={optionsObj?.classes?.participantIcons}
videoDisabledClass={optionsObj?.classes?.videoOff}
audioDisabledClass={optionsObj?.classes?.micOff}
videoDisabledContent={contents.videoOff}
audioDisabledContent={contents.micOff}
videoClass={optionsObj?.classes?.video}
key={participant.identity}
participant={participant}
/>
))}
<VideoRoomParticipant
participantClass={optionsObj?.classes?.localParticipant}
videoClass={optionsObj?.classes?.localVideo}
participant={room.localParticipant}
isMicDisabled={isMicDisabled}
isVideoDisabled={isVideoDisabled}
local={true}
/>
<div className={optionsObj?.classes?.controls}>
<div className={isMicDisabled ? optionsObj?.classes?.toggleMicDisabled : optionsObj?.classes?.toggleMic} onClick={toggleMic}>{isMicDisabled ? contents.toggleMic : contents.toggleMicDisabled}</div>
<div className={optionsObj?.classes?.disconnect} onClick={handleDisconnect} >{contents.disconnect}</div>
<div className={isVideoDisabled ? optionsObj?.classes?.toggleVideoDisabled : optionsObj?.classes?.toggleVideo} onClick={toggleVideo} >{isVideoDisabled ? contents.toggleVideo : contents.toggleVideoDisabled}</div>
</div>
</div>
)
}
export default VideoRoom;