mirror of https://github.com/NekoX-Dev/NekoX.git
483 lines
20 KiB
Java
483 lines
20 KiB
Java
/*
|
|
* This is the source code of Telegram for Android v. 5.x.x.
|
|
* It is licensed under GNU GPL v. 2 or later.
|
|
* You should have received a copy of the license in this archive (see LICENSE).
|
|
*
|
|
* Copyright Nikolai Kudashov, 2013-2018.
|
|
*/
|
|
|
|
package org.telegram.ui.Components;
|
|
|
|
import android.content.Context;
|
|
import android.graphics.drawable.Drawable;
|
|
import android.util.SparseArray;
|
|
import android.util.TypedValue;
|
|
import android.view.Gravity;
|
|
import android.view.MotionEvent;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.widget.FrameLayout;
|
|
import android.widget.TextView;
|
|
|
|
import org.telegram.messenger.AndroidUtilities;
|
|
import org.telegram.messenger.MediaDataController;
|
|
import org.telegram.messenger.LocaleController;
|
|
import org.telegram.messenger.MessagesController;
|
|
import org.telegram.messenger.NotificationCenter;
|
|
import org.telegram.messenger.R;
|
|
import org.telegram.messenger.UserConfig;
|
|
import org.telegram.tgnet.TLRPC;
|
|
import org.telegram.ui.ActionBar.Theme;
|
|
import org.telegram.ui.Cells.EmptyCell;
|
|
import org.telegram.ui.Cells.StickerEmojiCell;
|
|
import org.telegram.ui.ContentPreviewViewer;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
|
|
import androidx.recyclerview.widget.GridLayoutManager;
|
|
import androidx.recyclerview.widget.RecyclerView;
|
|
|
|
@SuppressWarnings("unchecked")
|
|
public class StickerMasksView extends FrameLayout implements NotificationCenter.NotificationCenterDelegate {
|
|
|
|
public interface Listener {
|
|
void onStickerSelected(Object parentObject, TLRPC.Document sticker);
|
|
void onTypeChanged();
|
|
}
|
|
|
|
private int currentAccount = UserConfig.selectedAccount;
|
|
private ArrayList<TLRPC.TL_messages_stickerSet>[] stickerSets = new ArrayList[]{new ArrayList<>(), new ArrayList<>()};
|
|
private ArrayList<TLRPC.Document>[] recentStickers = new ArrayList[]{new ArrayList<>(), new ArrayList<>()};
|
|
private int currentType = MediaDataController.TYPE_MASK;
|
|
|
|
private Listener listener;
|
|
private StickersGridAdapter stickersGridAdapter;
|
|
private ScrollSlidingTabStrip scrollSlidingTabStrip;
|
|
private RecyclerListView stickersGridView;
|
|
private GridLayoutManager stickersLayoutManager;
|
|
private TextView stickersEmptyView;
|
|
private RecyclerListView.OnItemClickListener stickersOnItemClickListener;
|
|
|
|
private int stickersTabOffset;
|
|
private int recentTabBum = -2;
|
|
|
|
private int lastNotifyWidth;
|
|
|
|
public StickerMasksView(final Context context) {
|
|
super(context);
|
|
setBackgroundColor(0xff222222);
|
|
setClickable(true);
|
|
|
|
MediaDataController.getInstance(currentAccount).checkStickers(MediaDataController.TYPE_IMAGE);
|
|
MediaDataController.getInstance(currentAccount).checkStickers(MediaDataController.TYPE_MASK);
|
|
stickersGridView = new RecyclerListView(context) {
|
|
@Override
|
|
public boolean onInterceptTouchEvent(MotionEvent event) {
|
|
boolean result = ContentPreviewViewer.getInstance().onInterceptTouchEvent(event, stickersGridView, StickerMasksView.this.getMeasuredHeight(), null);
|
|
return super.onInterceptTouchEvent(event) || result;
|
|
}
|
|
};
|
|
|
|
stickersGridView.setLayoutManager(stickersLayoutManager = new GridLayoutManager(context, 5));
|
|
stickersLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
|
|
@Override
|
|
public int getSpanSize(int position) {
|
|
if (position == stickersGridAdapter.totalItems) {
|
|
return stickersGridAdapter.stickersPerRow;
|
|
}
|
|
return 1;
|
|
}
|
|
});
|
|
stickersGridView.setPadding(0, AndroidUtilities.dp(4), 0, 0);
|
|
stickersGridView.setClipToPadding(false);
|
|
stickersGridView.setAdapter(stickersGridAdapter = new StickersGridAdapter(context));
|
|
stickersGridView.setOnTouchListener((v, event) -> ContentPreviewViewer.getInstance().onTouch(event, stickersGridView, StickerMasksView.this.getMeasuredHeight(), stickersOnItemClickListener, null));
|
|
stickersOnItemClickListener = (view, position) -> {
|
|
if (!(view instanceof StickerEmojiCell)) {
|
|
return;
|
|
}
|
|
ContentPreviewViewer.getInstance().reset();
|
|
StickerEmojiCell cell = (StickerEmojiCell) view;
|
|
if (cell.isDisabled()) {
|
|
return;
|
|
}
|
|
TLRPC.Document document = cell.getSticker();
|
|
Object parent = cell.getParentObject();
|
|
listener.onStickerSelected(parent, document);
|
|
MediaDataController.getInstance(currentAccount).addRecentSticker(MediaDataController.TYPE_MASK, parent, document, (int) (System.currentTimeMillis() / 1000), false);
|
|
MessagesController.getInstance(currentAccount).saveRecentSticker(parent, document, true);
|
|
};
|
|
stickersGridView.setOnItemClickListener(stickersOnItemClickListener);
|
|
stickersGridView.setGlowColor(0xfff5f6f7);
|
|
addView(stickersGridView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 0, 48, 0, 0));
|
|
|
|
stickersEmptyView = new TextView(context);
|
|
stickersEmptyView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18);
|
|
stickersEmptyView.setTextColor(0xff888888);
|
|
addView(stickersEmptyView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER, 0, 48, 0, 0));
|
|
stickersGridView.setEmptyView(stickersEmptyView);
|
|
|
|
scrollSlidingTabStrip = new ScrollSlidingTabStrip(context);
|
|
scrollSlidingTabStrip.setBackgroundColor(0xff000000);
|
|
scrollSlidingTabStrip.setUnderlineHeight(AndroidUtilities.dp(1));
|
|
scrollSlidingTabStrip.setIndicatorColor(0xff62bfe8);
|
|
scrollSlidingTabStrip.setUnderlineColor(0xff1a1a1a);
|
|
scrollSlidingTabStrip.setIndicatorHeight(AndroidUtilities.dp(1) + 1);
|
|
addView(scrollSlidingTabStrip, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.TOP));
|
|
updateStickerTabs();
|
|
scrollSlidingTabStrip.setDelegate(page -> {
|
|
if (page == 0) {
|
|
if (currentType == MediaDataController.TYPE_IMAGE) {
|
|
currentType = MediaDataController.TYPE_MASK;
|
|
} else {
|
|
currentType = MediaDataController.TYPE_IMAGE;
|
|
}
|
|
if (listener != null) {
|
|
listener.onTypeChanged();
|
|
}
|
|
recentStickers[currentType] = MediaDataController.getInstance(currentAccount).getRecentStickers(currentType);
|
|
stickersLayoutManager.scrollToPositionWithOffset(0, 0);
|
|
updateStickerTabs();
|
|
reloadStickersAdapter();
|
|
checkDocuments();
|
|
checkPanels();
|
|
return;
|
|
}
|
|
if (page == recentTabBum + 1) {
|
|
stickersLayoutManager.scrollToPositionWithOffset(0, 0);
|
|
return;
|
|
}
|
|
int index = page - 1 - stickersTabOffset;
|
|
if (index >= stickerSets[currentType].size()) {
|
|
index = stickerSets[currentType].size() - 1;
|
|
}
|
|
stickersLayoutManager.scrollToPositionWithOffset(stickersGridAdapter.getPositionForPack(stickerSets[currentType].get(index)), 0);
|
|
checkScroll();
|
|
});
|
|
|
|
stickersGridView.setOnScrollListener(new RecyclerView.OnScrollListener() {
|
|
@Override
|
|
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
|
checkScroll();
|
|
}
|
|
});
|
|
}
|
|
|
|
private void checkScroll() {
|
|
int firstVisibleItem = stickersLayoutManager.findFirstVisibleItemPosition();
|
|
if (firstVisibleItem == RecyclerView.NO_POSITION) {
|
|
return;
|
|
}
|
|
checkStickersScroll(firstVisibleItem);
|
|
}
|
|
|
|
private void checkStickersScroll(int firstVisibleItem) {
|
|
if (stickersGridView == null) {
|
|
return;
|
|
}
|
|
scrollSlidingTabStrip.onPageScrolled(stickersGridAdapter.getTabForPosition(firstVisibleItem) + 1, (recentTabBum > 0 ? recentTabBum : stickersTabOffset) + 1);
|
|
}
|
|
|
|
public int getCurrentType() {
|
|
return currentType;
|
|
}
|
|
|
|
private void updateStickerTabs() {
|
|
if (scrollSlidingTabStrip == null) {
|
|
return;
|
|
}
|
|
recentTabBum = -2;
|
|
|
|
stickersTabOffset = 0;
|
|
int lastPosition = scrollSlidingTabStrip.getCurrentPosition();
|
|
scrollSlidingTabStrip.removeTabs();
|
|
if (currentType == MediaDataController.TYPE_IMAGE) {
|
|
Drawable drawable = getContext().getResources().getDrawable(R.drawable.ic_masks_msk1);
|
|
Theme.setDrawableColorByKey(drawable, Theme.key_chat_emojiPanelIcon);
|
|
scrollSlidingTabStrip.addIconTab(0, drawable);
|
|
stickersEmptyView.setText(LocaleController.getString("NoStickers", R.string.NoStickers));
|
|
} else {
|
|
Drawable drawable = getContext().getResources().getDrawable(R.drawable.ic_masks_sticker1);
|
|
Theme.setDrawableColorByKey(drawable, Theme.key_chat_emojiPanelIcon);
|
|
scrollSlidingTabStrip.addIconTab(1, drawable);
|
|
stickersEmptyView.setText(LocaleController.getString("NoMasks", R.string.NoMasks));
|
|
}
|
|
|
|
if (!recentStickers[currentType].isEmpty()) {
|
|
recentTabBum = stickersTabOffset;
|
|
stickersTabOffset++;
|
|
scrollSlidingTabStrip.addIconTab(2, Theme.createEmojiIconSelectorDrawable(getContext(), R.drawable.ic_masks_recent1, Theme.getColor(Theme.key_chat_emojiPanelMasksIcon), Theme.getColor(Theme.key_chat_emojiPanelMasksIconSelected)));
|
|
}
|
|
|
|
stickerSets[currentType].clear();
|
|
ArrayList<TLRPC.TL_messages_stickerSet> packs = MediaDataController.getInstance(currentAccount).getStickerSets(currentType);
|
|
for (int a = 0; a < packs.size(); a++) {
|
|
TLRPC.TL_messages_stickerSet pack = packs.get(a);
|
|
if (pack.set.archived || pack.documents == null || pack.documents.isEmpty()) {
|
|
continue;
|
|
}
|
|
stickerSets[currentType].add(pack);
|
|
}
|
|
for (int a = 0; a < stickerSets[currentType].size(); a++) {
|
|
TLRPC.TL_messages_stickerSet set = stickerSets[currentType].get(a);
|
|
TLRPC.Document document = set.documents.get(0);
|
|
scrollSlidingTabStrip.addStickerTab(document, document, set);
|
|
}
|
|
scrollSlidingTabStrip.updateTabStyles();
|
|
if (lastPosition != 0) {
|
|
scrollSlidingTabStrip.onPageScrolled(lastPosition, lastPosition);
|
|
}
|
|
checkPanels();
|
|
}
|
|
|
|
private void checkPanels() {
|
|
if (scrollSlidingTabStrip == null) {
|
|
return;
|
|
}
|
|
int position = stickersLayoutManager.findFirstVisibleItemPosition();
|
|
if (position != RecyclerView.NO_POSITION) {
|
|
scrollSlidingTabStrip.onPageScrolled(stickersGridAdapter.getTabForPosition(position) + 1, (recentTabBum > 0 ? recentTabBum : stickersTabOffset) + 1);
|
|
}
|
|
}
|
|
|
|
public void addRecentSticker(TLRPC.Document document) {
|
|
if (document == null) {
|
|
return;
|
|
}
|
|
MediaDataController.getInstance(currentAccount).addRecentSticker(currentType, null, document, (int) (System.currentTimeMillis() / 1000), false);
|
|
boolean wasEmpty = recentStickers[currentType].isEmpty();
|
|
recentStickers[currentType] = MediaDataController.getInstance(currentAccount).getRecentStickers(currentType);
|
|
if (stickersGridAdapter != null) {
|
|
stickersGridAdapter.notifyDataSetChanged();
|
|
}
|
|
if (wasEmpty) {
|
|
updateStickerTabs();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
|
if (lastNotifyWidth != right - left) {
|
|
lastNotifyWidth = right - left;
|
|
reloadStickersAdapter();
|
|
}
|
|
super.onLayout(changed, left, top, right, bottom);
|
|
}
|
|
|
|
private void reloadStickersAdapter() {
|
|
if (stickersGridAdapter != null) {
|
|
stickersGridAdapter.notifyDataSetChanged();
|
|
}
|
|
if (ContentPreviewViewer.getInstance().isVisible()) {
|
|
ContentPreviewViewer.getInstance().close();
|
|
}
|
|
ContentPreviewViewer.getInstance().reset();
|
|
}
|
|
|
|
public void setListener(Listener value) {
|
|
listener = value;
|
|
}
|
|
|
|
@Override
|
|
protected void onAttachedToWindow() {
|
|
super.onAttachedToWindow();
|
|
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.stickersDidLoad);
|
|
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.recentDocumentsDidLoad);
|
|
AndroidUtilities.runOnUIThread(() -> {
|
|
updateStickerTabs();
|
|
reloadStickersAdapter();
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public void setVisibility(int visibility) {
|
|
super.setVisibility(visibility);
|
|
if (visibility != GONE) {
|
|
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.stickersDidLoad);
|
|
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.recentDocumentsDidLoad);
|
|
updateStickerTabs();
|
|
reloadStickersAdapter();
|
|
checkDocuments();
|
|
MediaDataController.getInstance(currentAccount).loadRecents(MediaDataController.TYPE_IMAGE, false, true, false);
|
|
MediaDataController.getInstance(currentAccount).loadRecents(MediaDataController.TYPE_MASK, false, true, false);
|
|
MediaDataController.getInstance(currentAccount).loadRecents(MediaDataController.TYPE_FAVE, false, true, false);
|
|
}
|
|
}
|
|
|
|
public void onDestroy() {
|
|
if (stickersGridAdapter != null) {
|
|
NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.stickersDidLoad);
|
|
NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.recentDocumentsDidLoad);
|
|
}
|
|
}
|
|
|
|
private void checkDocuments() {
|
|
int previousCount = recentStickers[currentType].size();
|
|
recentStickers[currentType] = MediaDataController.getInstance(currentAccount).getRecentStickers(currentType);
|
|
if (stickersGridAdapter != null) {
|
|
stickersGridAdapter.notifyDataSetChanged();
|
|
}
|
|
if (previousCount != recentStickers[currentType].size()) {
|
|
updateStickerTabs();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void didReceivedNotification(int id, int account, Object... args) {
|
|
if (id == NotificationCenter.stickersDidLoad) {
|
|
if ((Integer) args[0] == currentType) {
|
|
updateStickerTabs();
|
|
reloadStickersAdapter();
|
|
checkPanels();
|
|
}
|
|
} else if (id == NotificationCenter.recentDocumentsDidLoad) {
|
|
boolean isGif = (Boolean) args[0];
|
|
if (!isGif && (Integer) args[1] == currentType) {
|
|
checkDocuments();
|
|
}
|
|
}
|
|
}
|
|
|
|
private class StickersGridAdapter extends RecyclerListView.SelectionAdapter {
|
|
|
|
private Context context;
|
|
private int stickersPerRow;
|
|
private SparseArray<TLRPC.TL_messages_stickerSet> rowStartPack = new SparseArray<>();
|
|
private HashMap<TLRPC.TL_messages_stickerSet, Integer> packStartRow = new HashMap<>();
|
|
private SparseArray<TLRPC.Document> cache = new SparseArray<>();
|
|
private SparseArray<TLRPC.TL_messages_stickerSet> positionsToSets = new SparseArray<>();
|
|
private int totalItems;
|
|
|
|
public StickersGridAdapter(Context context) {
|
|
this.context = context;
|
|
}
|
|
|
|
@Override
|
|
public int getItemCount() {
|
|
return totalItems != 0 ? totalItems + 1 : 0;
|
|
}
|
|
|
|
public Object getItem(int i) {
|
|
return cache.get(i);
|
|
}
|
|
|
|
public int getPositionForPack(TLRPC.TL_messages_stickerSet stickerSet) {
|
|
return packStartRow.get(stickerSet) * stickersPerRow;
|
|
}
|
|
|
|
@Override
|
|
public int getItemViewType(int position) {
|
|
if (cache.get(position) != null) {
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
public int getTabForPosition(int position) {
|
|
if (stickersPerRow == 0) {
|
|
int width = getMeasuredWidth();
|
|
if (width == 0) {
|
|
width = AndroidUtilities.displaySize.x;
|
|
}
|
|
stickersPerRow = width / AndroidUtilities.dp(72);
|
|
}
|
|
int row = position / stickersPerRow;
|
|
TLRPC.TL_messages_stickerSet pack = rowStartPack.get(row);
|
|
if (pack == null) {
|
|
return recentTabBum;
|
|
}
|
|
return stickerSets[currentType].indexOf(pack) + stickersTabOffset;
|
|
}
|
|
|
|
@Override
|
|
public boolean isEnabled(RecyclerView.ViewHolder holder) {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
|
View view = null;
|
|
switch (viewType) {
|
|
case 0:
|
|
view = new StickerEmojiCell(context) {
|
|
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(82), MeasureSpec.EXACTLY));
|
|
}
|
|
};
|
|
break;
|
|
case 1:
|
|
view = new EmptyCell(context);
|
|
break;
|
|
}
|
|
|
|
return new RecyclerListView.Holder(view);
|
|
}
|
|
|
|
@Override
|
|
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
|
|
switch (holder.getItemViewType()) {
|
|
case 0:
|
|
TLRPC.Document sticker = cache.get(position);
|
|
((StickerEmojiCell) holder.itemView).setSticker(sticker, positionsToSets.get(position), false);
|
|
break;
|
|
case 1:
|
|
if (position == totalItems) {
|
|
int row = (position - 1) / stickersPerRow;
|
|
TLRPC.TL_messages_stickerSet pack = rowStartPack.get(row);
|
|
if (pack == null) {
|
|
((EmptyCell) holder.itemView).setHeight(1);
|
|
} else {
|
|
int height = stickersGridView.getMeasuredHeight() - (int) Math.ceil(pack.documents.size() / (float) stickersPerRow) * AndroidUtilities.dp(82);
|
|
((EmptyCell) holder.itemView).setHeight(height > 0 ? height : 1);
|
|
}
|
|
} else {
|
|
((EmptyCell) holder.itemView).setHeight(AndroidUtilities.dp(82));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void notifyDataSetChanged() {
|
|
int width = getMeasuredWidth();
|
|
if (width == 0) {
|
|
width = AndroidUtilities.displaySize.x;
|
|
}
|
|
stickersPerRow = width / AndroidUtilities.dp(72);
|
|
stickersLayoutManager.setSpanCount(stickersPerRow);
|
|
rowStartPack.clear();
|
|
packStartRow.clear();
|
|
cache.clear();
|
|
positionsToSets.clear();
|
|
totalItems = 0;
|
|
ArrayList<TLRPC.TL_messages_stickerSet> packs = stickerSets[currentType];
|
|
for (int a = -1; a < packs.size(); a++) {
|
|
ArrayList<TLRPC.Document> documents;
|
|
TLRPC.TL_messages_stickerSet pack = null;
|
|
int startRow = totalItems / stickersPerRow;
|
|
if (a == -1) {
|
|
documents = recentStickers[currentType];
|
|
} else {
|
|
pack = packs.get(a);
|
|
documents = pack.documents;
|
|
packStartRow.put(pack, startRow);
|
|
}
|
|
if (documents.isEmpty()) {
|
|
continue;
|
|
}
|
|
int count = (int) Math.ceil(documents.size() / (float) stickersPerRow);
|
|
for (int b = 0; b < documents.size(); b++) {
|
|
cache.put(b + totalItems, documents.get(b));
|
|
positionsToSets.put(b + totalItems, pack);
|
|
}
|
|
totalItems += count * stickersPerRow;
|
|
for (int b = 0; b < count; b++) {
|
|
rowStartPack.put(startRow + b, pack);
|
|
}
|
|
}
|
|
super.notifyDataSetChanged();
|
|
}
|
|
}
|
|
}
|