Files: e440f8c92caaa6857bccee89bb2de11d376d29a3 / thread.js
3524 bytesRaw
1 | var pull = require('pull-stream') |
2 | var ref = require('ssb-ref') |
3 | var msum = require('markdown-summary') |
4 | var sort = require('ssb-sort') |
5 | var u = require('yap-util') |
6 | |
7 | var toUrl = u.toUrl |
8 | |
9 | function uniqueRecps (recps) { |
10 | if(!recps || !recps.length) return |
11 | recps = recps.map(function (e) { |
12 | return 'string' === typeof e ? e : e.link |
13 | }) |
14 | .filter(Boolean) |
15 | return recps.filter(function (id, i) { |
16 | return !~recps.indexOf(id, i+1) |
17 | }) |
18 | } |
19 | |
20 | function getThread(sbot, id, cb) { |
21 | pull( |
22 | sbot.query.read({ |
23 | //hack so that ssb-query filters on post but uses |
24 | //indexes for root. |
25 | query: [{$filter: { |
26 | value: { content: {root: id} } |
27 | }},{$filter: { |
28 | value: { content: {type: 'post'} } |
29 | }}] |
30 | }), |
31 | pull.collect(function (err, ary) { |
32 | if(err) return cb(err) |
33 | cb(null, ary) |
34 | }) |
35 | ) |
36 | } |
37 | |
38 | function isObject(o) { |
39 | return o && 'object' === typeof o |
40 | } |
41 | var isArray = Array.isArray |
42 | |
43 | module.exports = function (sbot) { |
44 | return function (opts, apply, req) { |
45 | var context = req.cookies |
46 | var since = apply.since |
47 | var tr = require('./translations')(context.lang) |
48 | return function (cb) { |
49 | var cacheTime = 0 |
50 | if(!ref.isMsg(opts.id)) |
51 | return cb(new Error('expected valid msg id as id')) |
52 | sbot.get({id:opts.id, private: true}, function (err, msg) { |
53 | if(err) return cb(err) |
54 | var data = {key: opts.id, value: msg, timestamp: msg.timestamp || Date.now() } |
55 | /*if(data.value.content.root) |
56 | cb(null, apply('message', data)) //just show one message |
57 | else */ |
58 | if(data.value.content.type != 'post') |
59 | cb(null, apply('message', data)) //just show one message |
60 | else |
61 | getThread(sbot, opts.id, function (err, ary) { |
62 | var root = opts.id |
63 | ary = [data].concat(ary || []) |
64 | var branch = sort.heads(ary) |
65 | var recps = uniqueRecps(ary[0].value.content.recps) |
66 | |
67 | ary.unshift(data) |
68 | var o = {}, cacheTime |
69 | ary = ary.filter(function (e) { |
70 | if(o[e.key]) return false |
71 | return o[e.key] = true |
72 | }) |
73 | sort(ary) |
74 | var recipients = ' ' |
75 | if(ary[0].value.content.recps) |
76 | recipients = ['div.Recipients', tr('ThreadRecipients'), |
77 | ary[0].value.content.recps.map(function (e) { |
78 | return apply('avatar', e) |
79 | })] |
80 | cb(null, |
81 | ['div.thread', |
82 | apply.cacheAttrs(apply.toUrl('patch/thread', opts), data.key, since), |
83 | ary[0].value.content.text && ['title', msum.title(ary[0].value.content.text)], |
84 | recipients, |
85 | ary.map(function (data) { |
86 | var msg = apply('messageLayout', { |
87 | id: data.key, |
88 | author: data.value.author, |
89 | content: u.markdown(data.value.content), |
90 | root: root, branch: branch, |
91 | ts: data.value.timestamp || data.timestamp, |
92 | meta: [], |
93 | extra: true |
94 | }) |
95 | return msg |
96 | }), |
97 | apply('compose', { |
98 | content: { |
99 | type: 'post', |
100 | root: root, |
101 | recps: recps, |
102 | branch: branch, |
103 | channel: ary[0].value.content.channel |
104 | } |
105 | }) |
106 | ] |
107 | ) |
108 | }) |
109 | }) |
110 | } |
111 | } |
112 | } |
113 |
Built with git-ssb-web