git ssb

2+

ev / mvd



Tree: 60ea2a8f16d4a0a20cfabcb154eaf98c4e370387

Files: 60ea2a8f16d4a0a20cfabcb154eaf98c4e370387 / views.js

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

Built with git-ssb-web