Remove icu4j dependency

This commit is contained in:
Ammar Githam 2021-03-20 10:32:13 +09:00
parent 2590552b49
commit 0903804523
9 changed files with 70 additions and 6136 deletions

View File

@ -59,7 +59,7 @@ dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
def appcompat_version = "1.2.0"
def nav_version = '2.3.3'
def nav_version = '2.3.4'
def exoplayer_version = '2.12.0'
implementation 'com.google.android.material:material:1.4.0-alpha01'
@ -111,7 +111,6 @@ dependencies {
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'org.apache.commons:commons-imaging:1.0-alpha2'
implementation 'com.ibm.icu:icu4j:68.1'
implementation 'com.github.ammargitham:uCrop:2.3-native-beta-2'
implementation 'com.github.ammargitham:android-gpuimage:2.1.1-beta4'

View File

@ -16,35 +16,6 @@ public class EmojiCategory {
public EmojiCategory(final EmojiCategoryType type) {
this.type = type;
switch (type) {
case SMILEYS_AND_EMOTION:
drawableRes = R.drawable.ic_round_emoji_emotions_24;
break;
case ANIMALS_AND_NATURE:
drawableRes = R.drawable.ic_round_emoji_nature_24;
break;
case FOOD_AND_DRINK:
drawableRes = R.drawable.ic_round_emoji_food_beverage_24;
break;
case TRAVEL_AND_PLACES:
drawableRes = R.drawable.ic_round_emoji_transportation_24;
break;
case ACTIVITIES:
drawableRes = R.drawable.ic_round_emoji_events_24;
break;
case OBJECTS:
drawableRes = R.drawable.ic_round_emoji_objects_24;
break;
case SYMBOLS:
drawableRes = R.drawable.ic_round_emoji_symbols_24;
break;
case FLAGS:
drawableRes = R.drawable.ic_round_emoji_flags_24;
break;
case OTHERS:
drawableRes = R.drawable.ic_round_unknown_24;
break;
}
}
public EmojiCategoryType getType() {
@ -56,6 +27,37 @@ public class EmojiCategory {
}
public int getDrawableRes() {
if (drawableRes == 0) {
switch (type) {
case SMILEYS_AND_EMOTION:
drawableRes = R.drawable.ic_round_emoji_emotions_24;
break;
case ANIMALS_AND_NATURE:
drawableRes = R.drawable.ic_round_emoji_nature_24;
break;
case FOOD_AND_DRINK:
drawableRes = R.drawable.ic_round_emoji_food_beverage_24;
break;
case TRAVEL_AND_PLACES:
drawableRes = R.drawable.ic_round_emoji_transportation_24;
break;
case ACTIVITIES:
drawableRes = R.drawable.ic_round_emoji_events_24;
break;
case OBJECTS:
drawableRes = R.drawable.ic_round_emoji_objects_24;
break;
case SYMBOLS:
drawableRes = R.drawable.ic_round_emoji_symbols_24;
break;
case FLAGS:
drawableRes = R.drawable.ic_round_emoji_flags_24;
break;
case OTHERS:
drawableRes = R.drawable.ic_round_unknown_24;
break;
}
}
return drawableRes;
}

View File

@ -2,27 +2,25 @@ package awais.instagrabber.utils.emoji;
import android.util.Log;
import com.google.common.base.CharMatcher;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.lang.CharSequences;
import com.ibm.icu.text.UnicodeSet;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import awais.instagrabber.customviews.emoji.Emoji;
import awais.instagrabber.customviews.emoji.EmojiCategory;
import awais.instagrabber.customviews.emoji.EmojiCategoryType;
import awais.instagrabber.utils.NetworkUtils;
public final class EmojiParser {
private static final String TAG = EmojiParser.class.getSimpleName();
@ -30,51 +28,8 @@ public final class EmojiParser {
private static EmojiParser instance;
// private static final String COMBINING_ENCLOSING_KEYCAP = "\u20E3";
// private static final String ZWJ = "\u200D";
// private static final UnicodeSet REGIONAL_INDICATORS = new UnicodeSet(0x1F1E6, 0x1F1FF).freeze();
// private static final UnicodeSet TAGS = new UnicodeSet(0xE0000, 0xE007F).freeze();
// private static final UnicodeSet FAMILY = new UnicodeSet("[\u200D 👦-👩 💋 ❤]").freeze();
// private static final UnicodeSet GENDER = new UnicodeSet().add(0x2640).add(0x2642).freeze();
// private static final UnicodeSet SPECIALS = new UnicodeSet("["
// + "{🐈‍⬛}{🐻‍❄}{👨‍🍼}{👩‍🍼}{🧑‍🍼}{🧑‍🎄}{🧑‍🤝‍🧑}{🏳‍🌈} {👁‍🗨} {🏴‍☠} {🐕‍🦺} {👨‍🦯} {👨‍🦼} {👨‍🦽} {👩‍🦯} {👩‍🦼} {👩‍🦽}"
// + "{🏳‍⚧}{🧑‍⚕}{🧑‍⚖}{🧑‍✈}{🧑‍🌾}{🧑‍🍳}{🧑‍🎓}{🧑‍🎤}{🧑‍🎨}{🧑‍🏫}{🧑‍🏭}{🧑‍💻}{🧑‍💼}{🧑‍🔧}{🧑‍🔬}{🧑‍🚀}{🧑‍🚒}{🧑‍🦯}{🧑‍🦼}{🧑‍🦽}"
// + "{❤‍🔥}, {❤‍🩹}, {😮‍💨}, {😵‍💫}" // #E13.1
// + "]").freeze();
// May have to add from above, if there is a failure in testAnnotationPaths. Failure will be like:
// got java.util.TreeSet<[//ldml/annotations/annotation[@cp="🏳‍⚧"][@type="tts"], //ldml/annotations/annotation[@cp="🧑‍⚕"][@type="tts"], ...
// just extract the items in "...", and change into {...} for adding above.
// Example: //ldml/annotations/annotation[@cp="🧑‍⚕"] ==> {🧑}
// private static final UnicodeSet MAN_WOMAN = new UnicodeSet("[👨 👩]").freeze();
// private static final UnicodeSet OBJECT = new UnicodeSet("[👩 🎓 🌾 🍳 🏫 🏭 🎨 🚒 ✈ 🚀 🎤 💻 🔬 💼 🔧 ⚖ ⚕]").freeze();
// private static final String TYPE_TTS = "[@type=\"tts\"]";
private static final String EMOJI_VARIANT = "\uFE0F";
private static final UnicodeSet SKIN_TONE_MODIFIERS = new UnicodeSet("[🏻-🏿]").freeze();
private static final String SKIN_TONE_PATTERN = SKIN_TONE_MODIFIERS.toPattern(true);
private static final Map<EmojiCategoryType, EmojiCategory> CATEGORY_MAP = new LinkedHashMap<>();
private static final Map<String, Emoji> ALL_EMOJIS = new HashMap<>();
// private final UnicodeMap<String> emojiToMajorCategory = new UnicodeMap<>();
// private final UnicodeMap<String> emojiToMinorCategory = new UnicodeMap<>();
// private final UnicodeMap<String> toName = new UnicodeMap<>();
// /**
// * A mapping from a majorCategory to a unique ordering number, based on the first time it is encountered.
// */
// private final Map<String, Long> majorToOrder = new HashMap<>();
// private final List<String> majorToOrder = new LinkedList<String>();
// /**
// * A mapping from a minorCategory to a unique ordering number, based on the first time it is encountered.
// */
// private final Map<String, Long> minorToOrder = new HashMap<>();
// private final Map<String, Long> emojiToOrder = new LinkedHashMap<>();
// private final UnicodeSet nonConstructed = new UnicodeSet();
// private final UnicodeSet allRgi = new UnicodeSet();
// private final UnicodeSet allRgiNoES = new UnicodeSet();
// private final UnicodeMap<String> EXTRA_SYMBOL_MINOR_CATEGORIES = new UnicodeMap<>();
// private final Map<String, Long> EXTRA_SYMBOL_ORDER;
// private final boolean DEBUG = false;
// private Set<String> NAME_PATHS = null;
// private Set<String> KEYWORD_PATHS = null;
private Map<String, Emoji> allEmojis = Collections.emptyMap();
private Map<EmojiCategoryType, EmojiCategory> categoryMap = Collections.emptyMap();
private ImmutableList<EmojiCategory> categories;
public static EmojiParser getInstance() {
@ -89,267 +44,56 @@ public final class EmojiParser {
}
private EmojiParser() {
// Log.d(TAG, "Emoji: " + new Date());
// String[][] data = {
// {"arrow", "→ ↓ ↑ ← ↔ ↕ ⇆ ⇅"},
// {"alphanum", "© ® ℗ ™ µ"},
// {"geometric", "▼ ▶ ▲ ◀ ● ○ ◯ ◊"},
// {"math", "× ÷ √ ∞ ∆ ∇ ⁻ ¹ ² ³ ≡ ∈ ⊂ ∩ ° + ± = ≈ ≠ > < ≤ ≥ ¬ | ~"},
// {"punctuation", "§ † ‡ \\u0020 , 、 ، ; : ؛ ! ¡ ? ¿ ؟ ¶ ※ / \\ & # % ‰ ″ ‴ @ * ♪ ♭ ♯ ` ´ ^ ¨ ― _ - — • · . … 。 ‧ ・ ' “ ” „ » « ( ) [ ] { } 〈 〉 《 》 「 」 『 』 〖 〗 【 】"},
// {"currency", "€ £ ¥ ₹ ₽ $ ¢ ฿ ₪ ₺ ₫ ₱ ₩ ₡ ₦ ₮ ৳ ₴ ₸ ₲ ₵ ៛ ₭ ֏ ₥ ₾ ₼ ₿ ؋"},
// {"other-symbol", "‾‽‸⁂↚↛↮↙↜↝↞↟↠↡↢↣↤↥↦↧↨↫↬↭↯↰↱↲↳↴↵↶↷↸↹↺↻↼↽↾↿⇀⇁⇂⇃⇄⇇⇈⇉⇊⇋⇌⇐⇍⇑⇒⇏⇓⇔⇎⇖⇗⇘⇙⇚⇛⇜⇝⇞⇟⇠⇡⇢⇣⇤⇥⇦⇧⇨⇩⇪⇵∀∂∃∅∉∋∎∏∑≮≯∓∕⁄∗∘∙∝∟∠∣∥∧∫∬∮∴∵∶∷∼∽∾≃≅≌≒≖≣≦≧≪≫≬≳≺≻⊁⊃⊆⊇⊕⊖⊗⊘⊙⊚⊛⊞⊟⊥⊮⊰⊱⋭⊶⊹⊿⋁⋂⋃⋅⋆⋈⋒⋘⋙⋮⋯⋰⋱■□▢▣▤▥▦▧▨▩▬▭▮▰△▴▵▷▸▹►▻▽▾▿◁◂◃◄◅◆◇◈◉◌◍◎◐◑◒◓◔◕◖◗◘◙◜◝◞◟◠◡◢◣◤◥◦◳◷◻◽◿⨧⨯⨼⩣⩽⪍⪚⪺₢₣₤₰₳₶₷₨﷼"},
// };
// get the maximum suborder for each subcategory
// Map<String, Long> subcategoryToMaxSuborder = new HashMap<>();
// for (String[] row : data) {
// final String subcategory = row[0];
// for (Entry<String, String> entry : emojiToMinorCategory.entrySet()) {
// if (entry.getValue().equals(subcategory)) {
// String emoji = entry.getKey();
// Long order = emojiToOrder.get(emoji);
// Long currentMax = subcategoryToMaxSuborder.get(subcategory);
// if (order == null) continue;
// if (currentMax == null || currentMax < order) {
// subcategoryToMaxSuborder.put(subcategory, order);
// }
// }
// }
// }
// if (DEBUG) System.out.println(subcategoryToMaxSuborder);
// Map<String, Long> _EXTRA_SYMBOL_ORDER = new LinkedHashMap<>();
// for (String[] row : data) {
// final String subcategory = row[0];
// final String characters = row[1];
//
// List<String> items = new ArrayList<>();
// for (int cp : With.codePointArray(characters)) {
// if (cp != ' ') {
// items.add(With.fromCodePoint(cp));
// }
// }
// final UnicodeSet uset = new UnicodeSet().addAll(items);
// if (uset.containsSome(EXTRA_SYMBOL_MINOR_CATEGORIES.keySet())) {
// throw new IllegalArgumentException("Duplicate values in " + EXTRA_SYMBOL_MINOR_CATEGORIES);
// }
// EXTRA_SYMBOL_MINOR_CATEGORIES.putAll(uset, subcategory);
// final Long countObject = subcategoryToMaxSuborder.get(subcategory);
// if (countObject == null) continue;
// long count = countObject;
// for (String s : items) {
// ++count;
// _EXTRA_SYMBOL_ORDER.put(s, count);
// }
// subcategoryToMaxSuborder.put(subcategory, count);
// }
// if (DEBUG) System.out.println(_EXTRA_SYMBOL_ORDER);
// EXTRA_SYMBOL_MINOR_CATEGORIES.freeze();
// EXTRA_SYMBOL_ORDER = ImmutableMap.copyOf(_EXTRA_SYMBOL_ORDER);
/*
# group: Smileys & People
# subgroup: face-positive
1F600 ; fully-qualified # 😀 grinning face
*/
final Splitter semi = Splitter.on(CharMatcher.anyOf(";#")).trimResults();
String majorCategory;
final String file = "res/raw/emoji_test.txt";
final String file = "res/raw/emojis.json";
final ClassLoader classLoader = getClass().getClassLoader();
if (classLoader == null) {
Log.e(TAG, "Emoji: classLoader is null");
return;
}
try (final InputStream in = classLoader.getResourceAsStream(file);
final BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
String line;
EmojiCategoryType categoryType = null;
while ((line = reader.readLine()) != null) {
if (line.startsWith("#")) {
line = line.substring(1).trim();
if (line.startsWith("group:")) {
majorCategory = line.substring("group:".length()).trim();
if (!majorCategory.equals("Component")) { // Skip Component
if (majorCategory.equals("Smileys & Emotion") || majorCategory.equals("People & Body")) {
// Put 'People & Body' in 'Smileys & Emotion' category
categoryType = EmojiCategoryType.SMILEYS_AND_EMOTION;
} else {
categoryType = EmojiCategoryType.valueOfName(majorCategory);
}
final boolean contains = CATEGORY_MAP.containsKey(categoryType);
if (!contains) {
CATEGORY_MAP.put(categoryType, new EmojiCategory(categoryType));
}
}
}
continue;
}
if (categoryType == null) continue;
line = line.trim();
if (line.isEmpty()) {
continue;
}
final Iterator<String> it = semi.split(line).iterator();
String emojiHex = it.next();
String original = Utility.fromHex(emojiHex, 4, " ");
String status = it.next();
if (!status.startsWith("fully-qualified")) { // only use fully qualified
continue;
}
final EmojiCategory emojiCategory = CATEGORY_MAP.get(categoryType);
final Map<String, Emoji> emojis = emojiCategory == null ? new LinkedHashMap<>() : emojiCategory.getEmojis();
String comment = it.next();
// The comment is now of the form: # 😁 E0.6 beaming face with smiling eyes
int spacePos = comment.indexOf(' ');
spacePos = comment.indexOf(' ', spacePos + 1); // get second space
final String name = comment.substring(spacePos + 1).trim();
final Emoji emoji = new Emoji(original, name);
ALL_EMOJIS.put(original, emoji);
String minimal = original.replace(EMOJI_VARIANT, "");
//noinspection deprecation
boolean singleton = CharSequences.getSingleCodePoint(minimal) != Integer.MAX_VALUE;
if (!singleton && SKIN_TONE_MODIFIERS.containsSome(minimal)) {
// skin tone variant
final String parent = minimal.replaceAll(SKIN_TONE_PATTERN, "");
final Emoji parentEmoji = emojis.get(parent);
if (parentEmoji != null) {
parentEmoji.addVariant(emoji);
}
continue;
}
emojis.put(original, emoji);
// skip constructed values
// if (minimal.contains(COMBINING_ENCLOSING_KEYCAP)
// || REGIONAL_INDICATORS.containsSome(minimal)
// || TAGS.containsSome(minimal)
// || !singleton && MODIFIERS.containsSome(minimal)
// || !singleton && FAMILY.containsAll(minimal)) {
// // do nothing
// } else if (minimal.contains(ZWJ)) { // only do certain ZWJ sequences
// if (SPECIALS.contains(minimal)
// || GENDER.containsSome(minimal)
// || MAN_WOMAN.contains(minimal.codePointAt(0)) && OBJECT.contains(minimal.codePointBefore(minimal.length()))) {
// // nonConstructed.add(minimal);
// }
// } else if (!minimal.contains("🔟")) {
// // nonConstructed.add(minimal);
// }
}
// for (Entry<Pair<Integer,Integer>, String> entry : majorPlusMinorToEmoji.entries()) {
// String minimal = entry.getValue();
// emojiToOrder.put(minimal, emojiToOrder.size());
// }
try (final InputStream in = classLoader.getResourceAsStream(file)) {
final String json = NetworkUtils.readFromInputStream(in);
final Gson gson = new Gson();
final Type type = new TypeToken<Map<EmojiCategoryType, EmojiCategory>>() {}.getType();
categoryMap = gson.fromJson(json, type);
// Log.d(TAG, "EmojiParser: " + categoryMap);
allEmojis = categoryMap.values()
.stream()
.flatMap((Function<EmojiCategory, Stream<Emoji>>) emojiCategory -> {
final Map<String, Emoji> emojis = emojiCategory.getEmojis();
return emojis.values().stream();
})
.flatMap(emoji -> ImmutableList.<Emoji>builder()
.add(emoji)
.addAll(emoji.getVariants())
.build()
.stream())
.collect(Collectors.toMap(Emoji::getUnicode, Function.identity()));
} catch (IOException e) {
Log.e(TAG, "Emoji: ", e);
Log.e(TAG, "EmojiParser: ", e);
}
}
// private static <K, V> void putUnique(Map<K, V> map, K key, V value) {
// V oldValue = map.put(key, value);
// if (oldValue != null) {
// throw new ICUException("Attempt to change value of " + map
// + " for " + key
// + " from " + oldValue
// + " to " + value
// );
// }
// }
public Map<EmojiCategoryType, EmojiCategory> getCategoryMap() {
return CATEGORY_MAP;
return categoryMap;
}
public List<EmojiCategory> getEmojiCategories() {
if (categories == null) {
final Collection<EmojiCategory> categoryCollection = CATEGORY_MAP.values();
final Collection<EmojiCategory> categoryCollection = categoryMap.values();
categories = ImmutableList.copyOf(categoryCollection);
}
return categories;
}
public Map<String, Emoji> getAllEmojis() {
return ALL_EMOJIS;
return allEmojis;
}
public Emoji getEmoji(final String emoji) {
if (emoji == null) {
return null;
}
return ALL_EMOJIS.get(emoji);
return allEmojis.get(emoji);
}
// public String getMinorCategory(String emoji) {
// String minorCat = emojiToMinorCategory.get(emoji);
// if (minorCat == null) {
// minorCat = EXTRA_SYMBOL_MINOR_CATEGORIES.get(emoji);
// if (minorCat == null) {
// throw new InternalCldrException("No minor category (aka subgroup) found for " + emoji
// + ". Update emoji-test.txt to latest, and setValue PathHeader.. functionMap.put(\"minor\", ...");
// }
// }
// return minorCat;
// }
// public long getEmojiToOrder(String emoji) {
// Long result = emojiToOrder.get(emoji);
// if (result == null) {
// result = EXTRA_SYMBOL_ORDER.get(emoji);
// if (result == null) {
// throw new InternalCldrException("No Order found for " + emoji
// + ". Update emoji-test.txt to latest, and setValue PathHeader.. functionMap.put(\"minor\", ...");
// }
// }
// return result;
// }
// public long getEmojiMinorOrder(String minor) {
// Long result = minorToOrder.get(minor);
// if (result == null) {
// throw new InternalCldrException("No minor category (aka subgroup) found for " + minor
// + ". Update emoji-test.txt to latest, and setValue PathHeader.. functionMap.put(\"minor\", ...");
// }
// return result;
// }
// public String getMajorCategory(String emoji) {
// String majorCat = emojiToMajorCategory.get(emoji);
// if (majorCat == null) {
// if (EXTRA_SYMBOL_MINOR_CATEGORIES.containsKey(emoji)) {
// majorCat = "Symbols";
// } else {
// throw new InternalCldrException("No minor category (aka subgroup) found for " + emoji
// + ". Update emoji-test.txt to latest, and setValue PathHeader.. functionMap.put(\"major\", ...");
// }
// }
// return majorCat;
// }
// public Set<String> getMinorCategoriesWithExtras() {
// Set<String> result = new LinkedHashSet<>(emojiToMinorCategory.values());
// result.addAll(EXTRA_SYMBOL_MINOR_CATEGORIES.getAvailableValues());
// return ImmutableSet.copyOf(result);
// }
// public UnicodeSet getEmojiInMinorCategoriesWithExtras(String minorCategory) {
// return new UnicodeSet(emojiToMinorCategory.getSet(minorCategory))
// .addAll(EXTRA_SYMBOL_MINOR_CATEGORIES.getSet(minorCategory))
// .freeze();
// }
// public synchronized Set<String> getNamePaths() {
// return NAME_PATHS != null ? NAME_PATHS : (NAME_PATHS = buildPaths(TYPE_TTS));
// }
// public synchronized Set<String> getKeywordPaths() {
// return KEYWORD_PATHS != null ? KEYWORD_PATHS : (KEYWORD_PATHS = buildPaths(""));
// }
// private ImmutableSet<String> buildPaths(String suffix) {
// ImmutableSet.Builder<String> builder = ImmutableSet.builder();
// for (String s : getNonConstructed()) {
// String base = "//ldml/annotations/annotation[@cp=\"" + s + "\"]" + suffix;
// builder.add(base);
// }
// return builder.build();
// }
}

View File

@ -1,50 +0,0 @@
package awais.instagrabber.utils.emoji;
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
*******************************************************************************
* Copyright (C) 2009-2012, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
import java.util.Map;
/**
* @author markdavis
*/
public class ImmutableEntry<K, V> implements Map.Entry<K, V> {
final K k;
final V v;
ImmutableEntry(K key, V value) {
k = key;
v = value;
}
public K getKey() {return k;}
public V getValue() {return v;}
public V setValue(V value) {
throw new UnsupportedOperationException();
}
public boolean equals(Object o) {
try {
Map.Entry e = (Map.Entry) o;
return UnicodeMap.areEqual(e.getKey(), k) && UnicodeMap.areEqual(e.getValue(), v);
} catch (ClassCastException e) {
return false;
}
}
public int hashCode() {
return ((k == null ? 0 : k.hashCode()) ^ (v == null ? 0 : v.hashCode()));
}
public String toString() {
return k + "=" + v;
}
}

View File

@ -257,7 +257,7 @@
android:layout_width="0dp"
android:layout_height="250dp"
android:translationY="250dp"
android:visibility="gone"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -5,8 +5,8 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.2'
def nav_version = "2.3.3"
classpath 'com.android.tools.build:gradle:4.1.3'
def nav_version = "2.3.4"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
}
}