git ssb

2+

ev / mvd



Tree: 86ead1fef00900a6c2c146204116783ab4b69ce9

Files: 86ead1fef00900a6c2c146204116783ab4b69ce9 / views.js

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

Built with git-ssb-web