Status panel implementation completed; offline/reconnect feature added.
Esse commit está contido em:
+186
-34
@@ -49,7 +49,8 @@ AjaxIM = function(options, actions) {
|
||||
this.actions = $.extend({
|
||||
listen: this.settings.pollServer + '/listen',
|
||||
send: this.settings.pollServer + '/message',
|
||||
status: this.settings.pollServer + '/status'
|
||||
status: this.settings.pollServer + '/status',
|
||||
signoff: this.settings.pollServer + '/signoff'
|
||||
}, actions);
|
||||
|
||||
// We load the theme dynamically based on the passed
|
||||
@@ -80,7 +81,7 @@ AjaxIM = function(options, actions) {
|
||||
});
|
||||
|
||||
$('.imjs-chatbox .imjs-minimize').live('click', function() {
|
||||
$(this).parents('.imjs-tab').click();
|
||||
$(this).parents('.imjs-selected').click();
|
||||
});
|
||||
|
||||
// Setup message sending for all chatboxes
|
||||
@@ -174,9 +175,63 @@ AjaxIM = function(options, actions) {
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#imjs-status-panel .imjs-button').live('click', function() {
|
||||
var status = this.id.split('-')[2];
|
||||
|
||||
$('#imjs-away-message-text, #imjs-away-message-text-arrow').animate({
|
||||
opacity: (status == 'away' ? 'show' : 'hide'),
|
||||
height: (status == 'away' ? 'show' : 'hide')
|
||||
}, 50);
|
||||
|
||||
$('#imjs-status-panel .imjs-button').removeClass('imjs-toggled');
|
||||
$(this).addClass('imjs-toggled');
|
||||
|
||||
$('#imjs-away-message-text').val('');
|
||||
|
||||
self.status(status, '');
|
||||
return false;
|
||||
});
|
||||
|
||||
// Allow status messages to be changed
|
||||
$('#imjs-away-message-text').live('keyup', (function() {
|
||||
var msg_type_timer = null;
|
||||
|
||||
return function() {
|
||||
if(msg_type_timer) clearTimeout(msg_type_timer);
|
||||
|
||||
msg_type_timer = setTimeout(function() {
|
||||
self.current_status[1] = $('#imjs-away-message-text')
|
||||
.addClass('imjs-loading').val();
|
||||
self.status.apply(self, self.current_status);
|
||||
}, 250);
|
||||
};
|
||||
})());
|
||||
$(this).bind('changeStatusSuccessful changeStatusFailed', function() {
|
||||
$('#imjs-away-message-text').removeClass('imjs-loading');
|
||||
});
|
||||
|
||||
// Setup reconnect button
|
||||
$('#imjs-reconnect').live('click', function() {
|
||||
self.offline = false;
|
||||
store.remove(self.username + '-offline');
|
||||
$('#imjs-reconnect').hide();
|
||||
$('.imjs-input').attr('disabled', false);
|
||||
|
||||
// Reconnect
|
||||
self.storage();
|
||||
self.listen();
|
||||
|
||||
// Restore status to available
|
||||
$('#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');
|
||||
});
|
||||
|
||||
// Initialize the chatbox hash
|
||||
this.chats = {};
|
||||
this.friends = {};
|
||||
|
||||
$(window).resize(function() {
|
||||
try {
|
||||
@@ -197,11 +252,19 @@ $.extend(AjaxIM.prototype, {
|
||||
this._scrollers();
|
||||
|
||||
this.username = store.get('user');
|
||||
this._lastReconnect = 0;
|
||||
|
||||
if(this.username && store.get(this.username + '-offline') == true) {
|
||||
this.offline = true;
|
||||
|
||||
var self = this;
|
||||
setTimeout(function() { self._showReconnect(); }, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if(this.username)
|
||||
this.storage();
|
||||
|
||||
this._lastReconnect = 0;
|
||||
this.listen();
|
||||
},
|
||||
|
||||
@@ -214,17 +277,28 @@ $.extend(AjaxIM.prototype, {
|
||||
storage: function() {
|
||||
var self = this,
|
||||
chatstore = store.get(this.username + '-chats'),
|
||||
friends = store.get(this.username + '-friends');
|
||||
friends = store.get(this.username + '-friends'),
|
||||
status = store.get(this.username + '-status') || ['available', ''];
|
||||
|
||||
this.chatstore = chatstore || {};
|
||||
this.friends = {};
|
||||
this.current_status = status;
|
||||
|
||||
if(friends) {
|
||||
$.each(friends, function(friend, data) {
|
||||
self.addFriend(friend, data.status, data.group);
|
||||
});
|
||||
|
||||
$('#imjs-friends').removeClass('imjs-not-connected');
|
||||
$('#imjs-friends').removeClass('imjs-not-connected')
|
||||
.addClass('imjs-' + status[0]);
|
||||
|
||||
$('#imjs-button-' + status[0]).addClass('imjs-toggled');
|
||||
if(status[0] == 'away') {
|
||||
setTimeout(function() {
|
||||
$('#imjs-away-message-text, #imjs-away-message-text-arrow').show();
|
||||
}, 250);
|
||||
$('#imjs-away-message-text').val(this.current_status[1]);
|
||||
}
|
||||
}
|
||||
|
||||
$.each(this.chatstore, function(username, convo) {
|
||||
@@ -234,6 +308,9 @@ $.extend(AjaxIM.prototype, {
|
||||
msglog = chatbox.find('.imjs-msglog').empty();
|
||||
chatbox.data('lastDateStamp', null).css('display', 'none');
|
||||
|
||||
if(typeof convo == 'string')
|
||||
convo = self.chatstore[username] = JSON.parse(convo);
|
||||
|
||||
// Restore all messages, date stamps, and errors
|
||||
msglog.html(convo.join(''));
|
||||
|
||||
@@ -246,6 +323,10 @@ $.extend(AjaxIM.prototype, {
|
||||
var msglog = this.chats[activeTab].find('.imjs-msglog');
|
||||
msglog[0].scrollTop = msglog[0].scrollHeight;
|
||||
}
|
||||
|
||||
// Set username in Friends list
|
||||
var header = $('#imjs-friends-panel .imjs-header');
|
||||
header.html(header.html().replace('{username}', this.username));
|
||||
},
|
||||
|
||||
// === //private// {{{AjaxIM.}}}**{{{_clearSession()}}}** ===
|
||||
@@ -253,7 +334,8 @@ $.extend(AjaxIM.prototype, {
|
||||
// Clears all session data from the last known user.
|
||||
_clearSession: function() {
|
||||
var last_user = store.get('user');
|
||||
$.each(['friends', 'activeTab', 'chats'], function(i, key) {
|
||||
$.each(['friends', 'activeTab', 'chats', 'status',
|
||||
'connected'], function(i, key) {
|
||||
store.remove(last_user + '-' + key);
|
||||
});
|
||||
store.set('user', '');
|
||||
@@ -261,6 +343,8 @@ $.extend(AjaxIM.prototype, {
|
||||
this.chats = {};
|
||||
this.friends = {};
|
||||
this.chatstore = {};
|
||||
this.current_status = ['available', ''];
|
||||
|
||||
$('.imjs-tab').not('.imjs-tab.imjs-default').remove();
|
||||
$('.imjs-friend-group').not('.imjs-friend-group.imjs-default').remove();
|
||||
|
||||
@@ -271,6 +355,8 @@ $.extend(AjaxIM.prototype, {
|
||||
//
|
||||
// Queries the server for new messages.
|
||||
listen: function() {
|
||||
if(this.offline) return;
|
||||
|
||||
var self = this;
|
||||
AjaxIM.get(
|
||||
this.actions.listen,
|
||||
@@ -306,17 +392,29 @@ $.extend(AjaxIM.prototype, {
|
||||
this._clearSession();
|
||||
|
||||
this.username = message.username;
|
||||
this.current_status = ['available', ''];
|
||||
store.set('user', message.username);
|
||||
$('#imjs-friends').removeClass('imjs-not-connected');
|
||||
store.set(this.username + '-status', this.current_status);
|
||||
|
||||
$('#imjs-friends').attr('class', 'imjs-available');
|
||||
$.each(message.friends, function() {
|
||||
var friend;
|
||||
if(this.length == 2)
|
||||
friend = this;
|
||||
else
|
||||
friend = [this.toString(), 'offline'];
|
||||
friend = [this.toString(), ['offline', '']];
|
||||
self.addFriend(friend[0], friend[1], 'Friends');
|
||||
});
|
||||
store.set(this.username + '-friends', this.friends);
|
||||
|
||||
// Set username in Friends list
|
||||
var header = $('#imjs-friends-panel .imjs-header');
|
||||
header.html(header.html().replace('{username}', this.username));
|
||||
|
||||
// Set status available
|
||||
$('#imjs-away-message-text, #imjs-away-message-text-arrow').hide();
|
||||
$('#imjs-status-panel .imjs-button').removeClass('imjs-toggled');
|
||||
$('#imjs-button-available').addClass('imjs-toggled');
|
||||
break;
|
||||
|
||||
case 'message':
|
||||
@@ -331,6 +429,10 @@ $.extend(AjaxIM.prototype, {
|
||||
|
||||
case 'notice':
|
||||
break;
|
||||
|
||||
case 'goodbye':
|
||||
this._notConnected();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -393,11 +495,12 @@ $.extend(AjaxIM.prototype, {
|
||||
if(!$('#' + user_id).length) {
|
||||
var user_item = group_item.find('ul li.imjs-default').clone()
|
||||
.removeClass('imjs-default')
|
||||
.addClass('imjs-' + status)
|
||||
.addClass('imjs-' + status[0])
|
||||
.attr('id', user_id)
|
||||
.data('friend', username)
|
||||
.appendTo(group_item.find('ul'));
|
||||
if(status[0] == 0) user_item.hide();
|
||||
if(status[0] == 'offline')
|
||||
user_item.hide();
|
||||
user_item.html(user_item.html().replace('{username}', username));
|
||||
}
|
||||
|
||||
@@ -744,7 +847,15 @@ $.extend(AjaxIM.prototype, {
|
||||
// friends list to "not connected" and empties it; disallows new messages
|
||||
// to be sent.
|
||||
_notConnected: function() {
|
||||
$('#imjs-friends').addClass('imjs-not-connected').unbind('click', this.activateTab);
|
||||
$('#imjs-friends')
|
||||
.addClass('imjs-not-connected')
|
||||
.unbind('click', this.activateTab);
|
||||
if($('#imjs-friends').hasClass('imjs-selected'))
|
||||
this.activateTab($('#imjs-friends'));
|
||||
},
|
||||
|
||||
_showReconnect: function() {
|
||||
$('#imjs-reconnect').show();
|
||||
},
|
||||
|
||||
// === {{{AjaxIM.}}}**{{{send(to, message)}}}** ===
|
||||
@@ -821,33 +932,64 @@ $.extend(AjaxIM.prototype, {
|
||||
// * {{{s}}} is the status code, as defined by {{{AjaxIM.statuses}}}.
|
||||
// * {{{message}}} is the custom status message.
|
||||
status: function(s, message) {
|
||||
var self = this;
|
||||
|
||||
// update status icon(s)
|
||||
if(!this.statuses[s])
|
||||
if(!~this.statuses.indexOf(s))
|
||||
return;
|
||||
|
||||
$('#imjs-friends').attr('class', 'imjs-' + s);
|
||||
// check if selected before writing over the class!
|
||||
$(this.statuses).each(function() {
|
||||
$('#imjs-friends').removeClass('imjs-' + this);
|
||||
});
|
||||
$('#imjs-friends').addClass('imjs-' + s);
|
||||
|
||||
$(this).trigger('changingStatus', [s, message]);
|
||||
|
||||
AjaxIM.post(
|
||||
this.actions.status,
|
||||
{status: this.statuses[s], message: message},
|
||||
function(result) {
|
||||
switch(result.r) {
|
||||
case 'ok':
|
||||
$(self).trigger('changeStatusSuccessful', [s, message]);
|
||||
break;
|
||||
if(s == 'offline') {
|
||||
self._notConnected();
|
||||
self._showReconnect();
|
||||
store.set(this.username + '-offline', true);
|
||||
self.offline = true;
|
||||
$('.imjs-input').attr('disabled', true);
|
||||
|
||||
case 'error':
|
||||
default:
|
||||
$(self).trigger('changeStatusFailed', [result.e, s, message]);
|
||||
break;
|
||||
AjaxIM.post(
|
||||
this.actions.signoff,
|
||||
{},
|
||||
function(result) {
|
||||
if(result.type == 'success')
|
||||
$(self).trigger('changeStatusSuccessful', [s, null]);
|
||||
},
|
||||
function(error) {
|
||||
$(self).trigger('changeStatusFailed', ['not connected', s, null]);
|
||||
}
|
||||
},
|
||||
function(error) {
|
||||
$(self).trigger('changeStatusFailed', ['not connected', s, message]);
|
||||
}
|
||||
);
|
||||
);
|
||||
} else {
|
||||
if(!this.offline)
|
||||
this.listen();
|
||||
|
||||
AjaxIM.post(
|
||||
this.actions.status,
|
||||
{status: s, message: message},
|
||||
function(result) {
|
||||
switch(result.type) {
|
||||
case 'success':
|
||||
$(self).trigger('changeStatusSuccessful', [s, message]);
|
||||
self.current_status = [s, message];
|
||||
store.set(self.username + '-status', self.current_status);
|
||||
break;
|
||||
|
||||
case 'error':
|
||||
default:
|
||||
$(self).trigger('changeStatusFailed', [result.e, s, message]);
|
||||
break;
|
||||
}
|
||||
},
|
||||
function(error) {
|
||||
$(self).trigger('changeStatusFailed', ['not connected', s, message]);
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
// === {{{AjaxIM.}}}**{{{statuses}}}** ===
|
||||
@@ -889,14 +1031,17 @@ $.extend(AjaxIM.prototype, {
|
||||
|
||||
// Set up the friends list actions
|
||||
$(document).click(function(e) {
|
||||
if(e.target.id == 'imjs-friends' ||
|
||||
if(~['imjs-friends'].indexOf(e.target.id) ||
|
||||
$(e.target).parents('#imjs-friends').length) {
|
||||
return;
|
||||
}
|
||||
|
||||
if($('#imjs-friends').data('state') == 'active')
|
||||
self.activateTab.call(self, $('#imjs-friends'));
|
||||
else if($('#imjs-status').data('state') == 'active')
|
||||
self.activateTab.call(self, $('#imjs-status'));
|
||||
});
|
||||
|
||||
$('#imjs-friends')
|
||||
.data('state', 'minimized')
|
||||
.click(function(e) {
|
||||
@@ -927,6 +1072,7 @@ $.extend(AjaxIM.prototype, {
|
||||
$('.imjs-tooltip').css('display', '');
|
||||
}
|
||||
});
|
||||
|
||||
$('#imjs-friends-panel').css('display', 'none');
|
||||
},
|
||||
|
||||
@@ -946,6 +1092,7 @@ $.extend(AjaxIM.prototype, {
|
||||
$('#imjs-bar > li')
|
||||
.not(tab)
|
||||
.not('#imjs-friends, .imjs-scroll, .imjs-default')
|
||||
.add(tab.attr('id') == 'imjs-status' ? '#imjs-friends' : '')
|
||||
.removeClass('imjs-selected')
|
||||
.each(function() {
|
||||
var self = $(this);
|
||||
@@ -956,6 +1103,12 @@ $.extend(AjaxIM.prototype, {
|
||||
chatbox.css('display', 'none');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$('#imjs-status')
|
||||
.removeClass('imjs-selected')
|
||||
.data('state', 'minimized')
|
||||
.find('.imjs-chatbox')
|
||||
.css('display', 'none');
|
||||
}
|
||||
|
||||
if(chatbox && chatbox.css('display') == 'none')
|
||||
@@ -1207,9 +1360,8 @@ AjaxIM.request = function(url, type, data, successFunc, failureFunc) {
|
||||
type: type,
|
||||
cache: false,
|
||||
timeout: 299000,
|
||||
//callback: 'jsonp' + (new Date()).getTime(),
|
||||
success: function(json, textStatus, xhr) {
|
||||
if(xhr.status == '0') return;
|
||||
if('status' in xhr && xhr.status == '0') return;
|
||||
_dbg(json);
|
||||
successFunc(json);
|
||||
},
|
||||
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
// jquery.jsonp 1.1.3 (c)2010 Julian Aubourg | MIT License
|
||||
// http://code.google.com/p/jquery-jsonp/
|
||||
(function(d){var b=function(n){return n!==undefined&&n!==null},m=function(p,n,o){b(p)&&p.apply(n,o)},e=function(n){setTimeout(n,0)},f="",a="&",k="?",l="success",g="error",i=d("head"),h={},c={callback:"C",url:location.href},j=function(s){s=d.extend({},c,s);var r=s.beforeSend,A=0;s.abort=function(){A=1};if(b(r)&&(r(s,s)===false||A)){return s}var q=s.success,o=s.complete,v=s.error,C=s.dataFilter,G=s.callbackParameter,w=s.callback,D=s.cache,n=s.pageCache,t=s.url,I=s.data,x=s.timeout,z,H,F,E;t=b(t)?t:f;I=b(I)?((typeof I)=="string"?I:d.param(I)):f;b(G)&&(I+=(I==f?f:a)+escape(G)+"=?");!D&&!n&&(I+=(I==f?f:a)+"_"+(new Date()).getTime()+"=");z=t.split(k);if(I!=f){H=I.split(k);E=z.length-1;E&&(z[E]+=a+H.shift());z=z.concat(H)}F=z.length-2;F>0&&(z[F]+=w+z.pop());var p=z.join(k),B=function(J){b(C)&&(J=C.apply(s,[J]));m(q,s,[J,l]);m(o,s,[s,l])},y=function(J){m(v,s,[s,J]);m(o,s,[s,J])},u=h[p];if(n&&b(u)){e(function(){b(u.s)?B(u.s):y(g)});return s}e(function(){if(A){return}var J=d("<iframe style='display:none' />").appendTo(i),L=J[0],N=L.contentWindow||L.contentDocument,P=N.document,K,Q,R=function(S,T){n&&!b(T)&&(h[p]=f);K();y(b(T)?T:g)},M=function(T){N[T]=undefined;try{delete N[T]}catch(S){}},O=w=="E"?"X":"E";if(!b(P)){P=N;N=P.getParentNode()}P.open();N[w]=function(S){A=1;n&&(h[p]={s:S});e(function(){K();B(S)})};N[O]=function(S){(!S||S=="complete")&&!A++&&e(R)};s.abort=K=function(){clearTimeout(Q);P.open();M(O);M(w);P.write(f);P.close();J.remove()};P.write(['<html><head><script src="',p,'" onload="',O,'()" onreadystatechange="',O,'(this.readyState)"><\/script></head><body onload="',O,'()"></body></html>'].join(f));P.close();x>0&&(Q=setTimeout(function(){!A&&R(f,"timeout")},x))});return s};j.setup=function(n){d.extend(c,n)};d.jsonp=j})(jQuery);
|
||||
Arquivo binário não exibido.
|
Antes Largura: | Altura: | Tamanho: 121 B Depois Largura: | Altura: | Tamanho: 124 B |
Arquivo binário não exibido.
|
Depois Largura: | Altura: | Tamanho: 847 B |
@@ -149,6 +149,8 @@
|
||||
border: solid #aaa;
|
||||
border-width: 1px 0 0 0;
|
||||
overflow: hidden;
|
||||
resize: none;
|
||||
outline: none;
|
||||
}
|
||||
/* [end] Input */
|
||||
/* [end] Chatbox */
|
||||
@@ -189,7 +191,8 @@ ul#imjs-bar {
|
||||
position: relative;
|
||||
color: #00cc00;
|
||||
font-size: 28px;
|
||||
line-height: 19px;
|
||||
line-height: 13px;
|
||||
left: -1px;
|
||||
top: 6px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
@@ -231,13 +234,13 @@ ul#imjs-bar {
|
||||
border-bottom: 0;
|
||||
padding-bottom: 1px;
|
||||
background-image: url(images/bottom.png);
|
||||
background-position: left bottom;
|
||||
background-position: -142px bottom;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
ul#imjs-bar > li.imjs-selected > #imjs-friends-panel.imjs-chatbox {
|
||||
background-repeat: repeat-x;
|
||||
background-position: -45px bottom;
|
||||
background-position: -132px bottom;
|
||||
}
|
||||
|
||||
/* [begin] Generic bar close */
|
||||
@@ -329,10 +332,11 @@ ul#imjs-bar {
|
||||
/* [begin] Friends list button */
|
||||
ul#imjs-bar > li#imjs-friends {
|
||||
float: right;
|
||||
width: 125px;
|
||||
}
|
||||
|
||||
ul#imjs-bar > li#imjs-friends.imjs-not-connected,
|
||||
ul#imjs-bar > li#imjs-friends.not-connected:hover {
|
||||
ul#imjs-bar > li#imjs-friends.imjs-not-connected:hover {
|
||||
width: 10px;
|
||||
background-image: url(images/error.png);
|
||||
background-position: center;
|
||||
@@ -352,14 +356,111 @@ ul#imjs-bar {
|
||||
font-weight: 700;
|
||||
}
|
||||
/* [end] Friends list button */
|
||||
|
||||
/* [begin] Reconnect button */
|
||||
ul#imjs-bar > li#imjs-reconnect {
|
||||
display: none;
|
||||
float: right;
|
||||
width: 10px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
ul#imjs-bar > li#imjs-reconnect span {
|
||||
margin-left: -3px;
|
||||
}
|
||||
/* [end] Reconnect button */
|
||||
/* [end] Messenger bar */
|
||||
|
||||
/* [begin] Status panel */
|
||||
div#imjs-status-panel {
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
textarea#imjs-away-message-text {
|
||||
display: none;
|
||||
resize: none;
|
||||
width: 169px;
|
||||
height: 30px;
|
||||
margin: 5px 9px 0;
|
||||
padding: 5px;
|
||||
border: 1px solid #cfceca;
|
||||
font: 11px/17px Helvetica Neue, Helvetica, Arial, Calibri, Tahoma, Verdana, sans-serif;
|
||||
}
|
||||
|
||||
textarea#imjs-away-message-text.imjs-loading {
|
||||
background: url(images/loading.gif) 161px 2px no-repeat;
|
||||
}
|
||||
|
||||
div#imjs-away-message-text-arrow {
|
||||
display: none;
|
||||
width: 0;
|
||||
height: 0;
|
||||
margin: -3px 0 0 87px;
|
||||
border-style: solid;
|
||||
border-width: 4px 4px 0;
|
||||
border-color: #cfceca transparent transparent transparent;
|
||||
}
|
||||
|
||||
textarea#imjs-away-message-text:focus {
|
||||
outline: 2px solid #cfceca;
|
||||
}
|
||||
|
||||
div#imjs-status-panel > a.imjs-button {
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
color: #000;
|
||||
padding: 0 7px;
|
||||
font-size: 10px;
|
||||
margin: 5px 0;
|
||||
-moz-border-radius: 10px;
|
||||
-webkit-border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
div#imjs-status-panel > a.imjs-button span {
|
||||
float: left;
|
||||
font-size: 14px;
|
||||
margin: 1px 3px 0 0;
|
||||
}
|
||||
|
||||
div#imjs-status-panel > a.imjs-button.imjs-toggled {
|
||||
background-color: #e0e0e0;
|
||||
border-left-color: #c0c0c0;
|
||||
border-top-color: #c0c0c0;
|
||||
}
|
||||
|
||||
div#imjs-status-panel > a.imjs-button.imjs-toggled:hover {
|
||||
background-color: #d7d7d7;
|
||||
}
|
||||
|
||||
div#imjs-status-panel > a.imjs-button:hover {
|
||||
background: #e0e0e0;
|
||||
}
|
||||
|
||||
div#imjs-status-panel > a#imjs-button-away span {
|
||||
color: #df9b00;
|
||||
}
|
||||
|
||||
div#imjs-status-panel > a#imjs-button-available {
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
div#imjs-status-panel > a#imjs-button-available span {
|
||||
color: #00cc00;
|
||||
}
|
||||
|
||||
div#imjs-status-panel > a#imjs-button-offline span {
|
||||
color: #777;
|
||||
}
|
||||
/* [end] Status panel */
|
||||
|
||||
/* [begin] Friends list */
|
||||
div#imjs-friends-panel {
|
||||
background: #fff;
|
||||
width: 200px;
|
||||
right: auto;
|
||||
left: -1px;
|
||||
right: -1px;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
@@ -457,85 +558,3 @@ div#imjs-friends-panel form, div#imjs-friends-panel form p {
|
||||
color: #aaa;
|
||||
}
|
||||
/* [end] Friends list */
|
||||
|
||||
/* [begin] Login/Registration Forms */
|
||||
div#imjs-lr form {
|
||||
background: #F0EFED url(images/w.png) repeat-x;
|
||||
border: 1px solid #cfceca;
|
||||
max-width: 220px;
|
||||
padding: 5px 5px 10px 8px;
|
||||
overflow: auto;
|
||||
-moz-border-radius: 2px;
|
||||
-webkit-border-radius: 2px;
|
||||
}
|
||||
|
||||
div#imjs-lr .error {
|
||||
font: 700 12px/18px Helvetica Neue, Helvetica, Arial, Calibri, Tahoma, Verdana, sans-serif;
|
||||
color: #ff0000;
|
||||
}
|
||||
|
||||
div#imjs-lr form fieldset {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div#imjs-lr form h2 {
|
||||
font: 700 20px/24px Helvetica Neue, Helvetica, Arial, Calibri, Tahoma, Verdana, sans-serif;
|
||||
margin: 0;
|
||||
padding: 7px 0 0 2px;
|
||||
color: #555;
|
||||
text-shadow: 0 1px 0px #fff;
|
||||
}
|
||||
|
||||
div#imjs-lr form label {
|
||||
display: block;
|
||||
font: 700 12px/14px Helvetica Neue, Helvetica, Arial, Calibri, Tahoma, Verdana, sans-serif;
|
||||
color: #7B7A79;
|
||||
}
|
||||
|
||||
div#imjs-lr form input {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
div#imjs-lr form input.imjs-lr-error, div#imjs-lr form input.imjs-lr-error:focus {
|
||||
margin: -1px;
|
||||
border: 2px solid #ff1111;
|
||||
}
|
||||
|
||||
div#imjs-lr form button {
|
||||
float: right;
|
||||
background: #f4f3f1;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
div#imjs-lr form input, div#imjs-lr form button {
|
||||
border: 1px solid #ddd;
|
||||
color: #000;
|
||||
padding: 4px 3px;
|
||||
font: 16px/20px Helvetica Neue, Helvetica, Arial, Calibri, Tahoma, Verdana, sans-serif;
|
||||
-moz-border-radius: 2px;
|
||||
-webkit-border-radius: 2px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div#imjs-lr form p {
|
||||
padding-left: 2px;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
div#imjs-lr form input:focus, div#imjs-lr form button:focus {
|
||||
position: relative;
|
||||
border: 2px solid #999;
|
||||
margin: -1px;
|
||||
}
|
||||
|
||||
p.imjs-submit {
|
||||
width: 207px;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
form#imjs-login {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
/* [end] Login/Registration Forms */
|
||||
@@ -7,6 +7,13 @@
|
||||
<span>{username}</span>
|
||||
<a href="#" class="imjs-minimize">_</a>
|
||||
</div>
|
||||
<div id="imjs-status-panel">
|
||||
<textarea id="imjs-away-message-text"></textarea>
|
||||
<div id="imjs-away-message-text-arrow"></div>
|
||||
<a href="#" id="imjs-button-available" class="imjs-button"><span>•</span> Available</a>
|
||||
<a href="#" id="imjs-button-away" class="imjs-button"><span>•</span> Away</a>
|
||||
<a href="#" id="imjs-button-offline" class="imjs-button"><span>•</span> Offline</a>
|
||||
</div>
|
||||
<ul id="imjs-friends-list">
|
||||
<li class="imjs-friend-group imjs-default">
|
||||
<span class="imjs-friend-group-header">{group}</span>
|
||||
@@ -20,6 +27,7 @@
|
||||
</form>
|
||||
</div>
|
||||
</li>
|
||||
<li id="imjs-reconnect"><span class="imjs-tab-text">↻</span></li>
|
||||
<li id="imjs-scroll-left" class="imjs-scroll">{count}</li>
|
||||
<li class="imjs-tab imjs-default">
|
||||
<span class="imjs-tab-text"><strong>•</strong> {label} <a href="#" class="imjs-close">x</a></span>
|
||||
|
||||
+6
-1
@@ -126,4 +126,9 @@ app.post('/status', function(req, res) {
|
||||
} else {
|
||||
res.send(new packages.Error('invalid status'));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.post('/signoff', function(req, res) {
|
||||
res.signOff();
|
||||
res.send(new packages.Success('goodbye'));
|
||||
});
|
||||
|
||||
@@ -3,7 +3,6 @@ html
|
||||
head
|
||||
title Ajax IM
|
||||
script(src: '/js/jquery-1.4.1.js', type: 'text/javascript')
|
||||
script(src: '/js/jquery.jsonp-1.1.3.min.js', type: 'text/javascript')
|
||||
script(src: '/js/md5.js', type: 'text/javascript')
|
||||
script(src: '/js/store.js', type: 'text/javascript')
|
||||
script(src: '/js/cookies.js', type: 'text/javascript')
|
||||
|
||||
@@ -81,7 +81,7 @@ Offline.prototype.toJSON = function() {
|
||||
// A special type of status
|
||||
return {
|
||||
type: 'status',
|
||||
user: this.user.get('username'),
|
||||
user: this.username,
|
||||
status: 'offline',
|
||||
message: ''
|
||||
};
|
||||
|
||||
@@ -19,10 +19,17 @@ var Hub = module.exports = function Hub(options) {
|
||||
}
|
||||
|
||||
this.events.addListener('update', o_.bind(function(package) {
|
||||
if(package.constructor === exports.Offline) {
|
||||
for(var i = 0, l = this.users.length; i < l; i++) {
|
||||
if(this.users[i].get('username') == package.user)
|
||||
this.users.splice(i, 1);
|
||||
var _package = package.toJSON();
|
||||
if(package.type == 'status' && package.status == 'offline') {
|
||||
var sids = Object.keys(this.sessions), sid, sess;
|
||||
for(sid in this.sessions) {
|
||||
sess = this.sessions[sid];
|
||||
if(sess.data('username') == package.username) {
|
||||
if(sess.listeners.length)
|
||||
sess.send(200, {type: 'goodbye'});
|
||||
delete this.sessions[sid];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}, this));
|
||||
@@ -38,9 +45,7 @@ Hub.prototype.reap = function(ms) {
|
||||
for(var i = 0, len = sids.length; i < len; ++i) {
|
||||
var sid = sids[i], sess = this.sessions[sid];
|
||||
if(sess.lastAccess < threshold) {
|
||||
sess.signoff(o_.bind(function() {
|
||||
delete this.sessions[sid];
|
||||
}, this));
|
||||
this.events.emit('update', new packages.Offline(sess.data('username')));
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -111,7 +116,8 @@ Hub.prototype.message = function(from, to, package) {
|
||||
};
|
||||
|
||||
Hub.prototype.signOff = function(sid) {
|
||||
this.get(sid, function(session) {
|
||||
if(session) this.events.emit('update', new packages.Offline(this));
|
||||
});
|
||||
if(sid in this.sessions)
|
||||
this.events.emit('update',
|
||||
new packages.Offline(
|
||||
this.sessions[sid].data('username')));
|
||||
};
|
||||
|
||||
@@ -17,7 +17,7 @@ var User = module.exports = function(id, data) {
|
||||
};
|
||||
|
||||
User.prototype.receivedUpdate = function(package) {
|
||||
if(this.friends.indexOf(package.user))
|
||||
if(this.friends.indexOf(package.username))
|
||||
this.send(package);
|
||||
};
|
||||
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário