polyglot/app/javascript/packs/webrtc.js

238 lines
5.4 KiB
JavaScript

// Broadcast Types
const JOIN_ROOM = "JOIN_ROOM";
const EXCHANGE = "EXCHANGE";
const REMOVE_USER = "REMOVE_USER";
// DOM Elements
let currentUser;
let localVideo;
let remoteVideoContainer;
// Objects
let pcPeers = {}; // peer connection
let localstream;
window.onload = () => {
currentUser = document.getElementById("current-user").innerHTML;
localVideo = document.getElementById("local-video");
remoteVideoContainer = document.getElementById("remote-video-container");
};
// Ice Credentials
const ice = { iceServers: [{urls: ['stun:stun.l.google.com:19302', 'stun:stun.1.google.com:19302']}]};
// Initialize user's own video
document.onreadystatechange = async () => {
if (document.readyState === "interactive") {
try {
const stream = await navigator.mediaDevices.getUserMedia({
audio: true,
video: true
})
localstream = stream;
localVideo.srcObject = stream
localVideo.muted = true
} catch (e) { console.error(e); }
}
};
const chatroomId = document.getElementById('chatroom-hook').dataset["chatroomId"]
const handleJoinSession = async () => {
App['chatroom' + chatroomId] = await App.cable.subscriptions.create({
channel: "ChatRoomsChannel",
room: chatroomId
}, {
connected: () => {
broadcastData({
type: JOIN_ROOM,
from: currentUser,
room: chatroomId
});
},
received: data => {
if (data.from === currentUser) return;
switch (data.type) {
case JOIN_ROOM:
return joinRoom(data);
case EXCHANGE:
if (data.to !== currentUser) return;
return exchange(data);
case REMOVE_USER:
return removeUser(data);
default:
return;
}
}
});
};
const handleLeaveSession = () => {
for (user in pcPeers) {
pcPeers[user].close();
}
pcPeers = {};
App.session.unsubscribe();
// remoteVideoContainer.innerHTML = "";
broadcastData({
type: REMOVE_USER,
from: currentUser
});
};
const joinRoom = data => {
createPC(data.from, true);
};
const removeUser = data => {
remoteVideo = document.querySelector("#remote-video-container>video");
if (video.srcObject) video.srcObject = null;
delete pcPeers[data.from];
};
const broadcastData = data => {
fetch("chat_room_sessions", {
method: "POST",
body: JSON.stringify(data),
headers: { "content-type": "application/json", "X-CSRF-Token": document.querySelector('meta[name=csrf-token]').content }
});
};
const createPC = (userId, isOffer) => {
let pc = new RTCPeerConnection(ice);
let test = userId
pcPeers[userId] = pc;
pc.addStream(localstream);
if (isOffer) {
pc
.createOffer()
.then(offer => {
pc.setLocalDescription(offer);
broadcastData({
type: EXCHANGE,
from: currentUser,
to: userId,
sdp: JSON.stringify(pc.localDescription),
room: chatroomId
});
})
.catch(logError);
}
pc.onicecandidate = event => {
if (event.candidate) {
broadcastData({
type: EXCHANGE,
from: currentUser,
to: userId,
candidate: JSON.stringify(event.candidate),
room: chatroomId
});
}
};
pc.onaddstream = event => {
const remoteVideo = document.querySelector("#remote-video-container>video");
remoteVideo.srcObject = event.stream;
remoteVideo.height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
localVideo.classList.add("video-sm");
};
pc.oniceconnectionstatechange = event => {
if (pc.iceConnectionState == "disconnected") {
console.log("Disconnected:", userId);
broadcastData({
type: REMOVE_USER,
from: userId
});
}
};
return pc;
};
const exchange = data => {
let pc;
if (!pcPeers[data.from]) {
pc = createPC(data.from, false);
} else {
pc = pcPeers[data.from];
}
if (data.candidate) {
pc
.addIceCandidate(new RTCIceCandidate(JSON.parse(data.candidate)))
.then(() => console.log("Ice candidate added"))
.catch(logError);
}
if (data.sdp) {
const sdp = JSON.parse(data.sdp);
pc
.setRemoteDescription(new RTCSessionDescription(sdp))
.then(() => {
if (sdp.type === "offer") {
pc.createAnswer().then(answer => {
pc.setLocalDescription(answer);
broadcastData({
type: EXCHANGE,
from: currentUser,
to: data.from,
sdp: JSON.stringify(pc.localDescription),
room: chatroomId
});
});
}
})
.catch(logError);
}
};
const logError = error => {
console.error("Whoops! Error:", error);
// console.info("Reloading Page...")
// window.reload();
}
const joinButton = document.getElementById("join-btn")
joinButton.addEventListener('click', event => {
handleJoinSession()
})
// WARNING: COMPLETELY HACKISH SOLUTION --> MUST INTRODUCE SOME SORT OF DELAY!
setTimeout(function() {
joinButton.click()
}, 5000);
(function addReloadToWindowObject() {
window.__proto__.reload = () => { window.location = window.location }
})();
// // have enter with JS
// const form = document.getElementById("chat-form")
// document.getElementById("chat-input").addEventListener("keyup", event => {
// if(event == "Enter"){
// form.submit();
// }
// });
document.getElementById("chat-form").addEventListener("click", function(event){
event.preventDefault()
});