Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions src/client/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chat App</title>
</head>
<body>
<h1>Chat App</h1>
<input id="username" placeholder="Enter username" />
<input id="room" placeholder="Enter room name" />
<button onclick="joinRoom()">Join Room</button>

<div id="chat" style="display:none;">
<h2 id="roomTitle"></h2>
<div id="messages" style="height: 300px; overflow-y: scroll; border: 1px solid #ccc;"></div>
<input id="messageInput" placeholder="Type a message..." />
<button onclick="sendMessage()">Send</button>
</div>

<script src="script.js"></script>
</body>
</html>
58 changes: 58 additions & 0 deletions src/client/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/* eslint-env browser */
const ws = new WebSocket('ws://localhost:5000');

let username = '';
let room = '';

ws.onmessage = (e) => {
const data = JSON.parse(e.data);

if (data.type === 'history') {
document.getElementById('messages').innerHTML = data.messages
.map(
(msg) =>
`<p><strong>${msg.author}</strong>: ${msg.text} (${msg.time})</p>`,
)
.join('');
} else if (data.type === 'message') {
document.getElementById('messages').innerHTML +=
`<p><strong>${data.message.author}</strong>: ${data.message.text} (${data.message.time})</p>`;
} else if (data.type === 'deleted') {
alert('Room deleted!');
location.reload();
}
};

function joinRoom() {
username = document.getElementById('username').value;
room = document.getElementById('room').value;

if (!username || !room) {
return alert('Enter username and room name');
}

ws.send(JSON.stringify({ type: 'join', username, room }));
document.getElementById('chat').style.display = 'block';
document.getElementById('roomTitle').innerText = `Room: ${room}`;
}

function sendMessage() {
const message = document.getElementById('messageInput').value;

if (!message) {
return;
}

ws.send(
JSON.stringify({
type: 'message',
username,
room,
text: message,
}),
);
document.getElementById('messageInput').value = '';
}

window.joinRoom = joinRoom;
window.sendMessage = sendMessage;
1 change: 0 additions & 1 deletion src/index.js

This file was deleted.

77 changes: 77 additions & 0 deletions src/server/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/* eslint-disable no-console */
'use strict';
import express from 'express';
import { WebSocketServer } from 'ws';
import cors from 'cors';
import dotenv from 'dotenv';
import {
createRoom,
renameRoom,
deleteRoom,
addMessage,
getMessages,
} from './rooms.js';

dotenv.config();

const app = express();
const PORT = process.env.PORT || 5000;

app.use(cors());
app.use(express.json());

const server = app.listen(PORT);
// , () =>
// console.log(`Server running on http://localhost:${PORT}`),);

const wss = new WebSocketServer({ server });

wss.on('connection', (ws) => {
console.log(`New connection`);

ws.on('message', (data) => {
const { type, username, room, text, newRoom } = JSON.parse(data);

if (type === 'join') {
ws.room = room;
createRoom(room);
ws.send(JSON.stringify({ type: 'history', messages: getMessages(room) }));
}

if (type === 'message' && ws.room) {
const message = {
author: username,
time: new Date().toLocaleTimeString(),
text,
};

addMessage(ws.room, message);

wss.clients.forEach((client) => {
if (client.readyState === 1 && client.room === ws.room) {
client.send(JSON.stringify({ type: 'message', message }));
}
});
}

if (type === 'create') {
createRoom(room);
}

if (type === 'rename') {
renameRoom(room, newRoom);
}

if (type === 'delete') {
deleteRoom(room);

wss.clients.forEach((client) => {
if (client.room === room) {
client.send(JSON.stringify({ type: 'deleted' }));
}
});
}
});

ws.on('close', () => console.log(`User disconnected`));
});
30 changes: 30 additions & 0 deletions src/server/rooms.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const rooms = {}; // { roomName: [{ author, time, text }] }

const createRoom = (room) => {
if (!rooms[room]) {
rooms[room] = [];
}
};

const renameRoom = (oldRoom, newRoom) => {
if (rooms[oldRoom]) {
rooms[newRoom] = [...rooms[oldRoom]];
delete rooms[oldRoom];
}
};

const deleteRoom = (room) => {
delete rooms[room];
};

const addMessage = (room, message) => {
if (rooms[room]) {
rooms[room].push(message);
}
};

const getMessages = (room) => {
return rooms[room] || [];
};

export { createRoom, renameRoom, deleteRoom, addMessage, getMessages };