git ssb

16+

Dominic / patchbay



Tree: 78b1350ce9b39b237016dcce296cc3958139cde5

Files: 78b1350ce9b39b237016dcce296cc3958139cde5 / modules_basic / thread.js

3500 bytesRaw
1var pull = require('pull-stream')
2var sort = require('ssb-sort')
3var ref = require('ssb-ref')
4var h = require('hyperscript')
5var self_id = require('../keys').id
6
7function 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
21exports.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
31exports.gives = 'screen_view'
32
33
34exports.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