-
Notifications
You must be signed in to change notification settings - Fork 3
[FEAT] home api 연결 #81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
… into api/home # Conflicts: # app/src/main/java/com/kuit/ourmenu/data/di/ServiceModule.kt
… into api/home # Conflicts: # .idea/deploymentTargetSelector.xml
Walkthrough홈 화면 API 연동을 위해 네트워킹 계층(HomeService, 모델, Repository)과 DI를 추가하고, HomeViewModel을 도입해 UI(HomeScreen, 추천 컴포넌트, 다이얼로그)를 데이터 기반으로 개편했습니다. 내비게이션 콜백을 확장하고, 더미 데이터/공용 버튼 컴포저블을 제거했으며 문자열 리소스를 추가했습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant UI as HomeScreen
participant VM as HomeViewModel
participant Repo as HomeRepository
participant Svc as HomeService
participant API as Server
UI->>VM: 화면 시작/재개
VM->>Repo: getHome()
Repo->>Svc: GET /api/home
Svc->>API: Request
API-->>Svc: BaseResponse<HomeResponse>
Svc-->>Repo: HomeResponse
Repo-->>VM: HomeResponse
VM-->>UI: 상태 업데이트(배너/추천 리스트)
UI->>VM: 다이얼로그 트리거/초기 질문
VM->>Repo: postHomeQuestion()
Repo->>Svc: POST /api/home/questions
Svc->>API: Request
API-->>Svc: BaseResponse<HomeQuestionResponse>
Svc-->>Repo: HomeQuestionResponse
Repo-->>VM: HomeQuestionResponse
VM-->>UI: 다이얼로그 표시(질문/답변 리스트)
UI->>VM: 답변 선택(answer)
VM->>Repo: postHomeAnswer(answer)
Repo->>Svc: POST /api/home/questions/answers
Svc->>API: Request(body: HomeAnswerRequest)
API-->>Svc: BaseResponse<Unit>
Svc-->>Repo: Unit
Repo-->>VM: 성공
VM->>Repo: getHome() (갱신)
Repo->>Svc: GET /api/home
Svc-->>Repo: HomeResponse
Repo-->>VM: HomeResponse
VM-->>UI: 추천 영역 갱신, 다이얼로그 닫기
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
Possibly related PRs
Suggested reviewers
Poem
✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
🔭 Outside diff range comments (1)
app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/main/HomeMainRecommendationItem.kt (1)
60-69: 텍스트 줄바꿈/오버플로우 처리긴 메뉴명에서 레이아웃 깨짐 방지를 위해 한 줄 제한 + 말줄임표를 권장합니다.
Text( text = recommendData.menuTitle, style = ourMenuTypography().pretendard_700_24.copy( shadow = Shadow( color = Color.Black.copy(alpha = 0.2f), // 그림자 색상 및 투명도 offset = Offset(0f, 2f), // 그림자 오프셋 (x = 0px, y = 2px) blurRadius = 4f // 블러 반경 ) ), + maxLines = 1, + overflow = androidx.compose.ui.text.style.TextOverflow.Ellipsis, color = NeutralWhite, )필요 import:
import androidx.compose.ui.text.style.TextOverflow
🧹 Nitpick comments (17)
app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/main/HomeMainRecommendationText.kt (1)
12-16: 원격 이미지 로딩 구현
AsyncImage를 사용해서imgUrl로부터 이미지를 로드하도록 변경한 것이 좋네요. API에서 받아온 이미지 URL을 바로 사용할 수 있겠습니다.다만 이미지 로딩 실패나 로딩 중 상태에 대한 처리를 추가하면 더 좋을 것 같습니다:
AsyncImage( modifier = modifier, model = imgUrl, contentDescription = "Home Banner", + loading = { + // 로딩 중 placeholder + }, + error = { + // 에러 시 fallback 이미지 + }, )app/src/main/java/com/kuit/ourmenu/data/di/ServiceModule.kt (1)
6-6: 네이밍 컨벤션 정리 제안 (선택)파일 내에 providesX / provideX 네이밍이 혼재합니다. 지금 HomeService는 인접한 provideMenuFolderService / provideMenuInfoService와 맞춰져 있어 OK지만, 장기적으로 일관성 있게 정리하면 가독성이 더 좋아집니다. 별도 PR로 일괄 정리 추천.
app/src/main/java/com/kuit/ourmenu/data/model/home/request/HomeAnswerRequest.kt (1)
5-8: 직렬화 필드명 명시 및 스펙 확인 제안서버 스펙이 명확하다면 @SerialName으로 필드명을 고정해두는 걸 권장합니다. 기존 더미 모델들도 @SerialName을 사용하고 있어 컨벤션 일관성에도 좋아요. 또한 백엔드가 기대하는 키가 실제로 "answer"인지 한번만 확인 부탁드립니다.
아래처럼 보강할 수 있어요:
package com.kuit.ourmenu.data.model.home.request +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable data class HomeAnswerRequest( - val answer: String + @SerialName("answer") + val answer: String )서버 명세가 다르면 올바른 키명으로 수정할 수 있게 알려주세요. 필요하면 연동 테스트 코드도 만들어 드릴게요.
app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/main/HomeMainRecommendationList.kt (1)
24-31: 빈 리스트 가드 좋고, 초기 스크롤 로직은 소폭 보강 권장
- Line [25]의 빈 리스트 early-return으로 0 나눗셈 예외 방지한 점 좋습니다.
- 초기 센터 정렬을 위한 scrollToItem은 데이터 크기 변화에 반응하도록 키를 size에 묶어두면 더 견고합니다.
- startIndex 계산은 remember로 한 번만 계산되게 해도 깔끔합니다.
- 추후 재사용성/상태 복원을 위해 LazyListState hoisting을 지원하면 좋습니다(기본값으로 remember를 두면 호출부는 그대로 사용 가능).
적용 예시:
- LaunchedEffect(Unit) { + LaunchedEffect(homeMainDataList.size) { state.scrollToItem(startIndex) }그리고 파라미터로 상태 호이스팅을 허용하는 개선(호출부 변경 없이 사용 가능):
@Composable fun HomeMainRecommendationList( modifier: Modifier = Modifier, - homeMainDataList: List<RecommendMenuList>, + homeMainDataList: List<RecommendMenuList>, onItemClick: (Long) -> Unit ) {아래 변경은 함수 바디(선택):
// 변경 전 val state = rememberLazyListState() // 변경 후 (파라미터로 상태를 받는 형태로 리팩토링 시) val state = rememberLazyListState() // 또는 파라미터로 교체 val startIndex = remember(homeMainDataList.size) { (Int.MAX_VALUE / 2) - (Int.MAX_VALUE / 2) % homeMainDataList.size }원하시면 상태 파라미터 추가까지 포함한 풀 리팩터 diff도 만들어 드릴게요.
app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/sub/HomeSubRecommendationText.kt (2)
16-17: contentDescription 하드코딩 지양 + 접근성/현지화 고려 필요이미지 설명을 고정 문자열로 두기보다 파라미터로 받거나 stringResource를 사용하세요. 장식용 이미지면 null이 더 적절합니다.
- contentDescription = "Home Sub Recommendation 1", + contentDescription = null, // or pass as a parameter (stringResource)
9-12: 컴포저블 이름과 역할 불일치텍스트가 아닌 이미지를 렌더링하므로 HomeSubRecommendationText → HomeSubRecommendationImage(또는 HeaderImage)로의 리네이밍을 고려해 주세요.
app/src/main/java/com/kuit/ourmenu/data/model/home/response/HomeQuestionResponse.kt (1)
11-15: Answer 이름이 모호함 (충돌/가독성 우려)패키지 레벨에서 Answer는 범용적이라 다른 도메인의 Answer와 충돌/혼동될 수 있어요. HomeAnswer(또는 HomeQuestionAnswer)로의 리네이밍을 추천드립니다.
리네이밍 시 연관 파일(HomeDialog, HomeViewModel, HomeScreen) 참조도 함께 변경 필요합니다.
app/src/main/java/com/kuit/ourmenu/data/repository/HomeRepository.kt (1)
9-12: 반환 타입 명시로 가독성 강화각 메서드의 반환 타입을 Result<...>로 명시하면 사용 측 가독성이 좋아집니다.
예:
suspend fun getHome(): Result<HomeResponse> = ... suspend fun postHomeQuestion(): Result<HomeQuestionResponse> = ... suspend fun postHomeAnswer(answer: String): Result<Unit> = ...app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/main/HomeMainRecommendationItem.kt (3)
35-37: 접근성 역할 지정으로 사용성 향상클릭 가능한 컨테이너에 role = Role.Button을 지정해 스크린리더 경험을 개선하세요.
- modifier = modifier.clickable{ - onItemClick(recommendData.menuId) - }, + modifier = modifier.clickable( + role = androidx.compose.ui.semantics.Role.Button, + onClick = { onItemClick(recommendData.menuId) } + ),
40-48: 이미지 접근성/로딩 품질 개선 제안
- 오버레이 텍스트가 있으므로 이미지는 장식용으로 보고 contentDescription = null 권장.
- crossfade/placeholder를 추가하면 UX 개선됩니다.
- AsyncImage( - model = recommendData.menuImgUrl, - contentDescription = "Main Recommendation Image", + AsyncImage( + model = coil3.request.ImageRequest.Builder( + androidx.compose.ui.platform.LocalContext.current + ).data(recommendData.menuImgUrl).crossfade(true).build(), + contentDescription = null, contentScale = ContentScale.Crop,필요 import:
import androidx.compose.ui.platform.LocalContext import coil3.request.ImageRequest
79-90: 부가 텍스트도 동일한 오버플로우 처리 권장가게명도 길 수 있어 동일한 처리로 일관성 있게 가세요.
Text( text = recommendData.storeName, style = ourMenuTypography().pretendard_600_16.copy( shadow = Shadow( color = Color.Black.copy(alpha = 0.2f), // 그림자 색상 및 투명도 offset = Offset(0f, 2f), // 그림자 오프셋 (x = 0px, y = 2px) blurRadius = 4f // 블러 반경 ), letterSpacing = (-0.4).sp, fontStyle = FontStyle.Normal, ), + maxLines = 1, + overflow = androidx.compose.ui.text.style.TextOverflow.Ellipsis, color = NeutralWhite, )app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/sub/HomeSubRecommendationItem.kt (1)
57-66: TODO 주석 처리 필요Line 58의 TODO 주석을 확인해보니 디자인 시스템 적용이 필요한 상태네요. 현재 TextStyle을 직접 정의하고 있는데, 일관성을 위해 디자인 시스템의 타이포그래피를 사용하는 것이 좋을 것 같습니다.
디자인 시스템을 적용한 코드를 생성해드릴까요? 아니면 이 작업을 추적하기 위한 이슈를 열어드릴까요?
app/src/main/java/com/kuit/ourmenu/data/model/home/response/HomeResponse.kt (1)
15-21: 네이밍 일관성 검토
RecommendMenuList라는 이름이 단일 아이템을 나타내는데 "List" 접미사를 사용하고 있어요. 실제로는 리스트가 아닌 단일 메뉴 아이템을 표현하는 데이터 클래스이므로,RecommendMenuItem또는RecommendMenu와 같은 이름이 더 직관적일 것 같습니다.@Serializable -data class RecommendMenuList( +data class RecommendMenuItem( val menuId: Long = 0, val menuTitle: String = "", val storeName: String = "", val menuImgUrl: String = "", )그리고
HomeResponse의 필드들도 함께 수정:@Serializable data class HomeResponse( val answerImgUrl: String = "", - val answerRecommendMenus: List<RecommendMenuList> = emptyList(), + val answerRecommendMenus: List<RecommendMenuItem> = emptyList(), val tagRecommendImgUrl: String = "", - val tagRecommendMenus: List<RecommendMenuList> = emptyList(), + val tagRecommendMenus: List<RecommendMenuItem> = emptyList(), val otherRecommendImgUrl: String = "", - val otherRecommendMenus: List<RecommendMenuList> = emptyList(), + val otherRecommendMenus: List<RecommendMenuItem> = emptyList(), )app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/sub/HomeSubRecommendation.kt (1)
21-21: TODO: State hoisting 구현 필요Line 21의 TODO 주석을 보니
LazyListState를 상위 컴포넌트로 올려야 하는 상황이네요. 현재는 이 컴포넌트 내부에서 state를 생성하고 있어서 외부에서 스크롤 상태를 제어하거나 관찰할 수 없습니다.state hoisting을 적용한 코드를 생성해드릴까요? 아니면 이 작업을 위한 이슈를 열어드릴까요?
app/src/main/java/com/kuit/ourmenu/ui/home/component/dialog/HomeDialog.kt (1)
100-122: 이미지 로딩 중 빈 버튼 표시 개선 필요로딩 상태에서 빈 버튼만 표시되면 사용자가 의도를 파악하기 어려울 수 있습니다. 로딩 인디케이터나 플레이스홀더 텍스트를 추가하는 것이 좋을 것 같네요.
loading = { Button( modifier = Modifier .width(248.dp) .height(48.dp), shape = RoundedCornerShape(8.dp), colors = ButtonDefaults.buttonColors( containerColor = Primary500Main, contentColor = NeutralWhite ), onClick = {} ) { - + CircularProgressIndicator( + modifier = Modifier.size(24.dp), + color = NeutralWhite + ) } },CircularProgressIndicator import 추가:
+import androidx.compose.material3.CircularProgressIndicatorapp/src/main/java/com/kuit/ourmenu/ui/home/screen/HomeScreen.kt (2)
49-62: null 체크 중복 제거 가능questionData가 null이 아닌지 이미 체크했는데 51번 줄에서 또 !! 연산자를 사용하고 있네요. 조건문에서 이미 null 체크를 했으니 스마트 캐스트가 적용될 텐데요.
if (showDialog && questionData != null) { HomePopUpDialog( - questionData = questionData!!, + questionData = questionData, onAnswerSelected = { selectedAnswer -> viewModel.selectAnswer(selectedAnswer) }, onDismissRequest = { viewModel.onDialogDismiss() }, onDiceClick = { viewModel.refreshQuestion() } ) }
118-121: 프리뷰에서 ViewModel 주입 처리프리뷰에서 ViewModel을 주석 처리하셨네요. 프리뷰 환경에서는 Hilt가 작동하지 않아서 그런 것 같은데, MockViewModel을 만들거나 @PreviewParameter를 활용하는 방법도 고려해보세요.
프리뷰용 MockViewModel 구현을 도와드릴까요? 이렇게 하면 프리뷰에서도 실제 UI 상태를 확인할 수 있습니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (25)
.gitignore(1 hunks)app/src/main/java/com/kuit/ourmenu/data/di/ServiceModule.kt(2 hunks)app/src/main/java/com/kuit/ourmenu/data/model/home/request/HomeAnswerRequest.kt(1 hunks)app/src/main/java/com/kuit/ourmenu/data/model/home/response/HomeQuestionResponse.kt(1 hunks)app/src/main/java/com/kuit/ourmenu/data/model/home/response/HomeResponse.kt(1 hunks)app/src/main/java/com/kuit/ourmenu/data/repository/HomeRepository.kt(1 hunks)app/src/main/java/com/kuit/ourmenu/data/service/HomeService.kt(1 hunks)app/src/main/java/com/kuit/ourmenu/ui/common/dialog/DialogBigButton.kt(0 hunks)app/src/main/java/com/kuit/ourmenu/ui/common/topappbar/OurMenuAddButtonTopAppBar.kt(2 hunks)app/src/main/java/com/kuit/ourmenu/ui/home/component/dialog/HomeDialog.kt(4 hunks)app/src/main/java/com/kuit/ourmenu/ui/home/component/dialog/HomeDialogAssets.kt(3 hunks)app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/main/HomeMainRecommendation.kt(1 hunks)app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/main/HomeMainRecommendationItem.kt(4 hunks)app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/main/HomeMainRecommendationList.kt(2 hunks)app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/main/HomeMainRecommendationText.kt(1 hunks)app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/sub/HomeSubRecommendation.kt(1 hunks)app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/sub/HomeSubRecommendationItem.kt(3 hunks)app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/sub/HomeSubRecommendationList.kt(2 hunks)app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/sub/HomeSubRecommendationText.kt(1 hunks)app/src/main/java/com/kuit/ourmenu/ui/home/dummy/HomeDummyData.kt(0 hunks)app/src/main/java/com/kuit/ourmenu/ui/home/navigation/HomeNavigation.kt(1 hunks)app/src/main/java/com/kuit/ourmenu/ui/home/screen/HomeScreen.kt(3 hunks)app/src/main/java/com/kuit/ourmenu/ui/home/viewmodel/HomeViewModel.kt(1 hunks)app/src/main/java/com/kuit/ourmenu/ui/navigator/MainNavHost.kt(1 hunks)app/src/main/res/values/strings.xml(1 hunks)
💤 Files with no reviewable changes (2)
- app/src/main/java/com/kuit/ourmenu/ui/common/dialog/DialogBigButton.kt
- app/src/main/java/com/kuit/ourmenu/ui/home/dummy/HomeDummyData.kt
🧰 Additional context used
🧬 Code Graph Analysis (13)
app/src/main/java/com/kuit/ourmenu/data/di/ServiceModule.kt (1)
app/src/main/java/com/kuit/ourmenu/data/di/NetworkModule.kt (2)
provideJson(20-74)providesRetrofit(59-72)
app/src/main/java/com/kuit/ourmenu/ui/common/topappbar/OurMenuAddButtonTopAppBar.kt (2)
app/src/main/java/com/kuit/ourmenu/ui/menuinfo/screen/MenuInfoMapScreen.kt (1)
OurMenuAddButtonTopAppBar(44-44)app/src/main/java/com/kuit/ourmenu/ui/searchmenu/screen/SearchMenuScreen.kt (1)
OurMenuAddButtonTopAppBar(143-143)
app/src/main/java/com/kuit/ourmenu/data/model/home/request/HomeAnswerRequest.kt (2)
app/src/main/java/com/kuit/ourmenu/data/model/dummy/request/DummyRequest.kt (1)
dummyString(6-9)app/src/main/java/com/kuit/ourmenu/data/model/dummy/response/DummyResponse.kt (1)
dummyString(6-9)
app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/main/HomeMainRecommendationText.kt (3)
app/src/main/java/com/kuit/ourmenu/ui/addmenu/component/bottomsheet/AddMenuBottomSheetContent.kt (1)
i(96-119)app/src/main/java/com/kuit/ourmenu/ui/menuinfo/component/info/MenuInfoImagePager.kt (1)
{(42-45)app/src/main/java/com/kuit/ourmenu/OurMenuApp.kt (1)
newImageLoader(28-37)
app/src/main/java/com/kuit/ourmenu/ui/home/component/dialog/HomeDialogAssets.kt (1)
app/src/main/java/com/kuit/ourmenu/ui/home/component/dialog/HomeDialogTouchBox.kt (1)
HomeDialogTouchBox(21-52)
app/src/main/java/com/kuit/ourmenu/ui/navigator/MainNavHost.kt (2)
app/src/main/java/com/kuit/ourmenu/ui/addmenu/component/bottomsheet/AddMenuBottomSheetContent.kt (1)
{(159-161)app/src/main/java/com/kuit/ourmenu/ui/addmenu/screen/AddMenuScreen.kt (2)
onNavigateToAddMenuInfo(163-165)AddMenuScreen(57-255)
app/src/main/java/com/kuit/ourmenu/ui/home/navigation/HomeNavigation.kt (2)
app/src/main/java/com/kuit/ourmenu/ui/home/screen/HomeScreen.kt (1)
HomeScreen(27-109)app/src/main/java/com/kuit/ourmenu/ui/addmenu/screen/AddMenuScreen.kt (3)
onNavigateToAddMenuInfo(163-165)AddMenuScreen(57-255){}(264-264)
app/src/main/java/com/kuit/ourmenu/data/model/home/response/HomeQuestionResponse.kt (2)
app/src/main/java/com/kuit/ourmenu/data/model/dummy/response/DummyResponse.kt (1)
dummyString(6-9)app/src/main/java/com/kuit/ourmenu/data/model/dummy/request/DummyRequest.kt (1)
dummyString(6-9)
app/src/main/java/com/kuit/ourmenu/data/repository/HomeRepository.kt (2)
app/src/main/java/com/kuit/ourmenu/data/repository/DummyRepository.kt (3)
dummyService(9-16)getDummyData(14-15)dummyService(15-15)app/src/main/java/com/kuit/ourmenu/data/service/DummyService.kt (1)
getDummyData(10-18)
app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/sub/HomeSubRecommendationItem.kt (1)
app/src/main/java/com/kuit/ourmenu/ui/theme/Type.kt (1)
ourMenuTypography(141-141)
app/src/main/java/com/kuit/ourmenu/ui/home/component/dialog/HomeDialog.kt (2)
app/src/main/java/com/kuit/ourmenu/ui/theme/Type.kt (1)
ourMenuTypography(141-141)app/src/main/java/com/kuit/ourmenu/ui/home/component/dialog/HomeDialogTouchBox.kt (1)
HomeDialogTouchBox(21-52)
app/src/main/java/com/kuit/ourmenu/ui/home/screen/HomeScreen.kt (3)
app/src/main/java/com/kuit/ourmenu/ui/home/component/dialog/HomeDialog.kt (1)
HomePopUpDialog(38-128)app/src/main/java/com/kuit/ourmenu/ui/common/topappbar/OurMenuAddButtonTopAppBar.kt (1)
OurMenuAddButtonTopAppBar(19-52)app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/sub/HomeSubRecommendation.kt (1)
HomeSubRecommendation(14-39)
app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/sub/HomeSubRecommendation.kt (2)
app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/sub/HomeSubRecommendationText.kt (1)
HomeSubRecommendationText(8-18)app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/sub/HomeSubRecommendationList.kt (1)
HomeSubRecommendationList(11-32)
🔇 Additional comments (19)
.gitignore (1)
62-62: 좋은 추가네요!Android Studio 설정 파일을 .gitignore에 추가하는 건 좋은 관행입니다. deploymentTargetSelector.xml 파일은 개발자별로 다를 수 있는 설정이라 버전 관리에서 제외하는게 맞습니다.
app/src/main/res/values/strings.xml (1)
133-134: 홈 화면용 문자열 리소스 추가 확인새로 추가된 문자열들이 홈 화면 API 연동에 잘 맞춰져 있네요.
hello와home_recommend문자열이 사용자에게 친근하게 다가갈 것 같습니다.app/src/main/java/com/kuit/ourmenu/ui/home/component/dialog/HomeDialogAssets.kt (3)
4-4: clickable import 추가 확인인터랙티브 기능을 위한 import가 적절하게 추가되었네요.
48-48: 닫기 버튼 클릭 기능 추가아이콘에 클릭 이벤트가 적절하게 연결되었습니다. 사용자 경험이 좋아질 것 같네요.
60-60: 주사위 클릭 기능 구현주사위 이미지에 클릭 이벤트를 연결한 것이 홈 화면의 추천 기능과 잘 맞아떨어지는 것 같습니다. 사용자가 직관적으로 상호작용할 수 있겠네요.
app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/main/HomeMainRecommendationText.kt (1)
5-5: Coil AsyncImage 사용으로 전환로컬 리소스에서 원격 이미지 로딩으로 전환한 것이 API 연동에 적합한 변경입니다.
app/src/main/java/com/kuit/ourmenu/ui/common/topappbar/OurMenuAddButtonTopAppBar.kt (2)
21-24: 콜백 파라미터 추가로 네비게이션 연동
onAddMenuClick콜백을 추가해서 메뉴 추가 네비게이션을 연결할 수 있게 한 것이 좋습니다. 기본값으로 빈 람다를 제공해서 기존 코드의 호환성도 유지했네요.
41-41: TODO 제거하고 실제 기능 구현이전의 TODO를 제거하고 실제로
onAddMenuClick콜백을 연결한 것이 좋습니다. 이제 TopAppBar의 플러스 버튼이 실제로 동작하겠네요.app/src/main/java/com/kuit/ourmenu/ui/navigator/MainNavHost.kt (1)
60-61: 홈 그래프 네비게이션 콜백 연동 LGTMHomeNavGraph에 menuInfo(Long) / addMenu() 콜백을 넘겨주는 배선이 깔끔합니다. HomeNavigation.kt와 HomeScreen.kt의 시그니처 변경과도 정합적이에요.
app/src/main/java/com/kuit/ourmenu/data/di/ServiceModule.kt (1)
52-56: HomeService DI 등록 적절함Retrofit.create(HomeService::class.java)로의 바인딩 문제 없습니다. DI 그래프 상 위치도 MenuFolder, MenuInfo와 나란히 배치되어 알아보기 좋아요.
app/src/main/java/com/kuit/ourmenu/ui/home/navigation/HomeNavigation.kt (1)
17-19: HomeScreen 네비게이션 파이프라인 정합성 OKNavGraphBuilder 확장 함수에 (Long) -> Unit, () -> Unit 콜백 추가 후 HomeScreen으로 그대로 전달하는 흐름이 일관되고 단순해졌습니다. MainNavHost의 호출부 변경과도 정확히 맞물립니다.
Also applies to: 22-25
app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/main/HomeMainRecommendationList.kt (1)
21-23: 타입 전환 및 클릭 콜백 전달 깨끗함
- 데이터 타입을 List로 전환한 부분과
- onItemClick(Long) 콜백을 아이템에 위임하는 패스스루
둘 다 의도가 명확하고 사용성도 좋아졌습니다. 상위(HomeScreen)에서 menuId(Long)를 자연스럽게 받아서 navigate 처리하기에 적절해요.
Also applies to: 47-49
app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/main/HomeMainRecommendationItem.kt (1)
31-37: onItemClick 연결 깔끔합니다데이터 모델 전환과 클릭 전달 구조(Lifted callback) 적용 잘 됐어요.
app/src/main/java/com/kuit/ourmenu/data/service/HomeService.kt (1)
11-14: BaseUrl 정의 위치 및 실제 값 확인 요청현재
BuildConfig.BASE_URL이 어디서 어떤 값으로 설정되는지 자동 검색으로 확인되지 않았습니다. 실제 호출의 중복·누락 여부를 점검하려면 아래 사항을 확인해 주세요:
gradle.properties,local.properties또는 CI/CD 환경변수 등에 설정된BASE_URL값 확인- Android 스튜디오의 Build → Generate Sources and Update Folders For 기능을 통해 생성된
BuildConfig클래스에서BASE_URL상수 확인- 최종 호출 URL(
BaseUrl+@GET상대 경로)에서 접두사(prefix) 중복 혹은 누락 여부 검증확인 후 실제
BASE_URL값을 알려주시면, 중복/누락 문제 여부를 함께 검토하겠습니다.app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/sub/HomeSubRecommendationList.kt (1)
1-32: 코드가 깔끔하게 정리되었네요!
RecommendMenuList모델로 마이그레이션하고onItemClick콜백을 추가한 변경사항이 잘 구현되었습니다. API 연동을 위한 리팩토링이 체계적으로 진행된 것 같아요.app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/main/HomeMainRecommendation.kt (1)
14-18: 잘 구현되었습니다!더미 데이터에서 실제 API 모델로의 전환이 깔끔하게 처리되었고, 클릭 이벤트 처리를 위한
onItemClick콜백도 적절히 추가되었네요.app/src/main/java/com/kuit/ourmenu/ui/home/component/dialog/HomeDialog.kt (1)
39-44: 함수 시그니처가 크게 개선되었네요!데이터 기반 접근 방식으로 변경되어 더 유연하고 재사용 가능한 구조가 되었습니다. ViewModel과의 통합도 깔끔하게 처리되었습니다.
app/src/main/java/com/kuit/ourmenu/ui/home/screen/HomeScreen.kt (1)
27-27: Scaffold 패딩 미사용 경고 억제@SuppressLint 어노테이션을 사용하셨는데, Scaffold의 innerPadding을 사용하지 않고 외부에서 전달받은 padding을 사용하는 설계 선택이군요. 이 경우 lint 경고를 억제하는 것이 적절합니다.
app/src/main/java/com/kuit/ourmenu/ui/home/viewmodel/HomeViewModel.kt (1)
112-128: 에러 처리 로직 잘 구성되었네요OurMenuApiFailureException의 H400 코드를 특별히 처리하여 질문을 다시 가져오는 로직이 적절합니다. 네트워크 오류와 서버 오류를 구분하여 사용자 친화적인 메시지를 제공하는 것도 좋습니다.
| @Serializable | ||
| data class HomeQuestionResponse( | ||
| val question: String, | ||
| val answers: List<Answer> | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
백엔드 필드 네이밍 확인 및 @SerialName 필요 여부 체크
서버가 snake_case를 반환한다면 @SerialName이 필요합니다. 현재 camelCase로 선언되어 있어, Json 설정(namingStrategy) 여부에 따라 디코딩 실패 가능성이 있어요.
아래 스크립트로 Json 설정을 확인해 주세요. namingStrategy나 custom Json 설정이 없으면 @SerialName 추가를 고려하세요.
🏁 Script executed:
#!/bin/bash
# Json 빌더/설정 사용 위치 탐색
rg -n "Json\\s*\\{" -A 5
rg -n "namingStrategy|snake|ignoreUnknownKeys|isLenient"Length of output: 1028
DTO 필드 직렬화 이름 확인 및 @SerialName 검토
NetworkModule의 Json 설정(isLenient, prettyPrint, encodeDefaults, explicitNulls, ignoreUnknownKeys만 사용)에는 snake_case → camelCase 변환 전략이 없어요.
따라서 서버가 snake_case 필드를 반환할 경우 아래 DTO 필드 매핑이 실패할 수 있습니다.
- 파일: app/src/main/java/com/kuit/ourmenu/data/model/home/response/HomeQuestionResponse.kt (5–9행)
- question
- answers
▶ 백엔드 필드명이 snake_case인지 확인 후, snake_case로 전달된다면 각 필드에
@SerialName("snake_case_field") 어노테이션을 추가하거나
커스텀 네이밍 전략 구현을 검토해주세요.
🤖 Prompt for AI Agents
In
app/src/main/java/com/kuit/ourmenu/data/model/home/response/HomeQuestionResponse.kt
around lines 5 to 9, the DTO fields (question, answers) may not match backend
snake_case names because the project Json config does not perform
snake_case→camelCase mapping; if the backend sends snake_case, add @SerialName
annotations to each property with the exact snake_case field names (e.g.,
@SerialName("question_text") or whatever the backend uses) or alternatively
implement/apply a consistent naming strategy in the Json configuration to map
snake_case to camelCase across models.
| suspend fun getHome() = runCatching { | ||
| homeService.getHome().handleBaseResponse().getOrThrow() | ||
| } | ||
|
|
||
| suspend fun postHomeQuestion() = runCatching { | ||
| homeService.postHomeQuestion().handleBaseResponse().getOrThrow() | ||
| } | ||
|
|
||
| suspend fun postHomeAnswer(answer: String) = runCatching { | ||
| homeService.postHomeAnswer(HomeAnswerRequest(answer)) | ||
| .handleBaseResponse() | ||
| .getOrThrow() | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
runCatching이 CancellationException까지 삼킵니다 (코루틴 취소 전파 이슈)
네트워크 호출을 runCatching으로 감싸면 CancellationException까지 Result로 포장되어 취소가 전파되지 않을 수 있어요. 취소는 반드시 재던지거나 runCatching 대체 유틸로 처리하세요.
다음 유틸을 공용 모듈에 추가 후 사용을 권장합니다:
// 예: core/common/ResultExt.kt
suspend inline fun <T> cancellableRunCatching(crossinline block: suspend () -> T): Result<T> {
return try {
Result.success(block())
} catch (e: kotlinx.coroutines.CancellationException) {
throw e
} catch (t: Throwable) {
Result.failure(t)
}
}Repository에서는 아래처럼 교체:
- suspend fun getHome() = runCatching {
+ suspend fun getHome() = cancellableRunCatching {
homeService.getHome().handleBaseResponse().getOrThrow()
}
- suspend fun postHomeQuestion() = runCatching {
+ suspend fun postHomeQuestion() = cancellableRunCatching {
homeService.postHomeQuestion().handleBaseResponse().getOrThrow()
}
- suspend fun postHomeAnswer(answer: String) = runCatching {
+ suspend fun postHomeAnswer(answer: String) = cancellableRunCatching {
homeService.postHomeAnswer(HomeAnswerRequest(answer))
.handleBaseResponse()
.getOrThrow()
}🤖 Prompt for AI Agents
In app/src/main/java/com/kuit/ourmenu/data/repository/HomeRepository.kt around
lines 13 to 25, runCatching is currently wrapping suspend network calls and will
catch CancellationException which prevents coroutine cancellation from
propagating; replace runCatching with a cancellableRunCatching utility (add it
to a common module) or explicitly rethrow CancellationException in the catch
path so cancellations are not swallowed, then update each method (getHome,
postHomeQuestion, postHomeAnswer) to call the cancellableRunCatching helper so
Result only captures non-cancellation failures.
| @POST("/api/home/questions") | ||
| suspend fun postHomeQuestion(): BaseResponse<HomeQuestionResponse> | ||
|
|
||
| @POST("/api/home/questions/answers") | ||
| suspend fun postHomeAnswer( | ||
| @Body answerRequest: HomeAnswerRequest | ||
| ): BaseResponse<Unit> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Retrofit 경로 표기 혼용(선행 슬래시) — BaseUrl path 무시 위험
@post에 선행 슬래시가 있어 baseUrl의 path 세그먼트를 무시할 수 있습니다. 상대 경로로 통일하는 것을 권장합니다.
- @POST("/api/home/questions")
+ @POST("api/home/questions")
suspend fun postHomeQuestion(): BaseResponse<HomeQuestionResponse>
- @POST("/api/home/questions/answers")
+ @POST("api/home/questions/answers")
suspend fun postHomeAnswer(
@Body answerRequest: HomeAnswerRequest
): BaseResponse<Unit>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| @POST("/api/home/questions") | |
| suspend fun postHomeQuestion(): BaseResponse<HomeQuestionResponse> | |
| @POST("/api/home/questions/answers") | |
| suspend fun postHomeAnswer( | |
| @Body answerRequest: HomeAnswerRequest | |
| ): BaseResponse<Unit> | |
| @POST("api/home/questions") | |
| suspend fun postHomeQuestion(): BaseResponse<HomeQuestionResponse> | |
| @POST("api/home/questions/answers") | |
| suspend fun postHomeAnswer( | |
| @Body answerRequest: HomeAnswerRequest | |
| ): BaseResponse<Unit> |
🤖 Prompt for AI Agents
In app/src/main/java/com/kuit/ourmenu/data/service/HomeService.kt around lines
15 to 21, the @POST annotations use leading slashes which can cause Retrofit to
ignore baseUrl path segments; change the paths to relative by removing the
leading '/' for both "/api/home/questions" and "/api/home/questions/answers" so
they become "api/home/questions" and "api/home/questions/answers" respectively
to preserve the baseUrl path.
| fun OurMenuAddButtonTopAppBar( | ||
| modifier: Modifier = Modifier, | ||
| onAddMenuClick: () -> Unit = {} | ||
| ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
기존 사용처에서 업데이트 필요 확인
관련 파일들에서 OurMenuAddButtonTopAppBar() 호출부들이 새 파라미터 없이 사용되고 있는데, 기본값이 있어서 컴파일은 되겠지만 실제 기능을 원한다면 콜백을 전달해야 할 것 같습니다.
다음 스크립트로 다른 사용처들이 업데이트가 필요한지 확인해보세요:
Also applies to: 41-41
🏁 Script executed:
#!/bin/bash
# OurMenuAddButtonTopAppBar 사용처들을 찾아서 콜백 전달 여부 확인
rg -A 3 "OurMenuAddButtonTopAppBar\(" --type kotlinLength of output: 2037
기능 동작용 콜백 전달 필수 – 호출부 수정 필요
SearchMenuScreen.kt와 MenuInfoMapScreen.kt의 OurMenuAddButtonTopAppBar() 호출부가 기본 빈 람다만 받도록 남아있습니다. 실제 추가 메뉴로 이동하거나 원하는 액션을 수행하려면 onAddMenuClick 파라미터에 적절한 콜백을 전달해주세요.
- app/src/main/java/com/kuit/ourmenu/ui/searchmenu/screen/SearchMenuScreen.kt
- topBar = { OurMenuAddButtonTopAppBar() } + topBar = { OurMenuAddButtonTopAppBar(onAddMenuClick = onNavigateToAddMenu) }
- app/src/main/java/com/kuit/ourmenu/ui/menuinfo/screen/MenuInfoMapScreen.kt
- topBar = { OurMenuAddButtonTopAppBar() } + topBar = { + OurMenuAddButtonTopAppBar( + onAddMenuClick = { /* TODO: 추가 메뉴 화면으로 네비게이션 */ } + ) + }
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| fun OurMenuAddButtonTopAppBar( | |
| modifier: Modifier = Modifier, | |
| onAddMenuClick: () -> Unit = {} | |
| ) { | |
| // File: app/src/main/java/com/kuit/ourmenu/ui/searchmenu/screen/SearchMenuScreen.kt | |
| @@ | |
| - topBar = { OurMenuAddButtonTopAppBar() } | |
| + topBar = { OurMenuAddButtonTopAppBar(onAddMenuClick = onNavigateToAddMenu) } | |
| // File: app/src/main/java/com/kuit/ourmenu/ui/menuinfo/screen/MenuInfoMapScreen.kt | |
| @@ | |
| - topBar = { OurMenuAddButtonTopAppBar() } | |
| + topBar = { | |
| + OurMenuAddButtonTopAppBar( | |
| + onAddMenuClick = { /* TODO: 추가 메뉴 화면으로 네비게이션 */ } | |
| + ) | |
| + } |
| imgUrl: String = "", | ||
| ) { | ||
| Row( | ||
| AsyncImage( | ||
| modifier = modifier, | ||
| verticalAlignment = Alignment.CenterVertically | ||
| ) { | ||
| // TODO : Async Image Loading | ||
| Icon( | ||
| painter = painterResource(icon), | ||
| modifier = Modifier | ||
| .size(32.dp) | ||
| .padding(end = 4.dp), | ||
| contentDescription = "Home Sub Recommendation 1", | ||
| tint = Color.Unspecified | ||
| ) | ||
| Text( | ||
| text = text, | ||
| style = ourMenuTypography().pretendard_700_24.copy( | ||
| color = Neutral900 | ||
| ) | ||
| ) | ||
| } | ||
| model = imgUrl, | ||
| contentDescription = "Home Sub Recommendation 1", | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
빈 URL 처리와 이미지 로딩 옵션(placeholder/crossfade) 보강
imgUrl 기본값이 빈 문자열이면 불필요한 요청/로그가 발생할 수 있어요. 빈 값은 early-return하거나 placeholder를 보여주고, crossfade로 UX를 개선하는 게 좋아요.
아래처럼 수정 제안드립니다:
-fun HomeSubRecommendationText(
- modifier: Modifier = Modifier,
- imgUrl: String = "",
-) {
- AsyncImage(
- modifier = modifier,
- model = imgUrl,
- contentDescription = "Home Sub Recommendation 1",
- )
-}
+fun HomeSubRecommendationText(
+ modifier: Modifier = Modifier,
+ imgUrl: String?,
+ contentDescription: String? = null,
+) {
+ if (imgUrl.isNullOrBlank()) return
+ AsyncImage(
+ modifier = modifier,
+ model = coil3.request.ImageRequest.Builder(
+ androidx.compose.ui.platform.LocalContext.current
+ )
+ .data(imgUrl)
+ .crossfade(true)
+ .build(),
+ contentDescription = contentDescription,
+ contentScale = androidx.compose.ui.layout.ContentScale.Crop,
+ )
+}파일 상단에 필요한 import도 추가해주세요:
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import coil3.request.ImageRequest🤖 Prompt for AI Agents
In
app/src/main/java/com/kuit/ourmenu/ui/home/component/recommendation/sub/HomeSubRecommendationText.kt
around lines 11 to 17, handle empty imgUrl by early-returning or showing a
placeholder to avoid unnecessary network requests/logs, and enhance AsyncImage
with an ImageRequest using LocalContext that enables crossfade, a placeholder,
and proper contentScale; also add the imports
androidx.compose.ui.layout.ContentScale,
androidx.compose.ui.platform.LocalContext, and coil3.request.ImageRequest at the
top of the file.
| viewModelScope.launch { | ||
| _isLoading.value = true | ||
| _error.value = null | ||
|
|
||
| homeRepository.postHomeAnswer(answer) | ||
| .fold( | ||
| onSuccess = { | ||
| getHome() | ||
| }, | ||
| onFailure = { throwable -> | ||
| _error.value = throwable.message ?: "답변 제출 중 오류가 발생했습니다." | ||
| onDialogDismiss() | ||
| _isLoading.value = false | ||
| } | ||
| ) | ||
|
|
||
| _isLoading.value = false | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
로딩 상태 관리 중복 코드
59번 줄의 _isLoading.value = false는 실행되지 않을 수 있습니다. fold 블록 내부에서 이미 로딩 상태를 처리하고 있는데, onSuccess에서도 false로 설정하는 게 더 명확할 것 같네요.
fun selectAnswer(answer: String) {
viewModelScope.launch {
_isLoading.value = true
_error.value = null
homeRepository.postHomeAnswer(answer)
.fold(
onSuccess = {
getHome()
},
onFailure = { throwable ->
_error.value = throwable.message ?: "답변 제출 중 오류가 발생했습니다."
onDialogDismiss()
_isLoading.value = false
}
)
-
- _isLoading.value = false
}
}Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In app/src/main/java/com/kuit/ourmenu/ui/home/viewmodel/HomeViewModel.kt around
lines 43-61, _isLoading.value is set to false after the fold call but that line
may not execute reliably because the fold handlers manage completion
differently; move the loading-state reset into both fold branches (set
_isLoading.value = false in onSuccess after getHome() completes and in onFailure
where it already exists) or wrap the repository call in a try/finally so
_isLoading.value = false is always executed, and remove the redundant trailing
_isLoading.value = false.
| private fun fetchQuestion() { | ||
| viewModelScope.launch { | ||
| _isLoading.value = true | ||
| _error.value = null | ||
|
|
||
| homeRepository.postHomeQuestion() | ||
| .fold( | ||
| onSuccess = { response -> | ||
| _questionState.value = response | ||
| if (response == null) { | ||
| onDialogDismiss() | ||
| getHome() | ||
| } else { | ||
| _isLoading.value = false | ||
| } | ||
| }, | ||
| onFailure = { throwable -> | ||
| handleFailure(throwable) | ||
| _isLoading.value = false | ||
| } | ||
| ) | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
fetchQuestion 로직 개선 필요
76-81 라인에서 response가 null일 때와 아닐 때의 로딩 상태 처리가 일관성이 없습니다. null이 아닐 때만 로딩을 false로 설정하는데, null일 때는 getHome()이 자체적으로 로딩을 관리하는 구조네요.
private fun fetchQuestion() {
viewModelScope.launch {
_isLoading.value = true
_error.value = null
homeRepository.postHomeQuestion()
.fold(
onSuccess = { response ->
_questionState.value = response
if (response == null) {
onDialogDismiss()
getHome()
} else {
- _isLoading.value = false
+ _showDialog.value = true
}
+ _isLoading.value = false
},
onFailure = { throwable ->
handleFailure(throwable)
_isLoading.value = false
}
)
}
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| private fun fetchQuestion() { | |
| viewModelScope.launch { | |
| _isLoading.value = true | |
| _error.value = null | |
| homeRepository.postHomeQuestion() | |
| .fold( | |
| onSuccess = { response -> | |
| _questionState.value = response | |
| if (response == null) { | |
| onDialogDismiss() | |
| getHome() | |
| } else { | |
| _isLoading.value = false | |
| } | |
| }, | |
| onFailure = { throwable -> | |
| handleFailure(throwable) | |
| _isLoading.value = false | |
| } | |
| ) | |
| } | |
| } | |
| private fun fetchQuestion() { | |
| viewModelScope.launch { | |
| _isLoading.value = true | |
| _error.value = null | |
| homeRepository.postHomeQuestion() | |
| .fold( | |
| onSuccess = { response -> | |
| _questionState.value = response | |
| if (response == null) { | |
| onDialogDismiss() | |
| getHome() | |
| } else { | |
| _showDialog.value = true | |
| } | |
| _isLoading.value = false | |
| }, | |
| onFailure = { throwable -> | |
| handleFailure(throwable) | |
| _isLoading.value = false | |
| } | |
| ) | |
| } | |
| } |
🤖 Prompt for AI Agents
In app/src/main/java/com/kuit/ourmenu/ui/home/viewmodel/HomeViewModel.kt around
lines 67 to 89, the _isLoading flag is only set to false when response != null,
causing inconsistent loading state when response == null; change the flow so
_isLoading is set to false in all completion paths — either set _isLoading.value
= false once after the fold completes (outside the conditional) or explicitly
set it before calling onDialogDismiss()/getHome() for the null branch, ensuring
getHome() does not rely on this method to manage the loading flag to avoid
leaving the UI stuck loading.
🚀 이슈번호
✏️ 변경사항
📷 스크린샷
2025-08-13.4.01.03.online-video-cutter.com.mp4
✍️ 사용법
🎸 기타
Summary by CodeRabbit