git ssb

3+

ev / decent



Tree: fbfff87a5febf165ddb5240685ba7433b7083770

Files: fbfff87a5febf165ddb5240685ba7433b7083770 / views.js

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

Built with git-ssb-web