From a29ab1175a507b90075f1c7d96343c4318dbf460 Mon Sep 17 00:00:00 2001 From: Devendra Varma Date: Sun, 1 Oct 2023 14:57:10 +0530 Subject: [PATCH] migrate onboarding feature from xml to compose --- .../core/widgets/PrimaryButton.kt | 52 ++++++++++++++ .../core/widgets/SecondaryButton.kt | 65 +++++++++++++++++ .../onboarding/OnboardingActivity.kt | 34 ++------- .../onboarding/OnboardingScreen.kt | 31 ++++++++ .../widgets/OnboardingGetStartedButton.kt | 27 +++++++ .../widgets/OnboardingScreenBackground.kt | 28 ++++++++ .../widgets/OnboardingScreenContent.kt | 51 ++++++++++++++ .../{ic_carot_icon.xml => ic_carrot_icon.xml} | 0 .../main/res/layout/activity_onboarding.xml | 70 ------------------- app/src/main/res/values/strings.xml | 2 + 10 files changed, 260 insertions(+), 100 deletions(-) create mode 100644 app/src/main/java/com/hieuwu/groceriesstore/presentation/core/widgets/PrimaryButton.kt create mode 100644 app/src/main/java/com/hieuwu/groceriesstore/presentation/core/widgets/SecondaryButton.kt create mode 100644 app/src/main/java/com/hieuwu/groceriesstore/presentation/onboarding/OnboardingScreen.kt create mode 100644 app/src/main/java/com/hieuwu/groceriesstore/presentation/onboarding/widgets/OnboardingGetStartedButton.kt create mode 100644 app/src/main/java/com/hieuwu/groceriesstore/presentation/onboarding/widgets/OnboardingScreenBackground.kt create mode 100644 app/src/main/java/com/hieuwu/groceriesstore/presentation/onboarding/widgets/OnboardingScreenContent.kt rename app/src/main/res/drawable/{ic_carot_icon.xml => ic_carrot_icon.xml} (100%) delete mode 100644 app/src/main/res/layout/activity_onboarding.xml diff --git a/app/src/main/java/com/hieuwu/groceriesstore/presentation/core/widgets/PrimaryButton.kt b/app/src/main/java/com/hieuwu/groceriesstore/presentation/core/widgets/PrimaryButton.kt new file mode 100644 index 00000000..51fa0e93 --- /dev/null +++ b/app/src/main/java/com/hieuwu/groceriesstore/presentation/core/widgets/PrimaryButton.kt @@ -0,0 +1,52 @@ +package com.hieuwu.groceriesstore.presentation.core.widgets + +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.defaultMinSize +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.colorResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.hieuwu.groceriesstore.R + +@Composable +fun PrimaryButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + content: @Composable RowScope.() -> Unit +) { + + Button( + modifier = modifier.defaultMinSize(minHeight = 48.dp), + enabled = enabled, + onClick = onClick, + shape = RoundedCornerShape(8.dp), + colors = ButtonDefaults.buttonColors( + containerColor = colorResource(id = R.color.colorPrimaryDark), + disabledContainerColor = colorResource(id = R.color.light_gray), + contentColor = Color.White, + ), + content = content + ) +} +@Preview +@Composable +private fun EnabledPrimaryButtonPreview() { + PrimaryButton(onClick = {}) { + Text(text = "Enabled") + } +} + +@Preview +@Composable +private fun DisabledPrimaryButtonPreview() { + PrimaryButton(onClick = {}, enabled = false) { + Text(text = "Disabled") + } +} \ No newline at end of file diff --git a/app/src/main/java/com/hieuwu/groceriesstore/presentation/core/widgets/SecondaryButton.kt b/app/src/main/java/com/hieuwu/groceriesstore/presentation/core/widgets/SecondaryButton.kt new file mode 100644 index 00000000..2cb516b8 --- /dev/null +++ b/app/src/main/java/com/hieuwu/groceriesstore/presentation/core/widgets/SecondaryButton.kt @@ -0,0 +1,65 @@ +package com.hieuwu.groceriesstore.presentation.core.widgets + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.defaultMinSize +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.colorResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.hieuwu.groceriesstore.R + +@Composable +fun SecondaryButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + content: @Composable RowScope.() -> Unit +) { + + OutlinedButton( + modifier = modifier.defaultMinSize(minHeight = 48.dp), + enabled = enabled, + onClick = onClick, + shape = RoundedCornerShape(8.dp), + colors = ButtonDefaults.outlinedButtonColors( + contentColor = colorResource(id = R.color.colorPrimary), + disabledContentColor = colorResource(id = R.color.colorPrimary).copy( + alpha = SecondaryButtonTokens.DisabledLabelTextOpacity + ), + ), + border = BorderStroke( + width = 1.dp, + color = colorResource(id = R.color.colorPrimary).copy( + alpha = if (!enabled) SecondaryButtonTokens.DisabledContainerOpacity else 1f + ) + ), + content = content + ) +} + +internal object SecondaryButtonTokens { + const val DisabledContainerOpacity = 0.12f + const val DisabledLabelTextOpacity = 0.38f +} + +@Preview +@Composable +private fun EnabledSecondaryButtonPreview() { + SecondaryButton(onClick = {}) { + Text(text = "Enabled") + } +} + +@Preview +@Composable +private fun DisabledSecondaryButtonPreview() { + SecondaryButton(onClick = {}, enabled = false) { + Text(text = "Disabled") + } +} \ No newline at end of file diff --git a/app/src/main/java/com/hieuwu/groceriesstore/presentation/onboarding/OnboardingActivity.kt b/app/src/main/java/com/hieuwu/groceriesstore/presentation/onboarding/OnboardingActivity.kt index 8483e2f2..554ac734 100644 --- a/app/src/main/java/com/hieuwu/groceriesstore/presentation/onboarding/OnboardingActivity.kt +++ b/app/src/main/java/com/hieuwu/groceriesstore/presentation/onboarding/OnboardingActivity.kt @@ -2,35 +2,25 @@ package com.hieuwu.groceriesstore.presentation.onboarding import android.content.Intent import android.os.Bundle -import androidx.activity.viewModels +import androidx.activity.compose.setContent import androidx.appcompat.app.AppCompatActivity -import androidx.databinding.DataBindingUtil -import androidx.lifecycle.flowWithLifecycle -import androidx.lifecycle.lifecycleScope import com.google.android.gms.tasks.OnCompleteListener import com.google.firebase.messaging.FirebaseMessaging import com.hieuwu.groceriesstore.MainActivity import com.hieuwu.groceriesstore.R -import com.hieuwu.groceriesstore.databinding.ActivityOnboardingBinding import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.launch import timber.log.Timber @AndroidEntryPoint class OnboardingActivity : AppCompatActivity() { - lateinit var binding: ActivityOnboardingBinding - - private val viewModel: OnboardingViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setTheme(R.style.AppTheme) - binding = DataBindingUtil.setContentView(this, R.layout.activity_onboarding) - binding.viewModel = viewModel - binding.lifecycleOwner = this - + setContent { + OnboardingScreen(navigateToMainInitialScreen = ::navigateToMainInitialScreen) + } setEvenListener() - setObserver() } private fun navigateToMainInitialScreen() { @@ -40,18 +30,6 @@ class OnboardingActivity : AppCompatActivity() { startActivity(intent) } - private fun setObserver() { - lifecycleScope.launch { - viewModel.isSyncedSuccessful - .flowWithLifecycle(lifecycle) - .collect { - if (it) { - binding.getStartedButton.isEnabled = true - } - } - } - } - private fun setEvenListener() { FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task -> if (!task.isSuccessful) { @@ -61,9 +39,5 @@ class OnboardingActivity : AppCompatActivity() { val token = task.result Timber.d(token) }) - - binding.getStartedButton.setOnClickListener { - navigateToMainInitialScreen() - } } } diff --git a/app/src/main/java/com/hieuwu/groceriesstore/presentation/onboarding/OnboardingScreen.kt b/app/src/main/java/com/hieuwu/groceriesstore/presentation/onboarding/OnboardingScreen.kt new file mode 100644 index 00000000..a1251193 --- /dev/null +++ b/app/src/main/java/com/hieuwu/groceriesstore/presentation/onboarding/OnboardingScreen.kt @@ -0,0 +1,31 @@ +package com.hieuwu.groceriesstore.presentation.onboarding + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Scaffold +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import com.hieuwu.groceriesstore.presentation.onboarding.widgets.OnboardingScreenBackground +import com.hieuwu.groceriesstore.presentation.onboarding.widgets.OnboardingScreenContent + +@Composable +fun OnboardingScreen( + modifier: Modifier = Modifier, + navigateToMainInitialScreen: () -> Unit +) { + Scaffold { paddingValues -> + Box( + modifier = modifier.padding(paddingValues) + ) { + OnboardingScreenBackground( + modifier = modifier.fillMaxSize(), + ) + OnboardingScreenContent( + modifier = Modifier.align(Alignment.BottomCenter), + navigateToMainInitialScreen, + ) + } + } +} diff --git a/app/src/main/java/com/hieuwu/groceriesstore/presentation/onboarding/widgets/OnboardingGetStartedButton.kt b/app/src/main/java/com/hieuwu/groceriesstore/presentation/onboarding/widgets/OnboardingGetStartedButton.kt new file mode 100644 index 00000000..5d74743b --- /dev/null +++ b/app/src/main/java/com/hieuwu/groceriesstore/presentation/onboarding/widgets/OnboardingGetStartedButton.kt @@ -0,0 +1,27 @@ +package com.hieuwu.groceriesstore.presentation.onboarding.widgets + +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.hilt.navigation.compose.hiltViewModel +import com.hieuwu.groceriesstore.R +import com.hieuwu.groceriesstore.presentation.core.widgets.PrimaryButton +import com.hieuwu.groceriesstore.presentation.onboarding.OnboardingViewModel + +@Composable +fun OnboardingGetStartedButton( + modifier: Modifier = Modifier, + viewModel: OnboardingViewModel = hiltViewModel(), + navigateToMainInitialScreen: () -> Unit +) { + val enabled = viewModel.isSyncedSuccessful.collectAsState() + PrimaryButton( + modifier = modifier, + onClick = navigateToMainInitialScreen, + enabled = enabled.value, + ) { + Text(text = stringResource(id = R.string.get_started)) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/hieuwu/groceriesstore/presentation/onboarding/widgets/OnboardingScreenBackground.kt b/app/src/main/java/com/hieuwu/groceriesstore/presentation/onboarding/widgets/OnboardingScreenBackground.kt new file mode 100644 index 00000000..cc0839a7 --- /dev/null +++ b/app/src/main/java/com/hieuwu/groceriesstore/presentation/onboarding/widgets/OnboardingScreenBackground.kt @@ -0,0 +1,28 @@ +package com.hieuwu.groceriesstore.presentation.onboarding.widgets + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import com.hieuwu.groceriesstore.R + +@Composable +fun OnboardingScreenBackground(modifier: Modifier = Modifier) { + Image( + modifier = modifier, + painter = painterResource(id = R.drawable.onboarding_background), + contentScale = ContentScale.FillBounds, + contentDescription = null + ) +} + +@Preview(showBackground = true) +@Composable +fun OnboardingScreenBackgroundPreview() { + OnboardingScreenBackground( + modifier = Modifier.fillMaxSize() + ) +} diff --git a/app/src/main/java/com/hieuwu/groceriesstore/presentation/onboarding/widgets/OnboardingScreenContent.kt b/app/src/main/java/com/hieuwu/groceriesstore/presentation/onboarding/widgets/OnboardingScreenContent.kt new file mode 100644 index 00000000..18c25743 --- /dev/null +++ b/app/src/main/java/com/hieuwu/groceriesstore/presentation/onboarding/widgets/OnboardingScreenContent.kt @@ -0,0 +1,51 @@ +package com.hieuwu.groceriesstore.presentation.onboarding.widgets + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.hieuwu.groceriesstore.R + +@Composable +fun OnboardingScreenContent( + modifier: Modifier = Modifier, + navigateToMainInitialScreen: () -> Unit +) { + Column( + modifier = modifier.padding(start = 16.dp, end = 16.dp, bottom = 120.dp), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Image( + modifier = Modifier.size(64.dp), + painter = painterResource(id = R.drawable.ic_carrot_icon), + contentDescription = null, + ) + Text( + text = stringResource(R.string.welcome_to_our_store), + fontSize = 22.sp, + fontWeight = FontWeight.Bold, + color = Color.White, + ) + Text( + text = stringResource(R.string.get_your_gorceries_in_as_fast_as_one_hour), + color = Color.White, + ) + OnboardingGetStartedButton( + modifier = Modifier.fillMaxWidth(), + navigateToMainInitialScreen = navigateToMainInitialScreen + ) + } +} diff --git a/app/src/main/res/drawable/ic_carot_icon.xml b/app/src/main/res/drawable/ic_carrot_icon.xml similarity index 100% rename from app/src/main/res/drawable/ic_carot_icon.xml rename to app/src/main/res/drawable/ic_carrot_icon.xml diff --git a/app/src/main/res/layout/activity_onboarding.xml b/app/src/main/res/layout/activity_onboarding.xml deleted file mode 100644 index b474f577..00000000 --- a/app/src/main/res/layout/activity_onboarding.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - -