1package eu.siacs.conversations.ui.adapter;
2
3import java.lang.ref.WeakReference;
4import java.util.List;
5import java.util.concurrent.RejectedExecutionException;
6
7import eu.siacs.conversations.Config;
8import eu.siacs.conversations.R;
9import eu.siacs.conversations.entities.Conversation;
10import eu.siacs.conversations.entities.ListItem;
11import eu.siacs.conversations.ui.XmppActivity;
12import eu.siacs.conversations.utils.UIHelper;
13import eu.siacs.conversations.xmpp.jid.Jid;
14
15import android.content.Context;
16import android.content.SharedPreferences;
17import android.content.res.Resources;
18import android.graphics.Bitmap;
19import android.graphics.drawable.BitmapDrawable;
20import android.graphics.drawable.Drawable;
21import android.os.AsyncTask;
22import android.preference.PreferenceManager;
23import android.util.Log;
24import android.view.LayoutInflater;
25import android.view.View;
26import android.view.ViewGroup;
27import android.widget.ArrayAdapter;
28import android.widget.ImageView;
29import android.widget.LinearLayout;
30import android.widget.TextView;
31
32public class ListItemAdapter extends ArrayAdapter<ListItem> {
33
34 protected XmppActivity activity;
35 protected boolean showDynamicTags = false;
36 private View.OnClickListener onTagTvClick = new View.OnClickListener() {
37 @Override
38 public void onClick(View view) {
39 if (view instanceof TextView && mOnTagClickedListener != null) {
40 TextView tv = (TextView) view;
41 final String tag = tv.getText().toString();
42 mOnTagClickedListener.onTagClicked(tag);
43 }
44 }
45 };
46 private OnTagClickedListener mOnTagClickedListener = null;
47
48 public ListItemAdapter(XmppActivity activity, List<ListItem> objects) {
49 super(activity, 0, objects);
50 this.activity = activity;
51 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
52 this.showDynamicTags = preferences.getBoolean("show_dynamic_tags",false);
53 }
54
55 @Override
56 public View getView(int position, View view, ViewGroup parent) {
57 LayoutInflater inflater = (LayoutInflater) getContext()
58 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
59 ListItem item = getItem(position);
60 if (view == null) {
61 view = inflater.inflate(R.layout.contact, parent, false);
62 }
63 TextView tvName = (TextView) view.findViewById(R.id.contact_display_name);
64 TextView tvJid = (TextView) view.findViewById(R.id.contact_jid);
65 ImageView picture = (ImageView) view.findViewById(R.id.contact_photo);
66 LinearLayout tagLayout = (LinearLayout) view.findViewById(R.id.tags);
67
68 List<ListItem.Tag> tags = item.getTags();
69 if (tags.size() == 0 || !this.showDynamicTags) {
70 tagLayout.setVisibility(View.GONE);
71 } else {
72 tagLayout.setVisibility(View.VISIBLE);
73 tagLayout.removeAllViewsInLayout();
74 for(ListItem.Tag tag : tags) {
75 TextView tv = (TextView) inflater.inflate(R.layout.list_item_tag,tagLayout,false);
76 tv.setText(tag.getName());
77 tv.setBackgroundColor(tag.getColor());
78 tv.setOnClickListener(this.onTagTvClick);
79 tagLayout.addView(tv);
80 }
81 }
82 final Jid jid = item.getJid();
83 if (jid != null) {
84 tvJid.setText(jid.toString());
85 } else {
86 tvJid.setText("");
87 }
88 tvName.setText(item.getDisplayName());
89 loadAvatar(item,picture);
90 return view;
91 }
92
93 public void setOnTagClickedListener(OnTagClickedListener listener) {
94 this.mOnTagClickedListener = listener;
95 }
96
97 public interface OnTagClickedListener {
98 public void onTagClicked(String tag);
99 }
100
101 class BitmapWorkerTask extends AsyncTask<ListItem, Void, Bitmap> {
102 private final WeakReference<ImageView> imageViewReference;
103 private ListItem item = null;
104
105 public BitmapWorkerTask(ImageView imageView) {
106 imageViewReference = new WeakReference<>(imageView);
107 }
108
109 @Override
110 protected Bitmap doInBackground(ListItem... params) {
111 return activity.avatarService().get(params[0], activity.getPixel(48));
112 }
113
114 @Override
115 protected void onPostExecute(Bitmap bitmap) {
116 if (bitmap != null) {
117 final ImageView imageView = imageViewReference.get();
118 if (imageView != null) {
119 imageView.setImageBitmap(bitmap);
120 imageView.setBackgroundColor(0x00000000);
121 }
122 }
123 }
124 }
125
126 public void loadAvatar(ListItem item, ImageView imageView) {
127 Bitmap bm = activity.avatarService().get(item,activity.getPixel(56),true);
128 if (bm != null) {
129 imageView.setImageBitmap(bm);
130 imageView.setBackgroundColor(0x00000000);
131 } else if (cancelPotentialWork(item, imageView)) {
132 imageView.setBackgroundColor(UIHelper.getColorForName(item.getDisplayName()));
133 final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
134 final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task);
135 imageView.setImageDrawable(asyncDrawable);
136 try {
137 task.execute(item);
138 } catch (final RejectedExecutionException ignored) {
139 }
140 }
141 }
142
143 public static boolean cancelPotentialWork(ListItem item, ImageView imageView) {
144 final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
145
146 if (bitmapWorkerTask != null) {
147 final ListItem oldItem = bitmapWorkerTask.item;
148 if (oldItem == null || item != oldItem) {
149 bitmapWorkerTask.cancel(true);
150 } else {
151 return false;
152 }
153 }
154 return true;
155 }
156
157 private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
158 if (imageView != null) {
159 final Drawable drawable = imageView.getDrawable();
160 if (drawable instanceof AsyncDrawable) {
161 final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
162 return asyncDrawable.getBitmapWorkerTask();
163 }
164 }
165 return null;
166 }
167
168 static class AsyncDrawable extends BitmapDrawable {
169 private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
170
171 public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) {
172 super(res, bitmap);
173 bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask);
174 }
175
176 public BitmapWorkerTask getBitmapWorkerTask() {
177 return bitmapWorkerTaskReference.get();
178 }
179 }
180
181}