NekoX/TMessagesProj/src/main/java/org/telegram/ui/Adapters/StickersAdapter.java

497 lines
20 KiB
Java
Raw Normal View History

2015-01-02 23:15:07 +01:00
/*
* This is the source code of Telegram for Android v. 2.0.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).
*
2019-01-23 18:03:33 +01:00
* Copyright Nikolai Kudashov, 2013-2018.
2015-01-02 23:15:07 +01:00
*/
package org.telegram.ui.Adapters;
import android.content.Context;
2015-10-29 18:10:07 +01:00
import android.text.TextUtils;
2019-05-14 14:08:05 +02:00
import android.view.View;
2015-01-02 23:15:07 +01:00
import android.view.ViewGroup;
2018-07-30 04:07:02 +02:00
import org.telegram.messenger.AndroidUtilities;
2019-07-18 15:01:39 +02:00
import org.telegram.messenger.MediaDataController;
2018-07-30 04:07:02 +02:00
import org.telegram.messenger.Emoji;
2019-05-14 14:08:05 +02:00
import org.telegram.messenger.ImageLocation;
2019-07-18 15:01:39 +02:00
import org.telegram.messenger.MessageObject;
2015-09-24 22:52:02 +02:00
import org.telegram.messenger.NotificationCenter;
2018-07-30 04:07:02 +02:00
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.UserConfig;
2015-01-02 23:15:07 +01:00
import org.telegram.messenger.FileLoader;
2018-07-30 04:07:02 +02:00
import org.telegram.tgnet.ConnectionsManager;
2015-09-24 22:52:02 +02:00
import org.telegram.tgnet.TLRPC;
2019-05-14 14:08:05 +02:00
import org.telegram.ui.Cells.EmojiReplacementCell;
2015-01-02 23:15:07 +01:00
import org.telegram.ui.Cells.StickerCell;
2017-03-31 01:58:05 +02:00
import org.telegram.ui.Components.RecyclerListView;
2015-01-02 23:15:07 +01:00
import java.io.File;
import java.util.ArrayList;
2019-05-14 14:08:05 +02:00
import java.util.Arrays;
2016-05-25 23:49:47 +02:00
import java.util.Collections;
import java.util.Comparator;
2015-01-02 23:15:07 +01:00
import java.util.HashMap;
2019-05-14 14:08:05 +02:00
import androidx.recyclerview.widget.RecyclerView;
2017-03-31 01:58:05 +02:00
public class StickersAdapter extends RecyclerListView.SelectionAdapter implements NotificationCenter.NotificationCenterDelegate {
2015-01-02 23:15:07 +01:00
2020-03-30 14:00:09 +02:00
private static class StickerResult {
2019-07-18 15:01:39 +02:00
public TLRPC.Document sticker;
public Object parent;
public StickerResult(TLRPC.Document s, Object p) {
sticker = s;
parent = p;
}
}
2018-07-30 04:07:02 +02:00
private int currentAccount = UserConfig.selectedAccount;
2015-01-02 23:15:07 +01:00
private Context mContext;
2019-07-18 15:01:39 +02:00
private ArrayList<MediaDataController.KeywordResult> keywordResults;
private ArrayList<StickerResult> stickers;
2018-07-30 04:07:02 +02:00
private HashMap<String, TLRPC.Document> stickersMap;
2015-01-02 23:15:07 +01:00
private ArrayList<String> stickersToLoad = new ArrayList<>();
private StickersAdapterDelegate delegate;
private String lastSticker;
private boolean visible;
2018-07-30 04:07:02 +02:00
private int lastReqId;
private boolean delayLocalResults;
2019-05-14 14:08:05 +02:00
private String[] lastSearchKeyboardLanguage;
private Runnable searchRunnable;
2015-01-02 23:15:07 +01:00
public interface StickersAdapterDelegate {
void needChangePanelVisibility(boolean show);
2015-01-02 23:15:07 +01:00
}
public StickersAdapter(Context context, StickersAdapterDelegate delegate) {
mContext = context;
this.delegate = delegate;
2019-07-18 15:01:39 +02:00
MediaDataController.getInstance(currentAccount).checkStickers(MediaDataController.TYPE_IMAGE);
MediaDataController.getInstance(currentAccount).checkStickers(MediaDataController.TYPE_MASK);
2019-05-14 14:08:05 +02:00
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.newEmojiSuggestionsAvailable);
2019-01-23 18:03:33 +01:00
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.fileDidLoad);
2019-09-10 12:56:11 +02:00
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.fileDidFailToLoad);
2015-01-02 23:15:07 +01:00
}
2015-06-29 19:12:11 +02:00
public void onDestroy() {
2019-05-14 14:08:05 +02:00
NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.newEmojiSuggestionsAvailable);
2019-01-23 18:03:33 +01:00
NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.fileDidLoad);
2019-09-10 12:56:11 +02:00
NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.fileDidFailToLoad);
2015-01-02 23:15:07 +01:00
}
@Override
2018-07-30 04:07:02 +02:00
public void didReceivedNotification(int id, int account, final Object... args) {
2019-09-10 12:56:11 +02:00
if (id == NotificationCenter.fileDidLoad || id == NotificationCenter.fileDidFailToLoad) {
2015-05-21 23:27:27 +02:00
if (stickers != null && !stickers.isEmpty() && !stickersToLoad.isEmpty() && visible) {
String fileName = (String) args[0];
stickersToLoad.remove(fileName);
if (stickersToLoad.isEmpty()) {
2019-05-14 14:08:05 +02:00
boolean show = stickers != null && !stickers.isEmpty() && stickersToLoad.isEmpty();
if (show) {
keywordResults = null;
}
delegate.needChangePanelVisibility(show);
2015-01-02 23:15:07 +01:00
}
2015-05-21 23:27:27 +02:00
}
2019-05-14 14:08:05 +02:00
} else if (id == NotificationCenter.newEmojiSuggestionsAvailable) {
if ((keywordResults == null || keywordResults.isEmpty()) && !TextUtils.isEmpty(lastSticker) && getItemCount() == 0) {
searchEmojiByKeyword();
}
2015-01-02 23:15:07 +01:00
}
}
private boolean checkStickerFilesExistAndDownload() {
if (stickers == null) {
return false;
}
stickersToLoad.clear();
2019-01-23 18:03:33 +01:00
int size = Math.min(6, stickers.size());
2015-01-02 23:15:07 +01:00
for (int a = 0; a < size; a++) {
2019-07-18 15:01:39 +02:00
StickerResult result = stickers.get(a);
TLRPC.PhotoSize thumb = FileLoader.getClosestPhotoSizeWithSize(result.sticker.thumbs, 90);
2020-09-30 15:48:47 +02:00
if (thumb instanceof TLRPC.TL_photoSize || thumb instanceof TLRPC.TL_photoSizeProgressive) {
2019-01-23 18:03:33 +01:00
File f = FileLoader.getPathToAttach(thumb, "webp", true);
if (!f.exists()) {
stickersToLoad.add(FileLoader.getAttachFileName(thumb, "webp"));
2019-07-18 15:01:39 +02:00
FileLoader.getInstance(currentAccount).loadFile(ImageLocation.getForDocument(thumb, result.sticker), result.parent, "webp", 1, 1);
2019-01-23 18:03:33 +01:00
}
2015-01-02 23:15:07 +01:00
}
}
return stickersToLoad.isEmpty();
}
2018-07-30 04:07:02 +02:00
private boolean isValidSticker(TLRPC.Document document, String emoji) {
for (int b = 0, size2 = document.attributes.size(); b < size2; b++) {
TLRPC.DocumentAttribute attribute = document.attributes.get(b);
if (attribute instanceof TLRPC.TL_documentAttributeSticker) {
if (attribute.alt != null && attribute.alt.contains(emoji)) {
return true;
}
break;
}
}
return false;
}
2019-01-23 18:03:33 +01:00
private void addStickerToResult(TLRPC.Document document, Object parent) {
2018-07-30 04:07:02 +02:00
if (document == null) {
return;
}
String key = document.dc_id + "_" + document.id;
if (stickersMap != null && stickersMap.containsKey(key)) {
return;
}
if (stickers == null) {
stickers = new ArrayList<>();
stickersMap = new HashMap<>();
}
2019-07-18 15:01:39 +02:00
stickers.add(new StickerResult(document, parent));
2018-07-30 04:07:02 +02:00
stickersMap.put(key, document);
}
2019-01-23 18:03:33 +01:00
private void addStickersToResult(ArrayList<TLRPC.Document> documents, Object parent) {
2018-07-30 04:07:02 +02:00
if (documents == null || documents.isEmpty()) {
return;
}
for (int a = 0, size = documents.size(); a < size; a++) {
TLRPC.Document document = documents.get(a);
String key = document.dc_id + "_" + document.id;
if (stickersMap != null && stickersMap.containsKey(key)) {
continue;
}
if (stickers == null) {
stickers = new ArrayList<>();
stickersMap = new HashMap<>();
}
2019-01-23 18:03:33 +01:00
for (int b = 0, size2 = document.attributes.size(); b < size2; b++) {
TLRPC.DocumentAttribute attribute = document.attributes.get(b);
if (attribute instanceof TLRPC.TL_documentAttributeSticker) {
2019-07-18 15:01:39 +02:00
parent = attribute.stickerset;
2019-01-23 18:03:33 +01:00
break;
}
}
2019-07-18 15:01:39 +02:00
stickers.add(new StickerResult(document, parent));
2018-07-30 04:07:02 +02:00
stickersMap.put(key, document);
}
}
2019-05-14 14:08:05 +02:00
public void hide() {
if (visible && (stickers != null || keywordResults != null && !keywordResults.isEmpty())) {
visible = false;
delegate.needChangePanelVisibility(false);
2018-07-30 04:07:02 +02:00
}
2019-05-14 14:08:05 +02:00
}
private void cancelEmojiSearch() {
if (searchRunnable != null) {
AndroidUtilities.cancelRunOnUIThread(searchRunnable);
searchRunnable = null;
}
}
private void searchEmojiByKeyword() {
String[] newLanguage = AndroidUtilities.getCurrentKeyboardLanguage();
if (!Arrays.equals(newLanguage, lastSearchKeyboardLanguage)) {
2019-07-18 15:01:39 +02:00
MediaDataController.getInstance(currentAccount).fetchNewEmojiKeywords(newLanguage);
2019-05-14 14:08:05 +02:00
}
lastSearchKeyboardLanguage = newLanguage;
String query = lastSticker;
cancelEmojiSearch();
2019-07-18 15:01:39 +02:00
searchRunnable = () -> MediaDataController.getInstance(currentAccount).getEmojiSuggestions(lastSearchKeyboardLanguage, query, true, (param, alias) -> {
2019-05-14 14:08:05 +02:00
if (query.equals(lastSticker)) {
if (!param.isEmpty()) {
keywordResults = param;
2015-10-29 18:10:07 +01:00
}
2019-05-14 14:08:05 +02:00
notifyDataSetChanged();
delegate.needChangePanelVisibility(visible = !param.isEmpty());
2015-10-29 18:10:07 +01:00
}
2019-05-14 14:08:05 +02:00
});
if (keywordResults == null || keywordResults.isEmpty()) {
AndroidUtilities.runOnUIThread(searchRunnable, 1000);
} else {
searchRunnable.run();
}
}
public void loadStikersForEmoji(CharSequence emoji, boolean emojiOnly) {
boolean searchEmoji = emoji != null && emoji.length() > 0 && emoji.length() <= 14;
String originalEmoji = emoji.toString();
int length = emoji.length();
for (int a = 0; a < length; a++) {
2020-01-03 16:45:22 +01:00
char ch = emoji.charAt(a);
char nch = a < length - 1 ? emoji.charAt(a + 1) : 0;
if (a < length - 1 && ch == 0xD83C && nch >= 0xDFFB && nch <= 0xDFFF) {
2019-05-14 14:08:05 +02:00
emoji = TextUtils.concat(emoji.subSequence(0, a), emoji.subSequence(a + 2, emoji.length()));
length -= 2;
a--;
2020-01-03 16:45:22 +01:00
} else if (ch == 0xfe0f) {
2019-05-14 14:08:05 +02:00
emoji = TextUtils.concat(emoji.subSequence(0, a), emoji.subSequence(a + 1, emoji.length()));
length--;
a--;
}
}
2020-03-30 14:00:09 +02:00
lastSticker = emoji.toString().trim();
2019-07-18 15:01:39 +02:00
stickersToLoad.clear();
2019-05-14 14:08:05 +02:00
boolean isValidEmoji = searchEmoji && (Emoji.isValidEmoji(originalEmoji) || Emoji.isValidEmoji(lastSticker));
2019-08-22 01:53:26 +02:00
if (isValidEmoji) {
TLRPC.Document animatedSticker = MediaDataController.getInstance(currentAccount).getEmojiAnimatedSticker(emoji);
if (animatedSticker != null) {
ArrayList<TLRPC.TL_messages_stickerSet> sets = MediaDataController.getInstance(currentAccount).getStickerSets(MediaDataController.TYPE_EMOJI);
File f = FileLoader.getPathToAttach(animatedSticker, true);
if (!f.exists()) {
FileLoader.getInstance(currentAccount).loadFile(ImageLocation.getForDocument(animatedSticker), sets.get(0), null, 1, 1);
}
}
}
2019-05-14 14:08:05 +02:00
if (emojiOnly || SharedConfig.suggestStickers == 2 || !isValidEmoji) {
2019-12-31 14:08:08 +01:00
if (visible && (emojiOnly || SharedConfig.suggestStickers == 2 || keywordResults == null || keywordResults.isEmpty())) {
2019-05-14 14:08:05 +02:00
visible = false;
delegate.needChangePanelVisibility(false);
notifyDataSetChanged();
}
if (!isValidEmoji) {
searchEmojiByKeyword();
2018-07-30 04:07:02 +02:00
}
2019-05-14 14:08:05 +02:00
return;
}
cancelEmojiSearch();
stickers = null;
stickersMap = null;
if (lastReqId != 0) {
ConnectionsManager.getInstance(currentAccount).cancelRequest(lastReqId, true);
lastReqId = 0;
}
2018-07-30 04:07:02 +02:00
2019-05-14 14:08:05 +02:00
delayLocalResults = false;
2019-07-18 15:01:39 +02:00
final ArrayList<TLRPC.Document> recentStickers = MediaDataController.getInstance(currentAccount).getRecentStickersNoCopy(MediaDataController.TYPE_IMAGE);
final ArrayList<TLRPC.Document> favsStickers = MediaDataController.getInstance(currentAccount).getRecentStickersNoCopy(MediaDataController.TYPE_FAVE);
2019-05-14 14:08:05 +02:00
int recentsAdded = 0;
2020-03-30 14:00:09 +02:00
for (int a = 0, size = Math.min(20, recentStickers.size()); a < size; a++) {
2019-05-14 14:08:05 +02:00
TLRPC.Document document = recentStickers.get(a);
if (isValidSticker(document, lastSticker)) {
addStickerToResult(document, "recent");
recentsAdded++;
if (recentsAdded >= 5) {
break;
2018-07-30 04:07:02 +02:00
}
}
2019-05-14 14:08:05 +02:00
}
for (int a = 0, size = favsStickers.size(); a < size; a++) {
TLRPC.Document document = favsStickers.get(a);
if (isValidSticker(document, lastSticker)) {
addStickerToResult(document, "fav");
2018-07-30 04:07:02 +02:00
}
2019-05-14 14:08:05 +02:00
}
2016-10-11 13:57:01 +02:00
2019-07-18 15:01:39 +02:00
HashMap<String, ArrayList<TLRPC.Document>> allStickers = MediaDataController.getInstance(currentAccount).getAllStickers();
2019-05-14 14:08:05 +02:00
ArrayList<TLRPC.Document> newStickers = allStickers != null ? allStickers.get(lastSticker) : null;
if (newStickers != null && !newStickers.isEmpty()) {
2019-07-18 15:01:39 +02:00
addStickersToResult(newStickers, null);
}
if (stickers != null) {
Collections.sort(stickers, new Comparator<StickerResult>() {
2020-03-30 14:00:09 +02:00
private int getIndex(StickerResult result) {
2019-07-18 15:01:39 +02:00
for (int a = 0; a < favsStickers.size(); a++) {
2020-03-30 14:00:09 +02:00
if (favsStickers.get(a).id == result.sticker.id) {
return a + 2000000;
2016-05-25 23:49:47 +02:00
}
2019-07-18 15:01:39 +02:00
}
2020-03-30 14:00:09 +02:00
for (int a = 0; a < Math.min(20, recentStickers.size()); a++) {
if (recentStickers.get(a).id == result.sticker.id) {
return recentStickers.size() - a + 1000000;
2018-07-30 04:07:02 +02:00
}
2019-05-14 14:08:05 +02:00
}
2019-07-18 15:01:39 +02:00
return -1;
}
2019-01-23 18:03:33 +01:00
2019-07-18 15:01:39 +02:00
@Override
public int compare(StickerResult lhs, StickerResult rhs) {
2019-12-31 14:08:08 +01:00
boolean isAnimated1 = MessageObject.isAnimatedStickerDocument(lhs.sticker, true);
boolean isAnimated2 = MessageObject.isAnimatedStickerDocument(rhs.sticker, true);
2019-07-18 15:01:39 +02:00
if (isAnimated1 == isAnimated2) {
2020-03-30 14:00:09 +02:00
int idx1 = getIndex(lhs);
int idx2 = getIndex(rhs);
2019-05-14 14:08:05 +02:00
if (idx1 > idx2) {
return -1;
} else if (idx1 < idx2) {
return 1;
}
return 0;
2019-07-18 15:01:39 +02:00
} else {
if (isAnimated1 && !isAnimated2) {
return -1;
} else {
return 1;
}
2019-05-14 14:08:05 +02:00
}
2019-07-18 15:01:39 +02:00
}
});
2019-05-14 14:08:05 +02:00
}
if (SharedConfig.suggestStickers == 0) {
searchServerStickers(lastSticker, originalEmoji);
}
if (stickers != null && !stickers.isEmpty()) {
if (SharedConfig.suggestStickers == 0 && stickers.size() < 5) {
delayLocalResults = true;
2018-07-30 04:07:02 +02:00
delegate.needChangePanelVisibility(false);
visible = false;
2019-05-14 14:08:05 +02:00
} else {
checkStickerFilesExistAndDownload();
2019-07-18 15:01:39 +02:00
boolean show = stickersToLoad.isEmpty();
2019-05-14 14:08:05 +02:00
if (show) {
keywordResults = null;
}
delegate.needChangePanelVisibility(show);
visible = true;
2015-01-02 23:15:07 +01:00
}
2019-05-14 14:08:05 +02:00
notifyDataSetChanged();
} else if (visible) {
delegate.needChangePanelVisibility(false);
visible = false;
2015-01-02 23:15:07 +01:00
}
}
2019-01-23 18:03:33 +01:00
private void searchServerStickers(final String emoji, final String originalEmoji) {
2018-07-30 04:07:02 +02:00
TLRPC.TL_messages_getStickers req = new TLRPC.TL_messages_getStickers();
2019-01-23 18:03:33 +01:00
req.emoticon = originalEmoji;
2018-07-30 04:07:02 +02:00
req.hash = 0;
2018-08-27 10:33:11 +02:00
lastReqId = ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
lastReqId = 0;
if (!emoji.equals(lastSticker) || !(response instanceof TLRPC.TL_messages_stickers)) {
return;
}
delayLocalResults = false;
TLRPC.TL_messages_stickers res = (TLRPC.TL_messages_stickers) response;
int oldCount = stickers != null ? stickers.size() : 0;
2019-01-23 18:03:33 +01:00
addStickersToResult(res.stickers, "sticker_search_" + emoji);
2018-08-27 10:33:11 +02:00
int newCount = stickers != null ? stickers.size() : 0;
if (!visible && stickers != null && !stickers.isEmpty()) {
checkStickerFilesExistAndDownload();
2019-07-18 15:01:39 +02:00
boolean show = stickersToLoad.isEmpty();
2019-05-14 14:08:05 +02:00
if (show) {
keywordResults = null;
}
delegate.needChangePanelVisibility(show);
2018-08-27 10:33:11 +02:00
visible = true;
}
if (oldCount != newCount) {
notifyDataSetChanged();
2018-07-30 04:07:02 +02:00
}
2018-08-27 10:33:11 +02:00
}));
2018-07-30 04:07:02 +02:00
}
2015-01-02 23:15:07 +01:00
public void clearStickers() {
2019-05-14 14:08:05 +02:00
if (delayLocalResults || lastReqId != 0) {
return;
}
2019-07-18 15:01:39 +02:00
if (stickersToLoad.isEmpty()) {
lastSticker = null;
stickers = null;
stickersMap = null;
}
2019-05-14 14:08:05 +02:00
keywordResults = null;
2015-01-02 23:15:07 +01:00
notifyDataSetChanged();
2018-07-30 04:07:02 +02:00
if (lastReqId != 0) {
ConnectionsManager.getInstance(currentAccount).cancelRequest(lastReqId, true);
lastReqId = 0;
}
2015-01-02 23:15:07 +01:00
}
2019-05-14 14:08:05 +02:00
public boolean isShowingKeywords() {
return keywordResults != null && !keywordResults.isEmpty();
}
2015-01-02 23:15:07 +01:00
@Override
public int getItemCount() {
2019-05-14 14:08:05 +02:00
if (keywordResults != null && !keywordResults.isEmpty()) {
return keywordResults.size();
}
2018-07-30 04:07:02 +02:00
return !delayLocalResults && stickers != null ? stickers.size() : 0;
2015-01-02 23:15:07 +01:00
}
2019-05-14 14:08:05 +02:00
public Object getItem(int i) {
if (keywordResults != null && !keywordResults.isEmpty()) {
2020-07-26 10:03:38 +02:00
return i >= 0 && i < keywordResults.size() ? keywordResults.get(i).emoji : null;
2019-05-14 14:08:05 +02:00
}
2019-07-18 15:01:39 +02:00
return stickers != null && i >= 0 && i < stickers.size() ? stickers.get(i).sticker : null;
2015-01-02 23:15:07 +01:00
}
2019-01-23 18:03:33 +01:00
public Object getItemParent(int i) {
2019-05-14 14:08:05 +02:00
if (keywordResults != null && !keywordResults.isEmpty()) {
return null;
}
2019-07-18 15:01:39 +02:00
return stickers != null && i >= 0 && i < stickers.size() ? stickers.get(i).parent : null;
2019-01-23 18:03:33 +01:00
}
2015-01-02 23:15:07 +01:00
@Override
2017-03-31 01:58:05 +02:00
public boolean isEnabled(RecyclerView.ViewHolder holder) {
2019-05-14 14:08:05 +02:00
return false;
2015-01-02 23:15:07 +01:00
}
@Override
2019-05-14 14:08:05 +02:00
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View view;
switch (viewType) {
case 0:
view = new StickerCell(mContext);
break;
case 1:
default:
view = new EmojiReplacementCell(mContext);
}
2017-03-31 01:58:05 +02:00
return new RecyclerListView.Holder(view);
2015-01-02 23:15:07 +01:00
}
@Override
2019-05-14 14:08:05 +02:00
public int getItemViewType(int position) {
if (keywordResults != null && !keywordResults.isEmpty()) {
return 1;
}
return 0;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case 0: {
int side = 0;
if (position == 0) {
if (stickers.size() == 1) {
side = 2;
} else {
side = -1;
}
} else if (position == stickers.size() - 1) {
side = 1;
}
StickerCell stickerCell = (StickerCell) holder.itemView;
2019-07-18 15:01:39 +02:00
StickerResult result = stickers.get(position);
stickerCell.setSticker(result.sticker, result.parent, side);
2019-05-14 14:08:05 +02:00
stickerCell.setClearsInputField(true);
break;
}
case 1: {
int side = 0;
if (position == 0) {
if (keywordResults.size() == 1) {
side = 2;
} else {
side = -1;
}
} else if (position == keywordResults.size() - 1) {
side = 1;
}
EmojiReplacementCell cell = (EmojiReplacementCell) holder.itemView;
cell.setEmoji(keywordResults.get(position).emoji, side);
break;
2015-01-02 23:15:07 +01:00
}
}
}
}