Files: 9ac76bea4f88cc5ca22ff5d5f4a4c06980dda5b8 / views.js
19879 bytesRaw
1 | var pull = require('pull-stream') |
2 | var human = require('human-time') |
3 | var sbot = require('./scuttlebot') |
4 | var hyperscroll = require('hyperscroll') |
5 | var hyperfile = require('hyperfile') |
6 | var dataurl = require('dataurl-') |
7 | var More = require('pull-more') |
8 | var stream = require('hyperloadmore/stream') |
9 | var h = require('hyperscript') |
10 | var render = require('./render') |
11 | var ref = require('ssb-ref') |
12 | var client = require('ssb-client') |
13 | |
14 | var Next = require('pull-next-query') |
15 | |
16 | var config = require('./config')() |
17 | |
18 | var tools = require('./tools') |
19 | var avatar = require('./avatar') |
20 | var id = require('./keys').id |
21 | |
22 | var ssbKeys = require('ssb-keys') |
23 | var keys = require('./keys') |
24 | |
25 | var checkInvite = require('./invite') |
26 | |
27 | var compose = require('./compose') |
28 | |
29 | var 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 | |
39 | var labelStream = function (label){ |
40 | var content = h('div.content') |
41 | var screen = document.getElementById('screen') |
42 | screen.appendChild(hyperscroll(content)) |
43 | content.appendChild(h('div.breadcrumbs.message', h('a', {href: '/'}, 'label'), ' ⯈ ' , h('a', {href: '/#label/' + label}, label))) |
44 | function createStream (opts) { |
45 | return pull( |
46 | Next(sbot.query, opts, ['value', 'timestamp']), |
47 | pull.map(function (msg){ |
48 | if (msg.value) { |
49 | sbot.get(msg.value.content.link, function (err, data) { |
50 | if (data) { |
51 | var message = {} |
52 | message.value = data |
53 | message.key = msg.value.content.link |
54 | content.appendChild(render(message)) |
55 | } |
56 | }) |
57 | } |
58 | }) |
59 | ) |
60 | } |
61 | |
62 | pull( |
63 | createStream({ |
64 | limit: 10, |
65 | reverse: true, |
66 | live: false, |
67 | query: [{$filter: { value: { content: {type: 'label', label: label }, timestamp: { $gt: 0 }}}}] |
68 | }), |
69 | stream.bottom(content) |
70 | ) |
71 | |
72 | pull( |
73 | createStream({ |
74 | limit: 10, |
75 | old: false, |
76 | live: true, |
77 | query: [{$filter: { value: { content: {type: 'label', label: label }, timestamp: { $gt: 0 }}}}] |
78 | }), |
79 | stream.top(content) |
80 | ) |
81 | } |
82 | |
83 | |
84 | var privateStream = function () { |
85 | var screen = document.getElementById('screen') |
86 | var content = h('div.content') |
87 | |
88 | screen.appendChild(hyperscroll(content)) |
89 | |
90 | function createStream (opts) { |
91 | return pull( |
92 | Next(sbot.query, opts, ['value', 'timestamp']), |
93 | pull.filter(function (msg) { |
94 | return ((msg.value.private == true) || ('string' == typeof msg.value.content)) |
95 | }), |
96 | pull.map(function (msg) { |
97 | /*if (msg.value.private != true) { |
98 | var unboxed = ssbKeys.unbox(msg.value.content, keys) |
99 | if (unboxed) { |
100 | msg.value.content = unboxed |
101 | msg.value.private = true |
102 | return render(msg) |
103 | } else { |
104 | return render(msg) |
105 | } |
106 | } else {return render(msg)}*/ |
107 | return render(msg) |
108 | }) |
109 | ) |
110 | } |
111 | |
112 | pull( |
113 | createStream({ |
114 | limit: 100, |
115 | reverse: true, |
116 | live: false, |
117 | query: [{$filter: { value: { timestamp: { $gt: 0 }}}}] |
118 | }), |
119 | stream.bottom(content) |
120 | ) |
121 | |
122 | pull( |
123 | createStream({ |
124 | limit: 100, |
125 | old: false, |
126 | live: true, |
127 | query: [{$filter: { value: { timestamp: { $gt: 0 }}}}] |
128 | }), |
129 | stream.top(content) |
130 | ) |
131 | |
132 | |
133 | /*function createStream (opts) { |
134 | return pull( |
135 | Next(sbot.query, opts, ['value', 'timestamp']), |
136 | pull.map(function (msg) { |
137 | if (msg.value) { |
138 | if (msg.value.timestamp > Date.now()) { |
139 | return h('div.future') |
140 | } else { |
141 | return render(msg) |
142 | } |
143 | } |
144 | }) |
145 | ) |
146 | } |
147 | |
148 | pull( |
149 | createStream({ |
150 | limit: 10, |
151 | reverse: true, |
152 | live: false, |
153 | query: [{$filter: { value: { private: true, timestamp: { $gt: 0 }}}}] |
154 | }), |
155 | stream.bottom(content) |
156 | ) |
157 | |
158 | pull( |
159 | createStream({ |
160 | limit: 10, |
161 | old: false, |
162 | live: true, |
163 | query: [{$filter: { value: { private: true, timestamp: { $gt: 0 }}}}] |
164 | }), |
165 | stream.top(content) |
166 | )*/ |
167 | |
168 | |
169 | /*function createStream (opts) { |
170 | return pull( |
171 | More(sbot.createLogStream, opts), |
172 | pull.filter(function (msg) { |
173 | return 'string' == typeof msg.value.content |
174 | }), |
175 | pull.filter(function (msg) { |
176 | var unboxed = ssbKeys.unbox(msg.value.content, keys) |
177 | if (unboxed) { |
178 | msg.value.content = unboxed |
179 | msg.value.private = true |
180 | return msg |
181 | } else { |
182 | return msg |
183 | } |
184 | }), |
185 | pull.map(function (msg) { |
186 | return render(msg) |
187 | }) |
188 | ) |
189 | } |
190 | |
191 | pull( |
192 | createStream({old: false, limit: 1000}), |
193 | stream.top(content) |
194 | ) |
195 | |
196 | pull( |
197 | createStream({reverse: true, live: false, limit: 1000}), |
198 | stream.bottom(content) |
199 | )*/ |
200 | } |
201 | |
202 | var queueStream = function () { |
203 | var content = h('div.content') |
204 | var screen = document.getElementById('screen') |
205 | screen.appendChild(hyperscroll(content)) |
206 | |
207 | pull( |
208 | sbot.query({query: [{$filter: { value: {author: id, content: {type: 'queue'}}}}]}), |
209 | pull.drain(function (msg) { |
210 | if (msg.value) { |
211 | if (ref.isMsg(msg.value.content.message)) { |
212 | if (msg.value.content.queue == true) { |
213 | sbot.get(msg.value.content.message, function (err, data) { |
214 | if (data) { |
215 | var message = {} |
216 | message.value = data |
217 | message.key = msg.value.content.message |
218 | content.appendChild(render(message)) |
219 | } |
220 | }) |
221 | } |
222 | if (msg.value.content.queue == false) { |
223 | setTimeout(function () { |
224 | var gotIt = document.getElementById(msg.value.content.message.substring(0,44)) |
225 | if (gotIt != null) { |
226 | gotIt.outerHTML = '' |
227 | } |
228 | }, 100) |
229 | } |
230 | } |
231 | } |
232 | }) |
233 | ) |
234 | } |
235 | |
236 | var mentionsStream = function (src) { |
237 | var content = h('div.content') |
238 | |
239 | var screen = document.getElementById('screen') |
240 | |
241 | screen.appendChild(hyperscroll(content)) |
242 | |
243 | function createStream (opts) { |
244 | return pull( |
245 | Next(sbot.backlinks, opts, ['value', 'timestamp']), |
246 | pull.map(function (msg) { |
247 | if (msg.value.private == true) return h('div.private') |
248 | return render(msg) |
249 | }) |
250 | ) |
251 | } |
252 | |
253 | pull( |
254 | createStream({ |
255 | limit: 10, |
256 | reverse: true, |
257 | index: 'DTA', |
258 | live: false, |
259 | query: [{$filter: {dest: src}}] |
260 | }), |
261 | stream.bottom(content) |
262 | ) |
263 | |
264 | pull( |
265 | createStream({ |
266 | limit: 10, |
267 | old: false, |
268 | index: 'DTA', |
269 | live: true, |
270 | query: [{$filter: {dest: src}}] |
271 | }), |
272 | stream.top(content) |
273 | ) |
274 | } |
275 | |
276 | var userStream = function (src) { |
277 | var content = h('div.content') |
278 | var screen = document.getElementById('screen') |
279 | |
280 | screen.appendChild(hyperscroll(content)) |
281 | |
282 | function createStream (opts) { |
283 | return pull( |
284 | More(sbot.userStream, opts, ['value', 'sequence']), |
285 | pull.map(function (msg) { |
286 | return render(h('div', msg)) |
287 | }) |
288 | ) |
289 | } |
290 | |
291 | pull( |
292 | createStream({old: false, limit: 10, id: src}), |
293 | stream.top(content) |
294 | ) |
295 | |
296 | pull( |
297 | createStream({reverse: true, live: false, limit: 10, id: src}), |
298 | stream.bottom(content) |
299 | ) |
300 | |
301 | var profile = h('div.content#profile', h('div.message')) |
302 | |
303 | if (screen.firstChild.firstChild) { |
304 | screen.firstChild.insertBefore(profile, screen.firstChild.firstChild) |
305 | } else { |
306 | screen.firstChild.appendChild(profile) |
307 | } |
308 | |
309 | var name = avatar.name(src) |
310 | |
311 | var editname = h('span', |
312 | avatar.name(src), |
313 | h('button.btn', 'New name', { |
314 | onclick: function () { |
315 | var nameput = h('input', {placeholder: name.textContent}) |
316 | var nameedit = |
317 | h('span', nameput, |
318 | h('button.btn', 'Preview', { |
319 | onclick: function () { |
320 | if (nameput.value[0] != '@') |
321 | tobename = nameput.value |
322 | else |
323 | tobename = nameput.value.substring(1, 100) |
324 | var newname = h('span', h('a', {href: '#' + src}, '@' + tobename), h('button.btn', 'Publish', { |
325 | onclick: function () { |
326 | var donename = h('span', h('a', {href: '#' + src}, '@' + tobename)) |
327 | sbot.publish({type: 'about', about: src, name: tobename}) |
328 | localStorage[src + 'name'] = tobename |
329 | newname.parentNode.replaceChild(donename, newname) |
330 | } |
331 | })) |
332 | nameedit.parentNode.replaceChild(newname, nameedit) |
333 | } |
334 | }) |
335 | ) |
336 | editname.parentNode.replaceChild(nameedit, editname) |
337 | } |
338 | }) |
339 | ) |
340 | |
341 | var editimage = h('span', |
342 | h('button.btn', 'New image', { |
343 | onclick: function () { |
344 | var upload = |
345 | h('span', |
346 | hyperfile.asDataURL(function (data) { |
347 | if(data) { |
348 | //img.src = data |
349 | var _data = dataurl.parse(data) |
350 | pull( |
351 | pull.once(_data.data), |
352 | sbot.addblob(function (err, hash) { |
353 | if(err) return alert(err.stack) |
354 | selected = { |
355 | link: hash, |
356 | size: _data.data.length, |
357 | type: _data.mimetype |
358 | } |
359 | }) |
360 | ) |
361 | } |
362 | }), |
363 | h('button.btn', 'Preview image', { |
364 | onclick: function() { |
365 | if (selected) { |
366 | console.log(selected) |
367 | var oldImage = document.getElementById('profileImage') |
368 | var newImage = h('span.avatar--medium', h('img', {src: config.blobsUrl + selected.link})) |
369 | var publish = h('button.btn', 'Publish image', { |
370 | onclick: function () { |
371 | sbot.publish({ |
372 | type: 'about', |
373 | about: src, |
374 | image: selected |
375 | }, function (err, published) { |
376 | console.log(published) |
377 | }) |
378 | } |
379 | }) |
380 | upload.parentNode.replaceChild(publish, upload) |
381 | oldImage.parentNode.replaceChild(newImage, oldImage) |
382 | } |
383 | /*if(selected) { |
384 | api.message_confirm({ |
385 | type: 'about', |
386 | about: id, |
387 | image: selected |
388 | }) |
389 | } else { alert('select an image before hitting preview')}*/ |
390 | } |
391 | }) |
392 | ) |
393 | editimage.parentNode.replaceChild(upload, editimage) |
394 | } |
395 | }) |
396 | ) |
397 | |
398 | var avatars = h('div.avatars', |
399 | h('a', {href: '#' + src}, |
400 | h('span.avatar--medium#profileImage', avatar.image(src)), |
401 | editname, |
402 | h('br'), |
403 | editimage |
404 | ) |
405 | ) |
406 | |
407 | pull( |
408 | sbot.userStream({id: src, reverse: false, limit: 1}), |
409 | pull.drain(function (msg) { |
410 | var howlong = h('span', h('br'), ' arrived ', human(new Date(msg.value.timestamp))) |
411 | avatars.appendChild(howlong) |
412 | console.log(msg) |
413 | }) |
414 | ) |
415 | |
416 | |
417 | var buttons = h('div.buttons') |
418 | |
419 | profile.firstChild.appendChild(avatars) |
420 | profile.firstChild.appendChild(buttons) |
421 | buttons.appendChild(tools.mute(src)) |
422 | |
423 | var writeMessage = h('button.btn', 'Public message ', avatar.name(src), { |
424 | onclick: function () { |
425 | opts = {} |
426 | opts.type = 'post' |
427 | opts.mentions = '[' + name.textContent + '](' + src + ')' |
428 | var composer = h('div#composer', h('div.message', compose(opts))) |
429 | profile.appendChild(composer) |
430 | } |
431 | }) |
432 | |
433 | var writePrivate = h('button.btn', 'Private message ', avatar.name(src), { |
434 | onclick: function () { |
435 | opts = {} |
436 | opts.type = 'post' |
437 | opts.mentions = '[' + name.textContent + '](' + src + ')' |
438 | opts.recps = [src, id] |
439 | var composer = h('div#composer', h('div.message', compose(opts))) |
440 | profile.appendChild(composer) |
441 | } |
442 | }) |
443 | |
444 | buttons.appendChild(writeMessage) |
445 | buttons.appendChild(writePrivate) |
446 | buttons.appendChild(tools.follow(src)) |
447 | buttons.appendChild(tools.block(src)) |
448 | |
449 | buttons.appendChild(h('button.btn', 'Generate follows', { |
450 | onclick: function () { |
451 | profile.firstChild.appendChild(tools.getFollowing(src)) |
452 | profile.firstChild.appendChild(tools.getFollowers(src)) |
453 | } |
454 | })) |
455 | |
456 | buttons.appendChild(h('button.btn', 'Generate blocks', { |
457 | onclick: function () { |
458 | profile.firstChild.appendChild(tools.getBlocks(src)) |
459 | profile.firstChild.appendChild(tools.getBlocked(src)) |
460 | } |
461 | })) |
462 | buttons.appendChild(h('a', {href: '#wall/' + src}, h('button.btn', avatar.name(src), "'s wall"))) |
463 | |
464 | } |
465 | |
466 | var privateMsg = function (src) { |
467 | var content = h('div.content') |
468 | var screen = document.getElementById('screen') |
469 | screen.appendChild(hyperscroll(content)) |
470 | |
471 | sbot.get(src, function (err, data) { |
472 | if (err) { |
473 | var message = h('div.message', 'Missing message!') |
474 | content.appendChild(message) |
475 | } |
476 | if (data) { |
477 | console.log(data) |
478 | data.value = data |
479 | data.key = src |
480 | |
481 | content.appendChild(render(data)) |
482 | } |
483 | |
484 | }) |
485 | } |
486 | |
487 | var msgThread = function (src) { |
488 | |
489 | var content = h('div.content') |
490 | var screen = document.getElementById('screen') |
491 | screen.appendChild(hyperscroll(content)) |
492 | |
493 | pull( |
494 | sbot.query({query: [{$filter: { value: { content: {root: src}, timestamp: { $gt: 1 }}}}], live: true}), |
495 | pull.drain(function (msg) { |
496 | if (msg.value) { |
497 | content.appendChild(render(msg)) |
498 | } |
499 | }) |
500 | ) |
501 | |
502 | sbot.get(src, function (err, data) { |
503 | if (err) { |
504 | var message = h('div.message', 'Missing message!') |
505 | content.appendChild(message) |
506 | } |
507 | if (data) { |
508 | var message = {} |
509 | message.value = data |
510 | message.key = src |
511 | console.log(message) |
512 | var rootMsg = render(message) |
513 | |
514 | if (content.firstChild) { |
515 | content.insertBefore(rootMsg, content.firstChild) |
516 | } else { |
517 | content.appendChild(rootMsg) |
518 | } |
519 | if (message.value.content.type == 'git-repo') { |
520 | pull( |
521 | sbot.backlinks({query: [{$filter: {value: {content: {type: 'git-update'}}, dest: src}}]}), |
522 | pull.drain(function (msg) { |
523 | if (msg.value) { |
524 | content.appendChild(render(msg)) |
525 | } |
526 | }) |
527 | ) |
528 | } |
529 | |
530 | } |
531 | }) |
532 | |
533 | } |
534 | |
535 | var keyPage = function () { |
536 | var screen = document.getElementById('screen') |
537 | |
538 | var importKey = h('textarea.import', {placeholder: 'Import a new public/private key', name: 'textarea', style: 'width: 97%; height: 100px;'}) |
539 | |
540 | var content = h('div.content', |
541 | h('div.message#key', |
542 | h('h1', 'Your Key'), |
543 | h('p', {innerHTML: 'Your public/private key is: <pre><code>' + localStorage[config.caps.shs + '/secret'] + '</code></pre>'}, |
544 | h('button.btn', {onclick: function (e){ |
545 | localStorage[config.caps.shs +'/secret'] = '' |
546 | alert('Your public/private key has been deleted') |
547 | e.preventDefault() |
548 | location.hash = "" |
549 | location.reload() |
550 | }}, 'Delete Key') |
551 | ), |
552 | h('hr'), |
553 | h('form', |
554 | importKey, |
555 | h('button.btn', {onclick: function (e){ |
556 | if(importKey.value) { |
557 | localStorage[config.caps.shs + '/secret'] = importKey.value.replace(/\s+/g, ' ') |
558 | e.preventDefault() |
559 | alert('Your public/private key has been updated') |
560 | } |
561 | location.hash = "" |
562 | location.reload() |
563 | }}, 'Import key'), |
564 | ) |
565 | ) |
566 | ) |
567 | |
568 | screen.appendChild(hyperscroll(content)) |
569 | } |
570 | |
571 | |
572 | function friendsStream (src) { |
573 | |
574 | var screen = document.getElementById('screen') |
575 | var content = h('div.content') |
576 | |
577 | screen.appendChild(hyperscroll(content)) |
578 | |
579 | function createStream (opts) { |
580 | return pull( |
581 | Next(sbot.query, opts, ['value', 'timestamp']), |
582 | pull.map(function (msg) { |
583 | sbot.friends.get({source: src, dest: msg.value.author}, function (err, data) { |
584 | if (data === true) { |
585 | return content.appendChild(render(msg)) |
586 | console.log(msg) |
587 | } else { |
588 | return content.appendChild(h('div')) |
589 | } |
590 | }) |
591 | }) |
592 | ) |
593 | } |
594 | |
595 | pull( |
596 | createStream({ |
597 | limit: 1000, |
598 | reverse: true, |
599 | live: false, |
600 | query: [{$filter: { value: { timestamp: { $gt: 0 }}}}] |
601 | }), |
602 | stream.bottom(content) |
603 | ) |
604 | |
605 | } |
606 | |
607 | function everythingStream () { |
608 | |
609 | var screen = document.getElementById('screen') |
610 | var content = h('div.content') |
611 | |
612 | screen.appendChild(hyperscroll(content)) |
613 | |
614 | function createStream (opts) { |
615 | return pull( |
616 | Next(sbot.query, opts, ['value', 'timestamp']), |
617 | pull.map(function (msg) { |
618 | if (msg.value) { |
619 | if (msg.value.timestamp > Date.now()) { |
620 | return h('div.future') |
621 | } else { |
622 | return render(msg) |
623 | } |
624 | } |
625 | }) |
626 | ) |
627 | } |
628 | |
629 | pull( |
630 | createStream({ |
631 | limit: 10, |
632 | reverse: true, |
633 | live: false, |
634 | query: [{$filter: { value: { timestamp: { $gt: 0 }}}}] |
635 | }), |
636 | stream.bottom(content) |
637 | ) |
638 | |
639 | pull( |
640 | createStream({ |
641 | limit: 10, |
642 | old: false, |
643 | live: true, |
644 | query: [{$filter: { value: { timestamp: { $gt: 0 }}}}] |
645 | }), |
646 | stream.top(content) |
647 | ) |
648 | } |
649 | |
650 | |
651 | |
652 | |
653 | function backchannel () { |
654 | |
655 | var screen = document.getElementById('screen') |
656 | var content = h('div.content') |
657 | |
658 | screen.appendChild(hyperscroll(content)) |
659 | |
660 | var chatbox = h('input', {placeholder: 'Backchannel'}) |
661 | |
662 | var chat = h('div.content') |
663 | |
664 | var publish = h('button.btn', 'Publish', { |
665 | onclick: function () { |
666 | if (chatbox.value) { |
667 | var content = { |
668 | text: chatbox.value, |
669 | type: 'scat_message' |
670 | } |
671 | sbot.publish(content, function (err, msg) { |
672 | if (err) throw err |
673 | chatbox.value = '' |
674 | console.log('Published!', msg) |
675 | }) |
676 | } |
677 | } |
678 | }) |
679 | |
680 | chat.appendChild(h('div.message', chatbox, publish)) |
681 | |
682 | if (screen.firstChild.firstChild) { |
683 | screen.firstChild.insertBefore(chat, screen.firstChild.firstChild) |
684 | } else { |
685 | screen.firstChild.appendChild(chat) |
686 | } |
687 | |
688 | function createStream (opts) { |
689 | return pull( |
690 | Next(sbot.query, opts, ['value', 'timestamp']), |
691 | pull.map(function (msg) { |
692 | if (msg.value) { |
693 | return render(msg) |
694 | } |
695 | }) |
696 | ) |
697 | } |
698 | |
699 | pull( |
700 | createStream({ |
701 | limit: 10, |
702 | reverse: true, |
703 | live: false, |
704 | query: [{$filter: { value: { content: {type: 'scat_message'}, timestamp: { $gt: 0 }}}}] |
705 | }), |
706 | stream.bottom(content) |
707 | ) |
708 | |
709 | pull( |
710 | createStream({ |
711 | limit: 10, |
712 | old: false, |
713 | live: true, |
714 | query: [{$filter: { value: { content: {type: 'scat_message'}, timestamp: { $gt: 0 }}}}] |
715 | }), |
716 | stream.top(content) |
717 | ) |
718 | } |
719 | |
720 | function search (src) { |
721 | console.log('search' + src) |
722 | |
723 | var content = h('div.content') |
724 | var screen = document.getElementById('screen') |
725 | screen.appendChild(hyperscroll(content)) |
726 | |
727 | pull( |
728 | sbot.search.query({query: src, limit: 100}), |
729 | pull.drain(function (search) { |
730 | content.appendChild(render(search)) |
731 | }) |
732 | ) |
733 | |
734 | } |
735 | |
736 | function hash () { |
737 | return window.location.hash.substring(1) |
738 | } |
739 | |
740 | module.exports = function () { |
741 | var src = hash() |
742 | |
743 | if (src.substring(52, 59) == '?unbox=') { |
744 | privateMsg(src) |
745 | } else if (ref.isFeed(src)) { |
746 | userStream(src) |
747 | } else if (ref.isMsg(src)) { |
748 | msgThread(src) |
749 | } else if (ref.isFeed(src.substring(5))) { |
750 | mentionsStream(src.substring(5)) |
751 | } else if (ref.isFeed(src.substring(8))) { |
752 | friendsStream(src.substring(8)) |
753 | } else if (src.substring(0, 6) === 'label/') { |
754 | labelStream(src.substring(6)) |
755 | } else if (src == 'queue') { |
756 | queueStream() |
757 | } else if (src == 'about') { |
758 | about() |
759 | } else if (src == 'backchannel') { |
760 | backchannel() |
761 | } else if (src == 'private') { |
762 | privateStream() |
763 | } else if (src == 'key') { |
764 | keyPage() |
765 | } else if (src[0] == '?' || (src[0] == '#')) { |
766 | if (src[0] == '#') |
767 | search(src.split('%20').join(' ')) |
768 | else |
769 | search(src.substr(1).split('%20').join(' ')) |
770 | } else { |
771 | everythingStream() |
772 | //checkInvite() |
773 | } |
774 | |
775 | } |
776 |
Built with git-ssb-web