Java tutorial
/* * 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.annotation.TargetApi; import android.app.DatePickerDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Canvas; import android.graphics.Outline; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.PorterDuffXfermode; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.support.v4.content.FileProvider; import android.text.TextUtils; import android.text.style.CharacterStyle; import android.text.style.ClickableSpan; import android.text.style.URLSpan; import android.util.LongSparseArray; import android.util.SparseArray; import android.util.TypedValue; import android.view.Gravity; import android.view.TextureView; import android.view.View; import android.view.ViewGroup; import android.view.ViewOutlineProvider; import android.view.ViewTreeObserver; import android.widget.DatePicker; import android.widget.EditText; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.BuildConfig; import org.telegram.messenger.BuildVars; import org.telegram.messenger.ChatObject; import org.telegram.messenger.ContactsController; import org.telegram.messenger.DataQuery; import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; import org.telegram.messenger.ImageReceiver; import org.telegram.messenger.LocaleController; import org.telegram.messenger.MediaController; import org.telegram.messenger.MessageObject; import org.telegram.messenger.MessagesController; import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.R; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; import org.telegram.messenger.browser.Browser; import org.telegram.messenger.support.widget.LinearLayoutManager; import org.telegram.messenger.support.widget.LinearSmoothScrollerMiddle; import org.telegram.messenger.support.widget.RecyclerView; import org.telegram.tgnet.ConnectionsManager; 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.BottomSheet; import org.telegram.ui.ActionBar.SimpleTextView; import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.ThemeDescription; import org.telegram.ui.Cells.BotHelpCell; import org.telegram.ui.Cells.ChatActionCell; import org.telegram.ui.Cells.ChatLoadingCell; import org.telegram.ui.Cells.ChatMessageCell; import org.telegram.ui.Cells.ChatUnreadCell; import org.telegram.ui.Components.AdminLogFilterAlert; import org.telegram.ui.Components.ChatAvatarContainer; import org.telegram.ui.Components.EmbedBottomSheet; import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.PipRoundVideoView; import org.telegram.ui.Components.RadialProgressView; import org.telegram.ui.Components.RecyclerListView; import org.telegram.ui.Components.ShareAlert; import org.telegram.ui.Components.SizeNotifierFrameLayout; import org.telegram.ui.Components.StickersAlert; import org.telegram.ui.Components.URLSpanMono; import org.telegram.ui.Components.URLSpanNoUnderline; import org.telegram.ui.Components.URLSpanReplacement; import org.telegram.ui.Components.URLSpanUserMention; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; public class ChannelAdminLogActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate { protected TLRPC.Chat currentChat; private ArrayList<ChatMessageCell> chatMessageCellsCache = new ArrayList<>(); private FrameLayout progressView; private View progressView2; private RadialProgressView progressBar; private RecyclerListView chatListView; private LinearLayoutManager chatLayoutManager; private ChatActivityAdapter chatAdapter; private TextView bottomOverlayChatText; private ImageView bottomOverlayImage; private FrameLayout bottomOverlayChat; private FrameLayout emptyViewContainer; private ChatAvatarContainer avatarContainer; private TextView emptyView; private ChatActionCell floatingDateView; private ActionBarMenuItem searchItem; private long minEventId; private boolean currentFloatingDateOnScreen; private boolean currentFloatingTopIsNotMessage; private AnimatorSet floatingDateAnimation; private boolean scrollingFloatingDate; private int[] mid = new int[] { 2 }; private boolean searchWas; private boolean checkTextureViewPosition; private SizeNotifierFrameLayout contentView; private MessageObject selectedObject; private FrameLayout searchContainer; private ImageView searchCalendarButton; private ImageView searchUpButton; private ImageView searchDownButton; private SimpleTextView searchCountText; private FrameLayout roundVideoContainer; private AspectRatioFrameLayout aspectRatioFrameLayout; private TextureView videoTextureView; private Path aspectPath; private Paint aspectPaint; private int scrollToPositionOnRecreate = -1; private int scrollToOffsetOnRecreate = 0; private boolean paused = true; private boolean wasPaused = false; private boolean openAnimationEnded; private LongSparseArray<MessageObject> messagesDict = new LongSparseArray<>(); private HashMap<String, ArrayList<MessageObject>> messagesByDays = new HashMap<>(); protected ArrayList<MessageObject> messages = new ArrayList<>(); private int minDate; private boolean endReached; private boolean loading; private int loadsCount; private ArrayList<TLRPC.ChannelParticipant> admins; private TLRPC.TL_channelAdminLogEventsFilter currentFilter = null; private String searchQuery = ""; private SparseArray<TLRPC.User> selectedAdmins; private MessageObject scrollToMessage; private PhotoViewer.PhotoViewerProvider provider = new PhotoViewer.EmptyPhotoViewerProvider() { @Override public PhotoViewer.PlaceProviderObject getPlaceForPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index, boolean needPreview) { int count = chatListView.getChildCount(); for (int a = 0; a < count; a++) { ImageReceiver imageReceiver = null; View view = chatListView.getChildAt(a); if (view instanceof ChatMessageCell) { if (messageObject != null) { ChatMessageCell cell = (ChatMessageCell) view; MessageObject message = cell.getMessageObject(); if (message != null && message.getId() == messageObject.getId()) { imageReceiver = cell.getPhotoImage(); } } } else if (view instanceof ChatActionCell) { ChatActionCell cell = (ChatActionCell) view; MessageObject message = cell.getMessageObject(); if (message != null) { if (messageObject != null) { if (message.getId() == messageObject.getId()) { imageReceiver = cell.getPhotoImage(); } } else if (fileLocation != null && message.photoThumbs != null) { for (int b = 0; b < message.photoThumbs.size(); b++) { TLRPC.PhotoSize photoSize = message.photoThumbs.get(b); if (photoSize.location.volume_id == fileLocation.volume_id && photoSize.location.local_id == fileLocation.local_id) { imageReceiver = cell.getPhotoImage(); break; } } } } } if (imageReceiver != null) { int coords[] = new int[2]; view.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 = chatListView; object.imageReceiver = imageReceiver; object.thumb = imageReceiver.getBitmapSafe(); object.radius = imageReceiver.getRoundRadius(); object.isEvent = true; return object; } } return null; } }; public ChannelAdminLogActivity(TLRPC.Chat chat) { currentChat = chat; } @Override public boolean onFragmentCreate() { super.onFragmentCreate(); NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.emojiDidLoad); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.messagePlayingDidStart); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.messagePlayingPlayStateChanged); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.messagePlayingDidReset); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.messagePlayingProgressDidChanged); NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.didSetNewWallpapper); loadMessages(true); loadAdmins(); return true; } @Override public void onFragmentDestroy() { super.onFragmentDestroy(); NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.emojiDidLoad); NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.messagePlayingDidStart); NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.messagePlayingPlayStateChanged); NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.messagePlayingDidReset); NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.messagePlayingProgressDidChanged); NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.didSetNewWallpapper); } private void updateEmptyPlaceholder() { if (emptyView == null) { return; } if (!TextUtils.isEmpty(searchQuery)) { emptyView.setPadding(AndroidUtilities.dp(8), AndroidUtilities.dp(5), AndroidUtilities.dp(8), AndroidUtilities.dp(5)); emptyView.setText(AndroidUtilities.replaceTags(LocaleController.formatString("EventLogEmptyTextSearch", R.string.EventLogEmptyTextSearch, searchQuery))); } else if (selectedAdmins != null || currentFilter != null) { emptyView.setPadding(AndroidUtilities.dp(8), AndroidUtilities.dp(5), AndroidUtilities.dp(8), AndroidUtilities.dp(5)); emptyView.setText(AndroidUtilities .replaceTags(LocaleController.getString("EventLogEmptySearch", R.string.EventLogEmptySearch))); } else { emptyView.setPadding(AndroidUtilities.dp(16), AndroidUtilities.dp(16), AndroidUtilities.dp(16), AndroidUtilities.dp(16)); if (currentChat.megagroup) { emptyView.setText(AndroidUtilities .replaceTags(LocaleController.getString("EventLogEmpty", R.string.EventLogEmpty))); } else { emptyView.setText(AndroidUtilities.replaceTags( LocaleController.getString("EventLogEmptyChannel", R.string.EventLogEmptyChannel))); } } } private void loadMessages(boolean reset) { if (loading) { return; } if (reset) { minEventId = Long.MAX_VALUE; if (progressView != null) { progressView.setVisibility(View.VISIBLE); emptyViewContainer.setVisibility(View.INVISIBLE); chatListView.setEmptyView(null); } messagesDict.clear(); messages.clear(); messagesByDays.clear(); } loading = true; TLRPC.TL_channels_getAdminLog req = new TLRPC.TL_channels_getAdminLog(); req.channel = MessagesController.getInputChannel(currentChat); req.q = searchQuery; req.limit = 50; if (!reset && !messages.isEmpty()) { req.max_id = minEventId; } else { req.max_id = 0; } req.min_id = 0; if (currentFilter != null) { req.flags |= 1; req.events_filter = currentFilter; } if (selectedAdmins != null) { req.flags |= 2; for (int a = 0; a < selectedAdmins.size(); a++) { req.admins.add( MessagesController.getInstance(currentAccount).getInputUser(selectedAdmins.valueAt(a))); } } updateEmptyPlaceholder(); ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> { if (response != null) { final TLRPC.TL_channels_adminLogResults res = (TLRPC.TL_channels_adminLogResults) response; AndroidUtilities.runOnUIThread(() -> { MessagesController.getInstance(currentAccount).putUsers(res.users, false); MessagesController.getInstance(currentAccount).putChats(res.chats, false); boolean added = false; int oldRowsCount = messages.size(); for (int a = 0; a < res.events.size(); a++) { TLRPC.TL_channelAdminLogEvent event = res.events.get(a); if (messagesDict.indexOfKey(event.id) >= 0) { continue; } minEventId = Math.min(minEventId, event.id); added = true; MessageObject messageObject = new MessageObject(currentAccount, event, messages, messagesByDays, currentChat, mid); if (messageObject.contentType < 0) { continue; } messagesDict.put(event.id, messageObject); } int newRowsCount = messages.size() - oldRowsCount; loading = false; if (!added) { endReached = true; } progressView.setVisibility(View.INVISIBLE); chatListView.setEmptyView(emptyViewContainer); if (newRowsCount != 0) { boolean end = false; if (endReached) { end = true; chatAdapter.notifyItemRangeChanged(0, 2); } int firstVisPos = chatLayoutManager.findLastVisibleItemPosition(); View firstVisView = chatLayoutManager.findViewByPosition(firstVisPos); int top = ((firstVisView == null) ? 0 : firstVisView.getTop()) - chatListView.getPaddingTop(); if (newRowsCount - (end ? 1 : 0) > 0) { int insertStart = 1 + (end ? 0 : 1); chatAdapter.notifyItemChanged(insertStart); chatAdapter.notifyItemRangeInserted(insertStart, newRowsCount - (end ? 1 : 0)); } if (firstVisPos != -1) { chatLayoutManager.scrollToPositionWithOffset(firstVisPos + newRowsCount - (end ? 1 : 0), top); } } else if (endReached) { chatAdapter.notifyItemRemoved(0); } }); } }); if (reset && chatAdapter != null) { chatAdapter.notifyDataSetChanged(); } } @Override public void didReceivedNotification(int id, int account, Object... args) { if (id == NotificationCenter.emojiDidLoad) { if (chatListView != null) { chatListView.invalidateViews(); } } else if (id == NotificationCenter.messagePlayingDidStart) { MessageObject messageObject = (MessageObject) args[0]; if (messageObject.isRoundVideo()) { MediaController.getInstance().setTextureView(createTextureView(true), aspectRatioFrameLayout, roundVideoContainer, true); updateTextureViewPosition(); } if (chatListView != null) { int count = chatListView.getChildCount(); for (int a = 0; a < count; a++) { View view = chatListView.getChildAt(a); if (view instanceof ChatMessageCell) { ChatMessageCell cell = (ChatMessageCell) view; MessageObject messageObject1 = cell.getMessageObject(); if (messageObject1 != null) { if (messageObject1.isVoice() || messageObject1.isMusic()) { cell.updateButtonState(false, true, false); } else if (messageObject1.isRoundVideo()) { cell.checkVideoPlayback(false); if (!MediaController.getInstance().isPlayingMessage(messageObject1)) { if (messageObject1.audioProgress != 0) { messageObject1.resetPlayingProgress(); cell.invalidate(); } } } } } } } } else if (id == NotificationCenter.messagePlayingDidReset || id == NotificationCenter.messagePlayingPlayStateChanged) { if (chatListView != null) { int count = chatListView.getChildCount(); for (int a = 0; a < count; a++) { View view = chatListView.getChildAt(a); if (view instanceof ChatMessageCell) { ChatMessageCell cell = (ChatMessageCell) view; MessageObject messageObject = cell.getMessageObject(); if (messageObject != null) { if (messageObject.isVoice() || messageObject.isMusic()) { cell.updateButtonState(false, true, false); } else if (messageObject.isRoundVideo()) { if (!MediaController.getInstance().isPlayingMessage(messageObject)) { cell.checkVideoPlayback(true); } } } } } } } else if (id == NotificationCenter.messagePlayingProgressDidChanged) { Integer mid = (Integer) args[0]; if (chatListView != null) { int count = chatListView.getChildCount(); for (int a = 0; a < count; a++) { View view = chatListView.getChildAt(a); if (view instanceof ChatMessageCell) { ChatMessageCell cell = (ChatMessageCell) view; MessageObject playing = cell.getMessageObject(); if (playing != null && playing.getId() == mid) { MessageObject player = MediaController.getInstance().getPlayingMessageObject(); if (player != null) { playing.audioProgress = player.audioProgress; playing.audioProgressSec = player.audioProgressSec; playing.audioPlayerDuration = player.audioPlayerDuration; cell.updatePlayingMessageProgress(); } break; } } } } } else if (id == NotificationCenter.didSetNewWallpapper) { if (fragmentView != null) { contentView.setBackgroundImage(Theme.getCachedWallpaper(), Theme.isWallpaperMotion()); progressView2.getBackground().setColorFilter(Theme.colorFilter); if (emptyView != null) { emptyView.getBackground().setColorFilter(Theme.colorFilter); } chatListView.invalidateViews(); } } } private void updateBottomOverlay() { /*if (searchItem != null && searchItem.getVisibility() == View.VISIBLE) { searchContainer.setVisibility(View.VISIBLE); bottomOverlayChat.setVisibility(View.INVISIBLE); } else { searchContainer.setVisibility(View.INVISIBLE); bottomOverlayChat.setVisibility(View.VISIBLE); }*/ } @Override public View createView(Context context) { if (chatMessageCellsCache.isEmpty()) { for (int a = 0; a < 8; a++) { chatMessageCellsCache.add(new ChatMessageCell(context)); } } searchWas = false; hasOwnBackground = true; Theme.createChatResources(context, false); actionBar.setAddToContainer(false); actionBar.setOccupyStatusBar(Build.VERSION.SDK_INT >= 21 && !AndroidUtilities.isTablet()); actionBar.setBackButtonDrawable(new BackDrawable(false)); actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { @Override public void onItemClick(final int id) { if (id == -1) { finishFragment(); } } }); avatarContainer = new ChatAvatarContainer(context, null, false); avatarContainer.setOccupyStatusBar(!AndroidUtilities.isTablet()); actionBar.addView(avatarContainer, 0, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT, 56, 0, 40, 0)); ActionBarMenu menu = actionBar.createMenu(); searchItem = menu.addItem(0, R.drawable.ic_ab_search).setIsSearchField(true) .setActionBarMenuItemSearchListener(new ActionBarMenuItem.ActionBarMenuItemSearchListener() { @Override public void onSearchCollapse() { searchQuery = ""; avatarContainer.setVisibility(View.VISIBLE); if (searchWas) { searchWas = false; loadMessages(true); } /*highlightMessageId = Integer.MAX_VALUE; updateVisibleRows(); scrollToLastMessage(false); */ updateBottomOverlay(); } @Override public void onSearchExpand() { avatarContainer.setVisibility(View.GONE); updateBottomOverlay(); } @Override public void onSearchPressed(EditText editText) { searchWas = true; searchQuery = editText.getText().toString(); loadMessages(true); //updateSearchButtons(0, 0, 0); } }); searchItem.setSearchFieldHint(LocaleController.getString("Search", R.string.Search)); avatarContainer.setEnabled(false); avatarContainer.setTitle(currentChat.title); avatarContainer.setSubtitle(LocaleController.getString("EventLogAllEvents", R.string.EventLogAllEvents)); avatarContainer.setChatAvatar(currentChat); fragmentView = new SizeNotifierFrameLayout(context) { @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); MessageObject messageObject = MediaController.getInstance().getPlayingMessageObject(); if (messageObject != null && messageObject.isRoundVideo() && messageObject.eventId != 0 && messageObject.getDialogId() == -currentChat.id) { MediaController.getInstance().setTextureView(createTextureView(false), aspectRatioFrameLayout, roundVideoContainer, true); } } @Override protected boolean drawChild(Canvas canvas, View child, long drawingTime) { boolean result = super.drawChild(canvas, child, drawingTime); if (child == actionBar && parentLayout != null) { parentLayout.drawHeaderShadow(canvas, actionBar.getVisibility() == VISIBLE ? actionBar.getMeasuredHeight() : 0); } return result; } @Override protected boolean isActionBarVisible() { return actionBar.getVisibility() == VISIBLE; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int allHeight; int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); setMeasuredDimension(widthSize, heightSize); heightSize -= getPaddingTop(); measureChildWithMargins(actionBar, widthMeasureSpec, 0, heightMeasureSpec, 0); int actionBarHeight = actionBar.getMeasuredHeight(); if (actionBar.getVisibility() == VISIBLE) { heightSize -= actionBarHeight; } int keyboardSize = getKeyboardHeight(); int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View child = getChildAt(i); if (child == null || child.getVisibility() == GONE || child == actionBar) { continue; } if (child == chatListView || child == progressView) { int contentWidthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY); int contentHeightSpec = MeasureSpec.makeMeasureSpec( Math.max(AndroidUtilities.dp(10), heightSize - AndroidUtilities.dp(48 + 2)), MeasureSpec.EXACTLY); child.measure(contentWidthSpec, contentHeightSpec); } else if (child == emptyViewContainer) { int contentWidthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY); int contentHeightSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY); child.measure(contentWidthSpec, contentHeightSpec); } else { measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0); } } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = getChildCount(); for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() == GONE) { continue; } final LayoutParams lp = (LayoutParams) child.getLayoutParams(); final int width = child.getMeasuredWidth(); final int height = child.getMeasuredHeight(); int childLeft; int childTop; int gravity = lp.gravity; if (gravity == -1) { gravity = Gravity.TOP | Gravity.LEFT; } final int absoluteGravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK; final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK; switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) { case Gravity.CENTER_HORIZONTAL: childLeft = (r - l - width) / 2 + lp.leftMargin - lp.rightMargin; break; case Gravity.RIGHT: childLeft = r - width - lp.rightMargin; break; case Gravity.LEFT: default: childLeft = lp.leftMargin; } switch (verticalGravity) { case Gravity.TOP: childTop = lp.topMargin + getPaddingTop(); if (child != actionBar && actionBar.getVisibility() == VISIBLE) { childTop += actionBar.getMeasuredHeight(); } break; case Gravity.CENTER_VERTICAL: childTop = (b - t - height) / 2 + lp.topMargin - lp.bottomMargin; break; case Gravity.BOTTOM: childTop = (b - t) - height - lp.bottomMargin; break; default: childTop = lp.topMargin; } if (child == emptyViewContainer) { childTop -= AndroidUtilities.dp(24) - (actionBar.getVisibility() == VISIBLE ? actionBar.getMeasuredHeight() / 2 : 0); } else if (child == actionBar) { childTop -= getPaddingTop(); } child.layout(childLeft, childTop, childLeft + width, childTop + height); } updateMessagesVisisblePart(); notifyHeightChanged(); } }; contentView = (SizeNotifierFrameLayout) fragmentView; contentView.setOccupyStatusBar(!AndroidUtilities.isTablet()); contentView.setBackgroundImage(Theme.getCachedWallpaper(), Theme.isWallpaperMotion()); emptyViewContainer = new FrameLayout(context); emptyViewContainer.setVisibility(View.INVISIBLE); contentView.addView(emptyViewContainer, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER)); emptyViewContainer.setOnTouchListener((v, event) -> true); emptyView = new TextView(context); emptyView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); emptyView.setGravity(Gravity.CENTER); emptyView.setTextColor(Theme.getColor(Theme.key_chat_serviceText)); emptyView.setBackgroundDrawable( Theme.createRoundRectDrawable(AndroidUtilities.dp(10), Theme.getServiceMessageColor())); emptyView.setPadding(AndroidUtilities.dp(16), AndroidUtilities.dp(16), AndroidUtilities.dp(16), AndroidUtilities.dp(16)); emptyViewContainer.addView(emptyView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER, 16, 0, 16, 0)); chatListView = new RecyclerListView(context) { @Override public boolean drawChild(Canvas canvas, View child, long drawingTime) { boolean result = super.drawChild(canvas, child, drawingTime); if (child instanceof ChatMessageCell) { ChatMessageCell chatMessageCell = (ChatMessageCell) child; ImageReceiver imageReceiver = chatMessageCell.getAvatarImage(); if (imageReceiver != null) { int top = child.getTop(); if (chatMessageCell.isPinnedBottom()) { ViewHolder holder = chatListView.getChildViewHolder(child); if (holder != null) { holder = chatListView .findViewHolderForAdapterPosition(holder.getAdapterPosition() + 1); if (holder != null) { imageReceiver.setImageY(-AndroidUtilities.dp(1000)); imageReceiver.draw(canvas); return result; } } } if (chatMessageCell.isPinnedTop()) { ViewHolder holder = chatListView.getChildViewHolder(child); if (holder != null) { while (true) { holder = chatListView .findViewHolderForAdapterPosition(holder.getAdapterPosition() - 1); if (holder != null) { top = holder.itemView.getTop(); if (!(holder.itemView instanceof ChatMessageCell) || !((ChatMessageCell) holder.itemView).isPinnedTop()) { break; } } else { break; } } } } int y = child.getTop() + chatMessageCell.getLayoutHeight(); int maxY = chatListView.getHeight() - chatListView.getPaddingBottom(); if (y > maxY) { y = maxY; } if (y - AndroidUtilities.dp(48) < top) { y = top + AndroidUtilities.dp(48); } imageReceiver.setImageY(y - AndroidUtilities.dp(44)); imageReceiver.draw(canvas); } } return result; } }; chatListView.setOnItemClickListener((view, position) -> createMenu(view)); chatListView.setTag(1); chatListView.setVerticalScrollBarEnabled(true); chatListView.setAdapter(chatAdapter = new ChatActivityAdapter(context)); chatListView.setClipToPadding(false); chatListView.setPadding(0, AndroidUtilities.dp(4), 0, AndroidUtilities.dp(3)); chatListView.setItemAnimator(null); chatListView.setLayoutAnimation(null); chatLayoutManager = new LinearLayoutManager(context) { @Override public boolean supportsPredictiveItemAnimations() { return false; } @Override public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) { LinearSmoothScrollerMiddle linearSmoothScroller = new LinearSmoothScrollerMiddle( recyclerView.getContext()); linearSmoothScroller.setTargetPosition(position); startSmoothScroll(linearSmoothScroller); } }; chatLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); chatLayoutManager.setStackFromEnd(true); chatListView.setLayoutManager(chatLayoutManager); contentView.addView(chatListView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); chatListView.setOnScrollListener(new RecyclerView.OnScrollListener() { private float totalDy = 0; private final int scrollValue = AndroidUtilities.dp(100); @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { if (newState == RecyclerView.SCROLL_STATE_DRAGGING) { scrollingFloatingDate = true; checkTextureViewPosition = true; } else if (newState == RecyclerView.SCROLL_STATE_IDLE) { scrollingFloatingDate = false; checkTextureViewPosition = false; hideFloatingDateView(true); } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { chatListView.invalidate(); if (dy != 0 && scrollingFloatingDate && !currentFloatingTopIsNotMessage) { if (floatingDateView.getTag() == null) { if (floatingDateAnimation != null) { floatingDateAnimation.cancel(); } floatingDateView.setTag(1); floatingDateAnimation = new AnimatorSet(); floatingDateAnimation.setDuration(150); floatingDateAnimation.playTogether(ObjectAnimator.ofFloat(floatingDateView, "alpha", 1.0f)); floatingDateAnimation.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { if (animation.equals(floatingDateAnimation)) { floatingDateAnimation = null; } } }); floatingDateAnimation.start(); } } checkScrollForLoad(true); updateMessagesVisisblePart(); } }); if (scrollToPositionOnRecreate != -1) { chatLayoutManager.scrollToPositionWithOffset(scrollToPositionOnRecreate, scrollToOffsetOnRecreate); scrollToPositionOnRecreate = -1; } progressView = new FrameLayout(context); progressView.setVisibility(View.INVISIBLE); contentView.addView(progressView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT)); progressView2 = new View(context); progressView2.setBackgroundResource(R.drawable.system_loader); progressView2.getBackground().setColorFilter(Theme.colorFilter); progressView.addView(progressView2, LayoutHelper.createFrame(36, 36, Gravity.CENTER)); progressBar = new RadialProgressView(context); progressBar.setSize(AndroidUtilities.dp(28)); progressBar.setProgressColor(Theme.getColor(Theme.key_chat_serviceText)); progressView.addView(progressBar, LayoutHelper.createFrame(32, 32, Gravity.CENTER)); floatingDateView = new ChatActionCell(context); floatingDateView.setAlpha(0.0f); contentView.addView(floatingDateView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 4, 0, 0)); contentView.addView(actionBar); bottomOverlayChat = new FrameLayout(context) { @Override public 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); } }; bottomOverlayChat.setWillNotDraw(false); bottomOverlayChat.setPadding(0, AndroidUtilities.dp(3), 0, 0); contentView.addView(bottomOverlayChat, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 51, Gravity.BOTTOM)); bottomOverlayChat.setOnClickListener(view -> { if (getParentActivity() == null) { return; } AdminLogFilterAlert adminLogFilterAlert = new AdminLogFilterAlert(getParentActivity(), currentFilter, selectedAdmins, currentChat.megagroup); adminLogFilterAlert.setCurrentAdmins(admins); adminLogFilterAlert.setAdminLogFilterAlertDelegate((filter, admins) -> { currentFilter = filter; selectedAdmins = admins; if (currentFilter != null || selectedAdmins != null) { avatarContainer.setSubtitle( LocaleController.getString("EventLogSelectedEvents", R.string.EventLogSelectedEvents)); } else { avatarContainer.setSubtitle( LocaleController.getString("EventLogAllEvents", R.string.EventLogAllEvents)); } loadMessages(true); }); showDialog(adminLogFilterAlert); }); bottomOverlayChatText = new TextView(context); bottomOverlayChatText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); bottomOverlayChatText.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); bottomOverlayChatText.setTextColor(Theme.getColor(Theme.key_chat_fieldOverlayText)); bottomOverlayChatText.setText(LocaleController.getString("SETTINGS", R.string.SETTINGS).toUpperCase()); bottomOverlayChat.addView(bottomOverlayChatText, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER)); bottomOverlayImage = new ImageView(context); bottomOverlayImage.setImageResource(R.drawable.log_info); bottomOverlayImage.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_chat_fieldOverlayText), PorterDuff.Mode.MULTIPLY)); bottomOverlayImage.setScaleType(ImageView.ScaleType.CENTER); bottomOverlayChat.addView(bottomOverlayImage, LayoutHelper.createFrame(48, 48, Gravity.RIGHT | Gravity.TOP, 3, 0, 0, 0)); bottomOverlayImage.setOnClickListener(v -> { AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); if (currentChat.megagroup) { builder.setMessage(AndroidUtilities.replaceTags( LocaleController.getString("EventLogInfoDetail", R.string.EventLogInfoDetail))); } else { builder.setMessage(AndroidUtilities.replaceTags(LocaleController .getString("EventLogInfoDetailChannel", R.string.EventLogInfoDetailChannel))); } builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null); builder.setTitle(LocaleController.getString("EventLogInfoTitle", R.string.EventLogInfoTitle)); showDialog(builder.create()); }); searchContainer = new FrameLayout(context) { @Override public 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); } }; searchContainer.setWillNotDraw(false); searchContainer.setVisibility(View.INVISIBLE); searchContainer.setFocusable(true); searchContainer.setFocusableInTouchMode(true); searchContainer.setClickable(true); searchContainer.setPadding(0, AndroidUtilities.dp(3), 0, 0); contentView.addView(searchContainer, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 51, Gravity.BOTTOM)); /*searchUpButton = new ImageView(context); searchUpButton.setScaleType(ImageView.ScaleType.CENTER); searchUpButton.setImageResource(R.drawable.search_up); searchUpButton.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_chat_searchPanelIcons), PorterDuff.Mode.MULTIPLY)); searchContainer.addView(searchUpButton, LayoutHelper.createFrame(48, 48)); searchUpButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { MessagesSearchQuery.searchMessagesInChat(null, dialog_id, mergeDialogId, classGuid, 1); } }); searchDownButton = new ImageView(context); searchDownButton.setScaleType(ImageView.ScaleType.CENTER); searchDownButton.setImageResource(R.drawable.search_down); searchDownButton.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_chat_searchPanelIcons), PorterDuff.Mode.MULTIPLY)); searchContainer.addView(searchDownButton, LayoutHelper.createFrame(48, 48, Gravity.LEFT | Gravity.TOP, 48, 0, 0, 0)); searchDownButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { MessagesSearchQuery.searchMessagesInChat(null, dialog_id, mergeDialogId, classGuid, 2); } });*/ searchCalendarButton = new ImageView(context); searchCalendarButton.setScaleType(ImageView.ScaleType.CENTER); searchCalendarButton.setImageResource(R.drawable.search_calendar); searchCalendarButton.setColorFilter(new PorterDuffColorFilter( Theme.getColor(Theme.key_chat_searchPanelIcons), PorterDuff.Mode.MULTIPLY)); searchContainer.addView(searchCalendarButton, LayoutHelper.createFrame(48, 48, Gravity.RIGHT | Gravity.TOP)); searchCalendarButton.setOnClickListener(view -> { if (getParentActivity() == null) { return; } AndroidUtilities.hideKeyboard(searchItem.getSearchField()); Calendar calendar = Calendar.getInstance(); int year = calendar.get(Calendar.YEAR); int monthOfYear = calendar.get(Calendar.MONTH); int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH); try { DatePickerDialog dialog = new DatePickerDialog(getParentActivity(), (view1, year1, month, dayOfMonth1) -> { Calendar calendar1 = Calendar.getInstance(); calendar1.clear(); calendar1.set(year1, month, dayOfMonth1); int date = (int) (calendar1.getTime().getTime() / 1000); loadMessages(true); }, year, monthOfYear, dayOfMonth); final DatePicker datePicker = dialog.getDatePicker(); datePicker.setMinDate(1375315200000L); datePicker.setMaxDate(System.currentTimeMillis()); dialog.setButton(DialogInterface.BUTTON_POSITIVE, LocaleController.getString("JumpToDate", R.string.JumpToDate), dialog); dialog.setButton(DialogInterface.BUTTON_NEGATIVE, LocaleController.getString("Cancel", R.string.Cancel), (dialog12, which) -> { }); if (Build.VERSION.SDK_INT >= 21) { dialog.setOnShowListener(dialog1 -> { int count = datePicker.getChildCount(); for (int a = 0; a < count; a++) { View child = datePicker.getChildAt(a); ViewGroup.LayoutParams layoutParams = child.getLayoutParams(); layoutParams.width = LayoutHelper.MATCH_PARENT; child.setLayoutParams(layoutParams); } }); } showDialog(dialog); } catch (Exception e) { FileLog.e(e); } }); searchCountText = new SimpleTextView(context); searchCountText.setTextColor(Theme.getColor(Theme.key_chat_searchPanelText)); searchCountText.setTextSize(15); searchCountText.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); searchContainer.addView(searchCountText, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.CENTER_VERTICAL, 108, 0, 0, 0)); chatAdapter.updateRows(); if (loading && messages.isEmpty()) { progressView.setVisibility(View.VISIBLE); chatListView.setEmptyView(null); } else { progressView.setVisibility(View.INVISIBLE); chatListView.setEmptyView(emptyViewContainer); } updateEmptyPlaceholder(); return fragmentView; } private void createMenu(View v) { MessageObject message = null; if (v instanceof ChatMessageCell) { message = ((ChatMessageCell) v).getMessageObject(); } else if (v instanceof ChatActionCell) { message = ((ChatActionCell) v).getMessageObject(); } if (message == null) { return; } final int type = getMessageType(message); selectedObject = message; if (getParentActivity() == null) { return; } AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); ArrayList<CharSequence> items = new ArrayList<>(); final ArrayList<Integer> options = new ArrayList<>(); if (selectedObject.type == 0 || selectedObject.caption != null) { items.add(LocaleController.getString("Copy", R.string.Copy)); options.add(3); } if (type == 1) { if (selectedObject.currentEvent != null && selectedObject.currentEvent.action instanceof TLRPC.TL_channelAdminLogEventActionChangeStickerSet) { TLRPC.InputStickerSet stickerSet = selectedObject.currentEvent.action.new_stickerset; if (stickerSet == null || stickerSet instanceof TLRPC.TL_inputStickerSetEmpty) { stickerSet = selectedObject.currentEvent.action.prev_stickerset; } if (stickerSet != null) { showDialog(new StickersAlert(getParentActivity(), ChannelAdminLogActivity.this, stickerSet, null, null)); return; } } } else if (type == 3) { if (selectedObject.messageOwner.media instanceof TLRPC.TL_messageMediaWebPage && MessageObject.isNewGifDocument(selectedObject.messageOwner.media.webpage.document)) { items.add(LocaleController.getString("SaveToGIFs", R.string.SaveToGIFs)); options.add(11); } } else if (type == 4) { if (selectedObject.isVideo()) { items.add(LocaleController.getString("SaveToGallery", R.string.SaveToGallery)); options.add(4); items.add(LocaleController.getString("ShareFile", R.string.ShareFile)); options.add(6); } else if (selectedObject.isMusic()) { items.add(LocaleController.getString("SaveToMusic", R.string.SaveToMusic)); options.add(10); items.add(LocaleController.getString("ShareFile", R.string.ShareFile)); options.add(6); } else if (selectedObject.getDocument() != null) { if (MessageObject.isNewGifDocument(selectedObject.getDocument())) { items.add(LocaleController.getString("SaveToGIFs", R.string.SaveToGIFs)); options.add(11); } items.add(LocaleController.getString("SaveToDownloads", R.string.SaveToDownloads)); options.add(10); items.add(LocaleController.getString("ShareFile", R.string.ShareFile)); options.add(6); } else { items.add(LocaleController.getString("SaveToGallery", R.string.SaveToGallery)); options.add(4); } } else if (type == 5) { items.add(LocaleController.getString("ApplyLocalizationFile", R.string.ApplyLocalizationFile)); options.add(5); items.add(LocaleController.getString("SaveToDownloads", R.string.SaveToDownloads)); options.add(10); items.add(LocaleController.getString("ShareFile", R.string.ShareFile)); options.add(6); } else if (type == 10) { items.add(LocaleController.getString("ApplyThemeFile", R.string.ApplyThemeFile)); options.add(5); items.add(LocaleController.getString("SaveToDownloads", R.string.SaveToDownloads)); options.add(10); items.add(LocaleController.getString("ShareFile", R.string.ShareFile)); options.add(6); } else if (type == 6) { items.add(LocaleController.getString("SaveToGallery", R.string.SaveToGallery)); options.add(7); items.add(LocaleController.getString("SaveToDownloads", R.string.SaveToDownloads)); options.add(10); items.add(LocaleController.getString("ShareFile", R.string.ShareFile)); options.add(6); } else if (type == 7) { if (selectedObject.isMask()) { items.add(LocaleController.getString("AddToMasks", R.string.AddToMasks)); } else { items.add(LocaleController.getString("AddToStickers", R.string.AddToStickers)); } options.add(9); } else if (type == 8) { TLRPC.User user = MessagesController.getInstance(currentAccount) .getUser(selectedObject.messageOwner.media.user_id); if (user != null && user.id != UserConfig.getInstance(currentAccount).getClientUserId() && ContactsController.getInstance(currentAccount).contactsDict.get(user.id) == null) { items.add(LocaleController.getString("AddContactTitle", R.string.AddContactTitle)); options.add(15); } if (selectedObject.messageOwner.media.phone_number != null || selectedObject.messageOwner.media.phone_number.length() != 0) { items.add(LocaleController.getString("Copy", R.string.Copy)); options.add(16); items.add(LocaleController.getString("Call", R.string.Call)); options.add(17); } } if (options.isEmpty()) { return; } final CharSequence[] finalItems = items.toArray(new CharSequence[items.size()]); builder.setItems(finalItems, (dialogInterface, i) -> { if (selectedObject == null || i < 0 || i >= options.size()) { return; } processSelectedOption(options.get(i)); }); builder.setTitle(LocaleController.getString("Message", R.string.Message)); showDialog(builder.create()); } private String getMessageContent(MessageObject messageObject, int previousUid, boolean name) { String str = ""; if (name) { if (previousUid != messageObject.messageOwner.from_id) { if (messageObject.messageOwner.from_id > 0) { TLRPC.User user = MessagesController.getInstance(currentAccount) .getUser(messageObject.messageOwner.from_id); if (user != null) { str = ContactsController.formatName(user.first_name, user.last_name) + ":\n"; } } else if (messageObject.messageOwner.from_id < 0) { TLRPC.Chat chat = MessagesController.getInstance(currentAccount) .getChat(-messageObject.messageOwner.from_id); if (chat != null) { str = chat.title + ":\n"; } } } } if (messageObject.type == 0 && messageObject.messageOwner.message != null) { str += messageObject.messageOwner.message; } else if (messageObject.messageOwner.media != null && messageObject.messageOwner.message != null) { str += messageObject.messageOwner.message; } else { str += messageObject.messageText; } return str; } private TextureView createTextureView(boolean add) { if (parentLayout == null) { return null; } if (roundVideoContainer == null) { if (Build.VERSION.SDK_INT >= 21) { roundVideoContainer = new FrameLayout(getParentActivity()) { @Override public void setTranslationY(float translationY) { super.setTranslationY(translationY); contentView.invalidate(); } }; roundVideoContainer.setOutlineProvider(new ViewOutlineProvider() { @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public void getOutline(View view, Outline outline) { outline.setOval(0, 0, AndroidUtilities.roundMessageSize, AndroidUtilities.roundMessageSize); } }); roundVideoContainer.setClipToOutline(true); } else { roundVideoContainer = new FrameLayout(getParentActivity()) { @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); aspectPath.reset(); aspectPath.addCircle(w / 2, h / 2, w / 2, Path.Direction.CW); aspectPath.toggleInverseFillType(); } @Override public void setTranslationY(float translationY) { super.setTranslationY(translationY); contentView.invalidate(); } @Override public void setVisibility(int visibility) { super.setVisibility(visibility); if (visibility == VISIBLE) { setLayerType(View.LAYER_TYPE_HARDWARE, null); } } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); canvas.drawPath(aspectPath, aspectPaint); } }; aspectPath = new Path(); aspectPaint = new Paint(Paint.ANTI_ALIAS_FLAG); aspectPaint.setColor(0xff000000); aspectPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); } roundVideoContainer.setWillNotDraw(false); roundVideoContainer.setVisibility(View.INVISIBLE); aspectRatioFrameLayout = new AspectRatioFrameLayout(getParentActivity()); aspectRatioFrameLayout.setBackgroundColor(0); if (add) { roundVideoContainer.addView(aspectRatioFrameLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); } videoTextureView = new TextureView(getParentActivity()); videoTextureView.setOpaque(false); aspectRatioFrameLayout.addView(videoTextureView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); } if (roundVideoContainer.getParent() == null) { contentView.addView(roundVideoContainer, 1, new FrameLayout.LayoutParams( AndroidUtilities.roundMessageSize, AndroidUtilities.roundMessageSize)); } roundVideoContainer.setVisibility(View.INVISIBLE); aspectRatioFrameLayout.setDrawingReady(false); return videoTextureView; } private void destroyTextureView() { if (roundVideoContainer == null || roundVideoContainer.getParent() == null) { return; } contentView.removeView(roundVideoContainer); aspectRatioFrameLayout.setDrawingReady(false); roundVideoContainer.setVisibility(View.INVISIBLE); if (Build.VERSION.SDK_INT < 21) { roundVideoContainer.setLayerType(View.LAYER_TYPE_NONE, null); } } private void processSelectedOption(int option) { if (selectedObject == null) { return; } switch (option) { case 3: { AndroidUtilities.addToClipboard(getMessageContent(selectedObject, 0, true)); break; } case 4: { String path = selectedObject.messageOwner.attachPath; if (path != null && path.length() > 0) { File temp = new File(path); if (!temp.exists()) { path = null; } } if (path == null || path.length() == 0) { path = FileLoader.getPathToMessage(selectedObject.messageOwner).toString(); } if (selectedObject.type == 3 || selectedObject.type == 1) { 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); selectedObject = null; return; } MediaController.saveFile(path, getParentActivity(), selectedObject.type == 3 ? 1 : 0, null, null); } break; } case 5: { File locFile = null; if (selectedObject.messageOwner.attachPath != null && selectedObject.messageOwner.attachPath.length() != 0) { File f = new File(selectedObject.messageOwner.attachPath); if (f.exists()) { locFile = f; } } if (locFile == null) { File f = FileLoader.getPathToMessage(selectedObject.messageOwner); if (f.exists()) { locFile = f; } } if (locFile != null) { if (locFile.getName().toLowerCase().endsWith("attheme")) { if (chatLayoutManager != null) { int lastPosition = chatLayoutManager.findLastVisibleItemPosition(); if (lastPosition < chatLayoutManager.getItemCount() - 1) { scrollToPositionOnRecreate = chatLayoutManager.findFirstVisibleItemPosition(); RecyclerListView.Holder holder = (RecyclerListView.Holder) chatListView .findViewHolderForAdapterPosition(scrollToPositionOnRecreate); if (holder != null) { scrollToOffsetOnRecreate = holder.itemView.getTop(); } else { scrollToPositionOnRecreate = -1; } } else { scrollToPositionOnRecreate = -1; } } Theme.ThemeInfo themeInfo = Theme.applyThemeFile(locFile, selectedObject.getDocumentName(), true); if (themeInfo != null) { presentFragment(new ThemePreviewActivity(locFile, themeInfo)); } else { scrollToPositionOnRecreate = -1; if (getParentActivity() == null) { selectedObject = null; return; } AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); builder.setMessage(LocaleController.getString("IncorrectTheme", R.string.IncorrectTheme)); builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null); showDialog(builder.create()); } } else { if (LocaleController.getInstance().applyLanguageFile(locFile, currentAccount)) { presentFragment(new LanguageSelectActivity()); } else { if (getParentActivity() == null) { selectedObject = null; return; } AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); builder.setMessage(LocaleController.getString("IncorrectLocalization", R.string.IncorrectLocalization)); builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null); showDialog(builder.create()); } } } break; } case 6: { String path = selectedObject.messageOwner.attachPath; if (path != null && path.length() > 0) { File temp = new File(path); if (!temp.exists()) { path = null; } } if (path == null || path.length() == 0) { path = FileLoader.getPathToMessage(selectedObject.messageOwner).toString(); } Intent intent = new Intent(Intent.ACTION_SEND); intent.setType(selectedObject.getDocument().mime_type); if (Build.VERSION.SDK_INT >= 24) { try { intent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(getParentActivity(), BuildConfig.APPLICATION_ID + ".provider", new File(path))); intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); } catch (Exception ignore) { intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(path))); } } else { intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(path))); } getParentActivity().startActivityForResult( Intent.createChooser(intent, LocaleController.getString("ShareFile", R.string.ShareFile)), 500); break; } case 7: { String path = selectedObject.messageOwner.attachPath; if (path != null && path.length() > 0) { File temp = new File(path); if (!temp.exists()) { path = null; } } if (path == null || path.length() == 0) { path = FileLoader.getPathToMessage(selectedObject.messageOwner).toString(); } 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); selectedObject = null; return; } MediaController.saveFile(path, getParentActivity(), 0, null, null); break; } case 9: { showDialog( new StickersAlert(getParentActivity(), this, selectedObject.getInputStickerSet(), null, null)); break; } case 10: { 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); selectedObject = null; return; } String fileName = FileLoader.getDocumentFileName(selectedObject.getDocument()); if (TextUtils.isEmpty(fileName)) { fileName = selectedObject.getFileName(); } String path = selectedObject.messageOwner.attachPath; if (path != null && path.length() > 0) { File temp = new File(path); if (!temp.exists()) { path = null; } } if (path == null || path.length() == 0) { path = FileLoader.getPathToMessage(selectedObject.messageOwner).toString(); } MediaController.saveFile(path, getParentActivity(), selectedObject.isMusic() ? 3 : 2, fileName, selectedObject.getDocument() != null ? selectedObject.getDocument().mime_type : ""); break; } case 11: { TLRPC.Document document = selectedObject.getDocument(); MessagesController.getInstance(currentAccount).saveGif(selectedObject, document); break; } case 15: { Bundle args = new Bundle(); args.putInt("user_id", selectedObject.messageOwner.media.user_id); args.putString("phone", selectedObject.messageOwner.media.phone_number); args.putBoolean("addContact", true); presentFragment(new ContactAddActivity(args)); break; } case 16: { AndroidUtilities.addToClipboard(selectedObject.messageOwner.media.phone_number); break; } case 17: { try { Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + selectedObject.messageOwner.media.phone_number)); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); getParentActivity().startActivityForResult(intent, 500); } catch (Exception e) { FileLog.e(e); } break; } } selectedObject = null; } private int getMessageType(MessageObject messageObject) { if (messageObject == null) { return -1; } if (messageObject.type == 6) { return -1; } else if (messageObject.type == 10 || messageObject.type == 11 || messageObject.type == 16) { if (messageObject.getId() == 0) { return -1; } return 1; } else { if (messageObject.isVoice()) { return 2; } else if (messageObject.isSticker()) { TLRPC.InputStickerSet inputStickerSet = messageObject.getInputStickerSet(); if (inputStickerSet instanceof TLRPC.TL_inputStickerSetID) { if (!DataQuery.getInstance(currentAccount).isStickerPackInstalled(inputStickerSet.id)) { return 7; } } else if (inputStickerSet instanceof TLRPC.TL_inputStickerSetShortName) { if (!DataQuery.getInstance(currentAccount).isStickerPackInstalled(inputStickerSet.short_name)) { return 7; } } } else if ((!messageObject.isRoundVideo() || messageObject.isRoundVideo() && BuildVars.DEBUG_VERSION) && (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto || messageObject.getDocument() != null || messageObject.isMusic() || messageObject.isVideo())) { boolean canSave = false; if (messageObject.messageOwner.attachPath != null && messageObject.messageOwner.attachPath.length() != 0) { File f = new File(messageObject.messageOwner.attachPath); if (f.exists()) { canSave = true; } } if (!canSave) { File f = FileLoader.getPathToMessage(messageObject.messageOwner); if (f.exists()) { canSave = true; } } if (canSave) { if (messageObject.getDocument() != null) { String mime = messageObject.getDocument().mime_type; if (mime != null) { if (messageObject.getDocumentName().toLowerCase().endsWith("attheme")) { return 10; } else if (mime.endsWith("/xml")) { return 5; } else if (mime.endsWith("/png") || mime.endsWith("/jpg") || mime.endsWith("/jpeg")) { return 6; } } } return 4; } } else if (messageObject.type == 12) { return 8; } else if (messageObject.isMediaEmpty()) { return 3; } return 2; } } private void loadAdmins() { TLRPC.TL_channels_getParticipants req = new TLRPC.TL_channels_getParticipants(); req.channel = MessagesController.getInputChannel(currentChat); req.filter = new TLRPC.TL_channelParticipantsAdmins(); req.offset = 0; 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); admins = res.participants; if (visibleDialog instanceof AdminLogFilterAlert) { ((AdminLogFilterAlert) visibleDialog).setCurrentAdmins(admins); } } })); ConnectionsManager.getInstance(currentAccount).bindRequestToGuid(reqId, classGuid); } @Override protected void onRemoveFromParent() { MediaController.getInstance().setTextureView(videoTextureView, null, null, false); } private void hideFloatingDateView(boolean animated) { if (floatingDateView.getTag() != null && !currentFloatingDateOnScreen && (!scrollingFloatingDate || currentFloatingTopIsNotMessage)) { floatingDateView.setTag(null); if (animated) { floatingDateAnimation = new AnimatorSet(); floatingDateAnimation.setDuration(150); floatingDateAnimation.playTogether(ObjectAnimator.ofFloat(floatingDateView, "alpha", 0.0f)); floatingDateAnimation.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { if (animation.equals(floatingDateAnimation)) { floatingDateAnimation = null; } } }); floatingDateAnimation.setStartDelay(500); floatingDateAnimation.start(); } else { if (floatingDateAnimation != null) { floatingDateAnimation.cancel(); floatingDateAnimation = null; } floatingDateView.setAlpha(0.0f); } } } private void checkScrollForLoad(boolean scroll) { if (chatLayoutManager == null || paused) { return; } int firstVisibleItem = chatLayoutManager.findFirstVisibleItemPosition(); int visibleItemCount = firstVisibleItem == RecyclerView.NO_POSITION ? 0 : Math.abs(chatLayoutManager.findLastVisibleItemPosition() - firstVisibleItem) + 1; if (visibleItemCount > 0) { int totalItemCount = chatAdapter.getItemCount(); int checkLoadCount; if (scroll) { checkLoadCount = 25; } else { checkLoadCount = 5; } if (firstVisibleItem <= checkLoadCount && !loading && !endReached) { loadMessages(false); } } } private void moveScrollToLastMessage() { if (chatListView != null && !messages.isEmpty()) { chatLayoutManager.scrollToPositionWithOffset(messages.size() - 1, -100000 - chatListView.getPaddingTop()); } } private void updateTextureViewPosition() { boolean foundTextureViewMessage = false; int count = chatListView.getChildCount(); for (int a = 0; a < count; a++) { View view = chatListView.getChildAt(a); if (view instanceof ChatMessageCell) { ChatMessageCell messageCell = (ChatMessageCell) view; MessageObject messageObject = messageCell.getMessageObject(); if (roundVideoContainer != null && messageObject.isRoundVideo() && MediaController.getInstance().isPlayingMessage(messageObject)) { ImageReceiver imageReceiver = messageCell.getPhotoImage(); roundVideoContainer.setTranslationX(imageReceiver.getImageX()); roundVideoContainer.setTranslationY( fragmentView.getPaddingTop() + messageCell.getTop() + imageReceiver.getImageY()); fragmentView.invalidate(); roundVideoContainer.invalidate(); foundTextureViewMessage = true; break; } } } if (roundVideoContainer != null) { MessageObject messageObject = MediaController.getInstance().getPlayingMessageObject(); if (!foundTextureViewMessage) { roundVideoContainer.setTranslationY(-AndroidUtilities.roundMessageSize - 100); fragmentView.invalidate(); if (messageObject != null && messageObject.isRoundVideo()) { if (checkTextureViewPosition || PipRoundVideoView.getInstance() != null) { MediaController.getInstance().setCurrentVideoVisible(false); } } } else { MediaController.getInstance().setCurrentVideoVisible(true); } } } private void updateMessagesVisisblePart() { if (chatListView == null) { return; } int count = chatListView.getChildCount(); int height = chatListView.getMeasuredHeight(); int minPositionHolder = Integer.MAX_VALUE; int minPositionDateHolder = Integer.MAX_VALUE; View minDateChild = null; View minChild = null; View minMessageChild = null; boolean foundTextureViewMessage = false; for (int a = 0; a < count; a++) { View view = chatListView.getChildAt(a); if (view instanceof ChatMessageCell) { ChatMessageCell messageCell = (ChatMessageCell) view; int top = messageCell.getTop(); int bottom = messageCell.getBottom(); int viewTop = top >= 0 ? 0 : -top; int viewBottom = messageCell.getMeasuredHeight(); if (viewBottom > height) { viewBottom = viewTop + height; } messageCell.setVisiblePart(viewTop, viewBottom - viewTop); MessageObject messageObject = messageCell.getMessageObject(); if (roundVideoContainer != null && messageObject.isRoundVideo() && MediaController.getInstance().isPlayingMessage(messageObject)) { ImageReceiver imageReceiver = messageCell.getPhotoImage(); roundVideoContainer.setTranslationX(imageReceiver.getImageX()); roundVideoContainer .setTranslationY(fragmentView.getPaddingTop() + top + imageReceiver.getImageY()); fragmentView.invalidate(); roundVideoContainer.invalidate(); foundTextureViewMessage = true; } } if (view.getBottom() <= chatListView.getPaddingTop()) { continue; } int position = view.getBottom(); if (position < minPositionHolder) { minPositionHolder = position; if (view instanceof ChatMessageCell || view instanceof ChatActionCell) { minMessageChild = view; } minChild = view; } if (view instanceof ChatActionCell && ((ChatActionCell) view).getMessageObject().isDateObject) { if (view.getAlpha() != 1.0f) { view.setAlpha(1.0f); } if (position < minPositionDateHolder) { minPositionDateHolder = position; minDateChild = view; } } } if (roundVideoContainer != null) { if (!foundTextureViewMessage) { roundVideoContainer.setTranslationY(-AndroidUtilities.roundMessageSize - 100); fragmentView.invalidate(); MessageObject messageObject = MediaController.getInstance().getPlayingMessageObject(); if (messageObject != null && messageObject.isRoundVideo() && checkTextureViewPosition) { MediaController.getInstance().setCurrentVideoVisible(false); } } else { MediaController.getInstance().setCurrentVideoVisible(true); } } if (minMessageChild != null) { MessageObject messageObject; if (minMessageChild instanceof ChatMessageCell) { messageObject = ((ChatMessageCell) minMessageChild).getMessageObject(); } else { messageObject = ((ChatActionCell) minMessageChild).getMessageObject(); } floatingDateView.setCustomDate(messageObject.messageOwner.date); } currentFloatingDateOnScreen = false; currentFloatingTopIsNotMessage = !(minChild instanceof ChatMessageCell || minChild instanceof ChatActionCell); if (minDateChild != null) { if (minDateChild.getTop() > chatListView.getPaddingTop() || currentFloatingTopIsNotMessage) { if (minDateChild.getAlpha() != 1.0f) { minDateChild.setAlpha(1.0f); } hideFloatingDateView(!currentFloatingTopIsNotMessage); } else { if (minDateChild.getAlpha() != 0.0f) { minDateChild.setAlpha(0.0f); } if (floatingDateAnimation != null) { floatingDateAnimation.cancel(); floatingDateAnimation = null; } if (floatingDateView.getTag() == null) { floatingDateView.setTag(1); } if (floatingDateView.getAlpha() != 1.0f) { floatingDateView.setAlpha(1.0f); } currentFloatingDateOnScreen = true; } int offset = minDateChild.getBottom() - chatListView.getPaddingTop(); if (offset > floatingDateView.getMeasuredHeight() && offset < floatingDateView.getMeasuredHeight() * 2) { floatingDateView.setTranslationY(-floatingDateView.getMeasuredHeight() * 2 + offset); } else { floatingDateView.setTranslationY(0); } } else { hideFloatingDateView(true); floatingDateView.setTranslationY(0); } } @Override public void onTransitionAnimationStart(boolean isOpen, boolean backward) { NotificationCenter.getInstance(currentAccount).setAllowedNotificationsDutingAnimation( new int[] { NotificationCenter.chatInfoDidLoad, NotificationCenter.dialogsNeedReload, NotificationCenter.closeChats, NotificationCenter.messagesDidLoad, NotificationCenter.botKeyboardDidLoad/*, NotificationCenter.botInfoDidLoad*/ }); NotificationCenter.getInstance(currentAccount).setAnimationInProgress(true); if (isOpen) { openAnimationEnded = false; } } @Override public void onTransitionAnimationEnd(boolean isOpen, boolean backward) { NotificationCenter.getInstance(currentAccount).setAnimationInProgress(false); if (isOpen) { openAnimationEnded = true; } } @Override public void onResume() { super.onResume(); if (contentView != null) { contentView.onResume(); } paused = false; checkScrollForLoad(false); if (wasPaused) { wasPaused = false; if (chatAdapter != null) { chatAdapter.notifyDataSetChanged(); } } fixLayout(); } @Override public void onPause() { super.onPause(); if (contentView != null) { contentView.onPause(); } paused = true; wasPaused = true; } public void openVCard(String vcard, String first_name, String last_name) { try { File f = new File(FileLoader.getDirectory(FileLoader.MEDIA_DIR_CACHE), "sharing/"); f.mkdirs(); f = new File(f, "vcard.vcf"); BufferedWriter writer = new BufferedWriter(new FileWriter(f)); writer.write(vcard); writer.close(); presentFragment(new PhonebookShareActivity(null, null, f, ContactsController.formatName(first_name, last_name))); } catch (Exception e) { FileLog.e(e); } } private void fixLayout() { if (avatarContainer != null) { avatarContainer.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { if (avatarContainer != null) { avatarContainer.getViewTreeObserver().removeOnPreDrawListener(this); } return true; } }); } } @Override public void onConfigurationChanged(android.content.res.Configuration newConfig) { fixLayout(); if (visibleDialog instanceof DatePickerDialog) { visibleDialog.dismiss(); } } private void alertUserOpenError(MessageObject message) { if (getParentActivity() == null) { return; } AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null); if (message.type == 3) { builder.setMessage(LocaleController.getString("NoPlayerInstalled", R.string.NoPlayerInstalled)); } else { builder.setMessage(LocaleController.formatString("NoHandleAppInstalled", R.string.NoHandleAppInstalled, message.getDocument().mime_type)); } showDialog(builder.create()); } public TLRPC.Chat getCurrentChat() { return currentChat; } private void addCanBanUser(Bundle bundle, int uid) { if (!currentChat.megagroup || admins == null || !ChatObject.canBlockUsers(currentChat)) { return; } for (int a = 0; a < admins.size(); a++) { TLRPC.ChannelParticipant channelParticipant = admins.get(a); if (channelParticipant.user_id == uid) { if (!channelParticipant.can_edit) { return; } break; } } bundle.putInt("ban_chat_id", currentChat.id); } public void showOpenUrlAlert(final String url, boolean ask) { if (Browser.isInternalUrl(url, null) || !ask) { Browser.openUrl(getParentActivity(), url, true); } else { AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); builder.setMessage(LocaleController.formatString("OpenUrlAlert", R.string.OpenUrlAlert, url)); builder.setPositiveButton(LocaleController.getString("Open", R.string.Open), (dialogInterface, i) -> Browser.openUrl(getParentActivity(), url, true)); builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); showDialog(builder.create()); } } private void removeMessageObject(MessageObject messageObject) { int index = messages.indexOf(messageObject); if (index == -1) { return; } messages.remove(index); if (chatAdapter != null) { chatAdapter.notifyItemRemoved(chatAdapter.messagesStartRow + messages.size() - index - 1); } } public class ChatActivityAdapter extends RecyclerView.Adapter { private Context mContext; private int rowCount; private int loadingUpRow; private int messagesStartRow; private int messagesEndRow; public ChatActivityAdapter(Context context) { mContext = context; } public void updateRows() { rowCount = 0; if (!messages.isEmpty()) { if (!endReached) { loadingUpRow = rowCount++; } else { loadingUpRow = -1; } messagesStartRow = rowCount; rowCount += messages.size(); messagesEndRow = rowCount; } else { loadingUpRow = -1; messagesStartRow = -1; messagesEndRow = -1; } } @Override public int getItemCount() { return rowCount; } @Override public long getItemId(int i) { return RecyclerListView.NO_ID; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = null; if (viewType == 0) { if (!chatMessageCellsCache.isEmpty()) { view = chatMessageCellsCache.get(0); chatMessageCellsCache.remove(0); } else { view = new ChatMessageCell(mContext); } ChatMessageCell chatMessageCell = (ChatMessageCell) view; chatMessageCell.setDelegate(new ChatMessageCell.ChatMessageCellDelegate() { @Override public void didPressShare(ChatMessageCell cell) { if (getParentActivity() == null) { return; } showDialog(ShareAlert.createShareAlert(mContext, cell.getMessageObject(), null, ChatObject.isChannel(currentChat) && !currentChat.megagroup && currentChat.username != null && currentChat.username.length() > 0, null, false)); } @Override public boolean needPlayMessage(MessageObject messageObject) { if (messageObject.isVoice() || messageObject.isRoundVideo()) { boolean result = MediaController.getInstance().playMessage(messageObject); MediaController.getInstance().setVoiceMessagesPlaylist(null, false); return result; } else if (messageObject.isMusic()) { return MediaController.getInstance().setPlaylist(messages, messageObject); } return false; } @Override public void didPressChannelAvatar(ChatMessageCell cell, TLRPC.Chat chat, int postId) { if (chat != null && chat != currentChat) { Bundle args = new Bundle(); args.putInt("chat_id", chat.id); if (postId != 0) { args.putInt("message_id", postId); } if (MessagesController.getInstance(currentAccount).checkCanOpenChat(args, ChannelAdminLogActivity.this)) { presentFragment(new ChatActivity(args), true); } } } @Override public void didPressOther(ChatMessageCell cell) { createMenu(cell); } @Override public void didPressUserAvatar(ChatMessageCell cell, TLRPC.User user) { if (user != null && user.id != UserConfig.getInstance(currentAccount).getClientUserId()) { Bundle args = new Bundle(); args.putInt("user_id", user.id); addCanBanUser(args, user.id); ProfileActivity fragment = new ProfileActivity(args); fragment.setPlayProfileAnimation(false); presentFragment(fragment); } } @Override public void didPressBotButton(ChatMessageCell cell, TLRPC.KeyboardButton button) { } @Override public void didPressVoteButton(ChatMessageCell cell, TLRPC.TL_pollAnswer button) { } @Override public void didPressCancelSendButton(ChatMessageCell cell) { } @Override public void didLongPress(ChatMessageCell cell) { createMenu(cell); } @Override public boolean canPerformActions() { return true; } @Override public void didPressUrl(MessageObject messageObject, final CharacterStyle url, boolean longPress) { if (url == null) { return; } if (url instanceof URLSpanMono) { ((URLSpanMono) url).copyToClipboard(); Toast.makeText(getParentActivity(), LocaleController.getString("TextCopied", R.string.TextCopied), Toast.LENGTH_SHORT).show(); } else if (url instanceof URLSpanUserMention) { TLRPC.User user = MessagesController.getInstance(currentAccount) .getUser(Utilities.parseInt(((URLSpanUserMention) url).getURL())); if (user != null) { MessagesController.openChatOrProfileWith(user, null, ChannelAdminLogActivity.this, 0, false); } } else if (url instanceof URLSpanNoUnderline) { String str = ((URLSpanNoUnderline) url).getURL(); if (str.startsWith("@")) { MessagesController.getInstance(currentAccount).openByUserName(str.substring(1), ChannelAdminLogActivity.this, 0); } else if (str.startsWith("#")) { DialogsActivity fragment = new DialogsActivity(null); fragment.setSearchString(str); presentFragment(fragment); } } else { final String urlFinal = ((URLSpan) url).getURL(); if (longPress) { BottomSheet.Builder builder = new BottomSheet.Builder(getParentActivity()); builder.setTitle(urlFinal); builder.setItems( new CharSequence[] { LocaleController.getString("Open", R.string.Open), LocaleController.getString("Copy", R.string.Copy) }, (dialog, which) -> { if (which == 0) { Browser.openUrl(getParentActivity(), urlFinal, true); } else if (which == 1) { String url1 = urlFinal; if (url1.startsWith("mailto:")) { url1 = url1.substring(7); } else if (url1.startsWith("tel:")) { url1 = url1.substring(4); } AndroidUtilities.addToClipboard(url1); } }); showDialog(builder.create()); } else { if (url instanceof URLSpanReplacement) { showOpenUrlAlert(((URLSpanReplacement) url).getURL(), true); } else if (url instanceof URLSpan) { if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaWebPage && messageObject.messageOwner.media.webpage != null && messageObject.messageOwner.media.webpage.cached_page != null) { String lowerUrl = urlFinal.toLowerCase(); String lowerUrl2 = messageObject.messageOwner.media.webpage.url .toLowerCase(); if ((lowerUrl.contains("telegra.ph") || lowerUrl.contains("t.me/iv")) && (lowerUrl.contains(lowerUrl2) || lowerUrl2.contains(lowerUrl))) { ArticleViewer.getInstance().setParentActivity(getParentActivity(), ChannelAdminLogActivity.this); ArticleViewer.getInstance().open(messageObject); return; } } Browser.openUrl(getParentActivity(), urlFinal, true); } else if (url instanceof ClickableSpan) { ((ClickableSpan) url).onClick(fragmentView); } } } } @Override public void needOpenWebView(String url, String title, String description, String originalUrl, int w, int h) { EmbedBottomSheet.show(mContext, title, description, originalUrl, url, w, h); } @Override public void didPressReplyMessage(ChatMessageCell cell, int id) { } @Override public void didPressViaBot(ChatMessageCell cell, String username) { } @Override public void didPressImage(ChatMessageCell cell) { MessageObject message = cell.getMessageObject(); if (message.type == 13) { showDialog(new StickersAlert(getParentActivity(), ChannelAdminLogActivity.this, message.getInputStickerSet(), null, null)); } else if (message.isVideo() || message.type == 1 || message.type == 0 && !message.isWebpageDocument() || message.isGif()) { PhotoViewer.getInstance().setParentActivity(getParentActivity()); PhotoViewer.getInstance().openPhoto(message, 0, 0, provider); } else if (message.type == 3) { try { File f = null; if (message.messageOwner.attachPath != null && message.messageOwner.attachPath.length() != 0) { f = new File(message.messageOwner.attachPath); } if (f == null || !f.exists()) { f = FileLoader.getPathToMessage(message.messageOwner); } Intent intent = new Intent(Intent.ACTION_VIEW); if (Build.VERSION.SDK_INT >= 24) { intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.setDataAndType(FileProvider.getUriForFile(getParentActivity(), BuildConfig.APPLICATION_ID + ".provider", f), "video/mp4"); } else { intent.setDataAndType(Uri.fromFile(f), "video/mp4"); } getParentActivity().startActivityForResult(intent, 500); } catch (Exception e) { alertUserOpenError(message); } } else if (message.type == 4) { if (!AndroidUtilities.isGoogleMapsInstalled(ChannelAdminLogActivity.this)) { return; } LocationActivity fragment = new LocationActivity(0); fragment.setMessageObject(message); presentFragment(fragment); } else if (message.type == 9 || message.type == 0) { if (message.getDocumentName().toLowerCase().endsWith("attheme")) { File locFile = null; if (message.messageOwner.attachPath != null && message.messageOwner.attachPath.length() != 0) { File f = new File(message.messageOwner.attachPath); if (f.exists()) { locFile = f; } } if (locFile == null) { File f = FileLoader.getPathToMessage(message.messageOwner); if (f.exists()) { locFile = f; } } if (chatLayoutManager != null) { int lastPosition = chatLayoutManager.findLastVisibleItemPosition(); if (lastPosition < chatLayoutManager.getItemCount() - 1) { scrollToPositionOnRecreate = chatLayoutManager .findFirstVisibleItemPosition(); RecyclerListView.Holder holder = (RecyclerListView.Holder) chatListView .findViewHolderForAdapterPosition(scrollToPositionOnRecreate); if (holder != null) { scrollToOffsetOnRecreate = holder.itemView.getTop(); } else { scrollToPositionOnRecreate = -1; } } else { scrollToPositionOnRecreate = -1; } } Theme.ThemeInfo themeInfo = Theme.applyThemeFile(locFile, message.getDocumentName(), true); if (themeInfo != null) { presentFragment(new ThemePreviewActivity(locFile, themeInfo)); return; } else { scrollToPositionOnRecreate = -1; } } try { AndroidUtilities.openForView(message, getParentActivity()); } catch (Exception e) { alertUserOpenError(message); } } } @Override public void didPressInstantButton(ChatMessageCell cell, int type) { MessageObject messageObject = cell.getMessageObject(); if (type == 0) { if (messageObject.messageOwner.media != null && messageObject.messageOwner.media.webpage != null && messageObject.messageOwner.media.webpage.cached_page != null) { ArticleViewer.getInstance().setParentActivity(getParentActivity(), ChannelAdminLogActivity.this); ArticleViewer.getInstance().open(messageObject); } } else if (type == 5) { openVCard(messageObject.messageOwner.media.vcard, messageObject.messageOwner.media.first_name, messageObject.messageOwner.media.last_name); } else { if (messageObject.messageOwner.media != null && messageObject.messageOwner.media.webpage != null) { Browser.openUrl(getParentActivity(), messageObject.messageOwner.media.webpage.url); } } } @Override public boolean isChatAdminCell(int uid) { return false; } }); chatMessageCell.setAllowAssistant(true); } else if (viewType == 1) { view = new ChatActionCell(mContext); ((ChatActionCell) view).setDelegate(new ChatActionCell.ChatActionCellDelegate() { @Override public void didClickedImage(ChatActionCell cell) { MessageObject message = cell.getMessageObject(); PhotoViewer.getInstance().setParentActivity(getParentActivity()); TLRPC.PhotoSize photoSize = FileLoader.getClosestPhotoSizeWithSize(message.photoThumbs, 640); if (photoSize != null) { PhotoViewer.getInstance().openPhoto(photoSize.location, provider); } else { PhotoViewer.getInstance().openPhoto(message, 0, 0, provider); } } @Override public void didLongPressed(ChatActionCell cell) { createMenu(cell); } @Override public void needOpenUserProfile(int uid) { if (uid < 0) { Bundle args = new Bundle(); args.putInt("chat_id", -uid); if (MessagesController.getInstance(currentAccount).checkCanOpenChat(args, ChannelAdminLogActivity.this)) { presentFragment(new ChatActivity(args), true); } } else if (uid != UserConfig.getInstance(currentAccount).getClientUserId()) { Bundle args = new Bundle(); args.putInt("user_id", uid); addCanBanUser(args, uid); ProfileActivity fragment = new ProfileActivity(args); fragment.setPlayProfileAnimation(false); presentFragment(fragment); } } @Override public void didPressedReplyMessage(ChatActionCell cell, int id) { } @Override public void didPressedBotButton(MessageObject messageObject, TLRPC.KeyboardButton button) { } }); } else if (viewType == 2) { view = new ChatUnreadCell(mContext); } else if (viewType == 3) { view = new BotHelpCell(mContext); ((BotHelpCell) view).setDelegate(url -> { if (url.startsWith("@")) { MessagesController.getInstance(currentAccount).openByUserName(url.substring(1), ChannelAdminLogActivity.this, 0); } else if (url.startsWith("#")) { DialogsActivity fragment = new DialogsActivity(null); fragment.setSearchString(url); presentFragment(fragment); } }); } else if (viewType == 4) { view = new ChatLoadingCell(mContext); } view.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT)); return new RecyclerListView.Holder(view); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (position == loadingUpRow) { ChatLoadingCell loadingCell = (ChatLoadingCell) holder.itemView; loadingCell.setProgressVisible(loadsCount > 1); } else if (position >= messagesStartRow && position < messagesEndRow) { MessageObject message = messages.get(messages.size() - (position - messagesStartRow) - 1); View view = holder.itemView; if (view instanceof ChatMessageCell) { final ChatMessageCell messageCell = (ChatMessageCell) view; messageCell.isChat = true; int nextType = getItemViewType(position + 1); int prevType = getItemViewType(position - 1); boolean pinnedBotton; boolean pinnedTop; if (!(message.messageOwner.reply_markup instanceof TLRPC.TL_replyInlineMarkup) && nextType == holder.getItemViewType()) { MessageObject nextMessage = messages .get(messages.size() - (position + 1 - messagesStartRow) - 1); pinnedBotton = nextMessage.isOutOwner() == message.isOutOwner() && (nextMessage.messageOwner.from_id == message.messageOwner.from_id) && Math.abs(nextMessage.messageOwner.date - message.messageOwner.date) <= 5 * 60; } else { pinnedBotton = false; } if (prevType == holder.getItemViewType()) { MessageObject prevMessage = messages.get(messages.size() - (position - messagesStartRow)); pinnedTop = !(prevMessage.messageOwner.reply_markup instanceof TLRPC.TL_replyInlineMarkup) && prevMessage.isOutOwner() == message.isOutOwner() && (prevMessage.messageOwner.from_id == message.messageOwner.from_id) && Math.abs(prevMessage.messageOwner.date - message.messageOwner.date) <= 5 * 60; } else { pinnedTop = false; } messageCell.setMessageObject(message, null, pinnedBotton, pinnedTop); messageCell.setHighlighted(false); messageCell.setHighlightedText(null); } else if (view instanceof ChatActionCell) { ChatActionCell actionCell = (ChatActionCell) view; actionCell.setMessageObject(message); actionCell.setAlpha(1.0f); } } } @Override public int getItemViewType(int position) { if (position >= messagesStartRow && position < messagesEndRow) { return messages.get(messages.size() - (position - messagesStartRow) - 1).contentType; } return 4; } @Override public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) { if (holder.itemView instanceof ChatMessageCell) { final ChatMessageCell messageCell = (ChatMessageCell) holder.itemView; MessageObject message = messageCell.getMessageObject(); boolean selected = false; boolean disableSelection = false; messageCell.setBackgroundDrawable(null); messageCell.setCheckPressed(!disableSelection, disableSelection && selected); messageCell.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { messageCell.getViewTreeObserver().removeOnPreDrawListener(this); int height = chatListView.getMeasuredHeight(); int top = messageCell.getTop(); int bottom = messageCell.getBottom(); int viewTop = top >= 0 ? 0 : -top; int viewBottom = messageCell.getMeasuredHeight(); if (viewBottom > height) { viewBottom = viewTop + height; } messageCell.setVisiblePart(viewTop, viewBottom - viewTop); return true; } }); messageCell.setHighlighted(false); } } public void updateRowWithMessageObject(MessageObject messageObject) { int index = messages.indexOf(messageObject); if (index == -1) { return; } notifyItemChanged(messagesStartRow + messages.size() - index - 1); } @Override public void notifyDataSetChanged() { updateRows(); try { super.notifyDataSetChanged(); } catch (Exception e) { FileLog.e(e); } } @Override public void notifyItemChanged(int position) { updateRows(); try { super.notifyItemChanged(position); } catch (Exception e) { FileLog.e(e); } } @Override public void notifyItemRangeChanged(int positionStart, int itemCount) { updateRows(); try { super.notifyItemRangeChanged(positionStart, itemCount); } catch (Exception e) { FileLog.e(e); } } @Override public void notifyItemInserted(int position) { updateRows(); try { super.notifyItemInserted(position); } catch (Exception e) { FileLog.e(e); } } @Override public void notifyItemMoved(int fromPosition, int toPosition) { updateRows(); try { super.notifyItemMoved(fromPosition, toPosition); } catch (Exception e) { FileLog.e(e); } } @Override public void notifyItemRangeInserted(int positionStart, int itemCount) { updateRows(); try { super.notifyItemRangeInserted(positionStart, itemCount); } catch (Exception e) { FileLog.e(e); } } @Override public void notifyItemRemoved(int position) { updateRows(); try { super.notifyItemRemoved(position); } catch (Exception e) { FileLog.e(e); } } @Override public void notifyItemRangeRemoved(int positionStart, int itemCount) { updateRows(); try { super.notifyItemRangeRemoved(positionStart, itemCount); } catch (Exception e) { FileLog.e(e); } } } @Override public ThemeDescription[] getThemeDescriptions() { return new ThemeDescription[] { new ThemeDescription(fragmentView, 0, null, null, null, null, Theme.key_chat_wallpaper), new ThemeDescription(actionBar, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_actionBarDefault), new ThemeDescription(chatListView, ThemeDescription.FLAG_LISTGLOWCOLOR, null, null, null, null, Theme.key_actionBarDefault), new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_ITEMSCOLOR, null, null, null, null, Theme.key_actionBarDefaultIcon), new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SELECTORCOLOR, null, null, null, null, Theme.key_actionBarDefaultSelector), new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SUBMENUBACKGROUND, null, null, null, null, Theme.key_actionBarDefaultSubmenuBackground), new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SUBMENUITEM, null, null, null, null, Theme.key_actionBarDefaultSubmenuItem), new ThemeDescription(actionBar, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_actionBarDefault), new ThemeDescription(chatListView, ThemeDescription.FLAG_LISTGLOWCOLOR, null, null, null, null, Theme.key_actionBarDefault), new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_ITEMSCOLOR, null, null, null, null, Theme.key_actionBarDefaultIcon), new ThemeDescription(avatarContainer.getTitleTextView(), ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_actionBarDefaultTitle), new ThemeDescription(avatarContainer.getSubtitleTextView(), ThemeDescription.FLAG_TEXTCOLOR, null, new Paint[] { Theme.chat_statusPaint, Theme.chat_statusRecordPaint }, null, null, Theme.key_actionBarDefaultSubtitle, null), new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SELECTORCOLOR, null, null, null, null, Theme.key_actionBarDefaultSelector), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.avatar_broadcastDrawable, Theme.avatar_savedDrawable }, null, Theme.key_avatar_text), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_avatar_backgroundRed), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_avatar_backgroundOrange), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_avatar_backgroundViolet), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_avatar_backgroundGreen), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_avatar_backgroundCyan), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_avatar_backgroundBlue), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_avatar_backgroundPink), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_avatar_nameInMessageRed), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_avatar_nameInMessageOrange), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_avatar_nameInMessageViolet), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_avatar_nameInMessageGreen), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_avatar_nameInMessageCyan), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_avatar_nameInMessageBlue), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_avatar_nameInMessagePink), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgInDrawable, Theme.chat_msgInMediaDrawable }, null, Theme.key_chat_inBubble), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgInSelectedDrawable, Theme.chat_msgInMediaSelectedDrawable }, null, Theme.key_chat_inBubbleSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgInShadowDrawable, Theme.chat_msgInMediaShadowDrawable }, null, Theme.key_chat_inBubbleShadow), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgOutDrawable, Theme.chat_msgOutMediaDrawable }, null, Theme.key_chat_outBubble), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgOutSelectedDrawable, Theme.chat_msgOutMediaSelectedDrawable }, null, Theme.key_chat_outBubbleSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgOutShadowDrawable, Theme.chat_msgOutMediaShadowDrawable }, null, Theme.key_chat_outBubbleShadow), new ThemeDescription(chatListView, ThemeDescription.FLAG_TEXTCOLOR, new Class[] { ChatActionCell.class }, Theme.chat_actionTextPaint, null, null, Theme.key_chat_serviceText), new ThemeDescription(chatListView, ThemeDescription.FLAG_LINKCOLOR, new Class[] { ChatActionCell.class }, Theme.chat_actionTextPaint, null, null, Theme.key_chat_serviceLink), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_shareIconDrawable, Theme.chat_botInlineDrawable, Theme.chat_botLinkDrawalbe, Theme.chat_goIconDrawable }, null, Theme.key_chat_serviceIcon), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class, ChatActionCell.class }, null, null, null, Theme.key_chat_serviceBackground), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class, ChatActionCell.class }, null, null, null, Theme.key_chat_serviceBackgroundSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_messageTextIn), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_messageTextOut), new ThemeDescription(chatListView, ThemeDescription.FLAG_LINKCOLOR, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_messageLinkIn, null), new ThemeDescription(chatListView, ThemeDescription.FLAG_LINKCOLOR, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_messageLinkOut, null), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgOutCheckDrawable, Theme.chat_msgOutHalfCheckDrawable }, null, Theme.key_chat_outSentCheck), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgOutCheckSelectedDrawable, Theme.chat_msgOutHalfCheckSelectedDrawable }, null, Theme.key_chat_outSentCheckSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgOutClockDrawable }, null, Theme.key_chat_outSentClock), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgOutSelectedClockDrawable }, null, Theme.key_chat_outSentClockSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgInClockDrawable }, null, Theme.key_chat_inSentClock), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgInSelectedClockDrawable }, null, Theme.key_chat_inSentClockSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgMediaCheckDrawable, Theme.chat_msgMediaHalfCheckDrawable }, null, Theme.key_chat_mediaSentCheck), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgStickerHalfCheckDrawable, Theme.chat_msgStickerCheckDrawable, Theme.chat_msgStickerClockDrawable, Theme.chat_msgStickerViewsDrawable }, null, Theme.key_chat_serviceText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgMediaClockDrawable }, null, Theme.key_chat_mediaSentClock), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgOutViewsDrawable }, null, Theme.key_chat_outViews), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgOutViewsSelectedDrawable }, null, Theme.key_chat_outViewsSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgInViewsDrawable }, null, Theme.key_chat_inViews), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgInViewsSelectedDrawable }, null, Theme.key_chat_inViewsSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgMediaViewsDrawable }, null, Theme.key_chat_mediaViews), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgOutMenuDrawable }, null, Theme.key_chat_outMenu), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgOutMenuSelectedDrawable }, null, Theme.key_chat_outMenuSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgInMenuDrawable }, null, Theme.key_chat_inMenu), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgInMenuSelectedDrawable }, null, Theme.key_chat_inMenuSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgMediaMenuDrawable }, null, Theme.key_chat_mediaMenu), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgOutInstantDrawable, Theme.chat_msgOutCallDrawable }, null, Theme.key_chat_outInstant), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgOutCallSelectedDrawable }, null, Theme.key_chat_outInstantSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgInInstantDrawable, Theme.chat_msgInCallDrawable }, null, Theme.key_chat_inInstant), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgInCallSelectedDrawable }, null, Theme.key_chat_inInstantSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgCallUpRedDrawable, Theme.chat_msgCallDownRedDrawable }, null, Theme.key_calls_callReceivedRedIcon), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgCallUpGreenDrawable, Theme.chat_msgCallDownGreenDrawable }, null, Theme.key_calls_callReceivedGreenIcon), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, Theme.chat_msgErrorPaint, null, null, Theme.key_chat_sentError), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_msgErrorDrawable }, null, Theme.key_chat_sentErrorIcon), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, Theme.chat_durationPaint, null, null, Theme.key_chat_previewDurationText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, Theme.chat_gamePaint, null, null, Theme.key_chat_previewGameText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inPreviewInstantText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outPreviewInstantText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inPreviewInstantSelectedText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outPreviewInstantSelectedText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, Theme.chat_deleteProgressPaint, null, null, Theme.key_chat_secretTimeText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_stickerNameText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, Theme.chat_botButtonPaint, null, null, Theme.key_chat_botButtonText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, Theme.chat_botProgressPaint, null, null, Theme.key_chat_botProgress), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inForwardedNameText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outForwardedNameText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inViaBotNameText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outViaBotNameText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_stickerViaBotNameText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inReplyLine), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outReplyLine), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_stickerReplyLine), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inReplyNameText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outReplyNameText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_stickerReplyNameText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inReplyMessageText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outReplyMessageText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inReplyMediaMessageText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outReplyMediaMessageText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inReplyMediaMessageSelectedText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outReplyMediaMessageSelectedText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_stickerReplyMessageText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inPreviewLine), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outPreviewLine), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inSiteNameText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outSiteNameText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inContactNameText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outContactNameText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inContactPhoneText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outContactPhoneText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_mediaProgress), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inAudioProgress), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outAudioProgress), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inAudioSelectedProgress), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outAudioSelectedProgress), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_mediaTimeText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inTimeText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outTimeText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inTimeSelectedText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outTimeSelectedText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inAudioPerformerText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outAudioPerformerText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inAudioTitleText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outAudioTitleText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inAudioDurationText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outAudioDurationText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inAudioDurationSelectedText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outAudioDurationSelectedText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inAudioSeekbar), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outAudioSeekbar), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inAudioSeekbarSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outAudioSeekbarSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inAudioSeekbarFill), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inAudioCacheSeekbar), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outAudioSeekbarFill), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outAudioCacheSeekbar), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inVoiceSeekbar), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outVoiceSeekbar), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inVoiceSeekbarSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outVoiceSeekbarSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inVoiceSeekbarFill), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outVoiceSeekbarFill), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inFileProgress), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outFileProgress), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inFileProgressSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outFileProgressSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inFileNameText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outFileNameText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inFileInfoText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outFileInfoText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inFileInfoSelectedText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outFileInfoSelectedText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inFileBackground), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outFileBackground), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inFileBackgroundSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outFileBackgroundSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inVenueInfoText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outVenueInfoText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inVenueInfoSelectedText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outVenueInfoSelectedText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_mediaInfoText), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, Theme.chat_urlPaint, null, null, Theme.key_chat_linkSelectBackground), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, Theme.chat_textSearchSelectionPaint, null, null, Theme.key_chat_textSelectBackground), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outLoader), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outMediaIcon), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outLoaderSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_outMediaIconSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inLoader), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inMediaIcon), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inLoaderSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, null, null, Theme.key_chat_inMediaIconSelected), new ThemeDescription(chatListView, ThemeDescription.FLAG_BACKGROUNDFILTER, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_photoStatesDrawables[0][0], Theme.chat_photoStatesDrawables[1][0], Theme.chat_photoStatesDrawables[2][0], Theme.chat_photoStatesDrawables[3][0] }, null, Theme.key_chat_mediaLoaderPhoto), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_photoStatesDrawables[0][0], Theme.chat_photoStatesDrawables[1][0], Theme.chat_photoStatesDrawables[2][0], Theme.chat_photoStatesDrawables[3][0] }, null, Theme.key_chat_mediaLoaderPhotoIcon), new ThemeDescription(chatListView, ThemeDescription.FLAG_BACKGROUNDFILTER, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_photoStatesDrawables[0][1], Theme.chat_photoStatesDrawables[1][1], Theme.chat_photoStatesDrawables[2][1], Theme.chat_photoStatesDrawables[3][1] }, null, Theme.key_chat_mediaLoaderPhotoSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_photoStatesDrawables[0][1], Theme.chat_photoStatesDrawables[1][1], Theme.chat_photoStatesDrawables[2][1], Theme.chat_photoStatesDrawables[3][1] }, null, Theme.key_chat_mediaLoaderPhotoIconSelected), new ThemeDescription(chatListView, ThemeDescription.FLAG_BACKGROUNDFILTER, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_photoStatesDrawables[7][0], Theme.chat_photoStatesDrawables[8][0] }, null, Theme.key_chat_outLoaderPhoto), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_photoStatesDrawables[7][0], Theme.chat_photoStatesDrawables[8][0] }, null, Theme.key_chat_outLoaderPhotoIcon), new ThemeDescription(chatListView, ThemeDescription.FLAG_BACKGROUNDFILTER, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_photoStatesDrawables[7][1], Theme.chat_photoStatesDrawables[8][1] }, null, Theme.key_chat_outLoaderPhotoSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_photoStatesDrawables[7][1], Theme.chat_photoStatesDrawables[8][1] }, null, Theme.key_chat_outLoaderPhotoIconSelected), new ThemeDescription(chatListView, ThemeDescription.FLAG_BACKGROUNDFILTER, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_photoStatesDrawables[10][0], Theme.chat_photoStatesDrawables[11][0] }, null, Theme.key_chat_inLoaderPhoto), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_photoStatesDrawables[10][0], Theme.chat_photoStatesDrawables[11][0] }, null, Theme.key_chat_inLoaderPhotoIcon), new ThemeDescription(chatListView, ThemeDescription.FLAG_BACKGROUNDFILTER, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_photoStatesDrawables[10][1], Theme.chat_photoStatesDrawables[11][1] }, null, Theme.key_chat_inLoaderPhotoSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_photoStatesDrawables[10][1], Theme.chat_photoStatesDrawables[11][1] }, null, Theme.key_chat_inLoaderPhotoIconSelected), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_photoStatesDrawables[9][0] }, null, Theme.key_chat_outFileIcon), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_photoStatesDrawables[9][1] }, null, Theme.key_chat_outFileSelectedIcon), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_photoStatesDrawables[12][0] }, null, Theme.key_chat_inFileIcon), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_photoStatesDrawables[12][1] }, null, Theme.key_chat_inFileSelectedIcon), new ThemeDescription(chatListView, ThemeDescription.FLAG_BACKGROUNDFILTER, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_contactDrawable[0] }, null, Theme.key_chat_inContactBackground), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_contactDrawable[0] }, null, Theme.key_chat_inContactIcon), new ThemeDescription(chatListView, ThemeDescription.FLAG_BACKGROUNDFILTER, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_contactDrawable[1] }, null, Theme.key_chat_outContactBackground), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_contactDrawable[1] }, null, Theme.key_chat_outContactIcon), new ThemeDescription(chatListView, ThemeDescription.FLAG_BACKGROUNDFILTER, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_locationDrawable[0] }, null, Theme.key_chat_inLocationBackground), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_locationDrawable[0] }, null, Theme.key_chat_inLocationIcon), new ThemeDescription(chatListView, ThemeDescription.FLAG_BACKGROUNDFILTER, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_locationDrawable[1] }, null, Theme.key_chat_outLocationBackground), new ThemeDescription(chatListView, 0, new Class[] { ChatMessageCell.class }, null, new Drawable[] { Theme.chat_locationDrawable[1] }, null, Theme.key_chat_outLocationIcon), new ThemeDescription(bottomOverlayChat, 0, null, Theme.chat_composeBackgroundPaint, null, null, Theme.key_chat_messagePanelBackground), new ThemeDescription(bottomOverlayChat, 0, null, null, new Drawable[] { Theme.chat_composeShadowDrawable }, null, Theme.key_chat_messagePanelShadow), new ThemeDescription(bottomOverlayChatText, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_chat_fieldOverlayText), new ThemeDescription(emptyView, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_chat_serviceText), new ThemeDescription(progressBar, ThemeDescription.FLAG_PROGRESSBAR, null, null, null, null, Theme.key_chat_serviceText), new ThemeDescription(chatListView, ThemeDescription.FLAG_USEBACKGROUNDDRAWABLE, new Class[] { ChatUnreadCell.class }, new String[] { "backgroundLayout" }, null, null, null, Theme.key_chat_unreadMessagesStartBackground), new ThemeDescription(chatListView, ThemeDescription.FLAG_IMAGECOLOR, new Class[] { ChatUnreadCell.class }, new String[] { "imageView" }, null, null, null, Theme.key_chat_unreadMessagesStartArrowIcon), new ThemeDescription(chatListView, ThemeDescription.FLAG_TEXTCOLOR, new Class[] { ChatUnreadCell.class }, new String[] { "textView" }, null, null, null, Theme.key_chat_unreadMessagesStartText), new ThemeDescription(progressView2, ThemeDescription.FLAG_SERVICEBACKGROUND, null, null, null, null, Theme.key_chat_serviceBackground), new ThemeDescription(emptyView, ThemeDescription.FLAG_SERVICEBACKGROUND, null, null, null, null, Theme.key_chat_serviceBackground), new ThemeDescription(chatListView, ThemeDescription.FLAG_SERVICEBACKGROUND, new Class[] { ChatLoadingCell.class }, new String[] { "textView" }, null, null, null, Theme.key_chat_serviceBackground), new ThemeDescription(chatListView, ThemeDescription.FLAG_PROGRESSBAR, new Class[] { ChatLoadingCell.class }, new String[] { "textView" }, null, null, null, Theme.key_chat_serviceText), new ThemeDescription(avatarContainer != null ? avatarContainer.getTimeItem() : null, 0, null, null, null, null, Theme.key_chat_secretTimerBackground), new ThemeDescription(avatarContainer != null ? avatarContainer.getTimeItem() : null, 0, null, null, null, null, Theme.key_chat_secretTimerText), }; } }