store avatars received over muc presence in contact

This commit is contained in:
Daniel Gultsch 2018-09-21 12:27:58 +02:00
parent b8d831f02a
commit 1985f6bdec
7 changed files with 797 additions and 782 deletions

View file

@ -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);
} }

View file

@ -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;
}
}
} }

View file

@ -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);
} }

View file

@ -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 + "=?";

View file

@ -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;

View file

@ -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();
}
} }
} }
} }

View file

@ -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);