yayan 1 anno fa
parent
commit
659b1cdaff

+ 2 - 0
app/build.gradle

@@ -90,6 +90,8 @@ dependencies {
     implementation "androidx.compose.runtime:runtime"
     implementation "androidx.compose.runtime:runtime-livedata"
 
+    implementation "androidx.constraintlayout:constraintlayout-compose:1.0.1"
+
     implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2")
     implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0'
     implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0'

+ 2 - 1
app/src/main/java/io/nexilis/alpha/ui/components/InputChat.kt

@@ -46,6 +46,7 @@ import kotlinx.serialization.json.Json
 
 @Composable
 fun InputChat(
+    modifier: Modifier = Modifier,
     navController: NavHostController,
     pin: String,
     me: Buddy,
@@ -64,7 +65,7 @@ fun InputChat(
     val attachmentState = remember { mutableStateListOf<Uri>() }
     attachmentState.addAll(attachments)
     TextField(
-        modifier = Modifier
+        modifier = modifier
             .fillMaxWidth()
             .padding(4.dp)
             .graphicsLayer {

+ 51 - 6
app/src/main/java/io/nexilis/alpha/ui/main/Chat.kt

@@ -1,14 +1,20 @@
 package io.nexilis.alpha.ui.main
 
+import androidx.compose.animation.AnimatedVisibility
 import androidx.compose.foundation.layout.*
 import androidx.compose.foundation.lazy.LazyColumn
 import androidx.compose.foundation.lazy.rememberLazyListState
 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.runtime.*
 import androidx.compose.runtime.livedata.observeAsState
 import androidx.compose.ui.Modifier
 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.navigation.NavHostController
 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.service.data.entities.Buddy
 import io.nexilis.service.data.viewmodels.MessageViewModel
+import kotlinx.coroutines.launch
 
 @OptIn(ExperimentalLayoutApi::class)
 @Composable
@@ -28,22 +35,31 @@ fun Chat(
 ) {
     val messageModel: MessageViewModel = hiltViewModel()
     val list by messageModel.getOpposite(pin).observeAsState()
-    val state = rememberLazyListState()
-    Column(
+    val listState = rememberLazyListState()
+    val scope = rememberCoroutineScope()
+    ConstraintLayout(
         modifier = Modifier
             .fillMaxSize()
             .consumeWindowInsets(contentPadding)
             .imePadding()
             .imeNestedScroll()
     ) {
+        val (lazyColumn, fab, input) = createRefs()
         LazyColumn(
             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
         ) {
             list?.let { l ->
-                items(l) { message ->
+                items(items = l) { message ->
                     ListItem(modifier = Modifier.fillMaxWidth(), headlineContent = {
                         Row(
                             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
+        )
     }
 }