git ssb

0+

ev / 0qc



Tree: 34c6b405528c998bb419248c8bbfeaef62e071cb

Files: 34c6b405528c998bb419248c8bbfeaef62e071cb / render.js

15084 bytesRaw
1var h = require('hyperscript')
2var pull = require('pull-stream')
3var human = require('human-time')
4
5var sbot = require('./scuttlebot')
6var composer = require('./compose')
7var tools = require('./tools')
8var ref = require('ssb-ref')
9
10var config = require('./config')()
11var id = require('./keys').id
12var avatar = require('./avatar')
13var ssbAvatar = require('ssb-avatar')
14
15var ssbKeys = require('ssb-keys')
16var keys = require('./keys')
17
18var diff = require('diff')
19
20function hash () {
21 return window.location.hash.substring(1)
22}
23
24module.exports.render = function (msg) {
25
26
27 var messageExists = (document.getElementById(msg.key.substring(0, 44)) !== null);
28
29 if (!messageExists) {
30 var message = h('div.message#' + msg.key.substring(0, 44))
31 //console.log(msg)
32 var messageContent = h('div.messageContent')
33 message.appendChild(messageContent)
34
35 pull(
36 sbot.backlinks({
37 query: [{$filter: {dest: msg.key}}],
38 live: true,
39 reverse: false,
40 index: 'DTA'
41 }),
42 pull.drain(function (data) {
43 if (data.sync) {
44 } else {
45 if (data.value.content.type == 'vote') {
46 var subMessageExists = (document.getElementById(data.key.substring(0, 44)) !== null)
47 if (msg.key == data.value.content.vote.link) {
48 if (data.value.content.vote.value == 1) {
49 var link = h('span', ' ', h('img.emoji', {src: config.emojiUrl + 'star.png'}), ' ', h('a', {href: '#' + data.value.content.vote.link}, tools.messageLink(data.value.content.vote.link)))
50 if (!subMessageExists) {
51 message.appendChild(h('div.submessage', h('div.messageContent', tools.mini(data, link))))
52 }
53 if (data.value.author == id) {
54 var gotIt = document.getElementById('votebutton:' + msg.key.substring(0,44))
55 if (gotIt != null) {
56 gotIt.parentNode.appendChild(tools.unstar(msg))
57 gotIt.parentNode.removeChild(gotIt)
58 }
59 }
60 } else if (data.value.content.vote.value == -1) {
61 var link = h('span', ' ', h('img.emoji', {src: config.emojiUrl + 'stars.png'}), ' ', h('a', {href: '#' + data.value.content.vote.link}, tools.messageLink(data.value.content.vote.link)))
62 if (!subMessageExists) {
63 message.appendChild(h('div.submessage', h('div.messageContent', tools.mini(data, link))))
64 }
65 if (data.value.author == id) {
66 var gotIt = document.getElementById('votebutton:' + msg.key.substring(0,44))
67 if (gotIt != null) {
68 gotIt.parentNode.appendChild(tools.star(msg))
69 gotIt.parentNode.removeChild(gotIt)
70 }
71 }
72 }
73 }
74 }
75 else if (!subMessageExists) {
76 if (data.value.content.type == 'post') {
77 if (
78 (msg.key == data.value.content.root) ||
79 (msg.value.content.root == data.value.content.root)
80 ) {
81 message.appendChild(h('div.submessage', (exports.render(data))))
82 }
83
84
85
86
87 } else if (data.value.content.type == 'edit') {
88
89
90
91 message.appendChild(h('div.submessage', (exports.render(data))))
92
93
94 var editedMessage = h('div.messageContent')
95
96 editedMessage.appendChild(tools.header(msg))
97 editedMessage.appendChild(tools.timestamp(data, {edited: true})),
98 editedMessage.appendChild(h('div.message__body', tools.markdown(data.value.content.text)))
99
100
101
102 message.replaceChild(editedMessage, message.firstChild)
103
104
105
106
107
108 } else if (data.value.content.type == 'git-update') {
109 message.appendChild(h('div.submessage', (exports.render(data))))
110 } else {
111 var link = h('span', ' backlinked from ', tools.messageLink(data.key))
112 message.appendChild(h('div.submessage', h('div.messageContent', tools.mini(data, link))))
113 }
114 } else { //console.log('message already rendered')
115 }
116 }
117 })
118 )
119 if (msg.value.content.type == 'edit') {
120 messageContent.appendChild(tools.header(msg))
121 if (msg.value.content.text) {
122 var current = msg.value.content.text
123 sbot.get(msg.value.content.updated, function (err, updated) {
124 if (updated) {
125 // quick fix, need to decrypt messages if they're private
126 if (updated.content.text) {
127 fragment = document.createDocumentFragment()
128 var previous = updated.content.text
129 var ready = diff.diffWords(previous, current)
130 ready.forEach(function (part) {
131 if (part.added === true) {
132 color = 'cyan'
133 } else if (part.removed === true) {
134 color = 'gray'
135 } else {color = '#333'}
136 var span = h('span')
137 span.style.color = color
138 if (part.removed === true) {
139 span.appendChild(h('del', document.createTextNode(part.value)))
140 } else {
141 span.appendChild(document.createTextNode(part.value))
142 }
143 fragment.appendChild(span)
144 })
145 messageContent.appendChild(h('code', fragment))
146 }
147 }
148 })
149 }
150 return message
151
152 }
153 if (msg.value.content.type == 'post') {
154
155 var opts = {
156 type: 'post',
157 branch: msg.key
158 }
159 var fallback = {}
160
161 if (msg.value.content.root)
162 opts.root = msg.value.content.root
163 else
164 opts.root = msg.key
165
166 messageContent.appendChild(tools.header(msg))
167
168 if (msg.value.content.root) {
169 messageContent.appendChild(h('span', 're: ', tools.messageLink(msg.value.content.root)))
170 }
171
172 messageContent.appendChild(h('div.message__body', tools.markdown(msg.value.content.text)))
173
174 var name = avatar.name(msg.value.author)
175
176
177 var buttons = h('div.buttons')
178
179 buttons.appendChild(h('button.btn', 'Reply', {
180 onclick: function () {
181 opts.type = 'post'
182 opts.mentions = '[' + name.textContent + '](' + msg.value.author + ')'
183 if (msg.value.content.recps) {
184 opts.recps = msg.value.content.recps
185 }
186 var r = messageContent.childNodes.length - 1
187 delete opts.updated
188 delete opts.original
189 delete fallback.messageText
190 fallback.buttons = messageContent.childNodes[r]
191 var compose = h('div.submessage#re:' + msg.key.substring(0, 44), h('div.messageContent', composer(opts, fallback)))
192 messageContent.removeChild(messageContent.childNodes[r])
193 message.parentNode.insertBefore(compose, message.nextSibling)
194 }
195 }))
196
197 buttons.appendChild(h('button.btn', 'Edit', {
198 onclick: function () {
199 opts.type = 'edit'
200 if (!fallback.messageText)
201 fallback.messageText = msg.value.content.text
202
203 if (!opts.updated)
204 opts.updated = msg.key
205 opts.original = msg.key
206
207 var r = messageContent.childNodes.length - 1
208 fallback.buttons = messageContent.childNodes[r]
209 messageContent.removeChild(messageContent.childNodes[r])
210 var compose = h('div#edit:' + msg.key.substring(0, 44), composer(opts, fallback))
211 messageContent.replaceChild(compose, messageContent.lastElementChild)
212 }
213 }))
214
215 buttons.appendChild(h('button.btn', 'Boost', {
216 onclick: function () {
217 opts.type = 'post'
218 opts.mentions = '[' + name.textContent + '](' + msg.value.author + ')'
219 if (msg.value.content.recps) {
220 opts.recps = msg.value.content.recps
221 }
222 var r = messageContent.childNodes.length - 1
223 delete opts.updated
224 delete opts.original
225 delete fallback.messageText
226 opts.boostContent = msg.value.content.text
227 opts.boostKey = msg.key
228 opts.boostAuthor = msg.value.author
229 fallback.buttons = messageContent.childNodes[r]
230 var compose = h('div.submessage#re:' + msg.key.substring(0, 44), h('div.messageContent', composer(opts, fallback)))
231 messageContent.removeChild(messageContent.childNodes[r])
232 message.parentNode.insertBefore(compose, message.nextSibling)
233 }
234 }))
235
236
237
238 buttons.appendChild(tools.star(msg))
239
240 messageContent.appendChild(buttons)
241 return message
242 }
243
244 if (msg.value.content.type == 'vote') {
245 if (msg.value.content.vote.value == 1)
246 var link = h('span', ' ', h('img.emoji', {src: config.emojiUrl + 'star.png'}), ' ', h('a', {href: '#' + msg.value.content.vote.link}, tools.messageLink(msg.value.content.vote.link)))
247 else if (msg.value.content.vote.value == -1)
248 var link = h('span', ' ', h('img.emoji', {src: config.emojiUrl + 'stars.png'}), ' ', h('a', {href: '#' + msg.value.content.vote.link}, tools.messageLink(msg.value.content.vote.link)))
249 messageContent.appendChild(tools.mini(msg, link))
250 return message
251 }
252
253 if (msg.value.content.type == 'about') {
254 if (msg.value.content.image) {
255 if (ref.isBlob(msg.value.content.image.link)) {
256 var image = h('img', {src: config.blobsUrl + msg.value.content.image.link})
257 } else if (ref.isBlob(msg.value.content.image)) {
258 var image = h('img', {src: config.blobsUrl + msg.value.content.image})
259 } else { console.log('Not a valid image')}
260 var content = h('span.avatar--small',
261 ' identified ',
262 h('a', {href: '#' + msg.value.content.about}, avatar.cachedName(msg.value.content.about)),
263 ' as ',
264 image
265 )
266 messageContent.appendChild(tools.mini(msg, content))
267 return message
268 }
269 if (msg.value.content.name) {
270 var name = h('span',
271 ' identified ',
272 h('a', {href: '#' + msg.value.content.about}, avatar.cachedName(msg.value.content.about)),
273 ' as ', msg.value.content.name
274 )
275 messageContent.appendChild(tools.mini(msg, name))
276 return message
277 }
278 }
279
280 if (msg.value.content.type == 'label'){
281 var content = h('span', ' labeled ', tools.messageLink(msg.value.content.link), ' as ', h('mark', h('a', {href: '#label/' + msg.value.content.label}, msg.value.content.label)))
282 messageContent.appendChild(tools.mini(msg, content))
283 return message
284 }
285
286 if (msg.value.content.type == 'queue') {
287 if (msg.value.content.queue == true) {
288 var content = h('span', ' added ', tools.messageLink(msg.value.content.message), ' to their ', h('a', {href: '#queue'}, 'queue'))
289 messageContent.appendChild(tools.mini(msg, content))
290 }
291 if (msg.value.content.queue == false) {
292 var content = h('span', ' removed ', tools.messageLink(msg.value.content.message), ' from their ', h('a', {href: '#queue'}, 'queue'))
293 messageContent.appendChild(tools.mini(msg, content))
294
295 }
296 return message
297 }
298
299 if (msg.value.content.type == 'scat_message') {
300 var src = hash()
301 if (src != 'backchannel') {
302 messageContent.appendChild(h('button.btn.right', h('a', {href: '#backchannel'}, 'Chat')))
303 }
304 messageContent.appendChild(tools.mini(msg, ' ' + msg.value.content.text))
305 return message
306 }
307
308 else if (msg.value.content.type == 'contact') {
309 if (msg.value.content.contact) {
310 var contact = h('a', {href: '#' + msg.value.content.contact}, avatar.name(msg.value.content.contact))
311 } else { var contact = h('p', 'no contact named')}
312
313 if (msg.value.content.following == true) {
314 var following = h('span', ' follows ', contact)
315 messageContent.appendChild(tools.mini(msg, following))
316 }
317 if (msg.value.content.following == false) {
318 var unfollowing = h('span', ' unfollows ', contact)
319 messageContent.appendChild(tools.mini(msg, unfollowing))
320 }
321 if (msg.value.content.blocking == true) {
322 var blocking = h('span', ' blocks ', contact)
323 messageContent.appendChild(tools.mini(msg, blocking))
324 }
325 if (msg.value.content.blocking == false) {
326 var unblocking = h('span', ' unblocks ', contact)
327 messageContent.appendChild(tools.mini(msg, unblocking))
328 }
329 return message
330
331 }
332
333
334 if (msg.value.content.type == 'git-update') {
335
336 messageContent.appendChild(tools.header(msg))
337
338 var reponame = h('p', 'pushed to ', h('a', {href: '#' + msg.value.content.repo}, msg.value.content.repo))
339
340 var cloneurl = h('pre', 'git clone ssb://' + msg.value.content.repo)
341
342 messageContent.appendChild(reponame)
343
344 ssbAvatar(sbot, id, msg.value.content.repo, function (err, data) {
345 if (data) {
346 var actualname = h('p', 'pushed to ', h('a', {href: '#' + msg.value.content.repo}, '%' + data.name))
347 reponame.parentNode.replaceChild(actualname, reponame)
348 }
349 })
350
351 messageContent.appendChild(cloneurl)
352
353 var commits = h('ul')
354 if (msg.value.content.commits) {
355 msg.value.content.commits.map(function (commit) {
356 commits.appendChild(h('li', h('code', commit.sha1), ' - ', commit.title))
357 })
358 }
359
360 messageContent.appendChild(commits)
361 messageContent.appendChild(tools.star(msg))
362
363 return message
364 }
365
366 if (msg.value.content.type == 'git-repo') {
367 messageContent.appendChild(tools.header(msg))
368
369 var reponame = h('p', 'git-ssb repo ', h('a', {href: '#' + msg.key}, msg.key))
370
371 messageContent.appendChild(reponame)
372
373
374 ssbAvatar(sbot, id, msg.key, function (err, data) {
375 if (data)
376 var actualname = h('p', 'git-ssb repo ', h('a', {href: '#' + msg.key}, '%' + data.name))
377 reponame.parentNode.replaceChild(actualname, reponame)
378 })
379
380 var cloneurl = h('pre', 'git clone ssb://' + msg.key)
381 messageContent.appendChild(cloneurl)
382 messageContent.appendChild(tools.star(msg))
383 return message
384 }
385
386 if (typeof msg.value.content === 'string') {
387 var unboxed = ssbKeys.unbox(msg.value.content, keys)
388 if (unboxed) {
389 msg.value.content = unboxed
390 msg.value.private = true
391 return exports.render(msg)
392 } else {
393 var privateMsg = h('span', ' sent a private message.')
394 messageContent.appendChild(tools.mini(msg, privateMsg))
395 return message
396 }
397 }
398
399 else {
400 //FULL FALLBACK
401 //message.appendChild(tools.header(msg))
402 messageContent.appendChild(tools.header(msg))
403 messageContent.appendChild(h('pre', tools.rawJSON(msg.value)))
404
405 //MINI FALLBACK
406 //var fallback = h('span', ' ' + msg.value.content.type)
407 //message.appendChild(tools.mini(msg, fallback))
408 return message
409 }
410 }
411}
412

Built with git-ssb-web