feat: Enhance search animation in ChatsListScreen for smoother transitions
This commit is contained in:
@@ -379,45 +379,29 @@ fun ChatsListScreen(
|
||||
} // Auto-focus when search opens
|
||||
LaunchedEffect(isSearchExpanded) {
|
||||
if (isSearchExpanded) {
|
||||
kotlinx.coroutines.delay(150)
|
||||
kotlinx.coroutines.delay(100)
|
||||
focusRequester.requestFocus()
|
||||
}
|
||||
}
|
||||
|
||||
// Animated transition between title and search
|
||||
val searchProgress by
|
||||
animateFloatAsState(
|
||||
targetValue =
|
||||
if (isSearchExpanded) 1f
|
||||
else 0f,
|
||||
animationSpec =
|
||||
tween(
|
||||
durationMillis = 300,
|
||||
easing = FastOutSlowInEasing
|
||||
),
|
||||
label = "searchProgress"
|
||||
)
|
||||
// Animate alpha for smooth fade without position changes
|
||||
val titleAlpha by animateFloatAsState(
|
||||
targetValue = if (isSearchExpanded) 0f else 1f,
|
||||
animationSpec = tween(durationMillis = 200, easing = FastOutSlowInEasing),
|
||||
label = "titleAlpha"
|
||||
)
|
||||
val searchAlpha by animateFloatAsState(
|
||||
targetValue = if (isSearchExpanded) 1f else 0f,
|
||||
animationSpec = tween(durationMillis = 250, easing = FastOutSlowInEasing),
|
||||
label = "searchAlpha"
|
||||
)
|
||||
|
||||
Box(modifier = Modifier.fillMaxWidth()) {
|
||||
// Title - Triple click to open dev console
|
||||
if (searchProgress < 1f) {
|
||||
// Title - Triple click to open dev console (stays in place, just fades)
|
||||
if (titleAlpha > 0.01f) {
|
||||
Column(
|
||||
modifier =
|
||||
Modifier.graphicsLayer {
|
||||
alpha = 1f - searchProgress
|
||||
translationX =
|
||||
-100f *
|
||||
searchProgress
|
||||
scaleX =
|
||||
1f -
|
||||
(0.2f *
|
||||
searchProgress)
|
||||
scaleY =
|
||||
1f -
|
||||
(0.2f *
|
||||
searchProgress)
|
||||
}
|
||||
.clickable {
|
||||
modifier = Modifier
|
||||
.clickable {
|
||||
val currentTime =
|
||||
System.currentTimeMillis()
|
||||
if (currentTime -
|
||||
@@ -440,6 +424,7 @@ fun ChatsListScreen(
|
||||
lastClickTime =
|
||||
currentTime
|
||||
}
|
||||
.graphicsLayer { alpha = titleAlpha }
|
||||
) {
|
||||
Text(
|
||||
"Rosetta",
|
||||
@@ -476,39 +461,19 @@ fun ChatsListScreen(
|
||||
}
|
||||
}
|
||||
|
||||
// Search TextField with awesome animation
|
||||
if (searchProgress > 0f) {
|
||||
// Search TextField (appears on top with fade)
|
||||
if (searchAlpha > 0.01f) {
|
||||
Row(
|
||||
verticalAlignment =
|
||||
Alignment.CenterVertically,
|
||||
modifier =
|
||||
Modifier.fillMaxWidth()
|
||||
.graphicsLayer {
|
||||
alpha =
|
||||
searchProgress
|
||||
translationX =
|
||||
200f *
|
||||
(1f -
|
||||
searchProgress)
|
||||
scaleX =
|
||||
0.8f +
|
||||
(0.2f *
|
||||
searchProgress)
|
||||
scaleY =
|
||||
0.8f +
|
||||
(0.2f *
|
||||
searchProgress)
|
||||
}
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.graphicsLayer { alpha = searchAlpha }
|
||||
) {
|
||||
// Animated back arrow with fade
|
||||
// Back arrow
|
||||
IconButton(
|
||||
onClick = {
|
||||
searchViewModel.collapseSearch()
|
||||
},
|
||||
modifier =
|
||||
Modifier.graphicsLayer {
|
||||
alpha = searchProgress
|
||||
}
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.ArrowBack,
|
||||
@@ -569,23 +534,19 @@ fun ChatsListScreen(
|
||||
)
|
||||
)
|
||||
|
||||
// Animated underline
|
||||
// Underline
|
||||
Box(
|
||||
modifier =
|
||||
Modifier.align(
|
||||
Alignment
|
||||
.BottomCenter
|
||||
)
|
||||
.fillMaxWidth(
|
||||
searchProgress
|
||||
)
|
||||
.fillMaxWidth()
|
||||
.height(2.dp)
|
||||
.background(
|
||||
PrimaryBlue
|
||||
.copy(
|
||||
alpha =
|
||||
0.8f *
|
||||
searchProgress
|
||||
alpha = 0.8f
|
||||
),
|
||||
RoundedCornerShape(
|
||||
1.dp
|
||||
|
||||
Reference in New Issue
Block a user