aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/app.js2
-rw-r--r--lib/contacts.js159
-rw-r--r--lib/render.js12
-rw-r--r--lib/serve.js2
4 files changed, 170 insertions, 5 deletions
diff --git a/lib/app.js b/lib/app.js
index d895fa7..b49b378 100644
--- a/lib/app.js
+++ b/lib/app.js
@@ -6,7 +6,7 @@ var u = require('./util')
var pull = require('pull-stream')
var multicb = require('multicb')
var paramap = require('pull-paramap')
-var Contacts = require('ssb-contact')
+var Contacts = require('./contacts')
var PrivateBox = require('private-box')
var About = require('./about')
var Follows = require('./follows')
diff --git a/lib/contacts.js b/lib/contacts.js
new file mode 100644
index 0000000..846cdf9
--- /dev/null
+++ b/lib/contacts.js
@@ -0,0 +1,159 @@
+var pull = require('pull-stream')
+var defer = require('pull-defer')
+var many = require('pull-many')
+
+module.exports = Contacts
+
+function Contacts(sbot) {
+ if (!(this instanceof Contacts)) return new Contacts(sbot)
+ this.sbot = sbot
+}
+
+Contacts.prototype._createContactStream = function (source, dest) {
+ return pull(
+ this.sbot.links({
+ source: source,
+ dest: dest,
+ rel: 'contact',
+ values: true,
+ reverse: true
+ }),
+ pull.filter(function (msg) {
+ var c = msg && msg.value && msg.value.content
+ return c && c.type === 'contact' && (!dest || c.contact === dest)
+ }),
+ pull.map(function (msg) {
+ var c = msg && msg.value && msg.value.content
+ return {
+ source: msg.value.author,
+ dest: c.contact,
+ msg: msg,
+ value: c.following ? true : c.flagged || c.blocking ? false : null
+ }
+ }),
+ pull.unique(function (edge) {
+ return edge.source + '-' + edge.dest
+ })
+ )
+}
+
+Contacts.prototype.createFollowsStream = function (id) {
+ return pull(
+ this._createContactStream(id, null),
+ pull.filter('value'),
+ pull.map('dest')
+ )
+}
+
+Contacts.prototype.createFollowersStream = function (id) {
+ return pull(
+ this._createContactStream(null, id),
+ pull.filter('value'),
+ pull.map('source')
+ )
+}
+
+Contacts.prototype.createFollowedFollowersStream = function (source, dest) {
+ var follows = {}, followers = {}
+ return pull(
+ many([
+ this._createContactStream(source, null),
+ this._createContactStream(null, dest)
+ ]),
+ pull.filter('value'),
+ pull.map(function (edge) {
+ if (edge.source === source) {
+ if (followers[edge.dest]) {
+ delete followers[edge.dest]
+ return edge.dest
+ } else {
+ follows[edge.dest] = true
+ }
+ } else if (edge.dest === dest) {
+ if (follows[edge.source]) {
+ delete follows[edge.source]
+ return edge.source
+ } else {
+ followers[edge.source] = true
+ }
+ }
+ }),
+ pull.filter()
+ )
+}
+
+Contacts.prototype.createFriendsStream = function (opts, endCb) {
+ if (typeof opts === 'string') opts = {id: opts}
+ var id = opts.id
+ var msgIds = opts.msgIds
+ var follows = {}, followers = {}
+ var blocks = {}, blockers = {}
+ return pull(
+ many([
+ this._createContactStream(id, null),
+ this._createContactStream(null, id)
+ ]),
+ pull.map(function (edge) {
+ if (edge.value) {
+ if (edge.source === id) {
+ if (followers[edge.dest]) {
+ var item2 = followers[edge.dest]
+ delete followers[edge.dest]
+ return msgIds ? {feed: edge.dest, msg: edge.msg, msg2: item2.msg} : edge.dest
+ } else {
+ follows[edge.dest] = msgIds ? {feed: edge.dest, msg: edge.msg} : edge.dest
+ }
+ } else if (edge.dest === id) {
+ if (follows[edge.source]) {
+ var item2 = follows[edge.source]
+ delete follows[edge.source]
+ return msgIds ? {feed: edge.source, msg: edge.msg, msg2: item2.msg} : edge.source
+ } else {
+ followers[edge.source] = msgIds ? {feed: edge.source, msg: edge.msg} : edge.source
+ }
+ }
+ } else if (edge.value === false) {
+ if (edge.source === id) {
+ blocks[edge.dest] = msgIds ? {feed: edge.dest, msg: edge.msg} : edge.dest
+ } else if (edge.dest === id) {
+ blockers[edge.source] = msgIds ? {feed: edge.source, msg: edge.msg} : edge.source
+ }
+ }
+ }),
+ pull.filter(),
+ endCb && function (read) {
+ return function (abort, cb) {
+ read(abort, function (end, data) {
+ cb(end, data)
+ if (end) endCb(end === true ? null : end, {
+ followers: Object.values(followers),
+ follows: Object.values(follows),
+ blocks: Object.values(blocks),
+ blockers: Object.values(blockers),
+ })
+ })
+ }
+ }
+ )
+}
+
+Contacts.prototype.createContactStreams = function (opts) {
+ var msgIds = opts.msgIds
+ var follows = defer.source()
+ var followers = defer.source()
+ var blocks = defer.source()
+ var blockers = defer.source()
+ var friends = this.createFriendsStream(opts, function (err, more) {
+ follows.resolve(err ? pull.error(err) : pull.values(more.follows))
+ followers.resolve(err ? pull.error(err) : pull.values(more.followers))
+ blocks.resolve(err ? pull.error(err) : pull.values(more.blocks))
+ blockers.resolve(err ? pull.error(err) : pull.values(more.blockers))
+ })
+ return {
+ friends: friends,
+ follows: follows,
+ followers: followers,
+ blocks: blocks,
+ blockers: blockers,
+ }
+}
diff --git a/lib/render.js b/lib/render.js
index 862cfd9..deaf061 100644
--- a/lib/render.js
+++ b/lib/render.js
@@ -612,10 +612,16 @@ Render.prototype.friendsList = function (prefix) {
prefix = prefix || '/'
var self = this
return pull(
- paramap(function (id, cb) {
- self.app.getAbout(id, function (err, about) {
+ paramap(function (item, cb) {
+ if (typeof item === 'string') item = {feed: item}
+ var id = item.feed
+ self.app.getAbout(item.feed, function (err, about) {
var name = about && about.name || id.substr(0, 8) + '…'
- cb(null, h('a', {href: self.toUrl(prefix + id)}, name))
+ cb(null, [
+ h('a', {href: self.toUrl(prefix + id)}, name),
+ item.msg ? h('a', {href: self.toUrl(item.msg.key)}, '₁') : '',
+ item.msg2 ? h('a', {href: self.toUrl(item.msg2.key)}, '₂') : ''
+ ])
})
}, 8),
function (read) {
diff --git a/lib/serve.js b/lib/serve.js
index a58fb1a..0ca35a6 100644
--- a/lib/serve.js
+++ b/lib/serve.js
@@ -879,7 +879,7 @@ Serve.prototype.tags = function (path) {
Serve.prototype.contacts = function (path) {
var self = this
var id = String(path).substr(1)
- var contacts = self.app.contacts.createContactStreams(id)
+ var contacts = self.app.contacts.createContactStreams({id: id, msgIds: true})
var render = self.app.render
pull(