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