[call-me] - #2 add direct join with query params
This commit is contained in:
@@ -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
@@ -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
@@ -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
@@ -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 = '/';
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user