UserAdapter.java

  1package eu.siacs.conversations.ui.adapter;
  2
  3import android.app.PendingIntent;
  4import android.content.Context;
  5import android.content.IntentSender;
  6import android.view.ContextMenu;
  7import android.view.LayoutInflater;
  8import android.widget.TextView;
  9import android.view.View;
 10import android.view.ViewGroup;
 11
 12import androidx.annotation.NonNull;
 13import androidx.databinding.DataBindingUtil;
 14import androidx.recyclerview.widget.DiffUtil;
 15import androidx.recyclerview.widget.ListAdapter;
 16import androidx.recyclerview.widget.RecyclerView;
 17
 18import java.util.ArrayList;
 19import java.util.List;
 20
 21import org.openintents.openpgp.util.OpenPgpUtils;
 22
 23import eu.siacs.conversations.R;
 24import eu.siacs.conversations.crypto.PgpEngine;
 25import eu.siacs.conversations.databinding.ContactBinding;
 26import eu.siacs.conversations.entities.Contact;
 27import eu.siacs.conversations.entities.MucOptions;
 28import eu.siacs.conversations.services.XmppConnectionService;
 29import eu.siacs.conversations.ui.ConferenceDetailsActivity;
 30import eu.siacs.conversations.ui.XmppActivity;
 31import eu.siacs.conversations.ui.util.AvatarWorkerTask;
 32import eu.siacs.conversations.ui.util.MucDetailsContextMenuHelper;
 33import eu.siacs.conversations.xmpp.Jid;
 34
 35public class UserAdapter extends ListAdapter<MucOptions.User, UserAdapter.ViewHolder> implements View.OnCreateContextMenuListener {
 36
 37    static final DiffUtil.ItemCallback<MucOptions.User> DIFF = new DiffUtil.ItemCallback<MucOptions.User>() {
 38        @Override
 39        public boolean areItemsTheSame(@NonNull MucOptions.User a, @NonNull MucOptions.User b) {
 40            final Jid fullA = a.getFullJid();
 41            final Jid fullB = b.getFullJid();
 42            final Jid realA = a.getRealJid();
 43            final Jid realB = b.getRealJid();
 44            if (fullA != null && fullB != null) {
 45                return fullA.equals(fullB);
 46            } else if (realA != null && realB != null) {
 47                return realA.equals(realB);
 48            } else {
 49                return false;
 50            }
 51        }
 52
 53        @Override
 54        public boolean areContentsTheSame(@NonNull MucOptions.User a, @NonNull MucOptions.User b) {
 55            return a.equals(b);
 56        }
 57    };
 58    private final boolean advancedMode;
 59    private MucOptions.User selectedUser = null;
 60
 61    public UserAdapter(final boolean advancedMode) {
 62        super(DIFF);
 63        this.advancedMode = advancedMode;
 64    }
 65
 66    @NonNull
 67    @Override
 68    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) {
 69        return new ViewHolder(DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()), R.layout.contact, viewGroup, false));
 70    }
 71
 72    @Override
 73    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) {
 74        final MucOptions.User user = getItem(position);
 75        AvatarWorkerTask.loadAvatar(user, viewHolder.binding.contactPhoto, R.dimen.avatar);
 76        viewHolder.binding.getRoot().setOnClickListener(v -> {
 77            final XmppActivity activity = XmppActivity.find(v);
 78            if (activity != null) {
 79                activity.highlightInMuc(user.getConversation(), user.getNick());
 80            }
 81        });
 82        viewHolder.binding.getRoot().setTag(user);
 83        viewHolder.binding.getRoot().setOnCreateContextMenuListener(this);
 84        viewHolder.binding.getRoot().setOnLongClickListener(v -> {
 85            selectedUser = user;
 86            return false;
 87        });
 88        final String name = user.getNick();
 89        final Contact contact = user.getContact();
 90        viewHolder.binding.contactJid.setVisibility(View.GONE);
 91        viewHolder.binding.contactJid.setText("");
 92        if (contact != null) {
 93            final String displayName = contact.getDisplayName();
 94            viewHolder.binding.contactDisplayName.setText(displayName);
 95            if (name != null && !name.equals(displayName)) {
 96                viewHolder.binding.contactJid.setVisibility(View.VISIBLE);
 97                viewHolder.binding.contactJid.setText(name);
 98            }
 99        } else {
100            viewHolder.binding.contactDisplayName.setText(name == null ? "" : name);
101        }
102        if (advancedMode && user.getPgpKeyId() != 0) {
103            viewHolder.binding.key.setVisibility(View.VISIBLE);
104            viewHolder.binding.key.setOnClickListener(v -> {
105                final XmppActivity activity = XmppActivity.find(v);
106                final XmppConnectionService service = activity == null ? null : activity.xmppConnectionService;
107                final PgpEngine pgpEngine = service == null ? null : service.getPgpEngine();
108                if (pgpEngine != null) {
109                    PendingIntent intent = pgpEngine.getIntentForKey(user.getPgpKeyId());
110                    if (intent != null) {
111                        try {
112                            activity.startIntentSenderForResult(intent.getIntentSender(), 0, null, 0, 0, 0);
113                        } catch (IntentSender.SendIntentException ignored) {
114
115                        }
116                    }
117                }
118            });
119            viewHolder.binding.key.setText(OpenPgpUtils.convertKeyIdToHex(user.getPgpKeyId()));
120        } else {
121            viewHolder.binding.key.setVisibility(View.GONE);
122        }
123
124        viewHolder.binding.tags.setVisibility(View.VISIBLE);
125        viewHolder.binding.tags.removeAllViewsInLayout();
126        for (MucOptions.Hat hat : getPseudoHats(viewHolder.binding.getRoot().getContext(), user)) {
127            TextView tv = (TextView) LayoutInflater.from(viewHolder.binding.getRoot().getContext()).inflate(R.layout.list_item_tag, viewHolder.binding.tags, false);
128            tv.setText(hat.toString());
129            tv.setBackgroundColor(hat.getColor());
130            viewHolder.binding.tags.addView(tv);
131        }
132        for (MucOptions.Hat hat : user.getHats()) {
133            TextView tv = (TextView) LayoutInflater.from(viewHolder.binding.getRoot().getContext()).inflate(R.layout.list_item_tag, viewHolder.binding.tags, false);
134            tv.setText(hat.toString());
135            tv.setBackgroundColor(hat.getColor());
136            viewHolder.binding.tags.addView(tv);
137        }
138
139        if (viewHolder.binding.tags.getChildCount() < 1) {
140            viewHolder.binding.contactJid.setVisibility(View.VISIBLE);
141            viewHolder.binding.tags.setVisibility(View.GONE);
142        }
143    }
144
145    private List<MucOptions.Hat> getPseudoHats(Context context, MucOptions.User user) {
146        List<MucOptions.Hat> hats = new ArrayList<>();
147        if (user.getAffiliation() != MucOptions.Affiliation.NONE) {
148            hats.add(new MucOptions.Hat(null, context.getString(user.getAffiliation().getResId())));
149        }
150        if (user.getRole() != MucOptions.Role.PARTICIPANT) {
151            hats.add(new MucOptions.Hat(null, context.getString(user.getRole().getResId())));
152        }
153        return hats;
154    }
155
156    public MucOptions.User getSelectedUser() {
157        return selectedUser;
158    }
159
160    @Override
161    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
162        MucDetailsContextMenuHelper.onCreateContextMenu(menu,v);
163    }
164
165    class ViewHolder extends RecyclerView.ViewHolder {
166
167        private final ContactBinding binding;
168
169        private ViewHolder(ContactBinding binding) {
170            super(binding.getRoot());
171            this.binding = binding;
172        }
173    }
174}