Animate the send button

This commit is contained in:
2025-12-16 17:20:40 +03:00
Unverified
parent 07af5a2d24
commit 25f2ebc67b
2 changed files with 26 additions and 16 deletions
@@ -1,5 +1,9 @@
package ru.fromchat.ui.chat package ru.fromchat.ui.chat
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.border import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
@@ -8,19 +12,17 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.add
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.Send import androidx.compose.material.icons.automirrored.filled.Send
import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.FilledIconButton
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
@@ -39,6 +41,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@@ -85,10 +88,7 @@ fun ChatInput(
} }
Column( Column(
Modifier Modifier.windowInsetsPadding(WindowInsets.navigationBars)
.windowInsetsPadding(
WindowInsets.ime.add(WindowInsets.navigationBars)
)
) { ) {
// Reply preview // Reply preview
replyTo?.let { reply -> replyTo?.let { reply ->
@@ -163,15 +163,21 @@ fun ChatInput(
unfocusedBorderColor = Color.Transparent unfocusedBorderColor = Color.Transparent
), ),
trailingIcon = { trailingIcon = {
if (text.isNotBlank()) { val offset = with(LocalDensity.current) { 20.dp.toPx().toInt() }
Box(
modifier = Modifier AnimatedVisibility(
.size(36.dp) visible = text.isNotBlank(),
.clip(CircleShape) enter = slideInHorizontally(
.background(MaterialTheme.colorScheme.primary.copy(alpha = 0.8f)), initialOffsetX = { it + offset },
contentAlignment = Alignment.Center animationSpec = tween(durationMillis = 300)
) { ),
IconButton( exit = slideOutHorizontally(
targetOffsetX = { it + offset },
animationSpec = tween(durationMillis = 200)
)
) {
Box(Modifier.padding(end = 5.dp)) {
FilledIconButton(
onClick = { onClick = {
onSend(text.trim()) onSend(text.trim())
onTextChange("") onTextChange("")
@@ -9,10 +9,13 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.lazy.rememberLazyListState
@@ -264,6 +267,7 @@ fun ChatScreen(
bottomBar = { bottomBar = {
Column( // New Column to hold ChatInput below the LazyColumn Column( // New Column to hold ChatInput below the LazyColumn
modifier = Modifier modifier = Modifier
.windowInsetsPadding(WindowInsets.ime)
.fillMaxWidth() .fillMaxWidth()
.hazeEffect( .hazeEffect(
state = hazeState, state = hazeState,