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