diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a7b39ef7..6664e029 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -4,6 +4,7 @@ plugins { alias(libs.plugins.android.application) alias(libs.plugins.kotlin.android) alias(libs.plugins.kotlin.compose) + alias(libs.plugins.kotlin.serialization) } android { @@ -55,6 +56,7 @@ dependencies { implementation(libs.androidx.foundation) implementation(libs.androidx.lifecycle.viewmodel.compose) implementation(libs.androidx.navigation.runtime.android) + implementation(libs.kotlinx.serialization.json) implementation(libs.accompanist.pager) implementation(libs.accompanist.pager.indicators) testImplementation(libs.junit) diff --git a/app/src/main/java/com/texthip/thip/MainScreen.kt b/app/src/main/java/com/texthip/thip/MainScreen.kt index f408ea0e..d606b1f9 100644 --- a/app/src/main/java/com/texthip/thip/MainScreen.kt +++ b/app/src/main/java/com/texthip/thip/MainScreen.kt @@ -6,26 +6,29 @@ import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController import com.texthip.thip.ui.navigator.BottomNavigationBar import com.texthip.thip.ui.navigator.MainNavHost -import com.texthip.thip.ui.navigator.NavBarItems +import com.texthip.thip.ui.navigator.extensions.isMainTabRoute @Composable fun MainScreen() { val navController = rememberNavController() val navBackStackEntry by navController.currentBackStackEntryAsState() - val currentRoute = navBackStackEntry?.destination?.route - val showBottomBar = currentRoute in NavBarItems.BarItems.map { it.route } + val currentDestination = navBackStackEntry?.destination + + val showBottomBar = currentDestination?.isMainTabRoute() ?: true Scaffold( bottomBar = { if (showBottomBar) BottomNavigationBar(navController) - } + }, + containerColor = Color.Transparent ) { innerPadding -> Box(modifier = Modifier.padding(innerPadding)) { - MainNavHost (navController) + MainNavHost(navController) } } } \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/common/alarmpage/screen/AlarmScreen.kt b/app/src/main/java/com/texthip/thip/ui/common/alarmpage/screen/AlarmScreen.kt index cefec058..44f4e486 100644 --- a/app/src/main/java/com/texthip/thip/ui/common/alarmpage/screen/AlarmScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/common/alarmpage/screen/AlarmScreen.kt @@ -72,16 +72,10 @@ fun AlarmScreen( verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { - Icon( - painter = painterResource(R.drawable.ic_notification), - contentDescription = null, - tint = colors.Grey02, - ) - Spacer(modifier = Modifier.height(12.dp)) Text( text = stringResource(R.string.alarm_notification_comment), - style = typography.smalltitle_sb600_s16_h20, - color = colors.Grey01 + style = typography.smalltitle_sb600_s18_h24, + color = colors.White ) } } else { diff --git a/app/src/main/java/com/texthip/thip/ui/group/makeroom/screen/GroupMakeRoomScreen.kt b/app/src/main/java/com/texthip/thip/ui/group/makeroom/screen/GroupMakeRoomScreen.kt index 429408b0..3920a5f4 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/makeroom/screen/GroupMakeRoomScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/makeroom/screen/GroupMakeRoomScreen.kt @@ -24,6 +24,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.lifecycle.viewmodel.compose.viewModel import com.texthip.thip.R import com.texthip.thip.ui.common.buttons.GenreChipRow import com.texthip.thip.ui.common.buttons.ToggleSwitchButton @@ -36,13 +37,9 @@ import com.texthip.thip.ui.group.makeroom.component.GroupSelectBook import com.texthip.thip.ui.group.makeroom.component.GroupMemberLimitPicker import com.texthip.thip.ui.group.makeroom.component.SectionDivider import com.texthip.thip.ui.group.makeroom.mock.BookData -import com.texthip.thip.ui.group.makeroom.mock.GroupMakeRoomRequest import com.texthip.thip.ui.group.makeroom.mock.dummyGroupBooks import com.texthip.thip.ui.group.makeroom.mock.dummySavedBooks -import com.texthip.thip.ui.group.makeroom.viewmodel.ApiResult -import com.texthip.thip.ui.group.makeroom.viewmodel.GroupCreateResponse import com.texthip.thip.ui.group.makeroom.viewmodel.GroupMakeRoomViewModel -import com.texthip.thip.ui.group.makeroom.viewmodel.GroupRepository import com.texthip.thip.ui.theme.ThipTheme import com.texthip.thip.ui.theme.ThipTheme.colors import com.texthip.thip.ui.theme.ThipTheme.typography @@ -238,15 +235,7 @@ fun GroupMakeRoomScreen( @Preview @Composable private fun GroupMakeRoomScreenPreview() { - // Preview용 MockViewModel 생성 - val mockViewModel = object : GroupMakeRoomViewModel(MockGroupRepository()) { - // 필요한 경우 Preview용 초기 상태 설정 - init { - // 예시: 미리 선택된 책이 있는 상태로 Preview - // selectBook(BookData(id = "1", title = "예시 책", author = "작가")) - // selectGenre(0) - } - } + val mockViewModel: GroupMakeRoomViewModel = viewModel() ThipTheme { GroupMakeRoomScreen( @@ -256,16 +245,3 @@ private fun GroupMakeRoomScreenPreview() { ) } } - -// Preview용 Mock Repository -class MockGroupRepository : GroupRepository { - override suspend fun createGroup(request: GroupMakeRoomRequest): ApiResult { - return ApiResult( - isSuccess = true, - data = GroupCreateResponse( - groupId = "mock_group_id", - groupName = "Mock Group" - ) - ) - } -} diff --git a/app/src/main/java/com/texthip/thip/ui/group/makeroom/viewmodel/GroupMakeRoomViewModel.kt b/app/src/main/java/com/texthip/thip/ui/group/makeroom/viewmodel/GroupMakeRoomViewModel.kt index 20e28599..a857e861 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/makeroom/viewmodel/GroupMakeRoomViewModel.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/makeroom/viewmodel/GroupMakeRoomViewModel.kt @@ -12,8 +12,8 @@ import kotlinx.coroutines.launch import java.time.LocalDate // 나중에 서버와 연동할 때 사용할 뷰모델 예시 -open class GroupMakeRoomViewModel( - private val groupRepository: GroupRepository // 의존성 주입 +class GroupMakeRoomViewModel( + private val groupRepository: GroupRepository = MockGroupRepository() // 기본값으로 Mock Repository 사용 ) : ViewModel() { private val _uiState = MutableStateFlow(GroupMakeRoomUiState()) @@ -122,4 +122,18 @@ data class ApiResult( data class GroupCreateResponse( val groupId: String, val groupName: String -) \ No newline at end of file +) + +// Mock Repository 구현 +class MockGroupRepository : GroupRepository { + override suspend fun createGroup(request: GroupMakeRoomRequest): ApiResult { + // 임시로 성공 응답 반환 + return ApiResult( + isSuccess = true, + data = GroupCreateResponse( + groupId = "mock_group_${System.currentTimeMillis()}", + groupName = request.roomTitle + ) + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/group/screen/GroupScreen.kt b/app/src/main/java/com/texthip/thip/ui/group/screen/GroupScreen.kt index 20fe2f5f..95f8ecb7 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/screen/GroupScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/screen/GroupScreen.kt @@ -15,13 +15,11 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel -import androidx.navigation.NavHostController import com.texthip.thip.R import com.texthip.thip.ui.common.buttons.FloatingButton import com.texthip.thip.ui.common.topappbar.LogoTopAppBar @@ -29,19 +27,19 @@ import com.texthip.thip.ui.group.myroom.component.GroupMySectionHeader import com.texthip.thip.ui.group.myroom.component.GroupPager import com.texthip.thip.ui.group.myroom.component.GroupRoomDeadlineSection import com.texthip.thip.ui.group.myroom.component.GroupSearchTextField -import com.texthip.thip.ui.group.myroom.mock.GroupViewModel +import com.texthip.thip.ui.group.viewmodel.GroupViewModel import com.texthip.thip.ui.theme.ThipTheme import com.texthip.thip.ui.theme.ThipTheme.colors @Composable fun GroupScreen( - navController: NavHostController? = null, + onNavigateToMakeRoom: () -> Unit = {}, viewModel: GroupViewModel = viewModel() ) { val myGroups by viewModel.myGroups.collectAsState() val roomSections by viewModel.roomSections.collectAsState() val scrollState = rememberScrollState() - var searchText by remember { mutableStateOf("") } + val searchText by remember { mutableStateOf("") } Box( Modifier @@ -99,7 +97,7 @@ fun GroupScreen( // 오른쪽 하단 FAB FloatingButton( icon = painterResource(id = R.drawable.ic_makegroup), - onClick = { viewModel.onFabClick() } + onClick = onNavigateToMakeRoom ) } } diff --git a/app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupViewModel.kt b/app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt similarity index 94% rename from app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupViewModel.kt rename to app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt index 79139a7b..ded195d8 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupViewModel.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt @@ -1,7 +1,10 @@ -package com.texthip.thip.ui.group.myroom.mock +package com.texthip.thip.ui.group.viewmodel import androidx.lifecycle.ViewModel import com.texthip.thip.R +import com.texthip.thip.ui.group.myroom.mock.GroupCardData +import com.texthip.thip.ui.group.myroom.mock.GroupCardItemRoomData +import com.texthip.thip.ui.group.myroom.mock.GroupRoomSectionData import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -84,7 +87,4 @@ class GroupViewModel : ViewModel() { // 방 카드 클릭 (상세 진입) } - fun onFabClick() { - // FAB 클릭(모임방 생성 등) - } } \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/mypage/screen/MypageScreen.kt b/app/src/main/java/com/texthip/thip/ui/mypage/screen/MypageScreen.kt index a90d54bb..f8467f32 100644 --- a/app/src/main/java/com/texthip/thip/ui/mypage/screen/MypageScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/mypage/screen/MypageScreen.kt @@ -109,7 +109,7 @@ fun MyPageScreen( ) MenuItemButton( text = stringResource(R.string.notification_settings), - icon = painterResource(R.drawable.ic_notification), + icon = painterResource(R.drawable.ic_notice), contentColor = colors.White, backgroundColor = colors.DarkGrey02, hasRightIcon = true, diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/BarItem.kt b/app/src/main/java/com/texthip/thip/ui/navigator/BarItem.kt deleted file mode 100644 index 4a7f730b..00000000 --- a/app/src/main/java/com/texthip/thip/ui/navigator/BarItem.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.texthip.thip.ui.navigator - -import androidx.annotation.DrawableRes - -data class BarItem( - val title: String, - val route: String, - @DrawableRes val IconRes: Int, - @DrawableRes val SelectedIconRes: Int -) diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/BottomNavigationBar.kt b/app/src/main/java/com/texthip/thip/ui/navigator/BottomNavigationBar.kt index 515cef2b..3e25db24 100644 --- a/app/src/main/java/com/texthip/thip/ui/navigator/BottomNavigationBar.kt +++ b/app/src/main/java/com/texthip/thip/ui/navigator/BottomNavigationBar.kt @@ -17,17 +17,25 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Path +import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp -import androidx.navigation.NavController +import androidx.navigation.NavHostController import androidx.navigation.compose.currentBackStackEntryAsState +import com.texthip.thip.ui.navigator.data.NavBarItems +import com.texthip.thip.ui.navigator.extensions.navigateToTab +import com.texthip.thip.ui.navigator.extensions.isRoute import com.texthip.thip.ui.theme.ThipTheme.colors import com.texthip.thip.ui.theme.ThipTheme.typography @Composable -fun BottomNavigationBar(navController: NavController) { - val currentRoute = navController.currentBackStackEntryAsState().value?.destination?.route +fun BottomNavigationBar(navController: NavHostController) { + val currentDestination = navController.currentBackStackEntryAsState().value?.destination + val greyColor = colors.Grey02 Box( modifier = Modifier @@ -41,9 +49,48 @@ fun BottomNavigationBar(navController: NavController) { bottomEnd = 0.dp ) ) - .background(colors.Black), + .background(colors.Black) + .drawBehind { + val cornerRadius = 12.dp.toPx() + val strokeWidth = 2.dp.toPx() + + val path = Path().apply { + // 좌상단 모서리부터 시작 + moveTo(0f, cornerRadius) + arcTo( + rect = androidx.compose.ui.geometry.Rect( + left = 0f, + top = 0f, + right = cornerRadius * 2, + bottom = cornerRadius * 2 + ), + startAngleDegrees = 180f, + sweepAngleDegrees = 90f, + forceMoveTo = false + ) + lineTo(size.width - cornerRadius, 0f) + arcTo( + rect = androidx.compose.ui.geometry.Rect( + left = size.width - cornerRadius * 2, + top = 0f, + right = size.width, + bottom = cornerRadius * 2 + ), + startAngleDegrees = 270f, + sweepAngleDegrees = 90f, + forceMoveTo = false + ) + } + + drawPath( + path = path, + color = greyColor, + style = Stroke(width = strokeWidth) + ) + }, contentAlignment = Alignment.Center ) { + Row( modifier = Modifier .fillMaxSize() @@ -52,39 +99,32 @@ fun BottomNavigationBar(navController: NavController) { verticalAlignment = Alignment.CenterVertically ) { NavBarItems.BarItems.forEach { item -> - val isSelected = currentRoute == item.route + val isSelected = currentDestination?.isRoute(item.route) == true NavigationBarItem( icon = { Icon( - painter = painterResource(id = if (isSelected) item.SelectedIconRes else item.IconRes), - contentDescription = item.title, + painter = painterResource(id = if (isSelected) item.selectedIconRes else item.iconRes), + contentDescription = stringResource(item.titleRes), ) }, label = { Text( - text = item.title, + text = stringResource(item.titleRes), style = typography.navi_m500_s10 ) }, selected = isSelected, onClick = { if (!isSelected) { - navController.navigate(item.route) { - popUpTo(navController.graph.startDestinationId) { - saveState = true - } - launchSingleTop = true - restoreState = true - } + navController.navigateToTab(item.route) } }, - colors = NavigationBarItemDefaults.colors( indicatorColor = Color.Transparent, selectedIconColor = colors.Purple, - unselectedIconColor = Color.Unspecified, + unselectedIconColor = colors.Grey02, selectedTextColor = colors.Purple, - unselectedTextColor = Color.Unspecified + unselectedTextColor = colors.Grey02 ) ) } diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/MainNavHost.kt b/app/src/main/java/com/texthip/thip/ui/navigator/MainNavHost.kt index c0061dcc..4fdeae34 100644 --- a/app/src/main/java/com/texthip/thip/ui/navigator/MainNavHost.kt +++ b/app/src/main/java/com/texthip/thip/ui/navigator/MainNavHost.kt @@ -1,26 +1,21 @@ package com.texthip.thip.ui.navigator -import androidx.navigation.compose.NavHost -import androidx.navigation.compose.composable import androidx.compose.runtime.Composable import androidx.navigation.NavHostController -import com.texthip.thip.ui.search.screen.SearchBookScreen -import com.texthip.thip.ui.feed.screen.FeedScreen -import com.texthip.thip.ui.group.screen.GroupScreen -import com.texthip.thip.ui.mypage.screen.MyPageScreen +import androidx.navigation.compose.NavHost +import com.texthip.thip.ui.navigator.routes.MainTabRoutes +import com.texthip.thip.ui.navigator.navigations.feedNavigation +import com.texthip.thip.ui.navigator.navigations.groupNavigation +import com.texthip.thip.ui.navigator.navigations.myPageNavigation +import com.texthip.thip.ui.navigator.navigations.searchNavigation +// 메인 네비게이션 @Composable fun MainNavHost(navController: NavHostController) { - NavHost(navController = navController, startDestination = Routes.Feed.route) { - composable(Routes.Feed.route) { FeedScreen(navController) } - composable(Routes.Group.route) { GroupScreen(navController) } - composable(Routes.BookSearch.route) { SearchBookScreen(navController = navController) } - composable(Routes.MyPage.route) { - MyPageScreen( - navController, - nickname = "ThipUser01", - badgeText = "문학가" - ) - } + NavHost(navController = navController, startDestination = MainTabRoutes.Feed) { + feedNavigation(navController) + groupNavigation(navController) + searchNavigation(navController) + myPageNavigation(navController) } } \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/NavBarItems.kt b/app/src/main/java/com/texthip/thip/ui/navigator/NavBarItems.kt deleted file mode 100644 index faf8ce59..00000000 --- a/app/src/main/java/com/texthip/thip/ui/navigator/NavBarItems.kt +++ /dev/null @@ -1,32 +0,0 @@ -package com.texthip.thip.ui.navigator - -import com.texthip.thip.R - -object NavBarItems { - val BarItems = listOf( - BarItem( - title = "피드", - route = Routes.Feed.route, - IconRes = R.drawable.ic_feed, - SelectedIconRes = R.drawable.ic_feed_selected - ), - BarItem( - title = "모임", - route = Routes.Group.route, - IconRes = R.drawable.ic_group, - SelectedIconRes = R.drawable.ic_group_selected - ), - BarItem( - title = "검색", - route = Routes.BookSearch.route, - IconRes = R.drawable.ic_booksearch, - SelectedIconRes = R.drawable.ic_booksearch_selected - ), - BarItem( - title = "내 정보", - route = Routes.MyPage.route, - IconRes = R.drawable.ic_mypage, - SelectedIconRes = R.drawable.ic_mypage_selected - ) - ) -} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/Routes.kt b/app/src/main/java/com/texthip/thip/ui/navigator/Routes.kt deleted file mode 100644 index d27920da..00000000 --- a/app/src/main/java/com/texthip/thip/ui/navigator/Routes.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.texthip.thip.ui.navigator - - -sealed class Routes(val route: String) { - object Feed : Routes("Feed") - object Group : Routes("Group") - object BookSearch : Routes("BookSearch") - object MyPage : Routes("MyPage") -} diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/data/BarItem.kt b/app/src/main/java/com/texthip/thip/ui/navigator/data/BarItem.kt new file mode 100644 index 00000000..64b38d78 --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/navigator/data/BarItem.kt @@ -0,0 +1,12 @@ +package com.texthip.thip.ui.navigator.data + +import androidx.annotation.DrawableRes +import androidx.annotation.StringRes +import com.texthip.thip.ui.navigator.routes.MainTabRoutes + +data class BarItem( + @StringRes val titleRes: Int, + val route: MainTabRoutes, + @DrawableRes val iconRes: Int, + @DrawableRes val selectedIconRes: Int +) diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/data/NavBarItems.kt b/app/src/main/java/com/texthip/thip/ui/navigator/data/NavBarItems.kt new file mode 100644 index 00000000..004421da --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/navigator/data/NavBarItems.kt @@ -0,0 +1,33 @@ +package com.texthip.thip.ui.navigator.data + +import com.texthip.thip.R +import com.texthip.thip.ui.navigator.routes.MainTabRoutes + +object NavBarItems { + val BarItems = listOf( + BarItem( + titleRes = R.string.nav_feed, + route = MainTabRoutes.Feed, + iconRes = R.drawable.ic_feed, + selectedIconRes = R.drawable.ic_feed_selected + ), + BarItem( + titleRes = R.string.nav_group, + route = MainTabRoutes.Group, + iconRes = R.drawable.ic_group, + selectedIconRes = R.drawable.ic_group_selected + ), + BarItem( + titleRes = R.string.nav_search, + route = MainTabRoutes.Search, + iconRes = R.drawable.ic_booksearch, + selectedIconRes = R.drawable.ic_booksearch_selected + ), + BarItem( + titleRes = R.string.nav_mypage, + route = MainTabRoutes.MyPage, + iconRes = R.drawable.ic_mypage, + selectedIconRes = R.drawable.ic_mypage_selected + ) + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/extensions/CommonNavigationExtensions.kt b/app/src/main/java/com/texthip/thip/ui/navigator/extensions/CommonNavigationExtensions.kt new file mode 100644 index 00000000..61ff596b --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/navigator/extensions/CommonNavigationExtensions.kt @@ -0,0 +1,39 @@ +package com.texthip.thip.ui.navigator.extensions + +import androidx.navigation.NavDestination +import androidx.navigation.NavHostController +import com.texthip.thip.ui.navigator.routes.MainTabRoutes + + +// 공통 네비게이션 확장 함수들 + +// 뒤로가기 +fun NavHostController.navigateBack() { + popBackStack() +} + +// Bottom Navigation용 Tab 이동 (메인 탭에만 사용) +fun NavHostController.navigateToTab(route: MainTabRoutes) { + navigate(route) { + popUpTo(graph.startDestinationId) { + saveState = true + } + launchSingleTop = true + restoreState = true + } +} + +// 라우트 매칭 헬퍼 함수들 +fun NavDestination.isMainTabRoute(): Boolean { + return when (route) { + MainTabRoutes.Feed::class.qualifiedName, + MainTabRoutes.Group::class.qualifiedName, + MainTabRoutes.Search::class.qualifiedName, + MainTabRoutes.MyPage::class.qualifiedName -> true + else -> false + } +} + +fun NavDestination.isRoute(targetRoute: MainTabRoutes): Boolean { + return route == targetRoute::class.qualifiedName +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/extensions/FeedNavigationExtensions.kt b/app/src/main/java/com/texthip/thip/ui/navigator/extensions/FeedNavigationExtensions.kt new file mode 100644 index 00000000..ebc035cc --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/navigator/extensions/FeedNavigationExtensions.kt @@ -0,0 +1,9 @@ +package com.texthip.thip.ui.navigator.extensions + +import androidx.navigation.NavHostController +import com.texthip.thip.ui.navigator.routes.MainTabRoutes + +// Feed 확장 함수 +fun NavHostController.navigateToFeed() { + navigate(MainTabRoutes.Feed) +} diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/extensions/GroupNavigationExtensions.kt b/app/src/main/java/com/texthip/thip/ui/navigator/extensions/GroupNavigationExtensions.kt new file mode 100644 index 00000000..0e1aaa75 --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/navigator/extensions/GroupNavigationExtensions.kt @@ -0,0 +1,16 @@ +package com.texthip.thip.ui.navigator.extensions + +import androidx.navigation.NavHostController +import com.texthip.thip.ui.navigator.routes.MainTabRoutes +import com.texthip.thip.ui.navigator.routes.GroupRoutes + + +// Group 관련 네비게이션 확장 함수들 + +fun NavHostController.navigateToGroup() { + navigate(MainTabRoutes.Group) +} + +fun NavHostController.navigateToGroupMakeRoom() { + navigate(GroupRoutes.MakeRoom) +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/extensions/MyPageNavigationExtensions.kt b/app/src/main/java/com/texthip/thip/ui/navigator/extensions/MyPageNavigationExtensions.kt new file mode 100644 index 00000000..4ca4453a --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/navigator/extensions/MyPageNavigationExtensions.kt @@ -0,0 +1,11 @@ +package com.texthip.thip.ui.navigator.extensions + +import androidx.navigation.NavHostController +import com.texthip.thip.ui.navigator.routes.MainTabRoutes + + +// MyPage 관련 네비게이션 확장 함수들 + +fun NavHostController.navigateToMyPage() { + navigate(MainTabRoutes.MyPage) +} diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/extensions/SearchNavigationExtensions.kt b/app/src/main/java/com/texthip/thip/ui/navigator/extensions/SearchNavigationExtensions.kt new file mode 100644 index 00000000..aa993a8f --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/navigator/extensions/SearchNavigationExtensions.kt @@ -0,0 +1,10 @@ +package com.texthip.thip.ui.navigator.extensions + +import androidx.navigation.NavHostController +import com.texthip.thip.ui.navigator.routes.MainTabRoutes + + +// Search 관련 네비게이션 확장 함수들 +fun NavHostController.navigateToSearch() { + navigate(MainTabRoutes.Search) +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/navigations/FeedNavigation.kt b/app/src/main/java/com/texthip/thip/ui/navigator/navigations/FeedNavigation.kt new file mode 100644 index 00000000..d6868bbd --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/navigator/navigations/FeedNavigation.kt @@ -0,0 +1,14 @@ +package com.texthip.thip.ui.navigator.navigations + +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavHostController +import androidx.navigation.compose.composable +import com.texthip.thip.ui.feed.screen.FeedScreen +import com.texthip.thip.ui.navigator.routes.MainTabRoutes + +// Feed +fun NavGraphBuilder.feedNavigation(navController: NavHostController) { + composable { + FeedScreen(navController) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/navigations/GroupNavigation.kt b/app/src/main/java/com/texthip/thip/ui/navigator/navigations/GroupNavigation.kt new file mode 100644 index 00000000..711840ff --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/navigator/navigations/GroupNavigation.kt @@ -0,0 +1,39 @@ +package com.texthip.thip.ui.navigator.navigations + +import androidx.lifecycle.viewmodel.compose.viewModel +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavHostController +import androidx.navigation.compose.composable +import com.texthip.thip.ui.group.makeroom.screen.GroupMakeRoomScreen +import com.texthip.thip.ui.group.makeroom.viewmodel.GroupMakeRoomViewModel +import com.texthip.thip.ui.group.screen.GroupScreen +import com.texthip.thip.ui.navigator.routes.MainTabRoutes +import com.texthip.thip.ui.navigator.routes.GroupRoutes +import com.texthip.thip.ui.navigator.extensions.navigateBack +import com.texthip.thip.ui.navigator.extensions.navigateToGroupMakeRoom + +// Group +fun NavGraphBuilder.groupNavigation(navController: NavHostController) { + // 메인 Group 화면 + composable { + GroupScreen( + onNavigateToMakeRoom = { + navController.navigateToGroupMakeRoom() + } + ) + } + + // Group MakeRoom 화면 + composable { + val viewModel: GroupMakeRoomViewModel = viewModel() + GroupMakeRoomScreen( + viewModel = viewModel, + onNavigateBack = { + navController.navigateBack() + }, + onGroupCreated = { + navController.navigateBack() + } + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/navigations/MyPageNavigation.kt b/app/src/main/java/com/texthip/thip/ui/navigator/navigations/MyPageNavigation.kt new file mode 100644 index 00000000..92883f8f --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/navigator/navigations/MyPageNavigation.kt @@ -0,0 +1,19 @@ +package com.texthip.thip.ui.navigator.navigations + +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavHostController +import androidx.navigation.compose.composable +import com.texthip.thip.ui.mypage.screen.MyPageScreen +import com.texthip.thip.ui.navigator.routes.MainTabRoutes + +// MyPage +fun NavGraphBuilder.myPageNavigation(navController: NavHostController) { + composable { + MyPageScreen( + navController, + nickname = "ThipUser01", + badgeText = "문학가" + ) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/navigations/SearchNavigation.kt b/app/src/main/java/com/texthip/thip/ui/navigator/navigations/SearchNavigation.kt new file mode 100644 index 00000000..26558e63 --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/navigator/navigations/SearchNavigation.kt @@ -0,0 +1,13 @@ +package com.texthip.thip.ui.navigator.navigations + +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavHostController +import androidx.navigation.compose.composable +import com.texthip.thip.ui.navigator.routes.MainTabRoutes +import com.texthip.thip.ui.search.screen.SearchBookScreen + +fun NavGraphBuilder.searchNavigation(navController: NavHostController) { + composable { + SearchBookScreen(navController = navController) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/routes/FeedRoutes.kt b/app/src/main/java/com/texthip/thip/ui/navigator/routes/FeedRoutes.kt new file mode 100644 index 00000000..6cc7bc71 --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/navigator/routes/FeedRoutes.kt @@ -0,0 +1,10 @@ +package com.texthip.thip.ui.navigator.routes + +import kotlinx.serialization.Serializable + +@Serializable +sealed class FeedRoutes : Routes() { + // 향후 추가될 Feed 관련 화면들 + // @Serializable data object SubscriptionList : FeedRoutes + // @Serializable data object Detail : FeedRoutes +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/routes/GroupRoutes.kt b/app/src/main/java/com/texthip/thip/ui/navigator/routes/GroupRoutes.kt new file mode 100644 index 00000000..e68d8268 --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/navigator/routes/GroupRoutes.kt @@ -0,0 +1,15 @@ +package com.texthip.thip.ui.navigator.routes + +import kotlinx.serialization.Serializable + +@Serializable +sealed class GroupRoutes : Routes() { + @Serializable + data object MakeRoom : GroupRoutes() + + // 향후 추가될 Group 관련 화면들 + // @Serializable data object Room : GroupRoutes + // @Serializable data object RoomChat : GroupRoutes + // @Serializable data object Note : GroupRoutes + // @Serializable data object NoteCreate : GroupRoutes +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/routes/MyPageRoutes.kt b/app/src/main/java/com/texthip/thip/ui/navigator/routes/MyPageRoutes.kt new file mode 100644 index 00000000..85ab317f --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/navigator/routes/MyPageRoutes.kt @@ -0,0 +1,12 @@ +package com.texthip.thip.ui.navigator.routes + +import kotlinx.serialization.Serializable + +@Serializable +sealed class MyPageRoutes : Routes() { + // 향후 추가될 MyPage 관련 화면들 + // @Serializable data object Edit : MyPageRoutes + // @Serializable data object Save : MyPageRoutes + // @Serializable data object Reaction : MyPageRoutes + // @Serializable data object NotificationEdit : MyPageRoutes +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/routes/Routes.kt b/app/src/main/java/com/texthip/thip/ui/navigator/routes/Routes.kt new file mode 100644 index 00000000..8f503427 --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/navigator/routes/Routes.kt @@ -0,0 +1,21 @@ +package com.texthip.thip.ui.navigator.routes + +import kotlinx.serialization.Serializable + +@Serializable +sealed class Routes + +@Serializable +sealed class MainTabRoutes : Routes() { + @Serializable + data object Feed : MainTabRoutes() + + @Serializable + data object Group : MainTabRoutes() + + @Serializable + data object Search : MainTabRoutes() + + @Serializable + data object MyPage : MainTabRoutes() +} diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/routes/SearchRoutes.kt b/app/src/main/java/com/texthip/thip/ui/navigator/routes/SearchRoutes.kt new file mode 100644 index 00000000..2b8e1078 --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/navigator/routes/SearchRoutes.kt @@ -0,0 +1,10 @@ +package com.texthip.thip.ui.navigator.routes + +import kotlinx.serialization.Serializable + +@Serializable +sealed class SearchRoutes : Routes() { + // 향후 추가될 Search 관련 화면들 + // @Serializable data object BookDetail : SearchRoutes + // @Serializable data object BookGroup : SearchRoutes +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8e2099e1..39ff9357 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,6 +1,12 @@ Thip + + 피드 + 모임 + 검색 + 내 정보 + 🔥 %d명이 읽기에 참여중이에요! 🔥 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f596e68f..e0142547 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] -agp = "8.9.1" -kotlin = "2.0.21" +agp = "8.9.3" +kotlin = "2.2.0" coreKtx = "1.16.0" junit = "4.13.2" junitVersion = "1.2.1" @@ -8,12 +8,13 @@ espressoCore = "3.6.1" lifecycleRuntimeKtx = "2.8.7" activityCompose = "1.10.1" composeBom = "2024.09.00" -navigationCompose = "2.9.0" +navigationCompose = "2.9.2" foundation = "1.9.0-beta01" -lifecycleViewmodelCompose = "2.9.1" -navigationRuntimeAndroid = "2.9.0" +lifecycleViewmodelCompose = "2.9.2" +navigationRuntimeAndroid = "2.9.2" accompanistPager = "0.36.0" accompanistPagerIndicators = "0.36.0" +kotlinxSerializationJson = "1.9.0" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -36,9 +37,11 @@ androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "l androidx-navigation-runtime-android = { group = "androidx.navigation", name = "navigation-runtime-android", version.ref = "navigationRuntimeAndroid" } accompanist-pager = { group = "com.google.accompanist", name = "accompanist-pager", version.ref = "accompanistPager" } accompanist-pager-indicators = { group = "com.google.accompanist", name = "accompanist-pager-indicators", version.ref = "accompanistPagerIndicators" } +kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" } kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } +kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }