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}