Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,17 @@ import com.nativeapptemplate.nativeapptemplatefree.ui.app_root.navigation.resend
import com.nativeapptemplate.nativeapptemplatefree.ui.app_root.navigation.signInEmailAndPasswordView
import com.nativeapptemplate.nativeapptemplatefree.ui.app_root.navigation.signUpOrSignInView
import com.nativeapptemplate.nativeapptemplatefree.ui.app_root.navigation.signUpView
import com.nativeapptemplate.nativeapptemplatefree.ui.settings.navigation.settingBaseView
import com.nativeapptemplate.nativeapptemplatefree.ui.shop_detail.navigation.navigateToShopDetail
import com.nativeapptemplate.nativeapptemplatefree.ui.shop_detail.navigation.shopDetailView
import com.nativeapptemplate.nativeapptemplatefree.ui.shop_settings.navigation.navigateToShopBasicSettings
import com.nativeapptemplate.nativeapptemplatefree.ui.shop_settings.navigation.navigateToShopSettings
import com.nativeapptemplate.nativeapptemplatefree.ui.shop_settings.navigation.shopBasicSettingsView
import com.nativeapptemplate.nativeapptemplatefree.ui.shop_settings.navigation.shopSettingsView
import com.nativeapptemplate.nativeapptemplatefree.ui.shops.navigation.ShopsRoute
import com.nativeapptemplate.nativeapptemplatefree.ui.shops.navigation.ShopBaseRoute
import com.nativeapptemplate.nativeapptemplatefree.ui.shops.navigation.navigateToShopCreate
import com.nativeapptemplate.nativeapptemplatefree.ui.shops.navigation.navigateToShopList
import com.nativeapptemplate.nativeapptemplatefree.ui.shops.navigation.shopBaseView
import com.nativeapptemplate.nativeapptemplatefree.ui.shops.navigation.shopCreateView
import com.nativeapptemplate.nativeapptemplatefree.ui.shops.navigation.shopListView

Expand Down Expand Up @@ -85,7 +87,7 @@ fun NatNavHost(

NavHost(
navController = navController,
startDestination = ShopsRoute,
startDestination = ShopBaseRoute,
modifier = modifier,
) {
onboardingView(
Expand Down Expand Up @@ -123,42 +125,46 @@ fun NatNavHost(
onShowSnackbar = onShowSnackbar,
)

shopListView(
onItemClick = { shopId -> navController.navigateToShopDetail(shopId) },
onAddShopClick = { navController.navigateToShopCreate() },
onShowSnackbar = onShowSnackbar,
)
shopCreateView(
onShowSnackbar = onShowSnackbar,
onBackClick = navController::popBackStack,
)
shopDetailView(
onSettingsClick = { shopId -> navController.navigateToShopSettings(shopId) },
onShowSnackbar = onShowSnackbar,
onBackClick = navController::popBackStack,
)
shopSettingsView(
onShowBasicSettingsClick = { shopId -> navController.navigateToShopBasicSettings(shopId) },
onShowSnackbar = onShowSnackbar,
onBackClick = navController::popBackStack,
)
shopBasicSettingsView(
onShowSnackbar = onShowSnackbar,
onBackClick = navController::popBackStack,
)
shopBaseView {
shopListView(
onItemClick = { shopId -> navController.navigateToShopDetail(shopId) },
onAddShopClick = { navController.navigateToShopCreate() },
onShowSnackbar = onShowSnackbar,
)
shopCreateView(
onShowSnackbar = onShowSnackbar,
onBackClick = navController::popBackStack,
)
shopDetailView(
onSettingsClick = { shopId -> navController.navigateToShopSettings(shopId) },
onShowSnackbar = onShowSnackbar,
onBackClick = navController::popBackStack,
)
shopSettingsView(
onShowBasicSettingsClick = { shopId -> navController.navigateToShopBasicSettings(shopId) },
onShowSnackbar = onShowSnackbar,
onBackClick = navController::popBackStack,
)
shopBasicSettingsView(
onShowSnackbar = onShowSnackbar,
onBackClick = navController::popBackStack,
)
}

settingsView(
onShowShopkeeperEditClick = { navController.navigateToShopkeeperEdit() },
onShowPasswordEditClick = { navController.navigateToPasswordEdit() },
onShowSnackbar = onShowSnackbar,
)
shopkeeperEditView(
onShowSnackbar = onShowSnackbar,
onBackClick =navController::popBackStack,
)
passwordEditView(
onShowSnackbar = onShowSnackbar,
onBackClick =navController::popBackStack,
)
settingBaseView {
settingsView(
onShowShopkeeperEditClick = { navController.navigateToShopkeeperEdit() },
onShowPasswordEditClick = { navController.navigateToPasswordEdit() },
onShowSnackbar = onShowSnackbar,
)
shopkeeperEditView(
onShowSnackbar = onShowSnackbar,
onBackClick =navController::popBackStack,
)
passwordEditView(
onShowSnackbar = onShowSnackbar,
onBackClick =navController::popBackStack,
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,49 +1,42 @@
/*
* Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.nativeapptemplate.nativeapptemplatefree.navigation

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.People
import androidx.compose.material.icons.outlined.Settings
import androidx.compose.material.icons.outlined.Storefront
import androidx.compose.material.icons.rounded.People
import androidx.compose.material.icons.rounded.Settings
import androidx.compose.material.icons.rounded.Storefront
import androidx.compose.ui.graphics.vector.ImageVector
import com.nativeapptemplate.nativeapptemplatefree.R
import com.nativeapptemplate.nativeapptemplatefree.ui.settings.navigation.SettingBaseRoute
import com.nativeapptemplate.nativeapptemplatefree.ui.settings.navigation.SettingsRoute
import com.nativeapptemplate.nativeapptemplatefree.ui.shops.navigation.ShopBaseRoute
import com.nativeapptemplate.nativeapptemplatefree.ui.shops.navigation.ShopsRoute
import kotlin.reflect.KClass

/**
* Type for the top level destinations in the application. Each of these destinations
* can contain one or more screens (based on the window size). Navigation from one screen to the
* next within a single destination will be handled directly in composables.
*/
enum class TopLevelDestination(
val selectedIcon: ImageVector,
val unselectedIcon: ImageVector,
val iconTextId: Int,
val selectedIcon: ImageVector,
val unselectedIcon: ImageVector,
val iconTextId: Int,
val route: KClass<*>,
val baseRoute: KClass<*> = route,
) {
SHOPS_TAB(
selectedIcon = Icons.Rounded.Storefront,
unselectedIcon = Icons.Outlined.Storefront,
iconTextId = R.string.title_shops,
route = ShopsRoute::class,
baseRoute = ShopBaseRoute::class,
),
SETTINGS_TAB(
selectedIcon = Icons.Rounded.Settings,
unselectedIcon = Icons.Outlined.Settings,
iconTextId = R.string.title_settings,
route = SettingsRoute::class,
baseRoute = SettingBaseRoute::class,
),
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@ import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTagsAsResourceId
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavDestination
import androidx.navigation.NavDestination.Companion.hasRoute
import androidx.navigation.NavDestination.Companion.hierarchy
import com.nativeapptemplate.nativeapptemplatefree.R
import com.nativeapptemplate.nativeapptemplatefree.designsystem.component.NatBackground
import com.nativeapptemplate.nativeapptemplatefree.designsystem.component.NatNavigationBar
import com.nativeapptemplate.nativeapptemplatefree.designsystem.component.NatNavigationBarItem
import com.nativeapptemplate.nativeapptemplatefree.navigation.NatNavHost
import com.nativeapptemplate.nativeapptemplatefree.navigation.TopLevelDestination
import kotlin.reflect.KClass

@OptIn(
ExperimentalComposeUiApi::class,
Expand Down Expand Up @@ -162,7 +164,8 @@ private fun NatBottomBar(
modifier = modifier,
) {
destinations.forEach { destination ->
val selected = currentDestination.isTopLevelDestinationInHierarchy(destination)
val selected = currentDestination.isRouteInHierarchy(destination.baseRoute)

NatNavigationBarItem(
selected = selected,
onClick = { onNavigateToDestination(destination) },
Expand All @@ -184,7 +187,7 @@ private fun NatBottomBar(
}
}

private fun NavDestination?.isTopLevelDestinationInHierarchy(destination: TopLevelDestination) =
private fun NavDestination?.isRouteInHierarchy(route: KClass<*>) =
this?.hierarchy?.any {
it.route?.contains(destination.name, true) ?: false
} ?: false
it.hasRoute(route)
} ?: false
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,25 @@ import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavOptions
import androidx.navigation.compose.composable
import androidx.navigation.compose.navigation
import com.nativeapptemplate.nativeapptemplatefree.ui.settings.PasswordEditView
import com.nativeapptemplate.nativeapptemplatefree.ui.settings.SettingsView
import com.nativeapptemplate.nativeapptemplatefree.ui.settings.ShopkeeperEditView
import kotlinx.serialization.Serializable

@Serializable data object SettingBaseRoute
@Serializable data object SettingsRoute
@Serializable data object ShopkeeperEditRoute
@Serializable data object PasswordEditRoute

fun NavGraphBuilder.settingBaseView(
destination: NavGraphBuilder.() -> Unit,
) {
navigation<SettingBaseRoute>(startDestination = SettingsRoute) {
destination()
}
}

fun NavController.navigateToSettings(navOptions: NavOptions) = navigate(route = SettingsRoute, navOptions)

fun NavGraphBuilder.settingsView(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,23 @@ import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavOptions
import androidx.navigation.compose.composable
import androidx.navigation.compose.navigation
import com.nativeapptemplate.nativeapptemplatefree.ui.shops.ShopCreateView
import com.nativeapptemplate.nativeapptemplatefree.ui.shops.ShopListView
import kotlinx.serialization.Serializable

@Serializable data object ShopBaseRoute
@Serializable data object ShopsRoute
@Serializable data object ShopCreateRoute

fun NavGraphBuilder.shopBaseView(
destination: NavGraphBuilder.() -> Unit,
) {
navigation<ShopBaseRoute>(startDestination = ShopsRoute) {
destination()
}
}

fun NavController.navigateToShopList(navOptions: NavOptions? = null) = navigate(route = ShopsRoute, navOptions)

fun NavGraphBuilder.shopListView(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ private const val LOGGED_IN_SHOPKEEPER_ACCOUNT_NAME = "Account1"
private const val LOGGED_IN_SHOPKEEPER_EMAIL = "[email protected]"
private const val LOGGED_IN_SHOPKEEPER_NAME = "John Smith"
private const val LOGGED_IN_SHOPKEEPER_TIME_ZONE = "Tokyo"
private const val LOGGED_IN_SHOPKEEPER_TOKEN = "[email protected]"
private const val LOGGED_IN_SHOPKEEPER_TOKEN = "RVpFr8xbeiWRnj8cu7AeOP"
private const val LOGGED_IN_SHOPKEEPER_CLIENT = "Vd6GFW-9DaZrU2pzFd-Asa"
private const val LOGGED_IN_SHOPKEEPER_UID = "[email protected]"
private const val LOGGED_IN_SHOPKEEPER_EXPIRY = "1713165114"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ private const val LOGGED_IN_SHOPKEEPER_ACCOUNT_NAME = "Account1"
private const val LOGGED_IN_SHOPKEEPER_EMAIL = "[email protected]"
private const val LOGGED_IN_SHOPKEEPER_NAME = "John Smith"
private const val LOGGED_IN_SHOPKEEPER_TIME_ZONE = "Tokyo"
private const val LOGGED_IN_SHOPKEEPER_TOKEN = "[email protected]"
private const val LOGGED_IN_SHOPKEEPER_TOKEN = "RVpFr8xbeiWRnj8cu7AeOP"
private const val LOGGED_IN_SHOPKEEPER_CLIENT = "Vd6GFW-9DaZrU2pzFd-Asa"
private const val LOGGED_IN_SHOPKEEPER_UID = "[email protected]"
private const val LOGGED_IN_SHOPKEEPER_EXPIRY = "1713165114"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ private const val LOGGED_IN_SHOPKEEPER_ACCOUNT_NAME = "Account1"
private const val LOGGED_IN_SHOPKEEPER_EMAIL = "[email protected]"
private const val LOGGED_IN_SHOPKEEPER_NAME = "John Smith"
private const val LOGGED_IN_SHOPKEEPER_TIME_ZONE = "Tokyo"
private const val LOGGED_IN_SHOPKEEPER_TOKEN = "[email protected]"
private const val LOGGED_IN_SHOPKEEPER_TOKEN = "RVpFr8xbeiWRnj8cu7AeOP"
private const val LOGGED_IN_SHOPKEEPER_CLIENT = "Vd6GFW-9DaZrU2pzFd-Asa"
private const val LOGGED_IN_SHOPKEEPER_UID = "[email protected]"
private const val LOGGED_IN_SHOPKEEPER_EXPIRY = "1713165114"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ private const val LOGGED_IN_SHOPKEEPER_ACCOUNT_NAME = "Account1"
private const val LOGGED_IN_SHOPKEEPER_EMAIL = "[email protected]"
private const val LOGGED_IN_SHOPKEEPER_NAME = "John Smith"
private const val LOGGED_IN_SHOPKEEPER_TIME_ZONE = "Tokyo"
private const val LOGGED_IN_SHOPKEEPER_TOKEN = "[email protected]"
private const val LOGGED_IN_SHOPKEEPER_TOKEN = "RVpFr8xbeiWRnj8cu7AeOP"
private const val LOGGED_IN_SHOPKEEPER_CLIENT = "Vd6GFW-9DaZrU2pzFd-Asa"
private const val LOGGED_IN_SHOPKEEPER_UID = "[email protected]"
private const val LOGGED_IN_SHOPKEEPER_EXPIRY = "1713165114"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,20 @@ class ShopBasicSettingsViewModelTest {
fun stateIsUpdated_whenUpdatingShop_becomesTrue() = runTest {
backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.uiState.collect() }

viewModel.updateName(testInputShop.getName())
viewModel.updateDescription(testInputShop.getDescription())
viewModel.updateTimeZone(testInputShop.getTimeZone())
shopRepository.sendShop(testInputShop)

viewModel.reload()

viewModel.updateName(testInputNewName)
viewModel.updateDescription(testInputNewDescription)
viewModel.updateTimeZone(testInputNewTimeZone)

val uiStateValue = viewModel.uiState.value
assertEquals(uiStateValue.name, testInputShop.getName())
assertEquals(uiStateValue.description, testInputShop.getDescription())
assertEquals(uiStateValue.timeZone, testInputShop.getTimeZone())
assertEquals(uiStateValue.name, testInputNewName)
assertEquals(uiStateValue.description, testInputNewDescription)
assertEquals(uiStateValue.timeZone, testInputNewTimeZone)
assertFalse(viewModel.hasInvalidData())

shopRepository.sendShop(testInputShop)
viewModel.updateShop()

assertTrue(viewModel.uiState.value.isUpdated)
Expand Down Expand Up @@ -133,3 +137,6 @@ private val testInputShopsData =
private val testInputShop = Shop(
datum = testInputShopsData,
)
private const val testInputNewName = "Olivia Clark"
private const val testInputNewDescription = "[email protected]"
private const val testInputNewTimeZone = "Hawaii"