git ssb

2+

ev / mvd



Tree: 8c9cc0b21eca28ac144356172dd3e6751ff73d3b

Files: 8c9cc0b21eca28ac144356172dd3e6751ff73d3b / views.js

20172 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 screen.appendChild(hyperscroll(content))
280 function createStream (opts) {
281 return pull(
282 More(sbot.userStream, opts, ['value', 'sequence']),
283 pull.map(function (msg) {
284 return render(h('div', msg))
285 })
286 )
287 }
288
289 pull(
290 createStream({old: false, limit: 10, id: src}),
291 stream.top(content)
292 )
293
294 pull(
295 createStream({reverse: true, live: false, limit: 10, id: src}),
296 stream.bottom(content)
297 )
298
299 var profile = h('div.content#profile', h('div.message'))
300
301 if (screen.firstChild.firstChild) {
302 screen.firstChild.insertBefore(profile, screen.firstChild.firstChild)
303 } else {
304 screen.firstChild.appendChild(profile)
305 }
306
307 var name = avatar.name(src)
308
309 var editname = h('span',
310 avatar.name(src),
311 h('button.btn', 'New name', {
312 onclick: function () {
313 var nameput = h('input', {placeholder: name.textContent})
314 var nameedit =
315 h('span', nameput,
316 h('button.btn', 'Preview', {
317 onclick: function () {
318 if (nameput.value[0] != '@')
319 tobename = nameput.value
320 else
321 tobename = nameput.value.substring(1, 100)
322 var newname = h('span', h('a', {href: '#' + src}, '@' + tobename), h('button.btn', 'Publish', {
323 onclick: function () {
324 var donename = h('span', h('a', {href: '#' + src}, '@' + tobename))
325 sbot.publish({type: 'about', about: src, name: tobename})
326 localStorage[src + 'name'] = tobename
327 newname.parentNode.replaceChild(donename, newname)
328 }
329 }))
330 nameedit.parentNode.replaceChild(newname, nameedit)
331 }
332 })
333 )
334 editname.parentNode.replaceChild(nameedit, editname)
335 }
336 })
337 )
338
339 var editimage = h('span',
340 h('button.btn', 'New image', {
341 onclick: function () {
342 var upload =
343 h('span',
344 hyperfile.asDataURL(function (data) {
345 if(data) {
346 //img.src = data
347 var _data = dataurl.parse(data)
348 pull(
349 pull.once(_data.data),
350 sbot.addblob(function (err, hash) {
351 if(err) return alert(err.stack)
352 selected = {
353 link: hash,
354 size: _data.data.length,
355 type: _data.mimetype
356 }
357 })
358 )
359 }
360 }),
361 h('button.btn', 'Preview image', {
362 onclick: function() {
363 if (selected) {
364 console.log(selected)
365 var oldImage = document.getElementById('profileImage')
366 var newImage = h('span.avatar--medium', h('img', {src: config.blobsUrl + selected.link}))
367 var publish = h('button.btn', 'Publish image', {
368 onclick: function () {
369 sbot.publish({
370 type: 'about',
371 about: src,
372 image: selected
373 }, function (err, published) {
374 console.log(published)
375 })
376 }
377 })
378 upload.parentNode.replaceChild(publish, upload)
379 oldImage.parentNode.replaceChild(newImage, oldImage)
380 }
381 /*if(selected) {
382 api.message_confirm({
383 type: 'about',
384 about: id,
385 image: selected
386 })
387 } else { alert('select an image before hitting preview')}*/
388 }
389 })
390 )
391 editimage.parentNode.replaceChild(upload, editimage)
392 }
393 })
394 )
395
396 var avatars = h('div.avatars',
397 h('a', {href: '#' + src},
398 h('span.avatar--medium#profileImage', avatar.image(src)),
399 editname,
400 h('br'),
401 editimage
402 )
403 )
404
405 pull(
406 sbot.userStream({id: src, reverse: false, limit: 1}),
407 pull.drain(function (msg) {
408 var howlong = h('span', h('br'), ' arrived ', human(new Date(msg.value.timestamp)))
409 avatars.appendChild(howlong)
410 console.log(msg)
411 })
412 )
413
414
415 var buttons = h('div.buttons')
416
417 profile.firstChild.appendChild(avatars)
418 profile.firstChild.appendChild(buttons)
419 buttons.appendChild(tools.mute(src))
420
421 var writeMessage = h('button.btn', 'Public message ', avatar.name(src), {
422 onclick: function () {
423 opts = {}
424 opts.type = 'post'
425 opts.mentions = '[' + name.textContent + '](' + src + ')'
426 var composer = h('div#composer', h('div.message', compose(opts)))
427 profile.appendChild(composer)
428 }
429 })
430
431 var writePrivate = h('button.btn', 'Private message ', avatar.name(src), {
432 onclick: function () {
433 opts = {}
434 opts.type = 'post'
435 opts.mentions = '[' + name.textContent + '](' + src + ')'
436 opts.recps = [src, id]
437 var composer = h('div#composer', h('div.message', compose(opts)))
438 profile.appendChild(composer)
439 }
440 })
441
442 buttons.appendChild(writeMessage)
443 buttons.appendChild(writePrivate)
444 buttons.appendChild(tools.follow(src))
445 buttons.appendChild(tools.block(src))
446
447 buttons.appendChild(h('button.btn', 'Generate follows', {
448 onclick: function () {
449 profile.firstChild.appendChild(tools.getFollowing(src))
450 profile.firstChild.appendChild(tools.getFollowers(src))
451 }
452 }))
453
454 buttons.appendChild(h('button.btn', 'Generate blocks', {
455 onclick: function () {
456 profile.firstChild.appendChild(tools.getBlocks(src))
457 profile.firstChild.appendChild(tools.getBlocked(src))
458 }
459 }))
460 buttons.appendChild(h('a', {href: '#wall/' + src}, h('button.btn', avatar.name(src), "'s wall")))
461
462}
463
464var privateMsg = function (src) {
465 var content = h('div.content')
466 var screen = document.getElementById('screen')
467 screen.appendChild(hyperscroll(content))
468
469 sbot.get(src, function (err, data) {
470 if (err) {
471 var message = h('div.message', 'Missing message!')
472 content.appendChild(message)
473 }
474 if (data) {
475 console.log(data)
476 data.value = data
477 data.key = src
478
479 content.appendChild(render(data))
480 }
481
482 })
483}
484
485var msgThread = function (src) {
486
487 var content = h('div.content')
488 var screen = document.getElementById('screen')
489 screen.appendChild(hyperscroll(content))
490
491 pull(
492 sbot.query({query: [{$filter: { value: { content: {root: src}, timestamp: { $gt: 1 }}}}], live: true}),
493 pull.drain(function (msg) {
494 if (msg.value) {
495 content.appendChild(render(msg))
496 }
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 data.value = data
508 data.key = src
509 console.log(data)
510 var rootMsg = render(data)
511
512 if (content.firstChild) {
513 content.insertBefore(rootMsg, content.firstChild)
514 } else {
515 content.appendChild(rootMsg)
516 }
517 if (data.value.content.type == 'git-repo') {
518 pull(
519 sbot.backlinks({query: [{$filter: {value: {content: {type: 'git-update'}}, dest: src}}]}),
520 pull.drain(function (msg) {
521 if (msg.value) {
522 content.appendChild(render(msg))
523 }
524 })
525 )
526 }
527
528 }
529 })
530}
531
532var keyPage = function () {
533 var screen = document.getElementById('screen')
534
535 var importKey = h('textarea.import', {placeholder: 'Import a new public/private key', name: 'textarea', style: 'width: 97%; height: 100px;'})
536
537 var content = h('div.content',
538 h('div.message#key',
539 h('h1', 'Your Key'),
540 h('p', {innerHTML: 'Your public/private key is: <pre><code>' + localStorage[config.caps.shs + '/secret'] + '</code></pre>'},
541 h('button.btn', {onclick: function (e){
542 localStorage[config.caps.shs +'/secret'] = ''
543 alert('Your public/private key has been deleted')
544 e.preventDefault()
545 location.hash = ""
546 location.reload()
547 }}, 'Delete Key')
548 ),
549 h('hr'),
550 h('form',
551 importKey,
552 h('button.btn', {onclick: function (e){
553 if(importKey.value) {
554 localStorage[config.caps.shs + '/secret'] = importKey.value.replace(/\s+/g, ' ')
555 e.preventDefault()
556 alert('Your public/private key has been updated')
557 }
558 location.hash = ""
559 location.reload()
560 }}, 'Import key'),
561 )
562 )
563 )
564
565 screen.appendChild(hyperscroll(content))
566}
567
568
569function friendsStream (src) {
570
571 var screen = document.getElementById('screen')
572 var content = h('div.content')
573
574 screen.appendChild(hyperscroll(content))
575
576 function createStream (opts) {
577 return pull(
578 Next(sbot.query, opts, ['value', 'timestamp']),
579 pull.map(function (msg) {
580 sbot.friends.get({source: src, dest: msg.value.author}, function (err, data) {
581 if (data === true) {
582 return content.appendChild(render(msg))
583 console.log(msg)
584 } else {
585 return content.appendChild(h('div'))
586 }
587 })
588 })
589 )
590 }
591
592 pull(
593 createStream({
594 limit: 1000,
595 reverse: true,
596 live: false,
597 query: [{$filter: { value: { timestamp: { $gt: 0 }}}}]
598 }),
599 stream.bottom(content)
600 )
601
602}
603
604function everythingStream () {
605
606 var screen = document.getElementById('screen')
607 var content = h('div.content')
608
609 screen.appendChild(hyperscroll(content))
610
611 function createStream (opts) {
612 return pull(
613 Next(sbot.query, opts, ['value', 'timestamp']),
614 pull.map(function (msg) {
615 if (msg.value) {
616 if (msg.value.timestamp > Date.now()) {
617 return h('div.future')
618 } else {
619 return render(msg)
620 }
621 }
622 })
623 )
624 }
625
626 pull(
627 createStream({
628 limit: 10,
629 reverse: true,
630 live: false,
631 query: [{$filter: { value: { timestamp: { $gt: 0 }}}}]
632 }),
633 stream.bottom(content)
634 )
635
636 pull(
637 createStream({
638 limit: 10,
639 old: false,
640 live: true,
641 query: [{$filter: { value: { timestamp: { $gt: 0 }}}}]
642 }),
643 stream.top(content)
644 )
645}
646
647
648
649
650function backchannel () {
651
652 var screen = document.getElementById('screen')
653 var content = h('div.content')
654
655 screen.appendChild(hyperscroll(content))
656
657 var chatbox = h('input', {placeholder: 'Backchannel'})
658
659 var chat = h('div.content')
660
661 var publish = h('button.btn', 'Publish', {
662 onclick: function () {
663 if (chatbox.value) {
664 var content = {
665 text: chatbox.value,
666 type: 'scat_message'
667 }
668 sbot.publish(content, function (err, msg) {
669 if (err) throw err
670 chatbox.value = ''
671 console.log('Published!', msg)
672 })
673 }
674 }
675 })
676
677 chat.appendChild(h('div.message', chatbox, publish))
678
679 if (screen.firstChild.firstChild) {
680 screen.firstChild.insertBefore(chat, screen.firstChild.firstChild)
681 } else {
682 screen.firstChild.appendChild(chat)
683 }
684
685 function createStream (opts) {
686 return pull(
687 Next(sbot.query, opts, ['value', 'timestamp']),
688 pull.map(function (msg) {
689 if (msg.value) {
690 return render(msg)
691 }
692 })
693 )
694 }
695
696 pull(
697 createStream({
698 limit: 10,
699 reverse: true,
700 live: false,
701 query: [{$filter: { value: { content: {type: 'scat_message'}, timestamp: { $gt: 0 }}}}]
702 }),
703 stream.bottom(content)
704 )
705
706 pull(
707 createStream({
708 limit: 10,
709 old: false,
710 live: true,
711 query: [{$filter: { value: { content: {type: 'scat_message'}, timestamp: { $gt: 0 }}}}]
712 }),
713 stream.top(content)
714 )
715}
716
717function search (src) {
718 console.log('search' + src)
719
720 var content = h('div.content')
721 var screen = document.getElementById('screen')
722 screen.appendChild(hyperscroll(content))
723
724 pull(
725 sbot.search.query({query: src, limit: 100}),
726 pull.drain(function (search) {
727 content.appendChild(render(search))
728 })
729 )
730
731}
732
733function hash () {
734 return window.location.hash.substring(1)
735}
736
737module.exports = function () {
738 var src = hash()
739
740 if (src.substring(52, 59) == '?unbox=') {
741 privateMsg(src)
742 } else if (ref.isFeed(src)) {
743 userStream(src)
744 } else if (ref.isMsg(src)) {
745 msgThread(src)
746 } else if (ref.isFeed(src.substring(5))) {
747 mentionsStream(src.substring(5))
748 } else if (ref.isFeed(src.substring(8))) {
749 friendsStream(src.substring(8))
750 } else if (src.substring(0, 6) === 'label/') {
751 labelStream(src.substring(6))
752 } else if (src == 'queue') {
753 queueStream()
754 } else if (src == 'about') {
755 about()
756 } else if (src == 'backchannel') {
757 backchannel()
758 } else if (src == 'private') {
759 privateStream()
760 } else if (src == 'key') {
761 keyPage()
762 } else if (src[0] == '?' || (src[0] == '#')) {
763 if (src[0] == '#')
764 search(src.split('%20').join(' '))
765 else
766 search(src.substr(1).split('%20').join(' '))
767 } else {
768 everythingStream()
769 checkInvite()
770 }
771
772}
773

Built with git-ssb-web