keep conference members in memory and show them in conference details

This commit is contained in:
Daniel Gultsch 2016-05-16 14:10:40 +02:00
parent d7c5264ad0
commit 8d0693ed6a
10 changed files with 186 additions and 99 deletions

View file

@ -643,7 +643,6 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
jids = Arrays.asList(conversation.getJid().toBareJid()); jids = Arrays.asList(conversation.getJid().toBareJid());
} else { } else {
jids = conversation.getMucOptions().getMembers(); jids = conversation.getMucOptions().getMembers();
jids.remove(account.getJid().toBareJid());
} }
return jids; return jids;
} }

View file

@ -5,9 +5,7 @@ import android.annotation.SuppressLint;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import eu.siacs.conversations.R; import eu.siacs.conversations.R;
@ -28,6 +26,15 @@ public class MucOptions {
this.self = user; this.self = user;
} }
public void changeAffiliation(Jid jid, Affiliation affiliation) {
User user = findUserByRealJid(jid);
if (user != null) {
users.remove(user);
user.affiliation = affiliation;
users.add(user);
}
}
public enum Affiliation { public enum Affiliation {
OWNER("owner", 4, R.string.owner), OWNER("owner", 4, R.string.owner),
ADMIN("admin", 3, R.string.admin), ADMIN("admin", 3, R.string.admin),
@ -127,7 +134,7 @@ public class MucOptions {
public static class User { public static class User {
private Role role = Role.NONE; private Role role = Role.NONE;
private Affiliation affiliation = Affiliation.NONE; private Affiliation affiliation = Affiliation.NONE;
private Jid jid; private Jid realJid;
private Jid fullJid; private Jid fullJid;
private long pgpKeyId = 0; private long pgpKeyId = 0;
private Avatar avatar; private Avatar avatar;
@ -139,15 +146,15 @@ public class MucOptions {
} }
public String getName() { public String getName() {
return this.fullJid.getResourcepart(); return fullJid == null ? null : fullJid.getResourcepart();
} }
public void setJid(Jid jid) { public void setRealJid(Jid jid) {
this.jid = jid; this.realJid = jid != null ? jid.toBareJid() : null;
} }
public Jid getJid() { public Jid getRealJid() {
return this.jid; return this.realJid;
} }
public Role getRole() { public Role getRole() {
@ -155,6 +162,10 @@ public class MucOptions {
} }
public void setRole(String role) { public void setRole(String role) {
if (role == null) {
this.role = Role.NONE;
return;
}
role = role.toLowerCase(); role = role.toLowerCase();
switch (role) { switch (role) {
case "moderator": case "moderator":
@ -172,26 +183,15 @@ public class MucOptions {
} }
} }
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
} else if (!(other instanceof User)) {
return false;
} else {
User o = (User) other;
return getName() != null && getName().equals(o.getName())
&& jid != null && jid.equals(o.jid)
&& affiliation == o.affiliation
&& role == o.role;
}
}
public Affiliation getAffiliation() { public Affiliation getAffiliation() {
return this.affiliation; return this.affiliation;
} }
public void setAffiliation(String affiliation) { public void setAffiliation(String affiliation) {
if (affiliation == null) {
this.affiliation = Affiliation.NONE;
return;
}
affiliation = affiliation.toLowerCase(); affiliation = affiliation.toLowerCase();
switch (affiliation) { switch (affiliation) {
case "admin": case "admin":
@ -220,7 +220,7 @@ public class MucOptions {
} }
public Contact getContact() { public Contact getContact() {
return getAccount().getRoster().getContactFromRoster(getJid()); return getAccount().getRoster().getContactFromRoster(getRealJid());
} }
public boolean setAvatar(Avatar avatar) { public boolean setAvatar(Avatar avatar) {
@ -243,11 +243,39 @@ public class MucOptions {
public Jid getFullJid() { public Jid getFullJid() {
return fullJid; return fullJid;
} }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
if (role != user.role) return false;
if (affiliation != user.affiliation) return false;
if (realJid != null ? !realJid.equals(user.realJid) : user.realJid != null)
return false;
return fullJid != null ? fullJid.equals(user.fullJid) : user.fullJid == null;
}
@Override
public int hashCode() {
int result = role != null ? role.hashCode() : 0;
result = 31 * result + (affiliation != null ? affiliation.hashCode() : 0);
result = 31 * result + (realJid != null ? realJid.hashCode() : 0);
result = 31 * result + (fullJid != null ? fullJid.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "[fulljid:"+String.valueOf(fullJid)+",realjid:"+String.valueOf(realJid)+",affiliation"+affiliation.toString()+"]";
}
} }
private Account account; private Account account;
private final Map<String, User> users = Collections.synchronizedMap(new LinkedHashMap<String, User>()); private final Set<User> users = Collections.synchronizedSet(new HashSet<User>());
private final Set<Jid> members = Collections.synchronizedSet(new HashSet<Jid>());
private final List<String> features = new ArrayList<>(); private final List<String> features = new ArrayList<>();
private Data form = new Data(); private Data form = new Data();
private Conversation conversation; private Conversation conversation;
@ -315,20 +343,66 @@ public class MucOptions {
return hasFeature("muc_moderated"); return hasFeature("muc_moderated");
} }
public User deleteUser(String name) { public User deleteUser(Jid jid) {
return this.users.remove(name); User user = findUserByFullJid(jid);
if (user != null) {
users.remove(user);
if (user.affiliation.ranks(Affiliation.MEMBER)) {
user.role = Role.NONE;
user.avatar = null;
user.fullJid = null;
users.add(user);
}
}
return user;
} }
public void addUser(User user) { public void addUser(User user) {
this.users.put(user.getName(), user); User old;
if (user.fullJid == null && user.realJid != null) {
old = findUserByRealJid(user.realJid);
if (old != null) {
return; //don't add. user already exists
}
} else if (user.realJid != null) {
old = findUserByRealJid(user.realJid);
if (old != null && old.fullJid == null) {
users.remove(old);
}
}
old = findUserByFullJid(user.getFullJid());
if (old != null) {
users.remove(old);
}
this.users.add(user);
} }
public User findUser(String name) { public User findUserByFullJid(Jid jid) {
return this.users.get(name); if (jid == null) {
return null;
}
for(User user : users) {
if (jid.equals(user.getFullJid())) {
return user;
}
}
return null;
} }
public boolean isUserInRoom(String name) { public User findUserByRealJid(Jid jid) {
return findUser(name) != null; if (jid == null) {
return null;
}
for(User user : users) {
if (jid.equals(user.getRealJid())) {
return user;
}
}
return null;
}
public boolean isUserInRoom(Jid jid) {
return findUserByFullJid(jid) != null;
} }
public void setError(Error error) { public void setError(Error error) {
@ -341,7 +415,7 @@ public class MucOptions {
} }
public ArrayList<User> getUsers() { public ArrayList<User> getUsers() {
return new ArrayList<>(users.values()); return new ArrayList<>(users);
} }
public List<User> getUsers(int max) { public List<User> getUsers(int max) {
@ -410,7 +484,7 @@ public class MucOptions {
Contact contact = user.getContact(); Contact contact = user.getContact();
if (contact != null && !contact.getDisplayName().isEmpty()) { if (contact != null && !contact.getDisplayName().isEmpty()) {
names.add(contact.getDisplayName().split("\\s+")[0]); names.add(contact.getDisplayName().split("\\s+")[0]);
} else { } else if (user.getName() != null){
names.add(user.getName()); names.add(user.getName());
} }
} }
@ -429,7 +503,7 @@ public class MucOptions {
public long[] getPgpKeyIds() { public long[] getPgpKeyIds() {
List<Long> ids = new ArrayList<>(); List<Long> ids = new ArrayList<>();
for (User user : this.users.values()) { for (User user : this.users) {
if (user.getPgpKeyId() != 0) { if (user.getPgpKeyId() != 0) {
ids.add(user.getPgpKeyId()); ids.add(user.getPgpKeyId());
} }
@ -443,7 +517,7 @@ public class MucOptions {
} }
public boolean pgpKeysInUse() { public boolean pgpKeysInUse() {
for (User user : this.users.values()) { for (User user : this.users) {
if (user.getPgpKeyId() != 0) { if (user.getPgpKeyId() != 0) {
return true; return true;
} }
@ -452,7 +526,7 @@ public class MucOptions {
} }
public boolean everybodyHasKeys() { public boolean everybodyHasKeys() {
for (User user : this.users.values()) { for (User user : this.users) {
if (user.getPgpKeyId() == 0) { if (user.getPgpKeyId() == 0) {
return false; return false;
} }
@ -468,12 +542,12 @@ public class MucOptions {
} }
} }
public Jid getTrueCounterpart(String name) { public Jid getTrueCounterpart(Jid jid) {
if (name.equals(getSelf().getName())) { if (jid.equals(getSelf().getFullJid())) {
return account.getJid().toBareJid(); return account.getJid().toBareJid();
} }
User user = findUser(name); User user = findUserByFullJid(jid);
return user == null ? null : user.getJid(); return user == null ? null : user.getRealJid();
} }
public String getPassword() { public String getPassword() {
@ -499,11 +573,21 @@ public class MucOptions {
return this.conversation; return this.conversation;
} }
public void putMember(Jid jid) { public void putMember(Jid fullJid, Jid realJid, String affiliation, String role) {
members.add(jid); User user = new User(this, fullJid);
user.setRealJid(realJid);
user.setAffiliation(affiliation);
user.setRole(role);
addUser(user);
} }
public List<Jid> getMembers() { public List<Jid> getMembers() {
return new ArrayList<>(members); ArrayList<Jid> members = new ArrayList<>();
for(User user : users) {
if (user.affiliation.ranks(Affiliation.MEMBER) && user.getRealJid() != null) {
members.add(user.getRealJid());
}
}
return members;
} }
} }

View file

@ -402,7 +402,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
} else if (axolotlEncrypted != null && Config.supportOmemo()) { } else if (axolotlEncrypted != null && Config.supportOmemo()) {
Jid origin; Jid origin;
if (conversation.getMode() == Conversation.MODE_MULTI) { if (conversation.getMode() == Conversation.MODE_MULTI) {
origin = conversation.getMucOptions().getTrueCounterpart(counterpart.getResourcepart()); origin = conversation.getMucOptions().getTrueCounterpart(counterpart);
if (origin == null) { if (origin == null) {
Log.d(Config.LOGTAG,"axolotl message in non anonymous conference received"); Log.d(Config.LOGTAG,"axolotl message in non anonymous conference received");
return; return;
@ -430,7 +430,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
message.setOob(isOob); message.setOob(isOob);
message.markable = packet.hasChild("markable", "urn:xmpp:chat-markers:0"); message.markable = packet.hasChild("markable", "urn:xmpp:chat-markers:0");
if (conversation.getMode() == Conversation.MODE_MULTI) { if (conversation.getMode() == Conversation.MODE_MULTI) {
Jid trueCounterpart = conversation.getMucOptions().getTrueCounterpart(counterpart.getResourcepart()); Jid trueCounterpart = conversation.getMucOptions().getTrueCounterpart(counterpart);
message.setTrueCounterpart(trueCounterpart); message.setTrueCounterpart(trueCounterpart);
if (!isTypeGroupChat) { if (!isTypeGroupChat) {
message.setType(Message.TYPE_PRIVATE); message.setType(Message.TYPE_PRIVATE);

View file

@ -14,15 +14,12 @@ import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.entities.MucOptions; import eu.siacs.conversations.entities.MucOptions;
import eu.siacs.conversations.entities.Presence; import eu.siacs.conversations.entities.Presence;
import eu.siacs.conversations.entities.ServiceDiscoveryResult;
import eu.siacs.conversations.generator.PresenceGenerator; import eu.siacs.conversations.generator.PresenceGenerator;
import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.OnIqPacketReceived;
import eu.siacs.conversations.xmpp.OnPresencePacketReceived; import eu.siacs.conversations.xmpp.OnPresencePacketReceived;
import eu.siacs.conversations.xmpp.jid.Jid; import eu.siacs.conversations.xmpp.jid.Jid;
import eu.siacs.conversations.xmpp.pep.Avatar; import eu.siacs.conversations.xmpp.pep.Avatar;
import eu.siacs.conversations.xmpp.stanzas.IqPacket;
import eu.siacs.conversations.xmpp.stanzas.PresencePacket; import eu.siacs.conversations.xmpp.stanzas.PresencePacket;
public class PresenceParser extends AbstractParser implements public class PresenceParser extends AbstractParser implements
@ -67,11 +64,7 @@ public class PresenceParser extends AbstractParser implements
MucOptions.User user = new MucOptions.User(mucOptions, from); MucOptions.User user = new MucOptions.User(mucOptions, from);
user.setAffiliation(item.getAttribute("affiliation")); user.setAffiliation(item.getAttribute("affiliation"));
user.setRole(item.getAttribute("role")); user.setRole(item.getAttribute("role"));
Jid real = item.getAttributeAsJid("jid"); user.setRealJid(item.getAttributeAsJid("jid"));
if (real != null) {
user.setJid(real);
mucOptions.putMember(real.toBareJid());
}
if (codes.contains(MucOptions.STATUS_CODE_SELF_PRESENCE) || packet.getFrom().equals(mucOptions.getConversation().getJid())) { if (codes.contains(MucOptions.STATUS_CODE_SELF_PRESENCE) || packet.getFrom().equals(mucOptions.getConversation().getJid())) {
mucOptions.setOnline(); mucOptions.setOnline();
mucOptions.setSelf(user); mucOptions.setSelf(user);
@ -127,7 +120,7 @@ public class PresenceParser extends AbstractParser implements
Log.d(Config.LOGTAG, "unknown error in conference: " + packet); Log.d(Config.LOGTAG, "unknown error in conference: " + packet);
} }
} else if (!from.isBareJid()){ } else if (!from.isBareJid()){
MucOptions.User user = mucOptions.deleteUser(from.getResourcepart()); MucOptions.User user = mucOptions.deleteUser(from);
if (user != null) { if (user != null) {
mXmppConnectionService.getAvatarService().clear(user); mXmppConnectionService.getAvatarService().clear(user);
} }

View file

@ -246,7 +246,7 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
if (c != null && (c.getProfilePhoto() != null || c.getAvatar() != null)) { if (c != null && (c.getProfilePhoto() != null || c.getAvatar() != null)) {
return get(c, size, cachedOnly); return get(c, size, cachedOnly);
} else if (message.getConversation().getMode() == Conversation.MODE_MULTI){ } else if (message.getConversation().getMode() == Conversation.MODE_MULTI){
MucOptions.User user = conversation.getMucOptions().findUser(message.getCounterpart().getResourcepart()); MucOptions.User user = conversation.getMucOptions().findUserByFullJid(message.getCounterpart());
if (user != null) { if (user != null) {
return getImpl(user,size,cachedOnly); return getImpl(user,size,cachedOnly);
} }

View file

@ -1899,11 +1899,26 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
@Override @Override
public void onIqPacketReceived(Account account, IqPacket packet) { public void onIqPacketReceived(Account account, IqPacket packet) {
Element query = packet.query("http://jabber.org/protocol/muc#admin"); Element query = packet.query("http://jabber.org/protocol/muc#admin");
if (packet.getType() == IqPacket.TYPE.RESULT && query != null) { if (packet.getType() == IqPacket.TYPE.RESULT && query != null) {
final String local = conversation.getJid().getLocalpart();
final String domain = conversation.getJid().getDomainpart();
for(Element child : query.getChildren()) { for(Element child : query.getChildren()) {
if ("item".equals(child.getName())) { if ("item".equals(child.getName())) {
conversation.getMucOptions().putMember(child.getAttributeAsJid("jid")); String affiliation = child.getAttribute("affiliation");
String role = child.getAttribute("role");
String nick = child.getAttribute("nick");
Jid fullJid;
try {
fullJid = nick != null ? Jid.fromParts(local, domain, nick) : null;
} catch (InvalidJidException e) {
fullJid = null;
}
Jid realJid = child.getAttributeAsJid("jid");
if (realJid != null && !realJid.equals(account.getJid().toBareJid())) {
conversation.getMucOptions().putMember(fullJid, realJid, affiliation, role);
}
} }
} }
} else { } else {
@ -2175,13 +2190,14 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
} }
} }
public void changeAffiliationInConference(final Conversation conference, Jid user, MucOptions.Affiliation affiliation, final OnAffiliationChanged callback) { public void changeAffiliationInConference(final Conversation conference, Jid user, final MucOptions.Affiliation affiliation, final OnAffiliationChanged callback) {
final Jid jid = user.toBareJid(); final Jid jid = user.toBareJid();
IqPacket request = this.mIqGenerator.changeAffiliation(conference, jid, affiliation.toString()); IqPacket request = this.mIqGenerator.changeAffiliation(conference, jid, affiliation.toString());
sendIqPacket(conference.getAccount(), request, new OnIqPacketReceived() { sendIqPacket(conference.getAccount(), request, new OnIqPacketReceived() {
@Override @Override
public void onIqPacketReceived(Account account, IqPacket packet) { public void onIqPacketReceived(Account account, IqPacket packet) {
if (packet.getType() == IqPacket.TYPE.RESULT) { if (packet.getType() == IqPacket.TYPE.RESULT) {
conference.getMucOptions().changeAffiliation(jid, affiliation);
callback.onAffiliationChangedSuccessful(jid); callback.onAffiliationChangedSuccessful(jid);
} else { } else {
callback.onAffiliationChangeFailed(jid, R.string.could_not_change_affiliation); callback.onAffiliationChangeFailed(jid, R.string.could_not_change_affiliation);
@ -2193,8 +2209,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
public void changeAffiliationsInConference(final Conversation conference, MucOptions.Affiliation before, MucOptions.Affiliation after) { public void changeAffiliationsInConference(final Conversation conference, MucOptions.Affiliation before, MucOptions.Affiliation after) {
List<Jid> jids = new ArrayList<>(); List<Jid> jids = new ArrayList<>();
for (MucOptions.User user : conference.getMucOptions().getUsers()) { for (MucOptions.User user : conference.getMucOptions().getUsers()) {
if (user.getAffiliation() == before && user.getJid() != null) { if (user.getAffiliation() == before && user.getRealJid() != null) {
jids.add(user.getJid()); jids.add(user.getRealJid());
} }
} }
IqPacket request = this.mIqGenerator.changeAffiliation(conference, jids, after.toString()); IqPacket request = this.mIqGenerator.changeAffiliation(conference, jids, after.toString());
@ -2574,7 +2590,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
} else { } else {
Conversation conversation = find(account, avatar.owner.toBareJid()); Conversation conversation = find(account, avatar.owner.toBareJid());
if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) { if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) {
MucOptions.User user = conversation.getMucOptions().findUser(avatar.owner.getResourcepart()); MucOptions.User user = conversation.getMucOptions().findUserByFullJid(avatar.owner);
if (user != null) { if (user != null) {
if (user.setAvatar(avatar)) { if (user.setAvatar(avatar)) {
getAvatarService().clear(user); getAvatarService().clear(user);

View file

@ -1,6 +1,5 @@
package eu.siacs.conversations.ui; package eu.siacs.conversations.ui;
import android.annotation.TargetApi;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
@ -8,7 +7,6 @@ import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.IntentSender.SendIntentException; import android.content.IntentSender.SendIntentException;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.view.ContextMenu; import android.view.ContextMenu;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -365,13 +363,13 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
final Contact contact = user.getContact(); final Contact contact = user.getContact();
if (contact != null) { if (contact != null) {
name = contact.getDisplayName(); name = contact.getDisplayName();
} else if (user.getJid() != null){ } else if (user.getRealJid() != null){
name = user.getJid().toBareJid().toString(); name = user.getRealJid().toBareJid().toString();
} else { } else {
name = user.getName(); name = user.getName();
} }
menu.setHeaderTitle(name); menu.setHeaderTitle(name);
if (user.getJid() != null) { if (user.getRealJid() != null) {
MenuItem showContactDetails = menu.findItem(R.id.action_contact_details); MenuItem showContactDetails = menu.findItem(R.id.action_contact_details);
MenuItem startConversation = menu.findItem(R.id.start_conversation); MenuItem startConversation = menu.findItem(R.id.start_conversation);
MenuItem giveMembership = menu.findItem(R.id.give_membership); MenuItem giveMembership = menu.findItem(R.id.give_membership);
@ -424,22 +422,22 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
startConversation(mSelectedUser); startConversation(mSelectedUser);
return true; return true;
case R.id.give_admin_privileges: case R.id.give_admin_privileges:
xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.ADMIN,this); xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getRealJid(), MucOptions.Affiliation.ADMIN,this);
return true; return true;
case R.id.give_membership: case R.id.give_membership:
xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.MEMBER,this); xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getRealJid(), MucOptions.Affiliation.MEMBER,this);
return true; return true;
case R.id.remove_membership: case R.id.remove_membership:
xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.NONE,this); xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getRealJid(), MucOptions.Affiliation.NONE,this);
return true; return true;
case R.id.remove_admin_privileges: case R.id.remove_admin_privileges:
xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.MEMBER,this); xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getRealJid(), MucOptions.Affiliation.MEMBER,this);
return true; return true;
case R.id.remove_from_room: case R.id.remove_from_room:
removeFromRoom(mSelectedUser); removeFromRoom(mSelectedUser);
return true; return true;
case R.id.ban_from_conference: case R.id.ban_from_conference:
xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.OUTCAST,this); xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getRealJid(), MucOptions.Affiliation.OUTCAST,this);
xmppConnectionService.changeRoleInConference(mConversation,mSelectedUser.getName(), MucOptions.Role.NONE,this); xmppConnectionService.changeRoleInConference(mConversation,mSelectedUser.getName(), MucOptions.Role.NONE,this);
return true; return true;
case R.id.send_private_message: case R.id.send_private_message:
@ -452,7 +450,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
private void removeFromRoom(final User user) { private void removeFromRoom(final User user) {
if (mConversation.getMucOptions().membersOnly()) { if (mConversation.getMucOptions().membersOnly()) {
xmppConnectionService.changeAffiliationInConference(mConversation,user.getJid(), MucOptions.Affiliation.NONE,this); xmppConnectionService.changeAffiliationInConference(mConversation,user.getRealJid(), MucOptions.Affiliation.NONE,this);
xmppConnectionService.changeRoleInConference(mConversation,mSelectedUser.getName(), MucOptions.Role.NONE,ConferenceDetailsActivity.this); xmppConnectionService.changeRoleInConference(mConversation,mSelectedUser.getName(), MucOptions.Role.NONE,ConferenceDetailsActivity.this);
} else { } else {
AlertDialog.Builder builder = new AlertDialog.Builder(this); AlertDialog.Builder builder = new AlertDialog.Builder(this);
@ -462,7 +460,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
builder.setPositiveButton(R.string.ban_now,new DialogInterface.OnClickListener() { builder.setPositiveButton(R.string.ban_now,new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
xmppConnectionService.changeAffiliationInConference(mConversation,user.getJid(), MucOptions.Affiliation.OUTCAST,ConferenceDetailsActivity.this); xmppConnectionService.changeAffiliationInConference(mConversation,user.getRealJid(), MucOptions.Affiliation.OUTCAST,ConferenceDetailsActivity.this);
xmppConnectionService.changeRoleInConference(mConversation,mSelectedUser.getName(), MucOptions.Role.NONE,ConferenceDetailsActivity.this); xmppConnectionService.changeRoleInConference(mConversation,mSelectedUser.getName(), MucOptions.Role.NONE,ConferenceDetailsActivity.this);
} }
}); });
@ -471,8 +469,8 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
} }
protected void startConversation(User user) { protected void startConversation(User user) {
if (user.getJid() != null) { if (user.getRealJid() != null) {
Conversation conversation = xmppConnectionService.findOrCreateConversation(this.mConversation.getAccount(),user.getJid().toBareJid(),false); Conversation conversation = xmppConnectionService.findOrCreateConversation(this.mConversation.getAccount(),user.getRealJid().toBareJid(),false);
switchToConversation(conversation); switchToConversation(conversation);
} }
} }
@ -577,8 +575,8 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
final ArrayList<User> users = mucOptions.getUsers(); final ArrayList<User> users = mucOptions.getUsers();
Collections.sort(users,new Comparator<User>() { Collections.sort(users,new Comparator<User>() {
@Override @Override
public int compare(User lhs, User rhs) { public int compare(User l, User r) {
return lhs.getName().compareToIgnoreCase(rhs.getName()); return l.getName() == null || r.getName() == null ? 0 : l.getName().compareToIgnoreCase(r.getName());
} }
}); });
for (final User user : users) { for (final User user : users) {
@ -607,11 +605,12 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
tvKey.setText(OpenPgpUtils.convertKeyIdToHex(user.getPgpKeyId())); tvKey.setText(OpenPgpUtils.convertKeyIdToHex(user.getPgpKeyId()));
} }
Contact contact = user.getContact(); Contact contact = user.getContact();
String name = user.getName();
if (contact != null) { if (contact != null) {
tvDisplayName.setText(contact.getDisplayName()); tvDisplayName.setText(contact.getDisplayName());
tvStatus.setText(user.getName() + " \u2022 " + getStatus(user)); tvStatus.setText((name != null ? name+ " \u2022 " : "") + getStatus(user));
} else { } else {
tvDisplayName.setText(user.getName()); tvDisplayName.setText(name == null ? "" : name);
tvStatus.setText(getStatus(user)); tvStatus.setText(getStatus(user));
} }
@ -657,7 +656,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
@Override @Override
public void onAffiliationChangedSuccessful(Jid jid) { public void onAffiliationChangedSuccessful(Jid jid) {
refreshUi();
} }
@Override @Override

View file

@ -461,12 +461,12 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
public void onContactPictureClicked(Message message) { public void onContactPictureClicked(Message message) {
if (message.getStatus() <= Message.STATUS_RECEIVED) { if (message.getStatus() <= Message.STATUS_RECEIVED) {
if (message.getConversation().getMode() == Conversation.MODE_MULTI) { if (message.getConversation().getMode() == Conversation.MODE_MULTI) {
if (message.getCounterpart() != null) { Jid user = message.getCounterpart();
String user = message.getCounterpart().isBareJid() ? message.getCounterpart().toString() : message.getCounterpart().getResourcepart(); if (user != null && !user.isBareJid()) {
if (!message.getConversation().getMucOptions().isUserInRoom(user)) { if (!message.getConversation().getMucOptions().isUserInRoom(user)) {
Toast.makeText(activity,activity.getString(R.string.user_has_left_conference,user),Toast.LENGTH_SHORT).show(); Toast.makeText(activity,activity.getString(R.string.user_has_left_conference,user.getResourcepart()),Toast.LENGTH_SHORT).show();
} }
highlightInConference(user); highlightInConference(user.getResourcepart());
} }
} else { } else {
if (!message.getContact().isSelf()) { if (!message.getContact().isSelf()) {
@ -495,14 +495,12 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
public void onContactPictureLongClicked(Message message) { public void onContactPictureLongClicked(Message message) {
if (message.getStatus() <= Message.STATUS_RECEIVED) { if (message.getStatus() <= Message.STATUS_RECEIVED) {
if (message.getConversation().getMode() == Conversation.MODE_MULTI) { if (message.getConversation().getMode() == Conversation.MODE_MULTI) {
if (message.getCounterpart() != null) { Jid user = message.getCounterpart();
String user = message.getCounterpart().getResourcepart(); if (user != null && !user.isBareJid()) {
if (user != null) { if (message.getConversation().getMucOptions().isUserInRoom(user)) {
if (message.getConversation().getMucOptions().isUserInRoom(user)) { privateMessageWith(user);
privateMessageWith(message.getCounterpart()); } else {
} else { Toast.makeText(activity, activity.getString(R.string.user_has_left_conference, user.getResourcepart()), Toast.LENGTH_SHORT).show();
Toast.makeText(activity, activity.getString(R.string.user_has_left_conference, user), Toast.LENGTH_SHORT).show();
}
} }
} }
} }

View file

@ -42,7 +42,6 @@ import android.preference.PreferenceManager;
import android.text.InputType; import android.text.InputType;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.Log; import android.util.Log;
import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
@ -68,7 +67,6 @@ import java.util.ArrayList;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.List; import java.util.List;
import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RunnableFuture;
import eu.siacs.conversations.Config; import eu.siacs.conversations.Config;
import eu.siacs.conversations.R; import eu.siacs.conversations.R;
@ -481,7 +479,7 @@ public abstract class XmppActivity extends Activity {
List<String> contacts = new ArrayList<>(); List<String> contacts = new ArrayList<>();
if (conversation.getMode() == Conversation.MODE_MULTI) { if (conversation.getMode() == Conversation.MODE_MULTI) {
for (MucOptions.User user : conversation.getMucOptions().getUsers()) { for (MucOptions.User user : conversation.getMucOptions().getUsers()) {
Jid jid = user.getJid(); Jid jid = user.getRealJid();
if (jid != null) { if (jid != null) {
contacts.add(jid.toBareJid().toString()); contacts.add(jid.toBareJid().toString());
} }

View file

@ -447,7 +447,7 @@
<string name="disable_all_accounts">Disable all accounts</string> <string name="disable_all_accounts">Disable all accounts</string>
<string name="perform_action_with">Perform action with</string> <string name="perform_action_with">Perform action with</string>
<string name="no_affiliation">No affiliation</string> <string name="no_affiliation">No affiliation</string>
<string name="no_role">No role</string> <string name="no_role">Offline</string>
<string name="outcast">Outcast</string> <string name="outcast">Outcast</string>
<string name="member">Member</string> <string name="member">Member</string>
<string name="advanced_mode">Advanced mode</string> <string name="advanced_mode">Advanced mode</string>
@ -542,7 +542,7 @@
<string name="pref_use_white_background_summary">Show received messages as black text on a white background</string> <string name="pref_use_white_background_summary">Show received messages as black text on a white background</string>
<string name="account_status_tor_unavailable">Tor network unavailable</string> <string name="account_status_tor_unavailable">Tor network unavailable</string>
<string name="account_status_bind_failure">Bind failure</string> <string name="account_status_bind_failure">Bind failure</string>
<string name="account_status_host_unknown">Domain not recognized</string> <string name="account_status_host_unknown">Host unknown</string>
<string name="server_info_broken">Broken</string> <string name="server_info_broken">Broken</string>
<string name="pref_presence_settings">Presence</string> <string name="pref_presence_settings">Presence</string>
<string name="pref_away_when_screen_off">Away when screen is off</string> <string name="pref_away_when_screen_off">Away when screen is off</string>