feat: Enhance selection mode animations and adjust bottom padding in ChatDetailScreen
This commit is contained in:
@@ -10,14 +10,18 @@ import androidx.activity.result.contract.ActivityResultContracts
|
|||||||
import androidx.compose.animation.AnimatedContent
|
import androidx.compose.animation.AnimatedContent
|
||||||
import androidx.compose.animation.Crossfade
|
import androidx.compose.animation.Crossfade
|
||||||
import androidx.compose.animation.core.Spring
|
import androidx.compose.animation.core.Spring
|
||||||
|
import androidx.compose.animation.core.animateDpAsState
|
||||||
import androidx.compose.animation.core.animateFloatAsState
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
import androidx.compose.animation.core.spring
|
import androidx.compose.animation.core.spring
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
|
import androidx.compose.animation.SizeTransform
|
||||||
import androidx.compose.animation.fadeIn
|
import androidx.compose.animation.fadeIn
|
||||||
import androidx.compose.animation.fadeOut
|
import androidx.compose.animation.fadeOut
|
||||||
import androidx.compose.animation.expandVertically
|
import androidx.compose.animation.expandVertically
|
||||||
import androidx.compose.animation.shrinkVertically
|
import androidx.compose.animation.shrinkVertically
|
||||||
import androidx.compose.animation.scaleOut
|
import androidx.compose.animation.scaleOut
|
||||||
|
import androidx.compose.animation.slideInVertically
|
||||||
|
import androidx.compose.animation.slideOutVertically
|
||||||
import androidx.compose.animation.togetherWith
|
import androidx.compose.animation.togetherWith
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
@@ -1336,7 +1340,7 @@ fun ChatDetailScreen(
|
|||||||
// 🔥 Bottom bar - инпут с умным padding
|
// 🔥 Bottom bar - инпут с умным padding
|
||||||
bottomBar = {
|
bottomBar = {
|
||||||
val useImePadding =
|
val useImePadding =
|
||||||
!coordinator.isEmojiBoxVisible && !isSelectionMode
|
!coordinator.isEmojiBoxVisible
|
||||||
val bottomModifier =
|
val bottomModifier =
|
||||||
if (useImePadding) {
|
if (useImePadding) {
|
||||||
Modifier.imePadding()
|
Modifier.imePadding()
|
||||||
@@ -1349,10 +1353,22 @@ fun ChatDetailScreen(
|
|||||||
AnimatedContent(
|
AnimatedContent(
|
||||||
targetState = isSelectionMode,
|
targetState = isSelectionMode,
|
||||||
transitionSpec = {
|
transitionSpec = {
|
||||||
fadeIn(
|
(slideInVertically(
|
||||||
|
initialOffsetY = { fullHeight -> fullHeight },
|
||||||
|
animationSpec = tween(250)
|
||||||
|
) + fadeIn(
|
||||||
animationSpec = tween(200)
|
animationSpec = tween(200)
|
||||||
) togetherWith
|
)) togetherWith (
|
||||||
fadeOut(animationSpec = tween(150))
|
slideOutVertically(
|
||||||
|
targetOffsetY = { fullHeight -> fullHeight },
|
||||||
|
animationSpec = tween(200)
|
||||||
|
) + fadeOut(
|
||||||
|
animationSpec = tween(150)
|
||||||
|
)
|
||||||
|
) using SizeTransform(
|
||||||
|
clip = true,
|
||||||
|
sizeAnimationSpec = { _, _ -> tween(250) }
|
||||||
|
)
|
||||||
},
|
},
|
||||||
label = "bottomBarContent"
|
label = "bottomBarContent"
|
||||||
) { selectionMode ->
|
) { selectionMode ->
|
||||||
@@ -1400,9 +1416,9 @@ fun ChatDetailScreen(
|
|||||||
animationSpec =
|
animationSpec =
|
||||||
spring(
|
spring(
|
||||||
dampingRatio =
|
dampingRatio =
|
||||||
Spring.DampingRatioMediumBouncy,
|
Spring.DampingRatioNoBouncy,
|
||||||
stiffness =
|
stiffness =
|
||||||
Spring.StiffnessMedium
|
Spring.StiffnessMediumLow
|
||||||
),
|
),
|
||||||
label =
|
label =
|
||||||
"buttonScale"
|
"buttonScale"
|
||||||
@@ -1805,6 +1821,12 @@ fun ChatDetailScreen(
|
|||||||
) {
|
) {
|
||||||
// Список сообщений - занимает всё доступное место
|
// Список сообщений - занимает всё доступное место
|
||||||
Box(modifier = Modifier.weight(1f).fillMaxWidth()) {
|
Box(modifier = Modifier.weight(1f).fillMaxWidth()) {
|
||||||
|
// Плавная анимация bottom padding при входе/выходе из selection mode
|
||||||
|
val animatedListBottomPadding by animateDpAsState(
|
||||||
|
targetValue = if (isSelectionMode) 16.dp else 16.dp,
|
||||||
|
animationSpec = tween(250),
|
||||||
|
label = "listBottomPadding"
|
||||||
|
)
|
||||||
when {
|
when {
|
||||||
// 🔥 СКЕЛЕТОН - показываем пока загружаются
|
// 🔥 СКЕЛЕТОН - показываем пока загружаются
|
||||||
// сообщения
|
// сообщения
|
||||||
@@ -1965,11 +1987,7 @@ fun ChatDetailScreen(
|
|||||||
end = 0.dp,
|
end = 0.dp,
|
||||||
top = 8.dp,
|
top = 8.dp,
|
||||||
bottom =
|
bottom =
|
||||||
if (isSelectionMode
|
animatedListBottomPadding
|
||||||
)
|
|
||||||
100.dp
|
|
||||||
else
|
|
||||||
16.dp
|
|
||||||
),
|
),
|
||||||
reverseLayout = true,
|
reverseLayout = true,
|
||||||
verticalArrangement = Arrangement.Bottom
|
verticalArrangement = Arrangement.Bottom
|
||||||
|
|||||||
Reference in New Issue
Block a user