Skip to content

Commit

Permalink
migrate account feature from xml to compose
Browse files Browse the repository at this point in the history
  • Loading branch information
Devendra34 authored and Devendra Varma committed Oct 1, 2023
1 parent d539e86 commit d09102a
Show file tree
Hide file tree
Showing 11 changed files with 390 additions and 248 deletions.
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ dependencies {
implementation libs.glide
annotationProcessor libs.glide.compiler
implementation libs.lottie
implementation libs.lottie.compose

implementation libs.bundles.retrofit
implementation libs.gson
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,30 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.navigation.fragment.findNavController
import com.hieuwu.groceriesstore.R
import com.hieuwu.groceriesstore.databinding.FragmentAccountBinding
import com.hieuwu.groceriesstore.presentation.AuthActivity
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch

@AndroidEntryPoint
class AccountFragment : Fragment() {

private lateinit var binding: FragmentAccountBinding
private val viewModel: AccountViewModel by viewModels()

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate<FragmentAccountBinding>(
inflater, R.layout.fragment_account, container, false
)

binding.viewModel = viewModel
binding.lifecycleOwner = this
setObserver()
setEventListener()

return binding.root
}

private fun setObserver() {
viewLifecycleOwner.lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
launch {
viewModel.user.collect {}
}
): View {

return ComposeView(requireContext()).apply {
setContent {
AccountScreen(
onSignInClick = ::navigateToAuthentication,
onProfileSettingsClick = ::navigateToProfileSettings,
onNotificationSettingsClick = ::navigateToNotificationsSettings,
onOrderHistorySettingsClick = ::navigateToOrderHistory,
)
}
}
}
Expand All @@ -56,27 +38,15 @@ class AccountFragment : Fragment() {
startActivity(intent)
}

private fun setEventListener() {
with(binding) {
profileLayout.setOnClickListener {
findNavController().navigate(R.id.action_accountFragment_to_updateProfileFragment)
}

notificationSettingLayout.setOnClickListener {
findNavController().navigate(R.id.action_accountFragment_to_notificationSettingsFragment)
}

orderHistoryLayout.setOnClickListener {
findNavController().navigate(R.id.action_accountFragment_to_orderHistoryFragment)
}
private fun navigateToProfileSettings() {
findNavController().navigate(R.id.action_accountFragment_to_updateProfileFragment)
}

signoutButton.setOnClickListener {
viewModel?.signOut()
}
private fun navigateToNotificationsSettings() {
findNavController().navigate(R.id.action_accountFragment_to_notificationSettingsFragment)
}

signinButton.setOnClickListener {
navigateToAuthentication()
}
}
private fun navigateToOrderHistory() {
findNavController().navigate(R.id.action_accountFragment_to_orderHistoryFragment)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package com.hieuwu.groceriesstore.presentation.account

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel
import com.hieuwu.groceriesstore.R
import com.hieuwu.groceriesstore.domain.models.UserModel
import com.hieuwu.groceriesstore.presentation.account.widgets.AccountContentView
import com.hieuwu.groceriesstore.presentation.account.widgets.AccountHeaderView

@Composable
fun AccountScreen(
modifier: Modifier = Modifier,
viewModel: AccountViewModel = hiltViewModel(),
onSignInClick: (() -> Unit),
onProfileSettingsClick: (() -> Unit),
onNotificationSettingsClick: (() -> Unit),
onOrderHistorySettingsClick: (() -> Unit),
) {
val user = viewModel.user.collectAsState()

AccountScreenView(
modifier = modifier,
user = user.value,
onSignInClick = onSignInClick,
onProfileSettingsClick = onProfileSettingsClick,
onNotificationSettingsClick = onNotificationSettingsClick,
onOrderHistorySettingsClick = onOrderHistorySettingsClick,
onSignOutClick = { viewModel.signOut() },
)
}

@Composable
private fun AccountScreenView(
modifier: Modifier = Modifier,
user: UserModel? = null,
onSignInClick: () -> Unit,
onProfileSettingsClick: () -> Unit,
onNotificationSettingsClick: () -> Unit,
onOrderHistorySettingsClick: () -> Unit,
onSignOutClick: () -> Unit,
) {
Scaffold { contentPadding ->
Column(
modifier = modifier.padding(contentPadding),
verticalArrangement = Arrangement.Top
) {

AccountHeaderView(user = user)
AccountContentView(
modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.margin_medium)),
user = user,
onSignInClick = onSignInClick,
onProfileSettingsClick = onProfileSettingsClick,
onNotificationSettingsClick = onNotificationSettingsClick,
onOrderHistorySettingsClick = onOrderHistorySettingsClick,
onSignOutClick = onSignOutClick,
)
}
}
}

internal val DemoUser = UserModel(
"0", "J.K. Rowling", "[email protected]",
phone = "+1234567890",
address = "Earth",
isOrderCreatedNotiEnabled = false,
isPromotionNotiEnabled = false,
isDataRefreshedNotiEnabled = false
)

@Preview(showSystemUi = true)
@Composable
private fun SignedInAccountScreen() {
AccountScreenView(
user = DemoUser,
onSignInClick = { /*TODO*/ },
onProfileSettingsClick = { /*TODO*/ },
onNotificationSettingsClick = { /*TODO*/ },
onOrderHistorySettingsClick = { /*TODO*/ },
onSignOutClick = { /*TODO*/ },
)
}

@Preview(showSystemUi = true)
@Composable
private fun SignedOutAccountScreen() {
AccountScreenView(
onSignInClick = { /*TODO*/ },
onProfileSettingsClick = { /*TODO*/ },
onNotificationSettingsClick = { /*TODO*/ },
onOrderHistorySettingsClick = { /*TODO*/ },
onSignOutClick = { /*TODO*/ },
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package com.hieuwu.groceriesstore.presentation.account.widgets

import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
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.dimensionResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import com.hieuwu.groceriesstore.R
import com.hieuwu.groceriesstore.domain.models.UserModel
import com.hieuwu.groceriesstore.presentation.account.DemoUser
import com.hieuwu.groceriesstore.presentation.core.widgets.PrimaryButton
import com.hieuwu.groceriesstore.presentation.core.widgets.SecondaryButton

@Composable
fun AccountContentView(
modifier: Modifier = Modifier,
user: UserModel? = null,
onSignInClick: () -> Unit,
onProfileSettingsClick: () -> Unit,
onNotificationSettingsClick: () -> Unit,
onOrderHistorySettingsClick: () -> Unit,
onSignOutClick: () -> Unit,
) {
if (user != null) {
AccountContentSignedInView(
modifier = modifier,
onProfileSettingsClick = onProfileSettingsClick,
onNotificationSettingsClick = onNotificationSettingsClick,
onOrderHistorySettingsClick = onOrderHistorySettingsClick,
onSignOutClick = onSignOutClick,
)
} else {
AccountContentSignedOutView(
modifier = modifier.padding(vertical = dimensionResource(id = R.dimen.margin_medium)),
onSignInClick = onSignInClick
)
}
}

@Composable
fun AccountContentSignedInView(
modifier: Modifier = Modifier,
onProfileSettingsClick: (() -> Unit),
onNotificationSettingsClick: (() -> Unit),
onOrderHistorySettingsClick: (() -> Unit),
onSignOutClick: (() -> Unit),
) {
val actions = listOf(
R.string.profile_information to onProfileSettingsClick,
R.string.notification_settings to onNotificationSettingsClick,
R.string.order_history_settings to onOrderHistorySettingsClick,
)
for (action in actions) {
Row(
modifier = modifier
.fillMaxWidth()
.padding(top = dimensionResource(id = R.dimen.margin_small)),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = stringResource(id = action.first),
fontWeight = FontWeight.Bold,
color = Color(0xFF808080),
maxLines = 1
)
Image(
modifier = Modifier.size(dimensionResource(id = R.dimen.icon_small)),
painter = painterResource(id = R.drawable.ic_baseline_chevron_right_24),
contentDescription = null,
)
}
}

SecondaryButton(
modifier = modifier
.fillMaxWidth()
.padding(vertical = dimensionResource(id = R.dimen.margin_medium)),
onClick = onSignOutClick
) {
Text(text = stringResource(id = R.string.sign_out))
}
}

@Composable
fun AccountContentSignedOutView(
modifier: Modifier = Modifier,
onSignInClick: (() -> Unit),
) {
PrimaryButton(
modifier = modifier.fillMaxWidth(),
onClick = onSignInClick
) {
Text(text = stringResource(id = R.string.sign_in))
}
}

@Preview(showBackground = true)
@Composable
private fun AccountContentViewSignedInStatePreview() {
Column {
AccountContentView(
modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.margin_medium)),
user = DemoUser,
onSignInClick = {},
onProfileSettingsClick = {},
onNotificationSettingsClick = {},
onOrderHistorySettingsClick = {},
) {}
}
}

@Preview
@Composable
private fun AccountContentViewSignedOutStatePreview() {
Column {
AccountContentView(
modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.margin_medium)),
onSignInClick = {},
onProfileSettingsClick = {},
onNotificationSettingsClick = {},
onOrderHistorySettingsClick = {},
) {}
}
}
Loading

0 comments on commit d09102a

Please sign in to comment.