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;
 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}