From 8d0693ed6a46ea45844f4d8319f5d051ec256756 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 16 May 2016 14:10:40 +0200 Subject: keep conference members in memory and show them in conference details --- .../siacs/conversations/entities/MucOptions.java | 174 +++++++++++++++------ 1 file changed, 129 insertions(+), 45 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/entities/MucOptions.java') diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index 7681a3d4..a221c701 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -5,9 +5,7 @@ import android.annotation.SuppressLint; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; import java.util.Set; import eu.siacs.conversations.R; @@ -28,6 +26,15 @@ public class MucOptions { 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 { OWNER("owner", 4, R.string.owner), ADMIN("admin", 3, R.string.admin), @@ -127,7 +134,7 @@ public class MucOptions { public static class User { private Role role = Role.NONE; private Affiliation affiliation = Affiliation.NONE; - private Jid jid; + private Jid realJid; private Jid fullJid; private long pgpKeyId = 0; private Avatar avatar; @@ -139,15 +146,15 @@ public class MucOptions { } public String getName() { - return this.fullJid.getResourcepart(); + return fullJid == null ? null : fullJid.getResourcepart(); } - public void setJid(Jid jid) { - this.jid = jid; + public void setRealJid(Jid jid) { + this.realJid = jid != null ? jid.toBareJid() : null; } - public Jid getJid() { - return this.jid; + public Jid getRealJid() { + return this.realJid; } public Role getRole() { @@ -155,6 +162,10 @@ public class MucOptions { } public void setRole(String role) { + if (role == null) { + this.role = Role.NONE; + return; + } role = role.toLowerCase(); switch (role) { 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() { return this.affiliation; } public void setAffiliation(String affiliation) { + if (affiliation == null) { + this.affiliation = Affiliation.NONE; + return; + } affiliation = affiliation.toLowerCase(); switch (affiliation) { case "admin": @@ -220,7 +220,7 @@ public class MucOptions { } public Contact getContact() { - return getAccount().getRoster().getContactFromRoster(getJid()); + return getAccount().getRoster().getContactFromRoster(getRealJid()); } public boolean setAvatar(Avatar avatar) { @@ -243,11 +243,39 @@ public class MucOptions { public Jid getFullJid() { 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 final Map users = Collections.synchronizedMap(new LinkedHashMap()); - private final Set members = Collections.synchronizedSet(new HashSet()); + private final Set users = Collections.synchronizedSet(new HashSet()); private final List features = new ArrayList<>(); private Data form = new Data(); private Conversation conversation; @@ -315,20 +343,66 @@ public class MucOptions { return hasFeature("muc_moderated"); } - public User deleteUser(String name) { - return this.users.remove(name); + public User deleteUser(Jid jid) { + 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) { - 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 findUserByFullJid(Jid jid) { + if (jid == null) { + return null; + } + for(User user : users) { + if (jid.equals(user.getFullJid())) { + return user; + } + } + return null; } - public User findUser(String name) { - return this.users.get(name); + public User findUserByRealJid(Jid jid) { + if (jid == null) { + return null; + } + for(User user : users) { + if (jid.equals(user.getRealJid())) { + return user; + } + } + return null; } - public boolean isUserInRoom(String name) { - return findUser(name) != null; + public boolean isUserInRoom(Jid jid) { + return findUserByFullJid(jid) != null; } public void setError(Error error) { @@ -341,7 +415,7 @@ public class MucOptions { } public ArrayList getUsers() { - return new ArrayList<>(users.values()); + return new ArrayList<>(users); } public List getUsers(int max) { @@ -410,7 +484,7 @@ public class MucOptions { Contact contact = user.getContact(); if (contact != null && !contact.getDisplayName().isEmpty()) { names.add(contact.getDisplayName().split("\\s+")[0]); - } else { + } else if (user.getName() != null){ names.add(user.getName()); } } @@ -429,7 +503,7 @@ public class MucOptions { public long[] getPgpKeyIds() { List ids = new ArrayList<>(); - for (User user : this.users.values()) { + for (User user : this.users) { if (user.getPgpKeyId() != 0) { ids.add(user.getPgpKeyId()); } @@ -443,7 +517,7 @@ public class MucOptions { } public boolean pgpKeysInUse() { - for (User user : this.users.values()) { + for (User user : this.users) { if (user.getPgpKeyId() != 0) { return true; } @@ -452,7 +526,7 @@ public class MucOptions { } public boolean everybodyHasKeys() { - for (User user : this.users.values()) { + for (User user : this.users) { if (user.getPgpKeyId() == 0) { return false; } @@ -468,12 +542,12 @@ public class MucOptions { } } - public Jid getTrueCounterpart(String name) { - if (name.equals(getSelf().getName())) { + public Jid getTrueCounterpart(Jid jid) { + if (jid.equals(getSelf().getFullJid())) { return account.getJid().toBareJid(); } - User user = findUser(name); - return user == null ? null : user.getJid(); + User user = findUserByFullJid(jid); + return user == null ? null : user.getRealJid(); } public String getPassword() { @@ -499,11 +573,21 @@ public class MucOptions { return this.conversation; } - public void putMember(Jid jid) { - members.add(jid); + public void putMember(Jid fullJid, Jid realJid, String affiliation, String role) { + User user = new User(this, fullJid); + user.setRealJid(realJid); + user.setAffiliation(affiliation); + user.setRole(role); + addUser(user); } public List getMembers() { - return new ArrayList<>(members); + ArrayList members = new ArrayList<>(); + for(User user : users) { + if (user.affiliation.ranks(Affiliation.MEMBER) && user.getRealJid() != null) { + members.add(user.getRealJid()); + } + } + return members; } } -- cgit v1.2.3 From fc5304c6feb302334d15be183d55663965a29de1 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 16 May 2016 15:50:57 +0200 Subject: change affiliation for in memory users that are currently not joined in a conference --- src/main/java/eu/siacs/conversations/entities/MucOptions.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/entities/MucOptions.java') diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index a221c701..50641f5a 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -28,10 +28,12 @@ public class MucOptions { public void changeAffiliation(Jid jid, Affiliation affiliation) { User user = findUserByRealJid(jid); - if (user != null) { + if (user != null && user.getRole() == Role.NONE) { users.remove(user); - user.affiliation = affiliation; - users.add(user); + if (affiliation.ranks(Affiliation.MEMBER)) { + user.affiliation = affiliation; + users.add(user); + } } } -- cgit v1.2.3 From 14952ba5e5ffbbbda2d0453157f03779ffbdaffb Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 17 May 2016 10:43:48 +0200 Subject: offer offline members to be invited again --- .../eu/siacs/conversations/entities/MucOptions.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/entities/MucOptions.java') diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index 50641f5a..e931f5fd 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -349,7 +349,7 @@ public class MucOptions { User user = findUserByFullJid(jid); if (user != null) { users.remove(user); - if (user.affiliation.ranks(Affiliation.MEMBER)) { + if (user.affiliation.ranks(Affiliation.MEMBER) && user.realJid != null) { user.role = Role.NONE; user.avatar = null; user.fullJid = null; @@ -417,7 +417,21 @@ public class MucOptions { } public ArrayList getUsers() { - return new ArrayList<>(users); + return getUsers(true); + } + + public ArrayList getUsers(boolean includeOffline) { + if (includeOffline) { + return new ArrayList<>(users); + } else { + ArrayList onlineUsers = new ArrayList<>(); + for(User user : users) { + if(user.getRole().ranks(Role.PARTICIPANT)) { + onlineUsers.add(user); + } + } + return onlineUsers; + } } public List getUsers(int max) { -- cgit v1.2.3 From 61726f4994dffad0407bbc9dc539874ce9f79171 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 17 May 2016 14:25:58 +0200 Subject: refactored muc item parsing to also parse muc status messages --- .../java/eu/siacs/conversations/entities/MucOptions.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/entities/MucOptions.java') diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index e931f5fd..8d7c5adb 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -274,6 +274,10 @@ public class MucOptions { public String toString() { return "[fulljid:"+String.valueOf(fullJid)+",realjid:"+String.valueOf(realJid)+",affiliation"+affiliation.toString()+"]"; } + + public boolean realJidMatchesAccount() { + return realJid != null && realJid.equals(options.account.getJid().toBareJid()); + } } private Account account; @@ -589,14 +593,6 @@ public class MucOptions { return this.conversation; } - public void putMember(Jid fullJid, Jid realJid, String affiliation, String role) { - User user = new User(this, fullJid); - user.setRealJid(realJid); - user.setAffiliation(affiliation); - user.setRole(role); - addUser(user); - } - public List getMembers() { ArrayList members = new ArrayList<>(); for(User user : users) { -- cgit v1.2.3 From b478eca315661c50d76052aafcbbcc041790300f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 17 May 2016 15:01:56 +0200 Subject: improved ordering of muc participants --- .../siacs/conversations/entities/MucOptions.java | 25 ++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/entities/MucOptions.java') diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index 8d7c5adb..d26ecd7c 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -133,7 +133,7 @@ public class MucOptions { } - public static class User { + public static class User implements Comparable { private Role role = Role.NONE; private Affiliation affiliation = Affiliation.NONE; private Jid realJid; @@ -222,7 +222,13 @@ public class MucOptions { } public Contact getContact() { - return getAccount().getRoster().getContactFromRoster(getRealJid()); + if (fullJid != null) { + return getAccount().getRoster().getContactFromRoster(realJid); + } else if (realJid != null){ + return getAccount().getRoster().getContact(realJid); + } else { + return null; + } } public boolean setAvatar(Avatar avatar) { @@ -278,6 +284,21 @@ public class MucOptions { public boolean realJidMatchesAccount() { return realJid != null && realJid.equals(options.account.getJid().toBareJid()); } + + @Override + public int compareTo(User another) { + Contact ourContact = getContact(); + Contact anotherContact = another.getContact(); + if (ourContact != null && anotherContact != null) { + return ourContact.compareTo(anotherContact); + } else if (ourContact == null && anotherContact != null) { + return getName().compareToIgnoreCase(anotherContact.getDisplayName()); + } else if (ourContact != null) { + return ourContact.getDisplayName().compareToIgnoreCase(another.getName()); + } else { + return getName().compareToIgnoreCase(another.getName()); + } + } } private Account account; -- cgit v1.2.3 From 8d595c1fc2a083046a91919d9db29915d3dfeca6 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 19 May 2016 10:47:03 +0200 Subject: sync around individual calls instead of synchronizing entire object --- .../siacs/conversations/entities/MucOptions.java | 128 +++++++++++++-------- 1 file changed, 79 insertions(+), 49 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/entities/MucOptions.java') diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index d26ecd7c..44d16cf2 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -28,11 +28,13 @@ public class MucOptions { public void changeAffiliation(Jid jid, Affiliation affiliation) { User user = findUserByRealJid(jid); - if (user != null && user.getRole() == Role.NONE) { - users.remove(user); - if (affiliation.ranks(Affiliation.MEMBER)) { - user.affiliation = affiliation; - users.add(user); + synchronized (users) { + if (user != null && user.getRole() == Role.NONE) { + users.remove(user); + if (affiliation.ranks(Affiliation.MEMBER)) { + user.affiliation = affiliation; + users.add(user); + } } } } @@ -155,10 +157,6 @@ public class MucOptions { this.realJid = jid != null ? jid.toBareJid() : null; } - public Jid getRealJid() { - return this.realJid; - } - public Role getRole() { return this.role; } @@ -299,10 +297,14 @@ public class MucOptions { return getName().compareToIgnoreCase(another.getName()); } } + + public Jid getRealJid() { + return realJid; + } } private Account account; - private final Set users = Collections.synchronizedSet(new HashSet()); + private final Set users = new HashSet<>(); private final List features = new ArrayList<>(); private Data form = new Data(); private Conversation conversation; @@ -373,12 +375,14 @@ public class MucOptions { public User deleteUser(Jid jid) { User user = findUserByFullJid(jid); if (user != null) { - users.remove(user); - if (user.affiliation.ranks(Affiliation.MEMBER) && user.realJid != null) { - user.role = Role.NONE; - user.avatar = null; - user.fullJid = null; - users.add(user); + synchronized (users) { + users.remove(user); + if (user.affiliation.ranks(Affiliation.MEMBER) && user.realJid != null) { + user.role = Role.NONE; + user.avatar = null; + user.fullJid = null; + users.add(user); + } } } return user; @@ -389,28 +393,40 @@ public class MucOptions { if (user.fullJid == null && user.realJid != null) { old = findUserByRealJid(user.realJid); if (old != null) { - return; //don't add. user already exists + if (old.fullJid != null) { + return; //don't add. user already exists + } else { + synchronized (users) { + users.remove(old); + } + } } } else if (user.realJid != null) { old = findUserByRealJid(user.realJid); - if (old != null && old.fullJid == null) { - users.remove(old); + synchronized (users) { + if (old != null && old.fullJid == null) { + users.remove(old); + } } } old = findUserByFullJid(user.getFullJid()); - if (old != null) { - users.remove(old); + synchronized (this.users) { + if (old != null) { + users.remove(old); + } + this.users.add(user); } - this.users.add(user); } public User findUserByFullJid(Jid jid) { if (jid == null) { return null; } - for(User user : users) { - if (jid.equals(user.getFullJid())) { - return user; + synchronized (users) { + for (User user : users) { + if (jid.equals(user.getFullJid())) { + return user; + } } } return null; @@ -420,9 +436,11 @@ public class MucOptions { if (jid == null) { return null; } - for(User user : users) { - if (jid.equals(user.getRealJid())) { - return user; + synchronized (users) { + for (User user : users) { + if (jid.equals(user.realJid)) { + return user; + } } } return null; @@ -446,16 +464,18 @@ public class MucOptions { } public ArrayList getUsers(boolean includeOffline) { - if (includeOffline) { - return new ArrayList<>(users); - } else { - ArrayList onlineUsers = new ArrayList<>(); - for(User user : users) { - if(user.getRole().ranks(Role.PARTICIPANT)) { - onlineUsers.add(user); + synchronized (users) { + if (includeOffline) { + return new ArrayList<>(users); + } else { + ArrayList onlineUsers = new ArrayList<>(); + for (User user : users) { + if (user.getRole().ranks(Role.PARTICIPANT)) { + onlineUsers.add(user); + } } + return onlineUsers; } - return onlineUsers; } } @@ -465,7 +485,9 @@ public class MucOptions { } public int getUserCount() { - return this.users.size(); + synchronized (users) { + return users.size(); + } } public String getProposedNick() { @@ -501,7 +523,9 @@ public class MucOptions { } public void setOffline() { - this.users.clear(); + synchronized (users) { + this.users.clear(); + } this.error = Error.NO_RESPONSE; this.isOnline = false; } @@ -519,7 +543,7 @@ public class MucOptions { } public String createNameFromParticipants() { - if (users.size() >= 2) { + if (getUserCount() >= 2) { List names = new ArrayList<>(); for (User user : getUsers(5)) { Contact contact = user.getContact(); @@ -558,18 +582,22 @@ public class MucOptions { } public boolean pgpKeysInUse() { - for (User user : this.users) { - if (user.getPgpKeyId() != 0) { - return true; + synchronized (users) { + for (User user : users) { + if (user.getPgpKeyId() != 0) { + return true; + } } } return false; } public boolean everybodyHasKeys() { - for (User user : this.users) { - if (user.getPgpKeyId() == 0) { - return false; + synchronized (users) { + for (User user : users) { + if (user.getPgpKeyId() == 0) { + return false; + } } } return true; @@ -588,7 +616,7 @@ public class MucOptions { return account.getJid().toBareJid(); } User user = findUserByFullJid(jid); - return user == null ? null : user.getRealJid(); + return user == null ? null : user.realJid; } public String getPassword() { @@ -616,9 +644,11 @@ public class MucOptions { public List getMembers() { ArrayList members = new ArrayList<>(); - for(User user : users) { - if (user.affiliation.ranks(Affiliation.MEMBER) && user.getRealJid() != null) { - members.add(user.getRealJid()); + synchronized (users) { + for (User user : users) { + if (user.affiliation.ranks(Affiliation.MEMBER) && user.realJid != null) { + members.add(user.realJid); + } } } return members; -- cgit v1.2.3