mirror of https://github.com/NekoX-Dev/NekoX.git
956 lines
42 KiB
Java
956 lines
42 KiB
Java
/*
|
|
* This is the source code of Telegram for Android v. 5.x.x.
|
|
* It is licensed under GNU GPL v. 2 or later.
|
|
* You should have received a copy of the license in this archive (see LICENSE).
|
|
*
|
|
* Copyright Nikolai Kudashov, 2013-2018.
|
|
*/
|
|
|
|
package org.telegram.ui.Components;
|
|
|
|
import android.animation.Animator;
|
|
import android.animation.AnimatorListenerAdapter;
|
|
import android.animation.AnimatorSet;
|
|
import android.animation.ObjectAnimator;
|
|
import android.content.Context;
|
|
import android.graphics.Canvas;
|
|
import android.os.Build;
|
|
import android.text.TextUtils;
|
|
import android.util.SparseBooleanArray;
|
|
import android.view.Gravity;
|
|
import android.view.MotionEvent;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.widget.FrameLayout;
|
|
|
|
import org.telegram.PhoneFormat.PhoneFormat;
|
|
import org.telegram.messenger.AndroidUtilities;
|
|
import org.telegram.messenger.ContactsController;
|
|
import org.telegram.messenger.ImageLocation;
|
|
import org.telegram.messenger.LocaleController;
|
|
import org.telegram.messenger.MessagesController;
|
|
import org.telegram.messenger.NotificationCenter;
|
|
import org.telegram.messenger.R;
|
|
import org.telegram.messenger.UserConfig;
|
|
import org.telegram.messenger.UserObject;
|
|
import org.telegram.messenger.Utilities;
|
|
import org.telegram.tgnet.TLRPC;
|
|
import org.telegram.ui.ActionBar.SimpleTextView;
|
|
import org.telegram.ui.ActionBar.Theme;
|
|
import org.telegram.ui.ActionBar.ThemeDescription;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
|
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
import androidx.recyclerview.widget.LinearSmoothScroller;
|
|
import androidx.recyclerview.widget.RecyclerView;
|
|
|
|
public class ChatAttachAlertContactsLayout extends ChatAttachAlert.AttachAlertLayout implements NotificationCenter.NotificationCenterDelegate {
|
|
|
|
private FrameLayout frameLayout;
|
|
private RecyclerListView listView;
|
|
private LinearLayoutManager layoutManager;
|
|
private ShareAdapter listAdapter;
|
|
private ShareSearchAdapter searchAdapter;
|
|
private EmptyTextProgressView emptyView;
|
|
private View shadow;
|
|
private AnimatorSet shadowAnimation;
|
|
private SearchField searchField;
|
|
|
|
private boolean ignoreLayout;
|
|
|
|
private PhonebookShareAlertDelegate delegate;
|
|
|
|
public interface PhonebookShareAlertDelegate {
|
|
void didSelectContact(TLRPC.User user, boolean notify, int scheduleDate);
|
|
}
|
|
|
|
public static class UserCell extends FrameLayout {
|
|
|
|
private BackupImageView avatarImageView;
|
|
private SimpleTextView nameTextView;
|
|
private SimpleTextView statusTextView;
|
|
|
|
private AvatarDrawable avatarDrawable;
|
|
private TLRPC.User currentUser;
|
|
private int currentId;
|
|
|
|
private CharSequence currentName;
|
|
private CharSequence currentStatus;
|
|
|
|
private String lastName;
|
|
private int lastStatus;
|
|
private TLRPC.FileLocation lastAvatar;
|
|
|
|
private int currentAccount = UserConfig.selectedAccount;
|
|
|
|
private boolean needDivider;
|
|
|
|
public UserCell(Context context) {
|
|
super(context);
|
|
|
|
avatarDrawable = new AvatarDrawable();
|
|
|
|
avatarImageView = new BackupImageView(context);
|
|
avatarImageView.setRoundRadius(AndroidUtilities.dp(23));
|
|
addView(avatarImageView, LayoutHelper.createFrame(46, 46, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 14, 9, LocaleController.isRTL ? 14 : 0, 0));
|
|
|
|
nameTextView = new SimpleTextView(context);
|
|
nameTextView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
|
|
nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
|
nameTextView.setTextSize(16);
|
|
nameTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
|
|
addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 20, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 28 : 72, 12, LocaleController.isRTL ? 72 : 28, 0));
|
|
|
|
statusTextView = new SimpleTextView(context);
|
|
statusTextView.setTextSize(13);
|
|
statusTextView.setTextColor(Theme.getColor(Theme.key_dialogTextGray2));
|
|
statusTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
|
|
addView(statusTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 20, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 28 : 72, 36, LocaleController.isRTL ? 72 : 28, 0));
|
|
}
|
|
|
|
public void setCurrentId(int id) {
|
|
currentId = id;
|
|
}
|
|
|
|
public void setData(TLRPC.User user, CharSequence name, CharSequence status, boolean divider) {
|
|
if (user == null && name == null && status == null) {
|
|
currentStatus = null;
|
|
currentName = null;
|
|
nameTextView.setText("");
|
|
statusTextView.setText("");
|
|
avatarImageView.setImageDrawable(null);
|
|
return;
|
|
}
|
|
currentStatus = status;
|
|
currentName = name;
|
|
currentUser = user;
|
|
needDivider = divider;
|
|
setWillNotDraw(!needDivider);
|
|
update(0);
|
|
}
|
|
|
|
@Override
|
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(64) + (needDivider ? 1 : 0), MeasureSpec.EXACTLY));
|
|
}
|
|
|
|
public void update(int mask) {
|
|
TLRPC.FileLocation photo = null;
|
|
String newName = null;
|
|
if (currentUser != null && currentUser.photo != null) {
|
|
photo = currentUser.photo.photo_small;
|
|
}
|
|
|
|
if (mask != 0) {
|
|
boolean continueUpdate = false;
|
|
if ((mask & MessagesController.UPDATE_MASK_AVATAR) != 0) {
|
|
if (lastAvatar != null && photo == null || lastAvatar == null && photo != null || lastAvatar != null && photo != null && (lastAvatar.volume_id != photo.volume_id || lastAvatar.local_id != photo.local_id)) {
|
|
continueUpdate = true;
|
|
}
|
|
}
|
|
if (currentUser != null && !continueUpdate && (mask & MessagesController.UPDATE_MASK_STATUS) != 0) {
|
|
int newStatus = 0;
|
|
if (currentUser.status != null) {
|
|
newStatus = currentUser.status.expires;
|
|
}
|
|
if (newStatus != lastStatus) {
|
|
continueUpdate = true;
|
|
}
|
|
}
|
|
if (!continueUpdate && currentName == null && lastName != null && (mask & MessagesController.UPDATE_MASK_NAME) != 0) {
|
|
if (currentUser != null) {
|
|
newName = UserObject.getUserName(currentUser);
|
|
}
|
|
if (!newName.equals(lastName)) {
|
|
continueUpdate = true;
|
|
}
|
|
}
|
|
if (!continueUpdate) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (currentUser != null) {
|
|
avatarDrawable.setInfo(currentUser);
|
|
if (currentUser.status != null) {
|
|
lastStatus = currentUser.status.expires;
|
|
} else {
|
|
lastStatus = 0;
|
|
}
|
|
} else if (currentName != null) {
|
|
avatarDrawable.setInfo(currentId, currentName.toString(), null);
|
|
} else {
|
|
avatarDrawable.setInfo(currentId, "#", null);
|
|
}
|
|
|
|
if (currentName != null) {
|
|
lastName = null;
|
|
nameTextView.setText(currentName);
|
|
} else {
|
|
if (currentUser != null) {
|
|
lastName = newName == null ? UserObject.getUserName(currentUser) : newName;
|
|
} else {
|
|
lastName = "";
|
|
}
|
|
nameTextView.setText(lastName);
|
|
}
|
|
if (currentStatus != null) {
|
|
statusTextView.setText(currentStatus);
|
|
} else if (currentUser != null) {
|
|
if (TextUtils.isEmpty(currentUser.phone)) {
|
|
statusTextView.setText(LocaleController.getString("NumberUnknown", R.string.NumberUnknown));
|
|
} else {
|
|
statusTextView.setText(PhoneFormat.getInstance().format("+" + currentUser.phone));
|
|
}
|
|
}
|
|
|
|
lastAvatar = photo;
|
|
if (currentUser != null) {
|
|
avatarImageView.setImage(ImageLocation.getForUser(currentUser, false), "50_50", avatarDrawable, currentUser);
|
|
} else {
|
|
avatarImageView.setImageDrawable(avatarDrawable);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean hasOverlappingRendering() {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
protected void onDraw(Canvas canvas) {
|
|
if (needDivider) {
|
|
canvas.drawLine(LocaleController.isRTL ? 0 : AndroidUtilities.dp(70), getMeasuredHeight() - 1, getMeasuredWidth() - (LocaleController.isRTL ? AndroidUtilities.dp(70) : 0), getMeasuredHeight() - 1, Theme.dividerPaint);
|
|
}
|
|
}
|
|
}
|
|
|
|
public ChatAttachAlertContactsLayout(ChatAttachAlert alert, Context context) {
|
|
super(alert, context);
|
|
|
|
searchAdapter = new ShareSearchAdapter(context);
|
|
|
|
frameLayout = new FrameLayout(context);
|
|
frameLayout.setBackgroundColor(Theme.getColor(Theme.key_dialogBackground));
|
|
|
|
searchField = new SearchField(context) {
|
|
@Override
|
|
public void onTextChange(String text) {
|
|
if (text.length() != 0) {
|
|
if (emptyView != null) {
|
|
emptyView.setText(LocaleController.getString("NoResult", R.string.NoResult));
|
|
}
|
|
} else {
|
|
if (listView.getAdapter() != listAdapter) {
|
|
int top = getCurrentTop();
|
|
emptyView.setText(LocaleController.getString("NoContacts", R.string.NoContacts));
|
|
emptyView.showTextView();
|
|
listView.setAdapter(listAdapter);
|
|
listAdapter.notifyDataSetChanged();
|
|
if (top > 0) {
|
|
layoutManager.scrollToPositionWithOffset(0, -top);
|
|
}
|
|
}
|
|
}
|
|
if (searchAdapter != null) {
|
|
searchAdapter.search(text);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
|
parentAlert.makeFocusable(getSearchEditText(), true);
|
|
return super.onInterceptTouchEvent(ev);
|
|
}
|
|
|
|
@Override
|
|
public void processTouchEvent(MotionEvent event) {
|
|
MotionEvent e = MotionEvent.obtain(event);
|
|
e.setLocation(e.getRawX(), e.getRawY() - parentAlert.getSheetContainer().getTranslationY() - AndroidUtilities.dp(58));
|
|
listView.dispatchTouchEvent(e);
|
|
e.recycle();
|
|
}
|
|
|
|
@Override
|
|
protected void onFieldTouchUp(EditTextBoldCursor editText) {
|
|
parentAlert.makeFocusable(editText, true);
|
|
}
|
|
};
|
|
searchField.setHint(LocaleController.getString("SearchFriends", R.string.SearchFriends));
|
|
frameLayout.addView(searchField, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT));
|
|
|
|
emptyView = new EmptyTextProgressView(context);
|
|
emptyView.showTextView();
|
|
emptyView.setText(LocaleController.getString("NoContacts", R.string.NoContacts));
|
|
addView(emptyView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT, 0, 52, 0, 0));
|
|
|
|
listView = new RecyclerListView(context) {
|
|
@Override
|
|
protected boolean allowSelectChildAtPosition(float x, float y) {
|
|
return y >= parentAlert.scrollOffsetY[0] + AndroidUtilities.dp(30) + (Build.VERSION.SDK_INT >= 21 && !parentAlert.inBubbleMode ? AndroidUtilities.statusBarHeight : 0);
|
|
}
|
|
};
|
|
listView.setClipToPadding(false);
|
|
listView.setLayoutManager(layoutManager = new FillLastLinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false, AndroidUtilities.dp(9), listView) {
|
|
@Override
|
|
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
|
|
LinearSmoothScroller linearSmoothScroller = new LinearSmoothScroller(recyclerView.getContext()) {
|
|
@Override
|
|
public int calculateDyToMakeVisible(View view, int snapPreference) {
|
|
int dy = super.calculateDyToMakeVisible(view, snapPreference);
|
|
dy -= (listView.getPaddingTop() - AndroidUtilities.dp(8));
|
|
return dy;
|
|
}
|
|
|
|
@Override
|
|
protected int calculateTimeForDeceleration(int dx) {
|
|
return super.calculateTimeForDeceleration(dx) * 2;
|
|
}
|
|
};
|
|
linearSmoothScroller.setTargetPosition(position);
|
|
startSmoothScroll(linearSmoothScroller);
|
|
}
|
|
});
|
|
listView.setHorizontalScrollBarEnabled(false);
|
|
listView.setVerticalScrollBarEnabled(false);
|
|
addView(listView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT, 0, 0, 0, 0));
|
|
listView.setAdapter(listAdapter = new ShareAdapter(context));
|
|
listView.setGlowColor(Theme.getColor(Theme.key_dialogScrollGlow));
|
|
listView.setOnItemClickListener((view, position) -> {
|
|
Object object;
|
|
if (listView.getAdapter() == searchAdapter) {
|
|
object = searchAdapter.getItem(position);
|
|
} else {
|
|
int section = listAdapter.getSectionForPosition(position);
|
|
int row = listAdapter.getPositionInSectionForPosition(position);
|
|
if (row < 0 || section < 0) {
|
|
return;
|
|
}
|
|
object = listAdapter.getItem(section, row);
|
|
|
|
}
|
|
if (object != null) {
|
|
ContactsController.Contact contact;
|
|
String firstName;
|
|
String lastName;
|
|
if (object instanceof ContactsController.Contact) {
|
|
contact = (ContactsController.Contact) object;
|
|
if (contact.user != null) {
|
|
firstName = contact.user.first_name;
|
|
lastName = contact.user.last_name;
|
|
} else {
|
|
firstName = contact.first_name;
|
|
lastName = contact.last_name;
|
|
}
|
|
} else {
|
|
TLRPC.User user = (TLRPC.User) object;
|
|
contact = new ContactsController.Contact();
|
|
firstName = contact.first_name = user.first_name;
|
|
lastName = contact.last_name = user.last_name;
|
|
contact.phones.add(user.phone);
|
|
contact.user = user;
|
|
}
|
|
|
|
PhonebookShareAlert phonebookShareAlert = new PhonebookShareAlert(parentAlert.baseFragment, contact, null, null, null, firstName, lastName);
|
|
phonebookShareAlert.setDelegate((user, notify, scheduleDate) -> {
|
|
parentAlert.dismiss();
|
|
delegate.didSelectContact(user, notify, scheduleDate);
|
|
});
|
|
phonebookShareAlert.show();
|
|
}
|
|
});
|
|
listView.setOnScrollListener(new RecyclerView.OnScrollListener() {
|
|
@Override
|
|
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
|
parentAlert.updateLayout(ChatAttachAlertContactsLayout.this, true, dy);
|
|
updateEmptyViewPosition();
|
|
}
|
|
});
|
|
|
|
FrameLayout.LayoutParams frameLayoutParams = new FrameLayout.LayoutParams(LayoutHelper.MATCH_PARENT, AndroidUtilities.getShadowHeight(), Gravity.TOP | Gravity.LEFT);
|
|
frameLayoutParams.topMargin = AndroidUtilities.dp(58);
|
|
shadow = new View(context);
|
|
shadow.setBackgroundColor(Theme.getColor(Theme.key_dialogShadowLine));
|
|
shadow.setAlpha(0.0f);
|
|
shadow.setTag(1);
|
|
addView(shadow, frameLayoutParams);
|
|
|
|
addView(frameLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 58, Gravity.LEFT | Gravity.TOP));
|
|
|
|
NotificationCenter.getInstance(parentAlert.currentAccount).addObserver(this, NotificationCenter.contactsDidLoad);
|
|
updateEmptyView();
|
|
}
|
|
|
|
@Override
|
|
void scrollToTop() {
|
|
listView.smoothScrollToPosition(0);
|
|
}
|
|
|
|
@Override
|
|
int getCurrentItemTop() {
|
|
if (listView.getChildCount() <= 0) {
|
|
return Integer.MAX_VALUE;
|
|
}
|
|
View child = listView.getChildAt(0);
|
|
RecyclerListView.Holder holder = (RecyclerListView.Holder) listView.findContainingViewHolder(child);
|
|
int top = child.getTop() - AndroidUtilities.dp(8);
|
|
int newOffset = top > 0 && holder != null && holder.getAdapterPosition() == 0 ? top : 0;
|
|
if (top >= 0 && holder != null && holder.getAdapterPosition() == 0) {
|
|
newOffset = top;
|
|
runShadowAnimation(false);
|
|
} else {
|
|
runShadowAnimation(true);
|
|
}
|
|
frameLayout.setTranslationY(newOffset);
|
|
return newOffset + AndroidUtilities.dp(12);
|
|
}
|
|
|
|
@Override
|
|
int getFirstOffset() {
|
|
return getListTopPadding() + AndroidUtilities.dp(4);
|
|
}
|
|
|
|
@Override
|
|
public void setTranslationY(float translationY) {
|
|
super.setTranslationY(translationY);
|
|
parentAlert.getSheetContainer().invalidate();
|
|
}
|
|
|
|
@Override
|
|
int getListTopPadding() {
|
|
return listView.getPaddingTop();
|
|
}
|
|
|
|
@Override
|
|
void onPreMeasure(int availableWidth, int availableHeight) {
|
|
int padding;
|
|
if (parentAlert.sizeNotifierFrameLayout.measureKeyboardHeight() > AndroidUtilities.dp(20)) {
|
|
padding = AndroidUtilities.dp(8);
|
|
parentAlert.setAllowNestedScroll(false);
|
|
} else {
|
|
if (!AndroidUtilities.isTablet() && AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y) {
|
|
padding = (int) (availableHeight / 3.5f);
|
|
} else {
|
|
padding = (availableHeight / 5 * 2);
|
|
}
|
|
parentAlert.setAllowNestedScroll(true);
|
|
}
|
|
if (listView.getPaddingTop() != padding) {
|
|
ignoreLayout = true;
|
|
listView.setPadding(0, padding, 0, 0);
|
|
ignoreLayout = false;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void requestLayout() {
|
|
if (ignoreLayout) {
|
|
return;
|
|
}
|
|
super.requestLayout();
|
|
}
|
|
|
|
private void runShadowAnimation(final boolean show) {
|
|
if (show && shadow.getTag() != null || !show && shadow.getTag() == null) {
|
|
shadow.setTag(show ? null : 1);
|
|
if (show) {
|
|
shadow.setVisibility(View.VISIBLE);
|
|
}
|
|
if (shadowAnimation != null) {
|
|
shadowAnimation.cancel();
|
|
}
|
|
shadowAnimation = new AnimatorSet();
|
|
shadowAnimation.playTogether(ObjectAnimator.ofFloat(shadow, View.ALPHA, show ? 1.0f : 0.0f));
|
|
shadowAnimation.setDuration(150);
|
|
shadowAnimation.addListener(new AnimatorListenerAdapter() {
|
|
@Override
|
|
public void onAnimationEnd(Animator animation) {
|
|
if (shadowAnimation != null && shadowAnimation.equals(animation)) {
|
|
if (!show) {
|
|
shadow.setVisibility(View.INVISIBLE);
|
|
}
|
|
shadowAnimation = null;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onAnimationCancel(Animator animation) {
|
|
if (shadowAnimation != null && shadowAnimation.equals(animation)) {
|
|
shadowAnimation = null;
|
|
}
|
|
}
|
|
});
|
|
shadowAnimation.start();
|
|
}
|
|
}
|
|
|
|
private int getCurrentTop() {
|
|
if (listView.getChildCount() != 0) {
|
|
View child = listView.getChildAt(0);
|
|
RecyclerListView.Holder holder = (RecyclerListView.Holder) listView.findContainingViewHolder(child);
|
|
if (holder != null) {
|
|
return listView.getPaddingTop() - (holder.getAdapterPosition() == 0 && child.getTop() >= 0 ? child.getTop() : 0);
|
|
}
|
|
}
|
|
return -1000;
|
|
}
|
|
|
|
public void setDelegate(PhonebookShareAlertDelegate phonebookShareAlertDelegate) {
|
|
delegate = phonebookShareAlertDelegate;
|
|
}
|
|
|
|
@Override
|
|
public void didReceivedNotification(int id, int account, Object... args) {
|
|
if (id == NotificationCenter.contactsDidLoad) {
|
|
if (listAdapter != null) {
|
|
listAdapter.notifyDataSetChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
void onDestroy() {
|
|
NotificationCenter.getInstance(parentAlert.currentAccount).removeObserver(this, NotificationCenter.contactsDidLoad);
|
|
}
|
|
|
|
@Override
|
|
void onShow() {
|
|
layoutManager.scrollToPositionWithOffset(0, 0);
|
|
}
|
|
|
|
@Override
|
|
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
|
super.onLayout(changed, left, top, right, bottom);
|
|
updateEmptyViewPosition();
|
|
}
|
|
|
|
private void updateEmptyViewPosition() {
|
|
if (emptyView.getVisibility() != VISIBLE) {
|
|
return;
|
|
}
|
|
View child = listView.getChildAt(0);
|
|
if (child == null) {
|
|
return;
|
|
}
|
|
emptyView.setTranslationY((emptyView.getMeasuredHeight() - getMeasuredHeight() + child.getTop()) / 2);
|
|
}
|
|
|
|
private void updateEmptyView() {
|
|
boolean visible = listView.getAdapter().getItemCount() == 2;
|
|
emptyView.setVisibility(visible ? VISIBLE : GONE);
|
|
updateEmptyViewPosition();
|
|
}
|
|
|
|
public class ShareAdapter extends RecyclerListView.SectionsAdapter {
|
|
|
|
private int currentAccount = UserConfig.selectedAccount;
|
|
private Context mContext;
|
|
|
|
public ShareAdapter(Context context) {
|
|
mContext = context;
|
|
}
|
|
|
|
public Object getItem(int section, int position) {
|
|
if (section == 0) {
|
|
return null;
|
|
}
|
|
section--;
|
|
HashMap<String, ArrayList<Object>> usersSectionsDict = ContactsController.getInstance(currentAccount).phoneBookSectionsDict;
|
|
ArrayList<String> sortedUsersSectionsArray = ContactsController.getInstance(currentAccount).phoneBookSectionsArray;
|
|
if (section < sortedUsersSectionsArray.size()) {
|
|
ArrayList<Object> arr = usersSectionsDict.get(sortedUsersSectionsArray.get(section));
|
|
if (position < arr.size()) {
|
|
return arr.get(position);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public boolean isEnabled(int section, int row) {
|
|
if (section == 0 || section == getSectionCount() - 1) {
|
|
return false;
|
|
}
|
|
section--;
|
|
HashMap<String, ArrayList<Object>> usersSectionsDict = ContactsController.getInstance(currentAccount).phoneBookSectionsDict;
|
|
ArrayList<String> sortedUsersSectionsArray = ContactsController.getInstance(currentAccount).phoneBookSectionsArray;
|
|
return row < usersSectionsDict.get(sortedUsersSectionsArray.get(section)).size();
|
|
}
|
|
|
|
@Override
|
|
public int getSectionCount() {
|
|
ArrayList<String> sortedUsersSectionsArray = ContactsController.getInstance(currentAccount).phoneBookSectionsArray;
|
|
return sortedUsersSectionsArray.size() + 2;
|
|
}
|
|
|
|
@Override
|
|
public int getCountForSection(int section) {
|
|
if (section == 0 || section == getSectionCount() - 1) {
|
|
return 1;
|
|
}
|
|
section--;
|
|
HashMap<String, ArrayList<Object>> usersSectionsDict = ContactsController.getInstance(currentAccount).phoneBookSectionsDict;
|
|
ArrayList<String> sortedUsersSectionsArray = ContactsController.getInstance(currentAccount).phoneBookSectionsArray;
|
|
if (section < sortedUsersSectionsArray.size()) {
|
|
return usersSectionsDict.get(sortedUsersSectionsArray.get(section)).size();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public View getSectionHeaderView(int section, View view) {
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
|
View view;
|
|
switch (viewType) {
|
|
case 0: {
|
|
view = new UserCell(mContext);
|
|
break;
|
|
}
|
|
case 1: {
|
|
view = new View(mContext);
|
|
view.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, AndroidUtilities.dp(56)));
|
|
break;
|
|
}
|
|
case 2:
|
|
default: {
|
|
view = new View(mContext);
|
|
break;
|
|
}
|
|
}
|
|
return new RecyclerListView.Holder(view);
|
|
}
|
|
|
|
@Override
|
|
public void onBindViewHolder(int section, int position, RecyclerView.ViewHolder holder) {
|
|
if (holder.getItemViewType() == 0) {
|
|
UserCell userCell = (UserCell) holder.itemView;
|
|
Object object = getItem(section, position);
|
|
TLRPC.User user = null;
|
|
boolean divider = section != getSectionCount() - 2 || position != getCountForSection(section) - 1;
|
|
if (object instanceof ContactsController.Contact) {
|
|
ContactsController.Contact contact = (ContactsController.Contact) object;
|
|
if (contact.user != null) {
|
|
user = contact.user;
|
|
} else {
|
|
userCell.setCurrentId(contact.contact_id);
|
|
userCell.setData(null, ContactsController.formatName(contact.first_name, contact.last_name), contact.phones.isEmpty() ? "" : PhoneFormat.getInstance().format(contact.phones.get(0)), divider);
|
|
}
|
|
} else {
|
|
user = (TLRPC.User) object;
|
|
}
|
|
if (user != null) {
|
|
userCell.setData(user, null, PhoneFormat.getInstance().format("+" + user.phone), divider);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public int getItemViewType(int section, int position) {
|
|
if (section == 0) {
|
|
return 1;
|
|
} else if (section == getSectionCount() - 1) {
|
|
return 2;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public String getLetter(int position) {
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public int getPositionForScrollProgress(float progress) {
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public void notifyDataSetChanged() {
|
|
super.notifyDataSetChanged();
|
|
updateEmptyView();
|
|
}
|
|
}
|
|
|
|
public class ShareSearchAdapter extends RecyclerListView.SelectionAdapter {
|
|
|
|
private Context mContext;
|
|
private ArrayList<Object> searchResult = new ArrayList<>();
|
|
private ArrayList<CharSequence> searchResultNames = new ArrayList<>();
|
|
private Runnable searchRunnable;
|
|
private int lastSearchId;
|
|
|
|
public ShareSearchAdapter(Context context) {
|
|
mContext = context;
|
|
}
|
|
|
|
public void search(final String query) {
|
|
if (searchRunnable != null) {
|
|
Utilities.searchQueue.cancelRunnable(searchRunnable);
|
|
searchRunnable = null;
|
|
}
|
|
if (query == null) {
|
|
searchResult.clear();
|
|
searchResultNames.clear();
|
|
notifyDataSetChanged();
|
|
} else {
|
|
int searchId = ++lastSearchId;
|
|
Utilities.searchQueue.postRunnable(searchRunnable = () -> processSearch(query, searchId), 300);
|
|
}
|
|
}
|
|
|
|
private void processSearch(final String query, final int searchId) {
|
|
AndroidUtilities.runOnUIThread(() -> {
|
|
final int currentAccount = UserConfig.selectedAccount;
|
|
final ArrayList<ContactsController.Contact> contactsCopy = new ArrayList<>(ContactsController.getInstance(currentAccount).contactsBook.values());
|
|
final ArrayList<TLRPC.TL_contact> contactsCopy2 = new ArrayList<>(ContactsController.getInstance(currentAccount).contacts);
|
|
Utilities.searchQueue.postRunnable(() -> {
|
|
String search1 = query.trim().toLowerCase();
|
|
if (search1.length() == 0) {
|
|
lastSearchId = -1;
|
|
updateSearchResults(query, new ArrayList<>(), new ArrayList<>(), lastSearchId);
|
|
return;
|
|
}
|
|
String search2 = LocaleController.getInstance().getTranslitString(search1);
|
|
if (search1.equals(search2) || search2.length() == 0) {
|
|
search2 = null;
|
|
}
|
|
String[] search = new String[1 + (search2 != null ? 1 : 0)];
|
|
search[0] = search1;
|
|
if (search2 != null) {
|
|
search[1] = search2;
|
|
}
|
|
|
|
ArrayList<Object> resultArray = new ArrayList<>();
|
|
ArrayList<CharSequence> resultArrayNames = new ArrayList<>();
|
|
SparseBooleanArray foundUids = new SparseBooleanArray();
|
|
|
|
for (int a = 0; a < contactsCopy.size(); a++) {
|
|
ContactsController.Contact contact = contactsCopy.get(a);
|
|
String name = ContactsController.formatName(contact.first_name, contact.last_name).toLowerCase();
|
|
String tName = LocaleController.getInstance().getTranslitString(name);
|
|
String name2;
|
|
String tName2;
|
|
if (contact.user != null) {
|
|
name2 = ContactsController.formatName(contact.user.first_name, contact.user.last_name).toLowerCase();
|
|
tName2 = LocaleController.getInstance().getTranslitString(name);
|
|
} else {
|
|
name2 = null;
|
|
tName2 = null;
|
|
}
|
|
if (name.equals(tName)) {
|
|
tName = null;
|
|
}
|
|
|
|
int found = 0;
|
|
for (String q : search) {
|
|
if (name2 != null && (name2.startsWith(q) || name2.contains(" " + q)) || tName2 != null && (tName2.startsWith(q) || tName2.contains(" " + q))) {
|
|
found = 1;
|
|
} else if (contact.user != null && contact.user.username != null && contact.user.username.startsWith(q)) {
|
|
found = 2;
|
|
} else if (name.startsWith(q) || name.contains(" " + q) || tName != null && (tName.startsWith(q) || tName.contains(" " + q))) {
|
|
found = 3;
|
|
}
|
|
if (found != 0) {
|
|
if (found == 3) {
|
|
resultArrayNames.add(AndroidUtilities.generateSearchName(contact.first_name, contact.last_name, q));
|
|
} else if (found == 1) {
|
|
resultArrayNames.add(AndroidUtilities.generateSearchName(contact.user.first_name, contact.user.last_name, q));
|
|
} else {
|
|
resultArrayNames.add(AndroidUtilities.generateSearchName("@" + contact.user.username, null, "@" + q));
|
|
}
|
|
if (contact.user != null) {
|
|
foundUids.put(contact.user.id, true);
|
|
}
|
|
resultArray.add(contact);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int a = 0; a < contactsCopy2.size(); a++) {
|
|
TLRPC.TL_contact contact = contactsCopy2.get(a);
|
|
if (foundUids.indexOfKey(contact.user_id) >= 0) {
|
|
continue;
|
|
}
|
|
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(contact.user_id);
|
|
String name = ContactsController.formatName(user.first_name, user.last_name).toLowerCase();
|
|
String tName = LocaleController.getInstance().getTranslitString(name);
|
|
if (name.equals(tName)) {
|
|
tName = null;
|
|
}
|
|
|
|
int found = 0;
|
|
for (String q : search) {
|
|
if (name.startsWith(q) || name.contains(" " + q) || tName != null && (tName.startsWith(q) || tName.contains(" " + q))) {
|
|
found = 1;
|
|
} else if (user.username != null && user.username.startsWith(q)) {
|
|
found = 2;
|
|
}
|
|
|
|
if (found != 0) {
|
|
if (found == 1) {
|
|
resultArrayNames.add(AndroidUtilities.generateSearchName(user.first_name, user.last_name, q));
|
|
} else {
|
|
resultArrayNames.add(AndroidUtilities.generateSearchName("@" + user.username, null, "@" + q));
|
|
}
|
|
resultArray.add(user);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
updateSearchResults(query, resultArray, resultArrayNames, searchId);
|
|
});
|
|
});
|
|
}
|
|
|
|
private void updateSearchResults(final String query, final ArrayList<Object> users, final ArrayList<CharSequence> names, final int searchId) {
|
|
AndroidUtilities.runOnUIThread(() -> {
|
|
if (searchId != lastSearchId) {
|
|
return;
|
|
}
|
|
if (searchId != -1 && listView.getAdapter() != searchAdapter) {
|
|
listView.setAdapter(searchAdapter);
|
|
}
|
|
searchResult = users;
|
|
searchResultNames = names;
|
|
notifyDataSetChanged();
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public int getItemCount() {
|
|
return searchResult.size() + 2;
|
|
}
|
|
|
|
public Object getItem(int position) {
|
|
position--;
|
|
if (position < 0 || position >= searchResult.size()) {
|
|
return null;
|
|
}
|
|
return searchResult.get(position);
|
|
}
|
|
|
|
@Override
|
|
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
|
View view;
|
|
switch (viewType) {
|
|
case 0:
|
|
view = new UserCell(mContext);
|
|
break;
|
|
case 1:
|
|
view = new View(mContext);
|
|
view.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, AndroidUtilities.dp(56)));
|
|
break;
|
|
case 2:
|
|
default:
|
|
view = new View(mContext);
|
|
break;
|
|
}
|
|
return new RecyclerListView.Holder(view);
|
|
}
|
|
|
|
@Override
|
|
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
|
|
if (holder.getItemViewType() == 0) {
|
|
UserCell userCell = (UserCell) holder.itemView;
|
|
|
|
boolean divider = position != getItemCount() - 2;
|
|
Object object = getItem(position);
|
|
TLRPC.User user = null;
|
|
if (object instanceof ContactsController.Contact) {
|
|
ContactsController.Contact contact = (ContactsController.Contact) object;
|
|
if (contact.user != null) {
|
|
user = contact.user;
|
|
} else {
|
|
userCell.setCurrentId(contact.contact_id);
|
|
userCell.setData(null, searchResultNames.get(position - 1), contact.phones.isEmpty() ? "" : PhoneFormat.getInstance().format(contact.phones.get(0)), divider);
|
|
}
|
|
} else {
|
|
user = (TLRPC.User) object;
|
|
}
|
|
if (user != null) {
|
|
userCell.setData(user, searchResultNames.get(position - 1), PhoneFormat.getInstance().format("+" + user.phone), divider);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean isEnabled(RecyclerView.ViewHolder holder) {
|
|
return holder.getItemViewType() == 0;
|
|
}
|
|
|
|
@Override
|
|
public int getItemViewType(int position) {
|
|
if (position == 0) {
|
|
return 1;
|
|
} else if (position == getItemCount() - 1) {
|
|
return 2;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public void notifyDataSetChanged() {
|
|
super.notifyDataSetChanged();
|
|
updateEmptyView();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public ArrayList<ThemeDescription> getThemeDescriptions() {
|
|
|
|
ThemeDescription.ThemeDescriptionDelegate cellDelegate = () -> {
|
|
if (listView != null) {
|
|
int count = listView.getChildCount();
|
|
for (int a = 0; a < count; a++) {
|
|
View child = listView.getChildAt(a);
|
|
if (child instanceof UserCell) {
|
|
((UserCell) child).update(0);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
ArrayList<ThemeDescription> themeDescriptions = new ArrayList<>();
|
|
|
|
themeDescriptions.add(new ThemeDescription(frameLayout, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_dialogBackground));
|
|
|
|
themeDescriptions.add(new ThemeDescription(shadow, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_dialogShadowLine));
|
|
|
|
themeDescriptions.add(new ThemeDescription(searchField.getSearchBackground(), ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_dialogSearchBackground));
|
|
themeDescriptions.add(new ThemeDescription(searchField, ThemeDescription.FLAG_IMAGECOLOR, new Class[]{SearchField.class}, new String[]{"searchIconImageView"}, null, null, null, Theme.key_dialogSearchIcon));
|
|
themeDescriptions.add(new ThemeDescription(searchField, ThemeDescription.FLAG_IMAGECOLOR, new Class[]{SearchField.class}, new String[]{"clearSearchImageView"}, null, null, null, Theme.key_dialogSearchIcon));
|
|
themeDescriptions.add(new ThemeDescription(searchField.getSearchEditText(), ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_dialogSearchText));
|
|
themeDescriptions.add(new ThemeDescription(searchField.getSearchEditText(), ThemeDescription.FLAG_HINTTEXTCOLOR, null, null, null, null, Theme.key_dialogSearchHint));
|
|
themeDescriptions.add(new ThemeDescription(searchField.getSearchEditText(), ThemeDescription.FLAG_CURSORCOLOR, null, null, null, null, Theme.key_featuredStickers_addedIcon));
|
|
|
|
themeDescriptions.add(new ThemeDescription(emptyView, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_emptyListPlaceholder));
|
|
themeDescriptions.add(new ThemeDescription(emptyView, ThemeDescription.FLAG_PROGRESSBAR, null, null, null, null, Theme.key_progressCircle));
|
|
|
|
themeDescriptions.add(new ThemeDescription(listView, ThemeDescription.FLAG_LISTGLOWCOLOR, null, null, null, null, Theme.key_dialogScrollGlow));
|
|
|
|
themeDescriptions.add(new ThemeDescription(listView, ThemeDescription.FLAG_SELECTOR, null, null, null, null, Theme.key_listSelector));
|
|
themeDescriptions.add(new ThemeDescription(listView, 0, new Class[]{View.class}, Theme.dividerPaint, null, null, Theme.key_divider));
|
|
|
|
themeDescriptions.add(new ThemeDescription(listView, 0, new Class[]{UserCell.class}, new String[]{"nameTextView"}, null, null, null, Theme.key_dialogTextGray2));
|
|
themeDescriptions.add(new ThemeDescription(listView, 0, new Class[]{UserCell.class}, new String[]{"statusTextView"}, null, null, cellDelegate, Theme.key_dialogTextGray2));
|
|
themeDescriptions.add(new ThemeDescription(listView, 0, new Class[]{UserCell.class}, null, Theme.avatarDrawables, null, Theme.key_avatar_text));
|
|
themeDescriptions.add(new ThemeDescription(null, 0, null, null, null, cellDelegate, Theme.key_avatar_backgroundRed));
|
|
themeDescriptions.add(new ThemeDescription(null, 0, null, null, null, cellDelegate, Theme.key_avatar_backgroundOrange));
|
|
themeDescriptions.add(new ThemeDescription(null, 0, null, null, null, cellDelegate, Theme.key_avatar_backgroundViolet));
|
|
themeDescriptions.add(new ThemeDescription(null, 0, null, null, null, cellDelegate, Theme.key_avatar_backgroundGreen));
|
|
themeDescriptions.add(new ThemeDescription(null, 0, null, null, null, cellDelegate, Theme.key_avatar_backgroundCyan));
|
|
themeDescriptions.add(new ThemeDescription(null, 0, null, null, null, cellDelegate, Theme.key_avatar_backgroundBlue));
|
|
themeDescriptions.add(new ThemeDescription(null, 0, null, null, null, cellDelegate, Theme.key_avatar_backgroundPink));
|
|
|
|
return themeDescriptions;
|
|
}
|
|
}
|