deltachat/src/main/java/org/thoughtcrime/securesms/ProfileAdapter.java

380 lines
15 KiB
Java

package org.thoughtcrime.securesms;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;
import com.b44t.messenger.DcChat;
import com.b44t.messenger.DcChatlist;
import com.b44t.messenger.DcContact;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcLot;
import com.b44t.messenger.DcMsg;
import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.contacts.ContactSelectionListItem;
import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.util.DateUtils;
import org.thoughtcrime.securesms.util.Util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public class ProfileAdapter extends RecyclerView.Adapter
{
public static final int ITEM_AVATAR = 10;
public static final int ITEM_DIVIDER = 20;
public static final int ITEM_SIGNATURE = 25;
public static final int ITEM_ALL_MEDIA_BUTTON = 30;
public static final int ITEM_SEND_MESSAGE_BUTTON = 35;
public static final int ITEM_LAST_SEEN = 40;
public static final int ITEM_INTRODUCED_BY = 45;
public static final int ITEM_ADDRESS = 50;
public static final int ITEM_HEADER = 53;
public static final int ITEM_MEMBERS = 55;
public static final int ITEM_SHARED_CHATS = 60;
private final @NonNull Context context;
private final @NonNull Fragment fragment;
private final @NonNull DcContext dcContext;
private @Nullable DcChat dcChat;
private @Nullable DcContact dcContact;
private final @NonNull ArrayList<ItemData> itemData = new ArrayList<>();
private DcChatlist itemDataSharedChats;
private String itemDataStatusText;
private boolean isOutBroadcast;
private int memberCount;
private final Set<Integer> selectedMembers;
private final LayoutInflater layoutInflater;
private final ItemClickListener clickListener;
private final GlideRequests glideRequests;
static class ItemData {
final int viewType;
final int contactId;
final int chatlistIndex;
final String label;
final int icon;
ItemData(int viewType, String label, int icon) {
this(viewType, 0, 0, label, icon);
}
ItemData(int viewType, int contactId, int chatlistIndex) {
this(viewType, contactId, chatlistIndex, null, 0);
}
private ItemData(int viewType, int contactId, int chatlistIndex, @Nullable String label, int icon) {
this.viewType = viewType;
this.contactId = contactId;
this.chatlistIndex = chatlistIndex;
this.label = label;
this.icon = icon;
}
};
public ProfileAdapter(@NonNull Fragment fragment,
@NonNull GlideRequests glideRequests,
@Nullable ItemClickListener clickListener)
{
super();
this.fragment = fragment;
this.context = fragment.requireContext();
this.glideRequests = glideRequests;
this.clickListener = clickListener;
this.dcContext = DcHelper.getContext(context);
this.layoutInflater = LayoutInflater.from(context);
this.selectedMembers= new HashSet<>();
}
@Override
public int getItemCount() {
return itemData.size();
}
@Override
public int getItemViewType(int i) {
return itemData.get(i).viewType;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View itemView) {
super(itemView);
}
}
@NonNull
@Override
public ProfileAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == ITEM_HEADER) {
final View item = LayoutInflater.from(context).inflate(R.layout.contact_selection_list_divider, parent, false);
return new ViewHolder(item);
} else if (viewType == ITEM_DIVIDER) {
final View item = LayoutInflater.from(context).inflate(R.layout.profile_divider, parent, false);
return new ViewHolder(item);
} else if (viewType == ITEM_MEMBERS) {
final ContactSelectionListItem item = (ContactSelectionListItem)layoutInflater.inflate(R.layout.contact_selection_list_item, parent, false);
return new ViewHolder(item);
} else if (viewType == ITEM_SHARED_CHATS) {
final ConversationListItem item = (ConversationListItem)layoutInflater.inflate(R.layout.conversation_list_item_view, parent, false);
item.hideItemDivider();
return new ViewHolder(item);
} else if (viewType == ITEM_SIGNATURE) {
final ProfileStatusItem item = (ProfileStatusItem)layoutInflater.inflate(R.layout.profile_status_item, parent, false);
return new ViewHolder(item);
} else if (viewType == ITEM_AVATAR) {
final ProfileAvatarItem item = (ProfileAvatarItem)layoutInflater.inflate(R.layout.profile_avatar_item, parent, false);
return new ViewHolder(item);
} else if (viewType == ITEM_ALL_MEDIA_BUTTON || viewType == ITEM_SEND_MESSAGE_BUTTON) {
final ProfileTextItem item = (ProfileTextItem)layoutInflater.inflate(R.layout.profile_text_item_button, parent, false);
return new ViewHolder(item);
} else if (viewType == ITEM_LAST_SEEN || viewType == ITEM_INTRODUCED_BY || viewType == ITEM_ADDRESS) {
final ProfileTextItem item = (ProfileTextItem)layoutInflater.inflate(R.layout.profile_text_item_small, parent, false);
return new ViewHolder(item);
} else {
final ProfileTextItem item = (ProfileTextItem)layoutInflater.inflate(R.layout.profile_text_item, parent, false);
return new ViewHolder(item);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
ViewHolder holder = (ViewHolder) viewHolder;
ItemData data = itemData.get(i);
if (holder.itemView instanceof ContactSelectionListItem) {
ContactSelectionListItem contactItem = (ContactSelectionListItem) holder.itemView;
int contactId = data.contactId;
DcContact dcContact = null;
String label = null;
String name;
String addr = null;
if (contactId == DcContact.DC_CONTACT_ID_ADD_MEMBER) {
if (isOutBroadcast) {
name = context.getString(R.string.add_recipients);
} else {
name = context.getString(R.string.group_add_members);
}
}
else if (contactId == DcContact.DC_CONTACT_ID_QR_INVITE) {
name = context.getString(R.string.qrshow_title);
}
else {
dcContact = dcContext.getContact(contactId);
name = dcContact.getDisplayName();
addr = dcContact.getAddr();
}
contactItem.unbind(glideRequests);
contactItem.set(glideRequests, contactId, dcContact, name, addr, label, false, true);
contactItem.setSelected(selectedMembers.contains(contactId));
contactItem.setOnClickListener(view -> clickListener.onMemberClicked(contactId));
contactItem.setOnLongClickListener(view -> {clickListener.onMemberLongClicked(contactId); return true;});
}
else if (holder.itemView instanceof ConversationListItem) {
ConversationListItem conversationListItem = (ConversationListItem) holder.itemView;
int chatlistIndex = data.chatlistIndex;
int chatId = itemDataSharedChats.getChatId(chatlistIndex);
DcChat chat = dcContext.getChat(chatId);
DcLot summary = itemDataSharedChats.getSummary(chatlistIndex, chat);
conversationListItem.bind(DcHelper.getThreadRecord(context, summary, chat),
itemDataSharedChats.getMsgId(chatlistIndex), summary, glideRequests,
Collections.emptySet(), false);
conversationListItem.setOnClickListener(view -> clickListener.onSharedChatClicked(chatId));
}
else if(holder.itemView instanceof ProfileStatusItem) {
ProfileStatusItem item = (ProfileStatusItem) holder.itemView;
item.setOnLongClickListener(view -> {clickListener.onStatusLongClicked(); return true;});
item.set(data.label);
}
else if(holder.itemView instanceof ProfileAvatarItem) {
ProfileAvatarItem item = (ProfileAvatarItem) holder.itemView;
item.setAvatarClickListener(view -> clickListener.onAvatarClicked());
item.set(glideRequests, dcChat, dcContact, memberCount);
}
else if(holder.itemView instanceof ProfileTextItem) {
ProfileTextItem item = (ProfileTextItem) holder.itemView;
item.setOnClickListener(view -> clickListener.onSettingsClicked(data.viewType));
boolean tintIcon = data.viewType != ITEM_INTRODUCED_BY;
item.set(data.label, data.icon, tintIcon);
if (data.viewType == ITEM_LAST_SEEN || data.viewType == ITEM_ADDRESS) {
int padding = (int)((float)context.getResources().getDimensionPixelSize(R.dimen.contact_list_normal_padding) * 1.2);
item.setPadding(item.getPaddingLeft(), item.getPaddingTop(), item.getPaddingRight(), padding);
if (data.viewType == ITEM_ADDRESS) {
fragment.registerForContextMenu(item);
}
} else if (data.viewType == ITEM_INTRODUCED_BY) {
int padding = context.getResources().getDimensionPixelSize(R.dimen.contact_list_normal_padding);
item.setPadding(item.getPaddingLeft(), padding, item.getPaddingRight(), item.getPaddingBottom());
} else if (data.viewType == ITEM_ALL_MEDIA_BUTTON && dcChat != null) {
Util.runOnAnyBackgroundThread(() -> {
String c = getAllMediaCountString(dcChat.getId());
Util.runOnMain(() -> {
item.setValue(c);
});
});
}
} else if (data.viewType == ITEM_HEADER) {
TextView textView = holder.itemView.findViewById(R.id.label);
textView.setText(data.label);
}
}
public interface ItemClickListener {
void onSettingsClicked(int settingsId);
void onStatusLongClicked();
void onSharedChatClicked(int chatId);
void onMemberClicked(int contactId);
void onMemberLongClicked(int contactId);
void onAvatarClicked();
}
public void toggleMemberSelection(int contactId) {
if (!selectedMembers.remove(contactId)) {
selectedMembers.add(contactId);
}
notifyDataSetChanged();
}
@NonNull
public Collection<Integer> getSelectedMembers() {
return new HashSet<>(selectedMembers);
}
public int getSelectedMembersCount() {
return selectedMembers.size();
}
@NonNull
public String getStatusText() {
return itemDataStatusText;
}
public void clearSelection() {
selectedMembers.clear();
notifyDataSetChanged();
}
public void changeData(@Nullable int[] memberList, @Nullable DcContact dcContact, @Nullable DcChatlist sharedChats, @Nullable DcChat dcChat) {
this.dcChat = dcChat;
this.dcContact = dcContact;
itemData.clear();
itemDataSharedChats = sharedChats;
itemDataStatusText = "";
isOutBroadcast = dcChat != null && dcChat.isOutBroadcast();
boolean isMailingList = dcChat != null && dcChat.isMailingList();
boolean isInBroadcast = dcChat != null && dcChat.isInBroadcast();
boolean isSelfTalk = dcChat != null && dcChat.isSelfTalk();
boolean isDeviceTalk = dcChat != null && dcChat.isDeviceTalk();
memberCount = memberList!=null ? memberList.length : 0;
itemData.add(new ItemData(ITEM_AVATAR, null, 0));
if (isSelfTalk || dcContact != null && !dcContact.getStatus().isEmpty()) {
itemDataStatusText = isSelfTalk ? context.getString(R.string.saved_messages_explain) : dcContact.getStatus();
itemData.add(new ItemData(ITEM_SIGNATURE, itemDataStatusText, 0));
} else {
itemData.add(new ItemData(ITEM_DIVIDER, null, 0));
}
itemData.add(new ItemData(ITEM_ALL_MEDIA_BUTTON, context.getString(R.string.apps_and_media), R.drawable.ic_apps_24));
if (dcContact != null && !isDeviceTalk && !isSelfTalk) {
itemData.add(new ItemData(ITEM_SEND_MESSAGE_BUTTON, context.getString(R.string.send_message), R.drawable.ic_send_sms_white_24dp));
}
if (dcContact != null && !isDeviceTalk && !isSelfTalk) {
long lastSeenTimestamp = dcContact.getLastSeen();
String lastSeenTxt;
if (lastSeenTimestamp == 0) {
lastSeenTxt = context.getString(R.string.last_seen_unknown);
}
else {
lastSeenTxt = context.getString(R.string.last_seen_at, DateUtils.getExtendedTimeSpanString(context, lastSeenTimestamp));
}
itemData.add(new ItemData(ITEM_LAST_SEEN, lastSeenTxt, 0));
}
if (memberList!=null && !isInBroadcast && !isMailingList) {
itemData.add(new ItemData(ITEM_DIVIDER, null, 0));
if (dcChat != null) {
if (dcChat.canSend() && dcChat.isEncrypted()) {
if (!isOutBroadcast) {
itemData.add(new ItemData(ITEM_MEMBERS, DcContact.DC_CONTACT_ID_ADD_MEMBER, 0));
}
itemData.add(new ItemData(ITEM_MEMBERS, DcContact.DC_CONTACT_ID_QR_INVITE, 0));
}
}
for (int value : memberList) {
itemData.add(new ItemData(ITEM_MEMBERS, value, 0));
}
}
if (!isDeviceTalk && sharedChats != null && sharedChats.getCnt() > 0) {
itemData.add(new ItemData(ITEM_HEADER, context.getString(R.string.profile_shared_chats), 0));
for (int i = 0; i < sharedChats.getCnt(); i++) {
itemData.add(new ItemData(ITEM_SHARED_CHATS, 0, i));
}
}
if (dcContact != null && !isDeviceTalk && !isSelfTalk) {
int verifierId = dcContact.getVerifierId();
if (verifierId != 0) {
String introducedBy;
if (verifierId == DcContact.DC_CONTACT_ID_SELF) {
introducedBy = context.getString(R.string.verified_by_you);
} else {
introducedBy = context.getString(R.string.verified_by, dcContext.getContact(verifierId).getDisplayName());
}
itemData.add(new ItemData(ITEM_INTRODUCED_BY, introducedBy, dcContact.isVerified()? R.drawable.ic_verified : 0));
} else if (dcContact.isVerified()) {
String introducedBy = context.getString(R.string.verified_by_unknown);
itemData.add(new ItemData(ITEM_INTRODUCED_BY, introducedBy, R.drawable.ic_verified));
}
if (dcContact != null) {
itemData.add(new ItemData(ITEM_ADDRESS, dcContact.getAddr(), 0));
}
}
notifyDataSetChanged();
}
public int ALL_MEDIA_COUNT_MAX = 500;
public int getAllMediaCount(int chatId) {
int c = dcContext.getChatMedia(chatId, DcMsg.DC_MSG_IMAGE, DcMsg.DC_MSG_GIF, DcMsg.DC_MSG_VIDEO).length;
if (c < ALL_MEDIA_COUNT_MAX) {
c += dcContext.getChatMedia(chatId, DcMsg.DC_MSG_AUDIO, DcMsg.DC_MSG_VOICE, 0).length;
}
if (c < ALL_MEDIA_COUNT_MAX) {
c += dcContext.getChatMedia(chatId, DcMsg.DC_MSG_FILE, DcMsg.DC_MSG_WEBXDC, 0).length;
}
return c;
}
public String getAllMediaCountString(int chatId) {
final int c = getAllMediaCount(chatId);
if (c == 0) {
return context.getString(R.string.none);
} else if (c >= ALL_MEDIA_COUNT_MAX) {
return ALL_MEDIA_COUNT_MAX + "+";
} else {
return c + "";
}
}
}