From 7ca1ac0f3b7856c0ae44bfbf3b27ae4a424a1cc2 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Fri, 28 Nov 2014 16:03:56 +0100 Subject: web: virtual scrolling --- web/src/js/stores/base.js | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'web/src/js/stores/base.js') diff --git a/web/src/js/stores/base.js b/web/src/js/stores/base.js index 952fa847..cf9f015e 100644 --- a/web/src/js/stores/base.js +++ b/web/src/js/stores/base.js @@ -10,16 +10,20 @@ EventEmitter.prototype.emit = function (event) { listener.apply(this, args); }.bind(this)); }; -EventEmitter.prototype.addListener = function (event, f) { - this.listeners[event] = this.listeners[event] || []; - this.listeners[event].push(f); +EventEmitter.prototype.addListener = function (events, f) { + events.split(" ").forEach(function (event) { + this.listeners[event] = this.listeners[event] || []; + this.listeners[event].push(f); + }.bind(this)); }; -EventEmitter.prototype.removeListener = function (event, f) { - if (!(event in this.listeners)) { +EventEmitter.prototype.removeListener = function (events, f) { + if (!(events in this.listeners)) { return false; } - var index = this.listeners[event].indexOf(f); - if (index >= 0) { - this.listeners[event].splice(index, 1); - } + events.split(" ").forEach(function (event) { + var index = this.listeners[event].indexOf(f); + if (index >= 0) { + this.listeners[event].splice(index, 1); + } + }.bind(this)); }; -- cgit v1.2.3 From 05bc7e8cd8382aabdd44f7bc569d2fd421c26f21 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Tue, 9 Dec 2014 18:55:16 +0100 Subject: generalize store --- web/src/js/stores/base.js | 112 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) (limited to 'web/src/js/stores/base.js') diff --git a/web/src/js/stores/base.js b/web/src/js/stores/base.js index cf9f015e..f9534bd2 100644 --- a/web/src/js/stores/base.js +++ b/web/src/js/stores/base.js @@ -27,3 +27,115 @@ EventEmitter.prototype.removeListener = function (events, f) { } }.bind(this)); }; + + +function Store() { + this._views = []; + this.reset(); +} +_.extend(Store.prototype, { + add: function (elem) { + if (elem.id in this._pos_map) { + return; + } + + this._pos_map[elem.id] = this._list.length; + this._list.push(elem); + for (var i = 0; i < this._views.length; i++) { + this._views[i].add(elem); + } + }, + update: function (elem) { + if (!(elem.id in this._pos_map)) { + return; + } + + this._list[this._pos_map[elem.id]] = elem; + for (var i = 0; i < this._views.length; i++) { + this._views[i].update(elem); + } + }, + remove: function (elem_id) { + if (!(elem.id in this._pos_map)) { + return; + } + + this._list.splice(this._pos_map[elem_id], 1); + this._build_map(); + for (var i = 0; i < this._views.length; i++) { + this._views[i].remove(elem_id); + } + }, + reset: function (elems) { + this._list = elems || []; + this._build_map(); + for (var i = 0; i < this._views.length; i++) { + this._views[i].recalculate(this._list); + } + }, + _build_map: function () { + this._pos_map = {}; + for (var i = 0; i < this._list.length; i++) { + var elem = this._list[i]; + this._pos_map[elem.id] = i; + } + }, + get: function (elem_id) { + return this._list[this._pos_map[elem_id]]; + } +}); + + +function LiveStore(type) { + Store.call(this); + this.type = type; + + this._updates_before_fetch = undefined; + this._fetchxhr = false; + + this.handle = this.handle.bind(this); + AppDispatcher.register(this.handle); + + // Avoid double-fetch on startup. + if (!(window.ws && window.ws.readyState === WebSocket.CONNECTING)) { + this.fetch(); + } +} +_.extend(LiveStore.prototype, Store.prototype, { + handle: function (event) { + if (event.type === ActionTypes.CONNECTION_OPEN) { + return this.fetch(); + } + if (event.type === this.type) { + if (event.cmd === "reset") { + this.fetch(); + } else if (this._updates_before_fetch) { + console.log("defer update", event); + this._updates_before_fetch.push(event); + } else { + this[event.cmd](event.data); + } + } + }, + close: function () { + AppDispatcher.unregister(this.handle); + }, + fetch: function () { + console.log("fetch " + this.type); + if (this._fetchxhr) { + this._fetchxhr.abort(); + } + this._fetchxhr = $.getJSON("/" + this.type, this.handle_fetch.bind(this)); + this._updates_before_fetch = []; // (JS: empty array is true) + }, + handle_fetch: function (data) { + this._fetchxhr = false; + console.log(this.type + " fetched.", this._updates_before_fetch); + this.reset(data.flows); + var updates = this._updates_before_fetch; + this._updates_before_fetch = false; + for (var i = 0; i < updates.length; i++) { + this.handle(updates[i]); + } + }, +}); \ No newline at end of file -- cgit v1.2.3 From e12bf19e35867f3ea69f45054decb024a75fc2b4 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Wed, 10 Dec 2014 00:47:05 +0100 Subject: web: add event store, fix all those bugs --- web/src/js/stores/base.js | 141 ---------------------------------------------- 1 file changed, 141 deletions(-) delete mode 100644 web/src/js/stores/base.js (limited to 'web/src/js/stores/base.js') diff --git a/web/src/js/stores/base.js b/web/src/js/stores/base.js deleted file mode 100644 index f9534bd2..00000000 --- a/web/src/js/stores/base.js +++ /dev/null @@ -1,141 +0,0 @@ -function EventEmitter() { - this.listeners = {}; -} -EventEmitter.prototype.emit = function (event) { - if (!(event in this.listeners)) { - return; - } - var args = Array.prototype.slice.call(arguments, 1); - this.listeners[event].forEach(function (listener) { - listener.apply(this, args); - }.bind(this)); -}; -EventEmitter.prototype.addListener = function (events, f) { - events.split(" ").forEach(function (event) { - this.listeners[event] = this.listeners[event] || []; - this.listeners[event].push(f); - }.bind(this)); -}; -EventEmitter.prototype.removeListener = function (events, f) { - if (!(events in this.listeners)) { - return false; - } - events.split(" ").forEach(function (event) { - var index = this.listeners[event].indexOf(f); - if (index >= 0) { - this.listeners[event].splice(index, 1); - } - }.bind(this)); -}; - - -function Store() { - this._views = []; - this.reset(); -} -_.extend(Store.prototype, { - add: function (elem) { - if (elem.id in this._pos_map) { - return; - } - - this._pos_map[elem.id] = this._list.length; - this._list.push(elem); - for (var i = 0; i < this._views.length; i++) { - this._views[i].add(elem); - } - }, - update: function (elem) { - if (!(elem.id in this._pos_map)) { - return; - } - - this._list[this._pos_map[elem.id]] = elem; - for (var i = 0; i < this._views.length; i++) { - this._views[i].update(elem); - } - }, - remove: function (elem_id) { - if (!(elem.id in this._pos_map)) { - return; - } - - this._list.splice(this._pos_map[elem_id], 1); - this._build_map(); - for (var i = 0; i < this._views.length; i++) { - this._views[i].remove(elem_id); - } - }, - reset: function (elems) { - this._list = elems || []; - this._build_map(); - for (var i = 0; i < this._views.length; i++) { - this._views[i].recalculate(this._list); - } - }, - _build_map: function () { - this._pos_map = {}; - for (var i = 0; i < this._list.length; i++) { - var elem = this._list[i]; - this._pos_map[elem.id] = i; - } - }, - get: function (elem_id) { - return this._list[this._pos_map[elem_id]]; - } -}); - - -function LiveStore(type) { - Store.call(this); - this.type = type; - - this._updates_before_fetch = undefined; - this._fetchxhr = false; - - this.handle = this.handle.bind(this); - AppDispatcher.register(this.handle); - - // Avoid double-fetch on startup. - if (!(window.ws && window.ws.readyState === WebSocket.CONNECTING)) { - this.fetch(); - } -} -_.extend(LiveStore.prototype, Store.prototype, { - handle: function (event) { - if (event.type === ActionTypes.CONNECTION_OPEN) { - return this.fetch(); - } - if (event.type === this.type) { - if (event.cmd === "reset") { - this.fetch(); - } else if (this._updates_before_fetch) { - console.log("defer update", event); - this._updates_before_fetch.push(event); - } else { - this[event.cmd](event.data); - } - } - }, - close: function () { - AppDispatcher.unregister(this.handle); - }, - fetch: function () { - console.log("fetch " + this.type); - if (this._fetchxhr) { - this._fetchxhr.abort(); - } - this._fetchxhr = $.getJSON("/" + this.type, this.handle_fetch.bind(this)); - this._updates_before_fetch = []; // (JS: empty array is true) - }, - handle_fetch: function (data) { - this._fetchxhr = false; - console.log(this.type + " fetched.", this._updates_before_fetch); - this.reset(data.flows); - var updates = this._updates_before_fetch; - this._updates_before_fetch = false; - for (var i = 0; i < updates.length; i++) { - this.handle(updates[i]); - } - }, -}); \ No newline at end of file -- cgit v1.2.3