fix: replace compose cursor position code with view

Signed-off-by: Infi <infi@infi.sh>
This commit is contained in:
Infi 2023-11-12 21:37:09 +01:00
parent e2dfb7ecc0
commit afa1f5941f
3 changed files with 25 additions and 21 deletions

View File

@ -78,7 +78,8 @@ fun NativeMessageField(
disabled: Boolean = false, disabled: Boolean = false,
editMode: Boolean = false, editMode: Boolean = false,
cancelEdit: () -> Unit = {}, cancelEdit: () -> Unit = {},
onFocusChange: (Boolean) -> Unit = {} onFocusChange: (Boolean) -> Unit = {},
onSelectionChange: (Pair<Int, Int>) -> Unit = {}
) { ) {
val placeholderResource = when (channelType) { val placeholderResource = when (channelType) {
ChannelType.DirectMessage -> R.string.message_field_placeholder_dm ChannelType.DirectMessage -> R.string.message_field_placeholder_dm
@ -155,6 +156,11 @@ fun NativeMessageField(
} }
return ic return ic
} }
override fun onSelectionChanged(selStart: Int, selEnd: Int) {
super.onSelectionChanged(selStart, selEnd)
onSelectionChange(selStart to selEnd)
}
}.apply { }.apply {
background = null background = null
textSize = 16f textSize = 16f
@ -319,6 +325,7 @@ fun NativeMessageFieldPreview() {
disabled = false, disabled = false,
editMode = false, editMode = false,
cancelEdit = {}, cancelEdit = {},
onFocusChange = {} onFocusChange = {},
onSelectionChange = {}
) )
} }

View File

@ -57,7 +57,6 @@ import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
@ -91,10 +90,10 @@ import chat.revolt.sheets.ChannelInfoSheet
import chat.revolt.sheets.MessageContextSheet import chat.revolt.sheets.MessageContextSheet
import com.discord.simpleast.core.simple.SimpleMarkdownRules import com.discord.simpleast.core.simple.SimpleMarkdownRules
import com.discord.simpleast.core.simple.SimpleRenderer import com.discord.simpleast.core.simple.SimpleRenderer
import java.io.File
import java.io.FileNotFoundException
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.io.File
import java.io.FileNotFoundException
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
@ -180,13 +179,6 @@ fun ChannelScreen(
label = "ScrollDownFABPadding" label = "ScrollDownFABPadding"
) )
val fieldContent = remember(viewModel.pendingMessageContent, viewModel.textSelection) {
TextFieldValue(
viewModel.pendingMessageContent,
viewModel.textSelection
)
}
LaunchedEffect(channelId) { LaunchedEffect(channelId) {
viewModel.activeChannelId = channelId viewModel.activeChannelId = channelId
viewModel.fetchChannel(channelId) viewModel.fetchChannel(channelId)
@ -479,7 +471,7 @@ fun ChannelScreen(
) )
} else { } else {
NativeMessageField( NativeMessageField(
value = fieldContent.text, value = viewModel.pendingMessageContent,
onValueChange = { onValueChange = {
viewModel.pendingMessageContent = it viewModel.pendingMessageContent = it
// viewModel.textSelection = it.selection // viewModel.textSelection = it.selection
@ -528,6 +520,9 @@ fun ChannelScreen(
if (nowFocused && viewModel.currentBottomPane != BottomPane.None) { if (nowFocused && viewModel.currentBottomPane != BottomPane.None) {
viewModel.currentBottomPane = BottomPane.None viewModel.currentBottomPane = BottomPane.None
} }
},
onSelectionChange = {
viewModel.textSelection = it
} }
) )
} }

View File

@ -8,7 +8,6 @@ import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.runtime.toMutableStateList import androidx.compose.runtime.toMutableStateList
import androidx.compose.ui.text.TextRange
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import chat.revolt.R import chat.revolt.R
@ -71,7 +70,7 @@ class ChannelScreenViewModel : ViewModel() {
var hasNoMoreMessages by mutableStateOf(false) var hasNoMoreMessages by mutableStateOf(false)
var pendingMessageContent by mutableStateOf("") var pendingMessageContent by mutableStateOf("")
var textSelection by mutableStateOf(TextRange(0)) var textSelection by mutableStateOf(0 to 0)
var pendingReplies = mutableStateListOf<SendMessageReply>() var pendingReplies = mutableStateListOf<SendMessageReply>()
var pendingAttachments = mutableStateListOf<FileArgs>() var pendingAttachments = mutableStateListOf<FileArgs>()
@ -404,7 +403,8 @@ class ChannelScreenViewModel : ViewModel() {
msg.id == it.messageId msg.id == it.messageId
} ?: return@onEach } ?: return@onEach
pendingMessageContent = message.content ?: "" pendingMessageContent = message.content ?: ""
textSelection = TextRange(message.content?.length ?: 0) textSelection =
(message.content?.length ?: 0) to (message.content?.length ?: 0)
} }
} }
}.catch { }.catch {
@ -456,18 +456,20 @@ class ChannelScreenViewModel : ViewModel() {
val currentSelection = textSelection val currentSelection = textSelection
// if out of bounds, just append // if out of bounds, just append
if (currentSelection.start > currentContent.length) { if (currentSelection.first > currentContent.length) {
pendingMessageContent = currentContent + content pendingMessageContent = currentContent + content
textSelection = TextRange(currentContent.length + content.length) textSelection =
currentSelection.first + content.length to currentSelection.first + content.length
return return
} }
val newContent = currentContent.substring(0, currentSelection.start) + val newContent = currentContent.substring(0, currentSelection.first) +
content + content +
currentContent.substring(currentSelection.end) currentContent.substring(currentSelection.second)
pendingMessageContent = newContent pendingMessageContent = newContent
textSelection = TextRange(currentSelection.start + content.length) textSelection =
currentSelection.first + content.length to currentSelection.first + content.length
} }
suspend fun checkShouldDenyMessageField() { suspend fun checkShouldDenyMessageField() {