feat: cursor at end when editing and open keyboard
Signed-off-by: Infi <infi@infi.sh>
This commit is contained in:
parent
5a6a25c113
commit
3652d01ea8
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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 = {
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue