(function($)
{
$(document).ready(function()
{
// Check if there was a saved application state
var stateCookie = org.cometd.COOKIE?org.cometd.COOKIE.get('org.cometd.demo.state'):null;
var state = stateCookie ? org.cometd.JSON.fromJSON(stateCookie) : null;
var chat = new Chat(state);
// restore some values
if (state)
{
$('#username').val(state.username);
$('#useServer').attr('checked',state.useServer);
$('#altServer').val(state.altServer);
}
// Setup UI
$('#join').show();
$('#joined').hide();
$('#altServer').attr('autocomplete', 'off');
$('#joinButton').click(function() { chat.join($('#username').val()); });
$('#sendButton').click(chat.send);
$('#leaveButton').click(chat.leave);
$('#username').attr('autocomplete', 'off').focus();
$('#username').keyup(function(e)
{
if (e.keyCode == 13)
{
chat.join($('#username').val());
}
});
$('#phrase').attr('autocomplete', 'off');
$('#phrase').keyup(function(e)
{
if (e.keyCode == 13)
{
chat.send();
}
});
});
function Chat(state)
{
var _self = this;
var _wasConnected = false;
var _connected = false;
var _username;
var _lastUser;
var _disconnecting;
var _chatSubscription;
var _membersSubscription;
this.join = function(username)
{
_disconnecting = false;
_username = username;
if (!_username)
{
alert('Please enter a username');
return;
}
var cometdURL = location.protocol + "//" + location.host + config.contextPath + "/cometd";
var useServer = $('#useServer').attr('checked');
if (useServer)
{
var altServer = $('#altServer').val();
if (altServer.length == 0)
{
alert('Please enter a server address');
return;
}
cometdURL = altServer;
}
$.cometd.configure({
url: cometdURL,
logLevel: 'debug'
});
$.cometd.handshake();
$('#join').hide();
$('#joined').show();
$('#phrase').focus();
};
this.leave = function()
{
$.cometd.batch(function()
{
$.cometd.publish('/chat/demo', {
user: _username,
membership: 'leave',
chat: _username + ' has left'
});
_unsubscribe();
});
$.cometd.disconnect();
$('#join').show();
$('#joined').hide();
$('#username').focus();
$('#members').empty();
_username = null;
_lastUser = null;
_disconnecting = true;
};
this.send = function()
{
var phrase = $('#phrase');
var text = phrase.val();
phrase.val('');
if (!text || !text.length) return;
var colons = text.indexOf('::');
if (colons > 0)
{
$.cometd.publish('/service/privatechat', {
room: '/chat/demo',
user: _username,
chat: text.substring(colons + 2),
peer: text.substring(0, colons)
});
}
else
{
$.cometd.publish('/chat/demo', {
user: _username,
chat: text
});
}
};
this.receive = function(message)
{
var fromUser = message.data.user;
var membership = message.data.membership;
var text = message.data.chat;
if (!membership && fromUser == _lastUser)
{
fromUser = '...';
}
else
{
_lastUser = fromUser;
fromUser += ':';
}
var chat = $('#chat');
if (membership)
{
chat.append('' + fromUser + ' ' + text + '
');
_lastUser = null;
}
else if (message.data.scope == 'private')
{
chat.append('' + fromUser + ' [private] ' + text + '
');
}
else
{
chat.append('' + fromUser + ' ' + text + '
');
}
// There seems to be no easy way in jQuery to handle the scrollTop property
chat[0].scrollTop = chat[0].scrollHeight - chat.outerHeight();
};
/**
* Updates the members list.
* This function is called when a message arrives on channel /chat/members
*/
this.members = function(message)
{
var list = '';
$.each(message.data, function()
{
list += this + '
';
});
$('#members').html(list);
};
function _unsubscribe()
{
if (_chatSubscription)
{
$.cometd.unsubscribe(_chatSubscription);
}
_chatSubscription = null;
if (_membersSubscription)
{
$.cometd.unsubscribe(_membersSubscription);
}
_membersSubscription = null;
}
function _subscribe()
{
_chatSubscription = $.cometd.subscribe('/chat/demo', _self.receive);
_membersSubscription = $.cometd.subscribe('/chat/members', _self.members);
}
function _connectionInitialized()
{
// first time connection for this client, so subscribe tell everybody.
$.cometd.batch(function()
{
_subscribe();
$.cometd.publish('/chat/demo', {
user: _username,
membership: 'join',
chat: _username + ' has joined'
});
});
}
function _connectionEstablished()
{
// connection establish (maybe not for first time), so just
// tell local user and update membership
_self.receive({
data: {
user: 'system',
chat: 'Connection to Server Opened'
}
});
$.cometd.publish('/service/members', {
user: _username,
room: '/chat/demo'
});
}
function _connectionBroken()
{
_self.receive({
data: {
user: 'system',
chat: 'Connection to Server Broken'
}
});
$('#members').empty();
}
function _connectionClosed()
{
_self.receive({
data: {
user: 'system',
chat: 'Connection to Server Closed'
}
});
}
function _metaConnect(message)
{
if (_disconnecting)
{
_connected = false;
_connectionClosed();
}
else
{
_wasConnected = _connected;
_connected = message.successful === true;
if (!_wasConnected && _connected)
{
_connectionEstablished();
}
else if (_wasConnected && !_connected)
{
_connectionBroken();
}
}
}
function _metaHandshake(message)
{
if (message.successful)
{
_connectionInitialized();
}
}
$.cometd.addListener('/meta/handshake', _metaHandshake);
$.cometd.addListener('/meta/connect', _metaConnect);
// Restore the state, if present
if (state)
{
setTimeout(function()
{
// This will perform the handshake
_self.join(state.username);
}, 0);
}
$(window).unload(function()
{
if ($.cometd.reload)
{
$.cometd.reload();
// Save the application state only if the user was chatting
if (_wasConnected && _username)
{
var expires = new Date();
expires.setTime(expires.getTime() + 5 * 1000);
org.cometd.COOKIE.set('org.cometd.demo.state', org.cometd.JSON.toJSON({
username: _username,
useServer: $('#useServer').attr('checked'),
altServer: $('#altServer').val()
}), { 'max-age': 5, expires: expires });
}
}
else
{
$.cometd.disconnect();
}
});
}
})(jQuery);