Added message sending, status setting capabilities; remove old im.js; reconnect

* Sending messages between users now works
* Setting status now works (status message not working yet)
* Reconnecting setup
* Temporarily disabled "not connected" tooltip
Esse commit está contido em:
Joshua Gross
2011-04-19 11:10:58 -05:00
commit 7fe6758c6d
8 arquivos alterados com 160 adições e 1503 exclusões
+10 -8
Ver Arquivo
@@ -20,17 +20,18 @@ community experience.
## Installation ## Installation
Install `Node.js`: Install `Node.js`:
wget http://nodejs.org/dist/node-v0.2.5.tar.gz
tar xzf node-v0.2.5.tar.gz wget http://nodejs.org/dist/node-latest.tar.gz
cd node-v0.2.5 tar xzf node-latest.tar.gz
cd node-latest
./configure ./configure
make make
make install make install
Install Node Package Manager (`npm`): Install Node Package Manager (`npm`): see instructions on the [npm](http://github.com/isaacs/npm) page.
See instructions at http://github.com/isaacs/npm.
Install `Socket.io`:
Install `Socket.io` (included automatically):
npm install socket-io npm install socket-io
That's it! That's it!
@@ -43,8 +44,9 @@ That's it!
## Node Compatibility ## Node Compatibility
The `master` branch of Ajax IM is compatible with node --version: The `socket-io` branch of Ajax IM is compatible with node --version:
v0.4.1
v0.4.6
## Contributing ## Contributing
+137 -34
Ver Arquivo
@@ -14,8 +14,7 @@ AjaxIM = function(options) {
// Load & wire up the chat bar HTML // Load & wire up the chat bar HTML
var IM = $('<div id="AjaxIM"></div>') var IM = $('<div id="AjaxIM"></div>')
.appendTo('body') .appendTo('body')
.css('display', 'none') .css('display', 'none');
.append($(Template.bar));
if(this.settings.theme) { if(this.settings.theme) {
if(typeof document.createStyleSheet == 'function') if(typeof document.createStyleSheet == 'function')
@@ -48,12 +47,12 @@ AjaxIM = function(options) {
self._scrollers(); self._scrollers();
} catch(e) {} } catch(e) {}
}); });
//this._scrollers();
this.socket.connect(); this.socket.connect();
this.socket.on('connect', function() { self._connected(); }); this.socket.on('connect', function() { self._connected(); });
this.socket.on('message', function(msg) { self._message(msg); }); this.socket.on('message', function(msg) { self._message(msg); });
this.socket.on('disconnect', function() { self._disconnected(); }); this.socket.on('disconnect', function() { self._disconnected(); });
this.socket.on('connect_failed', function() { self._disconnected(); });
} else { } else {
return AjaxIM.init(options); return AjaxIM.init(options);
} }
@@ -65,7 +64,7 @@ AjaxIM.prototype._store = function(key, value) {
this.user[key] = value; this.user[key] = value;
store.set('user', this.user); store.set('user', this.user);
} else if(this.username.length) { } else if(this.username.length) {
store.set(key, Tea.encrypt(JSON.stringify(value), this.username)); store.set(key, Tea.encrypt(JSON.stringify(value), this.username));
} }
}; };
@@ -144,8 +143,7 @@ AjaxIM.prototype._wiring = function() {
chatbox.find('.imjs-input').focus(); chatbox.find('.imjs-input').focus();
}); });
// Setup and hide the scrollers // Setup the scrollers
$('.imjs-scroll').css('display', 'none');
$('#imjs-scroll-right').live('click', function() { $('#imjs-scroll-right').live('click', function() {
var hiddenTab = $(this) var hiddenTab = $(this)
.prevAll('#imjs-bar li.imjs-tab:hidden') .prevAll('#imjs-bar li.imjs-tab:hidden')
@@ -230,32 +228,16 @@ AjaxIM.prototype._wiring = function() {
}, 250); }, 250);
}; };
})()); })());
$(this).bind('changeStatusSuccessful changeStatusFailed', function() { $(this).bind('statusChanged', function() {
$('#imjs-away-message-text').removeClass('imjs-loading'); $('#imjs-away-message-text').removeClass('imjs-loading');
}); });
// Setup reconnect button // Setup reconnect button
$('#imjs-reconnect').live('click', function() { $('#imjs-reconnect').live('click', function() {
self._store('offline', false);
$('#imjs-reconnect').hide(); $('#imjs-reconnect').hide();
$('.imjs-input').attr('disabled', false); $('.imjs-input').attr('disabled', false);
// Restore status to available self.socket.connect();
$('#imjs-status-panel .imjs-button').removeClass('imjs-toggled');
$('#imjs-button-available').addClass('imjs-toggled');
$(self.statuses).each(function() {
$('#imjs-friends').removeClass('imjs-' + this);
});
$('#imjs-friends').addClass('imjs-available');
$('#imjs-away-message-text, #imjs-away-message-text-arrow')
.css('display', 'none');
// Set status
self._store('status', ['online', '']);
self.status('online', '');
// Reconnect
self._restore();
}); });
// Allow tabs to be activated and closed // Allow tabs to be activated and closed
@@ -283,13 +265,13 @@ AjaxIM.prototype._wiring = function() {
}); });
$('#imjs-friends') $('#imjs-friends')
.data('state', 'minimized') .live('click', function(e) {
.click(function(e) {
if(!$(this).hasClass('imjs-not-connected') && if(!$(this).hasClass('imjs-not-connected') &&
e.target.id != 'imjs-friends-panel' && e.target.id != 'imjs-friends-panel' &&
!$(e.target).parents('#imjs-friends-panel').length) !$(e.target).parents('#imjs-friends-panel').length)
self.activateTab.call(self, $(this)); self.activateTab.call(self, $(this));
}) })
/*
.mouseenter(function() { .mouseenter(function() {
if($(this).hasClass('imjs-not-connected')) { if($(this).hasClass('imjs-not-connected')) {
$('.imjs-tooltip') $('.imjs-tooltip')
@@ -314,8 +296,12 @@ AjaxIM.prototype._wiring = function() {
$('.imjs-tooltip').css('display', ''); $('.imjs-tooltip').css('display', '');
} }
}); });
*/
};
$('#imjs-friends-panel').css('display', 'none'); AjaxIM.prototype._setup = function() {
$('.imjs-scroll, #imjs-friends-panel').css('display', 'none');
$('#imjs-friends').data('state', 'minimized');
}; };
AjaxIM.prototype._restore = function() { AjaxIM.prototype._restore = function() {
@@ -338,8 +324,8 @@ AjaxIM.prototype._restore = function() {
} }
if(friends) { if(friends) {
$.each(friends, function(friend, status) { $.each(friends, function(friend, info) {
self.addFriend(friend, status, 'Friends'); self.addFriend(friend, info.status || 'offline', info.group || 'Friends');
}); });
$('#imjs-friends').removeClass('imjs-not-connected') $('#imjs-friends').removeClass('imjs-not-connected')
@@ -417,8 +403,13 @@ AjaxIM.prototype._message = function(msg) {
this.username = msg.username; this.username = msg.username;
$('#AjaxIM').show(); $('#AjaxIM').html('').append($(Template.bar)).show();
this._setup();
// a run-once-per-page-load function
this._wiring(); this._wiring();
this._wiring = function(){};
if(this.user.offline == true) { if(this.user.offline == true) {
var self = this; var self = this;
this.socket.disconnect(); this.socket.disconnect();
@@ -428,14 +419,13 @@ AjaxIM.prototype._message = function(msg) {
this._restore(); this._restore();
} }
$('#imjs-friends').attr('class', 'imjs-available'); $('#imjs-friends').attr('class', 'imjs-online');
if(msg.friends) { if(msg.friends) {
$.each(msg.friends, function(friend, status) { $.each(msg.friends, function(friend, status) {
self.addFriend(friend, status, 'Friends'); self.addFriend(friend, status, 'Friends');
}); });
this._store('friends', msg.friends); this._store('friends', this.friends);
this.friends = msg.friends;
} }
// Set username in Friends list // Set username in Friends list
@@ -445,19 +435,87 @@ AjaxIM.prototype._message = function(msg) {
// Set status available // Set status available
$('#imjs-away-message-text, #imjs-away-message-text-arrow').hide(); $('#imjs-away-message-text, #imjs-away-message-text-arrow').hide();
$('#imjs-status-panel .imjs-button').removeClass('imjs-toggled'); $('#imjs-status-panel .imjs-button').removeClass('imjs-toggled');
$('#imjs-button-available').addClass('imjs-toggled'); $('#imjs-button-online').addClass('imjs-toggled');
} }
break; break;
case 'IM': case 'IM':
if(!msg['from']) return;
if(!this.chats[msg.from])
this.createChatbox(msg.from);
this._storeChat(
msg.from,
this._addMessage('them', this.chats[msg.from], msg.from, msg.message)
);
break; break;
case 'STATUS': case 'STATUS':
if(!msg['username']) return;
this._friendUpdate(msg.username, msg.status);
this._store('friends', this.friends);
break; break;
} }
}; };
AjaxIM.prototype._disconnected = function() { AjaxIM.prototype._disconnected = function() {
$('#imjs-friends')
.addClass('imjs-not-connected');
if($('#imjs-friends').hasClass('imjs-selected'))
this.activateTab($('#imjs-friends'));
$('.imjs-input').attr('disabled', true);
$('#imjs-reconnect').show();
};
AjaxIM.prototype.friendsListNoop = function() {
if($(this).hasClass('imjs-not-connected'))
return false;
};
AjaxIM.prototype.send = function(username, message) {
if(!message) return;
var self = this;
if(this.chats[username]) {
// possibly add a datestamp
this._storeChat(username, this._addDateStamp(this.chats[username]));
this._storeChat(username,
this._addMessage('you', this.chats[username],
this.username, message));
}
this.socket.send({
type: 'IM',
to: username,
message: message
});
$(this).trigger('messageSent', [username, message]);
};
AjaxIM.prototype._statuses = ['offline', 'online', 'away'];
AjaxIM.prototype.status = function(value, message) {
var self = this;
// update status icon(s)
if(this._statuses.indexOf(value) == -1)
return;
// check if selected before writing over the class!
$(this._statuses).each(function() {
$('#imjs-friends').removeClass('imjs-' + this);
});
$('#imjs-friends').addClass('imjs-' + value);
this.socket.send({
type: 'STATUS',
status: value,
status_msg: message
});
$(this).trigger('statusChanged', [value, message]);
}; };
AjaxIM.prototype.addFriend = function(username, status, group) { AjaxIM.prototype.addFriend = function(username, status, group) {
@@ -505,6 +563,51 @@ AjaxIM.prototype._updateFriendCount = function() {
$('#imjs-friends .imjs-tab-text span span').html(friendsLength); $('#imjs-friends .imjs-tab-text span span').html(friendsLength);
}; };
AjaxIM.prototype._friendUpdate = function(username, status, statusMessage) {
if(this.chats[username]) {
var tab = this.chats[username].parents('.imjs-tab');
var tab_class = 'imjs-tab';
if(tab.data('state') == 'active') tab_class += ' imjs-selected';
tab_class += ' imjs-' + status;
tab.attr('class', tab_class);
// display the status in the chatbox
var date_stamp =
$('.imjs-tab.imjs-default .imjs-chatbox .imjs-msglog .imjs-date').clone();
var date_stamp_time = date_stamp.find('.imjs-msg-time');
if(date_stamp_time.length)
date_stamp_time.html(dateFormat(date_stamp_time.html()));
var date_stamp_date = date_stamp.find('.imjs-date-date').html(
AjaxIM.l10n[
'chat' + status.slice(0, 1).toUpperCase() + status.slice(1)
].replace(/%s/g, username));
var msglog = this.chats[username].find('.imjs-msglog');
date_stamp.appendTo(msglog);
msglog[0].scrollTop = msglog[0].scrollHeight;
}
if(this.friends[username]) {
var friend_id = 'imjs-friend-' + md5.hex(username + 'Friends');
$('#' + friend_id).attr('class', 'imjs-friend imjs-' + status);
$('#' + friend_id).find('.imjs-friend-status')
.html(statusMessage);
if(status == 'offline') {
$('#' + friend_id + ':visible').slideUp();
$('#' + friend_id + ':hidden').hide();
} else if(!$('#' + friend_id + ':visible').length) {
$('#' + friend_id).slideDown();
}
this.friends[username].status = status;
this._updateFriendCount();
}
};
AjaxIM.prototype.addTab = function(label, action, closable) { AjaxIM.prototype.addTab = function(label, action, closable) {
var tab = $(Template.tab).insertAfter('#imjs-scroll-left'); var tab = $(Template.tab).insertAfter('#imjs-scroll-left');
tab.attr('id', 'imjs-tab-' + md5.hex(label)) tab.attr('id', 'imjs-tab-' + md5.hex(label))
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+1 -1
Ver Arquivo
@@ -10,7 +10,7 @@ AjaxIM.l10n = {
], ],
chatOffline: '%s signed off.', chatOffline: '%s signed off.',
chatAvailable: '%s became available.', chatOnline: '%s became available.',
chatAway: '%s went away.', chatAway: '%s went away.',
notConnected: 'You are currently not connected or the server is not available. ' + notConnected: 'You are currently not connected or the server is not available. ' +
+1 -1
Ver Arquivo
@@ -11,7 +11,7 @@ var Template = {
'<div id="imjs-status-panel">' + '<div id="imjs-status-panel">' +
'<textarea id="imjs-away-message-text"></textarea>' + '<textarea id="imjs-away-message-text"></textarea>' +
'<div id="imjs-away-message-text-arrow"></div>' + '<div id="imjs-away-message-text-arrow"></div>' +
'<a href="#" id="imjs-button-available" class="imjs-button"><span>&bull;</span> Available</a>' + '<a href="#" id="imjs-button-online" class="imjs-button"><span>&bull;</span> Available</a>' +
'<a href="#" id="imjs-button-away" class="imjs-button"><span>&bull;</span> Away</a>' + '<a href="#" id="imjs-button-away" class="imjs-button"><span>&bull;</span> Away</a>' +
'<a href="#" id="imjs-button-offline" class="imjs-button"><span>&bull;</span> Offline</a>' + '<a href="#" id="imjs-button-offline" class="imjs-button"><span>&bull;</span> Offline</a>' +
'</div>' + '</div>' +
+6 -6
Ver Arquivo
@@ -142,18 +142,18 @@ iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVQI12P4//8/AAX+Av7czFnnAAAA
color: #ff0000; color: #ff0000;
} }
li.imjs-msg-a, li.imjs-msg-b { li.imjs-msg-you, li.imjs-msg-them {
display: block; display: block;
padding: 3px 5px 3px 8px; padding: 3px 5px 3px 8px;
border-top: 1px dotted #bfbfbf; border-top: 1px dotted #bfbfbf;
} }
li.imjs-msg-b > span { li.imjs-msg-them > span {
color: #ff0000; color: #ff0000;
font-weight: 700; font-weight: 700;
} }
li.imjs-msg-a > span { li.imjs-msg-you > span {
color: #0099ff; color: #0099ff;
font-weight: 700; font-weight: 700;
} }
@@ -178,7 +178,7 @@ iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVQI12P4//8/AAX+Av7czFnnAAAA
color: #bcbcbc; color: #bcbcbc;
} }
li.imjs-msg-a ul p, li.imjs-msg-b ul p, li.imjs-date ul p { li.imjs-msg-you ul p, li.imjs-msg-them ul p, li.imjs-date ul p {
margin: 0; margin: 0;
} }
/* [end] Message Log Messages */ /* [end] Message Log Messages */
@@ -487,11 +487,11 @@ div#imjs-status-panel > a.imjs-button {
color: #df9b00; color: #df9b00;
} }
div#imjs-status-panel > a#imjs-button-available { div#imjs-status-panel > a#imjs-button-online {
margin-left: 12px; margin-left: 12px;
} }
div#imjs-status-panel > a#imjs-button-available span { div#imjs-status-panel > a#imjs-button-online span {
color: #00cc00; color: #00cc00;
} }
+1 -1
Ver Arquivo
@@ -8,7 +8,7 @@ ExampleAuth.prototype.authenticate = function(client, msg, callback) {
}; };
ExampleAuth.prototype.friends = function(client, res, callback) { ExampleAuth.prototype.friends = function(client, res, callback) {
callback(['username1', 'username2', 'username3']); callback(['username0', 'username1', 'username2', 'username3']);
}; };
var instance = new ExampleAuth(); var instance = new ExampleAuth();
+4 -4
Ver Arquivo
@@ -74,11 +74,11 @@ MessageHandler.prototype._auth = function(client, message) {
} }
MessageHandler.prototype._im = function(client, to, message) { MessageHandler.prototype._im = function(client, to, message) {
var sender = this.session_handler.get('client', client), var sender = this.session_store.get('client', client.sessionId),
recipient; recipient;
if(session) { if(sender) {
recipient = this.session_handler.get('username', to); recipient = this.session_store.get('username', to);
if(recipient) { if(recipient) {
recipient.client.send({ recipient.client.send({
@@ -97,7 +97,7 @@ MessageHandler.prototype._im = function(client, to, message) {
}; };
MessageHandler.prototype._status = function(client, status, status_msg) { MessageHandler.prototype._status = function(client, status, status_msg) {
var session = this.session_handler.get('client', client), var session = this.session_store.get('client', client.sessionId),
friend; friend;
if(['online', 'away', 'offline'].indexOf(status) != -1) { if(['online', 'away', 'offline'].indexOf(status) != -1) {