git ssb

1+

punkmonk.termux / mvd



forked from ev / mvd

Tree: 3ac3f63409b2f6e177034de5ad8483d25749626a

Files: 3ac3f63409b2f6e177034de5ad8483d25749626a / mvd / views.js

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

Built with git-ssb-web