store avatars received over muc presence in contact
This commit is contained in:
		
							parent
							
								
									b8d831f02a
								
							
						
					
					
						commit
						1985f6bdec
					
				|  | @ -431,10 +431,14 @@ public class Contact implements ListItem, Blockable { | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public String getAvatar() { | 	public String getAvatarFilename() { | ||||||
| 		return avatar == null ? null : avatar.getFilename(); | 		return avatar == null ? null : avatar.getFilename(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	public Avatar getAvatar() { | ||||||
|  | 		return avatar; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	public boolean mutualPresenceSubscription() { | 	public boolean mutualPresenceSubscription() { | ||||||
| 		return getOption(Options.FROM) && getOption(Options.TO); | 		return getOption(Options.FROM) && getOption(Options.TO); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -23,7 +23,31 @@ import rocks.xmpp.addr.Jid; | ||||||
| 
 | 
 | ||||||
| public class MucOptions { | public class MucOptions { | ||||||
| 
 | 
 | ||||||
|  |     public static final String STATUS_CODE_SELF_PRESENCE = "110"; | ||||||
|  |     public static final String STATUS_CODE_ROOM_CREATED = "201"; | ||||||
|  |     public static final String STATUS_CODE_BANNED = "301"; | ||||||
|  |     public static final String STATUS_CODE_CHANGED_NICK = "303"; | ||||||
|  |     public static final String STATUS_CODE_KICKED = "307"; | ||||||
|  |     public static final String STATUS_CODE_AFFILIATION_CHANGE = "321"; | ||||||
|  |     public static final String STATUS_CODE_LOST_MEMBERSHIP = "322"; | ||||||
|  |     public static final String STATUS_CODE_SHUTDOWN = "332"; | ||||||
|  |     private final Set<User> users = new HashSet<>(); | ||||||
|  |     private final Conversation conversation; | ||||||
|  |     public OnRenameListener onRenameListener = null; | ||||||
|     private boolean mAutoPushConfiguration = true; |     private boolean mAutoPushConfiguration = true; | ||||||
|  |     private Account account; | ||||||
|  |     private ServiceDiscoveryResult serviceDiscoveryResult; | ||||||
|  |     private boolean isOnline = false; | ||||||
|  |     private Error error = Error.NONE; | ||||||
|  |     private User self; | ||||||
|  |     private String password = null; | ||||||
|  |     public MucOptions(Conversation conversation) { | ||||||
|  |         this.account = conversation.getAccount(); | ||||||
|  |         this.conversation = conversation; | ||||||
|  |         this.self = new User(this, createJoinJid(getProposedNick())); | ||||||
|  |         this.self.affiliation = Affiliation.of(conversation.getAttribute("affiliation")); | ||||||
|  |         this.self.role = Role.of(conversation.getAttribute("role")); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     public Account getAccount() { |     public Account getAccount() { | ||||||
|         return this.conversation.getAccount(); |         return this.conversation.getAccount(); | ||||||
|  | @ -73,302 +97,6 @@ public class MucOptions { | ||||||
|         return MessageArchiveService.Version.has(getFeatures()); |         return MessageArchiveService.Version.has(getFeatures()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 	public enum Affiliation { |  | ||||||
| 		OWNER(4, R.string.owner), |  | ||||||
| 		ADMIN(3, R.string.admin), |  | ||||||
| 		MEMBER(2, R.string.member), |  | ||||||
| 		OUTCAST(0, R.string.outcast), |  | ||||||
| 		NONE(1, R.string.no_affiliation); |  | ||||||
| 
 |  | ||||||
| 		Affiliation(int rank, int resId) { |  | ||||||
| 			this.resId = resId; |  | ||||||
| 			this.rank = rank; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		private int resId; |  | ||||||
| 		private int rank; |  | ||||||
| 
 |  | ||||||
| 		public int getResId() { |  | ||||||
| 			return resId; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		@Override |  | ||||||
| 		public String toString() { |  | ||||||
| 			return name().toLowerCase(Locale.US); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public boolean outranks(Affiliation affiliation) { |  | ||||||
| 			return rank > affiliation.rank; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public boolean ranks(Affiliation affiliation) { |  | ||||||
| 			return rank >= affiliation.rank; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public static Affiliation of(@Nullable String value) { |  | ||||||
| 			if (value == null) { |  | ||||||
| 				return NONE; |  | ||||||
| 			} |  | ||||||
| 			try { |  | ||||||
| 				return Affiliation.valueOf(value.toUpperCase(Locale.US)); |  | ||||||
| 			} catch (IllegalArgumentException e) { |  | ||||||
| 				return NONE; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public enum Role { |  | ||||||
| 		MODERATOR(R.string.moderator, 3), |  | ||||||
| 		VISITOR(R.string.visitor, 1), |  | ||||||
| 		PARTICIPANT(R.string.participant, 2), |  | ||||||
| 		NONE(R.string.no_role, 0); |  | ||||||
| 
 |  | ||||||
| 		Role(int resId, int rank) { |  | ||||||
| 			this.resId = resId; |  | ||||||
| 			this.rank = rank; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		private int resId; |  | ||||||
| 		private int rank; |  | ||||||
| 
 |  | ||||||
| 		public int getResId() { |  | ||||||
| 			return resId; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		@Override |  | ||||||
| 		public String toString() { |  | ||||||
| 			return name().toLowerCase(Locale.US); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public boolean ranks(Role role) { |  | ||||||
| 			return rank >= role.rank; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public static Role of(@Nullable String value) { |  | ||||||
| 			if (value == null) { |  | ||||||
| 				return NONE; |  | ||||||
| 			} |  | ||||||
| 			try { |  | ||||||
| 				return Role.valueOf(value.toUpperCase(Locale.US)); |  | ||||||
| 			} catch (IllegalArgumentException e) { |  | ||||||
| 				return NONE; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public enum Error { |  | ||||||
| 		NO_RESPONSE, |  | ||||||
| 		SERVER_NOT_FOUND, |  | ||||||
| 		NONE, |  | ||||||
| 		NICK_IN_USE, |  | ||||||
| 		PASSWORD_REQUIRED, |  | ||||||
| 		BANNED, |  | ||||||
| 		MEMBERS_ONLY, |  | ||||||
| 		RESOURCE_CONSTRAINT, |  | ||||||
| 		KICKED, |  | ||||||
| 		SHUTDOWN, |  | ||||||
| 		DESTROYED, |  | ||||||
| 		INVALID_NICK, |  | ||||||
| 		UNKNOWN |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public static final String STATUS_CODE_SELF_PRESENCE = "110"; |  | ||||||
| 	public static final String STATUS_CODE_ROOM_CREATED = "201"; |  | ||||||
| 	public static final String STATUS_CODE_BANNED = "301"; |  | ||||||
| 	public static final String STATUS_CODE_CHANGED_NICK = "303"; |  | ||||||
| 	public static final String STATUS_CODE_KICKED = "307"; |  | ||||||
| 	public static final String STATUS_CODE_AFFILIATION_CHANGE = "321"; |  | ||||||
| 	public static final String STATUS_CODE_LOST_MEMBERSHIP = "322"; |  | ||||||
| 	public static final String STATUS_CODE_SHUTDOWN = "332"; |  | ||||||
| 
 |  | ||||||
| 	private interface OnEventListener { |  | ||||||
| 		void onSuccess(); |  | ||||||
| 
 |  | ||||||
| 		void onFailure(); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public interface OnRenameListener extends OnEventListener { |  | ||||||
| 
 |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public static class User implements Comparable<User> { |  | ||||||
| 		private Role role = Role.NONE; |  | ||||||
| 		private Affiliation affiliation = Affiliation.NONE; |  | ||||||
| 		private Jid realJid; |  | ||||||
| 		private Jid fullJid; |  | ||||||
| 		private long pgpKeyId = 0; |  | ||||||
| 		private Avatar avatar; |  | ||||||
| 		private MucOptions options; |  | ||||||
| 		private ChatState chatState = Config.DEFAULT_CHATSTATE; |  | ||||||
| 
 |  | ||||||
| 		public User(MucOptions options, Jid from) { |  | ||||||
| 			this.options = options; |  | ||||||
| 			this.fullJid = from; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public String getName() { |  | ||||||
| 			return fullJid == null ? null : fullJid.getResource(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public void setRealJid(Jid jid) { |  | ||||||
| 			this.realJid = jid != null ? jid.asBareJid() : null; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public Role getRole() { |  | ||||||
| 			return this.role; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public void setRole(String role) { |  | ||||||
| 			this.role = Role.of(role); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public Affiliation getAffiliation() { |  | ||||||
| 			return this.affiliation; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public void setAffiliation(String affiliation) { |  | ||||||
| 			this.affiliation = Affiliation.of(affiliation); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public void setPgpKeyId(long id) { |  | ||||||
| 			this.pgpKeyId = id; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public long getPgpKeyId() { |  | ||||||
| 			if (this.pgpKeyId != 0) { |  | ||||||
| 				return this.pgpKeyId; |  | ||||||
| 			} else if (realJid != null) { |  | ||||||
| 				return getAccount().getRoster().getContact(realJid).getPgpKeyId(); |  | ||||||
| 			} else { |  | ||||||
| 				return 0; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public Contact getContact() { |  | ||||||
| 			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) { |  | ||||||
| 			if (this.avatar != null && this.avatar.equals(avatar)) { |  | ||||||
| 				return false; |  | ||||||
| 			} else { |  | ||||||
| 				this.avatar = avatar; |  | ||||||
| 				return true; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public String getAvatar() { |  | ||||||
| 			return avatar == null ? null : avatar.getFilename(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public Account getAccount() { |  | ||||||
| 			return options.getAccount(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public Conversation getConversation() { |  | ||||||
| 			return options.getConversation(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		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; |  | ||||||
| 
 |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public boolean isDomain() { |  | ||||||
| 			return realJid != null && realJid.getLocal() == null && role == Role.NONE; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		@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() + "]"; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public boolean realJidMatchesAccount() { |  | ||||||
| 			return realJid != null && realJid.equals(options.account.getJid().asBareJid()); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		@Override |  | ||||||
| 		public int compareTo(@NonNull User another) { |  | ||||||
| 			if (another.getAffiliation().outranks(getAffiliation())) { |  | ||||||
| 				return 1; |  | ||||||
| 			} else if (getAffiliation().outranks(another.getAffiliation())) { |  | ||||||
| 				return -1; |  | ||||||
| 			} else { |  | ||||||
| 				return getComparableName().compareToIgnoreCase(another.getComparableName()); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 		private String getComparableName() { |  | ||||||
| 			Contact contact = getContact(); |  | ||||||
| 			if (contact != null) { |  | ||||||
| 				return contact.getDisplayName(); |  | ||||||
| 			} else { |  | ||||||
| 				String name = getName(); |  | ||||||
| 				return name == null ? "" : name; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public Jid getRealJid() { |  | ||||||
| 			return realJid; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public boolean setChatState(ChatState chatState) { |  | ||||||
| 			if (this.chatState == chatState) { |  | ||||||
| 				return false; |  | ||||||
| 			} |  | ||||||
| 			this.chatState = chatState; |  | ||||||
| 			return true; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	private Account account; |  | ||||||
| 	private final Set<User> users = new HashSet<>(); |  | ||||||
| 	private ServiceDiscoveryResult serviceDiscoveryResult; |  | ||||||
| 	private final Conversation conversation; |  | ||||||
| 	private boolean isOnline = false; |  | ||||||
| 	private Error error = Error.NONE; |  | ||||||
| 	public OnRenameListener onRenameListener = null; |  | ||||||
| 	private User self; |  | ||||||
| 	private String password = null; |  | ||||||
| 
 |  | ||||||
| 	public MucOptions(Conversation conversation) { |  | ||||||
| 		this.account = conversation.getAccount(); |  | ||||||
| 		this.conversation = conversation; |  | ||||||
| 		this.self = new User(this, createJoinJid(getProposedNick())); |  | ||||||
| 		this.self.affiliation = Affiliation.of(conversation.getAttribute("affiliation")); |  | ||||||
| 		this.self.role = Role.of(conversation.getAttribute("role")); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
|     public boolean updateConfiguration(ServiceDiscoveryResult serviceDiscoveryResult) { |     public boolean updateConfiguration(ServiceDiscoveryResult serviceDiscoveryResult) { | ||||||
|         this.serviceDiscoveryResult = serviceDiscoveryResult; |         this.serviceDiscoveryResult = serviceDiscoveryResult; | ||||||
|         String name; |         String name; | ||||||
|  | @ -392,14 +120,13 @@ public class MucOptions { | ||||||
|         return changed; |         return changed; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|     private Data getRoomInfoForm() { |     private Data getRoomInfoForm() { | ||||||
|         final List<Data> forms = serviceDiscoveryResult == null ? Collections.emptyList() : serviceDiscoveryResult.forms; |         final List<Data> forms = serviceDiscoveryResult == null ? Collections.emptyList() : serviceDiscoveryResult.forms; | ||||||
|         return forms.size() == 0 ? new Data() : forms.get(0); |         return forms.size() == 0 ? new Data() : forms.get(0); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public String getAvatar() { |     public String getAvatar() { | ||||||
| 		return account.getRoster().getContact(conversation.getJid()).getAvatar(); |         return account.getRoster().getContact(conversation.getJid()).getAvatarFilename(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public boolean hasFeature(String feature) { |     public boolean hasFeature(String feature) { | ||||||
|  | @ -444,7 +171,6 @@ public class MucOptions { | ||||||
|         return conversation.getBooleanAttribute(Conversation.ATTRIBUTE_MEMBERS_ONLY, false); |         return conversation.getBooleanAttribute(Conversation.ATTRIBUTE_MEMBERS_ONLY, false); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|     public List<String> getFeatures() { |     public List<String> getFeatures() { | ||||||
|         return this.serviceDiscoveryResult != null ? this.serviceDiscoveryResult.features : Collections.emptyList(); |         return this.serviceDiscoveryResult != null ? this.serviceDiscoveryResult.features : Collections.emptyList(); | ||||||
|     } |     } | ||||||
|  | @ -559,10 +285,10 @@ public class MucOptions { | ||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 	public User findOrCreateUserByRealJid(Jid jid) { |     public User findOrCreateUserByRealJid(Jid jid, Jid fullJid) { | ||||||
|         User user = findUserByRealJid(jid); |         User user = findUserByRealJid(jid); | ||||||
|         if (user == null) { |         if (user == null) { | ||||||
| 			user = new User(this, null); |             user = new User(this, fullJid); | ||||||
|             user.setRealJid(jid); |             user.setRealJid(jid); | ||||||
|         } |         } | ||||||
|         return user; |         return user; | ||||||
|  | @ -570,12 +296,7 @@ public class MucOptions { | ||||||
| 
 | 
 | ||||||
|     public User findUser(ReadByMarker readByMarker) { |     public User findUser(ReadByMarker readByMarker) { | ||||||
|         if (readByMarker.getRealJid() != null) { |         if (readByMarker.getRealJid() != null) { | ||||||
| 			User user = findUserByRealJid(readByMarker.getRealJid().asBareJid()); |             return findOrCreateUserByRealJid(readByMarker.getRealJid().asBareJid(), readByMarker.getFullJid()); | ||||||
| 			if (user == null) { |  | ||||||
| 				user = new User(this, readByMarker.getFullJid()); |  | ||||||
| 				user.setRealJid(readByMarker.getRealJid()); |  | ||||||
| 			} |  | ||||||
| 			return user; |  | ||||||
|         } else if (readByMarker.getFullJid() != null) { |         } else if (readByMarker.getFullJid() != null) { | ||||||
|             return findUserByFullJid(readByMarker.getFullJid()); |             return findUserByFullJid(readByMarker.getFullJid()); | ||||||
|         } else { |         } else { | ||||||
|  | @ -591,11 +312,6 @@ public class MucOptions { | ||||||
|         return findUserByFullJid(jid) != null; |         return findUserByFullJid(jid) != null; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 	public void setError(Error error) { |  | ||||||
| 		this.isOnline = isOnline && error == Error.NONE; |  | ||||||
| 		this.error = error; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
|     public boolean setOnline() { |     public boolean setOnline() { | ||||||
|         boolean before = this.isOnline; |         boolean before = this.isOnline; | ||||||
|         this.isOnline = true; |         this.isOnline = true; | ||||||
|  | @ -684,6 +400,11 @@ public class MucOptions { | ||||||
|         return this.error; |         return this.error; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public void setError(Error error) { | ||||||
|  |         this.isOnline = isOnline && error == Error.NONE; | ||||||
|  |         this.error = error; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public void setOnRenameListener(OnRenameListener listener) { |     public void setOnRenameListener(OnRenameListener listener) { | ||||||
|         this.onRenameListener = listener; |         this.onRenameListener = listener; | ||||||
|     } |     } | ||||||
|  | @ -838,4 +559,274 @@ public class MucOptions { | ||||||
|         } |         } | ||||||
|         return members; |         return members; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     public enum Affiliation { | ||||||
|  |         OWNER(4, R.string.owner), | ||||||
|  |         ADMIN(3, R.string.admin), | ||||||
|  |         MEMBER(2, R.string.member), | ||||||
|  |         OUTCAST(0, R.string.outcast), | ||||||
|  |         NONE(1, R.string.no_affiliation); | ||||||
|  | 
 | ||||||
|  |         private int resId; | ||||||
|  |         private int rank; | ||||||
|  |         Affiliation(int rank, int resId) { | ||||||
|  |             this.resId = resId; | ||||||
|  |             this.rank = rank; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public static Affiliation of(@Nullable String value) { | ||||||
|  |             if (value == null) { | ||||||
|  |                 return NONE; | ||||||
|  |             } | ||||||
|  |             try { | ||||||
|  |                 return Affiliation.valueOf(value.toUpperCase(Locale.US)); | ||||||
|  |             } catch (IllegalArgumentException e) { | ||||||
|  |                 return NONE; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public int getResId() { | ||||||
|  |             return resId; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @Override | ||||||
|  |         public String toString() { | ||||||
|  |             return name().toLowerCase(Locale.US); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public boolean outranks(Affiliation affiliation) { | ||||||
|  |             return rank > affiliation.rank; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public boolean ranks(Affiliation affiliation) { | ||||||
|  |             return rank >= affiliation.rank; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public enum Role { | ||||||
|  |         MODERATOR(R.string.moderator, 3), | ||||||
|  |         VISITOR(R.string.visitor, 1), | ||||||
|  |         PARTICIPANT(R.string.participant, 2), | ||||||
|  |         NONE(R.string.no_role, 0); | ||||||
|  | 
 | ||||||
|  |         private int resId; | ||||||
|  |         private int rank; | ||||||
|  |         Role(int resId, int rank) { | ||||||
|  |             this.resId = resId; | ||||||
|  |             this.rank = rank; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public static Role of(@Nullable String value) { | ||||||
|  |             if (value == null) { | ||||||
|  |                 return NONE; | ||||||
|  |             } | ||||||
|  |             try { | ||||||
|  |                 return Role.valueOf(value.toUpperCase(Locale.US)); | ||||||
|  |             } catch (IllegalArgumentException e) { | ||||||
|  |                 return NONE; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public int getResId() { | ||||||
|  |             return resId; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @Override | ||||||
|  |         public String toString() { | ||||||
|  |             return name().toLowerCase(Locale.US); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public boolean ranks(Role role) { | ||||||
|  |             return rank >= role.rank; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public enum Error { | ||||||
|  |         NO_RESPONSE, | ||||||
|  |         SERVER_NOT_FOUND, | ||||||
|  |         NONE, | ||||||
|  |         NICK_IN_USE, | ||||||
|  |         PASSWORD_REQUIRED, | ||||||
|  |         BANNED, | ||||||
|  |         MEMBERS_ONLY, | ||||||
|  |         RESOURCE_CONSTRAINT, | ||||||
|  |         KICKED, | ||||||
|  |         SHUTDOWN, | ||||||
|  |         DESTROYED, | ||||||
|  |         INVALID_NICK, | ||||||
|  |         UNKNOWN | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private interface OnEventListener { | ||||||
|  |         void onSuccess(); | ||||||
|  | 
 | ||||||
|  |         void onFailure(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public interface OnRenameListener extends OnEventListener { | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static class User implements Comparable<User> { | ||||||
|  |         private Role role = Role.NONE; | ||||||
|  |         private Affiliation affiliation = Affiliation.NONE; | ||||||
|  |         private Jid realJid; | ||||||
|  |         private Jid fullJid; | ||||||
|  |         private long pgpKeyId = 0; | ||||||
|  |         private Avatar avatar; | ||||||
|  |         private MucOptions options; | ||||||
|  |         private ChatState chatState = Config.DEFAULT_CHATSTATE; | ||||||
|  | 
 | ||||||
|  |         public User(MucOptions options, Jid fullJid) { | ||||||
|  |             this.options = options; | ||||||
|  |             this.fullJid = fullJid; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public String getName() { | ||||||
|  |             return fullJid == null ? null : fullJid.getResource(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public Role getRole() { | ||||||
|  |             return this.role; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public void setRole(String role) { | ||||||
|  |             this.role = Role.of(role); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public Affiliation getAffiliation() { | ||||||
|  |             return this.affiliation; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public void setAffiliation(String affiliation) { | ||||||
|  |             this.affiliation = Affiliation.of(affiliation); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public long getPgpKeyId() { | ||||||
|  |             if (this.pgpKeyId != 0) { | ||||||
|  |                 return this.pgpKeyId; | ||||||
|  |             } else if (realJid != null) { | ||||||
|  |                 return getAccount().getRoster().getContact(realJid).getPgpKeyId(); | ||||||
|  |             } else { | ||||||
|  |                 return 0; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public void setPgpKeyId(long id) { | ||||||
|  |             this.pgpKeyId = id; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public Contact getContact() { | ||||||
|  |             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) { | ||||||
|  |             if (this.avatar != null && this.avatar.equals(avatar)) { | ||||||
|  |                 return false; | ||||||
|  |             } else { | ||||||
|  |                 this.avatar = avatar; | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public String getAvatar() { | ||||||
|  |             if (avatar != null) { | ||||||
|  |                 return avatar.getFilename(); | ||||||
|  |             } | ||||||
|  |             Avatar avatar = realJid != null ? getAccount().getRoster().getContact(realJid).getAvatar() : null; | ||||||
|  |             return avatar == null ? null : avatar.getFilename(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public Account getAccount() { | ||||||
|  |             return options.getAccount(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public Conversation getConversation() { | ||||||
|  |             return options.getConversation(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         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; | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public boolean isDomain() { | ||||||
|  |             return realJid != null && realJid.getLocal() == null && role == Role.NONE; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @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() + "]"; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public boolean realJidMatchesAccount() { | ||||||
|  |             return realJid != null && realJid.equals(options.account.getJid().asBareJid()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @Override | ||||||
|  |         public int compareTo(@NonNull User another) { | ||||||
|  |             if (another.getAffiliation().outranks(getAffiliation())) { | ||||||
|  |                 return 1; | ||||||
|  |             } else if (getAffiliation().outranks(another.getAffiliation())) { | ||||||
|  |                 return -1; | ||||||
|  |             } else { | ||||||
|  |                 return getComparableName().compareToIgnoreCase(another.getComparableName()); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private String getComparableName() { | ||||||
|  |             Contact contact = getContact(); | ||||||
|  |             if (contact != null) { | ||||||
|  |                 return contact.getDisplayName(); | ||||||
|  |             } else { | ||||||
|  |                 String name = getName(); | ||||||
|  |                 return name == null ? "" : name; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public Jid getRealJid() { | ||||||
|  |             return realJid; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public void setRealJid(Jid jid) { | ||||||
|  |             this.realJid = jid != null ? jid.asBareJid() : null; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public boolean setChatState(ChatState chatState) { | ||||||
|  |             if (this.chatState == chatState) { | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  |             this.chatState = chatState; | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -119,6 +119,14 @@ public class PresenceParser extends AbstractParser implements | ||||||
| 								if (user.setAvatar(avatar)) { | 								if (user.setAvatar(avatar)) { | ||||||
| 									mXmppConnectionService.getAvatarService().clear(user); | 									mXmppConnectionService.getAvatarService().clear(user); | ||||||
| 								} | 								} | ||||||
|  | 								if (user.getRealJid() != null) { | ||||||
|  | 									Contact c = conversation.getAccount().getRoster().getContact(user.getRealJid()); | ||||||
|  | 									if (c.setAvatar(avatar)) { | ||||||
|  | 										mXmppConnectionService.syncRoster(conversation.getAccount()); | ||||||
|  | 										mXmppConnectionService.getAvatarService().clear(c); | ||||||
|  | 										mXmppConnectionService.updateRosterUi(); | ||||||
|  | 									} | ||||||
|  | 								} | ||||||
| 							} else if (mXmppConnectionService.isDataSaverDisabled()) { | 							} else if (mXmppConnectionService.isDataSaverDisabled()) { | ||||||
| 								mXmppConnectionService.fetchAvatar(mucOptions.getAccount(), avatar); | 								mXmppConnectionService.fetchAvatar(mucOptions.getAccount(), avatar); | ||||||
| 							} | 							} | ||||||
|  |  | ||||||
|  | @ -911,7 +911,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { | ||||||
| 		final SQLiteDatabase db = this.getWritableDatabase(); | 		final SQLiteDatabase db = this.getWritableDatabase(); | ||||||
| 		db.beginTransaction(); | 		db.beginTransaction(); | ||||||
| 		for (Contact contact : roster.getContacts()) { | 		for (Contact contact : roster.getContacts()) { | ||||||
| 			if (contact.getOption(Contact.Options.IN_ROSTER) || contact.getAvatar() != null) { | 			if (contact.getOption(Contact.Options.IN_ROSTER) || contact.getAvatarFilename() != null) { | ||||||
| 				db.insert(Contact.TABLENAME, null, contact.getContentValues()); | 				db.insert(Contact.TABLENAME, null, contact.getContentValues()); | ||||||
| 			} else { | 			} else { | ||||||
| 				String where = Contact.ACCOUNT + "=? AND " + Contact.JID + "=?"; | 				String where = Contact.ACCOUNT + "=? AND " + Contact.JID + "=?"; | ||||||
|  |  | ||||||
|  | @ -69,8 +69,8 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded { | ||||||
| 		if (contact.getProfilePhoto() != null) { | 		if (contact.getProfilePhoto() != null) { | ||||||
| 			avatar = mXmppConnectionService.getFileBackend().cropCenterSquare(Uri.parse(contact.getProfilePhoto()), size); | 			avatar = mXmppConnectionService.getFileBackend().cropCenterSquare(Uri.parse(contact.getProfilePhoto()), size); | ||||||
| 		} | 		} | ||||||
| 		if (avatar == null && contact.getAvatar() != null) { | 		if (avatar == null && contact.getAvatarFilename() != null) { | ||||||
| 			avatar = mXmppConnectionService.getFileBackend().getAvatar(contact.getAvatar(), size); | 			avatar = mXmppConnectionService.getFileBackend().getAvatar(contact.getAvatarFilename(), size); | ||||||
| 		} | 		} | ||||||
| 		if (avatar == null) { | 		if (avatar == null) { | ||||||
| 			avatar = get(contact.getDisplayName(), contact.getJid().asBareJid().toString(), size, cachedOnly); | 			avatar = get(contact.getDisplayName(), contact.getJid().asBareJid().toString(), size, cachedOnly); | ||||||
|  | @ -128,7 +128,7 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded { | ||||||
| 
 | 
 | ||||||
| 	public Bitmap get(final MucOptions.User user, final int size, boolean cachedOnly) { | 	public Bitmap get(final MucOptions.User user, final int size, boolean cachedOnly) { | ||||||
| 		Contact c = user.getContact(); | 		Contact c = user.getContact(); | ||||||
| 		if (c != null && (c.getProfilePhoto() != null || c.getAvatar() != null || user.getAvatar() == null)) { | 		if (c != null && (c.getProfilePhoto() != null || c.getAvatarFilename() != null || user.getAvatar() == null)) { | ||||||
| 			return get(c, size, cachedOnly); | 			return get(c, size, cachedOnly); | ||||||
| 		} else { | 		} else { | ||||||
| 			return getImpl(user, size, cachedOnly); | 			return getImpl(user, size, cachedOnly); | ||||||
|  | @ -165,6 +165,10 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded { | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		for (Conversation conversation : mXmppConnectionService.findAllConferencesWith(contact)) { | 		for (Conversation conversation : mXmppConnectionService.findAllConferencesWith(contact)) { | ||||||
|  | 			MucOptions.User user = conversation.getMucOptions().findUserByRealJid(contact.getJid().asBareJid()); | ||||||
|  | 			if (user != null) { | ||||||
|  | 				clear(user); | ||||||
|  | 			} | ||||||
| 			clear(conversation); | 			clear(conversation); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -216,7 +220,7 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded { | ||||||
| 				Jid jid = bookmark.getJid(); | 				Jid jid = bookmark.getJid(); | ||||||
| 				Account account = bookmark.getAccount(); | 				Account account = bookmark.getAccount(); | ||||||
| 				Contact contact = jid == null ? null : account.getRoster().getContact(jid); | 				Contact contact = jid == null ? null : account.getRoster().getContact(jid); | ||||||
| 				if (contact != null && contact.getAvatar() != null) { | 				if (contact != null && contact.getAvatarFilename() != null) { | ||||||
| 					return get(contact, size, cachedOnly); | 					return get(contact, size, cachedOnly); | ||||||
| 				} | 				} | ||||||
| 				String seed = jid != null ? jid.asBareJid().toString() : null; | 				String seed = jid != null ? jid.asBareJid().toString() : null; | ||||||
|  | @ -400,14 +404,14 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded { | ||||||
| 			return get(message.getCounterparts(), size, cachedOnly); | 			return get(message.getCounterparts(), size, cachedOnly); | ||||||
| 		} else if (message.getStatus() == Message.STATUS_RECEIVED) { | 		} else if (message.getStatus() == Message.STATUS_RECEIVED) { | ||||||
| 			Contact c = message.getContact(); | 			Contact c = message.getContact(); | ||||||
| 			if (c != null && (c.getProfilePhoto() != null || c.getAvatar() != null)) { | 			if (c != null && (c.getProfilePhoto() != null || c.getAvatarFilename() != null)) { | ||||||
| 				return get(c, size, cachedOnly); | 				return get(c, size, cachedOnly); | ||||||
| 			} else if (conversation instanceof Conversation && message.getConversation().getMode() == Conversation.MODE_MULTI) { | 			} else if (conversation instanceof Conversation && message.getConversation().getMode() == Conversation.MODE_MULTI) { | ||||||
| 				final Jid trueCounterpart = message.getTrueCounterpart(); | 				final Jid trueCounterpart = message.getTrueCounterpart(); | ||||||
| 				final MucOptions mucOptions = ((Conversation) conversation).getMucOptions(); | 				final MucOptions mucOptions = ((Conversation) conversation).getMucOptions(); | ||||||
| 				MucOptions.User user; | 				MucOptions.User user; | ||||||
| 				if (trueCounterpart != null) { | 				if (trueCounterpart != null) { | ||||||
| 					user = mucOptions.findUserByRealJid(trueCounterpart); | 					user = mucOptions.findOrCreateUserByRealJid(trueCounterpart, message.getCounterpart()); | ||||||
| 				} else { | 				} else { | ||||||
| 					user = mucOptions.findUserByFullJid(message.getCounterpart()); | 					user = mucOptions.findUserByFullJid(message.getCounterpart()); | ||||||
| 				} | 				} | ||||||
|  | @ -508,9 +512,9 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded { | ||||||
| 			Uri uri = null; | 			Uri uri = null; | ||||||
| 			if (contact.getProfilePhoto() != null) { | 			if (contact.getProfilePhoto() != null) { | ||||||
| 				uri = Uri.parse(contact.getProfilePhoto()); | 				uri = Uri.parse(contact.getProfilePhoto()); | ||||||
| 			} else if (contact.getAvatar() != null) { | 			} else if (contact.getAvatarFilename() != null) { | ||||||
| 				uri = mXmppConnectionService.getFileBackend().getAvatarUri( | 				uri = mXmppConnectionService.getFileBackend().getAvatarUri( | ||||||
| 						contact.getAvatar()); | 						contact.getAvatarFilename()); | ||||||
| 			} | 			} | ||||||
| 			if (drawTile(canvas, uri, left, top, right, bottom)) { | 			if (drawTile(canvas, uri, left, top, right, bottom)) { | ||||||
| 				return true; | 				return true; | ||||||
|  |  | ||||||
|  | @ -3113,6 +3113,14 @@ public class XmppConnectionService extends Service { | ||||||
| 											getAvatarService().clear(user); | 											getAvatarService().clear(user); | ||||||
| 											updateConversationUi(); | 											updateConversationUi(); | ||||||
| 											updateMucRosterUi(); | 											updateMucRosterUi(); | ||||||
|  | 										} | ||||||
|  | 										if (user.getRealJid() != null) { | ||||||
|  | 										    Contact contact = account.getRoster().getContact(user.getRealJid()); | ||||||
|  | 										    if (contact.setAvatar(avatar)) { | ||||||
|  |                                                 syncRoster(account); | ||||||
|  |                                                 getAvatarService().clear(contact); | ||||||
|  |                                                 updateRosterUi(); | ||||||
|  |                                             } | ||||||
|                                         } |                                         } | ||||||
| 									} | 									} | ||||||
| 								} | 								} | ||||||
|  |  | ||||||
|  | @ -1033,7 +1033,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke | ||||||
|                     Jid tcp = message.getTrueCounterpart(); |                     Jid tcp = message.getTrueCounterpart(); | ||||||
|                     Jid cp = message.getCounterpart(); |                     Jid cp = message.getCounterpart(); | ||||||
|                     if (cp != null && !cp.isBareJid()) { |                     if (cp != null && !cp.isBareJid()) { | ||||||
|                         User userByRealJid = tcp != null ? conversation.getMucOptions().findOrCreateUserByRealJid(tcp) : null; |                         User userByRealJid = tcp != null ? conversation.getMucOptions().findOrCreateUserByRealJid(tcp, cp) : null; | ||||||
|                         final User user = userByRealJid != null ? userByRealJid : conversation.getMucOptions().findUserByFullJid(cp); |                         final User user = userByRealJid != null ? userByRealJid : conversation.getMucOptions().findUserByFullJid(cp); | ||||||
|                         final PopupMenu popupMenu = new PopupMenu(getActivity(), v); |                         final PopupMenu popupMenu = new PopupMenu(getActivity(), v); | ||||||
|                         popupMenu.inflate(R.menu.muc_details_context); |                         popupMenu.inflate(R.menu.muc_details_context); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Daniel Gultsch
						Daniel Gultsch