feat: animate pinned and composer state transitions
feat: add smooth pinned-message visibility changes and voice composer mode transitions
This commit is contained in:
@@ -82,6 +82,8 @@ import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.slideInVertically
|
||||
import androidx.compose.animation.slideOutVertically
|
||||
import androidx.compose.animation.scaleIn
|
||||
import androidx.compose.animation.scaleOut
|
||||
import androidx.compose.animation.core.LinearEasing
|
||||
@@ -1069,7 +1071,18 @@ private fun ChatScreen(
|
||||
)
|
||||
}
|
||||
val pinnedMessage = state.pinnedMessage
|
||||
if (pinnedMessage != null && dismissedPinnedMessageId != pinnedMessage.id) {
|
||||
AnimatedVisibility(
|
||||
visible = pinnedMessage != null && dismissedPinnedMessageId != pinnedMessage?.id,
|
||||
enter = fadeIn(animationSpec = tween(180)) + slideInVertically(
|
||||
initialOffsetY = { -it / 3 },
|
||||
animationSpec = tween(180),
|
||||
),
|
||||
exit = fadeOut(animationSpec = tween(120)) + slideOutVertically(
|
||||
targetOffsetY = { -it / 3 },
|
||||
animationSpec = tween(120),
|
||||
),
|
||||
) {
|
||||
val resolvedPinnedMessage = pinnedMessage ?: return@AnimatedVisibility
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
@@ -1092,12 +1105,12 @@ private fun ChatScreen(
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
)
|
||||
Text(
|
||||
text = pinnedMessage.text?.takeIf { it.isNotBlank() } ?: "[${pinnedMessage.type}]",
|
||||
text = resolvedPinnedMessage.text?.takeIf { it.isNotBlank() } ?: "[${resolvedPinnedMessage.type}]",
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
maxLines = 2,
|
||||
)
|
||||
}
|
||||
IconButton(onClick = { dismissedPinnedMessageId = pinnedMessage.id }) {
|
||||
IconButton(onClick = { dismissedPinnedMessageId = resolvedPinnedMessage.id }) {
|
||||
Icon(imageVector = Icons.Filled.Close, contentDescription = "Hide pinned")
|
||||
}
|
||||
}
|
||||
@@ -1825,7 +1838,17 @@ private fun ChatScreen(
|
||||
.padding(horizontal = 8.dp, vertical = 6.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(6.dp),
|
||||
) {
|
||||
if (state.isRecordingVoice) {
|
||||
AnimatedVisibility(
|
||||
visible = state.isRecordingVoice,
|
||||
enter = fadeIn(animationSpec = tween(150)) + slideInVertically(
|
||||
initialOffsetY = { it / 3 },
|
||||
animationSpec = tween(150),
|
||||
),
|
||||
exit = fadeOut(animationSpec = tween(100)) + slideOutVertically(
|
||||
targetOffsetY = { it / 3 },
|
||||
animationSpec = tween(100),
|
||||
),
|
||||
) {
|
||||
VoiceRecordingStatusRow(
|
||||
durationMs = state.voiceRecordingDurationMs,
|
||||
hint = state.voiceRecordingHint,
|
||||
@@ -1833,7 +1856,18 @@ private fun ChatScreen(
|
||||
onCancel = onVoiceRecordCancel,
|
||||
onSend = onVoiceRecordSend,
|
||||
)
|
||||
} else {
|
||||
}
|
||||
AnimatedVisibility(
|
||||
visible = !state.isRecordingVoice,
|
||||
enter = fadeIn(animationSpec = tween(150)) + slideInVertically(
|
||||
initialOffsetY = { it / 3 },
|
||||
animationSpec = tween(150),
|
||||
),
|
||||
exit = fadeOut(animationSpec = tween(100)) + slideOutVertically(
|
||||
targetOffsetY = { it / 3 },
|
||||
animationSpec = tween(100),
|
||||
),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
|
||||
Reference in New Issue
Block a user