mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 11:05:54 +01:00 
			
		
		
		
	crashing a lot less now, heh
This commit is contained in:
		| @@ -111,42 +111,6 @@ var socket, | |||||||
| 						}); | 						}); | ||||||
| 					}); | 					}); | ||||||
|  |  | ||||||
| 					socket.on('api:user.get_online_users', function (users) { |  | ||||||
| 						jQuery('a.username-field').each(function () { |  | ||||||
| 							if (this.processed === true) |  | ||||||
| 								return; |  | ||||||
|  |  | ||||||
| 							var el = jQuery(this), |  | ||||||
| 								uid = el.parents('li').attr('data-uid'); |  | ||||||
|  |  | ||||||
| 							if (uid && jQuery.inArray(uid, users) !== -1) { |  | ||||||
| 								el.find('i').remove(); |  | ||||||
| 								el.prepend('<i class="fa fa-circle"></i>'); |  | ||||||
| 							} else { |  | ||||||
| 								el.find('i').remove(); |  | ||||||
| 								el.prepend('<i class="fa fa-circle-o"></i>'); |  | ||||||
| 							} |  | ||||||
|  |  | ||||||
| 							el.processed = true; |  | ||||||
| 						}); |  | ||||||
| 						jQuery('button .username-field').each(function () { |  | ||||||
| 							//DRY FAIL |  | ||||||
| 							if (this.processed === true) |  | ||||||
| 								return; |  | ||||||
|  |  | ||||||
| 							var el = jQuery(this), |  | ||||||
| 								uid = el.parents('li').attr('data-uid'); |  | ||||||
|  |  | ||||||
| 							if (uid && jQuery.inArray(uid, users) !== -1) { |  | ||||||
| 								el.parent().addClass('btn-success'); |  | ||||||
| 							} else { |  | ||||||
| 								el.parent().addClass('btn-danger'); |  | ||||||
| 							} |  | ||||||
|  |  | ||||||
| 							el.processed = true; |  | ||||||
| 						}); |  | ||||||
| 					}); |  | ||||||
|  |  | ||||||
| 					socket.on('event:banned', function() { | 					socket.on('event:banned', function() { | ||||||
| 						app.alert({ | 						app.alert({ | ||||||
| 							title: 'Banned', | 							title: 'Banned', | ||||||
| @@ -287,7 +251,41 @@ var socket, | |||||||
| 			uids.push(this.getAttribute('data-uid')); | 			uids.push(this.getAttribute('data-uid')); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		socket.emit('api:user.get_online_users', uids); | 		socket.emit('api:user.get_online_users', uids, function (users) { | ||||||
|  | 			jQuery('a.username-field').each(function () { | ||||||
|  | 				if (this.processed === true) | ||||||
|  | 					return; | ||||||
|  |  | ||||||
|  | 				var el = jQuery(this), | ||||||
|  | 					uid = el.parents('li').attr('data-uid'); | ||||||
|  |  | ||||||
|  | 				if (uid && jQuery.inArray(uid, users) !== -1) { | ||||||
|  | 					el.find('i').remove(); | ||||||
|  | 					el.prepend('<i class="fa fa-circle"></i>'); | ||||||
|  | 				} else { | ||||||
|  | 					el.find('i').remove(); | ||||||
|  | 					el.prepend('<i class="fa fa-circle-o"></i>'); | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				el.processed = true; | ||||||
|  | 			}); | ||||||
|  | 			jQuery('button .username-field').each(function () { | ||||||
|  | 				//DRY FAIL | ||||||
|  | 				if (this.processed === true) | ||||||
|  | 					return; | ||||||
|  |  | ||||||
|  | 				var el = jQuery(this), | ||||||
|  | 					uid = el.parents('li').attr('data-uid'); | ||||||
|  |  | ||||||
|  | 				if (uid && jQuery.inArray(uid, users) !== -1) { | ||||||
|  | 					el.parent().addClass('btn-success'); | ||||||
|  | 				} else { | ||||||
|  | 					el.parent().addClass('btn-danger'); | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				el.processed = true; | ||||||
|  | 			}); | ||||||
|  | 		}); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	function highlightNavigationLink() { | 	function highlightNavigationLink() { | ||||||
|   | |||||||
| @@ -4,24 +4,21 @@ define(function() { | |||||||
| 	home.init = function() { | 	home.init = function() { | ||||||
|  |  | ||||||
| 		ajaxify.register_events([ | 		ajaxify.register_events([ | ||||||
| 			'user.count', | 			'api:user.count', | ||||||
| 			'post.stats', | 			'post.stats', | ||||||
| 			'api:user.active.get' | 			'api:user.getActiveUsers' | ||||||
| 		]); | 		]); | ||||||
|  |  | ||||||
| 		socket.emit('user.count', {}); | 		socket.emit('api:user.count', function(data) { | ||||||
| 		socket.on('user.count', function(data) { |  | ||||||
| 			$('#stats_users').html(utils.makeNumberHumanReadable(data.count)).attr('title', data.count); | 			$('#stats_users').html(utils.makeNumberHumanReadable(data.count)).attr('title', data.count); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		socket.emit('post.stats'); | 		socket.emit('post.stats', function(data) { | ||||||
| 		socket.on('post.stats', function(data) { |  | ||||||
| 			$('#stats_topics').html(utils.makeNumberHumanReadable(data.topics)).attr('title', data.topics); | 			$('#stats_topics').html(utils.makeNumberHumanReadable(data.topics)).attr('title', data.topics); | ||||||
| 			$('#stats_posts').html(utils.makeNumberHumanReadable(data.posts)).attr('title', data.posts); | 			$('#stats_posts').html(utils.makeNumberHumanReadable(data.posts)).attr('title', data.posts); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		socket.emit('api:user.active.get'); | 		socket.emit('api:user.getActiveUsers', function(data) { | ||||||
| 		socket.on('api:user.active.get', function(data) { |  | ||||||
| 			$('#stats_online').html(data.users); | 			$('#stats_online').html(data.users); | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -42,7 +42,7 @@ define(function() { | |||||||
| 			if (!utils.isEmailValid(emailEl.val())) { | 			if (!utils.isEmailValid(emailEl.val())) { | ||||||
| 				showError(email_notify, 'Invalid email address.'); | 				showError(email_notify, 'Invalid email address.'); | ||||||
| 			} else { | 			} else { | ||||||
| 				socket.emit('user.email.exists', { | 				socket.emit('api:user.emailExists', { | ||||||
| 					email: emailEl.val() | 					email: emailEl.val() | ||||||
| 				}); | 				}); | ||||||
| 			} | 			} | ||||||
| @@ -117,9 +117,9 @@ define(function() { | |||||||
| 			validatePasswordConfirm(); | 			validatePasswordConfirm(); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		ajaxify.register_events(['user.exists', 'user.email.exists']); | 		ajaxify.register_events(['api:user.exists', 'api:user.emailExists']); | ||||||
|  |  | ||||||
| 		socket.on('user.exists', function(data) { | 		socket.on('api:user.exists', function(data) { | ||||||
| 			if (data.exists === true) { | 			if (data.exists === true) { | ||||||
| 				showError(username_notify, 'Username already taken!'); | 				showError(username_notify, 'Username already taken!'); | ||||||
| 			} else { | 			} else { | ||||||
| @@ -127,7 +127,7 @@ define(function() { | |||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		socket.on('user.email.exists', function(data) { | 		socket.on('api:user.emailExists', function(data) { | ||||||
| 			if (data.exists === true) { | 			if (data.exists === true) { | ||||||
| 				showError(email_notify, 'Email address already taken!'); | 				showError(email_notify, 'Email address already taken!'); | ||||||
| 			} else { | 			} else { | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ define(function() { | |||||||
|  |  | ||||||
| 		document.getElementById('reset').onclick = function() { | 		document.getElementById('reset').onclick = function() { | ||||||
| 			if (inputEl.value.length > 0 && inputEl.value.indexOf('@') !== -1) { | 			if (inputEl.value.length > 0 && inputEl.value.indexOf('@') !== -1) { | ||||||
| 				socket.emit('user:reset.send', { | 				socket.emit('api:user.reset.send', { | ||||||
| 					email: inputEl.value | 					email: inputEl.value | ||||||
| 				}); | 				}); | ||||||
| 			} else { | 			} else { | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ define(function() { | |||||||
| 				noticeEl.querySelector('p').innerHTML = 'The two passwords you\'ve entered do not match.'; | 				noticeEl.querySelector('p').innerHTML = 'The two passwords you\'ve entered do not match.'; | ||||||
| 				noticeEl.style.display = 'block'; | 				noticeEl.style.display = 'block'; | ||||||
| 			} else { | 			} else { | ||||||
| 				socket.emit('user:reset.commit', { | 				socket.emit('api:user.reset.commit', { | ||||||
| 					code: reset_code, | 					code: reset_code, | ||||||
| 					password: password.value | 					password: password.value | ||||||
| 				}); | 				}); | ||||||
| @@ -29,13 +29,13 @@ define(function() { | |||||||
| 		}, false); | 		}, false); | ||||||
|  |  | ||||||
| 		// Enable the form if the code is valid | 		// Enable the form if the code is valid | ||||||
| 		socket.emit('user:reset.valid', { | 		socket.emit('api:user.reset.valid', { | ||||||
| 			code: reset_code | 			code: reset_code | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
|  |  | ||||||
| 		ajaxify.register_events(['user:reset.valid', 'user:reset.commit']); | 		ajaxify.register_events(['api:user.reset.valid', 'api:user.reset.commit']); | ||||||
| 		socket.on('user:reset.valid', function(data) { | 		socket.on('api:user.reset.valid', function(data) { | ||||||
| 			if ( !! data.valid) resetEl.disabled = false; | 			if ( !! data.valid) resetEl.disabled = false; | ||||||
| 			else { | 			else { | ||||||
| 				var formEl = document.getElementById('reset-form'); | 				var formEl = document.getElementById('reset-form'); | ||||||
| @@ -45,7 +45,7 @@ define(function() { | |||||||
| 			} | 			} | ||||||
| 		}) | 		}) | ||||||
|  |  | ||||||
| 		socket.on('user:reset.commit', function(data) { | 		socket.on('api:user.reset.commit', function(data) { | ||||||
| 			if (data.status === 'ok') { | 			if (data.status === 'ok') { | ||||||
| 				$('#error').hide(); | 				$('#error').hide(); | ||||||
| 				$('#notice').hide(); | 				$('#notice').hide(); | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ var	SocketIO = require('socket.io'), | |||||||
| 	socketioWildcard = require('socket.io-wildcard'), | 	socketioWildcard = require('socket.io-wildcard'), | ||||||
| 	util = require('util'), | 	util = require('util'), | ||||||
| 	async = require('async'), | 	async = require('async'), | ||||||
|  | 	path = require('path'), | ||||||
| 	fs = require('fs'), | 	fs = require('fs'), | ||||||
| 	nconf = require('nconf'), | 	nconf = require('nconf'), | ||||||
| 	express = require('express'), | 	express = require('express'), | ||||||
| @@ -30,6 +31,16 @@ Sockets.init = function() { | |||||||
| 		'browser client minification': true | 		'browser client minification': true | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
|  | 	fs.readdir(__dirname, function(err, files) { | ||||||
|  | 		files.splice(files.indexOf('index.js'), 1); | ||||||
|  |  | ||||||
|  | 		async.each(files, function(lib, next) { | ||||||
|  | 			lib = lib.slice(0, -3); | ||||||
|  | 			Namespaces[lib] = require('./' + lib); | ||||||
|  | 			next(); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
| 	io.sockets.on('connection', function(socket) { | 	io.sockets.on('connection', function(socket) { | ||||||
| 		var hs = socket.handshake, | 		var hs = socket.handshake, | ||||||
| 			sessionID, uid, lastPostTime = 0; | 			sessionID, uid, lastPostTime = 0; | ||||||
| @@ -123,36 +134,31 @@ Sockets.init = function() { | |||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		socket.on('*', function(payload) { | 		socket.on('*', function(payload, callback) { | ||||||
| 			// Ignore all non-api messages | 			// Ignore all non-api messages | ||||||
| 			if (payload.name.substr(0, 4) !== 'api:') { | 			if (payload.name.substr(0, 4) !== 'api:') { | ||||||
| 				return; | 				return; | ||||||
| 			} else { | 			} else { | ||||||
| 				// Deconstruct the message | 				// Deconstruct the message | ||||||
| 				var parts = payload.name.split('.'), | 				var parts = payload.name.slice(4).split('.'), | ||||||
| 					namespace = parts[0], | 					namespace = parts[0], | ||||||
| 					command = parts[1], | 					command = parts[1], | ||||||
| 					subcommand = parts[2],	// MUST ADD RECURSION (:P) | 					subcommand = parts[2],	// MUST ADD RECURSION (:P) | ||||||
| 					executeHandler = function(args) { | 					executeHandler = function(args) { | ||||||
|  | 						winston.info('[socket.io] Executing: ' + payload.name); | ||||||
| 						if (!subcommand) { | 						if (!subcommand) { | ||||||
| 							Namespaces[namespace][command](args); | 							Namespaces[namespace][command].call(Namespaces[namespace], args.length ? args : callback ? callback : undefined, args.length ? callback : undefined); | ||||||
| 						} else { | 						} else { | ||||||
| 							Namespaces[namespace][command][subcommand](args); | 							Namespaces[namespace][command][subcommand].call(Namespaces[namespace][command], args, callback); | ||||||
| 						} | 						} | ||||||
| 					}; | 					}; | ||||||
|  |  | ||||||
| 				if (Namespaces[namespace]) { | 				if (Namespaces[namespace]) { | ||||||
| 					executeHandler(payload.args); | 					console.log(payload); | ||||||
| 				} else { |  | ||||||
| 					fs.exists(path.join(__dirname, namespace + '.js'), function(exists) { |  | ||||||
| 						if (exists) { |  | ||||||
| 							Namespaces[namespace] = require('./' + namespace); |  | ||||||
| 					executeHandler(payload.args); | 					executeHandler(payload.args); | ||||||
| 				} else { | 				} else { | ||||||
| 					winston.warn('[socket.io] Unrecognized message: ' + payload.name); | 					winston.warn('[socket.io] Unrecognized message: ' + payload.name); | ||||||
| 				} | 				} | ||||||
| 					}) |  | ||||||
| 				} |  | ||||||
| 			} | 			} | ||||||
| 			console.log('message!', arguments); | 			console.log('message!', arguments); | ||||||
| 		}); | 		}); | ||||||
| @@ -251,7 +257,8 @@ function emitTopicPostStats() { | |||||||
| 	}); | 	}); | ||||||
| } | } | ||||||
|  |  | ||||||
| function emitOnlineUserCount() { | Sockets.emitOnlineUserCount = emitOnlineUserCount; | ||||||
|  | function emitOnlineUserCount(callback) { | ||||||
| 	var anon = userSockets[0] ? userSockets[0].length : 0; | 	var anon = userSockets[0] ? userSockets[0].length : 0; | ||||||
| 	var registered = Object.keys(userSockets).length; | 	var registered = Object.keys(userSockets).length; | ||||||
| 	if (anon) | 	if (anon) | ||||||
| @@ -261,8 +268,13 @@ function emitOnlineUserCount() { | |||||||
| 		users: registered + anon, | 		users: registered + anon, | ||||||
| 		anon: anon | 		anon: anon | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
|  | 	if (callback) { | ||||||
|  | 		callback(returnObj); | ||||||
|  | 	} else { | ||||||
| 		io.sockets.emit('api:user.active.get', returnObj) | 		io.sockets.emit('api:user.active.get', returnObj) | ||||||
| 	} | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| function emitAlert(socket, title, message) { | function emitAlert(socket, title, message) { | ||||||
| 	socket.emit('event:alert', { | 	socket.emit('event:alert', { | ||||||
|   | |||||||
| @@ -667,13 +667,13 @@ var bcrypt = require('bcrypt'), | |||||||
| 		}); | 		}); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	User.count = function(socket) { | 	User.count = function(callback) { | ||||||
| 		db.getObjectField('global', 'userCount', function(err, count) { | 		db.getObjectField('global', 'userCount', function(err, count) { | ||||||
| 			if(err) { | 			if(err) { | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			socket.emit('user.count', { | 			callback({ | ||||||
| 				count: count ? count : 0 | 				count: count ? count : 0 | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|   | |||||||
| @@ -93,121 +93,19 @@ websockets.init = function(io) { | |||||||
|  |  | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		socket.on('user.exists', function(data) { |  | ||||||
| 			if (data.username) { |  | ||||||
| 				user.exists(utils.slugify(data.username), function(exists) { |  | ||||||
| 					socket.emit('user.exists', { |  | ||||||
| 						exists: exists |  | ||||||
| 					}); |  | ||||||
| 				}); |  | ||||||
| 			} |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		socket.on('user.count', function(data) { |  | ||||||
| 			user.count(socket, data); |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		socket.on('post.stats', function(data) { | 		socket.on('post.stats', function(data) { | ||||||
| 			emitTopicPostStats(); | 			emitTopicPostStats(); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		socket.on('user.email.exists', function(data) { |  | ||||||
| 			user.email.exists(socket, data.email); |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		socket.on('user:reset.send', function(data) { |  | ||||||
| 			user.reset.send(socket, data.email); |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		socket.on('user:reset.valid', function(data) { |  | ||||||
| 			user.reset.validate(socket, data.code); |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		socket.on('user:reset.commit', function(data) { |  | ||||||
| 			user.reset.commit(socket, data.code, data.password); |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		socket.on('api:user.get_online_users', function(data) { |  | ||||||
| 			var returnData = []; |  | ||||||
|  |  | ||||||
| 			for (var i = 0; i < data.length; ++i) { |  | ||||||
| 				var uid = data[i]; |  | ||||||
| 				if (isUserOnline(uid)) |  | ||||||
| 					returnData.push(uid); |  | ||||||
| 				else |  | ||||||
| 					returnData.push(0); |  | ||||||
| 			} |  | ||||||
| 			socket.emit('api:user.get_online_users', returnData); |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		socket.on('api:user.isOnline', function(uid, callback) { |  | ||||||
| 			callback({ |  | ||||||
| 				online: isUserOnline(uid), |  | ||||||
| 				uid: uid, |  | ||||||
| 				timestamp: Date.now() |  | ||||||
| 			}); |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		socket.on('api:user.changePassword', function(data, callback) { |  | ||||||
| 			user.changePassword(uid, data, callback); |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		socket.on('api:user.updateProfile', function(data, callback) { |  | ||||||
| 			user.updateProfile(uid, data, callback); |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		socket.on('api:user.changePicture', function(data, callback) { |  | ||||||
|  |  | ||||||
| 			var type = data.type; |  | ||||||
|  |  | ||||||
| 			function updateHeader() { |  | ||||||
| 				user.getUserFields(uid, ['picture'], function(err, fields) { |  | ||||||
| 					if (!err && fields) { |  | ||||||
| 						fields.uid = uid; |  | ||||||
| 						socket.emit('api:updateHeader', fields); |  | ||||||
| 						callback(true); |  | ||||||
| 					} else { |  | ||||||
| 						callback(false); |  | ||||||
| 					} |  | ||||||
| 				}); |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			if (type === 'gravatar') { |  | ||||||
| 				user.getUserField(uid, 'gravatarpicture', function(err, gravatar) { |  | ||||||
| 					user.setUserField(uid, 'picture', gravatar); |  | ||||||
| 					updateHeader(); |  | ||||||
| 				}); |  | ||||||
| 			} else if (type === 'uploaded') { |  | ||||||
| 				user.getUserField(uid, 'uploadedpicture', function(err, uploadedpicture) { |  | ||||||
| 					user.setUserField(uid, 'picture', uploadedpicture); |  | ||||||
| 					updateHeader(); |  | ||||||
| 				}); |  | ||||||
| 			} else { |  | ||||||
| 				callback(false); |  | ||||||
| 			} |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		socket.on('api:user.follow', function(data, callback) { |  | ||||||
| 			if (uid) { |  | ||||||
| 				user.follow(uid, data.uid, callback); |  | ||||||
| 			} |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		socket.on('api:user.unfollow', function(data, callback) { |  | ||||||
| 			if (uid) { |  | ||||||
| 				user.unfollow(uid, data.uid, callback); |  | ||||||
| 			} |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		socket.on('api:user.saveSettings', function(data, callback) { |  | ||||||
| 			if (uid) { |  | ||||||
| 				user.setUserFields(uid, { |  | ||||||
| 					showemail: data.showemail |  | ||||||
| 				}, function(err, result) { |  | ||||||
| 					callback(err); |  | ||||||
| 				}); |  | ||||||
| 			} |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -346,18 +244,8 @@ websockets.init = function(io) { | |||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		socket.on('api:user.getOnlineAnonCount', function(data, callback) { |  | ||||||
| 			callback(websockets.getOnlineAnonCount()); |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 		socket.on('api:user.active.get', function() { |  | ||||||
| 			emitOnlineUserCount(); |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		socket.on('api:posts.favourite', function(data) { | 		socket.on('api:posts.favourite', function(data) { | ||||||
| 			favourites.favourite(data.pid, data.room_id, uid, socket); | 			favourites.favourite(data.pid, data.room_id, uid, socket); | ||||||
| 		}); | 		}); | ||||||
| @@ -995,11 +883,7 @@ websockets.init = function(io) { | |||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		socket.on('api:meta.buildTitle', function(text, callback) { |  | ||||||
| 			meta.title.build(text, function(err, title) { |  | ||||||
| 				callback(title); |  | ||||||
| 			}); |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		/* | 		/* | ||||||
| 			GROUPS | 			GROUPS | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user