git ssb

2+

ev / mvd



Tree: 3a73aa178d3d0aae49095e0befc1ae5fb2de81b4

Files: 3a73aa178d3d0aae49095e0befc1ae5fb2de81b4 / views.js

19879 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 labelStream = function (label){
40 var content = h('div.content')
41 var screen = document.getElementById('screen')
42 screen.appendChild(hyperscroll(content))
43 content.appendChild(h('div.breadcrumbs.message', h('a', {href: '/'}, 'label'), ' ⯈ ' , h('a', {href: '/#label/' + label}, label)))
44 function createStream (opts) {
45 return pull(
46 Next(sbot.query, opts, ['value', 'timestamp']),
47 pull.map(function (msg){
48 if (msg.value) {
49 sbot.get(msg.value.content.link, function (err, data) {
50 if (data) {
51 var message = {}
52 message.value = data
53 message.key = msg.value.content.link
54 content.appendChild(render(message))
55 }
56 })
57 }
58 })
59 )
60 }
61
62 pull(
63 createStream({
64 limit: 10,
65 reverse: true,
66 live: false,
67 query: [{$filter: { value: { content: {type: 'label', label: label }, timestamp: { $gt: 0 }}}}]
68 }),
69 stream.bottom(content)
70 )
71
72 pull(
73 createStream({
74 limit: 10,
75 old: false,
76 live: true,
77 query: [{$filter: { value: { content: {type: 'label', label: label }, timestamp: { $gt: 0 }}}}]
78 }),
79 stream.top(content)
80 )
81}
82
83
84var privateStream = function () {
85 var screen = document.getElementById('screen')
86 var content = h('div.content')
87
88 screen.appendChild(hyperscroll(content))
89
90 function createStream (opts) {
91 return pull(
92 Next(sbot.query, opts, ['value', 'timestamp']),
93 pull.filter(function (msg) {
94 return ((msg.value.private == true) || ('string' == typeof msg.value.content))
95 }),
96 pull.map(function (msg) {
97 /*if (msg.value.private != true) {
98 var unboxed = ssbKeys.unbox(msg.value.content, keys)
99 if (unboxed) {
100 msg.value.content = unboxed
101 msg.value.private = true
102 return render(msg)
103 } else {
104 return render(msg)
105 }
106 } else {return render(msg)}*/
107 return render(msg)
108 })
109 )
110 }
111
112 pull(
113 createStream({
114 limit: 100,
115 reverse: true,
116 live: false,
117 query: [{$filter: { value: { timestamp: { $gt: 0 }}}}]
118 }),
119 stream.bottom(content)
120 )
121
122 pull(
123 createStream({
124 limit: 100,
125 old: false,
126 live: true,
127 query: [{$filter: { value: { timestamp: { $gt: 0 }}}}]
128 }),
129 stream.top(content)
130 )
131
132
133 /*function createStream (opts) {
134 return pull(
135 Next(sbot.query, opts, ['value', 'timestamp']),
136 pull.map(function (msg) {
137 if (msg.value) {
138 if (msg.value.timestamp > Date.now()) {
139 return h('div.future')
140 } else {
141 return render(msg)
142 }
143 }
144 })
145 )
146 }
147
148 pull(
149 createStream({
150 limit: 10,
151 reverse: true,
152 live: false,
153 query: [{$filter: { value: { private: true, timestamp: { $gt: 0 }}}}]
154 }),
155 stream.bottom(content)
156 )
157
158 pull(
159 createStream({
160 limit: 10,
161 old: false,
162 live: true,
163 query: [{$filter: { value: { private: true, timestamp: { $gt: 0 }}}}]
164 }),
165 stream.top(content)
166 )*/
167
168
169 /*function createStream (opts) {
170 return pull(
171 More(sbot.createLogStream, opts),
172 pull.filter(function (msg) {
173 return 'string' == typeof msg.value.content
174 }),
175 pull.filter(function (msg) {
176 var unboxed = ssbKeys.unbox(msg.value.content, keys)
177 if (unboxed) {
178 msg.value.content = unboxed
179 msg.value.private = true
180 return msg
181 } else {
182 return msg
183 }
184 }),
185 pull.map(function (msg) {
186 return render(msg)
187 })
188 )
189 }
190
191 pull(
192 createStream({old: false, limit: 1000}),
193 stream.top(content)
194 )
195
196 pull(
197 createStream({reverse: true, live: false, limit: 1000}),
198 stream.bottom(content)
199 )*/
200}
201
202var queueStream = function () {
203 var content = h('div.content')
204 var screen = document.getElementById('screen')
205 screen.appendChild(hyperscroll(content))
206
207 pull(
208 sbot.query({query: [{$filter: { value: {author: id, content: {type: 'queue'}}}}]}),
209 pull.drain(function (msg) {
210 if (msg.value) {
211 if (ref.isMsg(msg.value.content.message)) {
212 if (msg.value.content.queue == true) {
213 sbot.get(msg.value.content.message, function (err, data) {
214 if (data) {
215 var message = {}
216 message.value = data
217 message.key = msg.value.content.message
218 content.appendChild(render(message))
219 }
220 })
221 }
222 if (msg.value.content.queue == false) {
223 setTimeout(function () {
224 var gotIt = document.getElementById(msg.value.content.message.substring(0,44))
225 if (gotIt != null) {
226 gotIt.outerHTML = ''
227 }
228 }, 100)
229 }
230 }
231 }
232 })
233 )
234}
235
236var mentionsStream = function (src) {
237 var content = h('div.content')
238
239 var screen = document.getElementById('screen')
240
241 screen.appendChild(hyperscroll(content))
242
243 function createStream (opts) {
244 return pull(
245 Next(sbot.backlinks, opts, ['value', 'timestamp']),
246 pull.map(function (msg) {
247 if (msg.value.private == true) return h('div.private')
248 return render(msg)
249 })
250 )
251 }
252
253 pull(
254 createStream({
255 limit: 10,
256 reverse: true,
257 index: 'DTA',
258 live: false,
259 query: [{$filter: {dest: src}}]
260 }),
261 stream.bottom(content)
262 )
263
264 pull(
265 createStream({
266 limit: 10,
267 old: false,
268 index: 'DTA',
269 live: true,
270 query: [{$filter: {dest: src}}]
271 }),
272 stream.top(content)
273 )
274}
275
276var userStream = function (src) {
277 var content = h('div.content')
278 var screen = document.getElementById('screen')
279
280 screen.appendChild(hyperscroll(content))
281
282 function createStream (opts) {
283 return pull(
284 More(sbot.userStream, opts, ['value', 'sequence']),
285 pull.map(function (msg) {
286 return render(h('div', msg))
287 })
288 )
289 }
290
291 pull(
292 createStream({old: false, limit: 10, id: src}),
293 stream.top(content)
294 )
295
296 pull(
297 createStream({reverse: true, live: false, limit: 10, id: src}),
298 stream.bottom(content)
299 )
300
301 var profile = h('div.content#profile', h('div.message'))
302
303 if (screen.firstChild.firstChild) {
304 screen.firstChild.insertBefore(profile, screen.firstChild.firstChild)
305 } else {
306 screen.firstChild.appendChild(profile)
307 }
308
309 var name = avatar.name(src)
310
311 var editname = h('span',
312 avatar.name(src),
313 h('button.btn', 'New name', {
314 onclick: function () {
315 var nameput = h('input', {placeholder: name.textContent})
316 var nameedit =
317 h('span', nameput,
318 h('button.btn', 'Preview', {
319 onclick: function () {
320 if (nameput.value[0] != '@')
321 tobename = nameput.value
322 else
323 tobename = nameput.value.substring(1, 100)
324 var newname = h('span', h('a', {href: '#' + src}, '@' + tobename), h('button.btn', 'Publish', {
325 onclick: function () {
326 var donename = h('span', h('a', {href: '#' + src}, '@' + tobename))
327 sbot.publish({type: 'about', about: src, name: tobename})
328 localStorage[src + 'name'] = tobename
329 newname.parentNode.replaceChild(donename, newname)
330 }
331 }))
332 nameedit.parentNode.replaceChild(newname, nameedit)
333 }
334 })
335 )
336 editname.parentNode.replaceChild(nameedit, editname)
337 }
338 })
339 )
340
341 var editimage = h('span',
342 h('button.btn', 'New image', {
343 onclick: function () {
344 var upload =
345 h('span',
346 hyperfile.asDataURL(function (data) {
347 if(data) {
348 //img.src = data
349 var _data = dataurl.parse(data)
350 pull(
351 pull.once(_data.data),
352 sbot.addblob(function (err, hash) {
353 if(err) return alert(err.stack)
354 selected = {
355 link: hash,
356 size: _data.data.length,
357 type: _data.mimetype
358 }
359 })
360 )
361 }
362 }),
363 h('button.btn', 'Preview image', {
364 onclick: function() {
365 if (selected) {
366 console.log(selected)
367 var oldImage = document.getElementById('profileImage')
368 var newImage = h('span.avatar--medium', h('img', {src: config.blobsUrl + selected.link}))
369 var publish = h('button.btn', 'Publish image', {
370 onclick: function () {
371 sbot.publish({
372 type: 'about',
373 about: src,
374 image: selected
375 }, function (err, published) {
376 console.log(published)
377 })
378 }
379 })
380 upload.parentNode.replaceChild(publish, upload)
381 oldImage.parentNode.replaceChild(newImage, oldImage)
382 }
383 /*if(selected) {
384 api.message_confirm({
385 type: 'about',
386 about: id,
387 image: selected
388 })
389 } else { alert('select an image before hitting preview')}*/
390 }
391 })
392 )
393 editimage.parentNode.replaceChild(upload, editimage)
394 }
395 })
396 )
397
398 var avatars = h('div.avatars',
399 h('a', {href: '#' + src},
400 h('span.avatar--medium#profileImage', avatar.image(src)),
401 editname,
402 h('br'),
403 editimage
404 )
405 )
406
407 pull(
408 sbot.userStream({id: src, reverse: false, limit: 1}),
409 pull.drain(function (msg) {
410 var howlong = h('span', h('br'), ' arrived ', human(new Date(msg.value.timestamp)))
411 avatars.appendChild(howlong)
412 console.log(msg)
413 })
414 )
415
416
417 var buttons = h('div.buttons')
418
419 profile.firstChild.appendChild(avatars)
420 profile.firstChild.appendChild(buttons)
421 buttons.appendChild(tools.mute(src))
422
423 var writeMessage = h('button.btn', 'Public message ', avatar.name(src), {
424 onclick: function () {
425 opts = {}
426 opts.type = 'post'
427 opts.mentions = '[' + name.textContent + '](' + src + ')'
428 var composer = h('div#composer', h('div.message', compose(opts)))
429 profile.appendChild(composer)
430 }
431 })
432
433 var writePrivate = h('button.btn', 'Private message ', avatar.name(src), {
434 onclick: function () {
435 opts = {}
436 opts.type = 'post'
437 opts.mentions = '[' + name.textContent + '](' + src + ')'
438 opts.recps = [src, id]
439 var composer = h('div#composer', h('div.message', compose(opts)))
440 profile.appendChild(composer)
441 }
442 })
443
444 buttons.appendChild(writeMessage)
445 buttons.appendChild(writePrivate)
446 buttons.appendChild(tools.follow(src))
447 buttons.appendChild(tools.block(src))
448
449 buttons.appendChild(h('button.btn', 'Generate follows', {
450 onclick: function () {
451 profile.firstChild.appendChild(tools.getFollowing(src))
452 profile.firstChild.appendChild(tools.getFollowers(src))
453 }
454 }))
455
456 buttons.appendChild(h('button.btn', 'Generate blocks', {
457 onclick: function () {
458 profile.firstChild.appendChild(tools.getBlocks(src))
459 profile.firstChild.appendChild(tools.getBlocked(src))
460 }
461 }))
462 buttons.appendChild(h('a', {href: '#wall/' + src}, h('button.btn', avatar.name(src), "'s wall")))
463
464}
465
466var privateMsg = function (src) {
467 var content = h('div.content')
468 var screen = document.getElementById('screen')
469 screen.appendChild(hyperscroll(content))
470
471 sbot.get(src, function (err, data) {
472 if (err) {
473 var message = h('div.message', 'Missing message!')
474 content.appendChild(message)
475 }
476 if (data) {
477 console.log(data)
478 data.value = data
479 data.key = src
480
481 content.appendChild(render(data))
482 }
483
484 })
485}
486
487var msgThread = function (src) {
488
489 var content = h('div.content')
490 var screen = document.getElementById('screen')
491 screen.appendChild(hyperscroll(content))
492
493 pull(
494 sbot.query({query: [{$filter: { value: { content: {root: src}, timestamp: { $gt: 1 }}}}], live: true}),
495 pull.drain(function (msg) {
496 if (msg.value) {
497 content.appendChild(render(msg))
498 }
499 })
500 )
501
502 sbot.get(src, function (err, data) {
503 if (err) {
504 var message = h('div.message', 'Missing message!')
505 content.appendChild(message)
506 }
507 if (data) {
508 var message = {}
509 message.value = data
510 message.key = src
511 console.log(message)
512 var rootMsg = render(message)
513
514 if (content.firstChild) {
515 content.insertBefore(rootMsg, content.firstChild)
516 } else {
517 content.appendChild(rootMsg)
518 }
519 if (message.value.content.type == 'git-repo') {
520 pull(
521 sbot.backlinks({query: [{$filter: {value: {content: {type: 'git-update'}}, dest: src}}]}),
522 pull.drain(function (msg) {
523 if (msg.value) {
524 content.appendChild(render(msg))
525 }
526 })
527 )
528 }
529
530 }
531 })
532
533}
534
535var keyPage = function () {
536 var screen = document.getElementById('screen')
537
538 var importKey = h('textarea.import', {placeholder: 'Import a new public/private key', name: 'textarea', style: 'width: 97%; height: 100px;'})
539
540 var content = h('div.content',
541 h('div.message#key',
542 h('h1', 'Your Key'),
543 h('p', {innerHTML: 'Your public/private key is: <pre><code>' + localStorage[config.caps.shs + '/secret'] + '</code></pre>'},
544 h('button.btn', {onclick: function (e){
545 localStorage[config.caps.shs +'/secret'] = ''
546 alert('Your public/private key has been deleted')
547 e.preventDefault()
548 location.hash = ""
549 location.reload()
550 }}, 'Delete Key')
551 ),
552 h('hr'),
553 h('form',
554 importKey,
555 h('button.btn', {onclick: function (e){
556 if(importKey.value) {
557 localStorage[config.caps.shs + '/secret'] = importKey.value.replace(/\s+/g, ' ')
558 e.preventDefault()
559 alert('Your public/private key has been updated')
560 }
561 location.hash = ""
562 location.reload()
563 }}, 'Import key'),
564 )
565 )
566 )
567
568 screen.appendChild(hyperscroll(content))
569}
570
571
572function friendsStream (src) {
573
574 var screen = document.getElementById('screen')
575 var content = h('div.content')
576
577 screen.appendChild(hyperscroll(content))
578
579 function createStream (opts) {
580 return pull(
581 Next(sbot.query, opts, ['value', 'timestamp']),
582 pull.map(function (msg) {
583 sbot.friends.get({source: src, dest: msg.value.author}, function (err, data) {
584 if (data === true) {
585 return content.appendChild(render(msg))
586 console.log(msg)
587 } else {
588 return content.appendChild(h('div'))
589 }
590 })
591 })
592 )
593 }
594
595 pull(
596 createStream({
597 limit: 1000,
598 reverse: true,
599 live: false,
600 query: [{$filter: { value: { timestamp: { $gt: 0 }}}}]
601 }),
602 stream.bottom(content)
603 )
604
605}
606
607function everythingStream () {
608
609 var screen = document.getElementById('screen')
610 var content = h('div.content')
611
612 screen.appendChild(hyperscroll(content))
613
614 function createStream (opts) {
615 return pull(
616 Next(sbot.query, opts, ['value', 'timestamp']),
617 pull.map(function (msg) {
618 if (msg.value) {
619 if (msg.value.timestamp > Date.now()) {
620 return h('div.future')
621 } else {
622 return render(msg)
623 }
624 }
625 })
626 )
627 }
628
629 pull(
630 createStream({
631 limit: 10,
632 reverse: true,
633 live: false,
634 query: [{$filter: { value: { timestamp: { $gt: 0 }}}}]
635 }),
636 stream.bottom(content)
637 )
638
639 pull(
640 createStream({
641 limit: 10,
642 old: false,
643 live: true,
644 query: [{$filter: { value: { timestamp: { $gt: 0 }}}}]
645 }),
646 stream.top(content)
647 )
648}
649
650
651
652
653function backchannel () {
654
655 var screen = document.getElementById('screen')
656 var content = h('div.content')
657
658 screen.appendChild(hyperscroll(content))
659
660 var chatbox = h('input', {placeholder: 'Backchannel'})
661
662 var chat = h('div.content')
663
664 var publish = h('button.btn', 'Publish', {
665 onclick: function () {
666 if (chatbox.value) {
667 var content = {
668 text: chatbox.value,
669 type: 'scat_message'
670 }
671 sbot.publish(content, function (err, msg) {
672 if (err) throw err
673 chatbox.value = ''
674 console.log('Published!', msg)
675 })
676 }
677 }
678 })
679
680 chat.appendChild(h('div.message', chatbox, publish))
681
682 if (screen.firstChild.firstChild) {
683 screen.firstChild.insertBefore(chat, screen.firstChild.firstChild)
684 } else {
685 screen.firstChild.appendChild(chat)
686 }
687
688 function createStream (opts) {
689 return pull(
690 Next(sbot.query, opts, ['value', 'timestamp']),
691 pull.map(function (msg) {
692 if (msg.value) {
693 return render(msg)
694 }
695 })
696 )
697 }
698
699 pull(
700 createStream({
701 limit: 10,
702 reverse: true,
703 live: false,
704 query: [{$filter: { value: { content: {type: 'scat_message'}, timestamp: { $gt: 0 }}}}]
705 }),
706 stream.bottom(content)
707 )
708
709 pull(
710 createStream({
711 limit: 10,
712 old: false,
713 live: true,
714 query: [{$filter: { value: { content: {type: 'scat_message'}, timestamp: { $gt: 0 }}}}]
715 }),
716 stream.top(content)
717 )
718}
719
720function search (src) {
721 console.log('search' + src)
722
723 var content = h('div.content')
724 var screen = document.getElementById('screen')
725 screen.appendChild(hyperscroll(content))
726
727 pull(
728 sbot.search.query({query: src, limit: 100}),
729 pull.drain(function (search) {
730 content.appendChild(render(search))
731 })
732 )
733
734}
735
736function hash () {
737 return window.location.hash.substring(1)
738}
739
740module.exports = function () {
741 var src = hash()
742
743 if (src.substring(52, 59) == '?unbox=') {
744 privateMsg(src)
745 } else if (ref.isFeed(src)) {
746 userStream(src)
747 } else if (ref.isMsg(src)) {
748 msgThread(src)
749 } else if (ref.isFeed(src.substring(5))) {
750 mentionsStream(src.substring(5))
751 } else if (ref.isFeed(src.substring(8))) {
752 friendsStream(src.substring(8))
753 } else if (src.substring(0, 6) === 'label/') {
754 labelStream(src.substring(6))
755 } else if (src == 'queue') {
756 queueStream()
757 } else if (src == 'about') {
758 about()
759 } else if (src == 'backchannel') {
760 backchannel()
761 } else if (src == 'private') {
762 privateStream()
763 } else if (src == 'key') {
764 keyPage()
765 } else if (src[0] == '?' || (src[0] == '#')) {
766 if (src[0] == '#')
767 search(src.split('%20').join(' '))
768 else
769 search(src.substr(1).split('%20').join(' '))
770 } else {
771 everythingStream()
772 //checkInvite()
773 }
774
775}
776

Built with git-ssb-web