diff --git a/vector/src/main/java/im/vector/riotx/EmojiCompatHelper.kt b/vector/src/main/java/im/vector/riotx/EmojiCompatHelper.kt new file mode 100644 index 00000000..9e4a6087 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/EmojiCompatHelper.kt @@ -0,0 +1,68 @@ +/* + * Copyright 2019 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package im.vector.riotx + +import android.content.Context +import androidx.core.provider.FontRequest +import androidx.emoji.text.EmojiCompat +import androidx.emoji.text.FontRequestEmojiCompatConfig +import timber.log.Timber + +object EmojiCompatHelper { + + var initialized = false + + fun init(context: Context) { + val fontRequest = FontRequest( + "com.google.android.gms.fonts", + "com.google.android.gms", + "Noto Color Emoji Compat", + R.array.com_google_android_gms_fonts_certs + ) + //Use emoji compat for the benefit of emoji spans + val config = FontRequestEmojiCompatConfig(context, fontRequest) + // we want to replace all emojis with selected font + .setReplaceAll(true) + //Debug options +// .setEmojiSpanIndicatorEnabled(true) +// .setEmojiSpanIndicatorColor(Color.GREEN) + EmojiCompat.init(config) + .registerInitCallback(object : EmojiCompat.InitCallback() { + override fun onInitialized() { + Timber.v("Emoji compat onInitialized success ") + initialized = true + } + + override fun onFailed(throwable: Throwable?) { + Timber.e(throwable, "Failed to init EmojiCompat") + } + }) + } + + fun safeEmojiSpanify(sequence: CharSequence): CharSequence { + if (initialized) { + try { + return EmojiCompat.get().process(sequence) + } catch (throwable: Throwable) { + //Defensive coding against error (should not happend as it is initialized) + Timber.e(throwable, "Failed to init EmojiCompat") + return sequence + } + } else { + return sequence + } + } +} \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotx/VectorApplication.kt b/vector/src/main/java/im/vector/riotx/VectorApplication.kt index 4e09d790..36b4d589 100644 --- a/vector/src/main/java/im/vector/riotx/VectorApplication.kt +++ b/vector/src/main/java/im/vector/riotx/VectorApplication.kt @@ -109,21 +109,7 @@ class VectorApplication : Application(), HasVectorInjector, MatrixConfiguration. FontsContractCompat.requestFont(this, fontRequest, emojiCompatFontProvider, getFontThreadHandler()) vectorConfiguration.initConfiguration() - //Use emoji compat for the benefit of emoji spans - val config = FontRequestEmojiCompatConfig(this, fontRequest) - .setReplaceAll(true) // we want to replace all emojis with selected font -// .setEmojiSpanIndicatorEnabled(true) -// .setEmojiSpanIndicatorColor(Color.GREEN) - EmojiCompat.init(config) - .registerInitCallback(object : EmojiCompat.InitCallback() { - override fun onInitialized() { - Timber.v("Emoji compat onInitialized success ") - } - - override fun onFailed(throwable: Throwable?) { - Timber.e(throwable,"Failed to init EmojiCompat") - } - }) + EmojiCompatHelper.init(this) NotificationUtils.createNotificationChannels(applicationContext) if (authenticator.hasAuthenticatedSessions() && !activeSessionHolder.hasActiveSession()) { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ViewReactionsEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ViewReactionsEpoxyController.kt index 33e1d4df..3c2ff93e 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ViewReactionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ViewReactionsEpoxyController.kt @@ -24,6 +24,7 @@ import com.airbnb.epoxy.TypedEpoxyController import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Incomplete import com.airbnb.mvrx.Success +import im.vector.riotx.EmojiCompatHelper import im.vector.riotx.R import im.vector.riotx.core.ui.list.genericFooterItem import im.vector.riotx.core.ui.list.genericLoaderItem @@ -52,7 +53,7 @@ class ViewReactionsEpoxyController(private val context: Context) reactionInfoSimpleItem { id(it.eventId) timeStamp(it.timestamp) - reactionKey(EmojiCompat.get().process(it.reactionKey)) + reactionKey(EmojiCompatHelper.safeEmojiSpanify(it.reactionKey)) authorDisplayName(it.authorName ?: it.authorId) } } diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/widget/ReactionButton.kt b/vector/src/main/java/im/vector/riotx/features/reactions/widget/ReactionButton.kt index 0644e962..c9bfa2df 100644 --- a/vector/src/main/java/im/vector/riotx/features/reactions/widget/ReactionButton.kt +++ b/vector/src/main/java/im/vector/riotx/features/reactions/widget/ReactionButton.kt @@ -21,7 +21,6 @@ import android.animation.AnimatorSet import android.animation.ObjectAnimator import android.content.Context import android.content.res.TypedArray -import android.graphics.Typeface import android.graphics.drawable.Drawable import android.util.AttributeSet import android.view.LayoutInflater @@ -35,7 +34,7 @@ import android.widget.TextView import androidx.annotation.ColorInt import androidx.annotation.ColorRes import androidx.core.content.ContextCompat -import androidx.emoji.text.EmojiCompat +import im.vector.riotx.EmojiCompatHelper import im.vector.riotx.R import im.vector.riotx.core.utils.TextUtils @@ -78,7 +77,7 @@ class ReactionButton @JvmOverloads constructor(context: Context, attrs: Attribut set(value) { field = value //maybe cache this for performances? - val emojiSpanned = EmojiCompat.get().process(value) + val emojiSpanned = EmojiCompatHelper.safeEmojiSpanify(value) emojiView?.text = emojiSpanned }