Browse Source

make meshstats, simplenodelist setData idempotent

Nils Schneider 9 years ago
parent
commit
7b57a2245b
4 changed files with 60 additions and 52 deletions
  1. 1 0
      app.js
  2. 2 1
      bower.json
  3. 11 7
      lib/meshstats.js
  4. 46 44
      lib/simplenodelist.js

+ 1 - 0
app.js

@@ -10,6 +10,7 @@ require.config({
     "d3": "../bower_components/d3/d3.min",
     "numeral": "../bower_components/numeraljs/min/numeral.min",
     "numeral-intl": "../bower_components/numeraljs/min/languages.min",
+    "virtual-dom": "../bower_components/virtual-dom/dist/virtual-dom",
     "helper": "../helper"
   },
   shim: {

+ 2 - 1
bower.json

@@ -21,7 +21,8 @@
     "r.js": "~2.1.16",
     "d3": "~3.5.5",
     "numeraljs": "~1.5.3",
-    "roboto-fontface": "~0.3.0"
+    "roboto-fontface": "~0.3.0",
+    "virtual-dom": "~2.0.1"
   },
   "authors": [
     "Nils Schneider <nils@nilsschneider.net>"

+ 11 - 7
lib/meshstats.js

@@ -1,7 +1,7 @@
 define(function () {
   return function () {
     var self = this
-    var p
+    var stats, timestamp
 
     self.setData = function (d) {
       var totalNodes = sum(d.nodes.all.filter(online).map(one))
@@ -12,12 +12,11 @@ define(function () {
         return d.flags.gateway
       }).map(one))
 
-      p.textContent = totalNodes + " Knoten (online), " +
-                      totalClients + " Clients, " +
-                      totalGateways + " Gateways"
+      stats.textContent = totalNodes + " Knoten (online), " +
+                          totalClients + " Clients, " +
+                          totalGateways + " Gateways"
 
-      p.appendChild(document.createElement("br"))
-      p.appendChild(document.createTextNode("Diese Daten sind von " + d.timestamp.format("LLLL") + "."))
+      timestamp.textContent = "Diese Daten sind von " + d.timestamp.format("LLLL") + "."
     }
 
     self.render = function (el) {
@@ -25,8 +24,13 @@ define(function () {
       h2.textContent = "Übersicht"
       el.appendChild(h2)
 
-      p = document.createElement("p")
+      var p = document.createElement("p")
       el.appendChild(p)
+      stats = document.createTextNode("")
+      p.appendChild(stats)
+      p.appendChild(document.createElement("br"))
+      timestamp = document.createTextNode("")
+      p.appendChild(timestamp)
     }
 
     return self

+ 46 - 44
lib/simplenodelist.js

@@ -1,7 +1,7 @@
-define(["moment"], function (moment) {
+define(["moment", "virtual-dom"], function (moment, V) {
   return function(config, nodes, field, router, title) {
     var self = this
-    var el
+    var el, tbody
 
     self.render = function (d) {
       el = document.createElement("div")
@@ -11,52 +11,54 @@ define(["moment"], function (moment) {
     self.setData = function (data) {
       var list = data.nodes[nodes]
 
-      if (list.length === 0)
+      if (list.length === 0) {
+        while (el.firstChild)
+              el.removeChild(el.firstChild)
+
+        tbody = null
+
         return
+      }
+
+      if (!tbody) {
+        var h2 = document.createElement("h2")
+        h2.textContent = title
+        el.appendChild(h2)
+
+        var table = document.createElement("table")
+        el.appendChild(table)
+
+        tbody = document.createElement("tbody")
+        tbody.last = V.h("tbody")
+        table.appendChild(tbody)
+      }
+
+      var items = list.map( function (d) {
+        var time = moment(d[field]).from(data.now)
+        var td1Content = []
+
+        var aClass = ["hostname", d.flags.online ? "online" : "offline"]
+
+        td1Content.push(V.h("a", { className: aClass.join(" "),
+                                   onclick: router.node(d),
+                                   href: "#"
+                                 }, d.nodeinfo.hostname))
+
+        if (has_location(d))
+          td1Content.push(V.h("span", {className: "icon ion-location"}))
+
+        if ("owner" in d.nodeinfo && config.showContact)
+          td1Content.push(" - " + d.nodeinfo.owner.contact)
+
+        var td1 = V.h("td", td1Content)
+        var td2 = V.h("td", time)
 
-      var h2 = document.createElement("h2")
-      h2.textContent = title
-      el.appendChild(h2)
-      var table = document.createElement("table")
-      el.appendChild(table)
-
-      var tbody = document.createElement("tbody")
-
-      list.forEach( function (d) {
-        var time = moment(d[field]).fromNow()
-
-        var row = document.createElement("tr")
-        var td1 = document.createElement("td")
-        var a = document.createElement("a")
-        a.classList.add("hostname")
-        a.classList.add(d.flags.online ? "online" : "offline")
-        a.textContent = d.nodeinfo.hostname
-        a.href = "#"
-        a.onclick = router.node(d)
-        td1.appendChild(a)
-
-        if (has_location(d)) {
-          var span = document.createElement("span")
-          span.classList.add("icon")
-          span.classList.add("ion-location")
-          td1.appendChild(span)
-        }
-
-        if ("owner" in d.nodeinfo && config.showContact) {
-          var contact = d.nodeinfo.owner.contact
-          td1.appendChild(document.createTextNode(" – " + contact + ""))
-        }
-
-        var td2 = document.createElement("td")
-        td2.textContent = time
-
-        row.appendChild(td1)
-        row.appendChild(td2)
-        tbody.appendChild(row)
+        return V.h("tr", [td1, td2])
       })
 
-      table.appendChild(tbody)
-      el.appendChild(table)
+      var tbodyNew = V.h("tbody", items)
+      tbody = V.patch(tbody, V.diff(tbody.last, tbodyNew))
+      tbody.last = tbodyNew
     }
 
     return self