gluon/package/gluon-status-page/src/js/main.js
Brother-Lal e80f751a85 fix error in statuspage if cookies are disabled (#912)
If cookies are disabled, the Statuspage only displays an empty ("Not connected")
This checks if the localStorage API is available and working and only uses it in this case
Also allows better backwards compatibility.
2016-10-24 14:18:01 +02:00

120 lines
2.8 KiB
JavaScript

"use strict"
require([ "bacon"
, "lib/helper"
, "lib/streams"
, "lib/gui"
], function(Bacon, Helper, Streams, GUI) {
var mgmtBus = new Bacon.Bus()
mgmtBus.pushEvent = function (key, a) {
var v = [key].concat(a)
return this.push(v)
}
mgmtBus.onEvent = function (events) {
return this.onValue(function (e) {
var d = e.slice() // shallow copy so calling shift doesn't change it
var ev = d.shift()
if (ev in events)
events[ev].apply(this, d)
})
}
var nodesBusIn = new Bacon.Bus()
var nodesBus = nodesBusIn.scan({ "nodes": {}
, "macs": {}
}, scanNodeInfo)
new GUI(mgmtBus, nodesBus)
mgmtBus.onEvent({ "goto": gotoNode
, "nodeinfo": function (d) { nodesBusIn.push(d) }
})
function tryIp(ip) {
return Helper.request(ip, "nodeinfo").map(function () { return ip })
}
var gotoEpoch = 0
function onEpoch(epoch, f) {
return function (d) {
if (epoch === gotoEpoch)
return f(d)
}
}
function gotoNode(nodeInfo) {
gotoEpoch++
var addresses = nodeInfo.network.addresses.filter(function (d) { return !/^fe80:/.test(d) })
var race = Bacon.fromArray(addresses).flatMap(tryIp).withStateMachine([], function (acc, ev) {
if (ev.isError())
return [acc.concat(ev.error), []]
else if (ev.isEnd() && acc.length > 0)
return [undefined, [new Bacon.Error(acc), ev]]
else if (ev.hasValue())
return [[], [ev, new Bacon.End()]]
})
race.onValue(onEpoch(gotoEpoch, function (d) {
mgmtBus.pushEvent("arrived", [nodeInfo, d])
}))
race.onError(onEpoch(gotoEpoch, function () {
mgmtBus.pushEvent("gotoFailed", nodeInfo)
}))
}
function scanNodeInfo(a, nodeInfo) {
a.nodes[nodeInfo.node_id] = nodeInfo
var mesh = Helper.dictGet(nodeInfo, ["network", "mesh"])
if (mesh)
for (var m in mesh)
for (var ifname in mesh[m].interfaces)
mesh[m].interfaces[ifname].forEach( function (d) {
a.macs[d] = nodeInfo
})
return a
}
var lsavailable = false
try {
localStorage.setItem("t", "t")
localStorage.removeItem("t")
lsavailable = true
} catch(e) {
lsavailable = false
}
if ( lsavailable && localStorage.nodes)
JSON.parse(localStorage.nodes).forEach(nodesBusIn.push)
nodesBus.map(".nodes").onValue(function (nodes) {
var out = []
for (var k in nodes)
out.push(nodes[k])
if (lsavailable)
localStorage.nodes = JSON.stringify(out)
})
var bootstrap = Helper.getJSON(bootstrapUrl)
bootstrap.onError(function () {
console.log("FIXME bootstrapping failed")
})
bootstrap.onValue(function (d) {
mgmtBus.pushEvent("nodeinfo", d)
mgmtBus.pushEvent("goto", d)
})
})