Skip to content
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

[#18] 카페 상세 페이지 추가 #20

Merged
merged 13 commits into from
Jan 16, 2024
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
<p align="center">
카자잇 안드로이드
</p>

![project.dot.png](images%2Fproject.dot.png)
6 changes: 6 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,15 @@ dependencies {
implementation(projects.feature.map)
implementation(projects.feature.signin)
implementation(projects.feature.splash)
implementation(projects.feature.mainNavGraph)

implementation(projects.feature.cafedetail.api)
implementation(projects.feature.cafedetail.impl)

implementation(projects.core.repo.signin.impl)
implementation(projects.core.repo.home.api)
implementation(projects.core.repo.home.impl)
implementation(projects.core.repo.cafedetail.impl)

implementation(projects.core.http)

Expand Down
52 changes: 47 additions & 5 deletions app/src/main/kotlin/org/cazait/cazaitandroid/MainNavigator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,30 @@ import androidx.navigation.NavHostController
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navOptions
import org.cazait.cazaitandroid.feature.cafedetail.api.CafeDetailNavController
import org.cazait.cazaitandroid.feature.cafedetail.api.CafeDetailNavControllerInfo
import org.cazait.cazaitandroid.feature.cafedetail.api.ReviewEditorNavController
import org.cazait.cazaitandroid.feature.cafedetail.api.ReviewEditorNavControllerInfo
import org.cazait.cazaitandroid.feature.home.HomeNav
import org.cazait.cazaitandroid.feature.home.navigateHome
import org.cazait.cazaitandroid.feature.map.navigateMap
import org.cazait.cazaitandroid.feature.mypage.navigateMyPage
import org.cazait.cazaitandroid.feature.signin.navigateSignIn
import org.cazait.cazaitandroid.feature.splash.SplashNav
import org.cazait.cazaitandroid.feature.viewmore.navigateViewMore
import javax.inject.Inject

internal class MainNavigator(
val navController: NavHostController,
private val cafeDetailNavController: CafeDetailNavController,
private val reviewEditorNavController: ReviewEditorNavController,
) {
private val currentDestination: NavDestination?
@Composable get() = navController
.currentBackStackEntryAsState().value?.destination

val startDestination = SplashNav.route
var startDestination = SplashNav.route
private set

val currentTab: MainTab?
@Composable get() = currentDestination
Expand All @@ -46,30 +55,63 @@ internal class MainNavigator(
}
}

fun popBackStack() {
navController.popBackStack()
}

fun navigateSignIn() {
navController.navigateSignIn()
}

fun navigateCafeDetail(cafeId: String) {
cafeDetailNavController.navigate(
navController = navController,
navInfo = CafeDetailNavControllerInfo(cafeId),
)
}

fun navigateReviewEditor(cafeId: String) {
reviewEditorNavController.navigate(
navController = navController,
navInfo = ReviewEditorNavControllerInfo(cafeId)
)
}

fun navigateHome() {
startDestination = HomeNav.route
navController.navigateHome(navOptions {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
popUpTo(HomeNav.route) {
inclusive = true
}
launchSingleTop = true
restoreState = true
})
}


@Composable
fun shouldShowBottomBar(): Boolean {
val currentRoute = currentDestination?.route ?: return false
return currentRoute in MainTab
}

class Factory @Inject constructor(
private val cafeDetailNavController: CafeDetailNavController,
private val reviewEditorNavController: ReviewEditorNavController,
) {
fun create(navController: NavHostController): MainNavigator {
return MainNavigator(
navController = navController,
cafeDetailNavController = cafeDetailNavController,
reviewEditorNavController = reviewEditorNavController,
)
}
}
}

@Composable
internal fun rememberMainNavigator(
navController: NavHostController = rememberNavController(),
mainNavigatorFactory: MainNavigator.Factory,
): MainNavigator = remember(navController) {
MainNavigator(navController)
mainNavigatorFactory.create(navController = navController)
}
17 changes: 16 additions & 1 deletion app/src/main/kotlin/org/cazait/cazaitandroid/ui/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,40 @@ import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat
import androidx.navigation.compose.rememberNavController
import dagger.hilt.android.AndroidEntryPoint
import org.cazait.cazaitandroid.MainNavigator
import org.cazait.cazaitandroid.core.designsystem.theme.CazaitTheme
import org.cazait.cazaitandroid.feature.cafedetail.api.CafeDetailNavGraph
import org.cazait.cazaitandroid.rememberMainNavigator
import javax.inject.Inject

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private val viewModel: MainViewModel by viewModels()

@Inject
lateinit var cafeDetailNavGraph: CafeDetailNavGraph

@Inject
internal lateinit var mainNavigatorFactory: MainNavigator.Factory

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContent {
// val isDarkTheme = false
val navigator: MainNavigator = rememberMainNavigator()
val navigator: MainNavigator = rememberMainNavigator(
rememberNavController(),
mainNavigatorFactory = mainNavigatorFactory,
)

CazaitTheme {
MainScreen(
navigator = navigator,
onChangeDarkTheme = { },
cafeDetailNavGraph = cafeDetailNavGraph,
)
}
}
Expand Down
20 changes: 15 additions & 5 deletions app/src/main/kotlin/org/cazait/cazaitandroid/ui/MainScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,21 @@ import org.cazait.cazaitandroid.MainNavigator
import org.cazait.cazaitandroid.MainTab
import org.cazait.cazaitandroid.R
import org.cazait.cazaitandroid.core.designsystem.theme.surfaceDim
import org.cazait.cazaitandroid.feature.cafedetail.api.CafeDetailNavGraph
import org.cazait.cazaitandroid.feature.cafedetail.api.CafeDetailNavGraphInfo
import org.cazait.cazaitandroid.feature.home.homeNavGraph
import org.cazait.cazaitandroid.feature.map.mapNavGraph
import org.cazait.cazaitandroid.feature.mypage.myPageNavGraph
import org.cazait.cazaitandroid.feature.signin.signInNavGraph
import org.cazait.cazaitandroid.feature.splash.splashNavGraph
import org.cazait.cazaitandroid.feature.viewmore.viewMoreNavGraph
import org.cazait.cazaitandroid.rememberMainNavigator
import java.net.UnknownHostException

@Composable
internal fun MainScreen(
navigator: MainNavigator = rememberMainNavigator(),
navigator: MainNavigator,
onChangeDarkTheme: (Boolean) -> Unit,
cafeDetailNavGraph: CafeDetailNavGraph,
) {
val snackbarHostState = remember { SnackbarHostState() }
val coroutineScope = rememberCoroutineScope()
Expand All @@ -73,8 +75,7 @@ internal fun MainScreen(
Scaffold(
content = { padding ->
Box(
modifier =
Modifier
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.surfaceDim),
) {
Expand All @@ -84,7 +85,7 @@ internal fun MainScreen(
) {
homeNavGraph(
padding = padding,
// onCafeClick = {},
onCafeClick = { navigator.navigateCafeDetail(it.id.asUUID().toString()) },
onShowErrorSnackbar = onShowErrorSnackbar,
)
mapNavGraph(
Expand All @@ -109,6 +110,15 @@ internal fun MainScreen(
onSignInSuccess = { navigator.navigateHome() },
onShowErrorSnackbar = onShowErrorSnackbar,
)
cafeDetailNavGraph.buildNavGraph(
navGraphBuilder = this,
navInfo = CafeDetailNavGraphInfo(
onEditReviewClick = { navigator.navigateReviewEditor(it) },
onBackButtonClick = { navigator.popBackStack() },
onNavArgError = { navigator.popBackStack() },
onShowErrorSnackbar = onShowErrorSnackbar,
)
)
}
}
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import org.cazait.cazaitandroid.configureCoroutineAndroid
import org.cazait.cazaitandroid.configureHiltAndroid
import org.cazait.cazaitandroid.configureKotest
import org.cazait.cazaitandroid.configureKotlinAndroid

plugins {
id("com.android.library")
id("cazait.verify.detekt")
}

configureKotlinAndroid()
configureKotest()
configureCoroutineAndroid()
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package org.cazait.cazaitandroid.core.designsystem.component

import android.content.res.Configuration
import androidx.annotation.StringRes
import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.tooling.preview.Preview
import org.cazait.cazaitandroid.core.designsystem.R
import org.cazait.cazaitandroid.core.designsystem.theme.CazaitTheme

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CazaitBackTopBar(
title: @Composable () -> Unit,
onBackButtonClick: () -> Unit,
scrollBehavior: TopAppBarScrollBehavior? = null,
) {
CenterAlignedTopAppBar(
title = title,
navigationIcon = {
IconButton(
onClick = onBackButtonClick
) {
Icon(
imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_back),
contentDescription = "뒤로 가기 버튼",
)
}
},
scrollBehavior = scrollBehavior,
)
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CazaitBackTopBar(
@StringRes title: Int,
onBackButtonClick: () -> Unit,
scrollBehavior: TopAppBarScrollBehavior? = null,
) {
CenterAlignedTopAppBar(
title = {
Text(
text = stringResource(id = title),
style = CazaitTheme.typography.titleLargeB
)
},
navigationIcon = {
IconButton(
onClick = onBackButtonClick,
) {
Icon(
imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_back),
contentDescription = "뒤로 가기 버튼",
)
}
},
scrollBehavior = scrollBehavior,
)
}

@OptIn(ExperimentalMaterial3Api::class)
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
@Composable
private fun PreviewCazaitBackTopBar() {
CazaitTheme {
CazaitBackTopBar(
title = { Text(text = "리뷰 쓰기", style = CazaitTheme.typography.titleLargeB) },
onBackButtonClick = {},
)
}
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,51 @@
package org.cazait.cazaitandroid.core.designsystem.component

import android.content.res.Configuration
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.cazait.cazaitandroid.core.designsystem.theme.CazaitTheme

@Composable
fun CazaitButton(
fun PrimaryButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
onClick: () -> Unit = {},
content: @Composable RowScope.() -> Unit,
) {
Button(
onClick = onClick,
modifier = modifier,
shape = RoundedCornerShape(48.dp),
colors = ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.primary
),
content = content,
)
}

@Composable
fun SecondaryButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
content: @Composable RowScope.() -> Unit,
) {
Button(
onClick = onClick,
modifier = modifier,
shape = RoundedCornerShape(48.dp),
colors = ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.secondary
),
content = content,
)
}
Expand All @@ -26,6 +55,15 @@ fun CazaitButton(
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
private fun PreviewCazaitButton() {
CazaitTheme {
CazaitButton {}
Surface(modifier = Modifier.size(300.dp)) {
Column {
PrimaryButton(onClick = {}) {
Text(text = "버튼")
}
SecondaryButton(onClick = {}) {
Text(text = "버튼")
}
}
}
}
}
Loading
Loading