diff --git a/src/main/java/eu/siacs/conversations/entities/Account.java b/src/main/java/eu/siacs/conversations/entities/Account.java index 08cb46026..82592d7b5 100644 --- a/src/main/java/eu/siacs/conversations/entities/Account.java +++ b/src/main/java/eu/siacs/conversations/entities/Account.java @@ -22,12 +22,14 @@ import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.PgpDecryptionService; import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession; +import eu.siacs.conversations.services.AvatarService; import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.utils.XmppUri; import eu.siacs.conversations.xmpp.XmppConnection; import rocks.xmpp.addr.Jid; -public class Account extends AbstractEntity { +public class Account extends AbstractEntity implements AvatarService.Avatarable { public static final String TABLENAME = "accounts"; @@ -579,6 +581,11 @@ public class Account extends AbstractEntity { return this.getStatus() == State.ONLINE && this.getXmppConnection() != null; } + @Override + public int getAvatarBackgroundColor() { + return UIHelper.getColorForName(jid.asBareJid().toString()); + } + public enum State { DISABLED(false, false), OFFLINE(false), diff --git a/src/main/java/eu/siacs/conversations/entities/Bookmark.java b/src/main/java/eu/siacs/conversations/entities/Bookmark.java index ebb5de671..aa7a1eedb 100644 --- a/src/main/java/eu/siacs/conversations/entities/Bookmark.java +++ b/src/main/java/eu/siacs/conversations/entities/Bookmark.java @@ -181,4 +181,9 @@ public class Bookmark extends Element implements ListItem { } return StringUtils.changed(before, name); } + + @Override + public int getAvatarBackgroundColor() { + return UIHelper.getColorForName(jid != null ? jid.asBareJid().toString() : getDisplayName()); + } } diff --git a/src/main/java/eu/siacs/conversations/entities/Contact.java b/src/main/java/eu/siacs/conversations/entities/Contact.java index d090f4579..63bab5787 100644 --- a/src/main/java/eu/siacs/conversations/entities/Contact.java +++ b/src/main/java/eu/siacs/conversations/entities/Contact.java @@ -537,7 +537,12 @@ public class Contact implements ListItem, Blockable { } } - public final class Options { + @Override + public int getAvatarBackgroundColor() { + return UIHelper.getColorForName(jid != null ? jid.asBareJid().toString() : getDisplayName()); + } + + public final class Options { public static final int TO = 0; public static final int FROM = 1; public static final int ASKING = 2; diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index f629274b2..3b56b7752 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -2,6 +2,7 @@ package eu.siacs.conversations.entities; import android.content.ContentValues; import android.database.Cursor; +import android.graphics.Color; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.text.TextUtils; @@ -24,8 +25,10 @@ import eu.siacs.conversations.crypto.OmemoSetting; import eu.siacs.conversations.crypto.PgpDecryptionService; import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.persistance.DatabaseBackend; +import eu.siacs.conversations.services.AvatarService; import eu.siacs.conversations.services.QuickConversationsService; import eu.siacs.conversations.utils.JidHelper; +import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xmpp.InvalidJid; import eu.siacs.conversations.xmpp.chatstate.ChatState; import eu.siacs.conversations.xmpp.mam.MamReference; @@ -34,7 +37,7 @@ import rocks.xmpp.addr.Jid; import static eu.siacs.conversations.entities.Bookmark.printableValue; -public class Conversation extends AbstractEntity implements Blockable, Comparable, Conversational { +public class Conversation extends AbstractEntity implements Blockable, Comparable, Conversational, AvatarService.Avatarable { public static final String TABLENAME = "conversations"; public static final int STATUS_AVAILABLE = 0; @@ -991,6 +994,11 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl return 0; } + @Override + public int getAvatarBackgroundColor() { + return UIHelper.getColorForName(getName().toString()); + } + public interface OnMessageFound { void onMessageFound(final Message message); } diff --git a/src/main/java/eu/siacs/conversations/entities/ListItem.java b/src/main/java/eu/siacs/conversations/entities/ListItem.java index d259aa4ab..10d2c897c 100644 --- a/src/main/java/eu/siacs/conversations/entities/ListItem.java +++ b/src/main/java/eu/siacs/conversations/entities/ListItem.java @@ -4,10 +4,11 @@ import android.content.Context; import java.util.List; +import eu.siacs.conversations.services.AvatarService; import rocks.xmpp.addr.Jid; -public interface ListItem extends Comparable { +public interface ListItem extends Comparable, AvatarService.Avatarable { String getDisplayName(); Jid getJid(); diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 772cf5b85..83eecc155 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -2,6 +2,8 @@ package eu.siacs.conversations.entities; import android.content.ContentValues; import android.database.Cursor; +import android.graphics.Color; +import android.support.annotation.ColorInt; import android.text.SpannableStringBuilder; import android.util.Log; @@ -19,6 +21,7 @@ import java.util.Set; import eu.siacs.conversations.Config; import eu.siacs.conversations.crypto.axolotl.FingerprintStatus; +import eu.siacs.conversations.services.AvatarService; import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.Emoticons; import eu.siacs.conversations.utils.GeoHelper; @@ -27,7 +30,7 @@ import eu.siacs.conversations.utils.MimeUtils; import eu.siacs.conversations.utils.UIHelper; import rocks.xmpp.addr.Jid; -public class Message extends AbstractEntity { +public class Message extends AbstractEntity implements AvatarService.Avatarable { public static final String TABLENAME = "messages"; @@ -627,6 +630,15 @@ public class Message extends AbstractEntity { return this.counterparts; } + @Override + public int getAvatarBackgroundColor() { + if (type == Message.TYPE_STATUS && getCounterparts() != null && getCounterparts().size() > 1) { + return Color.TRANSPARENT; + } else { + return UIHelper.getColorForName(UIHelper.getMessageDisplayName(this)); + } + } + public static class MergeSeparator { } diff --git a/src/main/java/eu/siacs/conversations/services/AvatarService.java b/src/main/java/eu/siacs/conversations/services/AvatarService.java index 5dc6996c7..a13acd074 100644 --- a/src/main/java/eu/siacs/conversations/services/AvatarService.java +++ b/src/main/java/eu/siacs/conversations/services/AvatarService.java @@ -13,6 +13,7 @@ import android.graphics.Typeface; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; +import android.support.annotation.ColorInt; import android.support.annotation.DrawableRes; import android.support.annotation.Nullable; import android.support.v4.content.res.ResourcesCompat; @@ -41,6 +42,7 @@ import eu.siacs.conversations.entities.MucOptions; import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xmpp.OnAdvancedStreamFeaturesLoaded; import eu.siacs.conversations.xmpp.XmppConnection; +import eu.siacs.conversations.xmpp.pep.Avatar; import rocks.xmpp.addr.Jid; public class AvatarService implements OnAdvancedStreamFeaturesLoaded { @@ -69,6 +71,20 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded { return (int) (SYSTEM_UI_AVATAR_SIZE * context.getResources().getDisplayMetrics().density); } + public Bitmap get(final Avatarable avatarable, final int size, final boolean cachedOnly) { + if (avatarable instanceof Account) { + return get((Account) avatarable,size,cachedOnly); + } else if (avatarable instanceof Conversation) { + return get((Conversation) avatarable, size, cachedOnly); + } else if (avatarable instanceof Message) { + return get((Message) avatarable, size, cachedOnly); + } else if (avatarable instanceof ListItem) { + return get((ListItem) avatarable, size, cachedOnly); + } + throw new AssertionError("AvatarService does not know how to generate avatar from "+avatarable.getClass().getName()); + + } + private Bitmap get(final Contact contact, final int size, boolean cachedOnly) { if (contact.isSelf()) { return get(contact.getAccount(), size, cachedOnly); @@ -646,4 +662,8 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded { private static String emptyOnNull(@Nullable Jid value) { return value == null ? "" : value.toString(); } + + public interface Avatarable { + @ColorInt int getAvatarBackgroundColor(); + } } diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index dfa5f7471..91b008d31 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -55,6 +55,7 @@ import eu.siacs.conversations.ui.adapter.MediaAdapter; import eu.siacs.conversations.ui.interfaces.OnMediaLoaded; import eu.siacs.conversations.ui.service.EmojiService; import eu.siacs.conversations.ui.util.Attachment; +import eu.siacs.conversations.ui.util.AvatarWorkerTask; import eu.siacs.conversations.ui.util.GridManager; import eu.siacs.conversations.ui.util.MenuDoubleTabUtil; import eu.siacs.conversations.ui.util.MucDetailsContextMenuHelper; @@ -544,7 +545,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers this.binding.editMucNameButton.setVisibility((self.getAffiliation().ranks(MucOptions.Affiliation.OWNER) || mucOptions.canChangeSubject()) ? View.VISIBLE : View.GONE); this.binding.detailsAccount.setText(getString(R.string.using_account, account)); this.binding.jid.setText(mConversation.getJid().asBareJid().toEscapedString()); - this.binding.yourPhoto.setImageBitmap(avatarService().get(mConversation,(int) getResources().getDimension(R.dimen.avatar_on_details_screen_size))); + AvatarWorkerTask.loadAvatar(mConversation,binding.yourPhoto,R.dimen.avatar_on_details_screen_size); String roomName = mucOptions.getName(); String subject = mucOptions.getSubject(); final boolean hasTitle; diff --git a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java index d68cb306a..b105ff1bc 100644 --- a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java @@ -43,6 +43,7 @@ import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate; import eu.siacs.conversations.ui.adapter.MediaAdapter; import eu.siacs.conversations.ui.interfaces.OnMediaLoaded; import eu.siacs.conversations.ui.util.Attachment; +import eu.siacs.conversations.ui.util.AvatarWorkerTask; import eu.siacs.conversations.ui.util.GridManager; import eu.siacs.conversations.ui.util.JidDialog; import eu.siacs.conversations.ui.util.MenuDoubleTabUtil; @@ -402,7 +403,7 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp account = contact.getAccount().getJid().asBareJid().toString(); } binding.detailsAccount.setText(getString(R.string.using_account, account)); - binding.detailsContactBadge.setImageBitmap(avatarService().get(contact, (int) getResources().getDimension(R.dimen.avatar_on_details_screen_size))); + AvatarWorkerTask.loadAvatar(contact,binding.detailsContactBadge,R.dimen.avatar_on_details_screen_size); binding.detailsContactBadge.setOnClickListener(this.onBadgeClick); binding.detailsContactKeys.removeAllViews(); diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java index ec6c4fe71..84307c446 100644 --- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java @@ -58,6 +58,7 @@ import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; import eu.siacs.conversations.services.XmppConnectionService.OnCaptchaRequested; import eu.siacs.conversations.ui.adapter.KnownHostsAdapter; import eu.siacs.conversations.ui.adapter.PresenceTemplateAdapter; +import eu.siacs.conversations.ui.util.AvatarWorkerTask; import eu.siacs.conversations.ui.util.MenuDoubleTabUtil; import eu.siacs.conversations.ui.util.PendingItem; import eu.siacs.conversations.ui.util.SoftKeyboardUtils; @@ -604,7 +605,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat } private void refreshAvatar() { - binding.avater.setImageBitmap(avatarService().get(mAccount, (int) getResources().getDimension(R.dimen.avatar_on_details_screen_size))); + AvatarWorkerTask.loadAvatar(mAccount,binding.avater,R.dimen.avatar_on_details_screen_size); } @Override @@ -952,7 +953,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat if (!mInitMode) { this.binding.avater.setVisibility(View.VISIBLE); - this.binding.avater.setImageBitmap(avatarService().get(this.mAccount, (int) getResources().getDimension(R.dimen.avatar_on_details_screen_size))); + AvatarWorkerTask.loadAvatar(mAccount,binding.avater,R.dimen.avatar_on_details_screen_size); } else { this.binding.avater.setVisibility(View.GONE); } diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index ac1fc66ee..5006e7f44 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -36,6 +36,7 @@ import android.os.PowerManager; import android.os.SystemClock; import android.preference.PreferenceManager; import android.support.annotation.BoolRes; +import android.support.annotation.NonNull; import android.support.annotation.StringRes; import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; @@ -993,11 +994,12 @@ public abstract class XmppActivity extends ActionBarActivity { } } - public static XmppActivity find(WeakReference viewWeakReference) { + public static XmppActivity find(@NonNull WeakReference viewWeakReference) { final View view = viewWeakReference.get(); - if (view == null) { - return null; - } + return view == null ? null : find(view); + } + + public static XmppActivity find(@NonNull final View view) { final Context context = view.getContext(); if (context instanceof XmppActivity) { return (XmppActivity) context; diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java index 8f006845f..c2d84c162 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java @@ -22,6 +22,7 @@ import eu.siacs.conversations.R; import eu.siacs.conversations.databinding.AccountRowBinding; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.ui.XmppActivity; +import eu.siacs.conversations.ui.util.AvatarWorkerTask; import eu.siacs.conversations.ui.util.StyledAttributes; import eu.siacs.conversations.utils.UIHelper; @@ -59,7 +60,7 @@ public class AccountAdapter extends ArrayAdapter { } else { viewHolder.binding.accountJid.setText(account.getJid().asBareJid().toString()); } - loadAvatar(account, viewHolder.binding.accountImage); + AvatarWorkerTask.loadAvatar(account, viewHolder.binding.accountImage, R.dimen.avatar); viewHolder.binding.accountStatus.setText(getContext().getString(account.getStatus().getReadableId())); switch (account.getStatus()) { case ONLINE: @@ -97,97 +98,10 @@ public class AccountAdapter extends ArrayAdapter { } } - private static class BitmapWorkerTask extends AsyncTask { - private final WeakReference imageViewReference; - private Account account = null; - - BitmapWorkerTask(ImageView imageView) { - imageViewReference = new WeakReference<>(imageView); - } - - @Override - protected Bitmap doInBackground(Account... params) { - this.account = params[0]; - final XmppActivity activity = XmppActivity.find(imageViewReference); - if (activity == null) { - return null; - } - return activity.avatarService().get(this.account, activity.getPixel(48), isCancelled()); - } - - @Override - protected void onPostExecute(Bitmap bitmap) { - if (bitmap != null && !isCancelled()) { - final ImageView imageView = imageViewReference.get(); - if (imageView != null) { - imageView.setImageBitmap(bitmap); - imageView.setBackgroundColor(0x00000000); - } - } - } - } - - private void loadAvatar(Account account, ImageView imageView) { - if (cancelPotentialWork(account, imageView)) { - final Bitmap bm = activity.avatarService().get(account, activity.getPixel(48), true); - if (bm != null) { - cancelPotentialWork(account, imageView); - imageView.setImageBitmap(bm); - imageView.setBackgroundColor(0x00000000); - } else { - imageView.setBackgroundColor(UIHelper.getColorForName(account.getJid().asBareJid().toString())); - imageView.setImageDrawable(null); - final BitmapWorkerTask task = new BitmapWorkerTask(imageView); - final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task); - imageView.setImageDrawable(asyncDrawable); - try { - task.execute(account); - } catch (final RejectedExecutionException ignored) { - } - } - } - } public interface OnTglAccountState { void onClickTglAccountState(Account account, boolean state); } - private static boolean cancelPotentialWork(Account account, ImageView imageView) { - final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); - - if (bitmapWorkerTask != null) { - final Account oldAccount = bitmapWorkerTask.account; - if (oldAccount == null || account != oldAccount) { - bitmapWorkerTask.cancel(true); - } else { - return false; - } - } - return true; - } - - private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) { - if (imageView != null) { - final Drawable drawable = imageView.getDrawable(); - if (drawable instanceof AsyncDrawable) { - final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable; - return asyncDrawable.getBitmapWorkerTask(); - } - } - return null; - } - - static class AsyncDrawable extends BitmapDrawable { - private final WeakReference bitmapWorkerTaskReference; - - AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) { - super(res, bitmap); - bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask); - } - - BitmapWorkerTask getBitmapWorkerTask() { - return bitmapWorkerTaskReference.get(); - } - } } diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java index 5bf1288ea..ad5ddce89 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java @@ -1,36 +1,24 @@ package eu.siacs.conversations.ui.adapter; -import android.content.Context; -import android.content.res.Resources; import android.databinding.DataBindingUtil; -import android.graphics.Bitmap; import android.graphics.Typeface; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.os.AsyncTask; import android.support.annotation.NonNull; import android.support.v7.widget.RecyclerView; import android.util.Pair; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.TextView; -import java.lang.ref.WeakReference; import java.util.List; -import java.util.concurrent.RejectedExecutionException; import eu.siacs.conversations.R; import eu.siacs.conversations.databinding.ConversationListRowBinding; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.ui.ConversationFragment; import eu.siacs.conversations.ui.XmppActivity; +import eu.siacs.conversations.ui.util.AvatarWorkerTask; import eu.siacs.conversations.ui.util.StyledAttributes; -import eu.siacs.conversations.ui.widget.UnreadCountCustomView; import eu.siacs.conversations.utils.EmojiWrapper; import eu.siacs.conversations.utils.IrregularUnicodeDetector; import eu.siacs.conversations.utils.UIHelper; @@ -47,30 +35,6 @@ public class ConversationAdapter extends RecyclerView.Adapter listener.onConversationClick(v, conversation)); } @@ -232,26 +196,6 @@ public class ConversationAdapter extends RecyclerView.Adapter bitmapWorkerTaskReference; - - AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) { - super(res, bitmap); - bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask); - } - - BitmapWorkerTask getBitmapWorkerTask() { - return bitmapWorkerTaskReference.get(); - } - } - - static class BitmapWorkerTask extends AsyncTask { - private final WeakReference imageViewReference; - private Conversation conversation = null; - - BitmapWorkerTask(ImageView imageView) { - imageViewReference = new WeakReference<>(imageView); - } - - - @Override - protected Bitmap doInBackground(Conversation... params) { - this.conversation = params[0]; - final XmppActivity activity = XmppActivity.find(imageViewReference); - if (activity == null) { - return null; - } - return activity.avatarService().get(this.conversation, activity.getPixel(56), isCancelled()); - } - - @Override - protected void onPostExecute(Bitmap bitmap) { - if (bitmap != null && !isCancelled()) { - final ImageView imageView = imageViewReference.get(); - if (imageView != null) { - imageView.setImageBitmap(bitmap); - imageView.setBackgroundColor(0x00000000); - } - } - } - } } diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/ListItemAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/ListItemAdapter.java index 93f94b379..8507d8da1 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/ListItemAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/ListItemAdapter.java @@ -26,6 +26,7 @@ import eu.siacs.conversations.databinding.ContactBinding; import eu.siacs.conversations.entities.ListItem; import eu.siacs.conversations.ui.SettingsActivity; import eu.siacs.conversations.ui.XmppActivity; +import eu.siacs.conversations.ui.util.AvatarWorkerTask; import eu.siacs.conversations.utils.EmojiWrapper; import eu.siacs.conversations.utils.IrregularUnicodeDetector; import eu.siacs.conversations.utils.UIHelper; @@ -49,30 +50,6 @@ public class ListItemAdapter extends ArrayAdapter { this.activity = activity; } - private static boolean cancelPotentialWork(ListItem item, ImageView imageView) { - final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); - - if (bitmapWorkerTask != null) { - final ListItem oldItem = bitmapWorkerTask.item; - if (oldItem == null || item != oldItem) { - bitmapWorkerTask.cancel(true); - } else { - return false; - } - } - return true; - } - - private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) { - if (imageView != null) { - final Drawable drawable = imageView.getDrawable(); - if (drawable instanceof AsyncDrawable) { - final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable; - return asyncDrawable.getBitmapWorkerTask(); - } - } - return null; - } public void refreshSettings() { SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity); @@ -114,7 +91,7 @@ public class ListItemAdapter extends ArrayAdapter { viewHolder.jid.setVisibility(View.GONE); } viewHolder.name.setText(EmojiWrapper.transform(item.getDisplayName())); - loadAvatar(item, viewHolder.avatar); + AvatarWorkerTask.loadAvatar(item, viewHolder.avatar, R.dimen.avatar); return view; } @@ -122,27 +99,6 @@ public class ListItemAdapter extends ArrayAdapter { this.mOnTagClickedListener = listener; } - private void loadAvatar(ListItem item, ImageView imageView) { - if (cancelPotentialWork(item, imageView)) { - final Bitmap bm = activity.avatarService().get(item, activity.getPixel(48), true); - if (bm != null) { - cancelPotentialWork(item, imageView); - imageView.setImageBitmap(bm); - imageView.setBackgroundColor(0x00000000); - } else { - String seed = item.getJid() != null ? item.getJid().asBareJid().toString() : item.getDisplayName(); - imageView.setBackgroundColor(UIHelper.getColorForName(seed)); - imageView.setImageDrawable(null); - final BitmapWorkerTask task = new BitmapWorkerTask(imageView); - final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task); - imageView.setImageDrawable(asyncDrawable); - try { - task.execute(item); - } catch (final RejectedExecutionException ignored) { - } - } - } - } public interface OnTagClickedListener { void onTagClicked(String tag); @@ -169,47 +125,4 @@ public class ListItemAdapter extends ArrayAdapter { } } - static class AsyncDrawable extends BitmapDrawable { - private final WeakReference bitmapWorkerTaskReference; - - AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) { - super(res, bitmap); - bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask); - } - - BitmapWorkerTask getBitmapWorkerTask() { - return bitmapWorkerTaskReference.get(); - } - } - - private static class BitmapWorkerTask extends AsyncTask { - private final WeakReference imageViewReference; - private ListItem item = null; - - BitmapWorkerTask(ImageView imageView) { - imageViewReference = new WeakReference<>(imageView); - } - - @Override - protected Bitmap doInBackground(ListItem... params) { - this.item = params[0]; - final XmppActivity activity = XmppActivity.find(imageViewReference); - if (activity == null) { - return null; - } - return activity.avatarService().get(this.item, activity.getPixel(48), isCancelled()); - } - - @Override - protected void onPostExecute(Bitmap bitmap) { - if (bitmap != null && !isCancelled()) { - final ImageView imageView = imageViewReference.get(); - if (imageView != null) { - imageView.setImageBitmap(bitmap); - imageView.setBackgroundColor(0x00000000); - } - } - } - } - } diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 046f862f8..a3a80b257 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -2,21 +2,11 @@ package eu.siacs.conversations.ui.adapter; import android.Manifest; import android.app.Activity; -import android.content.ActivityNotFoundException; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.Color; import android.graphics.Typeface; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.AsyncTask; import android.preference.PreferenceManager; -import android.support.annotation.ColorInt; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.text.Spannable; @@ -28,7 +18,6 @@ import android.text.style.ForegroundColorSpan; import android.text.style.RelativeSizeSpan; import android.text.style.StyleSpan; import android.util.DisplayMetrics; -import android.util.Log; import android.view.ActionMode; import android.view.Menu; import android.view.MenuItem; @@ -43,10 +32,8 @@ import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; -import java.lang.ref.WeakReference; import java.net.URL; import java.util.List; -import java.util.concurrent.RejectedExecutionException; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -64,12 +51,13 @@ import eu.siacs.conversations.http.P1S3UrlStreamHandler; import eu.siacs.conversations.persistance.FileBackend; import eu.siacs.conversations.services.MessageArchiveService; import eu.siacs.conversations.services.NotificationService; -import eu.siacs.conversations.ui.ConversationsActivity; import eu.siacs.conversations.ui.ConversationFragment; +import eu.siacs.conversations.ui.ConversationsActivity; import eu.siacs.conversations.ui.XmppActivity; import eu.siacs.conversations.ui.service.AudioPlayer; import eu.siacs.conversations.ui.text.DividerSpan; import eu.siacs.conversations.ui.text.QuoteSpan; +import eu.siacs.conversations.ui.util.AvatarWorkerTask; import eu.siacs.conversations.ui.util.MyLinkify; import eu.siacs.conversations.ui.util.ViewUtil; import eu.siacs.conversations.ui.widget.ClickableMovementMethod; @@ -109,30 +97,6 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie } - public static boolean cancelPotentialWork(Message message, ImageView imageView) { - final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); - - if (bitmapWorkerTask != null) { - final Message oldMessage = bitmapWorkerTask.message; - if (oldMessage == null || message != oldMessage) { - bitmapWorkerTask.cancel(true); - } else { - return false; - } - } - return true; - } - - private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) { - if (imageView != null) { - final Drawable drawable = imageView.getDrawable(); - if (drawable instanceof AsyncDrawable) { - final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable; - return asyncDrawable.getBitmapWorkerTask(); - } - } - return null; - } private static void resetClickListener(View... views) { for (View view : views) { @@ -704,10 +668,10 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie boolean showAvatar; if (conversation.getMode() == Conversation.MODE_SINGLE) { showAvatar = true; - loadAvatar(message, viewHolder.contact_picture, activity.getPixel(32)); + AvatarWorkerTask.loadAvatar(message, viewHolder.contact_picture, R.dimen.avatar_on_status_message); } else if (message.getCounterpart() != null || message.getTrueCounterpart() != null || (message.getCounterparts() != null && message.getCounterparts().size() > 0)) { showAvatar = true; - loadAvatar(message, viewHolder.contact_picture, activity.getPixel(32)); + AvatarWorkerTask.loadAvatar(message, viewHolder.contact_picture, R.dimen.avatar_on_status_message); } else { showAvatar = false; } @@ -720,7 +684,7 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie } return view; } else { - loadAvatar(message, viewHolder.contact_picture, activity.getPixel(48)); + AvatarWorkerTask.loadAvatar(message, viewHolder.contact_picture, R.dimen.avatar); } resetClickListener(viewHolder.message_box, viewHolder.messageBody); @@ -918,32 +882,6 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie this.mUseGreenBackground = p.getBoolean("use_green_background", activity.getResources().getBoolean(R.bool.use_green_background)); } - private void loadAvatar(Message message, ImageView imageView, int size) { - if (cancelPotentialWork(message, imageView)) { - final Bitmap bm = activity.avatarService().get(message, size, true); - if (bm != null) { - cancelPotentialWork(message, imageView); - imageView.setImageBitmap(bm); - imageView.setBackgroundColor(Color.TRANSPARENT); - } else { - @ColorInt int bg; - if (message.getType() == Message.TYPE_STATUS && message.getCounterparts() != null && message.getCounterparts().size() > 1) { - bg = Color.TRANSPARENT; - } else { - bg = UIHelper.getColorForName(UIHelper.getMessageDisplayName(message)); - } - imageView.setBackgroundColor(bg); - imageView.setImageDrawable(null); - final BitmapWorkerTask task = new BitmapWorkerTask(imageView, size); - final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task); - imageView.setImageDrawable(asyncDrawable); - try { - task.execute(message); - } catch (final RejectedExecutionException ignored) { - } - } - } - } public void setHighlightedTerm(List terms) { this.highlightedTerm = terms == null ? null : StylingHelper.filterHighlightedWords(terms); @@ -978,18 +916,6 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie protected TextView encryption; } - static class AsyncDrawable extends BitmapDrawable { - private final WeakReference bitmapWorkerTaskReference; - - public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) { - super(res, bitmap); - bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask); - } - - public BitmapWorkerTask getBitmapWorkerTask() { - return bitmapWorkerTaskReference.get(); - } - } private class MessageBodyActionModeCallback implements ActionMode.Callback { @@ -1036,36 +962,4 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie public void onDestroyActionMode(ActionMode mode) { } } - - private static class BitmapWorkerTask extends AsyncTask { - private final WeakReference imageViewReference; - private final int size; - private Message message = null; - - BitmapWorkerTask(ImageView imageView, int size) { - imageViewReference = new WeakReference<>(imageView); - this.size = size; - } - - @Override - protected Bitmap doInBackground(Message... params) { - this.message = params[0]; - final XmppActivity activity = XmppActivity.find(imageViewReference); - if (activity == null) { - return null; - } - return activity.avatarService().get(this.message, size, isCancelled()); - } - - @Override - protected void onPostExecute(Bitmap bitmap) { - if (bitmap != null && !isCancelled()) { - final ImageView imageView = imageViewReference.get(); - if (imageView != null) { - imageView.setImageBitmap(bitmap); - imageView.setBackgroundColor(0x00000000); - } - } - } - } } diff --git a/src/main/java/eu/siacs/conversations/ui/util/AvatarWorkerTask.java b/src/main/java/eu/siacs/conversations/ui/util/AvatarWorkerTask.java new file mode 100644 index 000000000..4e23f14f1 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/ui/util/AvatarWorkerTask.java @@ -0,0 +1,113 @@ +package eu.siacs.conversations.ui.util; + +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.AsyncTask; +import android.support.annotation.DimenRes; +import android.widget.ImageView; + +import java.lang.ref.WeakReference; +import java.util.concurrent.RejectedExecutionException; + +import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.services.AvatarService; +import eu.siacs.conversations.ui.XmppActivity; +import eu.siacs.conversations.ui.adapter.AccountAdapter; +import eu.siacs.conversations.utils.UIHelper; + +public class AvatarWorkerTask extends AsyncTask { + private final WeakReference imageViewReference; + private AvatarService.Avatarable avatarable = null; + private @DimenRes int size; + + public AvatarWorkerTask(ImageView imageView, @DimenRes int size) { + imageViewReference = new WeakReference<>(imageView); + this.size = size; + } + + @Override + protected Bitmap doInBackground(AvatarService.Avatarable... params) { + this.avatarable = params[0]; + final XmppActivity activity = XmppActivity.find(imageViewReference); + if (activity == null) { + return null; + } + return activity.avatarService().get(avatarable, (int) activity.getResources().getDimension(size), isCancelled()); + } + + @Override + protected void onPostExecute(Bitmap bitmap) { + if (bitmap != null && !isCancelled()) { + final ImageView imageView = imageViewReference.get(); + if (imageView != null) { + imageView.setImageBitmap(bitmap); + imageView.setBackgroundColor(0x00000000); + } + } + } + + public static boolean cancelPotentialWork(AvatarService.Avatarable avatarable, ImageView imageView) { + final AvatarWorkerTask workerTask = getBitmapWorkerTask(imageView); + + if (workerTask != null) { + final AvatarService.Avatarable old= workerTask.avatarable; + if (old == null || avatarable != old) { + workerTask.cancel(true); + } else { + return false; + } + } + return true; + } + + public static AvatarWorkerTask getBitmapWorkerTask(ImageView imageView) { + if (imageView != null) { + final Drawable drawable = imageView.getDrawable(); + if (drawable instanceof AsyncDrawable) { + final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable; + return asyncDrawable.getAvatarWorkerTask(); + } + } + return null; + } + + public static void loadAvatar(final AvatarService.Avatarable avatarable, final ImageView imageView, final @DimenRes int size) { + if (cancelPotentialWork(avatarable, imageView)) { + final XmppActivity activity = XmppActivity.find(imageView); + if (activity == null) { + return; + } + final Bitmap bm = activity.avatarService().get(avatarable, (int) activity.getResources().getDimension(size), true); + if (bm != null) { + cancelPotentialWork(avatarable, imageView); + imageView.setImageBitmap(bm); + imageView.setBackgroundColor(0x00000000); + } else { + imageView.setBackgroundColor(avatarable.getAvatarBackgroundColor()); + imageView.setImageDrawable(null); + final AvatarWorkerTask task = new AvatarWorkerTask(imageView, size); + final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task); + imageView.setImageDrawable(asyncDrawable); + try { + task.execute(avatarable); + } catch (final RejectedExecutionException ignored) { + } + } + } + } + + static class AsyncDrawable extends BitmapDrawable { + private final WeakReference avatarWorkerTaskReference; + + AsyncDrawable(Resources res, Bitmap bitmap, AvatarWorkerTask workerTask) { + super(res, bitmap); + avatarWorkerTaskReference = new WeakReference<>(workerTask); + } + + AvatarWorkerTask getAvatarWorkerTask() { + return avatarWorkerTaskReference.get(); + } + } +} diff --git a/src/main/res/values/dimens.xml b/src/main/res/values/dimens.xml index 5e38ad20a..751588fd8 100644 --- a/src/main/res/values/dimens.xml +++ b/src/main/res/values/dimens.xml @@ -18,7 +18,10 @@ 8dp 96dp + 32dp + 48dp 56dp + 56dp 4dp 4dp