git ssb

16+

Dominic / patchbay



Commit 2227f2f14f1094019ceb5e1cb1a8254841c2fe9e

Merge branch 'master' of ssb://%s9mSFATE4RGyJx9wgH22lBrvD4CgUQW4yeguSWWjtqc=.sha256 into evmaster

Ev Bogue committed on 11/3/2016, 9:08:55 PM
Parent: 5c65269d9872f15ab192ba3b916511db8505843b
Parent: c9a62bb9b4eb9236d7aae1a6487ad19d7affc72d

Files changed

modules/invite.jschanged
modules/network.jschanged
modules/notifications.jschanged
modules/private.jschanged
modules/public.jschanged
modules/search-box.jschanged
modules/setup.jsadded
package.jsonchanged
plugs.jschanged
sbot-api.jschanged
style.csschanged
util.jschanged
modules/invite.jsView
@@ -7,36 +7,64 @@
77 var Progress = require('hyperprogress')
88
99 var plugs = require('../plugs')
1010 var sbot_publish = plugs.first(exports.sbot_publish = [])
11 +var sbot_gossip_connect = plugs.first(exports.sbot_gossip_connect = [])
12 +var follower_of = plugs.first(exports.follower_of = [])
1113
14 +exports.invite_parse = function (invite) {
15 + return ref.parseInvite(invite)
16 +}
1217
13-//check that invite is
14-// ws:...~shs:key:seed
15-function parseMultiServerInvite (invite) {
16- var redirect = invite.split('#')
17- if(!redirect.length) return null
18 +exports.invite_accept = function (invite, onProgress, cb) {
19 + var data = exports.invite_parse(invite)
20 + if(!data) return cb(new Error('not a valid invite code:' + invite))
1821
19- var parts = redirect[0].split('~')
20- .map(function (e) { return e.split(':') })
22 + onProgress('connecting...')
23 +
24 + sbot_gossip_connect(data.remote, function (err) {
25 + if(err) console.log(err)
26 + })
2127
22- if(parts.length !== 2) return null
23- if(!/^(net|wss?)$/.test(parts[0][0])) return null
24- if(parts[1][0] !== 'shs') return null
25- if(parts[1].length !== 3) return null
26- var p2 = invite.split(':')
27- p2.pop()
28 + ssbClient(null, {
29 + remote: data.invite,
30 + manifest: { invite: {use: 'async'}, getAddress: 'async' }
31 + }, function (err, sbot) {
32 + if(err) return cb(err)
33 + onProgress('requesting follow...')
34 + console.log(sbot)
35 + sbot.invite.use({feed: id}, function (err, msg) {
2836
29- return {
30- invite: redirect[0],
31- remote: p2.join(':'),
32- redirect: '#' + redirect.slice(1).join('#')
33- }
37 + //if they already follow us, just check we actually follow them.
38 + if(err) follower_of(id, data.key, function (_err, follows) {
39 + if(follows) cb(err)
40 + else next()
41 + })
42 + else next()
43 +
44 + function next () {
45 + onProgress('following...')
46 +
47 + //remove the seed from the shs address.
48 + //then it's correct address.
49 + //this should make the browser connect to this as remote.
50 + //we don't want to do this if when using this locally, though.
51 + if(process.title === 'browser')
52 + localStorage.remote = data.remote
53 +
54 + sbot_publish({
55 + type: 'contact',
56 + contact: data.key,
57 + following: true,
58 + }, cb)
59 + }
60 + })
61 + })
3462 }
3563
3664 exports.screen_view = function (invite) {
3765
38- var data = parseMultiServerInvite(invite)
66 + var data = ref.parseInvite(invite)
3967 if(!data) return
4068
4169 var progress = Progress(4)
4270
@@ -52,47 +80,23 @@
5280 h('button', 'accept', {onclick: attempt}),
5381 progress
5482 )
5583
56- function attempt () {
57- progress.reset().next('connecting...')
58-
59- ssbClient(null, {
60- remote: data.invite,
61- manifest: { invite: {use: 'async'}, getAddress: 'async' }
62- }, function (err, sbot) {
84 + function attempt () {
85 + exports.invite_accept(invite, function (message) {
86 + progress.next(message)
87 + }, function (err) {
6388 if(err) return progress.fail(err)
64- progress.next('requesting follow...')
89 + progress.complete()
90 + //check for redirect
91 + var parts = location.hash.substring(1).split('#')
6592
66- sbot.invite.use({feed: id}, function (err, msg) {
67- if(err) return progress.fail(err)
68- progress.next('following...')
69-
70- //remove the seed from the shs address.
71- //then it's correct address.
72- //this should make the browser connect to this as remote.
73- //we don't want to do this if when using this locally, though.
74- if(process.title === 'browser')
75- localStorage.remote = data.remote
76-
77- sbot_publish({
78- type: 'contact',
79- contact: sbot.id,
80- following: true,
81- }, function (err) {
82- if(err) return progress.fail(err)
83- progress.complete()
84- //check for redirect
85- var parts = location.hash.substring(1).split('#')
86-
87- //TODO: handle in a consistent way with either hashrouting
88- //or with tabs...
89- if(parts[0] === data.invite)
90- location.hash = data.redirect
91- else
92- console.log("NO REDIRECT")
93- })
94- })
93 + //TODO: handle in a consistent way with either hashrouting
94 + //or with tabs...
95 + if(parts[0] === data.invite)
96 + location.hash = data.redirect
97 + else
98 + console.log("NO REDIRECT")
9599 })
96100 }
97101
98102 // If we are in the browser,
@@ -102,4 +106,7 @@
102106 return div
103107 }
104108
105109
110 +
111 +
112 +
modules/network.jsView
@@ -31,20 +31,20 @@
3131
3232 //pub is running scuttlebot >=8
3333 //have connected successfully.
3434 function isLongterm (e) {
35- return e.ping && e.ping.rtt.mean > 0
35 + return e.ping && e.ping.rtt && e.ping.rtt.mean > 0
3636 }
3737
3838 //pub is running scuttlebot < 8
3939 //have connected sucessfully
4040 function isLegacy (peer) {
41- return /connect/.test(peer.state) || peer.duration.mean > 0 && !exports.isLongterm(peer)
41 + return /connect/.test(peer.state) || (peer.duration && peer.duration.mean) > 0 && !isLongterm(peer)
4242 }
4343
4444 //tried to connect, but failed.
4545 function isInactive (e) {
46- return e.stateChange && e.duration.mean == 0
46 + return e.stateChange && e.duration && e.duration.mean == 0
4747 }
4848
4949 //havn't tried to connect peer yet.
5050 function isUnattempted (e) {
@@ -117,11 +117,11 @@
117117 ' ',
118118 getType(peer),
119119 ' ',
120120 //TODO: show nicer details, with labels. etc.
121- peer.ping ? duration(peer.ping.rtt.mean) : '',
121 + peer.ping && peer.ping.rtt ? duration(peer.ping.rtt.mean) : '',
122122 ' ',
123- peer.ping ? duration(peer.ping.skew.mean) : '',
123 + peer.ping && peer.ping.skew ? duration(peer.ping.skew.mean) : '',
124124 h('label',
125125 {title: new Date(peer.stateChange).toString()},
126126 peer.stateChange && ('(' + human(new Date(peer.stateChange))) + ')')
127127 ),
@@ -142,24 +142,5 @@
142142
143143 })()
144144
145145 return h('div.column.scroll-y', ol)
146-
147146 }
148-
149-
150-
151-
152-
153-
154-
155-
156-
157-
158-
159-
160-
161-
162-
163-
164-
165-
modules/notifications.jsView
@@ -121,9 +121,9 @@
121121 )
122122 )
123123
124124 pull(
125- sbot_log({old: false}),
125 + u.next(sbot_log, {old: false, limit: 100}),
126126 unbox(),
127127 notifications(ids),
128128 pull.filter(),
129129 Scroller(div, content, message_render, true, false)
@@ -147,4 +147,5 @@
147147
148148
149149
150150
151 +
modules/private.jsView
@@ -54,9 +54,9 @@
5454 h('div.scroller__wrapper', compose, content)
5555 )
5656
5757 pull(
58- sbot_log({old: false}),
58 + u.next(sbot_log, {old: false, limit: 100}),
5959 unbox(),
6060 Scroller(div, content, message_render, true, false)
6161 )
6262
@@ -83,5 +83,4 @@
8383 }))
8484 }
8585
8686
87-
modules/public.jsView
@@ -21,9 +21,9 @@
2121 )
2222 )
2323
2424 pull(
25- sbot_log({old: false}),
25 + u.next(sbot_log, {old: false, limit: 100}),
2626 Scroller(div, content, message_render, true, false)
2727 )
2828
2929 pull(
modules/search-box.jsView
@@ -10,9 +10,9 @@
1010 var signified = require('../plugs').first(exports.signified = [])
1111
1212 var builtinTabs = [
1313 '/public', '/private', '/notifications',
14- '/network', '/query', '/theme', '/versions'
14 + '/network', '/query', '/versions'
1515 ].map(function (name) {
1616 return {
1717 title: name,
1818 value: name,
modules/setup.jsView
@@ -1,0 +1,145 @@
1 +
2 +var h = require('hyperscript')
3 +var pull = require('pull-stream')
4 +
5 +var plugs = require('../plugs')
6 +
7 +var avatar_edit = plugs.first(exports.avatar_edit = [])
8 +var invite_parse = plugs.first(exports.invite_parse = [])
9 +var invite_accept = plugs.first(exports.invite_accept = [])
10 +var sbot_progress = plugs.first(exports.sbot_progress = [])
11 +var sbot_query = plugs.first(exports.sbot_query = [])
12 +var avatar = plugs.first(exports.avatar = [])
13 +
14 +//maybe this could show the pubs, or
15 +//if someone locally follows you,
16 +//it could show the second degree pubs?
17 +
18 +//maybe show the network as animated graph?
19 +
20 +function followers_query (id) {
21 + return [{$filter: {
22 + value: {content: {
23 + type: "contact",
24 + contact: id,
25 + following: true,
26 +// autofollow: true
27 + }}
28 + }}]
29 +}
30 +
31 +//test whether we are connected to the ssb network.
32 +exports.setup_is_fresh_install = function (cb) {
33 + //test by checking whether you have any friends following you?
34 + pull(
35 + sbot_query({query: followers_query(id), limit: 1, live: false}),
36 + pull.collect(function (err, ary) {
37 + cb(err, !!ary.length)
38 + })
39 + )
40 +}
41 +
42 +function invite_form () {
43 + var accept = h('button', 'enter code', {disabled: true, onclick: function () {
44 + invite_accept(input.value, function (msg) {
45 + status.textContent = msg
46 + }, function (err) {
47 + if(err) {
48 + accept.textContent = 'error:'+(err.message || err.stack || error.type)
49 + console.error(err)
50 + }
51 + else {
52 + input.value = ''
53 + accept.textContent = 'success!'
54 + }
55 + })
56 + }})
57 +
58 + function parseInput () {
59 + if(!input.value) {
60 + accept.disabled = true
61 + accept.textContent = 'enter code'
62 + }
63 + else if(!invite_parse(input.value)) {
64 + accept.disabled = true
65 + accept.textContent = 'invalid code'
66 + }
67 + else {
68 + accept.disabled = false
69 + accept.textContent = 'accept'
70 + }
71 + }
72 +
73 + var input = h('input.wide', {placeholder: 'invite code', oninput: parseInput, onchange: parseInput})
74 +
75 + return h('div.invite-form.row', input, accept)
76 +}
77 +
78 +exports.progress_bar = function () {
79 + var liquid = h('div.hyperprogress__liquid', '.')
80 + var bar = h('div.hyperprogress__bar', liquid)
81 + liquid.style.width = '0%'
82 +
83 + pull(
84 + sbot_progress(),
85 + pull.drain(function (e) {
86 + liquid.style.width = Math.round((e.progress/e.total)*100)+'%'
87 + })
88 + )
89 +
90 + return bar
91 +}
92 +
93 +//show the first 5 followers, and how they join you to the network.
94 +//so this will show if a local peer follows you.
95 +
96 +//when you join the network, I want this to show as people follow you.
97 +//that could be when a pub accepts the invite, or when a local peer accepts.
98 +
99 +exports.setup_joined_network = function (id) {
100 + var followers = h('div.column')
101 + var label = h('label', 'not connected to a network')
102 + var joined = h('div.setup__joined', label,followers)
103 +
104 + pull(
105 + sbot_query({query: followers_query(id), limit: 5, live: true, sync: false}),
106 + pull.drain(function (follower) {
107 + if(follower.sync) return
108 + label.textContent = 'connected to network via...'
109 + followers.appendChild(
110 + avatar(follower.value.author, 'thumbnail')
111 + )
112 + })
113 + )
114 +
115 + return joined
116 +}
117 +
118 +exports.screen_view = function (path) {
119 +
120 + if(path !== '/setup') return
121 +
122 + var id = require('../keys').id
123 +
124 + //set up an avatar
125 +
126 +
127 + var status = h('span')
128 + var invite = h('input', {placeholder: 'invite code'})
129 + return h('div.scroller', h('div.scroller__wrapper',
130 + h('h1', 'welcome to patchbay!'),
131 + h('div',
132 + 'please choose avatar image and name',
133 + avatar_edit(id)
134 + ),
135 + h('h2', 'join network'),
136 + invite_form(),
137 + //show avatars of anyone on the same local network.
138 + //show realtime changes in your followers, especially for local.
139 +
140 + exports.progress_bar(),
141 + exports.setup_joined_network(require('../keys').id)
142 + ))
143 +}
144 +
145 +
package.jsonView
@@ -1,8 +1,8 @@
11 {
22 "name": "patchbay",
33 "description": "a pluggable patchwork",
4- "version": "3.5.1",
4 + "version": "4.0.1",
55 "homepage": "https://github.com/dominictarr/patchbay",
66 "repository": {
77 "type": "git",
88 "url": "git://github.com/dominictarr/patchbay.git"
@@ -41,8 +41,9 @@
4141 "ssb-feed": "^2.2.1",
4242 "ssb-keys": "^6.1.0",
4343 "ssb-markdown": "^3.0.0",
4444 "ssb-mentions": "^0.1.0",
45 + "ssb-ref": "^2.6.2",
4546 "ssb-sort": "^1.0.0",
4647 "suggest-box": "^2.2.1",
4748 "text-node-searcher": "^1.1.0",
4849 "visualize-buffer": "0.0.0"
plugs.jsView
@@ -2,10 +2,9 @@
22
33 exports.first = function first(plug) {
44 return function () {
55 var args = [].slice.call(arguments)
6- args.unshift(plug)
7- return u.firstPlug.apply(null, args)
6 + return u.firstPlug(plug, args)
87 }
98 }
109
1110 exports.map = function (plug) {
@@ -17,4 +16,5 @@
1716 }
1817 }
1918
2019
20 +
sbot-api.jsView
@@ -151,17 +151,14 @@
151151 })
152152 }),
153153 sbot_whoami: rec.async(function (cb) {
154154 sbot.whoami(cb)
155 + }),
156 + sbot_progress: rec.source(function () {
157 + return sbot.replicate.changes()
155158 })
156159 }
157160 }
158161
159162
160163
161164
162-
163-
164-
165-
166-
167-
style.cssView
@@ -79,8 +79,12 @@
7979 white-space: pre-wrap;
8080 word-wrap: break-word;
8181 }
8282
83 +.wide {
84 + width: 100%;
85 +}
86 +
8387 p {
8488 margin-top: .35ex;
8589 }
8690
@@ -382,19 +386,8 @@
382386 .error {
383387 background: red;
384388 }
385389
386-/* themes */
387-
388-.theme {
389- margin-left: 1ex;
390-}
391-
392-.themes__form {
393- margin: 1ex;
394-}
395-
396-
397390 /* tabs */
398391
399392 .header {
400393 background: #f5f5f5;
@@ -468,4 +461,15 @@
468461 bottom: 0;
469462 left: 0;
470463 z-index: 1;
471464 }
465 +
466 +/* progress bar */
467 +
468 +.hyperprogress__bar {
469 + background: darkgrey;
470 +}
471 +.hyperprogress__liquid {
472 + background: lightblue;
473 +}
474 +
475 +
util.jsView
@@ -57,13 +57,12 @@
5757 )
5858 })
5959 }
6060
61-exports.firstPlug = function (plugs) {
61 +exports.firstPlug = function (plugs, args) {
6262 if(!Array.isArray(plugs)) throw new Error('plugs must be an array')
63- var args = [].slice.call(arguments)
64- var plugs = args.shift()
6563 return exports.first(plugs, function (fn) {
6664 return fn.apply(null, args)
6765 })
6866 }
6967
68 +

Built with git-ssb-web