DocSpace-client/common/ASC.Socket.IO/app/hubs/chat.js
2020-08-02 23:12:45 +03:00

219 lines
8.6 KiB
JavaScript

module.exports = (io, countersHub) => {
const apiRequestManager = require('../apiRequestManager.js');
const co = require('co');
const baseTalkApiUrl = 'portal/talk/';
const chat = io.of("/chat");
const onlineUsers = [];
chat.on('connection', (socket) => {
const request = socket.client.request;
if(!request.user || !request.user.id) return;
const user = request.user;
const portal = request.portal;
const userId = user.id;
const userName = user.userName.toLowerCase();
const tenantId = portal.tenantId;
const tenantDomain = portal.tenantDomain;
socket
.on('disconnect', onDisconnectUser)
.on('connectUser', onConnectUser)
.on('disconnectUser', onDisconnectUser)
.on('send', onSend)
.on('getStates', onGetStates)
.on('getContactInfo', onGetContactInfo)
.on('getInitData', onGetInitData)
.on('sendTyping', onSendTyping)
.on('sendStateToTenant', onSendStateToTenant)
.on('getRecentMessages', onGetRecentMessages)
.on('chatPing', onPing);
function onDisconnectUser(change, fn) {
co(function *() {
let state;
if (!onlineUsers[tenantId]) return;
if (!onlineUsers[tenantId][userId] || !socket.onConnectUser) {
if(typeof fn == "function") fn();
return;
}
if (change === true || onlineUsers[tenantId][userId].counter === 1) {
delete onlineUsers[tenantId][userId];
state = yield apiRequestManager.dlt(`${baseTalkApiUrl}connection?connectionId=${userId}`, request);
socket.emit("disconnectUser");
} else {
onlineUsers[tenantId][userId].counter--;
state = yield apiRequestManager.get(`${baseTalkApiUrl}state`, request, { userName });
if (state !== 4) {
// setStatus
socket.broadcast.to(`${tenantId}-${userName}`).emit('setStatus', state);
}
}
socket.broadcast.to(tenantId).emit('setState', userName, state);
})
.catch((err)=>{
if(typeof fn == "function") fn(err);
});
}
function onConnectUser(state) {
socket.join([tenantId, `${tenantId}-${userName}`]);
socket.onConnectUser = true;
if (!onlineUsers[tenantId]) {
onlineUsers[tenantId] = {};
}
var counter = onlineUsers[tenantId][userId];
if (!counter) {
counter = onlineUsers[tenantId][userId] = { counter: 1 };
} else {
counter.counter++;
}
co(function* () {
if (counter.counter === 1) {
state = yield apiRequestManager.post(`${baseTalkApiUrl}connection`, request, { connectionId: userId, state });
} else {
state = yield apiRequestManager.post(`${baseTalkApiUrl}state`, request, { state });
if (state !== 4) {
socket.broadcast.to(`${tenantId}-${userName}`).emit('setStatus', state);
}
}
socket.broadcast.to(tenantId).emit('setState', userName, state, false);
chat.to(`${tenantId}-${userName}`).emit("connectUser");
})
.catch((err)=>{
chat.to(`${tenantId}-${userName}`).emit("connectUser", err);
});
}
function onSend(calleeUserName, messageText) {
co(function* () {
const message = { u: userName, t: messageText };
if (calleeUserName) {
chat.to(`${tenantId}-${calleeUserName}`).emit('send', message, calleeUserName);
socket.broadcast.to(`${tenantId}-${userName}`).emit('send', message, calleeUserName);
}
yield apiRequestManager.post(`${baseTalkApiUrl}message`, request, { to: calleeUserName, text: messageText });
});
}
function onGetStates(fn) {
apiRequestManager.get(`${baseTalkApiUrl}states`, request)
.then((result) => {
socket.emit('statesRetrieved', result);
})
.catch((err) => {
if (typeof fn === "function") fn(err);
});;
}
function onGetContactInfo(calleeUserName, fn) {
co(function* () {
const calleeUser = yield apiRequestManager.get('people/' + calleeUserName, request);
if (!calleeUser || calleeUser.id === "4A515A15-D4D6-4b8e-828E-E0586F18F3A3") throw "Can't get UserInfo";
const calleeUserState = yield apiRequestManager.get(`${baseTalkApiUrl}state`, request, { userName: calleeUserName });
if(typeof fn === "function") fn(calleeUserName, calleeUserState);
})
.catch((err) => {
if (err && typeof fn === "function") fn(null, null, err);
});
}
function onGetInitData(fn) {
co(function* () {
const states = yield apiRequestManager.get(`${baseTalkApiUrl}states`, request);
const users = yield apiRequestManager.get('people', request);
const result = users
.filter((item) => item.id !== userId)
.sort((item1, item2) => {
if (item1.displayName < item2.displayName) return -1;
if (item1.displayName > item2.displayName) return 1;
return 0;
})
.map((item) => {
const uName = item.userName.toLowerCase();
return { u: uName, d: item.displayName, s: states[uName] || 4}
});
socket.emit('initDataRetrieved', userName, user.displayName, result, tenantId, tenantDomain);
})
.catch((err) => {
if (typeof fn === "function") fn(err);
});
}
function onSendTyping(calleeUserName) {
chat.to(`${tenantId}-${calleeUserName}`).emit('sendTypingSignal', userName);
}
function onSendStateToTenant(state) {
apiRequestManager.post(`${baseTalkApiUrl}state`, request, { state })
.then((result) => {
socket.broadcast.to(tenantId).emit('setState', userName, result, false);
});
}
function onGetRecentMessages(calleeUserName, id, fn) {
apiRequestManager.get(`${baseTalkApiUrl}recentMessages`, request, { calleeUserName, id })
.then((recentMessages) => {
if (typeof fn === "function") fn(recentMessages);
})
.catch((err) => {
if (typeof fn === "function") fn(null, err);
});
}
function onPing(state) {
apiRequestManager.post(`${baseTalkApiUrl}ping`, request, { state: state });
}
});
function tenantPlusUserRoom(tenantId, userName) {
return chat.to(`${tenantId}-${userName}`);
}
function send({ tenantId, callerUserName, calleeUserName, message, isTenantUser } = {}) {
if (typeof tenantId === "undefined" || !calleeUserName || !message) {
return;
}
tenantPlusUserRoom(tenantId, calleeUserName).emit('send', message, calleeUserName, isTenantUser);
if (!isTenantUser) {
tenantPlusUserRoom(tenantId, callerUserName).emit('send', message, calleeUserName, isTenantUser);
}
}
function sendInvite({ tenantId, calleeUserName, message } = {}) {
if (typeof tenantId === "undefined" || !calleeUserName || !message) {
return;
}
tenantPlusUserRoom(tenantId, calleeUserName).emit('sendInvite', message);
}
function setState({ tenantId, from, state } = {}) {
if (typeof tenantId === "undefined" || !from) {
return;
}
chat.to(`${tenantId}`).emit('setState', from, state);
}
function sendOfflineMessages({ tenantId, callerUserName, users } = {}) {
if (typeof tenantId === "undefined" || !callerUserName || !users) {
return;
}
tenantPlusUserRoom(tenantId, callerUserName).emit('sendOfflineMessages', users);
}
return { send, sendInvite, setState, sendOfflineMessages };
}