[call-me] - #2 add direct join with query params

This commit is contained in:
Miroslav Pejic
2024-09-21 20:57:47 +02:00
parent 84f850ae00
commit bba98d4658
4 changed files with 107 additions and 18 deletions
+12
View File
@@ -43,6 +43,18 @@ npm start
---
## One-Click Call Between Two Users
Allows a user to `join` the room as a `user1`
[http://localhost:8000/join?user=user1](http://localhost:8000/join?user=user1)
Lets the `user2 join` the room and initiate a `call` to the `user1`
[http://localhost:8000/join?user=user2&call=user1](http://localhost:8000/join?user=user2&call=user1)
---
## API
Get all connected users
+44 -11
View File
@@ -15,6 +15,9 @@ const packageJson = require('../package.json');
// Public directory location
const PUBLIC_DIR = path.join(__dirname, '../', 'public');
// Home page/client
const HOME = path.join(PUBLIC_DIR, '/index.html');
// Map to store connected users
const users = new Map();
@@ -101,7 +104,7 @@ app.use(config.apiBasePath + '/docs', swaggerUi.serve, swaggerUi.setup(config.sw
// Logs requests
app.use((req, res, next) => {
console.log('New request', {
headers: req.headers,
//headers: req.headers,
body: req.body,
method: req.method,
path: req.originalUrl,
@@ -111,7 +114,27 @@ app.use((req, res, next) => {
// Set up route to serve the main HTML file
app.get('/', (req, res) => {
res.sendFile(path.join(PUBLIC_DIR, '/index.html'));
res.sendFile(HOME);
});
// Direct Join room
app.get('/join/', (req, res) => {
if (Object.keys(req.query).length > 0) {
console.log('Request query', req.query);
// http://localhost:8000/join?user=user1
// http://localhost:8000/join?user=user2&call=user1
const { user, call } = req.query;
if (user || (user && call)) {
return res.sendFile(HOME);
}
return notFound(res);
}
return notFound(res);
});
// Page not found
app.get('*', (req, res) => {
return notFound(res);
});
// Axios API requests
@@ -131,6 +154,11 @@ app.get(`${config.apiBasePath}/users`, (req, res) => {
return res.json({ users });
});
// Page not found
function notFound(res) {
res.json({ data: '404 not found' });
}
// Function to handle individual WebSocket connections
function handleConnection(socket) {
console.log('User connected:', socket.id);
@@ -227,12 +255,21 @@ function handleConnection(socket) {
// Function to handle signaling messages (offer, answer, candidate, leave)
function handleSignalingMessage(data) {
const { name } = data;
const { type, name } = data;
const recipientSocket = users.get(name);
if (recipientSocket) {
sendMsgTo(recipientSocket, { ...data, name: socket.username });
} else {
sendError(socket, `User ${name} not found`);
switch (type) {
case 'leave':
if (recipientSocket !== undefined) {
console.log('Leave room', socket.username);
sendMsgTo(recipientSocket, { type: 'leave' });
}
break;
default:
if (recipientSocket !== undefined) {
sendMsgTo(recipientSocket, { ...data, name: socket.username });
}
break;
}
}
@@ -241,10 +278,6 @@ function handleConnection(socket) {
if (socket.username) {
console.log('User disconnected:', socket.username);
users.delete(socket.username);
const recipientSocket = users.get(socket.recipient);
if (recipientSocket) {
sendMsgTo(recipientSocket, { type: 'leave' });
}
console.log('Connected Users', getConnectedUsers());
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "call-me",
"version": "1.0.10",
"version": "1.0.12",
"description": "Your Go-To for Instant Video Calls",
"author": "Miroslav Pejic - miroslav.pejic.85@gmail.com",
"license": "AGPLv3",
+50 -6
View File
@@ -33,16 +33,47 @@ let stream;
// Hide room page initially
roomPage.style.display = 'none';
// On html page loaded...
document.addEventListener('DOMContentLoaded', function () {
// Initialize tooltips
handleToolTip();
handleLocalStorage();
handleDirectJoin();
});
// Initialize tooltips
function handleToolTip() {
const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-toggle="tooltip"]'));
const tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
return new bootstrap.Tooltip(tooltipTriggerEl);
});
// Handle localStorage data
}
// Handle localStorage data
function handleLocalStorage() {
usernameIn.value = localStorage.callMeUsername ? localStorage.callMeUsername : '';
callUsernameIn.value = localStorage.callMeUsernameToCall ? localStorage.callMeUsernameToCall : '';
});
}
// Handle Room direct join
function handleDirectJoin() {
const usp = new URLSearchParams(window.location.search);
const user = usp.get('user');
const call = usp.get('call');
console.log('Direct Join detected', { user, call });
if (user) {
// SignIn
usernameIn.value = user;
handleSignInClick();
if (call) {
// Call user if call is provided
callUsernameIn.value = call;
handleCallClick();
}
}
}
// WebSocket event listeners
socket.on('connect', handleSocketConnect);
@@ -147,7 +178,7 @@ function toggleLocalVideo() {
// Handle hang-up button click
function handleHangUpClick() {
sendMsg({ type: 'leave' });
sendMsg({ type: 'leave', name: socket.recipient });
handleLeave();
}
@@ -178,6 +209,7 @@ function handleSignIn(data) {
const { success } = data;
if (!success) {
handleError('Username already in use. Try a different username.');
setTimeout(handleHangUpClick, 2000);
} else {
githubDiv.style.display = 'none';
signInPage.style.display = 'none';
@@ -277,6 +309,7 @@ function offerAccept(data) {
callUsernameIn.style.display = 'none';
callBtn.style.display = 'none';
data.type = 'offerCreate';
socket.recipient = data.from;
} else {
data.type = 'offerDecline';
}
@@ -336,12 +369,23 @@ async function sound(name) {
// Handle leaving the room
function handleLeave() {
connectedUser = null;
remoteVideo.srcObject = null;
// Stop local video tracks
if (localVideo.srcObject != null) {
localVideo.srcObject.getTracks().forEach((track) => track.stop());
localVideo.srcObject = null;
}
// Stop remote video tracks
if (remoteVideo.srcObject != null) {
remoteVideo.srcObject.getTracks().forEach((track) => track.stop());
remoteVideo.srcObject = null;
}
// Disconnect from server
if (thisConnection) {
thisConnection.close();
thisConnection = null;
}
// GoTo homepage
connectedUser = null;
window.location.href = '/';
}