Skip to content

Commit

Permalink
Extract AppLockedScreen.kt to another file + minor refactor (& fix bu…
Browse files Browse the repository at this point in the history
…g caused by the previous refactor)
  • Loading branch information
Iliyan Germanov committed Nov 15, 2021
1 parent de799c3 commit ec3347c
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 130 deletions.
142 changes: 16 additions & 126 deletions app/src/main/java/com/ivy/wallet/ui/IvyActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,13 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.biometric.BiometricPrompt
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.*
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
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 androidx.core.content.ContextCompat
import androidx.core.view.WindowCompat
import androidx.lifecycle.viewmodel.compose.viewModel
import com.google.accompanist.insets.systemBarsPadding
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.android.gms.auth.api.signin.GoogleSignInClient
Expand All @@ -50,11 +36,11 @@ import com.google.android.gms.tasks.Task
import com.google.android.play.core.review.ReviewManagerFactory
import com.ivy.wallet.BuildConfig
import com.ivy.wallet.Constants
import com.ivy.wallet.R
import com.ivy.wallet.base.*
import com.ivy.wallet.logic.CustomerJourneyLogic
import com.ivy.wallet.model.TransactionType
import com.ivy.wallet.ui.analytics.AnalyticsReport
import com.ivy.wallet.ui.applocked.AppLockedScreen
import com.ivy.wallet.ui.balance.BalanceScreen
import com.ivy.wallet.ui.bankintegrations.ConnectBankScreen
import com.ivy.wallet.ui.budget.BudgetScreen
Expand All @@ -72,7 +58,6 @@ import com.ivy.wallet.ui.statistic.level1.PieChartStatisticScreen
import com.ivy.wallet.ui.statistic.level2.ItemStatisticScreen
import com.ivy.wallet.ui.test.TestScreen
import com.ivy.wallet.ui.theme.*
import com.ivy.wallet.ui.theme.components.IvyButton
import com.ivy.wallet.ui.webView.WebViewScreen
import com.ivy.wallet.widget.AddTransactionWidget
import dagger.hilt.android.AndroidEntryPoint
Expand Down Expand Up @@ -205,9 +190,8 @@ class IvyActivity : AppCompatActivity() {
val viewModel: IvyViewModel = viewModel()
val isSystemInDarkTheme = isSystemInDarkTheme()

val appLocked by viewModel.appLocked.observeAsState(false)
appLockedEnabled = appLocked
val isUserInactive = ivyContext.isUserInactive
val appLockedEnabled by viewModel.appLockedEnabled.observeAsState(false)
val isUserInactive by ivyContext.isUserInactive

LaunchedEffect(isSystemInDarkTheme) {
viewModel.start(isSystemInDarkTheme, intent)
Expand All @@ -217,7 +201,12 @@ class IvyActivity : AppCompatActivity() {
IvyApp(
ivyContext = ivyContext,
) {
if (appLocked) {
if (appLockedEnabled) {
//update this.appLockedEnabled here
// because only dependant Compose code on appLockedEnabled state will be updated
//when appLockedEnabled state is changed
this@IvyActivity.appLockedEnabled = true

ivyContext.navigateTo(
Screen.AppLock(
onShowOSBiometricsModal = {
Expand All @@ -237,14 +226,15 @@ class IvyActivity : AppCompatActivity() {
)
}

if (appLockedEnabled && isUserInactive.value) {
if (appLockedEnabled && isUserInactive) {
ivyContext.resetUserInActiveTimer()
ivyContext.navigateTo(
Screen.AppLock(
onShowOSBiometricsModal = {
authenticateWithOSBiometricsModal(
viewModel.handleBiometricAuthenticationResult(
onAuthSuccess = {
//go back to previous screen
ivyContext.back()
}
)
Expand Down Expand Up @@ -280,16 +270,7 @@ class IvyActivity : AppCompatActivity() {
is Screen.Report -> ReportScreen(screen = screen)
is Screen.Budget -> BudgetScreen(screen = screen)
is Screen.WebView -> WebViewScreen(screen = screen)
is Screen.AppLock -> {
AppLockedScreen(
onShowOSBiometricsModal = {
screen.onShowOSBiometricsModal()
},
onContinueWithoutAuthentication = {
screen.onContinueWithoutAuthentication()
}
)
}
is Screen.AppLock -> AppLockedScreen(screen = screen)
null -> {
}
}
Expand All @@ -304,101 +285,21 @@ class IvyActivity : AppCompatActivity() {
WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE
)
} else
} else {
window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
}
}

override fun onResume() {
super.onResume()
if (appLockedEnabled) {
if (appLockedEnabled)
ivyContext.checkUserInactiveTimeStatus()
}
}

override fun onPause() {
super.onPause()
if (appLockedEnabled) {
if (appLockedEnabled)
ivyContext.startUserInactiveTimeCounter()
}
}

@Composable
private fun AppLockedScreen(
onShowOSBiometricsModal: () -> Unit,
onContinueWithoutAuthentication: () -> Unit,
) {
Column(
modifier = Modifier
.fillMaxSize()
.systemBarsPadding(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(Modifier.height(32.dp))

Text(
modifier = Modifier
.background(IvyTheme.colors.medium, Shapes.roundedFull)
.padding(vertical = 12.dp)
.padding(horizontal = 32.dp),
text = "APP LOCKED",
style = Typo.body2.style(
fontWeight = FontWeight.ExtraBold,
)
)

Spacer(Modifier.weight(1f))

Image(
modifier = Modifier
.size(width = 96.dp, height = 138.dp),
painter = painterResource(id = R.drawable.ic_fingerprint),
colorFilter = ColorFilter.tint(IvyTheme.colors.medium),
contentScale = ContentScale.FillBounds,
contentDescription = "unlock icon"
)

Spacer(Modifier.weight(1f))

Text(
text = "Authenticate to enter the app",
style = Typo.body2.style(
fontWeight = FontWeight.SemiBold,
color = Gray
)
)

Spacer(Modifier.height(24.dp))

val context = LocalContext.current
IvyButton(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
text = "Unlock",
textStyle = Typo.body2.style(
color = White,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center
),
wrapContentMode = false
) {
if (hasLockScreen(context)) {
onShowOSBiometricsModal()
} else {
onContinueWithoutAuthentication()
}
}
Spacer(Modifier.height(24.dp))

//To automatically launch the biometric screen on load of this composable
LaunchedEffect(true) {
if (hasLockScreen(context)) {
onShowOSBiometricsModal()
} else {
onContinueWithoutAuthentication()
}
}
}
}

private fun authenticateWithOSBiometricsModal(
Expand Down Expand Up @@ -619,15 +520,4 @@ class IvyActivity : AppCompatActivity() {
val addTransactionWidget = ComponentName(this, AddTransactionWidget::class.java)
appWidgetManager.requestPinAppWidget(addTransactionWidget, null, null)
}

@Preview
@Composable
private fun Preview_Locked() {
IvyAppPreview {
AppLockedScreen(
onContinueWithoutAuthentication = {},
onShowOSBiometricsModal = {}
)
}
}
}
8 changes: 4 additions & 4 deletions app/src/main/java/com/ivy/wallet/ui/IvyViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ class IvyViewModel @Inject constructor(
const val EXTRA_ADD_TRANSACTION_TYPE = "add_transaction_type_extra"
}

private val _appLocked = MutableLiveData<Boolean>()
val appLocked = _appLocked.asLiveData()
private val _appLockedEnabled = MutableLiveData<Boolean>()
val appLockedEnabled = _appLockedEnabled.asLiveData()

fun start(systemDarkMode: Boolean, intent: Intent) {
viewModelScope.launch {
Expand All @@ -62,7 +62,7 @@ class IvyViewModel @Inject constructor(
if (onboardingCompleted()) {
val appLocked = sharedPrefs.getBoolean(SharedPrefs.LOCK_APP, false)
uiThread {
_appLocked.value = appLocked
_appLockedEnabled.value = appLocked
}

if (!appLocked) {
Expand Down Expand Up @@ -110,7 +110,7 @@ class IvyViewModel @Inject constructor(
}

fun unlockAuthenticated(intent: Intent) {
_appLocked.value = false
_appLockedEnabled.value = false
continueNavigation(intent)
}

Expand Down
116 changes: 116 additions & 0 deletions app/src/main/java/com/ivy/wallet/ui/applocked/AppLockedScreen.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package com.ivy.wallet.ui.applocked

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
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.google.accompanist.insets.systemBarsPadding
import com.ivy.wallet.R
import com.ivy.wallet.base.hasLockScreen
import com.ivy.wallet.ui.IvyAppPreview
import com.ivy.wallet.ui.Screen
import com.ivy.wallet.ui.theme.*
import com.ivy.wallet.ui.theme.components.IvyButton

@Composable
fun AppLockedScreen(
screen: Screen.AppLock
) {
Column(
modifier = Modifier
.fillMaxSize()
.systemBarsPadding(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(Modifier.height(32.dp))

Text(
modifier = Modifier
.background(IvyTheme.colors.medium, Shapes.roundedFull)
.padding(vertical = 12.dp)
.padding(horizontal = 32.dp),
text = "APP LOCKED",
style = Typo.body2.style(
fontWeight = FontWeight.ExtraBold,
)
)

Spacer(Modifier.weight(1f))

Image(
modifier = Modifier
.size(width = 96.dp, height = 138.dp),
painter = painterResource(id = R.drawable.ic_fingerprint),
colorFilter = ColorFilter.tint(IvyTheme.colors.medium),
contentScale = ContentScale.FillBounds,
contentDescription = "unlock icon"
)

Spacer(Modifier.weight(1f))

Text(
text = "Authenticate to enter the app",
style = Typo.body2.style(
fontWeight = FontWeight.SemiBold,
color = Gray
)
)

Spacer(Modifier.height(24.dp))

val context = LocalContext.current
IvyButton(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
text = "Unlock",
textStyle = Typo.body2.style(
color = White,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center
),
wrapContentMode = false
) {
if (hasLockScreen(context)) {
screen.onShowOSBiometricsModal()
} else {
screen.onContinueWithoutAuthentication()
}
}
Spacer(Modifier.height(24.dp))

//To automatically launch the biometric screen on load of this composable
LaunchedEffect(true) {
if (hasLockScreen(context)) {
screen.onShowOSBiometricsModal()
} else {
screen.onContinueWithoutAuthentication()
}
}
}
}

@Preview
@Composable
private fun Preview_Locked() {
IvyAppPreview {
AppLockedScreen(
Screen.AppLock(
onContinueWithoutAuthentication = {},
onShowOSBiometricsModal = {}
)
)
}
}

0 comments on commit ec3347c

Please sign in to comment.