aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcel <cel@f/6sQ6d2CMxRUhLpspgGIulDxDCwYD7DzFzPNr7u5AU=.ed25519>2017-10-13 13:18:56 -1000
committercel <cel@f/6sQ6d2CMxRUhLpspgGIulDxDCwYD7DzFzPNr7u5AU=.ed25519>2017-10-13 13:18:56 -1000
commit5119a5de3b2bba836f2847ca18227c14baf2b629 (patch)
treea0d92d2a17c27bd0cb7ca372718d44852547c1cf
parent7afbbc3ef5ed319fedcc079b860705ff63fa862d (diff)
downloadpatchfoo-5119a5de3b2bba836f2847ca18227c14baf2b629.tar.gz
patchfoo-5119a5de3b2bba836f2847ca18227c14baf2b629.zip
Filter messages socially
-rw-r--r--lib/app.js86
-rw-r--r--lib/render-msg.js9
-rw-r--r--lib/render.js7
-rw-r--r--lib/serve.js43
4 files changed, 134 insertions, 11 deletions
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
@@ -352,6 +352,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)
} else if (typeof self.c.text === 'string') {
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)