diff --git a/app/build.gradle b/app/build.gradle index 3a73110cf..2edfe4402 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -236,7 +236,7 @@ dependencies { implementation "org.apache.commons:commons-lang3:3.7" implementation "org.cyanogenmod:platform.sdk:6.0" implementation 'com.jaredrummler:colorpicker:1.1.0' - implementation 'com.github.wax911:android-emojify:0.1.7' + implementation 'com.github.wax911:android-emojify:1.9.2' implementation 'com.google.protobuf:protobuf-javalite:4.27.2' implementation 'com.android.volley:volley:1.2.1' diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 6ff419080..c3c9f2208 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -64,12 +64,10 @@ # Keep Nordic DFU library -keep class no.nordicsemi.android.dfu.** { *; } -# Keep dependency android-emojify (io.wax911.emojify) uses --keep class org.hamcrest.** { *; } --dontwarn java.beans.BeanInfo --dontwarn java.beans.IntrospectionException --dontwarn java.beans.Introspector --dontwarn java.beans.PropertyDescriptor +# For android-emojify - we are not using moshi, so ignore these +-dontwarn com.squareup.moshi.** +-dontwarn kotlinx.serialization.** +-dontwarn okio.** # Keep logback classes -keep class ch.qos.** { *; } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 82e08c474..5bf5266f1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -108,6 +108,7 @@ aliases = emoji.getAliases(); + if (aliases == null || aliases.isEmpty()) { + return null; + } + return String.format(":%s:", aliases.get(0)); + } + }; private static String convertSimpleEmojiToAscii(String text) { for (String[] emojiMap : simpleEmojiMapping) { @@ -74,25 +103,25 @@ public class EmojiConverter { return text; } - private static synchronized void initEmojiData(Context context) { + public static synchronized EmojiManager getEmojiManager(final Context context) { // Do a lazy initialisation not to slowdown the startup and when it is needed - if (!isEmojiDataInitialised) { - EmojiManager.initEmojiData(context); - isEmojiDataInitialised = true; + if (emojiManagerInstance == null) { + emojiManagerInstance = EmojiManager.Companion.create(context, new GsonDeserializer()); } + return emojiManagerInstance; } - private static String convertAdvancedEmojiToAscii(String text, Context context) { - initEmojiData(context); + private static String convertAdvancedEmojiToAscii(final String text, final Context context) { + final EmojiManager emojiManager = getEmojiManager(context); try { - return EmojiUtils.shortCodify(text); - } catch (Exception e){ - LOG.warn("An exception occured when converting advanced emoji to ASCII: " + text); + return EmojiParserKt.parseFromUnicode(emojiManager, text, EMOJI_TRANSFORMER_NO_FITZPATRICK); + } catch (final Exception e) { + LOG.warn("An exception occurred when converting advanced emoji to ASCII: {}", text); return text; } } - public static String convertUnicodeEmojiToAscii(String text, Context context) { + public static String convertUnicodeEmojiToAscii(String text, final Context context) { text = convertSimpleEmojiToAscii(text); text = convertAdvancedEmojiToAscii(text, context); diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/util/EmojiConverterTest.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/util/EmojiConverterTest.java new file mode 100644 index 000000000..6e07e435c --- /dev/null +++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/util/EmojiConverterTest.java @@ -0,0 +1,53 @@ +package nodomain.freeyourgadget.gadgetbridge.util; + +import static org.junit.Assert.*; + +import org.junit.Test; +import org.robolectric.RuntimeEnvironment; + +import java.util.HashMap; +import java.util.Map; + +import nodomain.freeyourgadget.gadgetbridge.test.TestBase; + +public class EmojiConverterTest extends TestBase { + @Test + public void testConvert() { + final Map snippets = new HashMap() {{ + put( + "no emoji", + "no emoji" + ); + + put( + "Hello! \uD83D\uDE0A", + "Hello! :-)" + ); + + put( + "\uD83D\uDE1B hi", + ":-P hi" + ); + + put( + "\uD83D\uDC7B\uD83D\uDC80", + ":ghost::skull:" + ); + + put( + "also \uD83D\uDE36 with words \uD83D\uDCAA\uD83C\uDFFC in-between \uD83D\uDE09", + "also :no_mouth: with words :muscle: in-between ;-)" + ); + }}; + + for (final Map.Entry e : snippets.entrySet()) { + assertEquals( + e.getValue(), + EmojiConverter.convertUnicodeEmojiToAscii( + e.getKey(), + RuntimeEnvironment.getApplication() + ) + ); + } + } +}