NekoX/TMessagesProj/src/main/java/org/telegram/messenger/Emoji.java

708 lines
26 KiB
Java
Raw Normal View History

2013-10-25 17:19:00 +02:00
/*
2019-01-23 18:03:33 +01:00
* This is the source code of Telegram for Android v. 5.x.x.
2013-10-25 17:19:00 +02:00
* 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.
2013-10-25 17:19:00 +02:00
*/
2015-09-24 22:52:02 +02:00
package org.telegram.messenger;
2013-10-25 17:19:00 +02:00
import java.io.File;
2013-10-25 17:19:00 +02:00
import java.io.InputStream;
2017-12-08 18:35:59 +01:00
import java.util.ArrayList;
import java.util.Collections;
2013-10-25 17:19:00 +02:00
import java.util.HashMap;
import java.util.Locale;
2013-10-25 17:19:00 +02:00
2017-12-08 18:35:59 +01:00
import android.content.SharedPreferences;
2014-10-30 22:27:41 +01:00
import android.graphics.Bitmap;
2013-10-25 17:19:00 +02:00
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
2015-10-29 18:10:07 +01:00
import android.graphics.PixelFormat;
2013-10-25 17:19:00 +02:00
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
2016-10-11 13:57:01 +02:00
import android.os.Build;
2013-10-25 17:19:00 +02:00
import android.text.Spannable;
2015-06-29 19:12:11 +02:00
import android.text.Spanned;
2021-08-31 21:06:39 +02:00
import android.text.TextUtils;
2013-10-25 17:19:00 +02:00
import android.text.style.DynamicDrawableSpan;
import android.text.style.ImageSpan;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class Emoji {
2017-12-08 18:35:59 +01:00
2015-10-29 18:10:07 +01:00
private static HashMap<CharSequence, DrawableInfo> rects = new HashMap<>();
2015-07-22 20:56:37 +02:00
private static int drawImgSize;
private static int bigImgSize;
2015-07-22 20:56:37 +02:00
private static boolean inited = false;
private static Paint placeholderPaint;
2021-08-05 22:35:18 +02:00
private static int[] emojiCounts = new int[]{1906, 199, 123, 332, 128, 222, 292, 259};
2020-01-03 16:45:22 +01:00
private static Bitmap[][] emojiBmp = new Bitmap[8][];
private static boolean[][] loadingEmoji = new boolean[8][];
2015-10-29 18:10:07 +01:00
2017-12-08 18:35:59 +01:00
public static HashMap<String, Integer> emojiUseHistory = new HashMap<>();
public static ArrayList<String> recentEmoji = new ArrayList<>();
public static HashMap<String, String> emojiColor = new HashMap<>();
private static boolean recentEmojiLoaded;
2021-06-25 02:43:10 +02:00
private static Runnable invalidateUiRunnable = () -> NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.emojiLoaded);
2017-12-08 18:35:59 +01:00
2019-05-14 14:08:05 +02:00
private final static int MAX_RECENT_EMOJI_COUNT = 48;
2015-07-22 20:56:37 +02:00
static {
drawImgSize = AndroidUtilities.dp(20);
2019-05-14 14:08:05 +02:00
bigImgSize = AndroidUtilities.dp(AndroidUtilities.isTablet() ? 40 : 34);
2020-01-03 16:45:22 +01:00
for (int a = 0; a < emojiBmp.length; a++) {
emojiBmp[a] = new Bitmap[emojiCounts[a]];
loadingEmoji[a] = new boolean[emojiCounts[a]];
}
2015-10-29 18:10:07 +01:00
for (int j = 0; j < EmojiData.data.length; j++) {
int position;
for (int i = 0; i < EmojiData.data[j].length; i++) {
2020-01-03 16:45:22 +01:00
rects.put(EmojiData.data[j][i], new DrawableInfo((byte) j, (short) i, i));
2015-07-22 20:56:37 +02:00
}
}
placeholderPaint = new Paint();
placeholderPaint.setColor(0x00000000);
}
public static void preloadEmoji(CharSequence code) {
final DrawableInfo info = getDrawableInfo(code);
if (info != null) {
loadEmoji(info.page, info.page2);
}
}
2020-01-03 16:45:22 +01:00
private static void loadEmoji(final byte page, final short page2) {
if (emojiBmp[page][page2] == null) {
if (loadingEmoji[page][page2]) {
return;
}
loadingEmoji[page][page2] = true;
Utilities.globalQueue.postRunnable(() -> {
loadEmojiInternal(page, page2);
loadingEmoji[page][page2] = false;
});
}
}
private static void loadEmojiInternal(final byte page, final short page2) {
2015-07-22 20:56:37 +02:00
try {
2021-08-05 22:35:18 +02:00
int imageResize;
if (AndroidUtilities.density <= 1.0f) {
imageResize = 2;
} else {
2021-08-05 22:35:18 +02:00
imageResize = 1;
2013-10-25 17:19:00 +02:00
}
String imageName;
File imageFile;
2016-10-11 13:57:01 +02:00
Bitmap bitmap = null;
try {
2020-01-03 16:45:22 +01:00
InputStream is = ApplicationLoader.applicationContext.getAssets().open("emoji/" + String.format(Locale.US, "%d_%d.png", page, page2));
2016-10-11 13:57:01 +02:00
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = false;
opts.inSampleSize = imageResize;
bitmap = BitmapFactory.decodeStream(is, null, opts);
is.close();
2016-10-11 13:57:01 +02:00
} catch (Throwable e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2013-10-25 17:19:00 +02:00
}
2016-10-11 13:57:01 +02:00
final Bitmap finalBitmap = bitmap;
2020-01-03 16:45:22 +01:00
emojiBmp[page][page2] = finalBitmap;
AndroidUtilities.cancelRunOnUIThread(invalidateUiRunnable);
AndroidUtilities.runOnUIThread(invalidateUiRunnable);
2015-07-22 20:56:37 +02:00
} catch (Throwable x) {
2018-07-30 04:07:02 +02:00
if (BuildVars.LOGS_ENABLED) {
FileLog.e("Error loading emoji", x);
}
2013-10-25 17:19:00 +02:00
}
2015-07-22 20:56:37 +02:00
}
public static void invalidateAll(View view) {
if (view instanceof ViewGroup) {
ViewGroup g = (ViewGroup) view;
for (int i = 0; i < g.getChildCount(); i++) {
invalidateAll(g.getChildAt(i));
}
} else if (view instanceof TextView) {
view.invalidate();
}
}
2015-10-29 18:10:07 +01:00
public static String fixEmoji(String emoji) {
char ch;
2018-07-30 04:07:02 +02:00
int length = emoji.length();
for (int a = 0; a < length; a++) {
2015-10-29 18:10:07 +01:00
ch = emoji.charAt(a);
if (ch >= 0xD83C && ch <= 0xD83E) {
2018-07-30 04:07:02 +02:00
if (ch == 0xD83C && a < length - 1) {
2015-10-29 18:10:07 +01:00
ch = emoji.charAt(a + 1);
if (ch == 0xDE2F || ch == 0xDC04 || ch == 0xDE1A || ch == 0xDD7F) {
emoji = emoji.substring(0, a + 2) + "\uFE0F" + emoji.substring(a + 2);
2018-07-30 04:07:02 +02:00
length++;
2015-10-29 18:10:07 +01:00
a += 2;
} else {
a++;
}
} else {
a++;
}
} else if (ch == 0x20E3) {
return emoji;
} else if (ch >= 0x203C && ch <= 0x3299) {
if (EmojiData.emojiToFE0FMap.containsKey(ch)) {
emoji = emoji.substring(0, a + 1) + "\uFE0F" + emoji.substring(a + 1);
2018-07-30 04:07:02 +02:00
length++;
2015-10-29 18:10:07 +01:00
a++;
}
}
}
return emoji;
}
public static EmojiDrawable getEmojiDrawable(CharSequence code) {
DrawableInfo info = getDrawableInfo(code);
2015-07-22 20:56:37 +02:00
if (info == null) {
2013-10-25 17:19:00 +02:00
return null;
}
2015-07-22 20:56:37 +02:00
EmojiDrawable ed = new EmojiDrawable(info);
ed.setBounds(0, 0, drawImgSize, drawImgSize);
return ed;
}
private static DrawableInfo getDrawableInfo(CharSequence code) {
DrawableInfo info = rects.get(code);
if (info == null) {
CharSequence newCode = EmojiData.emojiAliasMap.get(code);
if (newCode != null) {
info = Emoji.rects.get(newCode);
}
}
return info;
}
2019-09-10 12:56:11 +02:00
public static boolean isValidEmoji(CharSequence code) {
2021-08-31 21:06:39 +02:00
if (TextUtils.isEmpty(code)) {
return false;
}
2018-07-30 04:07:02 +02:00
DrawableInfo info = rects.get(code);
if (info == null) {
CharSequence newCode = EmojiData.emojiAliasMap.get(code);
if (newCode != null) {
info = Emoji.rects.get(newCode);
}
}
return info != null;
}
2015-10-29 18:10:07 +01:00
public static Drawable getEmojiBigDrawable(String code) {
2015-07-22 20:56:37 +02:00
EmojiDrawable ed = getEmojiDrawable(code);
2017-12-08 18:35:59 +01:00
if (ed == null) {
CharSequence newCode = EmojiData.emojiAliasMap.get(code);
if (newCode != null) {
ed = Emoji.getEmojiDrawable(newCode);
}
}
2015-07-22 20:56:37 +02:00
if (ed == null) {
return null;
}
ed.setBounds(0, 0, bigImgSize, bigImgSize);
ed.fullSize = true;
return ed;
}
public static class EmojiDrawable extends Drawable {
private DrawableInfo info;
2015-07-22 20:56:37 +02:00
private boolean fullSize = false;
2015-10-29 18:10:07 +01:00
private static Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
private static Rect rect = new Rect();
2015-07-22 20:56:37 +02:00
public EmojiDrawable(DrawableInfo i) {
info = i;
}
2014-10-30 22:27:41 +01:00
public DrawableInfo getDrawableInfo() {
return info;
}
public Rect getDrawRect() {
2015-10-29 18:10:07 +01:00
Rect original = getBounds();
int cX = original.centerX(), cY = original.centerY();
rect.left = cX - (fullSize ? bigImgSize : drawImgSize) / 2;
rect.right = cX + (fullSize ? bigImgSize : drawImgSize) / 2;
rect.top = cY - (fullSize ? bigImgSize : drawImgSize) / 2;
rect.bottom = cY + (fullSize ? bigImgSize : drawImgSize) / 2;
return rect;
2014-10-30 22:27:41 +01:00
}
@Override
2015-07-22 20:56:37 +02:00
public void draw(Canvas canvas) {
2016-10-11 13:57:01 +02:00
/*if (MessagesController.getInstance().useSystemEmoji) {
//textPaint.setTextSize(getBounds().width());
canvas.drawText(EmojiData.data[info.page][info.emojiIndex], getBounds().left, getBounds().bottom, textPaint);
return;
}*/
2020-08-14 18:58:22 +02:00
if (!isLoaded()) {
loadEmoji(info.page, info.page2);
2015-07-22 20:56:37 +02:00
canvas.drawRect(getBounds(), placeholderPaint);
return;
}
2015-10-29 18:10:07 +01:00
2014-10-31 20:02:29 +01:00
Rect b;
if (fullSize) {
b = getDrawRect();
} else {
b = getBounds();
}
2020-12-23 08:48:30 +01:00
if (!canvas.quickReject(b.left, b.top, b.right, b.bottom, Canvas.EdgeType.AA)) {
canvas.drawBitmap(emojiBmp[info.page][info.page2], null, b, paint);
}
2015-07-22 20:56:37 +02:00
}
2013-10-25 17:19:00 +02:00
2015-07-22 20:56:37 +02:00
@Override
public int getOpacity() {
2015-10-29 18:10:07 +01:00
return PixelFormat.TRANSPARENT;
2015-07-22 20:56:37 +02:00
}
2013-10-25 17:19:00 +02:00
2015-07-22 20:56:37 +02:00
@Override
public void setAlpha(int alpha) {
2021-07-15 16:24:57 +02:00
paint.setAlpha(alpha);
2013-10-25 17:19:00 +02:00
}
2015-07-22 20:56:37 +02:00
@Override
public void setColorFilter(ColorFilter cf) {
2013-10-25 17:19:00 +02:00
}
2020-08-14 18:58:22 +02:00
public boolean isLoaded() {
return emojiBmp[info.page][info.page2] != null;
}
public void preload() {
if (!isLoaded()) {
loadEmoji(info.page, info.page2);
}
}
2015-07-22 20:56:37 +02:00
}
private static class DrawableInfo {
public byte page;
2020-01-03 16:45:22 +01:00
public short page2;
2016-10-11 13:57:01 +02:00
public int emojiIndex;
2020-01-03 16:45:22 +01:00
public DrawableInfo(byte p, short p2, int index) {
page = p;
2015-10-29 18:10:07 +01:00
page2 = p2;
2016-10-11 13:57:01 +02:00
emojiIndex = index;
2015-07-22 20:56:37 +02:00
}
}
2013-10-25 17:19:00 +02:00
private static boolean inArray(char c, char[] a) {
for (char cc : a) {
if (cc == c) {
2013-10-25 17:19:00 +02:00
return true;
}
}
return false;
}
2015-07-22 20:56:37 +02:00
public static CharSequence replaceEmoji(CharSequence cs, Paint.FontMetricsInt fontMetrics, int size, boolean createNew) {
2016-10-11 13:57:01 +02:00
return replaceEmoji(cs, fontMetrics, size, createNew, null);
}
public static CharSequence replaceEmoji(CharSequence cs, Paint.FontMetricsInt fontMetrics, int size, boolean createNew, int[] emojiOnly) {
2018-07-30 04:07:02 +02:00
if (SharedConfig.useSystemEmoji || cs == null || cs.length() == 0) {
2013-10-25 17:19:00 +02:00
return cs;
}
Spannable s;
2015-07-22 20:56:37 +02:00
if (!createNew && cs instanceof Spannable) {
s = (Spannable) cs;
2013-10-25 17:19:00 +02:00
} else {
2015-07-22 20:56:37 +02:00
s = Spannable.Factory.getInstance().newSpannable(cs.toString());
2013-10-25 17:19:00 +02:00
}
long buf = 0;
2013-10-27 00:34:39 +02:00
int emojiCount = 0;
2015-10-29 18:10:07 +01:00
char c;
int startIndex = -1;
int startLength = 0;
int previousGoodIndex = 0;
StringBuilder emojiCode = new StringBuilder(16);
2017-03-31 01:58:05 +02:00
StringBuilder addionalCode = new StringBuilder(2);
2015-10-29 18:10:07 +01:00
boolean nextIsSkinTone;
EmojiDrawable drawable;
EmojiSpan span;
int length = cs.length();
boolean doneEmoji = false;
2017-03-31 01:58:05 +02:00
int nextValidLength;
boolean nextValid;
2020-12-23 08:48:30 +01:00
boolean notOnlyEmoji;
2015-07-22 20:56:37 +02:00
//s.setSpansCount(emojiCount);
2014-06-13 17:03:06 +02:00
try {
2015-10-29 18:10:07 +01:00
for (int i = 0; i < length; i++) {
c = cs.charAt(i);
2020-12-23 08:48:30 +01:00
notOnlyEmoji = false;
2015-10-29 18:10:07 +01:00
if (c >= 0xD83C && c <= 0xD83E || (buf != 0 && (buf & 0xFFFFFFFF00000000L) == 0 && (buf & 0xFFFF) == 0xD83C && (c >= 0xDDE6 && c <= 0xDDFF))) {
if (startIndex == -1) {
startIndex = i;
}
emojiCode.append(c);
startLength++;
2014-06-13 17:03:06 +02:00
buf <<= 16;
buf |= c;
2017-03-31 01:58:05 +02:00
} else if (emojiCode.length() > 0 && (c == 0x2640 || c == 0x2642 || c == 0x2695)) {
2016-10-11 13:57:01 +02:00
emojiCode.append(c);
startLength++;
buf = 0;
doneEmoji = true;
2014-06-13 17:03:06 +02:00
} else if (buf > 0 && (c & 0xF000) == 0xD000) {
2015-10-29 18:10:07 +01:00
emojiCode.append(c);
startLength++;
2014-06-13 17:03:06 +02:00
buf = 0;
2015-10-29 18:10:07 +01:00
doneEmoji = true;
2014-06-13 17:03:06 +02:00
} else if (c == 0x20E3) {
if (i > 0) {
2015-10-29 18:10:07 +01:00
char c2 = cs.charAt(previousGoodIndex);
if ((c2 >= '0' && c2 <= '9') || c2 == '#' || c2 == '*') {
startIndex = previousGoodIndex;
startLength = i - previousGoodIndex + 1;
emojiCode.append(c2);
emojiCode.append(c);
doneEmoji = true;
}
}
} else if ((c == 0x00A9 || c == 0x00AE || c >= 0x203C && c <= 0x3299) && EmojiData.dataCharsMap.containsKey(c)) {
if (startIndex == -1) {
startIndex = i;
}
startLength++;
emojiCode.append(c);
doneEmoji = true;
} else if (startIndex != -1) {
emojiCode.setLength(0);
startIndex = -1;
startLength = 0;
doneEmoji = false;
2016-10-11 13:57:01 +02:00
} else if (c != 0xfe0f) {
2020-12-23 08:48:30 +01:00
notOnlyEmoji = true;
2015-10-29 18:10:07 +01:00
}
2017-12-08 18:35:59 +01:00
if (doneEmoji && i + 2 < length) {
char next = cs.charAt(i + 1);
2020-01-03 16:45:22 +01:00
if (next == 0xD83C) {
2017-12-08 18:35:59 +01:00
next = cs.charAt(i + 2);
if (next >= 0xDFFB && next <= 0xDFFF) {
emojiCode.append(cs.subSequence(i + 1, i + 3));
startLength += 2;
i += 2;
}
} else if (emojiCode.length() >= 2 && emojiCode.charAt(0) == 0xD83C && emojiCode.charAt(1) == 0xDFF4 && next == 0xDB40) {
i++;
while (true) {
emojiCode.append(cs.subSequence(i, i + 2));
startLength += 2;
i += 2;
if (i >= cs.length() || cs.charAt(i) != 0xDB40) {
i--;
break;
}
}
2017-03-31 01:58:05 +02:00
}
}
2015-10-29 18:10:07 +01:00
previousGoodIndex = i;
2018-07-30 04:07:02 +02:00
char prevCh = c;
2015-10-29 18:10:07 +01:00
for (int a = 0; a < 3; a++) {
if (i + 1 < length) {
c = cs.charAt(i + 1);
if (a == 1) {
2016-10-11 13:57:01 +02:00
if (c == 0x200D && emojiCode.length() > 0) {
2020-12-23 08:48:30 +01:00
notOnlyEmoji = false;
2015-10-29 18:10:07 +01:00
emojiCode.append(c);
i++;
startLength++;
doneEmoji = false;
}
2020-12-23 08:48:30 +01:00
} else if (startIndex != -1 || prevCh == '*' || prevCh == '#' || prevCh >= '0' && prevCh <= '9') {
2015-10-29 18:10:07 +01:00
if (c >= 0xFE00 && c <= 0xFE0F) {
i++;
startLength++;
2020-12-23 08:48:30 +01:00
if (!doneEmoji) {
doneEmoji = i + 1 >= length;
}
2014-06-13 17:03:06 +02:00
}
}
}
2015-10-29 18:10:07 +01:00
}
2020-12-23 08:48:30 +01:00
if (notOnlyEmoji && emojiOnly != null) {
emojiOnly[0] = 0;
emojiOnly = null;
}
2017-03-31 01:58:05 +02:00
if (doneEmoji && i + 2 < length && cs.charAt(i + 1) == 0xD83C) {
char next = cs.charAt(i + 2);
if (next >= 0xDFFB && next <= 0xDFFF) {
emojiCode.append(cs.subSequence(i + 1, i + 3));
startLength += 2;
i += 2;
}
}
2015-10-29 18:10:07 +01:00
if (doneEmoji) {
2016-10-11 13:57:01 +02:00
if (emojiOnly != null) {
emojiOnly[0]++;
}
2017-12-08 18:35:59 +01:00
CharSequence code = emojiCode.subSequence(0, emojiCode.length());
drawable = Emoji.getEmojiDrawable(code);
2015-10-29 18:10:07 +01:00
if (drawable != null) {
span = new EmojiSpan(drawable, DynamicDrawableSpan.ALIGN_BOTTOM, size, fontMetrics);
s.setSpan(span, startIndex, startIndex + startLength, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
emojiCount++;
}
startLength = 0;
startIndex = -1;
emojiCode.setLength(0);
doneEmoji = false;
2013-10-25 17:19:00 +02:00
}
2021-08-05 22:35:18 +02:00
if ((Build.VERSION.SDK_INT < 23 || Build.VERSION.SDK_INT >= 29) && !BuildVars.DEBUG_PRIVATE_VERSION && emojiCount >= 50) {
2014-06-13 17:03:06 +02:00
break;
2013-10-25 17:19:00 +02:00
}
}
2014-06-13 17:03:06 +02:00
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2014-06-13 17:03:06 +02:00
return cs;
2013-10-25 17:19:00 +02:00
}
2020-07-26 10:03:38 +02:00
if (emojiOnly != null && emojiCode.length() != 0) {
emojiOnly[0] = 0;
}
2013-10-25 17:19:00 +02:00
return s;
}
public static class EmojiSpan extends ImageSpan {
2018-08-27 10:33:11 +02:00
private Paint.FontMetricsInt fontMetrics;
2014-10-30 22:27:41 +01:00
private int size = AndroidUtilities.dp(20);
2013-10-25 17:19:00 +02:00
2014-10-30 22:27:41 +01:00
public EmojiSpan(EmojiDrawable d, int verticalAlignment, int s, Paint.FontMetricsInt original) {
2013-10-25 17:19:00 +02:00
super(d, verticalAlignment);
fontMetrics = original;
if (original != null) {
size = Math.abs(fontMetrics.descent) + Math.abs(fontMetrics.ascent);
if (size == 0) {
size = AndroidUtilities.dp(20);
}
}
2013-10-25 17:19:00 +02:00
}
2016-10-11 13:57:01 +02:00
public void replaceFontMetrics(Paint.FontMetricsInt newMetrics, int newSize) {
fontMetrics = newMetrics;
size = newSize;
}
2013-10-25 17:19:00 +02:00
@Override
public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
if (fm == null) {
fm = new Paint.FontMetricsInt();
}
if (fontMetrics == null) {
int sz = super.getSize(paint, text, start, end, fm);
int offset = AndroidUtilities.dp(8);
int w = AndroidUtilities.dp(10);
fm.top = -w - offset;
fm.bottom = w - offset;
fm.ascent = -w - offset;
fm.leading = 0;
fm.descent = w - offset;
return sz;
} else {
if (fm != null) {
fm.ascent = fontMetrics.ascent;
fm.descent = fontMetrics.descent;
fm.top = fontMetrics.top;
fm.bottom = fontMetrics.bottom;
}
if (getDrawable() != null) {
getDrawable().setBounds(0, 0, size, size);
}
return size;
}
2013-10-25 17:19:00 +02:00
}
2021-07-15 16:24:57 +02:00
@Override
public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
boolean restoreAlpha = false;
if (paint.getAlpha() != 255) {
restoreAlpha = true;
getDrawable().setAlpha(paint.getAlpha());
}
super.draw(canvas, text, start, end, x, top, y, bottom, paint);
if (restoreAlpha) {
getDrawable().setAlpha(255);
}
}
2013-10-25 17:19:00 +02:00
}
2017-12-08 18:35:59 +01:00
public static void addRecentEmoji(String code) {
Integer count = emojiUseHistory.get(code);
if (count == null) {
count = 0;
}
2019-05-14 14:08:05 +02:00
if (count == 0 && emojiUseHistory.size() >= MAX_RECENT_EMOJI_COUNT) {
String emoji = recentEmoji.get(recentEmoji.size() - 1);
emojiUseHistory.remove(emoji);
recentEmoji.set(recentEmoji.size() - 1, code);
2017-12-08 18:35:59 +01:00
}
emojiUseHistory.put(code, ++count);
}
public static void sortEmoji() {
recentEmoji.clear();
for (HashMap.Entry<String, Integer> entry : emojiUseHistory.entrySet()) {
recentEmoji.add(entry.getKey());
}
2018-08-27 10:33:11 +02:00
Collections.sort(recentEmoji, (lhs, rhs) -> {
Integer count1 = emojiUseHistory.get(lhs);
Integer count2 = emojiUseHistory.get(rhs);
if (count1 == null) {
count1 = 0;
}
if (count2 == null) {
count2 = 0;
}
if (count1 > count2) {
return -1;
} else if (count1 < count2) {
return 1;
2017-12-08 18:35:59 +01:00
}
2018-08-27 10:33:11 +02:00
return 0;
2017-12-08 18:35:59 +01:00
});
2019-05-14 14:08:05 +02:00
while (recentEmoji.size() > MAX_RECENT_EMOJI_COUNT) {
2017-12-08 18:35:59 +01:00
recentEmoji.remove(recentEmoji.size() - 1);
}
}
public static void saveRecentEmoji() {
2018-07-30 04:07:02 +02:00
SharedPreferences preferences = MessagesController.getGlobalEmojiSettings();
2017-12-08 18:35:59 +01:00
StringBuilder stringBuilder = new StringBuilder();
for (HashMap.Entry<String, Integer> entry : emojiUseHistory.entrySet()) {
if (stringBuilder.length() != 0) {
stringBuilder.append(",");
}
stringBuilder.append(entry.getKey());
stringBuilder.append("=");
stringBuilder.append(entry.getValue());
}
preferences.edit().putString("emojis2", stringBuilder.toString()).commit();
}
public static void clearRecentEmoji() {
2018-07-30 04:07:02 +02:00
SharedPreferences preferences = MessagesController.getGlobalEmojiSettings();
2017-12-08 18:35:59 +01:00
preferences.edit().putBoolean("filled_default", true).commit();
emojiUseHistory.clear();
recentEmoji.clear();
saveRecentEmoji();
}
public static void loadRecentEmoji() {
if (recentEmojiLoaded) {
return;
}
recentEmojiLoaded = true;
2018-07-30 04:07:02 +02:00
SharedPreferences preferences = MessagesController.getGlobalEmojiSettings();
2017-12-08 18:35:59 +01:00
String str;
try {
emojiUseHistory.clear();
if (preferences.contains("emojis")) {
str = preferences.getString("emojis", "");
if (str != null && str.length() > 0) {
String[] args = str.split(",");
for (String arg : args) {
String[] args2 = arg.split("=");
long value = Utilities.parseLong(args2[0]);
2018-07-30 04:07:02 +02:00
StringBuilder string = new StringBuilder();
2017-12-08 18:35:59 +01:00
for (int a = 0; a < 4; a++) {
char ch = (char) value;
2019-09-10 12:56:11 +02:00
string.insert(0, ch);
2017-12-08 18:35:59 +01:00
value >>= 16;
if (value == 0) {
break;
}
}
if (string.length() > 0) {
2018-07-30 04:07:02 +02:00
emojiUseHistory.put(string.toString(), Utilities.parseInt(args2[1]));
2017-12-08 18:35:59 +01:00
}
}
}
preferences.edit().remove("emojis").commit();
saveRecentEmoji();
} else {
str = preferences.getString("emojis2", "");
if (str != null && str.length() > 0) {
String[] args = str.split(",");
for (String arg : args) {
String[] args2 = arg.split("=");
emojiUseHistory.put(args2[0], Utilities.parseInt(args2[1]));
}
}
}
if (emojiUseHistory.isEmpty()) {
if (!preferences.getBoolean("filled_default", false)) {
String[] newRecent = new String[]{
"\uD83D\uDE02", "\uD83D\uDE18", "\u2764", "\uD83D\uDE0D", "\uD83D\uDE0A", "\uD83D\uDE01",
"\uD83D\uDC4D", "\u263A", "\uD83D\uDE14", "\uD83D\uDE04", "\uD83D\uDE2D", "\uD83D\uDC8B",
"\uD83D\uDE12", "\uD83D\uDE33", "\uD83D\uDE1C", "\uD83D\uDE48", "\uD83D\uDE09", "\uD83D\uDE03",
"\uD83D\uDE22", "\uD83D\uDE1D", "\uD83D\uDE31", "\uD83D\uDE21", "\uD83D\uDE0F", "\uD83D\uDE1E",
"\uD83D\uDE05", "\uD83D\uDE1A", "\uD83D\uDE4A", "\uD83D\uDE0C", "\uD83D\uDE00", "\uD83D\uDE0B",
"\uD83D\uDE06", "\uD83D\uDC4C", "\uD83D\uDE10", "\uD83D\uDE15"};
for (int i = 0; i < newRecent.length; i++) {
emojiUseHistory.put(newRecent[i], newRecent.length - i);
}
preferences.edit().putBoolean("filled_default", true).commit();
saveRecentEmoji();
}
}
sortEmoji();
} catch (Exception e) {
FileLog.e(e);
}
try {
str = preferences.getString("color", "");
if (str != null && str.length() > 0) {
String[] args = str.split(",");
for (int a = 0; a < args.length; a++) {
String arg = args[a];
String[] args2 = arg.split("=");
emojiColor.put(args2[0], args2[1]);
}
}
} catch (Exception e) {
FileLog.e(e);
}
}
public static void saveEmojiColors() {
2018-07-30 04:07:02 +02:00
SharedPreferences preferences = MessagesController.getGlobalEmojiSettings();
2017-12-08 18:35:59 +01:00
StringBuilder stringBuilder = new StringBuilder();
for (HashMap.Entry<String, String> entry : emojiColor.entrySet()) {
if (stringBuilder.length() != 0) {
stringBuilder.append(",");
}
stringBuilder.append(entry.getKey());
stringBuilder.append("=");
stringBuilder.append(entry.getValue());
}
preferences.edit().putString("color", stringBuilder.toString()).commit();
}
2013-10-25 17:19:00 +02:00
}