Files: 634a3e47dc6133cc55dae03d47dc86880af6282c / thread.js
3511 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 if(data.value.content.type != 'post') |
58 | cb(null, apply('message', data)) //just show one message |
59 | else |
60 | getThread(sbot, opts.id, function (err, ary) { |
61 | var root = opts.id |
62 | ary = [data].concat(ary || []) |
63 | var branch = sort.heads(ary) |
64 | var recps = uniqueRecps(ary[0].value.content.recps) |
65 | |
66 | ary.unshift(data) |
67 | var o = {}, cacheTime |
68 | ary = ary.filter(function (e) { |
69 | if(o[e.key]) return false |
70 | return o[e.key] = true |
71 | }) |
72 | sort(ary) |
73 | var recipients = ' ' |
74 | if(ary[0].value.content.recps) |
75 | recipients = ['div.Recipients', tr('ThreadRecipients'), |
76 | ary[0].value.content.recps.map(function (e) { |
77 | return apply('avatar', e) |
78 | })] |
79 | cb(null, |
80 | ['div.thread', |
81 | apply.cacheAttrs(apply.toUrl('patch/thread', opts), data.key, since), |
82 | ary[0].value.content.text && ['title', msum.title(ary[0].value.content.text)], |
83 | recipients, |
84 | ary.map(function (data) { |
85 | var msg = apply('messageLayout', { |
86 | id: data.key, |
87 | author: data.value.author, |
88 | content: u.markdown(data.value.content), |
89 | root: root, branch: branch, |
90 | ts: data.value.timestamp || data.timestamp, |
91 | meta: [], |
92 | extra: true |
93 | }) |
94 | return msg |
95 | }), |
96 | apply('compose', { |
97 | content: { |
98 | type: 'post', |
99 | root: root, |
100 | recps: recps, |
101 | branch: branch, |
102 | channel: ary[0].value.content.channel |
103 | } |
104 | }) |
105 | ] |
106 | ) |
107 | }) |
108 | }) |
109 | } |
110 | } |
111 | } |
112 |
Built with git-ssb-web