git ssb

2+

ev / mvd



Tree: 2ab67531b8a5ecdd7419f3c8d9fa0ccee8cb9377

Files: 2ab67531b8a5ecdd7419f3c8d9fa0ccee8cb9377 / views.js

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

Built with git-ssb-web