Skip to content

Commit

Permalink
auto detekt code from a number phone (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
omarsanchezv authored Feb 8, 2024
1 parent ad2e4db commit 5fdf62a
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 8 deletions.
2 changes: 1 addition & 1 deletion ccp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ afterEvaluate {
groupId = "com.togisoft"
artifactId = "jetpack_country_code_picker"
// Update version in README when changing below
version = "2.2.7"
version = "2.2.8"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import com.togitech.ccp.data.CountryData
import com.togitech.ccp.data.Iso31661alpha2
import com.togitech.ccp.data.PhoneCode
import com.togitech.ccp.data.utils.ValidatePhoneNumber
import com.togitech.ccp.data.utils.extractCountryCode
import com.togitech.ccp.data.utils.getCountryFromPhoneCode
import com.togitech.ccp.data.utils.getUserIsoCode
import com.togitech.ccp.data.utils.numberHint
Expand All @@ -62,6 +63,7 @@ private const val TAG = "TogiCountryCodePicker"
* The first parameter is string pair of (country phone code, phone number) and the second parameter is
* a boolean indicating whether the phone number is valid.
* @param modifier Modifier to be applied to the inner OutlinedTextField.
* @param autoDetectCode Boolean indicating if will auto detect the code from initial phone number
* @param enabled Boolean indicating whether the field is enabled.
* @param shape Shape of the text field.
* @param showCountryCode Whether to show the country code in the text field.
Expand Down Expand Up @@ -92,6 +94,7 @@ private const val TAG = "TogiCountryCodePicker"
fun TogiCountryCodePicker(
onValueChange: (Pair<PhoneCode, String>, Boolean) -> Unit,
modifier: Modifier = Modifier,
autoDetectCode: Boolean = false,
enabled: Boolean = true,
shape: Shape = DEFAULT_TEXT_FIELD_SHAPE,
showCountryCode: Boolean = true,
Expand All @@ -114,35 +117,44 @@ fun TogiCountryCodePicker(
) {
val context = LocalContext.current
val focusRequester = remember { FocusRequester() }

val countryCode = autoDetectedCountryCode(
autoDetectCode = autoDetectCode,
initialPhoneNumber = initialPhoneNumber,
)

val phoneNumberWithoutCode = if (countryCode != null) {
initialPhoneNumber?.replace(countryCode, "")
} else {
initialPhoneNumber
}

var phoneNumber by remember {
mutableStateOf(
TextFieldValue(
text = initialPhoneNumber.orEmpty(),
selection = TextRange(initialPhoneNumber?.length ?: 0),
text = phoneNumberWithoutCode.orEmpty(),
selection = TextRange(phoneNumberWithoutCode?.length ?: 0),
),
)
}
val keyboardController = LocalSoftwareKeyboardController.current

var country: CountryData by rememberSaveable(
context,
countryCode,
initialCountryPhoneCode,
initialCountryIsoCode,
) {
mutableStateOf(
configureInitialCountry(
initialCountryPhoneCode = initialCountryPhoneCode,
initialCountryPhoneCode = countryCode ?: initialCountryPhoneCode,
context = context,
initialCountryIsoCode = initialCountryIsoCode,
fallbackCountry = fallbackCountry,
),
)
}

if (initialPhoneNumber?.startsWith("+") == true) {
Log.e(TAG, "initialPhoneNumber must not include the country code")
}

val phoneNumberTransformation = remember(country) {
PhoneNumberTransformation(country.countryIso, context)
}
Expand Down Expand Up @@ -310,6 +322,14 @@ private fun ClearIconButton(
)
}

@Composable
private fun autoDetectedCountryCode(autoDetectCode: Boolean, initialPhoneNumber: String?): String? =
if (initialPhoneNumber?.startsWith("+") == true && autoDetectCode) {
extractCountryCode(initialPhoneNumber)
} else {
null
}

@Preview
@Composable
private fun TogiCountryCodePickerPreview() {
Expand Down
1 change: 1 addition & 0 deletions ccp/src/main/java/com/togitech/ccp/data/CountryData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -249,5 +249,6 @@ enum class CountryData(val countryIso: Iso31661alpha2, val countryPhoneCode: Pho

companion object {
val isoMap: Map<Iso31661alpha2, CountryData> = entries.associateBy { it.countryIso }
internal val phoneCodeMap: Map<PhoneCode, CountryData> = entries.associateBy { it.countryPhoneCode }
}
}
14 changes: 14 additions & 0 deletions ccp/src/main/java/com/togitech/ccp/data/utils/CountryCodeUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import android.telephony.TelephonyManager
import com.togitech.ccp.data.CountryData
import com.togitech.ccp.data.Iso31661alpha2
import com.togitech.ccp.data.PhoneCode
import kotlin.math.min

private const val EMOJI_UNICODE = 0x1F1A5
private const val MAX_LENGTH_COUNTRY_CODE = 3

internal fun getCountryFromPhoneCode(code: PhoneCode, context: Context): CountryData? {
val countries = CountryData.entries.filter { it.countryPhoneCode == code }
Expand Down Expand Up @@ -39,3 +41,15 @@ fun countryCodeToEmojiFlag(countryCode: Iso31661alpha2): String =

private val Context.telephonyManager: TelephonyManager?
get() = getSystemService(Context.TELEPHONY_SERVICE) as? TelephonyManager

internal fun extractCountryCode(fullNumber: String): String? {
val numberLength = fullNumber.length
val minLength = min(a = numberLength, b = MAX_LENGTH_COUNTRY_CODE)
for (i in 1..minLength) {
val potentialCountryCode = fullNumber.substring(0, i)
if (CountryData.phoneCodeMap.containsKey(potentialCountryCode)) {
return potentialCountryCode
}
}
return null
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 5fdf62a

Please sign in to comment.