When forking a topic, updates user bookmarks in the topic to keep the last read position ()

from inadvertently being too far down the topic due to post indices decreasing because
some posts were moved to a new topic.
v1.18.x
boomzilla committed by Julian Lam
parent b12811d21d
commit 52e4a37df8

@ -55,7 +55,8 @@ define('forum/topic/fork', ['components', 'postSelect'], function(components, po
forkCommit.attr('disabled', true); forkCommit.attr('disabled', true);
socket.emit('topics.createTopicFromPosts', { socket.emit('topics.createTopicFromPosts', {
title: forkModal.find('#fork-title').val(), title: forkModal.find('#fork-title').val(),
pids: postSelect.pids pids: postSelect.pids,
fromTid: ajaxify.data.tid
}, function(err, newTopic) { }, function(err, newTopic) {
function fadeOutAndRemove(pid) { function fadeOutAndRemove(pid) {
components.get('post', 'pid', pid).fadeOut(500, function() { components.get('post', 'pid', pid).fadeOut(500, function() {

@ -135,4 +135,4 @@ module.exports = function(Meta) {
db.deleteObjectField('config', field); db.deleteObjectField('config', field);
}; };
}; };

@ -69,7 +69,7 @@ SocketTopics.createTopicFromPosts = function(socket, data, callback) {
return callback(new Error('[[error:invalid-data]]')); return callback(new Error('[[error:invalid-data]]'));
} }
topics.createTopicFromPosts(socket.uid, data.title, data.pids, callback); topics.createTopicFromPosts(socket.uid, data.title, data.pids, data.fromTid, callback);
}; };
SocketTopics.toggleFollow = function(socket, tid, callback) { SocketTopics.toggleFollow = function(socket, tid, callback) {

@ -328,4 +328,88 @@ var social = require('./social');
} }
}; };
Topics.getTopicBookmarks = function( tid, callback ){
db.getSortedSetRangeWithScores(['tid:' + tid + ':bookmarks'], 0, -1, callback );
};
Topics.updateTopicBookmarks = function( tid, pids, callback ){
var maxIndex;
var Posts = posts;
async.waterfall([
function(next){
Topics.getPostCount( tid, next );
},
function(postcount, next){
maxIndex = postcount;
Topics.getTopicBookmarks( tid, next );
},
function(bookmarks, next){
var uids = bookmarks.map( function( bookmark ){return bookmark.value});
var forkedPosts = pids.map( function( pid ){ return { pid: pid, tid: tid }; } );
var uidBookmark = new Object();
var uidData = bookmarks.map(
function( bookmark ){
var u = new Object();
u.uid = bookmark.value;
u.bookmark = bookmark.score;
return u;
} );
async.map(
uidData,
function( data, mapCallback ){
Posts.getPostIndices(
forkedPosts,
data.uid,
function( err, indices ){
if( err ){
callback( err );
}
data.postIndices = indices;
mapCallback( null, data );
} )
},
function( err, results ){
if( err ){
return callback();
}
async.map(
results,
function( data, mapCallback ){
var uid = data.uid;
var bookmark = data.bookmark;
bookmark = bookmark < maxIndex ? bookmark : maxIndex;
var postIndices = data.postIndices;
var i;
for( i = 0; i < postIndices.length && postIndices[i] < data.bookmark; ++i ){
--bookmark;
}
if( bookmark != data.bookmark ){
mapCallback( null, { uid: uid, bookmark: bookmark } );
}
else{
mapCallback( null, null );
}
},
function( err, results ){
async.map( results,
function(ui, cb ){
if( ui && ui.bookmark){
Topics.setUserBookmark( tid, ui.uid, ui.bookmark, cb );
}
else{
return cb( null, null );
}
},
function( err, results ){
next();
}
);
}
);
}
);
}],
function( err, result ){ callback();} );
};
}(exports)); }(exports));

@ -13,7 +13,7 @@ var meta = require('../meta');
module.exports = function(Topics) { module.exports = function(Topics) {
Topics.createTopicFromPosts = function(uid, title, pids, callback) { Topics.createTopicFromPosts = function(uid, title, pids, fromTid, callback) {
if (title) { if (title) {
title = title.trim(); title = title.trim();
} }
@ -55,6 +55,9 @@ module.exports = function(Topics) {
} }
Topics.create({uid: results.postData.uid, title: title, cid: cid}, next); Topics.create({uid: results.postData.uid, title: title, cid: cid}, next);
}, },
function( results, next) {
Topics.updateTopicBookmarks(fromTid, pids, function(){ next( null, results );} );
},
function(_tid, next) { function(_tid, next) {
function move(pid, next) { function move(pid, next) {
privileges.posts.canEdit(pid, uid, function(err, canEdit) { privileges.posts.canEdit(pid, uid, function(err, canEdit) {

@ -7,6 +7,8 @@ var db = require('./mocks/databasemock');
var topics = require('../src/topics'); var topics = require('../src/topics');
var categories = require('../src/categories'); var categories = require('../src/categories');
var User = require('../src/user'); var User = require('../src/user');
var groups = require('../src/groups');
var async = require('async');
describe('Topic\'s', function() { describe('Topic\'s', function() {
var topic, var topic,
@ -188,6 +190,100 @@ describe('Topic\'s', function() {
}); });
describe('.fork', function(){
var newTopic;
var replies = new Array();
var topicPids;
var originalBookmark = 5;
function postReply( next ){
topics.reply({uid: topic.userId, content: 'test post ' + replies.length, tid: newTopic.tid},
function(err, result) {
assert.equal(err, null, 'was created with error');
assert.ok(result);
replies.push( result );
next();
}
);
}
before( function(done) {
async.waterfall(
[
function(next){
groups.join('administrators', topic.userId, next);
},
function( next ){
topics.post({uid: topic.userId, title: topic.title, content: topic.content, cid: topic.categoryId}, function(err, result) {
assert.ifError( err );
newTopic = result.topicData;
next();
});
},
function( next ){ postReply( next );},
function( next ){ postReply( next );},
function( next ){ postReply( next );},
function( next ){ postReply( next );},
function( next ){ postReply( next );},
function( next ){ postReply( next );},
function( next ){ postReply( next );},
function( next ){ postReply( next );},
function( next ){ postReply( next );},
function( next ){ postReply( next );},
function( next ){ postReply( next );},
function( next ){ postReply( next );},
function( next ){
topicPids = replies.map( function( reply ){ return reply.pid; } );
topics.setUserBookmark( newTopic.tid, topic.userId, originalBookmark, next );
}],
done );
});
it('should have 12 replies', function(done) {
assert.equal( 12, replies.length );
done();
});
it('should not update the user\'s bookmark', function(done){
async.waterfall([
function(next){
topics.createTopicFromPosts(
topic.userId,
'Fork test, no bookmark update',
topicPids.slice( -2 ),
newTopic.tid,
next );
},
function( forkedTopicData, next){
topics.getUserBookmark( newTopic.tid, topic.userId, next );
},
function( bookmark, next ){
assert.equal( originalBookmark, bookmark );
next();
}
],done);
});
it('should update the user\'s bookmark ', function(done){
async.waterfall([
function(next){
topics.createTopicFromPosts(
topic.userId,
'Fork test, no bookmark update',
topicPids.slice( 1, 3 ),
newTopic.tid,
next );
},
function( forkedTopicData, next){
topics.getUserBookmark( newTopic.tid, topic.userId, next );
},
function( bookmark, next ){
assert.equal( originalBookmark - 2, bookmark );
next();
}
],done);
});
});
after(function() { after(function() {
db.flushdb(); db.flushdb();
}); });

Loading…
Cancel
Save