git ssb

0+

ev / gitmx



Tree: 4ebd64c079e0384a0b21f1f89f9cfc9606bd7d13

Files: 4ebd64c079e0384a0b21f1f89f9cfc9606bd7d13 / views.js

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

Built with git-ssb-web