Bug 1014472 - Support automatic MUC reconnection for all protocols. r=clokep, florian
This commit is contained in:
Родитель
d1f16207c4
Коммит
0f0c5d9fa6
|
@ -11,6 +11,7 @@ interface imIAccountBuddy;
|
|||
interface imIAccount;
|
||||
interface nsIURI;
|
||||
interface nsIDOMDocument;
|
||||
interface prplIChatRoomFieldValues;
|
||||
|
||||
/*
|
||||
* This is the XPCOM purple conversation component, a proxy for PurpleConversation.
|
||||
|
@ -86,7 +87,7 @@ interface prplIConvIM: prplIConversation {
|
|||
readonly attribute short typingState;
|
||||
};
|
||||
|
||||
[scriptable, uuid(91ad2ce5-f886-4653-ac75-ac22bed4ec7a)]
|
||||
[scriptable, uuid(47b42861-364a-477d-88a1-4616a7060df2)]
|
||||
interface prplIConvChat: prplIConversation {
|
||||
|
||||
/* Get an nsISimpleEnumerator of prplIConvChatBuddy objects:
|
||||
|
@ -119,6 +120,12 @@ interface prplIConvChat: prplIConversation {
|
|||
/* This is true if we are in the process of joining the channel */
|
||||
readonly attribute boolean joining;
|
||||
|
||||
/* This stores the data required to join the chat with joinChat().
|
||||
If null, the chat will not be rejoined automatically when the
|
||||
account reconnects after a disconnect.
|
||||
Should be set to null by the prpl if the user parts the chat. */
|
||||
readonly attribute prplIChatRoomFieldValues chatRoomFields;
|
||||
|
||||
/* Observers will receive chat-buddy-add, chat-buddy-update,
|
||||
chat-buddy-remove and chat-update-topic notifications.
|
||||
|
||||
|
|
|
@ -248,14 +248,24 @@ UIConversation.prototype = {
|
|||
connected: function() {
|
||||
if (this._disconnected) {
|
||||
delete this._disconnected;
|
||||
if (!this.isChat)
|
||||
let msg = bundle.GetStringFromName("accountReconnected");
|
||||
if (this.isChat) {
|
||||
if (!this._wasLeft) {
|
||||
this.systemMessage(msg);
|
||||
// Reconnect chat if possible.
|
||||
let chatRoomFields = this.target.chatRoomFields;
|
||||
if (chatRoomFields)
|
||||
this.account.joinChat(chatRoomFields);
|
||||
}
|
||||
delete this._wasLeft;
|
||||
}
|
||||
else {
|
||||
this._justReconnected = true;
|
||||
// Exclude convs with contacts, these receive presence info updates
|
||||
// (and therefore a reconnected message).
|
||||
if ((this.isChat && !this._wasLeft) ||
|
||||
(!this.isChat && !this.contact))
|
||||
this.systemMessage(bundle.GetStringFromName("accountReconnected"));
|
||||
delete this._wasLeft;
|
||||
// Exclude convs with contacts, these receive presence info updates
|
||||
// (and therefore a reconnected message).
|
||||
if (!this.contact)
|
||||
this.systemMessage(msg);
|
||||
}
|
||||
}
|
||||
this.notifyObservers(this, "update-buddy-status");
|
||||
},
|
||||
|
|
|
@ -531,6 +531,11 @@ const GenericConvChatPrototype = {
|
|||
|
||||
get isChat() true,
|
||||
|
||||
// Stores the prplIChatRoomFieldValues required to join this channel
|
||||
// to enable later reconnections. If null, the MUC will not be reconnected
|
||||
// automatically after disconnections.
|
||||
chatRoomFields: null,
|
||||
|
||||
_topic: "",
|
||||
_topicSetter: null,
|
||||
get topic() this._topic,
|
||||
|
|
|
@ -288,11 +288,6 @@ ircChannel.prototype = {
|
|||
aProperties);
|
||||
},
|
||||
|
||||
// Stores the prplIChatRoomFieldValues required to join this channel
|
||||
// to enable later reconnections. If absent, the MUC will not be reconnected
|
||||
// automatically after disconnections.
|
||||
_chatRoomFields: null,
|
||||
|
||||
// Section 3.2.2 of RFC 2812.
|
||||
part: function(aMessage) {
|
||||
let params = [this.name];
|
||||
|
@ -306,7 +301,7 @@ ircChannel.prototype = {
|
|||
this._account.sendMessage("PART", params);
|
||||
|
||||
// Remove reconnection information.
|
||||
delete this._chatRoomFields;
|
||||
delete this.chatRoomFields;
|
||||
},
|
||||
|
||||
close: function() {
|
||||
|
@ -446,8 +441,8 @@ ircChannel.prototype = {
|
|||
let key = getNextParam();
|
||||
// A new channel key was set, display a message if this key is not
|
||||
// already known.
|
||||
if (this._chatRoomFields &&
|
||||
this._chatRoomFields.getValue("password") == key) {
|
||||
if (this.chatRoomFields &&
|
||||
this.chatRoomFields.getValue("password") == key) {
|
||||
continue;
|
||||
}
|
||||
msg = _("message.channelKeyAdded", aSetter, key);
|
||||
|
@ -458,7 +453,7 @@ ircChannel.prototype = {
|
|||
|
||||
this.writeMessage(aSetter, msg, {system: true});
|
||||
// Store the new fields for reconnect.
|
||||
this._chatRoomFields =
|
||||
this.chatRoomFields =
|
||||
this._account.getChatRoomDefaultFieldValues(newFields);
|
||||
}
|
||||
else if (aNewMode[i] == "b") {
|
||||
|
@ -1450,15 +1445,19 @@ ircAccount.prototype = {
|
|||
let key = aComponents.getValue("password");
|
||||
if (key)
|
||||
params.push(key);
|
||||
let defaultName = key ? channel + " " + key : channel;
|
||||
|
||||
// Send the join command, but don't log the channel key.
|
||||
this.sendMessage("JOIN", params,
|
||||
"JOIN " + channel + (key ? " <key not logged>" : ""));
|
||||
|
||||
// Open conversation early for better responsiveness.
|
||||
let conv = this.getConversation(channel);
|
||||
// Store the prplIChatRoomFieldValues to enable later reconnections.
|
||||
conv._chatRoomFields = this.getChatRoomDefaultFieldValues(defaultName);
|
||||
conv.joining = true;
|
||||
|
||||
// Store the prplIChatRoomFieldValues to enable later reconnections.
|
||||
let defaultName = key ? channel + " " + key : channel;
|
||||
conv.chatRoomFields = this.getChatRoomDefaultFieldValues(defaultName);
|
||||
|
||||
return conv;
|
||||
},
|
||||
|
||||
|
|
|
@ -177,19 +177,19 @@ var ircBase = {
|
|||
conversation.joining = false;
|
||||
|
||||
// If the user parted from this room earlier, confirm the rejoin.
|
||||
// If conversation._chatRoomFields is present, the rejoin was due to
|
||||
// If conversation.chatRoomFields is present, the rejoin was due to
|
||||
// an automatic reconnection, for which we already notify the user.
|
||||
if (!conversation._firstJoin && !conversation._chatRoomFields) {
|
||||
if (!conversation._firstJoin && !conversation.chatRoomFields) {
|
||||
conversation.writeMessage(aMessage.nickname, _("message.rejoined"),
|
||||
{system: true});
|
||||
}
|
||||
delete conversation._firstJoin;
|
||||
|
||||
// Ensure chatRoomFields information is available for reconnection.
|
||||
if (!conversation._chatRoomFields) {
|
||||
if (!conversation.chatRoomFields) {
|
||||
this.WARN("Opening a MUC without storing its " +
|
||||
"prplIChatRoomFieldValues first.");
|
||||
conversation._chatRoomFields =
|
||||
conversation.chatRoomFields =
|
||||
this.getChatRoomDefaultFieldValues(channelName);
|
||||
}
|
||||
}
|
||||
|
@ -323,7 +323,6 @@ var ircBase = {
|
|||
},
|
||||
"001": function(aMessage) { // RPL_WELCOME
|
||||
// Welcome to the Internet Relay Network <nick>!<user>@<host>
|
||||
this.reportConnected();
|
||||
this._socket.resetPingTimer();
|
||||
this._currentServerName = aMessage.servername;
|
||||
|
||||
|
@ -345,12 +344,8 @@ var ircBase = {
|
|||
// Check if any of our buddies are online!
|
||||
this.sendIsOn();
|
||||
|
||||
// Reconnect channels if they were not parted by the user.
|
||||
this.conversations.forEach(conversation => {
|
||||
if (conversation.isChat && conversation._chatRoomFields)
|
||||
this.joinChat(conversation._chatRoomFields);
|
||||
});
|
||||
|
||||
// Done!
|
||||
this.reportConnected();
|
||||
return serverMessage(this, aMessage);
|
||||
},
|
||||
"002": function(aMessage) { // RPL_YOURHOST
|
||||
|
|
|
@ -205,10 +205,10 @@ var commands = [
|
|||
if (!conv.isChat || !conv.left)
|
||||
return false;
|
||||
// Rejoin the current channel. If the channel was explicitly parted
|
||||
// by the user, _chatRoomFields will have been deleted.
|
||||
// by the user, chatRoomFields will have been deleted.
|
||||
// Otherwise, make use of it (e.g. if the user was kicked).
|
||||
if (conv._chatRoomFields) {
|
||||
account.joinChat(conv._chatRoomFields);
|
||||
if (conv.chatRoomFields) {
|
||||
account.joinChat(conv.chatRoomFields);
|
||||
return true;
|
||||
}
|
||||
params = [conv.name];
|
||||
|
|
|
@ -231,9 +231,9 @@ function conversationErrorMessage(aAccount, aMessage, aError,
|
|||
if (aJoinFailed)
|
||||
conv.joining = false;
|
||||
// If the conversation cannot be rejoined automatically, delete
|
||||
// _chatRoomFields.
|
||||
// chatRoomFields.
|
||||
if (!aRejoinable)
|
||||
delete conv._chatRoomFields;
|
||||
delete conv.chatRoomFields;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -653,7 +653,7 @@ const XMPPAccountPrototype = {
|
|||
this._mucs[jid].left = false; // We are rejoining.
|
||||
}
|
||||
else
|
||||
this._mucs[jid] = nick;
|
||||
this._mucs[jid] = aComponents;
|
||||
|
||||
let x;
|
||||
let password = aComponents.getValue("password");
|
||||
|
@ -848,15 +848,17 @@ const XMPPAccountPrototype = {
|
|||
else if (jid in this._buddies)
|
||||
this._buddies[jid].onPresenceStanza(aStanza);
|
||||
else if (jid in this._mucs) {
|
||||
if (typeof(this._mucs[jid]) == "string") {
|
||||
if (this._mucs[jid] instanceof Ci.prplIChatRoomFieldValues) {
|
||||
// We have attempted to join, but not created the conversation yet.
|
||||
if (aStanza.attributes["type"] == "error") {
|
||||
delete this._mucs[jid];
|
||||
this.ERROR("Failed to join MUC: " + aStanza.convertToString());
|
||||
return;
|
||||
}
|
||||
let nick = this._mucs[jid];
|
||||
let chatRoomFields = this._mucs[jid];
|
||||
let nick = chatRoomFields.getValue("nick");
|
||||
this._mucs[jid] = new this._MUCConversationConstructor(this, jid, nick);
|
||||
this._mucs[jid].chatRoomFields = chatRoomFields;
|
||||
}
|
||||
this._mucs[jid].onPresenceStanza(aStanza);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче