Skip to content

Commit 722e275

Browse files
committed
feat(currencycreator): make entire description content scrollable
Signed-off-by: Brandon McAnsh <git@bmcreations.dev>
1 parent e8b5df4 commit 722e275

3 files changed

Lines changed: 228 additions & 64 deletions

File tree

apps/flipcash/features/currency-creator/src/main/kotlin/com/flipcash/app/currencycreator/internal/CurrencyCreatorViewModel.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ internal class CurrencyCreatorViewModel @Inject constructor(
4646
val nameFieldState: TextFieldState = TextFieldState(),
4747
val descriptionFieldState: TextFieldState = TextFieldState(),
4848
val icon: Loadable<Uri> = Loadable.Loading(),
49+
val customizations: TokenBillCustomizations? = null,
4950
val bill: Bill? = null,
5051
val purchaseAmount: Fiat = 20.toFiat(),
5152
val processingState: LoadingSuccessState = LoadingSuccessState(),

apps/flipcash/features/currency-creator/src/main/kotlin/com/flipcash/app/currencycreator/internal/screens/DescriptionSelectionScreen.kt

Lines changed: 68 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.flipcash.app.currencycreator.internal.screens
22

33
import androidx.compose.animation.AnimatedVisibility
4-
import androidx.compose.animation.Crossfade
4+
import androidx.compose.animation.animateColorAsState
55
import androidx.compose.animation.fadeIn
66
import androidx.compose.animation.fadeOut
77
import androidx.compose.foundation.layout.Arrangement
@@ -10,11 +10,12 @@ import androidx.compose.foundation.layout.Row
1010
import androidx.compose.foundation.layout.fillMaxWidth
1111
import androidx.compose.foundation.layout.navigationBarsPadding
1212
import androidx.compose.foundation.layout.padding
13+
import androidx.compose.foundation.rememberScrollState
1314
import androidx.compose.foundation.text.KeyboardOptions
15+
import androidx.compose.foundation.verticalScroll
1416
import androidx.compose.material3.Text
1517
import androidx.compose.runtime.Composable
1618
import androidx.compose.runtime.LaunchedEffect
17-
import androidx.compose.runtime.derivedStateOf
1819
import androidx.compose.runtime.getValue
1920
import androidx.compose.runtime.remember
2021
import androidx.compose.ui.Alignment
@@ -35,8 +36,8 @@ import com.flipcash.core.R
3536
import com.getcode.navigation.flow.flowSharedViewModel
3637
import com.getcode.navigation.flow.rememberFlowNavigator
3738
import com.getcode.theme.CodeTheme
38-
import com.getcode.theme.White10
3939
import com.getcode.ui.components.text.AnimatedNumberText
40+
import com.getcode.ui.core.verticalScrollStateGradient
4041
import com.getcode.ui.theme.CodeButton
4142
import com.getcode.ui.theme.CodeScaffold
4243
import com.getcode.ui.utils.rememberKeyboardController
@@ -59,47 +60,32 @@ internal fun DescriptionSelectionContent(
5960
CodeScaffold(
6061
modifier = Modifier
6162
.padding(horizontal = CodeTheme.dimens.inset),
62-
topBar = {
63-
Column(
64-
verticalArrangement = Arrangement.spacedBy(CodeTheme.dimens.inset),
65-
) {
66-
TokenIconWithName(
67-
tokenName = state.nameFieldState.text.let {
68-
if (it.isNotBlank()) it.toString() else stringResource(
69-
R.string.placeholder_currencyName
70-
)
71-
},
72-
tokenImage = state.icon.dataOrNull,
73-
imageSize = CodeTheme.dimens.staticGrid.x6,
74-
spacing = CodeTheme.dimens.grid.x2
75-
)
76-
77-
Text(
78-
text = stringResource(R.string.title_currencyCreatorDescription),
79-
style = CodeTheme.typography.textLarge,
80-
color = CodeTheme.colors.textMain,
81-
)
82-
}
83-
},
8463
bottomBar = {
8564
Column(
86-
modifier = Modifier.fillMaxWidth(),
65+
modifier = Modifier.fillMaxWidth().padding(top = CodeTheme.dimens.grid.x1),
8766
verticalArrangement = Arrangement.spacedBy(CodeTheme.dimens.grid.x3),
8867
) {
8968
Row(
9069
horizontalArrangement = Arrangement.spacedBy(4.dp),
9170
verticalAlignment = Alignment.CenterVertically,
9271
) {
72+
val isOverLimit = remember(state.remainingSpaceForDescription) {
73+
state.remainingSpaceForDescription < 0
74+
}
75+
val textColor by animateColorAsState(
76+
if (isOverLimit) CodeTheme.colors.errorText else CodeTheme.colors.textSecondary
77+
)
78+
9379
AnimatedNumberText(
9480
value = state.remainingSpaceForDescription.toString(),
9581
style = CodeTheme.typography.textSmall,
96-
color = CodeTheme.colors.textSecondary,
82+
color = textColor,
9783
)
9884

9985
Text(
10086
text = stringResource(R.string.label_characters),
10187
style = CodeTheme.typography.textSmall,
102-
color = CodeTheme.colors.textSecondary,
88+
color = textColor,
10389
)
10490

10591
AnimatedVisibility(
@@ -110,7 +96,7 @@ internal fun DescriptionSelectionContent(
11096
Text(
11197
text = stringResource(R.string.label_remaining),
11298
style = CodeTheme.typography.textSmall,
113-
color = CodeTheme.colors.textSecondary,
99+
color = textColor,
114100
)
115101
}
116102
}
@@ -134,30 +120,61 @@ internal fun DescriptionSelectionContent(
134120
}
135121
) { padding ->
136122
val focusRequester = remember { FocusRequester() }
137-
DisplayTextInput(
138-
state = state.descriptionFieldState,
139-
placeholder = stringResource(R.string.hint_description),
123+
val scrollState = rememberScrollState()
124+
Column(
140125
modifier = Modifier
141-
.fillMaxWidth()
142126
.padding(padding)
143-
.padding(top = CodeTheme.dimens.inset)
144-
.focusRequester(focusRequester),
145-
keyboardOptions = KeyboardOptions(
146-
keyboardType = KeyboardType.Text,
147-
imeAction = ImeAction.Done,
148-
),
149-
style = CodeTheme.typography.screenTitle,
150-
placeholderStyle = CodeTheme.typography.screenTitle.copy(
151-
color = CodeTheme.colors.textTertiary,
152-
),
153-
minLines = 3,
154-
maxLines = 6,
155-
onKeyboardAction = {
156-
keyboard.hideIfVisible {
157-
flowNavigator.navigateTo(CurrencyCreatorStep.BillCustomization())
158-
}
159-
},
160-
)
127+
.verticalScroll(scrollState)
128+
.verticalScrollStateGradient(
129+
scrollState = scrollState,
130+
color = CodeTheme.colors.background,
131+
isLongGradient = true
132+
),
133+
verticalArrangement = Arrangement.spacedBy(CodeTheme.dimens.inset),
134+
) {
135+
Column(
136+
verticalArrangement = Arrangement.spacedBy(CodeTheme.dimens.inset),
137+
) {
138+
TokenIconWithName(
139+
tokenName = state.nameFieldState.text.let {
140+
if (it.isNotBlank()) it.toString() else stringResource(
141+
R.string.placeholder_currencyName
142+
)
143+
},
144+
tokenImage = state.icon.dataOrNull,
145+
imageSize = CodeTheme.dimens.staticGrid.x6,
146+
spacing = CodeTheme.dimens.grid.x2
147+
)
148+
149+
Text(
150+
text = stringResource(R.string.title_currencyCreatorDescription),
151+
style = CodeTheme.typography.textLarge,
152+
color = CodeTheme.colors.textMain,
153+
)
154+
}
155+
156+
DisplayTextInput(
157+
state = state.descriptionFieldState,
158+
placeholder = stringResource(R.string.hint_description),
159+
modifier = Modifier
160+
.fillMaxWidth()
161+
.focusRequester(focusRequester),
162+
keyboardOptions = KeyboardOptions(
163+
keyboardType = KeyboardType.Text,
164+
imeAction = ImeAction.Done,
165+
),
166+
style = CodeTheme.typography.screenTitle,
167+
placeholderStyle = CodeTheme.typography.screenTitle.copy(
168+
color = CodeTheme.colors.textTertiary,
169+
),
170+
maxLines = Int.MAX_VALUE,
171+
onKeyboardAction = {
172+
keyboard.hideIfVisible {
173+
flowNavigator.navigateTo(CurrencyCreatorStep.BillCustomization())
174+
}
175+
},
176+
)
177+
}
161178

162179
LaunchedEffect(Unit) {
163180
focusRequester.requestFocus()

0 commit comments

Comments
 (0)