git ssb

2+

ev / mvd



Tree: 98a2107f7a6f0dc6ea2ca1a3e86d1b830cfb74ff

Files: 98a2107f7a6f0dc6ea2ca1a3e86d1b830cfb74ff / views.js

13009 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
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(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 width: 512,
196 height: 512
197 }
198 })
199 )
200 }
201 }),
202 h('button.btn', 'Preview image', {
203 onclick: function() {
204 if (selected) {
205 console.log(selected)
206 var oldImage = document.getElementById('profileImage')
207 var newImage = h('span.avatar--medium', h('img', {src: config.blobsUrl + selected.link}))
208 var publish = h('button.btn', 'Publish image', {
209 onclick: function () {
210 sbot.publish({
211 type: 'about',
212 about: src,
213 image: selected
214 }, function (err, published) {
215 console.log(published)
216 })
217 }
218 })
219 upload.parentNode.replaceChild(publish, upload)
220 oldImage.parentNode.replaceChild(newImage, oldImage)
221 }
222 /*if(selected) {
223 api.message_confirm({
224 type: 'about',
225 about: id,
226 image: selected
227 })
228 } else { alert('select an image before hitting preview')}*/
229 }
230 })
231 )
232 editimage.parentNode.replaceChild(upload, editimage)
233 }
234 })
235 )
236
237 var avatars = h('div.avatars',
238 h('a', {href: '#' + src},
239 h('span.avatar--medium#profileImage', avatar.image(src)),
240 editname,
241 h('br'),
242 editimage
243 )
244 )
245
246 pull(
247 sbot.userStream({id: src, reverse: false, limit: 1}),
248 pull.drain(function (msg) {
249 var howlong = h('span', h('br'), ' arrived ', human(new Date(msg.value.timestamp)))
250 avatars.appendChild(howlong)
251 console.log(msg)
252 })
253 )
254
255
256 var buttons = h('div.buttons')
257
258 profile.firstChild.appendChild(avatars)
259 profile.firstChild.appendChild(buttons)
260 buttons.appendChild(tools.mute(src))
261
262 var writeMessage = h('button.btn', 'Public message ', avatar.name(src), {
263 onclick: function () {
264 opts = {}
265 opts.type = 'post'
266 opts.mentions = '[' + name.textContent + '](' + src + ')'
267 var composer = h('div#composer', h('div.message', compose(opts)))
268 profile.appendChild(composer)
269 }
270 })
271
272 var writePrivate = h('button.btn', 'Private message ', avatar.name(src), {
273 onclick: function () {
274 opts = {}
275 opts.type = 'post'
276 opts.mentions = '[' + name.textContent + '](' + src + ')'
277 opts.recps = [src, id]
278 var composer = h('div#composer', h('div.message', compose(opts)))
279 profile.appendChild(composer)
280 }
281 })
282
283 buttons.appendChild(writeMessage)
284 buttons.appendChild(writePrivate)
285 buttons.appendChild(tools.follow(src))
286
287 profile.firstChild.appendChild(tools.getFollowing(src))
288 profile.firstChild.appendChild(tools.getFollowers(src))
289}
290
291var msgThread = function (src) {
292
293 var content = h('div.content')
294 var screen = document.getElementById('screen')
295 screen.appendChild(hyperscroll(content))
296
297 pull(
298 sbot.query({query: [{$filter: { value: { content: {root: src}, timestamp: { $gt: 1 }}}}], live: true}),
299 pull.drain(function (msg) {
300 if (msg.value) {
301 content.appendChild(render(msg))
302 }
303 })
304 )
305
306 sbot.get(src, function (err, data) {
307 if (err) {console.log('could not find message')}
308 data.value = data
309 data.key = src
310 console.log(data)
311 var rootMsg = render(data)
312
313 if (content.firstChild) {
314 content.insertBefore(rootMsg, content.firstChild)
315 } else {
316 content.appendChild(rootMsg)
317 }
318 })
319}
320
321var keyPage = function () {
322 var screen = document.getElementById('screen')
323
324 var importKey = h('textarea.import', {placeholder: 'Import a new public/private key', name: 'textarea', style: 'width: 97%; height: 100px;'})
325
326 var content = h('div.content',
327 h('div.message#key',
328 h('h1', 'Your Key'),
329 h('p', {innerHTML: 'Your public/private key is: <pre><code>' + localStorage[config.caps.shs + '/secret'] + '</code></pre>'},
330 h('button.btn', {onclick: function (e){
331 localStorage[config.caps.shs +'/secret'] = ''
332 alert('Your public/private key has been deleted')
333 e.preventDefault()
334 location.hash = ""
335 location.reload()
336 }}, 'Delete Key')
337 ),
338 h('hr'),
339 h('form',
340 importKey,
341 h('button.btn', {onclick: function (e){
342 if(importKey.value) {
343 localStorage[config.caps.shs + '/secret'] = importKey.value.replace(/\s+/g, ' ')
344 e.preventDefault()
345 alert('Your public/private key has been updated')
346 }
347 location.hash = ""
348 location.reload()
349 }}, 'Import key'),
350 )
351 )
352 )
353
354 screen.appendChild(hyperscroll(content))
355}
356
357function everythingStream () {
358
359 var screen = document.getElementById('screen')
360 var content = h('div.content')
361
362 screen.appendChild(hyperscroll(content))
363
364 function createStream (opts) {
365 return pull(
366 Next(sbot.query, opts, ['value', 'timestamp']),
367 pull.map(function (msg) {
368 if (msg.value) {
369 return render(msg)
370 }
371 })
372 )
373 }
374
375 pull(
376 createStream({
377 limit: 10,
378 reverse: true,
379 live: false,
380 query: [{$filter: { value: { timestamp: { $gt: 0 }}}}]
381 }),
382 stream.bottom(content)
383 )
384
385 pull(
386 createStream({
387 limit: 10,
388 old: false,
389 live: true,
390 query: [{$filter: { value: { timestamp: { $gt: 0 }}}}]
391 }),
392 stream.top(content)
393 )
394}
395
396function backchannel () {
397
398 var screen = document.getElementById('screen')
399 var content = h('div.content')
400
401 screen.appendChild(hyperscroll(content))
402
403 var chatbox = h('input', {placeholder: 'Backchannel'})
404
405 var chat = h('div.content')
406
407 var publish = h('button.btn', 'Publish', {
408 onclick: function () {
409 if (chatbox.value) {
410 var content = {
411 text: chatbox.value,
412 type: 'scat_message'
413 }
414 sbot.publish(content, function (err, msg) {
415 if (err) throw err
416 chatbox.value = ''
417 console.log('Published!', msg)
418 })
419 }
420 }
421 })
422
423 chat.appendChild(h('div.message', chatbox, publish))
424
425 if (screen.firstChild.firstChild) {
426 screen.firstChild.insertBefore(chat, screen.firstChild.firstChild)
427 } else {
428 screen.firstChild.appendChild(chat)
429 }
430
431 function createStream (opts) {
432 return pull(
433 Next(sbot.query, opts, ['value', 'timestamp']),
434 pull.map(function (msg) {
435 if (msg.value) {
436 return render(msg)
437 }
438 })
439 )
440 }
441
442 pull(
443 createStream({
444 limit: 10,
445 reverse: true,
446 live: false,
447 query: [{$filter: { value: { content: {type: 'scat_message'}, timestamp: { $gt: 0 }}}}]
448 }),
449 stream.bottom(content)
450 )
451
452 pull(
453 createStream({
454 limit: 10,
455 old: false,
456 live: true,
457 query: [{$filter: { value: { content: {type: 'scat_message'}, timestamp: { $gt: 0 }}}}]
458 }),
459 stream.top(content)
460 )
461}
462
463
464function hash () {
465 return window.location.hash.substring(1)
466}
467
468module.exports = function () {
469 var src = hash()
470
471 if (ref.isFeed(src)) {
472 userStream(src)
473 } else if (ref.isMsg(src)) {
474 msgThread(src)
475 } else if (src == 'mentions') {
476 mentionsStream()
477 } else if (src == 'about') {
478 about()
479 } else if (src == 'backchannel') {
480 backchannel()
481 } else if (src == 'private') {
482 privateStream()
483 } else if (src == 'key') {
484 keyPage()
485 } else {
486 everythingStream()
487 checkInvite()
488 }
489
490}
491

Built with git-ssb-web