You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
467 lines
12 KiB
JavaScript
467 lines
12 KiB
JavaScript
'use strict';
|
|
|
|
/* globals define, app, ajaxify, bootbox, socket, templates, utils, config */
|
|
|
|
define('forum/topic/postTools', ['share', 'navigator', 'components', 'translator'], function(share, navigator, components, translator) {
|
|
|
|
var PostTools = {};
|
|
|
|
PostTools.init = function(tid) {
|
|
renderMenu();
|
|
|
|
addPostHandlers(tid);
|
|
|
|
share.addShareHandlers(ajaxify.data.title);
|
|
|
|
addVoteHandler();
|
|
|
|
PostTools.updatePostCount(ajaxify.data.postcount);
|
|
};
|
|
|
|
function renderMenu() {
|
|
$('[component="topic"]').on('show.bs.dropdown', '.moderator-tools', function() {
|
|
var $this = $(this);
|
|
var dropdownMenu = $this.find('.dropdown-menu');
|
|
if (dropdownMenu.html()) {
|
|
return;
|
|
}
|
|
var postEl = $this.parents('[data-pid]');
|
|
var pid = postEl.attr('data-pid');
|
|
var index = parseInt(postEl.attr('data-index'), 10);
|
|
|
|
socket.emit('posts.loadPostTools', {pid: pid, cid: ajaxify.data.cid}, function(err, data) {
|
|
if (err) {
|
|
return app.alertError(err);
|
|
}
|
|
data.posts.display_move_tools = data.posts.display_move_tools && index !== 0;
|
|
|
|
templates.parse('partials/topic/post-menu-list', data, function(html) {
|
|
translator.translate(html, function(html) {
|
|
dropdownMenu.html(html);
|
|
$(window).trigger('action:post.tools.load');
|
|
});
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
PostTools.toggle = function(pid, isDeleted) {
|
|
var postEl = components.get('post', 'pid', pid);
|
|
|
|
postEl.find('[component="post/quote"], [component="post/favourite"], [component="post/reply"], [component="post/flag"], [component="user/chat"]')
|
|
.toggleClass('hidden', isDeleted);
|
|
|
|
postEl.find('[component="post/delete"]').toggleClass('hidden', isDeleted);
|
|
postEl.find('[component="post/restore"]').toggleClass('hidden', !isDeleted);
|
|
postEl.find('[component="post/purge"]').toggleClass('hidden', !isDeleted);
|
|
};
|
|
|
|
PostTools.updatePostCount = function(postCount) {
|
|
var postCountEl = components.get('topic/post-count');
|
|
postCountEl.html(postCount).attr('title', postCount);
|
|
utils.makeNumbersHumanReadable(postCountEl);
|
|
navigator.setCount(postCount);
|
|
};
|
|
|
|
function addVoteHandler() {
|
|
components.get('topic').on('mouseenter', '[data-pid] [component="post/vote-count"]', function() {
|
|
loadDataAndCreateTooltip($(this).parent());
|
|
});
|
|
}
|
|
|
|
function loadDataAndCreateTooltip(el) {
|
|
var pid = el.parents('[data-pid]').attr('data-pid');
|
|
socket.emit('posts.getUpvoters', [pid], function(err, data) {
|
|
if (!err && data.length) {
|
|
createTooltip(el, data[0]);
|
|
}
|
|
});
|
|
}
|
|
|
|
function createTooltip(el, data) {
|
|
function doCreateTooltip(title) {
|
|
el.attr('title', title).tooltip('fixTitle').tooltip('show');
|
|
el.on('hidden.bs.tooltip', function() {
|
|
el.tooltip('destroy');
|
|
el.off('hidden.bs.tooltip');
|
|
});
|
|
}
|
|
var usernames = data.usernames;
|
|
if (!usernames.length) {
|
|
return;
|
|
}
|
|
if (usernames.length + data.otherCount > 6) {
|
|
usernames = usernames.join(', ').replace(/,/g, '|');
|
|
translator.translate('[[topic:users_and_others, ' + usernames + ', ' + data.otherCount + ']]', function(translated) {
|
|
translated = translated.replace(/\|/g, ',');
|
|
doCreateTooltip(translated);
|
|
});
|
|
} else {
|
|
usernames = usernames.join(', ');
|
|
doCreateTooltip(usernames);
|
|
}
|
|
}
|
|
|
|
function addPostHandlers(tid) {
|
|
var postContainer = components.get('topic');
|
|
|
|
postContainer.on('click', '[component="post/quote"]', function() {
|
|
onQuoteClicked($(this), tid);
|
|
});
|
|
|
|
postContainer.on('click', '[component="post/reply"]', function() {
|
|
onReplyClicked($(this), tid);
|
|
});
|
|
|
|
$('.topic').on('click', '[component="topic/reply"]', function() {
|
|
onReplyClicked($(this), tid);
|
|
});
|
|
|
|
$('.topic').on('click', '[component="topic/reply-as-topic"]', function() {
|
|
translator.translate('[[topic:link_back, ' + ajaxify.data.titleRaw + ', ' + config.relative_path + '/topic/' + ajaxify.data.slug + ']]', function(body) {
|
|
$(window).trigger('action:composer.topic.new', {
|
|
cid: ajaxify.data.cid,
|
|
body: body
|
|
});
|
|
});
|
|
});
|
|
|
|
postContainer.on('click', '[component="post/favourite"]', function() {
|
|
favouritePost($(this), getData($(this), 'data-pid'));
|
|
});
|
|
|
|
postContainer.on('click', '[component="post/upvote"]', function() {
|
|
return toggleVote($(this), '.upvoted', 'posts.upvote');
|
|
});
|
|
|
|
postContainer.on('click', '[component="post/downvote"]', function() {
|
|
return toggleVote($(this), '.downvoted', 'posts.downvote');
|
|
});
|
|
|
|
postContainer.on('click', '[component="post/vote-count"]', function() {
|
|
showVotes(getData($(this), 'data-pid'));
|
|
});
|
|
|
|
postContainer.on('click', '[component="post/flag"]', function() {
|
|
var pid = getData($(this), 'data-pid');
|
|
require(['forum/topic/flag'], function(flag) {
|
|
flag.showFlagModal(pid);
|
|
});
|
|
});
|
|
|
|
postContainer.on('click', '[component="post/edit"]', function() {
|
|
var btn = $(this);
|
|
$(window).trigger('action:composer.post.edit', {
|
|
pid: getData(btn, 'data-pid')
|
|
});
|
|
});
|
|
|
|
postContainer.on('click', '[component="post/delete"]', function() {
|
|
togglePostDelete($(this), tid);
|
|
});
|
|
|
|
postContainer.on('click', '[component="post/restore"]', function() {
|
|
togglePostDelete($(this), tid);
|
|
});
|
|
|
|
postContainer.on('click', '[component="post/purge"]', function() {
|
|
purgePost($(this), tid);
|
|
});
|
|
|
|
postContainer.on('click', '[component="post/move"]', function() {
|
|
openMovePostModal($(this));
|
|
});
|
|
|
|
postContainer.on('click', '[component="post/chat"]', function() {
|
|
openChat($(this));
|
|
});
|
|
}
|
|
|
|
function onReplyClicked(button, tid) {
|
|
showStaleWarning(function(proceed) {
|
|
if (!proceed) {
|
|
var selectionText = '';
|
|
var selection = window.getSelection ? window.getSelection() : document.selection.createRange();
|
|
var selectionNode = $(selection.baseNode || selection.anchorNode);
|
|
|
|
if (selectionNode.parents('[component="post/content"]').length > 0) {
|
|
selectionText = selection.toString();
|
|
}
|
|
|
|
button = selectionText ? selectionNode : button;
|
|
var username = getUserName(button);
|
|
if (getData(button, 'data-uid') === '0' || !getData(button, 'data-userslug')) {
|
|
username = '';
|
|
}
|
|
|
|
var toPid = button.is('[component="post/reply"]') ? getData(button, 'data-pid') : null;
|
|
|
|
if (selectionText.length) {
|
|
$(window).trigger('action:composer.addQuote', {
|
|
tid: tid,
|
|
slug: ajaxify.data.slug,
|
|
index: getData(button, 'data-index'),
|
|
pid: toPid,
|
|
topicName: ajaxify.data.titleRaw,
|
|
username: username,
|
|
text: selectionText
|
|
});
|
|
} else {
|
|
$(window).trigger('action:composer.post.new', {
|
|
tid: tid,
|
|
pid: toPid,
|
|
topicName: ajaxify.data.titleRaw,
|
|
text: username ? username + ' ' : ''
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function onQuoteClicked(button, tid) {
|
|
showStaleWarning(function(proceed) {
|
|
if (!proceed) {
|
|
var username = getUserName(button),
|
|
pid = getData(button, 'data-pid');
|
|
|
|
socket.emit('posts.getRawPost', pid, function(err, post) {
|
|
if(err) {
|
|
return app.alertError(err.message);
|
|
}
|
|
|
|
$(window).trigger('action:composer.addQuote', {
|
|
tid: tid,
|
|
slug: ajaxify.data.slug,
|
|
index: getData(button, 'data-index'),
|
|
pid: pid,
|
|
username: username,
|
|
topicName: ajaxify.data.titleRaw,
|
|
text: post
|
|
});
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
function favouritePost(button, pid) {
|
|
var method = button.attr('data-favourited') === 'false' ? 'posts.favourite' : 'posts.unfavourite';
|
|
|
|
socket.emit(method, {
|
|
pid: pid,
|
|
room_id: app.currentRoom
|
|
}, function(err) {
|
|
if (err) {
|
|
app.alertError(err.message);
|
|
}
|
|
});
|
|
|
|
return false;
|
|
}
|
|
|
|
function toggleVote(button, className, method) {
|
|
var post = button.parents('[data-pid]'),
|
|
currentState = post.find(className).length;
|
|
|
|
socket.emit(currentState ? 'posts.unvote' : method , {
|
|
pid: post.attr('data-pid'),
|
|
room_id: app.currentRoom
|
|
}, function(err) {
|
|
if (err) {
|
|
if (err.message === 'self-vote') {
|
|
showVotes(post.attr('data-pid'));
|
|
} else {
|
|
app.alertError(err.message);
|
|
}
|
|
}
|
|
});
|
|
|
|
return false;
|
|
}
|
|
|
|
function showVotes(pid) {
|
|
socket.emit('posts.getVoters', {pid: pid, cid: ajaxify.data.cid}, function(err, data) {
|
|
if (err) {
|
|
if (err.message === '[[error:no-privileges]]') {
|
|
return;
|
|
}
|
|
|
|
// Only show error if it's an unexpected error.
|
|
return app.alertError(err.message);
|
|
}
|
|
|
|
templates.parse('partials/modals/votes_modal', data, function(html) {
|
|
var dialog = bootbox.dialog({
|
|
title: 'Voters',
|
|
message: html,
|
|
className: 'vote-modal',
|
|
show: true
|
|
});
|
|
|
|
dialog.on('click', function() {
|
|
dialog.modal('hide');
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
function getData(button, data) {
|
|
return button.parents('[data-pid]').attr(data);
|
|
}
|
|
|
|
function getUserName(button) {
|
|
var username = '';
|
|
var post = button.parents('[data-pid]');
|
|
|
|
if (button.attr('component') === 'topic/reply') {
|
|
return username;
|
|
}
|
|
|
|
if (post.length) {
|
|
username = post.attr('data-username').replace(/\s/g, '-');
|
|
}
|
|
if (post.length && post.attr('data-uid') !== '0') {
|
|
username = '@' + username;
|
|
}
|
|
|
|
return username;
|
|
}
|
|
|
|
function togglePostDelete(button, tid) {
|
|
var pid = getData(button, 'data-pid'),
|
|
postEl = components.get('post', 'pid', pid),
|
|
action = !postEl.hasClass('deleted') ? 'delete' : 'restore';
|
|
|
|
postAction(action, pid, tid);
|
|
}
|
|
|
|
function purgePost(button, tid) {
|
|
postAction('purge', getData(button, 'data-pid'), tid);
|
|
}
|
|
|
|
function postAction(action, pid, tid) {
|
|
translator.translate('[[topic:post_' + action + '_confirm]]', function(msg) {
|
|
bootbox.confirm(msg, function(confirm) {
|
|
if (!confirm) {
|
|
return;
|
|
}
|
|
|
|
socket.emit('posts.' + action, {
|
|
pid: pid,
|
|
tid: tid
|
|
}, function(err) {
|
|
if (err) {
|
|
app.alertError(err.message);
|
|
}
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
function openMovePostModal(button) {
|
|
parseMoveModal(function(html) {
|
|
var moveModal = $(html);
|
|
|
|
var moveBtn = moveModal.find('#move_post_commit'),
|
|
topicId = moveModal.find('#topicId');
|
|
|
|
moveModal.on('hidden.bs.modal', function() {
|
|
moveModal.remove();
|
|
});
|
|
|
|
showMoveModal(moveModal);
|
|
|
|
moveModal.find('.close, #move_post_cancel').on('click', function() {
|
|
moveModal.addClass('hide');
|
|
});
|
|
|
|
topicId.on('keyup change', function() {
|
|
moveBtn.attr('disabled', !topicId.val());
|
|
});
|
|
|
|
moveBtn.on('click', function() {
|
|
movePost(button.parents('[data-pid]'), getData(button, 'data-pid'), topicId.val(), function() {
|
|
moveModal.modal('hide');
|
|
topicId.val('');
|
|
});
|
|
});
|
|
|
|
});
|
|
}
|
|
|
|
function parseMoveModal(callback) {
|
|
templates.parse('partials/move_post_modal', {}, function(html) {
|
|
translator.translate(html, callback);
|
|
});
|
|
}
|
|
|
|
function showMoveModal(modal) {
|
|
modal.modal('show')
|
|
.css("position", "fixed")
|
|
.css("left", Math.max(0, (($(window).width() - modal.outerWidth()) / 2) + $(window).scrollLeft()) + "px")
|
|
.css("top", "0px")
|
|
.css("z-index", "2000");
|
|
}
|
|
|
|
function movePost(post, pid, tid, callback) {
|
|
socket.emit('posts.movePost', {pid: pid, tid: tid}, function(err) {
|
|
if (err) {
|
|
app.alertError(err.message);
|
|
return callback();
|
|
}
|
|
|
|
post.fadeOut(500, function() {
|
|
post.remove();
|
|
});
|
|
|
|
app.alertSuccess('[[topic:post_moved]]');
|
|
callback();
|
|
});
|
|
}
|
|
|
|
function openChat(button) {
|
|
var post = button.parents('[data-pid]');
|
|
|
|
app.newChat(post.attr('data-uid'));
|
|
button.parents('.btn-group').find('.dropdown-toggle').click();
|
|
return false;
|
|
}
|
|
|
|
function showStaleWarning(callback) {
|
|
if (ajaxify.data.lastposttime < (Date.now() - (1000 * 60 * 60 * 24 * ajaxify.data.topicStaleDays))) {
|
|
translator.translate('[[topic:stale.warning]]', function(translated) {
|
|
var warning = bootbox.dialog({
|
|
title: '[[topic:stale.title]]',
|
|
message: translated,
|
|
buttons: {
|
|
reply: {
|
|
label: '[[topic:stale.reply_anyway]]',
|
|
className: 'btn-link',
|
|
callback: function() {
|
|
callback(false);
|
|
}
|
|
},
|
|
create: {
|
|
label: '[[topic:stale.create]]',
|
|
className: 'btn-primary',
|
|
callback: function() {
|
|
translator.translate('[[topic:link_back, ' + ajaxify.data.title + ', ' + config.relative_path + '/topic/' + ajaxify.data.slug + ']]', function(body) {
|
|
$(window).trigger('action:composer.topic.new', {
|
|
cid: ajaxify.data.cid,
|
|
body: body
|
|
});
|
|
});
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
warning.modal();
|
|
});
|
|
} else {
|
|
callback(false);
|
|
}
|
|
}
|
|
|
|
return PostTools;
|
|
});
|