git ssb

2+

ev / mvd



Tree: 9899c393ca4253f2d31fa840a2aa4733dc2dc99d

Files: 9899c393ca4253f2d31fa840a2aa4733dc2dc99d / views.js

10789 bytesRaw
1var pull = require('pull-stream')
2var human = require('human-time')
3var sbot = require('./scuttlebot')
4var hyperscroll = require('hyperscroll')
5var More = require('pull-more')
6var stream = require('hyperloadmore/stream')
7var h = require('hyperscript')
8var render = require('./render')
9var ref = require('ssb-ref')
10var client = require('ssb-client')
11
12var Next = require('pull-next-query')
13
14var config = require('./config')()
15
16var tools = require('./tools')
17var avatar = require('./avatar')
18var id = require('./keys').id
19
20var ssbKeys = require('ssb-keys')
21var keys = require('./keys')
22
23var checkInvite = require('./invite')
24
25var compose = require('./compose')
26
27var about = function () {
28 var screen = document.getElementById('screen')
29
30 var about = require('./about')
31
32 var content = h('div.content', about)
33
34 screen.appendChild(hyperscroll(content))
35}
36
37var privateStream = function () {
38 var content = h('div.content')
39 var screen = document.getElementById('screen')
40 screen.appendChild(hyperscroll(content))
41
42 function createStream (opts) {
43 return pull(
44 More(sbot.createLogStream, opts),
45 pull.filter(function (msg) {
46 return 'string' == typeof msg.value.content
47 }),
48 pull.filter(function (msg) {
49 var unboxed = ssbKeys.unbox(msg.value.content, keys)
50 if (unboxed) {
51 msg.value.content = unboxed
52 msg.value.private = true
53 return msg
54 }
55 }),
56 pull.map(function (msg) {
57 return render(msg)
58 })
59 )
60 }
61
62 pull(
63 createStream({old: false, limit: 1000}),
64 stream.top(content)
65 )
66
67 pull(
68 createStream({reverse: true, live: false, limit: 1000}),
69 stream.bottom(content)
70 )
71}
72
73var mentionsStream = function () {
74 var content = h('div.content')
75
76 var screen = document.getElementById('screen')
77
78 screen.appendChild(hyperscroll(content))
79
80 function createStream (opts) {
81 return pull(
82 Next(sbot.backlinks, opts, ['value', 'timestamp']),
83 pull.map(function (msg) {
84 if (msg.value.private == true) return
85 return render(msg)
86 })
87 )
88 }
89
90 pull(
91 createStream({
92 limit: 10,
93 reverse: true,
94 index: 'DTA',
95 live: false,
96 query: [{$filter: {dest: id}}]
97 }),
98 stream.bottom(content)
99 )
100
101 pull(
102 createStream({
103 limit: 10,
104 old: false,
105 index: 'DTA',
106 live: true,
107 query: [{$filter: {dest: id}}]
108 }),
109 stream.top(content)
110 )
111}
112
113var userStream = function (src) {
114 var content = h('div.content')
115 var screen = document.getElementById('screen')
116 screen.appendChild(hyperscroll(content))
117 function createStream (opts) {
118 return pull(
119 More(sbot.userStream, opts, ['value', 'sequence']),
120 pull.map(function (msg) {
121 return render(msg)
122 })
123 )
124 }
125
126 pull(
127 createStream({old: false, limit: 10, id: src}),
128 stream.top(content)
129 )
130
131 pull(
132 createStream({reverse: true, live: false, limit: 10, id: src}),
133 stream.bottom(content)
134 )
135
136 var profile = h('div.content#profile', h('div.message'))
137
138 if (screen.firstChild.firstChild) {
139 screen.firstChild.insertBefore(profile, screen.firstChild.firstChild)
140 } else {
141 screen.firstChild.appendChild(profile)
142 }
143 var name = avatar.name(src)
144
145 var editname = h('span',
146 avatar.name(src),
147 h('button.btn', 'Edit', {
148 onclick: function () {
149 var nameput = h('input', {placeholder: name.textContent})
150 var nameedit =
151 h('span', nameput,
152 h('button.btn', 'Preview', {
153 onclick: function () {
154 if (nameput.value[0] != '@')
155 tobename = nameput.value
156 else
157 tobename = nameput.value.substring(1, 100)
158 var newname = h('span', h('a', {href: '#' + src}, '@' + tobename), h('button.btn', 'Publish', {
159 onclick: function () {
160 var donename = h('span', h('a', {href: '#' + src}, '@' + tobename))
161 sbot.publish({type: 'about', about: src, name: tobename})
162 localStorage[src + 'name'] = tobename
163 newname.parentNode.replaceChild(donename, newname)
164 }
165 }))
166 nameedit.parentNode.replaceChild(newname, nameedit)
167 }
168 })
169 )
170 editname.parentNode.replaceChild(nameedit, editname)
171 }
172 })
173 )
174
175 var avatars = h('div.avatars',
176 h('a', {href: '#' + src},
177 h('span.avatar--medium', avatar.image(src)),
178 editname
179 )
180 )
181
182 pull(
183 sbot.userStream({id: src, reverse: false, limit: 1}),
184 pull.drain(function (msg) {
185 var howlong = h('span', h('br'), ' arrived ', human(new Date(msg.value.timestamp)))
186 avatars.appendChild(howlong)
187 console.log(msg)
188 })
189 )
190
191
192 var buttons = h('div.buttons')
193
194 profile.firstChild.appendChild(avatars)
195 profile.firstChild.appendChild(buttons)
196 buttons.appendChild(tools.mute(src))
197
198 var writeMessage = h('button.btn', 'Public message ', avatar.name(src), {
199 onclick: function () {
200 opts = {}
201 opts.type = 'post'
202 opts.mentions = '[' + name.textContent + '](' + src + ')'
203 var composer = h('div#composer', h('div.message', compose(opts)))
204 profile.appendChild(composer)
205 }
206 })
207
208 var writePrivate = h('button.btn', 'Private message ', avatar.name(src), {
209 onclick: function () {
210 opts = {}
211 opts.type = 'post'
212 opts.mentions = '[' + name.textContent + '](' + src + ')'
213 opts.recps = [src, id]
214 var composer = h('div#composer', h('div.message', compose(opts)))
215 profile.appendChild(composer)
216 }
217 })
218
219 buttons.appendChild(writeMessage)
220 buttons.appendChild(writePrivate)
221 buttons.appendChild(tools.follow(src))
222
223 profile.firstChild.appendChild(tools.getFollowing(src))
224 profile.firstChild.appendChild(tools.getFollowers(src))
225}
226
227var msgThread = function (src) {
228
229 var content = h('div.content')
230 var screen = document.getElementById('screen')
231 screen.appendChild(hyperscroll(content))
232
233 pull(
234 sbot.query({query: [{$filter: { value: { content: {root: src}, timestamp: { $gt: 1 }}}}], live: true}),
235 pull.drain(function (msg) {
236 if (msg.value) {
237 content.appendChild(render(msg))
238 }
239 })
240 )
241
242 sbot.get(src, function (err, data) {
243 if (err) {console.log('could not find message')}
244 data.value = data
245 data.key = src
246 console.log(data)
247 var rootMsg = render(data)
248
249 if (content.firstChild) {
250 content.insertBefore(rootMsg, content.firstChild)
251 } else {
252 content.appendChild(rootMsg)
253 }
254 })
255}
256
257var keyPage = function () {
258 var screen = document.getElementById('screen')
259
260 var importKey = h('textarea.import', {placeholder: 'Import a new public/private key', name: 'textarea', style: 'width: 97%; height: 100px;'})
261
262 var content = h('div.content',
263 h('div.message#key',
264 h('h1', 'Your Key'),
265 h('p', {innerHTML: 'Your public/private key is: <pre><code>' + localStorage[config.caps.shs + '/secret'] + '</code></pre>'},
266 h('button.btn', {onclick: function (e){
267 localStorage[config.caps.shs +'/secret'] = ''
268 alert('Your public/private key has been deleted')
269 e.preventDefault()
270 location.hash = ""
271 location.reload()
272 }}, 'Delete Key')
273 ),
274 h('hr'),
275 h('form',
276 importKey,
277 h('button.btn', {onclick: function (e){
278 if(importKey.value) {
279 localStorage[config.caps.shs + '/secret'] = importKey.value.replace(/\s+/g, ' ')
280 e.preventDefault()
281 alert('Your public/private key has been updated')
282 }
283 location.hash = ""
284 location.reload()
285 }}, 'Import key'),
286 )
287 )
288 )
289
290 screen.appendChild(hyperscroll(content))
291}
292
293function everythingStream () {
294
295 var screen = document.getElementById('screen')
296 var content = h('div.content')
297
298 screen.appendChild(hyperscroll(content))
299
300 function createStream (opts) {
301 return pull(
302 Next(sbot.query, opts, ['value', 'timestamp']),
303 pull.map(function (msg) {
304 if (msg.value) {
305 return render(msg)
306 }
307 })
308 )
309 }
310
311 pull(
312 createStream({
313 limit: 10,
314 reverse: true,
315 live: false,
316 query: [{$filter: { value: { timestamp: { $gt: 0 }}}}]
317 }),
318 stream.bottom(content)
319 )
320
321 pull(
322 createStream({
323 limit: 10,
324 old: false,
325 live: true,
326 query: [{$filter: { value: { timestamp: { $gt: 0 }}}}]
327 }),
328 stream.top(content)
329 )
330}
331
332function backchannel () {
333
334 var screen = document.getElementById('screen')
335 var content = h('div.content')
336
337 screen.appendChild(hyperscroll(content))
338
339 var chatbox = h('input', {placeholder: 'Backchannel'})
340
341 var chat = h('div.content')
342
343 var publish = h('button.btn', 'Publish', {
344 onclick: function () {
345 if (chatbox.value) {
346 var content = {
347 text: chatbox.value,
348 type: 'scat_message'
349 }
350 sbot.publish(content, function (err, msg) {
351 if (err) throw err
352 chatbox.value = ''
353 console.log('Published!', msg)
354 })
355 }
356 }
357 })
358
359 chat.appendChild(h('div.message', chatbox, publish))
360
361 if (screen.firstChild.firstChild) {
362 screen.firstChild.insertBefore(chat, screen.firstChild.firstChild)
363 } else {
364 screen.firstChild.appendChild(chat)
365 }
366
367 function createStream (opts) {
368 return pull(
369 Next(sbot.query, opts, ['value', 'timestamp']),
370 pull.map(function (msg) {
371 if (msg.value) {
372 return render(msg)
373 }
374 })
375 )
376 }
377
378 pull(
379 createStream({
380 limit: 10,
381 reverse: true,
382 live: false,
383 query: [{$filter: { value: { content: {type: 'scat_message'}, timestamp: { $gt: 0 }}}}]
384 }),
385 stream.bottom(content)
386 )
387
388 pull(
389 createStream({
390 limit: 10,
391 old: false,
392 live: true,
393 query: [{$filter: { value: { content: {type: 'scat_message'}, timestamp: { $gt: 0 }}}}]
394 }),
395 stream.top(content)
396 )
397}
398
399
400function hash () {
401 return window.location.hash.substring(1)
402}
403
404module.exports = function () {
405 var src = hash()
406
407 if (ref.isFeed(src)) {
408 userStream(src)
409 } else if (ref.isMsg(src)) {
410 msgThread(src)
411 } else if (src == 'mentions') {
412 mentionsStream()
413 } else if (src == 'about') {
414 about()
415 } else if (src == 'backchannel') {
416 backchannel()
417 } else if (src == 'private') {
418 privateStream()
419 } else if (src == 'key') {
420 keyPage()
421 } else {
422 everythingStream()
423 checkInvite()
424 }
425
426}
427

Built with git-ssb-web