refactored user handling in conferences. show try again button when conference has errors
This commit is contained in:
parent
2eef37174e
commit
a3e11415ec
|
@ -3,7 +3,10 @@ package eu.siacs.conversations.entities;
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.xmpp.forms.Data;
|
import eu.siacs.conversations.xmpp.forms.Data;
|
||||||
|
@ -64,7 +67,7 @@ public class MucOptions {
|
||||||
PARTICIPANT("participant", R.string.participant,2),
|
PARTICIPANT("participant", R.string.participant,2),
|
||||||
NONE("none", R.string.no_role,0);
|
NONE("none", R.string.no_role,0);
|
||||||
|
|
||||||
private Role(String string, int resId, int rank) {
|
Role(String string, int resId, int rank) {
|
||||||
this.string = string;
|
this.string = string;
|
||||||
this.resId = resId;
|
this.resId = resId;
|
||||||
this.rank = rank;
|
this.rank = rank;
|
||||||
|
@ -94,6 +97,7 @@ public class MucOptions {
|
||||||
public static final int ERROR_PASSWORD_REQUIRED = 3;
|
public static final int ERROR_PASSWORD_REQUIRED = 3;
|
||||||
public static final int ERROR_BANNED = 4;
|
public static final int ERROR_BANNED = 4;
|
||||||
public static final int ERROR_MEMBERS_ONLY = 5;
|
public static final int ERROR_MEMBERS_ONLY = 5;
|
||||||
|
public static final int ERROR_NO_RESPONSE = 6;
|
||||||
|
|
||||||
public static final int KICKED_FROM_ROOM = 9;
|
public static final int KICKED_FROM_ROOM = 9;
|
||||||
|
|
||||||
|
@ -236,12 +240,12 @@ public class MucOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Account account;
|
private Account account;
|
||||||
private final List<User> users = new ArrayList<>();
|
private final Map<String, User> users = Collections.synchronizedMap(new LinkedHashMap<String, User>());
|
||||||
private List<String> features = new ArrayList<>();
|
private List<String> features = new ArrayList<>();
|
||||||
private Data form = new Data();
|
private Data form = new Data();
|
||||||
private Conversation conversation;
|
private Conversation conversation;
|
||||||
private boolean isOnline = false;
|
private boolean isOnline = false;
|
||||||
private int error = ERROR_UNKNOWN;
|
private int error = ERROR_NO_RESPONSE;
|
||||||
public OnRenameListener onRenameListener = null;
|
public OnRenameListener onRenameListener = null;
|
||||||
private User self;
|
private User self;
|
||||||
private String subject = null;
|
private String subject = null;
|
||||||
|
@ -303,40 +307,15 @@ public class MucOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
public User deleteUser(String name) {
|
public User deleteUser(String name) {
|
||||||
synchronized (this.users) {
|
return this.users.remove(name);
|
||||||
for (int i = 0; i < users.size(); ++i) {
|
|
||||||
if (users.get(i).getName().equals(name)) {
|
|
||||||
return users.remove(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addUser(User user) {
|
public void addUser(User user) {
|
||||||
synchronized (this.users) {
|
this.users.put(user.getName(), user);
|
||||||
for (int i = 0; i < users.size(); ++i) {
|
|
||||||
if (users.get(i).getName().equals(user.getName())) {
|
|
||||||
users.set(i, user);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
users.add(user);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public User findUser(String name) {
|
public User findUser(String name) {
|
||||||
if (name == null) {
|
return this.users.get(name);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
synchronized (this.users) {
|
|
||||||
for (User user : users) {
|
|
||||||
if (user.getName().equals(name)) {
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUserInRoom(String name) {
|
public boolean isUserInRoom(String name) {
|
||||||
|
@ -344,26 +323,34 @@ public class MucOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setError(int error) {
|
public void setError(int error) {
|
||||||
this.isOnline = error == ERROR_NO_ERROR;
|
this.isOnline = isOnline && error == ERROR_NO_ERROR;
|
||||||
this.error = error;
|
this.error = error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setOnline() {
|
||||||
|
this.isOnline = true;
|
||||||
|
}
|
||||||
|
|
||||||
public ArrayList<User> getUsers() {
|
public ArrayList<User> getUsers() {
|
||||||
synchronized (this.users) {
|
return new ArrayList<>(users.values());
|
||||||
return new ArrayList(this.users);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<User> getUsers(int max) {
|
public List<User> getUsers(int max) {
|
||||||
synchronized (this.users) {
|
ArrayList<User> users = new ArrayList<>();
|
||||||
return new ArrayList<>(users.subList(0,Math.min(users.size(),5)));
|
int i = 1;
|
||||||
|
for(User user : this.users.values()) {
|
||||||
|
users.add(user);
|
||||||
|
if (i >= max) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return users;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getUserCount() {
|
public int getUserCount() {
|
||||||
synchronized (this.users) {
|
return this.users.size();
|
||||||
return this.users.size();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getProposedNick() {
|
public String getProposedNick() {
|
||||||
|
@ -400,7 +387,7 @@ public class MucOptions {
|
||||||
|
|
||||||
public void setOffline() {
|
public void setOffline() {
|
||||||
this.users.clear();
|
this.users.clear();
|
||||||
this.error = 0;
|
this.error = ERROR_NO_RESPONSE;
|
||||||
this.isOnline = false;
|
this.isOnline = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,38 +404,34 @@ public class MucOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String createNameFromParticipants() {
|
public String createNameFromParticipants() {
|
||||||
synchronized (this.users) {
|
if (users.size() >= 2) {
|
||||||
if (users.size() >= 2) {
|
List<String> names = new ArrayList<>();
|
||||||
List<String> names = new ArrayList<String>();
|
for (User user : getUsers(5)) {
|
||||||
for (User user : users) {
|
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 {
|
names.add(user.getName());
|
||||||
names.add(user.getName());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
for (int i = 0; i < names.size(); ++i) {
|
|
||||||
builder.append(names.get(i));
|
|
||||||
if (i != names.size() - 1) {
|
|
||||||
builder.append(", ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return builder.toString();
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
for (int i = 0; i < names.size(); ++i) {
|
||||||
|
builder.append(names.get(i));
|
||||||
|
if (i != names.size() - 1) {
|
||||||
|
builder.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public long[] getPgpKeyIds() {
|
public long[] getPgpKeyIds() {
|
||||||
List<Long> ids = new ArrayList<>();
|
List<Long> ids = new ArrayList<>();
|
||||||
synchronized (this.users) {
|
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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ids.add(account.getPgpId());
|
ids.add(account.getPgpId());
|
||||||
|
@ -460,22 +443,18 @@ public class MucOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean pgpKeysInUse() {
|
public boolean pgpKeysInUse() {
|
||||||
synchronized (this.users) {
|
for (User user : this.users.values()) {
|
||||||
for (User user : this.users) {
|
if (user.getPgpKeyId() != 0) {
|
||||||
if (user.getPgpKeyId() != 0) {
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean everybodyHasKeys() {
|
public boolean everybodyHasKeys() {
|
||||||
synchronized (this.users) {
|
for (User user : this.users.values()) {
|
||||||
for (User user : this.users) {
|
if (user.getPgpKeyId() == 0) {
|
||||||
if (user.getPgpKeyId() == 0) {
|
return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -489,15 +468,9 @@ public class MucOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Jid getTrueCounterpart(String counterpart) {
|
public Jid getTrueCounterpart(String name) {
|
||||||
synchronized (this.users) {
|
User user = findUser(name);
|
||||||
for (User user : this.users) {
|
return user == null ? null : user.getJid();
|
||||||
if (user.getName().equals(counterpart)) {
|
|
||||||
return user.getJid();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPassword() {
|
public String getPassword() {
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
package eu.siacs.conversations.parser;
|
package eu.siacs.conversations.parser;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.crypto.PgpEngine;
|
import eu.siacs.conversations.crypto.PgpEngine;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
import eu.siacs.conversations.entities.Contact;
|
import eu.siacs.conversations.entities.Contact;
|
||||||
|
@ -35,6 +39,7 @@ public class PresenceParser extends AbstractParser implements
|
||||||
processConferencePresence(packet, mucOptions);
|
processConferencePresence(packet, mucOptions);
|
||||||
final List<MucOptions.User> tileUserAfter = mucOptions.getUsers(5);
|
final List<MucOptions.User> tileUserAfter = mucOptions.getUsers(5);
|
||||||
if (!tileUserAfter.equals(tileUserBefore)) {
|
if (!tileUserAfter.equals(tileUserBefore)) {
|
||||||
|
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": update tiles for "+conversation.getName());
|
||||||
mXmppConnectionService.getAvatarService().clear(mucOptions);
|
mXmppConnectionService.getAvatarService().clear(mucOptions);
|
||||||
}
|
}
|
||||||
if (before != mucOptions.online() || (mucOptions.online() && count != mucOptions.getUserCount())) {
|
if (before != mucOptions.online() || (mucOptions.online() && count != mucOptions.getUserCount())) {
|
||||||
|
@ -56,12 +61,13 @@ public class PresenceParser extends AbstractParser implements
|
||||||
if (x != null) {
|
if (x != null) {
|
||||||
Element item = x.findChild("item");
|
Element item = x.findChild("item");
|
||||||
if (item != null && !from.isBareJid()) {
|
if (item != null && !from.isBareJid()) {
|
||||||
|
mucOptions.setError(MucOptions.ERROR_NO_ERROR);
|
||||||
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"));
|
||||||
user.setJid(item.getAttributeAsJid("jid"));
|
user.setJid(item.getAttributeAsJid("jid"));
|
||||||
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.setError(MucOptions.ERROR_NO_ERROR);
|
mucOptions.setOnline();
|
||||||
mucOptions.setSelf(user);
|
mucOptions.setSelf(user);
|
||||||
if (mucOptions.mNickChangingInProgress) {
|
if (mucOptions.mNickChangingInProgress) {
|
||||||
if (mucOptions.onRenameListener != null) {
|
if (mucOptions.onRenameListener != null) {
|
||||||
|
@ -108,6 +114,7 @@ public class PresenceParser extends AbstractParser implements
|
||||||
mucOptions.setError(MucOptions.ERROR_MEMBERS_ONLY);
|
mucOptions.setError(MucOptions.ERROR_MEMBERS_ONLY);
|
||||||
} else {
|
} else {
|
||||||
mucOptions.setError(MucOptions.ERROR_UNKNOWN);
|
mucOptions.setError(MucOptions.ERROR_UNKNOWN);
|
||||||
|
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.getResourcepart());
|
||||||
|
|
|
@ -769,7 +769,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
|
||||||
case MucOptions.ERROR_NICK_IN_USE:
|
case MucOptions.ERROR_NICK_IN_USE:
|
||||||
showSnackbar(R.string.nick_in_use, R.string.edit, clickToMuc);
|
showSnackbar(R.string.nick_in_use, R.string.edit, clickToMuc);
|
||||||
break;
|
break;
|
||||||
case MucOptions.ERROR_UNKNOWN:
|
case MucOptions.ERROR_NO_RESPONSE:
|
||||||
showSnackbar(R.string.conference_not_found, R.string.leave, leaveMuc);
|
showSnackbar(R.string.conference_not_found, R.string.leave, leaveMuc);
|
||||||
break;
|
break;
|
||||||
case MucOptions.ERROR_PASSWORD_REQUIRED:
|
case MucOptions.ERROR_PASSWORD_REQUIRED:
|
||||||
|
@ -784,6 +784,9 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
|
||||||
case MucOptions.KICKED_FROM_ROOM:
|
case MucOptions.KICKED_FROM_ROOM:
|
||||||
showSnackbar(R.string.conference_kicked, R.string.join, joinMuc);
|
showSnackbar(R.string.conference_kicked, R.string.join, joinMuc);
|
||||||
break;
|
break;
|
||||||
|
case MucOptions.ERROR_UNKNOWN:
|
||||||
|
showSnackbar(R.string.conference_unknown_error, R.string.try_again, joinMuc);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -242,6 +242,7 @@
|
||||||
<string name="you">You</string>
|
<string name="you">You</string>
|
||||||
<string name="action_edit_subject">Edit conference subject</string>
|
<string name="action_edit_subject">Edit conference subject</string>
|
||||||
<string name="conference_not_found">Conference not found</string>
|
<string name="conference_not_found">Conference not found</string>
|
||||||
|
<string name="conference_unknown_error">Unknown error received</string>2
|
||||||
<string name="leave">Leave</string>
|
<string name="leave">Leave</string>
|
||||||
<string name="contact_added_you">Contact added you to contact list</string>
|
<string name="contact_added_you">Contact added you to contact list</string>
|
||||||
<string name="add_back">Add back</string>
|
<string name="add_back">Add back</string>
|
||||||
|
|
Loading…
Reference in New Issue