Skip to content

Commit

Permalink
added pinlock view
Browse files Browse the repository at this point in the history
  • Loading branch information
Gurupreet committed Sep 17, 2021
1 parent abf57ee commit d4f7b2f
Show file tree
Hide file tree
Showing 19 changed files with 436 additions and 15 deletions.
Binary file added .DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions animations/lottie/src/main/assets/success.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,43 @@ package com.guru.composecookbook.lottie

import android.animation.ValueAnimator
import android.content.Context
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.viewinterop.AndroidView
import com.airbnb.lottie.LottieAnimationView
import com.airbnb.lottie.compose.LottieCompositionSpec
import com.airbnb.lottie.compose.rememberLottieComposition
import androidx.compose.runtime.getValue
import androidx.compose.ui.unit.dp
import com.airbnb.lottie.compose.LottieAnimation


@Composable
fun LottieLoadingView(
context: Context,
file: String,
modifier: Modifier = Modifier
modifier: Modifier = Modifier,
iterations: Int = 10
) {
val lottieView = remember {
LottieAnimationView(context).apply {
setAnimation(file)
repeatCount = ValueAnimator.INFINITE
}
}
AndroidView(
{ lottieView },
modifier = modifier
) {
it.playAnimation()
}
val composition by rememberLottieComposition(LottieCompositionSpec.Asset(file))
LottieAnimation(composition, modifier = modifier.defaultMinSize(300.dp), iterations = iterations)

// OLD ANDROID VIEW IMPLEMENTATION
// val lottieView = remember {
// LottieAnimationView(context).apply {
// setAnimation(file)
// repeatCount = ValueAnimator.INFINITE
// }
// }
// AndroidView(
// { lottieView },
// modifier = modifier
// ) {
// it.playAnimation()
// }


}
2 changes: 2 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ dependencies {
implementation(project(":demos:moviesapp:app"))
implementation(project(":templates:onboarding"))
implementation(project(":templates:paymentcard"))
implementation(project(":templates:pinlock"))
implementation(project(":templates:profile"))
implementation(project(":templates:login"))
implementation(project(":components:fab"))
Expand Down Expand Up @@ -112,4 +113,5 @@ dependencies {
addThirdPartyUnitTestsDependencies()

addAndroidInstrumentationTestsDependencies()
addBiometricDependency()
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.guru.composecookbook.ui.templates

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
Expand All @@ -13,6 +14,7 @@ import androidx.compose.ui.platform.testTag
import androidx.compose.ui.unit.dp
import com.guru.composecookbook.ui.utils.TestTags

@ExperimentalFoundationApi
@Composable
fun TemplateScreen(darkTheme: Boolean) {
val context = LocalContext.current
Expand Down Expand Up @@ -45,6 +47,7 @@ val templates = listOf(
"On-boarding",
"Charts",
"Adding Payment Card",
"Pin Lock/BioMetric",
"Empty Screens",
"Settings",
"Loaders",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
package com.guru.composecookbook.ui.templates

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.WindowManager
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.biometric.BiometricPrompt
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.runtime.Composable
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity
import com.guru.composecookbook.charts.Charts
import com.guru.composecookbook.comingsoon.ComingSoon
import com.guru.composecookbook.login.LoginOnboarding
import com.guru.composecookbook.onboarding.OnBoardingScreen
import com.guru.composecookbook.paymentcard.AddPaymentScreen
import com.guru.composecookbook.profile.ProfileScreen
import com.guru.composecookbook.theme.ComposeCookBookTheme
import com.guru.pinlock.PinLockView

@ExperimentalFoundationApi
class TemplatesActivity : ComponentActivity() {

private val templateType: String by lazy { intent.getStringExtra(TYPE) ?: "Profiles" }
Expand All @@ -27,6 +34,7 @@ class TemplatesActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
// val prompt = createBiometricPrompt(this as FragmentActivity)
setContent {
ComposeCookBookTheme(darkTheme = darkTheme) {
TemplateApp(templateType)
Expand All @@ -46,6 +54,7 @@ class TemplatesActivity : ComponentActivity() {
}
}

@ExperimentalFoundationApi
@ExperimentalAnimationApi
@ExperimentalMaterialApi
@Composable
Expand All @@ -56,6 +65,34 @@ fun TemplateApp(templateType: String) {
"On-boarding" -> OnBoardingScreen { }
"Charts" -> Charts()
"Adding Payment Card" -> AddPaymentScreen()
"Pin Lock/BioMetric" -> PinLockView()
else -> ComingSoon()
}
}

private fun createBiometricPrompt(activity: FragmentActivity): BiometricPrompt {
val executor = ContextCompat.getMainExecutor(activity)

val callback = object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
super.onAuthenticationError(errorCode, errString)
if (errorCode == BiometricPrompt.ERROR_NEGATIVE_BUTTON) {
//loginWithPassword() // Because in this app, the negative button allows the user
// to enter an account password. This is completely optional and your app doesn’t have to do it.
}
}

override fun onAuthenticationFailed() {
super.onAuthenticationFailed()
}

override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
super.onAuthenticationSucceeded(result)
// Proceed with viewing the private encrypted message.
// showEncryptedMessage(result.cryptoObject)
}
}
val biometricPrompt = BiometricPrompt(activity, executor, callback)

return biometricPrompt
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,6 @@ object Dependencies {
const val kotlinTest = "org.jetbrains.kotlin:kotlin-test:${Versions.kotlin}"
const val androidXJunit = "androidx.test.ext:junit:${Versions.androidXJunit}"

const val biometric = "androidx.biometric:biometric:${Versions.biometric}"

}
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,7 @@ fun DependencyHandler.addThirdPartyUiDependencies() {
add("implementation", it)
}
}

fun DependencyHandler.addBiometricDependency() {
add("implementation", Dependencies.biometric)
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,5 +91,7 @@ internal val androidInstrumentationTestsDependencies = listOf(
internal val thirdPartyUiDependencies = listOf(
Dependencies.coilAccompanist,
Dependencies.coilCompose,
Dependencies.lottie
Dependencies.lottie,
Dependencies.composeLottie
)

Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal object Versions {
const val androidLifecycleGrouped = "2.3.1"
const val flinger = "1.0.5"
const val paging = "3.0.1"
const val lottie = "4.0.0"
const val lottie = "4.1.0"
const val room = "2.4.0-alpha03"
const val coreKtx = "1.6.0"
const val appcompat = "1.3.1"
Expand All @@ -34,4 +34,5 @@ internal object Versions {
const val junitJupiterEngine = "5.7.0"
const val truth = "1.1.3"
const val androidXJunit = "1.1.2"
const val biometric = "1.2.0-alpha03"
}
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ include(":templates:onboarding")
include(":templates:paymentcard")
include(":templates:profile")
include(":templates:login")
include(":templates:pinlock")
1 change: 1 addition & 0 deletions templates/pinlock/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
23 changes: 23 additions & 0 deletions templates/pinlock/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import com.guru.composecookbook.build.dependencies.addBiometricDependency
import com.guru.composecookbook.build.dependencies.addComposeOfficialDependencies
import com.guru.composecookbook.build.dependencies.addComposeThirdPartyDependencies


plugins {
/**
* See [common-compose-module-configs-script-plugin.gradle.kts] file
*/
id("common-compose-module-configs-script-plugin")
}

dependencies {
implementation(project(":theme"))
implementation(project(":data"))
implementation(project(":animations:lottie"))
implementation(project(":components:tags"))
implementation(project(":templates:onboarding"))

addComposeOfficialDependencies()
addComposeThirdPartyDependencies()
addBiometricDependency()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.guru.pinlock

import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4

import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*

/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.guru.pinlock.test", appContext.packageName)
}
}
12 changes: 12 additions & 0 deletions templates/pinlock/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.guru.pinlock">

<application>
<activity
android:name=".BiometricActivity"
android:exported="true"
android:theme="@style/Theme.Transparent"/>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.guru.pinlock

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.biometric.BiometricPrompt
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.material.ExperimentalMaterialApi
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity

@ExperimentalFoundationApi
class BiometricActivity : FragmentActivity() {

@ExperimentalMaterialApi
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val biometricPromt = createBiometricPrompt(this)
val promptInfo = BiometricPrompt.PromptInfo.Builder()
.setTitle("Verify Identity to login")
.setSubtitle("Log in using your biometric credential")
.setNegativeButtonText("Use pin password")
.build()
biometricPromt.authenticate(promptInfo)
}

companion object {
fun newIntent(context: Context) = Intent(context, BiometricActivity::class.java)
}
}

private fun createBiometricPrompt(activity: FragmentActivity): BiometricPrompt {
val executor = ContextCompat.getMainExecutor(activity)

val callback = object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
super.onAuthenticationError(errorCode, errString)
// if (errorCode == BiometricPrompt.ERROR_NEGATIVE_BUTTON) {
// activity.finish()
// }
activity.finish()
}

override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
super.onAuthenticationSucceeded(result)
activity.setResult(Activity.RESULT_OK)
activity.finish()
}
}
val biometricPrompt = BiometricPrompt(activity, executor, callback)

return biometricPrompt
}


Loading

0 comments on commit d4f7b2f

Please sign in to comment.