git ssb

3+

ev / decent



Tree: 060a2be4d73562a15bbf948d5fe42c83c9f4f02d

Files: 060a2be4d73562a15bbf948d5fe42c83c9f4f02d / views.js

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

Built with git-ssb-web