mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-07-08 18:43:04 +02:00
Merge branch 'master' of github.com:designcreateplay/NodeBB
This commit is contained in:
@@ -25,7 +25,6 @@
|
||||
"passport-facebook": "0.1.5",
|
||||
"less-middleware": "0.1.12",
|
||||
"marked": "0.2.8",
|
||||
"bcrypt": "0.7.5",
|
||||
"async": "~0.2.8",
|
||||
"node-imagemagick": "0.1.8",
|
||||
"gravatar": "1.0.6",
|
||||
@@ -47,7 +46,8 @@
|
||||
"semver": "~2.2.1",
|
||||
"string": "~1.7.0",
|
||||
"xregexp": "~2.0.0",
|
||||
"socket.io-wildcard": "~0.1.1"
|
||||
"socket.io-wildcard": "~0.1.1",
|
||||
"bcryptjs": "~0.7.10"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"redis": "0.8.3",
|
||||
|
||||
@@ -396,6 +396,16 @@ var socket,
|
||||
});
|
||||
};
|
||||
|
||||
app.enableInfiniteLoading = function(callback) {
|
||||
$(window).off('scroll').on('scroll', function() {
|
||||
var bottom = ($(document).height() - $(window).height()) * 0.9;
|
||||
|
||||
if ($(window).scrollTop() > bottom) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var titleObj = {
|
||||
active: false,
|
||||
interval: undefined,
|
||||
|
||||
@@ -178,13 +178,13 @@ define(['uploader'], function(uploader) {
|
||||
});
|
||||
|
||||
// Permissions modal
|
||||
$('.permissions').on('click', function() {
|
||||
$('.admin-categories').on('click', '.permissions', function() {
|
||||
var cid = $(this).parents('li[data-cid]').attr('data-cid');
|
||||
Categories.launchPermissionsModal(cid);
|
||||
});
|
||||
|
||||
|
||||
$('.upload-button').on('click', function() {
|
||||
$('.admin-categories').on('click', '.upload-button', function() {
|
||||
var inputEl = this;
|
||||
var cid = $(this).parents('li[data-cid]').attr('data-cid');
|
||||
uploader.open(RELATIVE_PATH + '/admin/category/uploadpicture', {cid:cid}, function(imageUrlOnServer) {
|
||||
@@ -196,7 +196,7 @@ define(['uploader'], function(uploader) {
|
||||
});
|
||||
});
|
||||
|
||||
$('.admin-categories').delegate('.delete-image', 'click', function() {
|
||||
$('.admin-categories').on('click', '.delete-image', function() {
|
||||
var parent = $(this).parents('li[data-cid]'),
|
||||
inputEl = parent.find('.upload-button'),
|
||||
preview = parent.find('.preview-box'),
|
||||
|
||||
@@ -18,6 +18,7 @@ define(function() {
|
||||
};
|
||||
|
||||
Admin.updateRoomUsage = function(err, data) {
|
||||
|
||||
function getUserCountIn(room) {
|
||||
var count = 0;
|
||||
for(var user in data[room]) {
|
||||
@@ -25,27 +26,36 @@ define(function() {
|
||||
}
|
||||
return count;
|
||||
}
|
||||
var active_users = $('#active_users'),
|
||||
|
||||
var active_users = $('#active_users').html(''),
|
||||
total = 0;
|
||||
|
||||
if(!active_users.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
active_users.html('');
|
||||
|
||||
var usersHtml = '';
|
||||
var sortedData = [];
|
||||
|
||||
for (var room in data) {
|
||||
if (room !== '') {
|
||||
var count = getUserCountIn(room);
|
||||
total += count;
|
||||
usersHtml += "<div class='alert alert-success'><strong>" + room + "</strong> " + count + " active user" + (count > 1 ? "s" : "") + "</div>";
|
||||
sortedData.push({room: room, count: data[room].length});
|
||||
total += data[room].length;
|
||||
}
|
||||
}
|
||||
|
||||
sortedData.sort(function(a, b) {
|
||||
return parseInt(b.count, 10) - parseInt(a.count, 10);
|
||||
});
|
||||
|
||||
var usersHtml = '';
|
||||
for(var i=0; i<sortedData.length; ++i) {
|
||||
usersHtml += "<div class='alert alert-success'><strong>" + sortedData[i].room + "</strong> " +
|
||||
sortedData[i].count + " active user" + (sortedData[i].count > 1 ? "s" : "") + "</div>";
|
||||
}
|
||||
|
||||
active_users.html(usersHtml);
|
||||
document.getElementById('connections').innerHTML = total;
|
||||
$('#connections').html(total);
|
||||
};
|
||||
|
||||
return Admin;
|
||||
|
||||
@@ -44,11 +44,9 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
|
||||
function enableInfiniteLoading() {
|
||||
if(!config.usePagination) {
|
||||
$(window).off('scroll').on('scroll', function (ev) {
|
||||
var bottom = ($(document).height() - $(window).height()) * 0.9;
|
||||
|
||||
if ($(window).scrollTop() > bottom && !loadingMoreTopics) {
|
||||
Category.loadMoreTopics(cid);
|
||||
app.enableInfiniteLoading(function() {
|
||||
if(!loadingMoreTopics) {
|
||||
Category.loadMoreTopics(templates.get('category_id'));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@@ -147,7 +145,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
loadingMoreTopics = true;
|
||||
socket.emit('categories.loadMore', {
|
||||
cid: cid,
|
||||
after: $('#topics-container').children('.category-item').length
|
||||
after: $('#topics-container').attr('data-nextstart')
|
||||
}, function (err, data) {
|
||||
if(err) {
|
||||
return app.alertError(err.message);
|
||||
@@ -155,6 +153,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
|
||||
if (data && data.topics.length) {
|
||||
Category.onTopicsLoaded(data.topics);
|
||||
$('#topics-container').attr('data-nextstart', data.nextStart);
|
||||
}
|
||||
loadingMoreTopics = false;
|
||||
});
|
||||
|
||||
@@ -52,12 +52,6 @@ define(function() {
|
||||
});
|
||||
|
||||
document.querySelector('#content input').focus();
|
||||
|
||||
if(!config.emailSetup)
|
||||
$('#reset-link').addClass('hide');
|
||||
else
|
||||
$('#reset-link').removeClass('hide');
|
||||
|
||||
};
|
||||
|
||||
return Login;
|
||||
|
||||
@@ -14,11 +14,11 @@ define(function() {
|
||||
|
||||
$('.pagination')
|
||||
.on('click', '.previous', function() {
|
||||
pagination.loadPage(pagination.currentPage - 1);
|
||||
return pagination.loadPage(pagination.currentPage - 1);
|
||||
}).on('click', '.next', function() {
|
||||
pagination.loadPage(pagination.currentPage + 1);
|
||||
return pagination.loadPage(pagination.currentPage + 1);
|
||||
}).on('click', '.page', function() {
|
||||
pagination.loadPage($(this).attr('data-page'));
|
||||
return pagination.loadPage($(this).attr('data-page'));
|
||||
}).on('click', '.select_page', function(e) {
|
||||
e.preventDefault();
|
||||
bootbox.prompt('Enter page number:', function(pageNum) {
|
||||
@@ -58,7 +58,7 @@ define(function() {
|
||||
for(var i=0; i<pagesToShow.length; ++i) {
|
||||
if(i > 0) {
|
||||
if (pagesToShow[i] - 1 !== pagesToShow[i-1]) {
|
||||
html += '<li class="disabled"><a class="select_page" href="#">|</a></li>';
|
||||
html += '<li><a class="select_page" href="#">|</a></li>';
|
||||
}
|
||||
}
|
||||
html += '<li class="page" data-page="' + pagesToShow[i] + '"><a href="#">' + pagesToShow[i] + '</a></li>';
|
||||
@@ -72,10 +72,11 @@ define(function() {
|
||||
pagination.loadPage = function(page, callback) {
|
||||
page = parseInt(page, 10);
|
||||
if(!utils.isNumber(page) || page < 1 || page > pagination.pageCount) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
ajaxify.go(window.location.pathname.slice(1) + '?page=' + page);
|
||||
return true;
|
||||
}
|
||||
|
||||
function updatePageLinks() {
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
define(function() {
|
||||
var Recent = {};
|
||||
|
||||
Recent.newTopicCount = 0;
|
||||
Recent.newPostCount = 0;
|
||||
Recent.loadingMoreTopics = false;
|
||||
var newTopicCount = 0,
|
||||
newPostCount = 0,
|
||||
loadingMoreTopics = false;
|
||||
|
||||
var active = '';
|
||||
|
||||
Recent.init = function() {
|
||||
app.enterRoom('recent_posts');
|
||||
|
||||
ajaxify.register_events([
|
||||
'event:new_topic',
|
||||
'event:new_post'
|
||||
]);
|
||||
|
||||
Recent.watchForNewPosts();
|
||||
|
||||
function getActiveSection() {
|
||||
var url = window.location.href,
|
||||
@@ -37,27 +33,35 @@ define(function() {
|
||||
$(this).addClass('hide');
|
||||
});
|
||||
|
||||
socket.on('event:new_topic', function(data) {
|
||||
|
||||
++Recent.newTopicCount;
|
||||
Recent.updateAlertText();
|
||||
|
||||
});
|
||||
|
||||
socket.on('event:new_post', function(data) {
|
||||
++Recent.newPostCount;
|
||||
Recent.updateAlertText();
|
||||
});
|
||||
|
||||
$(window).off('scroll').on('scroll', function() {
|
||||
var bottom = ($(document).height() - $(window).height()) * 0.9;
|
||||
|
||||
if ($(window).scrollTop() > bottom && !Recent.loadingMoreTopics) {
|
||||
app.enableInfiniteLoading(function() {
|
||||
if(!loadingMoreTopics) {
|
||||
Recent.loadMoreTopics();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Recent.watchForNewPosts = function () {
|
||||
|
||||
newPostCount = 0;
|
||||
newTopicCount = 0;
|
||||
|
||||
ajaxify.register_events([
|
||||
'event:new_topic',
|
||||
'event:new_post'
|
||||
]);
|
||||
|
||||
socket.on('event:new_topic', function(data) {
|
||||
++newTopicCount;
|
||||
Recent.updateAlertText();
|
||||
});
|
||||
|
||||
socket.on('event:new_post', function(data) {
|
||||
++newPostCount;
|
||||
Recent.updateAlertText();
|
||||
});
|
||||
}
|
||||
|
||||
Recent.updateAlertText = function() {
|
||||
var text = 'There';
|
||||
|
||||
@@ -76,41 +80,44 @@ define(function() {
|
||||
text += '. Click here to reload.';
|
||||
|
||||
$('#new-topics-alert').html(text).removeClass('hide').fadeIn('slow');
|
||||
$('#category-no-topics').addClass('hide');
|
||||
}
|
||||
|
||||
Recent.onTopicsLoaded = function(topics) {
|
||||
var html = templates.prepare(templates['recent'].blocks['topics']).parse({
|
||||
Recent.loadMoreTopics = function() {
|
||||
loadingMoreTopics = true;
|
||||
socket.emit('topics.loadMoreRecentTopics', {
|
||||
after: $('#topics-container').attr('data-nextstart'),
|
||||
term: active
|
||||
}, function(err, data) {
|
||||
if(err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
|
||||
if (data.topics && data.topics.length) {
|
||||
Recent.onTopicsLoaded('recent', data.topics);
|
||||
$('#topics-container').attr('data-nextstart', data.nextStart);
|
||||
}
|
||||
|
||||
loadingMoreTopics = false;
|
||||
});
|
||||
}
|
||||
|
||||
Recent.onTopicsLoaded = function(template, topics) {
|
||||
var html = templates.prepare(templates[template].blocks['topics']).parse({
|
||||
topics: topics
|
||||
});
|
||||
|
||||
translator.translate(html, function(translatedHTML) {
|
||||
var container = $('#topics-container');
|
||||
|
||||
$('#category-no-topics').remove();
|
||||
|
||||
html = $(translatedHTML);
|
||||
container.append(html);
|
||||
$('#topics-container').append(html);
|
||||
$('span.timeago').timeago();
|
||||
app.createUserTooltips();
|
||||
app.makeNumbersHumanReadable(html.find('.human-readable-number'));
|
||||
});
|
||||
}
|
||||
|
||||
Recent.loadMoreTopics = function() {
|
||||
Recent.loadingMoreTopics = true;
|
||||
socket.emit('topics.loadMoreRecentTopics', {
|
||||
after: $('#topics-container').children('li').length,
|
||||
term: active
|
||||
}, function(err, data) {
|
||||
if(err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
if (data.topics && data.topics.length) {
|
||||
Recent.onTopicsLoaded(data.topics);
|
||||
}
|
||||
Recent.loadingMoreTopics = false;
|
||||
});
|
||||
}
|
||||
|
||||
return Recent;
|
||||
});
|
||||
|
||||
@@ -2,9 +2,9 @@ define(function() {
|
||||
var Search = {};
|
||||
|
||||
Search.init = function() {
|
||||
var searchQuery = $('#topics-container').attr('data-search-query');
|
||||
|
||||
$('.search-result-text').each(function() {
|
||||
var searchQuery = $('#topic-results').attr('data-search-query');
|
||||
console.log(searchQuery);
|
||||
$('.search-result-text').children().each(function() {
|
||||
var text = $(this).html();
|
||||
var regex = new RegExp(searchQuery, 'gi');
|
||||
text = text.replace(regex, '<span class="label label-success">' + searchQuery + '</span>');
|
||||
|
||||
@@ -346,10 +346,8 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
|
||||
function enableInfiniteLoading() {
|
||||
if(!config.usePagination) {
|
||||
$(window).off('scroll').on('scroll', function() {
|
||||
var bottom = ($(document).height() - $(window).height()) * 0.9;
|
||||
|
||||
if ($(window).scrollTop() > bottom && !infiniteLoaderActive && $('#post-container').children().length) {
|
||||
app.enableInfiniteLoading(function() {
|
||||
if (!infiniteLoaderActive && $('#post-container').children().length) {
|
||||
loadMorePosts(tid, function(posts) {
|
||||
fixDeleteStateForPosts();
|
||||
});
|
||||
@@ -396,7 +394,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
|
||||
socket.emit('posts.getRawPost', pid, function(err, post) {
|
||||
if(err) {
|
||||
return app.alert(err.message);
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
var quoted = '';
|
||||
if(post) {
|
||||
@@ -895,47 +893,34 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
}
|
||||
|
||||
function toggle_post_delete_state(pid) {
|
||||
var postEl = $(document.querySelector('#post-container li[data-pid="' + pid + '"]'));
|
||||
var postEl = $('#post-container li[data-pid="' + pid + '"]');
|
||||
|
||||
if (postEl[0]) {
|
||||
quoteEl = postEl.find('.quote'),
|
||||
favEl = postEl.find('.favourite'),
|
||||
replyEl = postEl.find('.post_reply');
|
||||
if (postEl.length) {
|
||||
postEl.toggleClass('deleted');
|
||||
|
||||
socket.emit('posts.getPrivileges', pid, function(err, privileges) {
|
||||
if(err) {
|
||||
return app.alert(err.message);
|
||||
}
|
||||
toggle_post_tools(pid, postEl.hasClass('deleted'));
|
||||
|
||||
if (privileges.editable) {
|
||||
if (!postEl.hasClass('deleted')) {
|
||||
toggle_post_tools(pid, false);
|
||||
} else {
|
||||
toggle_post_tools(pid, true);
|
||||
}
|
||||
}
|
||||
|
||||
postEl.toggleClass('deleted');
|
||||
|
||||
updatePostCount();
|
||||
});
|
||||
updatePostCount();
|
||||
}
|
||||
}
|
||||
|
||||
function toggle_post_tools(pid, state) {
|
||||
var postEl = $(document.querySelector('#post-container li[data-pid="' + pid + '"]')),
|
||||
function toggle_post_tools(pid, isDeleted) {
|
||||
var postEl = $('#post-container li[data-pid="' + pid + '"]'),
|
||||
quoteEl = $(postEl[0].querySelector('.quote')),
|
||||
favEl = $(postEl[0].querySelector('.favourite')),
|
||||
replyEl = $(postEl[0].querySelector('.post_reply'));
|
||||
replyEl = $(postEl[0].querySelector('.post_reply')),
|
||||
chatEl = $(postEl[0].querySelector('.chat'));
|
||||
|
||||
if (state) {
|
||||
quoteEl.removeClass('none');
|
||||
favEl.removeClass('none');
|
||||
replyEl.removeClass('none');
|
||||
} else {
|
||||
if (isDeleted) {
|
||||
quoteEl.addClass('none');
|
||||
favEl.addClass('none');
|
||||
replyEl.addClass('none');
|
||||
chatEl.addClass('none');
|
||||
} else {
|
||||
quoteEl.removeClass('none');
|
||||
favEl.removeClass('none');
|
||||
replyEl.removeClass('none');
|
||||
chatEl.removeClass('none');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1112,7 +1097,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
|
||||
var insertAfter = findInsertionPoint();
|
||||
|
||||
parseAndTranslatePosts(data.posts, function(translatedHTML) {
|
||||
parseAndTranslatePosts(data, function(translatedHTML) {
|
||||
var translated = $(translatedHTML);
|
||||
|
||||
if(!infiniteLoaded) {
|
||||
@@ -1127,8 +1112,8 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
});
|
||||
}
|
||||
|
||||
function parseAndTranslatePosts(posts, callback) {
|
||||
var html = templates.prepare(templates['topic'].blocks['posts']).parse({posts: posts});
|
||||
function parseAndTranslatePosts(data, callback) {
|
||||
var html = templates.prepare(templates['topic'].blocks['posts']).parse(data);
|
||||
var regexp = new RegExp("<!--[\\s]*IF @first[\\s]*-->([\\s\\S]*?)<!--[\\s]*ENDIF @first[\\s]*-->", 'g');
|
||||
html = html.replace(regexp, '');
|
||||
|
||||
|
||||
@@ -1,53 +1,15 @@
|
||||
define(function() {
|
||||
define(['forum/recent'], function(recent) {
|
||||
var Unread = {},
|
||||
loadingMoreTopics = false;
|
||||
|
||||
Unread.init = function() {
|
||||
app.enterRoom('recent_posts');
|
||||
|
||||
ajaxify.register_events([
|
||||
'event:new_topic',
|
||||
'event:new_post',
|
||||
'topics.markAllRead'
|
||||
]);
|
||||
|
||||
var newTopicCount = 0,
|
||||
newPostCount = 0;
|
||||
|
||||
$('#new-topics-alert').on('click', function() {
|
||||
$(this).addClass('hide');
|
||||
});
|
||||
|
||||
socket.on('event:new_topic', function(data) {
|
||||
++newTopicCount;
|
||||
updateAlertText();
|
||||
});
|
||||
|
||||
function updateAlertText() {
|
||||
var text = 'There';
|
||||
|
||||
if (newTopicCount > 1) {
|
||||
text += ' are ' + newTopicCount + ' new topics';
|
||||
} else if (newTopicCount === 1) {
|
||||
text += ' is a new topic';
|
||||
}
|
||||
|
||||
if (newPostCount > 1) {
|
||||
text += (newTopicCount?' and ':' are ') + newPostCount + ' new posts';
|
||||
} else if(newPostCount === 1) {
|
||||
text += (newTopicCount?' and ':' is ') + ' a new post';
|
||||
}
|
||||
|
||||
text += '. Click here to reload.';
|
||||
|
||||
$('#new-topics-alert').html(text).removeClass('hide').fadeIn('slow');
|
||||
$('#category-no-topics').addClass('hidden');
|
||||
}
|
||||
|
||||
socket.on('event:new_post', function(data) {
|
||||
++newPostCount;
|
||||
updateAlertText();
|
||||
});
|
||||
recent.watchForNewPosts();
|
||||
|
||||
$('#mark-allread-btn').on('click', function() {
|
||||
var btn = $(this);
|
||||
@@ -67,54 +29,6 @@ define(function() {
|
||||
});
|
||||
});
|
||||
|
||||
function onTopicsLoaded(topics) {
|
||||
|
||||
var html = templates.prepare(templates['unread'].blocks['topics']).parse({
|
||||
topics: topics
|
||||
});
|
||||
|
||||
translator.translate(html, function(translatedHTML) {
|
||||
var container = $('#topics-container');
|
||||
|
||||
$('#category-no-topics').remove();
|
||||
|
||||
html = $(translatedHTML);
|
||||
container.append(html);
|
||||
$('span.timeago').timeago();
|
||||
app.createUserTooltips();
|
||||
app.makeNumbersHumanReadable(html.find('.human-readable-number'));
|
||||
});
|
||||
}
|
||||
|
||||
function loadMoreTopics() {
|
||||
loadingMoreTopics = true;
|
||||
socket.emit('topics.loadMoreUnreadTopics', {
|
||||
after: parseInt($('#topics-container').attr('data-next-start'), 10)
|
||||
}, function(err, data) {
|
||||
if(err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
|
||||
if (data.topics && data.topics.length) {
|
||||
onTopicsLoaded(data.topics);
|
||||
$('#topics-container').attr('data-next-start', data.nextStart);
|
||||
} else {
|
||||
$('#load-more-btn').hide();
|
||||
}
|
||||
|
||||
loadingMoreTopics = false;
|
||||
});
|
||||
}
|
||||
|
||||
$(window).off('scroll').on('scroll', function() {
|
||||
var bottom = ($(document).height() - $(window).height()) * 0.9;
|
||||
|
||||
if ($(window).scrollTop() > bottom && !loadingMoreTopics) {
|
||||
loadMoreTopics();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if ($("body").height() <= $(window).height() && $('#topics-container').children().length >= 20) {
|
||||
$('#load-more-btn').show();
|
||||
}
|
||||
@@ -122,6 +36,32 @@ define(function() {
|
||||
$('#load-more-btn').on('click', function() {
|
||||
loadMoreTopics();
|
||||
});
|
||||
|
||||
app.enableInfiniteLoading(function() {
|
||||
if(!loadingMoreTopics) {
|
||||
loadMoreTopics();
|
||||
}
|
||||
});
|
||||
|
||||
function loadMoreTopics() {
|
||||
loadingMoreTopics = true;
|
||||
socket.emit('topics.loadMoreUnreadTopics', {
|
||||
after: $('#topics-container').attr('data-nextstart')
|
||||
}, function(err, data) {
|
||||
if(err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
|
||||
if (data.topics && data.topics.length) {
|
||||
recent.onTopicsLoaded('unread', data.topics);
|
||||
$('#topics-container').attr('data-nextstart', data.nextStart);
|
||||
} else {
|
||||
$('#load-more-btn').hide();
|
||||
}
|
||||
|
||||
loadingMoreTopics = false;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return Unread;
|
||||
|
||||
@@ -106,6 +106,7 @@
|
||||
collapseWhitespace : /\s+/g,
|
||||
collapseDash : /-+/g,
|
||||
trimTrailingDash : /-$/g,
|
||||
trimLeadingDash : /^-/g,
|
||||
isLatin : /^[\w]+$/,
|
||||
|
||||
//http://dense13.com/blog/2009/05/03/converting-string-to-slug-javascript/
|
||||
@@ -120,6 +121,7 @@
|
||||
str = str.replace(utils.collapseWhitespace, '-')
|
||||
str = str.replace(utils.collapseDash, '-');
|
||||
str = str.replace(utils.trimTrailingDash, '');
|
||||
str = str.replace(utils.trimLeadingDash, '');
|
||||
return str;
|
||||
},
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
<div class="category row">
|
||||
<div class="{topic_row_size}">
|
||||
<ul id="topics-container" itemscope itemtype="http://www.schema.org/ItemList">
|
||||
<ul id="topics-container" itemscope itemtype="http://www.schema.org/ItemList" data-nextstart="{nextStart}">
|
||||
<meta itemprop="itemListOrder" content="descending">
|
||||
<!-- BEGIN topics -->
|
||||
<li class="category-item {topics.deleted-class}" itemprop="itemListElement">
|
||||
|
||||
@@ -41,7 +41,10 @@
|
||||
<div class="form-group">
|
||||
<div class="col-lg-offset-2 col-lg-10">
|
||||
<hr />
|
||||
<button class="btn btn-primary btn-lg btn-block" id="login" type="submit">[[login:login]]</button> <a id="reset-link" class="hide" href="{relative_path}/reset">[[login:forgot_password]]</a>
|
||||
<button class="btn btn-primary btn-lg btn-block" id="login" type="submit">[[login:login]]</button>
|
||||
<!-- IF showResetLink -->
|
||||
<a id="reset-link" href="{relative_path}/reset">[[login:forgot_password]]</a>
|
||||
<!-- ENDIF showResetLink -->
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="_csrf" value="{token}" id="csrf-token" />
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
<div class="category row">
|
||||
<div class="col-md-12">
|
||||
<ul id="topics-container">
|
||||
<ul id="topics-container" data-nextstart="{nextStart}">
|
||||
<!-- BEGIN topics -->
|
||||
<li class="category-item {topics.deleted-class}">
|
||||
<div class="col-md-12 col-xs-12 panel panel-default topic-row">
|
||||
|
||||
@@ -13,56 +13,86 @@
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="category search">
|
||||
<div class="{show_results}">
|
||||
<h3>[[topic:topics]]</h3>
|
||||
<div class="search favourites well">
|
||||
<div class="{show_results} row">
|
||||
|
||||
<!-- IF topic_matches -->
|
||||
<small>{topic_matches} result(s) matching "{search_query}"</small>
|
||||
<!-- ENDIF topic_matches -->
|
||||
<div class="alert alert-info {show_no_topics}">[[topic:no_topics_found]]</div>
|
||||
<div id="topic-results" class="col-md-12" data-search-query="{search_query}">
|
||||
|
||||
<ul id="topics-container" data-search-query="{search_query}">
|
||||
<h3>[[topic:topics]]</h3>
|
||||
|
||||
<!-- IF topic_matches -->
|
||||
<small>{topic_matches} result(s) matching "{search_query}"</small>
|
||||
<!-- ENDIF topic_matches -->
|
||||
<div class="alert alert-info {show_no_topics}">[[topic:no_topics_found]]</div>
|
||||
|
||||
<!-- BEGIN topics -->
|
||||
<li class="category-item">
|
||||
<a href="{relative_path}/topic/{topics.slug}" id="tid-{topics.tid}">
|
||||
<div>
|
||||
<div class="col-md-12 img-thumbnail">
|
||||
<div class="search-result-post">
|
||||
<img src="{topics.teaser_userpicture}" />
|
||||
<strong>{topics.teaser_username}</strong>: <span class="search-result-text">{topics.title}</span>
|
||||
</div>
|
||||
<div class="topic-row panel panel-default clearfix">
|
||||
<div class="panel-body">
|
||||
<a href="../../user/{topics.userslug}">
|
||||
<img title="{topics.username}" class="img-rounded user-img" src="{topics.picture}">
|
||||
</a>
|
||||
|
||||
</div>
|
||||
<a href="../../user/{topics.userslug}">
|
||||
<strong><span>{topics.username}</span></strong>
|
||||
</a>
|
||||
<span class="search-result-text">
|
||||
<p>{topics.title}</p>
|
||||
</span>
|
||||
|
||||
<div>
|
||||
<small>
|
||||
<span class="pull-right">
|
||||
<a href="../../topic/{topics.slug}">posted</a>
|
||||
in
|
||||
<a href="../../category/{topics.categorySlug}">
|
||||
<i class="fa {topics.categoryIcon}"></i> {topics.categoryName}
|
||||
</a>
|
||||
<span class="timeago" title="{topics.relativeTime}"></span>
|
||||
</span>
|
||||
</small>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</div>
|
||||
</div>
|
||||
<!-- END topics -->
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h3>Posts</h3>
|
||||
<!-- IF post_matches -->
|
||||
<small>{post_matches} result(s) matching "{search_query}"</small>
|
||||
<!-- ENDIF post_matches -->
|
||||
<div class="alert alert-info {show_no_posts}">No posts found!</div>
|
||||
<div id="post-results" class="col-md-12" data-search-query="{search_query}">
|
||||
<h3>Posts</h3>
|
||||
|
||||
<!-- IF post_matches -->
|
||||
<small>{post_matches} result(s) matching "{search_query}"</small>
|
||||
<!-- ENDIF post_matches -->
|
||||
<div class="alert alert-info {show_no_posts}">No posts found!</div>
|
||||
|
||||
<ul id="topics-container" data-search-query="{search_query}">
|
||||
<!-- BEGIN posts -->
|
||||
<li class="category-item">
|
||||
<a href="{relative_path}/topic/{posts.topicSlug}#{posts.pid}" id="tid-{posts.tid}">
|
||||
<div>
|
||||
<div class="col-md-12 img-thumbnail">
|
||||
<div class="search-result-post">
|
||||
<img src="{posts.picture}" />
|
||||
<strong>{posts.username}</strong>: <span class="search-result-text">{posts.content}</span>
|
||||
</div>
|
||||
<div class="topic-row panel panel-default clearfix">
|
||||
<div class="panel-body">
|
||||
<a href="../../user/{posts.userslug}">
|
||||
<img title="{posts.username}" class="img-rounded user-img" src="{posts.picture}">
|
||||
</a>
|
||||
|
||||
</div>
|
||||
<a href="../../user/{posts.userslug}">
|
||||
<strong><span>{posts.username}</span></strong>
|
||||
</a>
|
||||
<span class="search-result-text">
|
||||
{posts.content}
|
||||
</span>
|
||||
|
||||
<div>
|
||||
<small>
|
||||
<span class="pull-right">
|
||||
<a href="../../topic/{posts.topicSlug}#{posts.pid}">posted</a>
|
||||
in
|
||||
<a href="../../category/{posts.categorySlug}">
|
||||
<i class="fa {posts.categoryIcon}"></i> {posts.categoryName}
|
||||
</a>
|
||||
<span class="timeago" title="{posts.relativeTime}"></span>
|
||||
</span>
|
||||
</small>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</div>
|
||||
</div>
|
||||
<!-- END posts -->
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -186,7 +186,7 @@
|
||||
<!-- IF privileges.write -->
|
||||
<button class="btn btn-primary post_reply" type="button">[[topic:reply]]</button>
|
||||
<!-- ENDIF privileges.write -->
|
||||
<div class="btn-group thread-tools hide">
|
||||
<div class="btn-group thread-tools hide dropup">
|
||||
<button class="btn btn-default dropdown-toggle" data-toggle="dropdown" type="button">[[topic:thread_tools.title]] <span class="caret"></span></button>
|
||||
<ul class="dropdown-menu pull-right">
|
||||
<li><a href="#" class="markAsUnreadForAll"><i class="fa fa-inbox"></i> [[topic:thread_tools.markAsUnreadForAll]]</a></li>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
<div class="category row">
|
||||
<div class="col-md-12">
|
||||
<ul id="topics-container" data-next-start="{nextStart}">
|
||||
<ul id="topics-container" data-nextstart="{nextStart}">
|
||||
<!-- BEGIN topics -->
|
||||
<li class="category-item {topics.deleted-class}">
|
||||
<div class="col-md-12 col-xs-12 panel panel-default topic-row">
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
var db = require('./database.js'),
|
||||
posts = require('./posts.js'),
|
||||
utils = require('./../public/src/utils.js'),
|
||||
user = require('./user.js'),
|
||||
topics = require('./topics.js'),
|
||||
var db = require('./database'),
|
||||
posts = require('./posts'),
|
||||
utils = require('./../public/src/utils'),
|
||||
user = require('./user'),
|
||||
topics = require('./topics'),
|
||||
plugins = require('./plugins'),
|
||||
CategoryTools = require('./categoryTools'),
|
||||
meta = require('./meta'),
|
||||
@@ -52,8 +52,8 @@ var db = require('./database.js'),
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
function getTopicIds(next) {
|
||||
Categories.getTopicIds(category_id, start, end, next);
|
||||
function getTopics(next) {
|
||||
Categories.getCategoryTopics(category_id, start, end, current_user, next);
|
||||
}
|
||||
|
||||
function getActiveUsers(next) {
|
||||
@@ -70,9 +70,12 @@ var db = require('./database.js'),
|
||||
Categories.getPageCount(category_id, next);
|
||||
}
|
||||
|
||||
async.parallel([getTopicIds, getActiveUsers, getSidebars, getPageCount], function(err, results) {
|
||||
var tids = results[0],
|
||||
active_users = results[1],
|
||||
async.parallel([getTopics, getActiveUsers, getSidebars, getPageCount], function(err, results) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
var active_users = results[1],
|
||||
sidebars = results[2],
|
||||
pageCount = results[3];
|
||||
|
||||
@@ -87,27 +90,22 @@ var db = require('./database.js'),
|
||||
'topic_row_size': 'col-md-9',
|
||||
'category_id': category_id,
|
||||
'active_users': [],
|
||||
'topics': [],
|
||||
'topics': results[0].topics,
|
||||
'nextStart': results[0].nextStart,
|
||||
'pageCount': pageCount,
|
||||
'disableSocialButtons': meta.config.disableSocialButtons !== undefined ? parseInt(meta.config.disableSocialButtons, 10) !== 0 : false,
|
||||
'sidebars': sidebars
|
||||
};
|
||||
|
||||
function getTopics(next) {
|
||||
topics.getTopicsByTids(tids, category_id, current_user, next);
|
||||
}
|
||||
|
||||
function getModerators(next) {
|
||||
Categories.getModerators(category_id, next);
|
||||
}
|
||||
|
||||
function getActiveUsers(next) {
|
||||
user.getMultipleUserFields(active_users, ['uid', 'username', 'userslug', 'picture'], function(err, users) {
|
||||
next(err, users);
|
||||
});
|
||||
user.getMultipleUserFields(active_users, ['uid', 'username', 'userslug', 'picture'], next);
|
||||
}
|
||||
|
||||
if (tids.length === 0) {
|
||||
if (!category.topics.length) {
|
||||
getModerators(function(err, moderators) {
|
||||
category.moderator_block_class = moderators.length > 0 ? '' : 'none';
|
||||
category.moderators = moderators;
|
||||
@@ -116,11 +114,10 @@ var db = require('./database.js'),
|
||||
callback(null, category);
|
||||
});
|
||||
} else {
|
||||
async.parallel([getTopics, getModerators, getActiveUsers], function(err, results) {
|
||||
category.topics = results[0];
|
||||
category.moderator_block_class = results[1].length > 0 ? '' : 'none';
|
||||
category.moderators = results[1];
|
||||
category.active_users = results[2];
|
||||
async.parallel([getModerators, getActiveUsers], function(err, results) {
|
||||
category.moderator_block_class = results[0].length > 0 ? '' : 'none';
|
||||
category.moderators = results[0];
|
||||
category.active_users = results[1];
|
||||
category.show_sidebar = category.topics.length > 0 ? 'show' : 'hidden';
|
||||
callback(null, category);
|
||||
});
|
||||
@@ -131,13 +128,26 @@ var db = require('./database.js'),
|
||||
};
|
||||
|
||||
Categories.getCategoryTopics = function(cid, start, stop, uid, callback) {
|
||||
Categories.getTopicIds(cid, start, stop, function(err, tids) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
Categories.getTopicIds(cid, start, stop, next);
|
||||
},
|
||||
function(tids, next) {
|
||||
topics.getTopicsByTids(tids, cid, uid, next);
|
||||
},
|
||||
function(topics, next) {
|
||||
db.sortedSetRevRank('categories:' + cid + ':tid', topics[topics.length - 1].tid, function(err, rank) {
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
topics.getTopicsByTids(tids, cid, uid, callback);
|
||||
});
|
||||
return next(null, {
|
||||
topics: topics,
|
||||
nextStart: parseInt(rank, 10) + 1
|
||||
});
|
||||
});
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
|
||||
Categories.getTopicIds = function(cid, start, stop, callback) {
|
||||
|
||||
@@ -656,6 +656,23 @@
|
||||
});
|
||||
}
|
||||
|
||||
module.sortedSetRevRank = function(key, value, callback) {
|
||||
if(value !== null && value !== undefined) {
|
||||
value = value.toString();
|
||||
}
|
||||
module.getSortedSetRange(key, 0, -1, function(err, result) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
var rank = result.indexOf(value);
|
||||
if(rank === -1) {
|
||||
return callback(null, null);
|
||||
}
|
||||
|
||||
callback(null, result.length - rank - 1);
|
||||
});
|
||||
}
|
||||
|
||||
module.sortedSetScore = function(key, value, callback) {
|
||||
if(value !== null && value !== undefined) {
|
||||
value = value.toString();
|
||||
|
||||
@@ -382,6 +382,10 @@
|
||||
redisClient.zrank(key, value, callback);
|
||||
}
|
||||
|
||||
module.sortedSetRevRank = function(key, value, callback) {
|
||||
redisClient.zrevrank(key, value, callback);
|
||||
}
|
||||
|
||||
module.sortedSetScore = function(key, value, callback) {
|
||||
redisClient.zscore(key, value, callback);
|
||||
}
|
||||
|
||||
10
src/feed.js
10
src/feed.js
@@ -38,13 +38,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
var description = topicData.posts.length ? topicData.posts[0].content : '';
|
||||
var image_url = topicData.posts.length ? topicData.posts[0].picture : '';
|
||||
var author = topicData.posts.length ? topicData.posts[0].username : '';
|
||||
|
||||
var feed = new rss({
|
||||
title: topicData.topic_name,
|
||||
description: topicData.posts[0].content,
|
||||
description: description,
|
||||
feed_url: Feed.defaults.baseUrl + '/topics/' + tid + '.rss',
|
||||
site_url: nconf.get('url') + '/topic/' + topicData.slug,
|
||||
image_url: topicData.posts[0].picture,
|
||||
author: topicData.posts[0].username,
|
||||
image_url: image_url,
|
||||
author: author,
|
||||
ttl: Feed.defaults.ttl
|
||||
}),
|
||||
dateStamp;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var user = require('./user'),
|
||||
bcrypt = require('bcrypt'),
|
||||
bcrypt = require('bcryptjs'),
|
||||
db = require('./database'),
|
||||
path = require('path'),
|
||||
winston = require('winston'),
|
||||
|
||||
@@ -56,13 +56,16 @@ var db = require('./database'),
|
||||
|
||||
var messages = [];
|
||||
|
||||
userData[0].uid = touid;
|
||||
userData[1].uid = fromuid;
|
||||
|
||||
function getMessage(mid, next) {
|
||||
db.getObject('message:' + mid, function(err, message) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
Messaging.parse(message.content, message.fromuid, fromuid, userData[1], userData[0], function(result) {
|
||||
Messaging.parse(message.content, message.fromuid, fromuid, userData[1], userData[0], false, function(result) {
|
||||
message.content = result;
|
||||
messages.push(message);
|
||||
next(null);
|
||||
@@ -81,7 +84,7 @@ var db = require('./database'),
|
||||
});
|
||||
};
|
||||
|
||||
Messaging.parse = function (message, fromuid, myuid, toUserData, myUserData, callback) {
|
||||
Messaging.parse = function (message, fromuid, myuid, toUserData, myUserData, isNew, callback) {
|
||||
plugins.fireHook('filter:post.parse', message, function(err, parsed) {
|
||||
if (err) {
|
||||
return callback(message);
|
||||
@@ -97,7 +100,20 @@ var db = require('./database'),
|
||||
username = '<span class="chat-user"> ' + toUserData.username + '</span>: ';
|
||||
}
|
||||
|
||||
callback(picture + username + parsed);
|
||||
var messageData = {
|
||||
message: message,
|
||||
parsed: parsed,
|
||||
fromuid: fromuid,
|
||||
myuid: myuid,
|
||||
toUserData: toUserData,
|
||||
myUserData: myUserData,
|
||||
isNew: isNew,
|
||||
parsedMessage: picture + username + parsed
|
||||
};
|
||||
|
||||
plugins.fireHook('filter:messaging.parse', messageData, function(err, messageData) {
|
||||
callback(messageData.parsedMessage);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -202,6 +202,10 @@ var fs = require('fs'),
|
||||
} else return;
|
||||
};
|
||||
|
||||
Plugins.hasListeners = function(hook) {
|
||||
return (Plugins.loadedHooks[hook] && Plugins.loadedHooks[hook].length > 0);
|
||||
};
|
||||
|
||||
Plugins.fireHook = function(hook, args, callback) {
|
||||
hookList = Plugins.loadedHooks[hook];
|
||||
|
||||
|
||||
@@ -11,10 +11,11 @@ var path = require('path'),
|
||||
posts = require('../posts'),
|
||||
categories = require('../categories'),
|
||||
categoryTools = require('../categoryTools')
|
||||
meta = require('../meta'),
|
||||
Plugins = require('../plugins'),
|
||||
utils = require('../../public/src/utils'),
|
||||
translator = require('../../public/src/translator'),
|
||||
pkg = require('../../package.json'),
|
||||
meta = require('../meta');
|
||||
pkg = require('../../package.json');
|
||||
|
||||
|
||||
(function (Api) {
|
||||
@@ -46,7 +47,6 @@ var path = require('path'),
|
||||
config.topicsPerPage = meta.config.topicsPerPage || 20;
|
||||
config.postsPerPage = meta.config.postsPerPage || 20;
|
||||
config.maximumFileSize = meta.config.maximumFileSize;
|
||||
config.emailSetup = !!meta.config['email:from'];
|
||||
config.defaultLang = meta.config.defaultLang || 'en';
|
||||
|
||||
res.json(200, config);
|
||||
@@ -116,7 +116,8 @@ var path = require('path'),
|
||||
app.get('/login', function (req, res) {
|
||||
var data = {},
|
||||
login_strategies = auth.get_login_strategies(),
|
||||
num_strategies = login_strategies.length;
|
||||
num_strategies = login_strategies.length,
|
||||
emailersPresent = Plugins.hasListeners('action:email.send');
|
||||
|
||||
if (num_strategies == 0) {
|
||||
data = {
|
||||
@@ -131,8 +132,8 @@ var path = require('path'),
|
||||
}
|
||||
|
||||
data.authentication = login_strategies;
|
||||
|
||||
data.token = res.locals.csrf_token;
|
||||
data.showResetLink = emailersPresent;
|
||||
|
||||
res.json(data);
|
||||
});
|
||||
|
||||
@@ -75,12 +75,12 @@ var DebugRoute = function(app) {
|
||||
|
||||
app.get('/test', function(req, res) {
|
||||
|
||||
/*topics.getTopicPosts2(2, 0, 10, 5, function(err, data) {
|
||||
res.json(data);
|
||||
})*/
|
||||
topics.getTopicWithPosts(2, 1, 0, -1, true, function (err, topicData) {
|
||||
res.json(topicData);
|
||||
var db = require('./../database');
|
||||
|
||||
db.getSortedSetRevRange('topics:recent', 0 , -1, function(err, tids) {
|
||||
res.json(tids);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -18,14 +18,10 @@ SocketCategories.loadMore = function(socket, data, callback) {
|
||||
|
||||
var topicsPerPage = parseInt(meta.config.topicsPerPage, 10) || 20;
|
||||
|
||||
var start = data.after,
|
||||
var start = parseInt(data.after, 10),
|
||||
end = start + topicsPerPage - 1;
|
||||
|
||||
categories.getCategoryTopics(data.cid, start, end, socket.uid, function(err, topics) {
|
||||
callback(err, {
|
||||
topics: topics
|
||||
});
|
||||
});
|
||||
categories.getCategoryTopics(data.cid, start, end, socket.uid, callback);
|
||||
};
|
||||
|
||||
SocketCategories.getPageCount = function(socket, cid, callback) {
|
||||
|
||||
@@ -22,12 +22,11 @@ var SocketIO = require('socket.io'),
|
||||
|
||||
/* === */
|
||||
|
||||
var users = {},
|
||||
io;
|
||||
|
||||
var io;
|
||||
|
||||
|
||||
Sockets.userSockets = {};
|
||||
Sockets.rooms = {};
|
||||
|
||||
|
||||
Sockets.init = function(server) {
|
||||
@@ -59,9 +58,9 @@ Sockets.init = function(server) {
|
||||
sessionID = socket.handshake.signedCookies["express.sid"];
|
||||
db.sessionStore.get(sessionID, function(err, sessionData) {
|
||||
if (!err && sessionData && sessionData.passport && sessionData.passport.user) {
|
||||
uid = users[sessionID] = sessionData.passport.user;
|
||||
uid = sessionData.passport.user;
|
||||
} else {
|
||||
uid = users[sessionID] = 0;
|
||||
uid = 0;
|
||||
}
|
||||
|
||||
socket.uid = parseInt(uid, 10);
|
||||
@@ -110,8 +109,8 @@ Sockets.init = function(server) {
|
||||
}
|
||||
|
||||
if (Sockets.userSockets[uid] && Sockets.userSockets[uid].length === 0) {
|
||||
delete users[sessionID];
|
||||
delete Sockets.userSockets[uid];
|
||||
|
||||
if (uid) {
|
||||
db.sortedSetRemove('users:online', uid, function(err, data) {
|
||||
});
|
||||
@@ -126,17 +125,10 @@ Sockets.init = function(server) {
|
||||
|
||||
emitOnlineUserCount();
|
||||
|
||||
for (var roomName in Sockets.rooms) {
|
||||
if (Sockets.rooms.hasOwnProperty(roomName)) {
|
||||
socket.leave(roomName);
|
||||
|
||||
if (Sockets.rooms[roomName][socket.id]) {
|
||||
delete Sockets.rooms[roomName][socket.id];
|
||||
}
|
||||
|
||||
updateRoomBrowsingText(roomName);
|
||||
}
|
||||
for(var roomName in io.sockets.manager.roomClients[socket.id]) {
|
||||
updateRoomBrowsingText(roomName.slice(1));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
socket.on('*', function(payload, callback) {
|
||||
@@ -222,9 +214,10 @@ function updateRoomBrowsingText(roomName) {
|
||||
|
||||
function getUidsInRoom(room) {
|
||||
var uids = [];
|
||||
for (var socketId in room) {
|
||||
if (uids.indexOf(room[socketId]) === -1) {
|
||||
uids.push(room[socketId]);
|
||||
var clients = io.sockets.clients(roomName);
|
||||
for(var i=0; i<clients.length; ++i) {
|
||||
if (uids.indexOf(clients[i].uid) === -1 && clients[i].uid !== 0) {
|
||||
uids.push(clients[i].uid);
|
||||
}
|
||||
}
|
||||
return uids;
|
||||
@@ -235,15 +228,14 @@ function updateRoomBrowsingText(roomName) {
|
||||
var anonCount = 0;
|
||||
|
||||
for (var i = 0; i < clients.length; ++i) {
|
||||
var hs = clients[i].handshake;
|
||||
if (hs && clients[i].state && clients[i].state.user.uid === 0) {
|
||||
if(clients[i].uid === 0) {
|
||||
++anonCount;
|
||||
}
|
||||
}
|
||||
return anonCount;
|
||||
}
|
||||
|
||||
var uids = getUidsInRoom(Sockets.rooms[roomName]),
|
||||
var uids = getUidsInRoom(roomName),
|
||||
anonymousCount = getAnonymousCount(roomName);
|
||||
|
||||
user.getMultipleUserFields(uids, ['uid', 'username', 'userslug', 'picture'], function(err, users) {
|
||||
|
||||
@@ -84,18 +84,6 @@ SocketMeta.rooms.enter = function(socket, data) {
|
||||
}
|
||||
|
||||
socket.join(data.enter);
|
||||
server.rooms[data.enter] = server.rooms[data.enter] || {};
|
||||
|
||||
if (socket.uid) {
|
||||
server.rooms[data.enter][socket.id] = socket.uid;
|
||||
|
||||
if (data.leave && server.rooms[data.leave] && server.rooms[data.leave][socket.id] && data.enter !== data.leave) {
|
||||
delete server.rooms[data.leave][socket.id];
|
||||
if(!Object.keys(server.rooms[data.leave]).length) {
|
||||
delete server.rooms[data.leave];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data.leave) {
|
||||
module.parent.exports.updateRoomBrowsingText(data.leave);
|
||||
@@ -104,12 +92,12 @@ SocketMeta.rooms.enter = function(socket, data) {
|
||||
module.parent.exports.updateRoomBrowsingText(data.enter);
|
||||
|
||||
if (data.enter != 'admin') {
|
||||
server.in('admin').emit('event:meta.rooms.update', null, server.rooms);
|
||||
server.in('admin').emit('event:meta.rooms.update', null, server.server.sockets.manager.rooms);
|
||||
}
|
||||
};
|
||||
|
||||
SocketMeta.rooms.getAll = function(socket, data, callback) {
|
||||
callback(null, server.rooms);
|
||||
callback(null, server.server.sockets.manager.rooms);
|
||||
};
|
||||
|
||||
/* Exports */
|
||||
|
||||
@@ -109,7 +109,11 @@ SocketModules.chats.send = function(socket, data) {
|
||||
});
|
||||
});
|
||||
}
|
||||
Messaging.parse(msg, socket.uid, socket.uid, usersData[1], usersData[0], function(parsed) {
|
||||
|
||||
usersData[0].uid = socket.uid;
|
||||
usersData[1].uid = touid;
|
||||
|
||||
Messaging.parse(msg, socket.uid, socket.uid, usersData[1], usersData[0], true, function(parsed) {
|
||||
Messaging.addMessage(socket.uid, touid, msg, function(err, message) {
|
||||
var numSockets = 0,
|
||||
x;
|
||||
|
||||
@@ -93,7 +93,17 @@ SocketPosts.uploadFile = function(socket, data, callback) {
|
||||
};
|
||||
|
||||
SocketPosts.getRawPost = function(socket, pid, callback) {
|
||||
posts.getPostField(pid, 'content', callback);
|
||||
posts.getPostFields(pid, ['content', 'deleted'], function(err, data) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
if(data.deleted === '1') {
|
||||
return callback(new Error('This post no longer exists'));
|
||||
}
|
||||
|
||||
callback(null, data.content);
|
||||
});
|
||||
};
|
||||
|
||||
SocketPosts.edit = function(socket, data, callback) {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
var topics = require('../topics'),
|
||||
threadTools = require('../threadTools'),
|
||||
index = require('./index'),
|
||||
|
||||
async = require('async'),
|
||||
|
||||
SocketTopics = {};
|
||||
|
||||
SocketTopics.post = function(socket, data, callback) {
|
||||
@@ -233,15 +236,18 @@ SocketTopics.loadMore = function(socket, data, callback) {
|
||||
var postsPerPage = parseInt(meta.config.postsPerPage, 10);
|
||||
postsPerPage = postsPerPage ? postsPerPage : 20;
|
||||
|
||||
var start = data.after,
|
||||
var start = parseInt(data.after, 10),
|
||||
end = start + postsPerPage - 1;
|
||||
|
||||
topics.getTopicPosts(data.tid, start, end, socket.uid, function(err, posts) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
async.parallel({
|
||||
posts: function(next) {
|
||||
topics.getTopicPosts(data.tid, start, end, socket.uid, next);
|
||||
},
|
||||
privileges: function(next) {
|
||||
threadTools.privileges(data.tid, socket.uid, next);
|
||||
}
|
||||
|
||||
callback(err, {posts: posts});
|
||||
}, function(err, results) {
|
||||
callback(err, results);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -250,14 +256,14 @@ SocketTopics.loadMoreRecentTopics = function(socket, data, callback) {
|
||||
return callback(new Error('invalid data'));
|
||||
}
|
||||
|
||||
var start = data.after,
|
||||
var start = parseInt(data.after, 10),
|
||||
end = start + 9;
|
||||
|
||||
topics.getLatestTopics(socket.uid, start, end, data.term, callback);
|
||||
};
|
||||
|
||||
SocketTopics.loadMoreUnreadTopics = function(socket, data, callback) {
|
||||
var start = data.after,
|
||||
var start = parseInt(data.after, 10),
|
||||
end = start + 9;
|
||||
|
||||
topics.getUnreadTopics(socket.uid, start, end, callback);
|
||||
|
||||
@@ -187,9 +187,20 @@ var winston = require('winston'),
|
||||
|
||||
ThreadTools.move = function(tid, cid, callback) {
|
||||
topics.getTopicFields(tid, ['cid', 'lastposttime'], function(err, topicData) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
var oldCid = topicData.cid;
|
||||
if(!oldCid) {
|
||||
return callback(new Error('invalid-topic'));
|
||||
}
|
||||
|
||||
db.sortedSetRemove('categories:' + oldCid + ':tid', tid, function(err, result) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
db.sortedSetAdd('categories:' + cid + ':tid', topicData.lastposttime, tid, function(err, result) {
|
||||
|
||||
if(err) {
|
||||
|
||||
@@ -426,8 +426,9 @@ var async = require('async'),
|
||||
};
|
||||
|
||||
var since = terms['day'];
|
||||
if(terms[term])
|
||||
if(terms[term]) {
|
||||
since = terms[term];
|
||||
}
|
||||
|
||||
var args = ['topics:recent', '+inf', timestamp - since, 'LIMIT', start, end - start + 1];
|
||||
db.getSortedSetRevRangeByScore(args, function(err, tids) {
|
||||
@@ -442,23 +443,29 @@ var async = require('async'),
|
||||
|
||||
if (!tids || !tids.length) {
|
||||
latestTopics.no_topics_message = 'show';
|
||||
callback(err, latestTopics);
|
||||
return;
|
||||
return callback(null, latestTopics);
|
||||
}
|
||||
|
||||
// Filter out topics that belong to categories that this user cannot access
|
||||
async.filter(tids, function(tid, next) {
|
||||
threadTools.privileges(tid, current_user, function(err, privileges) {
|
||||
if (!err && privileges.read) {
|
||||
next(true);
|
||||
} else {
|
||||
next(false);
|
||||
}
|
||||
next(!err && privileges.read);
|
||||
});
|
||||
}, function(tids) {
|
||||
Topics.getTopicsByTids(tids, 0, current_user, function(err, topicData) {
|
||||
latestTopics.topics = topicData;
|
||||
callback(err, latestTopics);
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
if(!topicData || !topicData.length) {
|
||||
latestTopics.no_topics_message = 'show';
|
||||
return callback(null, latestTopics);
|
||||
}
|
||||
|
||||
db.sortedSetRevRank('topics:recent', topicData[topicData.length - 1].tid, function(err, rank) {
|
||||
latestTopics.nextStart = parseInt(rank,10) + 1;
|
||||
latestTopics.topics = topicData;
|
||||
callback(null, latestTopics);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -538,7 +545,7 @@ var async = require('async'),
|
||||
return parseInt(read[index], 10) === 0;
|
||||
});
|
||||
|
||||
// Filter out topics that belong to categories that this user cannot access
|
||||
|
||||
async.filter(newtids, function(tid, next) {
|
||||
threadTools.privileges(tid, uid, function(err, privileges) {
|
||||
if (!err && privileges.read) {
|
||||
@@ -588,16 +595,23 @@ var async = require('async'),
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
unreadTopics.topics = topicData;
|
||||
unreadTopics.nextStart = stop + 1;
|
||||
if (!topicData || topicData.length === 0) {
|
||||
unreadTopics.no_topics_message = 'show';
|
||||
}
|
||||
if (uid === 0 || topicData.length === 0) {
|
||||
unreadTopics.show_markallread_button = 'hidden';
|
||||
}
|
||||
db.sortedSetRevRank('topics:recent', topicData[topicData.length - 1].tid, function(err, rank) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
callback(null, unreadTopics);
|
||||
unreadTopics.topics = topicData;
|
||||
unreadTopics.nextStart = parseInt(rank, 10) + 1;
|
||||
|
||||
if (!topicData || topicData.length === 0) {
|
||||
unreadTopics.no_topics_message = 'show';
|
||||
}
|
||||
if (uid === 0 || topicData.length === 0) {
|
||||
unreadTopics.show_markallread_button = 'hidden';
|
||||
}
|
||||
|
||||
callback(null, unreadTopics);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -700,6 +714,7 @@ var async = require('async'),
|
||||
|
||||
function isTopicVisible(topicData, topicInfo) {
|
||||
var deleted = parseInt(topicData.deleted, 10) !== 0;
|
||||
|
||||
return !deleted || (deleted && topicInfo.privileges.view_deleted) || topicData.uid === current_user;
|
||||
}
|
||||
|
||||
|
||||
28
src/user.js
28
src/user.js
@@ -1,4 +1,4 @@
|
||||
var bcrypt = require('bcrypt'),
|
||||
var bcrypt = require('bcryptjs'),
|
||||
async = require('async'),
|
||||
nconf = require('nconf'),
|
||||
winston = require('winston'),
|
||||
@@ -859,6 +859,10 @@ var bcrypt = require('bcrypt'),
|
||||
|
||||
User.email = {
|
||||
verify: function(uid, email) {
|
||||
if (!plugins.hasListeners('action:email.send')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var confirm_code = utils.generateUUID(),
|
||||
confirm_link = nconf.get('url') + '/confirm/' + confirm_code;
|
||||
|
||||
@@ -895,21 +899,21 @@ var bcrypt = require('bcrypt'),
|
||||
confirm: function(code, callback) {
|
||||
db.getObject('confirm:' + code, function(err, confirmObj) {
|
||||
if (err) {
|
||||
callback({
|
||||
return callback({
|
||||
status:'error'
|
||||
});
|
||||
} else {
|
||||
if (confirmObj.uid && confirmObj.email) {
|
||||
db.setObjectField('email:confirmed', confirmObj.email, '1', function() {
|
||||
callback({
|
||||
status: 'ok'
|
||||
});
|
||||
});
|
||||
} else {
|
||||
}
|
||||
|
||||
if (confirmObj && confirmObj.uid && confirmObj.email) {
|
||||
db.setObjectField('email:confirmed', confirmObj.email, '1', function() {
|
||||
callback({
|
||||
status: 'not_ok'
|
||||
status: 'ok'
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
callback({
|
||||
status: 'not_ok'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -43,9 +43,9 @@ describe('Categories', function() {
|
||||
|
||||
describe('.getCategoryTopics', function() {
|
||||
it('should return a list of topics', function(done) {
|
||||
Categories.getCategoryTopics(categoryObj.cid, 0, 10, 0, function(err, topics) {
|
||||
assert(Array.isArray(topics));
|
||||
assert(topics.every(function(topic) {
|
||||
Categories.getCategoryTopics(categoryObj.cid, 0, 10, 0, function(err, result) {
|
||||
assert(Array.isArray(result.topics));
|
||||
assert(result.topics.every(function(topic) {
|
||||
return topic instanceof Object;
|
||||
}));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user