From 5119a5de3b2bba836f2847ca18227c14baf2b629 Mon Sep 17 00:00:00 2001 From: cel Date: Fri, 13 Oct 2017 13:18:56 -1000 Subject: Filter messages socially --- lib/app.js | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/render-msg.js | 9 ++++++ lib/render.js | 7 ++++- lib/serve.js | 43 +++++++++++++++++++++------- 4 files changed, 134 insertions(+), 11 deletions(-) (limited to 'lib') diff --git a/lib/app.js b/lib/app.js index 5cc4e62..3db24b8 100644 --- a/lib/app.js +++ b/lib/app.js @@ -48,6 +48,8 @@ function App(sbot, config) { this.reverseEmojiNameCache = lru(500) this.getBlobSize = memo({cache: this.blobSizeCache = lru(100)}, sbot.blobs.size.bind(sbot.blobs)) + this.getFollows = memo(this._getFollows.bind(this)) + this.getVotes = memo({cache: lru(100)}, this._getVotes.bind(this)) this.unboxMsg = this.unboxMsg.bind(this) @@ -671,3 +673,87 @@ App.prototype.getNpmReadme = function (tarballId, cb) { cb(null, text, true) }) } + +App.prototype.filterMsg = function (msg, opts, cb) { + var self = this + var myId = self.sbot.id + var author = msg.value && msg.value.author + var show = (opts.filter !== 'invert') + if (opts.filter === 'all' + || author === myId + || author === opts.feed + || msg.key === opts.msgId) return cb(null, show) + self.getFollows(myId, function (err, follows) { + if (err) return cb(err) + if (follows[author]) return cb(null, show) + self.getVotes(msg.key, function (err, votes) { + if (err) return cb(err) + for (var author in votes) { + if (follows[author] && votes[author] > 0) { + return cb(null, show) + } + } + return cb(null, !show) + }) + }) +} + +App.prototype.isFollowing = function (src, dest, cb) { + var self = this + self.getFollows(src, function (err, follows) { + if (err) return cb(err) + return cb(null, follows[dest]) + }) +} + +App.prototype._getFollows = function (id, cb) { + var follows = {} + function ready(err) { + if (!cb) return + var _cb = cb + cb = null + _cb(err, follows) + } + pull( + this.sbot.links2.read({ + live: true, + query: [ + {$filter: { + source: id, + rel: [{$prefix: 'contact'}] + }}, + {$map: { + following: ['rel', 1], + feed: 'dest' + }} + ] + }), + pull.drain(function (link) { + if (link.sync) return ready() + follows[link.feed] = link.following + }, ready) + ) +} + +App.prototype._getVotes = function (id, cb) { + var votes = {} + pull( + this.sbot.links2.read({ + query: [ + {$filter: { + dest: id, + rel: [{$prefix: 'vote'}] + }}, + {$map: { + value: ['rel', 1], + author: 'source' + }} + ] + }), + pull.drain(function (vote) { + votes[vote.author] = vote.value + }, function (err) { + cb(err, votes) + }) + ) +} diff --git a/lib/render-msg.js b/lib/render-msg.js index 8ba45eb..2d52c83 100644 --- a/lib/render-msg.js +++ b/lib/render-msg.js @@ -351,6 +351,15 @@ function title(str) { } RenderMsg.prototype.title = function (cb) { + var self = this + self.app.filterMsg(self.msg, self.opts, function (err, show) { + if (err) return cb(err) + if (show) self.title1(cb) + else cb(null, '[…]') + }) +} + +RenderMsg.prototype.title1 = function (cb) { var self = this if (!self.c || typeof self.c !== 'object') { cb(null, self.msg.key) diff --git a/lib/render.js b/lib/render.js index df7d378..a86bd92 100644 --- a/lib/render.js +++ b/lib/render.js @@ -304,7 +304,12 @@ Render.prototype.msgLink = function (msg, cb) { } Render.prototype.renderMsg = function (msg, opts, cb) { - new RenderMsg(this, this.app, msg, opts).message(cb) + var self = this + self.app.filterMsg(msg, opts, function (err, show) { + if (err) return cb(err) + if (show) new RenderMsg(self, self.app, msg, opts).message(cb) + else cb(null, '') + }) } Render.prototype.renderFeeds = function (opts) { diff --git a/lib/serve.js b/lib/serve.js index 75356a9..b8c296e 100644 --- a/lib/serve.js +++ b/lib/serve.js @@ -344,7 +344,8 @@ Serve.prototype.public = function (ext) { sortByTimestamp: q.sort === 'claimed', lt: Number(q.lt) || Date.now(), gt: Number(q.gt) || -Infinity, - limit: Number(q.limit) || 12 + limit: Number(q.limit) || 12, + filter: q.filter, } pull( @@ -397,7 +398,7 @@ Serve.prototype.new = function (ext) { }, -Infinity) pull( pull.values(msgs), - self.renderThread(opts, null, q), + self.renderThread(), self.wrapNew({ gt: isFinite(maxTS) ? maxTS : Date.now() }), @@ -417,6 +418,7 @@ Serve.prototype.private = function (ext) { lt: Number(q.lt) || Date.now(), gt: Number(q.gt) || -Infinity, limit: Number(q.limit) || 12, + filter: q.filter, } pull( @@ -440,6 +442,7 @@ Serve.prototype.mentions = function (ext) { lt: Number(q.lt) || Date.now(), gt: Number(q.gt) || -Infinity, limit: Number(q.limit) || 12, + filter: q.filter, } return pull( @@ -522,7 +525,9 @@ Serve.prototype.advsearch = function (ext) { ]), hasQuery && pull( self.app.advancedSearch(q), - self.renderThread(), + self.renderThread({ + feed: q.source, + }), self.wrapMessages() ) ]), @@ -548,6 +553,7 @@ Serve.prototype.live = function (ext) { self.app.sbot.createLogStream(opts), self.app.render.renderFeeds({ withGt: true, + filter: q.filter, }), pull.map(u.toHTML) )), @@ -900,6 +906,7 @@ Serve.prototype.type = function (path) { gt: Number(q.gt) || -Infinity, limit: Number(q.limit) || 12, type: type, + filter: q.filter, } pull( @@ -926,7 +933,7 @@ Serve.prototype.links = function (path) { pull( this.app.sbot.links(opts), - this.renderThread(opts, null, q), + this.renderThread(), this.wrapMessages(), this.wrapLinks(dest), this.wrapPage('links: ' + dest), @@ -965,6 +972,7 @@ Serve.prototype.channel = function (path) { gt: gt, limit: Number(q.limit) || 12, channel: channel, + filter: q.filter, } pull( @@ -1013,7 +1021,9 @@ Serve.prototype.id = function (id, path) { if (err) return self.respond(500, err.stack || err) pull( pull.values(sort(links)), - self.renderThread(), + self.renderThread({ + msgId: id, + }), self.wrapMessages(), self.wrapThread({ recps: recps, @@ -1039,7 +1049,9 @@ Serve.prototype.userFeed = function (id, path) { reverse: !q.forwards, lt: Number(q.lt) || Date.now(), gt: Number(q.gt) || -Infinity, - limit: Number(q.limit) || 20 + limit: Number(q.limit) || 20, + feed: id, + filter: q.filter, } var isScrolled = q.lt || q.gt @@ -1215,9 +1227,15 @@ Serve.prototype.wrapMessages = function () { }) } -Serve.prototype.renderThread = function () { +Serve.prototype.renderThread = function (opts) { return pull( - this.app.render.renderFeeds({raw: false, full: this.query.full != null}), + this.app.render.renderFeeds({ + raw: false, + full: this.query.full != null, + feed: opts.feed, + msgId: opts.msgId, + filter: this.query.filter, + }), pull.map(u.toHTML) ) } @@ -1258,7 +1276,7 @@ Serve.prototype.renderThreadPaginated = function (opts, feedId, q) { })) } }, - this.app.render.renderFeeds(), + this.app.render.renderFeeds(opts), function onLast(msg, cb) { var num = feedId ? msg.value.sequence : opts.sortByTimestamp ? msg.value.timestamp : @@ -1303,6 +1321,8 @@ Serve.prototype.renderRawMsgPage = function (id) { return pull( this.app.render.renderFeeds({ raw: raw, + msgId: id, + filter: this.query.filter, markdownSource: showMarkdownSource }), pull.map(u.toHTML), @@ -2578,7 +2598,10 @@ Serve.prototype.composer = function (opts, cb) { pull( pull.once(msg), self.app.unboxMessages(), - self.app.render.renderFeeds(raw), + self.app.render.renderFeeds({ + raw: raw, + filter: self.query.filter, + }), pull.drain(function (el) { msgContainer.appendChild(h('tbody', el)) }, cb) -- cgit v1.2.3