Merge pull request #574 from vector-im/feature/big_emoji

Embiggen messages with multiple emojis also for edited messages
This commit is contained in:
Benoit Marty 2019-09-23 16:22:53 +02:00 committed by GitHub
commit 001711d5a3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 60 additions and 28 deletions

View file

@ -16,6 +16,7 @@ Bugfix:
- Fix characters erased from the Search field when the result are coming (#545)
- "No connection" banner was displayed by mistake
- Leaving community (from another client) has no effect on RiotX (#497)
- Embiggen messages with multiple emojis also for edited messages (#458)
Translations:
-

View file

@ -27,6 +27,7 @@ import im.vector.riotx.EmojiCompatFontProvider
import im.vector.riotx.EmojiCompatWrapper
import im.vector.riotx.VectorApplication
import im.vector.riotx.core.pushers.PushersManager
import im.vector.riotx.core.utils.DimensionConverter
import im.vector.riotx.features.configuration.VectorConfiguration
import im.vector.riotx.features.crypto.keysrequest.KeyRequestHandler
import im.vector.riotx.features.crypto.verification.IncomingVerificationRequestHandler
@ -63,6 +64,8 @@ interface VectorComponent {
fun resources(): Resources
fun dimensionUtils(): DimensionConverter
fun vectorConfiguration(): VectorConfiguration
fun avatarRenderer(): AvatarRenderer

View file

@ -15,25 +15,26 @@
*/
package im.vector.riotx.core.utils
import android.content.Context
import android.content.res.Resources
import android.util.TypedValue
import javax.inject.Inject
object DimensionUtils {
class DimensionConverter @Inject constructor(val resources: Resources) {
fun dpToPx(dp: Int, context: Context): Int {
fun dpToPx(dp: Int): Int {
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dp.toFloat(),
context.resources.displayMetrics
resources.displayMetrics
).toInt()
}
fun spToPx(sp: Int, context: Context): Int {
fun spToPx(sp: Int): Int {
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP,
sp.toFloat(),
context.resources.displayMetrics
resources.displayMetrics
).toInt()
}
}

View file

@ -36,7 +36,7 @@ import im.vector.riotx.core.extensions.hideKeyboard
import im.vector.riotx.core.extensions.observeEvent
import im.vector.riotx.core.extensions.setupAsSearch
import im.vector.riotx.core.platform.VectorBaseFragment
import im.vector.riotx.core.utils.DimensionUtils
import im.vector.riotx.core.utils.DimensionConverter
import im.vector.riotx.features.home.AvatarRenderer
import kotlinx.android.synthetic.main.fragment_create_direct_room.*
import javax.inject.Inject
@ -51,6 +51,7 @@ class CreateDirectRoomKnownUsersFragment : VectorBaseFragment(), KnownUsersContr
@Inject lateinit var directRoomController: KnownUsersController
@Inject lateinit var avatarRenderer: AvatarRenderer
@Inject lateinit var dimensionConverter: DimensionConverter
private lateinit var navigationViewModel: CreateDirectRoomNavigationViewModel
override fun injectWith(injector: ScreenComponent) {
@ -156,7 +157,7 @@ class CreateDirectRoomKnownUsersFragment : VectorBaseFragment(), KnownUsersContr
private fun addChipToGroup(user: User, chipGroup: ChipGroup) {
val chip = Chip(requireContext())
chip.setChipBackgroundColorResource(android.R.color.transparent)
chip.chipStrokeWidth = DimensionUtils.dpToPx(1, requireContext()).toFloat()
chip.chipStrokeWidth = dimensionConverter.dpToPx(1).toFloat()
chip.text = if (user.displayName.isNullOrBlank()) user.userId else user.displayName
chip.isClickable = true
chip.isCheckable = false

View file

@ -25,6 +25,7 @@ import im.vector.riotx.core.epoxy.VectorEpoxyModel
import im.vector.riotx.core.resources.ColorProvider
import im.vector.riotx.core.resources.StringProvider
import im.vector.riotx.core.utils.DebouncedClickListener
import im.vector.riotx.core.utils.DimensionConverter
import im.vector.riotx.features.home.AvatarRenderer
import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
import im.vector.riotx.features.home.room.detail.timeline.item.MessageTextItem_
@ -36,7 +37,8 @@ import javax.inject.Inject
class EncryptedItemFactory @Inject constructor(private val messageInformationDataFactory: MessageInformationDataFactory,
private val colorProvider: ColorProvider,
private val stringProvider: StringProvider,
private val avatarRenderer: AvatarRenderer) {
private val avatarRenderer: AvatarRenderer,
private val dimensionConverter: DimensionConverter) {
fun create(event: TimelineEvent,
nextEvent: TimelineEvent?,
@ -69,6 +71,7 @@ class EncryptedItemFactory @Inject constructor(private val messageInformationDat
.message(spannableStr)
.avatarRenderer(avatarRenderer)
.colorProvider(colorProvider)
.dimensionConverter(dimensionConverter)
.informationData(informationData)
.highlighted(highlight)
.avatarCallback(callback)

View file

@ -23,6 +23,7 @@ import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.matrix.android.internal.crypto.model.event.EncryptionEventContent
import im.vector.riotx.R
import im.vector.riotx.core.resources.StringProvider
import im.vector.riotx.core.utils.DimensionConverter
import im.vector.riotx.features.home.AvatarRenderer
import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
import im.vector.riotx.features.home.room.detail.timeline.helper.senderAvatar
@ -33,7 +34,8 @@ import im.vector.riotx.features.home.room.detail.timeline.item.NoticeItem_
import javax.inject.Inject
class EncryptionItemFactory @Inject constructor(private val stringProvider: StringProvider,
private val avatarRenderer: AvatarRenderer) {
private val avatarRenderer: AvatarRenderer,
private val dimensionConverter: DimensionConverter) {
fun create(event: TimelineEvent,
highlight: Boolean,
@ -50,6 +52,7 @@ class EncryptionItemFactory @Inject constructor(private val stringProvider: Stri
)
return NoticeItem_()
.avatarRenderer(avatarRenderer)
.dimensionConverter(dimensionConverter)
.noticeText(text)
.informationData(informationData)
.highlighted(highlight)

View file

@ -19,9 +19,9 @@ package im.vector.riotx.features.home.room.detail.timeline.factory
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.TextPaint
import android.text.style.AbsoluteSizeSpan
import android.text.style.ClickableSpan
import android.text.style.ForegroundColorSpan
import android.text.style.RelativeSizeSpan
import android.view.View
import dagger.Lazy
import im.vector.matrix.android.api.permalinks.MatrixLinkify
@ -40,6 +40,8 @@ import im.vector.riotx.core.linkify.VectorLinkify
import im.vector.riotx.core.resources.ColorProvider
import im.vector.riotx.core.resources.StringProvider
import im.vector.riotx.core.utils.DebouncedClickListener
import im.vector.riotx.core.utils.DimensionConverter
import im.vector.riotx.core.utils.containsOnlyEmojis
import im.vector.riotx.features.home.AvatarRenderer
import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
import im.vector.riotx.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder
@ -62,7 +64,8 @@ class MessageItemFactory @Inject constructor(
private val imageContentRenderer: ImageContentRenderer,
private val messageInformationDataFactory: MessageInformationDataFactory,
private val contentUploadStateTrackerBinder: ContentUploadStateTrackerBinder,
private val noticeItemFactory: NoticeItemFactory) {
private val noticeItemFactory: NoticeItemFactory,
private val dimensionConverter: DimensionConverter) {
fun create(event: TimelineEvent,
@ -113,6 +116,7 @@ class MessageItemFactory @Inject constructor(
return MessageFileItem_()
.avatarRenderer(avatarRenderer)
.colorProvider(colorProvider)
.dimensionConverter(dimensionConverter)
.informationData(informationData)
.highlighted(highlight)
.avatarCallback(callback)
@ -142,6 +146,7 @@ class MessageItemFactory @Inject constructor(
return MessageFileItem_()
.avatarRenderer(avatarRenderer)
.colorProvider(colorProvider)
.dimensionConverter(dimensionConverter)
.informationData(informationData)
.highlighted(highlight)
.avatarCallback(callback)
@ -171,6 +176,7 @@ class MessageItemFactory @Inject constructor(
return DefaultItem_()
.text(text)
.avatarRenderer(avatarRenderer)
.dimensionConverter(dimensionConverter)
.highlighted(highlight)
.informationData(informationData)
.baseCallback(callback)
@ -197,6 +203,7 @@ class MessageItemFactory @Inject constructor(
return MessageImageVideoItem_()
.avatarRenderer(avatarRenderer)
.colorProvider(colorProvider)
.dimensionConverter(dimensionConverter)
.imageContentRenderer(imageContentRenderer)
.contentUploadStateTrackerBinder(contentUploadStateTrackerBinder)
.playable(messageContent.info?.mimeType == "image/gif")
@ -251,6 +258,7 @@ class MessageItemFactory @Inject constructor(
.contentUploadStateTrackerBinder(contentUploadStateTrackerBinder)
.avatarRenderer(avatarRenderer)
.colorProvider(colorProvider)
.dimensionConverter(dimensionConverter)
.playable(true)
.informationData(informationData)
.highlighted(highlight)
@ -290,9 +298,11 @@ class MessageItemFactory @Inject constructor(
message(linkifiedBody)
}
}
.useBigFont(linkifiedBody.length <= MAX_NUMBER_OF_EMOJI_FOR_BIG_FONT * 2 && containsOnlyEmojis(linkifiedBody.toString()))
.avatarRenderer(avatarRenderer)
.informationData(informationData)
.colorProvider(colorProvider)
.dimensionConverter(dimensionConverter)
.highlighted(highlight)
.avatarCallback(callback)
.urlClickCallback(callback)
@ -326,7 +336,8 @@ class MessageItemFactory @Inject constructor(
editEnd,
Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
spannable.setSpan(RelativeSizeSpan(.9f), editStart, editEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
// Note: text size is set to 14sp
spannable.setSpan(AbsoluteSizeSpan(dimensionConverter.spToPx(13)), editStart, editEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
spannable.setSpan(object : ClickableSpan() {
override fun onClick(widget: View?) {
callback?.onEditedDecorationClicked(informationData)
@ -359,6 +370,7 @@ class MessageItemFactory @Inject constructor(
.avatarRenderer(avatarRenderer)
.message(message)
.colorProvider(colorProvider)
.dimensionConverter(dimensionConverter)
.informationData(informationData)
.highlighted(highlight)
.avatarCallback(callback)
@ -400,6 +412,7 @@ class MessageItemFactory @Inject constructor(
}
.avatarRenderer(avatarRenderer)
.colorProvider(colorProvider)
.dimensionConverter(dimensionConverter)
.informationData(informationData)
.highlighted(highlight)
.avatarCallback(callback)
@ -423,6 +436,7 @@ class MessageItemFactory @Inject constructor(
return RedactedMessageItem_()
.avatarRenderer(avatarRenderer)
.colorProvider(colorProvider)
.dimensionConverter(dimensionConverter)
.informationData(informationData)
.highlighted(highlight)
.avatarCallback(callback)
@ -447,4 +461,8 @@ class MessageItemFactory @Inject constructor(
VectorLinkify.addLinks(spannable, true)
return spannable
}
companion object {
private const val MAX_NUMBER_OF_EMOJI_FOR_BIG_FONT = 5
}
}

View file

@ -17,12 +17,10 @@
package im.vector.riotx.features.home.room.detail.timeline.factory
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.riotx.core.utils.DimensionConverter
import im.vector.riotx.features.home.AvatarRenderer
import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
import im.vector.riotx.features.home.room.detail.timeline.format.NoticeEventFormatter
import im.vector.riotx.features.home.room.detail.timeline.helper.senderAvatar
import im.vector.riotx.features.home.room.detail.timeline.helper.senderName
import im.vector.riotx.features.home.room.detail.timeline.item.MessageInformationData
import im.vector.riotx.features.home.room.detail.timeline.item.NoticeItem
import im.vector.riotx.features.home.room.detail.timeline.item.NoticeItem_
import im.vector.riotx.features.home.room.detail.timeline.util.MessageInformationDataFactory
@ -30,7 +28,8 @@ import javax.inject.Inject
class NoticeItemFactory @Inject constructor(private val eventFormatter: NoticeEventFormatter,
private val avatarRenderer: AvatarRenderer,
private val informationDataFactory: MessageInformationDataFactory) {
private val informationDataFactory: MessageInformationDataFactory,
private val dimensionConverter: DimensionConverter) {
fun create(event: TimelineEvent,
highlight: Boolean,
@ -40,6 +39,7 @@ class NoticeItemFactory @Inject constructor(private val eventFormatter: NoticeEv
return NoticeItem_()
.avatarRenderer(avatarRenderer)
.dimensionConverter(dimensionConverter)
.noticeText(formattedText)
.highlighted(highlight)
.informationData(informationData)

View file

@ -33,7 +33,6 @@ import im.vector.matrix.android.api.session.room.send.SendState
import im.vector.riotx.R
import im.vector.riotx.core.resources.ColorProvider
import im.vector.riotx.core.utils.DebouncedClickListener
import im.vector.riotx.core.utils.DimensionUtils.dpToPx
import im.vector.riotx.features.home.AvatarRenderer
import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
import im.vector.riotx.features.reactions.widget.ReactionButton
@ -100,7 +99,7 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder> : BaseEventItem<H>() {
super.bind(holder)
if (informationData.showInformation) {
holder.avatarImageView.layoutParams = holder.avatarImageView.layoutParams?.apply {
val size = dpToPx(avatarStyle.avatarSizeDP, holder.view.context)
val size = dimensionConverter.dpToPx(avatarStyle.avatarSizeDP)
height = size
width = size
}

View file

@ -25,7 +25,7 @@ import im.vector.riotx.core.epoxy.VectorEpoxyHolder
import im.vector.riotx.core.epoxy.VectorEpoxyModel
import im.vector.riotx.core.platform.CheckableView
import im.vector.riotx.core.ui.views.ReadReceiptsView
import im.vector.riotx.core.utils.DimensionUtils.dpToPx
import im.vector.riotx.core.utils.DimensionConverter
/**
* Children must override getViewType()
@ -38,10 +38,13 @@ abstract class BaseEventItem<H : BaseEventItem.BaseHolder> : VectorEpoxyModel<H>
@EpoxyAttribute
var highlighted: Boolean = false
@EpoxyAttribute
lateinit var dimensionConverter: DimensionConverter
override fun bind(holder: H) {
super.bind(holder)
//optimize?
val px = dpToPx(avatarStyle.avatarSizeDP + 8, holder.view.context)
val px = dimensionConverter.dpToPx(avatarStyle.avatarSizeDP + 8)
holder.leftGuideline.setGuidelineBegin(px)
holder.checkableBackground.isChecked = highlighted

View file

@ -24,7 +24,6 @@ import androidx.core.widget.TextViewCompat
import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass
import im.vector.riotx.R
import im.vector.riotx.core.utils.containsOnlyEmojis
import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
import im.vector.riotx.features.html.PillImageSpan
import kotlinx.coroutines.Dispatchers
@ -39,6 +38,8 @@ abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
@EpoxyAttribute
var message: CharSequence? = null
@EpoxyAttribute
var useBigFont: Boolean = false
@EpoxyAttribute
var urlClickCallback: TimelineEventController.UrlClickCallback? = null
// Better link movement methods fixes the issue when
@ -65,9 +66,7 @@ abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
super.bind(holder)
holder.messageView.movementMethod = mvmtMethod
val msg = message ?: ""
if (msg.length <= 4 && containsOnlyEmojis(msg.toString())) {
if (useBigFont) {
holder.messageView.textSize = 44F
} else {
holder.messageView.textSize = 14F

View file

@ -32,13 +32,14 @@ import im.vector.matrix.android.internal.crypto.attachments.ElementToDecrypt
import im.vector.riotx.core.di.ActiveSessionHolder
import im.vector.riotx.core.glide.GlideApp
import im.vector.riotx.core.glide.GlideRequest
import im.vector.riotx.core.utils.DimensionUtils.dpToPx
import im.vector.riotx.core.utils.DimensionConverter
import kotlinx.android.parcel.Parcelize
import timber.log.Timber
import java.io.File
import javax.inject.Inject
class ImageContentRenderer @Inject constructor(private val activeSessionHolder: ActiveSessionHolder) {
class ImageContentRenderer @Inject constructor(private val activeSessionHolder: ActiveSessionHolder,
private val dimensionConverter: DimensionConverter) {
@Parcelize
data class Data(
@ -70,7 +71,7 @@ class ImageContentRenderer @Inject constructor(private val activeSessionHolder:
createGlideRequest(data, mode, imageView, width, height)
.dontAnimate()
.transform(RoundedCorners(dpToPx(8, imageView.context)))
.transform(RoundedCorners(dimensionConverter.dpToPx(8)))
.thumbnail(0.3f)
.into(imageView)