-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
154 lines (125 loc) · 3.42 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import express from "express";
import { Server } from "socket.io";
const PORT = process.env.PORT || 8000;
const ADMIN = "Admin";
const app = express();
const expressServer = app.listen(PORT, () => {
console.log(`listening on port ${PORT}`);
});
// state
const UsersState = {
users: [],
setUsers: function (newUsersArray) {
this.users = newUsersArray;
},
};
const io = new Server(expressServer, {
cors: {
origin:
process.env.NODE_ENV === "production"
? ["https://chat-608.pages.dev"]
: ["http://localhost:5500", "http://127.0.0.1:5500"],
},
});
io.on("connection", (socket) => {
console.log(`User ${socket.id} connected`);
// Upon connection - only to user
socket.emit("message", buildMsg(ADMIN, "Welcome to Chat App!"));
socket.on("enterRoom", ({ name, room }) => {
// leave previous room
const prevRoom = getUser(socket.id)?.room;
if (prevRoom) {
socket.leave(prevRoom);
io.to(prevRoom).emit(
"message",
buildMsg(ADMIN, `${name} has left the room`)
);
}
const user = activateUser(socket.id, name, room);
// Cannot update previous room users list until after the state update in activate user
if (prevRoom) {
io.to(prevRoom).emit("userList", {
users: getUsersInRoom(prevRoom),
});
}
// join room
socket.join(user.room);
// To user who joined
socket.emit(
"message",
buildMsg(ADMIN, `You have joined the ${user.room} chat room`)
);
// To everyone else
socket.broadcast
.to(user.room)
.emit("message", buildMsg(ADMIN, `${user.name} has joined the room`));
// Update user list for room
io.to(user.room).emit("userList", {
users: getUsersInRoom(user.room),
});
// Update rooms list for everyone
io.emit("roomList", {
rooms: getAllActiveRooms(),
});
});
// When user disconnects - to all others
socket.on("disconnect", () => {
const user = getUser(socket.id);
userLeavesApp(socket.id);
if (user) {
io.to(user.room).emit(
"message",
buildMsg(ADMIN, `${user.name} has left the room`)
);
io.to(user.room).emit("userList", {
users: getUsersInRoom(user.room),
});
io.emit("roomList", {
rooms: getAllActiveRooms(),
});
}
console.log(`User ${socket.id} disconnected`);
});
// Listening for a message event
socket.on("message", ({ name, text }) => {
const room = getUser(socket.id)?.room;
if (room) {
io.to(room).emit("message", buildMsg(name, text));
}
});
// Listen for activity
socket.on("activity", (name) => {
const room = getUser(socket.id)?.room;
if (room) {
socket.broadcast.to(room).emit("activity", name);
}
});
});
function buildMsg(name, text) {
return {
name,
text,
time: new Date(),
};
}
// User functions
function activateUser(id, name, room) {
const user = { id, name, room };
UsersState.setUsers([
...UsersState.users.filter((user) => user.id !== id),
user,
]);
return user;
}
function userLeavesApp(id) {
UsersState.setUsers(UsersState.users.filter((user) => user.id !== id));
}
function getUser(id) {
return UsersState.users.find((user) => user.id === id);
}
function getUsersInRoom(room) {
return UsersState.users.filter((user) => user.room === room);
}
function getAllActiveRooms() {
return Array.from(new Set(UsersState.users.map((user) => user.room)));
}