Files: 4d12101d5c56d1007d547af47a2cb083913aaf7c / modules_basic / thread.js
3500 bytesRaw
1 | var pull = require('pull-stream') |
2 | var sort = require('ssb-sort') |
3 | var ref = require('ssb-ref') |
4 | var h = require('hyperscript') |
5 | var self_id = require('../keys').id |
6 | |
7 | function once (cont) { |
8 | var ended = false |
9 | return function (abort, cb) { |
10 | if(abort) return cb(abort) |
11 | else if (ended) return cb(ended) |
12 | else |
13 | cont(function (err, data) { |
14 | if(err) return cb(ended = err) |
15 | ended = true |
16 | cb(null, data) |
17 | }) |
18 | } |
19 | } |
20 | |
21 | exports.needs = { |
22 | build_scroller: 'first', |
23 | message_render: 'first', |
24 | message_name: 'first', |
25 | message_compose: 'first', |
26 | message_unbox: 'first', |
27 | sbot_get: 'first', |
28 | sbot_links: 'first' |
29 | } |
30 | |
31 | exports.gives = 'screen_view' |
32 | |
33 | |
34 | exports.create = function (api) { |
35 | |
36 | function getThread (root, cb) { |
37 | //in this case, it's inconvienent that panel only takes |
38 | //a stream. maybe it would be better to accept an array? |
39 | |
40 | api.sbot_get(root, function (err, value) { |
41 | if (err) return cb(err) |
42 | var msg = {key: root, value: value} |
43 | // if(value.content.root) return getThread(value.content.root, cb) |
44 | |
45 | pull( |
46 | api.sbot_links({rel: 'root', dest: root, values: true, keys: true}), |
47 | pull.collect(function (err, ary) { |
48 | if(err) return cb(err) |
49 | ary.unshift(msg) |
50 | cb(null, ary) |
51 | }) |
52 | ) |
53 | }) |
54 | |
55 | } |
56 | |
57 | return function (id) { |
58 | if(ref.isMsg(id)) { |
59 | var meta = { |
60 | type: 'post', |
61 | root: id, |
62 | branch: id //mutated when thread is loaded. |
63 | } |
64 | |
65 | var composer = api.message_compose(meta, {shrink: false, placeholder: 'Write a reply'}) |
66 | var { container, content } = api.build_scroller({ append: composer }) |
67 | |
68 | api.message_name(id, function (err, name) { |
69 | container.title = name |
70 | }) |
71 | |
72 | pull( |
73 | api.sbot_links({ |
74 | rel: 'root', dest: id, keys: true, old: false |
75 | }), |
76 | pull.drain(function (msg) { |
77 | loadThread() //redraw thread |
78 | }, function () {} ) |
79 | ) |
80 | |
81 | |
82 | function loadThread () { |
83 | getThread(id, function (err, thread) { |
84 | //would probably be better keep an id for each message element |
85 | //(i.e. message key) and then update it if necessary. |
86 | //also, it may have moved (say, if you received a missing message) |
87 | content.innerHTML = '' |
88 | if(err) return content.appendChild(h('pre', err.stack)) |
89 | |
90 | //decrypt |
91 | thread = thread.map(function (msg) { |
92 | return 'string' === typeof msg.value.content ? api.message_unbox(msg) : msg |
93 | }) |
94 | |
95 | if(err) return content.appendChild(h('pre', err.stack)) |
96 | sort(thread).map(api.message_render).filter(Boolean).forEach(function (el) { |
97 | content.appendChild(el) |
98 | }) |
99 | |
100 | var branches = sort.heads(thread) |
101 | meta.branch = branches.length > 1 ? branches : branches[0] |
102 | meta.root = thread[0].value.content.root || thread[0].key |
103 | meta.channel = thread[0].value.content.channel |
104 | |
105 | if (meta.channel) { |
106 | const channelInput = composer.querySelector('input') |
107 | channelInput.value = `#${meta.channel}` |
108 | channelInput.disabled = true |
109 | } |
110 | |
111 | var recps = thread[0].value.content.recps |
112 | var priv = thread[0].value['private'] |
113 | if(priv) { |
114 | if(recps) |
115 | meta.recps = recps |
116 | else |
117 | meta.recps = [thread[0].value.author, self_id] |
118 | } |
119 | }) |
120 | } |
121 | |
122 | loadThread() |
123 | return container |
124 | } |
125 | } |
126 | } |
127 |
Built with git-ssb-web