-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
154 lines (122 loc) · 4.07 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"
import path from 'path'
import { fileURLToPath } from 'url'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const PORT = process.env.PORT || 3500
const ADMIN = "Admin"
const app = express()
app.use(express.static(path.join(__dirname, "public")))
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" ? false : ["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 Alumni Connect!"))
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 Intl.DateTimeFormat('default', {
hour: 'numeric',
minute: 'numeric',
second: 'numeric'
}).format(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)))
}