Put multi-user chats in the 'Contacts' window instead of really closing them when the conversation window is closed.
This commit is contained in:
Родитель
0120d44513
Коммит
14ac369d1d
|
@ -46,6 +46,7 @@ pref("messenger.buddies.hideTagPrompt", true);
|
|||
|
||||
pref("messenger.conversations.openInTabs", true);
|
||||
pref("messenger.conversations.useSeparateWindowsForMUCs", false);
|
||||
pref("messenger.conversations.alwaysClose", true);
|
||||
|
||||
pref("messenger.conversations.selections.magicCopyEnabled", true);
|
||||
pref("messenger.conversations.selections.ellipsis", "chrome://instantbird/locale/instantbird.properties");
|
||||
|
|
|
@ -147,3 +147,16 @@ contact[cansend]:hover .startChatBubble,
|
|||
contact[cansend][selected] .startChatBubble {
|
||||
display: -moz-box;
|
||||
}
|
||||
|
||||
conv {
|
||||
-moz-binding: url("chrome://instantbird/content/conv.xml#conv");
|
||||
-moz-box-align: center;
|
||||
}
|
||||
|
||||
.convUnreadCount[value="0"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#buddyListMsg[listedConvCount="0"] > .listboxHeader {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -40,9 +40,11 @@ Components.utils.import("resource:///modules/imStatusUtils.jsm");
|
|||
const events = ["contact-availability-changed",
|
||||
"contact-added",
|
||||
"contact-tag-added",
|
||||
"showing-ui-conversation",
|
||||
"status-changed",
|
||||
"tag-hidden",
|
||||
"tag-shown",
|
||||
"ui-conversation-hidden",
|
||||
"user-display-name-changed",
|
||||
"user-icon-changed",
|
||||
"purple-quit"];
|
||||
|
@ -350,6 +352,20 @@ var buddyList = {
|
|||
return;
|
||||
}
|
||||
|
||||
if (aTopic == "ui-conversation-hidden") {
|
||||
let convElt = document.createElement("conv");
|
||||
this.convBox.appendChild(convElt);
|
||||
convElt.build(aSubject);
|
||||
this._updateListConvCount();
|
||||
return;
|
||||
}
|
||||
else if (aTopic == "showing-ui-conversation") {
|
||||
if (this.convBox.listedConvs.hasOwnProperty(aSubject.id))
|
||||
this.convBox.listedConvs[aSubject.id].removeNode();
|
||||
this._updateListConvCount();
|
||||
return;
|
||||
}
|
||||
|
||||
// aSubject is an imIContact
|
||||
if (aSubject.online || this._showOffline) {
|
||||
aSubject.getTags().forEach(function (aTag) {
|
||||
|
@ -361,6 +377,11 @@ var buddyList = {
|
|||
}
|
||||
},
|
||||
|
||||
_updateListConvCount: function() {
|
||||
let count = Object.keys(this.convBox.listedConvs).length;
|
||||
this.convBox.parentNode.setAttribute("listedConvCount", count);
|
||||
},
|
||||
|
||||
displayUserIcon: function bl_displayUserIcon() {
|
||||
let icon = Services.core.getUserIcon();
|
||||
document.getElementById("userIcon").src = icon ? icon.spec : "";
|
||||
|
@ -641,6 +662,21 @@ var buddyList = {
|
|||
buddyList.showOtherContacts();
|
||||
blistBox.focus();
|
||||
|
||||
buddyList.convBox = document.getElementById("convlistbox");
|
||||
buddyList.convBox.listedConvs = {};
|
||||
let convs = Services.conversations.getUIConversations();
|
||||
if (convs.hasMoreElements()) {
|
||||
if (!("Conversations" in window))
|
||||
Components.utils.import("resource:///modules/imWindows.jsm");
|
||||
for (let conv in getIter(convs)) {
|
||||
if (Conversations.isUIConversationDisplayed(conv)) {
|
||||
let convElt = document.createElement("conv");
|
||||
buddyList.convBox.appendChild(convElt);
|
||||
convElt.build(conv);
|
||||
}
|
||||
}
|
||||
buddyList._updateListConvCount();
|
||||
}
|
||||
prefBranch.addObserver(showOfflineBuddiesPref, buddyList, false);
|
||||
addObservers(buddyList, events);
|
||||
|
||||
|
|
|
@ -168,7 +168,10 @@
|
|||
</toolbar>
|
||||
</toolbox>
|
||||
|
||||
<notificationbox id="buddyListMsg" flex="1">
|
||||
<notificationbox id="buddyListMsg" flex="1" listedConvCount="0">
|
||||
<label value="Hidden Conversations" class="listboxHeader"/>
|
||||
<richlistbox id="convlistbox"/>
|
||||
<label value="Contacts" class="listboxHeader"/>
|
||||
<richlistbox id="buddylistbox" flex="1"
|
||||
onkeypress="buddyList.keyPress(event);"
|
||||
context="buddyListContextMenu"
|
||||
|
|
|
@ -0,0 +1,178 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License Version
|
||||
- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
- the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is the Instantbird messenging client, released
|
||||
- 2007.
|
||||
-
|
||||
- The Initial Developer of the Original Code is
|
||||
- Florian QUEZE <florian@instantbird.org>.
|
||||
- Portions created by the Initial Developer are Copyright (C) 2007
|
||||
- the Initial Developer. All Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the terms of
|
||||
- either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
- in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
- of those above. If you wish to allow use of your version of this file only
|
||||
- under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
- use your version of this file under the terms of the MPL, indicate your
|
||||
- decision by deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this file under
|
||||
- the terms of any one of the MPL, the GPL or the LGPL.
|
||||
-
|
||||
- ***** END LICENSE BLOCK ***** -->
|
||||
|
||||
<!DOCTYPE bindings [
|
||||
<!ENTITY % instantbirdDTD SYSTEM "chrome://instantbird/locale/instantbird.dtd" >
|
||||
%instantbirdDTD;
|
||||
]>
|
||||
|
||||
<bindings id="convBindings"
|
||||
xmlns="http://www.mozilla.org/xbl"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:xbl="http://www.mozilla.org/xbl"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<binding id="conv" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
|
||||
<content>
|
||||
<xul:stack class="prplBuddyIcon" mousethrough="always">
|
||||
<xul:image xbl:inherits="src=iconPrpl" class="protoIcon"/>
|
||||
<xul:image class="statusIcon"/>
|
||||
</xul:stack>
|
||||
<xul:hbox flex="1" class="conv-hbox" mousethrough="always">
|
||||
<xul:label crop="end" flex="1" mousethrough="always"
|
||||
anonid="displayname" class="convDisplayName"
|
||||
xbl:inherits="value=displayname"/>
|
||||
<xul:label crop="end" mousethrough="always"
|
||||
anonid="unreadCount" class="convUnreadCount"
|
||||
xbl:inherits="value=unreadCount"/>
|
||||
</xul:hbox>
|
||||
</content>
|
||||
<implementation implements="nsIObserver">
|
||||
|
||||
<destructor>
|
||||
<![CDATA[
|
||||
if (this.conv) {
|
||||
this.conv.removeObserver(this);
|
||||
delete this.conv;
|
||||
}
|
||||
]]>
|
||||
</destructor>
|
||||
|
||||
<method name="build">
|
||||
<parameter name="aConv"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
this.conv = aConv;
|
||||
this.parentNode.listedConvs[this.conv.id] = this;
|
||||
this.conv.addObserver(this);
|
||||
this.update();
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<property name="displayName"
|
||||
onget="return this.conv.title;"/>
|
||||
|
||||
<!-- nsIObserver implementation -->
|
||||
<method name="observe">
|
||||
<parameter name="aSubject"/>
|
||||
<parameter name="aTopic"/>
|
||||
<parameter name="aData"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (aTopic == "target-purple-conversation-changed" ||
|
||||
aTopic == "unread-message-count-changed" ||
|
||||
aTopic == "update-conv-title" ||
|
||||
aTopic == "update-buddy-status" ||
|
||||
aTopic == "update-buddy-status" ||
|
||||
aTopic == "update-conv-chatleft")
|
||||
this.update();
|
||||
else if (aTopic == "ui-conversation-closed")
|
||||
this.removeNode();
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="update">
|
||||
<body>
|
||||
<![CDATA[
|
||||
this.setAttribute("displayname", this.displayName);
|
||||
this.setAttribute("unreadCount", this.conv.unreadMessageCount);
|
||||
this.setAttribute("iconPrpl",
|
||||
this.conv.account.protocol.iconBaseURI + "icon.png");
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="removeNode">
|
||||
<body>
|
||||
<![CDATA[
|
||||
this.conv.removeObserver(this);
|
||||
delete this.parentNode.listedConvs[this.conv.id];
|
||||
this.parentNode.removeChild(this);
|
||||
delete this.conv;
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="openConversation">
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (!("Conversations" in window))
|
||||
Components.utils.import("resource:///modules/imWindows.jsm");
|
||||
Conversations.showConversation(this.conv);
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="keyPress">
|
||||
<parameter name="aEvent"/>
|
||||
<body>this._keyPress(aEvent);</body>
|
||||
</method>
|
||||
<method name="_keyPress">
|
||||
<parameter name="aEvent"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
switch (aEvent.keyCode) {
|
||||
// If Enter or Return is pressed, open a new conversation
|
||||
case aEvent.DOM_VK_RETURN:
|
||||
case aEvent.DOM_VK_ENTER:
|
||||
this.openConversation();
|
||||
break;
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
</implementation>
|
||||
<handlers>
|
||||
<handler event="mousedown">
|
||||
<![CDATA[
|
||||
if (event.originalTarget.getAttribute("anonid") == "unreadCount")
|
||||
openConversation();
|
||||
]]>
|
||||
</handler>
|
||||
|
||||
<handler event="click">
|
||||
<![CDATA[
|
||||
if (event.detail == 2)
|
||||
openConversation();
|
||||
]]>
|
||||
</handler>
|
||||
</handlers>
|
||||
</binding>
|
||||
</bindings>
|
|
@ -125,10 +125,8 @@
|
|||
<method name="destroy">
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (this._conv) {
|
||||
this._conv.close();
|
||||
if (this._conv)
|
||||
this._forgetConv();
|
||||
}
|
||||
|
||||
if ("MessageFormat" in window) {
|
||||
let textbox = this.editor;
|
||||
|
@ -158,21 +156,19 @@
|
|||
this.editor.value = aConversation.editor.value;
|
||||
this.browser.browserResize();
|
||||
this.updateTyping();
|
||||
this.loaded = true;
|
||||
this.observe(this.browser, "conversation-loaded", null);
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<field name="loaded">false</field>
|
||||
<field name="messageQueue">[]</field>
|
||||
|
||||
<method name="_emptyMessageQueue">
|
||||
<method name="_showFirstMessages">
|
||||
<body>
|
||||
<![CDATA[
|
||||
this.loaded = true;
|
||||
for each(var m in this.messageQueue)
|
||||
this._addMsg(m);
|
||||
this.messageQueue = null;
|
||||
this._conv.getMessages().forEach(this.addMsg.bind(this));
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
@ -181,36 +177,13 @@
|
|||
<field name="_statusTextEnd">""</field>
|
||||
<field name="_statusTextEndIsError">false</field>
|
||||
|
||||
<!-- This is used when we want to remove close the conversation binding
|
||||
without closing the associated PurpleConversation.
|
||||
For example when quitting the application, we don't want to close the
|
||||
conversation. -->
|
||||
<method name="unInit">
|
||||
<body>
|
||||
<![CDATA[
|
||||
this._conv.removeObserver(this);
|
||||
Conversations.unregisterConversation(this);
|
||||
this._conv = null;
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="addMsg">
|
||||
<parameter name="aMsg"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (this.loaded)
|
||||
this._addMsg(aMsg);
|
||||
else
|
||||
this.messageQueue.push(aMsg);
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
if (!this.loaded)
|
||||
throw "Calling addMsg before the browser is ready?";
|
||||
|
||||
<method name="_addMsg">
|
||||
<parameter name="aMsg"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
var conv = aMsg.conversation;
|
||||
if (!conv) {
|
||||
// The conversation has already been destroyed,
|
||||
|
@ -236,12 +209,15 @@
|
|||
window.getAttention();
|
||||
|
||||
this.browser.appendMessage(aMsg);
|
||||
if (this.tab && aMsg.incoming && !aMsg.system &&
|
||||
(!this.tab.selected || !document.hasFocus())) {
|
||||
if (conv.isChat && aMsg.containsNick)
|
||||
this.tab.setAttribute("attention", "true");
|
||||
else
|
||||
this.tab.setAttribute("unread", "true");
|
||||
if (this.tab && aMsg.incoming && !aMsg.system) {
|
||||
if (this.tab.selected && document.hasFocus())
|
||||
this._conv.markAsRead();
|
||||
else {
|
||||
if (conv.isChat && aMsg.containsNick)
|
||||
this.tab.setAttribute("attention", "true");
|
||||
else
|
||||
this.tab.setAttribute("unread", "true");
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
|
@ -881,6 +857,7 @@
|
|||
this.editor.focus();
|
||||
this.tab.removeAttribute("unread");
|
||||
this.tab.removeAttribute("attention");
|
||||
this._conv.markAsRead();
|
||||
this.displayStatusText();
|
||||
]]>
|
||||
</body>
|
||||
|
@ -1072,7 +1049,8 @@
|
|||
|
||||
// Display all queued messages. Use a timeout so that message text
|
||||
// modifiers can be added with observers for this notification.
|
||||
setTimeout(function(aSelf) { aSelf._emptyMessageQueue(); }, 0, this);
|
||||
if (!this.loaded)
|
||||
setTimeout(this._showFirstMessages.bind(this), 0);
|
||||
|
||||
Services.obs.removeObserver(this, "conversation-loaded");
|
||||
return;
|
||||
|
@ -1080,7 +1058,8 @@
|
|||
|
||||
switch(aTopic) {
|
||||
case "new-text":
|
||||
this.addMsg(aSubject);
|
||||
if (this.loaded)
|
||||
this.addMsg(aSubject);
|
||||
break;
|
||||
|
||||
case "update-typing":
|
||||
|
|
|
@ -23,6 +23,7 @@ instantbird.jar:
|
|||
* content/instantbird/conversation.xml
|
||||
content/instantbird/convbrowser.xml
|
||||
content/instantbird/conv.html
|
||||
content/instantbird/conv.xml
|
||||
* content/instantbird/credits.xhtml
|
||||
* content/instantbird/engineManager.js
|
||||
* content/instantbird/engineManager.xul
|
||||
|
|
|
@ -83,12 +83,17 @@ var Conversations = {
|
|||
if (index != -1)
|
||||
this._conversations.splice(index, 1);
|
||||
|
||||
if (this._uiConv[aConversation.conv.id] == aConversation)
|
||||
delete this._uiConv[aConversation.conv.id];
|
||||
let uiConv = aConversation.conv;
|
||||
if (this._uiConv[uiConv.id] == aConversation) {
|
||||
delete this._uiConv[uiConv.id];
|
||||
if (!uiConv.checkClose())
|
||||
Services.obs.notifyObservers(uiConv, "ui-conversation-hidden", null);
|
||||
}
|
||||
},
|
||||
|
||||
isConversationWindowFocused: function()
|
||||
this._windows.length > 0 && this._windows[0].document.hasFocus(),
|
||||
isUIConversationDisplayed: function(aUIConv) aUIConv in this._uiConv,
|
||||
focusConversation: function(aConv) {
|
||||
let uiConv = Services.conversations.getUIConversation(aConv);
|
||||
uiConv.target = aConv;
|
||||
|
@ -146,25 +151,32 @@ var Conversations = {
|
|||
if (aTopic != "new-ui-conversation")
|
||||
return;
|
||||
|
||||
let conv = aSubject;
|
||||
if (!(aSubject.id in this._uiConv)) {
|
||||
// TODO: let addons customize this behavior.
|
||||
this.showConversation(aSubject);
|
||||
},
|
||||
|
||||
showConversation: function(aConv) {
|
||||
if (!(aConv.id in this._uiConv)) {
|
||||
Services.obs.notifyObservers(aConv, "showing-ui-conversation", null);
|
||||
// The conversation is not displayed anywhere yet.
|
||||
// First, check if an existing conversation window can accept it.
|
||||
for each (let win in this._windows)
|
||||
if (win.document.getElementById("conversations").addConversation(aSubject))
|
||||
if (win.document.getElementById("conversations").addConversation(aConv))
|
||||
return;
|
||||
|
||||
// At this point, no existing registered window can accept the conversation.
|
||||
if (this._pendingConversations) {
|
||||
// If we are already creating a window, append the notification.
|
||||
this._pendingConversations.push(aSubject);
|
||||
this._pendingConversations.push(aConv);
|
||||
}
|
||||
else {
|
||||
// We need to create a new window.
|
||||
this._pendingConversations = [aSubject];
|
||||
this._pendingConversations = [aConv];
|
||||
Services.ww.openWindow(null, CONVERSATION_WINDOW_URI, "_blank",
|
||||
"chrome,toolbar,resizable", null);
|
||||
}
|
||||
}
|
||||
else
|
||||
this.focusConversation(aConv.target);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -41,6 +41,22 @@ richlistbox {
|
|||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
.listboxHeader {
|
||||
-moz-appearance: treeheadercell;
|
||||
margin: 0 0;
|
||||
%ifdef XP_MACOSX
|
||||
margin-right: -1px;
|
||||
%endif
|
||||
}
|
||||
|
||||
.convUnreadCount {
|
||||
background-color:red;
|
||||
padding: 0 7px;
|
||||
border-radius: 50px;
|
||||
color: white;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
contact,
|
||||
group {
|
||||
padding: 0 2px;
|
||||
|
@ -89,6 +105,7 @@ contact[droptarget] > buddy[dummy] {
|
|||
|
||||
.contactDisplayName,
|
||||
.contactStatusText,
|
||||
.convDisplayName,
|
||||
.buddyDisplayName,
|
||||
.buddyStatusText {
|
||||
margin: 0;
|
||||
|
@ -98,7 +115,8 @@ contact[droptarget] > buddy[dummy] {
|
|||
-moz-margin-start: 2px;
|
||||
}
|
||||
|
||||
.contact-hbox {
|
||||
.contact-hbox,
|
||||
.conv-hbox {
|
||||
margin: 2px 0;
|
||||
-moz-margin-start: 2px;
|
||||
min-height: 16px;
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
#include "purpleIConversation.idl"
|
||||
#include "imIContactsService.idl"
|
||||
|
||||
interface purpleIMessage;
|
||||
|
||||
[scriptable, uuid(a09faf46-bb9d-402f-b460-89f8d7827ff1)]
|
||||
interface imIConversation: purpleIConversation {
|
||||
// Will be null for MUCs and IMs from people not in the contacts list.
|
||||
|
@ -48,6 +50,22 @@ interface imIConversation: purpleIConversation {
|
|||
void systemMessage(in AUTF8String aMessage);
|
||||
|
||||
attribute purpleIConversation target;
|
||||
|
||||
// Number of unread incoming messages.
|
||||
readonly attribute PRUint32 unreadMessageCount;
|
||||
// Reset unreadMessageCount.
|
||||
void markAsRead();
|
||||
|
||||
// Call this to give the core an opportunity to close an inactive
|
||||
// conversation. If the conversation is a left MUC or an IM
|
||||
// conversation without unread message, the implementation will call
|
||||
// close().
|
||||
// The returned value indicates if the conversation was closed.
|
||||
boolean checkClose();
|
||||
|
||||
// Get an array of all messages of the conversation.
|
||||
void getMessages([optional] out unsigned long messageCount,
|
||||
[retval, array, size_is(messageCount)] out purpleIMessage messages);
|
||||
};
|
||||
|
||||
[scriptable, uuid(984e182c-d395-4fba-ba6e-cc80c71f57bf)]
|
||||
|
@ -60,6 +78,7 @@ interface imIConversationsService: nsISupports {
|
|||
void addConversation(in purpleIConversation aConversation);
|
||||
void removeConversation(in purpleIConversation aConversation);
|
||||
|
||||
nsISimpleEnumerator getUIConversations();
|
||||
imIConversation getUIConversation(in purpleIConversation aConversation);
|
||||
imIConversation getUIConversationByContactId(in long aId);
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ function UIConversation(aPurpleConversation)
|
|||
this._purpleConv = {};
|
||||
this.id = ++gLastUIConvId;
|
||||
this._observers = [];
|
||||
this._pendingMessages = [];
|
||||
this._messages = [];
|
||||
this.changeTargetTo(aPurpleConversation);
|
||||
let iface = Ci["purpleIConv" + (aPurpleConversation.isChat ? "Chat" : "IM")];
|
||||
this._interfaces = this._interfaces.concat(iface);
|
||||
|
@ -137,6 +137,37 @@ UIConversation.prototype = {
|
|||
return true;
|
||||
},
|
||||
|
||||
_unreadMessageCount: 0,
|
||||
get unreadMessageCount() this._unreadMessageCount,
|
||||
markAsRead: function() {
|
||||
delete this._unreadMessageCount;
|
||||
this._notifyUnreadCountChanged();
|
||||
},
|
||||
_lastNotifiedUnreadCount: 0,
|
||||
_notifyUnreadCountChanged: function() {
|
||||
if (this._unreadMessageCount == this._lastNotifiedUnreadCount)
|
||||
return;
|
||||
|
||||
for each (let observer in this._observers)
|
||||
observer.observe(this, "unread-message-count-changed",
|
||||
this._unreadMessageCount.toString());
|
||||
this._lastNotifiedUnreadCount = this._unreadMessageCount;
|
||||
},
|
||||
getMessages: function(aMessageCount) {
|
||||
if (aMessageCount)
|
||||
aMessageCount.value = this._messages.length;
|
||||
return this._messages;
|
||||
},
|
||||
checkClose: function() {
|
||||
if (!Services.prefs.getBoolPref("messenger.conversations.alwaysClose") &&
|
||||
(this.isChat && !this.left ||
|
||||
!this.isChat && this.unreadMessageCount != 0))
|
||||
return false;
|
||||
|
||||
this.close();
|
||||
return true;
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
if (aTopic == "contact-no-longer-dummy") {
|
||||
let oldId = parseInt(aData);
|
||||
|
@ -248,23 +279,25 @@ UIConversation.prototype = {
|
|||
close: function() {
|
||||
for each (let conv in this._purpleConv)
|
||||
conv.close();
|
||||
this.notifyObservers(this, "ui-conversation-closed");
|
||||
Services.obs.notifyObservers(this, "ui-conversation-closed", null);
|
||||
},
|
||||
addObserver: function(aObserver) {
|
||||
if (this._observers.indexOf(aObserver) == -1) {
|
||||
if (this._observers.indexOf(aObserver) == -1)
|
||||
this._observers.push(aObserver);
|
||||
if (this._observers.length == 1)
|
||||
while (this._pendingMessages.length)
|
||||
this.notifyObservers(this._pendingMessages.shift(), "new-text");
|
||||
}
|
||||
},
|
||||
removeObserver: function(aObserver) {
|
||||
this._observers = this._observers.filter(function(o) o !== aObserver);
|
||||
},
|
||||
notifyObservers: function(aSubject, aTopic, aData) {
|
||||
if (aTopic == "new-text") {
|
||||
this._messages.push(aSubject);
|
||||
if (aSubject.incoming && !aSubject.system)
|
||||
++this._unreadMessageCount;
|
||||
}
|
||||
for each (let observer in this._observers)
|
||||
observer.observe(aSubject, aTopic, aData);
|
||||
if (!this._observers.length && aTopic == "new-text")
|
||||
this._pendingMessages.push(aSubject);
|
||||
this._notifyUnreadCountChanged();
|
||||
},
|
||||
|
||||
// purpleIConvIM
|
||||
|
@ -367,6 +400,9 @@ ConversationsService.prototype = {
|
|||
this._purpleConversations.filter(function(c) c !== aPurpleConversation);
|
||||
},
|
||||
|
||||
getUIConversations: function()
|
||||
new nsSimpleEnumerator(Object.keys(this._uiConv)
|
||||
.map(function (k) this._uiConv[k])),
|
||||
getUIConversation: function(aPurpleConversation) {
|
||||
let id = aPurpleConversation.id;
|
||||
if (id in this._uiConv)
|
||||
|
@ -376,7 +412,7 @@ ConversationsService.prototype = {
|
|||
getUIConversationByContactId: function(aId)
|
||||
(aId in this._uiConvByContactId) ? this._uiConvByContactId[aId] : null,
|
||||
|
||||
getConversations: function() nsSimpleEnumerator(this._purpleConversations),
|
||||
getConversations: function() new nsSimpleEnumerator(this._purpleConversations),
|
||||
getConversationById: function(aId) {
|
||||
for (let i = 0; i < this._purpleConversations.length; ++i)
|
||||
if (this._purpleConversations[i].id == aId)
|
||||
|
|
Загрузка…
Ссылка в новой задаче