first commit
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
node_modules/
|
||||||
|
movies/
|
||||||
15
README.md
Normal file
15
README.md
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# SyncApp
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Tiny app based on WebSockets, and implemented using Express.js, Node.js in pair with ws.
|
||||||
|
|
||||||
|
## To-Do List
|
||||||
|
|
||||||
|
The following tasks are on our to-do list:
|
||||||
|
|
||||||
|
1. Automatize syncing between clients
|
||||||
|
2. Free the clients map on client exit (causes memory leaks)
|
||||||
|
3. Implement hosts and automatize hosting
|
||||||
|
4. Workaround for autoplay
|
||||||
|
5. Implement room authorization for added security
|
||||||
237
index.js
Normal file
237
index.js
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const expressWs = require('express-ws');
|
||||||
|
const bodyParser = require('body-parser');
|
||||||
|
const dotenv = require('dotenv').config();
|
||||||
|
const { v4: uuidv4 } = require('uuid');
|
||||||
|
|
||||||
|
// Express Initialization + WS piggyback
|
||||||
|
const app = express();
|
||||||
|
expressWs(app);
|
||||||
|
|
||||||
|
// Middlewares
|
||||||
|
app.use(express.static('public'));
|
||||||
|
app.use(bodyParser.urlencoded({ extended: false }));
|
||||||
|
app.use(bodyParser.json());
|
||||||
|
app.set('view engine', 'ejs');
|
||||||
|
app.set('views', __dirname + '/views');
|
||||||
|
|
||||||
|
// Server startup
|
||||||
|
const server = app.listen(process.env.SERVER_PORT, () => {
|
||||||
|
console.log(`Server on port ${process.env.SERVER_PORT}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Client mapping
|
||||||
|
const clients = new Map();
|
||||||
|
const rooms = new Map();
|
||||||
|
const room_hosts = new Map();
|
||||||
|
const room_links = new Map();
|
||||||
|
|
||||||
|
// Websocket handlers
|
||||||
|
app.ws('/ws', (ws, req) => {
|
||||||
|
// Generates an unique ID
|
||||||
|
const id = uuidv4();
|
||||||
|
const clientData = { id: id, name: 'Guest', client: ws };
|
||||||
|
clients.set(id, clientData);
|
||||||
|
let clientRoom;
|
||||||
|
|
||||||
|
// Sets the ID for a new connection
|
||||||
|
const response = { command: 'set_id', id: id };
|
||||||
|
const responseJson = JSON.stringify(response);
|
||||||
|
ws.send(responseJson);
|
||||||
|
|
||||||
|
ws.on('message', (message) => {
|
||||||
|
const msg = JSON.parse(message);
|
||||||
|
|
||||||
|
// Null command handler
|
||||||
|
if (msg.command == null) {
|
||||||
|
const response = { error: 'Bad command.' };
|
||||||
|
const responseJson = JSON.stringify(response);
|
||||||
|
ws.send(responseJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg.command == 'sync') {
|
||||||
|
syncClients(msg.room_id, msg.time);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets the client into a room
|
||||||
|
if (msg.command == 'set_room') {
|
||||||
|
clientRoom = msg.room_id;
|
||||||
|
if (rooms.get(msg.room_id) != null) {
|
||||||
|
rooms.get(msg.room_id).push(clients.get(msg.id));
|
||||||
|
} else {
|
||||||
|
rooms.set(msg.room_id, [clients.get(msg.id)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (room_hosts.get(msg.room_id) == null) {
|
||||||
|
room_hosts.set(msg.room_id, id);
|
||||||
|
}
|
||||||
|
refreshAllClients(rooms, clientRoom);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg.command == 'set_link') {
|
||||||
|
room_links[clientRoom] = msg.link;
|
||||||
|
console.log(room_links);
|
||||||
|
console.log(room_links[clientRoom]);
|
||||||
|
refreshAllClients(rooms, clientRoom);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg.command == 'pause') {
|
||||||
|
console.log('PAUSED');
|
||||||
|
broadcastCommand(msg.room_id, 'pause');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg.command == 'play') {
|
||||||
|
console.log('PLAYED');
|
||||||
|
broadcastCommand(msg.room_id, 'play');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Websocket command to switch hosts
|
||||||
|
if (msg.command == 'make_host') {
|
||||||
|
if (room_hosts.get(msg.room_id) != msg.id) {
|
||||||
|
room_hosts.set(msg.room_id, msg.id);
|
||||||
|
refreshAllClients(rooms, clientRoom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg.command == 'sync_with_host') {
|
||||||
|
if (clients.get(room_hosts.get(msg.room_id)) != null) {
|
||||||
|
const response = { command: 'sync_with_me' };
|
||||||
|
const responseJson = JSON.stringify(response);
|
||||||
|
clients.get(room_hosts.get(msg.room_id)).client.send(responseJson);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Websocket command to change a name
|
||||||
|
if (msg.command == 'change_name') {
|
||||||
|
clients.get(id).name = msg.name;
|
||||||
|
refreshAllClients(rooms, clientRoom);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Websocket command to send a global message
|
||||||
|
if (msg.command == 'global') {
|
||||||
|
broadcastRoom(msg.room_id, msg.message, msg.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Websocket command to send a text to a specific client
|
||||||
|
if (msg.command == 'text_id') {
|
||||||
|
const id = msg.id;
|
||||||
|
const response = {
|
||||||
|
command: 'message',
|
||||||
|
message: msg.name + ': ' + msg.message,
|
||||||
|
};
|
||||||
|
const responseJson = JSON.stringify(response);
|
||||||
|
clients.get(id).client.send(responseJson);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// On close, deletes the client data and randomizes a new host, if it exists
|
||||||
|
ws.on('close', (data) => {
|
||||||
|
console.log('CLIENT LEFT');
|
||||||
|
clients.delete(id);
|
||||||
|
if (rooms.has(clientRoom)) {
|
||||||
|
const clients = rooms.get(clientRoom);
|
||||||
|
const updatedClients = clients.filter((client) => client.id !== id);
|
||||||
|
if (updatedClients.length == 0) {
|
||||||
|
rooms.delete(clientRoom);
|
||||||
|
randomizeHost(clientRoom);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rooms.set(clientRoom, updatedClients);
|
||||||
|
}
|
||||||
|
|
||||||
|
randomizeHost(clientRoom);
|
||||||
|
refreshAllClients(rooms, clientRoom);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Chooses a random host on call
|
||||||
|
function randomizeHost(room_id) {
|
||||||
|
if (rooms.has(room_id)) {
|
||||||
|
const newHost =
|
||||||
|
rooms.get(room_id)[Math.floor(Math.random() * rooms.get(room_id).length)];
|
||||||
|
room_hosts.set(room_id, newHost.id);
|
||||||
|
} else {
|
||||||
|
room_hosts.delete(room_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function refreshAllClients(rooms, room_id) {
|
||||||
|
const response = { command: 'refresh' };
|
||||||
|
const responseJson = JSON.stringify(response);
|
||||||
|
for (const client of rooms.get(room_id)) {
|
||||||
|
client.client.send(responseJson);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncClients(room_id, time) {
|
||||||
|
const response = { command: 'sync', time: time };
|
||||||
|
const responseJson = JSON.stringify(response);
|
||||||
|
for (const client of rooms.get(room_id)) {
|
||||||
|
client.client.send(responseJson);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function broadcastCommand(room_id, command) {
|
||||||
|
const response = { command: command };
|
||||||
|
const responseJson = JSON.stringify(response);
|
||||||
|
for (const client of rooms.get(room_id)) {
|
||||||
|
client.client.send(responseJson);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function broadcastLink(room_id, link) {
|
||||||
|
const response = { command: 'set_link', link: link };
|
||||||
|
const responseJson = JSON.stringify(response);
|
||||||
|
for (const client of rooms.get(room_id)) {
|
||||||
|
client.client.send(responseJson);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function broadcastRoom(room_id, message, name) {
|
||||||
|
const response = { command: 'global', message: name + ': ' + message };
|
||||||
|
const responseJson = JSON.stringify(response);
|
||||||
|
for (const client of rooms.get(room_id)) {
|
||||||
|
client.client.send(responseJson);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collects information about all clients
|
||||||
|
function getClientsJson(room_id) {
|
||||||
|
const clts = [];
|
||||||
|
for (const client of rooms.get(room_id)) {
|
||||||
|
const js = { id: client.id, name: client.name };
|
||||||
|
clts.push(js);
|
||||||
|
}
|
||||||
|
return JSON.stringify(clts);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collects and sends back updated data
|
||||||
|
app.post('/api/getRefreshData', (req, res) => {
|
||||||
|
const data = req.body;
|
||||||
|
const client = clients.get(data.id);
|
||||||
|
const isHost = client.id == room_hosts.get(data.room_id) ? true : false;
|
||||||
|
const toSend = {
|
||||||
|
host: isHost,
|
||||||
|
name: client.name,
|
||||||
|
client_data: getClientsJson(data.room_id),
|
||||||
|
link: room_links[data.room_id],
|
||||||
|
};
|
||||||
|
console.log(toSend);
|
||||||
|
res.json(toSend).status(200);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/', (req, res) => {
|
||||||
|
res.sendFile(__dirname + '/public/join.html');
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/img', (req, res) => {
|
||||||
|
res.sendFile(__dirname + '/public/img.png');
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/api/file/:filename', (req, res) => {
|
||||||
|
res.sendFile(__dirname + '/movies/' + req.params.filename);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/a', (req, res) => {
|
||||||
|
res.sendFile(__dirname + '/public/clt.html');
|
||||||
|
});
|
||||||
1268
package-lock.json
generated
Normal file
1268
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
23
package.json
Normal file
23
package.json
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"name": "nodejs-login-system",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "nodemon index.js"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"body-parser": "^1.20.2",
|
||||||
|
"dotenv": "^16.3.1",
|
||||||
|
"ejs": "^3.1.9",
|
||||||
|
"express": "^4.18.2",
|
||||||
|
"express-ws": "^5.0.2",
|
||||||
|
"jsonwebtoken": "^9.0.0",
|
||||||
|
"nodemon": "^2.0.22",
|
||||||
|
"uuid": "^9.0.0",
|
||||||
|
"ws": "^8.13.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
166
public/client.html
Normal file
166
public/client.html
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Room ID Form</title>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css"
|
||||||
|
integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
/>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#form-container {
|
||||||
|
text-align: center;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="form-container">
|
||||||
|
<form id="roomForm">
|
||||||
|
<h2>Room ID Form</h2>
|
||||||
|
<label for="roomId">Room ID:</label>
|
||||||
|
<input type="text" id="roomId" required />
|
||||||
|
<br /><br />
|
||||||
|
<button type="submit" id="submitBtn">Submit</button>
|
||||||
|
</form>
|
||||||
|
<div id="mainPage" style="display: none">
|
||||||
|
<div class="container text-center">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<img height="80" src="http://localhost:3000/img" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<video
|
||||||
|
id="video_field"
|
||||||
|
height="300"
|
||||||
|
src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
|
||||||
|
controls
|
||||||
|
></video>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<h4>Host? <span id="host_field"></span></h4>
|
||||||
|
<h4 id="room_field">Room ID:</h4>
|
||||||
|
<h4 id="name_field">Your name:</h4>
|
||||||
|
<h4>Other connected clients:</h4>
|
||||||
|
<p id="clients_field"></p>
|
||||||
|
</div>
|
||||||
|
<div class="col-5">
|
||||||
|
<p
|
||||||
|
id="global_field"
|
||||||
|
style="height: 200px; overflow-x: hidden; overflow-y: scroll"
|
||||||
|
></p>
|
||||||
|
<div style="display: flex; justify-content: center">
|
||||||
|
<input
|
||||||
|
style="width: 200px; margin-right: 10px"
|
||||||
|
type="text"
|
||||||
|
id="global_input"
|
||||||
|
class="form-control"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
onclick="ClientInstance.sendGlobal()"
|
||||||
|
class="btn btn-primary small-button"
|
||||||
|
>
|
||||||
|
Send Global
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<button
|
||||||
|
onclick="ClientInstance.makeHost()"
|
||||||
|
class="btn btn-primary small-button"
|
||||||
|
>
|
||||||
|
Make Host
|
||||||
|
</button>
|
||||||
|
<div
|
||||||
|
style="display: flex; justify-content: center; padding: 10px"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
placeholder="Change name:"
|
||||||
|
style="width: 200px; margin-right: 10px"
|
||||||
|
type="text"
|
||||||
|
id="name_input"
|
||||||
|
class="form-control"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
onclick="ClientInstance.changeName()"
|
||||||
|
class="btn btn-primary small-button"
|
||||||
|
>
|
||||||
|
Change Name
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div style="display: flex; justify-content: center">
|
||||||
|
<input
|
||||||
|
placeholder="Put link:"
|
||||||
|
style="width: 200px; margin-right: 10px"
|
||||||
|
type="text"
|
||||||
|
id="link_input"
|
||||||
|
class="form-control"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
style="margin-right: 10px"
|
||||||
|
onclick="ClientInstance.setLink()"
|
||||||
|
class="btn btn-primary small-button"
|
||||||
|
>
|
||||||
|
Set Link
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onclick="ClientInstance.syncVideo()"
|
||||||
|
class="btn btn-primary small-button"
|
||||||
|
>
|
||||||
|
Sync
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script
|
||||||
|
src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.min.js"
|
||||||
|
integrity="sha384-cuYeSxntonz0PPNlHhBs68uyIAVpIIOZZ5JqeqvYYIcEL727kskC66kF92t6Xl2V"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"
|
||||||
|
integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
></script>
|
||||||
|
<script src="https://unpkg.com/axios@1.1.2/dist/axios.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="/client.js"></script>
|
||||||
|
<script>
|
||||||
|
let ClientInstance;
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
const roomForm = document.getElementById('roomForm');
|
||||||
|
const mainPage = document.getElementById('mainPage');
|
||||||
|
let hasSubmitted = false;
|
||||||
|
roomForm.addEventListener('submit', function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
const ID = document.getElementById('roomId').value;
|
||||||
|
mainPage.style.display = 'block';
|
||||||
|
roomForm.style.display = 'none';
|
||||||
|
hasSubmitted = true;
|
||||||
|
ClientInstance = new Client(ID);
|
||||||
|
ClientInstance.connect();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
200
public/client.js
Normal file
200
public/client.js
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
class Client {
|
||||||
|
#ClientSocket;
|
||||||
|
#ClientData;
|
||||||
|
|
||||||
|
constructor(room_id) {
|
||||||
|
this.#ClientData = { name: 'Guest', id: 0, room: room_id };
|
||||||
|
this.#ClientSocket = new WebSocket('ws://93.116.13.156:3000/ws');
|
||||||
|
|
||||||
|
this.host_field = document.getElementById('host_field');
|
||||||
|
this.name_field = document.getElementById('name_field');
|
||||||
|
this.clients_field = document.getElementById('clients_field');
|
||||||
|
this.name_input = document.getElementById('name_input');
|
||||||
|
this.global_field = document.getElementById('global_field');
|
||||||
|
this.global_input = document.getElementById('global_input');
|
||||||
|
this.room_field = document.getElementById('room_field');
|
||||||
|
this.room_field.textContent += room_id;
|
||||||
|
this.video_field = document.getElementById('video_field');
|
||||||
|
this.link_input = document.getElementById('link_input');
|
||||||
|
}
|
||||||
|
|
||||||
|
connect() {
|
||||||
|
let isManuallySeeked = true;
|
||||||
|
let isManuallyPlayed = true;
|
||||||
|
let isManuallyPaused = true;
|
||||||
|
|
||||||
|
this.video_field.addEventListener('play', () => {
|
||||||
|
if (isManuallyPlayed) {
|
||||||
|
const js = {
|
||||||
|
command: 'play',
|
||||||
|
room_id: this.#ClientData.room,
|
||||||
|
};
|
||||||
|
this.sendCommand(js);
|
||||||
|
} else isManuallyPlayed = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
video_field.addEventListener('pause', () => {
|
||||||
|
if (isManuallyPaused) {
|
||||||
|
const js = {
|
||||||
|
command: 'pause',
|
||||||
|
room_id: this.#ClientData.room,
|
||||||
|
};
|
||||||
|
this.sendCommand(js);
|
||||||
|
} else isManuallyPaused = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
video_field.addEventListener('seeked', () => {
|
||||||
|
if (isManuallySeeked) this.syncForVid();
|
||||||
|
else isManuallySeeked = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.#ClientSocket.addEventListener('open', () => {
|
||||||
|
console.log('Connected');
|
||||||
|
});
|
||||||
|
|
||||||
|
this.#ClientSocket.addEventListener('message', (event) => {
|
||||||
|
try {
|
||||||
|
const msg = JSON.parse(event.data);
|
||||||
|
|
||||||
|
if (msg.command == 'set_id') {
|
||||||
|
this.#ClientData.id = msg.id;
|
||||||
|
this.refreshData();
|
||||||
|
const json = {
|
||||||
|
command: 'set_room',
|
||||||
|
room_id: this.#ClientData.room,
|
||||||
|
id: this.#ClientData.id,
|
||||||
|
};
|
||||||
|
this.sendCommand(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg.command == 'set_link') {
|
||||||
|
this.video_field.src = msg.link;
|
||||||
|
this.video_field.play();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg.command == 'sync') {
|
||||||
|
this.isManuallySeeked = false;
|
||||||
|
this.video_field.currentTime = msg.time;
|
||||||
|
// refresh_data(CLIENT.id, CLIENT.room);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg.command == 'refresh') {
|
||||||
|
this.refreshData();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg.command == 'play') {
|
||||||
|
this.isManuallyPlayed = false;
|
||||||
|
this.video_field.play();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg.command == 'pause') {
|
||||||
|
this.isManuallyPaused = false;
|
||||||
|
this.video_field.pause();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg.command == 'message') {
|
||||||
|
this.message_field.innerHTML += msg.message + '<br>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg.command == 'global') {
|
||||||
|
this.global_field.innerHTML += msg.message + '<br>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg.command == 'sync_with_me') {
|
||||||
|
this.syncVideo();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error parsing JSON:', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getSocket() {
|
||||||
|
return this.#ClientSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
getClientData() {
|
||||||
|
return this.#ClientData;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendCommand(json) {
|
||||||
|
this.#ClientSocket.send(JSON.stringify(json));
|
||||||
|
}
|
||||||
|
|
||||||
|
syncForVid() {
|
||||||
|
const js = {
|
||||||
|
command: 'sync_with_host',
|
||||||
|
room_id: this.#ClientData.room,
|
||||||
|
id: this.#ClientData.id,
|
||||||
|
};
|
||||||
|
this.sendCommand(js);
|
||||||
|
}
|
||||||
|
|
||||||
|
changeName() {
|
||||||
|
const js = {
|
||||||
|
command: 'change_name',
|
||||||
|
id: this.#ClientData.id,
|
||||||
|
room_id: this.#ClientData.room,
|
||||||
|
name: name_input.value,
|
||||||
|
};
|
||||||
|
this.sendCommand(js);
|
||||||
|
}
|
||||||
|
|
||||||
|
sendGlobal() {
|
||||||
|
const js = {
|
||||||
|
command: 'global',
|
||||||
|
message: global_input.value,
|
||||||
|
room_id: this.#ClientData.room,
|
||||||
|
name: this.#ClientData.name,
|
||||||
|
};
|
||||||
|
this.sendCommand(js);
|
||||||
|
}
|
||||||
|
|
||||||
|
makeHost() {
|
||||||
|
const js = {
|
||||||
|
command: 'make_host',
|
||||||
|
id: this.#ClientData.id,
|
||||||
|
room_id: this.#ClientData.room,
|
||||||
|
};
|
||||||
|
this.sendCommand(js);
|
||||||
|
}
|
||||||
|
|
||||||
|
setLink() {
|
||||||
|
const js = {
|
||||||
|
command: 'set_link',
|
||||||
|
link: link_input.value,
|
||||||
|
room_id: this.#ClientData.room,
|
||||||
|
};
|
||||||
|
this.sendCommand(js);
|
||||||
|
}
|
||||||
|
|
||||||
|
syncVideo() {
|
||||||
|
const js = {
|
||||||
|
command: 'sync',
|
||||||
|
time: video_field.currentTime,
|
||||||
|
room_id: this.#ClientData.room,
|
||||||
|
};
|
||||||
|
this.sendCommand(js);
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshData() {
|
||||||
|
axios
|
||||||
|
.post('/api/getRefreshData', {
|
||||||
|
id: this.#ClientData.id,
|
||||||
|
room_id: this.#ClientData.room,
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
const data = response.data;
|
||||||
|
this.host_field.textContent = data.host;
|
||||||
|
this.#ClientData.name = data.name;
|
||||||
|
this.name_field.textContent = `Your name: ${data.name}`;
|
||||||
|
this.clients_field.innerHTML = '';
|
||||||
|
let clients = JSON.parse(data.client_data);
|
||||||
|
for (const client of clients)
|
||||||
|
this.clients_field.innerHTML += `<h5>${client.name}</h5>`;
|
||||||
|
if (data.link != undefined) this.video_field.src = data.link;
|
||||||
|
this.video_field.play();
|
||||||
|
this.syncForVid();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
public/img.png
Normal file
BIN
public/img.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 68 KiB |
Reference in New Issue
Block a user