aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcel <cel@lOUVT+Phkvai9a/cCS/RKo+S9hnPAQdVixms/7ldpPA=.ed25519>2020-03-25 10:57:51 -0400
committercel <cel@lOUVT+Phkvai9a/cCS/RKo+S9hnPAQdVixms/7ldpPA=.ed25519>2020-03-28 13:55:36 -0400
commit4ee97dfaa67cc8ab77bbac574f0d05c6d60f4e37 (patch)
tree7e85d67e0e97c51f5b3d6bfa80b81ee7d61d4b56
parent646e70a38f1daae390271c3ad65c4b6c0d87de5f (diff)
downloadpatchfoo-4ee97dfaa67cc8ab77bbac574f0d05c6d60f4e37.tar.gz
patchfoo-4ee97dfaa67cc8ab77bbac574f0d05c6d60f4e37.zip
Render descriptions as diffs in gathering threads
-rw-r--r--lib/app.js4
-rw-r--r--lib/render-msg.js40
-rw-r--r--lib/render.js44
-rw-r--r--lib/serve.js6
4 files changed, 90 insertions, 4 deletions
diff --git a/lib/app.js b/lib/app.js
index 4fac422..b62a1d2 100644
--- a/lib/app.js
+++ b/lib/app.js
@@ -30,6 +30,10 @@ var zeros = new Buffer(24); zeros.fill(0)
module.exports = App
+function getKey(msg) {
+ return msg && msg.key
+}
+
function App(sbot, config) {
this.sbot = sbot
this.config = config
diff --git a/lib/render-msg.js b/lib/render-msg.js
index 68ea4d7..3a55a3b 100644
--- a/lib/render-msg.js
+++ b/lib/render-msg.js
@@ -19,13 +19,17 @@ function RenderMsg(render, app, msg, opts) {
this.isMissing = !content
this.hasFullLink =
this.c.type === 'chess_move' ||
- this.c.type === 'ssb_chess_move'
+ this.c.type === 'ssb_chess_move' ||
+ (this.c.type === 'about' && this.c.about == this.value.author
+ && typeof this.c.description === 'string')
if (typeof opts === 'boolean') opts = {raw: opts}
this.opts = opts || {}
this.shouldWrap = this.opts.wrap !== false
var ts = this.value.timestamp
this.date = ts ? new Date(ts) : null
+ this.thread = opts.links || []
+ this.single = opts.single
}
RenderMsg.prototype.getMsg = function (id, cb) {
@@ -645,6 +649,7 @@ var knownAboutProps = {
}
RenderMsg.prototype.about = function (cb) {
+ var self = this
var keys = Object.keys(this.c).filter(function (k) {
return k !== 'about' && k !== 'type' && k !== 'recps'
}).sort().join()
@@ -702,6 +707,15 @@ RenderMsg.prototype.about = function (cb) {
var target = this.c.about
var pwh = this.c.publicWebHosting
+ function descriptionOrDiff(cb) {
+ // show diff for self-description and gathering thread.
+ // otherwise it might require a more expensive query
+ var prevMsg = !self.opts.full && self.getPreviousAboutInThreadSync()
+ cb()
+ if (prevMsg) return self.render.textEditDiffTable(prevMsg, self.msg)
+ return h('div', {innerHTML: self.render.markdown(self.c.description)})
+ }
+
this.wrap([
this.c.root && this.c.root !== target ? h('div',
h('small', '→ ', this.link1(this.c.root, done()))
@@ -731,8 +745,7 @@ RenderMsg.prototype.about = function (cb) {
]) : '',
this.c.genre ? h('div', ['genre: ', h('u', u.toString(this.c.genre))]) : '',
this.c.shelve ? h('div', ['shelf: ', h('u', u.toString(this.c.shelve))]) : '',
- this.c.description ? h('div',
- {innerHTML: this.render.markdown(this.c.description)}) : '',
+ this.c.description ? descriptionOrDiff(done()) : '',
this.c.review ? h('blockquote',
{innerHTML: this.render.markdown(this.c.review)}) : '',
this.c.attendee ? h('div',
@@ -763,6 +776,27 @@ RenderMsg.prototype.about = function (cb) {
done(cb)
}
+RenderMsg.prototype.getPreviousAboutInThreadSync = function () {
+ var self = this
+ var root = this.thread[0]
+ if (!root) return
+ if (this.c.about !== root.key) {
+ // probably won't work
+ return
+ }
+ var i = this.thread.indexOf(this.msg)
+ var target = this.c.about
+ if (i === -1) return
+ for (var j = i-1; j >= 0; j--) {
+ var msg = this.thread[j]
+ var c = msg && msg.value && msg.value.content
+ if (c && c.type === 'about' && c.about === target
+ && typeof c.description === 'string') {
+ return msg
+ }
+ }
+}
+
RenderMsg.prototype.aboutRating = function (cb) {
var rating = Number(this.c.rating)
var max = Number(this.c.ratingMax)
diff --git a/lib/render.js b/lib/render.js
index 5d8fd66..7c2cf64 100644
--- a/lib/render.js
+++ b/lib/render.js
@@ -13,6 +13,7 @@ var multicb = require('multicb')
var RenderMsg = require('./render-msg')
var Highlight = require('highlight.js')
var md = require('ssb-markdown')
+var Diff = require('diff')
module.exports = Render
@@ -719,3 +720,46 @@ Render.prototype.friendsList = function (prefix) {
}
)
}
+
+Render.prototype.textEditDiffTable = function (oldMsg, newMsg) {
+ var oldC = oldMsg && oldMsg.value.content || {}
+ var newC = newMsg && newMsg.value.content || {}
+ var oldText = String(oldC.text || oldC.description || '')
+ var newText = String(newC.text || newC.description || '')
+ var diff = Diff.structuredPatch('', '', oldText, newText)
+ var self = this
+ return h('table', [
+ diff.hunks.map(function (hunk) {
+ var oldLine = hunk.oldStart
+ var newLine = hunk.newStart
+ return [
+ h('tr', [
+ h('td', {colspan: 2}),
+ h('td', h('pre',
+ '@@ -' + oldLine + ',' + hunk.oldLines + ' ' +
+ '+' + newLine + ',' + hunk.newLines + ' @@'))
+ ]),
+ hunk.lines.map(function (line) {
+ var s = line[0]
+ if (s == '\\') return
+ var lineNums = [s == '+' ? '' : oldLine++, s == '-' ? '' : newLine++]
+ return [
+ h('tr', {
+ class: s == '+' ? 'diff-new' : s == '-' ? 'diff-old' : ''
+ }, [
+ lineNums.map(function (num, i) {
+ return h('td', String(num))
+ }),
+ h('td', {innerHTML:
+ h('code', s).outerHTML +
+ u.unwrapP(self.markdown(line.substr(1),
+ s == '-' ? oldC.mentions : newC.mentions))
+ })
+ ])
+ ]
+ })
+ ]
+ })
+ ])
+}
+
diff --git a/lib/serve.js b/lib/serve.js
index e593f64..c35d4c9 100644
--- a/lib/serve.js
+++ b/lib/serve.js
@@ -1927,6 +1927,7 @@ Serve.prototype.streamThreadWithComposer = function (opts) {
self.renderThread({
msgId: id,
branches: branches,
+ links: links,
}),
self.wrapMessages(),
self.wrapThread({
@@ -1950,7 +1951,8 @@ Serve.prototype.streamMsg = function (id) {
return pull(
self.app.pullGetMsg(id),
self.renderThread({
- msgId: id
+ msgId: id,
+ single: self.query.single != null
}),
self.wrapMessages()
)
@@ -2236,6 +2238,8 @@ Serve.prototype.renderThread = function (opts) {
filter: this.query.filter,
limit: Number(this.query.limit),
serve: this,
+ links: opts && opts.links,
+ single: opts && opts.single,
branches: opts && opts.branches,
}),
pull.map(u.toHTML)