Files: 69e982a06262f72e77dcba72ded0074c435d8a2d / message / obs / likes.js
2549 bytesRaw
1 | var nest = require('depnest') |
2 | var ref = require('ssb-ref') |
3 | var MutantPullReduce = require('mutant-pull-reduce') |
4 | var SortedArray = require('sorted-array-functions') |
5 | |
6 | var { computed } = require('mutant') |
7 | |
8 | exports.needs = nest({ |
9 | 'message.sync.unbox': 'first', |
10 | 'sbot.pull.backlinks': '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({ |
35 | dest: c.vote.link, |
36 | id: msg.key, |
37 | expression: c.vote.expression, |
38 | value: c.vote.value, |
39 | timestamp: msg.value.timestamp, |
40 | author: msg.value.author |
41 | }) |
42 | } |
43 | }) |
44 | }, |
45 | 'message.obs.likes': (id) => { |
46 | if (!ref.isLink(id)) throw new Error('an id must be specified') |
47 | var obs = get(id) |
48 | obs.id = id |
49 | return computed(obs, getLikes, { |
50 | // allow manual append for simulated realtime |
51 | onListen: () => activeLikes.add(obs), |
52 | onUnlisten: () => activeLikes.delete(obs) |
53 | }) |
54 | } |
55 | }) |
56 | |
57 | function get (id) { |
58 | var likes = MutantPullReduce(api.sbot.pull.backlinks({ |
59 | live: true, |
60 | query: [ |
61 | {$filter: { |
62 | dest: id, |
63 | value: { |
64 | content: { |
65 | type: 'vote', |
66 | vote: { link: id } |
67 | } |
68 | } |
69 | }}, |
70 | {$map: { |
71 | dest: 'dest', |
72 | id: 'key', |
73 | expression: ['value', 'content', 'vote', 'expression'], |
74 | value: ['value', 'content', 'vote', 'value'], |
75 | timestamp: 'timestamp', |
76 | author: ['value', 'author'] |
77 | }} |
78 | ] |
79 | }), (result, msg) => { |
80 | if (!result[msg.author]) { |
81 | result[msg.author] = [] |
82 | } |
83 | SortedArray.add(result[msg.author], msg, mostRecent) |
84 | return result |
85 | }, { |
86 | startValue: [] |
87 | }) |
88 | return likes |
89 | } |
90 | } |
91 | |
92 | function getLikes (likes) { |
93 | return Object.keys(likes).reduce((result, id) => { |
94 | if (likes[id][0].value) { |
95 | result.push(id) |
96 | } |
97 | return result |
98 | }, []) |
99 | } |
100 | |
101 | function mostRecent (a, b) { |
102 | return b.timestamp - a.timestamp |
103 | } |
104 |
Built with git-ssb-web