ListItemAdapter.java

  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.colorCodeAccounts()) {
 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.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.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.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}