|
@@ -1,14 +1,20 @@
|
|
package io.nexilis.alpha.ui.main
|
|
package io.nexilis.alpha.ui.main
|
|
|
|
|
|
|
|
+import androidx.compose.animation.AnimatedVisibility
|
|
import androidx.compose.foundation.layout.*
|
|
import androidx.compose.foundation.layout.*
|
|
import androidx.compose.foundation.lazy.LazyColumn
|
|
import androidx.compose.foundation.lazy.LazyColumn
|
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
|
import androidx.compose.foundation.lazy.items
|
|
import androidx.compose.foundation.lazy.items
|
|
|
|
+import androidx.compose.foundation.shape.CircleShape
|
|
|
|
+import androidx.compose.material.icons.Icons
|
|
|
|
+import androidx.compose.material.icons.filled.KeyboardDoubleArrowDown
|
|
import androidx.compose.material3.*
|
|
import androidx.compose.material3.*
|
|
import androidx.compose.runtime.*
|
|
import androidx.compose.runtime.*
|
|
import androidx.compose.runtime.livedata.observeAsState
|
|
import androidx.compose.runtime.livedata.observeAsState
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.graphics.Color
|
|
import androidx.compose.ui.graphics.Color
|
|
|
|
+import androidx.compose.ui.unit.dp
|
|
|
|
+import androidx.constraintlayout.compose.ConstraintLayout
|
|
import androidx.hilt.navigation.compose.hiltViewModel
|
|
import androidx.hilt.navigation.compose.hiltViewModel
|
|
import androidx.navigation.NavHostController
|
|
import androidx.navigation.NavHostController
|
|
import io.nexilis.alpha.ui.components.ContentChat
|
|
import io.nexilis.alpha.ui.components.ContentChat
|
|
@@ -17,6 +23,7 @@ import io.nexilis.alpha.ui.components.LeftBubbleChat
|
|
import io.nexilis.alpha.ui.components.RightBubbleChat
|
|
import io.nexilis.alpha.ui.components.RightBubbleChat
|
|
import io.nexilis.service.data.entities.Buddy
|
|
import io.nexilis.service.data.entities.Buddy
|
|
import io.nexilis.service.data.viewmodels.MessageViewModel
|
|
import io.nexilis.service.data.viewmodels.MessageViewModel
|
|
|
|
+import kotlinx.coroutines.launch
|
|
|
|
|
|
@OptIn(ExperimentalLayoutApi::class)
|
|
@OptIn(ExperimentalLayoutApi::class)
|
|
@Composable
|
|
@Composable
|
|
@@ -28,22 +35,31 @@ fun Chat(
|
|
) {
|
|
) {
|
|
val messageModel: MessageViewModel = hiltViewModel()
|
|
val messageModel: MessageViewModel = hiltViewModel()
|
|
val list by messageModel.getOpposite(pin).observeAsState()
|
|
val list by messageModel.getOpposite(pin).observeAsState()
|
|
- val state = rememberLazyListState()
|
|
|
|
- Column(
|
|
|
|
|
|
+ val listState = rememberLazyListState()
|
|
|
|
+ val scope = rememberCoroutineScope()
|
|
|
|
+ ConstraintLayout(
|
|
modifier = Modifier
|
|
modifier = Modifier
|
|
.fillMaxSize()
|
|
.fillMaxSize()
|
|
.consumeWindowInsets(contentPadding)
|
|
.consumeWindowInsets(contentPadding)
|
|
.imePadding()
|
|
.imePadding()
|
|
.imeNestedScroll()
|
|
.imeNestedScroll()
|
|
) {
|
|
) {
|
|
|
|
+ val (lazyColumn, fab, input) = createRefs()
|
|
LazyColumn(
|
|
LazyColumn(
|
|
modifier = Modifier
|
|
modifier = Modifier
|
|
- .weight(1f),
|
|
|
|
- state = state,
|
|
|
|
|
|
+ .fillMaxSize()
|
|
|
|
+ .constrainAs(lazyColumn) {
|
|
|
|
+ start.linkTo(parent.start)
|
|
|
|
+ top.linkTo(parent.top)
|
|
|
|
+ end.linkTo(parent.end)
|
|
|
|
+ bottom.linkTo(input.top)
|
|
|
|
+ }
|
|
|
|
+ .padding(bottom = 32.dp),
|
|
|
|
+ state = listState,
|
|
reverseLayout = true
|
|
reverseLayout = true
|
|
) {
|
|
) {
|
|
list?.let { l ->
|
|
list?.let { l ->
|
|
- items(l) { message ->
|
|
|
|
|
|
+ items(items = l) { message ->
|
|
ListItem(modifier = Modifier.fillMaxWidth(), headlineContent = {
|
|
ListItem(modifier = Modifier.fillMaxWidth(), headlineContent = {
|
|
Row(
|
|
Row(
|
|
modifier = Modifier.fillMaxWidth(),
|
|
modifier = Modifier.fillMaxWidth(),
|
|
@@ -77,7 +93,36 @@ fun Chat(
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- InputChat(navController = navController, pin = pin, me = me)
|
|
|
|
|
|
+ val showButton by remember {
|
|
|
|
+ derivedStateOf {
|
|
|
|
+ listState.firstVisibleItemIndex > 0
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ AnimatedVisibility(visible = showButton, modifier = Modifier.constrainAs(fab) {
|
|
|
|
+ end.linkTo(parent.end)
|
|
|
|
+ bottom.linkTo(input.top)
|
|
|
|
+ }) {
|
|
|
|
+ Button(
|
|
|
|
+ onClick = {
|
|
|
|
+ scope.launch { listState.scrollToItem(0) }
|
|
|
|
+ },
|
|
|
|
+ modifier = Modifier
|
|
|
|
+ .padding(end = 16.dp)
|
|
|
|
+ .size(32.dp),
|
|
|
|
+ shape = CircleShape,
|
|
|
|
+ contentPadding = PaddingValues(0.dp)
|
|
|
|
+ ) {
|
|
|
|
+ Icon(imageVector = Icons.Default.KeyboardDoubleArrowDown, contentDescription = "")
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ InputChat(
|
|
|
|
+ modifier = Modifier.constrainAs(input) {
|
|
|
|
+ bottom.linkTo(parent.bottom)
|
|
|
|
+ },
|
|
|
|
+ navController = navController,
|
|
|
|
+ pin = pin,
|
|
|
|
+ me = me
|
|
|
|
+ )
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|