/* * 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; import android.Manifest; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.StateListAnimator; import android.animation.ValueAnimator; import android.annotation.SuppressLint; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.database.DataSetObserver; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Outline; import android.graphics.Paint; import android.graphics.Point; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Typeface; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.SystemClock; import android.text.TextPaint; import android.text.TextUtils; import android.util.Property; import android.util.SparseArray; import android.util.TypedValue; import android.view.Display; import android.view.Gravity; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; import android.view.ViewGroup; import android.view.ViewOutlineProvider; import android.view.ViewTreeObserver; import android.view.animation.AccelerateInterpolator; import android.view.animation.DecelerateInterpolator; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.Keep; import androidx.core.content.ContextCompat; import androidx.core.graphics.ColorUtils; import androidx.core.view.NestedScrollingParent3; import androidx.core.view.NestedScrollingParentHelper; import androidx.core.view.ViewCompat; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.viewpager.widget.PagerAdapter; import androidx.viewpager.widget.ViewPager; import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ChatObject; import org.telegram.messenger.ContactsController; import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; import org.telegram.messenger.ImageLocation; import org.telegram.messenger.ImageReceiver; import org.telegram.messenger.LocaleController; import org.telegram.messenger.MediaController; import org.telegram.messenger.MediaDataController; import org.telegram.messenger.MessageObject; import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesStorage; import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.NotificationsController; import org.telegram.messenger.R; import org.telegram.messenger.SecretChatHelper; import org.telegram.messenger.SendMessagesHelper; import org.telegram.messenger.SharedConfig; import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserObject; import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.TLObject; import org.telegram.tgnet.TLRPC; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.ActionBarMenuItem; import org.telegram.ui.ActionBar.AlertDialog; import org.telegram.ui.ActionBar.BackDrawable; import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.ActionBar.SimpleTextView; import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.ThemeDescription; import org.telegram.ui.Cells.AboutLinkCell; import org.telegram.ui.Cells.DividerCell; import org.telegram.ui.Cells.HeaderCell; import org.telegram.ui.Cells.NotificationsCheckCell; import org.telegram.ui.Cells.ShadowSectionCell; import org.telegram.ui.Cells.TextCell; import org.telegram.ui.Cells.TextDetailCell; import org.telegram.ui.Cells.TextInfoPrivacyCell; import org.telegram.ui.Cells.UserCell; import org.telegram.ui.Components.AlertsCreator; import org.telegram.ui.Components.AnimationProperties; import org.telegram.ui.Components.AvatarDrawable; import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.Components.CombinedDrawable; import org.telegram.ui.Components.CrossfadeDrawable; import org.telegram.ui.Components.CubicBezierInterpolator; import org.telegram.ui.Components.IdenticonDrawable; import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.ProfileGalleryView; import org.telegram.ui.Components.RecyclerListView; import org.telegram.ui.Components.ScamDrawable; import org.telegram.ui.Components.SharedMediaLayout; import org.telegram.ui.Components.UndoView; import org.telegram.ui.Components.voip.VoIPHelper; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.concurrent.CountDownLatch; import tw.nekomimi.nekogram.NekoConfig; import tw.nekomimi.nekogram.utils.ProxyUtil; public class ProfileActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate, DialogsActivity.DialogsActivityDelegate, SharedMediaLayout.SharedMediaPreloaderDelegate { private RecyclerListView listView; private LinearLayoutManager layoutManager; private ListAdapter listAdapter; private AvatarImageView avatarImage; private SimpleTextView[] nameTextView = new SimpleTextView[2]; private SimpleTextView[] onlineTextView = new SimpleTextView[3]; private SimpleTextView idTextView; private ImageView writeButton; private AnimatorSet writeButtonAnimation; private Drawable lockIconDrawable; private Drawable verifiedDrawable; private Drawable verifiedCheckDrawable; private CrossfadeDrawable verifiedCrossfadeDrawable; private ScamDrawable scamDrawable; private UndoView undoView; private ProfileGalleryView avatarsViewPager; private PagerIndicatorView avatarsViewPagerIndicatorView; private OverlaysView overlaysView; private SharedMediaLayout sharedMediaLayout; private boolean sharedMediaLayoutAttached; private SharedMediaLayout.SharedMediaPreloader sharedMediaPreloader; private int avatarColor; private int overlayCountVisible; private int lastMeasuredContentWidth; private int lastMeasuredContentHeight; private int listContentHeight; private boolean openingAvatar; private boolean[] isOnline = new boolean[1]; private boolean callItemVisible; private boolean editItemVisible; private AvatarDrawable avatarDrawable; private ActionBarMenuItem animatingItem; private ActionBarMenuItem callItem; private ActionBarMenuItem editItem; private ActionBarMenuItem otherItem; protected float headerShadowAlpha = 1.0f; private TopView topView; private int user_id; private int chat_id; private long dialog_id; private boolean creatingChat; private boolean userBlocked; private boolean reportSpam; private long mergeDialogId; private boolean expandPhoto; private boolean needSendMessage; private boolean canSearchMembers; private boolean loadingUsers; private SparseArray participantsMap = new SparseArray<>(); private boolean usersEndReached; private int banFromGroup; private boolean openAnimationInProgress; private boolean recreateMenuAfterAnimation; private int playProfileAnimation; private boolean allowProfileAnimation = true; private float extraHeight; private float initialAnimationExtraHeight; private float animationProgress; private HashMap positionToOffset = new HashMap<>(); private float avatarX; private float avatarY; private float avatarScale; private float nameX; private float nameY; private float onlineX; private float onlineY; private float idX; private float idY; private float expandProgress; private float listViewVelocityY; private ValueAnimator expandAnimator; private float currentExpanAnimatorFracture; private float[] expandAnimatorValues = new float[]{0f, 1f}; private boolean isInLandscapeMode; private boolean allowPullingDown; private boolean isPulledDown; private boolean isBot; private TLRPC.ChatFull chatInfo; private TLRPC.UserFull userInfo; private int selectedUser; private int onlineCount = -1; private ArrayList sortedUsers; private TLRPC.EncryptedChat currentEncryptedChat; private TLRPC.Chat currentChat; private TLRPC.BotInfo botInfo; private TLRPC.ChannelParticipant currentChannelParticipant; private final static int add_contact = 1; private final static int block_contact = 2; private final static int share_contact = 3; private final static int edit_contact = 4; private final static int delete_contact = 5; private final static int leave_group = 7; private final static int invite_to_group = 9; private final static int share = 10; private final static int qr_code = 11; private final static int edit_channel = 12; private final static int add_shortcut = 14; private final static int call_item = 15; private final static int search_members = 17; private final static int add_member = 18; private final static int statistics = 19; private final static int start_secret_chat = 20; private final static int gallery_menu_save = 21; private final static int event_log = 22; private Rect rect = new Rect(); private int rowCount; private int emptyRow; private int bottomPaddingRow; private int infoHeaderRow; private int phoneRow; private int locationRow; private int userInfoRow; private int channelInfoRow; private int usernameRow; private int notificationsDividerRow; private int notificationsRow; private int infoSectionRow; private int sendMessageRow; private int reportRow; private int settingsTimerRow; private int settingsKeyRow; private int settingsSectionRow; private int membersHeaderRow; private int membersStartRow; private int membersEndRow; private int addMemberRow; private int subscribersRow; private int administratorsRow; private int blockedUsersRow; private int membersSectionRow; private int sharedMediaRow; private int unblockRow; private int joinRow; private int lastSectionRow; private int transitionIndex; private final Property HEADER_SHADOW = new AnimationProperties.FloatProperty("headerShadow") { @Override public void setValue(ProfileActivity object, float value) { headerShadowAlpha = value; topView.invalidate(); } @Override public Float get(ProfileActivity object) { return headerShadowAlpha; } }; private PhotoViewer.PhotoViewerProvider provider = new PhotoViewer.EmptyPhotoViewerProvider() { @Override public PhotoViewer.PlaceProviderObject getPlaceForPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index, boolean needPreview) { if (fileLocation == null) { return null; } TLRPC.FileLocation photoBig = null; if (user_id != 0) { TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(user_id); if (user != null && user.photo != null && user.photo.photo_big != null) { photoBig = user.photo.photo_big; } } else if (chat_id != 0) { TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(chat_id); if (chat != null && chat.photo != null && chat.photo.photo_big != null) { photoBig = chat.photo.photo_big; } } if (photoBig != null && photoBig.local_id == fileLocation.local_id && photoBig.volume_id == fileLocation.volume_id && photoBig.dc_id == fileLocation.dc_id) { int[] coords = new int[2]; avatarImage.getLocationInWindow(coords); PhotoViewer.PlaceProviderObject object = new PhotoViewer.PlaceProviderObject(); object.viewX = coords[0]; object.viewY = coords[1] - (Build.VERSION.SDK_INT >= 21 ? 0 : AndroidUtilities.statusBarHeight); object.parentView = avatarImage; object.imageReceiver = avatarImage.getImageReceiver(); if (user_id != 0) { object.dialogId = user_id; } else if (chat_id != 0) { object.dialogId = -chat_id; } object.thumb = object.imageReceiver.getBitmapSafe(); object.size = -1; object.radius = avatarImage.getImageReceiver().getRoundRadius(); object.scale = avatarImage.getScaleX(); return object; } return null; } @Override public void willHidePhotoViewer() { avatarImage.getImageReceiver().setVisible(true, true); } }; public static class AvatarImageView extends BackupImageView { private final RectF rect = new RectF(); private final Paint placeholderPaint; private ImageReceiver foregroundImageReceiver; private float foregroundAlpha; public AvatarImageView(Context context) { super(context); foregroundImageReceiver = new ImageReceiver(this); placeholderPaint = new Paint(Paint.ANTI_ALIAS_FLAG); placeholderPaint.setColor(Color.BLACK); } public void setForegroundImage(ImageLocation imageLocation, String imageFilter, Drawable thumb) { foregroundImageReceiver.setImage(imageLocation, imageFilter, thumb, 0, null, null, 0); } public void setForegroundImageDrawable(Drawable drawable) { foregroundImageReceiver.setImageBitmap(drawable); } public float getForegroundAlpha() { return foregroundAlpha; } public void setForegroundAlpha(float value) { foregroundAlpha = value; invalidate(); } public void clearForeground() { foregroundImageReceiver.clearImage(); foregroundAlpha = 0f; invalidate(); } protected void onDetachedFromWindow() { super.onDetachedFromWindow(); foregroundImageReceiver.onDetachedFromWindow(); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); foregroundImageReceiver.onAttachedToWindow(); } @Override public void setRoundRadius(int value) { super.setRoundRadius(value); foregroundImageReceiver.setRoundRadius(value); } @Override protected void onDraw(Canvas canvas) { if (foregroundAlpha < 1f) { imageReceiver.setImageCoords(0, 0, getMeasuredWidth(), getMeasuredHeight()); imageReceiver.draw(canvas); } if (foregroundAlpha > 0f) { if (foregroundImageReceiver.getDrawable() != null) { foregroundImageReceiver.setImageCoords(0, 0, getMeasuredWidth(), getMeasuredHeight()); foregroundImageReceiver.setAlpha(foregroundAlpha); foregroundImageReceiver.draw(canvas); } else { rect.set(0f, 0f, getMeasuredWidth(), getMeasuredHeight()); placeholderPaint.setAlpha((int) (foregroundAlpha * 255f)); final int radius = foregroundImageReceiver.getRoundRadius()[0]; canvas.drawRoundRect(rect, radius, radius, placeholderPaint); } } } } private class TopView extends View { private int currentColor; private Paint paint = new Paint(); public TopView(Context context) { super(context); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(widthMeasureSpec) + AndroidUtilities.dp(3)); } @Override public void setBackgroundColor(int color) { if (color != currentColor) { currentColor = color; paint.setColor(color); invalidate(); } } @Override protected void onDraw(Canvas canvas) { final int height = ActionBar.getCurrentActionBarHeight() + (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0); final float v = extraHeight + height; int y1 = (int) (v * (1.0f - mediaHeaderAnimationProgress)); if (y1 != 0) { paint.setColor(currentColor); canvas.drawRect(0, 0, getMeasuredWidth(), y1, paint); } if (y1 != v) { int color = Theme.getColor(Theme.key_windowBackgroundWhite); paint.setColor(color); canvas.drawRect(0, y1, getMeasuredWidth(), v, paint); } if (parentLayout != null) { parentLayout.drawHeaderShadow(canvas, (int) (headerShadowAlpha * 255), (int) v); } } } private class OverlaysView extends View implements ProfileGalleryView.Callback { private final int statusBarHeight = actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0; private final Rect topOverlayRect = new Rect(); private final Rect bottomOverlayRect = new Rect(); private final RectF rect = new RectF(); private final GradientDrawable topOverlayGradient; private final GradientDrawable bottomOverlayGradient; private final ValueAnimator animator; private final float[] animatorValues = new float[]{0f, 1f}; private final Paint backgroundPaint; private final Paint barPaint; private final Paint selectedBarPaint; private final GradientDrawable[] pressedOverlayGradient = new GradientDrawable[2]; private final boolean[] pressedOverlayVisible = new boolean[2]; private final float[] pressedOverlayAlpha = new float[2]; private boolean isOverlaysVisible; private float currentAnimationValue; private float alpha = 1.0f; private float[] alphas = null; private long lastTime; public OverlaysView(Context context) { super(context); setVisibility(GONE); barPaint = new Paint(Paint.ANTI_ALIAS_FLAG); barPaint.setColor(0x55ffffff); selectedBarPaint = new Paint(Paint.ANTI_ALIAS_FLAG); selectedBarPaint.setColor(0xffffffff); topOverlayGradient = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, new int[]{0x42000000, 0}); topOverlayGradient.setShape(GradientDrawable.RECTANGLE); bottomOverlayGradient = new GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, new int[]{0x42000000, 0}); bottomOverlayGradient.setShape(GradientDrawable.RECTANGLE); for (int i = 0; i < 2; i++) { final GradientDrawable.Orientation orientation = i == 0 ? GradientDrawable.Orientation.LEFT_RIGHT : GradientDrawable.Orientation.RIGHT_LEFT; pressedOverlayGradient[i] = new GradientDrawable(orientation, new int[]{0x32000000, 0}); pressedOverlayGradient[i].setShape(GradientDrawable.RECTANGLE); } backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); backgroundPaint.setColor(Color.BLACK); backgroundPaint.setAlpha(66); animator = ValueAnimator.ofFloat(0f, 1f); animator.setDuration(250); animator.setInterpolator(CubicBezierInterpolator.EASE_BOTH); animator.addUpdateListener(anim -> { float value = AndroidUtilities.lerp(animatorValues, currentAnimationValue = anim.getAnimatedFraction()); setAlphaValue(value, true); }); animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { if (!isOverlaysVisible) { setVisibility(GONE); } } @Override public void onAnimationStart(Animator animation) { setVisibility(VISIBLE); } }); } public void setAlphaValue(float value, boolean self) { if (Build.VERSION.SDK_INT > 18) { int alpha = (int) (255 * value); topOverlayGradient.setAlpha(alpha); bottomOverlayGradient.setAlpha(alpha); backgroundPaint.setAlpha((int) (66 * value)); barPaint.setAlpha((int) (0x55 * value)); selectedBarPaint.setAlpha(alpha); this.alpha = value; } else { setAlpha(value); } if (!self) { currentAnimationValue = value; } invalidate(); } public boolean isOverlaysVisible() { return isOverlaysVisible; } public void setOverlaysVisible() { isOverlaysVisible = true; setVisibility(VISIBLE); } public void setOverlaysVisible(boolean overlaysVisible, float durationFactor) { if (overlaysVisible != isOverlaysVisible) { isOverlaysVisible = overlaysVisible; animator.cancel(); final float value = AndroidUtilities.lerp(animatorValues, currentAnimationValue); if (overlaysVisible) { animator.setDuration((long) ((1f - value) * 250f / durationFactor)); } else { animator.setDuration((long) (value * 250f / durationFactor)); } animatorValues[0] = value; animatorValues[1] = overlaysVisible ? 1f : 0f; animator.start(); } } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { final int actionBarHeight = statusBarHeight + ActionBar.getCurrentActionBarHeight(); final float k = 0.5f; topOverlayRect.set(0, 0, w, (int) (actionBarHeight * k)); bottomOverlayRect.set(0, (int) (h - AndroidUtilities.dp(72f) * k), w, h); topOverlayGradient.setBounds(0, topOverlayRect.bottom, w, actionBarHeight + AndroidUtilities.dp(16f)); bottomOverlayGradient.setBounds(0, h - AndroidUtilities.dp(72f) - AndroidUtilities.dp(24f), w, bottomOverlayRect.top); pressedOverlayGradient[0].setBounds(0, 0, w / 5, h); pressedOverlayGradient[1].setBounds(w - (w / 5), 0, w, h); } @Override protected void onDraw(Canvas canvas) { for (int i = 0; i < 2; i++) { if (pressedOverlayAlpha[i] > 0f) { pressedOverlayGradient[i].setAlpha((int) (pressedOverlayAlpha[i] * 255)); pressedOverlayGradient[i].draw(canvas); } } topOverlayGradient.draw(canvas); bottomOverlayGradient.draw(canvas); canvas.drawRect(topOverlayRect, backgroundPaint); canvas.drawRect(bottomOverlayRect, backgroundPaint); int count = avatarsViewPager.getRealCount(); int selected = avatarsViewPager.getRealPosition(); if (alphas == null || alphas.length != count) { alphas = new float[count]; Arrays.fill(alphas, 0.0f); } boolean invalidate = false; long newTime = SystemClock.elapsedRealtime(); long dt = (newTime - lastTime); if (dt < 0 || dt > 20) { dt = 17; } lastTime = newTime; if (count > 1 && count <= 20) { if (overlayCountVisible == 0) { alpha = 1.0f; overlayCountVisible = 3; } else if (overlayCountVisible == 1) { alpha = 0.0f; overlayCountVisible = 2; } if (overlayCountVisible == 2) { barPaint.setAlpha((int) (0x55 * alpha)); selectedBarPaint.setAlpha((int) (0xff * alpha)); } int width = (getMeasuredWidth() - AndroidUtilities.dp(5 * 2) - AndroidUtilities.dp(2 * (count - 1))) / count; int y = AndroidUtilities.dp(4) + (Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight : 0); for (int a = 0; a < count; a++) { int x = AndroidUtilities.dp(5 + a * 2) + width * a; rect.set(x, y, x + width, y + AndroidUtilities.dp(2)); if (a != selected) { if (overlayCountVisible == 3) { barPaint.setAlpha((int) (AndroidUtilities.lerp(0x55, 0xff, CubicBezierInterpolator.EASE_BOTH.getInterpolation(alphas[a])) * alpha)); } } else { alphas[a] = 0.75f; } canvas.drawRoundRect(rect, AndroidUtilities.dp(1), AndroidUtilities.dp(1), a == selected ? selectedBarPaint : barPaint); } if (overlayCountVisible == 2) { if (alpha < 1.0f) { alpha += dt / 180.0f; if (alpha > 1.0f) { alpha = 1.0f; } invalidate = true; } else { overlayCountVisible = 3; } } else if (overlayCountVisible == 3) { for (int i = 0; i < alphas.length; i++) { if (i != selected && alphas[i] > 0.0f) { alphas[i] -= dt / 500.0f; if (alphas[i] < 0.0f) { alphas[i] = 0.0f; } invalidate = true; } } } } for (int i = 0; i < 2; i++) { if (pressedOverlayVisible[i]) { if (pressedOverlayAlpha[i] < 1f) { pressedOverlayAlpha[i] += dt / 180.0f; if (pressedOverlayAlpha[i] > 1f) { pressedOverlayAlpha[i] = 1f; } invalidate = true; } } else { if (pressedOverlayAlpha[i] > 0f) { pressedOverlayAlpha[i] -= dt / 180.0f; if (pressedOverlayAlpha[i] < 0f) { pressedOverlayAlpha[i] = 0f; } invalidate = true; } } } if (invalidate) { postInvalidateOnAnimation(); } } @Override public void onDown(boolean left) { pressedOverlayVisible[left ? 0 : 1] = true; postInvalidateOnAnimation(); } @Override public void onRelease() { Arrays.fill(pressedOverlayVisible, false); postInvalidateOnAnimation(); } } private class NestedFrameLayout extends FrameLayout implements NestedScrollingParent3 { private NestedScrollingParentHelper nestedScrollingParentHelper; public NestedFrameLayout(Context context) { super(context); nestedScrollingParentHelper = new NestedScrollingParentHelper(this); } @Override public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type, int[] consumed) { if (target == listView && sharedMediaLayoutAttached) { RecyclerListView innerListView = sharedMediaLayout.getCurrentListView(); int top = sharedMediaLayout.getTop(); if (top == 0) { consumed[1] = dyUnconsumed; innerListView.scrollBy(0, dyUnconsumed); } } } @Override public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) { } @Override public boolean onNestedPreFling(View target, float velocityX, float velocityY) { return super.onNestedPreFling(target, velocityX, velocityY); } @Override public void onNestedPreScroll(View target, int dx, int dy, int[] consumed, int type) { if (target == listView && sharedMediaRow != -1 && sharedMediaLayoutAttached) { boolean searchVisible = actionBar.isSearchFieldVisible(); int t = sharedMediaLayout.getTop(); if (dy < 0) { boolean scrolledInner = false; if (t <= 0) { RecyclerListView innerListView = sharedMediaLayout.getCurrentListView(); LinearLayoutManager linearLayoutManager = (LinearLayoutManager) innerListView.getLayoutManager(); int pos = linearLayoutManager.findFirstVisibleItemPosition(); if (pos != RecyclerView.NO_POSITION) { RecyclerView.ViewHolder holder = innerListView.findViewHolderForAdapterPosition(pos); int top = holder != null ? holder.itemView.getTop() : -1; int paddingTop = innerListView.getPaddingTop(); if (top != paddingTop || pos != 0) { consumed[1] = pos != 0 ? dy : Math.max(dy, (top - paddingTop)); innerListView.scrollBy(0, dy); scrolledInner = true; } } } if (searchVisible) { if (!scrolledInner && t < 0) { consumed[1] = dy - Math.max(t, dy); } else { consumed[1] = dy; } } } else { if (searchVisible) { RecyclerListView innerListView = sharedMediaLayout.getCurrentListView(); consumed[1] = dy; if (t > 0) { consumed[1] -= Math.min(consumed[1], dy); } if (consumed[1] > 0) { innerListView.scrollBy(0, consumed[1]); } } } } } @Override public boolean onStartNestedScroll(View child, View target, int axes, int type) { return sharedMediaRow != -1 && axes == ViewCompat.SCROLL_AXIS_VERTICAL; } @Override public void onNestedScrollAccepted(View child, View target, int axes, int type) { nestedScrollingParentHelper.onNestedScrollAccepted(child, target, axes); } @Override public void onStopNestedScroll(View target, int type) { nestedScrollingParentHelper.onStopNestedScroll(target); } @Override public void onStopNestedScroll(View child) { } } private class PagerIndicatorView extends View { private final RectF indicatorRect = new RectF(); private final TextPaint textPaint; private final Paint backgroundPaint; private final ValueAnimator animator; private final float[] animatorValues = new float[]{0f, 1f}; private final PagerAdapter adapter = avatarsViewPager.getAdapter(); private boolean isIndicatorVisible; public PagerIndicatorView(Context context) { super(context); setVisibility(GONE); textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); textPaint.setColor(Color.WHITE); textPaint.setTypeface(Typeface.SANS_SERIF); textPaint.setTextAlign(Paint.Align.CENTER); textPaint.setTextSize(AndroidUtilities.dpf2(15f)); backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); backgroundPaint.setColor(0x26000000); animator = ValueAnimator.ofFloat(0f, 1f); animator.setInterpolator(CubicBezierInterpolator.EASE_BOTH); animator.addUpdateListener(a -> { final float value = AndroidUtilities.lerp(animatorValues, a.getAnimatedFraction()); final View menuItem = getSecondaryMenuItem(); if (menuItem != null) { menuItem.setScaleX(1f - value); menuItem.setScaleY(1f - value); menuItem.setAlpha(1f - value); } setScaleX(value); setScaleY(value); setAlpha(value); }); animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { if (isIndicatorVisible) { final View menuItem = getSecondaryMenuItem(); if (menuItem != null) { menuItem.setVisibility(GONE); } } else { setVisibility(GONE); } } @Override public void onAnimationStart(Animator animation) { final View menuItem = getSecondaryMenuItem(); if (menuItem != null) { menuItem.setVisibility(VISIBLE); } setVisibility(VISIBLE); } }); avatarsViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { invalidateIndicatorRect(); } @Override public void onPageScrollStateChanged(int state) { } }); adapter.registerDataSetObserver(new DataSetObserver() { @Override public void onChanged() { int count = avatarsViewPager.getRealCount(); if (overlayCountVisible == 0 && count > 1 && count <= 20 && overlaysView.isOverlaysVisible()) { overlayCountVisible = 1; } invalidateIndicatorRect(); refreshVisibility(1f); } }); } public boolean isIndicatorVisible() { return isIndicatorVisible; } public boolean isIndicatorFullyVisible() { return isIndicatorVisible && !animator.isRunning(); } public void setIndicatorVisible(boolean indicatorVisible, float durationFactor) { if (indicatorVisible != isIndicatorVisible) { isIndicatorVisible = indicatorVisible; animator.cancel(); final float value = AndroidUtilities.lerp(animatorValues, animator.getAnimatedFraction()); if (durationFactor <= 0f) { animator.setDuration(0); } else if (indicatorVisible) { animator.setDuration((long) ((1f - value) * 250f / durationFactor)); } else { animator.setDuration((long) (value * 250f / durationFactor)); } animatorValues[0] = value; animatorValues[1] = indicatorVisible ? 1f : 0f; animator.start(); } } public void refreshVisibility(float durationFactor) { setIndicatorVisible(isPulledDown && avatarsViewPager.getRealCount() > 20, durationFactor); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { invalidateIndicatorRect(); } private void invalidateIndicatorRect() { overlaysView.invalidate(); final float textWidth = textPaint.measureText(getCurrentTitle()); indicatorRect.right = getMeasuredWidth() - AndroidUtilities.dp(54f); indicatorRect.left = indicatorRect.right - (textWidth + AndroidUtilities.dpf2(16f)); indicatorRect.top = (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0) + AndroidUtilities.dp(15f); indicatorRect.bottom = indicatorRect.top + AndroidUtilities.dp(26); setPivotX(indicatorRect.centerX()); setPivotY(indicatorRect.centerY()); invalidate(); } @Override protected void onDraw(Canvas canvas) { final float radius = AndroidUtilities.dpf2(12); canvas.drawRoundRect(indicatorRect, radius, radius, backgroundPaint); canvas.drawText(getCurrentTitle(), indicatorRect.centerX(), indicatorRect.top + AndroidUtilities.dpf2(18.5f), textPaint); } private String getCurrentTitle() { return adapter.getPageTitle(avatarsViewPager.getCurrentItem()).toString(); } private ActionBarMenuItem getSecondaryMenuItem() { if (callItemVisible) { return callItem; } else if (editItemVisible) { return editItem; } else { return null; } } } public ProfileActivity(Bundle args) { this(args, null); } public ProfileActivity(Bundle args, SharedMediaLayout.SharedMediaPreloader preloader) { super(args); sharedMediaPreloader = preloader; } @Override public boolean onFragmentCreate() { user_id = arguments.getInt("user_id", 0); chat_id = arguments.getInt("chat_id", 0); banFromGroup = arguments.getInt("ban_chat_id", 0); reportSpam = arguments.getBoolean("reportSpam", false); if (!expandPhoto) { expandPhoto = arguments.getBoolean("expandPhoto", false); if (expandPhoto) { needSendMessage = true; } } if (user_id != 0) { dialog_id = arguments.getLong("dialog_id", 0); if (dialog_id != 0) { currentEncryptedChat = MessagesController.getInstance(currentAccount).getEncryptedChat((int) (dialog_id >> 32)); } TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(user_id); if (user == null) { return false; } NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.updateInterfaces); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.contactsDidLoad); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.encryptedChatCreated); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.encryptedChatUpdated); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.blockedUsersDidLoad); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.botInfoDidLoad); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.userInfoDidLoad); userBlocked = MessagesController.getInstance(currentAccount).blockedUsers.indexOfKey(user_id) >= 0; if (user.bot) { isBot = true; MediaDataController.getInstance(currentAccount).loadBotInfo(user.id, true, classGuid); } userInfo = MessagesController.getInstance(currentAccount).getUserFull(user_id); MessagesController.getInstance(currentAccount).loadFullUser(MessagesController.getInstance(currentAccount).getUser(user_id), classGuid, true); participantsMap = null; } else if (chat_id != 0) { currentChat = MessagesController.getInstance(currentAccount).getChat(chat_id); if (currentChat == null) { final CountDownLatch countDownLatch = new CountDownLatch(1); MessagesStorage.getInstance(currentAccount).getStorageQueue().postRunnable(() -> { currentChat = MessagesStorage.getInstance(currentAccount).getChat(chat_id); countDownLatch.countDown(); }); try { countDownLatch.await(); } catch (Exception e) { FileLog.e(e); } if (currentChat != null) { MessagesController.getInstance(currentAccount).putChat(currentChat, true); } else { return false; } } if (currentChat.megagroup) { getChannelParticipants(true); } else { participantsMap = null; } NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.chatInfoDidLoad); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.chatOnlineCountDidLoad); sortedUsers = new ArrayList<>(); updateOnlineCount(); if (chatInfo == null) { chatInfo = getMessagesController().getChatFull(chat_id); } if (ChatObject.isChannel(currentChat)) { MessagesController.getInstance(currentAccount).loadFullChat(chat_id, classGuid, true); } else if (chatInfo == null) { chatInfo = getMessagesStorage().loadChatInfo(chat_id, null, false, false); } } else { return false; } if (sharedMediaPreloader == null) { sharedMediaPreloader = new SharedMediaLayout.SharedMediaPreloader(this); } sharedMediaPreloader.addDelegate(this); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.updateInterfaces); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.didReceiveNewMessages); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.closeChats); NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.emojiDidLoad); updateRowsIds(); return true; } @Override public void onFragmentDestroy() { super.onFragmentDestroy(); if (sharedMediaLayout != null) { sharedMediaLayout.onDestroy(); } if (sharedMediaPreloader != null) { sharedMediaPreloader.onDestroy(this); } if (sharedMediaPreloader != null) { sharedMediaPreloader.removeDelegate(this); } NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.updateInterfaces); NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.closeChats); NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.didReceiveNewMessages); NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.emojiDidLoad); if (avatarsViewPager != null) { avatarsViewPager.onDestroy(); } if (user_id != 0) { NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.contactsDidLoad); NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.encryptedChatCreated); NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.encryptedChatUpdated); NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.blockedUsersDidLoad); NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.botInfoDidLoad); NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.userInfoDidLoad); MessagesController.getInstance(currentAccount).cancelLoadFullUser(user_id); } else if (chat_id != 0) { NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.chatInfoDidLoad); NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.chatOnlineCountDidLoad); } } @Override protected ActionBar createActionBar(Context context) { ActionBar actionBar = new ActionBar(context) { @Override public boolean onTouchEvent(MotionEvent event) { avatarImage.getHitRect(rect); if (rect.contains((int) event.getX(), (int) event.getY())) { return false; } return super.onTouchEvent(event); } }; actionBar.setBackgroundColor(Color.TRANSPARENT); actionBar.setItemsBackgroundColor(AvatarDrawable.getButtonColorForId(user_id != 0 || ChatObject.isChannel(chat_id, currentAccount) && !currentChat.megagroup ? 5 : chat_id), false); actionBar.setItemsColor(Theme.getColor(Theme.key_actionBarDefaultIcon), false); actionBar.setBackButtonDrawable(new BackDrawable(false)); actionBar.setCastShadows(false); actionBar.setAddToContainer(false); actionBar.setClipContent(true); actionBar.setOccupyStatusBar(Build.VERSION.SDK_INT >= 21 && !AndroidUtilities.isTablet()); return actionBar; } @Override public View createView(Context context) { Theme.createProfileResources(context); hasOwnBackground = true; extraHeight = AndroidUtilities.dp(88f); actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { @Override public void onItemClick(final int id) { if (getParentActivity() == null) { return; } if (id == -1) { finishFragment(); } else if (id == block_contact) { TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(user_id); if (user == null) { return; } if (!isBot || MessagesController.isSupportUser(user)) { if (userBlocked) { MessagesController.getInstance(currentAccount).unblockUser(user_id); AlertsCreator.showSimpleToast(ProfileActivity.this, LocaleController.getString("UserUnblocked", R.string.UserUnblocked)); } else { if (reportSpam) { AlertsCreator.showBlockReportSpamAlert(ProfileActivity.this, user_id, user, null, currentEncryptedChat, false, null, param -> { if (param == 1) { NotificationCenter.getInstance(currentAccount).removeObserver(ProfileActivity.this, NotificationCenter.closeChats); NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.closeChats); playProfileAnimation = 0; finishFragment(); } else { getNotificationCenter().postNotificationName(NotificationCenter.peerSettingsDidLoad, (long) user_id); } }); } else { AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); builder.setTitle(LocaleController.getString("BlockUser", R.string.BlockUser)); builder.setMessage(AndroidUtilities.replaceTags(LocaleController.formatString("AreYouSureBlockContact2", R.string.AreYouSureBlockContact2, ContactsController.formatName(user.first_name, user.last_name)))); builder.setPositiveButton(LocaleController.getString("BlockContact", R.string.BlockContact), (dialogInterface, i) -> { MessagesController.getInstance(currentAccount).blockUser(user_id); AlertsCreator.showSimpleToast(ProfileActivity.this, LocaleController.getString("UserBlocked", R.string.UserBlocked)); }); builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); AlertDialog dialog = builder.create(); showDialog(dialog); TextView button = (TextView) dialog.getButton(DialogInterface.BUTTON_POSITIVE); if (button != null) { button.setTextColor(Theme.getColor(Theme.key_dialogTextRed2)); } } } } else { if (!userBlocked) { MessagesController.getInstance(currentAccount).blockUser(user_id); } else { MessagesController.getInstance(currentAccount).unblockUser(user_id); SendMessagesHelper.getInstance(currentAccount).sendMessage("/start", user_id, null, null, false, null, null, null, true, 0); finishFragment(); } } } else if (id == add_contact) { TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(user_id); Bundle args = new Bundle(); args.putInt("user_id", user.id); args.putBoolean("addContact", true); presentFragment(new ContactAddActivity(args)); } else if (id == share_contact) { Bundle args = new Bundle(); args.putBoolean("onlySelect", true); args.putInt("dialogsType", 3); args.putString("selectAlertString", LocaleController.getString("SendContactToText", R.string.SendContactToText)); args.putString("selectAlertStringGroup", LocaleController.getString("SendContactToGroupText", R.string.SendContactToGroupText)); DialogsActivity fragment = new DialogsActivity(args); fragment.setDelegate(ProfileActivity.this); presentFragment(fragment); } else if (id == edit_contact) { Bundle args = new Bundle(); args.putInt("user_id", user_id); presentFragment(new ContactAddActivity(args)); } else if (id == delete_contact) { final TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(user_id); if (user == null || getParentActivity() == null) { return; } AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); builder.setTitle(LocaleController.getString("DeleteContact", R.string.DeleteContact)); builder.setMessage(LocaleController.getString("AreYouSureDeleteContact", R.string.AreYouSureDeleteContact)); builder.setPositiveButton(LocaleController.getString("Delete", R.string.Delete), (dialogInterface, i) -> { ArrayList arrayList = new ArrayList<>(); arrayList.add(user); ContactsController.getInstance(currentAccount).deleteContact(arrayList); }); builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); AlertDialog dialog = builder.create(); showDialog(dialog); TextView button = (TextView) dialog.getButton(DialogInterface.BUTTON_POSITIVE); if (button != null) { button.setTextColor(Theme.getColor(Theme.key_dialogTextRed2)); } } else if (id == leave_group) { leaveChatPressed(); } else if (id == event_log) { presentFragment(new ChannelAdminLogActivity(currentChat)); } else if (id == edit_channel) { Bundle args = new Bundle(); args.putInt("chat_id", chat_id); ChatEditActivity fragment = new ChatEditActivity(args); fragment.setInfo(chatInfo); presentFragment(fragment); } else if (id == invite_to_group) { final TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(user_id); if (user == null) { return; } Bundle args = new Bundle(); args.putBoolean("onlySelect", true); args.putInt("dialogsType", 2); args.putString("addToGroupAlertString", LocaleController.formatString("AddToTheGroupAlertText", R.string.AddToTheGroupAlertText, UserObject.getUserName(user), "%1$s")); DialogsActivity fragment = new DialogsActivity(args); fragment.setDelegate((fragment1, dids, message, param) -> { long did = dids.get(0); Bundle args1 = new Bundle(); args1.putBoolean("scrollToTopOnResume", true); args1.putInt("chat_id", -(int) did); if (!MessagesController.getInstance(currentAccount).checkCanOpenChat(args1, fragment1)) { return; } NotificationCenter.getInstance(currentAccount).removeObserver(ProfileActivity.this, NotificationCenter.closeChats); NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.closeChats); MessagesController.getInstance(currentAccount).addUserToChat(-(int) did, user, null, 0, null, ProfileActivity.this, null); presentFragment(new ChatActivity(args1), true); removeSelfFromStack(); }); presentFragment(fragment); } else if (id == share || id == qr_code) { try { String text = null; if (user_id != 0) { TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(user_id); if (user == null) { return; } if (botInfo != null && userInfo != null && !TextUtils.isEmpty(userInfo.about) && id == share) { text = String.format("%s https://" + MessagesController.getInstance(currentAccount).linkPrefix + "/%s", userInfo.about, user.username); } else { text = String.format("https://" + MessagesController.getInstance(currentAccount).linkPrefix + "/%s", user.username); } } else if (chat_id != 0) { TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(chat_id); if (chat == null) { return; } if (chatInfo != null && !TextUtils.isEmpty(chatInfo.about) && id == share) { text = String.format("%s\nhttps://" + MessagesController.getInstance(currentAccount).linkPrefix + "/%s", chatInfo.about, chat.username); } else { text = String.format("https://" + MessagesController.getInstance(currentAccount).linkPrefix + "/%s", chat.username); } } if (TextUtils.isEmpty(text)) { return; } if (id == share) { Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_TEXT, text); startActivityForResult(Intent.createChooser(intent, LocaleController.getString("BotShare", R.string.BotShare)), 500); } else { ProxyUtil.showQrDialog(getParentActivity(), text); } } catch (Exception e) { FileLog.e(e); } } else if (id == add_shortcut) { try { long did; if (currentEncryptedChat != null) { did = ((long) currentEncryptedChat.id) << 32; } else if (user_id != 0) { did = user_id; } else if (chat_id != 0) { did = -chat_id; } else { return; } MediaDataController.getInstance(currentAccount).installShortcut(did); } catch (Exception e) { FileLog.e(e); } } else if (id == call_item) { TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(user_id); if (user != null) { VoIPHelper.startCall(user, getParentActivity(), userInfo); } } else if (id == search_members) { Bundle args = new Bundle(); args.putInt("chat_id", chat_id); args.putInt("type", ChatUsersActivity.TYPE_USERS); args.putBoolean("open_search", true); ChatUsersActivity fragment = new ChatUsersActivity(args); fragment.setInfo(chatInfo); presentFragment(fragment); } else if (id == add_member) { openAddMember(); } else if (id == statistics) { Bundle args = new Bundle(); args.putInt("chat_id",chat_id); StatisticActivity fragment = new StatisticActivity(args); presentFragment(fragment); } else if (id == start_secret_chat) { AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); builder.setTitle(LocaleController.getString("AreYouSureSecretChatTitle", R.string.AreYouSureSecretChatTitle)); builder.setMessage(LocaleController.getString("AreYouSureSecretChat", R.string.AreYouSureSecretChat)); builder.setPositiveButton(LocaleController.getString("Start", R.string.Start), (dialogInterface, i) -> { creatingChat = true; SecretChatHelper.getInstance(currentAccount).startSecretChat(getParentActivity(), MessagesController.getInstance(currentAccount).getUser(user_id)); }); builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); showDialog(builder.create()); } else if (id == gallery_menu_save) { if (getParentActivity() == null) { return; } if (Build.VERSION.SDK_INT >= 23 && getParentActivity().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { getParentActivity().requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 4); return; } ImageLocation location = avatarsViewPager.getImageLocation(avatarsViewPager.getRealPosition()); if (location != null) { File f = FileLoader.getPathToAttach(location.location, true); if (f != null && f.exists()) { MediaController.saveFile(f.toString(), getParentActivity(), 0, null, null); } } } } }); if (sharedMediaLayout != null) { sharedMediaLayout.onDestroy(); } final long did; if (dialog_id != 0) { did = dialog_id; } else if (user_id != 0) { did = user_id; } else { did = -chat_id; } ArrayList users = chatInfo != null && chatInfo.participants != null && chatInfo.participants.participants.size() > 5 ? sortedUsers : null; sharedMediaLayout = new SharedMediaLayout(context, did, sharedMediaPreloader, userInfo != null ? userInfo.common_chats_count : 0, sortedUsers, chatInfo, users != null, this) { @Override protected void onSelectedTabChanged() { updateSelectedMediaTabText(); } @Override protected boolean canShowSearchItem() { return mediaHeaderVisible; } @Override protected void onSearchStateChanged(boolean expanded) { if (SharedConfig.smoothKeyboard) { if (expanded) { AndroidUtilities.requestAdjustResize(getParentActivity(), classGuid, true); } else { AndroidUtilities.removeAdjustResize(getParentActivity(), classGuid, true); } } listView.stopScroll(); avatarImage.setVisibility(expanded ? INVISIBLE : VISIBLE); nameTextView[1].setVisibility(expanded ? INVISIBLE : VISIBLE); onlineTextView[1].setVisibility(expanded ? INVISIBLE : VISIBLE); onlineTextView[2].setVisibility(expanded ? INVISIBLE : VISIBLE); callItem.setVisibility(expanded || !callItemVisible ? GONE : INVISIBLE); editItem.setVisibility(expanded || !editItemVisible ? GONE : INVISIBLE); otherItem.setVisibility(expanded ? GONE : INVISIBLE); } @Override protected boolean onMemberClick(TLRPC.ChatParticipant participant, boolean isLong) { return ProfileActivity.this.onMemberClick(participant, isLong); } }; sharedMediaLayout.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.MATCH_PARENT)); ActionBarMenu menu = actionBar.createMenu(); callItem = menu.addItem(call_item, R.drawable.ic_call); editItem = menu.addItem(edit_channel, R.drawable.group_edit_profile); otherItem = menu.addItem(10, R.drawable.ic_ab_other); createActionBarMenu(); listAdapter = new ListAdapter(context); avatarDrawable = new AvatarDrawable(); avatarDrawable.setProfile(true); fragmentView = new NestedFrameLayout(context) { private boolean ignoreLayout; private boolean firstLayout = true; @Override public boolean hasOverlappingRendering() { return false; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int actionBarHeight = ActionBar.getCurrentActionBarHeight() + (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0); if (listView != null) { FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); if (layoutParams.topMargin != actionBarHeight) { layoutParams.topMargin = actionBarHeight; } } super.onMeasure(widthMeasureSpec, heightMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); boolean changed = false; if (lastMeasuredContentWidth != getMeasuredWidth() || lastMeasuredContentHeight != getMeasuredHeight()) { changed = lastMeasuredContentWidth != 0 && lastMeasuredContentWidth != getMeasuredWidth(); listContentHeight = 0; int count = listAdapter.getItemCount(); lastMeasuredContentWidth = getMeasuredWidth(); lastMeasuredContentHeight = getMeasuredHeight(); int ws = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY); int hs = MeasureSpec.makeMeasureSpec(listView.getMeasuredHeight(), MeasureSpec.UNSPECIFIED); positionToOffset.clear(); for (int i = 0; i < count; i++) { int type = listAdapter.getItemViewType(i); positionToOffset.put(i, listContentHeight); if (type == 13) { listContentHeight += listView.getMeasuredHeight(); } else { RecyclerView.ViewHolder holder = listAdapter.createViewHolder(null, type); listAdapter.onBindViewHolder(holder, i); holder.itemView.measure(ws, hs); listContentHeight += holder.itemView.getMeasuredHeight(); } } } if (firstLayout && (expandPhoto || openAnimationInProgress && playProfileAnimation == 2)) { ignoreLayout = true; if (expandPhoto) { nameTextView[1].setTextColor(Color.WHITE); onlineTextView[1].setTextColor(Color.argb(179, 255, 255, 255)); idTextView.setTextColor(Color.argb(179, 255, 255, 255)); actionBar.setItemsBackgroundColor(Theme.ACTION_BAR_WHITE_SELECTOR_COLOR, false); actionBar.setItemsColor(Color.WHITE, false); overlaysView.setOverlaysVisible(); overlaysView.setAlphaValue(1.0f, false); avatarImage.setForegroundAlpha(1.0f); avatarImage.setVisibility(View.GONE); avatarsViewPager.resetCurrentItem(); avatarsViewPager.setVisibility(View.VISIBLE); expandPhoto = false; } allowPullingDown = true; isPulledDown = true; if (otherItem != null) { otherItem.showSubItem(gallery_menu_save); } currentExpanAnimatorFracture = 1.0f; int paddingTop; int paddingBottom; if (isInLandscapeMode) { paddingTop = AndroidUtilities.dp(88f); paddingBottom = 0; } else { paddingTop = listView.getMeasuredWidth(); paddingBottom = Math.max(0, getMeasuredHeight() - (listContentHeight + AndroidUtilities.dp(88) + actionBarHeight)); } if (banFromGroup != 0) { paddingBottom += AndroidUtilities.dp(48); listView.setBottomGlowOffset(AndroidUtilities.dp(48)); } else { listView.setBottomGlowOffset(0); } initialAnimationExtraHeight = paddingTop - actionBarHeight; layoutManager.scrollToPositionWithOffset(0, -actionBarHeight); listView.setPadding(0, paddingTop, 0, paddingBottom); measureChildWithMargins(listView, widthMeasureSpec, 0, heightMeasureSpec, 0); listView.layout(0, actionBarHeight, listView.getMeasuredWidth(), actionBarHeight + listView.getMeasuredHeight()); ignoreLayout = false; } else if (!openAnimationInProgress && !firstLayout) { ignoreLayout = true; int paddingTop; int paddingBottom; if (isInLandscapeMode) { paddingTop = AndroidUtilities.dp(88f); paddingBottom = 0; } else { paddingTop = listView.getMeasuredWidth(); paddingBottom = Math.max(0, getMeasuredHeight() - (listContentHeight + AndroidUtilities.dp(88) + actionBarHeight)); } if (banFromGroup != 0) { paddingBottom += AndroidUtilities.dp(48); listView.setBottomGlowOffset(AndroidUtilities.dp(48)); } else { listView.setBottomGlowOffset(0); } int currentPaddingTop = listView.getPaddingTop(); View view = listView.getChildAt(0); int pos = RecyclerView.NO_POSITION; int top = 0; if (view != null) { RecyclerView.ViewHolder holder = listView.findContainingViewHolder(view); pos = holder.getAdapterPosition(); if (pos == RecyclerView.NO_POSITION) { pos = holder.getPosition(); } top = view.getTop(); } boolean layout = false; if (actionBar.isSearchFieldVisible()) { layoutManager.scrollToPositionWithOffset(sharedMediaRow, -paddingTop); layout = true; } else if (!changed && pos != RecyclerView.NO_POSITION) { layoutManager.scrollToPositionWithOffset(pos, top - paddingTop); layout = true; } if (currentPaddingTop != paddingTop || listView.getPaddingBottom() != paddingBottom) { listView.setPadding(0, paddingTop, 0, paddingBottom); layout = true; } if (layout) { measureChildWithMargins(listView, widthMeasureSpec, 0, heightMeasureSpec, 0); listView.layout(0, actionBarHeight, listView.getMeasuredWidth(), actionBarHeight + listView.getMeasuredHeight()); } ignoreLayout = false; } } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); firstLayout = false; checkListViewScroll(); } @Override public void requestLayout() { if (ignoreLayout) { return; } super.requestLayout(); } }; FrameLayout frameLayout = (FrameLayout) fragmentView; listView = new RecyclerListView(context) { private final Paint paint = new Paint(); private VelocityTracker velocityTracker; @Override protected boolean allowSelectChildAtPosition(View child) { return child != sharedMediaLayout; } @Override public boolean hasOverlappingRendering() { return false; } @Override protected void requestChildOnScreen(View child, View focused) { } @Override public void onDraw(Canvas c) { ViewHolder holder; if (sharedMediaRow != -1) { holder = null; } else if (lastSectionRow != -1) { holder = findViewHolderForAdapterPosition(lastSectionRow); } else if (membersSectionRow != -1 && (sharedMediaRow == -1 || membersSectionRow > sharedMediaRow)) { holder = findViewHolderForAdapterPosition(membersSectionRow); } else if (settingsSectionRow != -1) { holder = findViewHolderForAdapterPosition(settingsSectionRow); } else if (infoSectionRow != -1) { holder = findViewHolderForAdapterPosition(infoSectionRow); } else { holder = null; } int bottom; int height = getMeasuredHeight(); if (holder != null) { bottom = holder.itemView.getBottom(); if (holder.itemView.getBottom() >= height) { bottom = height; } } else { bottom = height; } paint.setColor(Theme.getColor(Theme.key_windowBackgroundWhite)); c.drawRect(0, 0, getMeasuredWidth(), bottom, paint); if (bottom != height) { paint.setColor(Theme.getColor(Theme.key_windowBackgroundGray)); c.drawRect(0, bottom, getMeasuredWidth(), height, paint); } } @Override public boolean onTouchEvent(MotionEvent e) { final int action = e.getAction(); if (action == MotionEvent.ACTION_DOWN) { if (velocityTracker == null) { velocityTracker = VelocityTracker.obtain(); } else { velocityTracker.clear(); } velocityTracker.addMovement(e); } else if (action == MotionEvent.ACTION_MOVE) { if (velocityTracker != null) { velocityTracker.addMovement(e); velocityTracker.computeCurrentVelocity(1000); listViewVelocityY = velocityTracker.getYVelocity(e.getPointerId(e.getActionIndex())); } } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { if (velocityTracker != null) { velocityTracker.recycle(); velocityTracker = null; } } final boolean result = super.onTouchEvent(e); if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { if (allowPullingDown) { final View view = layoutManager.findViewByPosition(0); if (view != null) { if (isPulledDown) { final int actionBarHeight = ActionBar.getCurrentActionBarHeight() + (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0); listView.smoothScrollBy(0, view.getTop() - listView.getMeasuredWidth() + actionBarHeight, CubicBezierInterpolator.EASE_OUT_QUINT); } else { listView.smoothScrollBy(0, view.getTop() - AndroidUtilities.dp(88), CubicBezierInterpolator.EASE_OUT_QUINT); } } } } return result; } }; listView.setVerticalScrollBarEnabled(false); listView.setItemAnimator(null); listView.setLayoutAnimation(null); listView.setClipToPadding(false); layoutManager = new LinearLayoutManager(context) { @Override public boolean supportsPredictiveItemAnimations() { return false; } @Override public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) { final View view = layoutManager.findViewByPosition(0); if (view != null && !openingAvatar) { final int canScroll = view.getTop() - AndroidUtilities.dp(88); if (!allowPullingDown && canScroll > dy) { dy = canScroll; if (avatarsViewPager.hasImages() && avatarImage.getImageReceiver().hasNotThumb() && !isInLandscapeMode && !AndroidUtilities.isTablet()) { allowPullingDown = true; } } else if (allowPullingDown) { if (dy >= canScroll) { dy = canScroll; allowPullingDown = false; } else if (listView.getScrollState() == RecyclerListView.SCROLL_STATE_DRAGGING) { if (!isPulledDown) { dy /= 2; } } } } return super.scrollVerticallyBy(dy, recycler, state); } }; layoutManager.setOrientation(LinearLayoutManager.VERTICAL); listView.setLayoutManager(layoutManager); listView.setGlowColor(0); listView.setAdapter(listAdapter); frameLayout.addView(listView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT)); listView.setOnItemClickListener((view, position, x, y) -> { if (getParentActivity() == null) { return; } if (position == settingsKeyRow) { Bundle args = new Bundle(); args.putInt("chat_id", (int) (dialog_id >> 32)); presentFragment(new IdenticonActivity(args)); } else if (position == settingsTimerRow) { showDialog(AlertsCreator.createTTLAlert(getParentActivity(), currentEncryptedChat).create()); } else if (position == notificationsRow) { if (LocaleController.isRTL && x <= AndroidUtilities.dp(76) || !LocaleController.isRTL && x >= view.getMeasuredWidth() - AndroidUtilities.dp(76)) { NotificationsCheckCell checkCell = (NotificationsCheckCell) view; boolean checked = !checkCell.isChecked(); boolean defaultEnabled = NotificationsController.getInstance(currentAccount).isGlobalNotificationsEnabled(did); if (checked) { SharedPreferences preferences = MessagesController.getNotificationsSettings(currentAccount); SharedPreferences.Editor editor = preferences.edit(); if (defaultEnabled) { editor.remove("notify2_" + did); } else { editor.putInt("notify2_" + did, 0); } MessagesStorage.getInstance(currentAccount).setDialogFlags(did, 0); editor.commit(); TLRPC.Dialog dialog = MessagesController.getInstance(currentAccount).dialogs_dict.get(did); if (dialog != null) { dialog.notify_settings = new TLRPC.TL_peerNotifySettings(); } NotificationsController.getInstance(currentAccount).updateServerNotificationsSettings(did); } else { int untilTime = Integer.MAX_VALUE; SharedPreferences preferences = MessagesController.getNotificationsSettings(currentAccount); SharedPreferences.Editor editor = preferences.edit(); long flags; if (!defaultEnabled) { editor.remove("notify2_" + did); flags = 0; } else { editor.putInt("notify2_" + did, 2); flags = 1; } NotificationsController.getInstance(currentAccount).removeNotificationsForDialog(did); MessagesStorage.getInstance(currentAccount).setDialogFlags(did, flags); editor.commit(); TLRPC.Dialog dialog = MessagesController.getInstance(currentAccount).dialogs_dict.get(did); if (dialog != null) { dialog.notify_settings = new TLRPC.TL_peerNotifySettings(); if (defaultEnabled) { dialog.notify_settings.mute_until = untilTime; } } NotificationsController.getInstance(currentAccount).updateServerNotificationsSettings(did); } checkCell.setChecked(checked); RecyclerListView.Holder holder = (RecyclerListView.Holder) listView.findViewHolderForPosition(notificationsRow); if (holder != null) { listAdapter.onBindViewHolder(holder, notificationsRow); } return; } AlertsCreator.showCustomNotificationsDialog(ProfileActivity.this, did, -1, null, currentAccount, param -> listAdapter.notifyItemChanged(notificationsRow)); } else if (position == unblockRow) { MessagesController.getInstance(currentAccount).unblockUser(user_id); AlertsCreator.showSimpleToast(ProfileActivity.this, LocaleController.getString("UserUnblocked", R.string.UserUnblocked)); } else if (position == sendMessageRow) { writeButton.callOnClick(); } else if (position == reportRow) { AlertsCreator.createReportAlert(getParentActivity(), getDialogId(), 0, ProfileActivity.this); } else if (position >= membersStartRow && position < membersEndRow) { TLRPC.ChatParticipant participant; if (!sortedUsers.isEmpty()) { participant = chatInfo.participants.participants.get(sortedUsers.get(position - membersStartRow)); } else { participant = chatInfo.participants.participants.get(position - membersStartRow); } onMemberClick(participant, false); } else if (position == addMemberRow) { openAddMember(); } else if (position == usernameRow) { if (currentChat != null) { try { Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); if (!TextUtils.isEmpty(chatInfo.about)) { intent.putExtra(Intent.EXTRA_TEXT, currentChat.title + "\n" + chatInfo.about + "\nhttps://" + MessagesController.getInstance(currentAccount).linkPrefix + "/" + currentChat.username); } else { intent.putExtra(Intent.EXTRA_TEXT, currentChat.title + "\nhttps://" + MessagesController.getInstance(currentAccount).linkPrefix + "/" + currentChat.username); } getParentActivity().startActivityForResult(Intent.createChooser(intent, LocaleController.getString("BotShare", R.string.BotShare)), 500); } catch (Exception e) { FileLog.e(e); } } } else if (position == locationRow) { if (chatInfo.location instanceof TLRPC.TL_channelLocation) { LocationActivity fragment = new LocationActivity(LocationActivity.LOCATION_TYPE_GROUP_VIEW); fragment.setChatLocation(chat_id, (TLRPC.TL_channelLocation) chatInfo.location); presentFragment(fragment); } } else if (position == joinRow) { MessagesController.getInstance(currentAccount).addUserToChat(currentChat.id, UserConfig.getInstance(currentAccount).getCurrentUser(), null, 0, null, ProfileActivity.this, null); NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.closeSearchByActiveAction); } else if (position == subscribersRow) { Bundle args = new Bundle(); args.putInt("chat_id", chat_id); args.putInt("type", ChatUsersActivity.TYPE_USERS); ChatUsersActivity fragment = new ChatUsersActivity(args); fragment.setInfo(chatInfo); presentFragment(fragment); } else if (position == administratorsRow) { Bundle args = new Bundle(); args.putInt("chat_id", chat_id); args.putInt("type", ChatUsersActivity.TYPE_ADMIN); ChatUsersActivity fragment = new ChatUsersActivity(args); fragment.setInfo(chatInfo); presentFragment(fragment); } else if (position == blockedUsersRow) { Bundle args = new Bundle(); args.putInt("chat_id", chat_id); args.putInt("type", ChatUsersActivity.TYPE_BANNED); ChatUsersActivity fragment = new ChatUsersActivity(args); fragment.setInfo(chatInfo); presentFragment(fragment); } else { processOnClickOrPress(position); } }); listView.setOnItemLongClickListener((view, position) -> { if (position >= membersStartRow && position < membersEndRow) { final TLRPC.ChatParticipant participant; if (!sortedUsers.isEmpty()) { participant = chatInfo.participants.participants.get(sortedUsers.get(position - membersStartRow)); } else { participant = chatInfo.participants.participants.get(position - membersStartRow); } return onMemberClick(participant, true); } else { return processOnClickOrPress(position); } }); if (banFromGroup != 0) { TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(banFromGroup); if (currentChannelParticipant == null) { TLRPC.TL_channels_getParticipant req = new TLRPC.TL_channels_getParticipant(); req.channel = MessagesController.getInputChannel(chat); req.user_id = MessagesController.getInstance(currentAccount).getInputUser(user_id); ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> { if (response != null) { AndroidUtilities.runOnUIThread(() -> currentChannelParticipant = ((TLRPC.TL_channels_channelParticipant) response).participant); } }); } FrameLayout frameLayout1 = new FrameLayout(context) { @Override protected void onDraw(Canvas canvas) { int bottom = Theme.chat_composeShadowDrawable.getIntrinsicHeight(); Theme.chat_composeShadowDrawable.setBounds(0, 0, getMeasuredWidth(), bottom); Theme.chat_composeShadowDrawable.draw(canvas); canvas.drawRect(0, bottom, getMeasuredWidth(), getMeasuredHeight(), Theme.chat_composeBackgroundPaint); } }; frameLayout1.setWillNotDraw(false); frameLayout.addView(frameLayout1, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 51, Gravity.LEFT | Gravity.BOTTOM)); frameLayout1.setOnClickListener(v -> { ChatRightsEditActivity fragment = new ChatRightsEditActivity(user_id, banFromGroup, null, chat.default_banned_rights, currentChannelParticipant != null ? currentChannelParticipant.banned_rights : null, "", ChatRightsEditActivity.TYPE_BANNED, true, false); fragment.setDelegate(new ChatRightsEditActivity.ChatRightsEditActivityDelegate() { @Override public void didSetRights(int rights, TLRPC.TL_chatAdminRights rightsAdmin, TLRPC.TL_chatBannedRights rightsBanned, String rank) { removeSelfFromStack(); } @Override public void didChangeOwner(TLRPC.User user) { undoView.showWithAction(-chat_id, currentChat.megagroup ? UndoView.ACTION_OWNER_TRANSFERED_GROUP : UndoView.ACTION_OWNER_TRANSFERED_CHANNEL, user); } }); presentFragment(fragment); }); TextView textView = new TextView(context); textView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteRedText)); textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); textView.setGravity(Gravity.CENTER); textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); textView.setText(LocaleController.getString("BanFromTheGroup", R.string.BanFromTheGroup)); frameLayout1.addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER, 0, 1, 0, 0)); listView.setPadding(0, AndroidUtilities.dp(88), 0, AndroidUtilities.dp(48)); listView.setBottomGlowOffset(AndroidUtilities.dp(48)); } else { listView.setPadding(0, AndroidUtilities.dp(88), 0, 0); } topView = new TopView(context); topView.setBackgroundColor(Theme.getColor(Theme.key_avatar_backgroundActionBarBlue)); frameLayout.addView(topView); avatarImage = new AvatarImageView(context); avatarImage.setRoundRadius(AndroidUtilities.dp(21)); avatarImage.setPivotX(0); avatarImage.setPivotY(0); frameLayout.addView(avatarImage, LayoutHelper.createFrame(42, 42, Gravity.TOP | Gravity.LEFT, 64, 0, 0, 0)); avatarImage.setOnClickListener(v -> { if (!isInLandscapeMode && avatarImage.getImageReceiver().hasNotThumb()) { openingAvatar = true; allowPullingDown = true; View child = listView.getChildAt(0); if (child != null) { RecyclerView.ViewHolder holder = listView.findContainingViewHolder(child); if (holder != null) { Integer offset = positionToOffset.get(holder.getAdapterPosition()); if (offset != null) { listView.smoothScrollBy(0, -(offset + (listView.getPaddingTop() - child.getTop() - actionBar.getMeasuredHeight())), CubicBezierInterpolator.EASE_OUT_QUINT); return; } } } } openAvatar(); }); avatarImage.setOnLongClickListener(v -> { openAvatar(); return false; }); avatarImage.setContentDescription(LocaleController.getString("AccDescrProfilePicture", R.string.AccDescrProfilePicture)); if (avatarsViewPager != null) { avatarsViewPager.onDestroy(); } overlaysView = new OverlaysView(context); avatarsViewPager = new ProfileGalleryView(context, user_id != 0 ? user_id : -chat_id, actionBar, listView, avatarImage, getClassGuid(), overlaysView); frameLayout.addView(avatarsViewPager); frameLayout.addView(overlaysView); avatarsViewPagerIndicatorView = new PagerIndicatorView(context); frameLayout.addView(avatarsViewPagerIndicatorView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); frameLayout.addView(actionBar); for (int a = 0; a < nameTextView.length; a++) { if (playProfileAnimation == 0 && a == 0) { continue; } nameTextView[a] = new SimpleTextView(context); if (a == 1) { nameTextView[a].setTextColor(Theme.getColor(Theme.key_profile_title)); } else { nameTextView[a].setTextColor(Theme.getColor(Theme.key_actionBarDefaultTitle)); } nameTextView[a].setTextSize(18); nameTextView[a].setGravity(Gravity.LEFT); nameTextView[a].setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); nameTextView[a].setLeftDrawableTopPadding(-AndroidUtilities.dp(1.3f)); nameTextView[a].setPivotX(0); nameTextView[a].setPivotY(0); nameTextView[a].setAlpha(a == 0 ? 0.0f : 1.0f); if (a == 1) { nameTextView[a].setScrollNonFitText(true); nameTextView[a].setOnLongClickListener(v -> { AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); builder.setItems(new CharSequence[]{LocaleController.getString("Copy", R.string.Copy)}, (dialogInterface, i) -> { if (i == 0) { try { AndroidUtilities.addToClipboard(((SimpleTextView) v).getText()); Toast.makeText(getParentActivity(), LocaleController.getString("TextCopied", R.string.TextCopied), Toast.LENGTH_SHORT).show(); } catch (Exception e) { FileLog.e(e); } } }); showDialog(builder.create()); return false; }); } frameLayout.addView(nameTextView[a], LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 118, 0, a == 0 ? 48 : 0, 0)); } for (int a = 0; a < onlineTextView.length; a++) { onlineTextView[a] = new SimpleTextView(context); if (a == 2) { onlineTextView[a].setTextColor(Theme.getColor(Theme.key_player_actionBarSubtitle)); } else { onlineTextView[a].setTextColor(Theme.getColor(Theme.key_avatar_subtitleInProfileBlue)); } onlineTextView[a].setTextSize(14); onlineTextView[a].setGravity(Gravity.LEFT); onlineTextView[a].setAlpha(a == 0 || a == 2 ? 0.0f : 1.0f); frameLayout.addView(onlineTextView[a], LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 118, 0, a == 0 ? 48 : 8, 0)); } idTextView = new SimpleTextView(context); idTextView.setTextColor(Theme.getColor(Theme.key_avatar_subtitleInProfileBlue)); idTextView.setTextSize(14); idTextView.setGravity(Gravity.LEFT); idTextView.setAlpha(1.0f); frameLayout.addView(idTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 118, 0, 48, 0)); updateProfileData(); if (user_id != 0) { writeButton = new ImageView(context); Drawable drawable = Theme.createSimpleSelectorCircleDrawable(AndroidUtilities.dp(56), Theme.getColor(Theme.key_profile_actionBackground), Theme.getColor(Theme.key_profile_actionPressedBackground)); if (Build.VERSION.SDK_INT < 21) { Drawable shadowDrawable = context.getResources().getDrawable(R.drawable.floating_shadow_profile).mutate(); shadowDrawable.setColorFilter(new PorterDuffColorFilter(0xff000000, PorterDuff.Mode.SRC_IN)); CombinedDrawable combinedDrawable = new CombinedDrawable(shadowDrawable, drawable, 0, 0); combinedDrawable.setIconSize(AndroidUtilities.dp(56), AndroidUtilities.dp(56)); drawable = combinedDrawable; } writeButton.setBackgroundDrawable(drawable); writeButton.setImageResource(R.drawable.profile_newmsg); writeButton.setContentDescription(LocaleController.getString("AccDescrOpenChat", R.string.AccDescrOpenChat)); writeButton.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_profile_actionIcon), PorterDuff.Mode.SRC_IN)); writeButton.setScaleType(ImageView.ScaleType.CENTER); if (Build.VERSION.SDK_INT >= 21) { StateListAnimator animator = new StateListAnimator(); animator.addState(new int[]{android.R.attr.state_pressed}, ObjectAnimator.ofFloat(writeButton, View.TRANSLATION_Z, AndroidUtilities.dp(2), AndroidUtilities.dp(4)).setDuration(200)); animator.addState(new int[]{}, ObjectAnimator.ofFloat(writeButton, View.TRANSLATION_Z, AndroidUtilities.dp(4), AndroidUtilities.dp(2)).setDuration(200)); writeButton.setStateListAnimator(animator); writeButton.setOutlineProvider(new ViewOutlineProvider() { @SuppressLint("NewApi") @Override public void getOutline(View view, Outline outline) { outline.setOval(0, 0, AndroidUtilities.dp(56), AndroidUtilities.dp(56)); } }); } frameLayout.addView(writeButton, LayoutHelper.createFrame(Build.VERSION.SDK_INT >= 21 ? 56 : 60, Build.VERSION.SDK_INT >= 21 ? 56 : 60, Gravity.RIGHT | Gravity.TOP, 0, 0, 16, 0)); writeButton.setOnClickListener(v -> { if (playProfileAnimation != 0 && parentLayout.fragmentsStack.get(parentLayout.fragmentsStack.size() - 2) instanceof ChatActivity && !AndroidUtilities.isTablet()) { finishFragment(); } else { TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(user_id); if (user == null || user instanceof TLRPC.TL_userEmpty) { return; } Bundle args = new Bundle(); args.putInt("user_id", user_id); if (!MessagesController.getInstance(currentAccount).checkCanOpenChat(args, ProfileActivity.this)) { return; } if (!AndroidUtilities.isTablet()) { NotificationCenter.getInstance(currentAccount).removeObserver(ProfileActivity.this, NotificationCenter.closeChats); NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.closeChats); } presentFragment(new ChatActivity(args), true); if (AndroidUtilities.isTablet()) { finishFragment(); } } }); } needLayout(); listView.setOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { if (newState == RecyclerView.SCROLL_STATE_DRAGGING) { AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); } if (openingAvatar && newState != RecyclerView.SCROLL_STATE_SETTLING) { openingAvatar = false; } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { checkListViewScroll(); if (participantsMap != null && !usersEndReached && layoutManager.findLastVisibleItemPosition() > membersEndRow - 8) { getChannelParticipants(false); } } }); undoView = new UndoView(context); frameLayout.addView(undoView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM | Gravity.LEFT, 8, 0, 8, 8)); expandAnimator = ValueAnimator.ofFloat(0f, 1f); expandAnimator.addUpdateListener(anim -> { final int newTop = ActionBar.getCurrentActionBarHeight() + (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0); final float value = AndroidUtilities.lerp(expandAnimatorValues, currentExpanAnimatorFracture = anim.getAnimatedFraction()); avatarImage.setScaleX(avatarScale); avatarImage.setScaleY(avatarScale); avatarImage.setTranslationX(AndroidUtilities.lerp(avatarX, 0f, value)); avatarImage.setTranslationY(AndroidUtilities.lerp((float) Math.ceil(avatarY), 0f, value)); avatarImage.setRoundRadius((int) AndroidUtilities.lerp(AndroidUtilities.dpf2(21f), 0f, value)); if (extraHeight > AndroidUtilities.dp(88f) && expandProgress < 0.33f) { refreshNameAndOnlineXY(); } if (scamDrawable != null) { scamDrawable.setColor(ColorUtils.blendARGB(Theme.getColor(Theme.key_avatar_subtitleInProfileBlue), Color.argb(179, 255, 255, 255), value)); } if (lockIconDrawable != null) { lockIconDrawable.setColorFilter(ColorUtils.blendARGB(Theme.getColor(Theme.key_chat_lockIcon), Color.WHITE, value), PorterDuff.Mode.SRC_IN); } if (verifiedCrossfadeDrawable != null) { verifiedCrossfadeDrawable.setProgress(value); } final float k = AndroidUtilities.dpf2(8f); final float nameTextViewXEnd = AndroidUtilities.dpf2(16f) - nameTextView[1].getLeft(); final float nameTextViewYEnd = newTop + extraHeight - AndroidUtilities.dpf2(38f) - nameTextView[1].getBottom(); final float nameTextViewCx = k + nameX + (nameTextViewXEnd - nameX) / 2f; final float nameTextViewCy = k + nameY + (nameTextViewYEnd - nameY) / 2f; final float nameTextViewX = (1 - value) * (1 - value) * nameX + 2 * (1 - value) * value * nameTextViewCx + value * value * nameTextViewXEnd; final float nameTextViewY = (1 - value) * (1 - value) * nameY + 2 * (1 - value) * value * nameTextViewCy + value * value * nameTextViewYEnd; final float onlineTextViewXEnd = AndroidUtilities.dpf2(16f) - onlineTextView[1].getLeft(); final float onlineTextViewYEnd = newTop + extraHeight - AndroidUtilities.dpf2(18f) - onlineTextView[1].getBottom(); final float onlineTextViewCx = k + onlineX + (onlineTextViewXEnd - onlineX) / 2f; final float onlineTextViewCy = k + onlineY + (onlineTextViewYEnd - onlineY) / 2f; final float onlineTextViewX = (1 - value) * (1 - value) * onlineX + 2 * (1 - value) * value * onlineTextViewCx + value * value * onlineTextViewXEnd; final float onlineTextViewY = (1 - value) * (1 - value) * onlineY + 2 * (1 - value) * value * onlineTextViewCy + value * value * onlineTextViewYEnd; final float idTextViewXEnd = AndroidUtilities.dpf2(16f) - idTextView.getLeft(); final float idTextViewYEnd = newTop + extraHeight - AndroidUtilities.dpf2(3f) - idTextView.getBottom(); final float idTextViewCx = k + idX + (idTextViewXEnd - idX) / 2f; final float idTextViewCy = k + idY + (idTextViewYEnd - idY) / 2f; final float idTextViewX = (1 - value) * (1 - value) * idX + 2 * (1 - value) * value * idTextViewCx + value * value * idTextViewXEnd; final float idTextViewY = (1 - value) * (1 - value) * idY + 2 * (1 - value) * value * idTextViewCy + value * value * idTextViewYEnd; nameTextView[1].setTranslationX(nameTextViewX); nameTextView[1].setTranslationY(nameTextViewY); onlineTextView[1].setTranslationX(onlineTextViewX); onlineTextView[1].setTranslationY(onlineTextViewY); onlineTextView[2].setTranslationX(onlineTextViewX); onlineTextView[2].setTranslationY(onlineTextViewY); idTextView.setTranslationX(idTextViewX); idTextView.setTranslationY(idTextViewY); final Object onlineTextViewTag = onlineTextView[1].getTag(); int statusColor; if (onlineTextViewTag instanceof String) { statusColor = Theme.getColor((String) onlineTextViewTag); } else { statusColor = Theme.getColor(Theme.key_avatar_subtitleInProfileBlue); } onlineTextView[1].setTextColor(ColorUtils.blendARGB(statusColor, Color.argb(179, 255, 255, 255), value)); idTextView.setTextColor(ColorUtils.blendARGB(Theme.getColor(Theme.key_avatar_subtitleInProfileBlue), Color.argb(179, 255, 255, 255), value)); if (extraHeight > AndroidUtilities.dp(88f)) { nameTextView[1].setPivotY(AndroidUtilities.lerp(0, nameTextView[1].getMeasuredHeight(), value)); nameTextView[1].setScaleX(AndroidUtilities.lerp(1.12f, 1.67f, value)); nameTextView[1].setScaleY(AndroidUtilities.lerp(1.12f, 1.67f, value)); } needLayoutText(Math.min(1f, extraHeight / AndroidUtilities.dp(88f))); nameTextView[1].setTextColor(ColorUtils.blendARGB(Theme.getColor(Theme.key_profile_title), Color.WHITE, value)); actionBar.setItemsColor(ColorUtils.blendARGB(Theme.getColor(Theme.key_actionBarDefaultIcon), Color.WHITE, value), false); avatarImage.setForegroundAlpha(value); final FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) avatarImage.getLayoutParams(); params.width = (int) AndroidUtilities.lerp(AndroidUtilities.dpf2(42f), listView.getMeasuredWidth() / avatarScale, value); params.height = (int) AndroidUtilities.lerp(AndroidUtilities.dpf2(42f), (extraHeight + newTop) / avatarScale, value); params.leftMargin = (int) AndroidUtilities.lerp(AndroidUtilities.dpf2(64f), 0f, value); avatarImage.requestLayout(); }); expandAnimator.setInterpolator(CubicBezierInterpolator.EASE_BOTH); expandAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { actionBar.setItemsBackgroundColor(isPulledDown ? Theme.ACTION_BAR_WHITE_SELECTOR_COLOR : Theme.getColor(Theme.key_avatar_actionBarSelectorBlue), false); } }); updateSelectedMediaTabText(); return fragmentView; } public long getDialogId() { if (dialog_id != 0) { return dialog_id; } else if (user_id != 0) { return user_id; } else { return -chat_id; } } public TLRPC.Chat getCurrentChat() { return currentChat; } private void openAvatar() { if (listView.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING) { return; } if (user_id != 0) { TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(user_id); if (user.photo != null && user.photo.photo_big != null) { PhotoViewer.getInstance().setParentActivity(getParentActivity()); if (user.photo.dc_id != 0) { user.photo.photo_big.dc_id = user.photo.dc_id; } PhotoViewer.getInstance().openPhoto(user.photo.photo_big, provider); } } else if (chat_id != 0) { TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(chat_id); if (chat.photo != null && chat.photo.photo_big != null) { PhotoViewer.getInstance().setParentActivity(getParentActivity()); if (chat.photo.dc_id != 0) { chat.photo.photo_big.dc_id = chat.photo.dc_id; } PhotoViewer.getInstance().openPhoto(chat.photo.photo_big, provider); } } } public boolean onMemberClick(TLRPC.ChatParticipant participant, boolean isLong) { return onMemberClick(participant, isLong, false); } public boolean onMemberClick(TLRPC.ChatParticipant participant, boolean isLong, boolean resultOnly) { if (getParentActivity() == null) { return false; } if (isLong) { TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(participant.user_id); if (user == null || participant.user_id == UserConfig.getInstance(currentAccount).getClientUserId()) { return false; } selectedUser = participant.user_id; boolean allowKick; boolean canEditAdmin; boolean canRestrict; boolean editingAdmin; final TLRPC.ChannelParticipant channelParticipant; if (ChatObject.isChannel(currentChat)) { channelParticipant = ((TLRPC.TL_chatChannelParticipant) participant).channelParticipant; TLRPC.User u = MessagesController.getInstance(currentAccount).getUser(participant.user_id); canEditAdmin = ChatObject.canAddAdmins(currentChat); if (canEditAdmin && (channelParticipant instanceof TLRPC.TL_channelParticipantCreator || channelParticipant instanceof TLRPC.TL_channelParticipantAdmin && !channelParticipant.can_edit)) { canEditAdmin = false; } allowKick = canRestrict = ChatObject.canBlockUsers(currentChat) && (!(channelParticipant instanceof TLRPC.TL_channelParticipantAdmin || channelParticipant instanceof TLRPC.TL_channelParticipantCreator) || channelParticipant.can_edit); editingAdmin = channelParticipant instanceof TLRPC.TL_channelParticipantAdmin; } else { channelParticipant = null; allowKick = currentChat.creator || participant instanceof TLRPC.TL_chatParticipant && (ChatObject.canBlockUsers(currentChat) || participant.inviter_id == UserConfig.getInstance(currentAccount).getClientUserId()); canEditAdmin = currentChat.creator; canRestrict = currentChat.creator; editingAdmin = participant instanceof TLRPC.TL_chatParticipantAdmin; } ArrayList items = resultOnly ? null : new ArrayList<>(); ArrayList icons = resultOnly ? null : new ArrayList<>(); final ArrayList actions = resultOnly ? null : new ArrayList<>(); boolean hasRemove = false; if (canEditAdmin) { if (resultOnly) { return true; } items.add(editingAdmin ? LocaleController.getString("EditAdminRights", R.string.EditAdminRights) : LocaleController.getString("SetAsAdmin", R.string.SetAsAdmin)); icons.add(R.drawable.baseline_stars_18); actions.add(0); } if (canRestrict) { if (resultOnly) { return true; } items.add(LocaleController.getString("ChangePermissions", R.string.ChangePermissions)); icons.add(R.drawable.baseline_block_24); actions.add(1); } if (allowKick) { if (resultOnly) { return true; } items.add(LocaleController.getString("KickFromGroup", R.string.KickFromGroup)); icons.add(R.drawable.baseline_remove_circle_24); actions.add(2); hasRemove = true; } if (resultOnly) { return false; } if (items.isEmpty()) { return false; } AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); builder.setItems(items.toArray(new CharSequence[0]), AndroidUtilities.toIntArray(icons), (dialogInterface, i) -> { if (actions.get(i) == 2) { kickUser(selectedUser); } else { int action = actions.get(i); if (action == 1 && (channelParticipant instanceof TLRPC.TL_channelParticipantAdmin || participant instanceof TLRPC.TL_chatParticipantAdmin)) { AlertDialog.Builder builder2 = new AlertDialog.Builder(getParentActivity()); builder2.setTitle(LocaleController.getString("NekoX", R.string.NekoX)); builder2.setMessage(LocaleController.formatString("AdminWillBeRemoved", R.string.AdminWillBeRemoved, ContactsController.formatName(user.first_name, user.last_name))); builder2.setPositiveButton(LocaleController.getString("OK", R.string.OK), (dialog, which) -> { if (channelParticipant != null) { openRightsEdit(action, user.id, participant, channelParticipant.admin_rights, channelParticipant.banned_rights, channelParticipant.rank); } else { openRightsEdit(action, user.id, participant, null, null, ""); } }); builder2.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); showDialog(builder2.create()); } else { if (channelParticipant != null) { openRightsEdit(action, user.id, participant, channelParticipant.admin_rights, channelParticipant.banned_rights, channelParticipant.rank); } else { openRightsEdit(action, user.id, participant, null, null, ""); } } } }); AlertDialog alertDialog = builder.create(); showDialog(alertDialog); if (hasRemove) { alertDialog.setItemColor(items.size() - 1, Theme.getColor(Theme.key_dialogTextRed2), Theme.getColor(Theme.key_dialogRedIcon)); } } else { if (participant.user_id == UserConfig.getInstance(currentAccount).getClientUserId()) { return false; } Bundle args = new Bundle(); args.putInt("user_id", participant.user_id); presentFragment(new ProfileActivity(args)); } return true; } private void openRightsEdit(int action, int user_id, TLRPC.ChatParticipant participant, TLRPC.TL_chatAdminRights adminRights, TLRPC.TL_chatBannedRights bannedRights, String rank) { ChatRightsEditActivity fragment = new ChatRightsEditActivity(user_id, chat_id, adminRights, currentChat.default_banned_rights, bannedRights, rank, action, true, false, participant); fragment.setDelegate(new ChatRightsEditActivity.ChatRightsEditActivityDelegate() { @Override public void didSetRights(int rights, TLRPC.TL_chatAdminRights rightsAdmin, TLRPC.TL_chatBannedRights rightsBanned, String rank) { if (action == 0) { if (participant instanceof TLRPC.TL_chatChannelParticipant) { TLRPC.TL_chatChannelParticipant channelParticipant1 = ((TLRPC.TL_chatChannelParticipant) participant); if (rights == 1) { channelParticipant1.channelParticipant = new TLRPC.TL_channelParticipantAdmin(); channelParticipant1.channelParticipant.flags |= 4; } else { channelParticipant1.channelParticipant = new TLRPC.TL_channelParticipant(); } channelParticipant1.channelParticipant.inviter_id = UserConfig.getInstance(currentAccount).getClientUserId(); channelParticipant1.channelParticipant.user_id = participant.user_id; channelParticipant1.channelParticipant.date = participant.date; channelParticipant1.channelParticipant.banned_rights = rightsBanned; channelParticipant1.channelParticipant.admin_rights = rightsAdmin; channelParticipant1.channelParticipant.rank = rank; } else if (participant instanceof TLRPC.ChatParticipant) { TLRPC.ChatParticipant newParticipant; if (rights == 1) { newParticipant = new TLRPC.TL_chatParticipantAdmin(); } else { newParticipant = new TLRPC.TL_chatParticipant(); } newParticipant.user_id = participant.user_id; newParticipant.date = participant.date; newParticipant.inviter_id = participant.inviter_id; int index = chatInfo.participants.participants.indexOf(participant); if (index >= 0) { chatInfo.participants.participants.set(index, newParticipant); } } } else if (action == 1) { if (rights == 0) { if (currentChat.megagroup && chatInfo != null && chatInfo.participants != null) { boolean changed = false; for (int a = 0; a < chatInfo.participants.participants.size(); a++) { TLRPC.ChannelParticipant p = ((TLRPC.TL_chatChannelParticipant) chatInfo.participants.participants.get(a)).channelParticipant; if (p.user_id == participant.user_id) { if (chatInfo != null) { chatInfo.participants_count--; } chatInfo.participants.participants.remove(a); changed = true; break; } } if (chatInfo != null && chatInfo.participants != null) { for (int a = 0; a < chatInfo.participants.participants.size(); a++) { TLRPC.ChatParticipant p = chatInfo.participants.participants.get(a); if (p.user_id == participant.user_id) { chatInfo.participants.participants.remove(a); changed = true; break; } } } if (changed) { updateOnlineCount(); updateRowsIds(); listAdapter.notifyDataSetChanged(); } } } } } @Override public void didChangeOwner(TLRPC.User user) { undoView.showWithAction(-chat_id, currentChat.megagroup ? UndoView.ACTION_OWNER_TRANSFERED_GROUP : UndoView.ACTION_OWNER_TRANSFERED_CHANNEL, user); } }); presentFragment(fragment); } private boolean processOnClickOrPress(final int position) { if (position == usernameRow) { final String username; if (user_id != 0) { final TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(user_id); if (user == null || user.username == null) { return false; } username = user.username; } else if (chat_id != 0) { final TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(chat_id); if (chat == null || chat.username == null) { return false; } username = chat.username; } else { return false; } AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); builder.setItems(new CharSequence[]{LocaleController.getString("Copy", R.string.Copy)}, (dialogInterface, i) -> { if (i == 0) { try { android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); android.content.ClipData clip = android.content.ClipData.newPlainText("label", "@" + username); clipboard.setPrimaryClip(clip); Toast.makeText(getParentActivity(), LocaleController.getString("TextCopied", R.string.TextCopied), Toast.LENGTH_SHORT).show(); } catch (Exception e) { FileLog.e(e); } } }); showDialog(builder.create()); return true; } else if (position == phoneRow) { final TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(user_id); if (user == null || user.phone == null || user.phone.length() == 0 || getParentActivity() == null || (NekoConfig.hidePhone && user.id == UserConfig.getInstance(currentAccount).getClientUserId())) { return false; } AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); ArrayList items = new ArrayList<>(); final ArrayList actions = new ArrayList<>(); if (userInfo != null && userInfo.phone_calls_available) { items.add(LocaleController.getString("CallViaTelegram", R.string.CallViaTelegram)); actions.add(2); } items.add(LocaleController.getString("Call", R.string.Call)); actions.add(0); items.add(LocaleController.getString("Copy", R.string.Copy)); actions.add(1); builder.setItems(items.toArray(new CharSequence[0]), (dialogInterface, i) -> { i = actions.get(i); if (i == 0) { try { Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:+" + user.phone)); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); getParentActivity().startActivityForResult(intent, 500); } catch (Exception e) { FileLog.e(e); } } else if (i == 1) { try { android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); android.content.ClipData clip = android.content.ClipData.newPlainText("label", "+" + user.phone); clipboard.setPrimaryClip(clip); Toast.makeText(getParentActivity(), LocaleController.getString("PhoneCopied", R.string.PhoneCopied), Toast.LENGTH_SHORT).show(); } catch (Exception e) { FileLog.e(e); } } else if (i == 2) { VoIPHelper.startCall(user, getParentActivity(), userInfo); } }); showDialog(builder.create()); return true; } else if (position == channelInfoRow || position == userInfoRow || position == locationRow) { AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); builder.setItems(new CharSequence[]{LocaleController.getString("Copy", R.string.Copy)}, (dialogInterface, i) -> { try { String about; if (position == locationRow) { about = chatInfo != null && chatInfo.location instanceof TLRPC.TL_channelLocation ? ((TLRPC.TL_channelLocation) chatInfo.location).address : null; } else if (position == channelInfoRow) { about = chatInfo != null ? chatInfo.about : null; } else { about = userInfo != null ? userInfo.about : null; } if (TextUtils.isEmpty(about)) { return; } AndroidUtilities.addToClipboard(about); Toast.makeText(getParentActivity(), LocaleController.getString("TextCopied", R.string.TextCopied), Toast.LENGTH_SHORT).show(); } catch (Exception e) { FileLog.e(e); } }); showDialog(builder.create()); return true; } return false; } private void leaveChatPressed() { AlertsCreator.createClearOrDeleteDialogAlert(ProfileActivity.this, false, currentChat, null, false, (param) -> { playProfileAnimation = 0; NotificationCenter.getInstance(currentAccount).removeObserver(ProfileActivity.this, NotificationCenter.closeChats); NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.closeChats); finishFragment(); NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.needDeleteDialog, (long) -currentChat.id, null, currentChat, param); }); } private void getChannelParticipants(boolean reload) { if (loadingUsers || participantsMap == null || chatInfo == null) { return; } loadingUsers = true; final int delay = participantsMap.size() != 0 && reload ? 300 : 0; final TLRPC.TL_channels_getParticipants req = new TLRPC.TL_channels_getParticipants(); req.channel = MessagesController.getInstance(currentAccount).getInputChannel(chat_id); req.filter = new TLRPC.TL_channelParticipantsRecent(); req.offset = reload ? 0 : participantsMap.size(); req.limit = 200; int reqId = ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> { if (error == null) { TLRPC.TL_channels_channelParticipants res = (TLRPC.TL_channels_channelParticipants) response; MessagesController.getInstance(currentAccount).putUsers(res.users, false); if (res.users.size() < 200) { usersEndReached = true; } if (req.offset == 0) { participantsMap.clear(); chatInfo.participants = new TLRPC.TL_chatParticipants(); MessagesStorage.getInstance(currentAccount).putUsersAndChats(res.users, null, true, true); MessagesStorage.getInstance(currentAccount).updateChannelUsers(chat_id, res.participants); } for (int a = 0; a < res.participants.size(); a++) { TLRPC.TL_chatChannelParticipant participant = new TLRPC.TL_chatChannelParticipant(); participant.channelParticipant = res.participants.get(a); participant.inviter_id = participant.channelParticipant.inviter_id; participant.user_id = participant.channelParticipant.user_id; participant.date = participant.channelParticipant.date; if (participantsMap.indexOfKey(participant.user_id) < 0) { chatInfo.participants.participants.add(participant); participantsMap.put(participant.user_id, participant); } } } updateOnlineCount(); loadingUsers = false; updateRowsIds(); if (listAdapter != null) { listAdapter.notifyDataSetChanged(); } }, delay)); ConnectionsManager.getInstance(currentAccount).bindRequestToGuid(reqId, classGuid); } private AnimatorSet headerAnimatorSet; private AnimatorSet headerShadowAnimatorSet; private float mediaHeaderAnimationProgress; private boolean mediaHeaderVisible; private Property ACTIONBAR_HEADER_PROGRESS = new AnimationProperties.FloatProperty("animationProgress") { @Override public void setValue(ActionBar object, float value) { mediaHeaderAnimationProgress = value; topView.invalidate(); int color1 = Theme.getColor(Theme.key_profile_title); int color2 = Theme.getColor(Theme.key_player_actionBarTitle); int c = AndroidUtilities.getOffsetColor(color1, color2, value, 1.0f); nameTextView[1].setTextColor(c); if (lockIconDrawable != null) { lockIconDrawable.setColorFilter(c, PorterDuff.Mode.SRC_IN); } if (scamDrawable != null) { color1 = Theme.getColor(Theme.key_avatar_subtitleInProfileBlue); scamDrawable.setColor(AndroidUtilities.getOffsetColor(color1, color2, value, 1.0f)); } color1 = Theme.getColor(Theme.key_actionBarDefaultIcon); color2 = Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2); actionBar.setItemsColor(AndroidUtilities.getOffsetColor(color1, color2, value, 1.0f), false); color1 = Theme.getColor(Theme.key_avatar_actionBarSelectorBlue); color2 = Theme.getColor(Theme.key_actionBarActionModeDefaultSelector); actionBar.setItemsBackgroundColor(AndroidUtilities.getOffsetColor(color1, color2, value, 1.0f), false); topView.invalidate(); otherItem.setIconColor(Theme.getColor(Theme.key_actionBarDefaultIcon)); callItem.setIconColor(Theme.getColor(Theme.key_actionBarDefaultIcon)); editItem.setIconColor(Theme.getColor(Theme.key_actionBarDefaultIcon)); if (verifiedDrawable != null) { color1 = Theme.getColor(Theme.key_profile_verifiedBackground); color2 = Theme.getColor(Theme.key_player_actionBarTitle); verifiedDrawable.setColorFilter(AndroidUtilities.getOffsetColor(color1, color2, value, 1.0f), PorterDuff.Mode.SRC_IN); } if (verifiedCheckDrawable != null) { color1 = Theme.getColor(Theme.key_profile_verifiedCheck); color2 = Theme.getColor(Theme.key_windowBackgroundWhite); verifiedCheckDrawable.setColorFilter(AndroidUtilities.getOffsetColor(color1, color2, value, 1.0f), PorterDuff.Mode.SRC_IN); } } @Override public Float get(ActionBar object) { return mediaHeaderAnimationProgress; } }; private void setMediaHeaderVisible(boolean visible) { if (mediaHeaderVisible == visible) { return; } mediaHeaderVisible = visible; if (headerAnimatorSet != null) { headerAnimatorSet.cancel(); } if (headerShadowAnimatorSet != null) { headerShadowAnimatorSet.cancel(); } ActionBarMenuItem searchItem = sharedMediaLayout.getSearchItem(); if (!mediaHeaderVisible) { if (callItemVisible) { callItem.setVisibility(View.VISIBLE); } if (editItemVisible) { editItem.setVisibility(View.VISIBLE); } otherItem.setVisibility(View.VISIBLE); } else { if (sharedMediaLayout.isSearchItemVisible()) { searchItem.setVisibility(View.VISIBLE); } } ArrayList animators = new ArrayList<>(); animators.add(ObjectAnimator.ofFloat(callItem, View.ALPHA, visible ? 0.0f : 1.0f)); animators.add(ObjectAnimator.ofFloat(otherItem, View.ALPHA, visible ? 0.0f : 1.0f)); animators.add(ObjectAnimator.ofFloat(editItem, View.ALPHA, visible ? 0.0f : 1.0f)); animators.add(ObjectAnimator.ofFloat(callItem, View.TRANSLATION_Y, visible ? -AndroidUtilities.dp(10) : 0.0f)); animators.add(ObjectAnimator.ofFloat(otherItem, View.TRANSLATION_Y, visible ? -AndroidUtilities.dp(10) : 0.0f)); animators.add(ObjectAnimator.ofFloat(editItem, View.TRANSLATION_Y, visible ? -AndroidUtilities.dp(10) : 0.0f)); animators.add(ObjectAnimator.ofFloat(searchItem, View.ALPHA, visible ? 1.0f : 0.0f)); animators.add(ObjectAnimator.ofFloat(searchItem, View.TRANSLATION_Y, visible ? 0.0f : AndroidUtilities.dp(10))); animators.add(ObjectAnimator.ofFloat(actionBar, ACTIONBAR_HEADER_PROGRESS, visible ? 1.0f : 0.0f)); animators.add(ObjectAnimator.ofFloat(onlineTextView[1], View.ALPHA, visible ? 0.0f : 1.0f)); animators.add(ObjectAnimator.ofFloat(onlineTextView[2], View.ALPHA, visible ? 1.0f : 0.0f)); if (visible) { animators.add(ObjectAnimator.ofFloat(this, HEADER_SHADOW, 0.0f)); } headerAnimatorSet = new AnimatorSet(); headerAnimatorSet.playTogether(animators); headerAnimatorSet.setInterpolator(CubicBezierInterpolator.DEFAULT); headerAnimatorSet.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { if (headerAnimatorSet != null) { if (mediaHeaderVisible) { if (callItemVisible) { callItem.setVisibility(View.INVISIBLE); } if (editItemVisible) { editItem.setVisibility(View.INVISIBLE); } otherItem.setVisibility(View.INVISIBLE); } else { if (sharedMediaLayout.isSearchItemVisible()) { searchItem.setVisibility(View.VISIBLE); } headerShadowAnimatorSet = new AnimatorSet(); headerShadowAnimatorSet.playTogether(ObjectAnimator.ofFloat(ProfileActivity.this, HEADER_SHADOW, 1.0f)); headerShadowAnimatorSet.setDuration(100); headerShadowAnimatorSet.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { headerShadowAnimatorSet = null; } }); headerShadowAnimatorSet.start(); } } headerAnimatorSet = null; } @Override public void onAnimationCancel(Animator animation) { headerAnimatorSet = null; } }); headerAnimatorSet.setDuration(150); headerAnimatorSet.start(); } private void openAddMember() { Bundle args = new Bundle(); args.putBoolean("addToGroup", true); args.putInt("chatId", currentChat.id); GroupCreateActivity fragment = new GroupCreateActivity(args); fragment.setInfo(chatInfo); if (chatInfo != null && chatInfo.participants != null) { SparseArray users = new SparseArray<>(); for (int a = 0; a < chatInfo.participants.participants.size(); a++) { users.put(chatInfo.participants.participants.get(a).user_id, null); } fragment.setIgnoreUsers(users); } fragment.setDelegate((users, fwdCount) -> { for (int a = 0, N = users.size(); a < N; a++) { TLRPC.User user = users.get(a); MessagesController.getInstance(currentAccount).addUserToChat(chat_id, user, chatInfo, fwdCount, null, ProfileActivity.this, null); } }); presentFragment(fragment); } private void checkListViewScroll() { if (sharedMediaLayoutAttached) { sharedMediaLayout.setVisibleHeight(listView.getMeasuredHeight() - sharedMediaLayout.getTop()); } if (listView.getChildCount() <= 0 || openAnimationInProgress) { return; } View child = listView.getChildAt(0); RecyclerListView.Holder holder = (RecyclerListView.Holder) listView.findContainingViewHolder(child); int top = child.getTop(); int newOffset = 0; int adapterPosition = holder != null ? holder.getAdapterPosition() : RecyclerView.NO_POSITION; if (top >= 0 && adapterPosition == 0) { newOffset = top; } boolean mediaHeaderVisible; boolean searchVisible = actionBar.isSearchFieldVisible(); if (sharedMediaRow != -1 && !searchVisible) { holder = (RecyclerListView.Holder) listView.findViewHolderForAdapterPosition(sharedMediaRow); mediaHeaderVisible = holder != null && holder.itemView.getTop() <= 0; } else { mediaHeaderVisible = searchVisible; } setMediaHeaderVisible(mediaHeaderVisible); if (extraHeight != newOffset) { extraHeight = newOffset; topView.invalidate(); if (playProfileAnimation != 0) { allowProfileAnimation = extraHeight != 0; } needLayout(); } } private void updateSelectedMediaTabText() { if (sharedMediaLayout == null || onlineTextView[2] == null) { return; } int id = sharedMediaLayout.getSelectedTab(); int[] mediaCount = sharedMediaPreloader.getLastMediaCount(); if (id == 0) { onlineTextView[2].setText(LocaleController.formatPluralString("Media", mediaCount[MediaDataController.MEDIA_PHOTOVIDEO])); } else if (id == 1) { onlineTextView[2].setText(LocaleController.formatPluralString("Files", mediaCount[MediaDataController.MEDIA_FILE])); } else if (id == 2) { onlineTextView[2].setText(LocaleController.formatPluralString("Voice", mediaCount[MediaDataController.MEDIA_AUDIO])); } else if (id == 3) { onlineTextView[2].setText(LocaleController.formatPluralString("Links", mediaCount[MediaDataController.MEDIA_URL])); } else if (id == 4) { onlineTextView[2].setText(LocaleController.formatPluralString("MusicFiles", mediaCount[MediaDataController.MEDIA_MUSIC])); } else if (id == 5) { onlineTextView[2].setText(LocaleController.formatPluralString("GIFs", mediaCount[MediaDataController.MEDIA_GIF])); } else if (id == 6) { onlineTextView[2].setText(LocaleController.formatPluralString("CommonGroups", userInfo.common_chats_count)); } else if (id == 7) { onlineTextView[2].setText(onlineTextView[1].getText()); } } private void needLayout() { final int newTop = (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0) + ActionBar.getCurrentActionBarHeight(); FrameLayout.LayoutParams layoutParams; if (listView != null && !openAnimationInProgress) { layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); if (layoutParams.topMargin != newTop) { layoutParams.topMargin = newTop; listView.setLayoutParams(layoutParams); } } if (avatarImage != null) { final float diff = Math.min(1f, extraHeight / AndroidUtilities.dp(88f)); listView.setTopGlowOffset((int) extraHeight); listView.setOverScrollMode(extraHeight > AndroidUtilities.dp(88f) && extraHeight < listView.getMeasuredWidth() - newTop ? View.OVER_SCROLL_NEVER : View.OVER_SCROLL_ALWAYS); if (writeButton != null) { writeButton.setTranslationY((actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0) + ActionBar.getCurrentActionBarHeight() + extraHeight - AndroidUtilities.dp(29.5f)); if (!openAnimationInProgress) { final boolean setVisible = diff > 0.2f; boolean currentVisible = writeButton.getTag() == null; if (setVisible != currentVisible) { if (setVisible) { writeButton.setTag(null); } else { writeButton.setTag(0); } if (writeButtonAnimation != null) { AnimatorSet old = writeButtonAnimation; writeButtonAnimation = null; old.cancel(); } writeButtonAnimation = new AnimatorSet(); if (setVisible) { writeButtonAnimation.setInterpolator(new DecelerateInterpolator()); writeButtonAnimation.playTogether( ObjectAnimator.ofFloat(writeButton, View.SCALE_X, 1.0f), ObjectAnimator.ofFloat(writeButton, View.SCALE_Y, 1.0f), ObjectAnimator.ofFloat(writeButton, View.ALPHA, 1.0f) ); } else { writeButtonAnimation.setInterpolator(new AccelerateInterpolator()); writeButtonAnimation.playTogether( ObjectAnimator.ofFloat(writeButton, View.SCALE_X, 0.2f), ObjectAnimator.ofFloat(writeButton, View.SCALE_Y, 0.2f), ObjectAnimator.ofFloat(writeButton, View.ALPHA, 0.0f) ); } writeButtonAnimation.setDuration(150); writeButtonAnimation.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { if (writeButtonAnimation != null && writeButtonAnimation.equals(animation)) { writeButtonAnimation = null; } } }); writeButtonAnimation.start(); } } } avatarX = -AndroidUtilities.dpf2(47f) * diff; avatarY = (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0) + ActionBar.getCurrentActionBarHeight() / 2.0f * (1.0f + diff) - 21 * AndroidUtilities.density + 27 * AndroidUtilities.density * diff + actionBar.getTranslationY(); float h = openAnimationInProgress ? initialAnimationExtraHeight : extraHeight; if (h > AndroidUtilities.dp(88f) || isPulledDown) { expandProgress = Math.max(0f, Math.min(1f, (h - AndroidUtilities.dp(88f)) / (listView.getMeasuredWidth() - newTop - AndroidUtilities.dp(88f)))); avatarScale = AndroidUtilities.lerp((42f + 18f) / 42f, (42f + 42f + 18f) / 42f, Math.min(1f, expandProgress * 3f)); final float durationFactor = Math.min(AndroidUtilities.dpf2(2000f), Math.max(AndroidUtilities.dpf2(1100f), Math.abs(listViewVelocityY))) / AndroidUtilities.dpf2(1100f); if (openingAvatar || expandProgress >= 0.33f) { if (!isPulledDown) { if (otherItem != null) { otherItem.showSubItem(gallery_menu_save); } isPulledDown = true; overlaysView.setOverlaysVisible(true, durationFactor); avatarsViewPagerIndicatorView.refreshVisibility(durationFactor); expandAnimator.cancel(); float value = AndroidUtilities.lerp(expandAnimatorValues, currentExpanAnimatorFracture); expandAnimatorValues[0] = value; expandAnimatorValues[1] = 1f; expandAnimator.setDuration((long) ((1f - value) * 250f / durationFactor)); expandAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { avatarImage.setForegroundImage(avatarsViewPager.getImageLocation(0), null, avatarImage.getImageReceiver().getDrawable()); avatarsViewPager.resetCurrentItem(); } @Override public void onAnimationEnd(Animator animation) { expandAnimator.removeListener(this); avatarImage.clearForeground(); topView.setBackgroundColor(Color.BLACK); avatarImage.setVisibility(View.GONE); avatarsViewPager.setVisibility(View.VISIBLE); } }); expandAnimator.start(); } ViewGroup.LayoutParams params = avatarsViewPager.getLayoutParams(); params.width = listView.getMeasuredWidth(); params.height = (int) (h + newTop); avatarsViewPager.requestLayout(); if (!expandAnimator.isRunning()) { float additionalTranslationY = 0; if (openAnimationInProgress && playProfileAnimation == 2) { additionalTranslationY = -(1.0f - animationProgress) * AndroidUtilities.dp(50); } nameTextView[1].setTranslationX(AndroidUtilities.dpf2(16f) - nameTextView[1].getLeft()); nameTextView[1].setTranslationY(newTop + h - AndroidUtilities.dpf2(38f) - nameTextView[1].getBottom() + additionalTranslationY); onlineTextView[1].setTranslationX(AndroidUtilities.dpf2(16f) - onlineTextView[1].getLeft()); onlineTextView[1].setTranslationY(newTop + h - AndroidUtilities.dpf2(18f) - onlineTextView[1].getBottom() + additionalTranslationY); onlineTextView[2].setTranslationX(onlineTextView[1].getTranslationX()); onlineTextView[2].setTranslationY(onlineTextView[1].getTranslationY()); idTextView.setTranslationX(AndroidUtilities.dpf2(16f) - onlineTextView[1].getLeft()); idTextView.setTranslationY(newTop + h - AndroidUtilities.dpf2(3f) - idTextView.getBottom() + additionalTranslationY); } } else { if (isPulledDown) { isPulledDown = false; if (otherItem != null) { otherItem.hideSubItem(gallery_menu_save); } overlaysView.setOverlaysVisible(false, durationFactor); avatarsViewPagerIndicatorView.refreshVisibility(durationFactor); expandAnimator.cancel(); float value = AndroidUtilities.lerp(expandAnimatorValues, currentExpanAnimatorFracture); expandAnimatorValues[0] = value; expandAnimatorValues[1] = 0f; if (!isInLandscapeMode) { expandAnimator.setDuration((long) (value * 250f / durationFactor)); } else { expandAnimator.setDuration(0); } topView.setBackgroundColor(Theme.getColor(Theme.key_avatar_backgroundActionBarBlue)); BackupImageView imageView = avatarsViewPager.getCurrentItemView(); if (imageView != null) { avatarImage.setForegroundImageDrawable(imageView.getImageReceiver().getDrawable()); } avatarImage.setForegroundAlpha(1f); avatarImage.setVisibility(View.VISIBLE); avatarsViewPager.setVisibility(View.GONE); expandAnimator.start(); } avatarImage.setScaleX(avatarScale); avatarImage.setScaleY(avatarScale); if (expandAnimator == null || !expandAnimator.isRunning()) { refreshNameAndOnlineXY(); nameTextView[1].setTranslationX(nameX); nameTextView[1].setTranslationY(nameY); onlineTextView[1].setTranslationX(onlineX); onlineTextView[1].setTranslationY(onlineY); onlineTextView[2].setTranslationX(onlineX); onlineTextView[2].setTranslationY(onlineY); idTextView.setTranslationX(idX); idTextView.setTranslationY(idY); } } } if (openAnimationInProgress && playProfileAnimation == 2) { float avX = 0; float avY = (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0) + ActionBar.getCurrentActionBarHeight() / 2.0f - 21 * AndroidUtilities.density + actionBar.getTranslationY(); nameTextView[0].setTranslationX(0); nameTextView[0].setTranslationY((float) Math.floor(avY) + AndroidUtilities.dp(1.3f)); onlineTextView[0].setTranslationX(0); onlineTextView[0].setTranslationY((float) Math.floor(avY) + AndroidUtilities.dp(24)); nameTextView[0].setScaleX(1.0f); nameTextView[0].setScaleY(1.0f); nameTextView[1].setPivotY(nameTextView[1].getMeasuredHeight()); nameTextView[1].setScaleX(1.67f); nameTextView[1].setScaleY(1.67f); avatarScale = AndroidUtilities.lerp(1.0f, (42f + 42f + 18f) / 42f, animationProgress); avatarImage.setRoundRadius((int) AndroidUtilities.lerp(AndroidUtilities.dpf2(21f), 0f, animationProgress)); avatarImage.setTranslationX(AndroidUtilities.lerp(avX, 0, animationProgress)); avatarImage.setTranslationY(AndroidUtilities.lerp((float) Math.ceil(avY), 0f, animationProgress)); avatarImage.setScaleX(avatarScale); avatarImage.setScaleY(avatarScale); overlaysView.setAlphaValue(animationProgress, false); actionBar.setItemsColor(ColorUtils.blendARGB(Theme.getColor(Theme.key_actionBarDefaultIcon), Color.WHITE, animationProgress), false); if (scamDrawable != null) { scamDrawable.setColor(ColorUtils.blendARGB(Theme.getColor(Theme.key_avatar_subtitleInProfileBlue), Color.argb(179, 255, 255, 255), animationProgress)); } if (lockIconDrawable != null) { lockIconDrawable.setColorFilter(ColorUtils.blendARGB(Theme.getColor(Theme.key_chat_lockIcon), Color.WHITE, animationProgress), PorterDuff.Mode.SRC_IN); } if (verifiedCrossfadeDrawable != null) { verifiedCrossfadeDrawable.setProgress(animationProgress); nameTextView[1].invalidate(); } final FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) avatarImage.getLayoutParams(); params.width = params.height = (int) AndroidUtilities.lerp(AndroidUtilities.dpf2(42f), (extraHeight + newTop) / avatarScale, animationProgress); params.leftMargin = (int) AndroidUtilities.lerp(AndroidUtilities.dpf2(64f), 0f, animationProgress); avatarImage.requestLayout(); } else if (extraHeight <= AndroidUtilities.dp(88f)) { avatarScale = (42 + 18 * diff) / 42.0f; float nameScale = 1.0f + 0.12f * diff; if (expandAnimator == null || !expandAnimator.isRunning()) { avatarImage.setScaleX(avatarScale); avatarImage.setScaleY(avatarScale); avatarImage.setTranslationX(avatarX); avatarImage.setTranslationY((float) Math.ceil(avatarY)); } nameX = -21 * AndroidUtilities.density * diff; nameY = (float) Math.floor(avatarY) + AndroidUtilities.dp(1.3f) + AndroidUtilities.dp(7) * diff; onlineX = -21 * AndroidUtilities.density * diff; onlineY = (float) Math.floor(avatarY) + AndroidUtilities.dp(24) + (float) Math.floor(11 * AndroidUtilities.density) * diff; idX = -21 * AndroidUtilities.density * diff; idY = (float) Math.floor(avatarY) + AndroidUtilities.dp(32) + (float) Math.floor(22 * AndroidUtilities.density) * diff; for (int a = 0; a < nameTextView.length; a++) { if (nameTextView[a] == null) { continue; } if (expandAnimator == null || !expandAnimator.isRunning()) { nameTextView[a].setTranslationX(nameX); nameTextView[a].setTranslationY(nameY); onlineTextView[a].setTranslationX(onlineX); onlineTextView[a].setTranslationY(onlineY); idTextView.setTranslationX(idX); idTextView.setTranslationY(idY); if (a == 1) { onlineTextView[2].setTranslationX(onlineX); onlineTextView[2].setTranslationY(onlineY); } } nameTextView[a].setScaleX(nameScale); nameTextView[a].setScaleY(nameScale); } if (diff > 0.85 && NekoConfig.showIdAndDc) { idTextView.setVisibility(View.VISIBLE); } else { idTextView.setVisibility(View.GONE); } } if (!openAnimationInProgress && (expandAnimator == null || !expandAnimator.isRunning())) { needLayoutText(diff); } } if (isPulledDown || overlaysView.animator != null && overlaysView.animator.isRunning()) { final ViewGroup.LayoutParams overlaysLp = overlaysView.getLayoutParams(); overlaysLp.width = listView.getMeasuredWidth(); overlaysLp.height = (int) (extraHeight + newTop); overlaysView.requestLayout(); } } private void refreshNameAndOnlineXY() { nameX = AndroidUtilities.dp(-21f) + avatarImage.getMeasuredWidth() * (avatarScale - (42f + 18f) / 42f); nameY = (float) Math.floor(avatarY) + AndroidUtilities.dp(1.3f) + AndroidUtilities.dp(7f) + avatarImage.getMeasuredHeight() * (avatarScale - (42f + 18f) / 42f) / 2f; onlineX = AndroidUtilities.dp(-21f) + avatarImage.getMeasuredWidth() * (avatarScale - (42f + 18f) / 42f); onlineY = (float) Math.floor(avatarY) + AndroidUtilities.dp(24) + (float) Math.floor(11 * AndroidUtilities.density) + avatarImage.getMeasuredHeight() * (avatarScale - (42f + 18f) / 42f) / 2f; idX = AndroidUtilities.dp(-21f) + avatarImage.getMeasuredWidth() * (avatarScale - (42f + 18f) / 42f); idY = (float) Math.floor(avatarY) + AndroidUtilities.dp(32) + (float) Math.floor(22 * AndroidUtilities.density) + avatarImage.getMeasuredHeight() * (avatarScale - (42f + 18f) / 42f) / 2f; } public RecyclerListView getListView() { return listView; } private void needLayoutText(float diff) { FrameLayout.LayoutParams layoutParams; float scale = nameTextView[1].getScaleX(); float maxScale = extraHeight > AndroidUtilities.dp(88f) ? 1.67f : 1.12f; if (extraHeight > AndroidUtilities.dp(88f) && scale != maxScale) { return; } int viewWidth = AndroidUtilities.isTablet() ? AndroidUtilities.dp(490) : AndroidUtilities.displaySize.x; int buttonsWidth = AndroidUtilities.dp(118 + 8 + (40 + (callItemVisible || editItemVisible ? 48 : 0))); int minWidth = viewWidth - buttonsWidth; int width = (int) (viewWidth - buttonsWidth * Math.max(0.0f, 1.0f - (diff != 1.0f ? diff * 0.15f / (1.0f - diff) : 1.0f)) - nameTextView[1].getTranslationX()); float width2 = nameTextView[1].getPaint().measureText(nameTextView[1].getText().toString()) * scale + nameTextView[1].getSideDrawablesSize(); layoutParams = (FrameLayout.LayoutParams) nameTextView[1].getLayoutParams(); int prevWidth = layoutParams.width; if (width < width2) { layoutParams.width = Math.max(minWidth, (int) Math.ceil((width - AndroidUtilities.dp(24)) / (scale + ((maxScale - scale) * 7.0f)))); } else { layoutParams.width = (int) Math.ceil(width2); } layoutParams.width = (int) Math.min((viewWidth - nameTextView[1].getX()) / scale - AndroidUtilities.dp(8), layoutParams.width); if (layoutParams.width != prevWidth) { nameTextView[1].requestLayout(); } width2 = onlineTextView[1].getPaint().measureText(onlineTextView[1].getText().toString()); layoutParams = (FrameLayout.LayoutParams) onlineTextView[1].getLayoutParams(); FrameLayout.LayoutParams layoutParams2 = (FrameLayout.LayoutParams) onlineTextView[2].getLayoutParams(); prevWidth = layoutParams.width; layoutParams2.rightMargin = layoutParams.rightMargin = (int) Math.ceil(onlineTextView[1].getTranslationX() + AndroidUtilities.dp(8) + AndroidUtilities.dp(40) * (1.0f - diff)); if (width < width2) { layoutParams2.width = layoutParams.width = (int) Math.ceil(width); } else { layoutParams2.width = layoutParams.width = LayoutHelper.WRAP_CONTENT; } if (prevWidth != layoutParams.width) { onlineTextView[1].requestLayout(); onlineTextView[2].requestLayout(); } width2 = idTextView.getPaint().measureText(idTextView.getText().toString()); layoutParams = (FrameLayout.LayoutParams) idTextView.getLayoutParams(); prevWidth = layoutParams.width; layoutParams.rightMargin = (int) Math.ceil(idTextView.getTranslationX() + AndroidUtilities.dp(8) + AndroidUtilities.dp(40) * (1.0f - diff)); if (width < width2) { layoutParams.width = (int) Math.ceil(width); } else { layoutParams.width = LayoutHelper.WRAP_CONTENT; } if (prevWidth != layoutParams.width) { idTextView.requestLayout(); } } private void fixLayout() { if (fragmentView == null) { return; } fragmentView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { if (fragmentView != null) { checkListViewScroll(); needLayout(); fragmentView.getViewTreeObserver().removeOnPreDrawListener(this); } return true; } }); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); if (sharedMediaLayout != null) { sharedMediaLayout.onConfigurationChanged(newConfig); } invalidateIsInLandscapeMode(); if (isInLandscapeMode && isPulledDown) { final View view = layoutManager.findViewByPosition(0); if (view != null) { listView.scrollBy(0, view.getTop() - AndroidUtilities.dp(88)); } } fixLayout(); } private void invalidateIsInLandscapeMode() { final Point size = new Point(); final Display display = getParentActivity().getWindowManager().getDefaultDisplay(); display.getSize(size); isInLandscapeMode = size.x > size.y; } @SuppressWarnings("unchecked") @Override public void didReceivedNotification(int id, int account, final Object... args) { if (id == NotificationCenter.updateInterfaces) { int mask = (Integer) args[0]; boolean infoChanged = (mask & MessagesController.UPDATE_MASK_AVATAR) != 0 || (mask & MessagesController.UPDATE_MASK_NAME) != 0 || (mask & MessagesController.UPDATE_MASK_STATUS) != 0; if (user_id != 0) { if (infoChanged) { updateProfileData(); } if ((mask & MessagesController.UPDATE_MASK_PHONE) != 0) { if (listView != null) { RecyclerListView.Holder holder = (RecyclerListView.Holder) listView.findViewHolderForPosition(phoneRow); if (holder != null) { listAdapter.onBindViewHolder(holder, phoneRow); } } } } else if (chat_id != 0) { if ((mask & MessagesController.UPDATE_MASK_CHAT) != 0 || (mask & MessagesController.UPDATE_MASK_CHAT_AVATAR) != 0 || (mask & MessagesController.UPDATE_MASK_CHAT_NAME) != 0 || (mask & MessagesController.UPDATE_MASK_CHAT_MEMBERS) != 0 || (mask & MessagesController.UPDATE_MASK_STATUS) != 0) { updateOnlineCount(); updateProfileData(); } if ((mask & MessagesController.UPDATE_MASK_CHAT) != 0) { updateRowsIds(); if (listAdapter != null) { listAdapter.notifyDataSetChanged(); } } if (infoChanged) { 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(mask); } } } } } } else if (id == NotificationCenter.chatOnlineCountDidLoad) { Integer chatId = (Integer) args[0]; if (chatInfo == null || currentChat == null || currentChat.id != chatId) { return; } chatInfo.online_count = (Integer) args[1]; updateOnlineCount(); updateProfileData(); } else if (id == NotificationCenter.contactsDidLoad) { createActionBarMenu(); } else if (id == NotificationCenter.encryptedChatCreated) { if (creatingChat) { AndroidUtilities.runOnUIThread(() -> { NotificationCenter.getInstance(currentAccount).removeObserver(ProfileActivity.this, NotificationCenter.closeChats); NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.closeChats); TLRPC.EncryptedChat encryptedChat = (TLRPC.EncryptedChat) args[0]; Bundle args2 = new Bundle(); args2.putInt("enc_id", encryptedChat.id); if (MessagesController.getInstance(currentAccount).checkCanOpenChat(args2, ProfileActivity.this)) { presentFragment(new ChatActivity(args2), true); } }); } } else if (id == NotificationCenter.encryptedChatUpdated) { TLRPC.EncryptedChat chat = (TLRPC.EncryptedChat) args[0]; if (currentEncryptedChat != null && chat.id == currentEncryptedChat.id) { currentEncryptedChat = chat; updateRowsIds(); if (listAdapter != null) { listAdapter.notifyDataSetChanged(); } } } else if (id == NotificationCenter.blockedUsersDidLoad) { boolean oldValue = userBlocked; userBlocked = MessagesController.getInstance(currentAccount).blockedUsers.indexOfKey(user_id) >= 0; if (oldValue != userBlocked) { createActionBarMenu(); updateRowsIds(); listAdapter.notifyDataSetChanged(); } } else if (id == NotificationCenter.chatInfoDidLoad) { TLRPC.ChatFull chatFull = (TLRPC.ChatFull) args[0]; if (chatFull.id == chat_id) { boolean byChannelUsers = (Boolean) args[2]; if (chatInfo instanceof TLRPC.TL_channelFull) { if (chatFull.participants == null && chatInfo != null) { chatFull.participants = chatInfo.participants; } } boolean loadChannelParticipants = chatInfo == null && chatFull instanceof TLRPC.TL_channelFull; chatInfo = chatFull; if (mergeDialogId == 0 && chatInfo.migrated_from_chat_id != 0) { mergeDialogId = -chatInfo.migrated_from_chat_id; MediaDataController.getInstance(currentAccount).getMediaCount(mergeDialogId, MediaDataController.MEDIA_PHOTOVIDEO, classGuid, true); } fetchUsersFromChannelInfo(); updateOnlineCount(); updateRowsIds(); if (listAdapter != null) { listAdapter.notifyDataSetChanged(); } TLRPC.Chat newChat = MessagesController.getInstance(currentAccount).getChat(chat_id); if (newChat != null) { currentChat = newChat; createActionBarMenu(); } if (currentChat.megagroup && (loadChannelParticipants || !byChannelUsers)) { getChannelParticipants(true); } } } else if (id == NotificationCenter.closeChats) { removeSelfFromStack(); } else if (id == NotificationCenter.botInfoDidLoad) { TLRPC.BotInfo info = (TLRPC.BotInfo) args[0]; if (info.user_id == user_id) { botInfo = info; updateRowsIds(); if (listAdapter != null) { listAdapter.notifyDataSetChanged(); } } } else if (id == NotificationCenter.userInfoDidLoad) { int uid = (Integer) args[0]; if (uid == user_id) { userInfo = (TLRPC.UserFull) args[1]; if (!openAnimationInProgress && !callItemVisible) { createActionBarMenu(); } else { recreateMenuAfterAnimation = true; } updateRowsIds(); if (listAdapter != null) { try { listAdapter.notifyDataSetChanged(); } catch (Exception e) { FileLog.e(e); } } if (sharedMediaLayout != null) { sharedMediaLayout.setCommonGroupsCount(userInfo.common_chats_count); } updateSelectedMediaTabText(); } } else if (id == NotificationCenter.didReceiveNewMessages) { boolean scheduled = (Boolean) args[2]; if (scheduled) { return; } long did = getDialogId(); if (did == (Long) args[0]) { boolean enc = ((int) did) == 0; ArrayList arr = (ArrayList) args[1]; for (int a = 0; a < arr.size(); a++) { MessageObject obj = arr.get(a); if (currentEncryptedChat != null && obj.messageOwner.action instanceof TLRPC.TL_messageEncryptedAction && obj.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL) { TLRPC.TL_decryptedMessageActionSetMessageTTL action = (TLRPC.TL_decryptedMessageActionSetMessageTTL) obj.messageOwner.action.encryptedAction; if (listAdapter != null) { listAdapter.notifyDataSetChanged(); } } } } } else if (id == NotificationCenter.emojiDidLoad) { if (listView != null) { listView.invalidateViews(); } } } @Override public void mediaCountUpdated() { if (sharedMediaLayout != null && sharedMediaPreloader != null) { sharedMediaLayout.setNewMediaCounts(sharedMediaPreloader.getLastMediaCount()); } updateSharedMediaRows(); updateSelectedMediaTabText(); } @Override public void onResume() { super.onResume(); if (sharedMediaLayout != null) { sharedMediaLayout.onResume(); } invalidateIsInLandscapeMode(); if (listAdapter != null) { listAdapter.notifyDataSetChanged(); } updateProfileData(); fixLayout(); if (nameTextView[1] != null) { setParentActivityTitle(nameTextView[1].getText()); } } @Override public void onPause() { super.onPause(); if (undoView != null) { undoView.hide(true, 0); } } @Override public boolean isSwipeBackEnabled(MotionEvent event) { if (sharedMediaRow == -1 || sharedMediaLayout == null) { return true; } sharedMediaLayout.getHitRect(rect); if (!rect.contains((int) event.getX(), (int) event.getY() - actionBar.getMeasuredHeight())) { return true; } return sharedMediaLayout.isCurrentTabFirst(); } public boolean onBackPressed() { return actionBar.isEnabled() && (sharedMediaRow == -1 || sharedMediaLayout == null || !sharedMediaLayout.closeActionMode()); } @Override protected void onBecomeFullyHidden() { if (undoView != null) { undoView.hide(true, 0); } } public void setPlayProfileAnimation(int type) { SharedPreferences preferences = MessagesController.getGlobalMainSettings(); if (!AndroidUtilities.isTablet()) { if (preferences.getBoolean("view_animations", true)) { playProfileAnimation = type; } else if (type == 2) { expandPhoto = true; } } } private void updateSharedMediaRows() { if (listAdapter == null) { return; } int sharedMediaRowPrev = sharedMediaRow; updateRowsIds(); if (sharedMediaRowPrev != sharedMediaRow) { listAdapter.notifyDataSetChanged(); } } @Override protected void onTransitionAnimationStart(boolean isOpen, boolean backward) { if ((!isOpen && backward || isOpen && !backward) && playProfileAnimation != 0 && allowProfileAnimation && !isPulledDown) { openAnimationInProgress = true; } if (isOpen) { transitionIndex = NotificationCenter.getInstance(currentAccount).setAnimationInProgress(transitionIndex, new int[]{NotificationCenter.dialogsNeedReload, NotificationCenter.closeChats, NotificationCenter.mediaCountDidLoad, NotificationCenter.mediaCountsDidLoad}); } } @Override protected void onTransitionAnimationEnd(boolean isOpen, boolean backward) { if (isOpen) { if (!backward) { if (playProfileAnimation != 0 && allowProfileAnimation) { openAnimationInProgress = false; if (recreateMenuAfterAnimation) { createActionBarMenu(); } } } NotificationCenter.getInstance(currentAccount).onAnimationFinish(transitionIndex); } } @Keep public float getAnimationProgress() { return animationProgress; } @Keep public void setAnimationProgress(float progress) { animationProgress = progress; listView.setAlpha(progress); listView.setTranslationX(AndroidUtilities.dp(48) - AndroidUtilities.dp(48) * progress); int color; if (playProfileAnimation == 2 && avatarColor != 0) { color = avatarColor; } else { color = AvatarDrawable.getProfileBackColorForId(user_id != 0 || ChatObject.isChannel(chat_id, currentAccount) && !currentChat.megagroup ? 5 : chat_id); } int actionBarColor = Theme.getColor(Theme.key_actionBarDefault); int r = Color.red(actionBarColor); int g = Color.green(actionBarColor); int b = Color.blue(actionBarColor); int a; int rD = (int) ((Color.red(color) - r) * progress); int gD = (int) ((Color.green(color) - g) * progress); int bD = (int) ((Color.blue(color) - b) * progress); int aD; topView.setBackgroundColor(Color.rgb(r + rD, g + gD, b + bD)); color = AvatarDrawable.getIconColorForId(user_id != 0 || ChatObject.isChannel(chat_id, currentAccount) && !currentChat.megagroup ? 5 : chat_id); int iconColor = Theme.getColor(Theme.key_actionBarDefaultIcon); r = Color.red(iconColor); g = Color.green(iconColor); b = Color.blue(iconColor); rD = (int) ((Color.red(color) - r) * progress); gD = (int) ((Color.green(color) - g) * progress); bD = (int) ((Color.blue(color) - b) * progress); actionBar.setItemsColor(Color.rgb(r + rD, g + gD, b + bD), false); color = Theme.getColor(Theme.key_profile_title); int titleColor = Theme.getColor(Theme.key_actionBarDefaultTitle); r = Color.red(titleColor); g = Color.green(titleColor); b = Color.blue(titleColor); a = Color.alpha(titleColor); rD = (int) ((Color.red(color) - r) * progress); gD = (int) ((Color.green(color) - g) * progress); bD = (int) ((Color.blue(color) - b) * progress); aD = (int) ((Color.alpha(color) - a) * progress); for (int i = 0; i < 2; i++) { if (nameTextView[i] == null || i == 1 && playProfileAnimation == 2) { continue; } nameTextView[i].setTextColor(Color.argb(a + aD, r + rD, g + gD, b + bD)); } color = isOnline[0] ? Theme.getColor(Theme.key_profile_status) : AvatarDrawable.getProfileTextColorForId(user_id != 0 || ChatObject.isChannel(chat_id, currentAccount) && !currentChat.megagroup ? 5 : chat_id); int subtitleColor = Theme.getColor(isOnline[0] ? Theme.key_chat_status : Theme.key_actionBarDefaultSubtitle); r = Color.red(subtitleColor); g = Color.green(subtitleColor); b = Color.blue(subtitleColor); a = Color.alpha(subtitleColor); rD = (int) ((Color.red(color) - r) * progress); gD = (int) ((Color.green(color) - g) * progress); bD = (int) ((Color.blue(color) - b) * progress); aD = (int) ((Color.alpha(color) - a) * progress); for (int i = 0; i < 2; i++) { if (onlineTextView[i] == null || i == 1 && playProfileAnimation == 2) { continue; } onlineTextView[i].setTextColor(Color.argb(a + aD, r + rD, g + gD, b + bD)); } extraHeight = initialAnimationExtraHeight * progress; color = AvatarDrawable.getProfileColorForId(user_id != 0 ? user_id : chat_id); int color2 = AvatarDrawable.getColorForId(user_id != 0 ? user_id : chat_id); if (color != color2) { rD = (int) ((Color.red(color) - Color.red(color2)) * progress); gD = (int) ((Color.green(color) - Color.green(color2)) * progress); bD = (int) ((Color.blue(color) - Color.blue(color2)) * progress); avatarDrawable.setColor(Color.rgb(Color.red(color2) + rD, Color.green(color2) + gD, Color.blue(color2) + bD)); avatarImage.invalidate(); } topView.invalidate(); needLayout(); } @Override protected AnimatorSet onCustomTransitionAnimation(final boolean isOpen, final Runnable callback) { if (playProfileAnimation != 0 && allowProfileAnimation && !isPulledDown) { final AnimatorSet animatorSet = new AnimatorSet(); animatorSet.setDuration(playProfileAnimation == 2 ? 250 : 180); listView.setLayerType(View.LAYER_TYPE_HARDWARE, null); ActionBarMenu menu = actionBar.createMenu(); if (menu.getItem(10) == null) { if (animatingItem == null) { animatingItem = menu.addItem(10, R.drawable.ic_ab_other); } } if (isOpen) { FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) onlineTextView[1].getLayoutParams(); layoutParams.rightMargin = (int) (-21 * AndroidUtilities.density + AndroidUtilities.dp(8)); onlineTextView[1].setLayoutParams(layoutParams); if (playProfileAnimation != 2) { int width = (int) Math.ceil(AndroidUtilities.displaySize.x - AndroidUtilities.dp(118 + 8) + 21 * AndroidUtilities.density); float width2 = nameTextView[1].getPaint().measureText(nameTextView[1].getText().toString()) * 1.12f + nameTextView[1].getSideDrawablesSize(); layoutParams = (FrameLayout.LayoutParams) nameTextView[1].getLayoutParams(); if (width < width2) { layoutParams.width = (int) Math.ceil(width / 1.12f); } else { layoutParams.width = LayoutHelper.WRAP_CONTENT; } nameTextView[1].setLayoutParams(layoutParams); initialAnimationExtraHeight = AndroidUtilities.dp(88f); } else { layoutParams = (FrameLayout.LayoutParams) nameTextView[1].getLayoutParams(); layoutParams.width = (int) ((AndroidUtilities.displaySize.x - AndroidUtilities.dp(32)) / 1.67f); nameTextView[1].setLayoutParams(layoutParams); } fragmentView.setBackgroundColor(0); setAnimationProgress(0); ArrayList animators = new ArrayList<>(); animators.add(ObjectAnimator.ofFloat(this, "animationProgress", 0.0f, 1.0f)); if (writeButton != null) { writeButton.setScaleX(0.2f); writeButton.setScaleY(0.2f); writeButton.setAlpha(0.0f); animators.add(ObjectAnimator.ofFloat(writeButton, View.SCALE_X, 1.0f)); animators.add(ObjectAnimator.ofFloat(writeButton, View.SCALE_Y, 1.0f)); animators.add(ObjectAnimator.ofFloat(writeButton, View.ALPHA, 1.0f)); } if (playProfileAnimation == 2) { avatarColor = AndroidUtilities.calcBitmapColor(avatarImage.getImageReceiver().getBitmap()); nameTextView[1].setTextColor(Color.WHITE); onlineTextView[1].setTextColor(Color.argb(179, 255, 255, 255)); idTextView.setTextColor(Color.argb(179, 255, 255, 255)); actionBar.setItemsBackgroundColor(Theme.ACTION_BAR_WHITE_SELECTOR_COLOR, false); overlaysView.setOverlaysVisible(); } for (int a = 0; a < 2; a++) { onlineTextView[a].setAlpha(a == 0 ? 1.0f : 0.0f); nameTextView[a].setAlpha(a == 0 ? 1.0f : 0.0f); animators.add(ObjectAnimator.ofFloat(onlineTextView[a], View.ALPHA, a == 0 ? 0.0f : 1.0f)); animators.add(ObjectAnimator.ofFloat(nameTextView[a], View.ALPHA, a == 0 ? 0.0f : 1.0f)); } if (animatingItem != null) { animatingItem.setAlpha(1.0f); animators.add(ObjectAnimator.ofFloat(animatingItem, View.ALPHA, 0.0f)); } if (callItemVisible) { callItem.setAlpha(0.0f); animators.add(ObjectAnimator.ofFloat(callItem, View.ALPHA, 1.0f)); } if (editItemVisible) { editItem.setAlpha(0.0f); animators.add(ObjectAnimator.ofFloat(editItem, View.ALPHA, 1.0f)); } animatorSet.playTogether(animators); } else { initialAnimationExtraHeight = extraHeight; ArrayList animators = new ArrayList<>(); animators.add(ObjectAnimator.ofFloat(this, "animationProgress", 1.0f, 0.0f)); if (writeButton != null) { animators.add(ObjectAnimator.ofFloat(writeButton, View.SCALE_X, 0.2f)); animators.add(ObjectAnimator.ofFloat(writeButton, View.SCALE_Y, 0.2f)); animators.add(ObjectAnimator.ofFloat(writeButton, View.ALPHA, 0.0f)); } for (int a = 0; a < 2; a++) { animators.add(ObjectAnimator.ofFloat(onlineTextView[a], View.ALPHA, a == 0 ? 1.0f : 0.0f)); animators.add(ObjectAnimator.ofFloat(nameTextView[a], View.ALPHA, a == 0 ? 1.0f : 0.0f)); } if (animatingItem != null) { animatingItem.setAlpha(0.0f); animators.add(ObjectAnimator.ofFloat(animatingItem, View.ALPHA, 1.0f)); } if (callItemVisible) { callItem.setAlpha(1.0f); animators.add(ObjectAnimator.ofFloat(callItem, View.ALPHA, 0.0f)); } if (editItemVisible) { editItem.setAlpha(1.0f); animators.add(ObjectAnimator.ofFloat(editItem, View.ALPHA, 0.0f)); } animatorSet.playTogether(animators); } animatorSet.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { listView.setLayerType(View.LAYER_TYPE_NONE, null); if (animatingItem != null) { ActionBarMenu menu = actionBar.createMenu(); menu.clearItems(); animatingItem = null; } callback.run(); if (playProfileAnimation == 2) { playProfileAnimation = 1; avatarImage.setForegroundAlpha(1.0f); avatarImage.setVisibility(View.GONE); avatarsViewPager.resetCurrentItem(); avatarsViewPager.setVisibility(View.VISIBLE); } } }); animatorSet.setInterpolator(playProfileAnimation == 2 ? CubicBezierInterpolator.DEFAULT : new DecelerateInterpolator()); AndroidUtilities.runOnUIThread(animatorSet::start, 50); return animatorSet; } return null; } private void updateOnlineCount() { onlineCount = 0; int currentTime = ConnectionsManager.getInstance(currentAccount).getCurrentTime(); sortedUsers.clear(); if (chatInfo instanceof TLRPC.TL_chatFull || chatInfo instanceof TLRPC.TL_channelFull && chatInfo.participants_count <= 200 && chatInfo.participants != null) { for (int a = 0; a < chatInfo.participants.participants.size(); a++) { TLRPC.ChatParticipant participant = chatInfo.participants.participants.get(a); TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(participant.user_id); if (user != null && user.status != null && (user.status.expires > currentTime || user.id == UserConfig.getInstance(currentAccount).getClientUserId()) && user.status.expires > 10000) { onlineCount++; } sortedUsers.add(a); } try { Collections.sort(sortedUsers, (lhs, rhs) -> { TLRPC.User user1 = MessagesController.getInstance(currentAccount).getUser(chatInfo.participants.participants.get(rhs).user_id); TLRPC.User user2 = MessagesController.getInstance(currentAccount).getUser(chatInfo.participants.participants.get(lhs).user_id); int status1 = 0; int status2 = 0; if (user1 != null) { if (user1.bot) { status1 = -110; } else if (user1.self) { status1 = currentTime + 50000; } else if (user1.status != null) { status1 = user1.status.expires; } } if (user2 != null) { if (user2.bot) { status2 = -110; } else if (user2.self) { status2 = currentTime + 50000; } else if (user2.status != null) { status2 = user2.status.expires; } } if (status1 > 0 && status2 > 0) { if (status1 > status2) { return 1; } else if (status1 < status2) { return -1; } return 0; } else if (status1 < 0 && status2 < 0) { if (status1 > status2) { return 1; } else if (status1 < status2) { return -1; } return 0; } else if (status1 < 0 && status2 > 0 || status1 == 0 && status2 != 0) { return -1; } else if (status2 < 0 && status1 > 0 || status2 == 0 && status1 != 0) { return 1; } return 0; }); } catch (Exception e) { FileLog.e(e); } if (listAdapter != null && membersStartRow > 0) { listAdapter.notifyItemRangeChanged(membersStartRow, sortedUsers.size()); } if (sharedMediaLayout != null && sharedMediaRow != -1 && sortedUsers.size() > 5) { sharedMediaLayout.setChatUsers(sortedUsers, chatInfo); } } else if (chatInfo instanceof TLRPC.TL_channelFull && chatInfo.participants_count > 200) { onlineCount = chatInfo.online_count; } } public void setChatInfo(TLRPC.ChatFull value) { chatInfo = value; if (chatInfo != null && chatInfo.migrated_from_chat_id != 0 && mergeDialogId == 0) { mergeDialogId = -chatInfo.migrated_from_chat_id; MediaDataController.getInstance(currentAccount).getMediaCounts(mergeDialogId, classGuid); } if (sharedMediaLayout != null) { sharedMediaLayout.setChatInfo(chatInfo); } fetchUsersFromChannelInfo(); } public void setUserInfo(TLRPC.UserFull value) { userInfo = value; } public boolean canSearchMembers() { return canSearchMembers; } private void fetchUsersFromChannelInfo() { if (currentChat == null || !currentChat.megagroup) { return; } if (chatInfo instanceof TLRPC.TL_channelFull && chatInfo.participants != null) { for (int a = 0; a < chatInfo.participants.participants.size(); a++) { TLRPC.ChatParticipant chatParticipant = chatInfo.participants.participants.get(a); participantsMap.put(chatParticipant.user_id, chatParticipant); } } } private void kickUser(int uid) { if (uid != 0) { MessagesController.getInstance(currentAccount).deleteUserFromChat(chat_id, MessagesController.getInstance(currentAccount).getUser(uid), chatInfo); } else { NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.closeChats); if (AndroidUtilities.isTablet()) { NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.closeChats, -(long) chat_id); } else { NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.closeChats); } MessagesController.getInstance(currentAccount).deleteUserFromChat(chat_id, MessagesController.getInstance(currentAccount).getUser(UserConfig.getInstance(currentAccount).getClientUserId()), chatInfo); playProfileAnimation = 0; finishFragment(); } } public boolean isChat() { return chat_id != 0; } private void updateRowsIds() { int prevRowsCount = rowCount; rowCount = 0; sendMessageRow = -1; reportRow = -1; emptyRow = -1; infoHeaderRow = -1; phoneRow = -1; userInfoRow = -1; locationRow = -1; channelInfoRow = -1; usernameRow = -1; settingsTimerRow = -1; settingsKeyRow = -1; notificationsDividerRow = -1; notificationsRow = -1; infoSectionRow = -1; settingsSectionRow = -1; bottomPaddingRow = -1; membersHeaderRow = -1; membersStartRow = -1; membersEndRow = -1; addMemberRow = -1; subscribersRow = -1; administratorsRow = -1; blockedUsersRow = -1; membersSectionRow = -1; sharedMediaRow = -1; unblockRow = -1; joinRow = -1; lastSectionRow = -1; boolean hasMedia = false; if (sharedMediaPreloader != null) { int[] lastMediaCount = sharedMediaPreloader.getLastMediaCount(); for (int a = 0; a < lastMediaCount.length; a++) { if (lastMediaCount[a] > 0) { hasMedia = true; break; } } } if (user_id != 0 && LocaleController.isRTL) { emptyRow = rowCount++; } if (user_id != 0) { TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(user_id); boolean hasInfo = userInfo != null && !TextUtils.isEmpty(userInfo.about) || user != null && !TextUtils.isEmpty(user.username); boolean hasPhone = user != null && !TextUtils.isEmpty(user.phone); infoHeaderRow = rowCount++; if (!isBot && (hasPhone || !hasPhone && !hasInfo)) { phoneRow = rowCount++; } if (userInfo != null && !TextUtils.isEmpty(userInfo.about)) { userInfoRow = rowCount++; } if (user != null && !TextUtils.isEmpty(user.username)) { usernameRow = rowCount++; } if (phoneRow != -1 || userInfoRow != -1 || usernameRow != -1) { notificationsDividerRow = rowCount++; } if (user_id != UserConfig.getInstance(currentAccount).getClientUserId()) { notificationsRow = rowCount++; } infoSectionRow = rowCount++; if (currentEncryptedChat instanceof TLRPC.TL_encryptedChat) { settingsTimerRow = rowCount++; settingsKeyRow = rowCount++; settingsSectionRow = rowCount++; } if (user != null && !isBot && currentEncryptedChat == null && user.id != UserConfig.getInstance(currentAccount).getClientUserId()) { if (userBlocked) { unblockRow = rowCount++; lastSectionRow = rowCount++; } } if (hasMedia || userInfo != null && userInfo.common_chats_count != 0) { sharedMediaRow = rowCount++; } else if (lastSectionRow == -1 && needSendMessage) { sendMessageRow = rowCount++; reportRow = rowCount++; lastSectionRow = rowCount++; } } else if (chat_id != 0) { if (chatInfo != null && (!TextUtils.isEmpty(chatInfo.about) || chatInfo.location instanceof TLRPC.TL_channelLocation) || !TextUtils.isEmpty(currentChat.username)) { infoHeaderRow = rowCount++; if (chatInfo != null) { if (!TextUtils.isEmpty(chatInfo.about)) { channelInfoRow = rowCount++; } if (chatInfo.location instanceof TLRPC.TL_channelLocation) { locationRow = rowCount++; } } if (!TextUtils.isEmpty(currentChat.username)) { usernameRow = rowCount++; } } if (infoHeaderRow != -1) { notificationsDividerRow = rowCount++; } notificationsRow = rowCount++; infoSectionRow = rowCount++; if (ChatObject.isChannel(currentChat) && !currentChat.megagroup) { if (chatInfo != null && (currentChat.creator || chatInfo.can_view_participants)) { membersHeaderRow = rowCount++; subscribersRow = rowCount++; administratorsRow = rowCount++; if (chatInfo.banned_count != 0 || chatInfo.kicked_count != 0) { blockedUsersRow = rowCount++; } membersSectionRow = rowCount++; } } if (ChatObject.isChannel(currentChat)) { if (chatInfo != null && currentChat.megagroup && chatInfo.participants != null && !chatInfo.participants.participants.isEmpty()) { if (!ChatObject.isNotInChat(currentChat) && currentChat.megagroup && ChatObject.canAddUsers(currentChat) && (chatInfo == null || chatInfo.participants_count < MessagesController.getInstance(currentAccount).maxMegagroupCount)) { addMemberRow = rowCount++; } int count = chatInfo.participants.participants.size(); if (count <= 5 || !hasMedia) { if (addMemberRow == -1) { membersHeaderRow = rowCount++; } membersStartRow = rowCount; rowCount += chatInfo.participants.participants.size(); membersEndRow = rowCount; membersSectionRow = rowCount++; if (sharedMediaLayout != null) { sharedMediaLayout.setChatUsers(null, null); } } else { if (addMemberRow != -1) { membersSectionRow = rowCount++; } if (sharedMediaLayout != null) { sharedMediaLayout.setChatUsers(sortedUsers, chatInfo); } } } if (lastSectionRow == -1 && currentChat.left && !currentChat.kicked) { joinRow = rowCount++; lastSectionRow = rowCount++; } } else if (chatInfo != null) { if (!(chatInfo.participants instanceof TLRPC.TL_chatParticipantsForbidden)) { if (ChatObject.canAddUsers(currentChat) || currentChat.default_banned_rights == null || !currentChat.default_banned_rights.invite_users) { addMemberRow = rowCount++; } int count = chatInfo.participants.participants.size(); if (count <= 5 || !hasMedia) { if (addMemberRow == -1) { membersHeaderRow = rowCount++; } membersStartRow = rowCount; rowCount += chatInfo.participants.participants.size(); membersEndRow = rowCount; membersSectionRow = rowCount++; if (sharedMediaLayout != null) { sharedMediaLayout.setChatUsers(null, null); } } else { if (addMemberRow != -1) { membersSectionRow = rowCount++; } if (sharedMediaLayout != null) { sharedMediaLayout.setChatUsers(sortedUsers, chatInfo); } } } } if (hasMedia) { sharedMediaRow = rowCount++; } } if (sharedMediaRow == -1) { bottomPaddingRow = rowCount++; } final int actionBarHeight = actionBar != null ? ActionBar.getCurrentActionBarHeight() + (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0) : 0; if (listView == null || prevRowsCount > rowCount || listContentHeight != 0 && listContentHeight + actionBarHeight + AndroidUtilities.dp(88) < listView.getMeasuredHeight()) { lastMeasuredContentWidth = 0; } } private Drawable getScamDrawable() { if (scamDrawable == null) { scamDrawable = new ScamDrawable(11); scamDrawable.setColor(Theme.getColor(Theme.key_avatar_subtitleInProfileBlue)); } return scamDrawable; } private Drawable getLockIconDrawable() { if (lockIconDrawable == null) { lockIconDrawable = Theme.chat_lockIconDrawable.getConstantState().newDrawable().mutate(); } return lockIconDrawable; } private Drawable getVerifiedCrossfadeDrawable() { if (verifiedCrossfadeDrawable == null) { verifiedDrawable = Theme.profile_verifiedDrawable.getConstantState().newDrawable().mutate(); verifiedCheckDrawable = Theme.profile_verifiedCheckDrawable.getConstantState().newDrawable().mutate(); verifiedCrossfadeDrawable = new CrossfadeDrawable(new CombinedDrawable(verifiedDrawable, verifiedCheckDrawable), ContextCompat.getDrawable(getParentActivity(), R.drawable.verified_profile)); } return verifiedCrossfadeDrawable; } private void updateProfileData() { if (avatarImage == null || nameTextView == null) { return; } String onlineTextOverride; int currentConnectionState = ConnectionsManager.getInstance(currentAccount).getConnectionState(); if (currentConnectionState == ConnectionsManager.ConnectionStateWaitingForNetwork) { onlineTextOverride = LocaleController.getString("WaitingForNetwork", R.string.WaitingForNetwork); } else if (currentConnectionState == ConnectionsManager.ConnectionStateConnecting) { onlineTextOverride = LocaleController.getString("Connecting", R.string.Connecting); } else if (currentConnectionState == ConnectionsManager.ConnectionStateUpdating) { onlineTextOverride = LocaleController.getString("Updating", R.string.Updating); } else if (currentConnectionState == ConnectionsManager.ConnectionStateConnectingToProxy) { onlineTextOverride = LocaleController.getString("ConnectingToProxy", R.string.ConnectingToProxy); } else { onlineTextOverride = null; } int id = 0; if (user_id != 0) { TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(user_id); TLRPC.FileLocation photoBig = null; if (user.photo != null) { photoBig = user.photo.photo_big; } avatarDrawable.setInfo(user); final ImageLocation imageLocation = ImageLocation.getForUser(user, true); final ImageLocation thumbLocation = ImageLocation.getForUser(user, false); avatarsViewPager.initIfEmpty(imageLocation, thumbLocation); avatarImage.setImage(thumbLocation, "50_50", avatarDrawable, user); FileLoader.getInstance(currentAccount).loadFile(imageLocation, user, null, 0, 1); String newString = UserObject.getUserName(user); String newString2; if (user.id == UserConfig.getInstance(currentAccount).getClientUserId()) { newString2 = LocaleController.getString("ChatYourSelf", R.string.ChatYourSelf); newString = LocaleController.getString("ChatYourSelfName", R.string.ChatYourSelfName); } else if (user.id == 333000 || user.id == 777000 || user.id == 42777) { newString2 = LocaleController.getString("ServiceNotifications", R.string.ServiceNotifications); } else if (MessagesController.isSupportUser(user)) { newString2 = LocaleController.getString("SupportStatus", R.string.SupportStatus); } else if (isBot) { newString2 = LocaleController.getString("Bot", R.string.Bot); } else { isOnline[0] = false; newString2 = LocaleController.formatUserStatus(currentAccount, user, isOnline); if (onlineTextView[1] != null && !mediaHeaderVisible) { String key = isOnline[0] ? Theme.key_profile_status : Theme.key_avatar_subtitleInProfileBlue; onlineTextView[1].setTag(key); if (!isPulledDown) { onlineTextView[1].setTextColor(Theme.getColor(key)); } } } for (int a = 0; a < 2; a++) { if (nameTextView[a] == null) { continue; } if (!nameTextView[a].getText().equals(newString)) { nameTextView[a].setText(newString); } if (a == 0 && onlineTextOverride != null) { onlineTextView[a].setText(onlineTextOverride); } else { onlineTextView[a].setText(newString2); } Drawable leftIcon = currentEncryptedChat != null ? getLockIconDrawable() : null; Drawable rightIcon = null; if (a == 0) { if (user.scam) { rightIcon = getScamDrawable(); } else { rightIcon = MessagesController.getInstance(currentAccount).isDialogMuted(dialog_id != 0 ? dialog_id : (long) user_id) ? Theme.chat_muteIconDrawable : null; } } else if (user.scam) { rightIcon = getScamDrawable(); } else if (user.verified) { rightIcon = getVerifiedCrossfadeDrawable(); } nameTextView[a].setLeftDrawable(leftIcon); nameTextView[a].setRightDrawable(rightIcon); } if (user.photo != null && user.photo.dc_id != 0) { idTextView.setText("ID: " + user_id + ", DC: " + user.photo.dc_id); } else { idTextView.setText("ID: " + user_id); } id = user_id; avatarImage.getImageReceiver().setVisible(!PhotoViewer.isShowingImage(photoBig), false); } else if (chat_id != 0) { TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(chat_id); if (chat != null) { currentChat = chat; } else { chat = currentChat; } String statusString; String profileStatusString; if (ChatObject.isChannel(chat)) { if (chatInfo == null || !currentChat.megagroup && (chatInfo.participants_count == 0 || ChatObject.hasAdminRights(currentChat) || chatInfo.can_view_participants)) { if (currentChat.megagroup) { statusString = profileStatusString = LocaleController.getString("Loading", R.string.Loading).toLowerCase(); } else { if ((chat.flags & TLRPC.CHAT_FLAG_IS_PUBLIC) != 0) { statusString = profileStatusString = LocaleController.getString("ChannelPublic", R.string.ChannelPublic).toLowerCase(); } else { statusString = profileStatusString = LocaleController.getString("ChannelPrivate", R.string.ChannelPrivate).toLowerCase(); } } } else { if (currentChat.megagroup) { if (onlineCount > 1 && chatInfo.participants_count != 0) { statusString = String.format("%s, %s", LocaleController.formatPluralString("Members", chatInfo.participants_count), LocaleController.formatPluralString("OnlineCount", Math.min(onlineCount, chatInfo.participants_count))); profileStatusString = String.format("%s, %s", LocaleController.formatPluralStringComma("Members", chatInfo.participants_count), LocaleController.formatPluralStringComma("OnlineCount", Math.min(onlineCount, chatInfo.participants_count))); } else { if (chatInfo.participants_count == 0) { if (chat.has_geo) { statusString = profileStatusString = LocaleController.getString("MegaLocation", R.string.MegaLocation).toLowerCase(); } else if (!TextUtils.isEmpty(chat.username)) { statusString = profileStatusString = LocaleController.getString("MegaPublic", R.string.MegaPublic).toLowerCase(); } else { statusString = profileStatusString = LocaleController.getString("MegaPrivate", R.string.MegaPrivate).toLowerCase(); } } else { statusString = LocaleController.formatPluralString("Members", chatInfo.participants_count); profileStatusString = LocaleController.formatPluralStringComma("Members", chatInfo.participants_count); } } } else { int[] result = new int[1]; String shortNumber = LocaleController.formatShortNumber(chatInfo.participants_count, result); if (currentChat.megagroup) { statusString = LocaleController.formatPluralString("Members", chatInfo.participants_count); profileStatusString = LocaleController.formatPluralStringComma("Members", chatInfo.participants_count); } else { statusString = LocaleController.formatPluralString("Subscribers", chatInfo.participants_count); profileStatusString = LocaleController.formatPluralStringComma("Subscribers", chatInfo.participants_count); } } } } else { if (ChatObject.isKickedFromChat(chat)) { statusString = profileStatusString = LocaleController.getString("YouWereKicked", R.string.YouWereKicked); } else if (ChatObject.isLeftFromChat(chat)) { statusString = profileStatusString = LocaleController.getString("YouLeft", R.string.YouLeft); } else { int count = chat.participants_count; if (chatInfo != null) { count = chatInfo.participants.participants.size(); } if (count != 0 && onlineCount > 1) { statusString = profileStatusString = String.format("%s, %s", LocaleController.formatPluralString("Members", count), LocaleController.formatPluralString("OnlineCount", onlineCount)); } else { statusString = profileStatusString = LocaleController.formatPluralString("Members", count); } } } boolean changed = false; for (int a = 0; a < 2; a++) { if (nameTextView[a] == null) { continue; } if (chat.title != null) { if (nameTextView[a].setText(chat.title)) { changed = true; } } nameTextView[a].setLeftDrawable(null); if (a != 0) { if (chat.scam) { nameTextView[a].setRightDrawable(getScamDrawable()); } else if (chat.verified) { nameTextView[a].setRightDrawable(getVerifiedCrossfadeDrawable()); } else { nameTextView[a].setRightDrawable(null); } } else { if (chat.scam) { nameTextView[a].setRightDrawable(getScamDrawable()); } else { nameTextView[a].setRightDrawable(MessagesController.getInstance(currentAccount).isDialogMuted(-chat_id) ? Theme.chat_muteIconDrawable : null); } } if (a == 0 && onlineTextOverride != null) { onlineTextView[a].setText(onlineTextOverride); } else { if (currentChat.megagroup && chatInfo != null && onlineCount > 0) { onlineTextView[a].setText(a == 0 ? statusString : profileStatusString); } else if (a == 0 && ChatObject.isChannel(currentChat) && chatInfo != null && chatInfo.participants_count != 0 && (currentChat.megagroup || currentChat.broadcast)) { int[] result = new int[1]; String shortNumber = LocaleController.formatShortNumber(chatInfo.participants_count, result); if (currentChat.megagroup) { if (chatInfo.participants_count == 0) { if (chat.has_geo) { onlineTextView[a].setText(LocaleController.getString("MegaLocation", R.string.MegaLocation).toLowerCase()); } else if (!TextUtils.isEmpty(chat.username)) { onlineTextView[a].setText(LocaleController.getString("MegaPublic", R.string.MegaPublic).toLowerCase()); } else { onlineTextView[a].setText(LocaleController.getString("MegaPrivate", R.string.MegaPrivate).toLowerCase()); } } else { onlineTextView[a].setText(LocaleController.formatPluralString("Members", result[0]).replace(String.format("%d", result[0]), shortNumber)); } } else { onlineTextView[a].setText(LocaleController.formatPluralString("Subscribers", result[0]).replace(String.format("%d", result[0]), shortNumber)); } } else { onlineTextView[a].setText(a == 0 ? statusString : profileStatusString); } } } id = chat_id; if (changed) { needLayout(); } TLRPC.FileLocation photoBig = null; if (chat.photo != null) { photoBig = chat.photo.photo_big; } avatarDrawable.setInfo(chat); final ImageLocation imageLocation = ImageLocation.getForChat(chat, true); final ImageLocation thumbLocation = ImageLocation.getForChat(chat, false); avatarsViewPager.initIfEmpty(imageLocation, thumbLocation); avatarImage.setImage(thumbLocation, "50_50", avatarDrawable, chat); FileLoader.getInstance(currentAccount).loadFile(imageLocation, chat, null, 0, 1); avatarImage.getImageReceiver().setVisible(!PhotoViewer.isShowingImage(photoBig), false); if (chat.photo != null && chat.photo.dc_id != 0) { idTextView.setText("ID: " + chat_id + ", DC: " + chat.photo.dc_id); } else { idTextView.setText("ID: " + chat_id); } } if (id != 0) { int finalId = id; idTextView.setOnLongClickListener(v -> { AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); builder.setItems(new CharSequence[]{LocaleController.getString("Copy", R.string.Copy)}, (dialogInterface, i) -> { if (i == 0) { try { AndroidUtilities.addToClipboard(String.valueOf(finalId)); Toast.makeText(getParentActivity(), LocaleController.getString("TextCopied", R.string.TextCopied), Toast.LENGTH_SHORT).show(); } catch (Exception e) { FileLog.e(e); } } }); showDialog(builder.create()); return false; }); } } private void createActionBarMenu() { if (actionBar == null || otherItem == null) { return; } ActionBarMenu menu = actionBar.createMenu(); otherItem.removeAllSubItems(); animatingItem = null; editItemVisible = false; callItemVisible = false; canSearchMembers = false; if (user_id != 0) { TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(user_id); if (UserConfig.getInstance(currentAccount).getClientUserId() != user_id) { if (user == null) { return; } if (userInfo != null && userInfo.phone_calls_available) { callItemVisible = true; } if (isBot || ContactsController.getInstance(currentAccount).contactsDict.get(user_id) == null) { if (MessagesController.isSupportUser(user)) { if (userBlocked) { otherItem.addSubItem(block_contact, R.drawable.baseline_block_24, LocaleController.getString("Unblock", R.string.Unblock)); } } else { if (isBot) { if (!user.bot_nochats) { otherItem.addSubItem(invite_to_group, R.drawable.baseline_group_add_24, LocaleController.getString("BotInvite", R.string.BotInvite)); } otherItem.addSubItem(share, R.drawable.baseline_forward_24, LocaleController.getString("BotShare", R.string.BotShare)); otherItem.addSubItem(qr_code, R.drawable.wallet_qr, LocaleController.getString("ShareQRCode", R.string.ShareQRCode)); } else { otherItem.addSubItem(add_contact, R.drawable.baseline_person_add_24, LocaleController.getString("AddContact", R.string.AddContact)); } if (!TextUtils.isEmpty(user.phone)) { otherItem.addSubItem(share_contact, R.drawable.baseline_forward_24, LocaleController.getString("ShareContact", R.string.ShareContact)); } if (isBot) { otherItem.addSubItem(block_contact, !userBlocked ? R.drawable.baseline_block_24 : R.drawable.baseline_replay_24, !userBlocked ? LocaleController.getString("BotStop", R.string.BotStop) : LocaleController.getString("BotRestart", R.string.BotRestart)); } else { otherItem.addSubItem(block_contact, !userBlocked ? R.drawable.baseline_block_24 : R.drawable.baseline_block_24, !userBlocked ? LocaleController.getString("BlockContact", R.string.BlockContact) : LocaleController.getString("Unblock", R.string.Unblock)); } } } else { if (!TextUtils.isEmpty(user.phone)) { otherItem.addSubItem(share_contact, R.drawable.baseline_forward_24, LocaleController.getString("ShareContact", R.string.ShareContact)); } otherItem.addSubItem(block_contact, !userBlocked ? R.drawable.baseline_block_24 : R.drawable.baseline_block_24, !userBlocked ? LocaleController.getString("BlockContact", R.string.BlockContact) : LocaleController.getString("Unblock", R.string.Unblock)); otherItem.addSubItem(edit_contact, R.drawable.baseline_edit_24, LocaleController.getString("EditContact", R.string.EditContact)); otherItem.addSubItem(delete_contact, R.drawable.baseline_delete_24, LocaleController.getString("DeleteContact", R.string.DeleteContact)); } } else { otherItem.addSubItem(share_contact, R.drawable.baseline_forward_24, LocaleController.getString("ShareContact", R.string.ShareContact)); } if (!UserObject.isDeleted(user) && !isBot && currentEncryptedChat == null && user_id != getUserConfig().getClientUserId() && !userBlocked && user_id != 333000 && user_id != 777000 && user_id != 42777) { otherItem.addSubItem(start_secret_chat, R.drawable.deproko_baseline_lock_24, LocaleController.getString("StartEncryptedChat", R.string.StartEncryptedChat)); } } else if (chat_id != 0) { if (chat_id > 0) { TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(chat_id); if (ChatObject.isChannel(chat)) { if (ChatObject.hasAdminRights(chat) || chat.megagroup) { editItemVisible = true; } if (!chat.megagroup && chatInfo != null && chatInfo.can_view_stats) { otherItem.addSubItem(statistics, R.drawable.msg_stats, LocaleController.getString("Statistics", R.string.Statistics)); } if (!TextUtils.isEmpty(chat.username)) { otherItem.addSubItem(share, R.drawable.baseline_forward_24, LocaleController.getString("BotShare", R.string.BotShare)); otherItem.addSubItem(qr_code, R.drawable.wallet_qr, LocaleController.getString("ShareQRCode", R.string.ShareQRCode)); } if (chat.megagroup) { canSearchMembers = true; otherItem.addSubItem(search_members, R.drawable.baseline_search_24, LocaleController.getString("SearchMembers", R.string.SearchMembers)); if (!chat.creator && !chat.left && !chat.kicked) { otherItem.addSubItem(leave_group, R.drawable.baseline_exit_to_app_24, LocaleController.getString("LeaveMegaMenu", R.string.LeaveMegaMenu)); } } else { if (!currentChat.creator && !currentChat.left && !currentChat.kicked) { otherItem.addSubItem(leave_group, R.drawable.baseline_exit_to_app_24, LocaleController.getString("LeaveChannelMenu", R.string.LeaveChannelMenu)); } } if (ChatObject.hasAdminRights(currentChat)) { otherItem.addSubItem(event_log, R.drawable.group_log, LocaleController.getString("EventLog", R.string.EventLog)); } } else { editItemVisible = true; if (!ChatObject.isKickedFromChat(chat) && !ChatObject.isLeftFromChat(chat)) { canSearchMembers = true; otherItem.addSubItem(search_members, R.drawable.baseline_search_24, LocaleController.getString("SearchMembers", R.string.SearchMembers)); } otherItem.addSubItem(leave_group, R.drawable.baseline_exit_to_app_24, LocaleController.getString("DeleteAndExit", R.string.DeleteAndExit)); } } } otherItem.addSubItem(add_shortcut, R.drawable.baseline_home_24, LocaleController.getString("AddShortcut", R.string.AddShortcut)); otherItem.addSubItem(gallery_menu_save, R.drawable.baseline_image_24, LocaleController.getString("SaveToGallery", R.string.SaveToGallery)); if (!isPulledDown) { otherItem.hideSubItem(gallery_menu_save); } otherItem.setContentDescription(LocaleController.getString("AccDescrMoreOptions", R.string.AccDescrMoreOptions)); if (callItemVisible) { if (callItem.getVisibility() != View.VISIBLE) { callItem.setVisibility(View.VISIBLE); } } else { if (callItem.getVisibility() != View.GONE) { callItem.setVisibility(View.GONE); } } if (editItemVisible) { if (editItem.getVisibility() != View.VISIBLE) { editItem.setVisibility(View.VISIBLE); } } else { if (editItem.getVisibility() != View.GONE) { editItem.setVisibility(View.GONE); } } if (editItem != null) { editItem.setContentDescription(LocaleController.getString("Edit", R.string.Edit)); } if (callItem != null) { callItem.setContentDescription(LocaleController.getString("Call", R.string.Call)); } if (avatarsViewPagerIndicatorView != null) { if (avatarsViewPagerIndicatorView.isIndicatorFullyVisible()) { if (editItemVisible) { editItem.setVisibility(View.GONE); } if (callItemVisible) { callItem.setVisibility(View.GONE); } } } } @Override protected void onDialogDismiss(Dialog dialog) { if (listView != null) { listView.invalidateViews(); } } @Override public void didSelectDialogs(DialogsActivity fragment, ArrayList dids, CharSequence message, boolean param) { long did = dids.get(0); Bundle args = new Bundle(); args.putBoolean("scrollToTopOnResume", true); int lower_part = (int) did; if (lower_part != 0) { if (lower_part > 0) { args.putInt("user_id", lower_part); } else if (lower_part < 0) { args.putInt("chat_id", -lower_part); } } else { args.putInt("enc_id", (int) (did >> 32)); } if (!MessagesController.getInstance(currentAccount).checkCanOpenChat(args, fragment)) { return; } NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.closeChats); NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.closeChats); presentFragment(new ChatActivity(args), true); removeSelfFromStack(); TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(user_id); SendMessagesHelper.getInstance(currentAccount).sendMessage(user, did, null, null, null, true, 0); } @Override public void onRequestPermissionsResultFragment(int requestCode, String[] permissions, int[] grantResults) { if (requestCode == 101) { final TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(user_id); if (user == null) { return; } if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { VoIPHelper.startCall(user, getParentActivity(), userInfo); } else { VoIPHelper.permissionDenied(getParentActivity(), null); } } } private class ListAdapter extends RecyclerListView.SelectionAdapter { private Context mContext; public ListAdapter(Context context) { mContext = context; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = null; switch (viewType) { case 1: { view = new HeaderCell(mContext, 23); break; } case 2: { view = new TextDetailCell(mContext); break; } case 3: { view = new AboutLinkCell(mContext, ProfileActivity.this) { @Override protected void didPressUrl(String url) { if (url.startsWith("@")) { MessagesController.getInstance(currentAccount).openByUserName(url.substring(1), ProfileActivity.this, 0); } else if (url.startsWith("#")) { DialogsActivity fragment = new DialogsActivity(null); fragment.setSearchString(url); presentFragment(fragment); } else if (url.startsWith("/")) { if (parentLayout.fragmentsStack.size() > 1) { BaseFragment previousFragment = parentLayout.fragmentsStack.get(parentLayout.fragmentsStack.size() - 2); if (previousFragment instanceof ChatActivity) { finishFragment(); ((ChatActivity) previousFragment).chatActivityEnterView.setCommand(null, url, false, false); } } } } }; break; } case 4: { view = new TextCell(mContext); break; } case 5: { view = new DividerCell(mContext); view.setPadding(AndroidUtilities.dp(20), AndroidUtilities.dp(4), 0, 0); break; } case 6: { view = new NotificationsCheckCell(mContext, 23, 70, false); break; } case 7: { view = new ShadowSectionCell(mContext); break; } case 8: { view = new UserCell(mContext, addMemberRow == -1 ? 9 : 6, 0, true); break; } case 11: { view = new View(mContext) { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(32), MeasureSpec.EXACTLY)); } }; break; } case 12: { view = new View(mContext) { private int lastPaddingHeight = 0; private int lastListViewHeight = 0; @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (lastListViewHeight != listView.getMeasuredHeight()) { lastPaddingHeight = 0; } lastListViewHeight = listView.getMeasuredHeight(); int n = listView.getChildCount(); if (n == listAdapter.getItemCount()) { int totalHeight = 0; for (int i = 0; i < n; i++) { View view = listView.getChildAt(i); if (listView.getChildAdapterPosition(view) != bottomPaddingRow) { totalHeight += listView.getChildAt(i).getMeasuredHeight(); } } int paddingHeight = fragmentView.getMeasuredHeight() - ActionBar.getCurrentActionBarHeight() - AndroidUtilities.statusBarHeight - totalHeight; if (paddingHeight > AndroidUtilities.dp(88)) { paddingHeight = 0; } if (paddingHeight <= 0) { paddingHeight = 0; } setMeasuredDimension(listView.getMeasuredWidth(), lastPaddingHeight = paddingHeight); } else { setMeasuredDimension(listView.getMeasuredWidth(), lastPaddingHeight); } } }; break; } case 13: { if (sharedMediaLayout.getParent() != null) { ((ViewGroup) sharedMediaLayout.getParent()).removeView(sharedMediaLayout); } view = sharedMediaLayout; break; } } if (viewType != 13) { view.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT)); } return new RecyclerListView.Holder(view); } @Override public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) { if (holder.itemView == sharedMediaLayout) { sharedMediaLayoutAttached = true; } } @Override public void onViewDetachedFromWindow(RecyclerView.ViewHolder holder) { if (holder.itemView == sharedMediaLayout) { sharedMediaLayoutAttached = false; } } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { switch (holder.getItemViewType()) { case 1: HeaderCell headerCell = (HeaderCell) holder.itemView; if (position == infoHeaderRow) { if (ChatObject.isChannel(currentChat) && !currentChat.megagroup && channelInfoRow != -1) { headerCell.setText(LocaleController.getString("ReportChatDescription", R.string.ReportChatDescription)); } else { headerCell.setText(LocaleController.getString("Info", R.string.Info)); } } else if (position == membersHeaderRow) { headerCell.setText(LocaleController.getString("ChannelMembers", R.string.ChannelMembers)); } break; case 2: TextDetailCell detailCell = (TextDetailCell) holder.itemView; if (position == phoneRow) { String text; final TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(user_id); if (!TextUtils.isEmpty(user.phone) && !(NekoConfig.hidePhone && user.id == UserConfig.getInstance(currentAccount).getClientUserId())) { text = PhoneFormat.getInstance().format("+" + user.phone); } else { text = LocaleController.getString("PhoneHidden", R.string.PhoneHidden); } detailCell.setTextAndValue(text, LocaleController.getString("PhoneMobile", R.string.PhoneMobile), false); } else if (position == usernameRow) { String text; if (user_id != 0) { final TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(user_id); if (user != null && !TextUtils.isEmpty(user.username)) { text = "@" + user.username; } else { text = "-"; } detailCell.setTextAndValue(text, LocaleController.getString("Username", R.string.Username), false); } else if (currentChat != null) { TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(chat_id); detailCell.setTextAndValue(MessagesController.getInstance(currentAccount).linkPrefix + "/" + chat.username, LocaleController.getString("InviteLink", R.string.InviteLink), false); } } else if (position == locationRow) { if (chatInfo != null && chatInfo.location instanceof TLRPC.TL_channelLocation) { TLRPC.TL_channelLocation location = (TLRPC.TL_channelLocation) chatInfo.location; detailCell.setTextAndValue(location.address, LocaleController.getString("AttachLocation", R.string.AttachLocation), false); } } break; case 3: AboutLinkCell aboutLinkCell = (AboutLinkCell) holder.itemView; if (position == userInfoRow) { aboutLinkCell.setTextAndValue(userInfo.about, LocaleController.getString("UserBio", R.string.UserBio), true); } else if (position == channelInfoRow) { String text = chatInfo.about; while (text.contains("\n\n\n")) { text = text.replace("\n\n\n", "\n\n"); } aboutLinkCell.setText(text, true); } break; case 4: TextCell textCell = (TextCell) holder.itemView; textCell.setColors(Theme.key_windowBackgroundWhiteGrayIcon, Theme.key_windowBackgroundWhiteBlackText); textCell.setTag(Theme.key_windowBackgroundWhiteBlackText); if (position == settingsTimerRow) { TLRPC.EncryptedChat encryptedChat = MessagesController.getInstance(currentAccount).getEncryptedChat((int) (dialog_id >> 32)); String value; if (encryptedChat.ttl == 0) { value = LocaleController.getString("ShortMessageLifetimeForever", R.string.ShortMessageLifetimeForever); } else { value = LocaleController.formatTTLString(encryptedChat.ttl); } textCell.setTextAndValue(LocaleController.getString("MessageLifetime", R.string.MessageLifetime), value, false); } else if (position == unblockRow) { textCell.setText(LocaleController.getString("Unblock", R.string.Unblock), false); textCell.setColors(null, Theme.key_windowBackgroundWhiteRedText5); } else if (position == settingsKeyRow) { IdenticonDrawable identiconDrawable = new IdenticonDrawable(); TLRPC.EncryptedChat encryptedChat = MessagesController.getInstance(currentAccount).getEncryptedChat((int) (dialog_id >> 32)); identiconDrawable.setEncryptedChat(encryptedChat); textCell.setTextAndValueDrawable(LocaleController.getString("EncryptionKey", R.string.EncryptionKey), identiconDrawable, false); } else if (position == joinRow) { textCell.setColors(null, Theme.key_windowBackgroundWhiteBlueText2); textCell.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlueText2)); if (currentChat.megagroup) { textCell.setText(LocaleController.getString("ProfileJoinGroup", R.string.ProfileJoinGroup), false); } else { textCell.setText(LocaleController.getString("ProfileJoinChannel", R.string.ProfileJoinChannel), false); } } else if (position == subscribersRow) { if (chatInfo != null) { if (ChatObject.isChannel(currentChat) && !currentChat.megagroup) { textCell.setTextAndValueAndIcon(LocaleController.getString("ChannelSubscribers", R.string.ChannelSubscribers), String.format("%d", chatInfo.participants_count), R.drawable.baseline_group_24, position != membersSectionRow - 1); } else { textCell.setTextAndValueAndIcon(LocaleController.getString("ChannelMembers", R.string.ChannelMembers), String.format("%d", chatInfo.participants_count), R.drawable.baseline_group_24, position != membersSectionRow - 1); } } else { if (ChatObject.isChannel(currentChat) && !currentChat.megagroup) { textCell.setTextAndIcon(LocaleController.getString("ChannelSubscribers", R.string.ChannelSubscribers), R.drawable.baseline_group_24, position != membersSectionRow - 1); } else { textCell.setTextAndIcon(LocaleController.getString("ChannelMembers", R.string.ChannelMembers), R.drawable.baseline_group_24, position != membersSectionRow - 1); } } } else if (position == administratorsRow) { if (chatInfo != null) { textCell.setTextAndValueAndIcon(LocaleController.getString("ChannelAdministrators", R.string.ChannelAdministrators), String.format("%d", chatInfo.admins_count), R.drawable.baseline_stars_18, position != membersSectionRow - 1); } else { textCell.setTextAndIcon(LocaleController.getString("ChannelAdministrators", R.string.ChannelAdministrators), R.drawable.baseline_stars_18, position != membersSectionRow - 1); } } else if (position == blockedUsersRow) { if (chatInfo != null) { textCell.setTextAndValueAndIcon(LocaleController.getString("ChannelBlacklist", R.string.ChannelBlacklist), String.format("%d", Math.max(chatInfo.banned_count, chatInfo.kicked_count)), R.drawable.actions_removed, position != membersSectionRow - 1); } else { textCell.setTextAndIcon(LocaleController.getString("ChannelBlacklist", R.string.ChannelBlacklist), R.drawable.actions_removed, position != membersSectionRow - 1); } } else if (position == addMemberRow) { textCell.setColors(Theme.key_windowBackgroundWhiteBlueIcon, Theme.key_windowBackgroundWhiteBlueButton); textCell.setTextAndIcon(LocaleController.getString("AddMember", R.string.AddMember), R.drawable.baseline_person_add_24, membersSectionRow == -1); } else if (position == sendMessageRow) { textCell.setText(LocaleController.getString("SendMessageLocation", R.string.SendMessageLocation), true); } else if (position == reportRow) { textCell.setText(LocaleController.getString("ReportUserLocation", R.string.ReportUserLocation), false); textCell.setColors(null, Theme.key_windowBackgroundWhiteRedText5); } break; case 6: NotificationsCheckCell checkCell = (NotificationsCheckCell) holder.itemView; if (position == notificationsRow) { SharedPreferences preferences = MessagesController.getNotificationsSettings(currentAccount); long did; if (dialog_id != 0) { did = dialog_id; } else if (user_id != 0) { did = user_id; } else { did = -chat_id; } boolean enabled = false; boolean custom = preferences.getBoolean("custom_" + did, false); boolean hasOverride = preferences.contains("notify2_" + did); int value = preferences.getInt("notify2_" + did, 0); int delta = preferences.getInt("notifyuntil_" + did, 0); String val; if (value == 3 && delta != Integer.MAX_VALUE) { delta -= ConnectionsManager.getInstance(currentAccount).getCurrentTime(); if (delta <= 0) { if (custom) { val = LocaleController.getString("NotificationsCustom", R.string.NotificationsCustom); } else { val = LocaleController.getString("NotificationsOn", R.string.NotificationsOn); } enabled = true; } else if (delta < 60 * 60) { val = LocaleController.formatString("WillUnmuteIn", R.string.WillUnmuteIn, LocaleController.formatPluralString("Minutes", delta / 60)); } else if (delta < 60 * 60 * 24) { val = LocaleController.formatString("WillUnmuteIn", R.string.WillUnmuteIn, LocaleController.formatPluralString("Hours", (int) Math.ceil(delta / 60.0f / 60))); } else if (delta < 60 * 60 * 24 * 365) { val = LocaleController.formatString("WillUnmuteIn", R.string.WillUnmuteIn, LocaleController.formatPluralString("Days", (int) Math.ceil(delta / 60.0f / 60 / 24))); } else { val = null; } } else { if (value == 0) { if (hasOverride) { enabled = true; } else { enabled = NotificationsController.getInstance(currentAccount).isGlobalNotificationsEnabled(did); } } else if (value == 1) { enabled = true; } else if (value == 2) { enabled = false; } else { enabled = false; } if (enabled && custom) { val = LocaleController.getString("NotificationsCustom", R.string.NotificationsCustom); } else { val = enabled ? LocaleController.getString("NotificationsOn", R.string.NotificationsOn) : LocaleController.getString("NotificationsOff", R.string.NotificationsOff); } } if (val == null) { val = LocaleController.getString("NotificationsOff", R.string.NotificationsOff); } checkCell.setTextAndValueAndCheck(LocaleController.getString("Notifications", R.string.Notifications), val, enabled, false); } break; case 7: View sectionCell = holder.itemView; sectionCell.setTag(position); Drawable drawable; if (position == infoSectionRow && lastSectionRow == -1 && settingsSectionRow == -1 && sharedMediaRow == -1 && membersSectionRow == -1 || position == settingsSectionRow || position == lastSectionRow || position == membersSectionRow && lastSectionRow == -1 && sharedMediaRow == -1) { drawable = Theme.getThemedDrawable(mContext, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow); } else { drawable = Theme.getThemedDrawable(mContext, R.drawable.greydivider, Theme.key_windowBackgroundGrayShadow); } CombinedDrawable combinedDrawable = new CombinedDrawable(new ColorDrawable(Theme.getColor(Theme.key_windowBackgroundGray)), drawable); combinedDrawable.setFullsize(true); sectionCell.setBackgroundDrawable(combinedDrawable); break; case 8: UserCell userCell = (UserCell) holder.itemView; TLRPC.ChatParticipant part; if (!sortedUsers.isEmpty()) { part = chatInfo.participants.participants.get(sortedUsers.get(position - membersStartRow)); } else { part = chatInfo.participants.participants.get(position - membersStartRow); } if (part != null) { String role; if (part instanceof TLRPC.TL_chatChannelParticipant) { TLRPC.ChannelParticipant channelParticipant = ((TLRPC.TL_chatChannelParticipant) part).channelParticipant; if (!TextUtils.isEmpty(channelParticipant.rank)) { role = channelParticipant.rank; } else { if (channelParticipant instanceof TLRPC.TL_channelParticipantCreator) { role = LocaleController.getString("ChannelCreator", R.string.ChannelCreator); } else if (channelParticipant instanceof TLRPC.TL_channelParticipantAdmin) { role = LocaleController.getString("ChannelAdmin", R.string.ChannelAdmin); } else { role = null; } } } else { if (part instanceof TLRPC.TL_chatParticipantCreator) { role = LocaleController.getString("ChannelCreator", R.string.ChannelCreator); } else if (part instanceof TLRPC.TL_chatParticipantAdmin) { role = LocaleController.getString("ChannelAdmin", R.string.ChannelAdmin); } else { role = null; } } userCell.setAdminRole(role); userCell.setData(MessagesController.getInstance(currentAccount).getUser(part.user_id), null, null, 0, position != membersEndRow - 1); } break; } } @Override public boolean isEnabled(RecyclerView.ViewHolder holder) { int type = holder.getItemViewType(); return type != 1 && type != 5 && type != 7 && type != 9 && type != 10 && type != 11 && type != 12 && type != 13; } @Override public int getItemCount() { return rowCount; } @Override public int getItemViewType(int i) { if (i == infoHeaderRow || i == membersHeaderRow) { return 1; } else if (i == phoneRow || i == usernameRow || i == locationRow) { return 2; } else if (i == userInfoRow || i == channelInfoRow) { return 3; } else if (i == settingsTimerRow || i == settingsKeyRow || i == reportRow || i == subscribersRow || i == administratorsRow || i == blockedUsersRow || i == addMemberRow || i == joinRow || i == unblockRow || i == sendMessageRow) { return 4; } else if (i == notificationsDividerRow) { return 5; } else if (i == notificationsRow) { return 6; } else if (i == infoSectionRow || i == lastSectionRow || i == membersSectionRow || i == settingsSectionRow) { return 7; } else if (i >= membersStartRow && i < membersEndRow) { return 8; } else if (i == emptyRow) { return 11; } else if (i == bottomPaddingRow) { return 12; } else if (i == sharedMediaRow) { return 13; } return 0; } } @Override public ArrayList getThemeDescriptions() { ThemeDescription.ThemeDescriptionDelegate themeDelegate = () -> { 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); } } } if (!isPulledDown) { final Object onlineTextViewTag = onlineTextView[1].getTag(); if (onlineTextViewTag instanceof String) { onlineTextView[1].setTextColor(Theme.getColor((String) onlineTextViewTag)); } if (lockIconDrawable != null) { lockIconDrawable.setColorFilter(Theme.getColor(Theme.key_chat_lockIcon), PorterDuff.Mode.SRC_IN); } if (scamDrawable != null) { scamDrawable.setColor(Theme.getColor(Theme.key_avatar_subtitleInProfileBlue)); } nameTextView[1].setBackgroundColor(Theme.getColor(Theme.key_avatar_backgroundActionBarBlue)); nameTextView[1].setTextColor(Theme.getColor(Theme.key_profile_title)); idTextView.setTextColor(Theme.getColor(Theme.key_avatar_subtitleInProfileBlue)); actionBar.setItemsColor(Theme.getColor(Theme.key_actionBarDefaultIcon), false); actionBar.setItemsBackgroundColor(Theme.getColor(Theme.key_avatar_actionBarSelectorBlue), false); } }; ArrayList arrayList = new ArrayList<>(); if (sharedMediaLayout != null) { arrayList.addAll(sharedMediaLayout.getThemeDescriptions()); } arrayList.add(new ThemeDescription(listView, 0, null, null, null, null, Theme.key_windowBackgroundWhite)); arrayList.add(new ThemeDescription(listView, 0, null, null, null, null, Theme.key_windowBackgroundGray)); arrayList.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SUBMENUBACKGROUND, null, null, null, null, Theme.key_actionBarDefaultSubmenuBackground)); arrayList.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SUBMENUITEM, null, null, null, null, Theme.key_actionBarDefaultSubmenuItem)); arrayList.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SUBMENUITEM | ThemeDescription.FLAG_IMAGECOLOR, null, null, null, null, Theme.key_actionBarDefaultSubmenuItemIcon)); arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_actionBarDefaultIcon)); arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_actionBarSelectorBlue)); arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_chat_lockIcon)); arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_subtitleInProfileBlue)); arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_backgroundActionBarBlue)); arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_profile_title)); arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_profile_status)); arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_subtitleInProfileBlue)); arrayList.add(new ThemeDescription(onlineTextView[2], ThemeDescription.FLAG_TEXTCOLOR, null, null, null, themeDelegate, Theme.key_player_actionBarSubtitle)); arrayList.add(new ThemeDescription(topView, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_avatar_backgroundActionBarBlue)); arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_SELECTOR, null, null, null, null, Theme.key_listSelector)); arrayList.add(new ThemeDescription(listView, 0, new Class[]{View.class}, Theme.dividerPaint, null, null, Theme.key_divider)); arrayList.add(new ThemeDescription(avatarImage, 0, null, null, Theme.avatarDrawables, null, Theme.key_avatar_text)); arrayList.add(new ThemeDescription(avatarImage, 0, null, null, new Drawable[]{avatarDrawable}, null, Theme.key_avatar_backgroundInProfileBlue)); arrayList.add(new ThemeDescription(writeButton, ThemeDescription.FLAG_IMAGECOLOR, null, null, null, null, Theme.key_profile_actionIcon)); arrayList.add(new ThemeDescription(writeButton, ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_profile_actionBackground)); arrayList.add(new ThemeDescription(writeButton, ThemeDescription.FLAG_BACKGROUNDFILTER | ThemeDescription.FLAG_DRAWABLESELECTEDSTATE, null, null, null, null, Theme.key_profile_actionPressedBackground)); arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText)); arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteGreenText2)); arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteRedText5)); arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlueText2)); arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlueButton)); arrayList.add(new ThemeDescription(listView, 0, new Class[]{TextCell.class}, new String[]{"valueTextView"}, null, null, null, Theme.key_windowBackgroundWhiteValueText)); arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextCell.class}, new String[]{"imageView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayIcon)); arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextCell.class}, new String[]{"imageView"}, null, null, null, Theme.key_windowBackgroundWhiteBlueIcon)); arrayList.add(new ThemeDescription(listView, 0, new Class[]{TextDetailCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText)); arrayList.add(new ThemeDescription(listView, 0, new Class[]{TextDetailCell.class}, new String[]{"valueTextView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayText2)); arrayList.add(new ThemeDescription(listView, 0, new Class[]{HeaderCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlueHeader)); arrayList.add(new ThemeDescription(listView, 0, new Class[]{NotificationsCheckCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText)); arrayList.add(new ThemeDescription(listView, 0, new Class[]{NotificationsCheckCell.class}, new String[]{"valueTextView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayText2)); arrayList.add(new ThemeDescription(listView, 0, new Class[]{NotificationsCheckCell.class}, new String[]{"checkBox"}, null, null, null, Theme.key_switchTrack)); arrayList.add(new ThemeDescription(listView, 0, new Class[]{NotificationsCheckCell.class}, new String[]{"checkBox"}, null, null, null, Theme.key_switchTrackChecked)); arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{UserCell.class}, new String[]{"adminTextView"}, null, null, null, Theme.key_profile_creatorIcon)); arrayList.add(new ThemeDescription(listView, 0, new Class[]{UserCell.class}, new String[]{"imageView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayIcon)); arrayList.add(new ThemeDescription(listView, 0, new Class[]{UserCell.class}, new String[]{"nameTextView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText)); arrayList.add(new ThemeDescription(listView, 0, new Class[]{UserCell.class}, new String[]{"statusColor"}, null, null, themeDelegate, Theme.key_windowBackgroundWhiteGrayText)); arrayList.add(new ThemeDescription(listView, 0, new Class[]{UserCell.class}, new String[]{"statusOnlineColor"}, null, null, themeDelegate, Theme.key_windowBackgroundWhiteBlueText)); arrayList.add(new ThemeDescription(listView, 0, new Class[]{UserCell.class}, null, Theme.avatarDrawables, null, Theme.key_avatar_text)); arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_backgroundRed)); arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_backgroundOrange)); arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_backgroundViolet)); arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_backgroundGreen)); arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_backgroundCyan)); arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_backgroundBlue)); arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_backgroundPink)); arrayList.add(new ThemeDescription(undoView, ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_undo_background)); arrayList.add(new ThemeDescription(undoView, 0, new Class[]{UndoView.class}, new String[]{"undoImageView"}, null, null, null, Theme.key_undo_cancelColor)); arrayList.add(new ThemeDescription(undoView, 0, new Class[]{UndoView.class}, new String[]{"undoTextView"}, null, null, null, Theme.key_undo_cancelColor)); arrayList.add(new ThemeDescription(undoView, 0, new Class[]{UndoView.class}, new String[]{"infoTextView"}, null, null, null, Theme.key_undo_infoColor)); arrayList.add(new ThemeDescription(undoView, 0, new Class[]{UndoView.class}, new String[]{"textPaint"}, null, null, null, Theme.key_undo_infoColor)); arrayList.add(new ThemeDescription(undoView, 0, new Class[]{UndoView.class}, new String[]{"progressPaint"}, null, null, null, Theme.key_undo_infoColor)); arrayList.add(new ThemeDescription(undoView, ThemeDescription.FLAG_IMAGECOLOR, new Class[]{UndoView.class}, new String[]{"leftImageView"}, null, null, null, Theme.key_undo_infoColor)); arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{AboutLinkCell.class}, Theme.profile_aboutTextPaint, null, null, Theme.key_windowBackgroundWhiteBlackText)); arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_LINKCOLOR, new Class[]{AboutLinkCell.class}, Theme.profile_aboutTextPaint, null, null, Theme.key_windowBackgroundWhiteLinkText)); arrayList.add(new ThemeDescription(listView, 0, new Class[]{AboutLinkCell.class}, Theme.linkSelectionPaint, null, null, Theme.key_windowBackgroundWhiteLinkSelection)); arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_BACKGROUNDFILTER, new Class[]{ShadowSectionCell.class}, null, null, null, Theme.key_windowBackgroundGrayShadow)); arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_BACKGROUNDFILTER | ThemeDescription.FLAG_CELLBACKGROUNDCOLOR, new Class[]{ShadowSectionCell.class}, null, null, null, Theme.key_windowBackgroundGray)); arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_BACKGROUNDFILTER, new Class[]{TextInfoPrivacyCell.class}, null, null, null, Theme.key_windowBackgroundGrayShadow)); arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_BACKGROUNDFILTER | ThemeDescription.FLAG_CELLBACKGROUNDCOLOR, new Class[]{TextInfoPrivacyCell.class}, null, null, null, Theme.key_windowBackgroundGray)); arrayList.add(new ThemeDescription(listView, 0, new Class[]{TextInfoPrivacyCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayText4)); if (mediaHeaderVisible) { arrayList.add(new ThemeDescription(nameTextView[1], 0, null, null, new Drawable[]{verifiedCheckDrawable}, null, Theme.key_player_actionBarTitle)); arrayList.add(new ThemeDescription(nameTextView[1], 0, null, null, new Drawable[]{verifiedDrawable}, null, Theme.key_windowBackgroundWhite)); } else { arrayList.add(new ThemeDescription(nameTextView[1], 0, null, null, new Drawable[]{verifiedCheckDrawable}, null, Theme.key_profile_verifiedCheck)); arrayList.add(new ThemeDescription(nameTextView[1], 0, null, null, new Drawable[]{verifiedDrawable}, null, Theme.key_profile_verifiedBackground)); } return arrayList; } }