git ssb

0+

alanz / patchwork



forked from Matt McKegg / patchwork

Commit e4249874689b314078266a74aed30d8d3960e8db

realtime updating of local peers, show connection state

Matt McKegg committed on 11/3/2016, 3:21:32 PM
Parent: 9fdc650f04f0bea7982659a5d5de3ce799b8ad6a

Files changed

api/index.jschanged
lib/local-with-list.jsadded
modules/obs-local.jschanged
modules/public.jschanged
modules/obs-connected.jsadded
server-process.jschanged
styles/profile-list.mcsschanged
api/index.jsView
@@ -146,7 +146,10 @@
146146 CACHE[e.key] = CACHE[e.key] || e.value
147147 infoCache.updateFrom(e)
148148 })
149149 )
150+ },
151+ sbot_list_local: function (cb) {
152+ return sbot.local.list(cb)
150153 }
151154 }
152155 }
lib/local-with-list.jsView
@@ -1,0 +1,63 @@
1+// FROM: https://github.com/ssbc/scuttlebot/blob/master/plugins/local.js
2+
3+var broadcast = require('broadcast-stream')
4+var ref = require('ssb-ref')
5+var valid = require('scuttlebot/lib/validators')
6+
7+// local plugin
8+// broadcasts the address:port:pubkey triple of the sbot server
9+// on the LAN, using multicast UDP
10+
11+function isFunction (f) {
12+ return 'function' === typeof f
13+}
14+
15+module.exports = {
16+ name: 'local',
17+ version: '2.0.0',
18+ manifest: {
19+ list: 'sync'
20+ },
21+ init: function (sbot, config) {
22+ var local = broadcast(config.port)
23+ var lastSeen = {}
24+ var localKeys = new Set()
25+
26+ setInterval(function () {
27+ Object.keys(lastSeen).forEach((key) => {
28+ if (Date.now() - lastSeen[key] < 10e3) {
29+ localKeys.add(key)
30+ } else {
31+ localKeys.delete(key)
32+ delete lastSeen[key]
33+ }
34+ })
35+ }, 5e3)
36+
37+ local.on('data', function (buf) {
38+ if (buf.loopback) return
39+ var data = buf.toString()
40+ var peer = ref.parseAddress(data)
41+ if (peer) {
42+ lastSeen[peer.key] = Date.now()
43+ sbot.gossip.add(data, 'local')
44+ }
45+ })
46+
47+ setInterval(function () {
48+ // broadcast self
49+ // TODO: sign beacons, so that receipient can be confidant
50+ // that is really your id.
51+ // (which means they can update their peer table)
52+ // Oh if this includes your local address,
53+ // then it becomes unforgeable.
54+ local.write(sbot.getAddress())
55+ }, 1000)
56+
57+ return {
58+ list: valid.sync(function () {
59+ return Array.from(localKeys)
60+ })
61+ }
62+ }
63+}
modules/obs-local.jsView
@@ -1,8 +1,7 @@
11 var MutantSet = require('@mmckegg/mutant/set')
22 var plugs = require('patchbay/plugs')
3-var sbot_gossip_peers = plugs.first(exports.sbot_gossip_peers = [])
4-var ip = require('ip')
3+var sbot_list_local = plugs.first(exports.sbot_list_local = [])
54
65 var cache = null
76
87 exports.obs_local = function () {
@@ -11,19 +10,20 @@
1110 } else {
1211 var result = MutantSet([], {nextTick: true})
1312 // todo: make this clean up on unlisten
1413
15- setTimeout(() => {
16- sbot_gossip_peers((err, peers) => {
17- if (err) throw console.log(err)
18- peers.filter((peer) => {
19- if (ip.isPrivate(peer.host) && (peer.source === 'local')) {
20- result.add(peer.key)
21- }
22- })
23- })
24- }, 5000)
14+ refresh()
15+ setInterval(refresh, 10e3)
2516
2617 cache = result
2718 return result
2819 }
20+
21+ // scope
22+
23+ function refresh () {
24+ sbot_list_local((err, keys) => {
25+ if (err) throw console.log(err)
26+ result.set(keys)
27+ })
28+ }
2929 }
modules/public.jsView
@@ -21,20 +21,22 @@
2121 var obs_recently_updated_feeds = plugs.first(exports.obs_recently_updated_feeds = [])
2222 var avatar_image = plugs.first(exports.avatar_image = [])
2323 var avatar_name = plugs.first(exports.avatar_name = [])
2424 var obs_local = plugs.first(exports.obs_local = [])
25+var obs_connected = plugs.first(exports.obs_connected = [])
2526
2627 exports.screen_view = function (path, sbot) {
2728 if (path === '/public') {
2829 var id = get_id()
29- var channels = computed(obs_channels(), items => items.slice(0, 6), {comparer: arrayEq})
30+ var channels = computed(obs_channels(), items => items.slice(0, 8), {comparer: arrayEq})
3031 var subscribedChannels = obs_subscribed_channels(id)
3132 var loading = computed(subscribedChannels.sync, x => !x)
33+ var connectedPeers = obs_connected()
3234 var localPeers = obs_local()
3335 var following = obs_following(id)
3436
3537 var oldest = Date.now() - (2 * 24 * 60 * 60e3)
36- getFirstMessage(id, (err, msg) => {
38+ getFirstMessage(id, (_, msg) => {
3739 if (msg) {
3840 // fall back to timestamp stream before this, give 48 hrs for feeds to stabilize
3941 if (msg.value.timestamp > oldest) {
4042 oldest = Date.now()
@@ -42,9 +44,9 @@
4244 }
4345 })
4446
4547 var whoToFollow = computed([obs_following(id), obs_recently_updated_feeds(200)], (following, recent) => {
46- return Array.from(recent).filter(x => x !== id && !following.has(x)).slice(0, 20)
48+ return Array.from(recent).filter(x => x !== id && !following.has(x)).slice(0, 10)
4749 })
4850
4951 return h('SplitView', [
5052 h('div.side', [
@@ -77,8 +79,11 @@
7779 when(computed(localPeers, x => x.length), h('h2', 'Local')),
7880 h('ProfileList', [
7981 MutantMap(localPeers, (id) => {
8082 return h('a.profile', {
83+ classList: [
84+ when(computed([connectedPeers, id], (p, id) => p.includes(id)), '-connected')
85+ ],
8186 href: `#${id}`
8287 }, [
8388 h('div.avatar', [avatar_image(id)]),
8489 h('div.main', [
modules/obs-connected.jsView
@@ -1,0 +1,29 @@
1+var MutantSet = require('@mmckegg/mutant/set')
2+var plugs = require('patchbay/plugs')
3+var sbot_gossip_peers = plugs.first(exports.sbot_gossip_peers = [])
4+
5+var cache = null
6+
7+exports.obs_connected = function () {
8+ if (cache) {
9+ return cache
10+ } else {
11+ var result = MutantSet([], {nextTick: true})
12+ // todo: make this clean up on unlisten
13+
14+ refresh()
15+ setInterval(refresh, 10e3)
16+
17+ cache = result
18+ return result
19+ }
20+
21+ // scope
22+
23+ function refresh () {
24+ sbot_gossip_peers((err, peers) => {
25+ if (err) throw console.log(err)
26+ result.set(peers.filter(x => x.state === 'connected').map(x => x.key))
27+ })
28+ }
29+}
server-process.jsView
@@ -10,9 +10,9 @@
1010 .use(require('scuttlebot/plugins/replicate'))
1111 .use(require('ssb-blobs'))
1212 .use(require('scuttlebot/plugins/invite'))
1313 .use(require('scuttlebot/plugins/block'))
14- .use(require('scuttlebot/plugins/local'))
14+ .use(require('./lib/local-with-list'))
1515 .use(require('scuttlebot/plugins/logging'))
1616 .use(require('scuttlebot/plugins/private'))
1717 .use(require('ssb-links'))
1818 .use(require('ssb-query'))
styles/profile-list.mcssView
@@ -12,10 +12,20 @@
1212
1313 background-repeat: no-repeat
1414 background-position: right
1515
16+ -connected {
17+ background-image: svg(connected)
18+ }
19+
20+ @svg connected {
21+ width: 20px
22+ height: 12px
23+ content: "<circle cx='6' stroke='none' fill='green' cy='6' r='5' />"
24+ }
25+
1626 :hover {
17- background: rgba(255, 255, 255, 0.4);
27+ background-color: rgba(255, 255, 255, 0.4);
1828 }
1929
2030 div.avatar {
2131 img {

Built with git-ssb-web