Bug 1176958 - Update participants list when a nick is changed in XMPP MUC. r=aleth,clokep
This commit is contained in:
Родитель
125618e3cd
Коммит
0b0b3abde6
|
@ -56,6 +56,17 @@ topicChanged=%1$S has changed the topic to: %2$S.
|
||||||
# %1$S is the user who cleared the topic.
|
# %1$S is the user who cleared the topic.
|
||||||
topicCleared=%1$S has cleared the topic.
|
topicCleared=%1$S has cleared the topic.
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (nickSet):
|
||||||
|
# This is displayed as a system message when a participant changes his/her
|
||||||
|
# nickname in a conversation.
|
||||||
|
# %1$S is the old nick.
|
||||||
|
# %2$S is the new nick.
|
||||||
|
nickSet=%1$S is now known as %2$S.
|
||||||
|
# LOCALIZATION NOTE (nickSet.you):
|
||||||
|
# This is displayed as a system message when your nickname is changed.
|
||||||
|
# %S is your new nick.
|
||||||
|
nickSet.you=You are now known as %S.
|
||||||
|
|
||||||
# LOCALIZATION NOTE (messenger.conversations.selections.ellipsis):
|
# LOCALIZATION NOTE (messenger.conversations.selections.ellipsis):
|
||||||
# ellipsis is used when copying a part of a message to show that the message was cut
|
# ellipsis is used when copying a part of a message to show that the message was cut
|
||||||
messenger.conversations.selections.ellipsis=[…]
|
messenger.conversations.selections.ellipsis=[…]
|
||||||
|
|
|
@ -96,10 +96,6 @@ message.usermode=Mode %1$S for %2$S set by %3$S.
|
||||||
message.channelmode=Channel mode %1$S set by %2$S.
|
message.channelmode=Channel mode %1$S set by %2$S.
|
||||||
# %S is the user's mode.
|
# %S is the user's mode.
|
||||||
message.yourmode=Your mode is %S.
|
message.yourmode=Your mode is %S.
|
||||||
# %1$S is the old nick and %2$S is the new nick.
|
|
||||||
message.nick=%1$S is now known as %2$S.
|
|
||||||
# %S is your new nick.
|
|
||||||
message.nick.you=You are now known as %S.
|
|
||||||
# Could not change the nickname. %S is the user's nick.
|
# Could not change the nickname. %S is the user's nick.
|
||||||
message.nick.fail=Could not use the desired nickname. Your nick remains %S.
|
message.nick.fail=Could not use the desired nickname. Your nick remains %S.
|
||||||
# The parameter is the message.parted.reason, if a part message is given.
|
# The parameter is the message.parted.reason, if a part message is given.
|
||||||
|
|
|
@ -626,6 +626,66 @@ const GenericConvChatPrototype = {
|
||||||
},
|
},
|
||||||
getNormalizedChatBuddyName: aChatBuddyName => aChatBuddyName,
|
getNormalizedChatBuddyName: aChatBuddyName => aChatBuddyName,
|
||||||
|
|
||||||
|
// Updates the nick of a participant in conversation to a new one.
|
||||||
|
updateNick: function(aOldNick, aNewNick, isOwnNick) {
|
||||||
|
let message;
|
||||||
|
let isParticipant = this._participants.has(aOldNick);
|
||||||
|
if (isOwnNick) {
|
||||||
|
// If this is the user's nick, change it.
|
||||||
|
this.nick = aNewNick;
|
||||||
|
message = _("nickSet.you", aNewNick);
|
||||||
|
|
||||||
|
// If the account was disconnected, it's OK the user is not a participant.
|
||||||
|
if (!isParticipant)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (!isParticipant) {
|
||||||
|
this.ERROR("Trying to rename nick that doesn't exist! " + aOldNick +
|
||||||
|
" to " + aNewNick);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
message = _("nickSet", aOldNick, aNewNick);
|
||||||
|
|
||||||
|
// Get the original participant and then remove it.
|
||||||
|
let participant = this._participants.get(aOldNick);
|
||||||
|
this._participants.delete(aOldNick);
|
||||||
|
|
||||||
|
// Update the nickname and add it under the new nick.
|
||||||
|
participant.name = aNewNick;
|
||||||
|
this._participants.set(aNewNick, participant);
|
||||||
|
|
||||||
|
this.notifyObservers(participant, "chat-buddy-update", aOldNick);
|
||||||
|
this.writeMessage(aOldNick, message, {system: true});
|
||||||
|
},
|
||||||
|
|
||||||
|
// Removes a participant from conversation.
|
||||||
|
removeParticipant: function(aNick) {
|
||||||
|
if (!this._participants.has(aNick))
|
||||||
|
return;
|
||||||
|
|
||||||
|
let stringNickname = Cc["@mozilla.org/supports-string;1"]
|
||||||
|
.createInstance(Ci.nsISupportsString);
|
||||||
|
stringNickname.data = aNick;
|
||||||
|
this.notifyObservers(new nsSimpleEnumerator([stringNickname]),
|
||||||
|
"chat-buddy-remove");
|
||||||
|
this._participants.delete(aNick);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Removes all participant in conversation.
|
||||||
|
removeAllParticipants: function() {
|
||||||
|
let stringNicknames = [];
|
||||||
|
this._participants.forEach(function(aParticipant) {
|
||||||
|
let stringNickname = Cc["@mozilla.org/supports-string;1"]
|
||||||
|
.createInstance(Ci.nsISupportsString);
|
||||||
|
stringNickname.data = aParticipant.name;
|
||||||
|
stringNicknames.push(stringNickname);
|
||||||
|
});
|
||||||
|
this.notifyObservers(new nsSimpleEnumerator(stringNicknames),
|
||||||
|
"chat-buddy-remove");
|
||||||
|
this._participants.clear();
|
||||||
|
},
|
||||||
|
|
||||||
writeMessage: function (aWho, aText, aProperties) {
|
writeMessage: function (aWho, aText, aProperties) {
|
||||||
aProperties.containsNick =
|
aProperties.containsNick =
|
||||||
"incoming" in aProperties && this._pingRegexp.test(aText);
|
"incoming" in aProperties && this._pingRegexp.test(aText);
|
||||||
|
@ -637,7 +697,8 @@ const GenericConvChatBuddyPrototype = {
|
||||||
__proto__: ClassInfo("prplIConvChatBuddy", "generic ConvChatBuddy object"),
|
__proto__: ClassInfo("prplIConvChatBuddy", "generic ConvChatBuddy object"),
|
||||||
|
|
||||||
_name: "",
|
_name: "",
|
||||||
get name() { return this._name; },
|
get name() this._name,
|
||||||
|
set name(aName) this._name = aName,
|
||||||
alias: "",
|
alias: "",
|
||||||
buddy: false,
|
buddy: false,
|
||||||
|
|
||||||
|
|
|
@ -375,56 +375,6 @@ ircChannel.prototype = {
|
||||||
}
|
}
|
||||||
return participant;
|
return participant;
|
||||||
},
|
},
|
||||||
updateNick: function(aOldNick, aNewNick) {
|
|
||||||
let isParticipant = this._participants.has(aOldNick);
|
|
||||||
if (this.normalizeNick(aOldNick) == this.normalizeNick(this.nick)) {
|
|
||||||
// If this is the user's nick, change it.
|
|
||||||
this.nick = aNewNick;
|
|
||||||
// If the account was disconnected, it's OK the user is not a participant.
|
|
||||||
if (!isParticipant)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (!isParticipant) {
|
|
||||||
this.ERROR("Trying to rename nick that doesn't exist! " + aOldNick +
|
|
||||||
" to " + aNewNick);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the original ircParticipant and then remove it.
|
|
||||||
let participant = this.getParticipant(aOldNick);
|
|
||||||
this._participants.delete(aOldNick);
|
|
||||||
|
|
||||||
// Update the nickname and add it under the new nick.
|
|
||||||
participant._name = aNewNick;
|
|
||||||
this._participants.set(aNewNick, participant);
|
|
||||||
|
|
||||||
this.notifyObservers(participant, "chat-buddy-update", aOldNick);
|
|
||||||
},
|
|
||||||
removeParticipant: function(aNick) {
|
|
||||||
if (!this._participants.has(aNick))
|
|
||||||
return;
|
|
||||||
|
|
||||||
let stringNickname = Cc["@mozilla.org/supports-string;1"]
|
|
||||||
.createInstance(Ci.nsISupportsString);
|
|
||||||
stringNickname.data = aNick;
|
|
||||||
this.notifyObservers(new nsSimpleEnumerator([stringNickname]),
|
|
||||||
"chat-buddy-remove");
|
|
||||||
this._participants.delete(aNick);
|
|
||||||
},
|
|
||||||
// Use this before joining to avoid errors of trying to re-add an existing
|
|
||||||
// participant
|
|
||||||
removeAllParticipants: function() {
|
|
||||||
let stringNicknames = [];
|
|
||||||
this._participants.forEach(function(aParticipant) {
|
|
||||||
let stringNickname = Cc["@mozilla.org/supports-string;1"]
|
|
||||||
.createInstance(Ci.nsISupportsString);
|
|
||||||
stringNickname.data = aParticipant.name;
|
|
||||||
stringNicknames.push(stringNickname);
|
|
||||||
});
|
|
||||||
this.notifyObservers(new nsSimpleEnumerator(stringNicknames),
|
|
||||||
"chat-buddy-remove");
|
|
||||||
this._participants.clear();
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add/remove modes from this channel.
|
* Add/remove modes from this channel.
|
||||||
|
@ -1285,25 +1235,24 @@ ircAccount.prototype = {
|
||||||
return buddy;
|
return buddy;
|
||||||
},
|
},
|
||||||
changeBuddyNick: function(aOldNick, aNewNick) {
|
changeBuddyNick: function(aOldNick, aNewNick) {
|
||||||
let msg;
|
|
||||||
if (this.normalizeNick(aOldNick) == this.normalizeNick(this._nickname)) {
|
if (this.normalizeNick(aOldNick) == this.normalizeNick(this._nickname)) {
|
||||||
// Your nickname changed!
|
// Your nickname changed!
|
||||||
this._nickname = aNewNick;
|
this._nickname = aNewNick;
|
||||||
msg = _("message.nick.you", aNewNick);
|
|
||||||
this.conversations.forEach(conversation => {
|
this.conversations.forEach(conversation => {
|
||||||
// Update the nick for chats, and inform the user in every conversation.
|
// Update the nick for chats, and inform the user in every conversation.
|
||||||
if (conversation.isChat)
|
if (conversation.isChat)
|
||||||
conversation.updateNick(aOldNick, aNewNick);
|
conversation.updateNick(aOldNick, aNewNick, true);
|
||||||
conversation.writeMessage(aOldNick, msg, {system: true});
|
else {
|
||||||
|
conversation.writeMessage(aOldNick, _conv("nickSet.you", aNewNick),
|
||||||
|
{system: true});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
msg = _("message.nick", aOldNick, aNewNick);
|
|
||||||
this.conversations.forEach(conversation => {
|
this.conversations.forEach(conversation => {
|
||||||
if (conversation.isChat && conversation._participants.has(aOldNick)) {
|
if (conversation.isChat && conversation._participants.has(aOldNick)) {
|
||||||
// Update the nick in every chat conversation it is in.
|
// Update the nick in every chat conversation it is in.
|
||||||
conversation.updateNick(aOldNick, aNewNick);
|
conversation.updateNick(aOldNick, aNewNick, false);
|
||||||
conversation.writeMessage(aOldNick, msg, {system: true});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
const EXPORTED_SYMBOLS = ["_", "ctcpFormatToText", "ctcpFormatToHTML",
|
const EXPORTED_SYMBOLS = ["_", "_conv", "ctcpFormatToText", "ctcpFormatToHTML",
|
||||||
"conversationErrorMessage", "kListRefreshInterval"];
|
"conversationErrorMessage", "kListRefreshInterval"];
|
||||||
|
|
||||||
const {classes: Cc, interfaces: Ci} = Components;
|
const {classes: Cc, interfaces: Ci} = Components;
|
||||||
|
@ -13,6 +13,10 @@ XPCOMUtils.defineLazyGetter(this, "_", () =>
|
||||||
l10nHelper("chrome://chat/locale/irc.properties")
|
l10nHelper("chrome://chat/locale/irc.properties")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyGetter(this, "_conv", () =>
|
||||||
|
l10nHelper("chrome://chat/locale/conversations.properties")
|
||||||
|
);
|
||||||
|
|
||||||
XPCOMUtils.defineLazyGetter(this, "TXTToHTML", function() {
|
XPCOMUtils.defineLazyGetter(this, "TXTToHTML", function() {
|
||||||
let cs = Cc["@mozilla.org/txttohtmlconv;1"].getService(Ci.mozITXTToHTMLConv);
|
let cs = Cc["@mozilla.org/txttohtmlconv;1"].getService(Ci.mozITXTToHTMLConv);
|
||||||
return aTXT => cs.scanTXT(aTXT, cs.kEntities);
|
return aTXT => cs.scanTXT(aTXT, cs.kEntities);
|
||||||
|
|
|
@ -249,6 +249,17 @@ const XMPPMUCConversationPrototype = {
|
||||||
let codes = x.getElements(["status"]).map(elt => elt.attributes["code"]);
|
let codes = x.getElements(["status"]).map(elt => elt.attributes["code"]);
|
||||||
let item = x.getElement(["item"]);
|
let item = x.getElement(["item"]);
|
||||||
|
|
||||||
|
// Changes the nickname of a participant for this muc.
|
||||||
|
let changeNick = () => {
|
||||||
|
if (!item || !item.attributes["nick"]) {
|
||||||
|
this.WARN("Received a MUC presence code 303 or 210 stanza without an " +
|
||||||
|
"item element or a nick attribute.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let newNick = item.attributes["nick"];
|
||||||
|
this.updateNick(nick, newNick, nick == this.nick);
|
||||||
|
};
|
||||||
|
|
||||||
if (aStanza.attributes["type"] == "unavailable") {
|
if (aStanza.attributes["type"] == "unavailable") {
|
||||||
if (!this._participants.has(nick)) {
|
if (!this._participants.has(nick)) {
|
||||||
this.WARN("received unavailable presence for an unknown MUC participant: " +
|
this.WARN("received unavailable presence for an unknown MUC participant: " +
|
||||||
|
@ -258,13 +269,7 @@ const XMPPMUCConversationPrototype = {
|
||||||
if (codes.indexOf("303") != -1) {
|
if (codes.indexOf("303") != -1) {
|
||||||
// XEP-0045 (7.6): Changing Nickname.
|
// XEP-0045 (7.6): Changing Nickname.
|
||||||
// Service Updates Nick for user.
|
// Service Updates Nick for user.
|
||||||
if (!item || !item.attributes["nick"]) {
|
changeNick();
|
||||||
this.WARN("Received a MUC presence code 303 stanza without an item " +
|
|
||||||
"element or a nick attribute.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let participant = this._participants.get(nick);
|
|
||||||
participant.name = item.attributes["nick"];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (item && item.attributes["role"] == "none") {
|
if (item && item.attributes["role"] == "none") {
|
||||||
|
@ -350,6 +355,13 @@ const XMPPMUCConversationPrototype = {
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
else if (codes.indexOf("210") != -1) {
|
||||||
|
// XEP-0045 (7.6): Changing Nickname.
|
||||||
|
// Service modifies this user's nickname in accordance with local service
|
||||||
|
// policies.
|
||||||
|
changeNick();
|
||||||
|
return;
|
||||||
|
}
|
||||||
else if (codes.indexOf("110") != -1) {
|
else if (codes.indexOf("110") != -1) {
|
||||||
// XEP-0045: Room exists and joined successfully.
|
// XEP-0045: Room exists and joined successfully.
|
||||||
this.left = false;
|
this.left = false;
|
||||||
|
@ -414,33 +426,6 @@ const XMPPMUCConversationPrototype = {
|
||||||
return this._account.normalizeFullJid(this.name + "/" + aNick);
|
return this._account.normalizeFullJid(this.name + "/" + aNick);
|
||||||
},
|
},
|
||||||
|
|
||||||
// Removes a participant from MUC conversation.
|
|
||||||
removeParticipant: function(aNick) {
|
|
||||||
if (!this._participants.has(aNick))
|
|
||||||
return;
|
|
||||||
|
|
||||||
this._participants.delete(aNick);
|
|
||||||
let nickString = Cc["@mozilla.org/supports-string;1"]
|
|
||||||
.createInstance(Ci.nsISupportsString);
|
|
||||||
nickString.data = aNick;
|
|
||||||
this.notifyObservers(new nsSimpleEnumerator([nickString]),
|
|
||||||
"chat-buddy-remove");
|
|
||||||
},
|
|
||||||
|
|
||||||
// Removes all participant in MUC conversation.
|
|
||||||
removeAllParticipants: function() {
|
|
||||||
let stringNicknames = [];
|
|
||||||
this._participants.forEach(function(aParticipant) {
|
|
||||||
let stringNickname = Cc["@mozilla.org/supports-string;1"]
|
|
||||||
.createInstance(Ci.nsISupportsString);
|
|
||||||
stringNickname.data = aParticipant.name;
|
|
||||||
stringNicknames.push(stringNickname);
|
|
||||||
});
|
|
||||||
this.notifyObservers(new nsSimpleEnumerator(stringNicknames),
|
|
||||||
"chat-buddy-remove");
|
|
||||||
this._participants.clear();
|
|
||||||
},
|
|
||||||
|
|
||||||
// Leaves MUC conversation.
|
// Leaves MUC conversation.
|
||||||
part: function(aMsg = null) {
|
part: function(aMsg = null) {
|
||||||
let s = Stanza.presence({to: this.name + "/" + this._nick, type: "unavailable"},
|
let s = Stanza.presence({to: this.name + "/" + this._nick, type: "unavailable"},
|
||||||
|
|
|
@ -121,23 +121,6 @@ YahooConference.prototype = {
|
||||||
{system: true});
|
{system: true});
|
||||||
},
|
},
|
||||||
|
|
||||||
removeParticipant: function(aName) {
|
|
||||||
// In case we receive two logoff packets, make sure that the user is
|
|
||||||
// actually here before continuing.
|
|
||||||
if (!this._participants.has(aName))
|
|
||||||
return;
|
|
||||||
|
|
||||||
let stringNickname = Cc["@mozilla.org/supports-string;1"]
|
|
||||||
.createInstance(Ci.nsISupportsString);
|
|
||||||
stringNickname.data = aName;
|
|
||||||
this.notifyObservers(new nsSimpleEnumerator([stringNickname]),
|
|
||||||
"chat-buddy-remove");
|
|
||||||
this._participants.delete(aName);
|
|
||||||
this.writeMessage(this._roomName,
|
|
||||||
_("system.message.conferenceLogoff", aName),
|
|
||||||
{system: true});
|
|
||||||
},
|
|
||||||
|
|
||||||
getParticipantNames: function() { return [for (p of this._participants.values()) p.name]; }
|
getParticipantNames: function() { return [for (p of this._participants.values()) p.name]; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -304,6 +287,9 @@ YahooAccount.prototype = {
|
||||||
return;
|
return;
|
||||||
let conf = this._conferences.get(aRoom);
|
let conf = this._conferences.get(aRoom);
|
||||||
conf.removeParticipant(aUsername);
|
conf.removeParticipant(aUsername);
|
||||||
|
conf.writeMessage(this._roomName,
|
||||||
|
_("system.message.conferenceLogoff", aName),
|
||||||
|
{system: true});
|
||||||
},
|
},
|
||||||
|
|
||||||
deleteConference: function(aName) {
|
deleteConference: function(aName) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче