diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index 3b3d3d900..0b288ee77 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -55,7 +55,6 @@ 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"; @@ -478,10 +477,13 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl public @NonNull CharSequence getName() { if (getMode() == MODE_MULTI) { + final String roomName = getMucOptions().getName(); final String subject = getMucOptions().getSubject(); final Bookmark bookmark = getBookmark(); final String bookmarkName = bookmark != null ? bookmark.getBookmarkName() : null; - if (printableValue(subject)) { + if (printableValue(roomName)) { + return roomName; + } else if (printableValue(subject)) { return subject; } else if (printableValue(bookmarkName, false)) { return bookmarkName; @@ -739,10 +741,20 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl public boolean setAttribute(String key, String value) { synchronized (this.attributes) { try { - this.attributes.put(key, value == null ? "" : value); - return true; + if (value == null) { + if (this.attributes.has(key)) { + this.attributes.remove(key); + return true; + } else { + return false; + } + } else { + String prev = this.attributes.getString(key); + this.attributes.put(key, value); + return !value.equals(prev); + } } catch (JSONException e) { - return false; + throw new AssertionError(e); } } } diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index 836f33b64..7243a54d0 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -1,9 +1,10 @@ package eu.siacs.conversations.entities; import android.annotation.SuppressLint; -import android.util.Log; +import android.support.annotation.NonNull; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -323,7 +324,7 @@ public class MucOptions { } @Override - public int compareTo(User another) { + public int compareTo(@NonNull User another) { if (another.getAffiliation().outranks(getAffiliation())) { return 1; } else if (getAffiliation().outranks(another.getAffiliation())) { @@ -359,8 +360,7 @@ public class MucOptions { private Account account; private final Set users = new HashSet<>(); - private final List features = new ArrayList<>(); - private Data form = new Data(); + private ServiceDiscoveryResult serviceDiscoveryResult; private final Conversation conversation; private boolean isOnline = false; private Error error = Error.NONE; @@ -374,34 +374,40 @@ public class MucOptions { this.self = new User(this, createJoinJid(getProposedNick())); } - public boolean updateConfiguration(List features, String name, 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())); + public boolean updateConfiguration(ServiceDiscoveryResult serviceDiscoveryResult) { + this.serviceDiscoveryResult = serviceDiscoveryResult; + String name; + Field roomInfoName = getRoomInfoForm().getFieldByName("muc#roominfo_name"); + if (roomInfoName != null) { + name = roomInfoName.getValue(); + } else { + List identities = serviceDiscoveryResult.getIdentities(); + String identityName = identities.size() > 0 ? identities.get(0).getName() : null; + if (!conversation.getJid().getEscapedLocal().equals(identityName)) { + name = identityName; + } else { + name = null; + } + } + boolean changed = conversation.setAttribute("muc_name", name); 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")); - changed |= setName(name); return changed; } - private void updateFeatures(List features) { - this.features.clear(); - this.features.addAll(features); + + private Data getRoomInfoForm() { + final List forms = serviceDiscoveryResult == null ? Collections.emptyList() : serviceDiscoveryResult.forms; + return forms.size() == 0 ? new Data() : forms.get(0); } public String getAvatar() { return account.getRoster().getContact(conversation.getJid()).getAvatar(); } - private void updateFormData(Data form) { - this.form = form; - } - public boolean hasFeature(String feature) { - return this.features.contains(feature); + return this.serviceDiscoveryResult != null && this.serviceDiscoveryResult.features.contains(feature); } public boolean hasVCards() { @@ -409,17 +415,18 @@ public class MucOptions { } public boolean canInvite() { - Field field = this.form.getFieldByName("muc#roomconfig_allowinvites"); + Field field = getRoomInfoForm().getFieldByName("muc#roominfo_allowinvites"); return !membersOnly() || self.getRole().ranks(Role.MODERATOR) || (field != null && "1".equals(field.getValue())); } public boolean canChangeSubject() { - Field field = this.form.getFieldByName("muc#roomconfig_changesubject"); + Field field = getRoomInfoForm().getFieldByName("muc#roominfo_changesubject"); return self.getRole().ranks(Role.MODERATOR) || (field != null && "1".equals(field.getValue())); } public boolean allowPm() { - return conversation.getBooleanAttribute(Conversation.ATTRIBUTE_ALLOW_PM, false); + Field field = getRoomInfoForm().getFieldByName("muc#roominfo_allowpm"); + return field != null && "1".equals(field.getValue()); } public boolean participating() { @@ -694,15 +701,12 @@ public class MucOptions { return this.conversation.getAttribute("subject"); } - private boolean setName(String name) { - return this.conversation.setAttribute("muc_name", name); - } - public String getName() { - return this.conversation.getAttribute("muc_name"); + String mucName = this.conversation.getAttribute("muc_name"); + return conversation.getJid().getEscapedLocal().equals(mucName) ? null : mucName; } - public List getFallbackUsersFromCryptoTargets() { + private List getFallbackUsersFromCryptoTargets() { List users = new ArrayList<>(); for (Jid jid : conversation.getAcceptedCryptoTargets()) { User user = new User(this, null); diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 1fb43f189..7cb31b33e 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -2447,23 +2447,8 @@ public class XmppConnectionService extends Service { sendIqPacket(conversation.getAccount(), request, new OnIqPacketReceived() { @Override public void onIqPacketReceived(Account account, IqPacket packet) { - Element query = packet.findChild("query", "http://jabber.org/protocol/disco#info"); - if (packet.getType() == IqPacket.TYPE.RESULT && query != null) { - String name = null; - ArrayList features = new ArrayList<>(); - for (Element child : query.getChildren()) { - if (child.getName().equals("feature")) { - String var = child.getAttribute("var"); - if (var != null) { - features.add(var); - } - } else if (child.getName().equals("identity")) { - name = child.getAttribute("name"); - } - } - Element form = query.findChild("x", Namespace.DATA); - Data data = form == null ? null : Data.parse(form); - if (conversation.getMucOptions().updateConfiguration(features, name, data)) { + if (packet.getType() == IqPacket.TYPE.RESULT) { + if (conversation.getMucOptions().updateConfiguration(new ServiceDiscoveryResult(packet))) { Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": muc configuration changed for " + conversation.getJid().asBareJid()); updateConversation(conversation); } diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index b67a132f5..19fe52c2b 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -50,6 +50,8 @@ import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.utils.XmppUri; import rocks.xmpp.addr.Jid; +import static eu.siacs.conversations.entities.Bookmark.printableValue; + public class ConferenceDetailsActivity extends XmppActivity implements OnConversationUpdate, OnMucRosterUpdate, XmppConnectionService.OnAffiliationChanged, XmppConnectionService.OnRoleChanged, XmppConnectionService.OnConfigurationPushed { public static final String ACTION_VIEW_MUC = "view_muc"; @@ -533,8 +535,23 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers this.binding.detailsAccount.setText(getString(R.string.using_account, account)); this.binding.jid.setText(mConversation.getJid().asBareJid().toEscapedString()); this.binding.yourPhoto.setImageBitmap(avatarService().get(mConversation, getPixel(72))); - this.binding.mucTitle.setText(mucOptions.getName()); - this.binding.mucSubject.setText(mucOptions.getSubject()); + String roomName = mucOptions.getName(); + String subject = mucOptions.getSubject(); + if (printableValue(roomName)) { + this.binding.mucTitle.setText(roomName); + this.binding.mucTitle.setVisibility(View.VISIBLE); + } else if (!printableValue(subject)) { + this.binding.mucTitle.setText(mConversation.getName()); + this.binding.mucTitle.setVisibility(View.VISIBLE); + } else { + this.binding.mucTitle.setVisibility(View.GONE); + } + if (printableValue(subject)) { + this.binding.mucSubject.setText(mucOptions.getSubject()); + this.binding.mucSubject.setVisibility(View.VISIBLE); + } else { + this.binding.mucSubject.setVisibility(View.GONE); + } this.binding.mucYourNick.setText(mucOptions.getActualNick()); if (mucOptions.online()) { this.binding.mucMoreDetails.setVisibility(View.VISIBLE);