mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-02-02 20:59:56 +01:00
closes #524
This commit is contained in:
@@ -20,11 +20,13 @@
|
||||
"thread_tools.pin": "Pin Thread",
|
||||
"thread_tools.lock": "Lock Thread",
|
||||
"thread_tools.move": "Move Thread",
|
||||
"thread_tools.fork": "Fork Thread",
|
||||
"thread_tools.delete": "Delete Thread",
|
||||
|
||||
"load_categories": "Loading Categories",
|
||||
"disabled_categories_note": "Disabled Categories are greyed out",
|
||||
"confirm_move": "Move",
|
||||
"confirm_fork": "Fork",
|
||||
|
||||
"favourite": "Favourite",
|
||||
"favourites": "Favorites",
|
||||
@@ -36,7 +38,11 @@
|
||||
"loading": "Loading",
|
||||
"more_posts": "More Posts",
|
||||
"move_topic": "Move Topic",
|
||||
"fork_topic": "Fork Topic",
|
||||
"topic_will_be_moved_to": "This topic will be moved to the category",
|
||||
"fork_topic_instruction": "Click the posts you want to fork",
|
||||
"fork_no_pids": "No posts selected!",
|
||||
"fork_success": "Succesfully forked topic!",
|
||||
|
||||
"reputation": "Reputation",
|
||||
"posts": "Posts"
|
||||
|
||||
@@ -174,6 +174,96 @@ define(['composer'], function(composer) {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$('.fork_thread').on('click', function() {
|
||||
var pids = [];
|
||||
var forkModal = $('#fork-thread-modal'),
|
||||
forkCommit = forkModal.find('#fork_thread_commit');
|
||||
forkModal.removeClass('hide');
|
||||
forkModal.css("position", "fixed")
|
||||
.css("left", Math.max(0, (($(window).width() - $(forkModal).outerWidth()) / 2) + $(window).scrollLeft()) + "px")
|
||||
.css("top", "0px")
|
||||
.css("z-index", "2000");
|
||||
|
||||
showNoPostsSelected();
|
||||
|
||||
forkModal.find('.close,#fork_thread_cancel').on('click', closeForkModal);
|
||||
forkModal.find('#fork-title').on('change', checkForkButtonEnable);
|
||||
$('#post-container').on('click', 'li', togglePostSelection);
|
||||
forkCommit.on('click', createTopicFromPosts);
|
||||
|
||||
function createTopicFromPosts() {
|
||||
socket.emit('api:topic.createTopicFromPosts', {
|
||||
title: forkModal.find('#fork-title').val(),
|
||||
pids: pids
|
||||
}, function(err) {
|
||||
if(err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
|
||||
translator.get('topic:fork_success', function(translated) {
|
||||
app.alertSuccess(translated);
|
||||
});
|
||||
|
||||
for(var i=0; i<pids.length; ++i) {
|
||||
$('#post-container li[data-pid="' + pids[i] + '"]').fadeOut(500, function() {
|
||||
$(this).remove();
|
||||
});
|
||||
}
|
||||
closeForkModal();
|
||||
});
|
||||
}
|
||||
|
||||
function togglePostSelection() {
|
||||
|
||||
var newPid = $(this).attr('data-pid');
|
||||
|
||||
if($(this).attr('data-index') === '0') {
|
||||
return;
|
||||
}
|
||||
|
||||
if(newPid) {
|
||||
var index = pids.indexOf(newPid);
|
||||
if(index === -1) {
|
||||
pids.push(newPid);
|
||||
$(this).css('opacity', '0.5');
|
||||
} else {
|
||||
pids.splice(index, 1);
|
||||
$(this).css('opacity', '1.0');
|
||||
}
|
||||
|
||||
if(pids.length) {
|
||||
pids.sort();
|
||||
forkModal.find('#fork-pids').html(pids.toString());
|
||||
} else {
|
||||
showNoPostsSelected();
|
||||
}
|
||||
checkForkButtonEnable();
|
||||
}
|
||||
}
|
||||
|
||||
function closeForkModal() {
|
||||
for(var i=0; i<pids.length; ++i) {
|
||||
$('#post-container li[data-pid="' + pids[i] + '"]').css('opacity', 1.0);
|
||||
}
|
||||
forkModal.addClass('hide');
|
||||
$('#post-container').off('click', 'li');
|
||||
}
|
||||
|
||||
function checkForkButtonEnable() {
|
||||
if(forkModal.find('#fork-title').length && pids.length) {
|
||||
forkCommit.removeAttr('disabled');
|
||||
} else {
|
||||
forkCommit.attr('disabled', true);
|
||||
}
|
||||
}
|
||||
|
||||
function showNoPostsSelected() {
|
||||
translator.get('topic:fork_no_pids', function(translated) {
|
||||
forkModal.find('#fork-pids').html(translated);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fixDeleteStateForPosts();
|
||||
@@ -375,21 +465,6 @@ define(['composer'], function(composer) {
|
||||
}
|
||||
});
|
||||
|
||||
$('#post-container').on('click', '.fork-post', function(e) {
|
||||
var post = $(this).parents('li'),
|
||||
pid = post.attr('data-pid');
|
||||
|
||||
socket.emit('api:topic.createTopicFromPost', {pid:pid}, function(err) {
|
||||
if(err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
post.fadeOut(500, function() {
|
||||
post.remove();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
$('#post-container').on('click', '.chat', function(e) {
|
||||
var username = $(this).parents('li.row').attr('data-username');
|
||||
var touid = $(this).parents('li.row').attr('data-uid');
|
||||
|
||||
@@ -4,11 +4,11 @@ define(['taskbar', 'string'], function(taskbar, S) {
|
||||
|
||||
module.bringModalToTop = function(chatModal) {
|
||||
var topZ = 0;
|
||||
$('.modal').each(function() {
|
||||
var thisZ = parseInt($(this).css('zIndex'), 10);
|
||||
if (thisZ > topZ) {
|
||||
topZ = thisZ;
|
||||
}
|
||||
$('.chat-modal').each(function() {
|
||||
var thisZ = parseInt($(this).css('zIndex'), 10);
|
||||
if (thisZ > topZ) {
|
||||
topZ = thisZ;
|
||||
}
|
||||
});
|
||||
chatModal.css('zIndex', topZ + 1);
|
||||
}
|
||||
|
||||
@@ -97,9 +97,6 @@
|
||||
<div class="btn-group post-tools">
|
||||
<button class="btn btn-sm btn-default edit" type="button" title="[[topic:edit]]"><i class="fa fa-pencil"></i></button>
|
||||
<button class="btn btn-sm btn-default delete" type="button" title="[[topic:delete]]"><i class="fa fa-trash-o"></i></button>
|
||||
<!-- IF !@first -->
|
||||
<button class="btn btn-sm btn-default fork-post" type="button" title="[[topic:fork]]"><i class="fa fa-code-fork"></i></button>
|
||||
<!-- ENDIF !@first -->
|
||||
</div>
|
||||
<!-- ENDIF posts.display_moderator_tools -->
|
||||
</div>
|
||||
@@ -151,6 +148,7 @@
|
||||
<li><a href="#" class="lock_thread"><i class="fa fa-lock"></i> [[topic:thread_tools.lock]]</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="#" class="move_thread"><i class="fa fa-arrows"></i> [[topic:thread_tools.move]]</a></li>
|
||||
<li><a href="#" class="fork_thread"><i class="fa fa-code-fork"></i> [[topic:thread_tools.fork]]</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="#" class="delete_thread"><span class="text-error"><i class="fa fa-trash-o"></i> [[topic:thread_tools.delete]]</span></a></li>
|
||||
</ul>
|
||||
@@ -175,6 +173,7 @@
|
||||
<li><a href="#" class="lock_thread"><i class="fa fa-lock"></i> [[topic:thread_tools.lock]]</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="#" class="move_thread"><i class="fa fa-arrows"></i> [[topic:thread_tools.move]]</a></li>
|
||||
<li><a href="#" class="fork_thread"><i class="fa fa-code-fork"></i> [[topic:thread_tools.fork]]</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="#" class="delete_thread"><span class="text-error"><i class="fa fa-trash-o"></i> [[topic:thread_tools.delete]]</span></a></li>
|
||||
</ul>
|
||||
@@ -209,4 +208,29 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="fork-thread-modal" class="hide" tabindex="-1" role="dialog" aria-labelledby="Chat" aria-hidden="true" data-backdrop="none">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h4>[[topic:fork_topic]]</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label for="title">Title</label>
|
||||
<input id="fork-title" type="text" class="form-control" placeholder="Enter new thread title"><br/>
|
||||
<label>[[topic:fork_topic_instruction]]</label> <br/>
|
||||
<span id="fork-pids"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal" id="fork_thread_cancel">[[global:buttons.close]]</button>
|
||||
<button type="button" class="btn btn-primary" id="fork_thread_commit" disabled>[[topic:confirm_fork]]</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -198,40 +198,70 @@ var async = require('async'),
|
||||
});
|
||||
}
|
||||
|
||||
Topics.createTopicFromPost = function(pid, callback) {
|
||||
posts.getPostData(pid, function(err, postData) {
|
||||
Topics.createTopicFromPosts = function(title, pids, callback) {
|
||||
if(title) {
|
||||
title = title.trim();
|
||||
}
|
||||
|
||||
if(!title) {
|
||||
return callback(new Error('invalid-title'));
|
||||
}
|
||||
|
||||
if(!pids || !pids.length) {
|
||||
return callback(new Error('invalid-pids'));
|
||||
}
|
||||
|
||||
pids.sort();
|
||||
var mainPid = pids[0];
|
||||
|
||||
posts.getPostData(mainPid, function(err, postData) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
posts.getCidByPid(pid, function(err, cid) {
|
||||
posts.getCidByPid(mainPid, function(err, cid) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
// TODO : title should be given by client
|
||||
var title = postData.content.substr(0, 20);
|
||||
|
||||
Topics.create(postData.uid, title, cid, function(err, tid) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
Topics.removePostFromTopic(postData.tid, postData.pid);
|
||||
Topics.decreasePostCount(postData.tid);
|
||||
async.eachSeries(pids, move, function(err) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
posts.setPostField(pid, 'tid', tid);
|
||||
|
||||
Topics.onNewPostMade(tid, postData.pid, postData.timestamp);
|
||||
|
||||
Topics.getTopicData(tid, function(err, topicData) {
|
||||
callback(err, topicData);
|
||||
Topics.getTopicData(tid, function(err, topicData) {
|
||||
callback(err, topicData);
|
||||
});
|
||||
});
|
||||
|
||||
function move(pid, next) {
|
||||
posts.getPostField(pid, 'timestamp', function(err, timestamp) {
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
Topics.movePostToTopic(pid, postData.tid, tid, timestamp, next);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Topics.movePostToTopic = function(pid, oldTid, newTid, timestamp, callback) {
|
||||
Topics.removePostFromTopic(oldTid, pid);
|
||||
Topics.decreasePostCount(oldTid);
|
||||
|
||||
posts.setPostField(pid, 'tid', newTid);
|
||||
|
||||
Topics.onNewPostMade(newTid, pid, timestamp, callback);
|
||||
}
|
||||
|
||||
Topics.getTopicData = function(tid, callback) {
|
||||
db.getObject('topic:' + tid, function(err, data) {
|
||||
if(err) {
|
||||
@@ -986,14 +1016,14 @@ var async = require('async'),
|
||||
Topics.setTopicField(tid, 'lastposttime', timestamp);
|
||||
}
|
||||
|
||||
Topics.onNewPostMade = function(tid, pid, timestamp) {
|
||||
Topics.addPostToTopic(tid, pid);
|
||||
Topics.onNewPostMade = function(tid, pid, timestamp, callback) {
|
||||
Topics.increasePostCount(tid);
|
||||
Topics.updateTimestamp(tid, timestamp);
|
||||
Topics.addPostToTopic(tid, pid, callback);
|
||||
}
|
||||
|
||||
Topics.addPostToTopic = function(tid, pid) {
|
||||
db.listAppend('tid:' + tid + ':posts', pid);
|
||||
Topics.addPostToTopic = function(tid, pid, callback) {
|
||||
db.listAppend('tid:' + tid + ':posts', pid, callback);
|
||||
}
|
||||
|
||||
Topics.removePostFromTopic = function(tid, pid) {
|
||||
|
||||
@@ -622,8 +622,8 @@ websockets.init = function(io) {
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('api:topic.createTopicFromPost', function(data, callback) {
|
||||
topics.createTopicFromPost(data.pid, function(err, data) {
|
||||
socket.on('api:topic.createTopicFromPosts', function(data, callback) {
|
||||
topics.createTopicFromPosts(data.title, data.pids, function(err, data) {
|
||||
callback(err?{message:err.message}:null, data);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user