|
1 | 1 | package com.getcode.ui.components.chat |
2 | 2 |
|
3 | | -import androidx.compose.animation.AnimatedContent |
| 3 | +import androidx.compose.animation.animateContentSize |
| 4 | +import androidx.compose.animation.core.animateFloatAsState |
4 | 5 | import androidx.compose.animation.core.spring |
5 | | -import androidx.compose.animation.fadeIn |
6 | | -import androidx.compose.animation.fadeOut |
7 | | -import androidx.compose.animation.scaleIn |
8 | | -import androidx.compose.animation.scaleOut |
9 | | -import androidx.compose.animation.togetherWith |
10 | 6 | import androidx.compose.foundation.background |
11 | 7 | import androidx.compose.foundation.clickable |
12 | 8 | import androidx.compose.foundation.layout.Arrangement |
13 | 9 | import androidx.compose.foundation.layout.Box |
14 | | -import androidx.compose.foundation.layout.IntrinsicSize |
15 | 10 | import androidx.compose.foundation.layout.PaddingValues |
16 | 11 | import androidx.compose.foundation.layout.Row |
17 | | -import androidx.compose.foundation.layout.Spacer |
18 | 12 | import androidx.compose.foundation.layout.fillMaxWidth |
19 | | -import androidx.compose.foundation.layout.height |
20 | 13 | import androidx.compose.foundation.layout.padding |
21 | | -import androidx.compose.foundation.layout.requiredSize |
22 | 14 | import androidx.compose.foundation.layout.size |
23 | 15 | import androidx.compose.foundation.text.KeyboardOptions |
24 | 16 | import androidx.compose.foundation.text.input.TextFieldState |
25 | 17 | import androidx.compose.foundation.text.input.rememberTextFieldState |
26 | 18 | import androidx.compose.material3.Icon |
27 | | -import androidx.compose.material.icons.Icons |
28 | | -import androidx.compose.material.icons.rounded.ArrowUpward |
29 | 19 | import androidx.compose.runtime.Composable |
| 20 | +import androidx.compose.runtime.getValue |
30 | 21 | import androidx.compose.runtime.remember |
31 | 22 | import androidx.compose.ui.Alignment |
32 | 23 | import androidx.compose.ui.Modifier |
@@ -57,13 +48,25 @@ fun ChatInput( |
57 | 48 | onSendMessage: () -> Unit, |
58 | 49 | ) { |
59 | 50 | val shape = CodeTheme.shapes.medium |
| 51 | + val sendVisible = state.text.isNotEmpty() |
| 52 | + val sendSpec = spring<Float>(dampingRatio = 0.66f, stiffness = 4000f) |
| 53 | + val sendAlpha by animateFloatAsState( |
| 54 | + targetValue = if (sendVisible) 1f else 0f, |
| 55 | + animationSpec = sendSpec, |
| 56 | + label = "send button alpha", |
| 57 | + ) |
| 58 | + val sendScale by animateFloatAsState( |
| 59 | + targetValue = if (sendVisible) 1f else 0.6f, |
| 60 | + animationSpec = sendSpec, |
| 61 | + label = "send button scale", |
| 62 | + ) |
60 | 63 | Row( |
61 | 64 | modifier = Modifier |
62 | 65 | .graphicsLayer { compositingStrategy = CompositingStrategy.Offscreen } |
63 | 66 | .clip(shape) |
64 | 67 | .then(modifier) |
65 | 68 | .fillMaxWidth() |
66 | | - .height(IntrinsicSize.Min), |
| 69 | + .animateContentSize(), |
67 | 70 | horizontalArrangement = Arrangement.spacedBy(CodeTheme.dimens.grid.x2), |
68 | 71 | verticalAlignment = Alignment.Bottom |
69 | 72 | ) { |
@@ -93,36 +96,27 @@ fun ChatInput( |
93 | 96 | unfocusedBorderColor = Color.Transparent, |
94 | 97 | ), |
95 | 98 | trailingIcon = { |
96 | | - AnimatedContent( |
97 | | - targetState = state.text.isNotEmpty(), |
98 | | - label = "show/hide send button", |
99 | | - transitionSpec = { |
100 | | - val spec = spring<Float>(dampingRatio = 0.66f, stiffness = 4000f) |
101 | | - (fadeIn(spec) + scaleIn(spec, initialScale = 0.6f)) togetherWith |
102 | | - (fadeOut(spec) + scaleOut(spec, targetScale = 0.6f)) |
103 | | - } |
104 | | - ) { show -> |
105 | | - if (show) { |
106 | | - Icon( |
107 | | - modifier = Modifier |
108 | | - .padding(vertical = CodeTheme.dimens.grid.x1) |
109 | | - .padding(end = CodeTheme.dimens.staticGrid.x1) |
110 | | - .background( |
111 | | - Color.White, |
112 | | - shape = CodeTheme.shapes.extraSmall |
113 | | - ) |
114 | | - .clip(CodeTheme.shapes.extraSmall) |
115 | | - .clickable { onSendMessage() } |
116 | | - .padding(CodeTheme.dimens.staticGrid.x1) |
117 | | - .size(CodeTheme.dimens.staticGrid.x5), |
118 | | - painter = painterResource(R.drawable.ic_arrow_up), |
119 | | - tint = Color.Black, |
120 | | - contentDescription = "Send message" |
| 99 | + Icon( |
| 100 | + modifier = Modifier |
| 101 | + .graphicsLayer { |
| 102 | + alpha = sendAlpha |
| 103 | + scaleX = sendScale |
| 104 | + scaleY = sendScale |
| 105 | + } |
| 106 | + .padding(vertical = CodeTheme.dimens.grid.x1) |
| 107 | + .padding(end = CodeTheme.dimens.staticGrid.x1) |
| 108 | + .background( |
| 109 | + Color.White, |
| 110 | + shape = CodeTheme.shapes.extraSmall |
121 | 111 | ) |
122 | | - } else { |
123 | | - Spacer(Modifier.requiredSize(CodeTheme.dimens.staticGrid.x9)) |
124 | | - } |
125 | | - } |
| 112 | + .clip(CodeTheme.shapes.extraSmall) |
| 113 | + .clickable(enabled = sendVisible) { onSendMessage() } |
| 114 | + .padding(CodeTheme.dimens.staticGrid.x1) |
| 115 | + .size(CodeTheme.dimens.staticGrid.x5), |
| 116 | + painter = painterResource(R.drawable.ic_arrow_up), |
| 117 | + tint = Color.Black, |
| 118 | + contentDescription = "Send message" |
| 119 | + ) |
126 | 120 | } |
127 | 121 | ) |
128 | 122 | } |
|
0 commit comments