mirror of https://github.com/status-im/codimd.git
refactor(realtime): extract user event "cursor" related
1. move "cursor focus", "cursor activity", "cursor blur" event handler to SocketClient 2. add test case for that Signed-off-by: BoHong Li <a60814billy@gmail.com>
This commit is contained in:
parent
8171860d47
commit
3259bd0f11
|
@ -763,10 +763,53 @@ class SocketClient {
|
|||
this.socket.on('refresh', this.refreshEventHandler.bind(this))
|
||||
// received user status
|
||||
this.socket.on('user status', this.userStatusEventHandler.bind(this))
|
||||
|
||||
// when a new client disconnect
|
||||
this.socket.on('disconnect', this.disconnectEventHandler.bind(this))
|
||||
// received cursor focus
|
||||
this.socket.on('cursor focus', this.cursorFocusEventHandler.bind(this))
|
||||
// received cursor activity
|
||||
this.socket.on('cursor activity', this.cursorActivityEventHandler.bind(this))
|
||||
// received cursor blur
|
||||
this.socket.on('cursor blur', this.cursorBlurEventHandlder.bind(this))
|
||||
}
|
||||
|
||||
isNoteAndUserExists () {
|
||||
const note = getNoteFromNotePool(this.socket.noteId)
|
||||
const user = getUserFromUserPool(this.socket.id)
|
||||
return note && user
|
||||
}
|
||||
|
||||
getCurrentUser () {
|
||||
return getUserFromUserPool(this.socket.id)
|
||||
}
|
||||
|
||||
getNoteChannel () {
|
||||
return this.socket.broadcast.to(this.socket.noteId)
|
||||
}
|
||||
|
||||
cursorFocusEventHandler (data) {
|
||||
if (!this.isNoteAndUserExists()) return
|
||||
const user = this.getCurrentUser()
|
||||
user.cursor = data
|
||||
const out = buildUserOutData(user)
|
||||
this.getNoteChannel().emit('cursor focus', out)
|
||||
}
|
||||
|
||||
cursorActivityEventHandler (data) {
|
||||
if (!this.isNoteAndUserExists()) return
|
||||
const user = this.getCurrentUser()
|
||||
user.cursor = data
|
||||
const out = buildUserOutData(user)
|
||||
this.getNoteChannel().emit('cursor activity', out)
|
||||
}
|
||||
|
||||
cursorBlurEventHandlder () {
|
||||
if (!this.isNoteAndUserExists()) return
|
||||
const user = this.getCurrentUser()
|
||||
user.cursor = null
|
||||
this.getNoteChannel().emit('cursor blur', {
|
||||
id: this.socket.id
|
||||
})
|
||||
}
|
||||
|
||||
refreshEventHandler () {
|
||||
|
@ -774,11 +817,11 @@ class SocketClient {
|
|||
}
|
||||
|
||||
userStatusEventHandler (data) {
|
||||
const noteId = this.socket.noteId
|
||||
const user = getUserFromUserPool(this.socket.id)
|
||||
if (!noteId || !getNoteFromNotePool(noteId) || !user) return
|
||||
|
||||
if (config.debug) { logger.info('SERVER received [' + noteId + '] user status from [' + this.socket.id + ']: ' + JSON.stringify(data)) }
|
||||
if (!this.isNoteAndUserExists()) return
|
||||
const user = this.getCurrentUser()
|
||||
if (config.debug) {
|
||||
logger.info('SERVER received [' + this.socket.noteId + '] user status from [' + this.socket.id + ']: ' + JSON.stringify(data))
|
||||
}
|
||||
if (data) {
|
||||
user.idle = data.idle
|
||||
user.type = data.type
|
||||
|
@ -946,7 +989,9 @@ function connection (socket) {
|
|||
var users = []
|
||||
Object.keys(notes[noteId].users).forEach(function (key) {
|
||||
var user = notes[noteId].users[key]
|
||||
if (user) { users.push(buildUserOutData(user)) }
|
||||
if (user) {
|
||||
users.push(buildUserOutData(user))
|
||||
}
|
||||
})
|
||||
var out = {
|
||||
users: users
|
||||
|
@ -961,38 +1006,6 @@ function connection (socket) {
|
|||
minimumCompatibleVersion: config.minimumCompatibleVersion
|
||||
})
|
||||
})
|
||||
|
||||
// received cursor focus
|
||||
socket.on('cursor focus', function (data) {
|
||||
var noteId = socket.noteId
|
||||
var user = users[socket.id]
|
||||
if (!noteId || !notes[noteId] || !user) return
|
||||
user.cursor = data
|
||||
var out = buildUserOutData(user)
|
||||
socket.broadcast.to(noteId).emit('cursor focus', out)
|
||||
})
|
||||
|
||||
// received cursor activity
|
||||
socket.on('cursor activity', function (data) {
|
||||
var noteId = socket.noteId
|
||||
var user = users[socket.id]
|
||||
if (!noteId || !notes[noteId] || !user) return
|
||||
user.cursor = data
|
||||
var out = buildUserOutData(user)
|
||||
socket.broadcast.to(noteId).emit('cursor activity', out)
|
||||
})
|
||||
|
||||
// received cursor blur
|
||||
socket.on('cursor blur', function () {
|
||||
var noteId = socket.noteId
|
||||
var user = users[socket.id]
|
||||
if (!noteId || !notes[noteId] || !user) return
|
||||
user.cursor = null
|
||||
var out = {
|
||||
id: socket.id
|
||||
}
|
||||
socket.broadcast.to(noteId).emit('cursor blur', out)
|
||||
})
|
||||
}
|
||||
|
||||
exports = module.exports = realtime
|
||||
|
|
|
@ -7,13 +7,26 @@ const assert = require('assert')
|
|||
const sinon = require('sinon')
|
||||
|
||||
function makeMockSocket (headers, query) {
|
||||
const broadCastChannelCache = {}
|
||||
return {
|
||||
id: Math.round(Math.random() * 10000),
|
||||
handshake: {
|
||||
headers: Object.assign({}, headers),
|
||||
query: Object.assign({}, query)
|
||||
},
|
||||
on: sinon.fake()
|
||||
on: sinon.fake(),
|
||||
broadCastChannelCache: {},
|
||||
broadcast: {
|
||||
to: (channel) => {
|
||||
if (!broadCastChannelCache[channel]) {
|
||||
broadCastChannelCache[channel] = {
|
||||
channel: channel,
|
||||
emit: sinon.fake()
|
||||
}
|
||||
}
|
||||
return broadCastChannelCache[channel]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -553,9 +566,48 @@ describe('realtime', function () {
|
|||
disconnectFunc()
|
||||
assert(disconnectStub.called === false)
|
||||
})
|
||||
})
|
||||
|
||||
;['cursor focus', 'cursor activity', 'cursor blur'].forEach( (event) => {
|
||||
describe(event, function () {
|
||||
let cursorFocusFunc
|
||||
|
||||
const cursorData = {
|
||||
cursor: 10
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
cursorFocusFunc = eventFuncMap.get(event)
|
||||
realtime.notes[noteId] = {}
|
||||
})
|
||||
|
||||
it('should broadcast to all client', () => {
|
||||
cursorFocusFunc(cursorData)
|
||||
const broadChannelEmitFake = clientSocket.broadcast.to(noteId).emit
|
||||
assert(broadChannelEmitFake.calledOnce)
|
||||
assert(broadChannelEmitFake.lastCall.args[0] === event)
|
||||
if (event === 'cursor blur') {
|
||||
assert(broadChannelEmitFake.lastCall.args[1].id === clientSocket.id)
|
||||
} else {
|
||||
assert.deepStrictEqual(broadChannelEmitFake.lastCall.args[1].cursor, cursorData)
|
||||
}
|
||||
})
|
||||
|
||||
it('should not broadcast when note not exists', () => {
|
||||
delete realtime.notes[noteId]
|
||||
cursorFocusFunc(cursorData)
|
||||
const broadChannelEmitFake = clientSocket.broadcast.to(noteId).emit
|
||||
assert(broadChannelEmitFake.called === false)
|
||||
})
|
||||
|
||||
it('should not broadcast when user not exists', () => {
|
||||
delete realtime.users[clientSocket.id]
|
||||
cursorFocusFunc(cursorData)
|
||||
const broadChannelEmitFake = clientSocket.broadcast.to(noteId).emit
|
||||
assert(broadChannelEmitFake.called === false)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue