Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solution found: Newer Unicode emojis don't render on older Android devices #3885

Open
chrisbobbe opened this issue Feb 7, 2020 · 1 comment

Comments

@chrisbobbe
Copy link
Contributor

chrisbobbe commented Feb 7, 2020

Older Android devices are missing newer Unicode emoji; they just show up as empty squares. I'm mostly sure this is the same issue as #3181, but that one is mostly screenshots, and I'd like to start fresh with some (hopefully clear) steps to a solution at the top.

To use the Android EmojiCompat library would be the best solution if React Native supported it. Without support, we'd be left to do a lot of imperative string processing to get it to work, and probably make our own wrapper of Android's native TextView component, and we'd get in the way of the React Native layer by doing this. See the React Native feature request here.

So, without that, we can ask the app to use an emoji font of our choosing for all of its Unicode emoji. We considered using it as a fallback font, just to fill in what's missing, but the inconsistency in style between the system font and the new font would be jarring, so it's preferable to use the new font for all Unicode emojis. We'd like to try using the Noto Color Emoji font, as mentioned by @raphlinus (thanks Raph!) in the RC realm (link accessible only to users in that realm). Since it's a large font (around 9 MB), we'd like to load it dynamically instead of shipping it with the app.

We've found a way to do that, which should work with compatibility back to Android API version 14, inclusive, using Downloadable Fonts.

We don't see documentation in React Native about its support for Downloadable Fonts, so I'll refer directly to the commit (facebook/react-native@fd6386a on PR facebook/react-native#24595) that introduced it, included in React Native versions 0.60.0 and above. (This is a second attempt; the history shows a first attempt in facebook/react-native@f01c4e2 on PR facebook/react-native#23865, but that was reverted in facebook/react-native@eb40b09.)

So, let's try:

  1. Await the upgrade to React Native 0.60.0; this is already in progress. 🙂
  2. As directed in a comment at facebook/react-native@fe3dd73#diff-d4141c42bc6789637b6fdc7754ec1dd9R86-R92, we need to put some XML in the res/font folder to identify the Noto Color Emoji font. An Android developer guide describes what to put there.
    2.a. It shows that we need the Android Support Library 26; we don't have to do anything here because we're using 28.
    2.b. We can optionally pre-declare the font in the manifest to mitigate delays in the initial load of the font.
  3. Then, I believe (again, from facebook/react-native@fe3dd73#diff-d4141c42bc6789637b6fdc7754ec1dd9R86-R92, and also from a tester app modified at facebook/react-native@fe3dd73#diff-fa16d6c913409ad4467bc9a55506815fR50 in that same commit), we can do ReactFontManager.getInstance().addCustomFont(this, "NotoColorEmoji", R.font.NotoColorEmoji); in public void onCreate in /android/app/src/main/java/com/zulipmobile/MainApplication.java.
  4. We can then change the CSS in the MessageList WebView to use the font. Since it's an emoji font, we expect that it only has glyphs for emojis themselves, and that regular text will still be rendered with the system font. (@WesleyAC)
  5. And we can style the React Native components that use emoji (the emoji picker and reactions list, possibly others) to also use the font.

Then: 🪀🧱🦙🦞🪗!

@chrisbobbe chrisbobbe added a-Android blocked on other work To come back to after another related PR, or some other task. a-emoji labels Feb 7, 2020
@chrisbobbe chrisbobbe changed the title Solution found: Android Unicode emoji not up-to-date on older devices Solution found: Newer Unicode emojis don't render on older Android devices Feb 7, 2020
@gnprice gnprice removed the blocked on other work To come back to after another related PR, or some other task. label Jun 8, 2020
@gnprice
Copy link
Member

gnprice commented Jun 8, 2020

The RN upgrade is complete! So it should now be possible for us to try this solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants