Skip to content

Commit d65e1ad

Browse files
authored
Merge pull request #93 from code-payments/chore/phone-verify-alignment
chore(phone): properly align textfield with contents
2 parents 26fa9bd + 6e3003d commit d65e1ad

1 file changed

Lines changed: 124 additions & 102 deletions

File tree

app/src/main/java/com/getcode/view/login/PhoneVerify.kt

Lines changed: 124 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import androidx.compose.foundation.layout.Column
1313
import androidx.compose.foundation.layout.Row
1414
import androidx.compose.foundation.layout.Spacer
1515
import androidx.compose.foundation.layout.WindowInsets
16+
import androidx.compose.foundation.layout.fillMaxHeight
1617
import androidx.compose.foundation.layout.fillMaxSize
1718
import androidx.compose.foundation.layout.height
1819
import androidx.compose.foundation.layout.imePadding
@@ -21,22 +22,18 @@ import androidx.compose.foundation.layout.padding
2122
import androidx.compose.foundation.layout.size
2223
import androidx.compose.foundation.layout.width
2324
import androidx.compose.foundation.layout.windowInsetsPadding
24-
import androidx.compose.foundation.layout.wrapContentWidth
2525
import androidx.compose.foundation.shape.ZeroCornerSize
2626
import androidx.compose.foundation.text.BasicTextField
2727
import androidx.compose.foundation.text.KeyboardActions
2828
import androidx.compose.foundation.text.KeyboardOptions
2929
import androidx.compose.material.Text
30-
import androidx.compose.material.TextField
31-
import androidx.compose.material.TextFieldDefaults
3230
import androidx.compose.runtime.Composable
3331
import androidx.compose.runtime.LaunchedEffect
3432
import androidx.compose.runtime.collectAsState
3533
import androidx.compose.runtime.getValue
3634
import androidx.compose.runtime.remember
3735
import androidx.compose.runtime.rememberCoroutineScope
3836
import androidx.compose.ui.Alignment
39-
import androidx.compose.ui.Alignment.Companion.BottomCenter
4037
import androidx.compose.ui.Alignment.Companion.Center
4138
import androidx.compose.ui.Alignment.Companion.CenterStart
4239
import androidx.compose.ui.Alignment.Companion.CenterVertically
@@ -52,11 +49,11 @@ import androidx.compose.ui.platform.LocalFocusManager
5249
import androidx.compose.ui.res.painterResource
5350
import androidx.compose.ui.res.stringResource
5451
import androidx.compose.ui.text.input.KeyboardType
52+
import androidx.compose.ui.text.input.TextFieldValue
5553
import androidx.compose.ui.text.style.TextAlign
5654
import androidx.compose.ui.tooling.preview.Preview
5755
import androidx.compose.ui.unit.dp
5856
import androidx.compose.ui.unit.sp
59-
import androidx.constraintlayout.compose.ConstraintLayout
6057
import androidx.hilt.navigation.compose.hiltViewModel
6158
import com.getcode.R
6259
import com.getcode.navigation.core.LocalCodeNavigator
@@ -66,7 +63,7 @@ import com.getcode.theme.CodeTheme
6663
import com.getcode.theme.White05
6764
import com.getcode.theme.White50
6865
import com.getcode.theme.extraSmall
69-
import com.getcode.util.debugBounds
66+
import com.getcode.util.PhoneUtils
7067
import com.getcode.util.getActivity
7168
import com.getcode.util.rememberedClickable
7269
import com.getcode.view.components.ButtonState
@@ -75,7 +72,6 @@ import com.google.android.gms.auth.api.identity.GetPhoneNumberHintIntentRequest
7572
import com.google.android.gms.auth.api.identity.Identity
7673
import kotlinx.coroutines.delay
7774
import kotlinx.coroutines.launch
78-
import timber.log.Timber
7975

8076
@Preview
8177
@Composable
@@ -88,7 +84,6 @@ internal fun PhoneVerify(
8884
val dataState by viewModel.uiFlow.collectAsState()
8985
val focusRequester = remember { FocusRequester() }
9086
val context = LocalContext.current
91-
val composeScope = rememberCoroutineScope()
9287
val focusManager = LocalFocusManager.current
9388

9489
Column(
@@ -105,101 +100,21 @@ internal fun PhoneVerify(
105100
horizontalAlignment = Alignment.CenterHorizontally,
106101
verticalArrangement = Arrangement.spacedBy(CodeTheme.dimens.inset),
107102
) {
108-
Row(
103+
PhoneEntry(
109104
modifier = Modifier
110-
.height(CodeTheme.dimens.grid.x12)
111-
.border(
112-
width = CodeTheme.dimens.border,
113-
color = BrandLight,
114-
shape = CodeTheme.shapes.extraSmall
115-
)
116-
.background(White05)
117-
) {
118-
Row(
119-
modifier = Modifier
120-
.height(CodeTheme.dimens.grid.x12)
121-
.clip(
122-
CodeTheme.shapes.extraSmall
123-
.copy(bottomEnd = ZeroCornerSize, topEnd = ZeroCornerSize)
124-
)
125-
.rememberedClickable {
126-
composeScope.launch {
127-
focusManager.clearFocus(true)
128-
delay(500)
129-
openCountrySelector()
130-
}
131-
},
132-
) {
133-
dataState.countryLocale.resId?.let { resId ->
134-
Image(
135-
modifier = Modifier
136-
.align(CenterVertically)
137-
.padding(start = CodeTheme.dimens.grid.x3)
138-
.size(CodeTheme.dimens.staticGrid.x5)
139-
.clip(CodeTheme.shapes.large),
140-
painter = painterResource(resId),
141-
contentDescription = "",
142-
)
143-
}
144-
Box(
145-
modifier = Modifier
146-
.height(CodeTheme.dimens.grid.x12)
147-
.align(CenterVertically)
148-
.padding(horizontal = CodeTheme.dimens.grid.x3,),
149-
contentAlignment = Center
150-
) {
151-
Text(
152-
style = CodeTheme.typography.subtitle1,
153-
text = "+${dataState.countryLocale.phoneCode}"
154-
)
155-
}
156-
}
157-
Spacer(
158-
modifier = Modifier
159-
.background(BrandLight)
160-
.width(1.dp)
161-
.height(CodeTheme.dimens.grid.x12)
162-
)
163-
BasicTextField(
164-
modifier = Modifier
165-
.wrapContentWidth()
166-
.weight(1f)
167-
.focusRequester(focusRequester),
168-
value = dataState.phoneNumberFormattedTextFieldValue,
169-
textStyle = CodeTheme.typography.subtitle1.copy(color = CodeTheme.colors.onBackground),
170-
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Phone),
171-
cursorBrush = SolidColor(Color.White),
172-
singleLine = true,
173-
keyboardActions = KeyboardActions(
174-
onDone = {
175-
viewModel.onSubmit(navigator, context.getActivity())
176-
}
177-
),
178-
onValueChange = {
179-
if (!dataState.isLoading) {
180-
viewModel.setPhoneInput(it.text, it.selection)
181-
}
182-
},
183-
enabled = !dataState.isLoading && !dataState.isSuccess,
184-
) { textField ->
185-
Box(
186-
modifier = Modifier
187-
.fillMaxSize()
188-
.padding(start = CodeTheme.dimens.staticGrid.x2),
189-
contentAlignment = CenterStart
190-
) {
191-
if (dataState.phoneNumberFormattedTextFieldValue.text.isEmpty()) {
192-
Text(
193-
text = stringResource(id = R.string.title_phoneNumber),
194-
color = White50,
195-
fontSize = 20.sp
196-
)
197-
}
198-
textField()
199-
}
200-
}
201-
202-
}
105+
.height(CodeTheme.dimens.grid.x12),
106+
focusManager = focusManager,
107+
focusRequester = focusRequester,
108+
locale = dataState.countryLocale,
109+
isLoading = dataState.isLoading,
110+
isSuccess = dataState.isSuccess,
111+
value = dataState.phoneNumberFormattedTextFieldValue,
112+
onValueChanged = {
113+
viewModel.setPhoneInput(it.text, it.selection)
114+
},
115+
openCountrySelector = openCountrySelector,
116+
onSubmit = { viewModel.onSubmit(navigator, context.getActivity()) }
117+
)
203118

204119
Text(
205120
modifier = Modifier.padding(horizontal = CodeTheme.dimens.grid.x2),
@@ -262,4 +177,111 @@ internal fun PhoneVerify(
262177
}
263178
}
264179
}
180+
}
181+
182+
@Composable
183+
private fun PhoneEntry(
184+
modifier: Modifier = Modifier,
185+
focusManager: FocusManager,
186+
focusRequester: FocusRequester,
187+
locale: PhoneUtils.CountryLocale,
188+
isLoading: Boolean,
189+
isSuccess: Boolean,
190+
value: TextFieldValue,
191+
onValueChanged: (TextFieldValue) -> Unit,
192+
openCountrySelector: () -> Unit,
193+
onSubmit: () -> Unit,
194+
) {
195+
val composeScope = rememberCoroutineScope()
196+
Row(
197+
modifier = modifier
198+
.border(
199+
width = CodeTheme.dimens.border,
200+
color = BrandLight,
201+
shape = CodeTheme.shapes.extraSmall
202+
)
203+
.background(White05)
204+
) {
205+
Row(
206+
modifier = Modifier
207+
.height(CodeTheme.dimens.grid.x12)
208+
.clip(
209+
CodeTheme.shapes.extraSmall
210+
.copy(bottomEnd = ZeroCornerSize, topEnd = ZeroCornerSize)
211+
)
212+
.rememberedClickable {
213+
composeScope.launch {
214+
focusManager.clearFocus(true)
215+
delay(500)
216+
openCountrySelector()
217+
}
218+
},
219+
) {
220+
locale.resId?.let { resId ->
221+
Image(
222+
modifier = Modifier
223+
.align(CenterVertically)
224+
.padding(start = CodeTheme.dimens.grid.x3)
225+
.size(CodeTheme.dimens.staticGrid.x5)
226+
.clip(CodeTheme.shapes.large),
227+
painter = painterResource(resId),
228+
contentDescription = "",
229+
)
230+
}
231+
Box(
232+
modifier = Modifier
233+
.fillMaxHeight()
234+
.padding(vertical = CodeTheme.dimens.border)
235+
.padding(horizontal = CodeTheme.dimens.grid.x3,),
236+
contentAlignment = Center
237+
) {
238+
Text(
239+
style = CodeTheme.typography.subtitle1,
240+
text = "+${locale.phoneCode}"
241+
)
242+
}
243+
}
244+
Spacer(
245+
modifier = Modifier
246+
.background(BrandLight)
247+
.width(1.dp)
248+
.fillMaxHeight()
249+
)
250+
BasicTextField(
251+
modifier = Modifier
252+
.fillMaxHeight()
253+
.padding(top = CodeTheme.dimens.border)
254+
.weight(1f)
255+
.focusRequester(focusRequester),
256+
value = value,
257+
textStyle = CodeTheme.typography.subtitle1.copy(color = CodeTheme.colors.onBackground),
258+
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Phone),
259+
cursorBrush = SolidColor(Color.White),
260+
singleLine = true,
261+
keyboardActions = KeyboardActions(onDone = { onSubmit() }),
262+
onValueChange = {
263+
if (!isLoading) {
264+
onValueChanged(it)
265+
}
266+
},
267+
enabled = !isLoading && !isSuccess,
268+
) { textField ->
269+
Box(
270+
modifier = Modifier
271+
.fillMaxSize()
272+
.padding(start = CodeTheme.dimens.staticGrid.x2),
273+
contentAlignment = CenterStart
274+
) {
275+
if (value.text.isEmpty()) {
276+
Text(
277+
text = stringResource(id = R.string.title_phoneNumber),
278+
color = White50,
279+
fontSize = 20.sp
280+
)
281+
}
282+
textField()
283+
}
284+
}
285+
286+
}
265287
}

0 commit comments

Comments
 (0)