git ssb

2+

ev / mvd



Tree: ed36da04fb161112f1cad169cc8460e5b988937e

Files: ed36da04fb161112f1cad169cc8460e5b988937e / views.js

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

Built with git-ssb-web