From 54db98a9cf71d5f79379ab83c12474a688f0d5ae Mon Sep 17 00:00:00 2001 From: cel Date: Wed, 23 Jan 2019 13:00:07 -1000 Subject: Add about-diff page --- lib/app.js | 11 +++++++ lib/render-msg.js | 5 ++- lib/serve.js | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 109 insertions(+), 5 deletions(-) diff --git a/lib/app.js b/lib/app.js index ac275a4..73b313d 100644 --- a/lib/app.js +++ b/lib/app.js @@ -1135,6 +1135,17 @@ App.prototype.getThread = function (msg) { ]) } +App.prototype.getLinks = function (id) { + return this.sbot.backlinks ? this.sbot.backlinks.read({ + query: [ + {$filter: {dest: id}} + ] + }) : this.sbotLinks({ + dest: id, + values: true + }) +} + App.prototype.getShard = function (id, cb) { var self = this this.getMsgDecrypted(id, function (err, msg) { diff --git a/lib/render-msg.js b/lib/render-msg.js index e40934e..fbaf741 100644 --- a/lib/render-msg.js +++ b/lib/render-msg.js @@ -175,7 +175,10 @@ RenderMsg.prototype.actions = function (mini) { }.bind(this)) : '', this.c.type === 'edit' ? [ h('a', {href: this.toUrl('/edit-diff/' + encodeURIComponent(this.msg.key)), - title: 'view post edit diff'}, 'diff'), ' '] : '', + title: 'view post edit diff'}, 'diff'), ' '] : + this.c.type === 'about' && typeof this.c.description === 'string' ? [ + h('a', {href: this.toUrl('/about-diff/' + encodeURIComponent(this.msg.key)), + title: 'view about description diff'}, 'diff'), ' '] : '', this.c.type === 'gathering' ? [ h('a', {href: this.render.toUrl('/about/' + encodeURIComponent(this.msg.key))}, 'about'), ' '] : '', this.c.type === 'ssb-igo' && (lastMove = this.c.values[0] && this.c.values[0].lastMove) ? [ diff --git a/lib/serve.js b/lib/serve.js index f975f4b..d87880c 100644 --- a/lib/serve.js +++ b/lib/serve.js @@ -386,6 +386,7 @@ Serve.prototype.path = function (url) { case '/npm-registry': return this.npmRegistry(m[2]) case '/markdown': return this.markdown(m[2]) case '/edit-diff': return this.editDiff(m[2]) + case '/about-diff': return this.aboutDiff(m[2]) case '/shard': return this.shard(m[2]) case '/zip': return this.zip(m[2]) case '/web': return this.web(m[2]) @@ -3837,14 +3838,14 @@ Serve.prototype.editDiff = function (url) { return pull( ph('section', {}, [ 'diff: ', - ph('a', {href: self.app.render.toUrl(id)}, id.substr(0, 8) + '…'), + ph('a', {href: self.app.render.toUrl(id)}, ph('code', id.substr(0, 8) + '…')), u.readNext(function (cb) { self.getMsgDecryptedMaybeOoo(id, function (err, msg) { if (err) return cb(null, pull.once(u.renderError(err).outerHTML)) var c = msg.value.content || {} self.getMsgDecryptedMaybeOoo(c.updated, function (err, oldMsg) { if (err) return cb(null, pull.once(u.renderError(err).outerHTML)) - cb(null, self.postEditDiffTable(oldMsg, msg)) + cb(null, self.textEditDiffTable(oldMsg, msg)) }) }) }) @@ -3854,10 +3855,99 @@ Serve.prototype.editDiff = function (url) { ) } -Serve.prototype.postEditDiffTable = function (oldMsg, newMsg) { +function findMsg(msgs, id) { + for (var i = 0; i < msgs.length; i++) { + if (msgs[i].key === id) return i + } + return -1 +} + +Serve.prototype.aboutDiff = function (url) { + var self = this + var id + try { + id = decodeURIComponent(url.substr(1)) + } catch(err) { + return pull( + pull.once(u.renderError(err).outerHTML), + self.wrapPage('diff: ' + id), + self.respondSink(400) + ) + } + return pull( + ph('section', {}, [ + 'diff: ', + ph('a', {href: self.app.render.toUrl(id)}, ph('code', id.substr(0, 8) + '…')), + u.readNext(function (cb) { + // About messages don't always include branch links. So get the whole thread + // and use ssb-sort to find what to consider the previous message(s). + self.getMsgDecryptedMaybeOoo(id, function (err, msg) { + if (err) return cb(null, pull.once(u.renderError(err).outerHTML)) + var c = msg.value.content || {} + var rootId = c.about + if (!rootId) return gotLinks(new Error('Missing about root')) + var msgDate = new Date(msg.value.timestamp) + cb(null, ph('div', [ + self.phIdLink(msg.value.author), ' ', + ph('span', {title: msgDate.toLocaleString()}, htime(msgDate)), + ph('div', u.readNext(next.bind(this, rootId, msg))) + ])) + }) + }) + ]), + self.wrapPage('diff: ' + id), + self.respondSink(200) + ) + + function next(rootId, msg, cb) { + pull( + self.app.getLinks(rootId), + pull.unique('key'), + self.app.unboxMessages(), + pull.collect(function (err, links) { + if (err) return gotLinks(err) + if (!self.useOoo) return gotLinks(null, links) + self.app.expandOoo({msgs: links, dest: id}, gotLinks) + }) + ) + function gotLinks(err, links) { + if (err) return cb(null, pull.once(u.renderError(err).outerHTML)) + + sort(links) + links = links.filter(function (msg) { + var c = msg && msg.value && msg.value.content + return c && c.type === 'about' && c.about === rootId + && typeof c.description === 'string' + }) + var i = findMsg(links, id) + if (i < 0) return cb(null, ph('div', 'Unable to find previous message')) + var prevMsg = links[i-1] + var nextMsg = links[i+1] + var prevHref = prevMsg ? + self.app.render.toUrl('/about-diff/' + encodeURIComponent(prevMsg.key)) : null + var nextHref = nextMsg ? + self.app.render.toUrl('/about-diff/' + encodeURIComponent(nextMsg.key)) : null + cb(null, cat([ + prevMsg + ? pull.values(['prev: ', ph('a', {href: prevHref}, ph('code', + prevMsg.key.substr(0, 8) + '…')), ', ']) + : pull.empty(), + nextMsg + ? pull.values(['next: ', ph('a', {href: nextHref}, ph('code', + nextMsg.key.substr(0, 8) + '…'))]) + : pull.empty(), + prevMsg ? self.textEditDiffTable(prevMsg, msg) : pull.empty() + ])) + } + } +} + +Serve.prototype.textEditDiffTable = function (oldMsg, newMsg) { var oldC = oldMsg.value.content || {} var newC = newMsg.value.content || {} - var diff = Diff.structuredPatch('', '', String(oldC.text), String(newC.text)) + var oldText = String(oldC.text || oldC.description) + var newText = String(newC.text || newC.description) + var diff = Diff.structuredPatch('', '', oldText, newText) var self = this return pull( ph('table', [ -- cgit v1.2.3