From 5060bf595337ee4d27a313d3508ae48cb00968cf Mon Sep 17 00:00:00 2001 From: Chris Stasiak Date: Thu, 29 Jan 2015 13:47:46 +0100 Subject: [PATCH 01/20] Added elasticfeed.init() --- service/stream/static/elasticfeed.js | 31 ++++++++++++++++++---------- service/stream/static/lp.html | 9 +++++++- service/stream/static/ws.html | 9 ++++++-- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/service/stream/static/elasticfeed.js b/service/stream/static/elasticfeed.js index d592b96..19ff459 100644 --- a/service/stream/static/elasticfeed.js +++ b/service/stream/static/elasticfeed.js @@ -15,27 +15,36 @@ includeJs('lib/event/system.js'); (function(window) { + /** @type {Object} */ + var defaultOptions = { + channel: { + url: 'localhost', + transport: 'ws' + }, + styler: function(data) { + } + } + var elasticfeed = { + /** @type {Object} */ + options: {}, + /** @type {Object} */ channelList: {}, /** @type {Object} */ feedList: {}, - initFeed: function(options) { - options = _extend({ - channel: { - url: 'ws://localhost:80/ws', - transport: 'ws' - }, - styler: function(data) { - } - }, options); + init: function(options) { + this.options = _extend(defaultOptions, options); + }, - channel = this.getChannel(options.channel); + initFeed: function(id, options) { + feed_options = _extend(this.options, options || {}); + channel = this.getChannel(feed_options.channel); - return new Feed(options, channel); + return new Feed(feed_options, channel); }, /** diff --git a/service/stream/static/lp.html b/service/stream/static/lp.html index 14a059e..89c3c2b 100644 --- a/service/stream/static/lp.html +++ b/service/stream/static/lp.html @@ -5,7 +5,14 @@ window.onload = function() { - feed = elasticfeed.initFeed({ + elasticfeed.init({ + channel: { + url: 'http://localhost:80', + transport: 'ws' + } + }); + + feed = elasticfeed.initFeed('0000000001', { channel: { url: 'http://localhost:80', transport: 'lp' diff --git a/service/stream/static/ws.html b/service/stream/static/ws.html index b658150..b9f96cd 100644 --- a/service/stream/static/ws.html +++ b/service/stream/static/ws.html @@ -5,10 +5,15 @@ window.onload = function() { - feed = elasticfeed.initFeed({ - transport: 'ws' + elasticfeed.init({ + channel: { + url: 'ws://localhost:80', + transport: 'ws' + } }); + feed = elasticfeed.initFeed('0000000002'); + feed.channel.on('join', function(chid, ts) { console.log(chid + " joined the chat room"); }); From ab4d66b9a71010baefc4bc9f02569c09f1949093 Mon Sep 17 00:00:00 2001 From: Chris Stasiak Date: Thu, 29 Jan 2015 14:06:04 +0100 Subject: [PATCH 02/20] Added init for examples; added style functions --- service/stream/static/elasticfeed.js | 2 +- service/stream/static/lib/feed.js | 34 ++++++++++++++++++++-------- service/stream/static/lp.html | 12 +++++++--- service/stream/static/ws.html | 15 ++++++++---- 4 files changed, 45 insertions(+), 18 deletions(-) diff --git a/service/stream/static/elasticfeed.js b/service/stream/static/elasticfeed.js index 19ff459..352b388 100644 --- a/service/stream/static/elasticfeed.js +++ b/service/stream/static/elasticfeed.js @@ -21,7 +21,7 @@ includeJs('lib/event/system.js'); url: 'localhost', transport: 'ws' }, - styler: function(data) { + stylerFunction: function(data) { } } diff --git a/service/stream/static/lib/feed.js b/service/stream/static/lib/feed.js index 945dd1e..1812018 100644 --- a/service/stream/static/lib/feed.js +++ b/service/stream/static/lib/feed.js @@ -50,44 +50,53 @@ var Feed = (function() { this.socket = this.channel.getLongPoolingConnection(); } + /** @type {Object} */ this.options = _extend(globalOptions, options); - this._stylerFunction = options.styler || this._stylerFunction; + + /** @type {Function} */ + this.stylerFunction = options.stylerFunction || this._stylerFunction; + + /** @type {DOM} */ this.outputContainer = document.getElementById(this.options.outputContainerId); this.bindChannel(this.channel); } Feed.prototype.on = function(type, callback) { - } // Events callbacks - Feed.prototype.onReload = function(callback) { + Feed.prototype.onReload = function() { } - Feed.prototype.onReset = function(callback) { + Feed.prototype.onReset = function() { } - Feed.prototype.onEntryAdd = function(callback) { + Feed.prototype.onEntryAdd = function(entry) { } - Feed.prototype.onEntryDelete = function(callback) { + Feed.prototype.onEntryDelete = function(entry) { } - Feed.prototype.onEntryUpdate = function(callback) { + Feed.prototype.onEntryUpdate = function(entry) { } - Feed.prototype.onEvent = function(eventName, callback) { + Feed.prototype.onEvent = function(event) { } - Feed.prototype.onData = function(callback) { + Feed.prototype.onData = function(data) { } // Entries management Feed.prototype.addEntry = function(data) { - this.entryList.push(new Entry(data)) + entry = new Entry(data); + + this.entryList.push(entry); + this.onEntryAdd(entry); + + this.outputContainer.innerHTML = this.stylerFunction.call(this, data) + this.outputContainer.innerHTML; } Feed.prototype.deleteEntry = function(id) { @@ -99,6 +108,11 @@ var Feed = (function() { Feed.prototype.findEntry = function(id) { } + // UI + + Feed.prototype.render = function() { + } + // Handlers Feed.prototype.bindChannel = function(channel) { diff --git a/service/stream/static/lp.html b/service/stream/static/lp.html index 89c3c2b..ff79042 100644 --- a/service/stream/static/lp.html +++ b/service/stream/static/lp.html @@ -16,24 +16,30 @@ channel: { url: 'http://localhost:80', transport: 'lp' + }, + outputContainerId: 'my-elastic-feed', + stylerFunction: function(data) { + return '
' + data + '
'; } }); feed.channel.on('join', function(chid, ts) { - console.log(chid + " joined the chat room"); + feed.addEntry(chid + " joined the chat room"); }); feed.channel.on('leave', function(chid, ts) { - console.log(chid + " left the chat room"); + feed.addEntry(chid + " left the chat room"); }); feed.channel.on('message', function(chid, ts, data) { - console.log(chid + " " + JSON.stringify(data)); + feed.addEntry(chid + " " + JSON.stringify(data)); }); window['socket'] = feed.socket } + +
diff --git a/service/stream/static/ws.html b/service/stream/static/ws.html index b9f96cd..a0efd4c 100644 --- a/service/stream/static/ws.html +++ b/service/stream/static/ws.html @@ -12,23 +12,30 @@ } }); - feed = elasticfeed.initFeed('0000000002'); + feed = elasticfeed.initFeed('0000000002', { + outputContainerId: 'my-elastic-feed', + stylerFunction: function(data) { + return '
' + data + '
'; + } + }); feed.channel.on('join', function(chid, ts) { - console.log(chid + " joined the chat room"); + feed.addEntry(chid + " joined the chat room"); }); feed.channel.on('leave', function(chid, ts) { - console.log(chid + " left the chat room"); + feed.addEntry(chid + " left the chat room"); }); feed.channel.on('message', function(chid, ts, data) { - console.log(chid + " " + JSON.stringify(data)); + feed.addEntry(chid + " " + JSON.stringify(data)); }); window['socket'] = feed.socket } + +
From 19d5bcd50915bd9ea773abbff0f15835a1c3c8b5 Mon Sep 17 00:00:00 2001 From: Chris Stasiak Date: Thu, 29 Jan 2015 16:23:32 +0100 Subject: [PATCH 03/20] Extended websocket example with 2 feeds --- service/stream/static/ws.html | 42 ++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/service/stream/static/ws.html b/service/stream/static/ws.html index a0efd4c..350c352 100644 --- a/service/stream/static/ws.html +++ b/service/stream/static/ws.html @@ -12,30 +12,50 @@ } }); - feed = elasticfeed.initFeed('0000000002', { - outputContainerId: 'my-elastic-feed', + feed1 = elasticfeed.initFeed('0000000002', { + outputContainerId: 'my-elastic-feed-left', stylerFunction: function(data) { - return '
' + data + '
'; + return '
' + data + '
'; } }); - feed.channel.on('join', function(chid, ts) { - feed.addEntry(chid + " joined the chat room"); + feed2 = elasticfeed.initFeed('0000000003', { + outputContainerId: 'my-elastic-feed-right', + stylerFunction: function(data) { + return '
' + data + '
'; + } + }); + + feed1.channel.on('join', function(chid, ts) { + feed1.addEntry(chid + " joined the chat room"); + }); + + feed1.channel.on('leave', function(chid, ts) { + feed1.addEntry(chid + " left the chat room"); + }); + + feed1.channel.on('message', function(chid, ts, data) { + feed1.addEntry(chid + " " + JSON.stringify(data)); + }); + + feed2.channel.on('join', function(chid, ts) { + feed2.addEntry(chid + " joined the chat room"); }); - feed.channel.on('leave', function(chid, ts) { - feed.addEntry(chid + " left the chat room"); + feed2.channel.on('leave', function(chid, ts) { + feed2.addEntry(chid + " left the chat room"); }); - feed.channel.on('message', function(chid, ts, data) { - feed.addEntry(chid + " " + JSON.stringify(data)); + feed2.channel.on('message', function(chid, ts, data) { + feed2.addEntry(chid + " " + JSON.stringify(data)); }); - window['socket'] = feed.socket + window['socket'] = feed1.socket } -
+
+
From 1b3c168322d9dd9b33b2c4f317bafbda5d5dc684 Mon Sep 17 00:00:00 2001 From: Chris Stasiak Date: Thu, 29 Jan 2015 23:38:45 +0100 Subject: [PATCH 04/20] Multi feed on view support; --- docs/examples/javascript.md | 37 ++++++ service/stream/static/elasticfeed.js | 4 +- service/stream/static/lib/channel.js | 37 +++--- service/stream/static/lib/entry.js | 7 +- service/stream/static/lib/event/feed.js | 5 +- service/stream/static/lib/event/system.js | 7 +- service/stream/static/lib/feed.js | 148 ++++++++++++++++++---- service/stream/static/ws.html | 50 +++----- 8 files changed, 203 insertions(+), 92 deletions(-) create mode 100644 docs/examples/javascript.md diff --git a/docs/examples/javascript.md b/docs/examples/javascript.md new file mode 100644 index 0000000..8f3f96f --- /dev/null +++ b/docs/examples/javascript.md @@ -0,0 +1,37 @@ +### JS client + +#### Usage +``` + elasticfeed.init({ + channel: { + url: 'ws://localhost:80', + transport: 'ws' + } + }); + + feed = elasticfeed.initFeed('000001', { + outputContainerId: 'my-elastic-feed-1', + stylerFunction: function(data) { + return '
' + data + '
'; + } + }); + + feed.channel.on('join', function(chid, ts) { + feed1.addEntry(chid + " joined the chat room"); + }); + + feed.channel.on('leave', function(chid, ts) { + feed1.addEntry(chid + " left the chat room"); + }); + + window['socket'] = feed1.socket; +``` + +#### Test data broadcast +``` + // single feed + socket.send({Type:1, Timestamp:1111111, Content: {Type:3, Timestamp:22222, Id: "000001", Content: "data-examples"}}) + + // all feeds in the view on the chanel + socket.send({Type:1, Timestamp:1111111, Content: {Type:3, Timestamp:22222, Id: "*", Content: "data-examples"}}) +``` diff --git a/service/stream/static/elasticfeed.js b/service/stream/static/elasticfeed.js index 352b388..f207293 100644 --- a/service/stream/static/elasticfeed.js +++ b/service/stream/static/elasticfeed.js @@ -12,6 +12,8 @@ includeJs('lib/entry.js'); includeJs('lib/channel.js'); includeJs('lib/event/channel.js'); includeJs('lib/event/system.js'); +includeJs('lib/event/feed.js'); +includeJs('lib/event/entry.js'); (function(window) { @@ -44,7 +46,7 @@ includeJs('lib/event/system.js'); feed_options = _extend(this.options, options || {}); channel = this.getChannel(feed_options.channel); - return new Feed(feed_options, channel); + return new Feed(id, feed_options, channel); }, /** diff --git a/service/stream/static/lib/channel.js b/service/stream/static/lib/channel.js index 8a6e711..1a688fd 100644 --- a/service/stream/static/lib/channel.js +++ b/service/stream/static/lib/channel.js @@ -31,6 +31,9 @@ var Channel = (function() { /** @type {Object} */ this._handlers = {}; + + /** @type {WebSocket} */ + this._socket = null; } // Handlers @@ -64,18 +67,18 @@ var Channel = (function() { // Events /** - * @param {ChannelEvent} event + * @param {ChannelEvent} channelEvent */ - Channel.prototype.onData = function(event) { - switch (event.Type) { + Channel.prototype.onData = function(channelEvent) { + switch (channelEvent.Type) { case JOIN: - this.onJoin(event.User, event.ts) + this.onJoin(channelEvent.User, channelEvent.ts) break; case LEAVE: - this.onLeave(event.User, event.ts) + this.onLeave(channelEvent.User, channelEvent.ts) break; case MESSAGE: - this.onMessage(event.User, event.ts, event.Content) + this.onMessage(channelEvent.User, channelEvent.ts, channelEvent.Content) break; } } @@ -93,13 +96,19 @@ var Channel = (function() { } Channel.prototype.onMessage = function(chid, timestamp, data) { + systemEvent = new SystemEvent(chid, data); + for (var i in this._handlers[MESSAGE]) { - this._handlers[MESSAGE][i].call(this, chid, timestamp, data); + this._handlers[MESSAGE][i].call(this, chid, timestamp, systemEvent); } } // Connection + Channel.prototype.isWebSocket = function() { + return this._socket != undefined; + } + Channel.prototype.getConnection = function() { } @@ -244,20 +253,6 @@ var Channel = (function() { xhr1.send(dataString); } - Channel.prototype.EventToString = function(event) { - switch (event.Type) { - case JOIN: - console.log(event.User + " joined the chat room"); - break; - case LEAVE: - console.log(event.User + " left the chat room"); - break; - case MESSAGE: - console.log(event.User + ", " + event.PrintContent()); - break; - } - } - // Helpers var _extend = function(a, b) { diff --git a/service/stream/static/lib/entry.js b/service/stream/static/lib/entry.js index 149fefe..62f37b6 100644 --- a/service/stream/static/lib/entry.js +++ b/service/stream/static/lib/entry.js @@ -17,11 +17,8 @@ var Entry = (function() { /** @type {String} */ this.id = null; - /** @type {Integer} */ - this.ts = null; - - /** @type {Feed} */ - this.parent = null; + /** @type {String} */ + this.data = data; } // Management diff --git a/service/stream/static/lib/event/feed.js b/service/stream/static/lib/event/feed.js index 3b0432e..d869f6f 100644 --- a/service/stream/static/lib/event/feed.js +++ b/service/stream/static/lib/event/feed.js @@ -3,7 +3,7 @@ var FeedEvent = (function() { function FeedEvent(event) { /** @type {String} */ - this.id = null; + this.id = event.Id; /** @type {Integer} */ this.ts = event.Timestamp; @@ -14,9 +14,6 @@ var FeedEvent = (function() { /** @type {Integer} */ this.actionType = null - /** @type {String} */ - this.User = event.User - /** @type {String} */ this.Type = event.Type diff --git a/service/stream/static/lib/event/system.js b/service/stream/static/lib/event/system.js index 2afedb6..24cc52f 100644 --- a/service/stream/static/lib/event/system.js +++ b/service/stream/static/lib/event/system.js @@ -1,9 +1,9 @@ var SystemEvent = (function() { - function SystemEvent(event) { + function SystemEvent(chid, event) { /** @type {String} */ - this.id = null; + this.chid = chid; /** @type {Integer} */ this.ts = event.Timestamp; @@ -14,9 +14,6 @@ var SystemEvent = (function() { /** @type {Integer} */ this.actionType = null - /** @type {String} */ - this.User = event.User - /** @type {String} */ this.Type = event.Type diff --git a/service/stream/static/lib/feed.js b/service/stream/static/lib/feed.js index 1812018..f02bda6 100644 --- a/service/stream/static/lib/feed.js +++ b/service/stream/static/lib/feed.js @@ -1,13 +1,14 @@ var Feed = (function() { - const ACTION_GROUP_TYPE = 1 + const GROUP_TYPE = 1 - const ACTION_RELOAD = 1 - const ACTION_RESET = 2 - const ACTION_DATA_INIT = 3 - const ACTION_DATA_MORE = 4 - const ACTION_HIDE = 5 - const ACTION_SHOW = 6 + const RELOAD = 1 + const RESET = 2 + const ENTRY = 3 + const ENTRY_INIT = 4 + const ENTRY_MORE = 5 + const HIDE = 6 + const SHOW = 7 const AUTHENTICATED = 100 const AUTHENTICATION_REQUIRED = 101 @@ -32,10 +33,10 @@ var Feed = (function() { method: 'basic' }; - function Feed(options, channel) { + function Feed(id, options, channel) { /** @type {String} */ - this.id = null; + this.id = id; /** @type {Channel} */ this.channel = channel; @@ -45,7 +46,11 @@ var Feed = (function() { /** @type {Object} */ if (this.channel.options.transport == 'ws') { - this.socket = this.channel.getWebSocketConnection(); + if (this.channel._socket == undefined) { + this.socket = this.channel.getWebSocketConnection(); + } else { + this.socket = this.channel._socket; + } } else if (this.channel.options.transport == 'lp') { this.socket = this.channel.getLongPoolingConnection(); } @@ -60,43 +65,128 @@ var Feed = (function() { this.outputContainer = document.getElementById(this.options.outputContainerId); this.bindChannel(this.channel); + + /** @type {Object} */ + this._handlers = {}; } Feed.prototype.on = function(type, callback) { + switch (name) { + case 'reload': + type = RELOAD + break; + case 'reset': + type = RESET + break; + case 'entry': + type = ENTRY + break; + case 'entry-init': + type = ENTRY_INIT + break; + case 'entry-more': + type = ENTRY_MORE + break; + case 'hide': + type = HIDE + break; + case 'show': + type = SHOW + break; + default: + return false; + break; + } + if (this._handlers[type] == undefined) { + this._handlers[type] = [] + } + this._handlers[type].push(callback); + return true; + } + + Feed.prototype.onData = function(feedEvent) { + switch (feedEvent.Type) { + case RELOAD: + this.onReload(feedEvent.ts) + break; + case RESET: + this.onReset(feedEvent.ts) + break; + case ENTRY: + this.onEntry(feedEvent.ts, feedEvent.Content) + break; + case ENTRY_INIT: + this.onEntryInit(feedEvent.ts, feedEvent.Content) + break; + case ENTRY_MORE: + this.onEntryMore(feedEvent.ts, feedEvent.Content) + break; + case HIDE: + this.onHide(feedEvent.ts) + break; + case SHOW: + this.onShow(feedEvent.ts) + break; + } } // Events callbacks - Feed.prototype.onReload = function() { + Feed.prototype.onReload = function(timestamp) { + for (var i in this._handlers[RELOAD]) { + this._handlers[RELOAD][i].call(this, chid, timestamp); + } } - Feed.prototype.onReset = function() { + Feed.prototype.onReset = function(timestamp) { + for (var i in this._handlers[RESET]) { + this._handlers[RESET][i].call(this, chid, timestamp); + } } - Feed.prototype.onEntryAdd = function(entry) { + Feed.prototype.onEntry = function(timestamp, data) { + entry = new Entry(data); + + this.addEntry(entry) + + for (var i in this._handlers[ENTRY]) { + this._handlers[ENTRY][i].call(this, timestamp, entry); + } } - Feed.prototype.onEntryDelete = function(entry) { + Feed.prototype.onEntryInit = function(timestamp, data) { + entries = JSON.parse(data); + + for (var i in this._handlers[ENTRY_INIT]) { + this._handlers[ENTRY_INIT][i].call(this, timestamp, entries); + } } - Feed.prototype.onEntryUpdate = function(entry) { + Feed.prototype.onEntryMore = function(timestamp, data) { + entries = JSON.parse(data); + + for (var i in this._handlers[ENTRY_MORE]) { + this._handlers[ENTRY_MORE][i].call(this, timestamp, entries); + } } - Feed.prototype.onEvent = function(event) { + Feed.prototype.onHide = function(timestamp) { + for (var i in this._handlers[HIDE]) { + this._handlers[HIDE][i].call(this, timestamp); + } } - Feed.prototype.onData = function(data) { + Feed.prototype.onShow = function(timestamp) { + for (var i in this._handlers[SHOW]) { + this._handlers[SHOW][i].call(this, timestamp); + } } // Entries management - Feed.prototype.addEntry = function(data) { - entry = new Entry(data); - + Feed.prototype.addEntry = function(entry) { this.entryList.push(entry); - this.onEntryAdd(entry); - - this.outputContainer.innerHTML = this.stylerFunction.call(this, data) + this.outputContainer.innerHTML; + this.outputContainer.innerHTML = this.stylerFunction.call(this, entry.data) + this.outputContainer.innerHTML; } Feed.prototype.deleteEntry = function(id) { @@ -116,10 +206,14 @@ var Feed = (function() { // Handlers Feed.prototype.bindChannel = function(channel) { - channel.on('message', function(chid, ts, data) { - // should detect type of message - // if feed addressed then check id - // trigger action if needed + var self = this; + channel.on('message', function(chid, ts, systemEvent) { + if (systemEvent.Type == GROUP_TYPE) { + feedEvent = new FeedEvent(systemEvent.Content); + if (feedEvent.id == self.id || feedEvent.id == '*') { + self.onData(feedEvent); + } + } }); } diff --git a/service/stream/static/ws.html b/service/stream/static/ws.html index 350c352..25b772a 100644 --- a/service/stream/static/ws.html +++ b/service/stream/static/ws.html @@ -12,50 +12,42 @@ } }); - feed1 = elasticfeed.initFeed('0000000002', { - outputContainerId: 'my-elastic-feed-left', + feed1 = elasticfeed.initFeed('1', { + outputContainerId: 'my-elastic-feed-1', stylerFunction: function(data) { - return '
' + data + '
'; + return '
' + data + '
'; } }); - feed2 = elasticfeed.initFeed('0000000003', { - outputContainerId: 'my-elastic-feed-right', + feed2 = elasticfeed.initFeed('2', { + outputContainerId: 'my-elastic-feed-2', stylerFunction: function(data) { - return '
' + data + '
'; + return '
' + data + '
'; } }); - feed1.channel.on('join', function(chid, ts) { - feed1.addEntry(chid + " joined the chat room"); - }); - - feed1.channel.on('leave', function(chid, ts) { - feed1.addEntry(chid + " left the chat room"); - }); - - feed1.channel.on('message', function(chid, ts, data) { - feed1.addEntry(chid + " " + JSON.stringify(data)); - }); - - feed2.channel.on('join', function(chid, ts) { - feed2.addEntry(chid + " joined the chat room"); - }); - - feed2.channel.on('leave', function(chid, ts) { - feed2.addEntry(chid + " left the chat room"); + feed3 = elasticfeed.initFeed('3', { + outputContainerId: 'my-elastic-feed-3', + stylerFunction: function(data) { + return '
' + data + '
'; + } }); - feed2.channel.on('message', function(chid, ts, data) { - feed2.addEntry(chid + " " + JSON.stringify(data)); + feed4 = elasticfeed.initFeed('4', { + outputContainerId: 'my-elastic-feed-4', + stylerFunction: function(data) { + return '
' + data + '
'; + } }); - window['socket'] = feed1.socket + window['socket'] = feed1.socket; } -
-
+
+
+
+
From 597c41c4af68688584fd5a30946a7a8f694f8c0e Mon Sep 17 00:00:00 2001 From: Chris Stasiak Date: Fri, 30 Jan 2015 00:47:31 +0100 Subject: [PATCH 05/20] Lowered object keys --- docs/examples/javascript.md | 40 ++++++++++++---------- service/stream/model/event.go | 2 +- service/stream/static/elasticfeed.js | 6 ++-- service/stream/static/lib/channel.js | 8 ++--- service/stream/static/lib/event/channel.js | 18 +++++----- service/stream/static/lib/event/entry.js | 19 +++++----- service/stream/static/lib/event/feed.js | 16 ++++----- service/stream/static/lib/event/system.js | 14 ++++---- service/stream/static/lib/feed.js | 14 ++++---- service/stream/static/lp.html | 15 +------- service/stream/static/ws.html | 1 - 11 files changed, 69 insertions(+), 84 deletions(-) diff --git a/docs/examples/javascript.md b/docs/examples/javascript.md index 8f3f96f..9055496 100644 --- a/docs/examples/javascript.md +++ b/docs/examples/javascript.md @@ -2,29 +2,31 @@ #### Usage ``` - elasticfeed.init({ - channel: { - url: 'ws://localhost:80', - transport: 'ws' - } - }); + window.onload = function() { + elasticfeed.init({ + channel: { + url: 'ws://localhost:80', + transport: 'ws' + } + }); - feed = elasticfeed.initFeed('000001', { - outputContainerId: 'my-elastic-feed-1', - stylerFunction: function(data) { - return '
' + data + '
'; - } - }); + feed = elasticfeed.initFeed('000001', { + outputContainerId: 'my-elastic-feed-1', + stylerFunction: function(data) { + return '
' + data + '
'; + } + }); - feed.channel.on('join', function(chid, ts) { - feed1.addEntry(chid + " joined the chat room"); - }); + feed.channel.on('join', function(chid, ts) { + feed1.addEntry(chid + " joined the chat room"); + }); - feed.channel.on('leave', function(chid, ts) { - feed1.addEntry(chid + " left the chat room"); - }); + feed.channel.on('leave', function(chid, ts) { + feed1.addEntry(chid + " left the chat room"); + }); - window['socket'] = feed1.socket; + window['socket'] = feed1.socket; + } ``` #### Test data broadcast diff --git a/service/stream/model/event.go b/service/stream/model/event.go index eb8049b..afd544c 100644 --- a/service/stream/model/event.go +++ b/service/stream/model/event.go @@ -19,7 +19,7 @@ type Event struct { Content string } -const archiveSize = 100 +const archiveSize = 1 var Archive = list.New() diff --git a/service/stream/static/elasticfeed.js b/service/stream/static/elasticfeed.js index f207293..d721349 100644 --- a/service/stream/static/elasticfeed.js +++ b/service/stream/static/elasticfeed.js @@ -43,10 +43,10 @@ includeJs('lib/event/entry.js'); }, initFeed: function(id, options) { - feed_options = _extend(this.options, options || {}); - channel = this.getChannel(feed_options.channel); + opts = _extend(this.options, options || {}); + channel = this.getChannel(opts.channel); - return new Feed(id, feed_options, channel); + return new Feed(id, opts, channel); }, /** diff --git a/service/stream/static/lib/channel.js b/service/stream/static/lib/channel.js index 1a688fd..b1922c3 100644 --- a/service/stream/static/lib/channel.js +++ b/service/stream/static/lib/channel.js @@ -70,15 +70,15 @@ var Channel = (function() { * @param {ChannelEvent} channelEvent */ Channel.prototype.onData = function(channelEvent) { - switch (channelEvent.Type) { + switch (channelEvent.type) { case JOIN: - this.onJoin(channelEvent.User, channelEvent.ts) + this.onJoin(channelEvent.user, channelEvent.ts) break; case LEAVE: - this.onLeave(channelEvent.User, channelEvent.ts) + this.onLeave(channelEvent.user, channelEvent.ts) break; case MESSAGE: - this.onMessage(channelEvent.User, channelEvent.ts, channelEvent.Content) + this.onMessage(channelEvent.user, channelEvent.ts, channelEvent.content) break; } } diff --git a/service/stream/static/lib/event/channel.js b/service/stream/static/lib/event/channel.js index dfbf253..d65e150 100644 --- a/service/stream/static/lib/event/channel.js +++ b/service/stream/static/lib/event/channel.js @@ -15,20 +15,20 @@ var ChannelEvent = (function() { this.actionType = null /** @type {String} */ - this.User = event.User + this.user = event.User /** @type {String} */ - this.Type = event.Type + this.type = event.Type /** @type {String} */ - this.ContentType = 'string' + this.contentType = 'string' /** @type {String} */ try { - this.Content = JSON.parse(event.Content) - this.ContentType = 'json' + this.content = JSON.parse(event.Content) + this.contentType = 'json' } catch (e) { - this.Content = event.Content + this.content = event.Content } } @@ -37,10 +37,10 @@ var ChannelEvent = (function() { } ChannelEvent.prototype.PrintContent = function() { - if (this.ContentType == 'string') { - return this.Content + if (this.contentType == 'string') { + return this.content } - return JSON.stringify(this.Content) + return JSON.stringify(this.content) } return ChannelEvent; diff --git a/service/stream/static/lib/event/entry.js b/service/stream/static/lib/event/entry.js index fef5b97..65a7b88 100644 --- a/service/stream/static/lib/event/entry.js +++ b/service/stream/static/lib/event/entry.js @@ -15,20 +15,17 @@ var EntryEvent = (function() { this.actionType = null /** @type {String} */ - this.User = event.User + this.type = event.Type /** @type {String} */ - this.Type = event.Type - - /** @type {String} */ - this.ContentType = 'string' + this.contentType = 'string' /** @type {String} */ try { - this.Content = JSON.parse(event.Content) - this.ContentType = 'json' + this.content = JSON.parse(event.Content) + this.contentType = 'json' } catch (e) { - this.Content = event.Content + this.content = event.Content } } @@ -37,10 +34,10 @@ var EntryEvent = (function() { } EntryEvent.prototype.PrintContent = function() { - if (this.ContentType == 'string') { - return this.Content + if (this.contentType == 'string') { + return this.content } - return JSON.stringify(this.Content) + return JSON.stringify(this.content) } return EntryEvent; diff --git a/service/stream/static/lib/event/feed.js b/service/stream/static/lib/event/feed.js index d869f6f..3e3a79a 100644 --- a/service/stream/static/lib/event/feed.js +++ b/service/stream/static/lib/event/feed.js @@ -15,17 +15,17 @@ var FeedEvent = (function() { this.actionType = null /** @type {String} */ - this.Type = event.Type + this.type = event.Type /** @type {String} */ - this.ContentType = 'string' + this.contentType = 'string' /** @type {String} */ try { - this.Content = JSON.parse(event.Content) - this.ContentType = 'json' + this.content = JSON.parse(event.Content) + this.contentType = 'json' } catch (e) { - this.Content = event.Content + this.content = event.Content } } @@ -34,10 +34,10 @@ var FeedEvent = (function() { } FeedEvent.prototype.PrintContent = function() { - if (this.ContentType == 'string') { - return this.Content + if (this.contentType == 'string') { + return this.content } - return JSON.stringify(this.Content) + return JSON.stringify(this.content) } return FeedEvent; diff --git a/service/stream/static/lib/event/system.js b/service/stream/static/lib/event/system.js index 24cc52f..9fe01ff 100644 --- a/service/stream/static/lib/event/system.js +++ b/service/stream/static/lib/event/system.js @@ -15,17 +15,17 @@ var SystemEvent = (function() { this.actionType = null /** @type {String} */ - this.Type = event.Type + this.type = event.Type /** @type {String} */ - this.ContentType = 'string' + this.contentType = 'string' /** @type {String} */ try { - this.Content = JSON.parse(event.Content) - this.ContentType = 'json' + this.content = JSON.parse(event.Content) + this.contentType = 'json' } catch (e) { - this.Content = event.Content + this.content = event.Content } } @@ -34,8 +34,8 @@ var SystemEvent = (function() { } SystemEvent.prototype.PrintContent = function() { - if (this.ContentType == 'string') { - return this.Content + if (this.contentType == 'string') { + return this.content } return JSON.stringify(this.Content) } diff --git a/service/stream/static/lib/feed.js b/service/stream/static/lib/feed.js index f02bda6..223c042 100644 --- a/service/stream/static/lib/feed.js +++ b/service/stream/static/lib/feed.js @@ -105,7 +105,7 @@ var Feed = (function() { } Feed.prototype.onData = function(feedEvent) { - switch (feedEvent.Type) { + switch (feedEvent.type) { case RELOAD: this.onReload(feedEvent.ts) break; @@ -113,13 +113,13 @@ var Feed = (function() { this.onReset(feedEvent.ts) break; case ENTRY: - this.onEntry(feedEvent.ts, feedEvent.Content) + this.onEntry(feedEvent.ts, feedEvent.content) break; case ENTRY_INIT: - this.onEntryInit(feedEvent.ts, feedEvent.Content) + this.onEntryInit(feedEvent.ts, feedEvent.content) break; case ENTRY_MORE: - this.onEntryMore(feedEvent.ts, feedEvent.Content) + this.onEntryMore(feedEvent.ts, feedEvent.content) break; case HIDE: this.onHide(feedEvent.ts) @@ -208,8 +208,8 @@ var Feed = (function() { Feed.prototype.bindChannel = function(channel) { var self = this; channel.on('message', function(chid, ts, systemEvent) { - if (systemEvent.Type == GROUP_TYPE) { - feedEvent = new FeedEvent(systemEvent.Content); + if (systemEvent.type == GROUP_TYPE) { + feedEvent = new FeedEvent(systemEvent.content); if (feedEvent.id == self.id || feedEvent.id == '*') { self.onData(feedEvent); } @@ -220,7 +220,7 @@ var Feed = (function() { // Stylers Feed.prototype._stylerFunction = function(data) { - return JSON.stringify(data.Data); + return JSON.stringify(data); } // Helpers diff --git a/service/stream/static/lp.html b/service/stream/static/lp.html index ff79042..85eca45 100644 --- a/service/stream/static/lp.html +++ b/service/stream/static/lp.html @@ -12,7 +12,7 @@ } }); - feed = elasticfeed.initFeed('0000000001', { + feed = elasticfeed.initFeed('1', { channel: { url: 'http://localhost:80', transport: 'lp' @@ -23,19 +23,6 @@ } }); - feed.channel.on('join', function(chid, ts) { - feed.addEntry(chid + " joined the chat room"); - }); - - feed.channel.on('leave', function(chid, ts) { - feed.addEntry(chid + " left the chat room"); - }); - - feed.channel.on('message', function(chid, ts, data) { - feed.addEntry(chid + " " + JSON.stringify(data)); - }); - - window['socket'] = feed.socket } diff --git a/service/stream/static/ws.html b/service/stream/static/ws.html index 25b772a..0f30355 100644 --- a/service/stream/static/ws.html +++ b/service/stream/static/ws.html @@ -40,7 +40,6 @@ } }); - window['socket'] = feed1.socket; } From 7c8a5127fac5c3c519443b027ab65f263ab36f33 Mon Sep 17 00:00:00 2001 From: Chris Stasiak Date: Fri, 30 Jan 2015 01:18:38 +0100 Subject: [PATCH 06/20] Fixes; workarounds --- service/stream/controller/room/feed.go | 4 ++- service/stream/model/event.go | 12 +++++---- service/stream/static/elasticfeed.js | 35 ++++++++++++-------------- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/service/stream/controller/room/feed.go b/service/stream/controller/room/feed.go index dc1fbdd..f23f443 100644 --- a/service/stream/controller/room/feed.go +++ b/service/stream/controller/room/feed.go @@ -1,6 +1,7 @@ package room import ( + "strconv" "time" "container/list" "encoding/json" @@ -49,7 +50,8 @@ type Subscriber struct { } func NewEvent(ep model.EventType, user, msg string) model.Event { - return model.Event{ep, user, time.Now().UnixNano(), msg} + ts := time.Now().UnixNano() + return model.Event{ep, user, ts, strconv.Itoa(int(ts)), msg} } func NewChannelEvent(ep model.EventType, user, msg string) model.Event { diff --git a/service/stream/model/event.go b/service/stream/model/event.go index afd544c..b8c7dd5 100644 --- a/service/stream/model/event.go +++ b/service/stream/model/event.go @@ -13,10 +13,11 @@ const ( ) type Event struct { - Type EventType - User string - Timestamp int64 - Content string + Type EventType + User string + Ts int64 + Timestamp string + Content string } const archiveSize = 1 @@ -34,7 +35,8 @@ func GetEvents(lastReceived int) []Event { events := make([]Event, 0, Archive.Len()) for event := Archive.Front(); event != nil; event = event.Next() { e := event.Value.(Event) - if e.Timestamp > int64(lastReceived) { + if e.Ts > int64(lastReceived) { + events = append(events, e) } } diff --git a/service/stream/static/elasticfeed.js b/service/stream/static/elasticfeed.js index d721349..473c4f8 100644 --- a/service/stream/static/elasticfeed.js +++ b/service/stream/static/elasticfeed.js @@ -43,27 +43,18 @@ includeJs('lib/event/entry.js'); }, initFeed: function(id, options) { - opts = _extend(this.options, options || {}); - channel = this.getChannel(opts.channel); - - return new Feed(id, opts, channel); - }, - - /** - * Returns Feed object - * @param options - * @returns {*} - */ - getFeed: function(options) { - if (options.id == undefined) { - return null; + if (id == undefined) { + return false; } if (this.feedList[id] == undefined) { - this.feedList[id] = new Feed(options) + opts = _extend(this.options, options || {}); + channel = this.getChannel(opts.channel); + + this.feedList[id] = new Feed(id, opts, channel); } - return this.feedList[options.id]; + return this.feedList[id]; }, /** @@ -74,7 +65,7 @@ includeJs('lib/event/entry.js'); */ getChannel: function(options, credential) { if (options.url == undefined) { - return null; + return false; } if (this.channelList[options.url] == undefined) { @@ -85,11 +76,17 @@ includeJs('lib/event/entry.js'); }, findFeed: function(id) { - return this.getFeed({id: id}); + if (this.feedList[id] == undefined) { + return false; + } + return this.feedList[id]; }, findChannel: function(url) { - return this.getChannel({url: url}); + if (this.channelList[url] == undefined) { + return false; + } + return this.channelList[url]; } }; From ef60153f9e42bfcfe4e3aa29875059d5843cd34d Mon Sep 17 00:00:00 2001 From: Chris Stasiak Date: Fri, 30 Jan 2015 15:21:00 +0100 Subject: [PATCH 07/20] Added entry object; self rendering; binding to feed events --- service/stream/static/lib/entry.js | 126 +++++++++++++++++++++++------ service/stream/static/lib/feed.js | 45 ++++++++--- 2 files changed, 135 insertions(+), 36 deletions(-) diff --git a/service/stream/static/lib/entry.js b/service/stream/static/lib/entry.js index 62f37b6..a4167a0 100644 --- a/service/stream/static/lib/entry.js +++ b/service/stream/static/lib/entry.js @@ -1,24 +1,86 @@ var Entry = (function() { - const ACTION_GROUP_TYPE = 2 + const GROUP_TYPE = 2 - const ACTION_ADD = 1 - const ACTION_DELETE = 2 - const ACTION_UPDATE = 3 - const ACTION_HIDE = 4 - const ACTION_SHOW = 5 - - const PUBLISH_METRIC = 6 + const ADD = 1 + const DELETE = 2 + const UPDATE = 3 + const HIDE = 4 + const SHOW = 5 /** @type {Entry} */ var localCache = {} - function Entry(data) { + function Entry(feed, id, data, styler) { /** @type {String} */ - this.id = null; + this.id = id; /** @type {String} */ this.data = data; + + /** @type {Object} */ + this._feed = feed; + + /** @type {Function} */ + this._styler = styler; + + this.bindFeedMessages(); + } + + // UI + + Entry.prototype.render = function() { + document.getElementById(this.id).innerHTML = this._styler.call(this, this.data); + } + + // Events + + Entry.prototype.on = function(type, callback) { + switch (name) { + case 'add': + type = ADD + break; + case 'delete': + type = DELETE + break; + case 'update': + type = UPDATE + break; + case 'hide': + type = HIDE + break; + case 'show': + type = SHOW + break; + default: + return false; + break; + } + if (this._handlers[type] == undefined) { + this._handlers[type] = [] + } + this._handlers[type].push(callback); + return true; + } + + Entry.prototype.onData = function(entryEvent) { + switch (entryEvent.type) { + case ADD: + this.onAdd(entryEvent.ts, entryEvent.content) + break; + case DELETE: + this.onDelete(entryEvent.ts) + break; + case UPDATE: + this.onUpdate(entryEvent.ts, entryEvent.content) + break; + case HIDE: + this.onHide(entryEvent.ts) + break; + case SHOW: + this.onShow(entryEvent.ts) + break; + } } // Management @@ -26,7 +88,7 @@ var Entry = (function() { Entry.prototype.update = function() { } - Entry.prototype.remove = function() { + Entry.prototype.delete = function() { } Entry.prototype.hide = function() { @@ -37,37 +99,49 @@ var Entry = (function() { // Events callbacks - Entry.prototype.onBeforeUpdate = function(callback) { - + Entry.prototype.onAdd = function(timestamp, data) { + for (var i in this._handlers[ADD]) { + this._handlers[ADD][i].call(this, timestamp, data); + } } - Entry.prototype.onAfterUpdate = function(callback) { - + Entry.prototype.onUpdate = function(timestamp, data) { + for (var i in this._handlers[UPDATE]) { + this._handlers[UPDATE][i].call(this, timestamp, data); + } } - Entry.prototype.onBeforeRemove = function(callback) { - + Entry.prototype.onDelete = function(timestamp) { + for (var i in this._handlers[DELETE]) { + this._handlers[DELETE][i].call(this, timestamp); + } } - Entry.prototype.onAfterRemove = function(callback) { - + Entry.prototype.onDelete = function(timestamp) { + for (var i in this._handlers[HIDE]) { + this._handlers[HIDE][i].call(this, timestamp); + } } - Entry.prototype.onData = function(callback) { - + Entry.prototype.onDelete = function(timestamp) { + for (var i in this._handlers[SHOW]) { + this._handlers[SHOW][i].call(this, timestamp); + } } // Handlers - Entry.prototype.registerHandlers = function() { - // bind to feed events + Entry.prototype.bindFeedMessages = function() { + var self = this; + this._feed.on('entry', function(ts, entryEvent) { + if (entryEvent.id == self.id || entryEvent.id == '*') { + self.onData(entryEvent); + } + }); } // Helpers - Entry.prototype.getParent = function() { - } - Entry.prototype.getTimestamp = function() { return this.ts; } diff --git a/service/stream/static/lib/feed.js b/service/stream/static/lib/feed.js index 223c042..570aa50 100644 --- a/service/stream/static/lib/feed.js +++ b/service/stream/static/lib/feed.js @@ -4,11 +4,12 @@ var Feed = (function() { const RELOAD = 1 const RESET = 2 - const ENTRY = 3 + const ENTRY_NEW = 3 const ENTRY_INIT = 4 const ENTRY_MORE = 5 const HIDE = 6 const SHOW = 7 + const ENTRY = 8 const AUTHENTICATED = 100 const AUTHENTICATION_REQUIRED = 101 @@ -79,7 +80,7 @@ var Feed = (function() { type = RESET break; case 'entry': - type = ENTRY + type = ENTRY_NEW break; case 'entry-init': type = ENTRY_INIT @@ -93,6 +94,9 @@ var Feed = (function() { case 'show': type = SHOW break; + case 'entry': + type = ENTRY + break; default: return false; break; @@ -112,8 +116,8 @@ var Feed = (function() { case RESET: this.onReset(feedEvent.ts) break; - case ENTRY: - this.onEntry(feedEvent.ts, feedEvent.content) + case ENTRY_NEW: + this.onEntryNew(feedEvent.ts, feedEvent.content) break; case ENTRY_INIT: this.onEntryInit(feedEvent.ts, feedEvent.content) @@ -127,6 +131,9 @@ var Feed = (function() { case SHOW: this.onShow(feedEvent.ts) break; + case ENTRY: + this.onEntry(feedEvent.ts, feedEvent.content) + break; } } @@ -144,13 +151,13 @@ var Feed = (function() { } } - Feed.prototype.onEntry = function(timestamp, data) { - entry = new Entry(data); + Feed.prototype.onEntryNew = function(timestamp, data) { + entry = new Entry(this, _uniqueId(), data, this.stylerFunction); this.addEntry(entry) - for (var i in this._handlers[ENTRY]) { - this._handlers[ENTRY][i].call(this, timestamp, entry); + for (var i in this._handlers[ENTRY_NEW]) { + this._handlers[ENTRY_NEW][i].call(this, timestamp, entry); } } @@ -182,11 +189,22 @@ var Feed = (function() { } } + Feed.prototype.onEntry = function(timestamp, content) { + entryEvent = new EntryEvent(content); + + for (var i in this._handlers[ENTRY]) { + this._handlers[ENTRY][i].call(this, timestamp, entryEvent); + } + } + // Entries management Feed.prototype.addEntry = function(entry) { this.entryList.push(entry); - this.outputContainer.innerHTML = this.stylerFunction.call(this, entry.data) + this.outputContainer.innerHTML; + + this.outputContainer.innerHTML = '
' + this.outputContainer.innerHTML; + + this.render(); } Feed.prototype.deleteEntry = function(id) { @@ -200,7 +218,10 @@ var Feed = (function() { // UI - Feed.prototype.render = function() { + Feed.prototype.render = function(id) { + for (var i in this.entryList) { + this.entryList[i].render(); + } } // Handlers @@ -225,6 +246,10 @@ var Feed = (function() { // Helpers + var _uniqueId = function() { + return '_' + Math.random().toString(36).substr(2, 36); + } + var _extend = function(a, b) { var c = {}, prop; for (prop in a) { From bd6fc833f6266cff978617e9acb3d40751d02257 Mon Sep 17 00:00:00 2001 From: Chris Stasiak Date: Fri, 30 Jan 2015 16:01:49 +0100 Subject: [PATCH 08/20] general improvements --- service/stream/static/lib/entry.js | 14 +++++++++++++- service/stream/static/lib/feed.js | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/service/stream/static/lib/entry.js b/service/stream/static/lib/entry.js index a4167a0..f86d024 100644 --- a/service/stream/static/lib/entry.js +++ b/service/stream/static/lib/entry.js @@ -85,10 +85,14 @@ var Entry = (function() { // Management - Entry.prototype.update = function() { + Entry.prototype.update = function(data) { + this.data = data; + this.render(); } Entry.prototype.delete = function() { + this.hide(); + this._feed.deleteEntry(this); } Entry.prototype.hide = function() { @@ -97,6 +101,14 @@ var Entry = (function() { Entry.prototype.show = function() { } + // API + + Entry.prototype.apiEntryUpdate = function(data) { + } + + Entry.prototype.apiMetricSave = function(data) { + } + // Events callbacks Entry.prototype.onAdd = function(timestamp, data) { diff --git a/service/stream/static/lib/feed.js b/service/stream/static/lib/feed.js index 570aa50..d55bd27 100644 --- a/service/stream/static/lib/feed.js +++ b/service/stream/static/lib/feed.js @@ -204,7 +204,7 @@ var Feed = (function() { this.outputContainer.innerHTML = '
' + this.outputContainer.innerHTML; - this.render(); + entry.render(); } Feed.prototype.deleteEntry = function(id) { From 30c072f9ee439dc29cdb6bec37d6ecbab80be442 Mon Sep 17 00:00:00 2001 From: Chris Stasiak Date: Fri, 30 Jan 2015 16:28:50 +0100 Subject: [PATCH 09/20] Made entry type independent for feed type --- service/stream/static/lib/entry.js | 29 +++++++++++++++++++++++------ service/stream/static/lib/feed.js | 9 +++------ 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/service/stream/static/lib/entry.js b/service/stream/static/lib/entry.js index f86d024..2627a31 100644 --- a/service/stream/static/lib/entry.js +++ b/service/stream/static/lib/entry.js @@ -11,26 +11,38 @@ var Entry = (function() { /** @type {Entry} */ var localCache = {} - function Entry(feed, id, data, styler) { + function Entry(data, options) { /** @type {String} */ - this.id = id; + this.id = null; + + /** @type {String} */ + this.viewId = _uniqueId(); /** @type {String} */ this.data = data; /** @type {Object} */ - this._feed = feed; + this._feed = null; /** @type {Function} */ - this._styler = styler; + this._styler = (options ? options.styler : undefined) || function() { + return data; + }; + } + Entry.prototype.setParent = function(feed) { + this._feed = feed; this.bindFeedMessages(); } + Entry.prototype.getViewId = function() { + return this.viewId; + } + // UI Entry.prototype.render = function() { - document.getElementById(this.id).innerHTML = this._styler.call(this, this.data); + document.getElementById(this.viewId).innerHTML = this._styler.call(this, this.data); } // Events @@ -152,12 +164,17 @@ var Entry = (function() { }); } - // Helpers Entry.prototype.getTimestamp = function() { return this.ts; } + // Helpers + + var _uniqueId = function() { + return '_' + Math.random().toString(36).substr(2, 36); + } + return Entry; })(); diff --git a/service/stream/static/lib/feed.js b/service/stream/static/lib/feed.js index d55bd27..f0ebb0e 100644 --- a/service/stream/static/lib/feed.js +++ b/service/stream/static/lib/feed.js @@ -152,7 +152,7 @@ var Feed = (function() { } Feed.prototype.onEntryNew = function(timestamp, data) { - entry = new Entry(this, _uniqueId(), data, this.stylerFunction); + entry = new Entry(data, {styler: this.stylerFunction}); this.addEntry(entry) @@ -200,9 +200,10 @@ var Feed = (function() { // Entries management Feed.prototype.addEntry = function(entry) { + entry.setParent(this); this.entryList.push(entry); - this.outputContainer.innerHTML = '
' + this.outputContainer.innerHTML; + this.outputContainer.innerHTML = '
' + this.outputContainer.innerHTML; entry.render(); } @@ -246,10 +247,6 @@ var Feed = (function() { // Helpers - var _uniqueId = function() { - return '_' + Math.random().toString(36).substr(2, 36); - } - var _extend = function(a, b) { var c = {}, prop; for (prop in a) { From 76103b8a90d2c26cffd07a0e20f1f8300099182f Mon Sep 17 00:00:00 2001 From: Chris Stasiak Date: Fri, 30 Jan 2015 16:50:58 +0100 Subject: [PATCH 10/20] Added feed.empty() --- service/stream/static/lib/entry.js | 3 +-- service/stream/static/lib/feed.js | 13 +++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/service/stream/static/lib/entry.js b/service/stream/static/lib/entry.js index 2627a31..5d644f0 100644 --- a/service/stream/static/lib/entry.js +++ b/service/stream/static/lib/entry.js @@ -103,8 +103,7 @@ var Entry = (function() { } Entry.prototype.delete = function() { - this.hide(); - this._feed.deleteEntry(this); + document.getElementById(this.viewId).remove(); } Entry.prototype.hide = function() { diff --git a/service/stream/static/lib/feed.js b/service/stream/static/lib/feed.js index f0ebb0e..79452cb 100644 --- a/service/stream/static/lib/feed.js +++ b/service/stream/static/lib/feed.js @@ -208,10 +208,19 @@ var Feed = (function() { entry.render(); } - Feed.prototype.deleteEntry = function(id) { + Feed.prototype.deleteEntry = function(entry) { + entry.delete(); } - Feed.prototype.updateEntry = function(id, data) { + Feed.prototype.updateEntry = function(entry, data) { + } + + Feed.prototype.empty = function() { + for (var i in this.entryList) { + this.deleteEntry(this.entryList[i]); + delete this.entryList[i]; + } + this.entryList = [] } Feed.prototype.findEntry = function(id) { From 0adf4d825babb6d2cf7a6de6cfbd06bab4c36d49 Mon Sep 17 00:00:00 2001 From: Chris Stasiak Date: Sat, 31 Jan 2015 02:18:47 +0100 Subject: [PATCH 11/20] Simplified to single event instance --- service/stream/static/elasticfeed.js | 5 +-- service/stream/static/lib/channel.js | 23 +++++----- .../static/lib/{event/channel.js => event.js} | 12 ++--- service/stream/static/lib/event/entry.js | 45 ------------------- service/stream/static/lib/event/feed.js | 45 ------------------- service/stream/static/lib/event/system.js | 45 ------------------- service/stream/static/lib/feed.js | 4 +- 7 files changed, 21 insertions(+), 158 deletions(-) rename service/stream/static/lib/{event/channel.js => event.js} (76%) delete mode 100644 service/stream/static/lib/event/entry.js delete mode 100644 service/stream/static/lib/event/feed.js delete mode 100644 service/stream/static/lib/event/system.js diff --git a/service/stream/static/elasticfeed.js b/service/stream/static/elasticfeed.js index 473c4f8..4f155a8 100644 --- a/service/stream/static/elasticfeed.js +++ b/service/stream/static/elasticfeed.js @@ -10,10 +10,7 @@ function includeJs(jsFilePath) { includeJs('lib/feed.js'); includeJs('lib/entry.js'); includeJs('lib/channel.js'); -includeJs('lib/event/channel.js'); -includeJs('lib/event/system.js'); -includeJs('lib/event/feed.js'); -includeJs('lib/event/entry.js'); +includeJs('lib/event.js'); (function(window) { diff --git a/service/stream/static/lib/channel.js b/service/stream/static/lib/channel.js index b1922c3..24d1ba6 100644 --- a/service/stream/static/lib/channel.js +++ b/service/stream/static/lib/channel.js @@ -39,7 +39,7 @@ var Channel = (function() { // Handlers /** - * @param {ChannelEvent} event + * @param {Event} event * @param {Function} callback */ Channel.prototype.on = function(name, callback) { @@ -67,18 +67,18 @@ var Channel = (function() { // Events /** - * @param {ChannelEvent} channelEvent + * @param {Event} event */ - Channel.prototype.onData = function(channelEvent) { - switch (channelEvent.type) { + Channel.prototype.onData = function(event) { + switch (event.type) { case JOIN: - this.onJoin(channelEvent.user, channelEvent.ts) + this.onJoin(event.user, event.ts) break; case LEAVE: - this.onLeave(channelEvent.user, channelEvent.ts) + this.onLeave(event.user, event.ts) break; case MESSAGE: - this.onMessage(channelEvent.user, channelEvent.ts, channelEvent.content) + this.onMessage(event.user, event.ts, event.content) break; } } @@ -96,7 +96,7 @@ var Channel = (function() { } Channel.prototype.onMessage = function(chid, timestamp, data) { - systemEvent = new SystemEvent(chid, data); + systemEvent = new Event(data); for (var i in this._handlers[MESSAGE]) { this._handlers[MESSAGE][i].call(this, chid, timestamp, systemEvent); @@ -117,7 +117,7 @@ var Channel = (function() { self = this this._socket.onmessage = function(event) { - event = new ChannelEvent(JSON.parse(event.data)) + event = new Event(JSON.parse(event.data)) self.onData(event) }; @@ -133,7 +133,8 @@ var Channel = (function() { var lastReceived = 0; var isWait = false; - this.getJSON('http://localhost:10100/stream/lp/join?chid=' + this.id, function() { + this.getJSON('http://localhost:10100/stream/lp/join?chid=' + this.id, function(data) { + // should set timestamp to proper one! }) self = this; @@ -153,7 +154,7 @@ var Channel = (function() { } self.each(data, function(i, event) { - event = new ChannelEvent(event) + event = new Event(event) self.onData(event) lastReceived = event.GetTimestamp(); diff --git a/service/stream/static/lib/event/channel.js b/service/stream/static/lib/event.js similarity index 76% rename from service/stream/static/lib/event/channel.js rename to service/stream/static/lib/event.js index d65e150..5706608 100644 --- a/service/stream/static/lib/event/channel.js +++ b/service/stream/static/lib/event.js @@ -1,9 +1,9 @@ -var ChannelEvent = (function() { +var Event = (function() { - function ChannelEvent(event) { + function Event(event) { /** @type {String} */ - this.id = null; + this.id = event.Id || null; /** @type {Integer} */ this.ts = event.Timestamp; @@ -32,17 +32,17 @@ var ChannelEvent = (function() { } } - ChannelEvent.prototype.GetTimestamp = function() { + Event.prototype.GetTimestamp = function() { return this.ts; } - ChannelEvent.prototype.PrintContent = function() { + Event.prototype.PrintContent = function() { if (this.contentType == 'string') { return this.content } return JSON.stringify(this.content) } - return ChannelEvent; + return Event; })(); diff --git a/service/stream/static/lib/event/entry.js b/service/stream/static/lib/event/entry.js deleted file mode 100644 index 65a7b88..0000000 --- a/service/stream/static/lib/event/entry.js +++ /dev/null @@ -1,45 +0,0 @@ -var EntryEvent = (function() { - - function EntryEvent(event) { - - /** @type {String} */ - this.id = null; - - /** @type {Integer} */ - this.ts = event.Timestamp; - - /** @type {Integer} */ - this.actionGroup = null - - /** @type {Integer} */ - this.actionType = null - - /** @type {String} */ - this.type = event.Type - - /** @type {String} */ - this.contentType = 'string' - - /** @type {String} */ - try { - this.content = JSON.parse(event.Content) - this.contentType = 'json' - } catch (e) { - this.content = event.Content - } - } - - EntryEvent.prototype.GetTimestamp = function() { - return this.ts; - } - - EntryEvent.prototype.PrintContent = function() { - if (this.contentType == 'string') { - return this.content - } - return JSON.stringify(this.content) - } - - return EntryEvent; - -})(); diff --git a/service/stream/static/lib/event/feed.js b/service/stream/static/lib/event/feed.js deleted file mode 100644 index 3e3a79a..0000000 --- a/service/stream/static/lib/event/feed.js +++ /dev/null @@ -1,45 +0,0 @@ -var FeedEvent = (function() { - - function FeedEvent(event) { - - /** @type {String} */ - this.id = event.Id; - - /** @type {Integer} */ - this.ts = event.Timestamp; - - /** @type {Integer} */ - this.actionGroup = null - - /** @type {Integer} */ - this.actionType = null - - /** @type {String} */ - this.type = event.Type - - /** @type {String} */ - this.contentType = 'string' - - /** @type {String} */ - try { - this.content = JSON.parse(event.Content) - this.contentType = 'json' - } catch (e) { - this.content = event.Content - } - } - - FeedEvent.prototype.GetTimestamp = function() { - return this.ts; - } - - FeedEvent.prototype.PrintContent = function() { - if (this.contentType == 'string') { - return this.content - } - return JSON.stringify(this.content) - } - - return FeedEvent; - -})(); diff --git a/service/stream/static/lib/event/system.js b/service/stream/static/lib/event/system.js deleted file mode 100644 index 9fe01ff..0000000 --- a/service/stream/static/lib/event/system.js +++ /dev/null @@ -1,45 +0,0 @@ -var SystemEvent = (function() { - - function SystemEvent(chid, event) { - - /** @type {String} */ - this.chid = chid; - - /** @type {Integer} */ - this.ts = event.Timestamp; - - /** @type {Integer} */ - this.actionGroup = null - - /** @type {Integer} */ - this.actionType = null - - /** @type {String} */ - this.type = event.Type - - /** @type {String} */ - this.contentType = 'string' - - /** @type {String} */ - try { - this.content = JSON.parse(event.Content) - this.contentType = 'json' - } catch (e) { - this.content = event.Content - } - } - - SystemEvent.prototype.GetTimestamp = function() { - return this.ts; - } - - SystemEvent.prototype.PrintContent = function() { - if (this.contentType == 'string') { - return this.content - } - return JSON.stringify(this.Content) - } - - return SystemEvent; - -})(); diff --git a/service/stream/static/lib/feed.js b/service/stream/static/lib/feed.js index 79452cb..36cd9a8 100644 --- a/service/stream/static/lib/feed.js +++ b/service/stream/static/lib/feed.js @@ -190,7 +190,7 @@ var Feed = (function() { } Feed.prototype.onEntry = function(timestamp, content) { - entryEvent = new EntryEvent(content); + entryEvent = new Event(content); for (var i in this._handlers[ENTRY]) { this._handlers[ENTRY][i].call(this, timestamp, entryEvent); @@ -240,7 +240,7 @@ var Feed = (function() { var self = this; channel.on('message', function(chid, ts, systemEvent) { if (systemEvent.type == GROUP_TYPE) { - feedEvent = new FeedEvent(systemEvent.content); + feedEvent = new Event(systemEvent.content); if (feedEvent.id == self.id || feedEvent.id == '*') { self.onData(feedEvent); } From c43c3d01a58cf7c7cac09211ffc48e1926a45047 Mon Sep 17 00:00:00 2001 From: Chris Stasiak Date: Sun, 1 Feb 2015 19:11:50 +0100 Subject: [PATCH 12/20] new entry event notification to feed --- resource/entry.go | 72 +++++--------------------- resource/feed.go | 9 ++-- service/stream/controller/room/feed.go | 10 +++- service/stream/static/lib/entry.js | 5 +- service/stream/static/lib/feed.js | 13 ++++- service/stream/static/ws.html | 4 +- 6 files changed, 42 insertions(+), 71 deletions(-) diff --git a/resource/entry.go b/resource/entry.go index 9a77700..9c3989e 100644 --- a/resource/entry.go +++ b/resource/entry.go @@ -8,59 +8,12 @@ import ( "github.com/feedlabs/feedify/graph" "github.com/feedlabs/elasticfeed/service/stream/controller/room" - "github.com/feedlabs/elasticfeed/service/stream/model" ) -// user_feed_token = channel_id + feed_id => e.g aabbccddee + aabbcc -// for private feeds there will be 1 websocket connection -// for public company feeds will be 1 websocket connection -// basically for each channel is 1 websocket connection -// private and public channel will stream through multiple feed-pages events -// -// channel => channel_id -// event => 'feed:' + feed_id -// data => [{ // action object -// id => string // entryId -// tags => strings... // array of strings -// action => string // add/delete/update -// data => string // entry data as content; string e.g. json.stringify -// }, {}, {}] - -const BODY_HEADER = `{ - "channel": "iO5wshd5fFE5YXxJ/hfyKQ==:17", - "event": "CM_Action_Abstract:SEND:31", - "data": { - "action": { - "actor": { - "_type": 33, - "_id": { - "id": "1" - }, - "id": 1, - "displayName": "user1", - "visible": true, - "_class": "Feed_Model_User" - }, - "verb": 13, - "type": 31, - "_class": "Feed_Action_Feed" - }, - "model": { - "_type": 33, - "_id": { - "id": "1" - }, - "id": 1, - "displayName": "user1", - "visible": true, - "_class": "Feed_Model_User" - }, - "data": {` - -const BODY_BOTTOM = ` - } - } -}` +const ( + ENTRY_UPDATE = 1 + ENTRY_DELETE = 2 +) func GetEntryList(FeedId string, ApplicationId string, OrgId string) (feedEntries []*Entry, err error) { feed, err := GetFeed(FeedId, ApplicationId, OrgId) @@ -136,14 +89,11 @@ func AddEntry(feedEntry Entry, FeedId string, ApplicationId string, OrgId string return "0", err } -// _data := BODY_HEADER + `"Id": "` + feedEntry.Id + `", "Action": "add", "Tag": {}, "Data": ` + strconv.Quote(feedEntry.Data) + BODY_BOTTOM -// message.Publish(_data) - feedEntry.Id = strconv.Itoa(entry.Id) // notify - data, _ := json.Marshal(entry) - room.Publish <- room.NewEntryEvent(model.EVENT_MESSAGE, "system", string(data)) + d, _ := json.Marshal(feedEntry) + room.Publish <- room.NewFeedEvent(ENTRY_NEW, feed.Id, string(d)) return feedEntry.Id, nil } @@ -155,8 +105,9 @@ func UpdateEntry(id string, FeedId string, ApplicationId string, OrgId string, d return err } - _data := BODY_HEADER + `"Id": "` + entry.Id + `", "Action": "update", "Tag": {}, "Data": ` + strconv.Quote(data) + BODY_BOTTOM - message.Publish(_data) + // notify + d, _ := json.Marshal(entry) + room.Publish <- room.NewFeedEvent(ENTRY_UPDATE, entry.Id, string(d)) _id, _ := strconv.Atoi(entry.Id) return storage.SetPropertyNode(_id, "data", data) @@ -176,8 +127,9 @@ func DeleteEntry(id string, FeedId string, ApplicationId string, OrgId string) ( storage.DeleteRelation(rel.Id) } - _data := BODY_HEADER + `"Id": "` + entry.Id + `", "Action": "remove"` + BODY_BOTTOM - message.Publish(_data) + // notify + d, _ := json.Marshal(entry) + room.Publish <- room.NewFeedEvent(ENTRY_DELETE, entry.Id, string(d)) return storage.DeleteNode(_id) } diff --git a/resource/feed.go b/resource/feed.go index c8a735a..1f8da76 100644 --- a/resource/feed.go +++ b/resource/feed.go @@ -8,7 +8,10 @@ import ( "github.com/feedlabs/feedify/graph" "github.com/feedlabs/elasticfeed/service/stream/controller/room" - "github.com/feedlabs/elasticfeed/service/stream/model" +) + +const ( + ENTRY_NEW = 3 ) func (this *Feed) AddEntry(entry Entry) (EntryId string, err error) { @@ -93,10 +96,6 @@ func AddFeed(feed Feed, applicationId string, orgId string) (id string, err erro feed.Id = strconv.Itoa(_feed.Id) - // notify - data, _ := json.Marshal(feed) - room.Publish <- room.NewFeedEvent(model.EVENT_MESSAGE, "system", string(data)) - return feed.Id, nil } diff --git a/service/stream/controller/room/feed.go b/service/stream/controller/room/feed.go index f23f443..1c34373 100644 --- a/service/stream/controller/room/feed.go +++ b/service/stream/controller/room/feed.go @@ -59,11 +59,17 @@ func NewChannelEvent(ep model.EventType, user, msg string) model.Event { } func NewSystemEvent(ep model.EventType, user, msg string) model.Event { - return NewChannelEvent(ep, user, msg) + event := NewEvent(ep, user, msg) + data, _ := json.Marshal(event) + + return NewChannelEvent(model.EVENT_MESSAGE, user, string(data)) } func NewFeedEvent(ep model.EventType, user, msg string) model.Event { - return NewSystemEvent(ep, user, msg) + event := NewEvent(ep, user, msg) + data, _ := json.Marshal(event) + + return NewSystemEvent(1, user, string(data)) } func NewEntryEvent(ep model.EventType, user, msg string) model.Event { diff --git a/service/stream/static/lib/entry.js b/service/stream/static/lib/entry.js index 5d644f0..5e1c388 100644 --- a/service/stream/static/lib/entry.js +++ b/service/stream/static/lib/entry.js @@ -41,8 +41,11 @@ var Entry = (function() { // UI + // TODO: + // should make animations, should be configurable by developer + // first level is style function; second level is render function Entry.prototype.render = function() { - document.getElementById(this.viewId).innerHTML = this._styler.call(this, this.data); + document.getElementById(this.viewId).innerHTML = this._styler.call(this, JSON.stringify(this.data)); } // Events diff --git a/service/stream/static/lib/feed.js b/service/stream/static/lib/feed.js index 36cd9a8..8168305 100644 --- a/service/stream/static/lib/feed.js +++ b/service/stream/static/lib/feed.js @@ -62,6 +62,9 @@ var Feed = (function() { /** @type {Function} */ this.stylerFunction = options.stylerFunction || this._stylerFunction; + /** @type {Function} */ + this.renderFunction = options.renderFunction || this._renderFunction; + /** @type {DOM} */ this.outputContainer = document.getElementById(this.options.outputContainerId); @@ -200,6 +203,10 @@ var Feed = (function() { // Entries management Feed.prototype.addEntry = function(entry) { + + // types + // add by: timestamp up/down; always to top; always to bottom + entry.setParent(this); this.entryList.push(entry); @@ -241,7 +248,7 @@ var Feed = (function() { channel.on('message', function(chid, ts, systemEvent) { if (systemEvent.type == GROUP_TYPE) { feedEvent = new Event(systemEvent.content); - if (feedEvent.id == self.id || feedEvent.id == '*') { + if (feedEvent.user == self.id || feedEvent.user == '*') { self.onData(feedEvent); } } @@ -254,6 +261,10 @@ var Feed = (function() { return JSON.stringify(data); } + Feed.prototype._renderFunction = function(data) { + return JSON.stringify(data); + } + // Helpers var _extend = function(a, b) { diff --git a/service/stream/static/ws.html b/service/stream/static/ws.html index 0f30355..e455690 100644 --- a/service/stream/static/ws.html +++ b/service/stream/static/ws.html @@ -12,10 +12,10 @@ } }); - feed1 = elasticfeed.initFeed('1', { + feed1 = elasticfeed.initFeed('89', { outputContainerId: 'my-elastic-feed-1', stylerFunction: function(data) { - return '
' + data + '
'; + return '
' + data + '
'; } }); From b4aeed765205d1fdbb6a4788dadfe2031c591005 Mon Sep 17 00:00:00 2001 From: Chris Stasiak Date: Sun, 1 Feb 2015 20:20:55 +0100 Subject: [PATCH 13/20] Added RELOAD|EMPTY action to feed --- docs/examples/feed.md | 20 ++++++++++++++++++++ resource/feed.go | 11 ++++++++++- service/db/v1/controller/feed.go | 18 ++++++++++++++++++ service/db/v1/router/feed.go | 3 +++ service/stream/static/lib/feed.js | 22 +++++++++++----------- service/stream/static/ws.html | 17 +++++++++++++---- 6 files changed, 75 insertions(+), 16 deletions(-) diff --git a/docs/examples/feed.md b/docs/examples/feed.md index 9c5a6bc..e2a238a 100644 --- a/docs/examples/feed.md +++ b/docs/examples/feed.md @@ -29,3 +29,23 @@ Subscribe } }) ``` + +Reload +------ +``` +curl -u john:hello 127.0.0.1:10100/v1/application/30/feed/89/reload --digest +{ + "result": "Feed reloaded", + "status": "ok" +} +``` + +Empty +----- +``` +curl -u john:hello 127.0.0.1:10100/v1/application/30/feed/86/empty --digest +{ + "result": "Feed empty done.", + "status": "ok" +} +``` diff --git a/resource/feed.go b/resource/feed.go index 1f8da76..5e66f71 100644 --- a/resource/feed.go +++ b/resource/feed.go @@ -3,7 +3,6 @@ package resource import ( "errors" "strconv" - "encoding/json" "github.com/feedlabs/feedify/graph" @@ -11,6 +10,8 @@ import ( ) const ( + RELOAD = 1 + EMPTY = 2 ENTRY_NEW = 3 ) @@ -109,6 +110,14 @@ func DeleteFeed(id string) (error) { return storage.DeleteNode(_id) } +func ActionReloadFeed(id string) { + room.Publish <- room.NewFeedEvent(RELOAD, id, "reload") +} + +func ActionEmptyFeed(id string) { + room.Publish <- room.NewFeedEvent(EMPTY, id, "empty") +} + func init() { Feeds = make(map[string]*Feed) } diff --git a/service/db/v1/controller/feed.go b/service/db/v1/controller/feed.go index e9a4b29..e421435 100644 --- a/service/db/v1/controller/feed.go +++ b/service/db/v1/controller/feed.go @@ -5,6 +5,8 @@ import ( "github.com/feedlabs/elasticfeed/resource" "github.com/feedlabs/elasticfeed/service/db/v1/template/feed" + + "github.com/feedlabs/elasticfeed/service/db/v1/template" ) type FeedController struct { @@ -152,3 +154,19 @@ func (this *FeedController) Delete() { feed.ResponseDelete() this.Controller.ServeJson() } + +func (this *FeedController) ActionReload() { + feedId := this.Ctx.Input.Params[":feedId"] + + resource.ActionReloadFeed(feedId) + + this.ServeJson(template.Success("Feed reloaded.")) +} + +func (this *FeedController) ActionEmpty() { + feedId := this.Ctx.Input.Params[":feedId"] + + resource.ActionEmptyFeed(feedId) + + this.ServeJson(template.Success("Feed empty done.")) +} diff --git a/service/db/v1/router/feed.go b/service/db/v1/router/feed.go index bf70232..bde8170 100644 --- a/service/db/v1/router/feed.go +++ b/service/db/v1/router/feed.go @@ -8,4 +8,7 @@ import ( func init() { feedify.Router("/v1/application/:applicationId:string/feed", &controller.FeedController{}, "get:GetList;post:Post") feedify.Router("/v1/application/:applicationId:string/feed/:feedId:int", &controller.FeedController{}, "get:Get;delete:Delete;put:Put") + + feedify.Router("/v1/application/:applicationId:string/feed/:feedId:int/reload", &controller.FeedController{}, "get:ActionReload") + feedify.Router("/v1/application/:applicationId:string/feed/:feedId:int/empty", &controller.FeedController{}, "get:ActionEmpty") } diff --git a/service/stream/static/lib/feed.js b/service/stream/static/lib/feed.js index 8168305..b4cf618 100644 --- a/service/stream/static/lib/feed.js +++ b/service/stream/static/lib/feed.js @@ -3,7 +3,7 @@ var Feed = (function() { const GROUP_TYPE = 1 const RELOAD = 1 - const RESET = 2 + const EMPTY = 2 const ENTRY_NEW = 3 const ENTRY_INIT = 4 const ENTRY_MORE = 5 @@ -74,13 +74,13 @@ var Feed = (function() { this._handlers = {}; } - Feed.prototype.on = function(type, callback) { + Feed.prototype.on = function(name, callback) { switch (name) { case 'reload': type = RELOAD break; - case 'reset': - type = RESET + case 'empty': + type = EMPTY break; case 'entry': type = ENTRY_NEW @@ -101,13 +101,13 @@ var Feed = (function() { type = ENTRY break; default: - return false; break; } if (this._handlers[type] == undefined) { this._handlers[type] = [] } this._handlers[type].push(callback); + return true; } @@ -116,8 +116,8 @@ var Feed = (function() { case RELOAD: this.onReload(feedEvent.ts) break; - case RESET: - this.onReset(feedEvent.ts) + case EMPTY: + this.onEmpty(feedEvent.ts) break; case ENTRY_NEW: this.onEntryNew(feedEvent.ts, feedEvent.content) @@ -144,13 +144,13 @@ var Feed = (function() { Feed.prototype.onReload = function(timestamp) { for (var i in this._handlers[RELOAD]) { - this._handlers[RELOAD][i].call(this, chid, timestamp); + this._handlers[RELOAD][i].call(this, timestamp); } } - Feed.prototype.onReset = function(timestamp) { - for (var i in this._handlers[RESET]) { - this._handlers[RESET][i].call(this, chid, timestamp); + Feed.prototype.onEmpty = function(timestamp) { + for (var i in this._handlers[EMPTY]) { + this._handlers[EMPTY][i].call(this, timestamp); } } diff --git a/service/stream/static/ws.html b/service/stream/static/ws.html index e455690..e95168c 100644 --- a/service/stream/static/ws.html +++ b/service/stream/static/ws.html @@ -12,28 +12,37 @@ } }); - feed1 = elasticfeed.initFeed('89', { + feed1 = elasticfeed.initFeed('86', { outputContainerId: 'my-elastic-feed-1', stylerFunction: function(data) { return '
' + data + '
'; } }); - feed2 = elasticfeed.initFeed('2', { + feed1.on('reload', function(ts) { + feed1.addEntry(new Entry("reload feed by ts:" + ts)) + }) + + feed1.on('empty', function(ts) { + feed1.empty(); + feed1.addEntry(new Entry("reload feed by ts:" + ts)) + }) + + feed2 = elasticfeed.initFeed('87', { outputContainerId: 'my-elastic-feed-2', stylerFunction: function(data) { return '
' + data + '
'; } }); - feed3 = elasticfeed.initFeed('3', { + feed3 = elasticfeed.initFeed('88', { outputContainerId: 'my-elastic-feed-3', stylerFunction: function(data) { return '
' + data + '
'; } }); - feed4 = elasticfeed.initFeed('4', { + feed4 = elasticfeed.initFeed('89', { outputContainerId: 'my-elastic-feed-4', stylerFunction: function(data) { return '
' + data + '
'; From 4776104da793b769c3749b63c1d1a0538b9ebcd2 Mon Sep 17 00:00:00 2001 From: Chris Stasiak Date: Sun, 1 Feb 2015 21:40:48 +0100 Subject: [PATCH 14/20] Example WS updates --- service/stream/static/ws.html | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/service/stream/static/ws.html b/service/stream/static/ws.html index e95168c..032a291 100644 --- a/service/stream/static/ws.html +++ b/service/stream/static/ws.html @@ -12,43 +12,47 @@ } }); - feed1 = elasticfeed.initFeed('86', { + feedList = {} + + feedList[1] = elasticfeed.initFeed('86', { outputContainerId: 'my-elastic-feed-1', stylerFunction: function(data) { return '
' + data + '
'; } }); - feed1.on('reload', function(ts) { - feed1.addEntry(new Entry("reload feed by ts:" + ts)) - }) - - feed1.on('empty', function(ts) { - feed1.empty(); - feed1.addEntry(new Entry("reload feed by ts:" + ts)) - }) - - feed2 = elasticfeed.initFeed('87', { + feedList[2] = elasticfeed.initFeed('87', { outputContainerId: 'my-elastic-feed-2', stylerFunction: function(data) { return '
' + data + '
'; } }); - feed3 = elasticfeed.initFeed('88', { + feedList[3] = elasticfeed.initFeed('88', { outputContainerId: 'my-elastic-feed-3', stylerFunction: function(data) { return '
' + data + '
'; } }); - feed4 = elasticfeed.initFeed('89', { + feedList[4] = elasticfeed.initFeed('89', { outputContainerId: 'my-elastic-feed-4', stylerFunction: function(data) { return '
' + data + '
'; } }); + for (var i in feedList) { + feedList[i].on('reload', function(ts) { + this.addEntry(new Entry("reload feed by ts:" + ts)) + }) + + feedList[i].on('empty', function(ts) { + this.empty(); + this.addEntry(new Entry("empty feed by ts:" + ts)) + }) + } + } From d7a12797ddc6cf62a1929e353a0292e49b5f63c2 Mon Sep 17 00:00:00 2001 From: Chris Stasiak Date: Mon, 2 Feb 2015 17:05:16 +0100 Subject: [PATCH 15/20] Intorduced entryEvent; support for updates --- resource/entry.go | 7 ++++-- service/db/v1/router/entry.go | 2 +- service/stream/controller/room/feed.go | 24 +++++++++---------- service/stream/static/lib/entry.js | 32 ++++++++++---------------- service/stream/static/lib/feed.js | 16 ++++++------- 5 files changed, 38 insertions(+), 43 deletions(-) diff --git a/resource/entry.go b/resource/entry.go index 9c3989e..e2cfc33 100644 --- a/resource/entry.go +++ b/resource/entry.go @@ -105,9 +105,12 @@ func UpdateEntry(id string, FeedId string, ApplicationId string, OrgId string, d return err } + // update entry + entry.Data = data + // notify d, _ := json.Marshal(entry) - room.Publish <- room.NewFeedEvent(ENTRY_UPDATE, entry.Id, string(d)) + room.Publish <- room.NewEntryEvent(ENTRY_UPDATE, entry.Id, string(d)) _id, _ := strconv.Atoi(entry.Id) return storage.SetPropertyNode(_id, "data", data) @@ -129,7 +132,7 @@ func DeleteEntry(id string, FeedId string, ApplicationId string, OrgId string) ( // notify d, _ := json.Marshal(entry) - room.Publish <- room.NewFeedEvent(ENTRY_DELETE, entry.Id, string(d)) + room.Publish <- room.NewEntryEvent(ENTRY_DELETE, entry.Id, string(d)) return storage.DeleteNode(_id) } diff --git a/service/db/v1/router/entry.go b/service/db/v1/router/entry.go index 4adad9f..dfa9104 100644 --- a/service/db/v1/router/entry.go +++ b/service/db/v1/router/entry.go @@ -10,5 +10,5 @@ func init() { feedify.Router("/v1/application/:applicationId:string/entry/:feedEntryId:int", &controller.EntryController{}, "get:Get;delete:Delete;put:Put") feedify.Router("/v1/application/:applicationId:string/feed/:feedId:int/entry", &controller.EntryController{}, "get:GetListByFeed;post:PostToFeed") - feedify.Router("/v1/application/:applicationId:string/feed/:feedId:int/entry/:feedEntryId:int", &controller.EntryController{}, "get:Get;delete:Remove") + feedify.Router("/v1/application/:applicationId:string/feed/:feedId:int/entry/:feedEntryId:int", &controller.EntryController{}, "get:Get;delete:Remove;put:Put") } diff --git a/service/stream/controller/room/feed.go b/service/stream/controller/room/feed.go index 1c34373..41c2d49 100644 --- a/service/stream/controller/room/feed.go +++ b/service/stream/controller/room/feed.go @@ -15,16 +15,9 @@ import ( ) const ( - FEED_ADD = iota - FEED_DELETE - FEED_UPDATE - FEED_RESET - FEED_RELOAD - - ENTRY_ADD - ENTRY_DELETE - ENTRY_UPDATE - ENTRY_RELOAD + SYSTEM_FEED_MESSAGE = 1 + FEED_ENTRY_MESSAGE = 2 + ENTRY_MESSAGE = 8 ) var ( @@ -66,14 +59,21 @@ func NewSystemEvent(ep model.EventType, user, msg string) model.Event { } func NewFeedEvent(ep model.EventType, user, msg string) model.Event { + // "msg" is a feed action; can contain entry specific event event := NewEvent(ep, user, msg) data, _ := json.Marshal(event) - return NewSystemEvent(1, user, string(data)) + // "user" is and feed-id; "*" means all feeds on the client site + return NewSystemEvent(SYSTEM_FEED_MESSAGE, user, string(data)) } func NewEntryEvent(ep model.EventType, user, msg string) model.Event { - return NewSystemEvent(ep, user, msg) + // "msg" is a feed entry data as a string + event := NewEvent(ep, user, msg) + data, _ := json.Marshal(event) + + // "*" all feeds on client site will receive this message + return NewFeedEvent(ENTRY_MESSAGE, "*", string(data)) } func Join(user string, ws *websocket.Conn) { diff --git a/service/stream/static/lib/entry.js b/service/stream/static/lib/entry.js index 5e1c388..ac72a6a 100644 --- a/service/stream/static/lib/entry.js +++ b/service/stream/static/lib/entry.js @@ -2,11 +2,10 @@ var Entry = (function() { const GROUP_TYPE = 2 - const ADD = 1 + const UPDATE = 1 const DELETE = 2 - const UPDATE = 3 - const HIDE = 4 - const SHOW = 5 + const HIDE = 3 + const SHOW = 4 /** @type {Entry} */ var localCache = {} @@ -28,6 +27,9 @@ var Entry = (function() { this._styler = (options ? options.styler : undefined) || function() { return data; }; + + /** @type {Object} */ + this._handlers = {}; } Entry.prototype.setParent = function(feed) { @@ -52,9 +54,6 @@ var Entry = (function() { Entry.prototype.on = function(type, callback) { switch (name) { - case 'add': - type = ADD - break; case 'delete': type = DELETE break; @@ -80,9 +79,6 @@ var Entry = (function() { Entry.prototype.onData = function(entryEvent) { switch (entryEvent.type) { - case ADD: - this.onAdd(entryEvent.ts, entryEvent.content) - break; case DELETE: this.onDelete(entryEvent.ts) break; @@ -100,7 +96,7 @@ var Entry = (function() { // Management - Entry.prototype.update = function(data) { + Entry.prototype.update = function(timestamp, data) { this.data = data; this.render(); } @@ -125,13 +121,9 @@ var Entry = (function() { // Events callbacks - Entry.prototype.onAdd = function(timestamp, data) { - for (var i in this._handlers[ADD]) { - this._handlers[ADD][i].call(this, timestamp, data); - } - } - Entry.prototype.onUpdate = function(timestamp, data) { + this.update(timestamp, data); + for (var i in this._handlers[UPDATE]) { this._handlers[UPDATE][i].call(this, timestamp, data); } @@ -143,13 +135,13 @@ var Entry = (function() { } } - Entry.prototype.onDelete = function(timestamp) { + Entry.prototype.onHide = function(timestamp) { for (var i in this._handlers[HIDE]) { this._handlers[HIDE][i].call(this, timestamp); } } - Entry.prototype.onDelete = function(timestamp) { + Entry.prototype.onShow = function(timestamp) { for (var i in this._handlers[SHOW]) { this._handlers[SHOW][i].call(this, timestamp); } @@ -159,7 +151,7 @@ var Entry = (function() { Entry.prototype.bindFeedMessages = function() { var self = this; - this._feed.on('entry', function(ts, entryEvent) { + this._feed.on('entry-message', function(ts, entryEvent) { if (entryEvent.id == self.id || entryEvent.id == '*') { self.onData(entryEvent); } diff --git a/service/stream/static/lib/feed.js b/service/stream/static/lib/feed.js index b4cf618..ddf3b76 100644 --- a/service/stream/static/lib/feed.js +++ b/service/stream/static/lib/feed.js @@ -9,7 +9,7 @@ var Feed = (function() { const ENTRY_MORE = 5 const HIDE = 6 const SHOW = 7 - const ENTRY = 8 + const ENTRY_MESSAGE = 8 const AUTHENTICATED = 100 const AUTHENTICATION_REQUIRED = 101 @@ -97,8 +97,8 @@ var Feed = (function() { case 'show': type = SHOW break; - case 'entry': - type = ENTRY + case 'entry-message': + type = ENTRY_MESSAGE break; default: break; @@ -134,8 +134,8 @@ var Feed = (function() { case SHOW: this.onShow(feedEvent.ts) break; - case ENTRY: - this.onEntry(feedEvent.ts, feedEvent.content) + case ENTRY_MESSAGE: + this.onEntryMessage(feedEvent.ts, feedEvent.content) break; } } @@ -192,11 +192,11 @@ var Feed = (function() { } } - Feed.prototype.onEntry = function(timestamp, content) { + Feed.prototype.onEntryMessage = function(timestamp, content) { entryEvent = new Event(content); - for (var i in this._handlers[ENTRY]) { - this._handlers[ENTRY][i].call(this, timestamp, entryEvent); + for (var i in this._handlers[ENTRY_MESSAGE]) { + this._handlers[ENTRY_MESSAGE][i].call(this, timestamp, entryEvent); } } From 3ccc594028a8a98e511879cd248137578fa16f72 Mon Sep 17 00:00:00 2001 From: Chris Stasiak Date: Mon, 2 Feb 2015 17:14:20 +0100 Subject: [PATCH 16/20] Moved rooms events to feed room manager --- resource/entry.go | 11 +++-------- resource/feed.go | 10 ++-------- service/stream/controller/room/feed.go | 12 +++++++++--- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/resource/entry.go b/resource/entry.go index e2cfc33..fdc2f48 100644 --- a/resource/entry.go +++ b/resource/entry.go @@ -10,11 +10,6 @@ import ( "github.com/feedlabs/elasticfeed/service/stream/controller/room" ) -const ( - ENTRY_UPDATE = 1 - ENTRY_DELETE = 2 -) - func GetEntryList(FeedId string, ApplicationId string, OrgId string) (feedEntries []*Entry, err error) { feed, err := GetFeed(FeedId, ApplicationId, OrgId) @@ -93,7 +88,7 @@ func AddEntry(feedEntry Entry, FeedId string, ApplicationId string, OrgId string // notify d, _ := json.Marshal(feedEntry) - room.Publish <- room.NewFeedEvent(ENTRY_NEW, feed.Id, string(d)) + room.Publish <- room.NewFeedEvent(room.FEED_ENTRY_NEW, feed.Id, string(d)) return feedEntry.Id, nil } @@ -110,7 +105,7 @@ func UpdateEntry(id string, FeedId string, ApplicationId string, OrgId string, d // notify d, _ := json.Marshal(entry) - room.Publish <- room.NewEntryEvent(ENTRY_UPDATE, entry.Id, string(d)) + room.Publish <- room.NewEntryEvent(room.ENTRY_UPDATE, entry.Id, string(d)) _id, _ := strconv.Atoi(entry.Id) return storage.SetPropertyNode(_id, "data", data) @@ -132,7 +127,7 @@ func DeleteEntry(id string, FeedId string, ApplicationId string, OrgId string) ( // notify d, _ := json.Marshal(entry) - room.Publish <- room.NewEntryEvent(ENTRY_DELETE, entry.Id, string(d)) + room.Publish <- room.NewEntryEvent(room.ENTRY_DELETE, entry.Id, string(d)) return storage.DeleteNode(_id) } diff --git a/resource/feed.go b/resource/feed.go index 5e66f71..632b00d 100644 --- a/resource/feed.go +++ b/resource/feed.go @@ -9,12 +9,6 @@ import ( "github.com/feedlabs/elasticfeed/service/stream/controller/room" ) -const ( - RELOAD = 1 - EMPTY = 2 - ENTRY_NEW = 3 -) - func (this *Feed) AddEntry(entry Entry) (EntryId string, err error) { return AddEntry(entry, this.Id, this.Application.Id, this.Application.Org.Id) } @@ -111,11 +105,11 @@ func DeleteFeed(id string) (error) { } func ActionReloadFeed(id string) { - room.Publish <- room.NewFeedEvent(RELOAD, id, "reload") + room.Publish <- room.NewFeedEvent(room.FEED_RELOAD, id, "reload") } func ActionEmptyFeed(id string) { - room.Publish <- room.NewFeedEvent(EMPTY, id, "empty") + room.Publish <- room.NewFeedEvent(room.FEED_EMPTY, id, "empty") } func init() { diff --git a/service/stream/controller/room/feed.go b/service/stream/controller/room/feed.go index 41c2d49..d4ead6e 100644 --- a/service/stream/controller/room/feed.go +++ b/service/stream/controller/room/feed.go @@ -16,8 +16,14 @@ import ( const ( SYSTEM_FEED_MESSAGE = 1 - FEED_ENTRY_MESSAGE = 2 - ENTRY_MESSAGE = 8 + + FEED_RELOAD = 1 + FEED_EMPTY = 2 + FEED_ENTRY_NEW = 3 + FEED_ENTRY_MESSAGE = 8 + + ENTRY_UPDATE = 1 + ENTRY_DELETE = 2 ) var ( @@ -73,7 +79,7 @@ func NewEntryEvent(ep model.EventType, user, msg string) model.Event { data, _ := json.Marshal(event) // "*" all feeds on client site will receive this message - return NewFeedEvent(ENTRY_MESSAGE, "*", string(data)) + return NewFeedEvent(FEED_ENTRY_MESSAGE, "*", string(data)) } func Join(user string, ws *websocket.Conn) { From cde6dd545a824df8720ee49086d9afc98da1d6b4 Mon Sep 17 00:00:00 2001 From: Chris Stasiak Date: Mon, 2 Feb 2015 17:18:44 +0100 Subject: [PATCH 17/20] Extended feed room events --- service/stream/controller/room/feed.go | 14 ++++++++++---- service/stream/static/lib/feed.js | 4 ++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/service/stream/controller/room/feed.go b/service/stream/controller/room/feed.go index d4ead6e..7989cf0 100644 --- a/service/stream/controller/room/feed.go +++ b/service/stream/controller/room/feed.go @@ -17,13 +17,19 @@ import ( const ( SYSTEM_FEED_MESSAGE = 1 - FEED_RELOAD = 1 - FEED_EMPTY = 2 - FEED_ENTRY_NEW = 3 - FEED_ENTRY_MESSAGE = 8 + FEED_RELOAD = 1 + FEED_EMPTY = 2 + FEED_ENTRY_NEW = 3 + FEED_ENTRY_INIT = 4 + FEED_ENTRY_MORE = 5 + FEED_HIDE = 6 + FEED_SHOW = 7 + FEED_ENTRY_MESSAGE = 8 ENTRY_UPDATE = 1 ENTRY_DELETE = 2 + ENTRY_SHOW = 3 + ENTRY_HIDE = 4 ) var ( diff --git a/service/stream/static/lib/feed.js b/service/stream/static/lib/feed.js index ddf3b76..1de7283 100644 --- a/service/stream/static/lib/feed.js +++ b/service/stream/static/lib/feed.js @@ -1,6 +1,6 @@ var Feed = (function() { - const GROUP_TYPE = 1 + const SYSTEM_FEED_MESSAGE = 1 const RELOAD = 1 const EMPTY = 2 @@ -246,7 +246,7 @@ var Feed = (function() { Feed.prototype.bindChannel = function(channel) { var self = this; channel.on('message', function(chid, ts, systemEvent) { - if (systemEvent.type == GROUP_TYPE) { + if (systemEvent.type == SYSTEM_FEED_MESSAGE) { feedEvent = new Event(systemEvent.content); if (feedEvent.user == self.id || feedEvent.user == '*') { self.onData(feedEvent); From e98190c9ed3071229005ec3f1fe15cf8b59314fd Mon Sep 17 00:00:00 2001 From: Chris Stasiak Date: Tue, 3 Feb 2015 00:12:05 +0100 Subject: [PATCH 18/20] Refactoring; Fixes; --- .../stream/controller/channel/long_pooling.go | 2 +- service/stream/controller/channel/websocket.go | 3 +-- service/stream/controller/room/feed.go | 12 ++++++++---- service/stream/model/event.go | 6 ------ service/stream/static/lib/entry.js | 18 ++++++++++++++---- service/stream/static/lib/feed.js | 13 ++++++++++++- 6 files changed, 36 insertions(+), 18 deletions(-) diff --git a/service/stream/controller/channel/long_pooling.go b/service/stream/controller/channel/long_pooling.go index 67e5380..8e2d838 100644 --- a/service/stream/controller/channel/long_pooling.go +++ b/service/stream/controller/channel/long_pooling.go @@ -37,7 +37,7 @@ func (this *LongPollingController) Post() { // should be executed and returned directly to user // lastReceived time should not be changed in that case - room.Publish <- room.NewSystemEvent(model.EVENT_MESSAGE, chid, data) + room.Publish <- room.NewSystemEvent(room.CHANNEL_MESSAGE, chid, data) } func (this *LongPollingController) Fetch() { diff --git a/service/stream/controller/channel/websocket.go b/service/stream/controller/channel/websocket.go index ea8619d..568cc00 100644 --- a/service/stream/controller/channel/websocket.go +++ b/service/stream/controller/channel/websocket.go @@ -6,7 +6,6 @@ import ( "github.com/feedlabs/feedify" "github.com/gorilla/websocket" - "github.com/feedlabs/elasticfeed/service/stream/model" "github.com/feedlabs/elasticfeed/service/stream/controller/room" ) @@ -43,7 +42,7 @@ func (this *WebSocketController) Join() { return } - room.Publish <- room.NewSystemEvent(model.EVENT_MESSAGE, chid, string(p)) + room.Publish <- room.NewSystemEvent(room.CHANNEL_MESSAGE, chid, string(p)) room.P2P <- ws } } diff --git a/service/stream/controller/room/feed.go b/service/stream/controller/room/feed.go index 7989cf0..becb85c 100644 --- a/service/stream/controller/room/feed.go +++ b/service/stream/controller/room/feed.go @@ -15,6 +15,10 @@ import ( ) const ( + CHANNEL_JOIN = 0 + CHANNEL_LEAVE = 1 + CHANNEL_MESSAGE = 2 + SYSTEM_FEED_MESSAGE = 1 FEED_RELOAD = 1 @@ -67,7 +71,7 @@ func NewSystemEvent(ep model.EventType, user, msg string) model.Event { event := NewEvent(ep, user, msg) data, _ := json.Marshal(event) - return NewChannelEvent(model.EVENT_MESSAGE, user, string(data)) + return NewChannelEvent(CHANNEL_MESSAGE, user, string(data)) } func NewFeedEvent(ep model.EventType, user, msg string) model.Event { @@ -102,10 +106,10 @@ func FeedManager() { case sub := <-Subscribe: Subscribers.PushBack(sub) - Publish <- NewChannelEvent(model.EVENT_JOIN, sub.Name, "") + Publish <- NewChannelEvent(CHANNEL_JOIN, sub.Name, "") case client := <-P2P: - data, _ := json.Marshal(NewSystemEvent(model.EVENT_MESSAGE, "system", "ok")) + data, _ := json.Marshal(NewSystemEvent(CHANNEL_MESSAGE, "system", "ok")) client.WriteMessage(websocket.TextMessage, data) case event := <-Publish: @@ -128,7 +132,7 @@ func FeedManager() { ws.Close() feedify.Error("WebSocket closed:", unsub) } - Publish <- NewChannelEvent(model.EVENT_LEAVE, unsub, "") + Publish <- NewChannelEvent(CHANNEL_LEAVE, unsub, "") break } } diff --git a/service/stream/model/event.go b/service/stream/model/event.go index b8c7dd5..eb8b776 100644 --- a/service/stream/model/event.go +++ b/service/stream/model/event.go @@ -6,12 +6,6 @@ import ( type EventType int -const ( - EVENT_JOIN = iota - EVENT_LEAVE - EVENT_MESSAGE -) - type Event struct { Type EventType User string diff --git a/service/stream/static/lib/entry.js b/service/stream/static/lib/entry.js index ac72a6a..1e537af 100644 --- a/service/stream/static/lib/entry.js +++ b/service/stream/static/lib/entry.js @@ -34,7 +34,7 @@ var Entry = (function() { Entry.prototype.setParent = function(feed) { this._feed = feed; - this.bindFeedMessages(); + this.bindMessages(); } Entry.prototype.getViewId = function() { @@ -47,7 +47,11 @@ var Entry = (function() { // should make animations, should be configurable by developer // first level is style function; second level is render function Entry.prototype.render = function() { - document.getElementById(this.viewId).innerHTML = this._styler.call(this, JSON.stringify(this.data)); + try { + document.getElementById(this.viewId).innerHTML = this._styler.call(this, JSON.stringify(this.data)); + } catch (e) { + // serious error + } } // Events @@ -102,6 +106,7 @@ var Entry = (function() { } Entry.prototype.delete = function() { + this.unbindMessages(); document.getElementById(this.viewId).remove(); } @@ -149,15 +154,20 @@ var Entry = (function() { // Handlers - Entry.prototype.bindFeedMessages = function() { + Entry.prototype.bindMessages = function() { var self = this; - this._feed.on('entry-message', function(ts, entryEvent) { + this.__bindFeed = this._feed.on('entry-message', function(ts, entryEvent) { if (entryEvent.id == self.id || entryEvent.id == '*') { self.onData(entryEvent); } }); } + Entry.prototype.unbindMessages = function() { + this._feed.off(this.__bindFeed); + } + + // Getters Entry.prototype.getTimestamp = function() { return this.ts; diff --git a/service/stream/static/lib/feed.js b/service/stream/static/lib/feed.js index 1de7283..a0a8f3d 100644 --- a/service/stream/static/lib/feed.js +++ b/service/stream/static/lib/feed.js @@ -108,7 +108,18 @@ var Feed = (function() { } this._handlers[type].push(callback); - return true; + return callback; + } + + Feed.prototype.off = function(callback) { + for (var i in this._handlers) { + for (var x in this._handlers[i]) { + if (this._handlers[i][x] == callback) { + delete this._handlers[i][x]; + return; + } + } + } } Feed.prototype.onData = function(feedEvent) { From bf2a56c186ddff6a15b84e0ab8461823eaa2db11 Mon Sep 17 00:00:00 2001 From: Chris Stasiak Date: Tue, 3 Feb 2015 00:21:13 +0100 Subject: [PATCH 19/20] Extended feed event handlers --- service/stream/controller/room/feed.go | 28 ++++++++------- service/stream/static/lib/entry.js | 2 -- service/stream/static/lib/feed.js | 48 ++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 14 deletions(-) diff --git a/service/stream/controller/room/feed.go b/service/stream/controller/room/feed.go index becb85c..0efbdc6 100644 --- a/service/stream/controller/room/feed.go +++ b/service/stream/controller/room/feed.go @@ -15,25 +15,29 @@ import ( ) const ( - CHANNEL_JOIN = 0 - CHANNEL_LEAVE = 1 + CHANNEL_JOIN = 0 + CHANNEL_LEAVE = 1 CHANNEL_MESSAGE = 2 SYSTEM_FEED_MESSAGE = 1 - FEED_RELOAD = 1 - FEED_EMPTY = 2 - FEED_ENTRY_NEW = 3 - FEED_ENTRY_INIT = 4 - FEED_ENTRY_MORE = 5 - FEED_HIDE = 6 - FEED_SHOW = 7 - FEED_ENTRY_MESSAGE = 8 + FEED_RELOAD = 1 + FEED_EMPTY = 2 + FEED_ENTRY_NEW = 3 + FEED_ENTRY_INIT = 4 + FEED_ENTRY_MORE = 5 + FEED_HIDE = 6 + FEED_SHOW = 7 + FEED_ENTRY_MESSAGE = 8 + FEED_AUTHENTICATED = 100 + FEED_AUTHENTICATION_REQUIRED = 101 + FEED_AUTHENTICATION_FAILED = 102 + FEED_LOGGED_OUT = 103 ENTRY_UPDATE = 1 ENTRY_DELETE = 2 - ENTRY_SHOW = 3 - ENTRY_HIDE = 4 + ENTRY_SHOW = 3 + ENTRY_HIDE = 4 ) var ( diff --git a/service/stream/static/lib/entry.js b/service/stream/static/lib/entry.js index 1e537af..ced554a 100644 --- a/service/stream/static/lib/entry.js +++ b/service/stream/static/lib/entry.js @@ -1,7 +1,5 @@ var Entry = (function() { - const GROUP_TYPE = 2 - const UPDATE = 1 const DELETE = 2 const HIDE = 3 diff --git a/service/stream/static/lib/feed.js b/service/stream/static/lib/feed.js index a0a8f3d..626fb6f 100644 --- a/service/stream/static/lib/feed.js +++ b/service/stream/static/lib/feed.js @@ -100,6 +100,18 @@ var Feed = (function() { case 'entry-message': type = ENTRY_MESSAGE break; + case 'authenticated': + type = AUTHENTICATED + break; + case 'authentication-required': + type = AUTHENTICATION_REQUIRED + break; + case 'authentication-failed': + type = AUTHENTICATION_FAILED + break; + case 'logout': + type = LOGGED_OUT + break; default: break; } @@ -148,6 +160,18 @@ var Feed = (function() { case ENTRY_MESSAGE: this.onEntryMessage(feedEvent.ts, feedEvent.content) break; + case AUTHENTICATED: + this.onAuthenticated(feedEvent.ts, feedEvent.content) + break; + case AUTHENTICATION_REQUIRED: + this.onAuthenticationRequired(feedEvent.ts, feedEvent.content) + break; + case AUTHENTICATION_FAILED: + this.onAuthenticationFailed(feedEvent.ts, feedEvent.content) + break; + case LOGGED_OUT: + this.onLogout(feedEvent.ts, feedEvent.content) + break; } } @@ -211,6 +235,30 @@ var Feed = (function() { } } + Feed.prototype.onAuthenticated = function(timestamp, content) { + for (var i in this._handlers[AUTHENTICATED]) { + this._handlers[AUTHENTICATED][i].call(this, timestamp); + } + } + + Feed.prototype.onAuthenticationRequired = function(timestamp, content) { + for (var i in this._handlers[AUTHENTICATION_REQUIRED]) { + this._handlers[AUTHENTICATION_REQUIRED][i].call(this, timestamp); + } + } + + Feed.prototype.onAuthenticationFailed = function(timestamp, content) { + for (var i in this._handlers[AUTHENTICATION_FAILED]) { + this._handlers[AUTHENTICATION_FAILED][i].call(this, timestamp); + } + } + + Feed.prototype.onLogout = function(timestamp, content) { + for (var i in this._handlers[LOGGED_OUT]) { + this._handlers[LOGGED_OUT][i].call(this, timestamp); + } + } + // Entries management Feed.prototype.addEntry = function(entry) { From 605521d21e1c68e5e27ce81a821ea87c872e8d44 Mon Sep 17 00:00:00 2001 From: Chris Stasiak Date: Tue, 3 Feb 2015 00:25:46 +0100 Subject: [PATCH 20/20] Formatting --- service/stream/controller/room/feed.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/service/stream/controller/room/feed.go b/service/stream/controller/room/feed.go index 0efbdc6..2ef6d2e 100644 --- a/service/stream/controller/room/feed.go +++ b/service/stream/controller/room/feed.go @@ -8,9 +8,7 @@ import ( "github.com/feedlabs/feedify" "github.com/gorilla/websocket" - "github.com/astaxie/beego/session" - "github.com/feedlabs/elasticfeed/service/stream/model" )