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