diff options
-rw-r--r-- | lib/render-msg.js | 49 | ||||
-rw-r--r-- | lib/serve.js | 77 | ||||
-rw-r--r-- | lib/util.js | 7 |
3 files changed, 121 insertions, 12 deletions
diff --git a/lib/render-msg.js b/lib/render-msg.js index 08eb03e..d21f095 100644 --- a/lib/render-msg.js +++ b/lib/render-msg.js @@ -158,6 +158,9 @@ RenderMsg.prototype.actions = function () { this.msg.rel ? [this.msg.rel, ' '] : '', this.opts.withGt && this.msg.timestamp ? [ h('a', {href: '?gt=' + this.msg.timestamp}, '↓'), ' '] : '', + this.c.type === 'edit' ? [ + h('a', {href: this.toUrl('/edit-diff/' + encodeURIComponent(this.msg.key)), + title: 'view post edit diff'}, 'diff'), ' '] : '', this.c.type === 'gathering' ? [ h('a', {href: this.render.toUrl('/about/' + encodeURIComponent(this.msg.key))}, 'about'), ' '] : '', /^(ssb_)?chess_/.test(this.c.type) ? [ @@ -300,6 +303,7 @@ RenderMsg.prototype.message = function (cb) { case 'scat_message': return this.scat(cb) case 'share': return this.share(cb) case 'tag': return this.tag(cb) + case 'edit': return this.edit(cb) default: return this.object(cb) } } @@ -346,6 +350,33 @@ RenderMsg.prototype.post = function (cb) { }) } +RenderMsg.prototype.edit = function (cb) { + var self = this + var done = multicb({pluck: 1, spread: true}) + if (self.c.root === self.c.branch) done()() + else self.link(self.c.root, done()) + self.links(self.c.branch, done()) + self.links(self.c.fork, done()) + self.link(self.c.original, done()) + if (self.c.updated === self.c.branch) done()() + else self.link(self.c.updated, done()) + done(function (err, rootLink, branchLinks, forkLinks, originalLink, updatedLink) { + if (err) return self.wrap(u.renderError(err), cb) + self.wrap(h('div.ssb-post', + h('div', 'edit ', originalLink || ''), + rootLink ? h('div', h('small', h('span.symbol', '→'), ' ', rootLink)) : '', + updatedLink ? h('div', h('small', h('span.symbol', ' ↳'), ' ', updatedLink)) : '', + branchLinks.map(function (a, i) { + return h('div', h('small', h('span.symbol', ' ↳'), ' ', a)) + }), + forkLinks.map(function (a, i) { + return h('div', h('small', h('span.symbol', '⑂'), ' ', a)) + }), + h('blockquote.ssb-post-text', {innerHTML: self.markdown()}) + ), cb) + }) +} + RenderMsg.prototype.vote = function (cb) { var self = this var v = self.c.vote || self.c.like || {} @@ -613,7 +644,7 @@ RenderMsg.prototype.aboutRating = function (cb) { var el = h('div', {title: text}) for (var i = 0; i < rating; i++) { el.appendChild(h('span', - {innerHTML: unwrapP(this.render.markdown(type) + ' ')} + {innerHTML: u.unwrapP(this.render.markdown(type) + ' ')} )) } return el @@ -1010,7 +1041,7 @@ RenderMsg.prototype.mutualCredit = function (cb) { ? h('a', {href: self.toUrl(currency)}, currency) : h('ins', currency), self.c.memo ? [' for ', - h('q', {innerHTML: unwrapP(self.render.markdown(self.c.memo))}) + h('q', {innerHTML: u.unwrapP(self.render.markdown(self.c.memo))}) ] : '' ], cb) }) @@ -1024,14 +1055,8 @@ RenderMsg.prototype.gathering = function (cb) { this.wrapMini('gathering', cb) } -function unwrapP(html) { - return String(html).replace(/^<p>(.*)<\/p>\s*$/, function ($0, $1) { - return $1 - }) -} - RenderMsg.prototype.micro = function (cb) { - var el = h('span', {innerHTML: unwrapP(this.markdown())}) + var el = h('span', {innerHTML: u.unwrapP(this.markdown())}) this.wrapMini(el, cb) } @@ -1087,7 +1112,7 @@ RenderMsg.prototype.npmPublish = function (cb) { ), pkgDescription ? h('div', // TODO: make mdInline use custom emojis - h('q', {innerHTML: unwrapP(render.markdown(pkgDescription))})) : '', + h('q', {innerHTML: u.unwrapP(render.markdown(pkgDescription))})) : '', prevLinks.length ? h('div', 'previous: ', prevLinks) : '', pkgReadme && pkgReadme !== singleReadme ? h('blockquote', {innerHTML: render.markdown(pkgReadme)}) : '', @@ -1748,8 +1773,8 @@ RenderMsg.prototype.poll = function (cb) { var details = self.c.pollDetails || self.c.details || {} var choices = u.toArray(details.choices) return self.wrap(h('div', - h('h3', {innerHTML: unwrapP(self.render.markdown(self.c.title))}), - h('div', {innerHTML: unwrapP(self.render.markdown(self.c.body, self.c.mentions))}), + h('h3', {innerHTML: u.unwrapP(self.render.markdown(self.c.title))}), + h('div', {innerHTML: u.unwrapP(self.render.markdown(self.c.body, self.c.mentions))}), h('p', 'closes at: ', h('span', { title: closeDate.toLocaleString() }, closeDate.toString())), diff --git a/lib/serve.js b/lib/serve.js index db99b49..b0e1267 100644 --- a/lib/serve.js +++ b/lib/serve.js @@ -376,6 +376,7 @@ Serve.prototype.path = function (url) { case '/npm-readme': return this.npmReadme(m[2]) case '/npm-registry': return this.npmRegistry(m[2]) case '/markdown': return this.markdown(m[2]) + case '/edit-diff': return this.editDiff(m[2]) case '/zip': return this.zip(m[2]) case '/web': return this.web(m[2]) } @@ -3466,3 +3467,79 @@ Serve.prototype.emojis = function (path) { this.respondSink(200) ) } + +Serve.prototype.editDiff = function (url) { + var self = this + var id + try { + id = decodeURIComponent(url.substr(1)) + } catch(err) { + return ph('div', u.renderError(err).outerHTML) + } + return pull( + ph('section', {}, [ + 'diff: ', + ph('a', {href: self.app.render.toUrl(id)}, 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)) + }) + }) + }) + ]), + self.wrapPage('diff: ' + id), + self.respondSink(200) + ) +} + +Serve.prototype.postEditDiffTable = function (oldMsg, newMsg) { + var oldC = oldMsg.value.content || {} + var newC = newMsg.value.content || {} + var diff = Diff.structuredPatch('', '', String(oldC.text), String(newC.text)) + var self = this + return pull( + ph('table', [ + pull( + pull.values(diff.hunks), + pull.map(function (hunk) { + var oldLine = hunk.oldStart + var newLine = hunk.newStart + return [ + ph('tr', [ + ph('td', {colspan: 2}), + ph('td', ph('pre', + '@@ -' + oldLine + ',' + hunk.oldLines + ' ' + + '+' + newLine + ',' + hunk.newLines + ' @@')) + ]), + pull( + pull.values(hunk.lines), + pull.map(function (line) { + var s = line[0] + if (s == '\\') return + var lineNums = [s == '+' ? '' : oldLine++, s == '-' ? '' : newLine++] + return [ + ph('tr', { + class: s == '+' ? 'diff-new' : s == '-' ? 'diff-old' : '' + }, [ + lineNums.map(function (num, i) { + return ph('td', String(num)) + }), + ph('td', [ + ph('code', s), + u.unwrapP(self.app.render.markdown(line.substr(1), + s == '-' ? oldC.mentions : newC.mentions)) + ]) + ]) + ] + }) + ) + ] + }) + ) + ]) + ) +} diff --git a/lib/util.js b/lib/util.js index b80ea04..9f17966 100644 --- a/lib/util.js +++ b/lib/util.js @@ -226,3 +226,10 @@ u.rows = function (str) { u.token = function () { return '__' + Math.random().toString(36).substr(2) + '__' } + +u.unwrapP = function(html) { + return String(html).replace(/^<p>(.*)<\/p>\s*$/, function ($0, $1) { + return $1 + }) +} + |