Linkify story captions.

This commit is contained in:
Sagar
2025-04-08 21:11:29 +05:30
committed by Michelle Tang
parent 9c95cfd64b
commit 8d8519b52e
2 changed files with 38 additions and 16 deletions

View File

@@ -9,11 +9,14 @@ import android.graphics.Rect
import android.graphics.Typeface
import android.media.AudioManager
import android.os.Bundle
import android.text.Spannable
import android.text.SpannableString
import android.text.Spanned
import android.text.method.ScrollingMovementMethod
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
import android.text.style.StyleSpan
import android.text.style.URLSpan
import android.text.util.Linkify
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.ScaleGestureDetector
@@ -27,6 +30,7 @@ import androidx.constraintlayout.widget.ConstraintSet
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
import androidx.core.text.util.LinkifyCompat
import androidx.core.view.GestureDetectorCompat
import androidx.core.view.animation.PathInterpolatorCompat
import androidx.fragment.app.DialogFragment
@@ -89,6 +93,8 @@ import org.thoughtcrime.securesms.util.AvatarUtil
import org.thoughtcrime.securesms.util.BottomSheetUtil
import org.thoughtcrime.securesms.util.DateUtils
import org.thoughtcrime.securesms.util.Debouncer
import org.thoughtcrime.securesms.util.LinkUtil
import org.thoughtcrime.securesms.util.LongClickCopySpan
import org.thoughtcrime.securesms.util.LongClickMovementMethod
import org.thoughtcrime.securesms.util.Projection
import org.thoughtcrime.securesms.util.ServiceUtil
@@ -941,7 +947,7 @@ class StoryViewerPageFragment :
if (ranges != null && displayBodySpan.isNotEmpty()) {
MessageStyler.style(storyPost.conversationMessage.messageRecord.dateSent, ranges, displayBodySpan)
}
linkifyUrlLinks(displayBodySpan)
displayBodySpan
} else {
""
@@ -960,9 +966,9 @@ class StoryViewerPageFragment :
caption.setOverflowText(overflow)
caption.maxLines = 5
caption.text = displayBody
caption.setMaxLength(280)
caption.setMaxLength(SMALL_CAPTION_TEXT_MAX_LENGTH)
if (caption.text.length == displayBody.length) {
if (displayBody.length <= SMALL_CAPTION_TEXT_MAX_LENGTH) {
caption.setOnClickListener(null)
caption.isClickable = false
} else {
@@ -972,13 +978,32 @@ class StoryViewerPageFragment :
}
}
fun linkifyUrlLinks(spannable: Spannable) {
val hasLinks = LinkifyCompat.addLinks(spannable, CAPTION_LINK_PATTERN)
if (hasLinks) {
spannable.getSpans(0, spannable.length, URLSpan::class.java)
.filterNot { url -> LinkUtil.isLegalUrl(url.url) }
.forEach { spannable.removeSpan(it) }
val urlSpans = spannable.getSpans(0, spannable.length, URLSpan::class.java)
for (urlSpan in urlSpans) {
val start = spannable.getSpanStart(urlSpan)
val end = spannable.getSpanEnd(urlSpan)
val span = LongClickCopySpan(urlSpan.url)
spannable.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
}
}
}
private fun onShowCaptionOverlay(caption: TextView, largeCaption: TextView, largeCaptionOverlay: View) {
sharedViewModel.setIsChildScrolling(true)
caption.visible = false
largeCaption.visible = true
largeCaptionOverlay.visible = true
largeCaption.movementMethod = ScrollingMovementMethod()
largeCaption.movementMethod = LinkMovementMethod.getInstance()
largeCaption.scrollY = 0
largeCaption.setOnClickListener {
onHideCaptionOverlay(caption, largeCaption, largeCaptionOverlay)
@@ -1273,6 +1298,8 @@ class StoryViewerPageFragment :
private val CHARACTERS_PER_SECOND = 15L
private val DEFAULT_DURATION = TimeUnit.SECONDS.toMillis(5)
private val ONBOARDING_DURATION = TimeUnit.SECONDS.toMillis(10)
private const val SMALL_CAPTION_TEXT_MAX_LENGTH = 280
private const val CAPTION_LINK_PATTERN = Linkify.WEB_URLS or Linkify.EMAIL_ADDRESSES or Linkify.PHONE_NUMBERS
private const val ARGS = "args"