diff --git a/vector/src/main/java/im/vector/app/core/ui/views/NotificationAreaView.kt b/vector/src/main/java/im/vector/app/core/ui/views/NotificationAreaView.kt index b298a6d4d5..9eadafb423 100644 --- a/vector/src/main/java/im/vector/app/core/ui/views/NotificationAreaView.kt +++ b/vector/src/main/java/im/vector/app/core/ui/views/NotificationAreaView.kt @@ -28,6 +28,7 @@ import im.vector.app.R import im.vector.app.core.epoxy.onClick import im.vector.app.core.error.ResourceLimitErrorFormatter import im.vector.app.core.utils.DimensionConverter +import im.vector.app.core.utils.SafeBetterLinkMovementMethod import im.vector.app.databinding.ViewNotificationAreaBinding import im.vector.app.features.themes.ThemeUtils import me.gujun.android.span.span @@ -156,7 +157,7 @@ class NotificationAreaView @JvmOverloads constructor( onClick = { delegate?.onTombstoneEventClicked() } } } - views.roomNotificationMessage.movementMethod = BetterLinkMovementMethod.getInstance() + views.roomNotificationMessage.movementMethod = SafeBetterLinkMovementMethod views.roomNotificationMessage.text = message } diff --git a/vector/src/main/java/im/vector/app/core/utils/EvenBetterLinkMovementMethod.kt b/vector/src/main/java/im/vector/app/core/utils/EvenBetterLinkMovementMethod.kt index a53c8161b1..978d607480 100644 --- a/vector/src/main/java/im/vector/app/core/utils/EvenBetterLinkMovementMethod.kt +++ b/vector/src/main/java/im/vector/app/core/utils/EvenBetterLinkMovementMethod.kt @@ -36,11 +36,16 @@ class EvenBetterLinkMovementMethod(private val onLinkClickListener: OnLinkClickL } override fun dispatchUrlClick(textView: TextView, clickableSpan: ClickableSpan) { - val spanned = textView.text as Spanned - val actualText = textView.text.subSequence(spanned.getSpanStart(clickableSpan), spanned.getSpanEnd(clickableSpan)).toString() - val url = (clickableSpan as? URLSpan)?.url ?: actualText + try { + val spanned = textView.text as Spanned + val actualText = textView.text.subSequence(spanned.getSpanStart(clickableSpan), spanned.getSpanEnd(clickableSpan)).toString() + val url = (clickableSpan as? URLSpan)?.url ?: actualText - if (onLinkClickListener == null || !onLinkClickListener.onLinkClicked(textView, clickableSpan, url, actualText)) { + if (onLinkClickListener == null || !onLinkClickListener.onLinkClicked(textView, clickableSpan, url, actualText)) { + // Let Android handle this long click as a short-click. + clickableSpan.onClick(textView) + } + } catch (e: StringIndexOutOfBoundsException) { // Let Android handle this long click as a short-click. clickableSpan.onClick(textView) } diff --git a/vector/src/main/java/im/vector/app/core/utils/SafeBetterLinkMovementMethod.kt b/vector/src/main/java/im/vector/app/core/utils/SafeBetterLinkMovementMethod.kt new file mode 100644 index 0000000000..752b3e24ed --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/utils/SafeBetterLinkMovementMethod.kt @@ -0,0 +1,33 @@ +package im.vector.app.core.utils + +import android.text.style.ClickableSpan +import android.widget.TextView +import me.saket.bettermovementmethod.BetterLinkMovementMethod +import timber.log.Timber + +object SafeBetterLinkMovementMethod: BetterLinkMovementMethod() { + + override fun dispatchUrlClick(textView: TextView?, clickableSpan: ClickableSpan?) { + try { + super.dispatchUrlClick(textView, clickableSpan) + } catch (e: StringIndexOutOfBoundsException) { + Timber.w("BetterLinkMovement dispatchUrlClick StringIndexOutOfBoundsException $e") + // Let Android handle this click. + textView?.let { + clickableSpan?.onClick(it) + } + } + } + + override fun dispatchUrlLongClick(textView: TextView?, clickableSpan: ClickableSpan?) { + try { + super.dispatchUrlLongClick(textView, clickableSpan) + } catch (e: StringIndexOutOfBoundsException) { + Timber.w("BetterLinkMovement dispatchUrlLongClick StringIndexOutOfBoundsException $e") + // Let Android handle this long click as a short-click. + textView?.let { + clickableSpan?.onClick(it) + } + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/RoomCreateItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/RoomCreateItem.kt index 394079ed5f..d3c5f61a64 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/RoomCreateItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/RoomCreateItem.kt @@ -22,8 +22,8 @@ import com.airbnb.epoxy.EpoxyModelClass import im.vector.app.R import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyModel +import im.vector.app.core.utils.SafeBetterLinkMovementMethod import im.vector.lib.core.utils.epoxy.charsequence.EpoxyCharSequence -import me.saket.bettermovementmethod.BetterLinkMovementMethod @EpoxyModelClass abstract class RoomCreateItem : VectorEpoxyModel(R.layout.item_timeline_event_create) { @@ -32,7 +32,7 @@ abstract class RoomCreateItem : VectorEpoxyModel(R.layout override fun bind(holder: Holder) { super.bind(holder) - holder.description.movementMethod = BetterLinkMovementMethod.getInstance() + holder.description.movementMethod = SafeBetterLinkMovementMethod holder.description.text = text.charSequence }