forked from GitHub-Mirror/riotX-android
Use Font emoji compat for quickReactions and pills
This commit is contained in:
parent
53c91dc0c2
commit
d2f648edec
@ -0,0 +1,48 @@
|
|||||||
|
package im.vector.riotredesign
|
||||||
|
|
||||||
|
import android.graphics.Typeface
|
||||||
|
import androidx.core.provider.FontsContractCompat
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
|
|
||||||
|
class EmojiCompatFontProvider : FontsContractCompat.FontRequestCallback() {
|
||||||
|
|
||||||
|
var typeface: Typeface? = null
|
||||||
|
set(value) {
|
||||||
|
if (value != field) {
|
||||||
|
field = value
|
||||||
|
listeners.forEach {
|
||||||
|
try {
|
||||||
|
it.compatibilityFontUpdate(value)
|
||||||
|
} catch (t: Throwable) {
|
||||||
|
Timber.e(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val listeners = ArrayList<FontProviderListener>()
|
||||||
|
|
||||||
|
override fun onTypefaceRetrieved(typeface: Typeface) {
|
||||||
|
this.typeface = typeface
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTypefaceRequestFailed(reason: Int) {
|
||||||
|
Timber.e("Failed to load Emoji Compatible font, reason:$reason")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addListener(listener: FontProviderListener) {
|
||||||
|
if (!listeners.contains(listener)) {
|
||||||
|
listeners.add(listener)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeListener(listener: FontProviderListener) {
|
||||||
|
listeners.remove(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface FontProviderListener {
|
||||||
|
fun compatibilityFontUpdate(typeface: Typeface?)
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,10 @@ package im.vector.riotredesign
|
|||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.HandlerThread
|
||||||
|
import androidx.core.provider.FontRequest
|
||||||
|
import androidx.core.provider.FontsContractCompat
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import androidx.multidex.MultiDex
|
import androidx.multidex.MultiDex
|
||||||
import com.airbnb.epoxy.EpoxyAsyncUtil
|
import com.airbnb.epoxy.EpoxyAsyncUtil
|
||||||
@ -41,6 +45,10 @@ import timber.log.Timber
|
|||||||
|
|
||||||
class VectorApplication : Application() {
|
class VectorApplication : Application() {
|
||||||
|
|
||||||
|
//font thread handler
|
||||||
|
private var mFontThreadHandler: Handler? = null
|
||||||
|
|
||||||
|
|
||||||
val vectorConfiguration: VectorConfiguration by inject()
|
val vectorConfiguration: VectorConfiguration by inject()
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
@ -63,10 +71,20 @@ class VectorApplication : Application() {
|
|||||||
val appModule = AppModule(applicationContext).definition
|
val appModule = AppModule(applicationContext).definition
|
||||||
val homeModule = HomeModule().definition
|
val homeModule = HomeModule().definition
|
||||||
val roomDirectoryModule = RoomDirectoryModule().definition
|
val roomDirectoryModule = RoomDirectoryModule().definition
|
||||||
startKoin(listOf(appModule, homeModule, roomDirectoryModule), logger = EmptyLogger())
|
val koin = startKoin(listOf(appModule, homeModule, roomDirectoryModule), logger = EmptyLogger())
|
||||||
|
|
||||||
Matrix.getInstance().setApplicationFlavor(BuildConfig.FLAVOR_DESCRIPTION)
|
Matrix.getInstance().setApplicationFlavor(BuildConfig.FLAVOR_DESCRIPTION)
|
||||||
|
|
||||||
|
val fontRequest = FontRequest(
|
||||||
|
"com.google.android.gms.fonts",
|
||||||
|
"com.google.android.gms",
|
||||||
|
"Noto Color Emoji Compat",
|
||||||
|
R.array.com_google_android_gms_fonts_certs
|
||||||
|
)
|
||||||
|
|
||||||
|
// val efp = koin.koinContext.get<EmojiCompatFontProvider>()
|
||||||
|
FontsContractCompat.requestFont(this, fontRequest, koin.koinContext.get<EmojiCompatFontProvider>(), getFontThreadHandler())
|
||||||
|
|
||||||
vectorConfiguration.initConfiguration()
|
vectorConfiguration.initConfiguration()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,4 +99,13 @@ class VectorApplication : Application() {
|
|||||||
vectorConfiguration.onConfigurationChanged(newConfig)
|
vectorConfiguration.onConfigurationChanged(newConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getFontThreadHandler(): Handler {
|
||||||
|
if (mFontThreadHandler == null) {
|
||||||
|
val handlerThread = HandlerThread("fonts")
|
||||||
|
handlerThread.start()
|
||||||
|
mFontThreadHandler = Handler(handlerThread.looper)
|
||||||
|
}
|
||||||
|
return mFontThreadHandler!!
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -20,6 +20,7 @@ import android.content.Context
|
|||||||
import android.content.Context.MODE_PRIVATE
|
import android.content.Context.MODE_PRIVATE
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import im.vector.matrix.android.api.Matrix
|
import im.vector.matrix.android.api.Matrix
|
||||||
|
import im.vector.riotredesign.EmojiCompatFontProvider
|
||||||
import im.vector.riotredesign.core.error.ErrorFormatter
|
import im.vector.riotredesign.core.error.ErrorFormatter
|
||||||
import im.vector.riotredesign.core.resources.LocaleProvider
|
import im.vector.riotredesign.core.resources.LocaleProvider
|
||||||
import im.vector.riotredesign.core.resources.StringArrayProvider
|
import im.vector.riotredesign.core.resources.StringArrayProvider
|
||||||
@ -90,5 +91,9 @@ class AppModule(private val context: Context) {
|
|||||||
DefaultNavigator(fragment) as Navigator
|
DefaultNavigator(fragment) as Navigator
|
||||||
}
|
}
|
||||||
|
|
||||||
|
single {
|
||||||
|
EmojiCompatFontProvider()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -72,7 +72,8 @@ class HomeModule {
|
|||||||
val timelineMediaSizeProvider = TimelineMediaSizeProvider()
|
val timelineMediaSizeProvider = TimelineMediaSizeProvider()
|
||||||
val colorProvider = ColorProvider(fragment.requireContext())
|
val colorProvider = ColorProvider(fragment.requireContext())
|
||||||
val timelineDateFormatter = get<TimelineDateFormatter>()
|
val timelineDateFormatter = get<TimelineDateFormatter>()
|
||||||
val messageItemFactory = MessageItemFactory(colorProvider, timelineMediaSizeProvider, timelineDateFormatter, eventHtmlRenderer, get())
|
val messageItemFactory = MessageItemFactory(colorProvider, timelineMediaSizeProvider,
|
||||||
|
timelineDateFormatter, eventHtmlRenderer, get(), get())
|
||||||
|
|
||||||
val timelineItemFactory = TimelineItemFactory(
|
val timelineItemFactory = TimelineItemFactory(
|
||||||
messageItemFactory = messageItemFactory,
|
messageItemFactory = messageItemFactory,
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package im.vector.riotredesign.features.home.room.detail.timeline.action
|
package im.vector.riotredesign.features.home.room.detail.timeline.action
|
||||||
|
|
||||||
|
import android.graphics.Typeface
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@ -28,7 +29,9 @@ import com.airbnb.mvrx.BaseMvRxFragment
|
|||||||
import com.airbnb.mvrx.MvRx
|
import com.airbnb.mvrx.MvRx
|
||||||
import com.airbnb.mvrx.fragmentViewModel
|
import com.airbnb.mvrx.fragmentViewModel
|
||||||
import com.airbnb.mvrx.withState
|
import com.airbnb.mvrx.withState
|
||||||
|
import im.vector.riotredesign.EmojiCompatFontProvider
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
|
import org.koin.android.ext.android.inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Quick Reaction Fragment (agree / like reactions)
|
* Quick Reaction Fragment (agree / like reactions)
|
||||||
@ -54,6 +57,8 @@ class QuickReactionFragment : BaseMvRxFragment() {
|
|||||||
|
|
||||||
var interactionListener: InteractionListener? = null
|
var interactionListener: InteractionListener? = null
|
||||||
|
|
||||||
|
val fontProvider by inject<EmojiCompatFontProvider>()
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
val view = inflater.inflate(R.layout.adapter_item_action_quick_reaction, container, false)
|
val view = inflater.inflate(R.layout.adapter_item_action_quick_reaction, container, false)
|
||||||
ButterKnife.bind(this, view)
|
ButterKnife.bind(this, view)
|
||||||
@ -68,6 +73,10 @@ class QuickReactionFragment : BaseMvRxFragment() {
|
|||||||
quickReact3Text.text = QuickReactionViewModel.likePositive
|
quickReact3Text.text = QuickReactionViewModel.likePositive
|
||||||
quickReact4Text.text = QuickReactionViewModel.likeNegative
|
quickReact4Text.text = QuickReactionViewModel.likeNegative
|
||||||
|
|
||||||
|
listOf(quickReact1Text, quickReact2Text, quickReact3Text, quickReact4Text).forEach {
|
||||||
|
it.typeface = fontProvider.typeface ?: Typeface.DEFAULT
|
||||||
|
}
|
||||||
|
|
||||||
//configure click listeners
|
//configure click listeners
|
||||||
quickReact1Text.setOnClickListener {
|
quickReact1Text.setOnClickListener {
|
||||||
viewModel.toggleAgree(true)
|
viewModel.toggleAgree(true)
|
||||||
@ -88,11 +97,11 @@ class QuickReactionFragment : BaseMvRxFragment() {
|
|||||||
|
|
||||||
TransitionManager.beginDelayedTransition(rootLayout)
|
TransitionManager.beginDelayedTransition(rootLayout)
|
||||||
when (it.agreeTrigleState) {
|
when (it.agreeTrigleState) {
|
||||||
TriggleState.NONE -> {
|
TriggleState.NONE -> {
|
||||||
quickReact1Text.alpha = 1f
|
quickReact1Text.alpha = 1f
|
||||||
quickReact2Text.alpha = 1f
|
quickReact2Text.alpha = 1f
|
||||||
}
|
}
|
||||||
TriggleState.FIRST -> {
|
TriggleState.FIRST -> {
|
||||||
quickReact1Text.alpha = 1f
|
quickReact1Text.alpha = 1f
|
||||||
quickReact2Text.alpha = 0.2f
|
quickReact2Text.alpha = 0.2f
|
||||||
|
|
||||||
@ -103,11 +112,11 @@ class QuickReactionFragment : BaseMvRxFragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
when (it.likeTriggleState) {
|
when (it.likeTriggleState) {
|
||||||
TriggleState.NONE -> {
|
TriggleState.NONE -> {
|
||||||
quickReact3Text.alpha = 1f
|
quickReact3Text.alpha = 1f
|
||||||
quickReact4Text.alpha = 1f
|
quickReact4Text.alpha = 1f
|
||||||
}
|
}
|
||||||
TriggleState.FIRST -> {
|
TriggleState.FIRST -> {
|
||||||
quickReact3Text.alpha = 1f
|
quickReact3Text.alpha = 1f
|
||||||
quickReact4Text.alpha = 0.2f
|
quickReact4Text.alpha = 0.2f
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ import im.vector.matrix.android.api.session.room.model.EditAggregatedSummary
|
|||||||
import im.vector.matrix.android.api.session.room.model.message.*
|
import im.vector.matrix.android.api.session.room.model.message.*
|
||||||
import im.vector.matrix.android.api.session.room.send.SendState
|
import im.vector.matrix.android.api.session.room.send.SendState
|
||||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||||
|
import im.vector.riotredesign.EmojiCompatFontProvider
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.epoxy.VectorEpoxyModel
|
import im.vector.riotredesign.core.epoxy.VectorEpoxyModel
|
||||||
import im.vector.riotredesign.core.extensions.localDateTime
|
import im.vector.riotredesign.core.extensions.localDateTime
|
||||||
@ -55,7 +56,8 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
|||||||
private val timelineMediaSizeProvider: TimelineMediaSizeProvider,
|
private val timelineMediaSizeProvider: TimelineMediaSizeProvider,
|
||||||
private val timelineDateFormatter: TimelineDateFormatter,
|
private val timelineDateFormatter: TimelineDateFormatter,
|
||||||
private val htmlRenderer: EventHtmlRenderer,
|
private val htmlRenderer: EventHtmlRenderer,
|
||||||
private val stringProvider: StringProvider) {
|
private val stringProvider: StringProvider,
|
||||||
|
private val emojiCompatFontProvider: EmojiCompatFontProvider) {
|
||||||
|
|
||||||
fun create(event: TimelineEvent,
|
fun create(event: TimelineEvent,
|
||||||
nextEvent: TimelineEvent?,
|
nextEvent: TimelineEvent?,
|
||||||
@ -115,24 +117,24 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
|||||||
// val all = event.root.toContent()
|
// val all = event.root.toContent()
|
||||||
// val ev = all.toModel<Event>()
|
// val ev = all.toModel<Event>()
|
||||||
return when (messageContent) {
|
return when (messageContent) {
|
||||||
is MessageEmoteContent -> buildEmoteMessageItem(messageContent,
|
is MessageEmoteContent -> buildEmoteMessageItem(messageContent,
|
||||||
informationData,
|
informationData,
|
||||||
hasBeenEdited,
|
hasBeenEdited,
|
||||||
event.annotations?.editSummary,
|
event.annotations?.editSummary,
|
||||||
callback)
|
callback)
|
||||||
is MessageTextContent -> buildTextMessageItem(event.sendState,
|
is MessageTextContent -> buildTextMessageItem(event.sendState,
|
||||||
messageContent,
|
messageContent,
|
||||||
informationData,
|
informationData,
|
||||||
hasBeenEdited,
|
hasBeenEdited,
|
||||||
event.annotations?.editSummary,
|
event.annotations?.editSummary,
|
||||||
callback
|
callback
|
||||||
)
|
)
|
||||||
is MessageImageContent -> buildImageMessageItem(messageContent, informationData, callback)
|
is MessageImageContent -> buildImageMessageItem(messageContent, informationData, callback)
|
||||||
is MessageNoticeContent -> buildNoticeMessageItem(messageContent, informationData, callback)
|
is MessageNoticeContent -> buildNoticeMessageItem(messageContent, informationData, callback)
|
||||||
is MessageVideoContent -> buildVideoMessageItem(messageContent, informationData, callback)
|
is MessageVideoContent -> buildVideoMessageItem(messageContent, informationData, callback)
|
||||||
is MessageFileContent -> buildFileMessageItem(messageContent, informationData, callback)
|
is MessageFileContent -> buildFileMessageItem(messageContent, informationData, callback)
|
||||||
is MessageAudioContent -> buildAudioMessageItem(messageContent, informationData, callback)
|
is MessageAudioContent -> buildAudioMessageItem(messageContent, informationData, callback)
|
||||||
else -> buildNotHandledMessageItem(messageContent)
|
else -> buildNotHandledMessageItem(messageContent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,20 +146,21 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
|||||||
.filename(messageContent.body)
|
.filename(messageContent.body)
|
||||||
.iconRes(R.drawable.filetype_audio)
|
.iconRes(R.drawable.filetype_audio)
|
||||||
.reactionPillCallback(callback)
|
.reactionPillCallback(callback)
|
||||||
|
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
||||||
.avatarClickListener(
|
.avatarClickListener(
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
DebouncedClickListener(View.OnClickListener {
|
||||||
callback?.onAvatarClicked(informationData)
|
callback?.onAvatarClicked(informationData)
|
||||||
}))
|
}))
|
||||||
.memberClickListener(
|
.memberClickListener(
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
DebouncedClickListener(View.OnClickListener {
|
||||||
callback?.onMemberNameClicked(informationData)
|
callback?.onMemberNameClicked(informationData)
|
||||||
}))
|
}))
|
||||||
.cellClickListener(
|
.cellClickListener(
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
DebouncedClickListener(View.OnClickListener { view: View ->
|
||||||
callback?.onEventCellClicked(informationData, messageContent, view)
|
callback?.onEventCellClicked(informationData, messageContent, view)
|
||||||
}))
|
}))
|
||||||
.clickListener(
|
.clickListener(
|
||||||
DebouncedClickListener(View.OnClickListener { _ ->
|
DebouncedClickListener(View.OnClickListener {
|
||||||
callback?.onAudioMessageClicked(messageContent)
|
callback?.onAudioMessageClicked(messageContent)
|
||||||
}))
|
}))
|
||||||
.longClickListener { view ->
|
.longClickListener { view ->
|
||||||
@ -173,6 +176,7 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
|||||||
.informationData(informationData)
|
.informationData(informationData)
|
||||||
.filename(messageContent.body)
|
.filename(messageContent.body)
|
||||||
.reactionPillCallback(callback)
|
.reactionPillCallback(callback)
|
||||||
|
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
||||||
.iconRes(R.drawable.filetype_attachment)
|
.iconRes(R.drawable.filetype_attachment)
|
||||||
.avatarClickListener(
|
.avatarClickListener(
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
DebouncedClickListener(View.OnClickListener { view ->
|
||||||
@ -221,6 +225,7 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
|||||||
.informationData(informationData)
|
.informationData(informationData)
|
||||||
.mediaData(data)
|
.mediaData(data)
|
||||||
.reactionPillCallback(callback)
|
.reactionPillCallback(callback)
|
||||||
|
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
||||||
.avatarClickListener(
|
.avatarClickListener(
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
DebouncedClickListener(View.OnClickListener { view ->
|
||||||
callback?.onAvatarClicked(informationData)
|
callback?.onAvatarClicked(informationData)
|
||||||
@ -268,6 +273,7 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
|||||||
.informationData(informationData)
|
.informationData(informationData)
|
||||||
.mediaData(thumbnailData)
|
.mediaData(thumbnailData)
|
||||||
.reactionPillCallback(callback)
|
.reactionPillCallback(callback)
|
||||||
|
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
||||||
.avatarClickListener(
|
.avatarClickListener(
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
DebouncedClickListener(View.OnClickListener { view ->
|
||||||
callback?.onAvatarClicked(informationData)
|
callback?.onAvatarClicked(informationData)
|
||||||
@ -311,6 +317,7 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
|||||||
}
|
}
|
||||||
.informationData(informationData)
|
.informationData(informationData)
|
||||||
.reactionPillCallback(callback)
|
.reactionPillCallback(callback)
|
||||||
|
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
||||||
.avatarClickListener(
|
.avatarClickListener(
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
DebouncedClickListener(View.OnClickListener { view ->
|
||||||
callback?.onAvatarClicked(informationData)
|
callback?.onAvatarClicked(informationData)
|
||||||
@ -384,6 +391,7 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
|||||||
.message(message)
|
.message(message)
|
||||||
.informationData(informationData)
|
.informationData(informationData)
|
||||||
.reactionPillCallback(callback)
|
.reactionPillCallback(callback)
|
||||||
|
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
||||||
.avatarClickListener(
|
.avatarClickListener(
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
DebouncedClickListener(View.OnClickListener { view ->
|
||||||
callback?.onAvatarClicked(informationData)
|
callback?.onAvatarClicked(informationData)
|
||||||
@ -423,6 +431,7 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
|||||||
}
|
}
|
||||||
.informationData(informationData)
|
.informationData(informationData)
|
||||||
.reactionPillCallback(callback)
|
.reactionPillCallback(callback)
|
||||||
|
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
||||||
.avatarClickListener(
|
.avatarClickListener(
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
DebouncedClickListener(View.OnClickListener { view ->
|
||||||
callback?.onAvatarClicked(informationData)
|
callback?.onAvatarClicked(informationData)
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package im.vector.riotredesign.features.home.room.detail.timeline.item
|
package im.vector.riotredesign.features.home.room.detail.timeline.item
|
||||||
|
|
||||||
|
import android.graphics.Typeface
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@ -50,6 +51,9 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder> : BaseEventItem<H>() {
|
|||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var memberClickListener: View.OnClickListener? = null
|
var memberClickListener: View.OnClickListener? = null
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
var emojiTypeFace: Typeface? = null
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var reactionPillCallback: TimelineEventController.ReactionPillCallback? = null
|
var reactionPillCallback: TimelineEventController.ReactionPillCallback? = null
|
||||||
|
|
||||||
@ -116,6 +120,7 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder> : BaseEventItem<H>() {
|
|||||||
idToRefInFlow.add(reactionButton.id)
|
idToRefInFlow.add(reactionButton.id)
|
||||||
reactionButton.reactionString = reaction.key
|
reactionButton.reactionString = reaction.key
|
||||||
reactionButton.reactionCount = reaction.count
|
reactionButton.reactionCount = reaction.count
|
||||||
|
reactionButton.emojiTypeFace = emojiTypeFace
|
||||||
reactionButton.setChecked(reaction.addedByMe)
|
reactionButton.setChecked(reaction.addedByMe)
|
||||||
reactionButton.isEnabled = reaction.synced
|
reactionButton.isEnabled = reaction.synced
|
||||||
}
|
}
|
||||||
|
@ -19,23 +19,20 @@ import android.app.Activity
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import android.os.Handler
|
|
||||||
import android.os.HandlerThread
|
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuInflater
|
import android.view.MenuInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.widget.SearchView
|
import android.widget.SearchView
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import androidx.core.provider.FontRequest
|
|
||||||
import androidx.core.provider.FontsContractCompat
|
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProviders
|
import androidx.lifecycle.ViewModelProviders
|
||||||
import com.google.android.material.tabs.TabLayout
|
import com.google.android.material.tabs.TabLayout
|
||||||
|
import im.vector.riotredesign.EmojiCompatFontProvider
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.platform.VectorBaseActivity
|
import im.vector.riotredesign.core.platform.VectorBaseActivity
|
||||||
import kotlinx.android.synthetic.main.activity_emoji_reaction_picker.*
|
import kotlinx.android.synthetic.main.activity_emoji_reaction_picker.*
|
||||||
import timber.log.Timber
|
import org.koin.android.ext.android.inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -44,20 +41,21 @@ import timber.log.Timber
|
|||||||
* TODO: Finish Refactor to vector base activity
|
* TODO: Finish Refactor to vector base activity
|
||||||
* TODO: Move font request to app
|
* TODO: Move font request to app
|
||||||
*/
|
*/
|
||||||
class EmojiReactionPickerActivity : VectorBaseActivity() {
|
class EmojiReactionPickerActivity : VectorBaseActivity(), EmojiCompatFontProvider.FontProviderListener {
|
||||||
|
|
||||||
|
|
||||||
private lateinit var tabLayout: TabLayout
|
private lateinit var tabLayout: TabLayout
|
||||||
|
|
||||||
lateinit var viewModel: EmojiChooserViewModel
|
lateinit var viewModel: EmojiChooserViewModel
|
||||||
|
|
||||||
private var mHandler: Handler? = null
|
|
||||||
|
|
||||||
override fun getMenuRes(): Int = R.menu.menu_emoji_reaction_picker
|
override fun getMenuRes(): Int = R.menu.menu_emoji_reaction_picker
|
||||||
|
|
||||||
override fun getLayoutRes(): Int = R.layout.activity_emoji_reaction_picker
|
override fun getLayoutRes(): Int = R.layout.activity_emoji_reaction_picker
|
||||||
|
|
||||||
override fun getTitleRes(): Int = R.string.title_activity_emoji_reaction_picker
|
override fun getTitleRes(): Int = R.string.title_activity_emoji_reaction_picker
|
||||||
|
|
||||||
|
val emojiCompatFontProvider by inject<EmojiCompatFontProvider>()
|
||||||
|
|
||||||
private var tabLayoutSelectionListener = object : TabLayout.BaseOnTabSelectedListener<TabLayout.Tab> {
|
private var tabLayoutSelectionListener = object : TabLayout.BaseOnTabSelectedListener<TabLayout.Tab> {
|
||||||
override fun onTabReselected(p0: TabLayout.Tab) {
|
override fun onTabReselected(p0: TabLayout.Tab) {
|
||||||
}
|
}
|
||||||
@ -71,19 +69,13 @@ class EmojiReactionPickerActivity : VectorBaseActivity() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getFontThreadHandler(): Handler {
|
|
||||||
if (mHandler == null) {
|
|
||||||
val handlerThread = HandlerThread("fonts")
|
|
||||||
handlerThread.start()
|
|
||||||
mHandler = Handler(handlerThread.looper)
|
|
||||||
}
|
|
||||||
return mHandler!!
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun initUiAndData() {
|
override fun initUiAndData() {
|
||||||
configureToolbar(emojiPickerToolbar)
|
configureToolbar(emojiPickerToolbar)
|
||||||
|
|
||||||
requestEmojivUnicode10CompatibleFont()
|
emojiCompatFontProvider.let {
|
||||||
|
EmojiDrawView.configureTextPaint(this, it.typeface)
|
||||||
|
it.addListener(this)
|
||||||
|
}
|
||||||
|
|
||||||
tabLayout = findViewById(R.id.tabs)
|
tabLayout = findViewById(R.id.tabs)
|
||||||
|
|
||||||
@ -124,27 +116,13 @@ class EmojiReactionPickerActivity : VectorBaseActivity() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun requestEmojivUnicode10CompatibleFont() {
|
override fun compatibilityFontUpdate(typeface: Typeface?) {
|
||||||
val fontRequest = FontRequest(
|
EmojiDrawView.configureTextPaint(this, typeface)
|
||||||
"com.google.android.gms.fonts",
|
}
|
||||||
"com.google.android.gms",
|
|
||||||
"Noto Color Emoji Compat",
|
|
||||||
R.array.com_google_android_gms_fonts_certs
|
|
||||||
)
|
|
||||||
|
|
||||||
EmojiDrawView.configureTextPaint(this, null)
|
override fun onDestroy() {
|
||||||
val callback = object : FontsContractCompat.FontRequestCallback() {
|
emojiCompatFontProvider.removeListener(this)
|
||||||
|
super.onDestroy()
|
||||||
override fun onTypefaceRetrieved(typeface: Typeface) {
|
|
||||||
EmojiDrawView.configureTextPaint(this@EmojiReactionPickerActivity, typeface)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onTypefaceRequestFailed(reason: Int) {
|
|
||||||
Timber.e("Failed to load Emoji Compatible font, reason:$reason")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FontsContractCompat.requestFont(this, fontRequest, callback, getFontThreadHandler())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
|
@ -21,6 +21,7 @@ import android.animation.AnimatorSet
|
|||||||
import android.animation.ObjectAnimator
|
import android.animation.ObjectAnimator
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.res.TypedArray
|
import android.content.res.TypedArray
|
||||||
|
import android.graphics.Typeface
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
@ -56,6 +57,11 @@ class ReactionButton @JvmOverloads constructor(context: Context, attrs: Attribut
|
|||||||
|
|
||||||
private var reactionSelector: View? = null
|
private var reactionSelector: View? = null
|
||||||
|
|
||||||
|
var emojiTypeFace: Typeface? = null
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
emojiView?.typeface = value ?: Typeface.DEFAULT
|
||||||
|
}
|
||||||
|
|
||||||
private var dotsView: DotsView
|
private var dotsView: DotsView
|
||||||
private var circleView: CircleView
|
private var circleView: CircleView
|
||||||
@ -97,6 +103,8 @@ class ReactionButton @JvmOverloads constructor(context: Context, attrs: Attribut
|
|||||||
|
|
||||||
countTextView?.text = reactionCount.toString()
|
countTextView?.text = reactionCount.toString()
|
||||||
|
|
||||||
|
emojiView?.typeface = this.emojiTypeFace ?: Typeface.DEFAULT
|
||||||
|
|
||||||
val array = context.obtainStyledAttributes(attrs, R.styleable.ReactionButton, defStyleAttr, 0)
|
val array = context.obtainStyledAttributes(attrs, R.styleable.ReactionButton, defStyleAttr, 0)
|
||||||
|
|
||||||
onDrawable = ContextCompat.getDrawable(context, R.drawable.rounded_rect_shape)
|
onDrawable = ContextCompat.getDrawable(context, R.drawable.rounded_rect_shape)
|
||||||
@ -239,7 +247,7 @@ class ReactionButton @JvmOverloads constructor(context: Context, attrs: Attribut
|
|||||||
return true
|
return true
|
||||||
|
|
||||||
when (event.action) {
|
when (event.action) {
|
||||||
MotionEvent.ACTION_DOWN ->
|
MotionEvent.ACTION_DOWN ->
|
||||||
/*
|
/*
|
||||||
Commented out this line and moved the animation effect to the action up event due to
|
Commented out this line and moved the animation effect to the action up event due to
|
||||||
conflicts that were occurring when library is used in sliding type views.
|
conflicts that were occurring when library is used in sliding type views.
|
||||||
@ -248,7 +256,7 @@ class ReactionButton @JvmOverloads constructor(context: Context, attrs: Attribut
|
|||||||
*/
|
*/
|
||||||
isPressed = true
|
isPressed = true
|
||||||
|
|
||||||
MotionEvent.ACTION_MOVE -> {
|
MotionEvent.ACTION_MOVE -> {
|
||||||
val x = event.x
|
val x = event.x
|
||||||
val y = event.y
|
val y = event.y
|
||||||
val isInside = x > 0 && x < width && y > 0 && y < height
|
val isInside = x > 0 && x < width && y > 0 && y < height
|
||||||
@ -257,7 +265,7 @@ class ReactionButton @JvmOverloads constructor(context: Context, attrs: Attribut
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MotionEvent.ACTION_UP -> {
|
MotionEvent.ACTION_UP -> {
|
||||||
emojiView!!.animate().scaleX(0.7f).scaleY(0.7f).setDuration(150).interpolator = DECCELERATE_INTERPOLATOR
|
emojiView!!.animate().scaleX(0.7f).scaleY(0.7f).setDuration(150).interpolator = DECCELERATE_INTERPOLATOR
|
||||||
emojiView!!.animate().scaleX(1f).scaleY(1f).interpolator = DECCELERATE_INTERPOLATOR
|
emojiView!!.animate().scaleX(1f).scaleY(1f).interpolator = DECCELERATE_INTERPOLATOR
|
||||||
if (isPressed) {
|
if (isPressed) {
|
||||||
|
Loading…
Reference in New Issue
Block a user