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