feat: добавить onTextLongPress callback и getLayoutInfo() в AppleEmojiTextView

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-12 15:05:25 +05:00
parent 419761e34d
commit a10482b794

View File

@@ -558,6 +558,8 @@ fun AppleEmojiText(
onClickableSpanPressStart: (() -> Unit)? = null, onClickableSpanPressStart: (() -> Unit)? = null,
onClick: (() -> Unit)? = null, // 🔥 Обычный tap (selection mode в MessageBubble) onClick: (() -> Unit)? = null, // 🔥 Обычный tap (selection mode в MessageBubble)
onLongClick: (() -> Unit)? = null, // 🔥 Callback для long press (selection в MessageBubble) onLongClick: (() -> Unit)? = null, // 🔥 Callback для long press (selection в MessageBubble)
onTextLongPress: ((touchX: Int, touchY: Int) -> Unit)? = null,
onViewCreated: ((com.rosetta.messenger.ui.components.AppleEmojiTextView) -> Unit)? = null,
minHeightMultiplier: Float = 1.5f minHeightMultiplier: Float = 1.5f
) { ) {
val fontSizeValue = if (fontSize == androidx.compose.ui.unit.TextUnit.Unspecified) 15f val fontSizeValue = if (fontSize == androidx.compose.ui.unit.TextUnit.Unspecified) 15f
@@ -601,6 +603,8 @@ fun AppleEmojiText(
enableMentionHighlight(enableMentions) enableMentionHighlight(enableMentions)
setOnMentionClickListener(onMentionClick) setOnMentionClickListener(onMentionClick)
setOnClickableSpanPressStartListener(onClickableSpanPressStart) setOnClickableSpanPressStartListener(onClickableSpanPressStart)
onTextLongPressCallback = onTextLongPress
onViewCreated?.invoke(this)
// In link/mention mode, keep span clicks exclusive to avoid parent bubble menu tap. // In link/mention mode, keep span clicks exclusive to avoid parent bubble menu tap.
val canUseTextViewClick = !enableLinks val canUseTextViewClick = !enableLinks
setOnClickListener( setOnClickListener(
@@ -634,6 +638,7 @@ fun AppleEmojiText(
view.enableMentionHighlight(enableMentions) view.enableMentionHighlight(enableMentions)
view.setOnMentionClickListener(onMentionClick) view.setOnMentionClickListener(onMentionClick)
view.setOnClickableSpanPressStartListener(onClickableSpanPressStart) view.setOnClickableSpanPressStartListener(onClickableSpanPressStart)
view.onTextLongPressCallback = onTextLongPress
// In link/mention mode, keep span clicks exclusive to avoid parent bubble menu tap. // In link/mention mode, keep span clicks exclusive to avoid parent bubble menu tap.
val canUseTextViewClick = !enableLinks val canUseTextViewClick = !enableLinks
view.setOnClickListener( view.setOnClickListener(
@@ -695,13 +700,17 @@ class AppleEmojiTextView @JvmOverloads constructor(
// 🔥 Long press callback для selection в MessageBubble // 🔥 Long press callback для selection в MessageBubble
var onLongClickCallback: (() -> Unit)? = null var onLongClickCallback: (() -> Unit)? = null
var onTextLongPressCallback: ((touchX: Int, touchY: Int) -> Unit)? = null
private var downOnClickableSpan: Boolean = false private var downOnClickableSpan: Boolean = false
private var suppressPerformClickOnce: Boolean = false private var suppressPerformClickOnce: Boolean = false
// 🔥 GestureDetector для обработки long press поверх LinkMovementMethod // 🔥 GestureDetector для обработки long press поверх LinkMovementMethod
private val gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() { private val gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
override fun onLongPress(e: MotionEvent) { override fun onLongPress(e: MotionEvent) {
if (!downOnClickableSpan) { if (downOnClickableSpan) return
if (onTextLongPressCallback != null) {
onTextLongPressCallback?.invoke(e.rawX.toInt(), e.rawY.toInt())
} else {
onLongClickCallback?.invoke() onLongClickCallback?.invoke()
} }
} }
@@ -822,6 +831,18 @@ class AppleEmojiTextView @JvmOverloads constructor(
} }
} }
fun getLayoutInfo(): com.rosetta.messenger.ui.chats.components.LayoutInfo? {
val l = layout ?: return null
val loc = IntArray(2)
getLocationInWindow(loc)
return com.rosetta.messenger.ui.chats.components.LayoutInfo(
layout = l,
windowX = loc[0] + totalPaddingLeft,
windowY = loc[1] + totalPaddingTop,
text = text ?: return null
)
}
fun setTextWithEmojis(text: String) { fun setTextWithEmojis(text: String) {
val isLargeText = text.length > LARGE_TEXT_RENDER_THRESHOLD val isLargeText = text.length > LARGE_TEXT_RENDER_THRESHOLD
val processMentions = mentionsEnabled && !isLargeText val processMentions = mentionsEnabled && !isLargeText