diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java
index 9e8f376a4..727b06226 100644
--- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java
+++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java
@@ -167,6 +167,7 @@ public class MucOptions {
RESOURCE_CONSTRAINT,
KICKED,
SHUTDOWN,
+ DESTROYED,
INVALID_NICK,
UNKNOWN
}
diff --git a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java
index 333a95899..062f87b7f 100644
--- a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java
+++ b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java
@@ -20,6 +20,7 @@ import eu.siacs.conversations.entities.Presence;
import eu.siacs.conversations.generator.IqGenerator;
import eu.siacs.conversations.generator.PresenceGenerator;
import eu.siacs.conversations.services.XmppConnectionService;
+import eu.siacs.conversations.utils.XmppUri;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xml.Namespace;
import eu.siacs.conversations.xmpp.InvalidJid;
@@ -125,7 +126,15 @@ public class PresenceParser extends AbstractParser implements
}
}
} else if (type.equals("unavailable")) {
- if (codes.contains(MucOptions.STATUS_CODE_SHUTDOWN) && from.equals(mucOptions.getSelf().getFullJid())) {
+ final boolean fullJidMatches = from.equals(mucOptions.getSelf().getFullJid());
+ if (x.hasChild("destroy") && fullJidMatches) {
+ Element destroy = x.findChild("destroy");
+ final Jid alternate = destroy == null ? null : InvalidJid.getNullForInvalid(destroy.getAttributeAsJid("jid"));
+ mucOptions.setError(MucOptions.Error.DESTROYED);
+ if (alternate != null) {
+ Log.d(Config.LOGTAG, conversation.getAccount().getJid().asBareJid() + ": muc destroyed. alternate location " + alternate);
+ }
+ } else if (codes.contains(MucOptions.STATUS_CODE_SHUTDOWN) && fullJidMatches) {
mucOptions.setError(MucOptions.Error.SHUTDOWN);
} else if (codes.contains(MucOptions.STATUS_CODE_SELF_PRESENCE)) {
if (codes.contains(MucOptions.STATUS_CODE_KICKED)) {
@@ -171,6 +180,23 @@ public class PresenceParser extends AbstractParser implements
mucOptions.setError(MucOptions.Error.MEMBERS_ONLY);
} else if (error.hasChild("resource-constraint")) {
mucOptions.setError(MucOptions.Error.RESOURCE_CONSTRAINT);
+ } else if (error.hasChild("gone")) {
+ final String gone = error.findChildContent("gone");
+ final Jid alternate;
+ if (gone != null) {
+ final XmppUri xmppUri = new XmppUri(gone);
+ if (xmppUri.isJidValid()) {
+ alternate = xmppUri.getJid();
+ } else {
+ alternate = null;
+ }
+ } else {
+ alternate = null;
+ }
+ mucOptions.setError(MucOptions.Error.DESTROYED);
+ if (alternate != null) {
+ Log.d(Config.LOGTAG, conversation.getAccount().getJid().asBareJid() + ": muc destroyed. alternate location " + alternate);
+ }
} else {
final String text = error.findChildContent("text");
if (text != null && text.contains("attribute 'to'")) {
diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
index 264469ec0..86efe38fa 100644
--- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
+++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
@@ -2034,6 +2034,9 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
case SHUTDOWN:
showSnackbar(R.string.conference_shutdown, R.string.try_again, joinMuc);
break;
+ case DESTROYED:
+ showSnackbar(R.string.conference_destroyed, R.string.leave, leaveMuc);
+ break;
default:
hideSnackbar();
break;
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 8942a7f49..7d6edd221 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -721,4 +721,5 @@
Name
Providing a name is optional
Group chat name
+ This group chat has been destroyed