'use strict'; var nconf = require('nconf'), async = require('async'), topics = require('../topics'), categories = require('../categories'), privileges = require('../privileges'), notifications = require('../notifications'), threadTools = require('../threadTools'), websockets = require('./index'), user = require('../user'), db = require('../database'), meta = require('../meta'), utils = require('../../public/src/utils'), SocketPosts = require('./posts'), SocketTopics = {}; SocketTopics.post = function(socket, data, callback) { if(!data) { return callback(new Error('[[error:invalid-data]]')); } topics.post({ uid: socket.uid, title: data.title, content: data.content, cid: data.category_id, thumb: data.topic_thumb, tags: data.tags, req: websockets.reqFromSocket(socket) }, function(err, result) { if(err) { return callback(err); } if (result) { websockets.server.sockets.in('category_' + data.category_id).emit('event:new_topic', result.topicData); websockets.server.sockets.in('recent_posts').emit('event:new_topic', result.topicData); websockets.server.sockets.in('home').emit('event:new_topic', result.topicData); websockets.server.sockets.in('home').emit('event:new_post', { posts: result.postData }); websockets.server.sockets.in('user/' + socket.uid).emit('event:new_post', { posts: result.postData }); module.parent.exports.emitTopicPostStats(); topics.pushUnreadCount(); callback(null, result.topicData); } }); }; SocketTopics.enter = function(socket, tid, callback) { if (!tid || !socket.uid) { return; } SocketTopics.markAsRead(socket, tid); topics.markTopicNotificationsRead(tid, socket.uid); topics.increaseViewCount(tid); }; SocketTopics.postcount = function(socket, tid, callback) { topics.getTopicField(tid, 'postcount', callback); }; SocketTopics.increaseViewCount = function(socket, tid) { topics.increaseViewCount(tid); }; SocketTopics.markAsRead = function(socket, tid) { if(!tid || !socket.uid) { return; } topics.markAsRead(tid, socket.uid, function(err) { topics.pushUnreadCount(socket.uid); }); }; SocketTopics.markTidsRead = function(socket, tids, callback) { if (!Array.isArray(tids)) { return callback(new Error('[[error:invalid-data]]')); } topics.markTidsRead(socket.uid, tids, function(err) { if(err) { return callback(err); } topics.pushUnreadCount(socket.uid); for (var i=0; i= 0)) { return callback(new Error('[[error:invalid-data]]')); } async.parallel({ settings: function(next) { user.getSettings(socket.uid, next); }, privileges: function(next) { privileges.topics.get(data.tid, socket.uid, next); }, postCount: function(next) { topics.getPostCount(data.tid, next); } }, function(err, results) { if (err) { return callback(err); } if (!results.privileges.read) { return callback(new Error('[[error:no-privileges]]')); } var set = 'tid:' + data.tid + ':posts', reverse = false, start = Math.max(parseInt(data.after, 10) - 1, 0); if (results.settings.topicPostSort === 'newest_to_oldest') { reverse = true; data.after = results.postCount - data.after; start = Math.max(parseInt(data.after, 10), 0); } else if (results.settings.topicPostSort === 'most_votes') { reverse = true; data.after = results.postCount - data.after; start = Math.max(parseInt(data.after, 10), 0); set = 'tid:' + data.tid + ':posts:votes'; } var end = start + results.settings.postsPerPage - 1; async.parallel({ posts: function(next) { topics.getTopicPosts(data.tid, set, start, end, socket.uid, reverse, next); }, privileges: function(next) { next(null, results.privileges); }, 'reputation:disabled': function(next) { next(null, parseInt(meta.config['reputation:disabled'], 10) === 1); }, 'downvote:disabled': function(next) { next(null, parseInt(meta.config['downvote:disabled'], 10) === 1); } }, callback); }); }; SocketTopics.loadMoreRecentTopics = function(socket, data, callback) { if(!data || !data.term || !data.after) { return callback(new Error('[[error:invalid-data]]')); } var start = parseInt(data.after, 10), end = start + 9; topics.getLatestTopics(socket.uid, start, end, data.term, callback); }; SocketTopics.loadMoreUnreadTopics = function(socket, data, callback) { if(!data || !data.after) { return callback(new Error('[[error:invalid-data]]')); } var start = parseInt(data.after, 10), end = start + 9; topics.getUnreadTopics(socket.uid, start, end, callback); }; SocketTopics.loadMoreFromSet = function(socket, data, callback) { if(!data || !data.after || !data.set) { return callback(new Error('[[error:invalid-data]]')); } var start = parseInt(data.after, 10), end = start + 9; topics.getTopicsFromSet(socket.uid, data.set, start, end, callback); }; SocketTopics.loadTopics = function(socket, data, callback) { if(!data || !data.set || !utils.isNumber(data.start) || !utils.isNumber(data.end)) { return callback(new Error('[[error:invalid-data]]')); } topics.getTopicsFromSet(socket.uid, data.set, data.start, data.end, callback); }; SocketTopics.getPageCount = function(socket, tid, callback) { topics.getPageCount(tid, socket.uid, callback); }; SocketTopics.getTidPage = function(socket, tid, callback) { topics.getTidPage(tid, socket.uid, callback); }; SocketTopics.getTidIndex = function(socket, tid, callback) { categories.getTopicIndex(tid, callback); }; SocketTopics.searchTags = function(socket, data, callback) { topics.searchTags(data, callback); }; SocketTopics.search = function(socket, data, callback) { topics.search(data.tid, data.term, callback); }; SocketTopics.searchAndLoadTags = function(socket, data, callback) { topics.searchTags(data, function(err, tags) { if (err) { return callback(err); } async.parallel({ counts: function(next) { db.sortedSetScores('tags:topic:count', tags, next); }, tagData: function(next) { tags = tags.map(function(tag) { return {value: tag}; }); topics.getTagData(tags, next); } }, function(err, results) { if (err) { return callback(err); } results.tagData.forEach(function(tag, index) { tag.score = results.counts[index]; }); results.tagData.sort(function(a, b) { return parseInt(b.score, 10) - parseInt(a.score, 10); }); callback(null, results.tagData); }); }); }; SocketTopics.loadMoreTags = function(socket, data, callback) { if(!data || !data.after) { return callback(new Error('[[error:invalid-data]]')); } var start = parseInt(data.after, 10), end = start + 99; topics.getTags(start, end, function(err, tags) { if (err) { return callback(err); } callback(null, {tags: tags, nextStart: end + 1}); }); }; module.exports = SocketTopics;