mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-07-05 21:48:11 +02:00
ability to add/remove users from chat rooms, tagsinput
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
"use strict";
|
||||
/*global io, templates, ajaxify, utils, bootbox, overrides, socket, config, Visibility*/
|
||||
/*global templates, translator, ajaxify, utils, bootbox, overrides, socket, config, Visibility*/
|
||||
|
||||
var app = app || {};
|
||||
|
||||
@@ -159,7 +159,7 @@ app.cacheBuster = null;
|
||||
}
|
||||
app.currentRoom = '';
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function highlightNavigationLink() {
|
||||
var path = window.location.pathname;
|
||||
@@ -251,12 +251,21 @@ app.cacheBuster = null;
|
||||
chat.focusInput(chatModal);
|
||||
}
|
||||
|
||||
if (!chat.modalExists(roomId)) {
|
||||
chat.createModal({
|
||||
roomId: roomId
|
||||
}, loadAndCenter);
|
||||
} else {
|
||||
if (chat.modalExists(roomId)) {
|
||||
loadAndCenter(chat.getModal(roomId));
|
||||
} else {
|
||||
socket.emit('modules.chats.getUsersInRoom', {roomId: roomId}, function(err, users) {
|
||||
if (err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
users = users.filter(function(user) {
|
||||
return user && parseInt(user.uid, 10) !== parseInt(app.user.uid, 10);
|
||||
});
|
||||
chat.createModal({
|
||||
roomId: roomId,
|
||||
users: users
|
||||
}, loadAndCenter);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -266,6 +275,12 @@ app.cacheBuster = null;
|
||||
return app.alertError('[[error:not-logged-in]]');
|
||||
}
|
||||
|
||||
socket.emit('modules.chats.newRoom', {touid: touid}, function(err, roomId) {
|
||||
if (err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
app.openChat(roomId);
|
||||
});
|
||||
};
|
||||
|
||||
var titleObj = {
|
||||
@@ -410,7 +425,7 @@ app.cacheBuster = null;
|
||||
function handleStatusChange() {
|
||||
$('[component="header/usercontrol"] [data-status]').off('click').on('click', function(e) {
|
||||
var status = $(this).attr('data-status');
|
||||
socket.emit('user.setStatus', status, function(err, data) {
|
||||
socket.emit('user.setStatus', status, function(err) {
|
||||
if(err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ define('forum/account/header', [
|
||||
});
|
||||
|
||||
components.get('account/chat').on('click', function() {
|
||||
app.openChat($('.account-username').html(), theirid);
|
||||
app.newChat(theirid);
|
||||
});
|
||||
|
||||
components.get('account/ban').on('click', banAccount);
|
||||
|
||||
@@ -18,6 +18,7 @@ define('forum/chats', ['components', 'string', 'sounds', 'forum/infinitescroll',
|
||||
}
|
||||
|
||||
Chats.addEventListeners();
|
||||
Chats.createTagsInput(ajaxify.data.roomId, ajaxify.data.users);
|
||||
|
||||
if (env === 'md' || env === 'lg') {
|
||||
Chats.resizeMainWindow();
|
||||
@@ -191,6 +192,42 @@ define('forum/chats', ['components', 'string', 'sounds', 'forum/infinitescroll',
|
||||
});
|
||||
};
|
||||
|
||||
Chats.createTagsInput = function(roomId, users) {
|
||||
var tagEl = $('.users-tag-input');
|
||||
|
||||
tagEl.tagsinput({
|
||||
confirmKeys: [13, 44],
|
||||
trimValue: true
|
||||
});
|
||||
|
||||
if (users && users.length) {
|
||||
users.forEach(function(user) {
|
||||
tagEl.tagsinput('add', user.username);
|
||||
});
|
||||
}
|
||||
|
||||
tagEl.on('itemAdded', function(event) {
|
||||
if (event.item === app.user.username) {
|
||||
return;
|
||||
}
|
||||
socket.emit('modules.chats.addUserToRoom', {roomId: roomId, username: event.item}, function(err) {
|
||||
if (err && err.message === '[[error:no-user]]') {
|
||||
tagEl.tagsinput('remove', event.item);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
tagEl.on('itemRemoved', function(event) {
|
||||
socket.emit('modules.chats.removeUserFromRoom', {roomId: roomId, username: event.item});
|
||||
});
|
||||
|
||||
var input = $('.users-tag-container').find('.bootstrap-tagsinput input');
|
||||
|
||||
require(['autocomplete'], function(autocomplete) {
|
||||
autocomplete.user(input);
|
||||
});
|
||||
};
|
||||
|
||||
Chats.switchChat = function(roomid) {
|
||||
ajaxify.go('chats/' + roomid);
|
||||
};
|
||||
|
||||
@@ -405,12 +405,10 @@ define('forum/topic/postTools', ['share', 'navigator', 'components', 'translator
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
function openChat(button) {
|
||||
var post = button.parents('[data-pid]');
|
||||
|
||||
app.openChat(post.attr('data-username'), post.attr('data-uid'));
|
||||
app.newChat(post.attr('data-uid'));
|
||||
button.parents('.btn-group').find('.dropdown-toggle').click();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,9 @@ define('autocomplete', function() {
|
||||
app.loadJQueryUI(function() {
|
||||
input.autocomplete({
|
||||
delay: 100,
|
||||
open: function() {
|
||||
$(this).autocomplete('widget').css('z-index', 20000);
|
||||
},
|
||||
select: onselect,
|
||||
source: function(request, response) {
|
||||
socket.emit('user.search', {query: request.term}, function(err, result) {
|
||||
|
||||
@@ -229,7 +229,7 @@ define('chat', ['components', 'taskbar', 'string', 'sounds', 'forum/chats', 'tra
|
||||
components.get('chat/input').val(text);
|
||||
});
|
||||
|
||||
ajaxify.go('chats/' + utils.slugify(data.username));
|
||||
ajaxify.go('chats/' + chatModal.attr('roomId'));
|
||||
module.close(chatModal);
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ define('chat', ['components', 'taskbar', 'string', 'sounds', 'forum/chats', 'tra
|
||||
module.bringModalToTop(chatModal);
|
||||
|
||||
if (!dragged) {
|
||||
chatModal.find('#chat-message-input').focus();
|
||||
//chatModal.find('#chat-message-input').focus();
|
||||
} else {
|
||||
dragged = false;
|
||||
}
|
||||
@@ -274,6 +274,8 @@ define('chat', ['components', 'taskbar', 'string', 'sounds', 'forum/chats', 'tra
|
||||
|
||||
Chats.addSendHandlers(chatModal.attr('roomId'), chatModal.find('#chat-message-input'), chatModal.find('#chat-message-send-btn'));
|
||||
|
||||
Chats.createTagsInput(data.roomId, data.users);
|
||||
|
||||
Chats.loadChatSince(chatModal.attr('roomId'), chatModal.find('.chat-content'), 'recent');
|
||||
|
||||
checkStatus(chatModal);
|
||||
|
||||
@@ -14,7 +14,7 @@ chatsController.get = function(req, res, callback) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
messaging.getRecentChats(req.user.uid, 0, 19, function(err, recentChats) {
|
||||
messaging.getRecentChats(req.uid, 0, 19, function(err, recentChats) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
@@ -41,12 +41,12 @@ chatsController.get = function(req, res, callback) {
|
||||
async.parallel({
|
||||
users: async.apply(messaging.getUsersInRoom, req.params.roomid, 0, -1),
|
||||
messages: async.apply(messaging.getMessages, {
|
||||
uid: req.user.uid,
|
||||
uid: req.uid,
|
||||
roomId: req.params.roomid,
|
||||
since: 'recent',
|
||||
isNew: false
|
||||
}),
|
||||
allowed: async.apply(messaging.canMessageRoom, req.user.uid, req.params.roomid)
|
||||
allowed: async.apply(messaging.canMessageRoom, req.uid, req.params.roomid)
|
||||
}, next);
|
||||
}
|
||||
], function(err, data) {
|
||||
@@ -54,6 +54,10 @@ chatsController.get = function(req, res, callback) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
data.users = data.users.filter(function(user) {
|
||||
return user && parseInt(user.uid, 10) !== req.uid;
|
||||
});
|
||||
|
||||
var usernames = data.users.map(function(user) {
|
||||
return user && user.username;
|
||||
}).join(', ');
|
||||
|
||||
@@ -274,7 +274,9 @@ var async = require('async'),
|
||||
markRead: false
|
||||
}, function(err, teaser) {
|
||||
teaser = teaser[0];
|
||||
teaser.content = S(teaser.content).stripTags().decodeHTMLEntities().s;
|
||||
if (teaser && teaser.content) {
|
||||
teaser.content = S(teaser.content).stripTags().decodeHTMLEntities().s;
|
||||
}
|
||||
next(err, teaser);
|
||||
});
|
||||
}, next);
|
||||
|
||||
@@ -9,29 +9,6 @@ var db = require('../database');
|
||||
|
||||
module.exports = function(Messaging) {
|
||||
|
||||
|
||||
Messaging.newMessage = function(uid, toUids, content, timestamp, callback) {
|
||||
var roomId;
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
Messaging.checkContent(content, next);
|
||||
},
|
||||
function (next) {
|
||||
db.incrObjectField('global', 'nextChatRoomId', next);
|
||||
},
|
||||
function (_roomId, next) {
|
||||
roomId = _roomId;
|
||||
db.sortedSetAdd('chat:room:' + roomId + ':uids', timestamp, uid, next);
|
||||
},
|
||||
function (next) {
|
||||
Messaging.addUsersToRoom(uid, toUids, roomId, next);
|
||||
},
|
||||
function (next) {
|
||||
Messaging.sendMessage(uid, roomId, content, timestamp, next);
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
|
||||
Messaging.sendMessage = function(uid, roomId, content, timestamp, callback) {
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
@@ -87,7 +64,7 @@ module.exports = function(Messaging) {
|
||||
},
|
||||
function (uids, next) {
|
||||
async.parallel([
|
||||
async.apply(Messaging.updateChatTime, roomId, uids, timestamp),
|
||||
async.apply(Messaging.addRoomToUsers, roomId, uids, timestamp),
|
||||
async.apply(Messaging.addMessageToUsers, roomId, uids, mid, timestamp),
|
||||
async.apply(Messaging.markRead, fromuid, roomId),
|
||||
async.apply(Messaging.markUnread, uids, roomId)
|
||||
@@ -112,7 +89,7 @@ module.exports = function(Messaging) {
|
||||
], callback);
|
||||
};
|
||||
|
||||
Messaging.updateChatTime = function(roomId, uids, timestamp, callback) {
|
||||
Messaging.addRoomToUsers = function(roomId, uids, timestamp, callback) {
|
||||
if (!uids.length) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
@@ -7,6 +7,29 @@ var user = require('../user');
|
||||
|
||||
module.exports = function(Messaging) {
|
||||
|
||||
Messaging.newRoom = function(uid, toUids, callback) {
|
||||
var roomId;
|
||||
var now = Date.now();
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
db.incrObjectField('global', 'nextChatRoomId', next);
|
||||
},
|
||||
function (_roomId, next) {
|
||||
roomId = _roomId;
|
||||
db.sortedSetAdd('chat:room:' + roomId + ':uids', now, uid, next);
|
||||
},
|
||||
function (next) {
|
||||
Messaging.addUsersToRoom(uid, toUids, roomId, next);
|
||||
},
|
||||
function (next) {
|
||||
Messaging.addRoomToUsers(roomId, [uid].concat(toUids), now, next);
|
||||
},
|
||||
function (next) {
|
||||
next(null, roomId);
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
|
||||
Messaging.isUserInRoom = function(uid, roomId, callback) {
|
||||
db.isSortedSetMember('chat:room:' + roomId + ':uids', uid, callback);
|
||||
};
|
||||
@@ -27,31 +50,40 @@ module.exports = function(Messaging) {
|
||||
});
|
||||
};
|
||||
|
||||
Messaging.addUsersToRoom = function(fromuid, toUids, roomId, callback) {
|
||||
Messaging.addUsersToRoom = function(uid, uids, roomId, callback) {
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
Messaging.isRoomOwner(fromuid, roomId, next);
|
||||
Messaging.isRoomOwner(uid, roomId, next);
|
||||
},
|
||||
function (isOwner, next) {
|
||||
if (!isOwner) {
|
||||
return next(new Error('[[error:cant-add-users-to-chat-room]]'));
|
||||
}
|
||||
var now = Date.now();
|
||||
var timestamps = toUids.map(function() {
|
||||
var timestamps = uids.map(function() {
|
||||
return now;
|
||||
});
|
||||
db.sortedSetAdd('chat:room:' + roomId + ':uids', timestamps, toUids, next);
|
||||
db.sortedSetAdd('chat:room:' + roomId + ':uids', timestamps, uids, next);
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
|
||||
Messaging.leaveRoom = function(uid, roomId, callback) {
|
||||
Messaging.removeUsersFromRoom = function(uid, uids, roomId, callback) {
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
db.sortedSetRemove('chat:room:' + roomId + ':uids', uid, next);
|
||||
Messaging.isRoomOwner(uid, roomId, next);
|
||||
},
|
||||
function (isOwner, next) {
|
||||
if (!isOwner) {
|
||||
return next(new Error('[[error:cant-add-users-to-chat-room]]'));
|
||||
}
|
||||
db.sortedSetRemove('chat:room:' + roomId + ':uids', uids, next);
|
||||
},
|
||||
function (next) {
|
||||
db.sortedSetRemove('uid:' + uid + ':chat:rooms', roomId, next);
|
||||
var keys = uids.map(function(uid) {
|
||||
return 'uid:' + uid + ':chat:rooms';
|
||||
});
|
||||
db.sortedSetsRemove(keys, roomId, next);
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
"use strict";
|
||||
|
||||
var meta = require('../meta'),
|
||||
Messaging = require('../messaging'),
|
||||
utils = require('../../public/src/utils'),
|
||||
var async = require('async');
|
||||
var meta = require('../meta');
|
||||
var Messaging = require('../messaging');
|
||||
var utils = require('../../public/src/utils');
|
||||
var server = require('./');
|
||||
var user = require('../user');
|
||||
|
||||
async = require('async'),
|
||||
|
||||
server = require('./'),
|
||||
|
||||
SocketModules = {
|
||||
var SocketModules = {
|
||||
chats: {},
|
||||
sounds: {},
|
||||
settings: {}
|
||||
@@ -39,7 +38,7 @@ SocketModules.chats.getRaw = function(socket, data, callback) {
|
||||
Messaging.getMessageField(data.mid, 'content', callback);
|
||||
};
|
||||
|
||||
SocketModules.chats.newMessage = function(socket, data, callback) {
|
||||
SocketModules.chats.newRoom = function(socket, data, callback) {
|
||||
if (!data) {
|
||||
return callback(new Error('[[error:invalid-data]]'));
|
||||
}
|
||||
@@ -57,15 +56,7 @@ SocketModules.chats.newMessage = function(socket, data, callback) {
|
||||
return callback(err || new Error('[[error:chat-restricted]]'));
|
||||
}
|
||||
|
||||
Messaging.newMessage(socket.uid, [data.touid], data.content, now, function(err, message) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
Messaging.notifyUsersInRoom(socket.uid, message.roomId, message);
|
||||
|
||||
callback();
|
||||
});
|
||||
Messaging.newRoom(socket.uid, [data.touid], callback);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -101,6 +92,59 @@ SocketModules.chats.send = function(socket, data, callback) {
|
||||
});
|
||||
};
|
||||
|
||||
SocketModules.chats.getUsersInRoom = function(socket, data, callback) {
|
||||
if (!data || !data.roomId) {
|
||||
return callback(new Error('[[error:invalid-data]]'));
|
||||
}
|
||||
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
Messaging.isUserInRoom(socket.uid, data.roomId, next);
|
||||
},
|
||||
function (inRoom, next) {
|
||||
if (!inRoom) {
|
||||
return next(new Error('[[error:not-allowerd]]'));
|
||||
}
|
||||
Messaging.getUsersInRoom(data.roomId, 0, -1, next);
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
|
||||
SocketModules.chats.addUserToRoom = function(socket, data, callback) {
|
||||
if (!data || !data.roomId || !data.username) {
|
||||
return callback(new Error('[[error:invalid-data]]'));
|
||||
}
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
user.getUidByUsername(data.username, next);
|
||||
},
|
||||
function (uid, next) {
|
||||
if (!uid) {
|
||||
return next(new Error('[[error:no-user]]'));
|
||||
}
|
||||
Messaging.addUsersToRoom(socket.uid, [uid], data.roomId, next);
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
|
||||
SocketModules.chats.removeUserFromRoom = function(socket, data, callback) {
|
||||
if (!data || !data.roomId) {
|
||||
return callback(new Error('[[error:invalid-data]]'));
|
||||
}
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
user.getUidByUsername(data.username, next);
|
||||
},
|
||||
function (uid, next) {
|
||||
if (!uid) {
|
||||
return next(new Error('[[error:no-user]]'));
|
||||
}
|
||||
|
||||
Messaging.removeUsersFromRoom(socket.uid, [uid], data.roomId, next);
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
|
||||
SocketModules.chats.edit = function(socket, data, callback) {
|
||||
if (!data || !data.roomId) {
|
||||
return callback(new Error('[[error:invalid-data]]'));
|
||||
|
||||
Reference in New Issue
Block a user