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