Files: e0439586cabe63fc84e88ff400edb18470cdec52 / message / obs / likes.js
2243 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.likes': true |
16 | }) |
17 | |
18 | exports.create = function (api) { |
19 | var activeLikes = new Set() |
20 | return nest({ |
21 | 'sbot.hook.publish': (msg) => { |
22 | if (!(msg && msg.value && msg.value.content)) return |
23 | if (typeof msg.value.content === 'string') { |
24 | msg = api.message.sync.unbox(msg) |
25 | if (!msg) return |
26 | } |
27 | |
28 | var c = msg.value.content |
29 | if (c.type !== 'vote') return |
30 | if (!c.vote || !c.vote.link) return |
31 | |
32 | activeLikes.forEach((likes) => { |
33 | if (likes.id === c.vote.link) { |
34 | likes.push(msg) |
35 | } |
36 | }) |
37 | }, |
38 | 'message.obs.likes': (id) => { |
39 | if (!ref.isLink(id)) throw new Error('an id must be specified') |
40 | var obs = get(id) |
41 | obs.id = id |
42 | var result = computed(obs, getLikes, { |
43 | // allow manual append for simulated realtime |
44 | onListen: () => activeLikes.add(obs), |
45 | onUnlisten: () => activeLikes.delete(obs) |
46 | }) |
47 | result.sync = obs.sync |
48 | return result |
49 | } |
50 | }) |
51 | |
52 | function get (id) { |
53 | var backlinks = api.backlinks.obs.for(id) |
54 | var merge = MutantArray() |
55 | |
56 | var likes = computed([backlinks.sync, concat([backlinks, merge])], (sync, backlinks) => { |
57 | if (sync) { |
58 | return backlinks.reduce((result, msg) => { |
59 | var c = msg.value.content |
60 | if (c.type === 'vote' && c.vote && c.vote.link === id) { |
61 | var value = result[msg.value.author] |
62 | if (!value || value[0] < msg.value.timestamp) { |
63 | result[msg.value.author] = [msg.value.timestamp, c.vote.value, c.vote.expression] |
64 | } |
65 | } |
66 | return result |
67 | }, {}) |
68 | } else { |
69 | return {} |
70 | } |
71 | }) |
72 | |
73 | likes.push = merge.push |
74 | likes.sync = backlinks.sync |
75 | return likes |
76 | } |
77 | } |
78 | |
79 | function getLikes (likes) { |
80 | return Object.keys(likes).reduce((result, id) => { |
81 | if (likes[id][1] > 0) { |
82 | result.push(id) |
83 | } |
84 | return result |
85 | }, []) |
86 | } |
87 |
Built with git-ssb-web