Skip to content

Commit 9786dfa

Browse files
committed
feat(fc): add counter to room description
Signed-off-by: Brandon McAnsh <git@bmcreations.dev>
1 parent 860daec commit 9786dfa

3 files changed

Lines changed: 82 additions & 18 deletions

File tree

flipchatApp/src/main/kotlin/xyz/flipchat/app/features/chat/description/RoomDescriptionScreen.kt

Lines changed: 73 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ package xyz.flipchat.app.features.chat.description
22

33
import android.os.Parcelable
44
import androidx.activity.compose.BackHandler
5+
import androidx.compose.animation.Crossfade
6+
import androidx.compose.animation.animateColorAsState
7+
import androidx.compose.foundation.background
58
import androidx.compose.foundation.layout.Arrangement
69
import androidx.compose.foundation.layout.Box
710
import androidx.compose.foundation.layout.Column
@@ -11,7 +14,11 @@ import androidx.compose.foundation.layout.fillMaxWidth
1114
import androidx.compose.foundation.layout.imePadding
1215
import androidx.compose.foundation.layout.navigationBarsPadding
1316
import androidx.compose.foundation.layout.padding
17+
import androidx.compose.foundation.layout.wrapContentHeight
18+
import androidx.compose.foundation.shape.CornerSize
19+
import androidx.compose.foundation.shape.ZeroCornerSize
1420
import androidx.compose.foundation.text.KeyboardOptions
21+
import androidx.compose.material.Text
1522
import androidx.compose.runtime.Composable
1623
import androidx.compose.runtime.LaunchedEffect
1724
import androidx.compose.runtime.collectAsState
@@ -27,6 +34,7 @@ import androidx.compose.ui.platform.LocalSoftwareKeyboardController
2734
import androidx.compose.ui.res.stringResource
2835
import androidx.compose.ui.text.input.KeyboardCapitalization
2936
import androidx.compose.ui.text.input.KeyboardType
37+
import androidx.compose.ui.text.style.TextAlign
3038
import androidx.compose.ui.unit.dp
3139
import cafe.adriel.voyager.core.screen.Screen
3240
import cafe.adriel.voyager.core.screen.ScreenKey
@@ -55,7 +63,8 @@ import xyz.flipchat.app.R
5563
import kotlin.time.Duration.Companion.seconds
5664

5765
@Parcelize
58-
data class RoomDescriptionScreen(val roomId: ID, val existingDescription: String) : Screen, Parcelable {
66+
data class RoomDescriptionScreen(val roomId: ID, val existingDescription: String) : Screen,
67+
Parcelable {
5968

6069
@IgnoredOnParcel
6170
override val key: ScreenKey = uniqueScreenKey
@@ -140,7 +149,7 @@ private fun RoomDescriptionScreenContent(
140149
.padding(bottom = CodeTheme.dimens.grid.x3),
141150
) {
142151
CodeButton(
143-
enabled = state.canCheck || state.previousRoomDescription.isNotEmpty(), // allow resets
152+
enabled = state.canCheck || (state.previousRoomDescription.isNotEmpty() && state.isLimitValid), // allow resets
144153
modifier = Modifier
145154
.fillMaxWidth()
146155
.padding(horizontal = CodeTheme.dimens.inset),
@@ -169,23 +178,70 @@ private fun RoomDescriptionScreenContent(
169178
.padding(horizontal = CodeTheme.dimens.inset),
170179
verticalArrangement = Arrangement.spacedBy(CodeTheme.dimens.inset)
171180
) {
172-
TextInput(
181+
Box(
173182
modifier = Modifier
174183
.fillMaxWidth()
175-
.focusRequester(focusRequester),
176-
state = state.textFieldState,
177-
colors = inputColors(backgroundColor = Color.Transparent),
178-
keyboardOptions = KeyboardOptions(
179-
keyboardType = KeyboardType.Text,
180-
capitalization = KeyboardCapitalization.Sentences
181-
),
182-
contentPadding = PaddingValues(CodeTheme.dimens.grid.x3),
183-
textFieldAlignment = Alignment.TopStart,
184-
minHeight = 120.dp,
185-
maxLines = 6,
186-
isError = state.textFieldState.text.length > state.maxLimit,
187-
placeholder = stringResource(R.string.subtitle_roomDescription),
188-
)
184+
.wrapContentHeight(),
185+
) {
186+
TextInput(
187+
modifier = Modifier
188+
.fillMaxWidth()
189+
.focusRequester(focusRequester)
190+
.align(Alignment.Center),
191+
state = state.textFieldState,
192+
colors = inputColors(
193+
backgroundColor = Color.Transparent,
194+
errorBorderColor = CodeTheme.colors.errorText,
195+
),
196+
keyboardOptions = KeyboardOptions(
197+
keyboardType = KeyboardType.Text,
198+
capitalization = KeyboardCapitalization.Sentences
199+
),
200+
contentPadding = PaddingValues(CodeTheme.dimens.grid.x3),
201+
textFieldAlignment = Alignment.TopStart,
202+
minHeight = 120.dp,
203+
maxLines = 6,
204+
isError = state.textFieldState.text.length > state.maxLimit,
205+
placeholder = stringResource(R.string.subtitle_roomDescription),
206+
)
207+
208+
Crossfade(
209+
modifier = Modifier
210+
.align(Alignment.BottomEnd)
211+
.padding(
212+
bottom = CodeTheme.dimens.border,
213+
end = CodeTheme.dimens.border,
214+
),
215+
targetState = state.isApproachingLengthOrOver
216+
) { show ->
217+
if (show) {
218+
val textColor by animateColorAsState(
219+
if (state.textFieldState.text.length > state.maxLimit) {
220+
CodeTheme.colors.errorText
221+
} else {
222+
CodeTheme.colors.textSecondary
223+
}
224+
)
225+
Text(
226+
modifier = Modifier
227+
.background(
228+
color = CodeTheme.colors.brandDark.copy(0.54f),
229+
shape = CodeTheme.shapes.small.copy(
230+
topEnd = ZeroCornerSize,
231+
bottomStart = ZeroCornerSize,
232+
)
233+
)
234+
.padding(5.dp),
235+
textAlign = TextAlign.Center,
236+
text = "${state.textFieldState.text.length}/${state.maxLimit}",
237+
style = CodeTheme.typography.caption,
238+
color = textColor,
239+
)
240+
} else {
241+
Text("")
242+
}
243+
}
244+
}
189245
}
190246
}
191247

flipchatApp/src/main/kotlin/xyz/flipchat/app/features/chat/description/RoomDescriptionScreenViewModel.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,14 @@ internal class RoomDescriptionScreenViewModel @Inject constructor(
4747
val update: LoadingSuccessState = LoadingSuccessState(),
4848
val textFieldState: TextFieldState = TextFieldState(""),
4949
) {
50+
val isApproachingLengthOrOver: Boolean
51+
get() = textFieldState.text.length >= 150
52+
53+
val isLimitValid: Boolean
54+
get() = textFieldState.text.length <= 160
55+
5056
val canCheck: Boolean
51-
get() = textFieldState.text.isNotEmpty() && textFieldState.text.length <= 160
57+
get() = textFieldState.text.isNotEmpty() && isLimitValid
5258
}
5359

5460
sealed interface Event {

ui/theme/src/main/kotlin/com/getcode/theme/Theme.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ fun inputColors(
271271
backgroundColor: Color = White05,
272272
placeholderColor: Color = White50,
273273
cursorColor: Color = Color.White,
274+
errorBorderColor: Color = CodeTheme.colors.error,
274275
) = TextFieldDefaults.outlinedTextFieldColors(
275276
textColor = textColor,
276277
disabledTextColor = disabledTextColor,
@@ -279,4 +280,5 @@ fun inputColors(
279280
focusedBorderColor = borderColor,
280281
unfocusedBorderColor = unfocusedBorderColor,
281282
cursorColor = cursorColor,
283+
errorBorderColor = errorBorderColor
282284
)

0 commit comments

Comments
 (0)