git ssb

0+

dangerousbeans / yap



forked from Dominic / yap

Tree: 8c686fb2b73c28246604759c61d6636e2812d871

Files: 8c686fb2b73c28246604759c61d6636e2812d871 / apis / thread.js

5431 bytesRaw
1var pull = require('pull-stream')
2var ref = require('ssb-ref')
3var msum = require('markdown-summary')
4var sort = require('ssb-sort')
5
6var u = require('../util')
7
8var h = u.h
9toUrl = u.toUrl
10
11function uniqueRecps (recps) {
12 if(!recps || !recps.length) return
13 recps = recps.map(function (e) {
14 return 'string' === typeof e ? e : e.link
15 })
16 .filter(Boolean)
17 return recps.filter(function (id, i) {
18 return !~recps.indexOf(id, i+1)
19 })
20}
21
22function getThread(sbot, id, cb) {
23 pull(
24 sbot.query.read({
25 //hack so that ssb-query filters on post but uses
26 //indexes for root.
27 query: [{$filter: {
28 value: { content: {root: id} }
29 }},{$filter: {
30 value: { content: {type: 'post'} }
31 }}]
32 }),
33 pull.collect(function (err, ary) {
34 if(err) return cb(err)
35 cb(null, ary)
36 })
37 )
38}
39
40function isObject(o) {
41 return o && 'object' === typeof o
42}
43var isArray = Array.isArray
44
45function backlinks (sbot, id, cb) {
46 var likes = [], backlinks = []
47 pull(
48 sbot.links({dest: id, values: true}),
49 pull.drain(function (e) {
50 var content = e.value.content
51 var vote = content.vote
52 if(isObject(vote) &&
53 vote.value == 1 && vote.link == id)
54 likes.push(e)
55 else if(content.type == 'post' && isArray(content.mentions)) {
56 for(var i in content.mentions) {
57 var m = content.mentions[i]
58 if(m && m.link == id) {
59 backlinks.push(e)
60 return //if something links twice, don't back link it twice
61 }
62 }
63 }
64 }, function () {
65 cb(null, likes, backlinks)
66 })
67 )
68}
69
70
71module.exports = function (sbot) {
72 return function (opts, apply, req) {
73 var context = req.cookies
74 var since = apply.since
75 var tr = require('../translations')(context.lang)
76 return function (cb) {
77 var cacheTime = 0
78 if(!ref.isMsg(opts.id))
79 return cb(new Error('expected valid msg id as id'))
80 sbot.get({id:opts.id, private: true}, function (err, msg) {
81 if(err) return cb(err)
82 var data = {key: opts.id, value: msg, timestamp: msg.timestamp || Date.now() }
83 if(data.value.content.root)
84 cb(null, apply('message', data)) //just show one message
85 else if(data.value.content.type != 'post')
86 cb(null, apply('message', data)) //just show one message
87 else
88 getThread(sbot, opts.id, function (err, ary) {
89 ary.unshift(data)
90 var o = {}, cacheTime
91 ary = ary.filter(function (e) {
92 if(o[e.key]) return false
93 return o[e.key] = true
94 })
95 sort(ary)
96 var recipients = ' '
97 if(ary[0].value.content.recps)
98 recipients = ['div.Recipients', tr('ThreadRecipients'),
99 ary[0].value.content.recps.map(function (e) {
100 return apply('avatar', e)
101 })]
102 cb(null,
103 h('div.thread',
104 u.cacheTag(apply.toUrl('thread', opts), data.key, since),
105 ary[0].value.content.text && h('title', msum.title(ary[0].value.content.text)),
106 recipients,
107 h('form', {name: 'publish', method: 'POST'},
108 ary.map(function (data) {
109 return h('div',
110 apply('message', data),
111 function (cb) {
112 backlinks(sbot, data.key, function (err, likes, backlinks) {
113 if(err) return cb(err)
114
115 var expression = tr('Like')
116 cb(null, ['div.MessageExtra',
117 apply('publish', {
118 id: context.id,
119 suggestedRecps: data.value.author,
120 content: {
121 type: 'vote',
122 vote: {
123 link:data.key, value: 1,
124 expression: expression
125 },
126 channel: data.value.content.channel
127 },
128 name: expression + ' ' + (likes.length ? '('+likes.length+')' : '')
129 }),
130 (backlinks.length ?
131 ['ul.MessageBacklinks',
132 backlinks.map(function (e) {
133 return ['li',
134 apply('avatar', {id:e.value.author}),
135 ' ',
136 apply('messageLink', e),
137 ' ',
138 e.value.content.channel && apply('channelLink', e.value.content.channel)
139 ]
140 })
141 ] : '')
142 ])
143 })
144 }
145 )
146 })
147 ),
148 apply('compose', {
149 content: {
150 type: 'post',
151 root: opts.id,
152 recps: uniqueRecps(ary[0].value.content.recps),
153 branch: sort.heads(ary)
154 }
155 })
156 )
157 )
158 })
159 })
160 }
161 }
162}
163
164

Built with git-ssb-web