Skip to content

Conversation

@Nico1eKim
Copy link
Member

@Nico1eKim Nico1eKim commented Aug 13, 2025

🚀 이슈번호

✏️ 변경사항

  • 홈화면 api 연결했습니다
  • 홈 모달 api 연결했습니다
  • 홈화면 navigation 이동 구현했습니다

📷 스크린샷

2025-08-13.4.01.03.online-video-cutter.com.mp4

✍️ 사용법

🎸 기타

  • 좀 느려보이는건 .. 제 에뮬이 느려서 그렇고 평소에는 잘 받아와집니다!
  • 홈에 데이터 없을 때 화면 추가되면 수정해야합니당

Summary by CodeRabbit

  • New Features
    • 홈 화면에 서버 연동 추천 영역 추가(메인/서브 배너 이미지, 메뉴 리스트, 원격 이미지 로딩)
    • 질문/답변 팝업 대화상자 도입 및 답변 선택 인터랙션
    • 메뉴 상세 및 메뉴 추가로 이동 가능한 내비게이션 훅 추가
  • Refactor
    • 더미 데이터를 실제 모델로 교체하고 주요 컴포저블 API(파라미터/콜백) 정비
    • HomeScreen을 MVVM 구조로 전환하고 상태 기반 UI로 개선
    • 불필요 컴포넌트 삭제 및 클릭 동작 일관화
  • Chores
    • IDE 파일 무시 규칙(.gitignore) 업데이트
    • 문자열 리소스(인사말/가이드) 추가

Nico1eKim added 30 commits May 23, 2025 15:48
… into api/home

# Conflicts:
#	app/src/main/java/com/kuit/ourmenu/data/di/ServiceModule.kt
… into api/home

# Conflicts:
#	.idea/deploymentTargetSelector.xml
@coderabbitai
Copy link

coderabbitai bot commented Aug 13, 2025

Walkthrough

홈 화면 API 연동을 위해 네트워킹 계층(HomeService, 모델, Repository)과 DI를 추가하고, HomeViewModel을 도입해 UI(HomeScreen, 추천 컴포넌트, 다이얼로그)를 데이터 기반으로 개편했습니다. 내비게이션 콜백을 확장하고, 더미 데이터/공용 버튼 컴포저블을 제거했으며 문자열 리소스를 추가했습니다.

Changes

Cohort / File(s) Summary
Tooling
/.gitignore
IntelliJ/Android Studio 설정 파일(deploymentTargetSelector.xml) 무시 항목 추가
Networking & DI
app/.../data/service/HomeService.kt, app/.../data/di/ServiceModule.kt, app/.../data/repository/HomeRepository.kt, app/.../data/model/home/request/HomeAnswerRequest.kt, app/.../data/model/home/response/*
Home API 인터페이스 3종(GET/POST) 추가, 요청/응답 모델 추가, Repository 추가, DI 바인딩 추가
ViewModel
app/.../ui/home/viewmodel/HomeViewModel.kt
홈 상태(StateFlow) 관리, 질문/답변/홈 데이터 로딩 및 에러 처리 로직 추가
Home UI - Screen & Navigation
app/.../ui/home/screen/HomeScreen.kt, app/.../ui/home/navigation/HomeNavigation.kt, app/.../ui/navigator/MainNavHost.kt, app/.../ui/common/topappbar/OurMenuAddButtonTopAppBar.kt
HomeScreen을 MVVM 연동 및 내비게이션 콜백(onNavigateToMenuInfo, onNavigateToAddMenu) 연결로 개편, TopAppBar에 클릭 콜백 추가
Home UI - Dialog
app/.../ui/home/component/dialog/HomeDialog.kt, app/.../ui/home/component/dialog/HomeDialogAssets.kt
질문 데이터 기반 다이얼로그로 변경, 닫기/주사위 클릭 처리 및 답변 선택 콜백 추가
Home UI - Recommendation(Main/Sub)
app/.../ui/home/component/recommendation/main/*, app/.../ui/home/component/recommendation/sub/*
더미 타입 제거→RecommendMenuList 사용, 이미지 URL(AsyncImage) 로딩, 아이템 클릭 콜백 추가 및 시그니처 변경
Cleanup
app/.../ui/common/dialog/DialogBigButton.kt (삭제), app/.../ui/home/dummy/HomeDummyData.kt (삭제)
공용 큰 버튼 컴포저블과 홈 더미 데이터 제거
Resources
app/src/main/res/values/strings.xml
홈 인사/설명 문자열 2종 추가

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: 추천 영역 갱신, 다이얼로그 닫기
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Assessment against linked issues

Objective Addressed Explanation
홈 화면 API 연동: 네트워크 계층(HomeService/모델/Repository) 구현 (#64)
홈 화면 UI가 실제 API 데이터로 렌더링되도록 ViewModel 연동 (#64)
질문/답변 플로우(질문 요청, 답변 전송, 홈 데이터 갱신) 연결 (#64)

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
공용 컴포저블 삭제 DialogBigButton (app/src/main/java/com/kuit/ourmenu/ui/common/dialog/DialogBigButton.kt, entire file) 홈 화면 API 연동과 직접적 기능 연계가 불분명합니다. 공용 UI 컴포넌트 제거는 범위를 벗어날 수 있습니다.
TopAppBar에 onAddMenuClick 추가 (app/.../ui/common/topappbar/OurMenuAddButtonTopAppBar.kt, lines: function signature) 홈 API 연동 요구사항에 포함되지 않은 내비게이션 확장입니다.
.gitignore에 IDE 항목 추가 (/.gitignore, specific line add) 기능 요구와 무관한 툴링 변경입니다.

Possibly related PRs

Suggested reviewers

  • ikseong00
  • casper-jr

Poem

새 배너 휙, 답변은 탭!
서버에 물어, 추천은 꽉 찹.
더미는 안녕, URL은 반짝✨
클릭하면 쓱— 메뉴 정보로 착.
홈의 심장, 이제 API로 박동한다!

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a 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.CircularProgressIndicator
app/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

📥 Commits

Reviewing files that changed from the base of the PR and between 6c48157 and 6710078.

📒 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 연동에 잘 맞춰져 있네요. hellohome_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: 홈 그래프 네비게이션 콜백 연동 LGTM

HomeNavGraph에 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 네비게이션 파이프라인 정합성 OK

NavGraphBuilder 확장 함수에 (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 코드를 특별히 처리하여 질문을 다시 가져오는 로직이 적절합니다. 네트워크 오류와 서버 오류를 구분하여 사용자 친화적인 메시지를 제공하는 것도 좋습니다.

Comment on lines +5 to +9
@Serializable
data class HomeQuestionResponse(
val question: String,
val answers: List<Answer>
)
Copy link

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.

Comment on lines +13 to +25
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()
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

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.

Comment on lines +15 to +21
@POST("/api/home/questions")
suspend fun postHomeQuestion(): BaseResponse<HomeQuestionResponse>

@POST("/api/home/questions/answers")
suspend fun postHomeAnswer(
@Body answerRequest: HomeAnswerRequest
): BaseResponse<Unit>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

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.

Suggested change
@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.

Comment on lines +21 to +24
fun OurMenuAddButtonTopAppBar(
modifier: Modifier = Modifier,
onAddMenuClick: () -> Unit = {}
) {
Copy link

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 kotlin

Length 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.

Suggested change
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: 추가 메뉴 화면으로 네비게이션 */ }
+ )
+ }

Comment on lines +11 to +17
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",
)
Copy link

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.

Comment on lines +43 to +61
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
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

로딩 상태 관리 중복 코드

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.

Comment on lines +67 to +89
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
}
)
}
}
Copy link

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.

Suggested change
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.

@casper-jr casper-jr merged commit 517219b into OurMenu:develop Aug 29, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] home화면 api 연결

3 participants