123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- package io.nexilis.alpha.ui.components
- import android.net.Uri
- import androidx.compose.foundation.background
- import androidx.compose.foundation.layout.Row
- import androidx.compose.foundation.layout.fillMaxWidth
- import androidx.compose.foundation.layout.height
- import androidx.compose.foundation.layout.padding
- import androidx.compose.foundation.shape.CircleShape
- import androidx.compose.foundation.shape.RoundedCornerShape
- import androidx.compose.foundation.text.KeyboardOptions
- import androidx.compose.material.icons.Icons
- import androidx.compose.material.icons.automirrored.filled.Send
- import androidx.compose.material3.AlertDialog
- import androidx.compose.material3.Icon
- import androidx.compose.material3.IconButton
- import androidx.compose.material3.MaterialTheme
- import androidx.compose.material3.Text
- import androidx.compose.material3.TextButton
- import androidx.compose.material3.TextField
- import androidx.compose.material3.TextFieldDefaults
- import androidx.compose.runtime.Composable
- import androidx.compose.runtime.getValue
- import androidx.compose.runtime.livedata.observeAsState
- import androidx.compose.runtime.mutableStateListOf
- import androidx.compose.runtime.mutableStateOf
- import androidx.compose.runtime.remember
- import androidx.compose.runtime.saveable.rememberSaveable
- import androidx.compose.runtime.setValue
- import androidx.compose.ui.Modifier
- import androidx.compose.ui.graphics.Color
- import androidx.compose.ui.graphics.graphicsLayer
- import androidx.compose.ui.platform.LocalContext
- import androidx.compose.ui.text.TextRange
- import androidx.compose.ui.text.input.KeyboardCapitalization
- import androidx.compose.ui.text.input.TextFieldValue
- import androidx.compose.ui.unit.dp
- import androidx.hilt.navigation.compose.hiltViewModel
- import androidx.navigation.NavHostController
- import io.nexilis.alpha.ui.screen.Screen
- import io.nexilis.service.data.entities.Buddy
- import io.nexilis.service.data.entities.Message
- import io.nexilis.service.data.viewmodels.BuddyViewModel
- import io.nexilis.service.data.viewmodels.MessageViewModel
- import kotlinx.serialization.encodeToString
- import kotlinx.serialization.json.Json
- @Composable
- fun InputChat(
- navController: NavHostController,
- pin: String,
- me: Buddy,
- placeHolderText: String = "Typing here...",
- enableAttachment: Boolean = true,
- enableEmpty: Boolean = false,
- popAfterSent: Boolean = false,
- attachments: ArrayList<Uri> = arrayListOf()
- ) {
- val context = LocalContext.current
- val messageModel: MessageViewModel = hiltViewModel()
- var textInput by rememberSaveable(stateSaver = TextFieldValue.Saver) {
- mutableStateOf(TextFieldValue("", TextRange(0, 7)))
- }
- var openAlertDialog by remember { mutableStateOf(false) }
- val attachmentState = remember { mutableStateListOf<Uri>() }
- attachmentState.addAll(attachments)
- val leadingIcon: (@Composable () -> Unit)? = if (enableAttachment) {
- {
- Attachments(
- modifier = Modifier
- .height(300.dp)
- .fillMaxWidth()
- .padding(start = 16.dp, end = 16.dp, bottom = 8.dp)
- .graphicsLayer {
- shape = RoundedCornerShape(16.dp)
- clip = true
- }
- .background(MaterialTheme.colorScheme.surfaceContainerLowest),
- onAttachment = { list ->
- attachmentState.addAll(list)
- val items = list.map {
- context.toAttachmentItem(it)
- }
- if (items.size == 1) {
- val params = AttachmentItemList(items)
- val data = Uri.encode(Json.encodeToString(params))
- navController.navigate(Screen.AttachmentCaption.route + "?data=${data}&pin=${pin}") {
- launchSingleTop = true
- restoreState = true
- }
- } else if (items.size > 1) {
- openAlertDialog = true
- }
- }
- )
- }
- } else null
- TextField(
- modifier = Modifier
- .fillMaxWidth()
- .padding(4.dp)
- .graphicsLayer {
- shape = RoundedCornerShape(16.dp)
- clip = true
- },
- value = textInput,
- onValueChange = { textInput = it },
- label = null,
- placeholder = {
- Text(text = placeHolderText, color = MaterialTheme.colorScheme.onSurface)
- },
- leadingIcon = leadingIcon,
- trailingIcon = {
- Row {
- IconButton(onClick = {
- if (pin.trim().isEmpty()) {
- return@IconButton
- }
- if (!enableEmpty && textInput.text.trim().isEmpty()) {
- return@IconButton
- }
- me.let {
- messageModel.send(
- context = context,
- entity = Message(
- message_id = System.nanoTime().toString(),
- f_pin = it.f_pin,
- l_pin = pin,
- message_scope_id = "3", // 3: chat, 15: sms, 16: email
- server_date = System.currentTimeMillis(),
- status = "1",
- message_text = textInput.text,
- opposite_pin = pin,
- f_display_name = "${it.first_name} ${it.last_name}".trim(),
- message_large_text = "",
- message_text_plain = "",
- uri = if (attachmentState.size > 0) attachmentState[0] else Uri.EMPTY
- )
- )
- textInput = TextFieldValue("")
- if (popAfterSent) navController.popBackStack()
- }
- }) {
- Icon(
- imageVector = Icons.AutoMirrored.Filled.Send,
- contentDescription = "",
- tint = MaterialTheme.colorScheme.primary
- )
- }
- }
- },
- colors = TextFieldDefaults.colors(
- focusedContainerColor = MaterialTheme.colorScheme.surfaceContainerLowest,
- unfocusedContainerColor = MaterialTheme.colorScheme.surfaceContainerLowest,
- disabledContainerColor = MaterialTheme.colorScheme.surfaceContainerLowest,
- focusedIndicatorColor = Color.Transparent,
- unfocusedIndicatorColor = Color.Transparent,
- disabledIndicatorColor = Color.Transparent,
- errorIndicatorColor = Color.Transparent,
- ),
- keyboardOptions = KeyboardOptions(KeyboardCapitalization.Sentences),
- maxLines = 3
- )
- if (openAlertDialog) {
- val buddyModel: BuddyViewModel = hiltViewModel()
- val buddy by buddyModel.getBuddy(pin).observeAsState()
- buddy?.let {
- AlertDialog(
- text = {
- Text(text = "Send ${attachmentState.size} documents to ${it.first_name} ${it.last_name}?".trim())
- },
- onDismissRequest = {
- openAlertDialog = false
- },
- confirmButton = {
- TextButton(
- onClick = {
- openAlertDialog = false
- me.let {
- attachmentState.forEach { uri ->
- messageModel.send(
- context = context,
- entity = Message(
- message_id = System.nanoTime().toString(),
- f_pin = it.f_pin,
- l_pin = pin,
- message_scope_id = "3", // 3: chat, 15: sms, 16: email
- server_date = System.currentTimeMillis(),
- status = "1",
- message_text = "",
- opposite_pin = pin,
- f_display_name = "${it.first_name} ${it.last_name}".trim(),
- message_large_text = "",
- message_text_plain = "",
- uri = uri
- )
- )
- }
- textInput = TextFieldValue("")
- }
- }
- ) {
- Text("Send")
- }
- },
- dismissButton = {
- TextButton(
- onClick = {
- openAlertDialog = false
- }
- ) {
- Text("Cancel")
- }
- }
- )
- }
- }
- }
|