From 1bf3bcdf4d8ebae875629b8ac82dc7d31576d2da Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Sun, 27 Jul 2025 16:38:45 +0900 Subject: [PATCH 01/32] =?UTF-8?q?[feat]:=20=EC=95=8C=EB=9E=8C=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EB=84=A4=EB=B9=84=EA=B2=8C=EC=9D=B4?= =?UTF-8?q?=EC=85=98,=20=EB=A3=A8=ED=8A=B8=20=EC=B6=94=EA=B0=80=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../navigator/navigations/CommonNavigation.kt | 22 +++++++++++++++++++ .../thip/ui/navigator/routes/CommonRoutes.kt | 9 ++++++++ 2 files changed, 31 insertions(+) create mode 100644 app/src/main/java/com/texthip/thip/ui/navigator/navigations/CommonNavigation.kt create mode 100644 app/src/main/java/com/texthip/thip/ui/navigator/routes/CommonRoutes.kt diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/navigations/CommonNavigation.kt b/app/src/main/java/com/texthip/thip/ui/navigator/navigations/CommonNavigation.kt new file mode 100644 index 00000000..934c1869 --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/navigator/navigations/CommonNavigation.kt @@ -0,0 +1,22 @@ +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.common.alarmpage.screen.AlarmScreen +import com.texthip.thip.ui.navigator.routes.CommonRoutes +import com.texthip.thip.ui.navigator.extensions.navigateBack + +// Common 관련 네비게이션 +fun NavGraphBuilder.commonNavigation(navController: NavHostController) { + // Alarm 화면 + composable { + AlarmScreen( + alarmItems = emptyList(), // TODO: ViewModel에서 가져오기 + onCardClick = { /* TODO: 알림 카드 클릭 처리 */ }, + onNavigateBack = { + navController.navigateBack() + } + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/routes/CommonRoutes.kt b/app/src/main/java/com/texthip/thip/ui/navigator/routes/CommonRoutes.kt new file mode 100644 index 00000000..623bb43f --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/navigator/routes/CommonRoutes.kt @@ -0,0 +1,9 @@ +package com.texthip.thip.ui.navigator.routes + +import kotlinx.serialization.Serializable + +@Serializable +sealed class CommonRoutes : Routes() { + @Serializable + data object Alarm : CommonRoutes() +} \ No newline at end of file From 7f111d211f238cc8f7a569a24a7819a015f3b9d3 Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Sun, 27 Jul 2025 16:40:35 +0900 Subject: [PATCH 02/32] =?UTF-8?q?[ui]:=20=EA=B2=80=EC=83=89=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=20=ED=84=B0=EC=B9=98=EB=A7=8C=20=EB=90=98=EA=B2=8C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/common/forms/SearchBookTextField.kt | 2 +- .../myroom/component/GroupSearchTextField.kt | 63 +++++-------------- 2 files changed, 18 insertions(+), 47 deletions(-) diff --git a/app/src/main/java/com/texthip/thip/ui/common/forms/SearchBookTextField.kt b/app/src/main/java/com/texthip/thip/ui/common/forms/SearchBookTextField.kt index 11233ceb..066ada9d 100644 --- a/app/src/main/java/com/texthip/thip/ui/common/forms/SearchBookTextField.kt +++ b/app/src/main/java/com/texthip/thip/ui/common/forms/SearchBookTextField.kt @@ -53,7 +53,7 @@ fun SearchBookTextField( .fillMaxWidth() .height(40.dp) .clip(shape) - .background(colors.DarkGrey02), + .background(colors.DarkGrey), contentAlignment = Alignment.CenterStart ) { Row( diff --git a/app/src/main/java/com/texthip/thip/ui/group/myroom/component/GroupSearchTextField.kt b/app/src/main/java/com/texthip/thip/ui/group/myroom/component/GroupSearchTextField.kt index 22b2d107..e2a644f6 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/myroom/component/GroupSearchTextField.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/myroom/component/GroupSearchTextField.kt @@ -1,6 +1,7 @@ package com.texthip.thip.ui.group.myroom.component import androidx.compose.foundation.background +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize @@ -8,18 +9,12 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.text.BasicTextField import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview @@ -32,18 +27,11 @@ import com.texthip.thip.ui.theme.ThipTheme.typography @Composable fun GroupSearchTextField( modifier: Modifier = Modifier, - value: String, placeholder: String = stringResource(R.string.group_search_placeholder), - onValueChange: (String) -> Unit, - onClick: (() -> Unit)? = null + onClick: () -> Unit ) { - val textStyle = typography.menu_r400_s14_h24.copy( - lineHeight = 16.sp, - color = colors.White - ) val shape = RoundedCornerShape(12.dp) val backgroundColor = colors.DarkGrey - val cursorColor = colors.NeonGreen Box( modifier @@ -51,44 +39,29 @@ fun GroupSearchTextField( .fillMaxWidth() .height(40.dp) .clip(shape) - .background(backgroundColor), + .background(backgroundColor) + .clickable { onClick() }, contentAlignment = Alignment.CenterStart ) { Row( verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.fillMaxSize() + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 12.dp) ) { - BasicTextField( - value = value, - onValueChange = onValueChange, - singleLine = true, - textStyle = textStyle, - cursorBrush = SolidColor(cursorColor), - modifier = Modifier - .weight(1f) - .padding(start = 12.dp, end = 8.dp), - decorationBox = { innerTextField -> - Box(contentAlignment = Alignment.CenterStart) { - if (value.isEmpty()) { - Text( - text = placeholder, - color = colors.Grey02, - style = typography.menu_r400_s14_h24.copy( - fontSize = 14.sp, - lineHeight = 16.sp - ) - ) - } - innerTextField() - } - } + Text( + text = placeholder, + color = colors.Grey02, + style = typography.menu_r400_s14_h24.copy( + fontSize = 14.sp, + lineHeight = 16.sp + ), + modifier = Modifier.weight(1f) ) Icon( painter = painterResource(id = R.drawable.ic_search), contentDescription = "검색", - tint = colors.White, - modifier = Modifier - .padding(end = 12.dp) + tint = colors.White ) } } @@ -97,9 +70,7 @@ fun GroupSearchTextField( @Preview(showBackground = true, backgroundColor = 0xFF000000, widthDp = 360) @Composable fun PreviewGroupSearchTextField() { - var value by remember { mutableStateOf("") } GroupSearchTextField( - value = value, - onValueChange = { value = it } + onClick = { } ) } From ae33e8c36c3259f8ff7f0cf7d672821a5090c7c1 Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Sun, 27 Jul 2025 16:42:29 +0900 Subject: [PATCH 03/32] =?UTF-8?q?[feat]:=20=EB=84=A4=EB=B9=84=EA=B2=8C?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EB=A3=A8=ED=8A=B8,=20=ED=95=A8=EC=88=98?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EA=B7=B8=EB=A3=B9=20?= =?UTF-8?q?=EC=8A=A4=ED=81=AC=EB=A6=B0=EA=B3=BC=20=EC=97=B0=EA=B2=B0=20(#5?= =?UTF-8?q?8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../texthip/thip/ui/navigator/MainNavHost.kt | 2 + .../extensions/GroupNavigationExtensions.kt | 18 ++++++- .../navigator/navigations/GroupNavigation.kt | 52 +++++++++++++++++++ .../thip/ui/navigator/routes/GroupRoutes.kt | 13 +++-- 4 files changed, 79 insertions(+), 6 deletions(-) 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 4fdeae34..c2f8cb76 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 @@ -8,6 +8,7 @@ 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 +import com.texthip.thip.ui.navigator.navigations.commonNavigation // 메인 네비게이션 @Composable @@ -17,5 +18,6 @@ fun MainNavHost(navController: NavHostController) { groupNavigation(navController) searchNavigation(navController) myPageNavigation(navController) + commonNavigation(navController) } } \ No newline at end of file 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 index 0e1aaa75..80434826 100644 --- 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 @@ -3,14 +3,30 @@ 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 +import com.texthip.thip.ui.navigator.routes.CommonRoutes // Group 관련 네비게이션 확장 함수들 - fun NavHostController.navigateToGroup() { navigate(MainTabRoutes.Group) } fun NavHostController.navigateToGroupMakeRoom() { navigate(GroupRoutes.MakeRoom) +} + +fun NavHostController.navigateToGroupDone() { + navigate(GroupRoutes.Done) +} + +fun NavHostController.navigateToGroupSearch() { + navigate(GroupRoutes.Search) +} + +fun NavHostController.navigateToGroupMy() { + navigate(GroupRoutes.My) +} + +fun NavHostController.navigateToAlarm() { + navigate(CommonRoutes.Alarm) } \ 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 index 711840ff..794e50d3 100644 --- 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 @@ -7,10 +7,17 @@ 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.group.screen.GroupDoneScreen +import com.texthip.thip.ui.group.myroom.screen.GroupMyScreen +import com.texthip.thip.ui.group.search.screen.GroupSearchScreen 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 +import com.texthip.thip.ui.navigator.extensions.navigateToGroupDone +import com.texthip.thip.ui.navigator.extensions.navigateToGroupSearch +import com.texthip.thip.ui.navigator.extensions.navigateToGroupMy +import com.texthip.thip.ui.navigator.extensions.navigateToAlarm // Group fun NavGraphBuilder.groupNavigation(navController: NavHostController) { @@ -19,6 +26,18 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { GroupScreen( onNavigateToMakeRoom = { navController.navigateToGroupMakeRoom() + }, + onNavigateToGroupDone = { + navController.navigateToGroupDone() + }, + onNavigateToAlarm = { + navController.navigateToAlarm() + }, + onNavigateToGroupSearch = { + navController.navigateToGroupSearch() + }, + onNavigateToGroupMy = { + navController.navigateToGroupMy() } ) } @@ -36,4 +55,37 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { } ) } + + // Group Done 화면 + composable { + GroupDoneScreen( + name = "규빈", // TODO: ViewModel에서 가져오기 + allDataList = emptyList(), // TODO: ViewModel에서 가져오기 + onCardClick = { /* TODO: 카드 클릭 처리 */ }, + onNavigateBack = { + navController.navigateBack() + } + ) + } + + // Group My 화면 + composable { + GroupMyScreen( + allDataList = emptyList(), // TODO: ViewModel에서 가져오기 + onCardClick = { /* TODO: 카드 클릭 처리 */ }, + onNavigateBack = { + navController.navigateBack() + } + ) + } + + // Group Search 화면 + composable { + GroupSearchScreen( + roomList = emptyList(), // TODO: ViewModel에서 가져오기 + onNavigateBack = { + navController.navigateBack() + } + ) + } } \ 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 index e68d8268..061b76ad 100644 --- 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 @@ -7,9 +7,12 @@ 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 + @Serializable + data object Done : GroupRoutes() + + @Serializable + data object Search : GroupRoutes() + + @Serializable + data object My : GroupRoutes() } \ No newline at end of file From 0c901f73e36543013ba1f7a3c942a470c87668dd Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Sun, 27 Jul 2025 16:42:49 +0900 Subject: [PATCH 04/32] =?UTF-8?q?[feat]:=20=EB=84=A4=EB=B9=84=EA=B2=8C?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EB=A3=A8=ED=8A=B8,=20=ED=95=A8=EC=88=98?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EA=B7=B8=EB=A3=B9=20?= =?UTF-8?q?=EC=8A=A4=ED=81=AC=EB=A6=B0=EA=B3=BC=20=EC=97=B0=EA=B2=B0=20(#5?= =?UTF-8?q?8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../texthip/thip/ui/group/screen/GroupScreen.kt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) 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 95f8ecb7..45ac1222 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 @@ -13,7 +13,6 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource @@ -34,12 +33,15 @@ import com.texthip.thip.ui.theme.ThipTheme.colors @Composable fun GroupScreen( onNavigateToMakeRoom: () -> Unit = {}, + onNavigateToGroupDone: () -> Unit = {}, + onNavigateToAlarm: () -> Unit = {}, + onNavigateToGroupSearch: () -> Unit = {}, + onNavigateToGroupMy: () -> Unit = {}, viewModel: GroupViewModel = viewModel() ) { val myGroups by viewModel.myGroups.collectAsState() val roomSections by viewModel.roomSections.collectAsState() val scrollState = rememberScrollState() - val searchText by remember { mutableStateOf("") } Box( Modifier @@ -55,21 +57,19 @@ fun GroupScreen( LogoTopAppBar( leftIcon = painterResource(R.drawable.ic_done), hasNotification = false, - onLeftClick = { }, - onRightClick = { } + onLeftClick = onNavigateToGroupDone, + onRightClick = onNavigateToAlarm ) // 검색창 GroupSearchTextField( modifier = Modifier.padding(top = 16.dp, bottom = 32.dp), - value = searchText, - onValueChange = {}, - onClick = {} + onClick = onNavigateToGroupSearch ) // 내 모임방 헤더 + 카드 GroupMySectionHeader( - onClick = { viewModel.onMyGroupHeaderClick() } + onClick = onNavigateToGroupMy ) Spacer(Modifier.height(20.dp)) From df1f63a9765ab17905019db9d2687ea95076f7ea Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Sun, 27 Jul 2025 16:43:33 +0900 Subject: [PATCH 05/32] =?UTF-8?q?[feat]:=20=EC=95=8C=EB=9E=8C=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4,=20=EC=99=84=EB=A3=8C=20=ED=99=94=EB=A9=B4,=20?= =?UTF-8?q?=EB=82=B4=20=EB=AA=A8=EC=9E=84=EB=B0=A9=20=ED=99=94=EB=A9=B4,?= =?UTF-8?q?=20=EB=AA=A8=EC=9E=84=EB=B0=A9=20=EA=B2=80=EC=83=89=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EC=97=B0=EA=B2=B0=20=EB=B0=8F=20=EB=92=A4=EB=A1=9C?= =?UTF-8?q?=20=EA=B0=80=EA=B8=B0=20=EC=97=B0=EA=B2=B0=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../thip/ui/common/alarmpage/screen/AlarmScreen.kt | 9 ++++----- .../texthip/thip/ui/group/myroom/screen/GroupMyScreen.kt | 5 +++-- .../com/texthip/thip/ui/group/screen/GroupDoneScreen.kt | 5 +++-- .../thip/ui/group/search/screen/GroupSearchScreen.kt | 5 +++-- 4 files changed, 13 insertions(+), 11 deletions(-) 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 44f4e486..ec222abb 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 @@ -1,6 +1,5 @@ package com.texthip.thip.ui.common.alarmpage.screen -import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues @@ -10,7 +9,6 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -19,7 +17,6 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -34,7 +31,9 @@ import com.texthip.thip.ui.theme.ThipTheme.typography @Composable fun AlarmScreen( - alarmItems: List, onCardClick: (AlarmItem) -> Unit = {} + alarmItems: List, + onCardClick: (AlarmItem) -> Unit = {}, + onNavigateBack: () -> Unit = {} ) { var selectedStates by remember { mutableStateOf(booleanArrayOf(false, false)) } var alarms by remember { mutableStateOf(alarmItems) } @@ -51,7 +50,7 @@ fun AlarmScreen( ) { DefaultTopAppBar( title = stringResource(R.string.alarm_string), - onLeftClick = {}, + onLeftClick = onNavigateBack, ) Column( Modifier diff --git a/app/src/main/java/com/texthip/thip/ui/group/myroom/screen/GroupMyScreen.kt b/app/src/main/java/com/texthip/thip/ui/group/myroom/screen/GroupMyScreen.kt index 4df8b8fb..3cd3f584 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/myroom/screen/GroupMyScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/myroom/screen/GroupMyScreen.kt @@ -35,7 +35,8 @@ import com.texthip.thip.ui.theme.ThipTheme.typography @Composable fun GroupMyScreen( allDataList: List, - onCardClick: (GroupCardItemRoomData) -> Unit = {} + onCardClick: (GroupCardItemRoomData) -> Unit = {}, + onNavigateBack: () -> Unit = {} ) { var selectedStates by remember { mutableStateOf(booleanArrayOf(false, false)) } @@ -58,7 +59,7 @@ fun GroupMyScreen( ) { DefaultTopAppBar( title = stringResource(R.string.my_group_room), - onLeftClick = {}, + onLeftClick = onNavigateBack, ) Column( Modifier diff --git a/app/src/main/java/com/texthip/thip/ui/group/screen/GroupDoneScreen.kt b/app/src/main/java/com/texthip/thip/ui/group/screen/GroupDoneScreen.kt index e55b4d51..e5fe84fb 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/screen/GroupDoneScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/screen/GroupDoneScreen.kt @@ -27,7 +27,8 @@ import com.texthip.thip.ui.theme.ThipTheme.typography fun GroupDoneScreen( name: String, allDataList: List, - onCardClick: (GroupCardItemRoomData) -> Unit = {} + onCardClick: (GroupCardItemRoomData) -> Unit = {}, + onNavigateBack: () -> Unit = {} ) { // isRecruiting == false 인 방만 필터링 (혹시 몰라서 넣어둡니다) val doneList = remember(allDataList) { @@ -40,7 +41,7 @@ fun GroupDoneScreen( ) { DefaultTopAppBar( title = stringResource(R.string.group_done_title), - onLeftClick = {}, + onLeftClick = onNavigateBack, ) Column( Modifier diff --git a/app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt b/app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt index 00691975..e8d2e044 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt @@ -38,7 +38,8 @@ import com.texthip.thip.ui.theme.ThipTheme @Composable fun GroupSearchScreen( modifier: Modifier = Modifier, - roomList: List + roomList: List, + onNavigateBack: () -> Unit = {} ) { var recentSearches by rememberSaveable { mutableStateOf(listOf("user.02", "ㅇㅇ", "훽후ㅣㅣ", "검색4", "검색5", "검색6")) @@ -107,7 +108,7 @@ fun GroupSearchScreen( ) { DefaultTopAppBar( title = stringResource(R.string.group_room_search_topappbar), - onLeftClick = {}, + onLeftClick = onNavigateBack, ) Column( modifier = Modifier From 37ae32eea087586adbeb87d60221f9b8515f1d25 Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Sun, 27 Jul 2025 16:59:05 +0900 Subject: [PATCH 06/32] =?UTF-8?q?[feat]:=20SharedPreferences=EB=A5=BC=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=ED=99=94=EB=A9=B4=EC=9D=84=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../group/search/screen/GroupSearchScreen.kt | 28 ++++++++++++++++--- .../thip/ui/search/screen/SearchBookScreen.kt | 28 ++++++++++++++++--- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt b/app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt index e8d2e044..f3ad570f 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt @@ -20,10 +20,12 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import android.content.Context import com.texthip.thip.R import com.texthip.thip.ui.common.buttons.FilterButton import com.texthip.thip.ui.common.forms.SearchBookTextField @@ -41,8 +43,24 @@ fun GroupSearchScreen( roomList: List, onNavigateBack: () -> Unit = {} ) { - var recentSearches by rememberSaveable { - mutableStateOf(listOf("user.02", "ㅇㅇ", "훽후ㅣㅣ", "검색4", "검색5", "검색6")) + val context = LocalContext.current + val sharedPrefs = remember { + context.getSharedPreferences("group_search_prefs", Context.MODE_PRIVATE) + } + + // SharedPreferences에서 최근 검색어 불러오기 + var recentSearches by remember { + mutableStateOf( + sharedPrefs.getStringSet("recent_searches", emptySet())?.toList() ?: emptyList() + ) + } + + // 최근 검색어를 SharedPreferences에 저장하는 함수 + fun saveRecentSearches(searches: List) { + sharedPrefs.edit() + .putStringSet("recent_searches", searches.toSet()) + .apply() + recentSearches = searches } var searchText by rememberSaveable { mutableStateOf("") } var isSearched by rememberSaveable { mutableStateOf(false) } @@ -129,7 +147,8 @@ fun GroupSearchScreen( }, onSearch = { query -> if (query.isNotBlank() && !recentSearches.contains(query)) { - recentSearches = listOf(query) + recentSearches + val newSearches = listOf(query) + recentSearches.take(9) // 최대 10개 유지 + saveRecentSearches(newSearches) } isSearched = true selectedGenreIndex = -1 @@ -154,7 +173,8 @@ fun GroupSearchScreen( isSearched = true }, onRemove = { keyword -> - recentSearches = recentSearches.filterNot { it == keyword } + val updatedSearches = recentSearches.filterNot { it == keyword } + saveRecentSearches(updatedSearches) } ) } diff --git a/app/src/main/java/com/texthip/thip/ui/search/screen/SearchBookScreen.kt b/app/src/main/java/com/texthip/thip/ui/search/screen/SearchBookScreen.kt index efa3f02d..d9febbc7 100644 --- a/app/src/main/java/com/texthip/thip/ui/search/screen/SearchBookScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/search/screen/SearchBookScreen.kt @@ -18,11 +18,13 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.navigation.NavHostController +import android.content.Context import com.texthip.thip.R import com.texthip.thip.ui.search.component.SearchEmptyResult import com.texthip.thip.ui.search.component.SearchBookFilteredResult @@ -40,8 +42,24 @@ fun SearchBookScreen( bookList: List = emptyList(), popularBooks: List = emptyList() ) { - var recentSearches by rememberSaveable { - mutableStateOf(listOf("asd", "qwe", "xcv", "dfggfd", "asdasd", "gfhjghj")) + val context = LocalContext.current + val sharedPrefs = remember { + context.getSharedPreferences("book_search_prefs", Context.MODE_PRIVATE) + } + + // SharedPreferences에서 최근 검색어 불러오기 + var recentSearches by remember { + mutableStateOf( + sharedPrefs.getStringSet("recent_book_searches", emptySet())?.toList() ?: emptyList() + ) + } + + // 최근 검색어를 SharedPreferences에 저장하는 함수 + fun saveRecentSearches(searches: List) { + sharedPrefs.edit() + .putStringSet("recent_book_searches", searches.toSet()) + .apply() + recentSearches = searches } var searchText by rememberSaveable { mutableStateOf("") } var isSearched by rememberSaveable { mutableStateOf(false) } @@ -107,7 +125,8 @@ fun SearchBookScreen( }, onSearch = { query -> if (query.isNotBlank() && !recentSearches.contains(query)) { - recentSearches = listOf(query) + recentSearches + val newSearches = listOf(query) + recentSearches.take(9) // 최대 10개 유지 + saveRecentSearches(newSearches) } isSearched = true } @@ -125,7 +144,8 @@ fun SearchBookScreen( isSearched = true }, onRemove = { keyword -> - recentSearches = recentSearches.filterNot { it == keyword } + val updatedSearches = recentSearches.filterNot { it == keyword } + saveRecentSearches(updatedSearches) }, onBookClick = { book -> // 책 클릭 시 처리 From 03473272511138e80daafc1345e44252f4f57527 Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Sun, 27 Jul 2025 17:02:30 +0900 Subject: [PATCH 07/32] =?UTF-8?q?[feat]:=20=EA=B7=B8=EB=A3=B9=EA=B3=BC=20?= =?UTF-8?q?=EC=95=8C=EB=9E=8C=ED=99=94=EB=A9=B4=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EB=B7=B0=EB=AA=A8=EB=8D=B8=EC=97=90=EC=84=9C=20=EC=9E=84?= =?UTF-8?q?=EC=8B=9C=20=EB=8D=B0=EC=9D=B4=ED=84=B0=EB=A5=BC=20=EA=B0=80?= =?UTF-8?q?=EC=A0=B8=EC=98=A4=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95=20(#5?= =?UTF-8?q?8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../alarmpage/viewmodel/AlarmViewModel.kt | 27 ++++++++++++++ .../thip/ui/group/viewmodel/GroupViewModel.kt | 35 +++++++++++++++++-- .../navigator/navigations/CommonNavigation.kt | 11 ++++-- .../navigator/navigations/GroupNavigation.kt | 25 +++++++++---- 4 files changed, 87 insertions(+), 11 deletions(-) create mode 100644 app/src/main/java/com/texthip/thip/ui/common/alarmpage/viewmodel/AlarmViewModel.kt diff --git a/app/src/main/java/com/texthip/thip/ui/common/alarmpage/viewmodel/AlarmViewModel.kt b/app/src/main/java/com/texthip/thip/ui/common/alarmpage/viewmodel/AlarmViewModel.kt new file mode 100644 index 00000000..bba60b6b --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/common/alarmpage/viewmodel/AlarmViewModel.kt @@ -0,0 +1,27 @@ +package com.texthip.thip.ui.common.alarmpage.viewmodel + +import androidx.lifecycle.ViewModel +import com.texthip.thip.ui.common.alarmpage.mock.AlarmItem +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow + +class AlarmViewModel : ViewModel() { + private val _alarmItems = MutableStateFlow>(emptyList()) + val alarmItems: StateFlow> = _alarmItems.asStateFlow() + + init { + _alarmItems.value = listOf( + AlarmItem(1, "피드", "내 글을 좋아합니다.", "user123님이 내 글에 좋아요를 눌렀어요.", "2시간 전", false), + AlarmItem(2, "모임", "같이 읽기를 시작했어요!", "모임방에서 20분 동안 같이 읽기가 시작되었어요!", "7시간 전", false), + AlarmItem(3, "피드", "내 글에 댓글이 달렸어요.", "user1: 진짜 공감합니다!", "2025.01.12", true), + AlarmItem(4, "모임", "투표가 시작되었어요!", "투표지를 먼저 열람합니다.", "17시간 전", false), + AlarmItem(5, "피드", "팔로워가 새 글을 올렸어요.", "user456님이 새 리뷰를 작성했습니다.", "1일 전", true), + AlarmItem(6, "모임", "새로운 모임방 초대", "호르몬 체인지 완독하는 방에 초대되었습니다.", "2일 전", false) + ) + } + + fun onCardClick(item: AlarmItem) { + // TODO: 알림 카드 클릭 처리 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt b/app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt index ded195d8..6ff00743 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt @@ -16,6 +16,18 @@ class GroupViewModel : ViewModel() { private val _roomSections = MutableStateFlow>(emptyList()) val roomSections: StateFlow> = _roomSections + private val _userName = MutableStateFlow("규빈") // 임시 유저 이름 + val userName: StateFlow = _userName + + private val _doneGroups = MutableStateFlow>(emptyList()) + val doneGroups: StateFlow> = _doneGroups + + private val _myRoomGroups = MutableStateFlow>(emptyList()) + val myRoomGroups: StateFlow> = _myRoomGroups + + private val _searchGroups = MutableStateFlow>(emptyList()) + val searchGroups: StateFlow> = _searchGroups + private val _genres = listOf("문학", "과학·IT", "사회과학", "인문학", "예술") val genres: List get() = _genres @@ -73,10 +85,27 @@ class GroupViewModel : ViewModel() { genres = _genres ) ) - } - fun onMyGroupHeaderClick() { - // 내 모임방 리스트로 이동 (Nav 이벤트 트리거 등) + // 완료된 모임방 데이터 + _doneGroups.value = listOf( + GroupCardItemRoomData("완료된 독서 모임방 1", 15, 20, false, null, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData("완료된 독서 모임방 2", 25, 30, false, null, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData("완료된 독서 모임방 3", 12, 15, false, null, R.drawable.bookcover_sample, 2), + GroupCardItemRoomData("호르몬 체인지 완독한 방", 22, 22, false, null, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData("명작 읽기방 완료", 10, 10, false, null, R.drawable.bookcover_sample, 0) + ) + + // 내 모임방 데이터 + _myRoomGroups.value = listOf( + GroupCardItemRoomData("호르몬 체인지 완독하는 방", 22, 30, true, 5, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData("명작 읽기방", 10, 20, true, 3, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData("또 다른 방", 13, 25, false, 10, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData("내가 참여한 과학책방", 18, 25, true, 7, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData("인문학 토론방", 12, 20, true, 2, R.drawable.bookcover_sample, 3) + ) + + // 검색용 모임방 데이터 (모든 모임방 합쳐서) + _searchGroups.value = deadlineRooms + popularRooms + influencerRooms } fun onMyGroupCardClick(data: GroupCardData) { diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/navigations/CommonNavigation.kt b/app/src/main/java/com/texthip/thip/ui/navigator/navigations/CommonNavigation.kt index 934c1869..2e7d3242 100644 --- a/app/src/main/java/com/texthip/thip/ui/navigator/navigations/CommonNavigation.kt +++ b/app/src/main/java/com/texthip/thip/ui/navigator/navigations/CommonNavigation.kt @@ -1,9 +1,13 @@ 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 androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue import com.texthip.thip.ui.common.alarmpage.screen.AlarmScreen +import com.texthip.thip.ui.common.alarmpage.viewmodel.AlarmViewModel import com.texthip.thip.ui.navigator.routes.CommonRoutes import com.texthip.thip.ui.navigator.extensions.navigateBack @@ -11,9 +15,12 @@ import com.texthip.thip.ui.navigator.extensions.navigateBack fun NavGraphBuilder.commonNavigation(navController: NavHostController) { // Alarm 화면 composable { + val alarmViewModel: AlarmViewModel = viewModel() + val alarmItems by alarmViewModel.alarmItems.collectAsState() + AlarmScreen( - alarmItems = emptyList(), // TODO: ViewModel에서 가져오기 - onCardClick = { /* TODO: 알림 카드 클릭 처리 */ }, + alarmItems = alarmItems, + onCardClick = { alarmViewModel.onCardClick(it) }, onNavigateBack = { navController.navigateBack() } 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 index 794e50d3..b8e94539 100644 --- 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 @@ -4,12 +4,15 @@ import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController import androidx.navigation.compose.composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue 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.group.screen.GroupDoneScreen import com.texthip.thip.ui.group.myroom.screen.GroupMyScreen import com.texthip.thip.ui.group.search.screen.GroupSearchScreen +import com.texthip.thip.ui.group.viewmodel.GroupViewModel import com.texthip.thip.ui.navigator.routes.MainTabRoutes import com.texthip.thip.ui.navigator.routes.GroupRoutes import com.texthip.thip.ui.navigator.extensions.navigateBack @@ -58,10 +61,14 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { // Group Done 화면 composable { + val groupViewModel: GroupViewModel = viewModel() + val userName by groupViewModel.userName.collectAsState() + val doneGroups by groupViewModel.doneGroups.collectAsState() + GroupDoneScreen( - name = "규빈", // TODO: ViewModel에서 가져오기 - allDataList = emptyList(), // TODO: ViewModel에서 가져오기 - onCardClick = { /* TODO: 카드 클릭 처리 */ }, + name = userName, + allDataList = doneGroups, + onCardClick = { groupViewModel.onRoomCardClick(it) }, onNavigateBack = { navController.navigateBack() } @@ -70,9 +77,12 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { // Group My 화면 composable { + val groupViewModel: GroupViewModel = viewModel() + val myRoomGroups by groupViewModel.myRoomGroups.collectAsState() + GroupMyScreen( - allDataList = emptyList(), // TODO: ViewModel에서 가져오기 - onCardClick = { /* TODO: 카드 클릭 처리 */ }, + allDataList = myRoomGroups, + onCardClick = { groupViewModel.onRoomCardClick(it) }, onNavigateBack = { navController.navigateBack() } @@ -81,8 +91,11 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { // Group Search 화면 composable { + val groupViewModel: GroupViewModel = viewModel() + val searchGroups by groupViewModel.searchGroups.collectAsState() + GroupSearchScreen( - roomList = emptyList(), // TODO: ViewModel에서 가져오기 + roomList = searchGroups, onNavigateBack = { navController.navigateBack() } From 068127b9d81f78c06e3e956dc4d4f586fcf39e11 Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Sun, 27 Jul 2025 22:59:04 +0900 Subject: [PATCH 08/32] =?UTF-8?q?[feat]:=20=EB=AA=A8=EC=9E=84=EB=B0=A9=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=EC=97=90=20id(Int)=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=8F=20id=EB=A1=9C=20=EB=B0=A9=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component/GroupDeadlineRoomSection.kt | 12 ++ .../myroom/mock/GroupCardItemRoomData.kt | 1 + .../ui/group/myroom/mock/GroupRoomData.kt | 1 + .../room/screen/GroupRoomRecruitScreen.kt | 14 +++ .../thip/ui/group/screen/GroupDoneScreen.kt | 9 +- .../thip/ui/group/viewmodel/GroupViewModel.kt | 114 +++++++++++++----- .../ui/search/screen/SearchBookGroupScreen.kt | 8 ++ 7 files changed, 129 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/com/texthip/thip/ui/group/myroom/component/GroupDeadlineRoomSection.kt b/app/src/main/java/com/texthip/thip/ui/group/myroom/component/GroupDeadlineRoomSection.kt index bf956155..fa6984c4 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/myroom/component/GroupDeadlineRoomSection.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/myroom/component/GroupDeadlineRoomSection.kt @@ -189,6 +189,7 @@ fun PreviewGroupRoomPagerSection() { // 마감 임박한 독서 모임방 val deadlineRooms = listOf( GroupCardItemRoomData( + id = 1, title = "시집만 읽는 사람들 3월", participants = 22, maxParticipants = 30, @@ -197,6 +198,7 @@ fun PreviewGroupRoomPagerSection() { genreIndex = 0 ), GroupCardItemRoomData( + id = 2, title = "일본 소설 좋아하는 사람들", participants = 15, maxParticipants = 20, @@ -205,6 +207,7 @@ fun PreviewGroupRoomPagerSection() { genreIndex = 0 ), GroupCardItemRoomData( + id = 3, title = "명작 같이 읽기방", participants = 22, maxParticipants = 30, @@ -213,6 +216,7 @@ fun PreviewGroupRoomPagerSection() { genreIndex = 0 ), GroupCardItemRoomData( + id = 4, title = "명작 같이 읽기방", participants = 22, maxParticipants = 30, @@ -221,6 +225,7 @@ fun PreviewGroupRoomPagerSection() { genreIndex = 0 ), GroupCardItemRoomData( + id = 5, title = "물리책 읽는 방", participants = 13, maxParticipants = 20, @@ -233,6 +238,7 @@ fun PreviewGroupRoomPagerSection() { // 인기 있는 독서 모임방 val popularRooms = listOf( GroupCardItemRoomData( + id = 6, title = "베스트셀러 토론방", participants = 28, maxParticipants = 30, @@ -241,6 +247,7 @@ fun PreviewGroupRoomPagerSection() { genreIndex = 0 ), GroupCardItemRoomData( + id = 7, title = "인기 소설 완독방", participants = 25, maxParticipants = 25, @@ -249,6 +256,7 @@ fun PreviewGroupRoomPagerSection() { genreIndex = 0 ), GroupCardItemRoomData( + id = 8, title = "트렌드 과학서 읽기", participants = 20, maxParticipants = 25, @@ -261,6 +269,7 @@ fun PreviewGroupRoomPagerSection() { // 인플루언서, 작가 독서 모임방 val influencerRooms = listOf( GroupCardItemRoomData( + id = 9, title = "작가와 함께하는 독서방", participants = 30, maxParticipants = 30, @@ -269,6 +278,7 @@ fun PreviewGroupRoomPagerSection() { genreIndex = 0 ), GroupCardItemRoomData( + id = 10, title = "유명 북튜버와 읽기", participants = 18, maxParticipants = 20, @@ -277,6 +287,7 @@ fun PreviewGroupRoomPagerSection() { genreIndex = 2 ), GroupCardItemRoomData( + id = 11, title = "작가 초청 인문학방", participants = 15, maxParticipants = 20, @@ -320,6 +331,7 @@ fun PreviewGroupRoomPagerSectionEmptyGenre() { // 특정 장르에만 데이터가 있는 경우 (문학 장르만 데이터 존재) val deadlineRooms = listOf( GroupCardItemRoomData( + id = 12, title = "시집만 읽는 사람들 3월", participants = 22, maxParticipants = 30, diff --git a/app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupCardItemRoomData.kt b/app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupCardItemRoomData.kt index 11f779c9..00a64c30 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupCardItemRoomData.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupCardItemRoomData.kt @@ -3,6 +3,7 @@ package com.texthip.thip.ui.group.myroom.mock import com.texthip.thip.R data class GroupCardItemRoomData( + val id: Int, val title: String, val participants: Int, val maxParticipants: Int, diff --git a/app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupRoomData.kt b/app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupRoomData.kt index 55468f20..4a227a4c 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupRoomData.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupRoomData.kt @@ -1,6 +1,7 @@ package com.texthip.thip.ui.group.myroom.mock data class GroupRoomData( + val id: Int, val title: String, val isSecret: Boolean, val description: String, diff --git a/app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomRecruitScreen.kt b/app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomRecruitScreen.kt index a0cf9125..4ff90801 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomRecruitScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomRecruitScreen.kt @@ -436,6 +436,7 @@ fun GroupRoomRecruitScreenPreviewJoin() { ThipTheme { val recommendations = listOf( GroupCardItemRoomData( + id = 1, title = "일본 소설 좋아하는 사람들 일본 소설 좋아하는 사람들", participants = 19, maxParticipants = 25, @@ -444,6 +445,7 @@ fun GroupRoomRecruitScreenPreviewJoin() { genreIndex = 0 ), GroupCardItemRoomData( + id = 2, title = "일본 소설 좋아하는 사람들 일본 소설 좋아하는 사람들", participants = 12, maxParticipants = 16, @@ -452,6 +454,7 @@ fun GroupRoomRecruitScreenPreviewJoin() { genreIndex = 0 ), GroupCardItemRoomData( + id = 3, title = "일본 소설 좋아하는 사람들 일본 소설 좋아하는 사람들", participants = 30, maxParticipants = 30, @@ -460,6 +463,7 @@ fun GroupRoomRecruitScreenPreviewJoin() { genreIndex = 0 ), GroupCardItemRoomData( + id = 4, title = "일본 소설 좋아하는 사람들 일본 소설 좋아하는 사람들", participants = 10, maxParticipants = 12, @@ -468,6 +472,7 @@ fun GroupRoomRecruitScreenPreviewJoin() { genreIndex = 0 ), GroupCardItemRoomData( + id = 5, title = "에세이 나눔방", participants = 14, maxParticipants = 20, @@ -486,6 +491,7 @@ fun GroupRoomRecruitScreenPreviewJoin() { ) val detailJoin = GroupRoomData( + id = 1, title = "시집만 읽는 사람들 3월", isSecret = true, description = "'시집만 읽는 사람들' 3월 모임입니다. 이번 달 모임에서는 심장보다 단단한 토마토 한 알을 함께 읽어요.", @@ -517,6 +523,7 @@ fun GroupRoomRecruitScreenPreviewCancel() { ThipTheme { val recommendations = listOf( GroupCardItemRoomData( + id = 6, title = "일본 소설 좋아하는 사람들 일본 소설 좋아하는 사람들", participants = 19, maxParticipants = 25, @@ -525,6 +532,7 @@ fun GroupRoomRecruitScreenPreviewCancel() { genreIndex = 0 ), GroupCardItemRoomData( + id = 7, title = "일본 소설 좋아하는 사람들 일본 소설 좋아하는 사람들", participants = 12, maxParticipants = 16, @@ -533,6 +541,7 @@ fun GroupRoomRecruitScreenPreviewCancel() { genreIndex = 0 ), GroupCardItemRoomData( + id = 8, title = "에세이 나눔방", participants = 14, maxParticipants = 20, @@ -551,6 +560,7 @@ fun GroupRoomRecruitScreenPreviewCancel() { ) val detailCancel = GroupRoomData( + id = 2, title = "시집만 읽는 사람들 3월", isSecret = true, description = "'시집만 읽는 사람들' 3월 모임입니다. 이번 달 모임에서는 심장보다 단단한 토마토 한 알을 함께 읽어요.", @@ -582,6 +592,7 @@ fun GroupRoomRecruitScreenClose() { ThipTheme { val recommendations = listOf( GroupCardItemRoomData( + id = 9, title = "일본 소설 좋아하는 사람들 일본 소설 좋아하는 사람들", participants = 19, maxParticipants = 25, @@ -590,6 +601,7 @@ fun GroupRoomRecruitScreenClose() { genreIndex = 0 ), GroupCardItemRoomData( + id = 10, title = "일본 소설 좋아하는 사람들 일본 소설 좋아하는 사람들", participants = 12, maxParticipants = 16, @@ -598,6 +610,7 @@ fun GroupRoomRecruitScreenClose() { genreIndex = 0 ), GroupCardItemRoomData( + id = 11, title = "미스터리 소설 탐구", participants = 8, maxParticipants = 15, @@ -616,6 +629,7 @@ fun GroupRoomRecruitScreenClose() { ) val detailClose = GroupRoomData( + id = 3, title = "시집만 읽는 사람들 3월", isSecret = false, // 오픈방으로 변경 description = "'시집만 읽는 사람들' 3월 모임입니다. 이번 달 모임에서는 심장보다 단단한 토마토 한 알을 함께 읽어요. 모임장이 모집을 마감할 수 있는 상태입니다.", diff --git a/app/src/main/java/com/texthip/thip/ui/group/screen/GroupDoneScreen.kt b/app/src/main/java/com/texthip/thip/ui/group/screen/GroupDoneScreen.kt index e5fe84fb..9ab058b2 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/screen/GroupDoneScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/screen/GroupDoneScreen.kt @@ -30,7 +30,6 @@ fun GroupDoneScreen( onCardClick: (GroupCardItemRoomData) -> Unit = {}, onNavigateBack: () -> Unit = {} ) { - // isRecruiting == false 인 방만 필터링 (혹시 몰라서 넣어둡니다) val doneList = remember(allDataList) { allDataList.filter { !it.isRecruiting } } @@ -83,12 +82,13 @@ fun GroupDoneScreen( -@Preview() +@Preview @Composable fun MyGroupListFilterScreenPreview() { ThipTheme { val dataList = listOf( GroupCardItemRoomData( + id = 1, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, @@ -96,6 +96,7 @@ fun MyGroupListFilterScreenPreview() { genreIndex = 0 ), GroupCardItemRoomData( + id = 2, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, @@ -103,6 +104,7 @@ fun MyGroupListFilterScreenPreview() { genreIndex = 0 ), GroupCardItemRoomData( + id = 3, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, @@ -110,6 +112,7 @@ fun MyGroupListFilterScreenPreview() { genreIndex = 0 ), GroupCardItemRoomData( + id = 4, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, @@ -117,6 +120,7 @@ fun MyGroupListFilterScreenPreview() { genreIndex = 0 ), GroupCardItemRoomData( + id = 5, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, @@ -124,6 +128,7 @@ fun MyGroupListFilterScreenPreview() { genreIndex = 0 ), GroupCardItemRoomData( + id = 6, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, diff --git a/app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt b/app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt index 6ff00743..df79abbc 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt @@ -5,6 +5,8 @@ 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 com.texthip.thip.ui.group.myroom.mock.GroupRoomData +import com.texthip.thip.ui.group.myroom.mock.GroupBookData import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -31,6 +33,9 @@ class GroupViewModel : ViewModel() { private val _genres = listOf("문학", "과학·IT", "사회과학", "인문학", "예술") val genres: List get() = _genres + // 모든 모임방 데이터 (ID로 조회하기 위한 맵) + private val _allRoomDetails = mutableMapOf() + // 초기 데이터 세팅 (실제에선 repository/remote에서 받아옴) init { _myGroups.value = listOf( @@ -41,31 +46,31 @@ class GroupViewModel : ViewModel() { // 마감 임박한 독서 모임방 val deadlineRooms = listOf( - GroupCardItemRoomData("시집만 읽는 사람들 3월", 22, 30, true, 3, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData("일본 소설 좋아하는 사람들", 15, 20, true, 2, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData("명작 같이 읽기방", 22, 30, true, 3, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData("물리책 읽는 방", 13, 20, true, 1, R.drawable.bookcover_sample, 1), - GroupCardItemRoomData("코딩 과학 동아리", 12, 15, true, 5, R.drawable.bookcover_sample, 1), - GroupCardItemRoomData("사회과학 인문 탐구", 8, 12, true, 4, R.drawable.bookcover_sample, 2) + GroupCardItemRoomData(1, "시집만 읽는 사람들 3월", 22, 30, true, 3, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(2, "일본 소설 좋아하는 사람들", 15, 20, true, 2, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(3, "명작 같이 읽기방", 22, 30, true, 3, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(4, "물리책 읽는 방", 13, 20, true, 1, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(5, "코딩 과학 동아리", 12, 15, true, 5, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(6, "사회과학 인문 탐구", 8, 12, true, 4, R.drawable.bookcover_sample, 2) ) // 인기 있는 독서 모임방 val popularRooms = listOf( - GroupCardItemRoomData("베스트셀러 토론방", 28, 30, true, 7, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData("인기 소설 완독방", 25, 25, false, 5, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData("트렌드 과학서 읽기", 20, 25, true, 10, R.drawable.bookcover_sample, 1), - GroupCardItemRoomData("화제의 경영서", 18, 20, true, 8, R.drawable.bookcover_sample, 2), - GroupCardItemRoomData("인기 철학서 모임", 15, 18, true, 12, R.drawable.bookcover_sample, 3), - GroupCardItemRoomData("예술서 베스트", 12, 15, true, 6, R.drawable.bookcover_sample, 4) + GroupCardItemRoomData(7, "베스트셀러 토론방", 28, 30, true, 7, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(8, "인기 소설 완독방", 25, 25, false, 5, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(9, "트렌드 과학서 읽기", 20, 25, true, 10, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(10, "화제의 경영서", 18, 20, true, 8, R.drawable.bookcover_sample, 2), + GroupCardItemRoomData(11, "인기 철학서 모임", 15, 18, true, 12, R.drawable.bookcover_sample, 3), + GroupCardItemRoomData(12, "예술서 베스트", 12, 15, true, 6, R.drawable.bookcover_sample, 4) ) // 인플루언서, 작가 독서 모임방 val influencerRooms = listOf( - GroupCardItemRoomData("작가와 함께하는 독서방", 30, 30, false, 14, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData("유명 북튜버와 읽기", 18, 20, true, 8, R.drawable.bookcover_sample, 2), - GroupCardItemRoomData("작가 초청 인문학방", 15, 20, true, 12, R.drawable.bookcover_sample, 3), - GroupCardItemRoomData("인플루언서 과학책", 22, 25, true, 9, R.drawable.bookcover_sample, 1), - GroupCardItemRoomData("유명작가 예술론", 16, 18, true, 11, R.drawable.bookcover_sample, 4) + GroupCardItemRoomData(13, "작가와 함께하는 독서방", 30, 30, false, 14, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(14, "유명 북튜버와 읽기", 18, 20, true, 8, R.drawable.bookcover_sample, 2), + GroupCardItemRoomData(15, "작가 초청 인문학방", 15, 20, true, 12, R.drawable.bookcover_sample, 3), + GroupCardItemRoomData(16, "인플루언서 과학책", 22, 25, true, 9, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(17, "유명작가 예술론", 16, 18, true, 11, R.drawable.bookcover_sample, 4) ) _roomSections.value = listOf( @@ -88,32 +93,85 @@ class GroupViewModel : ViewModel() { // 완료된 모임방 데이터 _doneGroups.value = listOf( - GroupCardItemRoomData("완료된 독서 모임방 1", 15, 20, false, null, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData("완료된 독서 모임방 2", 25, 30, false, null, R.drawable.bookcover_sample, 1), - GroupCardItemRoomData("완료된 독서 모임방 3", 12, 15, false, null, R.drawable.bookcover_sample, 2), - GroupCardItemRoomData("호르몬 체인지 완독한 방", 22, 22, false, null, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData("명작 읽기방 완료", 10, 10, false, null, R.drawable.bookcover_sample, 0) + GroupCardItemRoomData(18, "완료된 독서 모임방 1", 15, 20, false, null, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(19, "완료된 독서 모임방 2", 25, 30, false, null, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(20, "완료된 독서 모임방 3", 12, 15, false, null, R.drawable.bookcover_sample, 2), + GroupCardItemRoomData(21, "호르몬 체인지 완독한 방", 22, 22, false, null, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(22, "명작 읽기방 완료", 10, 10, false, null, R.drawable.bookcover_sample, 0) ) // 내 모임방 데이터 _myRoomGroups.value = listOf( - GroupCardItemRoomData("호르몬 체인지 완독하는 방", 22, 30, true, 5, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData("명작 읽기방", 10, 20, true, 3, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData("또 다른 방", 13, 25, false, 10, R.drawable.bookcover_sample, 1), - GroupCardItemRoomData("내가 참여한 과학책방", 18, 25, true, 7, R.drawable.bookcover_sample, 1), - GroupCardItemRoomData("인문학 토론방", 12, 20, true, 2, R.drawable.bookcover_sample, 3) + GroupCardItemRoomData(23, "호르몬 체인지 완독하는 방", 22, 30, true, 5, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(24, "명작 읽기방", 10, 20, true, 3, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(25, "또 다른 방", 13, 25, false, 10, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(26, "내가 참여한 과학책방", 18, 25, true, 7, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(27, "인문학 토론방", 12, 20, true, 2, R.drawable.bookcover_sample, 3) ) // 검색용 모임방 데이터 (모든 모임방 합쳐서) _searchGroups.value = deadlineRooms + popularRooms + influencerRooms + + // 상세 모임방 데이터 초기화 (모든 모임방 데이터 포함) + val allRooms = deadlineRooms + popularRooms + influencerRooms + _doneGroups.value + _myRoomGroups.value + initializeRoomDetails(allRooms) } fun onMyGroupCardClick(data: GroupCardData) { // 내 모임방 카드 클릭 (상세 진입) } - fun onRoomCardClick(data: GroupCardItemRoomData) { + fun onRoomCardClick( + data: GroupCardItemRoomData, + onNavigateToRecruit: (Int) -> Unit, + onNavigateToRoom: (Int) -> Unit + ) { // 방 카드 클릭 (상세 진입) + if (data.isRecruiting) { + onNavigateToRecruit(data.id) + } else { + onNavigateToRoom(data.id) + } + } + + // 상세 모임방 데이터 초기화 (임시 예시) + private fun initializeRoomDetails(rooms: List) { + rooms.forEach { room -> + val bookData = GroupBookData( + title = "심장보다 단단한 토마토 한 알", + author = "고선지", + publisher = "푸른출판사", + description = "${room.title}에서 읽는 책입니다. 감동적인 이야기로 가득한 작품입니다.", + imageRes = room.imageRes ?: R.drawable.bookcover_sample + ) + + val roomDetail = GroupRoomData( + id = room.id, + title = room.title, + isSecret = room.isSecret, + description = "${room.title} 모임입니다. 함께 책을 읽고 토론해요.", + startDate = "2025.01.12", + endDate = "2025.02.12", + members = room.participants, + maxMembers = room.maxParticipants, + daysLeft = room.endDate ?: 0, + genre = _genres[room.genreIndex], + bookData = bookData, + recommendations = getRecommendations(room.id) + ) + + _allRoomDetails[room.id] = roomDetail + } + } + + // 추천 모임방 가져오기 (간단한 더미 로직) + private fun getRecommendations(roomId: Int): List { + return _searchGroups.value.filter { it.id != roomId }.take(3) + } + + // ID로 모임방 상세 정보 조회 + fun getRoomDetail(roomId: Int): GroupRoomData? { + return _allRoomDetails[roomId] } } \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/search/screen/SearchBookGroupScreen.kt b/app/src/main/java/com/texthip/thip/ui/search/screen/SearchBookGroupScreen.kt index f21c0ff3..c181a487 100644 --- a/app/src/main/java/com/texthip/thip/ui/search/screen/SearchBookGroupScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/search/screen/SearchBookGroupScreen.kt @@ -145,6 +145,7 @@ fun GroupRecruitingScreenPreview() { ThipTheme { val dataList = listOf( GroupCardItemRoomData( + id = 1, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, @@ -153,6 +154,7 @@ fun GroupRecruitingScreenPreview() { genreIndex = 0 ), GroupCardItemRoomData( + id = 2, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, @@ -161,6 +163,7 @@ fun GroupRecruitingScreenPreview() { genreIndex = 0 ), GroupCardItemRoomData( + id = 3, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, @@ -169,6 +172,7 @@ fun GroupRecruitingScreenPreview() { genreIndex = 0 ), GroupCardItemRoomData( + id = 4, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, @@ -177,6 +181,7 @@ fun GroupRecruitingScreenPreview() { genreIndex = 0 ), GroupCardItemRoomData( + id = 5, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, @@ -185,6 +190,7 @@ fun GroupRecruitingScreenPreview() { genreIndex = 0 ), GroupCardItemRoomData( + id = 6, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, @@ -193,6 +199,7 @@ fun GroupRecruitingScreenPreview() { genreIndex = 0 ), GroupCardItemRoomData( + id = 7, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, @@ -201,6 +208,7 @@ fun GroupRecruitingScreenPreview() { genreIndex = 0 ), GroupCardItemRoomData( + id = 8, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, From c9429966d1c3a755bf32d9c1c808944b30192a73 Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Sun, 27 Jul 2025 23:05:12 +0900 Subject: [PATCH 09/32] =?UTF-8?q?[feat]:=20=EB=84=A4=EB=B9=84=EA=B2=8C?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EB=A3=A8=ED=8A=B8=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EB=B0=8F=20=EC=97=B0=EA=B2=B0=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../extensions/GroupNavigationExtensions.kt | 8 ++ .../navigator/navigations/GroupNavigation.kt | 99 ++++++++++++++++++- .../thip/ui/navigator/routes/GroupRoutes.kt | 6 ++ 3 files changed, 111 insertions(+), 2 deletions(-) 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 index 80434826..d7651967 100644 --- 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 @@ -29,4 +29,12 @@ fun NavHostController.navigateToGroupMy() { fun NavHostController.navigateToAlarm() { navigate(CommonRoutes.Alarm) +} + +fun NavHostController.navigateToGroupRecruit(roomId: Int) { + navigate(GroupRoutes.Recruit(roomId)) +} + +fun NavHostController.navigateToGroupRoom(roomId: Int) { + navigate(GroupRoutes.Room(roomId)) } \ 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 index b8e94539..a49ced5e 100644 --- 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 @@ -4,6 +4,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController import androidx.navigation.compose.composable +import androidx.navigation.toRoute import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import com.texthip.thip.ui.group.makeroom.screen.GroupMakeRoomScreen @@ -12,7 +13,10 @@ import com.texthip.thip.ui.group.screen.GroupScreen import com.texthip.thip.ui.group.screen.GroupDoneScreen import com.texthip.thip.ui.group.myroom.screen.GroupMyScreen import com.texthip.thip.ui.group.search.screen.GroupSearchScreen +import com.texthip.thip.ui.group.room.screen.GroupRoomRecruitScreen +import com.texthip.thip.ui.group.room.screen.GroupRoomScreen import com.texthip.thip.ui.group.viewmodel.GroupViewModel +import com.texthip.thip.ui.group.myroom.mock.GroupBottomButtonType import com.texthip.thip.ui.navigator.routes.MainTabRoutes import com.texthip.thip.ui.navigator.routes.GroupRoutes import com.texthip.thip.ui.navigator.extensions.navigateBack @@ -21,6 +25,8 @@ import com.texthip.thip.ui.navigator.extensions.navigateToGroupDone import com.texthip.thip.ui.navigator.extensions.navigateToGroupSearch import com.texthip.thip.ui.navigator.extensions.navigateToGroupMy import com.texthip.thip.ui.navigator.extensions.navigateToAlarm +import com.texthip.thip.ui.navigator.extensions.navigateToGroupRecruit +import com.texthip.thip.ui.navigator.extensions.navigateToGroupRoom // Group fun NavGraphBuilder.groupNavigation(navController: NavHostController) { @@ -41,6 +47,12 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { }, onNavigateToGroupMy = { navController.navigateToGroupMy() + }, + onNavigateToGroupRecruit = { roomId -> + navController.navigateToGroupRecruit(roomId) + }, + onNavigateToGroupRoom = { roomId -> + navController.navigateToGroupRoom(roomId) } ) } @@ -68,7 +80,17 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { GroupDoneScreen( name = userName, allDataList = doneGroups, - onCardClick = { groupViewModel.onRoomCardClick(it) }, + onCardClick = { room -> + groupViewModel.onRoomCardClick( + room, + onNavigateToRecruit = { roomId -> + navController.navigateToGroupRecruit(roomId) + }, + onNavigateToRoom = { roomId -> + navController.navigateToGroupRoom(roomId) + } + ) + }, onNavigateBack = { navController.navigateBack() } @@ -82,7 +104,17 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { GroupMyScreen( allDataList = myRoomGroups, - onCardClick = { groupViewModel.onRoomCardClick(it) }, + onCardClick = { room -> + groupViewModel.onRoomCardClick( + room, + onNavigateToRecruit = { roomId -> + navController.navigateToGroupRecruit(roomId) + }, + onNavigateToRoom = { roomId -> + navController.navigateToGroupRoom(roomId) + } + ) + }, onNavigateBack = { navController.navigateBack() } @@ -98,7 +130,70 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { roomList = searchGroups, onNavigateBack = { navController.navigateBack() + }, + onRoomClick = { room -> + groupViewModel.onRoomCardClick( + room, + onNavigateToRecruit = { roomId -> + navController.navigateToGroupRecruit(roomId) + }, + onNavigateToRoom = { roomId -> + navController.navigateToGroupRoom(roomId) + } + ) } ) } + + // Group Recruit 화면 + composable { backStackEntry -> + val route = backStackEntry.toRoute() + val roomId = route.roomId + val groupViewModel: GroupViewModel = viewModel() + val roomDetail = groupViewModel.getRoomDetail(roomId) + + if (roomDetail != null) { + GroupRoomRecruitScreen( + detail = roomDetail, + buttonType = GroupBottomButtonType.JOIN, // 기본값, 실제로는 사용자 상태에 따라 결정 + onRecommendationClick = { recommendation -> + navController.navigateToGroupRecruit(recommendation.id) + }, + onParticipation = { + // 참여 로직 + }, + onCancelParticipation = { + // 참여 취소 로직 + }, + onCloseRecruitment = { + // 모집 마감 로직 + }, + onBackClick = { + navController.navigateBack() + } + ) + } else { + // 데이터를 찾을 수 없는 경우 바로 뒤로 이동 + navController.navigateBack() + } + } + + // Group Room 화면 + composable { backStackEntry -> + val route = backStackEntry.toRoute() + val roomId = route.roomId + val groupViewModel: GroupViewModel = viewModel() + val roomDetail = groupViewModel.getRoomDetail(roomId) + + if (roomDetail != null) { + GroupRoomScreen( + onBackClick = { + navController.navigateBack() + } + ) + } else { + // 데이터를 찾을 수 없는 경우 바로 뒤로 이동 + navController.navigateBack() + } + } } \ 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 index 061b76ad..7c327d3c 100644 --- 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 @@ -15,4 +15,10 @@ sealed class GroupRoutes : Routes() { @Serializable data object My : GroupRoutes() + + @Serializable + data class Recruit(val roomId: Int) : GroupRoutes() + + @Serializable + data class Room(val roomId: Int) : GroupRoutes() } \ No newline at end of file From b4b892ed8ef17bf8d902eca4137b110b67ed2999 Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Sun, 27 Jul 2025 23:06:03 +0900 Subject: [PATCH 10/32] =?UTF-8?q?[feat]:=20=EB=AA=A8=EC=9E=84=EB=B0=A9=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=20=EB=84=A4=EB=B9=84=EA=B2=8C=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20=EC=97=B0=EA=B2=B0=20=EC=99=84=EB=A3=8C=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/group/myroom/screen/GroupMyScreen.kt | 38 ++++++++++++------- .../ui/group/room/screen/GroupRoomScreen.kt | 6 ++- .../thip/ui/group/screen/GroupScreen.kt | 10 ++++- .../component/GroupFilteredSearchResult.kt | 8 +++- .../search/component/GroupLiveSearchResult.kt | 9 ++++- .../group/search/screen/GroupSearchScreen.kt | 21 +++++----- 6 files changed, 62 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/com/texthip/thip/ui/group/myroom/screen/GroupMyScreen.kt b/app/src/main/java/com/texthip/thip/ui/group/myroom/screen/GroupMyScreen.kt index 3cd3f584..b3a5d9b0 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/myroom/screen/GroupMyScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/myroom/screen/GroupMyScreen.kt @@ -1,35 +1,33 @@ package com.texthip.thip.ui.group.myroom.screen +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.texthip.thip.ui.common.cards.CardItemRoom -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.ui.Modifier import com.texthip.thip.R -import com.texthip.thip.ui.theme.ThipTheme.colors -import androidx.compose.foundation.lazy.items -import androidx.compose.material3.Icon -import androidx.compose.material3.Text -import androidx.compose.ui.Alignment -import androidx.compose.ui.res.painterResource +import com.texthip.thip.ui.common.cards.CardItemRoom import com.texthip.thip.ui.common.topappbar.DefaultTopAppBar -import com.texthip.thip.ui.group.myroom.mock.GroupCardItemRoomData import com.texthip.thip.ui.group.myroom.component.GroupMyRoomFilterRow +import com.texthip.thip.ui.group.myroom.mock.GroupCardItemRoomData import com.texthip.thip.ui.theme.ThipTheme +import com.texthip.thip.ui.theme.ThipTheme.colors import com.texthip.thip.ui.theme.ThipTheme.typography @Composable @@ -128,6 +126,7 @@ fun MyGroupListFilterScreenPreview() { ThipTheme { val dataList = listOf( GroupCardItemRoomData( + id = 1, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, @@ -136,6 +135,7 @@ fun MyGroupListFilterScreenPreview() { genreIndex = 0 ), GroupCardItemRoomData( + id = 2, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, @@ -144,6 +144,7 @@ fun MyGroupListFilterScreenPreview() { genreIndex = 0 ), GroupCardItemRoomData( + id = 3, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, @@ -152,6 +153,7 @@ fun MyGroupListFilterScreenPreview() { genreIndex = 0 ), GroupCardItemRoomData( + id = 4, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, @@ -160,6 +162,7 @@ fun MyGroupListFilterScreenPreview() { genreIndex = 0 ), GroupCardItemRoomData( + id = 5, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, @@ -168,6 +171,7 @@ fun MyGroupListFilterScreenPreview() { genreIndex = 0 ), GroupCardItemRoomData( + id = 6, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, @@ -176,6 +180,7 @@ fun MyGroupListFilterScreenPreview() { genreIndex = 0 ), GroupCardItemRoomData( + id = 7, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, @@ -184,6 +189,7 @@ fun MyGroupListFilterScreenPreview() { genreIndex = 0 ), GroupCardItemRoomData( + id = 8, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, @@ -192,6 +198,7 @@ fun MyGroupListFilterScreenPreview() { genreIndex = 0 ), GroupCardItemRoomData( + id = 9, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, @@ -200,6 +207,7 @@ fun MyGroupListFilterScreenPreview() { genreIndex = 0 ), GroupCardItemRoomData( + id = 10, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, @@ -208,6 +216,7 @@ fun MyGroupListFilterScreenPreview() { genreIndex = 0 ), GroupCardItemRoomData( + id = 11, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, @@ -216,6 +225,7 @@ fun MyGroupListFilterScreenPreview() { genreIndex = 0 ), GroupCardItemRoomData( + id = 12, title = "모임방 이름입니다. 모임방...", participants = 22, maxParticipants = 30, diff --git a/app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomScreen.kt b/app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomScreen.kt index 9b42ef22..bd97b6d2 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomScreen.kt @@ -39,7 +39,9 @@ import com.texthip.thip.ui.theme.ThipTheme.colors @OptIn(ExperimentalMaterial3Api::class) @Composable -fun GroupRoomScreen() { +fun GroupRoomScreen( + onBackClick: () -> Unit = {} +) { val scrollState = rememberScrollState() var isBottomSheetVisible by remember { mutableStateOf(false) } @@ -98,7 +100,7 @@ fun GroupRoomScreen() { } GradationTopAppBar( - onLeftClick = {}, + onLeftClick = onBackClick, onRightClick = { isBottomSheetVisible = true }, ) } 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 45ac1222..5575c35d 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 @@ -37,6 +37,8 @@ fun GroupScreen( onNavigateToAlarm: () -> Unit = {}, onNavigateToGroupSearch: () -> Unit = {}, onNavigateToGroupMy: () -> Unit = {}, + onNavigateToGroupRecruit: (Int) -> Unit = {}, + onNavigateToGroupRoom: (Int) -> Unit = {}, viewModel: GroupViewModel = viewModel() ) { val myGroups by viewModel.myGroups.collectAsState() @@ -90,7 +92,13 @@ fun GroupScreen( // 마감 임박한 독서 모임방 GroupRoomDeadlineSection( roomSections = roomSections, - onRoomClick = { viewModel.onRoomCardClick(it) } + onRoomClick = { room -> + viewModel.onRoomCardClick( + room, + onNavigateToRecruit = onNavigateToGroupRecruit, + onNavigateToRoom = onNavigateToGroupRoom + ) + } ) Spacer(Modifier.height(102.dp)) } diff --git a/app/src/main/java/com/texthip/thip/ui/group/search/component/GroupFilteredSearchResult.kt b/app/src/main/java/com/texthip/thip/ui/group/search/component/GroupFilteredSearchResult.kt index 554e9482..ea039d5d 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/search/component/GroupFilteredSearchResult.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/search/component/GroupFilteredSearchResult.kt @@ -36,7 +36,8 @@ fun GroupFilteredSearchResult( selectedGenreIndex: Int, onGenreSelect: (Int) -> Unit, resultCount: Int, - roomList: List + roomList: List, + onRoomClick: (GroupCardItemRoomData) -> Unit = {} ) { Column { GenreChipRow( @@ -79,7 +80,8 @@ fun GroupFilteredSearchResult( endDate = room.endDate, imageRes = room.imageRes, isWide = true, - isSecret = room.isSecret + isSecret = room.isSecret, + onClick = { onRoomClick(room) } ) if (index < roomList.size - 1) { Spacer( @@ -113,6 +115,7 @@ fun GroupFilteredSearchResultPreview() { resultCount = 3, roomList = listOf( GroupCardItemRoomData( + id = 1, title = "해리포터 독서모임", participants = 5, maxParticipants = 10, @@ -122,6 +125,7 @@ fun GroupFilteredSearchResultPreview() { genreIndex = 1, isSecret = false ), GroupCardItemRoomData( + id = 2, title = "소설 읽기 모임", participants = 8, maxParticipants = 12, diff --git a/app/src/main/java/com/texthip/thip/ui/group/search/component/GroupLiveSearchResult.kt b/app/src/main/java/com/texthip/thip/ui/group/search/component/GroupLiveSearchResult.kt index 817626d9..7674e39e 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/search/component/GroupLiveSearchResult.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/search/component/GroupLiveSearchResult.kt @@ -21,7 +21,8 @@ import com.texthip.thip.ui.theme.ThipTheme.colors @Composable fun GroupLiveSearchResult( - roomList: List + roomList: List, + onRoomClick: (GroupCardItemRoomData) -> Unit = {} ) { LazyColumn { itemsIndexed(roomList) { index, room -> @@ -32,7 +33,8 @@ fun GroupLiveSearchResult( endDate = room.endDate, imageRes = room.imageRes, isWide = true, - isSecret = room.isSecret + isSecret = room.isSecret, + onClick = { onRoomClick(room) } ) if (index < roomList.size - 1) { Spacer( @@ -58,6 +60,7 @@ fun GroupLiveSearchResultPreview() { GroupLiveSearchResult( roomList = listOf( GroupCardItemRoomData( + id = 1, title = "해리포터 독서모임", participants = 5, maxParticipants = 10, @@ -68,6 +71,7 @@ fun GroupLiveSearchResultPreview() { isSecret = false ), GroupCardItemRoomData( + id = 2, title = "소설 읽기 모임", participants = 8, maxParticipants = 12, @@ -78,6 +82,7 @@ fun GroupLiveSearchResultPreview() { isSecret = true ), GroupCardItemRoomData( + id = 3, title = "비즈니스 서적 스터디", participants = 3, maxParticipants = 8, diff --git a/app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt b/app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt index f3ad570f..da708b1d 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt @@ -41,7 +41,8 @@ import com.texthip.thip.ui.theme.ThipTheme fun GroupSearchScreen( modifier: Modifier = Modifier, roomList: List, - onNavigateBack: () -> Unit = {} + onNavigateBack: () -> Unit = {}, + onRoomClick: (GroupCardItemRoomData) -> Unit = {} ) { val context = LocalContext.current val sharedPrefs = remember { @@ -187,7 +188,8 @@ fun GroupSearchScreen( ) } else { GroupLiveSearchResult( - roomList = liveFilteredRoomList + roomList = liveFilteredRoomList, + onRoomClick = onRoomClick ) } } @@ -199,6 +201,7 @@ fun GroupSearchScreen( onGenreSelect = { selectedGenreIndex = it }, resultCount = filteredRoomList.size, roomList = filteredRoomList, + onRoomClick = onRoomClick ) } } @@ -227,13 +230,13 @@ fun PreviewGroupSearchScreen() { ThipTheme { GroupSearchScreen( roomList = listOf( - GroupCardItemRoomData("aaa", 22, 30, true, 3, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData("abc", 15, 20, true, 7, R.drawable.bookcover_sample, 1, true), - GroupCardItemRoomData("abcd", 10, 15, true, 5, R.drawable.bookcover_sample, 2, true), - GroupCardItemRoomData("abcde", 8, 12, false, 2, R.drawable.bookcover_sample, 3, true), - GroupCardItemRoomData("abcdef", 18, 25, true, 4, R.drawable.bookcover_sample, 4), - GroupCardItemRoomData("abcdefg", 12, 20, true, 1, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData("abcdefgh", 10, 14, true, 6, R.drawable.bookcover_sample, 1) + GroupCardItemRoomData(1, "aaa", 22, 30, true, 3, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(2, "abc", 15, 20, true, 7, R.drawable.bookcover_sample, 1, true), + GroupCardItemRoomData(3, "abcd", 10, 15, true, 5, R.drawable.bookcover_sample, 2, true), + GroupCardItemRoomData(4, "abcde", 8, 12, false, 2, R.drawable.bookcover_sample, 3, true), + GroupCardItemRoomData(5, "abcdef", 18, 25, true, 4, R.drawable.bookcover_sample, 4), + GroupCardItemRoomData(6, "abcdefg", 12, 20, true, 1, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(7, "abcdefgh", 10, 14, true, 6, R.drawable.bookcover_sample, 1) ) ) } From a762ba09e068ec6f224de6792296a12a5fca97a0 Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Mon, 28 Jul 2025 00:29:16 +0900 Subject: [PATCH 11/32] =?UTF-8?q?[feat]:=20=EC=99=84=EB=A3=8C=EB=90=9C=20?= =?UTF-8?q?=EB=AA=A8=EC=9E=84=EB=B0=A9=EC=9D=80=20=EC=9D=B4=EB=8F=99=20?= =?UTF-8?q?=EC=95=88=ED=95=98=EA=B2=8C=20=EC=88=98=EC=A0=95=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/texthip/thip/ui/group/screen/GroupDoneScreen.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/com/texthip/thip/ui/group/screen/GroupDoneScreen.kt b/app/src/main/java/com/texthip/thip/ui/group/screen/GroupDoneScreen.kt index 9ab058b2..205b0423 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/screen/GroupDoneScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/screen/GroupDoneScreen.kt @@ -27,7 +27,6 @@ import com.texthip.thip.ui.theme.ThipTheme.typography fun GroupDoneScreen( name: String, allDataList: List, - onCardClick: (GroupCardItemRoomData) -> Unit = {}, onNavigateBack: () -> Unit = {} ) { val doneList = remember(allDataList) { @@ -72,7 +71,7 @@ fun GroupDoneScreen( maxParticipants = item.maxParticipants, isRecruiting = item.isRecruiting, imageRes = item.imageRes, - onClick = { onCardClick(item) } + onClick = { /* 완료된 모임방은 클릭 불가 */ } ) } } From c1637c0db5eb7771e62d16f26a27863ac79a9b04 Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Mon, 28 Jul 2025 00:29:44 +0900 Subject: [PATCH 12/32] =?UTF-8?q?[feat]:=20=EB=82=B4=20=EB=AA=A8=EC=9E=84?= =?UTF-8?q?=EB=B0=A9=20Pager=20=EC=B9=B4=EB=93=9C=EB=A5=BC=20=ED=84=B0?= =?UTF-8?q?=EC=B9=98=ED=96=88=EC=9D=84=20=EB=95=8C=20=EB=AA=A8=EC=9E=84?= =?UTF-8?q?=EB=B0=A9=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EB=8F=99=ED=95=98?= =?UTF-8?q?=EA=B2=8C=20=EC=88=98=EC=A0=95=20=EC=99=84=EB=A3=8C=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../thip/ui/group/myroom/mock/GroupCardData.kt | 1 + .../texthip/thip/ui/group/screen/GroupScreen.kt | 7 ++++++- .../thip/ui/group/viewmodel/GroupViewModel.kt | 14 +++++++++----- .../ui/navigator/navigations/GroupNavigation.kt | 11 ----------- 4 files changed, 16 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupCardData.kt b/app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupCardData.kt index dab51e6b..79b6b34b 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupCardData.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupCardData.kt @@ -3,6 +3,7 @@ package com.texthip.thip.ui.group.myroom.mock import com.texthip.thip.R data class GroupCardData( + val id: Int = 0, // 모임방 ID 추가 val title: String, val members: Int, val imageRes: Int = R.drawable.bookcover_sample, 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 5575c35d..7397b168 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 @@ -77,7 +77,12 @@ fun GroupScreen( GroupPager( groupCards = myGroups, - onCardClick = { viewModel.onMyGroupCardClick(it) } + onCardClick = { groupCard -> + viewModel.onMyGroupCardClick( + groupCard, + onNavigateToRoom = onNavigateToGroupRoom + ) + } ) Spacer(Modifier.height(32.dp)) diff --git a/app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt b/app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt index df79abbc..98bb5b27 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt @@ -39,9 +39,9 @@ class GroupViewModel : ViewModel() { // 초기 데이터 세팅 (실제에선 repository/remote에서 받아옴) init { _myGroups.value = listOf( - GroupCardData("호르몬 체인지 완독하는 방", 22, R.drawable.bookcover_sample, 40, "uibowl1"), - GroupCardData("명작 읽기방", 10, R.drawable.bookcover_sample, 70, "joyce"), - GroupCardData("또 다른 방", 13, R.drawable.bookcover_sample, 10, "other") + GroupCardData(23, "호르몬 체인지 완독하는 방", 22, R.drawable.bookcover_sample, 40, "uibowl1"), + GroupCardData(24, "명작 읽기방", 10, R.drawable.bookcover_sample, 70, "joyce"), + GroupCardData(25, "또 다른 방", 13, R.drawable.bookcover_sample, 10, "other") ) // 마감 임박한 독서 모임방 @@ -117,8 +117,12 @@ class GroupViewModel : ViewModel() { initializeRoomDetails(allRooms) } - fun onMyGroupCardClick(data: GroupCardData) { - // 내 모임방 카드 클릭 (상세 진입) + fun onMyGroupCardClick( + data: GroupCardData, + onNavigateToRoom: (Int) -> Unit + ) { + // 내 모임방은 진행중인 방으로 이동 + onNavigateToRoom(data.id) } fun onRoomCardClick( 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 index a49ced5e..6568ab72 100644 --- 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 @@ -80,17 +80,6 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { GroupDoneScreen( name = userName, allDataList = doneGroups, - onCardClick = { room -> - groupViewModel.onRoomCardClick( - room, - onNavigateToRecruit = { roomId -> - navController.navigateToGroupRecruit(roomId) - }, - onNavigateToRoom = { roomId -> - navController.navigateToGroupRoom(roomId) - } - ) - }, onNavigateBack = { navController.navigateBack() } From e0055e938830004f837f0c8c14447e0f5deffefa Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Mon, 28 Jul 2025 00:35:24 +0900 Subject: [PATCH 13/32] =?UTF-8?q?[feat]:=20=EA=B2=80=EC=83=89=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=EC=97=90=EC=84=9C=20=EC=B5=9C=EA=B7=BC=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=EC=96=B4=EB=A5=BC=20JSON=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5=ED=95=98=EA=B2=8C=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../group/search/screen/GroupSearchScreen.kt | 31 ++++++++++------ .../thip/ui/search/screen/SearchBookScreen.kt | 37 ++++++++++++------- 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt b/app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt index da708b1d..dfef3f09 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt @@ -1,5 +1,6 @@ package com.texthip.thip.ui.group.search.screen +import android.content.Context import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -25,7 +26,6 @@ import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import android.content.Context import com.texthip.thip.R import com.texthip.thip.ui.common.buttons.FilterButton import com.texthip.thip.ui.common.forms.SearchBookTextField @@ -33,9 +33,10 @@ import com.texthip.thip.ui.common.topappbar.DefaultTopAppBar import com.texthip.thip.ui.group.myroom.component.GroupRecentSearch import com.texthip.thip.ui.group.myroom.mock.GroupCardItemRoomData import com.texthip.thip.ui.group.search.component.GroupEmptyResult -import com.texthip.thip.ui.group.search.component.GroupLiveSearchResult import com.texthip.thip.ui.group.search.component.GroupFilteredSearchResult +import com.texthip.thip.ui.group.search.component.GroupLiveSearchResult import com.texthip.thip.ui.theme.ThipTheme +import kotlinx.serialization.json.Json @Composable fun GroupSearchScreen( @@ -48,20 +49,28 @@ fun GroupSearchScreen( val sharedPrefs = remember { context.getSharedPreferences("group_search_prefs", Context.MODE_PRIVATE) } - - // SharedPreferences에서 최근 검색어 불러오기 + var recentSearches by remember { mutableStateOf( - sharedPrefs.getStringSet("recent_searches", emptySet())?.toList() ?: emptyList() + try { + val jsonString = sharedPrefs.getString("recent_searches", "[]") ?: "[]" + Json.decodeFromString>(jsonString) + } catch (e: Exception) { + emptyList() + } ) } - - // 최근 검색어를 SharedPreferences에 저장하는 함수 + fun saveRecentSearches(searches: List) { - sharedPrefs.edit() - .putStringSet("recent_searches", searches.toSet()) - .apply() - recentSearches = searches + try { + val jsonString = Json.encodeToString(searches) + sharedPrefs.edit() + .putString("recent_searches", jsonString) + .apply() + recentSearches = searches + } catch (e: Exception) { + recentSearches = emptyList() + } } var searchText by rememberSaveable { mutableStateOf("") } var isSearched by rememberSaveable { mutableStateOf(false) } diff --git a/app/src/main/java/com/texthip/thip/ui/search/screen/SearchBookScreen.kt b/app/src/main/java/com/texthip/thip/ui/search/screen/SearchBookScreen.kt index d9febbc7..3fa2dcab 100644 --- a/app/src/main/java/com/texthip/thip/ui/search/screen/SearchBookScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/search/screen/SearchBookScreen.kt @@ -1,5 +1,6 @@ package com.texthip.thip.ui.search.screen +import android.content.Context import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -24,16 +25,16 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.navigation.NavHostController -import android.content.Context import com.texthip.thip.R -import com.texthip.thip.ui.search.component.SearchEmptyResult -import com.texthip.thip.ui.search.component.SearchBookFilteredResult +import com.texthip.thip.ui.common.forms.SearchBookTextField +import com.texthip.thip.ui.common.topappbar.LeftNameTopAppBar import com.texthip.thip.ui.search.component.SearchActiveField +import com.texthip.thip.ui.search.component.SearchBookFilteredResult +import com.texthip.thip.ui.search.component.SearchEmptyResult import com.texthip.thip.ui.search.component.SearchRecentBook import com.texthip.thip.ui.search.mock.BookData -import com.texthip.thip.ui.common.forms.SearchBookTextField -import com.texthip.thip.ui.common.topappbar.LeftNameTopAppBar import com.texthip.thip.ui.theme.ThipTheme +import kotlinx.serialization.json.Json @Composable fun SearchBookScreen( @@ -46,20 +47,28 @@ fun SearchBookScreen( val sharedPrefs = remember { context.getSharedPreferences("book_search_prefs", Context.MODE_PRIVATE) } - - // SharedPreferences에서 최근 검색어 불러오기 + var recentSearches by remember { mutableStateOf( - sharedPrefs.getStringSet("recent_book_searches", emptySet())?.toList() ?: emptyList() + try { + val jsonString = sharedPrefs.getString("recent_book_searches", "[]") ?: "[]" + Json.decodeFromString>(jsonString) + } catch (e: Exception) { + emptyList() + } ) } - - // 최근 검색어를 SharedPreferences에 저장하는 함수 + fun saveRecentSearches(searches: List) { - sharedPrefs.edit() - .putStringSet("recent_book_searches", searches.toSet()) - .apply() - recentSearches = searches + try { + val jsonString = Json.encodeToString(searches) + sharedPrefs.edit() + .putString("recent_book_searches", jsonString) + .apply() + recentSearches = searches + } catch (e: Exception) { + recentSearches = emptyList() + } } var searchText by rememberSaveable { mutableStateOf("") } var isSearched by rememberSaveable { mutableStateOf(false) } From 27a070084a2f3f54922462e1b896093b3c28a99b Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Mon, 28 Jul 2025 17:28:04 +0900 Subject: [PATCH 14/32] =?UTF-8?q?[feat]:=20=EA=B8=B0=ED=83=80=20=EC=A3=BC?= =?UTF-8?q?=EC=84=9D=20=EB=B0=8F=20=EA=B2=BD=EA=B3=A0=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/common/alarmpage/screen/AlarmScreen.kt | 2 +- .../common/alarmpage/viewmodel/AlarmViewModel.kt | 1 + .../thip/ui/group/myroom/screen/GroupMyScreen.kt | 3 +-- .../texthip/thip/ui/group/screen/GroupScreen.kt | 16 +++++++--------- .../ui/group/search/screen/GroupSearchScreen.kt | 7 ++++--- .../thip/ui/search/screen/SearchBookScreen.kt | 7 ++++--- 6 files changed, 18 insertions(+), 18 deletions(-) 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 ec222abb..9d80da0e 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 @@ -32,7 +32,7 @@ import com.texthip.thip.ui.theme.ThipTheme.typography @Composable fun AlarmScreen( alarmItems: List, - onCardClick: (AlarmItem) -> Unit = {}, + onCardClick: (AlarmItem) -> Unit = {}, // 나중에 서버랑 연동할 때 사용 onNavigateBack: () -> Unit = {} ) { var selectedStates by remember { mutableStateOf(booleanArrayOf(false, false)) } diff --git a/app/src/main/java/com/texthip/thip/ui/common/alarmpage/viewmodel/AlarmViewModel.kt b/app/src/main/java/com/texthip/thip/ui/common/alarmpage/viewmodel/AlarmViewModel.kt index bba60b6b..c1e31f27 100644 --- a/app/src/main/java/com/texthip/thip/ui/common/alarmpage/viewmodel/AlarmViewModel.kt +++ b/app/src/main/java/com/texthip/thip/ui/common/alarmpage/viewmodel/AlarmViewModel.kt @@ -10,6 +10,7 @@ class AlarmViewModel : ViewModel() { private val _alarmItems = MutableStateFlow>(emptyList()) val alarmItems: StateFlow> = _alarmItems.asStateFlow() + // 알림 더미 데이터 init { _alarmItems.value = listOf( AlarmItem(1, "피드", "내 글을 좋아합니다.", "user123님이 내 글에 좋아요를 눌렀어요.", "2시간 전", false), diff --git a/app/src/main/java/com/texthip/thip/ui/group/myroom/screen/GroupMyScreen.kt b/app/src/main/java/com/texthip/thip/ui/group/myroom/screen/GroupMyScreen.kt index b3a5d9b0..2e436a72 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/myroom/screen/GroupMyScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/myroom/screen/GroupMyScreen.kt @@ -119,8 +119,7 @@ fun GroupMyScreen( } } - -@Preview() +@Preview @Composable fun MyGroupListFilterScreenPreview() { ThipTheme { 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 7397b168..cda56940 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 @@ -33,12 +33,12 @@ import com.texthip.thip.ui.theme.ThipTheme.colors @Composable fun GroupScreen( onNavigateToMakeRoom: () -> Unit = {}, - onNavigateToGroupDone: () -> Unit = {}, - onNavigateToAlarm: () -> Unit = {}, - onNavigateToGroupSearch: () -> Unit = {}, - onNavigateToGroupMy: () -> Unit = {}, - onNavigateToGroupRecruit: (Int) -> Unit = {}, - onNavigateToGroupRoom: (Int) -> Unit = {}, + onNavigateToGroupDone: () -> Unit = {}, // 완료된 화면으로 이동 + onNavigateToAlarm: () -> Unit = {}, // 알림 화면으로 이동 + onNavigateToGroupSearch: () -> Unit = {}, // 검색 화면으로 이동 + onNavigateToGroupMy: () -> Unit = {}, // 내 모임방 화면으로 이동 + onNavigateToGroupRecruit: (Int) -> Unit = {}, // 모집 중인 모임방 화면으로 이동 + onNavigateToGroupRoom: (Int) -> Unit = {}, // 기록장 화면으로 이동 viewModel: GroupViewModel = viewModel() ) { val myGroups by viewModel.myGroups.collectAsState() @@ -46,9 +46,7 @@ fun GroupScreen( val scrollState = rememberScrollState() Box( - Modifier - .background(colors.Black) - .fillMaxSize() + modifier = Modifier.fillMaxSize() ) { Column( Modifier diff --git a/app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt b/app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt index dfef3f09..d1b28177 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt @@ -37,6 +37,7 @@ import com.texthip.thip.ui.group.search.component.GroupFilteredSearchResult import com.texthip.thip.ui.group.search.component.GroupLiveSearchResult import com.texthip.thip.ui.theme.ThipTheme import kotlinx.serialization.json.Json +import androidx.core.content.edit @Composable fun GroupSearchScreen( @@ -64,9 +65,9 @@ fun GroupSearchScreen( fun saveRecentSearches(searches: List) { try { val jsonString = Json.encodeToString(searches) - sharedPrefs.edit() - .putString("recent_searches", jsonString) - .apply() + sharedPrefs.edit { + putString("recent_searches", jsonString) + } recentSearches = searches } catch (e: Exception) { recentSearches = emptyList() diff --git a/app/src/main/java/com/texthip/thip/ui/search/screen/SearchBookScreen.kt b/app/src/main/java/com/texthip/thip/ui/search/screen/SearchBookScreen.kt index 3fa2dcab..09e24694 100644 --- a/app/src/main/java/com/texthip/thip/ui/search/screen/SearchBookScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/search/screen/SearchBookScreen.kt @@ -35,6 +35,7 @@ import com.texthip.thip.ui.search.component.SearchRecentBook import com.texthip.thip.ui.search.mock.BookData import com.texthip.thip.ui.theme.ThipTheme import kotlinx.serialization.json.Json +import androidx.core.content.edit @Composable fun SearchBookScreen( @@ -62,9 +63,9 @@ fun SearchBookScreen( fun saveRecentSearches(searches: List) { try { val jsonString = Json.encodeToString(searches) - sharedPrefs.edit() - .putString("recent_book_searches", jsonString) - .apply() + sharedPrefs.edit { + putString("recent_book_searches", jsonString) + } recentSearches = searches } catch (e: Exception) { recentSearches = emptyList() From 8e0c89cc31077d6eb05f5860d35851386d24718b Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Mon, 28 Jul 2025 17:39:21 +0900 Subject: [PATCH 15/32] =?UTF-8?q?[feat]:=20=EA=B3=B5=ED=86=B5=20viewModel?= =?UTF-8?q?=EC=9D=84=20=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../navigator/navigations/GroupNavigation.kt | 81 +++++++++++++++---- 1 file changed, 64 insertions(+), 17 deletions(-) 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 index 6568ab72..bcea4d20 100644 --- 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 @@ -7,6 +7,11 @@ import androidx.navigation.compose.composable import androidx.navigation.toRoute import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.compose.runtime.LaunchedEffect +import kotlinx.coroutines.delay 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 @@ -17,6 +22,7 @@ import com.texthip.thip.ui.group.room.screen.GroupRoomRecruitScreen import com.texthip.thip.ui.group.room.screen.GroupRoomScreen import com.texthip.thip.ui.group.viewmodel.GroupViewModel import com.texthip.thip.ui.group.myroom.mock.GroupBottomButtonType +import com.texthip.thip.ui.group.myroom.mock.GroupRoomData import com.texthip.thip.ui.navigator.routes.MainTabRoutes import com.texthip.thip.ui.navigator.routes.GroupRoutes import com.texthip.thip.ui.navigator.extensions.navigateBack @@ -31,8 +37,13 @@ import com.texthip.thip.ui.navigator.extensions.navigateToGroupRoom // Group fun NavGraphBuilder.groupNavigation(navController: NavHostController) { // 메인 Group 화면 - composable { + composable { backStackEntry -> + val groupViewModel: GroupViewModel = viewModel( + viewModelStoreOwner = navController.getBackStackEntry(MainTabRoutes.Group) + ) + GroupScreen( + viewModel = groupViewModel, onNavigateToMakeRoom = { navController.navigateToGroupMakeRoom() }, @@ -73,7 +84,9 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { // Group Done 화면 composable { - val groupViewModel: GroupViewModel = viewModel() + val groupViewModel: GroupViewModel = viewModel( + viewModelStoreOwner = navController.getBackStackEntry(MainTabRoutes.Group) + ) val userName by groupViewModel.userName.collectAsState() val doneGroups by groupViewModel.doneGroups.collectAsState() @@ -88,7 +101,9 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { // Group My 화면 composable { - val groupViewModel: GroupViewModel = viewModel() + val groupViewModel: GroupViewModel = viewModel( + viewModelStoreOwner = navController.getBackStackEntry(MainTabRoutes.Group) + ) val myRoomGroups by groupViewModel.myRoomGroups.collectAsState() GroupMyScreen( @@ -112,7 +127,9 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { // Group Search 화면 composable { - val groupViewModel: GroupViewModel = viewModel() + val groupViewModel: GroupViewModel = viewModel( + viewModelStoreOwner = navController.getBackStackEntry(MainTabRoutes.Group) + ) val searchGroups by groupViewModel.searchGroups.collectAsState() GroupSearchScreen( @@ -138,12 +155,19 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { composable { backStackEntry -> val route = backStackEntry.toRoute() val roomId = route.roomId - val groupViewModel: GroupViewModel = viewModel() - val roomDetail = groupViewModel.getRoomDetail(roomId) + val groupViewModel: GroupViewModel = viewModel( + viewModelStoreOwner = navController.getBackStackEntry(MainTabRoutes.Group) + ) + + // suspend 함수를 위한 LaunchedEffect 사용 + var roomDetail by remember { mutableStateOf(null) } + LaunchedEffect(roomId) { + roomDetail = groupViewModel.getRoomDetail(roomId) + } - if (roomDetail != null) { + roomDetail?.let { detail -> GroupRoomRecruitScreen( - detail = roomDetail, + detail = detail, buttonType = GroupBottomButtonType.JOIN, // 기본값, 실제로는 사용자 상태에 따라 결정 onRecommendationClick = { recommendation -> navController.navigateToGroupRecruit(recommendation.id) @@ -161,9 +185,17 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { navController.navigateBack() } ) - } else { - // 데이터를 찾을 수 없는 경우 바로 뒤로 이동 - navController.navigateBack() + } ?: run { + // 로딩 중이거나 데이터를 찾을 수 없는 경우 + LaunchedEffect(Unit) { + if (roomDetail == null) { + // 잠시 기다린 후에도 데이터가 없으면 뒤로 이동 + delay(1000) + if (roomDetail == null) { + navController.navigateBack() + } + } + } } } @@ -171,18 +203,33 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { composable { backStackEntry -> val route = backStackEntry.toRoute() val roomId = route.roomId - val groupViewModel: GroupViewModel = viewModel() - val roomDetail = groupViewModel.getRoomDetail(roomId) + val groupViewModel: GroupViewModel = viewModel( + viewModelStoreOwner = navController.getBackStackEntry(MainTabRoutes.Group) + ) + + // suspend 함수를 위한 LaunchedEffect 사용 + var roomDetail by remember { mutableStateOf(null) } + LaunchedEffect(roomId) { + roomDetail = groupViewModel.getRoomDetail(roomId) + } - if (roomDetail != null) { + roomDetail?.let { GroupRoomScreen( onBackClick = { navController.navigateBack() } ) - } else { - // 데이터를 찾을 수 없는 경우 바로 뒤로 이동 - navController.navigateBack() + } ?: run { + // 로딩 중이거나 데이터를 찾을 수 없는 경우 + LaunchedEffect(Unit) { + if (roomDetail == null) { + // 잠시 기다린 후에도 데이터가 없으면 뒤로 이동 + delay(1000) + if (roomDetail == null) { + navController.navigateBack() + } + } + } } } } \ No newline at end of file From c34460d9026fc0e18c3534dfbf25223fe71e6525 Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Mon, 28 Jul 2025 17:40:14 +0900 Subject: [PATCH 16/32] =?UTF-8?q?[feat]:=20=EC=95=88=EC=93=B0=EB=8A=94=20?= =?UTF-8?q?=ED=95=A8=EC=88=98=20=EC=82=AD=EC=A0=9C=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/navigator/extensions/CommonNavigationExtensions.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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 index 61ff596b..1687a7a6 100644 --- 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 @@ -34,6 +34,4 @@ fun NavDestination.isMainTabRoute(): Boolean { } } -fun NavDestination.isRoute(targetRoute: MainTabRoutes): Boolean { - return route == targetRoute::class.qualifiedName -} \ No newline at end of file + From 7e40247a338c80d171e99cc70294c2348da792bc Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Mon, 28 Jul 2025 17:40:34 +0900 Subject: [PATCH 17/32] =?UTF-8?q?[chore]:=20=EC=A3=BC=EC=84=9D=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../extensions/GroupNavigationExtensions.kt | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) 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 index d7651967..fe414e3b 100644 --- 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 @@ -1,9 +1,9 @@ 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 import com.texthip.thip.ui.navigator.routes.CommonRoutes +import com.texthip.thip.ui.navigator.routes.GroupRoutes +import com.texthip.thip.ui.navigator.routes.MainTabRoutes // Group 관련 네비게이션 확장 함수들 @@ -11,30 +11,39 @@ fun NavHostController.navigateToGroup() { navigate(MainTabRoutes.Group) } +// 모임방 만들기 화면으로 이동 fun NavHostController.navigateToGroupMakeRoom() { navigate(GroupRoutes.MakeRoom) } +// 완료된 모임방 목록으로 이동 fun NavHostController.navigateToGroupDone() { navigate(GroupRoutes.Done) } +// 모임방 검색 화면으로 이동 fun NavHostController.navigateToGroupSearch() { navigate(GroupRoutes.Search) } +// 내 모임방 화면으로 이동 fun NavHostController.navigateToGroupMy() { navigate(GroupRoutes.My) } +// 알람 화면으로 이동 fun NavHostController.navigateToAlarm() { navigate(CommonRoutes.Alarm) } +// 모집중인 모임방 상세 화면으로 이동 fun NavHostController.navigateToGroupRecruit(roomId: Int) { navigate(GroupRoutes.Recruit(roomId)) } +// 진행중인 모임방 화면으로 이동 fun NavHostController.navigateToGroupRoom(roomId: Int) { navigate(GroupRoutes.Room(roomId)) -} \ No newline at end of file +} + + From 4dfc77608de03897f89574951663f2df6e966863 Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Mon, 28 Jul 2025 17:43:49 +0900 Subject: [PATCH 18/32] =?UTF-8?q?[feat]:=20viewModel=20+=20=EB=A0=88?= =?UTF-8?q?=ED=8F=AC=EC=A7=80=ED=86=A0=EB=A6=AC=20=ED=8C=A8=ED=84=B4?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=88=98=EC=A0=95=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../group/data/repository/GroupRepository.kt | 36 +++ .../data/repository/GroupRepositoryImpl.kt | 229 ++++++++++++++++++ .../ui/group/data/viewmodel/GroupViewModel.kt | 144 +++++++++++ .../thip/ui/group/screen/GroupScreen.kt | 2 +- .../thip/ui/group/viewmodel/GroupViewModel.kt | 181 -------------- .../navigator/navigations/GroupNavigation.kt | 2 +- 6 files changed, 411 insertions(+), 183 deletions(-) create mode 100644 app/src/main/java/com/texthip/thip/ui/group/data/repository/GroupRepository.kt create mode 100644 app/src/main/java/com/texthip/thip/ui/group/data/repository/GroupRepositoryImpl.kt create mode 100644 app/src/main/java/com/texthip/thip/ui/group/data/viewmodel/GroupViewModel.kt delete mode 100644 app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt diff --git a/app/src/main/java/com/texthip/thip/ui/group/data/repository/GroupRepository.kt b/app/src/main/java/com/texthip/thip/ui/group/data/repository/GroupRepository.kt new file mode 100644 index 00000000..4db260c5 --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/group/data/repository/GroupRepository.kt @@ -0,0 +1,36 @@ +package com.texthip.thip.ui.group.data.repository + +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.GroupRoomData +import com.texthip.thip.ui.group.myroom.mock.GroupRoomSectionData + + +// 그룹 데이터를 제공하는 Repository 인터페이스 +interface GroupRepository { + // 사용저의 이름 + suspend fun getUserName(): Result + + // 내 모임방 카드 목록 + suspend fun getMyGroups(): Result> + + // 모임방 섹션 데이터 (마감 임박, 인기, 인플루언서 등) + suspend fun getRoomSections(): Result> + + // 완료된 모임방 목록 + suspend fun getDoneGroups(): Result> + + // 내 참여 모임방 목록 + suspend fun getMyRoomGroups(): Result> + + // 검색용 모임방 목록 + suspend fun getSearchGroups(): Result> + + // 특정 모임방 상세 정보 + suspend fun getRoomDetail(roomId: Int): Result + + // 모임방 검색 + suspend fun searchRooms(query: String): Result> + + suspend fun getGenres(): Result> +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/group/data/repository/GroupRepositoryImpl.kt b/app/src/main/java/com/texthip/thip/ui/group/data/repository/GroupRepositoryImpl.kt new file mode 100644 index 00000000..a4ddb68b --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/group/data/repository/GroupRepositoryImpl.kt @@ -0,0 +1,229 @@ +package com.texthip.thip.ui.group.data.repository + +import com.texthip.thip.R +import com.texthip.thip.ui.group.myroom.mock.GroupBookData +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.GroupRoomData +import com.texthip.thip.ui.group.myroom.mock.GroupRoomSectionData +import kotlinx.coroutines.delay + +// GroupRepository의 구현 +// 실제로는 서버의 API와 통신할 거라서 다 삭제하고 함수 구조만 유지한 채 수정하면 될 듯 합니다. + +class GroupRepositoryImpl : GroupRepository { + + private val genres = listOf("문학", "과학·IT", "사회과학", "인문학", "예술") + private val roomDetailsCache = mutableMapOf() + + override suspend fun getUserName(): Result { + return try { + Result.success("규빈") // 임시 이름 + } catch (e: Exception) { + Result.failure(e) + } + } + + override suspend fun getMyGroups(): Result> { + return try { + delay(200) + val myGroups = listOf( + GroupCardData(23, "호르몬 체인지 완독하는 방", 22, R.drawable.bookcover_sample, 40, "uibowl1"), + GroupCardData(24, "명작 읽기방", 10, R.drawable.bookcover_sample, 70, "joyce"), + GroupCardData(25, "또 다른 방", 13, R.drawable.bookcover_sample, 10, "other") + ) + Result.success(myGroups) + } catch (e: Exception) { + Result.failure(e) + } + } + + override suspend fun getRoomSections(): Result> { + return try { + + // 마감 임박한 독서 모임방 + val deadlineRooms = listOf( + GroupCardItemRoomData(1, "시집만 읽는 사람들 3월", 22, 30, true, 3, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(2, "일본 소설 좋아하는 사람들", 15, 20, true, 2, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(3, "명작 같이 읽기방", 22, 30, true, 3, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(4, "물리책 읽는 방", 13, 20, true, 1, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(5, "코딩 과학 동아리", 12, 15, true, 5, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(6, "사회과학 인문 탐구", 8, 12, true, 4, R.drawable.bookcover_sample, 2) + ) + + // 인기 있는 독서 모임방 + val popularRooms = listOf( + GroupCardItemRoomData(7, "베스트셀러 토론방", 28, 30, true, 7, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(8, "인기 소설 완독방", 25, 25, false, 5, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(9, "트렌드 과학서 읽기", 20, 25, true, 10, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(10, "화제의 경영서", 18, 20, true, 8, R.drawable.bookcover_sample, 2), + GroupCardItemRoomData(11, "인기 철학서 모임", 15, 18, true, 12, R.drawable.bookcover_sample, 3), + GroupCardItemRoomData(12, "예술서 베스트", 12, 15, true, 6, R.drawable.bookcover_sample, 4) + ) + + // 인플루언서, 작가 독서 모임방 + val influencerRooms = listOf( + GroupCardItemRoomData(13, "작가와 함께하는 독서방", 30, 30, false, 14, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(14, "유명 북튜버와 읽기", 18, 20, true, 8, R.drawable.bookcover_sample, 2), + GroupCardItemRoomData(15, "작가 초청 인문학방", 15, 20, true, 12, R.drawable.bookcover_sample, 3), + GroupCardItemRoomData(16, "인플루언서 과학책", 22, 25, true, 9, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(17, "유명작가 예술론", 16, 18, true, 11, R.drawable.bookcover_sample, 4) + ) + + val sections = listOf( + GroupRoomSectionData( + title = "마감 임박한 독서 모임방", + rooms = deadlineRooms, + genres = genres + ), + GroupRoomSectionData( + title = "인기 있는 독서 모임방", + rooms = popularRooms, + genres = genres + ), + GroupRoomSectionData( + title = "인플루언서·작가 독서 모임방", + rooms = influencerRooms, + genres = genres + ) + ) + + // 상세 데이터 캐시에 저장 + (deadlineRooms + popularRooms + influencerRooms).forEach { room -> + initializeRoomDetail(room) + } + + Result.success(sections) + } catch (e: Exception) { + Result.failure(e) + } + } + + override suspend fun getDoneGroups(): Result> { + return try { + val doneGroups = listOf( + GroupCardItemRoomData(18, "완료된 독서 모임방 1", 15, 20, false, null, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(19, "완료된 독서 모임방 2", 25, 30, false, null, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(20, "완료된 독서 모임방 3", 12, 15, false, null, R.drawable.bookcover_sample, 2), + GroupCardItemRoomData(21, "호르몬 체인지 완독한 방", 22, 22, false, null, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(22, "명작 읽기방 완료", 10, 10, false, null, R.drawable.bookcover_sample, 0) + ) + + // 상세 데이터 캐시에 저장 + doneGroups.forEach { room -> + initializeRoomDetail(room) + } + + Result.success(doneGroups) + } catch (e: Exception) { + Result.failure(e) + } + } + + override suspend fun getMyRoomGroups(): Result> { + return try { + val myRoomGroups = listOf( + GroupCardItemRoomData(23, "호르몬 체인지 완독하는 방", 22, 30, true, 5, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(24, "명작 읽기방", 10, 20, true, 3, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(25, "또 다른 방", 13, 25, false, 10, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(26, "내가 참여한 과학책방", 18, 25, true, 7, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(27, "인문학 토론방", 12, 20, true, 2, R.drawable.bookcover_sample, 3) + ) + + // 상세 데이터 캐시에 저장 + myRoomGroups.forEach { room -> + initializeRoomDetail(room) + } + + Result.success(myRoomGroups) + } catch (e: Exception) { + Result.failure(e) + } + } + + override suspend fun getSearchGroups(): Result> { + return try { + // 기존에 로드된 섹션 데이터들을 합쳐서 반환 + val sectionsResult = getRoomSections() + if (sectionsResult.isSuccess) { + val allRooms = sectionsResult.getOrThrow().flatMap { it.rooms } + Result.success(allRooms) + } else { + Result.failure(sectionsResult.exceptionOrNull() ?: Exception("Failed to load search groups")) + } + } catch (e: Exception) { + Result.failure(e) + } + } + + override suspend fun getRoomDetail(roomId: Int): Result { + return try { + delay(150) + val roomDetail = roomDetailsCache[roomId] + if (roomDetail != null) { + Result.success(roomDetail) + } else { + Result.failure(Exception("Room not found: $roomId")) + } + } catch (e: Exception) { + Result.failure(e) + } + } + + override suspend fun searchRooms(query: String): Result> { + return try { + val searchResult = getSearchGroups() + if (searchResult.isSuccess) { + val filteredRooms = searchResult.getOrThrow().filter { room -> + room.title.contains(query, ignoreCase = true) + } + Result.success(filteredRooms) + } else { + searchResult + } + } catch (e: Exception) { + Result.failure(e) + } + } + + override suspend fun getGenres(): Result> { + return try { + delay(50) + Result.success(genres) + } catch (e: Exception) { + Result.failure(e) + } + } + + + private fun initializeRoomDetail(room: GroupCardItemRoomData) { + val bookData = GroupBookData( + title = "심장보다 단단한 토마토 한 알", + author = "고선지", + publisher = "푸른출판사", + description = "${room.title}에서 읽는 책입니다. 감동적인 이야기로 가득한 작품입니다.", + imageRes = room.imageRes ?: R.drawable.bookcover_sample + ) + + val roomDetail = GroupRoomData( + id = room.id, + title = room.title, + isSecret = room.isSecret, + description = "${room.title} 모임입니다. 함께 책을 읽고 토론해요.", + startDate = "2025.01.12", + endDate = "2025.02.12", + members = room.participants, + maxMembers = room.maxParticipants, + daysLeft = room.endDate ?: 0, + genre = genres[room.genreIndex], + bookData = bookData, + recommendations = getRecommendations(room.id) + ) + + roomDetailsCache[room.id] = roomDetail + } + + private fun getRecommendations(roomId: Int): List { + return emptyList() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/group/data/viewmodel/GroupViewModel.kt b/app/src/main/java/com/texthip/thip/ui/group/data/viewmodel/GroupViewModel.kt new file mode 100644 index 00000000..75d17675 --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/group/data/viewmodel/GroupViewModel.kt @@ -0,0 +1,144 @@ +package com.texthip.thip.ui.group.data.viewmodel + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.texthip.thip.ui.group.data.repository.GroupRepository +import com.texthip.thip.ui.group.data.repository.GroupRepositoryImpl +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 com.texthip.thip.ui.group.myroom.mock.GroupRoomData +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch + +class GroupViewModel( + private val repository: GroupRepository = GroupRepositoryImpl() +) : ViewModel() { + + private val _myGroups = MutableStateFlow>(emptyList()) + val myGroups: StateFlow> = _myGroups.asStateFlow() + + private val _roomSections = MutableStateFlow>(emptyList()) + val roomSections: StateFlow> = _roomSections.asStateFlow() + + private val _userName = MutableStateFlow("") + val userName: StateFlow = _userName.asStateFlow() + + private val _doneGroups = MutableStateFlow>(emptyList()) + val doneGroups: StateFlow> = _doneGroups.asStateFlow() + + private val _myRoomGroups = MutableStateFlow>(emptyList()) + val myRoomGroups: StateFlow> = _myRoomGroups.asStateFlow() + + private val _searchGroups = MutableStateFlow>(emptyList()) + val searchGroups: StateFlow> = _searchGroups.asStateFlow() + + private val _genres = MutableStateFlow>(emptyList()) + val genres: StateFlow> = _genres.asStateFlow() + + init { + loadInitialData() + } + + private fun loadInitialData() { + loadUserName() + loadMyGroups() + loadRoomSections() + loadDoneGroups() + loadMyRoomGroups() + loadSearchGroups() + } + + private fun loadUserName() { + viewModelScope.launch { + repository.getUserName() + .onSuccess { userName -> + _userName.value = userName + } + } + } + + private fun loadMyGroups() { + viewModelScope.launch { + repository.getMyGroups() + .onSuccess { groups -> + _myGroups.value = groups + } + } + } + + private fun loadRoomSections() { + viewModelScope.launch { + repository.getRoomSections() + .onSuccess { sections -> + _roomSections.value = sections + } + } + } + + private fun loadDoneGroups() { + viewModelScope.launch { + repository.getDoneGroups() + .onSuccess { groups -> + _doneGroups.value = groups + } + } + } + + private fun loadMyRoomGroups() { + viewModelScope.launch { + repository.getMyRoomGroups() + .onSuccess { groups -> + _myRoomGroups.value = groups + } + } + } + + private fun loadSearchGroups() { + viewModelScope.launch { + repository.getSearchGroups() + .onSuccess { groups -> + _searchGroups.value = groups + } + } + } + + fun refresh() { + loadInitialData() + } + + fun onMyGroupCardClick( + data: GroupCardData, + onNavigateToRoom: (Int) -> Unit + ) { + onNavigateToRoom(data.id) + } + + fun onRoomCardClick( + data: GroupCardItemRoomData, + onNavigateToRecruit: (Int) -> Unit, + onNavigateToRoom: (Int) -> Unit + ) { + if (data.isRecruiting) { + onNavigateToRecruit(data.id) + } else { + onNavigateToRoom(data.id) + } + } + + suspend fun getRoomDetail(roomId: Int): GroupRoomData? { + return repository.getRoomDetail(roomId).getOrNull() + } + + fun searchRooms(query: String, onResult: (List) -> Unit) { + viewModelScope.launch { + repository.searchRooms(query) + .onSuccess { results -> + onResult(results) + } + } + } + +} \ 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 cda56940..ec6130e9 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 @@ -26,7 +26,7 @@ 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.viewmodel.GroupViewModel +import com.texthip.thip.ui.group.data.viewmodel.GroupViewModel import com.texthip.thip.ui.theme.ThipTheme import com.texthip.thip.ui.theme.ThipTheme.colors diff --git a/app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt b/app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt deleted file mode 100644 index 98bb5b27..00000000 --- a/app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt +++ /dev/null @@ -1,181 +0,0 @@ -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 com.texthip.thip.ui.group.myroom.mock.GroupRoomData -import com.texthip.thip.ui.group.myroom.mock.GroupBookData -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow - -class GroupViewModel : ViewModel() { - - private val _myGroups = MutableStateFlow>(emptyList()) - val myGroups: StateFlow> = _myGroups - - private val _roomSections = MutableStateFlow>(emptyList()) - val roomSections: StateFlow> = _roomSections - - private val _userName = MutableStateFlow("규빈") // 임시 유저 이름 - val userName: StateFlow = _userName - - private val _doneGroups = MutableStateFlow>(emptyList()) - val doneGroups: StateFlow> = _doneGroups - - private val _myRoomGroups = MutableStateFlow>(emptyList()) - val myRoomGroups: StateFlow> = _myRoomGroups - - private val _searchGroups = MutableStateFlow>(emptyList()) - val searchGroups: StateFlow> = _searchGroups - - private val _genres = listOf("문학", "과학·IT", "사회과학", "인문학", "예술") - val genres: List get() = _genres - - // 모든 모임방 데이터 (ID로 조회하기 위한 맵) - private val _allRoomDetails = mutableMapOf() - - // 초기 데이터 세팅 (실제에선 repository/remote에서 받아옴) - init { - _myGroups.value = listOf( - GroupCardData(23, "호르몬 체인지 완독하는 방", 22, R.drawable.bookcover_sample, 40, "uibowl1"), - GroupCardData(24, "명작 읽기방", 10, R.drawable.bookcover_sample, 70, "joyce"), - GroupCardData(25, "또 다른 방", 13, R.drawable.bookcover_sample, 10, "other") - ) - - // 마감 임박한 독서 모임방 - val deadlineRooms = listOf( - GroupCardItemRoomData(1, "시집만 읽는 사람들 3월", 22, 30, true, 3, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(2, "일본 소설 좋아하는 사람들", 15, 20, true, 2, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(3, "명작 같이 읽기방", 22, 30, true, 3, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(4, "물리책 읽는 방", 13, 20, true, 1, R.drawable.bookcover_sample, 1), - GroupCardItemRoomData(5, "코딩 과학 동아리", 12, 15, true, 5, R.drawable.bookcover_sample, 1), - GroupCardItemRoomData(6, "사회과학 인문 탐구", 8, 12, true, 4, R.drawable.bookcover_sample, 2) - ) - - // 인기 있는 독서 모임방 - val popularRooms = listOf( - GroupCardItemRoomData(7, "베스트셀러 토론방", 28, 30, true, 7, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(8, "인기 소설 완독방", 25, 25, false, 5, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(9, "트렌드 과학서 읽기", 20, 25, true, 10, R.drawable.bookcover_sample, 1), - GroupCardItemRoomData(10, "화제의 경영서", 18, 20, true, 8, R.drawable.bookcover_sample, 2), - GroupCardItemRoomData(11, "인기 철학서 모임", 15, 18, true, 12, R.drawable.bookcover_sample, 3), - GroupCardItemRoomData(12, "예술서 베스트", 12, 15, true, 6, R.drawable.bookcover_sample, 4) - ) - - // 인플루언서, 작가 독서 모임방 - val influencerRooms = listOf( - GroupCardItemRoomData(13, "작가와 함께하는 독서방", 30, 30, false, 14, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(14, "유명 북튜버와 읽기", 18, 20, true, 8, R.drawable.bookcover_sample, 2), - GroupCardItemRoomData(15, "작가 초청 인문학방", 15, 20, true, 12, R.drawable.bookcover_sample, 3), - GroupCardItemRoomData(16, "인플루언서 과학책", 22, 25, true, 9, R.drawable.bookcover_sample, 1), - GroupCardItemRoomData(17, "유명작가 예술론", 16, 18, true, 11, R.drawable.bookcover_sample, 4) - ) - - _roomSections.value = listOf( - GroupRoomSectionData( - title = "마감 임박한 독서 모임방", - rooms = deadlineRooms, - genres = _genres - ), - GroupRoomSectionData( - title = "인기 있는 독서 모임방", - rooms = popularRooms, - genres = _genres - ), - GroupRoomSectionData( - title = "인플루언서·작가 독서 모임방", - rooms = influencerRooms, - genres = _genres - ) - ) - - // 완료된 모임방 데이터 - _doneGroups.value = listOf( - GroupCardItemRoomData(18, "완료된 독서 모임방 1", 15, 20, false, null, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(19, "완료된 독서 모임방 2", 25, 30, false, null, R.drawable.bookcover_sample, 1), - GroupCardItemRoomData(20, "완료된 독서 모임방 3", 12, 15, false, null, R.drawable.bookcover_sample, 2), - GroupCardItemRoomData(21, "호르몬 체인지 완독한 방", 22, 22, false, null, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(22, "명작 읽기방 완료", 10, 10, false, null, R.drawable.bookcover_sample, 0) - ) - - // 내 모임방 데이터 - _myRoomGroups.value = listOf( - GroupCardItemRoomData(23, "호르몬 체인지 완독하는 방", 22, 30, true, 5, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(24, "명작 읽기방", 10, 20, true, 3, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(25, "또 다른 방", 13, 25, false, 10, R.drawable.bookcover_sample, 1), - GroupCardItemRoomData(26, "내가 참여한 과학책방", 18, 25, true, 7, R.drawable.bookcover_sample, 1), - GroupCardItemRoomData(27, "인문학 토론방", 12, 20, true, 2, R.drawable.bookcover_sample, 3) - ) - - // 검색용 모임방 데이터 (모든 모임방 합쳐서) - _searchGroups.value = deadlineRooms + popularRooms + influencerRooms - - // 상세 모임방 데이터 초기화 (모든 모임방 데이터 포함) - val allRooms = deadlineRooms + popularRooms + influencerRooms + _doneGroups.value + _myRoomGroups.value - initializeRoomDetails(allRooms) - } - - fun onMyGroupCardClick( - data: GroupCardData, - onNavigateToRoom: (Int) -> Unit - ) { - // 내 모임방은 진행중인 방으로 이동 - onNavigateToRoom(data.id) - } - - fun onRoomCardClick( - data: GroupCardItemRoomData, - onNavigateToRecruit: (Int) -> Unit, - onNavigateToRoom: (Int) -> Unit - ) { - // 방 카드 클릭 (상세 진입) - if (data.isRecruiting) { - onNavigateToRecruit(data.id) - } else { - onNavigateToRoom(data.id) - } - } - - // 상세 모임방 데이터 초기화 (임시 예시) - private fun initializeRoomDetails(rooms: List) { - rooms.forEach { room -> - val bookData = GroupBookData( - title = "심장보다 단단한 토마토 한 알", - author = "고선지", - publisher = "푸른출판사", - description = "${room.title}에서 읽는 책입니다. 감동적인 이야기로 가득한 작품입니다.", - imageRes = room.imageRes ?: R.drawable.bookcover_sample - ) - - val roomDetail = GroupRoomData( - id = room.id, - title = room.title, - isSecret = room.isSecret, - description = "${room.title} 모임입니다. 함께 책을 읽고 토론해요.", - startDate = "2025.01.12", - endDate = "2025.02.12", - members = room.participants, - maxMembers = room.maxParticipants, - daysLeft = room.endDate ?: 0, - genre = _genres[room.genreIndex], - bookData = bookData, - recommendations = getRecommendations(room.id) - ) - - _allRoomDetails[room.id] = roomDetail - } - } - - // 추천 모임방 가져오기 (간단한 더미 로직) - private fun getRecommendations(roomId: Int): List { - return _searchGroups.value.filter { it.id != roomId }.take(3) - } - - // ID로 모임방 상세 정보 조회 - fun getRoomDetail(roomId: Int): GroupRoomData? { - return _allRoomDetails[roomId] - } - -} \ 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 index bcea4d20..b78ad1db 100644 --- 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 @@ -20,7 +20,7 @@ import com.texthip.thip.ui.group.myroom.screen.GroupMyScreen import com.texthip.thip.ui.group.search.screen.GroupSearchScreen import com.texthip.thip.ui.group.room.screen.GroupRoomRecruitScreen import com.texthip.thip.ui.group.room.screen.GroupRoomScreen -import com.texthip.thip.ui.group.viewmodel.GroupViewModel +import com.texthip.thip.ui.group.data.viewmodel.GroupViewModel import com.texthip.thip.ui.group.myroom.mock.GroupBottomButtonType import com.texthip.thip.ui.group.myroom.mock.GroupRoomData import com.texthip.thip.ui.navigator.routes.MainTabRoutes From 200855fb0dbe13e41a16c1a8c96f75f8e2a890eb Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Mon, 28 Jul 2025 18:37:23 +0900 Subject: [PATCH 19/32] =?UTF-8?q?[refactor]:=20copilot=20pr=20=EB=B0=98?= =?UTF-8?q?=EC=98=81=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../texthip/thip/ui/group/search/screen/GroupSearchScreen.kt | 4 +++- .../com/texthip/thip/ui/search/screen/SearchBookScreen.kt | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt b/app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt index d1b28177..bfcaedb8 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt @@ -38,6 +38,8 @@ import com.texthip.thip.ui.group.search.component.GroupLiveSearchResult import com.texthip.thip.ui.theme.ThipTheme import kotlinx.serialization.json.Json import androidx.core.content.edit +import kotlinx.serialization.builtins.ListSerializer +import kotlinx.serialization.builtins.serializer @Composable fun GroupSearchScreen( @@ -64,7 +66,7 @@ fun GroupSearchScreen( fun saveRecentSearches(searches: List) { try { - val jsonString = Json.encodeToString(searches) + val jsonString = Json.encodeToString(ListSerializer(String.serializer()), searches) sharedPrefs.edit { putString("recent_searches", jsonString) } diff --git a/app/src/main/java/com/texthip/thip/ui/search/screen/SearchBookScreen.kt b/app/src/main/java/com/texthip/thip/ui/search/screen/SearchBookScreen.kt index 09e24694..7062aa3a 100644 --- a/app/src/main/java/com/texthip/thip/ui/search/screen/SearchBookScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/search/screen/SearchBookScreen.kt @@ -36,6 +36,8 @@ import com.texthip.thip.ui.search.mock.BookData import com.texthip.thip.ui.theme.ThipTheme import kotlinx.serialization.json.Json import androidx.core.content.edit +import kotlinx.serialization.builtins.ListSerializer +import kotlinx.serialization.builtins.serializer @Composable fun SearchBookScreen( @@ -62,7 +64,7 @@ fun SearchBookScreen( fun saveRecentSearches(searches: List) { try { - val jsonString = Json.encodeToString(searches) + val jsonString = Json.encodeToString(ListSerializer(String.serializer()), searches) sharedPrefs.edit { putString("recent_book_searches", jsonString) } From b9ce3764ae741838019539fa3ba01bbe8e1a4d84 Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Mon, 28 Jul 2025 18:38:27 +0900 Subject: [PATCH 20/32] =?UTF-8?q?[refactor]:=20=EB=A9=94=EC=9D=B8=20?= =?UTF-8?q?=EB=A3=A8=ED=8A=B8=20=ED=99=95=EC=9D=B8=20=EB=8B=A4=EC=8B=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/navigator/extensions/CommonNavigationExtensions.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) 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 index 1687a7a6..ac5245ec 100644 --- 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 @@ -23,7 +23,7 @@ fun NavHostController.navigateToTab(route: MainTabRoutes) { } } -// 라우트 매칭 헬퍼 함수들 +// 메인 루트 헬퍼 함수들 fun NavDestination.isMainTabRoute(): Boolean { return when (route) { MainTabRoutes.Feed::class.qualifiedName, @@ -34,4 +34,9 @@ fun NavDestination.isMainTabRoute(): Boolean { } } +// 매인 루트인지 확인 +fun NavDestination.isRoute(targetRoute: MainTabRoutes): Boolean { + return route == targetRoute::class.qualifiedName +} + From 4bc716e38a2ee6317011038e329bf4075c9ef719 Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Mon, 28 Jul 2025 18:39:13 +0900 Subject: [PATCH 21/32] =?UTF-8?q?[refactor]:=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EB=AA=A8=EC=9E=84=20=EB=B0=A9?= =?UTF-8?q?=20=EC=B6=94=EC=B2=9C=20=EB=8D=94=EB=AF=B8=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=B6=94=EA=B0=80=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/repository/GroupRepositoryImpl.kt | 99 ++++++++++++- .../navigator/navigations/GroupNavigation.kt | 132 +++++++++++------- 2 files changed, 177 insertions(+), 54 deletions(-) diff --git a/app/src/main/java/com/texthip/thip/ui/group/data/repository/GroupRepositoryImpl.kt b/app/src/main/java/com/texthip/thip/ui/group/data/repository/GroupRepositoryImpl.kt index a4ddb68b..665fc573 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/data/repository/GroupRepositoryImpl.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/data/repository/GroupRepositoryImpl.kt @@ -205,6 +205,8 @@ class GroupRepositoryImpl : GroupRepository { imageRes = room.imageRes ?: R.drawable.bookcover_sample ) + val recommendations = getRecommendations(room.id) + val roomDetail = GroupRoomData( id = room.id, title = room.title, @@ -217,13 +219,106 @@ class GroupRepositoryImpl : GroupRepository { daysLeft = room.endDate ?: 0, genre = genres[room.genreIndex], bookData = bookData, - recommendations = getRecommendations(room.id) + recommendations = recommendations + ) + + roomDetailsCache[room.id] = roomDetail + + // 추천 모임방들의 상세 정보도 캐시에 추가 + recommendations.forEach { recommendedRoom -> + if (!roomDetailsCache.containsKey(recommendedRoom.id)) { + initializeRecommendedRoomDetail(recommendedRoom) + } + } + } + + // 추천 모임방 예시 by gpt + private fun initializeRecommendedRoomDetail(room: GroupCardItemRoomData) { + val bookTitles = listOf( + "데미안", "1984", "노인과 바다", "위대한 개츠비", "햄릿", + "코스모스", "이기적 유전자", "블랙홀과 시간여행", "총균쇠", + "국부론", "자본론", "사피엔스", "총균쇠", "정의란 무엇인가", + "예술의 역사", "음악의 역사", "미학 오디세이" + ) + + val authors = listOf( + "헤르만 헤세", "조지 오웰", "어니스트 헤밍웨이", "스콧 피츠제럴드", + "칼 세이건", "리처드 도킨스", "킵 손", "재레드 다이아몬드", + "아담 스미스", "칼 마르크스", "유발 하라리", "마이클 샌델" + ) + + val publishers = listOf("푸른출판사", "문학동네", "민음사", "창비", "열린책들", "김영사") + + val bookData = GroupBookData( + title = bookTitles.random(), + author = authors.random(), + publisher = publishers.random(), + description = "${room.title}에서 읽는 흥미로운 책입니다. 함께 읽으며 깊이 있는 토론을 나눠보세요.", + imageRes = room.imageRes ?: R.drawable.bookcover_sample + ) + + val roomDetail = GroupRoomData( + id = room.id, + title = room.title, + isSecret = room.isSecret, + description = "${room.title} 모임입니다. 다양한 관점으로 책을 읽고 의견을 나눠보세요.", + startDate = "2025.01.15", + endDate = "2025.02.15", + members = room.participants, + maxMembers = room.maxParticipants, + daysLeft = room.endDate ?: 0, + genre = genres.getOrElse(room.genreIndex) { genres[0] }, + bookData = bookData, + recommendations = emptyList() // 추천의 추천은 제공하지 않음 ) roomDetailsCache[room.id] = roomDetail } private fun getRecommendations(roomId: Int): List { - return emptyList() + // 추천 모임방 더미데이터 풀 + val recommendationPool = listOf( + // 문학 관련 추천 + GroupCardItemRoomData(1001, "한국 근현대 소설 읽기", 18, 25, true, 3, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(1002, "일본 문학 애호가들", 22, 30, true, 1, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(1003, "시 읽기 모임", 16, 25, true, 2, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(1004, "해외문학 번역서 읽기", 15, 22, true, 3, R.drawable.bookcover_sample, 0, true), + GroupCardItemRoomData(1005, "고전 문학 탐구", 20, 25, true, 5, R.drawable.bookcover_sample, 0), + + // 과학·IT 관련 추천 + GroupCardItemRoomData(1006, "SF 소설 탐험대", 12, 20, true, 7, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(1007, "과학도서 함께 읽기", 7, 15, true, 9, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(1008, "컴퓨터 과학 스터디", 14, 18, true, 4, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(1009, "물리학 입문서 모임", 10, 16, true, 6, R.drawable.bookcover_sample, 1), + + // 사회과학 관련 추천 + GroupCardItemRoomData(1010, "경제경영서 스터디", 9, 12, true, 6, R.drawable.bookcover_sample, 2), + GroupCardItemRoomData(1011, "사회학 도서 토론", 13, 18, true, 4, R.drawable.bookcover_sample, 2), + GroupCardItemRoomData(1012, "정치학 입문 모임", 11, 15, true, 8, R.drawable.bookcover_sample, 2), + + // 인문학 관련 추천 + GroupCardItemRoomData(1013, "철학 에세이 읽기 모임", 8, 15, true, 5, R.drawable.bookcover_sample, 3), + GroupCardItemRoomData(1014, "인문학 고전 읽기", 20, 25, true, 5, R.drawable.bookcover_sample, 3, true), + GroupCardItemRoomData(1015, "심리학 도서 스터디", 10, 16, true, 7, R.drawable.bookcover_sample, 3), + GroupCardItemRoomData(1016, "역사서 탐구 모임", 11, 16, true, 8, R.drawable.bookcover_sample, 3), + + // 예술 관련 추천 + GroupCardItemRoomData(1017, "미술사 도서 읽기", 14, 20, true, 3, R.drawable.bookcover_sample, 4), + GroupCardItemRoomData(1018, "음악 관련 서적 모임", 12, 18, true, 5, R.drawable.bookcover_sample, 4), + + // 기타 장르 + GroupCardItemRoomData(1019, "로맨스 소설 감상회", 14, 20, true, 4, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(1020, "미스터리 소설 동호회", 15, 18, true, 2, R.drawable.bookcover_sample, 0, true), + GroupCardItemRoomData(1021, "자기계발서 함께 읽기", 25, 30, true, 3, R.drawable.bookcover_sample, 2, true), + GroupCardItemRoomData(1022, "판타지 소설 동호회", 24, 30, true, 1, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(1023, "여행 에세이 모임", 13, 18, true, 4, R.drawable.bookcover_sample, 3), + GroupCardItemRoomData(1024, "추리소설 마니아", 19, 24, true, 6, R.drawable.bookcover_sample, 0) + ) + + // 현재 방과 관련 없는 추천을 제공하기 위해 현재 roomId와 다른 것들만 필터링 + val filteredRecommendations = recommendationPool.filter { it.id != roomId } + + // 랜덤하게 3-5개의 추천 반환 + return filteredRecommendations.shuffled().take(5) } } \ 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 index b78ad1db..213afa16 100644 --- 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 @@ -1,45 +1,46 @@ package com.texthip.thip.ui.navigator.navigations +import android.annotation.SuppressLint +import androidx.compose.runtime.LaunchedEffect +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.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController import androidx.navigation.compose.composable import androidx.navigation.toRoute -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.setValue -import androidx.compose.runtime.LaunchedEffect -import kotlinx.coroutines.delay +import com.texthip.thip.ui.group.data.viewmodel.GroupViewModel 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.group.screen.GroupDoneScreen +import com.texthip.thip.ui.group.myroom.mock.GroupBottomButtonType +import com.texthip.thip.ui.group.myroom.mock.GroupRoomData import com.texthip.thip.ui.group.myroom.screen.GroupMyScreen -import com.texthip.thip.ui.group.search.screen.GroupSearchScreen import com.texthip.thip.ui.group.room.screen.GroupRoomRecruitScreen import com.texthip.thip.ui.group.room.screen.GroupRoomScreen -import com.texthip.thip.ui.group.data.viewmodel.GroupViewModel -import com.texthip.thip.ui.group.myroom.mock.GroupBottomButtonType -import com.texthip.thip.ui.group.myroom.mock.GroupRoomData -import com.texthip.thip.ui.navigator.routes.MainTabRoutes -import com.texthip.thip.ui.navigator.routes.GroupRoutes +import com.texthip.thip.ui.group.screen.GroupDoneScreen +import com.texthip.thip.ui.group.screen.GroupScreen +import com.texthip.thip.ui.group.search.screen.GroupSearchScreen import com.texthip.thip.ui.navigator.extensions.navigateBack -import com.texthip.thip.ui.navigator.extensions.navigateToGroupMakeRoom +import com.texthip.thip.ui.navigator.extensions.navigateToAlarm import com.texthip.thip.ui.navigator.extensions.navigateToGroupDone -import com.texthip.thip.ui.navigator.extensions.navigateToGroupSearch +import com.texthip.thip.ui.navigator.extensions.navigateToGroupMakeRoom import com.texthip.thip.ui.navigator.extensions.navigateToGroupMy -import com.texthip.thip.ui.navigator.extensions.navigateToAlarm import com.texthip.thip.ui.navigator.extensions.navigateToGroupRecruit import com.texthip.thip.ui.navigator.extensions.navigateToGroupRoom +import com.texthip.thip.ui.navigator.extensions.navigateToGroupSearch +import com.texthip.thip.ui.navigator.routes.GroupRoutes +import com.texthip.thip.ui.navigator.routes.MainTabRoutes // Group +@SuppressLint("UnrememberedGetBackStackEntry") fun NavGraphBuilder.groupNavigation(navController: NavHostController) { // 메인 Group 화면 composable { backStackEntry -> val groupViewModel: GroupViewModel = viewModel( - viewModelStoreOwner = navController.getBackStackEntry(MainTabRoutes.Group) + viewModelStoreOwner = backStackEntry ) GroupScreen( @@ -84,9 +85,18 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { // Group Done 화면 composable { - val groupViewModel: GroupViewModel = viewModel( - viewModelStoreOwner = navController.getBackStackEntry(MainTabRoutes.Group) - ) + val parentEntry = remember(navController) { + try { + navController.getBackStackEntry(MainTabRoutes.Group) + } catch (e: Exception) { + null + } + } + val groupViewModel: GroupViewModel = if (parentEntry != null) { + viewModel(viewModelStoreOwner = parentEntry) + } else { + viewModel() + } val userName by groupViewModel.userName.collectAsState() val doneGroups by groupViewModel.doneGroups.collectAsState() @@ -101,9 +111,18 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { // Group My 화면 composable { - val groupViewModel: GroupViewModel = viewModel( - viewModelStoreOwner = navController.getBackStackEntry(MainTabRoutes.Group) - ) + val parentEntry = remember(navController) { + try { + navController.getBackStackEntry(MainTabRoutes.Group) + } catch (e: Exception) { + null + } + } + val groupViewModel: GroupViewModel = if (parentEntry != null) { + viewModel(viewModelStoreOwner = parentEntry) + } else { + viewModel() + } val myRoomGroups by groupViewModel.myRoomGroups.collectAsState() GroupMyScreen( @@ -127,9 +146,18 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { // Group Search 화면 composable { - val groupViewModel: GroupViewModel = viewModel( - viewModelStoreOwner = navController.getBackStackEntry(MainTabRoutes.Group) - ) + val parentEntry = remember(navController) { + try { + navController.getBackStackEntry(MainTabRoutes.Group) + } catch (e: Exception) { + null + } + } + val groupViewModel: GroupViewModel = if (parentEntry != null) { + viewModel(viewModelStoreOwner = parentEntry) + } else { + viewModel() + } val searchGroups by groupViewModel.searchGroups.collectAsState() GroupSearchScreen( @@ -155,9 +183,18 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { composable { backStackEntry -> val route = backStackEntry.toRoute() val roomId = route.roomId - val groupViewModel: GroupViewModel = viewModel( - viewModelStoreOwner = navController.getBackStackEntry(MainTabRoutes.Group) - ) + val parentEntry = remember(navController) { + try { + navController.getBackStackEntry(MainTabRoutes.Group) + } catch (e: Exception) { + null + } + } + val groupViewModel: GroupViewModel = if (parentEntry != null) { + viewModel(viewModelStoreOwner = parentEntry) + } else { + viewModel() + } // suspend 함수를 위한 LaunchedEffect 사용 var roomDetail by remember { mutableStateOf(null) } @@ -187,15 +224,6 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { ) } ?: run { // 로딩 중이거나 데이터를 찾을 수 없는 경우 - LaunchedEffect(Unit) { - if (roomDetail == null) { - // 잠시 기다린 후에도 데이터가 없으면 뒤로 이동 - delay(1000) - if (roomDetail == null) { - navController.navigateBack() - } - } - } } } @@ -203,9 +231,18 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { composable { backStackEntry -> val route = backStackEntry.toRoute() val roomId = route.roomId - val groupViewModel: GroupViewModel = viewModel( - viewModelStoreOwner = navController.getBackStackEntry(MainTabRoutes.Group) - ) + val parentEntry = remember(navController) { + try { + navController.getBackStackEntry(MainTabRoutes.Group) + } catch (e: Exception) { + null + } + } + val groupViewModel: GroupViewModel = if (parentEntry != null) { + viewModel(viewModelStoreOwner = parentEntry) + } else { + viewModel() + } // suspend 함수를 위한 LaunchedEffect 사용 var roomDetail by remember { mutableStateOf(null) } @@ -221,15 +258,6 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { ) } ?: run { // 로딩 중이거나 데이터를 찾을 수 없는 경우 - LaunchedEffect(Unit) { - if (roomDetail == null) { - // 잠시 기다린 후에도 데이터가 없으면 뒤로 이동 - delay(1000) - if (roomDetail == null) { - navController.navigateBack() - } - } - } } } } \ No newline at end of file From bba7b905bad6bfe1b76c611d8810aa6131117780 Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Mon, 28 Jul 2025 18:47:56 +0900 Subject: [PATCH 22/32] =?UTF-8?q?[feat]:=20=EC=B6=94=EC=B2=9C=20=EB=AA=A8?= =?UTF-8?q?=EC=9E=84=EB=B0=A9=20=EC=9D=B4=EB=8F=99=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../thip/ui/group/data/repository/GroupRepositoryImpl.kt | 2 +- .../ui/navigator/extensions/GroupNavigationExtensions.kt | 9 +++++++++ .../thip/ui/navigator/navigations/GroupNavigation.kt | 3 ++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/texthip/thip/ui/group/data/repository/GroupRepositoryImpl.kt b/app/src/main/java/com/texthip/thip/ui/group/data/repository/GroupRepositoryImpl.kt index 665fc573..1a145c58 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/data/repository/GroupRepositoryImpl.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/data/repository/GroupRepositoryImpl.kt @@ -269,7 +269,7 @@ class GroupRepositoryImpl : GroupRepository { daysLeft = room.endDate ?: 0, genre = genres.getOrElse(room.genreIndex) { genres[0] }, bookData = bookData, - recommendations = emptyList() // 추천의 추천은 제공하지 않음 + recommendations = getRecommendations(room.id) // 추천 모임방에도 추천 제공 ) roomDetailsCache[room.id] = roomDetail 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 index fe414e3b..48fc3ddb 100644 --- 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 @@ -41,6 +41,15 @@ fun NavHostController.navigateToGroupRecruit(roomId: Int) { navigate(GroupRoutes.Recruit(roomId)) } +// 추천 모임방으로 이동 (현재 화면을 대체) +fun NavHostController.navigateToRecommendedGroupRecruit(roomId: Int) { + navigate(GroupRoutes.Recruit(roomId)) { + popUpTo(currentDestination?.route ?: return@navigate) { + inclusive = true + } + } +} + // 진행중인 모임방 화면으로 이동 fun NavHostController.navigateToGroupRoom(roomId: Int) { navigate(GroupRoutes.Room(roomId)) 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 index 213afa16..c3c3a23c 100644 --- 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 @@ -29,6 +29,7 @@ import com.texthip.thip.ui.navigator.extensions.navigateToGroupDone import com.texthip.thip.ui.navigator.extensions.navigateToGroupMakeRoom import com.texthip.thip.ui.navigator.extensions.navigateToGroupMy import com.texthip.thip.ui.navigator.extensions.navigateToGroupRecruit +import com.texthip.thip.ui.navigator.extensions.navigateToRecommendedGroupRecruit import com.texthip.thip.ui.navigator.extensions.navigateToGroupRoom import com.texthip.thip.ui.navigator.extensions.navigateToGroupSearch import com.texthip.thip.ui.navigator.routes.GroupRoutes @@ -207,7 +208,7 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { detail = detail, buttonType = GroupBottomButtonType.JOIN, // 기본값, 실제로는 사용자 상태에 따라 결정 onRecommendationClick = { recommendation -> - navController.navigateToGroupRecruit(recommendation.id) + navController.navigateToRecommendedGroupRecruit(recommendation.id) }, onParticipation = { // 참여 로직 From c5ef4c53489a039751edca6c969c0ee384a5003a Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Tue, 29 Jul 2025 22:31:40 +0900 Subject: [PATCH 23/32] =?UTF-8?q?[refactor]:=20toml=20=EB=B2=84=EC=A0=84?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gradle/libs.versions.toml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e0142547..7cf86970 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] -agp = "8.9.3" -kotlin = "2.2.0" +agp = "8.9.1" +kotlin = "2.0.21" coreKtx = "1.16.0" junit = "4.13.2" junitVersion = "1.2.1" @@ -8,13 +8,13 @@ espressoCore = "3.6.1" lifecycleRuntimeKtx = "2.8.7" activityCompose = "1.10.1" composeBom = "2024.09.00" -navigationCompose = "2.9.2" +navigationCompose = "2.9.0" foundation = "1.9.0-beta01" -lifecycleViewmodelCompose = "2.9.2" -navigationRuntimeAndroid = "2.9.2" +lifecycleViewmodelCompose = "2.9.1" +navigationRuntimeAndroid = "2.9.0" accompanistPager = "0.36.0" accompanistPagerIndicators = "0.36.0" -kotlinxSerializationJson = "1.9.0" +kotlinxSerializationJson = "1.7.3" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } From 4e6c78a5364aedd77877b55c2e91f6afcbf63bcf Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Thu, 31 Jul 2025 18:10:07 +0900 Subject: [PATCH 24/32] =?UTF-8?q?[feat]:=20=ED=95=A8=EC=88=98=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EA=B7=B8=EB=A3=B9?= =?UTF-8?q?=20=EB=B0=A9=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EB=8F=99=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=ED=95=A8=EC=88=98=EB=A5=BC=20viewModel=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=A0=9C=EA=B1=B0=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/group/data/viewmodel/GroupViewModel.kt | 29 +------------------ 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/app/src/main/java/com/texthip/thip/ui/group/data/viewmodel/GroupViewModel.kt b/app/src/main/java/com/texthip/thip/ui/group/data/viewmodel/GroupViewModel.kt index 75d17675..45f2ea0a 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/data/viewmodel/GroupViewModel.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/data/viewmodel/GroupViewModel.kt @@ -105,40 +105,13 @@ class GroupViewModel( } } - fun refresh() { + fun refreshGroupData() { loadInitialData() } - fun onMyGroupCardClick( - data: GroupCardData, - onNavigateToRoom: (Int) -> Unit - ) { - onNavigateToRoom(data.id) - } - - fun onRoomCardClick( - data: GroupCardItemRoomData, - onNavigateToRecruit: (Int) -> Unit, - onNavigateToRoom: (Int) -> Unit - ) { - if (data.isRecruiting) { - onNavigateToRecruit(data.id) - } else { - onNavigateToRoom(data.id) - } - } suspend fun getRoomDetail(roomId: Int): GroupRoomData? { return repository.getRoomDetail(roomId).getOrNull() } - - fun searchRooms(query: String, onResult: (List) -> Unit) { - viewModelScope.launch { - repository.searchRooms(query) - .onSuccess { results -> - onResult(results) - } - } - } } \ No newline at end of file From 05f807ff7ca7addf6942e889631326094220e8e5 Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Thu, 31 Jul 2025 18:10:59 +0900 Subject: [PATCH 25/32] =?UTF-8?q?[feat]:=20=ED=95=A8=EC=88=98=20=EB=B0=98?= =?UTF-8?q?=EC=98=81=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../texthip/thip/ui/group/screen/GroupScreen.kt | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) 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 ec6130e9..82eb31e4 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 @@ -76,10 +76,7 @@ fun GroupScreen( GroupPager( groupCards = myGroups, onCardClick = { groupCard -> - viewModel.onMyGroupCardClick( - groupCard, - onNavigateToRoom = onNavigateToGroupRoom - ) + onNavigateToGroupRoom(groupCard.id) } ) Spacer(Modifier.height(32.dp)) @@ -96,11 +93,11 @@ fun GroupScreen( GroupRoomDeadlineSection( roomSections = roomSections, onRoomClick = { room -> - viewModel.onRoomCardClick( - room, - onNavigateToRecruit = onNavigateToGroupRecruit, - onNavigateToRoom = onNavigateToGroupRoom - ) + if (room.isRecruiting) { + onNavigateToGroupRecruit(room.id) + } else { + onNavigateToGroupRoom(room.id) + } } ) Spacer(Modifier.height(102.dp)) From 9df2d0070bd3de66ad6d4271fb6b306adf1a8dcb Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Thu, 31 Jul 2025 18:11:23 +0900 Subject: [PATCH 26/32] =?UTF-8?q?[feat]:=20=ED=95=A8=EC=88=98=20=EB=B0=98?= =?UTF-8?q?=EC=98=81=20=EB=B0=8F=20navigateBack=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../extensions/CommonNavigationExtensions.kt | 4 -- .../navigator/navigations/CommonNavigation.kt | 3 +- .../navigator/navigations/GroupNavigation.kt | 43 ++++++++----------- 3 files changed, 18 insertions(+), 32 deletions(-) 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 index ac5245ec..1e16cea8 100644 --- 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 @@ -7,10 +7,6 @@ import com.texthip.thip.ui.navigator.routes.MainTabRoutes // 공통 네비게이션 확장 함수들 -// 뒤로가기 -fun NavHostController.navigateBack() { - popBackStack() -} // Bottom Navigation용 Tab 이동 (메인 탭에만 사용) fun NavHostController.navigateToTab(route: MainTabRoutes) { diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/navigations/CommonNavigation.kt b/app/src/main/java/com/texthip/thip/ui/navigator/navigations/CommonNavigation.kt index 2e7d3242..b9804e77 100644 --- a/app/src/main/java/com/texthip/thip/ui/navigator/navigations/CommonNavigation.kt +++ b/app/src/main/java/com/texthip/thip/ui/navigator/navigations/CommonNavigation.kt @@ -9,7 +9,6 @@ import androidx.compose.runtime.getValue import com.texthip.thip.ui.common.alarmpage.screen.AlarmScreen import com.texthip.thip.ui.common.alarmpage.viewmodel.AlarmViewModel import com.texthip.thip.ui.navigator.routes.CommonRoutes -import com.texthip.thip.ui.navigator.extensions.navigateBack // Common 관련 네비게이션 fun NavGraphBuilder.commonNavigation(navController: NavHostController) { @@ -22,7 +21,7 @@ fun NavGraphBuilder.commonNavigation(navController: NavHostController) { alarmItems = alarmItems, onCardClick = { alarmViewModel.onCardClick(it) }, onNavigateBack = { - navController.navigateBack() + navController.popBackStack() } ) } 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 index c3c3a23c..25503ff9 100644 --- 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 @@ -23,7 +23,6 @@ import com.texthip.thip.ui.group.room.screen.GroupRoomScreen import com.texthip.thip.ui.group.screen.GroupDoneScreen import com.texthip.thip.ui.group.screen.GroupScreen import com.texthip.thip.ui.group.search.screen.GroupSearchScreen -import com.texthip.thip.ui.navigator.extensions.navigateBack import com.texthip.thip.ui.navigator.extensions.navigateToAlarm import com.texthip.thip.ui.navigator.extensions.navigateToGroupDone import com.texthip.thip.ui.navigator.extensions.navigateToGroupMakeRoom @@ -76,10 +75,10 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { GroupMakeRoomScreen( viewModel = viewModel, onNavigateBack = { - navController.navigateBack() + navController.popBackStack() }, onGroupCreated = { - navController.navigateBack() + navController.popBackStack() } ) } @@ -105,7 +104,7 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { name = userName, allDataList = doneGroups, onNavigateBack = { - navController.navigateBack() + navController.popBackStack() } ) } @@ -129,18 +128,14 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { GroupMyScreen( allDataList = myRoomGroups, onCardClick = { room -> - groupViewModel.onRoomCardClick( - room, - onNavigateToRecruit = { roomId -> - navController.navigateToGroupRecruit(roomId) - }, - onNavigateToRoom = { roomId -> - navController.navigateToGroupRoom(roomId) - } - ) + if (room.isRecruiting) { + navController.navigateToGroupRecruit(room.id) + } else { + navController.navigateToGroupRoom(room.id) + } }, onNavigateBack = { - navController.navigateBack() + navController.popBackStack() } ) } @@ -164,18 +159,14 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { GroupSearchScreen( roomList = searchGroups, onNavigateBack = { - navController.navigateBack() + navController.popBackStack() }, onRoomClick = { room -> - groupViewModel.onRoomCardClick( - room, - onNavigateToRecruit = { roomId -> - navController.navigateToGroupRecruit(roomId) - }, - onNavigateToRoom = { roomId -> - navController.navigateToGroupRoom(roomId) - } - ) + if (room.isRecruiting) { + navController.navigateToGroupRecruit(room.id) + } else { + navController.navigateToGroupRoom(room.id) + } } ) } @@ -220,7 +211,7 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { // 모집 마감 로직 }, onBackClick = { - navController.navigateBack() + navController.popBackStack() } ) } ?: run { @@ -254,7 +245,7 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { roomDetail?.let { GroupRoomScreen( onBackClick = { - navController.navigateBack() + navController.popBackStack() } ) } ?: run { From 7de46778507e2861764e6bd310f68d14645c9637 Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Thu, 31 Jul 2025 18:18:49 +0900 Subject: [PATCH 27/32] =?UTF-8?q?[feat]:=20=EA=B3=B5=ED=86=B5=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=EC=9D=80=20=EC=A3=BC=EC=9E=85=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EB=B0=A9=EB=B2=95=EC=9C=BC=EB=A1=9C=20=EA=B5=AC=ED=98=84=20(#5?= =?UTF-8?q?8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../texthip/thip/ui/navigator/MainNavHost.kt | 10 ++++++++-- .../navigator/navigations/CommonNavigation.kt | 9 +++++---- .../navigator/navigations/GroupNavigation.kt | 19 +++++++++++-------- 3 files changed, 24 insertions(+), 14 deletions(-) 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 c2f8cb76..894a09d8 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 @@ -15,9 +15,15 @@ import com.texthip.thip.ui.navigator.navigations.commonNavigation fun MainNavHost(navController: NavHostController) { NavHost(navController = navController, startDestination = MainTabRoutes.Feed) { feedNavigation(navController) - groupNavigation(navController) + groupNavigation( + navController = navController, + navigateBack = navController::popBackStack + ) searchNavigation(navController) myPageNavigation(navController) - commonNavigation(navController) + commonNavigation( + navController = navController, + navigateBack = navController::popBackStack + ) } } \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/navigations/CommonNavigation.kt b/app/src/main/java/com/texthip/thip/ui/navigator/navigations/CommonNavigation.kt index b9804e77..d2cd398c 100644 --- a/app/src/main/java/com/texthip/thip/ui/navigator/navigations/CommonNavigation.kt +++ b/app/src/main/java/com/texthip/thip/ui/navigator/navigations/CommonNavigation.kt @@ -11,7 +11,10 @@ import com.texthip.thip.ui.common.alarmpage.viewmodel.AlarmViewModel import com.texthip.thip.ui.navigator.routes.CommonRoutes // Common 관련 네비게이션 -fun NavGraphBuilder.commonNavigation(navController: NavHostController) { +fun NavGraphBuilder.commonNavigation( + navController: NavHostController, + navigateBack: () -> Unit +) { // Alarm 화면 composable { val alarmViewModel: AlarmViewModel = viewModel() @@ -20,9 +23,7 @@ fun NavGraphBuilder.commonNavigation(navController: NavHostController) { AlarmScreen( alarmItems = alarmItems, onCardClick = { alarmViewModel.onCardClick(it) }, - onNavigateBack = { - navController.popBackStack() - } + onNavigateBack = navigateBack ) } } \ 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 index 25503ff9..bc1a7722 100644 --- 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 @@ -36,7 +36,10 @@ import com.texthip.thip.ui.navigator.routes.MainTabRoutes // Group @SuppressLint("UnrememberedGetBackStackEntry") -fun NavGraphBuilder.groupNavigation(navController: NavHostController) { +fun NavGraphBuilder.groupNavigation( + navController: NavHostController, + navigateBack: () -> Unit +) { // 메인 Group 화면 composable { backStackEntry -> val groupViewModel: GroupViewModel = viewModel( @@ -75,10 +78,10 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { GroupMakeRoomScreen( viewModel = viewModel, onNavigateBack = { - navController.popBackStack() + navigateBack() }, onGroupCreated = { - navController.popBackStack() + navigateBack() } ) } @@ -104,7 +107,7 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { name = userName, allDataList = doneGroups, onNavigateBack = { - navController.popBackStack() + navigateBack() } ) } @@ -135,7 +138,7 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { } }, onNavigateBack = { - navController.popBackStack() + navigateBack() } ) } @@ -159,7 +162,7 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { GroupSearchScreen( roomList = searchGroups, onNavigateBack = { - navController.popBackStack() + navigateBack() }, onRoomClick = { room -> if (room.isRecruiting) { @@ -211,7 +214,7 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { // 모집 마감 로직 }, onBackClick = { - navController.popBackStack() + navigateBack() } ) } ?: run { @@ -245,7 +248,7 @@ fun NavGraphBuilder.groupNavigation(navController: NavHostController) { roomDetail?.let { GroupRoomScreen( onBackClick = { - navController.popBackStack() + navigateBack() } ) } ?: run { From 74e36da0457513b1f6ad49427d732740f673c2e5 Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Fri, 1 Aug 2025 22:45:13 +0900 Subject: [PATCH 28/32] =?UTF-8?q?[feat]:=20=ED=8C=8C=EC=9D=BC=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0=20=EB=B3=80=EA=B2=BD=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/texthip/thip/ui/group/screen/GroupScreen.kt | 2 +- .../texthip/thip/ui/navigator/navigations/GroupNavigation.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 82eb31e4..ff2fb15d 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 @@ -26,7 +26,7 @@ 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.data.viewmodel.GroupViewModel +import com.texthip.thip.ui.group.viewmodel.GroupViewModel import com.texthip.thip.ui.theme.ThipTheme import com.texthip.thip.ui.theme.ThipTheme.colors 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 index bc1a7722..0c8adce7 100644 --- 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 @@ -12,7 +12,7 @@ import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController import androidx.navigation.compose.composable import androidx.navigation.toRoute -import com.texthip.thip.ui.group.data.viewmodel.GroupViewModel +import com.texthip.thip.ui.group.viewmodel.GroupViewModel import com.texthip.thip.ui.group.makeroom.screen.GroupMakeRoomScreen import com.texthip.thip.ui.group.makeroom.viewmodel.GroupMakeRoomViewModel import com.texthip.thip.ui.group.myroom.mock.GroupBottomButtonType From 1f0aa1f505a5c70bac3aec3da2fc7af909b0fd8f Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Fri, 1 Aug 2025 22:45:58 +0900 Subject: [PATCH 29/32] =?UTF-8?q?[feat]:=20GroupRepository=20=EC=9D=B8?= =?UTF-8?q?=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EC=82=AD=EC=A0=9C=20(#5?= =?UTF-8?q?8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/repository/GroupRepositoryImpl.kt | 324 ------------------ 1 file changed, 324 deletions(-) delete mode 100644 app/src/main/java/com/texthip/thip/ui/group/data/repository/GroupRepositoryImpl.kt diff --git a/app/src/main/java/com/texthip/thip/ui/group/data/repository/GroupRepositoryImpl.kt b/app/src/main/java/com/texthip/thip/ui/group/data/repository/GroupRepositoryImpl.kt deleted file mode 100644 index 1a145c58..00000000 --- a/app/src/main/java/com/texthip/thip/ui/group/data/repository/GroupRepositoryImpl.kt +++ /dev/null @@ -1,324 +0,0 @@ -package com.texthip.thip.ui.group.data.repository - -import com.texthip.thip.R -import com.texthip.thip.ui.group.myroom.mock.GroupBookData -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.GroupRoomData -import com.texthip.thip.ui.group.myroom.mock.GroupRoomSectionData -import kotlinx.coroutines.delay - -// GroupRepository의 구현 -// 실제로는 서버의 API와 통신할 거라서 다 삭제하고 함수 구조만 유지한 채 수정하면 될 듯 합니다. - -class GroupRepositoryImpl : GroupRepository { - - private val genres = listOf("문학", "과학·IT", "사회과학", "인문학", "예술") - private val roomDetailsCache = mutableMapOf() - - override suspend fun getUserName(): Result { - return try { - Result.success("규빈") // 임시 이름 - } catch (e: Exception) { - Result.failure(e) - } - } - - override suspend fun getMyGroups(): Result> { - return try { - delay(200) - val myGroups = listOf( - GroupCardData(23, "호르몬 체인지 완독하는 방", 22, R.drawable.bookcover_sample, 40, "uibowl1"), - GroupCardData(24, "명작 읽기방", 10, R.drawable.bookcover_sample, 70, "joyce"), - GroupCardData(25, "또 다른 방", 13, R.drawable.bookcover_sample, 10, "other") - ) - Result.success(myGroups) - } catch (e: Exception) { - Result.failure(e) - } - } - - override suspend fun getRoomSections(): Result> { - return try { - - // 마감 임박한 독서 모임방 - val deadlineRooms = listOf( - GroupCardItemRoomData(1, "시집만 읽는 사람들 3월", 22, 30, true, 3, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(2, "일본 소설 좋아하는 사람들", 15, 20, true, 2, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(3, "명작 같이 읽기방", 22, 30, true, 3, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(4, "물리책 읽는 방", 13, 20, true, 1, R.drawable.bookcover_sample, 1), - GroupCardItemRoomData(5, "코딩 과학 동아리", 12, 15, true, 5, R.drawable.bookcover_sample, 1), - GroupCardItemRoomData(6, "사회과학 인문 탐구", 8, 12, true, 4, R.drawable.bookcover_sample, 2) - ) - - // 인기 있는 독서 모임방 - val popularRooms = listOf( - GroupCardItemRoomData(7, "베스트셀러 토론방", 28, 30, true, 7, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(8, "인기 소설 완독방", 25, 25, false, 5, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(9, "트렌드 과학서 읽기", 20, 25, true, 10, R.drawable.bookcover_sample, 1), - GroupCardItemRoomData(10, "화제의 경영서", 18, 20, true, 8, R.drawable.bookcover_sample, 2), - GroupCardItemRoomData(11, "인기 철학서 모임", 15, 18, true, 12, R.drawable.bookcover_sample, 3), - GroupCardItemRoomData(12, "예술서 베스트", 12, 15, true, 6, R.drawable.bookcover_sample, 4) - ) - - // 인플루언서, 작가 독서 모임방 - val influencerRooms = listOf( - GroupCardItemRoomData(13, "작가와 함께하는 독서방", 30, 30, false, 14, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(14, "유명 북튜버와 읽기", 18, 20, true, 8, R.drawable.bookcover_sample, 2), - GroupCardItemRoomData(15, "작가 초청 인문학방", 15, 20, true, 12, R.drawable.bookcover_sample, 3), - GroupCardItemRoomData(16, "인플루언서 과학책", 22, 25, true, 9, R.drawable.bookcover_sample, 1), - GroupCardItemRoomData(17, "유명작가 예술론", 16, 18, true, 11, R.drawable.bookcover_sample, 4) - ) - - val sections = listOf( - GroupRoomSectionData( - title = "마감 임박한 독서 모임방", - rooms = deadlineRooms, - genres = genres - ), - GroupRoomSectionData( - title = "인기 있는 독서 모임방", - rooms = popularRooms, - genres = genres - ), - GroupRoomSectionData( - title = "인플루언서·작가 독서 모임방", - rooms = influencerRooms, - genres = genres - ) - ) - - // 상세 데이터 캐시에 저장 - (deadlineRooms + popularRooms + influencerRooms).forEach { room -> - initializeRoomDetail(room) - } - - Result.success(sections) - } catch (e: Exception) { - Result.failure(e) - } - } - - override suspend fun getDoneGroups(): Result> { - return try { - val doneGroups = listOf( - GroupCardItemRoomData(18, "완료된 독서 모임방 1", 15, 20, false, null, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(19, "완료된 독서 모임방 2", 25, 30, false, null, R.drawable.bookcover_sample, 1), - GroupCardItemRoomData(20, "완료된 독서 모임방 3", 12, 15, false, null, R.drawable.bookcover_sample, 2), - GroupCardItemRoomData(21, "호르몬 체인지 완독한 방", 22, 22, false, null, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(22, "명작 읽기방 완료", 10, 10, false, null, R.drawable.bookcover_sample, 0) - ) - - // 상세 데이터 캐시에 저장 - doneGroups.forEach { room -> - initializeRoomDetail(room) - } - - Result.success(doneGroups) - } catch (e: Exception) { - Result.failure(e) - } - } - - override suspend fun getMyRoomGroups(): Result> { - return try { - val myRoomGroups = listOf( - GroupCardItemRoomData(23, "호르몬 체인지 완독하는 방", 22, 30, true, 5, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(24, "명작 읽기방", 10, 20, true, 3, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(25, "또 다른 방", 13, 25, false, 10, R.drawable.bookcover_sample, 1), - GroupCardItemRoomData(26, "내가 참여한 과학책방", 18, 25, true, 7, R.drawable.bookcover_sample, 1), - GroupCardItemRoomData(27, "인문학 토론방", 12, 20, true, 2, R.drawable.bookcover_sample, 3) - ) - - // 상세 데이터 캐시에 저장 - myRoomGroups.forEach { room -> - initializeRoomDetail(room) - } - - Result.success(myRoomGroups) - } catch (e: Exception) { - Result.failure(e) - } - } - - override suspend fun getSearchGroups(): Result> { - return try { - // 기존에 로드된 섹션 데이터들을 합쳐서 반환 - val sectionsResult = getRoomSections() - if (sectionsResult.isSuccess) { - val allRooms = sectionsResult.getOrThrow().flatMap { it.rooms } - Result.success(allRooms) - } else { - Result.failure(sectionsResult.exceptionOrNull() ?: Exception("Failed to load search groups")) - } - } catch (e: Exception) { - Result.failure(e) - } - } - - override suspend fun getRoomDetail(roomId: Int): Result { - return try { - delay(150) - val roomDetail = roomDetailsCache[roomId] - if (roomDetail != null) { - Result.success(roomDetail) - } else { - Result.failure(Exception("Room not found: $roomId")) - } - } catch (e: Exception) { - Result.failure(e) - } - } - - override suspend fun searchRooms(query: String): Result> { - return try { - val searchResult = getSearchGroups() - if (searchResult.isSuccess) { - val filteredRooms = searchResult.getOrThrow().filter { room -> - room.title.contains(query, ignoreCase = true) - } - Result.success(filteredRooms) - } else { - searchResult - } - } catch (e: Exception) { - Result.failure(e) - } - } - - override suspend fun getGenres(): Result> { - return try { - delay(50) - Result.success(genres) - } catch (e: Exception) { - Result.failure(e) - } - } - - - private fun initializeRoomDetail(room: GroupCardItemRoomData) { - val bookData = GroupBookData( - title = "심장보다 단단한 토마토 한 알", - author = "고선지", - publisher = "푸른출판사", - description = "${room.title}에서 읽는 책입니다. 감동적인 이야기로 가득한 작품입니다.", - imageRes = room.imageRes ?: R.drawable.bookcover_sample - ) - - val recommendations = getRecommendations(room.id) - - val roomDetail = GroupRoomData( - id = room.id, - title = room.title, - isSecret = room.isSecret, - description = "${room.title} 모임입니다. 함께 책을 읽고 토론해요.", - startDate = "2025.01.12", - endDate = "2025.02.12", - members = room.participants, - maxMembers = room.maxParticipants, - daysLeft = room.endDate ?: 0, - genre = genres[room.genreIndex], - bookData = bookData, - recommendations = recommendations - ) - - roomDetailsCache[room.id] = roomDetail - - // 추천 모임방들의 상세 정보도 캐시에 추가 - recommendations.forEach { recommendedRoom -> - if (!roomDetailsCache.containsKey(recommendedRoom.id)) { - initializeRecommendedRoomDetail(recommendedRoom) - } - } - } - - // 추천 모임방 예시 by gpt - private fun initializeRecommendedRoomDetail(room: GroupCardItemRoomData) { - val bookTitles = listOf( - "데미안", "1984", "노인과 바다", "위대한 개츠비", "햄릿", - "코스모스", "이기적 유전자", "블랙홀과 시간여행", "총균쇠", - "국부론", "자본론", "사피엔스", "총균쇠", "정의란 무엇인가", - "예술의 역사", "음악의 역사", "미학 오디세이" - ) - - val authors = listOf( - "헤르만 헤세", "조지 오웰", "어니스트 헤밍웨이", "스콧 피츠제럴드", - "칼 세이건", "리처드 도킨스", "킵 손", "재레드 다이아몬드", - "아담 스미스", "칼 마르크스", "유발 하라리", "마이클 샌델" - ) - - val publishers = listOf("푸른출판사", "문학동네", "민음사", "창비", "열린책들", "김영사") - - val bookData = GroupBookData( - title = bookTitles.random(), - author = authors.random(), - publisher = publishers.random(), - description = "${room.title}에서 읽는 흥미로운 책입니다. 함께 읽으며 깊이 있는 토론을 나눠보세요.", - imageRes = room.imageRes ?: R.drawable.bookcover_sample - ) - - val roomDetail = GroupRoomData( - id = room.id, - title = room.title, - isSecret = room.isSecret, - description = "${room.title} 모임입니다. 다양한 관점으로 책을 읽고 의견을 나눠보세요.", - startDate = "2025.01.15", - endDate = "2025.02.15", - members = room.participants, - maxMembers = room.maxParticipants, - daysLeft = room.endDate ?: 0, - genre = genres.getOrElse(room.genreIndex) { genres[0] }, - bookData = bookData, - recommendations = getRecommendations(room.id) // 추천 모임방에도 추천 제공 - ) - - roomDetailsCache[room.id] = roomDetail - } - - private fun getRecommendations(roomId: Int): List { - // 추천 모임방 더미데이터 풀 - val recommendationPool = listOf( - // 문학 관련 추천 - GroupCardItemRoomData(1001, "한국 근현대 소설 읽기", 18, 25, true, 3, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(1002, "일본 문학 애호가들", 22, 30, true, 1, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(1003, "시 읽기 모임", 16, 25, true, 2, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(1004, "해외문학 번역서 읽기", 15, 22, true, 3, R.drawable.bookcover_sample, 0, true), - GroupCardItemRoomData(1005, "고전 문학 탐구", 20, 25, true, 5, R.drawable.bookcover_sample, 0), - - // 과학·IT 관련 추천 - GroupCardItemRoomData(1006, "SF 소설 탐험대", 12, 20, true, 7, R.drawable.bookcover_sample, 1), - GroupCardItemRoomData(1007, "과학도서 함께 읽기", 7, 15, true, 9, R.drawable.bookcover_sample, 1), - GroupCardItemRoomData(1008, "컴퓨터 과학 스터디", 14, 18, true, 4, R.drawable.bookcover_sample, 1), - GroupCardItemRoomData(1009, "물리학 입문서 모임", 10, 16, true, 6, R.drawable.bookcover_sample, 1), - - // 사회과학 관련 추천 - GroupCardItemRoomData(1010, "경제경영서 스터디", 9, 12, true, 6, R.drawable.bookcover_sample, 2), - GroupCardItemRoomData(1011, "사회학 도서 토론", 13, 18, true, 4, R.drawable.bookcover_sample, 2), - GroupCardItemRoomData(1012, "정치학 입문 모임", 11, 15, true, 8, R.drawable.bookcover_sample, 2), - - // 인문학 관련 추천 - GroupCardItemRoomData(1013, "철학 에세이 읽기 모임", 8, 15, true, 5, R.drawable.bookcover_sample, 3), - GroupCardItemRoomData(1014, "인문학 고전 읽기", 20, 25, true, 5, R.drawable.bookcover_sample, 3, true), - GroupCardItemRoomData(1015, "심리학 도서 스터디", 10, 16, true, 7, R.drawable.bookcover_sample, 3), - GroupCardItemRoomData(1016, "역사서 탐구 모임", 11, 16, true, 8, R.drawable.bookcover_sample, 3), - - // 예술 관련 추천 - GroupCardItemRoomData(1017, "미술사 도서 읽기", 14, 20, true, 3, R.drawable.bookcover_sample, 4), - GroupCardItemRoomData(1018, "음악 관련 서적 모임", 12, 18, true, 5, R.drawable.bookcover_sample, 4), - - // 기타 장르 - GroupCardItemRoomData(1019, "로맨스 소설 감상회", 14, 20, true, 4, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(1020, "미스터리 소설 동호회", 15, 18, true, 2, R.drawable.bookcover_sample, 0, true), - GroupCardItemRoomData(1021, "자기계발서 함께 읽기", 25, 30, true, 3, R.drawable.bookcover_sample, 2, true), - GroupCardItemRoomData(1022, "판타지 소설 동호회", 24, 30, true, 1, R.drawable.bookcover_sample, 0), - GroupCardItemRoomData(1023, "여행 에세이 모임", 13, 18, true, 4, R.drawable.bookcover_sample, 3), - GroupCardItemRoomData(1024, "추리소설 마니아", 19, 24, true, 6, R.drawable.bookcover_sample, 0) - ) - - // 현재 방과 관련 없는 추천을 제공하기 위해 현재 roomId와 다른 것들만 필터링 - val filteredRecommendations = recommendationPool.filter { it.id != roomId } - - // 랜덤하게 3-5개의 추천 반환 - return filteredRecommendations.shuffled().take(5) - } -} \ No newline at end of file From 5f0d68840ec4bc0704225474ebe2939e51fcdb2d Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Fri, 1 Aug 2025 22:46:21 +0900 Subject: [PATCH 30/32] =?UTF-8?q?[feat]:=20GroupRepository=20=EC=9D=B8?= =?UTF-8?q?=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EC=82=AD=EC=A0=9C=20(#5?= =?UTF-8?q?8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/group/repository/GroupRepository.kt | 324 ++++++++++++++++++ .../group/data/repository/GroupRepository.kt | 36 -- .../{data => }/viewmodel/GroupViewModel.kt | 7 +- 3 files changed, 327 insertions(+), 40 deletions(-) create mode 100644 app/src/main/java/com/texthip/thip/data/group/repository/GroupRepository.kt delete mode 100644 app/src/main/java/com/texthip/thip/ui/group/data/repository/GroupRepository.kt rename app/src/main/java/com/texthip/thip/ui/group/{data => }/viewmodel/GroupViewModel.kt (93%) diff --git a/app/src/main/java/com/texthip/thip/data/group/repository/GroupRepository.kt b/app/src/main/java/com/texthip/thip/data/group/repository/GroupRepository.kt new file mode 100644 index 00000000..4fbd66fa --- /dev/null +++ b/app/src/main/java/com/texthip/thip/data/group/repository/GroupRepository.kt @@ -0,0 +1,324 @@ +package com.texthip.thip.data.group.repository + +import com.texthip.thip.R +import com.texthip.thip.ui.group.myroom.mock.GroupBookData +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.GroupRoomData +import com.texthip.thip.ui.group.myroom.mock.GroupRoomSectionData +import kotlinx.coroutines.delay + +// 그룹 데이터를 제공하는 Repository +// 실제로는 서버의 API와 통신할 거라서 다 삭제하고 함수 구조만 유지한 채 수정하면 될 듯 합니다. + +class GroupRepository { + + private val genres = listOf("문학", "과학·IT", "사회과학", "인문학", "예술") + private val roomDetailsCache = mutableMapOf() + + suspend fun getUserName(): Result { + return try { + Result.success("규빈") // 임시 이름 + } catch (e: Exception) { + Result.failure(e) + } + } + + suspend fun getMyGroups(): Result> { + return try { + delay(200) + val myGroups = listOf( + GroupCardData(23, "호르몬 체인지 완독하는 방", 22, R.drawable.bookcover_sample, 40, "uibowl1"), + GroupCardData(24, "명작 읽기방", 10, R.drawable.bookcover_sample, 70, "joyce"), + GroupCardData(25, "또 다른 방", 13, R.drawable.bookcover_sample, 10, "other") + ) + Result.success(myGroups) + } catch (e: Exception) { + Result.failure(e) + } + } + + suspend fun getRoomSections(): Result> { + return try { + + // 마감 임박한 독서 모임방 + val deadlineRooms = listOf( + GroupCardItemRoomData(1, "시집만 읽는 사람들 3월", 22, 30, true, 3, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(2, "일본 소설 좋아하는 사람들", 15, 20, true, 2, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(3, "명작 같이 읽기방", 22, 30, true, 3, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(4, "물리책 읽는 방", 13, 20, true, 1, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(5, "코딩 과학 동아리", 12, 15, true, 5, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(6, "사회과학 인문 탐구", 8, 12, true, 4, R.drawable.bookcover_sample, 2) + ) + + // 인기 있는 독서 모임방 + val popularRooms = listOf( + GroupCardItemRoomData(7, "베스트셀러 토론방", 28, 30, true, 7, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(8, "인기 소설 완독방", 25, 25, false, 5, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(9, "트렌드 과학서 읽기", 20, 25, true, 10, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(10, "화제의 경영서", 18, 20, true, 8, R.drawable.bookcover_sample, 2), + GroupCardItemRoomData(11, "인기 철학서 모임", 15, 18, true, 12, R.drawable.bookcover_sample, 3), + GroupCardItemRoomData(12, "예술서 베스트", 12, 15, true, 6, R.drawable.bookcover_sample, 4) + ) + + // 인플루언서, 작가 독서 모임방 + val influencerRooms = listOf( + GroupCardItemRoomData(13, "작가와 함께하는 독서방", 30, 30, false, 14, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(14, "유명 북튜버와 읽기", 18, 20, true, 8, R.drawable.bookcover_sample, 2), + GroupCardItemRoomData(15, "작가 초청 인문학방", 15, 20, true, 12, R.drawable.bookcover_sample, 3), + GroupCardItemRoomData(16, "인플루언서 과학책", 22, 25, true, 9, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(17, "유명작가 예술론", 16, 18, true, 11, R.drawable.bookcover_sample, 4) + ) + + val sections = listOf( + GroupRoomSectionData( + title = "마감 임박한 독서 모임방", + rooms = deadlineRooms, + genres = genres + ), + GroupRoomSectionData( + title = "인기 있는 독서 모임방", + rooms = popularRooms, + genres = genres + ), + GroupRoomSectionData( + title = "인플루언서·작가 독서 모임방", + rooms = influencerRooms, + genres = genres + ) + ) + + // 상세 데이터 캐시에 저장 + (deadlineRooms + popularRooms + influencerRooms).forEach { room -> + initializeRoomDetail(room) + } + + Result.success(sections) + } catch (e: Exception) { + Result.failure(e) + } + } + + suspend fun getDoneGroups(): Result> { + return try { + val doneGroups = listOf( + GroupCardItemRoomData(18, "완료된 독서 모임방 1", 15, 20, false, null, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(19, "완료된 독서 모임방 2", 25, 30, false, null, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(20, "완료된 독서 모임방 3", 12, 15, false, null, R.drawable.bookcover_sample, 2), + GroupCardItemRoomData(21, "호르몬 체인지 완독한 방", 22, 22, false, null, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(22, "명작 읽기방 완료", 10, 10, false, null, R.drawable.bookcover_sample, 0) + ) + + // 상세 데이터 캐시에 저장 + doneGroups.forEach { room -> + initializeRoomDetail(room) + } + + Result.success(doneGroups) + } catch (e: Exception) { + Result.failure(e) + } + } + + suspend fun getMyRoomGroups(): Result> { + return try { + val myRoomGroups = listOf( + GroupCardItemRoomData(23, "호르몬 체인지 완독하는 방", 22, 30, true, 5, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(24, "명작 읽기방", 10, 20, true, 3, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(25, "또 다른 방", 13, 25, false, 10, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(26, "내가 참여한 과학책방", 18, 25, true, 7, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(27, "인문학 토론방", 12, 20, true, 2, R.drawable.bookcover_sample, 3) + ) + + // 상세 데이터 캐시에 저장 + myRoomGroups.forEach { room -> + initializeRoomDetail(room) + } + + Result.success(myRoomGroups) + } catch (e: Exception) { + Result.failure(e) + } + } + + suspend fun getSearchGroups(): Result> { + return try { + // 기존에 로드된 섹션 데이터들을 합쳐서 반환 + val sectionsResult = getRoomSections() + if (sectionsResult.isSuccess) { + val allRooms = sectionsResult.getOrThrow().flatMap { it.rooms } + Result.success(allRooms) + } else { + Result.failure(sectionsResult.exceptionOrNull() ?: Exception("Failed to load search groups")) + } + } catch (e: Exception) { + Result.failure(e) + } + } + + suspend fun getRoomDetail(roomId: Int): Result { + return try { + delay(150) + val roomDetail = roomDetailsCache[roomId] + if (roomDetail != null) { + Result.success(roomDetail) + } else { + Result.failure(Exception("Room not found: $roomId")) + } + } catch (e: Exception) { + Result.failure(e) + } + } + + suspend fun searchRooms(query: String): Result> { + return try { + val searchResult = getSearchGroups() + if (searchResult.isSuccess) { + val filteredRooms = searchResult.getOrThrow().filter { room -> + room.title.contains(query, ignoreCase = true) + } + Result.success(filteredRooms) + } else { + searchResult + } + } catch (e: Exception) { + Result.failure(e) + } + } + + suspend fun getGenres(): Result> { + return try { + delay(50) + Result.success(genres) + } catch (e: Exception) { + Result.failure(e) + } + } + + + private fun initializeRoomDetail(room: GroupCardItemRoomData) { + val bookData = GroupBookData( + title = "심장보다 단단한 토마토 한 알", + author = "고선지", + publisher = "푸른출판사", + description = "${room.title}에서 읽는 책입니다. 감동적인 이야기로 가득한 작품입니다.", + imageRes = room.imageRes ?: R.drawable.bookcover_sample + ) + + val recommendations = getRecommendations(room.id) + + val roomDetail = GroupRoomData( + id = room.id, + title = room.title, + isSecret = room.isSecret, + description = "${room.title} 모임입니다. 함께 책을 읽고 토론해요.", + startDate = "2025.01.12", + endDate = "2025.02.12", + members = room.participants, + maxMembers = room.maxParticipants, + daysLeft = room.endDate ?: 0, + genre = genres[room.genreIndex], + bookData = bookData, + recommendations = recommendations + ) + + roomDetailsCache[room.id] = roomDetail + + // 추천 모임방들의 상세 정보도 캐시에 추가 + recommendations.forEach { recommendedRoom -> + if (!roomDetailsCache.containsKey(recommendedRoom.id)) { + initializeRecommendedRoomDetail(recommendedRoom) + } + } + } + + // 추천 모임방 예시 by gpt + private fun initializeRecommendedRoomDetail(room: GroupCardItemRoomData) { + val bookTitles = listOf( + "데미안", "1984", "노인과 바다", "위대한 개츠비", "햄릿", + "코스모스", "이기적 유전자", "블랙홀과 시간여행", "총균쇠", + "국부론", "자본론", "사피엔스", "총균쇠", "정의란 무엇인가", + "예술의 역사", "음악의 역사", "미학 오디세이" + ) + + val authors = listOf( + "헤르만 헤세", "조지 오웰", "어니스트 헤밍웨이", "스콧 피츠제럴드", + "칼 세이건", "리처드 도킨스", "킵 손", "재레드 다이아몬드", + "아담 스미스", "칼 마르크스", "유발 하라리", "마이클 샌델" + ) + + val publishers = listOf("푸른출판사", "문학동네", "민음사", "창비", "열린책들", "김영사") + + val bookData = GroupBookData( + title = bookTitles.random(), + author = authors.random(), + publisher = publishers.random(), + description = "${room.title}에서 읽는 흥미로운 책입니다. 함께 읽으며 깊이 있는 토론을 나눠보세요.", + imageRes = room.imageRes ?: R.drawable.bookcover_sample + ) + + val roomDetail = GroupRoomData( + id = room.id, + title = room.title, + isSecret = room.isSecret, + description = "${room.title} 모임입니다. 다양한 관점으로 책을 읽고 의견을 나눠보세요.", + startDate = "2025.01.15", + endDate = "2025.02.15", + members = room.participants, + maxMembers = room.maxParticipants, + daysLeft = room.endDate ?: 0, + genre = genres.getOrElse(room.genreIndex) { genres[0] }, + bookData = bookData, + recommendations = getRecommendations(room.id) // 추천 모임방에도 추천 제공 + ) + + roomDetailsCache[room.id] = roomDetail + } + + private fun getRecommendations(roomId: Int): List { + // 추천 모임방 더미데이터 풀 + val recommendationPool = listOf( + // 문학 관련 추천 + GroupCardItemRoomData(1001, "한국 근현대 소설 읽기", 18, 25, true, 3, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(1002, "일본 문학 애호가들", 22, 30, true, 1, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(1003, "시 읽기 모임", 16, 25, true, 2, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(1004, "해외문학 번역서 읽기", 15, 22, true, 3, R.drawable.bookcover_sample, 0, true), + GroupCardItemRoomData(1005, "고전 문학 탐구", 20, 25, true, 5, R.drawable.bookcover_sample, 0), + + // 과학·IT 관련 추천 + GroupCardItemRoomData(1006, "SF 소설 탐험대", 12, 20, true, 7, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(1007, "과학도서 함께 읽기", 7, 15, true, 9, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(1008, "컴퓨터 과학 스터디", 14, 18, true, 4, R.drawable.bookcover_sample, 1), + GroupCardItemRoomData(1009, "물리학 입문서 모임", 10, 16, true, 6, R.drawable.bookcover_sample, 1), + + // 사회과학 관련 추천 + GroupCardItemRoomData(1010, "경제경영서 스터디", 9, 12, true, 6, R.drawable.bookcover_sample, 2), + GroupCardItemRoomData(1011, "사회학 도서 토론", 13, 18, true, 4, R.drawable.bookcover_sample, 2), + GroupCardItemRoomData(1012, "정치학 입문 모임", 11, 15, true, 8, R.drawable.bookcover_sample, 2), + + // 인문학 관련 추천 + GroupCardItemRoomData(1013, "철학 에세이 읽기 모임", 8, 15, true, 5, R.drawable.bookcover_sample, 3), + GroupCardItemRoomData(1014, "인문학 고전 읽기", 20, 25, true, 5, R.drawable.bookcover_sample, 3, true), + GroupCardItemRoomData(1015, "심리학 도서 스터디", 10, 16, true, 7, R.drawable.bookcover_sample, 3), + GroupCardItemRoomData(1016, "역사서 탐구 모임", 11, 16, true, 8, R.drawable.bookcover_sample, 3), + + // 예술 관련 추천 + GroupCardItemRoomData(1017, "미술사 도서 읽기", 14, 20, true, 3, R.drawable.bookcover_sample, 4), + GroupCardItemRoomData(1018, "음악 관련 서적 모임", 12, 18, true, 5, R.drawable.bookcover_sample, 4), + + // 기타 장르 + GroupCardItemRoomData(1019, "로맨스 소설 감상회", 14, 20, true, 4, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(1020, "미스터리 소설 동호회", 15, 18, true, 2, R.drawable.bookcover_sample, 0, true), + GroupCardItemRoomData(1021, "자기계발서 함께 읽기", 25, 30, true, 3, R.drawable.bookcover_sample, 2, true), + GroupCardItemRoomData(1022, "판타지 소설 동호회", 24, 30, true, 1, R.drawable.bookcover_sample, 0), + GroupCardItemRoomData(1023, "여행 에세이 모임", 13, 18, true, 4, R.drawable.bookcover_sample, 3), + GroupCardItemRoomData(1024, "추리소설 마니아", 19, 24, true, 6, R.drawable.bookcover_sample, 0) + ) + + // 현재 방과 관련 없는 추천을 제공하기 위해 현재 roomId와 다른 것들만 필터링 + val filteredRecommendations = recommendationPool.filter { it.id != roomId } + + // 랜덤하게 3-5개의 추천 반환 + return filteredRecommendations.shuffled().take(5) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/group/data/repository/GroupRepository.kt b/app/src/main/java/com/texthip/thip/ui/group/data/repository/GroupRepository.kt deleted file mode 100644 index 4db260c5..00000000 --- a/app/src/main/java/com/texthip/thip/ui/group/data/repository/GroupRepository.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.texthip.thip.ui.group.data.repository - -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.GroupRoomData -import com.texthip.thip.ui.group.myroom.mock.GroupRoomSectionData - - -// 그룹 데이터를 제공하는 Repository 인터페이스 -interface GroupRepository { - // 사용저의 이름 - suspend fun getUserName(): Result - - // 내 모임방 카드 목록 - suspend fun getMyGroups(): Result> - - // 모임방 섹션 데이터 (마감 임박, 인기, 인플루언서 등) - suspend fun getRoomSections(): Result> - - // 완료된 모임방 목록 - suspend fun getDoneGroups(): Result> - - // 내 참여 모임방 목록 - suspend fun getMyRoomGroups(): Result> - - // 검색용 모임방 목록 - suspend fun getSearchGroups(): Result> - - // 특정 모임방 상세 정보 - suspend fun getRoomDetail(roomId: Int): Result - - // 모임방 검색 - suspend fun searchRooms(query: String): Result> - - suspend fun getGenres(): Result> -} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/group/data/viewmodel/GroupViewModel.kt b/app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt similarity index 93% rename from app/src/main/java/com/texthip/thip/ui/group/data/viewmodel/GroupViewModel.kt rename to app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt index 45f2ea0a..561adffe 100644 --- a/app/src/main/java/com/texthip/thip/ui/group/data/viewmodel/GroupViewModel.kt +++ b/app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt @@ -1,9 +1,8 @@ -package com.texthip.thip.ui.group.data.viewmodel +package com.texthip.thip.ui.group.viewmodel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.texthip.thip.ui.group.data.repository.GroupRepository -import com.texthip.thip.ui.group.data.repository.GroupRepositoryImpl +import com.texthip.thip.data.group.repository.GroupRepository 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 @@ -14,7 +13,7 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch class GroupViewModel( - private val repository: GroupRepository = GroupRepositoryImpl() + private val repository: GroupRepository = GroupRepository() ) : ViewModel() { private val _myGroups = MutableStateFlow>(emptyList()) From 56d99d2073e707e266b2993bb8d9793204fb0d76 Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Fri, 1 Aug 2025 22:54:42 +0900 Subject: [PATCH 31/32] =?UTF-8?q?[feat]:=20Hilt=20=EC=9D=98=EC=A1=B4?= =?UTF-8?q?=EC=84=B1=20=EC=B6=94=EA=B0=80=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 6 ++++++ build.gradle.kts | 2 ++ gradle/libs.versions.toml | 11 +++++++++-- gradle/wrapper/gradle-wrapper.properties | 2 +- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 6664e029..26c15da3 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -5,6 +5,8 @@ plugins { alias(libs.plugins.kotlin.android) alias(libs.plugins.kotlin.compose) alias(libs.plugins.kotlin.serialization) + alias(libs.plugins.kotlin.android.ksp) + alias(libs.plugins.hilt.android) } android { @@ -66,4 +68,8 @@ dependencies { androidTestImplementation(libs.androidx.ui.test.junit4) debugImplementation(libs.androidx.ui.tooling) debugImplementation(libs.androidx.ui.test.manifest) + + implementation(libs.hilt.android) + implementation(libs.hilt.navigation.compose) + ksp(libs.hilt.compiler) } \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 952b9306..b50b246d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,4 +3,6 @@ plugins { alias(libs.plugins.android.application) apply false alias(libs.plugins.kotlin.android) apply false alias(libs.plugins.kotlin.compose) apply false + alias(libs.plugins.kotlin.android.ksp) apply false + alias(libs.plugins.hilt.android) apply false } \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7cf86970..c7bd95f4 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -agp = "8.9.1" +agp = "8.11.1" kotlin = "2.0.21" coreKtx = "1.16.0" junit = "4.13.2" @@ -15,6 +15,9 @@ navigationRuntimeAndroid = "2.9.0" accompanistPager = "0.36.0" accompanistPagerIndicators = "0.36.0" kotlinxSerializationJson = "1.7.3" +ksp = "2.0.21-1.0.28" +hilt = "2.51.1" +hiltNavigationCompose = "1.2.0" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -38,10 +41,14 @@ androidx-navigation-runtime-android = { group = "androidx.navigation", name = "n 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" } +hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" } +hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hilt" } +hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "hiltNavigationCompose" } [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" } - +kotlin-android-ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } +hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "hilt" } \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c686c423..bc55b151 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Mon Apr 28 18:50:30 KST 2025 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From 7dc33b176faff53b2fa16a1eb63c2688e267d677 Mon Sep 17 00:00:00 2001 From: rbqks529 Date: Sun, 3 Aug 2025 22:14:28 +0900 Subject: [PATCH 32/32] =?UTF-8?q?[feat]:=20Hilt=20=EC=9D=98=EC=A1=B4?= =?UTF-8?q?=EC=84=B1=20=EC=82=AD=EC=A0=9C=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 6 ------ build.gradle.kts | 2 -- gradle/libs.versions.toml | 10 +--------- 3 files changed, 1 insertion(+), 17 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 26c15da3..6664e029 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -5,8 +5,6 @@ plugins { alias(libs.plugins.kotlin.android) alias(libs.plugins.kotlin.compose) alias(libs.plugins.kotlin.serialization) - alias(libs.plugins.kotlin.android.ksp) - alias(libs.plugins.hilt.android) } android { @@ -68,8 +66,4 @@ dependencies { androidTestImplementation(libs.androidx.ui.test.junit4) debugImplementation(libs.androidx.ui.tooling) debugImplementation(libs.androidx.ui.test.manifest) - - implementation(libs.hilt.android) - implementation(libs.hilt.navigation.compose) - ksp(libs.hilt.compiler) } \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index b50b246d..952b9306 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,6 +3,4 @@ plugins { alias(libs.plugins.android.application) apply false alias(libs.plugins.kotlin.android) apply false alias(libs.plugins.kotlin.compose) apply false - alias(libs.plugins.kotlin.android.ksp) apply false - alias(libs.plugins.hilt.android) apply false } \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c7bd95f4..d47cb6ea 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,9 +15,6 @@ navigationRuntimeAndroid = "2.9.0" accompanistPager = "0.36.0" accompanistPagerIndicators = "0.36.0" kotlinxSerializationJson = "1.7.3" -ksp = "2.0.21-1.0.28" -hilt = "2.51.1" -hiltNavigationCompose = "1.2.0" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -41,14 +38,9 @@ androidx-navigation-runtime-android = { group = "androidx.navigation", name = "n 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" } -hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" } -hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hilt" } -hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "hiltNavigationCompose" } [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" } -kotlin-android-ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } -hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "hilt" } \ No newline at end of file +kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } \ No newline at end of file