* use a pool of conversations for handling attention calling

* ignore messages from self (can be sent from other application)
This commit is contained in:
foudfou 2013-04-08 00:42:51 +02:00
parent 837901c301
commit d43e992ed4
1 changed files with 74 additions and 47 deletions

View File

@ -15,8 +15,10 @@ let log = firetray.Logging.getLogger("firetray.Chat");
firetray.Chat = { firetray.Chat = {
initialized: false, initialized: false,
observedTopics: {}, observedTopics: {},
acknowledgeOnFocus: {}, shouldAcknowledgeConvs: {
_isAttentionCalling: false, ids: {},
length: function(){return Object.keys(this.ids).length;}
},
init: function() { init: function() {
if (this.initialized) { if (this.initialized) {
@ -88,11 +90,16 @@ firetray.Chat = {
to the conversation differently. The actual read should be caught by to the conversation differently. The actual read should be caught by
focus-in-event and 'select' event on tabmail and contactlist */ focus-in-event and 'select' event on tabmail and contactlist */
case "new-text": case "new-text":
conv = subject.QueryInterface(Ci.prplIMessage).conversation; let msg = subject.QueryInterface(Ci.prplIMessage);
log.info("new-text from "+conv.title); conv = msg.conversation;
let proto = conv.account.QueryInterface(Ci.imIAccount).protocol; log.debug("new-text from "+conv.title);
if (proto.normalizedName === 'twitter') let account = conv.account.QueryInterface(Ci.imIAccount);
this.startGetAttentionMaybe(conv); let proto = account.protocol;
log.debug("msg from "+msg.who+", alias="+msg.alias+", account.normalizedName="+account.normalizedName);
if (msg.who === account.normalizedName) break; // ignore msg from self
if (proto.normalizedName !== 'twitter') break;
this.startGetAttentionMaybe(conv);
break; break;
case "unread-im-count-changed": case "unread-im-count-changed":
@ -114,33 +121,21 @@ firetray.Chat = {
}, },
startGetAttentionMaybe: function(conv) { startGetAttentionMaybe: function(conv) {
log.debug('startGetAttentionMaybe'); log.debug('startGetAttentionMaybe conv.id='+conv.id);
let convIsCurrentlyShown = this.isConvCurrentlyShown(conv); if (this.shouldAcknowledgeConvs.ids[conv.id]) return; // multiple messages
let convIsCurrentlyShown =
this.isConvCurrentlyShown(conv, firetray.Handler.findActiveWindow());
log.debug("convIsCurrentlyShown="+convIsCurrentlyShown); log.debug("convIsCurrentlyShown="+convIsCurrentlyShown);
if (convIsCurrentlyShown) // don't blink when conv tab already on top if (convIsCurrentlyShown) return; // don't blink when conv tab already on top
return;
if (this._isAttentionCalling) return; this.shouldAcknowledgeConvs.ids[conv.id] = conv;
this._isAttentionCalling = true; log.debug(conv.id+' added to shouldAcknowledgeConvs');
log.debug('shouldAcknowledgeConvs.length='+this.shouldAcknowledgeConvs.length());
this.acknowledgeOnFocus.must = true; if (this.shouldAcknowledgeConvs.length() > 1) return; // already calling attention
this.acknowledgeOnFocus.conv = conv;
/* there can potentially be multiple windows, each with a Chat tab and the
same conv open... so we need to handle urgency for all windows */
for (let xid in firetray.Handler.windows) {
let win = firetray.Handler.windows[xid].chromeWin;
let contactlist = win.document.getElementById("contactlistbox");
for (let i=0; i<contactlist.itemCount; ++i) {
let item = contactlist.getItemAtIndex(i);
if (item.localName !== 'imconv')
continue;
if (item.hasOwnProperty('conv') && item.conv.target === conv) {
firetray.ChatStatusIcon.setUrgency(xid, true);
}
}
}
this.setUrgencyMaybe(conv);
firetray.ChatStatusIcon.startIconBlinking(); firetray.ChatStatusIcon.startIconBlinking();
}, },
@ -148,21 +143,27 @@ firetray.Chat = {
* @param xid id of the window that MUST have initiated this event * @param xid id of the window that MUST have initiated this event
*/ */
stopGetAttentionMaybe: function(xid) { stopGetAttentionMaybe: function(xid) {
log.debug("stopGetAttentionMaybe acknowledgeOnFocus.must="+this.acknowledgeOnFocus.must); log.debug("stopGetAttentionMaybe");
if (!this.acknowledgeOnFocus.must) return; let shouldAcknowledgeConvsLength = this.shouldAcknowledgeConvs.length();
log.debug("shouldAcknowledgeConvsLength="+shouldAcknowledgeConvsLength);
if (!shouldAcknowledgeConvsLength) return;
let convIsCurrentlyShown = this.isConvCurrentlyShown( let selectedConv = this.getSelectedConv(xid);
this.acknowledgeOnFocus.conv, xid); if (!selectedConv) return;
log.debug("convIsCurrentlyShown="+convIsCurrentlyShown);
if (this.acknowledgeOnFocus.must && convIsCurrentlyShown) { for (convId in this.shouldAcknowledgeConvs.ids) {
log.debug(convId+" == "+selectedConv.id);
if (convId == selectedConv.id) {
delete this.shouldAcknowledgeConvs.ids[convId];
break;
}
}
if(this.shouldAcknowledgeConvs.length() === 0) {
log.debug("do stop icon blinking !!!"); log.debug("do stop icon blinking !!!");
firetray.ChatStatusIcon.setUrgency(xid, false); firetray.ChatStatusIcon.setUrgency(xid, false);
firetray.ChatStatusIcon.stopIconBlinking(); firetray.ChatStatusIcon.stopIconBlinking();
this.acknowledgeOnFocus.must = false;
} }
this._isAttentionCalling = false;
}, },
onSelect: function(event) { onSelect: function(event) {
@ -172,23 +173,30 @@ firetray.Chat = {
isConvCurrentlyShown: function(conv, activeWin) { isConvCurrentlyShown: function(conv, activeWin) {
log.debug("isConvCurrentlyShown"); log.debug("isConvCurrentlyShown");
if (!firetray.Handler.windows[activeWin]) return false; let selectedConv = this.getSelectedConv(activeWin);
log.debug("1 ***"); if (!selectedConv) return false;
log.debug("conv.title='"+conv.title+"' selectedConv.title='"+selectedConv.title+"'");
return (conv.id == selectedConv.id);
},
getSelectedConv: function(activeWin) {
if (!firetray.Handler.windows[activeWin]) return null;
log.debug("getSelectedConv *");
let activeChatTab = this.findSelectedChatTab(activeWin); let activeChatTab = this.findSelectedChatTab(activeWin);
if (!activeChatTab) return false; if (!activeChatTab) return null;
log.debug("2 ***"); log.debug("getSelectedConv **");
/* for now there is only one Chat tab, so we don't need to /* for now there is only one Chat tab, so we don't need to
findSelectedChatTabFromTab(activeChatTab.tabNode). And, as there is only findSelectedChatTabFromTab(activeChatTab.tabNode). And, as there is only
one forlderPaneBox, there will also probably be only one contactlistbox one forlderPaneBox, there will also probably be only one contactlistbox
for all Chat tabs anyway */ for all Chat tabs anyway */
let selectedConv = this.findSelectedConv(activeWin); let selectedConv = this.findSelectedConv(activeWin);
if (!selectedConv) return false; if (!selectedConv) return null;
log.debug("3 ***"); log.debug("getSelectedConv ***");
log.debug("conv.title='"+conv.title+"' selectedConv.title='"+selectedConv.title+"'"); return selectedConv;
return (conv.id == selectedConv.id);
}, },
findSelectedChatTab: function(xid) { findSelectedChatTab: function(xid) {
@ -207,6 +215,25 @@ firetray.Chat = {
return selectedItem.conv; return selectedItem.conv;
}, },
/* there can potentially be multiple windows, each with a Chat tab and the
same conv open... so we need to handle urgency for all windows */
setUrgencyMaybe: function(conv) {
for (let xid in firetray.Handler.windows) {
let win = firetray.Handler.windows[xid].chromeWin;
let contactlist = win.document.getElementById("contactlistbox");
for (let i=0; i<contactlist.itemCount; ++i) {
let item = contactlist.getItemAtIndex(i);
if (item.localName !== 'imconv')
continue;
/* item.conv is only initialized if chat tab is open */
if (item.hasOwnProperty('conv') && item.conv.target === conv) {
firetray.ChatStatusIcon.setUrgency(xid, true);
break;
}
}
}
},
updateIcon: function() { updateIcon: function() {
let globalConnectedStatus = this.globalConnectedStatus(); let globalConnectedStatus = this.globalConnectedStatus();
let userStatus; let userStatus;