session-android/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/LinkPreviewView.kt

99 lines
4.1 KiB
Kotlin
Raw Normal View History

2021-06-01 06:56:58 +02:00
package org.thoughtcrime.securesms.conversation.v2.messages
import android.content.Context
2021-06-25 06:06:53 +02:00
import android.graphics.Canvas
import android.graphics.Rect
2021-06-01 06:56:58 +02:00
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.MotionEvent
2021-06-01 06:56:58 +02:00
import android.widget.LinearLayout
import android.widget.TextView
2021-06-29 06:23:36 +02:00
import androidx.appcompat.app.AppCompatActivity
2021-06-22 02:39:34 +02:00
import androidx.core.content.res.ResourcesCompat
import androidx.core.view.isVisible
2021-06-01 06:56:58 +02:00
import kotlinx.android.synthetic.main.view_link_preview.view.*
import network.loki.messenger.R
2021-06-25 06:06:53 +02:00
import org.thoughtcrime.securesms.components.CornerMask
import org.thoughtcrime.securesms.conversation.v2.ModalUrlBottomSheet
2021-06-25 06:06:53 +02:00
import org.thoughtcrime.securesms.conversation.v2.utilities.MessageBubbleUtilities
import org.thoughtcrime.securesms.conversation.v2.utilities.TextUtilities.getIntersectedModalSpans
2021-06-21 07:26:09 +02:00
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.mms.GlideRequests
2021-06-24 07:03:29 +02:00
import org.thoughtcrime.securesms.mms.ImageSlide
import org.thoughtcrime.securesms.util.UiModeUtilities
2021-06-01 06:56:58 +02:00
class LinkPreviewView : LinearLayout {
2021-06-25 06:06:53 +02:00
private val cornerMask by lazy { CornerMask(this) }
2021-06-29 06:23:36 +02:00
private var url: String? = null
lateinit var bodyTextView: TextView
2021-06-01 06:56:58 +02:00
// region Lifecycle
2021-06-21 06:24:00 +02:00
constructor(context: Context) : super(context) { initialize() }
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { initialize() }
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { initialize() }
2021-06-01 06:56:58 +02:00
2021-06-21 06:24:00 +02:00
private fun initialize() {
2021-06-01 06:56:58 +02:00
LayoutInflater.from(context).inflate(R.layout.view_link_preview, this)
}
// endregion
// region Updating
2021-06-29 03:49:45 +02:00
fun bind(message: MmsMessageRecord, glide: GlideRequests, isStartOfMessageCluster: Boolean, isEndOfMessageCluster: Boolean, searchQuery: String?) {
2021-06-21 07:26:09 +02:00
val linkPreview = message.linkPreviews.first()
2021-06-29 06:23:36 +02:00
url = linkPreview.url
// Thumbnail
2021-06-24 07:03:29 +02:00
if (linkPreview.getThumbnail().isPresent) {
2021-06-25 01:19:21 +02:00
// This internally fetches the thumbnail
thumbnailImageView.setImageResource(glide, ImageSlide(context, linkPreview.getThumbnail().get()), isPreview = false, message)
thumbnailImageView.loadIndicator.isVisible = false
2021-06-24 07:03:29 +02:00
}
2021-06-21 07:26:09 +02:00
// Title
titleTextView.text = linkPreview.title
2021-06-22 02:39:34 +02:00
val textColorID = if (message.isOutgoing && UiModeUtilities.isDayUiMode(context)) {
R.color.white
} else {
if (UiModeUtilities.isDayUiMode(context)) R.color.black else R.color.white
}
titleTextView.setTextColor(ResourcesCompat.getColor(resources, textColorID, context.theme))
2021-06-22 01:34:23 +02:00
// Body
bodyTextView = VisibleMessageContentView.getBodyTextView(context, message, searchQuery)
2021-06-23 06:08:17 +02:00
mainLinkPreviewContainer.addView(bodyTextView)
2021-06-25 06:06:53 +02:00
// Corner radii
val cornerRadii = MessageBubbleUtilities.calculateRadii(context, isStartOfMessageCluster, isEndOfMessageCluster, message.isOutgoing)
cornerMask.setTopLeftRadius(cornerRadii[0])
cornerMask.setTopRightRadius(cornerRadii[1])
cornerMask.setBottomRightRadius(cornerRadii[2])
cornerMask.setBottomLeftRadius(cornerRadii[3])
}
override fun dispatchDraw(canvas: Canvas) {
super.dispatchDraw(canvas)
cornerMask.mask(canvas)
2021-06-01 06:56:58 +02:00
}
// endregion
2021-06-29 06:23:36 +02:00
// region Interaction
fun calculateHit(event: MotionEvent) {
val rawXInt = event.rawX.toInt()
val rawYInt = event.rawY.toInt()
val hitRect = Rect(rawXInt, rawYInt, rawXInt, rawYInt)
val previewRect = Rect()
mainLinkPreviewParent.getGlobalVisibleRect(previewRect)
if (previewRect.contains(hitRect)) {
openURL()
return
}
// intersectedModalSpans should only be a list of one item
val hitSpans = bodyTextView.getIntersectedModalSpans(hitRect)
hitSpans.forEach { span ->
span.onClick(bodyTextView)
}
}
2021-06-29 06:23:36 +02:00
fun openURL() {
val url = this.url ?: return
val activity = context as AppCompatActivity
ModalUrlBottomSheet(url).show(activity.supportFragmentManager, "Open URL Dialog")
2021-06-01 06:56:58 +02:00
}
// endregion
}