1package eu.siacs.conversations.ui.adapter;
2
3import android.content.Context;
4import android.content.res.Resources;
5import android.graphics.Bitmap;
6import android.graphics.Color;
7import android.graphics.Typeface;
8import android.graphics.drawable.BitmapDrawable;
9import android.graphics.drawable.Drawable;
10import android.os.AsyncTask;
11import android.util.Pair;
12import android.view.LayoutInflater;
13import android.view.View;
14import android.view.ViewGroup;
15import android.widget.ArrayAdapter;
16import android.widget.ImageView;
17import android.widget.TextView;
18
19import java.lang.ref.WeakReference;
20import java.util.List;
21import java.util.concurrent.RejectedExecutionException;
22
23import eu.siacs.conversations.R;
24import eu.siacs.conversations.entities.Conversation;
25import eu.siacs.conversations.entities.Downloadable;
26import eu.siacs.conversations.entities.Message;
27import eu.siacs.conversations.ui.ConversationActivity;
28import eu.siacs.conversations.ui.XmppActivity;
29import eu.siacs.conversations.utils.UIHelper;
30
31public class ConversationAdapter extends ArrayAdapter<Conversation> {
32
33 private XmppActivity activity;
34
35 public ConversationAdapter(XmppActivity activity,
36 List<Conversation> conversations) {
37 super(activity, 0, conversations);
38 this.activity = activity;
39 }
40
41 @Override
42 public View getView(int position, View view, ViewGroup parent) {
43 if (view == null) {
44 LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
45 view = inflater.inflate(R.layout.conversation_list_row,parent, false);
46 }
47 Conversation conversation = getItem(position);
48 if (this.activity instanceof ConversationActivity) {
49 ConversationActivity activity = (ConversationActivity) this.activity;
50 if (!activity.isConversationsOverviewHideable()) {
51 if (conversation == activity.getSelectedConversation()) {
52 view.setBackgroundColor(activity
53 .getSecondaryBackgroundColor());
54 } else {
55 view.setBackgroundColor(Color.TRANSPARENT);
56 }
57 } else {
58 view.setBackgroundColor(Color.TRANSPARENT);
59 }
60 }
61 TextView convName = (TextView) view.findViewById(R.id.conversation_name);
62 if (conversation.getMode() == Conversation.MODE_SINGLE || activity.useSubjectToIdentifyConference()) {
63 convName.setText(conversation.getName());
64 } else {
65 convName.setText(conversation.getJid().toBareJid().toString());
66 }
67 TextView mLastMessage = (TextView) view.findViewById(R.id.conversation_lastmsg);
68 TextView mTimestamp = (TextView) view.findViewById(R.id.conversation_lastupdate);
69 ImageView imagePreview = (ImageView) view.findViewById(R.id.conversation_lastimage);
70
71 Message message = conversation.getLatestMessage();
72
73 if (!conversation.isRead()) {
74 convName.setTypeface(null, Typeface.BOLD);
75 } else {
76 convName.setTypeface(null, Typeface.NORMAL);
77 }
78
79 if (message.getImageParams().width > 0
80 && (message.getDownloadable() == null
81 || message.getDownloadable().getStatus() != Downloadable.STATUS_DELETED)) {
82 mLastMessage.setVisibility(View.GONE);
83 imagePreview.setVisibility(View.VISIBLE);
84 activity.loadBitmap(message, imagePreview);
85 } else {
86 Pair<String,Boolean> preview = UIHelper.getMessagePreview(activity,message);
87 mLastMessage.setVisibility(View.VISIBLE);
88 imagePreview.setVisibility(View.GONE);
89 mLastMessage.setText(preview.first);
90 if (preview.second) {
91 if (conversation.isRead()) {
92 mLastMessage.setTypeface(null, Typeface.ITALIC);
93 } else {
94 mLastMessage.setTypeface(null,Typeface.BOLD_ITALIC);
95 }
96 } else {
97 if (conversation.isRead()) {
98 mLastMessage.setTypeface(null,Typeface.NORMAL);
99 } else {
100 mLastMessage.setTypeface(null,Typeface.BOLD);
101 }
102 }
103 }
104
105 mTimestamp.setText(UIHelper.readableTimeDifference(activity,conversation.getLatestMessage().getTimeSent()));
106 ImageView profilePicture = (ImageView) view.findViewById(R.id.conversation_image);
107 loadAvatar(conversation,profilePicture);
108
109 return view;
110 }
111
112 class BitmapWorkerTask extends AsyncTask<Conversation, Void, Bitmap> {
113 private final WeakReference<ImageView> imageViewReference;
114 private Conversation conversation = null;
115
116 public BitmapWorkerTask(ImageView imageView) {
117 imageViewReference = new WeakReference<>(imageView);
118 }
119
120 @Override
121 protected Bitmap doInBackground(Conversation... params) {
122 return activity.avatarService().get(params[0], activity.getPixel(56));
123 }
124
125 @Override
126 protected void onPostExecute(Bitmap bitmap) {
127 if (bitmap != null) {
128 final ImageView imageView = imageViewReference.get();
129 if (imageView != null) {
130 imageView.setImageBitmap(bitmap);
131 imageView.setBackgroundColor(0x00000000);
132 }
133 }
134 }
135 }
136
137 public void loadAvatar(Conversation conversation, ImageView imageView) {
138 if (cancelPotentialWork(conversation, imageView)) {
139 final Bitmap bm = activity.avatarService().get(conversation, activity.getPixel(56), true);
140 if (bm != null) {
141 imageView.setImageBitmap(bm);
142 imageView.setBackgroundColor(0x00000000);
143 } else {
144 imageView.setBackgroundColor(UIHelper.getColorForName(conversation.getName()));
145 imageView.setImageDrawable(null);
146 final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
147 final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task);
148 imageView.setImageDrawable(asyncDrawable);
149 try {
150 task.execute(conversation);
151 } catch (final RejectedExecutionException ignored) {
152 }
153 }
154 }
155 }
156
157 public static boolean cancelPotentialWork(Conversation conversation, ImageView imageView) {
158 final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
159
160 if (bitmapWorkerTask != null) {
161 final Conversation oldConversation = bitmapWorkerTask.conversation;
162 if (oldConversation == null || conversation != oldConversation) {
163 bitmapWorkerTask.cancel(true);
164 } else {
165 return false;
166 }
167 }
168 return true;
169 }
170
171 private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
172 if (imageView != null) {
173 final Drawable drawable = imageView.getDrawable();
174 if (drawable instanceof AsyncDrawable) {
175 final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
176 return asyncDrawable.getBitmapWorkerTask();
177 }
178 }
179 return null;
180 }
181
182 static class AsyncDrawable extends BitmapDrawable {
183 private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
184
185 public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) {
186 super(res, bitmap);
187 bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask);
188 }
189
190 public BitmapWorkerTask getBitmapWorkerTask() {
191 return bitmapWorkerTaskReference.get();
192 }
193 }
194}