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