@emartech/faye-redis-sharded
Version:
Redis backend engine for Faye with support for sharding
115 lines (99 loc) • 3.58 kB
JavaScript
Soapbox = {
/**
* Initializes the application, passing in the globally shared Bayeux client.
* Apps on the same page should share a Bayeux client so that they may share
* an open HTTP connection with the server.
*/
init: function(bayeux) {
var self = this;
this._bayeux = bayeux;
this._login = $('#enterUsername');
this._app = $('#app');
this._follow = $('#addFollowee');
this._post = $('#postMessage');
this._stream = $('#stream');
this._app.hide();
// When the user enters a username, store it and start the app
this._login.submit(function() {
self._username = $('#username').val();
self.launch();
return false;
});
this._bayeux.addExtension({
outgoing: function(message, callback) {
var type = message.connectionType;
if (type) $('#transport').html('(' + type + ')');
callback(message);
}
});
},
/**
* Starts the application after a username has been entered. A subscription is
* made to receive messages that mention this user, and forms are set up to
* accept new followers and send messages.
*/
launch: function() {
var self = this;
this._bayeux.subscribe('/members/' + this._username, this.accept, this);
// Hide login form, show main application UI
this._login.fadeOut('slow', function() {
self._app.fadeIn('slow');
});
// When we add a follower, subscribe to a channel to which the followed user
// will publish messages
this._follow.submit(function() {
var follow = $('#followee'),
name = follow.val();
self._bayeux.subscribe('/chat/' + name, self.accept, self);
follow.val('');
return false;
});
// When we enter a message, send it and clear the message field.
this._post.submit(function() {
var msg = $('#message');
self.post(msg.val());
msg.val('');
return false;
});
// Detect network problems and disable the form when offline
this._bayeux.bind('transport:down', function() {
this._post.find('textarea,input').attr('disabled', true);
}, this);
this._bayeux.bind('transport:up', function() {
this._post.find('textarea,input').attr('disabled', false);
}, this);
},
/**
* Sends messages that the user has entered. The message is scanned for
* @reply-style mentions of other users, and the message is sent to those
* users' channels.
*/
post: function(message) {
var mentions = [],
words = message.split(/\s+/),
self = this,
pattern = /\@[a-z0-9]+/i;
// Extract @replies from the message
$.each(words, function(i, word) {
if (!pattern.test(word)) return;
word = word.replace(/[^a-z0-9]/ig, '');
if (word !== self._username) mentions.push(word);
});
// Message object to transmit over Bayeux channels
message = {user: this._username, message: message};
// Publish to this user's 'from' channel, and to channels for any @replies
// found in the message
this._bayeux.publish('/chat/' + this._username, message);
$.each(mentions, function(i, name) {
self._bayeux.publish('/members/' + name, message);
});
},
/**
* Handler for messages received over subscribed channels. Takes the message
* object sent by the post() method and displays it in the user's message list.
*/
accept: function(message) {
this._stream.prepend('<li><b>' + message.user + ':</b> ' +
message.message + '</li>');
}
};