From a86d91a5520f8dcdc0f15a4bf506431e806292a8 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 16 Feb 2018 21:22:26 -0500 Subject: [PATCH] wrapping up post history work --- public/language/en-GB/topic.json | 7 ++- public/src/client/topic/diffs.js | 65 ++++++++++++++++++++++++++++ public/src/client/topic/postTools.js | 8 +++- src/posts/diffs.js | 16 +++++-- src/socket.io/posts/diffs.js | 2 +- 5 files changed, 91 insertions(+), 7 deletions(-) create mode 100644 public/src/client/topic/diffs.js diff --git a/public/language/en-GB/topic.json b/public/language/en-GB/topic.json index e084a9f24f..4b30d84356 100644 --- a/public/language/en-GB/topic.json +++ b/public/language/en-GB/topic.json @@ -35,6 +35,7 @@ "moved": "Moved", "copy-ip": "Copy IP", "ban-ip": "Ban IP", + "view-history": "Edit History", "bookmark_instructions" : "Click here to return to the last read post in this thread.", @@ -143,5 +144,9 @@ "stale.create": "Create a new topic", "stale.reply_anyway": "Reply to this topic anyway", - "link_back": "Re: [%1](%2)\n\n" + "link_back": "Re: [%1](%2)\n\n", + + "diffs.title": "Post Edit History", + "diffs.description": "This post has %1 revisions. Click one of the revisions below to see the post content at that point in time.", + "diffs.no-revisions-description": "This post has %1 revisions." } diff --git a/public/src/client/topic/diffs.js b/public/src/client/topic/diffs.js new file mode 100644 index 0000000000..63dd2b7b28 --- /dev/null +++ b/public/src/client/topic/diffs.js @@ -0,0 +1,65 @@ +'use strict'; + +define('forum/topic/diffs', ['benchpress', 'translator'], function (Benchpress, translator) { + var Diffs = {}; + + Diffs.open = function (pid) { + var localeStringOpts = { year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric' }; + + socket.emit('posts.getDiffs', { pid: pid }, function (err, timestamps) { + if (err) { + return app.alertError(err.message); + } + + Benchpress.parse('partials/modals/post_history', { + diffs: timestamps.map(function (timestamp) { + return { + timestamp: timestamp, + pretty: new Date(timestamp).toLocaleString(config.userLang.replace('_', '-'), localeStringOpts), + }; + }), + numDiffs: timestamps.length, + }, function (html) { + translator.translate(html, function (html) { + var modal = bootbox.dialog({ + title: '[[topic:diffs.title]]', + message: html, + }); + + if (!timestamps.length) { + return; + } + + var selectEl = modal.find('select'); + var postContainer = modal.find('ul.posts-list'); + + selectEl.on('change', function () { + Diffs.load(pid, this.value, postContainer); + }); + + modal.on('shown.bs.modal', function () { + Diffs.load(pid, selectEl.val(), postContainer); + }); + }); + }); + }); + }; + + Diffs.load = function (pid, since, postContainer) { + socket.emit('posts.showPostAt', { pid: pid, since: since }, function (err, data) { + if (err) { + return app.alertError(err.message); + } + + data.deleted = !!parseInt(data.deleted, 10); + + app.parseAndTranslate('partials/posts_list', 'posts', { + posts: [data], + }, function (html) { + postContainer.empty().append(html); + }); + }); + }; + + return Diffs; +}); diff --git a/public/src/client/topic/postTools.js b/public/src/client/topic/postTools.js index 9cbfdbb366..a164f97ee2 100644 --- a/public/src/client/topic/postTools.js +++ b/public/src/client/topic/postTools.js @@ -8,7 +8,8 @@ define('forum/topic/postTools', [ 'translator', 'forum/topic/votes', 'forum/topic/move-post', -], function (share, navigator, components, translator, votes, movePost) { + 'forum/topic/diffs', +], function (share, navigator, components, translator, votes, movePost, diffs) { var PostTools = {}; var staleReplyAnyway = false; @@ -139,6 +140,11 @@ define('forum/topic/postTools', [ } }); + postContainer.on('click', '[component="post/view-history"], [component="post/edit-indicator"]', function () { + var btn = $(this); + diffs.open(getData(btn, 'data-pid')); + }); + postContainer.on('click', '[component="post/delete"]', function () { var btn = $(this); var timestamp = parseInt(getData(btn, 'data-timestamp'), 10); diff --git a/src/posts/diffs.js b/src/posts/diffs.js index 869cd25298..1ce67f8e0f 100644 --- a/src/posts/diffs.js +++ b/src/posts/diffs.js @@ -1,6 +1,7 @@ 'use strict'; var async = require('async'); +var validator = require('validator'); var db = require('../database'); var diff = require('diff'); @@ -18,7 +19,7 @@ module.exports = function (Posts) { db.getSortedSetRangeWithScores('post:' + pid + ':diffs', 0, -1, function (err, diffs) { callback(err, diffs ? diffs.map(function (diffObj) { return diffObj.score; - }) : null); + }).reverse() : null); }); }; @@ -26,7 +27,7 @@ module.exports = function (Posts) { db.sortedSetAdd('post:' + pid + ':diffs', Date.now(), diff.createPatch('', newContent, oldContent), callback); }; - Posts.diffs.load = function (pid, since, callback) { + Posts.diffs.load = function (pid, since, uid, callback) { // Retrieves all diffs made since `since` and replays them to reconstruct what the post looked like at `since` since = parseInt(since, 10); @@ -35,13 +36,18 @@ module.exports = function (Posts) { } async.parallel({ - post: async.apply(Posts.getPostData, pid), + post: async.apply(Posts.getPostSummaryByPids, [pid], uid, { + parse: false, + }), diffs: async.apply(db.getSortedSetRangeByScore.bind(db), 'post:' + pid + ':diffs', 0, -1, since, Date.now()), }, function (err, data) { if (err) { return callback(err); } + data.post = data.post[0]; + data.post.content = validator.unescape(data.post.content); + // Replace content with re-constructed content from that point in time data.post.content = data.diffs.reverse().reduce(function (content, diffString) { return diff.applyPatch(content, diffString); @@ -51,7 +57,9 @@ module.exports = function (Posts) { delete data.post.edited; data.post.editor = null; - return callback(null, data.post); + Posts.parsePost(data.post, function (err, post) { + callback(err, post); + }); }); }; }; diff --git a/src/socket.io/posts/diffs.js b/src/socket.io/posts/diffs.js index 3ce7542399..7f208dc71f 100644 --- a/src/socket.io/posts/diffs.js +++ b/src/socket.io/posts/diffs.js @@ -8,6 +8,6 @@ module.exports = function (SocketPosts) { }; SocketPosts.showPostAt = function (socket, data, callback) { - posts.diffs.load(data.pid, data.since, callback); + posts.diffs.load(data.pid, data.since, socket.uid, callback); }; };