git ssb

1+

punkmonk.termux / mvd



forked from ev / mvd

Tree: fd5b5ec859326033c364c31f5df00f867216815f

Files: fd5b5ec859326033c364c31f5df00f867216815f / views.js

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

Built with git-ssb-web