1package eu.siacs.conversations.ui.adapter;
2
3import android.content.Context;
4import android.content.res.Resources;
5import android.graphics.Bitmap;
6import android.graphics.drawable.BitmapDrawable;
7import android.graphics.drawable.Drawable;
8import android.os.AsyncTask;
9import android.view.LayoutInflater;
10import android.view.View;
11import android.view.ViewGroup;
12import android.widget.ArrayAdapter;
13import android.widget.CompoundButton;
14import android.widget.ImageView;
15import android.widget.TextView;
16
17import java.lang.ref.WeakReference;
18import java.util.List;
19import java.util.concurrent.RejectedExecutionException;
20
21import eu.siacs.conversations.Config;
22import eu.siacs.conversations.R;
23import eu.siacs.conversations.entities.Account;
24import eu.siacs.conversations.ui.ManageAccountActivity;
25import eu.siacs.conversations.ui.XmppActivity;
26import eu.siacs.conversations.ui.widget.Switch;
27import eu.siacs.conversations.utils.UIHelper;
28
29public class AccountAdapter extends ArrayAdapter<Account> {
30
31 private XmppActivity activity;
32
33 public AccountAdapter(XmppActivity activity, List<Account> objects) {
34 super(activity, 0, objects);
35 this.activity = activity;
36 }
37
38 @Override
39 public View getView(int position, View view, ViewGroup parent) {
40 final Account account = getItem(position);
41 if (view == null) {
42 LayoutInflater inflater = (LayoutInflater) getContext()
43 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
44 view = inflater.inflate(R.layout.account_row, parent, false);
45 }
46 TextView jid = (TextView) view.findViewById(R.id.account_jid);
47 if (Config.DOMAIN_LOCK != null) {
48 jid.setText(account.getJid().getLocalpart());
49 } else {
50 jid.setText(account.getJid().toBareJid().toString());
51 }
52 TextView statusView = (TextView) view.findViewById(R.id.account_status);
53 ImageView imageView = (ImageView) view.findViewById(R.id.account_image);
54 loadAvatar(account,imageView);
55 statusView.setText(getContext().getString(account.getStatus().getReadableId()));
56 switch (account.getStatus()) {
57 case ONLINE:
58 statusView.setTextColor(activity.getOnlineColor());
59 break;
60 case DISABLED:
61 case CONNECTING:
62 statusView.setTextColor(activity.getSecondaryTextColor());
63 break;
64 default:
65 statusView.setTextColor(activity.getWarningTextColor());
66 break;
67 }
68 final Switch tglAccountState = (Switch) view.findViewById(R.id.tgl_account_status);
69 final boolean isDisabled = (account.getStatus() == Account.State.DISABLED);
70 tglAccountState.setChecked(!isDisabled,false);
71 tglAccountState.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
72 @Override
73 public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
74 if (b == isDisabled && activity instanceof ManageAccountActivity) {
75 ((ManageAccountActivity) activity).onClickTglAccountState(account,b);
76 }
77 }
78 });
79 return view;
80 }
81
82 class BitmapWorkerTask extends AsyncTask<Account, Void, Bitmap> {
83 private final WeakReference<ImageView> imageViewReference;
84 private Account account = null;
85
86 public BitmapWorkerTask(ImageView imageView) {
87 imageViewReference = new WeakReference<>(imageView);
88 }
89
90 @Override
91 protected Bitmap doInBackground(Account... params) {
92 return activity.avatarService().get(params[0], activity.getPixel(48), isCancelled());
93 }
94
95 @Override
96 protected void onPostExecute(Bitmap bitmap) {
97 if (bitmap != null && !isCancelled()) {
98 final ImageView imageView = imageViewReference.get();
99 if (imageView != null) {
100 imageView.setImageBitmap(bitmap);
101 imageView.setBackgroundColor(0x00000000);
102 }
103 }
104 }
105 }
106
107 public void loadAvatar(Account account, ImageView imageView) {
108 if (cancelPotentialWork(account, imageView)) {
109 final Bitmap bm = activity.avatarService().get(account,activity.getPixel(48),true);
110 if (bm != null) {
111 cancelPotentialWork(account, imageView);
112 imageView.setImageBitmap(bm);
113 imageView.setBackgroundColor(0x00000000);
114 } else {
115 imageView.setBackgroundColor(UIHelper.getColorForName(account.getJid().toBareJid().toString()));
116 imageView.setImageDrawable(null);
117 final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
118 final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task);
119 imageView.setImageDrawable(asyncDrawable);
120 try {
121 task.execute(account);
122 } catch (final RejectedExecutionException ignored) {
123 }
124 }
125 }
126 }
127
128 public static boolean cancelPotentialWork(Account account, ImageView imageView) {
129 final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
130
131 if (bitmapWorkerTask != null) {
132 final Account oldAccount = bitmapWorkerTask.account;
133 if (oldAccount == null || account != oldAccount) {
134 bitmapWorkerTask.cancel(true);
135 } else {
136 return false;
137 }
138 }
139 return true;
140 }
141
142 private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
143 if (imageView != null) {
144 final Drawable drawable = imageView.getDrawable();
145 if (drawable instanceof AsyncDrawable) {
146 final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
147 return asyncDrawable.getBitmapWorkerTask();
148 }
149 }
150 return null;
151 }
152
153 static class AsyncDrawable extends BitmapDrawable {
154 private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
155
156 public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) {
157 super(res, bitmap);
158 bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask);
159 }
160
161 public BitmapWorkerTask getBitmapWorkerTask() {
162 return bitmapWorkerTaskReference.get();
163 }
164 }
165}