Commit 7d510f40ceb47f6b4863bc121426ce7492a1bbbc
complete working network page, unstyled
mix irving committed on 1/11/2017, 3:14:40 AMParent: e6c835809ff3378173c42cc91fccedf5521f6366
Files changed
modules_extra/network.js | changed |
modules_extra/network.js | |||
---|---|---|---|
@@ -1,6 +1,14 @@ | |||
1 | -var isVisible = require('is-visible').isVisible | ||
2 | -var h = require('../h') | ||
1 … | +const isVisible = require('is-visible').isVisible | ||
2 … | +const h = require('../h') | ||
3 … | +const mutantMap = require('@mmckegg/mutant/map') | ||
4 … | +const mutantDict = require('@mmckegg/mutant/dict') | ||
5 … | +const Struct = require('@mmckegg/mutant/struct') | ||
6 … | +const Value = require('@mmckegg/mutant/value') | ||
7 … | +const toCollection = require('@mmckegg/mutant/dict-to-collection') | ||
8 … | +const when = require('@mmckegg/mutant/when') | ||
9 … | +const computed = require('@mmckegg/mutant/computed') | ||
10 … | +const human = require('human-time') | ||
3 | 11 … | ||
4 | 12 … | //var avatar = plugs.first(exports.avatar = []) | |
5 | 13 … | //var sbot_gossip_peers = plugs.first(exports.sbot_gossip_peers = []) | |
6 | 14 … | //var sbot_gossip_connect = plugs.first(exports.sbot_gossip_connect = []) | |
@@ -19,28 +27,27 @@ | |||
19 | 27 … | ||
20 | 28 … | //sbot_gossip_connect | |
21 | 29 … | //sbot_gossip_add | |
22 | 30 … | ||
23 | -var human = require('human-time') | ||
24 | 31 … | ||
25 | 32 … | function legacyToMultiServer(addr) { | |
26 | 33 … | return 'net:'+addr.host + ':'+addr.port + '~shs:'+addr.key.substring(1).replace('.ed25519','') | |
27 | 34 … | } | |
28 | 35 … | ||
29 | 36 … | ||
30 | 37 … | ||
31 | 38 … | //on the same wifi network | |
32 | -function isLocal (e) { | ||
39 … | +function isLocal (peer) { | ||
33 | 40 … | // don't rely on private ip address, because | |
34 | 41 … | // cjdns creates fake private ip addresses. | |
35 | - return ip.isPrivate(e.host) && e.type === 'local' | ||
42 … | + return ip.isPrivate(peer.host) && peer.type === 'local' | ||
36 | 43 … | } | |
37 | 44 … | ||
38 | 45 … | ||
39 | 46 … | //pub is running scuttlebot >=8 | |
40 | 47 … | //have connected successfully. | |
41 | -function isLongterm (e) { | ||
42 | - return e.ping && e.ping.rtt && e.ping.rtt.mean > 0 | ||
48 … | +function isLongterm (peer) { | ||
49 … | + return peer.ping && peer.ping.rtt && peer.ping.rtt.mean > 0 | ||
43 | 50 … | } | |
44 | 51 … | ||
45 | 52 … | //pub is running scuttlebot < 8 | |
46 | 53 … | //have connected sucessfully | |
@@ -48,29 +55,29 @@ | |||
48 | 55 … | return /connect/.test(peer.state) || (peer.duration && peer.duration.mean) > 0 && !isLongterm(peer) | |
49 | 56 … | } | |
50 | 57 … | ||
51 | 58 … | //tried to connect, but failed. | |
52 | -function isInactive (e) { | ||
53 | - return e.stateChange && (e.duration && e.duration.mean == 0) | ||
59 … | +function isInactive (peer) { | ||
60 … | + return peer.stateChange && (peer.duration && peer.duration.mean == 0) | ||
54 | 61 … | } | |
55 | 62 … | ||
56 | 63 … | //havn't tried to connect peer yet. | |
57 | -function isUnattempted (e) { | ||
58 | - return !e.stateChange | ||
64 … | +function isUnattempted (peer) { | ||
65 … | + return !peer.stateChange | ||
59 | 66 … | } | |
60 | 67 … | ||
61 | -function getType (e) { | ||
68 … | +function getType (peer) { | ||
62 | 69 … | return ( | |
63 | - isLongterm(e) ? 'modern' | ||
64 | - : isLegacy(e) ? 'legacy' | ||
65 | - : isInactive(e) ? 'inactive' | ||
66 | - : isUnattempted(e) ? 'unattempted' | ||
67 | - : 'other' //should never happen | ||
70 … | + isLongterm(peer) ? 'modern' | ||
71 … | + : isLegacy(peer) ? 'legacy' | ||
72 … | + : isInactive(peer) ? 'inactive' | ||
73 … | + : isUnattempted(peer) ? 'unattempted' | ||
74 … | + : 'other' //should never happen | ||
68 | 75 … | ) | |
69 | 76 … | } | |
70 | 77 … | ||
71 | -function origin (e) { | ||
72 | - return e.source === 'local' ? 0 : 1 | ||
78 … | +function origin (peer) { | ||
79 … | + return peer.source === 'local' ? 0 : 1 | ||
73 | 80 … | } | |
74 | 81 … | ||
75 | 82 … | ||
76 | 83 … | function round(n) { | |
@@ -109,9 +116,16 @@ | |||
109 | 116 … | || b.stateChange - a.stateChange | |
110 | 117 … | ) | |
111 | 118 … | } | |
112 | 119 … | ||
120 … | +function formatDate (time) { | ||
121 … | + return new Date(time).toString() | ||
122 … | +} | ||
113 | 123 … | ||
124 … | +function humanDate (time) { | ||
125 … | + return human(new Date(time)) | ||
126 … | +} | ||
127 … | + | ||
114 | 128 … | exports.create = function (api) { | |
115 | 129 … | ||
116 | 130 … | return { | |
117 | 131 … | menu_items: () => h('a', {href: '#/network'}, '/network'), | |
@@ -121,54 +135,99 @@ | |||
121 | 135 … | ||
122 | 136 … | function screen_view (path) { | |
123 | 137 … | if (path !== '/network') return | |
124 | 138 … | ||
125 | - var ol = h('ul', { className: 'network' }) | ||
139 … | + var peers = obs_gossip_peers(api) | ||
126 | 140 … | ||
127 | - ;(function poll () { | ||
141 … | + return h('div', { style: {'overflow':'auto'}, className: 'column scroller' }, [ | ||
142 … | + h('Network', [ | ||
143 … | + mutantMap(peers, peer => { | ||
144 … | + var { key, ping, source, state, stateChange } = peer | ||
128 | 145 … | ||
129 | - //if this tab isn't open, don't update. | ||
130 | - //todo: make a better way to do this... | ||
131 | - if (!isVisible(ol)) return setTimeout(poll, 1000) | ||
146 … | + console.log('ping', ping()) | ||
132 | 147 … | ||
133 | - api.sbot_gossip_peers((err, list) => { | ||
134 | - ol.innerHTML = '' | ||
135 | - list.sort(peerListSort).forEach(peer => { | ||
136 | - ol.appendChild(h('div', [ | ||
137 | - api.avatar(peer.key, 'thumbnail'), | ||
148 … | + return h('NetworkConnection', [ | ||
149 … | + api.avatar(key(), 'thumbnail'), | ||
138 | 150 … | h('div', [ | |
139 | - peer.state || 'not connected', | ||
151 … | + when(state, state, 'not connected'), | ||
140 | 152 … | ' ', | |
141 | - getType(peer), | ||
153 … | + computed(peer, getType), | ||
142 | 154 … | ' ', | |
143 | - //TODO: show nicer details, with labels. etc. | ||
144 | - (peer.ping && peer.ping.rtt) ? duration(peer.ping.rtt.mean) : '', | ||
155 … | + // //TODO: show nicer details, with labels. etc. | ||
156 … | + computed(ping.rtt.mean, duration), | ||
145 | 157 … | ' ', | |
146 | - (peer.ping && peer.ping.skew) ? duration(peer.ping.skew.mean) : '', | ||
147 | - h('label', | ||
148 | - { title: new Date(peer.stateChange).toString() }, | ||
149 | - peer.stateChange && ('(' + human(new Date(peer.stateChange))) + ')' | ||
150 | - ) | ||
158 … | + computed(ping.skew.mean, duration), | ||
159 … | + ' ', | ||
160 … | + h('label', | ||
161 … | + { title: computed(stateChange, formatDate) }, | ||
162 … | + [ computed(stateChange, humanDate) ] | ||
163 … | + ) | ||
151 | 164 … | ]), | |
152 | - 'source:'+peer.source, | ||
153 | - h('pre', legacyToMultiServer(peer)), | ||
165 … | + 'source: ', | ||
166 … | + source, | ||
167 … | + h('pre', computed(peer, legacyToMultiServer)), | ||
154 | 168 … | h('button', { | |
155 | 169 … | 'ev-click': () => { | |
156 | - api.sbot_gossip_connect(peer, (err) => { | ||
170 … | + api.sbot_gossip_connect(peer(), (err) => { | ||
157 | 171 … | if(err) console.error(err) | |
158 | - else console.log('connected to', peer) | ||
172 … | + else console.log('connected to', peer()) | ||
159 | 173 … | }) | |
160 | 174 … | }}, | |
161 | 175 … | 'connect' | |
162 | 176 … | ) | |
163 | - ])) | ||
177 … | + ]) | ||
164 | 178 … | }) | |
179 … | + ]) | ||
180 … | + ]) | ||
181 … | + } | ||
182 … | +} | ||
165 | 183 … | ||
166 | - setTimeout(poll, 5000) | ||
167 | - }) | ||
184 … | +function obs_gossip_peers (api) { | ||
185 … | + var timer = null | ||
186 … | + var state = mutantDict({}, { | ||
187 … | + onListen: () => { | ||
188 … | + timer = setInterval(refresh, 5e3) | ||
189 … | + }, | ||
190 … | + onUnlisten: () => { | ||
191 … | + clearInterval(timer) | ||
192 … | + } | ||
193 … | + }) | ||
168 | 194 … | ||
169 | - })() | ||
195 … | + refresh() | ||
170 | 196 … | ||
171 | - return h('div', { className: 'column scroll-y' }, ol) | ||
197 … | + return toCollection.values(state) | ||
198 … | + | ||
199 … | + function refresh () { | ||
200 … | + api.sbot_gossip_peers((err, peers) => { | ||
201 … | + peers.forEach(data => { | ||
202 … | + var current = state.get(data.key) | ||
203 … | + if (!current) { | ||
204 … | + current = Peer() | ||
205 … | + current.set(data) | ||
206 … | + state.put(data.key, current) | ||
207 … | + } else { | ||
208 … | + current.set(data) | ||
209 … | + } | ||
210 … | + }) | ||
211 … | + }) | ||
172 | 212 … | } | |
173 | 213 … | } | |
174 | 214 … | ||
215 … | +function Peer () { | ||
216 … | + var peer = Struct({ | ||
217 … | + key: Value(), | ||
218 … | + ping: Struct({ | ||
219 … | + rtt: Struct({ | ||
220 … | + mean: Value() | ||
221 … | + }), | ||
222 … | + skew: Struct({ | ||
223 … | + mean: Value() | ||
224 … | + }) | ||
225 … | + }), | ||
226 … | + source: Value(), | ||
227 … | + state: Value(), | ||
228 … | + stateChange: Value() | ||
229 … | + }) | ||
230 … | + | ||
231 … | + return peer | ||
232 … | +} | ||
233 … | + |
Built with git-ssb-web