feat: cursor at end when editing and open keyboard

Signed-off-by: Infi <infi@infi.sh>
This commit is contained in:
Infi 2023-10-01 00:53:41 +02:00
parent 5a6a25c113
commit 3652d01ea8
3 changed files with 61 additions and 40 deletions

View File

@ -29,6 +29,7 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TextFieldDefaults import androidx.compose.material3.TextFieldDefaults
import androidx.compose.material3.surfaceColorAtElevation import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
@ -39,6 +40,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.platform.testTag import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
@ -51,8 +53,8 @@ import chat.revolt.api.schemas.ChannelType
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun MessageField( fun MessageField(
messageContent: String, value: TextFieldValue,
onMessageContentChange: (String) -> Unit, onValueChange: (TextFieldValue) -> Unit,
onAddAttachment: () -> Unit, onAddAttachment: () -> Unit,
onSendMessage: () -> Unit, onSendMessage: () -> Unit,
channelType: ChannelType, channelType: ChannelType,
@ -73,16 +75,23 @@ fun MessageField(
ChannelType.SavedMessages -> R.string.message_field_placeholder_notes ChannelType.SavedMessages -> R.string.message_field_placeholder_notes
} }
val sendButtonVisible = (messageContent.isNotBlank() || forceSendButton) && !disabled val sendButtonVisible = (value.text.isNotBlank() || forceSendButton) && !disabled
LaunchedEffect(editMode) {
if (editMode) {
focusRequester.requestFocus()
} else {
focusRequester.freeFocus()
}
}
Row( Row(
modifier = Modifier modifier = Modifier
.background(MaterialTheme.colorScheme.surfaceColorAtElevation(1.dp)) .background(MaterialTheme.colorScheme.surfaceColorAtElevation(1.dp))
) { ) {
BasicTextField( BasicTextField(
value = messageContent, value = value,
onValueChange = onMessageContentChange, onValueChange = onValueChange,
singleLine = false, singleLine = false,
enabled = !disabled, enabled = !disabled,
textStyle = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.onSurface), textStyle = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.onSurface),
@ -97,7 +106,7 @@ fun MessageField(
keyboardActions = KeyboardActions.Default, keyboardActions = KeyboardActions.Default,
decorationBox = @Composable { innerTextField -> decorationBox = @Composable { innerTextField ->
TextFieldDefaults.DecorationBox( TextFieldDefaults.DecorationBox(
value = messageContent, value = value.text,
innerTextField = innerTextField, innerTextField = innerTextField,
enabled = !disabled, enabled = !disabled,
singleLine = false, singleLine = false,
@ -186,8 +195,8 @@ fun MessageField(
@Composable @Composable
fun MessageFieldPreview() { fun MessageFieldPreview() {
MessageField( MessageField(
messageContent = "Hello world!", value = TextFieldValue("Hello world!"),
onMessageContentChange = {}, onValueChange = {},
onSendMessage = {}, onSendMessage = {},
onAddAttachment = {}, onAddAttachment = {},
channelType = ChannelType.TextChannel, channelType = ChannelType.TextChannel,

View File

@ -54,6 +54,7 @@ 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
@ -173,6 +174,13 @@ fun ChannelScreen(
label = "ScrollDownFABPadding" label = "ScrollDownFABPadding"
) )
val fieldContent = remember(viewModel.pendingMessageContent, viewModel.textSelection) {
TextFieldValue(
viewModel.pendingMessageContent,
viewModel.textSelection
)
}
LaunchedEffect(channelId) { LaunchedEffect(channelId) {
viewModel.fetchChannel(channelId) viewModel.fetchChannel(channelId)
@ -465,9 +473,10 @@ fun ChannelScreen(
) )
} else { } else {
MessageField( MessageField(
messageContent = viewModel.pendingMessageContent, value = fieldContent,
onMessageContentChange = { onValueChange = {
viewModel.pendingMessageContent = it viewModel.pendingMessageContent = it.text
viewModel.textSelection = it.selection
}, },
onSendMessage = viewModel::sendPendingMessage, onSendMessage = viewModel::sendPendingMessage,
onAddAttachment = { onAddAttachment = {

View File

@ -8,6 +8,7 @@ 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
@ -64,6 +65,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 pendingReplies = mutableStateListOf<SendMessageReply>() var pendingReplies = mutableStateListOf<SendMessageReply>()
var pendingAttachments = mutableStateListOf<FileArgs>() var pendingAttachments = mutableStateListOf<FileArgs>()
@ -394,6 +396,7 @@ 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)
} }
} }
}.catch { }.catch {