Files: 3fa3e23c4b756580c6cf49253941a9e7d55b9023 / message / obs / shares.js
2417 bytesRaw
1 | var nest = require('depnest') |
2 | var ref = require('ssb-ref') |
3 | var MutantArray = require('mutant/array') |
4 | var concat = require('mutant/concat') |
5 | |
6 | var { computed } = require('mutant') |
7 | |
8 | exports.needs = nest({ |
9 | 'message.sync.unbox': 'first', |
10 | 'backlinks.obs.for': 'first' |
11 | }) |
12 | |
13 | exports.gives = nest({ |
14 | 'sbot.hook.publish': true, |
15 | 'message.obs.shares': true |
16 | }) |
17 | |
18 | function isShare(c) { |
19 | if (c.type !== 'share') return false |
20 | |
21 | if (!c.share || !c.share.link || !ref.isMsg(c.share.link) || !c.share.hasOwnProperty('text')) { |
22 | return false |
23 | } |
24 | |
25 | return true |
26 | } |
27 | |
28 | exports.create = function (api) { |
29 | var activeShares = new Set() |
30 | return nest({ |
31 | 'sbot.hook.publish': (msg) => { |
32 | if (!(msg && msg.value && msg.value.content)) return |
33 | if (typeof msg.value.content === 'string') { |
34 | msg = api.message.sync.unbox(msg) |
35 | if (!msg) return |
36 | } |
37 | |
38 | var c = msg.value.content |
39 | if (c.type !== 'share') return |
40 | if (!isShare(c)) return |
41 | |
42 | activeShares.forEach((shares) => { |
43 | if (shares.id === c.share.link) { |
44 | shares.push(msg) |
45 | } |
46 | }) |
47 | }, |
48 | 'message.obs.shares': (id) => { |
49 | if (!ref.isLink(id)) throw new Error('an id must be specified') |
50 | var obs = get(id) |
51 | obs.id = id |
52 | var result = computed(obs, getShares, { |
53 | // allow manual append for simulated realtime |
54 | onListen: () => activeShares.add(obs), |
55 | onUnlisten: () => activeShares.delete(obs) |
56 | }) |
57 | result.sync = obs.sync |
58 | return result |
59 | } |
60 | }) |
61 | |
62 | function get(id) { |
63 | var backlinks = api.backlinks.obs.for(id) |
64 | var merge = MutantArray() |
65 | |
66 | var shares = computed([backlinks.sync, concat([backlinks, merge])], (sync, backlinks) => { |
67 | if (sync) { |
68 | return backlinks.reduce((result, msg) => { |
69 | var c = msg.value.content |
70 | if (isShare(c) && c.share.link === id) { |
71 | var value = result[msg.value.author] |
72 | if (!value || value[0] < msg.value.timestamp) { |
73 | result[msg.value.author] = [msg.value.timestamp, c.share.text] |
74 | } |
75 | } |
76 | return result |
77 | }, {}) |
78 | } else { |
79 | return {} |
80 | } |
81 | }) |
82 | |
83 | shares.push = merge.push |
84 | shares.sync = backlinks.sync |
85 | return shares |
86 | } |
87 | } |
88 | |
89 | function getShares(shares) { |
90 | return Object.keys(shares).reduce((result, id) => { |
91 | if (shares[id].length >= 1) { |
92 | result.push(id) |
93 | } |
94 | return result |
95 | }, []) |
96 | } |
Built with git-ssb-web