mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-01 19:46:01 +01:00
closes #5078
This commit is contained in:
@@ -101,7 +101,9 @@ define('forum/chats', [
|
|||||||
if (err) {
|
if (err) {
|
||||||
return app.alertError(err.message);
|
return app.alertError(err.message);
|
||||||
}
|
}
|
||||||
|
if (!data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
messages.parseMessage(data, function(html) {
|
messages.parseMessage(data, function(html) {
|
||||||
var currentScrollTop = el.scrollTop();
|
var currentScrollTop = el.scrollTop();
|
||||||
var previousHeight = el[0].scrollHeight;
|
var previousHeight = el[0].scrollHeight;
|
||||||
@@ -309,7 +311,9 @@ define('forum/chats', [
|
|||||||
if (err) {
|
if (err) {
|
||||||
return app.alertError(err.message);
|
return app.alertError(err.message);
|
||||||
}
|
}
|
||||||
|
if (!messageData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
chatContentEl.find('[component="chat/message"]').remove();
|
chatContentEl.find('[component="chat/message"]').remove();
|
||||||
|
|
||||||
messages.appendChatMessage(chatContentEl, messageData);
|
messages.appendChatMessage(chatContentEl, messageData);
|
||||||
|
|||||||
@@ -30,10 +30,13 @@ chatsController.get = function(req, res, callback) {
|
|||||||
if (!uid) {
|
if (!uid) {
|
||||||
return callback();
|
return callback();
|
||||||
}
|
}
|
||||||
messaging.getRecentChats(uid, 0, 19, next);
|
messaging.getRecentChats(req.uid, uid, 0, 19, next);
|
||||||
},
|
},
|
||||||
function(_recentChats, next) {
|
function(_recentChats, next) {
|
||||||
recentChats = _recentChats;
|
recentChats = _recentChats;
|
||||||
|
if (!recentChats) {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
if (!req.params.roomid) {
|
if (!req.params.roomid) {
|
||||||
return res.render('chats', {
|
return res.render('chats', {
|
||||||
rooms: recentChats.rooms,
|
rooms: recentChats.rooms,
|
||||||
@@ -48,12 +51,13 @@ chatsController.get = function(req, res, callback) {
|
|||||||
messaging.isUserInRoom(req.uid, req.params.roomid, next);
|
messaging.isUserInRoom(req.uid, req.params.roomid, next);
|
||||||
},
|
},
|
||||||
function(inRoom, next) {
|
function(inRoom, next) {
|
||||||
if (!inRoom && parseInt(req.uid, 10) === parseInt(uid, 10)) {
|
if (!inRoom) {
|
||||||
return callback();
|
return callback();
|
||||||
}
|
}
|
||||||
async.parallel({
|
async.parallel({
|
||||||
users: async.apply(messaging.getUsersInRoom, req.params.roomid, 0, -1),
|
users: async.apply(messaging.getUsersInRoom, req.params.roomid, 0, -1),
|
||||||
messages: async.apply(messaging.getMessages, {
|
messages: async.apply(messaging.getMessages, {
|
||||||
|
callerUid: req.uid,
|
||||||
uid: uid,
|
uid: uid,
|
||||||
roomId: req.params.roomid,
|
roomId: req.params.roomid,
|
||||||
since: 'recent',
|
since: 'recent',
|
||||||
|
|||||||
108
src/messaging.js
108
src/messaging.js
@@ -1,18 +1,17 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
|
||||||
var async = require('async'),
|
var async = require('async');
|
||||||
winston = require('winston'),
|
var winston = require('winston');
|
||||||
S = require('string'),
|
var S = require('string');
|
||||||
|
|
||||||
|
var db = require('./database');
|
||||||
db = require('./database'),
|
var user = require('./user');
|
||||||
user = require('./user'),
|
var plugins = require('./plugins');
|
||||||
plugins = require('./plugins'),
|
var meta = require('./meta');
|
||||||
meta = require('./meta'),
|
var utils = require('../public/src/utils');
|
||||||
utils = require('../public/src/utils'),
|
var notifications = require('./notifications');
|
||||||
notifications = require('./notifications'),
|
var userNotifications = require('./user/notifications');
|
||||||
userNotifications = require('./user/notifications');
|
|
||||||
|
|
||||||
(function(Messaging) {
|
(function(Messaging) {
|
||||||
|
|
||||||
@@ -63,34 +62,37 @@ var async = require('async'),
|
|||||||
count = 50;
|
count = 50;
|
||||||
min = 0;
|
min = 0;
|
||||||
}
|
}
|
||||||
|
var indices = {};
|
||||||
db.getSortedSetRevRangeByScore('uid:' + uid + ':chat:room:' + roomId + ':mids', start, count, '+inf', min, function(err, mids) {
|
async.waterfall([
|
||||||
if (err) {
|
function(next) {
|
||||||
return callback(err);
|
canGetMessages(params.callerUid, params.uid, next);
|
||||||
|
},
|
||||||
|
function(canGet, next) {
|
||||||
|
if (!canGet) {
|
||||||
|
return callback(null, null);
|
||||||
}
|
}
|
||||||
|
db.getSortedSetRevRangeByScore('uid:' + uid + ':chat:room:' + roomId + ':mids', start, count, '+inf', min, next);
|
||||||
|
},
|
||||||
|
function(mids, next) {
|
||||||
if (!Array.isArray(mids) || !mids.length) {
|
if (!Array.isArray(mids) || !mids.length) {
|
||||||
return callback(null, []);
|
return callback(null, []);
|
||||||
}
|
}
|
||||||
var indices = {};
|
|
||||||
mids.forEach(function(mid, index) {
|
mids.forEach(function(mid, index) {
|
||||||
indices[mid] = start + index;
|
indices[mid] = start + index;
|
||||||
});
|
});
|
||||||
|
|
||||||
mids.reverse();
|
mids.reverse();
|
||||||
|
|
||||||
Messaging.getMessagesData(mids, uid, roomId, isNew, function(err, messageData) {
|
Messaging.getMessagesData(mids, uid, roomId, isNew, next);
|
||||||
if (err) {
|
},
|
||||||
return callback(err);
|
function(messageData, next) {
|
||||||
}
|
messageData.forEach(function(messageData) {
|
||||||
|
messageData.index = indices[messageData.messageId.toString()];
|
||||||
for(var i=0; i<messageData.length; i++) {
|
|
||||||
messageData[i].index = indices[messageData[i].messageId.toString()];
|
|
||||||
}
|
|
||||||
|
|
||||||
callback(null, messageData);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
next(null, messageData);
|
||||||
|
}
|
||||||
|
], callback);
|
||||||
|
|
||||||
if (markRead) {
|
if (markRead) {
|
||||||
notifications.markRead('chat_' + roomId + '_' + uid, uid, function(err) {
|
notifications.markRead('chat_' + roomId + '_' + uid, uid, function(err) {
|
||||||
@@ -103,6 +105,16 @@ var async = require('async'),
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function canGetMessages(callerUid, uid, callback) {
|
||||||
|
plugins.fireHook('filter:messaging.canGetMessages', {
|
||||||
|
callerUid: callerUid,
|
||||||
|
uid: uid,
|
||||||
|
canGet: parseInt(callerUid, 10) === parseInt(uid, 10)
|
||||||
|
}, function(err, data) {
|
||||||
|
callback(err, data ? data.canGet : false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Messaging.getMessagesData = function(mids, uid, roomId, isNew, callback) {
|
Messaging.getMessagesData = function(mids, uid, roomId, isNew, callback) {
|
||||||
|
|
||||||
var keys = mids.map(function(mid) {
|
var keys = mids.map(function(mid) {
|
||||||
@@ -250,12 +262,18 @@ var async = require('async'),
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Messaging.getRecentChats = function(uid, start, stop, callback) {
|
Messaging.getRecentChats = function(callerUid, uid, start, stop, callback) {
|
||||||
db.getSortedSetRevRange('uid:' + uid + ':chat:rooms', start, stop, function(err, roomIds) {
|
async.waterfall([
|
||||||
if (err) {
|
function(next) {
|
||||||
return callback(err);
|
canGetRecentChats(callerUid, uid, next);
|
||||||
|
},
|
||||||
|
function(canGet, next) {
|
||||||
|
if (!canGet) {
|
||||||
|
return callback(null, null);
|
||||||
}
|
}
|
||||||
|
db.getSortedSetRevRange('uid:' + uid + ':chat:rooms', start, stop, next);
|
||||||
|
},
|
||||||
|
function(roomIds, next) {
|
||||||
async.parallel({
|
async.parallel({
|
||||||
roomData: function(next) {
|
roomData: function(next) {
|
||||||
Messaging.getRoomsData(roomIds, next);
|
Messaging.getRoomsData(roomIds, next);
|
||||||
@@ -281,11 +299,9 @@ var async = require('async'),
|
|||||||
Messaging.getTeaser(uid, roomId, next);
|
Messaging.getTeaser(uid, roomId, next);
|
||||||
}, next);
|
}, next);
|
||||||
}
|
}
|
||||||
}, function(err, results) {
|
}, next);
|
||||||
if (err) {
|
},
|
||||||
return callback(err);
|
function(results, next) {
|
||||||
}
|
|
||||||
|
|
||||||
results.roomData.forEach(function(room, index) {
|
results.roomData.forEach(function(room, index) {
|
||||||
room.users = results.users[index];
|
room.users = results.users[index];
|
||||||
room.groupChat = room.hasOwnProperty('groupChat') ? room.groupChat : room.users.length > 2;
|
room.groupChat = room.hasOwnProperty('groupChat') ? room.groupChat : room.users.length > 2;
|
||||||
@@ -307,11 +323,21 @@ var async = require('async'),
|
|||||||
}).join(', ');
|
}).join(', ');
|
||||||
});
|
});
|
||||||
|
|
||||||
callback(null, {rooms: results.roomData, nextStart: stop + 1});
|
next(null, {rooms: results.roomData, nextStart: stop + 1});
|
||||||
});
|
}
|
||||||
});
|
], callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function canGetRecentChats(callerUid, uid, callback) {
|
||||||
|
plugins.fireHook('filter:messaging.canGetRecentChats', {
|
||||||
|
callerUid: callerUid,
|
||||||
|
uid: uid,
|
||||||
|
canGet: parseInt(callerUid, 10) === parseInt(uid, 10)
|
||||||
|
}, function(err, data) {
|
||||||
|
callback(err, data ? data.canGet : false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Messaging.getTeaser = function (uid, roomId, callback) {
|
Messaging.getTeaser = function (uid, roomId, callback) {
|
||||||
var teaser;
|
var teaser;
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ var validator = require('validator');
|
|||||||
|
|
||||||
var db = require('../database');
|
var db = require('../database');
|
||||||
var user = require('../user');
|
var user = require('../user');
|
||||||
|
var plugins = require('../plugins');
|
||||||
|
|
||||||
module.exports = function(Messaging) {
|
module.exports = function(Messaging) {
|
||||||
|
|
||||||
@@ -74,7 +75,17 @@ module.exports = function(Messaging) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Messaging.isUserInRoom = function(uid, roomId, callback) {
|
Messaging.isUserInRoom = function(uid, roomId, callback) {
|
||||||
db.isSortedSetMember('chat:room:' + roomId + ':uids', uid, callback);
|
async.waterfall([
|
||||||
|
function(next) {
|
||||||
|
db.isSortedSetMember('chat:room:' + roomId + ':uids', uid, next);
|
||||||
|
},
|
||||||
|
function(inRoom, next) {
|
||||||
|
plugins.fireHook('filter:messaging.isUserInRoom', {uid: uid, roomId: roomId, inRoom: inRoom}, next);
|
||||||
|
},
|
||||||
|
function(data, next) {
|
||||||
|
next(null, data.inRoom);
|
||||||
|
}
|
||||||
|
], callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
Messaging.roomExists = function(roomId, callback) {
|
Messaging.roomExists = function(roomId, callback) {
|
||||||
|
|||||||
@@ -31,6 +31,6 @@ module.exports = function (app, middleware, controllers) {
|
|||||||
app.delete('/api/user/:userslug/session/:uuid', [middleware.requireUser], controllers.accounts.session.revoke);
|
app.delete('/api/user/:userslug/session/:uuid', [middleware.requireUser], controllers.accounts.session.revoke);
|
||||||
|
|
||||||
setupPageRoute(app, '/notifications', middleware, [middleware.authenticate], controllers.accounts.notifications.get);
|
setupPageRoute(app, '/notifications', middleware, [middleware.authenticate], controllers.accounts.notifications.get);
|
||||||
setupPageRoute(app, '/user/:userslug/chats/:roomid?', middleware, accountMiddlewares, controllers.accounts.chats.get);
|
setupPageRoute(app, '/user/:userslug/chats/:roomid?', middleware, middlewares, controllers.accounts.chats.get);
|
||||||
setupPageRoute(app, '/chats/:roomid?', middleware, [], controllers.accounts.chats.redirectToChat);
|
setupPageRoute(app, '/chats/:roomid?', middleware, [], controllers.accounts.chats.redirectToChat);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ SocketModules.chats.newRoom = function(socket, data, callback) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
SocketModules.chats.send = function(socket, data, callback) {
|
SocketModules.chats.send = function(socket, data, callback) {
|
||||||
if (!data || !data.roomId) {
|
if (!data || !data.roomId || !socket.uid) {
|
||||||
return callback(new Error('[[error:invalid-data]]'));
|
return callback(new Error('[[error:invalid-data]]'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,13 +106,10 @@ SocketModules.chats.loadRoom = function(socket, data, callback) {
|
|||||||
|
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function (next) {
|
function (next) {
|
||||||
async.parallel({
|
Messaging.isUserInRoom(socket.uid, data.roomId, next);
|
||||||
inRoom: async.apply(Messaging.isUserInRoom, socket.uid, data.roomId),
|
|
||||||
isAdminOrGlobalMod: async.apply(user.isAdminOrGlobalMod, socket.uid)
|
|
||||||
}, next);
|
|
||||||
},
|
},
|
||||||
function (results, next) {
|
function (inRoom, next) {
|
||||||
if (!results.isAdminOrGlobalMod && !results.inRoom) {
|
if (!inRoom) {
|
||||||
return next(new Error('[[error:not-allowed]]'));
|
return next(new Error('[[error:not-allowed]]'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,6 +219,9 @@ SocketModules.chats.canMessage = function(socket, roomId, callback) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
SocketModules.chats.markRead = function(socket, roomId, callback) {
|
SocketModules.chats.markRead = function(socket, roomId, callback) {
|
||||||
|
if (!socket.uid) {
|
||||||
|
return callback(new Error('[[error:invalid-data]]'));
|
||||||
|
}
|
||||||
async.parallel({
|
async.parallel({
|
||||||
usersInRoom: async.apply(Messaging.getUidsInRoom, roomId, 0, -1),
|
usersInRoom: async.apply(Messaging.getUidsInRoom, roomId, 0, -1),
|
||||||
markRead: async.apply(Messaging.markRead, socket.uid, roomId)
|
markRead: async.apply(Messaging.markRead, socket.uid, roomId)
|
||||||
@@ -283,21 +283,12 @@ SocketModules.chats.renameRoom = function(socket, data, callback) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
SocketModules.chats.getRecentChats = function(socket, data, callback) {
|
SocketModules.chats.getRecentChats = function(socket, data, callback) {
|
||||||
if (!data || !utils.isNumber(data.after)) {
|
if (!data || !utils.isNumber(data.after) || !utils.isNumber(data.uid)) {
|
||||||
return callback(new Error('[[error:invalid-data]]'));
|
return callback(new Error('[[error:invalid-data]]'));
|
||||||
}
|
}
|
||||||
var start = parseInt(data.after, 10);
|
var start = parseInt(data.after, 10);
|
||||||
var stop = start + 9;
|
var stop = start + 9;
|
||||||
if (socket.uid === parseInt(data.uid, 10)) {
|
Messaging.getRecentChats(socket.uid, data.uid, start, stop, callback);
|
||||||
return Messaging.getRecentChats(socket.uid, start, stop, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
user.isAdminOrGlobalMod(socket.uid, function(err, isAdminOrGlobalMod) {
|
|
||||||
if (err || !isAdminOrGlobalMod) {
|
|
||||||
return callback(err || new Error('[[error:no-privileges]]'));
|
|
||||||
}
|
|
||||||
Messaging.getRecentChats(data.uid, start, stop, callback);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
SocketModules.chats.hasPrivateChat = function(socket, uid, callback) {
|
SocketModules.chats.hasPrivateChat = function(socket, uid, callback) {
|
||||||
@@ -313,6 +304,7 @@ SocketModules.chats.getMessages = function(socket, data, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var params = {
|
var params = {
|
||||||
|
callerUid: socket.uid,
|
||||||
uid: data.uid,
|
uid: data.uid,
|
||||||
roomId: data.roomId,
|
roomId: data.roomId,
|
||||||
start: parseInt(data.start, 10) || 0,
|
start: parseInt(data.start, 10) || 0,
|
||||||
@@ -328,15 +320,7 @@ SocketModules.chats.getMessages = function(socket, data, callback) {
|
|||||||
params.markRead = data.markRead;
|
params.markRead = data.markRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (socket.uid === parseInt(data.uid, 10)) {
|
|
||||||
return Messaging.getMessages(params, callback);
|
|
||||||
}
|
|
||||||
user.isAdminOrGlobalMod(socket.uid, function(err, isAdminOrGlobalMod) {
|
|
||||||
if (err || !isAdminOrGlobalMod) {
|
|
||||||
return callback(err || new Error('[[error:no-privileges]]'));
|
|
||||||
}
|
|
||||||
Messaging.getMessages(params, callback);
|
Messaging.getMessages(params, callback);
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Sounds */
|
/* Sounds */
|
||||||
|
|||||||
Reference in New Issue
Block a user