Skip to content

[Woo Pos] Compose navigation template #11512

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2 changes: 2 additions & 0 deletions WooCommerce/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,9 @@ dependencies {
implementation 'androidx.compose.runtime:runtime-livedata'
implementation "androidx.compose.material:material-icons-extended"
implementation 'androidx.compose.ui:ui-text-google-fonts'
implementation 'androidx.navigation:navigation-compose'

implementation 'androidx.hilt:hilt-navigation-compose:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout-compose:1.0.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2'
implementation "com.google.accompanist:accompanist-swiperefresh:$composeAccompanistVersion"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.woocommerce.android.ui.woopos.cart

import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable

internal const val CART_ROUTE = "cart"

internal fun NavGraphBuilder.cartScreen(
onCheckoutClick: () -> Unit
) {
composable(CART_ROUTE) {
val viewModel: WooPosCartViewModel = hiltViewModel()

WooPosCartScreen(
viewModel = viewModel,
onCheckoutClick = onCheckoutClick
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.woocommerce.android.ui.woopos.cart

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import com.woocommerce.android.ui.woopos.util.WooPosPreview

@Composable
@Suppress("UNUSED_PARAMETER")
fun WooPosCartScreen(
viewModel: WooPosCartViewModel,
onCheckoutClick: () -> Unit,
) {
WooPosCartScreen(
onButtonClicked = onCheckoutClick
)
}

@Composable
private fun WooPosCartScreen(onButtonClicked: () -> Unit) {
Box(
Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Column {
Text(
text = "Cart",
style = MaterialTheme.typography.h3,
color = MaterialTheme.colors.primary,
)
Button(onClick = onButtonClicked) {
Text("Checkout")
}
}
}
}

@Composable
@WooPosPreview
fun WooPosCartScreenPreview() {
WooPosCartScreen(onButtonClicked = {})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.woocommerce.android.ui.woopos.cart

import androidx.lifecycle.SavedStateHandle
import com.woocommerce.android.viewmodel.ScopedViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject

@HiltViewModel
class WooPosCartViewModel @Inject constructor(
savedStateHandle: SavedStateHandle,
) : ScopedViewModel(savedStateHandle)
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.woocommerce.android.ui.woopos.checkout

import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable

private const val CHECKOUT_ROUTE = "checkout"

fun NavController.navigateToCheckoutScreen() {
navigate(CHECKOUT_ROUTE)
}

fun NavGraphBuilder.checkoutScreen(
onBackClick: () -> Unit
) {
composable(CHECKOUT_ROUTE) {
val viewModel: WooPosCheckoutViewModel = hiltViewModel()

WooPosCheckoutScreen(
viewModel = viewModel,
onBackClick = onBackClick
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.woocommerce.android.ui.woopos.checkout

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import com.woocommerce.android.ui.woopos.util.WooPosPreview

@Composable
@Suppress("UNUSED_PARAMETER")
fun WooPosCheckoutScreen(viewModel: WooPosCheckoutViewModel, onBackClick: () -> Unit) {
WooPosCheckoutScreen(
onBackClick = onBackClick
)
}

@Composable
private fun WooPosCheckoutScreen(onBackClick: () -> Unit) {
Box(
Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Column {
Text(
text = "Checkout",
style = MaterialTheme.typography.h3,
color = MaterialTheme.colors.primary,
)
Button(onClick = onBackClick) {
Text("To Cart")
}
}
}
}

@Composable
@WooPosPreview
fun WooPosCheckoutScreenPreview() {
WooPosCheckoutScreen(onBackClick = {})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.woocommerce.android.ui.woopos.checkout

import androidx.lifecycle.SavedStateHandle
import com.woocommerce.android.viewmodel.ScopedViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject

@HiltViewModel
class WooPosCheckoutViewModel @Inject constructor(
savedStateHandle: SavedStateHandle,
) : ScopedViewModel(savedStateHandle)
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,17 @@ package com.woocommerce.android.ui.woopos.root
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import com.woocommerce.android.ui.woopos.root.navigation.WooPosRootHost
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class WooPosActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Box(
Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Text(
text = "Woo POS!",
style = MaterialTheme.typography.h3,
color = MaterialTheme.colors.primary,
)
MaterialTheme {
WooPosRootHost()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.woocommerce.android.ui.woopos.root.navigation

import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.navigation
import com.woocommerce.android.ui.woopos.cart.CART_ROUTE
import com.woocommerce.android.ui.woopos.cart.cartScreen
import com.woocommerce.android.ui.woopos.checkout.checkoutScreen
import com.woocommerce.android.ui.woopos.checkout.navigateToCheckoutScreen

const val MAIN_GRAPH_ROUTE = "main-graph"

fun NavGraphBuilder.checkoutGraph(
navController: NavController
) {
navigation(
startDestination = CART_ROUTE,
route = MAIN_GRAPH_ROUTE,
) {
cartScreen(
onCheckoutClick = navController::navigateToCheckoutScreen
)
checkoutScreen(
onBackClick = navController::popBackStack
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.woocommerce.android.ui.woopos.root.navigation

import androidx.compose.animation.AnimatedContentTransitionScope
import androidx.compose.animation.EnterTransition
import androidx.compose.animation.ExitTransition
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.navigation.NavBackStackEntry

fun AnimatedContentTransitionScope<NavBackStackEntry>.screenSlideIn(): EnterTransition =
slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Start)

fun screenFadeOut(): ExitTransition = fadeOut()

fun screenFadeIn(): EnterTransition = fadeIn()

fun AnimatedContentTransitionScope<NavBackStackEntry>.screenSlideOut(): ExitTransition =
slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.End)
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.woocommerce.android.ui.woopos.root.navigation

import androidx.compose.runtime.Composable
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.rememberNavController

@Composable
fun WooPosRootHost() {
val rootController = rememberNavController()

NavHost(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to keep in mind that now even if it's just 1 screen, we still need to separate parts of the screen in easily reusable components (so probably products and cart will have their own VM, screen etc) so if potential phone support will come we can use another NavHost here and reuse the same screens

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. Good point. Also kind of makes those classes simpler since they will be focused on doing one thing.

navController = rootController,
startDestination = MAIN_GRAPH_ROUTE,
enterTransition = { screenSlideIn() },
exitTransition = { screenFadeOut() },
popEnterTransition = { screenFadeIn() },
popExitTransition = { screenSlideOut() },
) {
checkoutGraph(
navController = rootController,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@file:Suppress("MatchingDeclarationName", "Filename")

package com.woocommerce.android.ui.woopos.util

import android.content.res.Configuration
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview

@Retention(AnnotationRetention.BINARY)
@Target(
AnnotationTarget.ANNOTATION_CLASS,
AnnotationTarget.FUNCTION
)
@Preview(
name = "Tablet Big",
device = Devices.TABLET,
showSystemUi = true,
uiMode = Configuration.UI_MODE_NIGHT_YES or Configuration.UI_MODE_TYPE_NORMAL
)
@Preview(
name = "Tablet Small",
showSystemUi = true,
device = "spec:width=440dp,height=920dp,dpi=420,isRound=false,chinSize=0dp,orientation=landscape",
uiMode = Configuration.UI_MODE_TYPE_NORMAL
)
annotation class WooPosPreview
Loading