1package eu.siacs.conversations.ui.adapter;
2
3import android.content.SharedPreferences;
4import android.content.res.ColorStateList;
5import android.preference.PreferenceManager;
6import android.util.Log;
7import android.view.LayoutInflater;
8import android.view.View;
9import android.view.ViewGroup;
10import android.widget.ArrayAdapter;
11import android.widget.ImageView;
12import android.widget.TextView;
13import androidx.annotation.NonNull;
14import androidx.constraintlayout.helper.widget.Flow;
15import androidx.constraintlayout.widget.ConstraintLayout;
16import androidx.core.content.ContextCompat;
17import androidx.core.view.ViewCompat;
18import androidx.databinding.DataBindingUtil;
19import com.google.android.material.color.MaterialColors;
20import com.google.common.collect.ImmutableList;
21import com.google.common.primitives.Ints;
22import eu.siacs.conversations.AppSettings;
23import eu.siacs.conversations.Config;
24import eu.siacs.conversations.R;
25import eu.siacs.conversations.databinding.ItemContactBinding;
26import eu.siacs.conversations.entities.Contact;
27import eu.siacs.conversations.entities.ListItem;
28import eu.siacs.conversations.ui.XmppActivity;
29import eu.siacs.conversations.ui.util.AvatarWorkerTask;
30import eu.siacs.conversations.utils.IrregularUnicodeDetector;
31import eu.siacs.conversations.utils.UIHelper;
32import eu.siacs.conversations.utils.XEP0392Helper;
33import eu.siacs.conversations.xmpp.Jid;
34import im.conversations.android.xmpp.model.stanza.Presence;
35import java.util.List;
36
37public class ListItemAdapter extends ArrayAdapter<ListItem> {
38
39 protected XmppActivity activity;
40 private boolean showDynamicTags = false;
41 private OnTagClickedListener mOnTagClickedListener = null;
42 private final View.OnClickListener onTagTvClick =
43 view -> {
44 if (view instanceof TextView tv && mOnTagClickedListener != null) {
45 final String tag = tv.getText().toString();
46 mOnTagClickedListener.onTagClicked(tag);
47 }
48 };
49
50 public ListItemAdapter(XmppActivity activity, List<ListItem> objects) {
51 super(activity, 0, objects);
52 this.activity = activity;
53 }
54
55 public void refreshSettings() {
56 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
57 this.showDynamicTags = preferences.getBoolean(AppSettings.SHOW_DYNAMIC_TAGS, false);
58 }
59
60 @NonNull
61 @Override
62 public View getView(int position, View view, @NonNull ViewGroup parent) {
63 LayoutInflater inflater = activity.getLayoutInflater();
64 final ListItem item = getItem(position);
65 ViewHolder viewHolder;
66 if (view == null) {
67 final ItemContactBinding binding =
68 DataBindingUtil.inflate(inflater, R.layout.item_contact, parent, false);
69 viewHolder = ViewHolder.get(binding);
70 view = binding.getRoot();
71 } else {
72 viewHolder = (ViewHolder) view.getTag();
73 }
74 if (view.isActivated()) {
75 Log.d(Config.LOGTAG, "item " + item.getDisplayName() + " is activated");
76 }
77 // view.setBackground(StyledAttributes.getDrawable(view.getContext(),R.attr.list_item_background));
78 final List<ListItem.Tag> tags = item.getTags(activity);
79 final boolean hasMetaTags;
80 if (item instanceof Contact contact) {
81 hasMetaTags =
82 contact.isBlocked()
83 || contact.getShownStatus() != Presence.Availability.OFFLINE;
84 } else {
85 hasMetaTags = false;
86 }
87 if ((tags.isEmpty() && !hasMetaTags) || !this.showDynamicTags) {
88 viewHolder.tags.setVisibility(View.GONE);
89 } else {
90 viewHolder.tags.setVisibility(View.VISIBLE);
91 viewHolder.tags.removeViews(1, viewHolder.tags.getChildCount() - 1);
92 final ImmutableList.Builder<Integer> viewIdBuilder = new ImmutableList.Builder<>();
93 for (final ListItem.Tag tag : tags) {
94 final String name = tag.getName();
95 final TextView tv =
96 (TextView) inflater.inflate(R.layout.item_tag, viewHolder.tags, false);
97 tv.setText(name);
98 tv.setBackgroundTintList(
99 ColorStateList.valueOf(
100 MaterialColors.harmonizeWithPrimary(
101 getContext(), XEP0392Helper.rgbFromNick(name))));
102 tv.setOnClickListener(this.onTagTvClick);
103 final int id = ViewCompat.generateViewId();
104 tv.setId(id);
105 viewIdBuilder.add(id);
106 viewHolder.tags.addView(tv);
107 }
108 if (item instanceof Contact contact) {
109 if (contact.isBlocked()) {
110 final TextView tv =
111 (TextView) inflater.inflate(R.layout.item_tag, viewHolder.tags, false);
112 tv.setText(R.string.blocked);
113 tv.setBackgroundTintList(
114 ColorStateList.valueOf(
115 MaterialColors.harmonizeWithPrimary(
116 tv.getContext(),
117 ContextCompat.getColor(
118 tv.getContext(), R.color.gray_800))));
119 final int id = ViewCompat.generateViewId();
120 tv.setId(id);
121 viewIdBuilder.add(id);
122 viewHolder.tags.addView(tv);
123 } else {
124 final Presence.Availability status = contact.getShownStatus();
125 if (status != Presence.Availability.OFFLINE) {
126 final TextView tv =
127 (TextView)
128 inflater.inflate(R.layout.item_tag, viewHolder.tags, false);
129 UIHelper.setStatus(tv, status);
130 final int id = ViewCompat.generateViewId();
131 tv.setId(id);
132 viewIdBuilder.add(id);
133 viewHolder.tags.addView(tv);
134 }
135 }
136 }
137 viewHolder.flowWidget.setReferencedIds(Ints.toArray(viewIdBuilder.build()));
138 }
139 final Jid jid = item.getJid();
140 if (jid != null) {
141 viewHolder.jid.setVisibility(View.VISIBLE);
142 viewHolder.jid.setText(IrregularUnicodeDetector.style(activity, jid));
143 } else {
144 viewHolder.jid.setVisibility(View.GONE);
145 }
146 viewHolder.name.setText(item.getDisplayName());
147 AvatarWorkerTask.loadAvatar(item, viewHolder.avatar, R.dimen.avatar);
148 return view;
149 }
150
151 public void setOnTagClickedListener(OnTagClickedListener listener) {
152 this.mOnTagClickedListener = listener;
153 }
154
155 public interface OnTagClickedListener {
156 void onTagClicked(String tag);
157 }
158
159 private static class ViewHolder {
160 private TextView name;
161 private TextView jid;
162 private ImageView avatar;
163 private ConstraintLayout tags;
164 private Flow flowWidget;
165
166 private ViewHolder() {}
167
168 public static ViewHolder get(final ItemContactBinding binding) {
169 ViewHolder viewHolder = new ViewHolder();
170 viewHolder.name = binding.contactDisplayName;
171 viewHolder.jid = binding.contactJid;
172 viewHolder.avatar = binding.contactPhoto;
173 viewHolder.tags = binding.tags;
174 viewHolder.flowWidget = binding.flowWidget;
175 binding.getRoot().setTag(viewHolder);
176 return viewHolder;
177 }
178 }
179}