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"); log.debug("Enabling Chat");
firetray.Utils.addObservers(firetray.Chat, [ firetray.Utils.addObservers(firetray.Chat, [
// "*" // debugging // "*", // debugging
"account-connected", "account-disconnected", "idle-time-changed", "account-connected", "account-disconnected", "idle-time-changed",
"new-directed-incoming-message", "status-changed", "new-directed-incoming-message", "status-changed",
"unread-im-count-changed" "unread-im-count-changed", "new-text"
]); ]);
firetray.ChatStatusIcon.init(); firetray.ChatStatusIcon.init();
@ -47,8 +47,27 @@ firetray.Chat = {
this.initialized = false; 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) { observe: function(subject, topic, data) {
log.debug("RECEIVED Chat: "+topic+" subject="+subject+" data="+data); log.debug("RECEIVED Chat: "+topic+" subject="+subject+" data="+data);
let conv = null;
switch (topic) { switch (topic) {
case "account-connected": case "account-connected":
case "account-disconnected": case "account-disconnected":
@ -58,19 +77,25 @@ firetray.Chat = {
break; break;
case "new-directed-incoming-message": // when PM or cited in channel 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 log.debug("conversation name="+conv.name); // normalizedName shouldn't be necessary
this.startIconBlinkingMaybe(conv);
break;
let convIsCurrentlyShown = this.isConvCurrentlyShown(conv); /* Twitter is obviously considered a chatroom, not a private
log.debug("convIsCurrentlyShown="+convIsCurrentlyShown); conversation. This is why we need to detect incoming messages and switch
if (!convIsCurrentlyShown) { // don't blink when conv tab already on top to the conversation differently. The actual read should be caught by
this.acknowledgeOnFocus.must = true; focus-in-event and 'select' event on tabmail and contactlist */
this.acknowledgeOnFocus.conv = conv; case "new-text":
firetray.ChatStatusIcon.setIconBlinking(true); 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; break;
case "unread-im-count-changed": case "unread-im-count-changed":
log.debug("unread-im-count-changed");
let unreadMsgCount = data; let unreadMsgCount = data;
if (unreadMsgCount == 0) if (unreadMsgCount == 0)
this.stopIconBlinkingMaybe(); 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); log.debug("acknowledgeOnFocus.must="+this.acknowledgeOnFocus.must);
if (!this.acknowledgeOnFocus.must) return; if (!this.acknowledgeOnFocus.must) return;
@ -96,23 +132,34 @@ firetray.Chat = {
log.debug("convIsCurrentlyShown="+convIsCurrentlyShown); log.debug("convIsCurrentlyShown="+convIsCurrentlyShown);
if (this.acknowledgeOnFocus.must && convIsCurrentlyShown) { if (this.acknowledgeOnFocus.must && convIsCurrentlyShown) {
log.debug("do stop icon blinking !!!");
firetray.ChatStatusIcon.setIconBlinking(false); firetray.ChatStatusIcon.setIconBlinking(false);
this.acknowledgeOnFocus.must = false; this.acknowledgeOnFocus.must = false;
} }
}, },
onSelect: function(event) {
log.debug("select event ! ");
firetray.Chat.stopIconBlinkingMaybe();
},
isConvCurrentlyShown: function(conv, xid) { isConvCurrentlyShown: function(conv, xid) {
log.debug("isConvCurrentlyShown");
let activeWin = xid || firetray.Handler.findActiveWindow(); let activeWin = xid || firetray.Handler.findActiveWindow();
if (!firetray.Handler.windows[activeWin]) return false; if (!firetray.Handler.windows[activeWin]) return false;
log.debug("1 ***");
let activeChatTab = this.findSelectedChatTab(activeWin); let activeChatTab = this.findSelectedChatTab(activeWin);
if (!activeChatTab) return false; if (!activeChatTab) return false;
log.debug("2 ***");
// 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;
log.debug("3 ***");
log.debug("conv.title='"+conv.title+"' selectedConv.title='"+selectedConv.title+"'"); log.debug("conv.title='"+conv.title+"' selectedConv.title='"+selectedConv.title+"'");
return (conv.id == selectedConv.id); return (conv.id == selectedConv.id);

View File

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

View File

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

View File

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

View File

@ -98,7 +98,7 @@ firetray.ChatStatusIcon = {
attachOnFocusInCallback: function(xid) { attachOnFocusInCallback: function(xid) {
log.debug("attachOnFocusInCallback xid="+xid); log.debug("attachOnFocusInCallback xid="+xid);
this.signals['focus-in'].callback[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( this.signals['focus-in'].handler[xid] = gobject.g_signal_connect(
firetray.Handler.gtkWindows.get(xid), "focus-in-event", firetray.Handler.gtkWindows.get(xid), "focus-in-event",
firetray.ChatStatusIcon.signals['focus-in'].callback[xid], null); firetray.ChatStatusIcon.signals['focus-in'].callback[xid], null);

View File

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