Files: afe7de9580840925af61711b5ab0d6c57d1131a4 / modules / network.js
4097 bytesRaw
1 | var isVisible = require('is-visible').isVisible |
2 | var h = require('hyperscript') |
3 | |
4 | exports.needs = { |
5 | avatar: 'first', |
6 | sbot_gossip_peers: 'first', |
7 | sbot_gossip_connect: 'first' |
8 | } |
9 | |
10 | exports.gives = { |
11 | menu_items: true, |
12 | builtin_tabs: true, |
13 | screen_view: true |
14 | } |
15 | |
16 | //sbot_gossip_connect |
17 | //sbot_gossip_add |
18 | |
19 | var human = require('human-time') |
20 | |
21 | function legacyToMultiServer(addr) { |
22 | return 'net:'+addr.host + ':'+addr.port + '~shs:'+addr.key.substring(1).replace('.ed25519','') |
23 | } |
24 | |
25 | //types of peers |
26 | |
27 | |
28 | //on the same wifi network |
29 | function isLocal (e) { |
30 | // don't rely on private ip address, because |
31 | // cjdns creates fake private ip addresses. |
32 | return ip.isPrivate(e.host) && e.type === 'local' |
33 | } |
34 | |
35 | |
36 | //pub is running scuttlebot >=8 |
37 | //have connected successfully. |
38 | function isLongterm (e) { |
39 | return e.ping && e.ping.rtt && e.ping.rtt.mean > 0 |
40 | } |
41 | |
42 | //pub is running scuttlebot < 8 |
43 | //have connected sucessfully |
44 | function isLegacy (peer) { |
45 | return /connect/.test(peer.state) || (peer.duration && peer.duration.mean) > 0 && !isLongterm(peer) |
46 | } |
47 | |
48 | //tried to connect, but failed. |
49 | function isInactive (e) { |
50 | return e.stateChange && (e.duration && e.duration.mean == 0) |
51 | } |
52 | |
53 | //havn't tried to connect peer yet. |
54 | function isUnattempted (e) { |
55 | return !e.stateChange |
56 | } |
57 | |
58 | function getType (e) { |
59 | return ( |
60 | isLongterm(e) ? 'modern' |
61 | : isLegacy(e) ? 'legacy' |
62 | : isInactive(e) ? 'inactive' |
63 | : isUnattempted(e) ? 'unattempted' |
64 | : 'other' //should never happen |
65 | ) |
66 | } |
67 | |
68 | function origin (e) { |
69 | return e.source === 'local' ? 0 : 1 |
70 | } |
71 | |
72 | var states = { |
73 | connected: 3, |
74 | connecting: 2 |
75 | } |
76 | |
77 | var types = { |
78 | modern: 4, |
79 | legacy: 3, |
80 | inactive: 2, |
81 | unattempted: 1, |
82 | other: 0 |
83 | } |
84 | |
85 | function round(n) { |
86 | return Math.round(n*100)/100 |
87 | } |
88 | |
89 | function duration (s) { |
90 | if(!s) return s |
91 | if (Math.abs(s) > 30000) |
92 | return round(s/60000)+'m' |
93 | else if (Math.abs(s) > 500) |
94 | return round(s/1000)+'s' |
95 | else |
96 | return round(s)+'ms' |
97 | } |
98 | |
99 | |
100 | |
101 | exports.create = function (api) { |
102 | |
103 | return { |
104 | menu_items: function () { |
105 | return h('a', {href: '#Network'}, 'Network') |
106 | }, |
107 | |
108 | builtin_tabs: function () { |
109 | return ['Network'] |
110 | }, |
111 | |
112 | screen_view: function (path) { |
113 | |
114 | if(path !== 'Network') return |
115 | |
116 | var ol = h('div.network') |
117 | |
118 | ;(function poll () { |
119 | |
120 | //if this tab isn't open, don't update. |
121 | //todo: make a better way to do this... |
122 | if(!isVisible(ol)) |
123 | return setTimeout(poll, 1000) |
124 | |
125 | api.sbot_gossip_peers(function (err, list) { |
126 | ol.innerHTML = '' |
127 | list.sort(function (a, b) { |
128 | return ( |
129 | (states[b.state] || 0) - (states[a.state] || 0) |
130 | || origin(b) - origin(a) |
131 | || types[getType(b)] - types[getType(a)] |
132 | || b.stateChange - a.stateChange |
133 | ) |
134 | }).forEach(function (peer) { |
135 | ol.appendChild(h('div.message', |
136 | api.avatar(peer.key, 'thumbnail'), |
137 | h('div', |
138 | peer.state || 'not connected', |
139 | ' ', |
140 | getType(peer), |
141 | ' ', |
142 | //TODO: show nicer details, with labels. etc. |
143 | (peer.ping && peer.ping.rtt) ? duration(peer.ping.rtt.mean) : '', |
144 | ' ', |
145 | (peer.ping && peer.ping.skew) ? duration(peer.ping.skew.mean) : '', |
146 | h('label', |
147 | {title: new Date(peer.stateChange).toString()}, |
148 | peer.stateChange && ('(' + human(new Date(peer.stateChange))) + ')') |
149 | ), |
150 | 'source:'+peer.source, |
151 | h('pre', legacyToMultiServer(peer)), |
152 | h('button', 'connect', {onclick: function () { |
153 | api.sbot_gossip_connect(peer, function (err) { |
154 | if(err) console.error(err) |
155 | else console.log('connected to', peer) |
156 | }) |
157 | }}) |
158 | ) |
159 | ) |
160 | }) |
161 | setTimeout(poll, 1000) |
162 | }) |
163 | })() |
164 | return h('div.column.scroller', h('div.column.scroll-y', h('div.column.scroller__wrapper', ol))) |
165 | } |
166 | } |
167 | } |
168 | |
169 | |
170 |
Built with git-ssb-web