handle blinking on new messages for twitter accounts

No 'new-directed-incoming-message' event is issued on new messages for twitter
accounts, which seem to be considered chatrooms (instead of private
conversations).
This commit is contained in:
foudfou 2013-04-07 16:45:17 +02:00
parent 6b1bd0cfe6
commit 7af80d0119
6 changed files with 78 additions and 23 deletions

View File

@ -25,10 +25,10 @@ firetray.Chat = {
log.debug("Enabling Chat");
firetray.Utils.addObservers(firetray.Chat, [
// "*" // debugging
// "*", // debugging
"account-connected", "account-disconnected", "idle-time-changed",
"new-directed-incoming-message", "status-changed",
"unread-im-count-changed"
"unread-im-count-changed", "new-text"
]);
firetray.ChatStatusIcon.init();
@ -47,8 +47,27 @@ firetray.Chat = {
this.initialized = false;
},
// FIXME: the listener should probably attached on the conv entry in the
// contactlist during startIconBlinkingMaybe
attachSelectListeners: function(win) {
log.debug("attachSelectListeners");
["contactlistbox", "tabmail"].forEach(function(eltId) {
win.document.getElementById(eltId)
.addEventListener('select', firetray.Chat.onSelect);
});
},
detachSelectListeners: function(win) {
["contactlistbox", "tabmail"].forEach(function(eltId) {
win.document.getElementById(eltId)
.removeEventListener('select', firetray.Chat.onSelect);
});
},
observe: function(subject, topic, data) {
log.debug("RECEIVED Chat: "+topic+" subject="+subject+" data="+data);
let conv = null;
switch (topic) {
case "account-connected":
case "account-disconnected":
@ -58,19 +77,25 @@ firetray.Chat = {
break;
case "new-directed-incoming-message": // when PM or cited in channel
let conv = subject.QueryInterface(Ci.prplIMessage).conversation;
conv = subject.QueryInterface(Ci.prplIMessage).conversation;
log.debug("conversation name="+conv.name); // normalizedName shouldn't be necessary
this.startIconBlinkingMaybe(conv);
break;
let convIsCurrentlyShown = this.isConvCurrentlyShown(conv);
log.debug("convIsCurrentlyShown="+convIsCurrentlyShown);
if (!convIsCurrentlyShown) { // don't blink when conv tab already on top
this.acknowledgeOnFocus.must = true;
this.acknowledgeOnFocus.conv = conv;
firetray.ChatStatusIcon.setIconBlinking(true);
}
/* Twitter is obviously considered a chatroom, not a private
conversation. This is why we need to detect incoming messages and switch
to the conversation differently. The actual read should be caught by
focus-in-event and 'select' event on tabmail and contactlist */
case "new-text":
conv = subject.QueryInterface(Ci.prplIMessage).conversation;
log.info("new-text from "+conv.title);
let proto = conv.account.QueryInterface(Ci.imIAccount).protocol;
if (proto.normalizedName === 'twitter')
this.startIconBlinkingMaybe(conv);
break;
case "unread-im-count-changed":
log.debug("unread-im-count-changed");
let unreadMsgCount = data;
if (unreadMsgCount == 0)
this.stopIconBlinkingMaybe();
@ -87,7 +112,18 @@ firetray.Chat = {
}
},
stopIconBlinkingMaybe: function(xid) {
// FIXME: implement a pool of conv which initiated a warning
startIconBlinkingMaybe: function(conv) {
let convIsCurrentlyShown = this.isConvCurrentlyShown(conv);
log.debug("convIsCurrentlyShown="+convIsCurrentlyShown);
if (!convIsCurrentlyShown) { // don't blink when conv tab already on top
this.acknowledgeOnFocus.must = true;
this.acknowledgeOnFocus.conv = conv;
firetray.ChatStatusIcon.setIconBlinking(true);
}
},
stopIconBlinkingMaybe: function(xid) { // xid optional
log.debug("acknowledgeOnFocus.must="+this.acknowledgeOnFocus.must);
if (!this.acknowledgeOnFocus.must) return;
@ -96,23 +132,34 @@ firetray.Chat = {
log.debug("convIsCurrentlyShown="+convIsCurrentlyShown);
if (this.acknowledgeOnFocus.must && convIsCurrentlyShown) {
log.debug("do stop icon blinking !!!");
firetray.ChatStatusIcon.setIconBlinking(false);
this.acknowledgeOnFocus.must = false;
}
},
onSelect: function(event) {
log.debug("select event ! ");
firetray.Chat.stopIconBlinkingMaybe();
},
isConvCurrentlyShown: function(conv, xid) {
log.debug("isConvCurrentlyShown");
let activeWin = xid || firetray.Handler.findActiveWindow();
if (!firetray.Handler.windows[activeWin]) return false;
log.debug("1 ***");
let activeChatTab = this.findSelectedChatTab(activeWin);
if (!activeChatTab) return false;
log.debug("2 ***");
// for now there is only one Chat tab, so we don't need to
// findSelectedChatTabFromTab(activeChatTab.tabNode). And, as there is only
// one forlderPaneBox, there will also probably be only one contactlistbox
// for all Chat tabs anyway
/* for now there is only one Chat tab, so we don't need to
findSelectedChatTabFromTab(activeChatTab.tabNode). And, as there is only
one forlderPaneBox, there will also probably be only one contactlistbox
for all Chat tabs anyway */
let selectedConv = this.findSelectedConv(activeWin);
if (!selectedConv) return false;
log.debug("3 ***");
log.debug("conv.title='"+conv.title+"' selectedConv.title='"+selectedConv.title+"'");
return (conv.id == selectedConv.id);

View File

@ -255,12 +255,16 @@ firetray.Handler = {
if (enabled) {
firetray.Chat.init();
for (let winId in firetray.Handler.windows)
for (let winId in firetray.Handler.windows) {
firetray.ChatStatusIcon.attachOnFocusInCallback(winId);
firetray.Chat.attachSelectListeners(firetray.Handler.windows[winId].chromeWin);
}
} else {
for (let winId in firetray.Handler.windows)
for (let winId in firetray.Handler.windows) {
firetray.ChatStatusIcon.detachOnFocusInCallback(winId);
firetray.Chat.detachSelectListeners(firetray.Handler.windows[winId].chromeWin);
}
firetray.Chat.shutdown();
}
},

View File

@ -200,7 +200,7 @@ firetray.Utils = {
str += "obj["+i+"]: Unavailable\n";
}
}
log.debug(str);
log.info(str);
},
_nsResolver: function(prefix) {

View File

@ -78,7 +78,7 @@ function gtk_defines(lib) {
this.GCallbackWindowStateEvent_t = ctypes.FunctionType(
ctypes.default_abi, gobject.gboolean,
[this.GtkWidget.ptr, gdk.GdkEventWindowState.ptr, gobject.gpointer]).ptr;
this.GCallbackWidgetFocuEvent_t = ctypes.FunctionType(
this.GCallbackWidgetFocusEvent_t = ctypes.FunctionType(
ctypes.default_abi, gobject.gboolean,
[this.GtkWidget.ptr, gdk.GdkEventFocus.ptr, gobject.gpointer]).ptr;

View File

@ -98,7 +98,7 @@ firetray.ChatStatusIcon = {
attachOnFocusInCallback: function(xid) {
log.debug("attachOnFocusInCallback xid="+xid);
this.signals['focus-in'].callback[xid] =
gtk.GCallbackWidgetFocuEvent_t(firetray.ChatStatusIcon.onFocusIn);
gtk.GCallbackWidgetFocusEvent_t(firetray.ChatStatusIcon.onFocusIn);
this.signals['focus-in'].handler[xid] = gobject.g_signal_connect(
firetray.Handler.gtkWindows.get(xid), "focus-in-event",
firetray.ChatStatusIcon.signals['focus-in'].callback[xid], null);

View File

@ -215,8 +215,10 @@ firetray.Window = {
return false;
}
if (firetray.Handler.isChatEnabled() && firetray.Chat.initialized)
if (firetray.Handler.isChatEnabled() && firetray.Chat.initialized) {
firetray.ChatStatusIcon.detachOnFocusInCallback(xid);
firetray.Chat.detachSelectListeners(firetray.Handler.windows[xid].chromeWin);
}
if (!delete firetray.Handler.windows[xid])
throw new DeleteError();
@ -298,7 +300,7 @@ firetray.Window = {
firetray.Handler.windows[xid].savedHeight,
false); // repaint
['savedX', 'savedX', 'savedWidth', 'savedHeight'].forEach(function(element, index, array) {
['savedX', 'savedX', 'savedWidth', 'savedHeight'].forEach(function(element) {
delete firetray.Handler.windows[xid][element];
});
},
@ -658,8 +660,10 @@ firetray.Handler.registerWindow = function(win) {
this.windows[xid].startupFilterCb = gdk.GdkFilterFunc_t(firetray.Window.startupFilter);
gdk.gdk_window_add_filter(gdkWin, this.windows[xid].startupFilterCb, null);
if (firetray.Handler.isChatEnabled() && firetray.Chat.initialized)
if (firetray.Handler.isChatEnabled() && firetray.Chat.initialized) {
firetray.ChatStatusIcon.attachOnFocusInCallback(xid);
firetray.Chat.attachSelectListeners(win);
}
} catch (x) {
firetray.Window.unregisterWindowByXID(xid);