diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/ChatDetailScreen.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/ChatDetailScreen.kt index 27b3702..8e92cbe 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/ChatDetailScreen.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/ChatDetailScreen.kt @@ -396,6 +396,7 @@ fun ChatDetailScreen( // 🔤 TEXT SELECTION - Telegram-style character-level selection val textSelectionHelper = remember { com.rosetta.messenger.ui.chats.components.TextSelectionHelper() } + LaunchedEffect(Unit) { textSelectionHelper.setMagnifierView(view) } // 💬 MESSAGE CONTEXT MENU STATE var contextMenuMessage by remember { mutableStateOf(null) } diff --git a/app/src/test/java/com/rosetta/messenger/ui/chats/components/TextSelectionHelperTest.kt b/app/src/test/java/com/rosetta/messenger/ui/chats/components/TextSelectionHelperTest.kt new file mode 100644 index 0000000..db746fc --- /dev/null +++ b/app/src/test/java/com/rosetta/messenger/ui/chats/components/TextSelectionHelperTest.kt @@ -0,0 +1,77 @@ +package com.rosetta.messenger.ui.chats.components + +import org.junit.Assert.* +import org.junit.Before +import org.junit.Test + +class TextSelectionHelperTest { + + private lateinit var helper: TextSelectionHelper + + @Before + fun setup() { + helper = TextSelectionHelper() + } + + @Test + fun `initial state is not active`() { + assertFalse(helper.isActive) + assertFalse(helper.isInSelectionMode) + assertEquals(-1, helper.selectionStart) + assertEquals(-1, helper.selectionEnd) + assertNull(helper.selectedMessageId) + } + + @Test + fun `clear resets all state`() { + helper.clear() + assertFalse(helper.isActive) + assertEquals(-1, helper.selectionStart) + assertEquals(-1, helper.selectionEnd) + assertNull(helper.selectedMessageId) + assertNull(helper.layoutInfo) + assertFalse(helper.showToolbar) + assertFalse(helper.movingHandle) + } + + @Test + fun `getSelectedText returns null when not active`() { + assertNull(helper.getSelectedText()) + } + + @Test + fun `updateSelectionEnd does not change when not active`() { + helper.updateSelectionEnd(5) + assertEquals(-1, helper.selectionEnd) + } + + @Test + fun `updateSelectionStart does not change when not active`() { + helper.updateSelectionStart(0) + assertEquals(-1, helper.selectionStart) + } + + @Test + fun `getCharOffsetFromCoords returns -1 when no layout`() { + assertEquals(-1, helper.getCharOffsetFromCoords(100, 100)) + } + + @Test + fun `selectAll does nothing when no layout`() { + helper.selectAll() + assertEquals(-1, helper.selectionStart) + assertEquals(-1, helper.selectionEnd) + } + + @Test + fun `moveHandle does nothing when not moving`() { + helper.moveHandle(100f, 100f) + assertFalse(helper.movingHandle) + } + + @Test + fun `endHandleDrag sets movingHandle to false`() { + helper.endHandleDrag() + assertFalse(helper.movingHandle) + } +}