diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index c12c0faa1..aa5d0b9fd 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -56,6 +56,10 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl private static final String ATTRIBUTE_NEXT_MESSAGE_TIMESTAMP = "next_message_timestamp"; private static final String ATTRIBUTE_CRYPTO_TARGETS = "crypto_targets"; private static final String ATTRIBUTE_NEXT_ENCRYPTION = "next_encryption"; + public static final String ATTRIBUTE_ALLOW_PM = "allow_pm"; + public static final String ATTRIBUTE_MEMBERS_ONLY = "members_only"; + public static final String ATTRIBUTE_MODERATED = "moderated"; + public static final String ATTRIBUTE_NON_ANONYMOUS = "non_anonymous"; protected final ArrayList messages = new ArrayList<>(); public AtomicBoolean messagesLoaded = new AtomicBoolean(true); protected Account account = null; @@ -725,6 +729,12 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl return mode == MODE_SINGLE || getBooleanAttribute(ATTRIBUTE_ALWAYS_NOTIFY, Config.ALWAYS_NOTIFY_BY_DEFAULT || isPrivateAndNonAnonymous()); } + public boolean setAttribute(String key, boolean value) { + boolean prev = getBooleanAttribute(key,false); + setAttribute(key,Boolean.toString(value)); + return prev != value; + } + private boolean setAttribute(String key, long value) { return setAttribute(key, Long.toString(value)); } @@ -811,7 +821,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl } } - private boolean getBooleanAttribute(String key, boolean defaultValue) { + public boolean getBooleanAttribute(String key, boolean defaultValue) { String value = this.getAttribute(key); if (value == null) { return defaultValue; diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index eb7c8b68e..3dd0b183a 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -58,7 +58,7 @@ public class MucOptions { public void resetChatState() { synchronized (users) { - for(User user : users) { + for (User user : users) { user.chatState = Config.DEFAULT_CHATSTATE; } } @@ -100,10 +100,10 @@ public class MucOptions { } public enum Role { - MODERATOR("moderator", R.string.moderator,3), - VISITOR("visitor", R.string.visitor,1), - PARTICIPANT("participant", R.string.participant,2), - NONE("none", R.string.no_role,0); + MODERATOR("moderator", R.string.moderator, 3), + VISITOR("visitor", R.string.visitor, 1), + PARTICIPANT("participant", R.string.participant, 2), + NONE("none", R.string.no_role, 0); Role(String string, int resId, int rank) { this.string = string; @@ -256,7 +256,7 @@ public class MucOptions { public Contact getContact() { if (fullJid != null) { return getAccount().getRoster().getContactFromRoster(realJid); - } else if (realJid != null){ + } else if (realJid != null) { return getAccount().getRoster().getContact(realJid); } else { return null; @@ -314,7 +314,7 @@ public class MucOptions { @Override public String toString() { - return "[fulljid:"+String.valueOf(fullJid)+",realjid:"+String.valueOf(realJid)+",affiliation"+affiliation.toString()+"]"; + return "[fulljid:" + String.valueOf(fullJid) + ",realjid:" + String.valueOf(realJid) + ",affiliation" + affiliation.toString() + "]"; } public boolean realJidMatchesAccount() { @@ -370,15 +370,27 @@ public class MucOptions { public MucOptions(Conversation conversation) { this.account = conversation.getAccount(); this.conversation = conversation; - this.self = new User(this,createJoinJid(getProposedNick())); + this.self = new User(this, createJoinJid(getProposedNick())); } - public void updateFeatures(ArrayList features) { + public boolean updateConfiguration(List features, Data data) { + updateFeatures(features); + updateFormData(data == null ? new Data() : data); + Field allowPmField = this.form.getFieldByName("muc#roomconfig_allowpm"); + boolean changed = false; + changed |= conversation.setAttribute(Conversation.ATTRIBUTE_ALLOW_PM, allowPmField == null || "1".equals(allowPmField.getValue())); + changed |= conversation.setAttribute(Conversation.ATTRIBUTE_MEMBERS_ONLY, this.hasFeature("muc_membersonly")); + changed |= conversation.setAttribute(Conversation.ATTRIBUTE_MODERATED, this.hasFeature("muc_moderated")); + changed |= conversation.setAttribute(Conversation.ATTRIBUTE_NON_ANONYMOUS, this.hasFeature("muc_nonanonymous")); + return changed; + } + + private void updateFeatures(List features) { this.features.clear(); this.features.addAll(features); } - public void updateFormData(Data form) { + private void updateFormData(Data form) { this.form = form; } @@ -397,8 +409,7 @@ public class MucOptions { } public boolean allowPm() { - Field field = this.form.getFieldByName("muc#roomconfig_allowpm"); - return field == null || "1".equals(field.getValue()); + return conversation.getBooleanAttribute(Conversation.ATTRIBUTE_ALLOW_PM, false); } public boolean participating() { @@ -408,7 +419,7 @@ public class MucOptions { } public boolean membersOnly() { - return hasFeature("muc_membersonly"); + return conversation.getBooleanAttribute(Conversation.ATTRIBUTE_MEMBERS_ONLY, false); } public boolean mamSupport() { @@ -420,19 +431,15 @@ public class MucOptions { } public boolean nonanonymous() { - return hasFeature("muc_nonanonymous"); + return conversation.getBooleanAttribute(Conversation.ATTRIBUTE_NON_ANONYMOUS, false); } public boolean isPrivateAndNonAnonymous() { return membersOnly() && nonanonymous(); } - public boolean persistent() { - return hasFeature("muc_persistent"); - } - public boolean moderated() { - return hasFeature("muc_moderated"); + return conversation.getBooleanAttribute(Conversation.ATTRIBUTE_MODERATED, false); } public User deleteUser(Jid jid) { @@ -497,7 +504,7 @@ public class MucOptions { boolean fullJidIsSelf = isOnline && user.getFullJid() != null && user.getFullJid().equals(self.getFullJid()); if ((!membersOnly() || user.getAffiliation().ranks(Affiliation.MEMBER)) && user.getAffiliation().outranks(Affiliation.OUTCAST) - && !fullJidIsSelf){ + && !fullJidIsSelf) { this.users.add(user); return !realJidFound && user.realJid != null; } @@ -537,7 +544,7 @@ public class MucOptions { if (readByMarker.getRealJid() != null) { User user = findUserByRealJid(readByMarker.getRealJid().asBareJid()); if (user == null) { - user = new User(this,readByMarker.getFullJid()); + user = new User(this, readByMarker.getFullJid()); user.setRealJid(readByMarker.getRealJid()); } return user; @@ -590,7 +597,7 @@ public class MucOptions { public ArrayList getUsersWithChatState(ChatState state, int max) { synchronized (users) { ArrayList list = new ArrayList<>(); - for(User user : users) { + for (User user : users) { if (user.chatState == state) { list.add(user); if (list.size() >= max) { @@ -607,7 +614,7 @@ public class MucOptions { HashSet jids = new HashSet<>(); jids.add(account.getJid().asBareJid()); synchronized (users) { - for(User user : users) { + for (User user : users) { if (user.getRealJid() == null || jids.add(user.getRealJid())) { subset.add(user); } @@ -670,7 +677,7 @@ public class MucOptions { } public boolean setSubject(String subject) { - return this.conversation.setAttribute("subject",subject); + return this.conversation.setAttribute("subject", subject); } public String getSubject() { @@ -679,8 +686,8 @@ public class MucOptions { public List getFallbackUsersFromCryptoTargets() { List users = new ArrayList<>(); - for(Jid jid : conversation.getAcceptedCryptoTargets()) { - User user = new User(this,null); + for (Jid jid : conversation.getAcceptedCryptoTargets()) { + User user = new User(this, null); user.setRealJid(jid); users.add(user); } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index bc7a4617f..312319c43 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -2510,14 +2510,14 @@ public class XmppConnectionService extends Service { } } Element form = query.findChild("x", Namespace.DATA); - if (form != null) { - conversation.getMucOptions().updateFormData(Data.parse(form)); + Data data = form == null ? null : Data.parse(form); + if (conversation.getMucOptions().updateConfiguration(features, data)) { + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": muc configuration changed for " + conversation.getJid().asBareJid()); + updateConversation(conversation); } - conversation.getMucOptions().updateFeatures(features); if (callback != null) { callback.onConferenceConfigurationFetched(conversation); } - Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": fetched muc configuration for " + conversation.getJid().asBareJid() + " - " + features.toString()); updateConversationUi(); } else if (packet.getType() == IqPacket.TYPE.ERROR) { if (callback != null) {