git ssb

1+

punkmonk.termux / mvd



forked from ev / mvd

Tree: bea0d6f86662e5db7348deb37bef697f1226edae

Files: bea0d6f86662e5db7348deb37bef697f1226edae / ui / views.js

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

Built with git-ssb-web