From 9fe5f359239c18883e542ffab7430b35041a70a1 Mon Sep 17 00:00:00 2001 From: k1ngsterr1 Date: Sun, 12 Apr 2026 16:17:32 +0500 Subject: [PATCH] =?UTF-8?q?fix:=20=D0=BF=D0=BE=D1=81=D0=B8=D0=BC=D0=B2?= =?UTF-8?q?=D0=BE=D0=BB=D1=8C=D0=BD=D0=BE=D0=B5=20=D0=B2=D1=8B=D0=B4=D0=B5?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20+=20magnifier=20=D0=BD=D0=B0?= =?UTF-8?q?=20=D0=BF=D0=BE=D0=B7=D0=B8=D1=86=D0=B8=D0=B8=20handle=20+=20ha?= =?UTF-8?q?ptic=20=D0=BD=D0=B0=20=D0=BA=D0=B0=D0=B6=D0=B4=D1=8B=D0=B9=20?= =?UTF-8?q?=D1=81=D0=B8=D0=BC=D0=B2=D0=BE=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Было: word snap при drag handle → нельзя выделить часть слова Стало: посимвольно при drag (word snap только при первом long press) Magnifier: показывается на позиции handle (текущий символ), а не на позиции пальца. По Y — центр строки текста. Haptic: TEXT_HANDLE_MOVE на каждый символ (не на каждое слово). Co-Authored-By: Claude Opus 4.6 (1M context) --- .../chats/components/TextSelectionHelper.kt | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/components/TextSelectionHelper.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/components/TextSelectionHelper.kt index 513faf4..8e7f8ba 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/components/TextSelectionHelper.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/components/TextSelectionHelper.kt @@ -124,8 +124,7 @@ class TextSelectionHelper { fun updateSelectionStart(charOffset: Int) { if (!isActive) return val text = layoutInfo?.text ?: return - var newStart = charOffset.coerceIn(0, text.length) - while (newStart > 0 && Character.isLetterOrDigit(text[newStart - 1])) newStart-- + val newStart = charOffset.coerceIn(0, text.length) if (newStart >= selectionEnd) return val changed = newStart != selectionStart selectionStart = newStart @@ -135,8 +134,7 @@ class TextSelectionHelper { fun updateSelectionEnd(charOffset: Int) { if (!isActive) return val text = layoutInfo?.text ?: return - var newEnd = charOffset.coerceIn(0, text.length) - while (newEnd < text.length && Character.isLetterOrDigit(text[newEnd])) newEnd++ + val newEnd = charOffset.coerceIn(0, text.length) if (newEnd <= selectionStart) return val changed = newEnd != selectionEnd selectionEnd = newEnd @@ -201,7 +199,7 @@ class TextSelectionHelper { .setSize(240, 64) .setCornerRadius(12f) .setElevation(4f) - .setDefaultSourceToMagnifierOffset(0, -80) + .setDefaultSourceToMagnifierOffset(0, -96) .build() } else { @Suppress("DEPRECATION") @@ -209,11 +207,21 @@ class TextSelectionHelper { } } val info = layoutInfo ?: return - // Convert overlay-local → view-local (magnifierView coords) + + // Magnifier should show at the HANDLE position (current char), not finger + // Use handle X for horizontal, and line center for vertical + val handleX = if (movingHandleStart) startHandleX else endHandleX + val handleY = if (movingHandleStart) startHandleY else endHandleY + val activeOffset = if (movingHandleStart) selectionStart else selectionEnd + val layout = info.layout + val line = layout.getLineForOffset(activeOffset.coerceIn(0, info.text.length)) + val lineCenter = (layout.getLineTop(line) + layout.getLineBottom(line)) / 2f + + // Convert to view-local coordinates val viewLoc = IntArray(2) view.getLocationInWindow(viewLoc) - val sourceX = (overlayLocalX + overlayWindowX - viewLoc[0]).coerceIn(0f, view.width.toFloat()) - val sourceY = (overlayLocalY + overlayWindowY - viewLoc[1]).coerceIn(0f, view.height.toFloat()) + val sourceX = (handleX + overlayWindowX - viewLoc[0]).coerceIn(0f, view.width.toFloat()) + val sourceY = (lineCenter + info.windowY - viewLoc[1]).coerceIn(0f, view.height.toFloat()) magnifier?.show(sourceX, sourceY) }