Skip to content

Instantly share code, notes, and snippets.

View JoaoGeniselli's full-sized avatar

João Guilherme Geniselli JoaoGeniselli

View GitHub Profile
// Depends on:
"com.google.zxing:core"
"com.journeyapps:zxing-android-embedded"
"com.google.accompanist:accompanist-permissions"
@Composable
fun BarcodeScanner(
label: String = "Ler código",
onDetectBarcode: (barcodes: List<String>) -> Unit,
onManualInputClick: () -> Unit = {},
interface OrientationLocker {
fun lockToOrientation(orientation: ScreenOrientation)
}
enum class ScreenOrientation {
PORTRAIT,
LANDSCAPE,
AUTO,
}
@Composable
fun OnLifecycleEvent(block: (owner: LifecycleOwner, event: Lifecycle.Event) -> Unit) {
val eventHandler = rememberUpdatedState(block)
val lifecycleOwner = rememberUpdatedState(LocalLifecycleOwner.current)
DisposableEffect(lifecycleOwner.value) {
val lifecycle = lifecycleOwner.value.lifecycle
val observer = LifecycleEventObserver { owner, event ->
eventHandler.value(owner, event)
}
const val RAW_CPF_LENGTH = 11
const val RAW_CNPJ_LENGTH = 14
fun String.formatCPF(): String {
val digits = this.filter { it.isDigit() }
if (digits.length != RAW_CPF_LENGTH) return this // invalid.
return buildString {
append(digits.substring(0 .. 2))
append(".")
append(digits.substring(3 .. 5))
class Phone(val rawPhone: String) {
val countryCode: String
val regionCode: String
val number: String
init {
when (rawPhone.length) {
COMPLETE_CELLPHONE_LENGTH -> {
countryCode = rawPhone.take(2)
val gson = Gson()
inline fun <reified T> String.fromJson(): T = gson.fromJson(this, T::class.java)
inline fun <reified T> String.fromJsonOrNull(): T? =
runCatching { gson.fromJson(this, T::class.java) }.getOrNull()
fun Any.toJson(): String = gson.toJson(this)
@Composable
inline fun <reified T : ViewModel> NavBackStackEntry.sharedViewModel(
controller: NavHostController
): T {
val graphRoute = destination.parent?.route ?: return koinViewModel()
val parentEntry = remember(this) {
controller.getBackStackEntry(graphRoute)
}
return koinViewModel(viewModelStoreOwner = parentEntry)
}
@JoaoGeniselli
JoaoGeniselli / BirthdateFieldCompose.kt
Created November 4, 2023 16:43
Birthdate input textfield for Jetpack Compose.
const val MAJORITY_AGE = 18
val isRequiredMajority = true
val yearRange = Calendar.getInstance()
.run { get(Calendar.YEAR) }
.let { currentYear ->
val firstYear = currentYear - 100
val lastYear = if (isRequiredMajority) currentYear - MAJORITY_AGE else currentYear
firstYear..lastYear
@JoaoGeniselli
JoaoGeniselli / CurrencyValueFieldCompose.kt
Created November 4, 2023 16:28
Right to left currency value input for Jetpack Compose.
const val CENTS_TO_REALS_POINTS = 2
fun Int.centsToReals(): BigDecimal = BigDecimal(this).movePointLeft(CENTS_TO_REALS_POINTS)
fun BigDecimal.realsToCents(): Int = movePointRight(CENTS_TO_REALS_POINTS).intValueExact()
val localeBR = Locale("pt", "BR")
val blrFormatter = NumberFormat.getCurrencyInstance(localeBR)
fun Int.formatBlr() = blrFormatter.format(centsToReals())
fun BigDecimal.formatBlr() = blrFormatter.format(this)
@JoaoGeniselli
JoaoGeniselli / PhoneComposeTextField.kt
Created November 4, 2023 16:20
Phone number input for Jetpack Compose.
const val RAW_PHONE_LENGTH = 11
@Composable
fun ComposeField() {
var phone by remember { mutableStateOf("") }
val mask = remember { mask("(##) #####-####") } // See 'Masquerade.kt' Gist.
OutlinedTextField(
value = phone,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
placeholder = { Text(mask.pattern) },