Skip to content

Instantly share code, notes, and snippets.

@Puneet1796
Last active November 24, 2022 23:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Puneet1796/645a89d558c1f477f212b9686e0b673e to your computer and use it in GitHub Desktop.
Save Puneet1796/645a89d558c1f477f212b9686e0b673e to your computer and use it in GitHub Desktop.
Pin Unlock View
package com.datavault.compose.components
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Backspace
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.datavault.compose.ui.theme.DataVaultTheme
typealias OnSubmitEvent = (String) -> Unit
typealias OnKeyTapEvent = (Char) -> Unit
typealias onSubmitTapEvent = () -> Unit
@Composable
fun NumberLockView(
title: String,
subtitle: String,
length: Int,
onSubmit: OnSubmitEvent
) {
val (code, setCode) = remember { mutableStateOf("") }
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp),
modifier = Modifier
.fillMaxSize()
.padding(vertical = 40.dp)
) {
// Title
TitleView(
title = title,
modifier = Modifier.padding(bottom = 20.dp)
)
// Subtitle
SubtitleView(
subtitle = subtitle,
modifier = Modifier.padding(
bottom = 20.dp,
end = 20.dp,
start = 20.dp
)
)
// Spacer
Spacer(modifier = Modifier.weight(1f))
// Circle Row based on length
PinCircleView(
code = code,
length = length,
modifier = Modifier.padding(bottom = 20.dp)
)
// Spacer
Spacer(modifier = Modifier.weight(1f))
// Number Keyboard view
NumberKeyboardView(onTap = { char ->
if (char == '<' && code.isNotEmpty()) {
setCode(code.substring(0, code.length - 1))
} else if (char.isDigit() && code.length < length) {
setCode(code.plus(char))
}
})
// Submit button
SubmitButton(
label = "Submit",
enabled = code.length == length
) {
onSubmit(code)
setCode("")
}
}
}
@Composable
fun TitleView(
modifier: Modifier = Modifier,
title: String
) {
Text(
title,
style = MaterialTheme.typography.h5,
fontWeight = FontWeight.Bold,
color = Color.Black,
textAlign = TextAlign.Center,
modifier = modifier
)
}
@Composable
fun SubtitleView(
modifier: Modifier = Modifier,
subtitle: String
) {
Text(
subtitle,
style = MaterialTheme.typography.body2,
color = Color.Gray,
textAlign = TextAlign.Center,
modifier = modifier
)
}
@Composable
fun PinCircleView(
modifier: Modifier = Modifier,
code: String,
length: Int
) {
val filledCircleLength = code.length
Row(
modifier = modifier.padding(vertical = 10.dp),
horizontalArrangement = Arrangement.spacedBy(10.dp)
) {
(0 until length).forEach { index ->
DotView(filled = index < filledCircleLength)
}
}
}
@Composable
fun DotView(
filled: Boolean,
fillColor: Color = Color.Black
) {
val conditionalModifier = if (filled)
Modifier.background(fillColor, shape = CircleShape)
else
Modifier.border(width = 1.dp, color = fillColor, shape = CircleShape)
Box(
modifier = Modifier
.size(12.dp)
.then(conditionalModifier)
)
}
@Composable
fun NumberKeyboardView(
onTap: OnKeyTapEvent
) {
val keys = "123456789 0<"
LazyVerticalGrid(columns = GridCells.Fixed(3)) {
items(keys.length - 1) { index ->
Box(
modifier = Modifier.height(100.dp),
contentAlignment = Alignment.Center
) {
Box(
modifier = Modifier
.clip(CircleShape)
.clickable(
enabled = !keys[index].isWhitespace(),
onClick = { onTap(keys[index]) },
role = Role.Button
)
.size(60.dp),
contentAlignment = Alignment.Center
) {
Text(
keys[index].toString(),
style = MaterialTheme.typography.h5
)
}
}
}
item {
IconButton(
onClick = { onTap('<') },
modifier = Modifier.height(100.dp)
) {
Icon(
Icons.Filled.Backspace,
contentDescription = null
)
}
}
}
}
@Composable
fun SubmitButton(
modifier: Modifier = Modifier,
label: String,
enabled: Boolean,
onClick: onSubmitTapEvent
) {
Button(
onClick = onClick,
enabled = enabled,
modifier = modifier
.fillMaxWidth()
.padding(horizontal = 20.dp)
) {
Text(label)
}
}
@Preview(showBackground = true)
@Composable
fun Preview_NumberLockView() {
DataVaultTheme {
NumberLockView(
title = "Create Consent Pin",
subtitle = "Please create your consent pin. It will be required later for login.",
length = 4,
onSubmit = {}
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment