-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
185 lines (155 loc) · 5.72 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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
const express = require('express')
const app = express()
const server = require('http').createServer(app)
const io = require('socket.io')(server)
const rooms = {}
let id = 0
const mockUsers = require('./mockUsers.json').map((user) => {
user.id = (id++).toString()
user.mocked = true
return user
})
// DEBUGGING: Testing with mock users
app.set('mockData', false)
app.set('port', process.env.PORT || 3000)
app.set('view engine', 'hbs')
app.use(express.static('public'))
io.on('connection', (socket) => {
socket.on('join', ({ room, user, mocked }) => {
socket.user = user
socket.mocked = mocked || app.get('mockData')
// Create or get room in our map
if (!rooms.hasOwnProperty(room)) {
rooms[room] = socket.room = {
name: room,
users: socket.mocked ? [user].concat(mockUsers) : [],
mocked: socket.mocked
}
console.log('CREATE ROOM:', socket.room.name, socket.mocked ? 'MOCKED' : '')
}
else {
socket.room = rooms[room]
}
socket.join(room)
if (!mocked) {
socket.room.users.push(user)
}
console.log('JOIN ROOM:', socket.room.name, socket.user)
socket.emit('joined', socket.room)
io.in(socket.room.name).emit('updates.users', socket.room)
})
socket.on('changeOwner', ({ ownerId, authId }) => {
// Ensure the real owner is making the request
if (socket.id === authId && socket.room.users[0].id === authId) {
// Loop through users to get index of user
let index = -1
let newOwner = socket.room.users.find((user, i) => {
if (user.id === ownerId) {
index = i
return true
}
})
// Splice out new owner
socket.room.users.splice(index, 1)
// Bump them to the front as owner
socket.room.users.unshift(newOwner)
io.in(socket.room.name).emit('updates.users', socket.room)
console.log('CHANGE OWNER:', socket.room.name, socket.user)
}
})
// Send a request to get live updates from userId
socket.on('updates.editor.request', ({ userId }) => {
// If I am the owner
if (socket.id !== socket.room.users[0].id) {
console.log('ERR:', 'Non-owner requested editor value')
return
}
let currentEditorId = rooms[socket.room.name].editorId
if (currentEditorId) {
// console.log('EDITOR REVOKE:', currentEditorId)
socket.to(currentEditorId).emit('updates.editor.terminate')
rooms[socket.room.name].editorId = null
}
// console.log('EDITOR UPDATE:', userId)
rooms[socket.room.name].editorId = userId
// If the user is a mocked user, we'll skip this
if (!Number.isNaN(+userId)) {
console.log(socket.room)
const userData = socket.room.users.filter(user => user.id === socket.room.editorId)[0]
console.log(userData)
socket.emit('updates.editor', { value: userData.value })
console.log('NOTICE:', 'User was mocked so no request sent')
return
}
socket.to(userId).emit('updates.editor.request')
})
// Terminate whoever was sharing coding
socket.on('updates.editor.terminate', () => {
let currentEditorId = rooms[socket.room.name].editorId
if (currentEditorId) {
// console.log('EDITOR REVOKE:', currentEditorId)
socket.to(currentEditorId).emit('updates.editor.terminate')
rooms[socket.room.name].editorId = null
}
})
socket.on('updates.editor.random', () => {
// Only allow if owner
if (socket.id === socket.room.users[0].id) {
// Don't include our code
let random = Math.floor(Math.random() * socket.room.users.slice(1).length) + 1
let randomUser = socket.room.users[random]
// Mock data support
if (!Number.isNaN(+randomUser.id)) {
socket.emit('updates.editor', { value: randomUser.value })
console.log('RANDOM [MOCKED] ANSWER:', randomUser)
}
else {
socket.emit('updates.editor.randomAnswer', randomUser.id)
console.log('RANDOM ANSWER:', randomUser.name, randomUser.id)
}
}
else {
console.log('updates.editor.random ERR:', 'You are not an owner')
}
})
// Request to listen to user editor changes fullfilled
socket.on('updates.editor.requestFulfilled', ({ id, value }) => {
// Set the userId to our room
rooms[socket.room.name].editorId = id
//console.log('EMIT UPDATE:', value, 'updates.editor.requestFulfilled')
socket.to(socket.room.users[0].id).emit('updates.editor', { value })
})
socket.on('updates.editor', ({ value }) => {
//console.log('EMIT UPDATE:', value, 'updates.editor')
socket.to(socket.room.users[0].id).emit('updates.editor', { value })
})
socket.on('updates.editor.type', (type) => {
//console.log('EMIT UPDATE:', value, 'updates.editor')
io.in(socket.room.name).emit('updates.editor.type', type)
})
socket.on('disconnect', () => {
// If a user connected AND joined the room
if (socket.room) {
const index = socket.room.users.indexOf(socket.user)
socket.room.users.splice(index, 1)
// Send user updates to everyone in room
io.in(socket.room.name).emit('updates.users', socket.room)
console.log('DISCONNECTED:', socket.room.name, socket.user)
// Delete room if no users left
if (!socket.room.users.length || socket.mocked) {
delete rooms[socket.room.name]
console.log('DELETE ROOM:', socket.room.name, Object.keys(rooms))
}
}
})
})
app.get('/', (req, res) => {
res.render('index')
})
app.get('/rooms/:name', (req, res) => {
let room = req.params.name
// If we want mocked data and no room exists, create it
let mocked = !!req.query.mockData && !rooms.hasOwnProperty(room)
res.render('room', { room, mocked })
})
server.listen(app.get('port'), () => console.log('Running at http://localhost:' + app.get('port')))