git ssb

1+

ev / minbay



Tree: afe7de9580840925af61711b5ab0d6c57d1131a4

Files: afe7de9580840925af61711b5ab0d6c57d1131a4 / modules / network.js

4097 bytesRaw
1var isVisible = require('is-visible').isVisible
2var h = require('hyperscript')
3
4exports.needs = {
5 avatar: 'first',
6 sbot_gossip_peers: 'first',
7 sbot_gossip_connect: 'first'
8}
9
10exports.gives = {
11 menu_items: true,
12 builtin_tabs: true,
13 screen_view: true
14}
15
16//sbot_gossip_connect
17//sbot_gossip_add
18
19var human = require('human-time')
20
21function 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
29function 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.
38function 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
44function isLegacy (peer) {
45 return /connect/.test(peer.state) || (peer.duration && peer.duration.mean) > 0 && !isLongterm(peer)
46}
47
48//tried to connect, but failed.
49function isInactive (e) {
50 return e.stateChange && (e.duration && e.duration.mean == 0)
51}
52
53//havn't tried to connect peer yet.
54function isUnattempted (e) {
55 return !e.stateChange
56}
57
58function 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
68function origin (e) {
69 return e.source === 'local' ? 0 : 1
70}
71
72var states = {
73 connected: 3,
74 connecting: 2
75}
76
77var types = {
78 modern: 4,
79 legacy: 3,
80 inactive: 2,
81 unattempted: 1,
82 other: 0
83}
84
85function round(n) {
86 return Math.round(n*100)/100
87}
88
89function 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
101exports.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