Files: b89cb9e2e4c5564ad3803cee6f962ec8e65e8018 / lib / contacts.js
5496 bytesRaw
1 | var pull = require('pull-stream') |
2 | var defer = require('pull-defer') |
3 | var many = require('pull-many') |
4 | |
5 | module.exports = Contacts |
6 | |
7 | function Contacts(sbot) { |
8 | if (!(this instanceof Contacts)) return new Contacts(sbot) |
9 | this.sbot = sbot |
10 | } |
11 | |
12 | Contacts.prototype._createContactStream = function (source, dest) { |
13 | if (!this.sbot.links) return pull.error(new Error('missing sbot.links')) |
14 | return pull( |
15 | this.sbot.links({ |
16 | source: source, |
17 | dest: dest, |
18 | rel: 'contact', |
19 | values: true, |
20 | reverse: true |
21 | }), |
22 | pull.filter(function (msg) { |
23 | var c = msg && msg.value && msg.value.content |
24 | return c && c.type === 'contact' && (!dest || c.contact === dest) |
25 | }), |
26 | pull.map(function (msg) { |
27 | var c = msg && msg.value && msg.value.content |
28 | return { |
29 | source: msg.value.author, |
30 | dest: c.contact, |
31 | msg: msg, |
32 | value: c.following ? true : c.flagged || c.blocking ? false : null |
33 | } |
34 | }), |
35 | pull.unique(function (edge) { |
36 | return edge.source + '-' + edge.dest |
37 | }) |
38 | ) |
39 | } |
40 | |
41 | Contacts.prototype.createFollowsStream = function (id) { |
42 | return pull( |
43 | this._createContactStream(id, null), |
44 | pull.filter('value'), |
45 | pull.map('dest') |
46 | ) |
47 | } |
48 | |
49 | Contacts.prototype.createFollowersStream = function (id) { |
50 | return pull( |
51 | this._createContactStream(null, id), |
52 | pull.filter('value'), |
53 | pull.map('source') |
54 | ) |
55 | } |
56 | |
57 | Contacts.prototype.createFollowedFollowersStream = function (source, dest) { |
58 | var follows = {}, followers = {} |
59 | return pull( |
60 | many([ |
61 | this._createContactStream(source, null), |
62 | this._createContactStream(null, dest) |
63 | ]), |
64 | pull.filter('value'), |
65 | pull.map(function (edge) { |
66 | if (edge.source === source) { |
67 | if (followers[edge.dest]) { |
68 | delete followers[edge.dest] |
69 | return edge.dest |
70 | } else { |
71 | follows[edge.dest] = true |
72 | } |
73 | } else if (edge.dest === dest) { |
74 | if (follows[edge.source]) { |
75 | delete follows[edge.source] |
76 | return edge.source |
77 | } else { |
78 | followers[edge.source] = true |
79 | } |
80 | } |
81 | }), |
82 | pull.filter() |
83 | ) |
84 | } |
85 | |
86 | Contacts.prototype.createFriendsStream = function (opts, endCb) { |
87 | if (typeof opts === 'string') opts = {id: opts} |
88 | var id = opts.id |
89 | var msgIds = opts.msgIds |
90 | var follows = {}, followers = {} |
91 | var blocks = {}, blockers = {} |
92 | var enemies = opts.enemies && {} |
93 | return pull( |
94 | many([ |
95 | this._createContactStream(id, null), |
96 | this._createContactStream(null, id) |
97 | ]), |
98 | pull.map(function (edge) { |
99 | if (edge.value) { |
100 | if (edge.source === id) { |
101 | if (followers[edge.dest]) { |
102 | var item2 = followers[edge.dest] |
103 | delete followers[edge.dest] |
104 | return msgIds ? {feed: edge.dest, msg: edge.msg, msg2: item2.msg} : edge.dest |
105 | } else { |
106 | follows[edge.dest] = msgIds ? {feed: edge.dest, msg: edge.msg} : edge.dest |
107 | } |
108 | } else if (edge.dest === id) { |
109 | if (follows[edge.source]) { |
110 | var item2 = follows[edge.source] |
111 | delete follows[edge.source] |
112 | return msgIds ? {feed: edge.source, msg: edge.msg, msg2: item2.msg} : edge.source |
113 | } else { |
114 | followers[edge.source] = msgIds ? {feed: edge.source, msg: edge.msg} : edge.source |
115 | } |
116 | } |
117 | } else if (edge.value === false) { |
118 | if (edge.source === id) { |
119 | if (enemies && blockers[edge.dest]) { |
120 | var item2 = blockers[edge.dest] |
121 | delete blockers[edge.dest] |
122 | enemies[edge.dest] = msgIds ? {feed: edge.dest, msg: edge.msg, msg2: item2.msg} : edge.dest |
123 | } else { |
124 | blocks[edge.dest] = msgIds ? {feed: edge.dest, msg: edge.msg} : edge.dest |
125 | } |
126 | } else if (edge.dest === id) { |
127 | if (enemies && blocks[edge.source]) { |
128 | var item2 = blocks[edge.source] |
129 | delete blocks[edge.source] |
130 | enemies[edge.source] = msgIds ? {feed: edge.source, msg: edge.msg, msg2: item2.msg} : edge.source |
131 | } else { |
132 | blockers[edge.source] = msgIds ? {feed: edge.source, msg: edge.msg} : edge.source |
133 | } |
134 | } |
135 | } |
136 | }), |
137 | pull.filter(), |
138 | endCb && function (read) { |
139 | return function (abort, cb) { |
140 | read(abort, function (end, data) { |
141 | cb(end, data) |
142 | if (end) endCb(end === true ? null : end, { |
143 | followers: Object.values(followers), |
144 | follows: Object.values(follows), |
145 | blocks: Object.values(blocks), |
146 | blockers: Object.values(blockers), |
147 | enemies: Object.values(enemies), |
148 | }) |
149 | }) |
150 | } |
151 | } |
152 | ) |
153 | } |
154 | |
155 | Contacts.prototype.createContactStreams = function (opts) { |
156 | var msgIds = opts.msgIds |
157 | var follows = defer.source() |
158 | var followers = defer.source() |
159 | var blocks = defer.source() |
160 | var blockers = defer.source() |
161 | var enemies = defer.source() |
162 | var friends = this.createFriendsStream(opts, function (err, more) { |
163 | follows.resolve(err ? pull.error(err) : pull.values(more.follows)) |
164 | followers.resolve(err ? pull.error(err) : pull.values(more.followers)) |
165 | blocks.resolve(err ? pull.error(err) : pull.values(more.blocks)) |
166 | blockers.resolve(err ? pull.error(err) : pull.values(more.blockers)) |
167 | enemies.resolve(err ? pull.error(err) : pull.values(more.enemies)) |
168 | }) |
169 | return { |
170 | friends: friends, |
171 | follows: follows, |
172 | followers: followers, |
173 | enemies: enemies, |
174 | blocks: blocks, |
175 | blockers: blockers, |
176 | } |
177 | } |
178 |
Built with git-ssb-web