Нормальный чат
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -71,7 +71,6 @@ fun ChatDetailScreen(
|
||||
val listState = rememberLazyListState()
|
||||
val scope = rememberCoroutineScope()
|
||||
val voiceRecorder = remember { VoiceRecorder(context) }
|
||||
var textInput by remember { mutableStateOf("") }
|
||||
var isEmojiPickerVisible by remember { mutableStateOf(false) }
|
||||
var isRecording by remember { mutableStateOf(false) }
|
||||
var recordingOffset by remember { mutableFloatStateOf(0f) }
|
||||
@@ -601,8 +600,8 @@ fun ChatDetailScreen(
|
||||
}
|
||||
|
||||
BasicTextField(
|
||||
value = textInput,
|
||||
onValueChange = { textInput = it },
|
||||
value = state.inputText,
|
||||
onValueChange = { viewModel.onInputTextChanged(it) },
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.onFocusChanged {
|
||||
@@ -611,23 +610,14 @@ fun ChatDetailScreen(
|
||||
}
|
||||
},
|
||||
textStyle = MaterialTheme.typography.bodyLarge.copy(color = MaterialTheme.colorScheme.onSurface),
|
||||
cursorBrush = androidx.compose.ui.graphics.SolidColor(MaterialTheme.colorScheme.primary),
|
||||
keyboardOptions = KeyboardOptions(
|
||||
imeAction = ImeAction.Send,
|
||||
imeAction = ImeAction.Default,
|
||||
capitalization = KeyboardCapitalization.Sentences
|
||||
),
|
||||
keyboardActions = KeyboardActions(
|
||||
onSend = {
|
||||
if (textInput.isNotBlank() || state.pendingAttachments.isNotEmpty()) {
|
||||
viewModel.sendMessage(textInput, onFail = { failedText ->
|
||||
textInput = failedText
|
||||
})
|
||||
textInput = ""
|
||||
isEmojiPickerVisible = false
|
||||
}
|
||||
}
|
||||
),
|
||||
maxLines = 6,
|
||||
decorationBox = { innerTextField ->
|
||||
if (textInput.isEmpty()) {
|
||||
if (state.inputText.isEmpty()) {
|
||||
Text(
|
||||
stringResource(R.string.message_placeholder),
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
@@ -643,15 +633,12 @@ fun ChatDetailScreen(
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
|
||||
// 3. Кнопка действия (в синем квадрате)
|
||||
val showMic = textInput.isEmpty() && state.pendingAttachments.isEmpty()
|
||||
val showMic = state.inputText.isEmpty() && state.pendingAttachments.isEmpty()
|
||||
|
||||
Surface(
|
||||
onClick = {
|
||||
if (!showMic) {
|
||||
viewModel.sendMessage(textInput, onFail = { failedText ->
|
||||
textInput = failedText
|
||||
})
|
||||
textInput = ""
|
||||
viewModel.sendMessage()
|
||||
isEmojiPickerVisible = false
|
||||
}
|
||||
},
|
||||
@@ -747,7 +734,7 @@ fun ChatDetailScreen(
|
||||
gifCategories = state.gifCategories,
|
||||
isGifsLoading = state.isGifsLoading,
|
||||
error = state.error,
|
||||
onEmojiSelected = { textInput += it },
|
||||
onEmojiSelected = { viewModel.onInputTextChanged(state.inputText + it) },
|
||||
onGifSelected = { url ->
|
||||
viewModel.sendGif(url)
|
||||
isEmojiPickerVisible = false
|
||||
|
||||
@@ -40,7 +40,8 @@ data class ChatDetailState(
|
||||
val initialScrollIndex: Int? = null,
|
||||
val pendingAttachments: List<File> = emptyList(),
|
||||
val isUploading: Boolean = false,
|
||||
val isCompressionEnabled: Boolean = true
|
||||
val isCompressionEnabled: Boolean = true,
|
||||
val inputText: String = ""
|
||||
)
|
||||
|
||||
@HiltViewModel
|
||||
@@ -277,11 +278,19 @@ class ChatDetailViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun sendMessage(text: String, onFail: (String) -> Unit = {}) {
|
||||
fun onInputTextChanged(text: String) {
|
||||
_state.update { it.copy(inputText = text) }
|
||||
}
|
||||
|
||||
fun sendMessage(onFail: (String) -> Unit = {}) {
|
||||
val chatId = currentChatId ?: return
|
||||
val text = _state.value.inputText
|
||||
val pending = _state.value.pendingAttachments
|
||||
if (text.isBlank() && pending.isEmpty()) return
|
||||
|
||||
// Clear input immediately to avoid double clicks and ensure UI experience
|
||||
_state.update { it.copy(inputText = "") }
|
||||
|
||||
val tempId = "temp_${System.currentTimeMillis()}"
|
||||
val userId = getCurrentUserId()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user