mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-28 20:45:17 +00:00
192 lines
6.0 KiB
Java
192 lines
6.0 KiB
Java
package org.thoughtcrime.securesms.util;
|
|
|
|
import android.content.Context;
|
|
import android.content.SharedPreferences;
|
|
import android.graphics.Bitmap;
|
|
import android.graphics.BitmapFactory;
|
|
import android.graphics.drawable.BitmapDrawable;
|
|
import android.graphics.drawable.Drawable;
|
|
import android.preference.PreferenceManager;
|
|
import android.text.Spannable;
|
|
import android.text.SpannableString;
|
|
import android.text.style.ImageSpan;
|
|
import android.util.Log;
|
|
|
|
import com.google.thoughtcrimegson.Gson;
|
|
import com.google.thoughtcrimegson.reflect.TypeToken;
|
|
|
|
import org.thoughtcrime.securesms.R;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.lang.reflect.Type;
|
|
import java.util.Collection;
|
|
import java.util.Collections;
|
|
import java.util.HashSet;
|
|
import java.util.Iterator;
|
|
import java.util.LinkedHashSet;
|
|
import java.util.LinkedList;
|
|
import java.util.List;
|
|
import java.util.Set;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
public class Emoji {
|
|
|
|
private static Emoji instance = null;
|
|
|
|
public synchronized static Emoji getInstance(Context context) {
|
|
if (instance == null) {
|
|
instance = new Emoji(context);
|
|
}
|
|
|
|
return instance;
|
|
}
|
|
|
|
private static final Pattern EMOJI_RANGE = Pattern.compile("[\ud83d\ude01-\ud83d\ude4f]");
|
|
public static final double EMOJI_LARGE = 1;
|
|
public static final double EMOJI_SMALL = 0.7;
|
|
|
|
private final Context context;
|
|
private final String[] emojiAssets;
|
|
private final Set<String> emojiAssetsSet;
|
|
private final BitmapFactory.Options bitmapOptions;
|
|
|
|
private Emoji(Context context) {
|
|
this.context = context.getApplicationContext();
|
|
this.emojiAssets = initializeEmojiAssets();
|
|
this.emojiAssetsSet = new HashSet<String>();
|
|
this.bitmapOptions = initializeBitmapOptions();
|
|
|
|
Collections.addAll(this.emojiAssetsSet, emojiAssets);
|
|
}
|
|
|
|
public int getEmojiAssetCount() {
|
|
return emojiAssets.length;
|
|
}
|
|
|
|
public String getEmojiUnicode(int position) {
|
|
return getEmojiUnicodeFromAssetName(emojiAssets[position]);
|
|
}
|
|
|
|
public String getRecentEmojiUnicode(int position) {
|
|
return getEmojiUnicodeFromAssetName(EmojiLRU.getRecentlyUsed(context).get(position));
|
|
}
|
|
|
|
public Drawable getEmojiDrawable(int position) {
|
|
return getEmojiDrawable(emojiAssets[position]);
|
|
}
|
|
|
|
public SpannableString emojify(String text) {
|
|
return emojify(new SpannableString(text), EMOJI_LARGE);
|
|
}
|
|
|
|
public SpannableString emojify(SpannableString text, double size) {
|
|
if (text.toString().contains("\ud83d")) {
|
|
|
|
Matcher matches = EMOJI_RANGE.matcher(text);
|
|
|
|
while (matches.find()) {
|
|
String resource = Integer.toHexString(matches.group().codePointAt(0)) + ".png";
|
|
|
|
if (emojiAssetsSet.contains(resource)) {
|
|
Drawable drawable = getEmojiDrawable(resource);
|
|
drawable.setBounds(0, 0, (int)(drawable.getIntrinsicWidth()*size),
|
|
(int)(drawable.getIntrinsicHeight()*size));
|
|
|
|
ImageSpan imageSpan = new ImageSpan(drawable, ImageSpan.ALIGN_BOTTOM);
|
|
text.setSpan(imageSpan, matches.start(), matches.end(),
|
|
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
return text;
|
|
}
|
|
|
|
public void setRecentlyUsed(int position) {
|
|
String assetName = emojiAssets[position];
|
|
EmojiLRU.putRecentlyUsed(context, assetName);
|
|
}
|
|
|
|
public int getRecentlyUsedAssetCount() {
|
|
return EmojiLRU.getRecentlyUsed(context).size();
|
|
}
|
|
|
|
public Drawable getRecentlyUsed(int position) {
|
|
return getEmojiDrawable(EmojiLRU.getRecentlyUsed(context).get(position));
|
|
}
|
|
|
|
private String getEmojiUnicodeFromAssetName(String assetName) {
|
|
String hexString = assetName.split("\\.")[0];
|
|
Integer unicodePoint = Integer.parseInt(hexString, 16);
|
|
return new String(Character.toChars(unicodePoint));
|
|
}
|
|
|
|
private Drawable getEmojiDrawable(String assetName) {
|
|
try {
|
|
Bitmap bitmap = BitmapFactory.decodeStream(context.getAssets().open("emoji" + File.separator + assetName),
|
|
null, bitmapOptions);
|
|
|
|
bitmap = Bitmap.createScaledBitmap(bitmap, 40, 40, true);
|
|
|
|
return new BitmapDrawable(context.getResources(), bitmap);
|
|
} catch (IOException e) {
|
|
throw new AssertionError(e);
|
|
}
|
|
}
|
|
|
|
private String[] initializeEmojiAssets() {
|
|
try {
|
|
return context.getAssets().list("emoji");
|
|
} catch (IOException e) {
|
|
Log.w("Emoji", e);
|
|
return new String[0];
|
|
}
|
|
}
|
|
|
|
private BitmapFactory.Options initializeBitmapOptions() {
|
|
BitmapFactory.Options options = new BitmapFactory.Options();
|
|
|
|
options.inScaled = true;
|
|
// options.inDensity = 64;
|
|
options.inTargetDensity = context.getResources().getDimensionPixelSize(R.dimen.emoji_size);
|
|
options.inSampleSize = 1;
|
|
options.inJustDecodeBounds = false;
|
|
|
|
return options;
|
|
}
|
|
|
|
private static class EmojiLRU {
|
|
|
|
private static final String EMOJI_LRU_PREFERENCE = "pref_popular_emoji";
|
|
private static final int EMOJI_LRU_SIZE = 10;
|
|
|
|
public static List<String> getRecentlyUsed(Context context) {
|
|
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
|
|
String serialized = preferences.getString(EMOJI_LRU_PREFERENCE, "[]");
|
|
Type type = new TypeToken<Collection<String>>(){}.getType();
|
|
|
|
return new Gson().fromJson(serialized, type);
|
|
}
|
|
|
|
public static void putRecentlyUsed(Context context, String asset) {
|
|
LinkedHashSet<String> recentlyUsed = new LinkedHashSet<String>(getRecentlyUsed(context));
|
|
recentlyUsed.add(asset);
|
|
|
|
if (recentlyUsed.size() > 10) {
|
|
Iterator<String> iterator = recentlyUsed.iterator();
|
|
iterator.next();
|
|
iterator.remove();
|
|
}
|
|
|
|
String serialized = new Gson().toJson(recentlyUsed);
|
|
PreferenceManager.getDefaultSharedPreferences(context)
|
|
.edit()
|
|
.putString(EMOJI_LRU_PREFERENCE, serialized)
|
|
.commit();
|
|
}
|
|
}
|
|
}
|