From afa1f5941f1081a2e56db37ffe36eb175af6ac95 Mon Sep 17 00:00:00 2001 From: Infi Date: Sun, 12 Nov 2023 21:37:09 +0100 Subject: [PATCH] fix: replace compose cursor position code with view Signed-off-by: Infi --- .../components/chat/NativeMessageField.kt | 11 +++++++++-- .../chat/views/channel/ChannelScreen.kt | 17 ++++++----------- .../views/channel/ChannelScreenViewModel.kt | 18 ++++++++++-------- 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/chat/revolt/components/chat/NativeMessageField.kt b/app/src/main/java/chat/revolt/components/chat/NativeMessageField.kt index e93e6ca7..8689c2ee 100644 --- a/app/src/main/java/chat/revolt/components/chat/NativeMessageField.kt +++ b/app/src/main/java/chat/revolt/components/chat/NativeMessageField.kt @@ -78,7 +78,8 @@ fun NativeMessageField( disabled: Boolean = false, editMode: Boolean = false, cancelEdit: () -> Unit = {}, - onFocusChange: (Boolean) -> Unit = {} + onFocusChange: (Boolean) -> Unit = {}, + onSelectionChange: (Pair) -> Unit = {} ) { val placeholderResource = when (channelType) { ChannelType.DirectMessage -> R.string.message_field_placeholder_dm @@ -155,6 +156,11 @@ fun NativeMessageField( } return ic } + + override fun onSelectionChanged(selStart: Int, selEnd: Int) { + super.onSelectionChanged(selStart, selEnd) + onSelectionChange(selStart to selEnd) + } }.apply { background = null textSize = 16f @@ -319,6 +325,7 @@ fun NativeMessageFieldPreview() { disabled = false, editMode = false, cancelEdit = {}, - onFocusChange = {} + onFocusChange = {}, + onSelectionChange = {} ) } diff --git a/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreen.kt b/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreen.kt index e8f81b55..0bcedd1d 100644 --- a/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreen.kt +++ b/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreen.kt @@ -57,7 +57,6 @@ import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.documentfile.provider.DocumentFile @@ -91,10 +90,10 @@ import chat.revolt.sheets.ChannelInfoSheet import chat.revolt.sheets.MessageContextSheet import com.discord.simpleast.core.simple.SimpleMarkdownRules import com.discord.simpleast.core.simple.SimpleRenderer -import java.io.File -import java.io.FileNotFoundException import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.launch +import java.io.File +import java.io.FileNotFoundException @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -180,13 +179,6 @@ fun ChannelScreen( label = "ScrollDownFABPadding" ) - val fieldContent = remember(viewModel.pendingMessageContent, viewModel.textSelection) { - TextFieldValue( - viewModel.pendingMessageContent, - viewModel.textSelection - ) - } - LaunchedEffect(channelId) { viewModel.activeChannelId = channelId viewModel.fetchChannel(channelId) @@ -479,7 +471,7 @@ fun ChannelScreen( ) } else { NativeMessageField( - value = fieldContent.text, + value = viewModel.pendingMessageContent, onValueChange = { viewModel.pendingMessageContent = it // viewModel.textSelection = it.selection @@ -528,6 +520,9 @@ fun ChannelScreen( if (nowFocused && viewModel.currentBottomPane != BottomPane.None) { viewModel.currentBottomPane = BottomPane.None } + }, + onSelectionChange = { + viewModel.textSelection = it } ) } diff --git a/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreenViewModel.kt b/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreenViewModel.kt index dc268813..63ad68e4 100644 --- a/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreenViewModel.kt +++ b/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreenViewModel.kt @@ -8,7 +8,6 @@ import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.runtime.toMutableStateList -import androidx.compose.ui.text.TextRange import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import chat.revolt.R @@ -71,7 +70,7 @@ class ChannelScreenViewModel : ViewModel() { var hasNoMoreMessages by mutableStateOf(false) var pendingMessageContent by mutableStateOf("") - var textSelection by mutableStateOf(TextRange(0)) + var textSelection by mutableStateOf(0 to 0) var pendingReplies = mutableStateListOf() var pendingAttachments = mutableStateListOf() @@ -404,7 +403,8 @@ class ChannelScreenViewModel : ViewModel() { msg.id == it.messageId } ?: return@onEach pendingMessageContent = message.content ?: "" - textSelection = TextRange(message.content?.length ?: 0) + textSelection = + (message.content?.length ?: 0) to (message.content?.length ?: 0) } } }.catch { @@ -456,18 +456,20 @@ class ChannelScreenViewModel : ViewModel() { val currentSelection = textSelection // if out of bounds, just append - if (currentSelection.start > currentContent.length) { + if (currentSelection.first > currentContent.length) { pendingMessageContent = currentContent + content - textSelection = TextRange(currentContent.length + content.length) + textSelection = + currentSelection.first + content.length to currentSelection.first + content.length return } - val newContent = currentContent.substring(0, currentSelection.start) + + val newContent = currentContent.substring(0, currentSelection.first) + content + - currentContent.substring(currentSelection.end) + currentContent.substring(currentSelection.second) pendingMessageContent = newContent - textSelection = TextRange(currentSelection.start + content.length) + textSelection = + currentSelection.first + content.length to currentSelection.first + content.length } suspend fun checkShouldDenyMessageField() {