git ssb

2+

ev / mvd



Tree: c73d5a63da14de54092ef0559bc803136834352c

Files: c73d5a63da14de54092ef0559bc803136834352c / views.js

16140 bytesRaw
1var pull = require('pull-stream')
2var human = require('human-time')
3var sbot = require('./scuttlebot')
4var hyperscroll = require('hyperscroll')
5var hyperfile = require('hyperfile')
6var dataurl = require('dataurl-')
7var More = require('pull-more')
8var stream = require('hyperloadmore/stream')
9var h = require('hyperscript')
10var render = require('./render')
11var ref = require('ssb-ref')
12var client = require('ssb-client')
13
14var Next = require('pull-next-query')
15
16var config = require('./config')()
17
18var tools = require('./tools')
19var avatar = require('./avatar')
20var id = require('./keys').id
21
22var ssbKeys = require('ssb-keys')
23var keys = require('./keys')
24
25var checkInvite = require('./invite')
26
27var compose = require('./compose')
28
29var about = function () {
30 var screen = document.getElementById('screen')
31
32 var about = require('./about')
33
34 var content = h('div.content', about)
35
36 screen.appendChild(hyperscroll(content))
37}
38
39var privateStream = function () {
40 var content = h('div.content')
41 var screen = document.getElementById('screen')
42 screen.appendChild(hyperscroll(content))
43
44 function createStream (opts) {
45 return pull(
46 More(sbot.createLogStream, opts),
47 pull.filter(function (msg) {
48 return 'string' == typeof msg.value.content
49 }),
50 pull.filter(function (msg) {
51 var unboxed = ssbKeys.unbox(msg.value.content, keys)
52 if (unboxed) {
53 msg.value.content = unboxed
54 msg.value.private = true
55 return msg
56 }
57 }),
58 pull.map(function (msg) {
59 return render(msg)
60 })
61 )
62 }
63
64 pull(
65 createStream({old: false, limit: 1000}),
66 stream.top(content)
67 )
68
69 pull(
70 createStream({reverse: true, live: false, limit: 1000}),
71 stream.bottom(content)
72 )
73}
74
75var queueStream = function () {
76 var content = h('div.content')
77 var screen = document.getElementById('screen')
78 screen.appendChild(hyperscroll(content))
79
80 pull(
81 sbot.query({query: [{$filter: { value: {author: id, content: {type: 'queue'}}}}]}),
82 pull.drain(function (msg) {
83 if (msg.value) {
84 if (ref.isMsg(msg.value.content.message)) {
85 if (msg.value.content.queue == true) {
86 sbot.get(msg.value.content.message, function (err, data) {
87 if (data) {
88 var message = {}
89 message.value = data
90 message.key = msg.value.content.message
91 content.appendChild(render(message))
92 }
93 })
94 }
95 if (msg.value.content.queue == false) {
96 setTimeout(function () {
97 var gotIt = document.getElementById(msg.value.content.message.substring(0,44))
98 if (gotIt != null) {
99 gotIt.outerHTML = ''
100 }
101 }, 100)
102 }
103 }
104 }
105 })
106 )
107}
108
109var mentionsStream = function (src) {
110 var content = h('div.content')
111
112 var screen = document.getElementById('screen')
113
114 screen.appendChild(hyperscroll(content))
115
116 function createStream (opts) {
117 return pull(
118 Next(sbot.backlinks, opts, ['value', 'timestamp']),
119 pull.map(function (msg) {
120 if (msg.value.private == true) return h('div.private')
121 return render(msg)
122 })
123 )
124 }
125
126 pull(
127 createStream({
128 limit: 10,
129 reverse: true,
130 index: 'DTA',
131 live: false,
132 query: [{$filter: {dest: src}}]
133 }),
134 stream.bottom(content)
135 )
136
137 pull(
138 createStream({
139 limit: 10,
140 old: false,
141 index: 'DTA',
142 live: true,
143 query: [{$filter: {dest: src}}]
144 }),
145 stream.top(content)
146 )
147}
148
149var userStream = function (src) {
150 var content = h('div.content')
151 var screen = document.getElementById('screen')
152 screen.appendChild(hyperscroll(content))
153 function createStream (opts) {
154 return pull(
155 More(sbot.userStream, opts, ['value', 'sequence']),
156 pull.map(function (msg) {
157 return render(h('div', msg))
158 })
159 )
160 }
161
162 pull(
163 createStream({old: false, limit: 10, id: src}),
164 stream.top(content)
165 )
166
167 pull(
168 createStream({reverse: true, live: false, limit: 10, id: src}),
169 stream.bottom(content)
170 )
171
172 var profile = h('div.content#profile', h('div.message'))
173
174 if (screen.firstChild.firstChild) {
175 screen.firstChild.insertBefore(profile, screen.firstChild.firstChild)
176 } else {
177 screen.firstChild.appendChild(profile)
178 }
179
180 var name = avatar.name(src)
181
182 var editname = h('span',
183 avatar.name(src),
184 h('button.btn', 'New name', {
185 onclick: function () {
186 var nameput = h('input', {placeholder: name.textContent})
187 var nameedit =
188 h('span', nameput,
189 h('button.btn', 'Preview', {
190 onclick: function () {
191 if (nameput.value[0] != '@')
192 tobename = nameput.value
193 else
194 tobename = nameput.value.substring(1, 100)
195 var newname = h('span', h('a', {href: '#' + src}, '@' + tobename), h('button.btn', 'Publish', {
196 onclick: function () {
197 var donename = h('span', h('a', {href: '#' + src}, '@' + tobename))
198 sbot.publish({type: 'about', about: src, name: tobename})
199 localStorage[src + 'name'] = tobename
200 newname.parentNode.replaceChild(donename, newname)
201 }
202 }))
203 nameedit.parentNode.replaceChild(newname, nameedit)
204 }
205 })
206 )
207 editname.parentNode.replaceChild(nameedit, editname)
208 }
209 })
210 )
211
212 var editimage = h('span',
213 h('button.btn', 'New image', {
214 onclick: function () {
215 var upload =
216 h('span',
217 hyperfile.asDataURL(function (data) {
218 if(data) {
219 //img.src = data
220 var _data = dataurl.parse(data)
221 pull(
222 pull.once(_data.data),
223 sbot.addblob(function (err, hash) {
224 if(err) return alert(err.stack)
225 selected = {
226 link: hash,
227 size: _data.data.length,
228 type: _data.mimetype
229 }
230 })
231 )
232 }
233 }),
234 h('button.btn', 'Preview image', {
235 onclick: function() {
236 if (selected) {
237 console.log(selected)
238 var oldImage = document.getElementById('profileImage')
239 var newImage = h('span.avatar--medium', h('img', {src: config.blobsUrl + selected.link}))
240 var publish = h('button.btn', 'Publish image', {
241 onclick: function () {
242 sbot.publish({
243 type: 'about',
244 about: src,
245 image: selected
246 }, function (err, published) {
247 console.log(published)
248 })
249 }
250 })
251 upload.parentNode.replaceChild(publish, upload)
252 oldImage.parentNode.replaceChild(newImage, oldImage)
253 }
254 /*if(selected) {
255 api.message_confirm({
256 type: 'about',
257 about: id,
258 image: selected
259 })
260 } else { alert('select an image before hitting preview')}*/
261 }
262 })
263 )
264 editimage.parentNode.replaceChild(upload, editimage)
265 }
266 })
267 )
268
269 var avatars = h('div.avatars',
270 h('a', {href: '#' + src},
271 h('span.avatar--medium#profileImage', avatar.image(src)),
272 editname,
273 h('br'),
274 editimage
275 )
276 )
277
278 pull(
279 sbot.userStream({id: src, reverse: false, limit: 1}),
280 pull.drain(function (msg) {
281 var howlong = h('span', h('br'), ' arrived ', human(new Date(msg.value.timestamp)))
282 avatars.appendChild(howlong)
283 console.log(msg)
284 })
285 )
286
287
288 var buttons = h('div.buttons')
289
290 profile.firstChild.appendChild(avatars)
291 profile.firstChild.appendChild(buttons)
292 buttons.appendChild(tools.mute(src))
293
294 var writeMessage = h('button.btn', 'Public message ', avatar.name(src), {
295 onclick: function () {
296 opts = {}
297 opts.type = 'post'
298 opts.mentions = '[' + name.textContent + '](' + src + ')'
299 var composer = h('div#composer', h('div.message', compose(opts)))
300 profile.appendChild(composer)
301 }
302 })
303
304 var writePrivate = h('button.btn', 'Private message ', avatar.name(src), {
305 onclick: function () {
306 opts = {}
307 opts.type = 'post'
308 opts.mentions = '[' + name.textContent + '](' + src + ')'
309 opts.recps = [src, id]
310 var composer = h('div#composer', h('div.message', compose(opts)))
311 profile.appendChild(composer)
312 }
313 })
314
315 buttons.appendChild(writeMessage)
316 buttons.appendChild(writePrivate)
317 buttons.appendChild(tools.follow(src))
318
319 buttons.appendChild(h('button.btn', 'Generate follows', {
320 onclick: function () {
321 profile.firstChild.appendChild(tools.getFollowing(src))
322 profile.firstChild.appendChild(tools.getFollowers(src))
323 }
324 }))
325
326 buttons.appendChild(h('button.btn', 'Generate blocks', {
327 onclick: function () {
328 profile.firstChild.appendChild(tools.getBlocks(src))
329 profile.firstChild.appendChild(tools.getBlocked(src))
330 }
331 }))
332 buttons.appendChild(h('a', {href: '#wall/' + src}, h('button.btn', avatar.name(src), "'s wall")))
333
334}
335
336var privateMsg = function (src) {
337 var content = h('div.content')
338 var screen = document.getElementById('screen')
339 screen.appendChild(hyperscroll(content))
340
341 sbot.get(src, function (err, data) {
342 if (err) {
343 var message = h('div.message', 'Missing message!')
344 content.appendChild(message)
345 }
346 if (data) {
347 console.log(data)
348 data.value = data
349 data.key = src
350
351 content.appendChild(render(data))
352 }
353
354 })
355}
356
357var msgThread = function (src) {
358
359 var content = h('div.content')
360 var screen = document.getElementById('screen')
361 screen.appendChild(hyperscroll(content))
362
363 pull(
364 sbot.query({query: [{$filter: { value: { content: {root: src}, timestamp: { $gt: 1 }}}}], live: true}),
365 pull.drain(function (msg) {
366 if (msg.value) {
367 content.appendChild(render(msg))
368 }
369 })
370 )
371
372
373 sbot.get(src, function (err, data) {
374 if (err) {
375 var message = h('div.message', 'Missing message!')
376 content.appendChild(message)
377 }
378 if (data) {
379 data.value = data
380 data.key = src
381 console.log(data)
382 var rootMsg = render(data)
383
384 if (content.firstChild) {
385 content.insertBefore(rootMsg, content.firstChild)
386 } else {
387 content.appendChild(rootMsg)
388 }
389 if (data.value.content.type == 'git-repo') {
390 pull(
391 sbot.backlinks({query: [{$filter: {value: {content: {type: 'git-update'}}, dest: src}}]}),
392 pull.drain(function (msg) {
393 if (msg.value) {
394 content.appendChild(render(msg))
395 }
396 })
397 )
398 }
399
400 }
401 })
402}
403
404var keyPage = function () {
405 var screen = document.getElementById('screen')
406
407 var importKey = h('textarea.import', {placeholder: 'Import a new public/private key', name: 'textarea', style: 'width: 97%; height: 100px;'})
408
409 var content = h('div.content',
410 h('div.message#key',
411 h('h1', 'Your Key'),
412 h('p', {innerHTML: 'Your public/private key is: <pre><code>' + localStorage[config.caps.shs + '/secret'] + '</code></pre>'},
413 h('button.btn', {onclick: function (e){
414 localStorage[config.caps.shs +'/secret'] = ''
415 alert('Your public/private key has been deleted')
416 e.preventDefault()
417 location.hash = ""
418 location.reload()
419 }}, 'Delete Key')
420 ),
421 h('hr'),
422 h('form',
423 importKey,
424 h('button.btn', {onclick: function (e){
425 if(importKey.value) {
426 localStorage[config.caps.shs + '/secret'] = importKey.value.replace(/\s+/g, ' ')
427 e.preventDefault()
428 alert('Your public/private key has been updated')
429 }
430 location.hash = ""
431 location.reload()
432 }}, 'Import key'),
433 )
434 )
435 )
436
437 screen.appendChild(hyperscroll(content))
438}
439
440function everythingStream () {
441
442 var screen = document.getElementById('screen')
443 var content = h('div.content')
444
445 screen.appendChild(hyperscroll(content))
446
447 function createStream (opts) {
448 return pull(
449 Next(sbot.query, opts, ['value', 'timestamp']),
450 pull.map(function (msg) {
451 if (msg.value) {
452 if (msg.value.timestamp > Date.now()) {
453 return h('div.future')
454 } else {
455 return render(msg)
456 }
457 }
458 })
459 )
460 }
461
462 pull(
463 createStream({
464 limit: 10,
465 reverse: true,
466 live: false,
467 query: [{$filter: { value: { timestamp: { $gt: 0 }}}}]
468 }),
469 stream.bottom(content)
470 )
471
472 pull(
473 createStream({
474 limit: 10,
475 old: false,
476 live: true,
477 query: [{$filter: { value: { timestamp: { $gt: 0 }}}}]
478 }),
479 stream.top(content)
480 )
481}
482
483function backchannel () {
484
485 var screen = document.getElementById('screen')
486 var content = h('div.content')
487
488 screen.appendChild(hyperscroll(content))
489
490 var chatbox = h('input', {placeholder: 'Backchannel'})
491
492 var chat = h('div.content')
493
494 var publish = h('button.btn', 'Publish', {
495 onclick: function () {
496 if (chatbox.value) {
497 var content = {
498 text: chatbox.value,
499 type: 'scat_message'
500 }
501 sbot.publish(content, function (err, msg) {
502 if (err) throw err
503 chatbox.value = ''
504 console.log('Published!', msg)
505 })
506 }
507 }
508 })
509
510 chat.appendChild(h('div.message', chatbox, publish))
511
512 if (screen.firstChild.firstChild) {
513 screen.firstChild.insertBefore(chat, screen.firstChild.firstChild)
514 } else {
515 screen.firstChild.appendChild(chat)
516 }
517
518 function createStream (opts) {
519 return pull(
520 Next(sbot.query, opts, ['value', 'timestamp']),
521 pull.map(function (msg) {
522 if (msg.value) {
523 return render(msg)
524 }
525 })
526 )
527 }
528
529 pull(
530 createStream({
531 limit: 10,
532 reverse: true,
533 live: false,
534 query: [{$filter: { value: { content: {type: 'scat_message'}, timestamp: { $gt: 0 }}}}]
535 }),
536 stream.bottom(content)
537 )
538
539 pull(
540 createStream({
541 limit: 10,
542 old: false,
543 live: true,
544 query: [{$filter: { value: { content: {type: 'scat_message'}, timestamp: { $gt: 0 }}}}]
545 }),
546 stream.top(content)
547 )
548}
549
550function search (src) {
551 console.log('search' + src)
552
553 var content = h('div.content')
554 var screen = document.getElementById('screen')
555 screen.appendChild(hyperscroll(content))
556
557 pull(
558 sbot.search.query({query: src, limit: 100}),
559 pull.drain(function (search) {
560 content.appendChild(render(search))
561 })
562 )
563
564}
565
566function hash () {
567 return window.location.hash.substring(1)
568}
569
570module.exports = function () {
571 var src = hash()
572
573 if (src.substring(52, 59) == '?unbox=') {
574 privateMsg(src)
575 } else if (ref.isFeed(src)) {
576 userStream(src)
577 } else if (ref.isMsg(src)) {
578 msgThread(src)
579 } else if (ref.isFeed(src.substring(5))) {
580 mentionsStream(src.substring(5))
581 } else if (src == 'queue') {
582 queueStream()
583 } else if (src == 'about') {
584 about()
585 } else if (src == 'backchannel') {
586 backchannel()
587 } else if (src == 'private') {
588 privateStream()
589 } else if (src == 'key') {
590 keyPage()
591 } else if (src[0] == '?' || (src[0] == '#')) {
592 if (src[0] == '#')
593 search(src.split('%20').join(' '))
594 else
595 search(src.substr(1).split('%20').join(' '))
596 } else {
597 everythingStream()
598 checkInvite()
599 }
600
601}
602

Built with git-ssb-web