Skip to content

Conversation

@kimjeakwan
Copy link
Collaborator

@kimjeakwan kimjeakwan commented Feb 18, 2025

💡 개요

MainScreen 에 통신한 것을 적용위한 리펙토링을 했습니다.

📃 작업내용

MainScreen 에 통신한 것을 적용위한 리펙토링을 했습니다.

🔀 변경사항

RankingComponet
MyRankingComponet
MainNavigation
MainScreen

🙋‍♂️ 질문사항

  • 개선할 점, 오타, 코드에 이산한 부분이 있다면 Comment 달아주세요.

🍴 사용방법

🎸 기타

Summary by CodeRabbit

  • New Features

    • 메인 스크린에 내비게이션 기능과 상태 기반 UI 전환을 위한 새로운 컴포저블이 추가되었습니다.
    • 랭킹 정보를 효율적으로 표시할 수 있는 새로운 목록 및 항목 UI 요소가 도입되었습니다.
  • Refactor

    • UI 구성요소들의 파라미터와 상태 관리 로직이 업데이트되어 더욱 직관적인 사용자 경험을 제공합니다.
    • 에러 처리 방식이 개선되어 실패 시 보다 상세한 정보를 전달합니다.
  • Chores

    • 새로운 에러 메시지 리소스가 추가되었습니다.

@kimjeakwan kimjeakwan added the 1️⃣ Priority: High 우선순위 - 상 label Feb 18, 2025
@kimjeakwan kimjeakwan requested a review from xx-lvr February 18, 2025 03:16
@kimjeakwan kimjeakwan self-assigned this Feb 18, 2025
@coderabbitai
Copy link

coderabbitai bot commented Feb 18, 2025

Walkthrough

이 PR은 Jetpack Compose 기반 주요 화면과 관련 컴포저블 함수들의 기능을 개선하고, UI 상태 관리 및 네비게이션, 오류 처리 로직을 업데이트합니다. 주요 변경 사항으로는 MainScreen.kt에서 상태 전달 방식과 콜백 호출 추가, 새로운 MainRoute 컴포저블 도입, MyRanking 및 RankingList 함수의 추가, 그리고 뷰모델과 상태 클래스(Fail 상태)의 예외 정보 포함 등이 있습니다. 또한, 네비게이션 관련 MainNavigation.kt와 문자열 리소스(string.xml)에도 변경이 이루어졌습니다.

Changes

파일 변경 사항
presentation/.../Screen/MainScreen.kt
presentation/.../navigation/MainNavigation.kt
MainScreen에서 상태 전달 및 네비게이션 관련 파라미터 추가, 새로운 MainRoute, RankingList, MyRanking 컴포저블 도입, LaunchedEffect로 콜백 실행 및 네비게이션 경로 상수 및 함수 추가.
presentation/.../component/MyRankingComponent.kt
presentation/.../component/Rankingcomponent.kt
MyRanking 컴포저블 추가, 기존 MyRankingComponent 인자 (int → MyRankResponseModel) 변경, RankingListRankingListItem 도입, UI 상태에 따른 처리 및 텍스트 포맷 업데이트.
presentation/.../viewModel/homes/HomesViewmodel.kt
presentation/.../viewModel/homes/uistate/(HomesMyRankUiState.kt, HomesUiState.kt)
getRankgetMyRank 함수에서 실패 상태에 예외 정보를 포함하도록 수정, HomesMyRankUiState와 HomesUiState의 Fail 상태를 데이터 클래스로 변경하여 예외 및 메시지 정보 전달.
presentation/.../res/values/string.xml 새로운 오류 메시지 문자열 리소스 <string name="error">사용자 정보를 찾을수 없습니다</string> 추가.

Sequence Diagram(s)

sequenceDiagram
    participant Nav as NavController
    participant Main as MainScreen/MainRoute
    participant VM as HomesViewModel
    participant UI as UI Components

    Nav->>Main: navigationToMain() 호출
    Main->>VM: collectAsStateWithLifecycle로 UI 상태 수집
    VM-->>Main: 상태 전송 (Loading/Success/Fail)
    Main->>UI: MyRanking, RankingList 등 컴포저블 실행
    UI->>Main: 오류 발생 시 onErrorToast 콜백 호출
Loading

Possibly related PRs

Suggested reviewers

  • xx-lvr

Poem

나는 작은 토끼, 코드를 뛰노네,
변화하는 UI 숲 속을 달리며,
기능 하나하나 반짝이는 별처럼,
오류는 발자국에 남지 않게,
새로운 길을 열어주는 코드,
🐰 함께 춤추며 전진하세!


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 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.
    • Generate unit testing code for this file.
    • 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. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • 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 src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

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

Documentation and Community

  • 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: 2

🧹 Nitpick comments (5)
presentation/src/main/res/values/string.xml (1)

7-8: 신규 오류 문자열 리소스 추가됨
새로운 문자열 리소스 <string name="error">사용자 정보를 찾을수 없습니다</string>가 추가되었습니다. 해당 문자열은 MainScreen에서 오류 처리시 사용자에게 전달될 메시지로 적절해 보입니다.
추가로 "찾을수" 보다 "찾을 수"와 같이 띄어쓰기를 적용하면 가독성이 더 좋아질 수 있으므로 검토해 보시길 권장합니다.

presentation/src/main/java/viewModel/homes/HomesViewmodel.kt (2)

39-40: 불필요한 빈 줄을 제거해주세요.

코드의 가독성을 위해 40번 줄의 불필요한 빈 줄을 제거하는 것이 좋겠습니다.


61-61: 오류 메시지 처리 방식을 개선해주세요.

HomesMyRankUiState.Fail의 message 매개변수에 null을 하드코딩하는 대신, 의미 있는 기본 오류 메시지를 제공하는 것이 좋겠습니다.

예시:

-    _homesMyRankUiState.value = HomesMyRankUiState.Fail(result.exception,null)
+    _homesMyRankUiState.value = HomesMyRankUiState.Fail(
+        throwable = result.exception,
+        message = R.string.error_failed_to_load_rank
+    )
presentation/src/main/java/view/main/component/Rankingcomponent.kt (2)

35-63: UI 상태 처리 개선이 필요합니다.

다음 사항들을 개선하면 좋을 것 같습니다:

  1. Empty 상태에 대한 처리가 누락되어 있습니다.
  2. Loading 상태가 단순 텍스트로만 표시되고 있습니다.

다음과 같이 개선하는 것을 제안드립니다:

 HomesUiState.Loading -> {
-    Text(text = "로딩중")
+    CircularProgressIndicator(
+        modifier = Modifier.align(Alignment.CenterHorizontally)
+    )
 }

 is HomesUiState.Empty -> {
+    Text(
+        text = stringResource(R.string.no_ranking_data),
+        modifier = Modifier.align(Alignment.CenterHorizontally),
+        style = MaterialTheme.typography.bodyLarge
+    )
 }

90-90: 문자열 리소스 사용을 권장드립니다.

순위와 점수 표시에 사용되는 접미사("위", "점")를 strings.xml 리소스로 분리하면 좋을 것 같습니다.

다음과 같이 수정하는 것을 제안드립니다:

-text = "${data.rank}위"
+text = stringResource(R.string.rank_format, data.rank)

-text = "${data.penaltyPoint}점"
+text = stringResource(R.string.points_format, data.penaltyPoint)

strings.xml에 다음 내용 추가:

<string name="rank_format">%d위</string>
<string name="points_format">%d점</string>

Also applies to: 108-108

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 531a710 and d240865.

📒 Files selected for processing (8)
  • presentation/src/main/java/view/main/Screen/MainScreen.kt (5 hunks)
  • presentation/src/main/java/view/main/component/MyRankingComponent.kt (2 hunks)
  • presentation/src/main/java/view/main/component/Rankingcomponent.kt (5 hunks)
  • presentation/src/main/java/view/main/navigation/MainNavigation.kt (1 hunks)
  • presentation/src/main/java/viewModel/homes/HomesViewmodel.kt (2 hunks)
  • presentation/src/main/java/viewModel/homes/uistate/HomesMyRankUiState.kt (1 hunks)
  • presentation/src/main/java/viewModel/homes/uistate/HomesUiState.kt (1 hunks)
  • presentation/src/main/res/values/string.xml (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build
🔇 Additional comments (14)
presentation/src/main/java/viewModel/homes/uistate/HomesUiState.kt (1)

9-9: 예외 처리 개선을 위한 Fail 상태 리팩토링이 잘 되었습니다.

예외 정보를 포함하도록 Fail 상태를 개선한 것이 좋습니다. 이를 통해 사용자에게 더 자세한 오류 정보를 제공할 수 있게 되었습니다.

presentation/src/main/java/viewModel/homes/uistate/HomesMyRankUiState.kt (1)

9-9: Fail 상태의 매개변수에 대한 검토가 필요합니다.

Fail 상태에 nullable 매개변수들을 사용하고 있습니다:

  1. throwable이 null일 때의 처리 방식을 명확히 해야 합니다
  2. message의 용도와 null일 때의 기본값을 문서화하면 좋겠습니다

다음과 같이 개선하는 것을 고려해보세요:

-    data class Fail(val throwable: Throwable?, val message: Int?) : HomesMyRankUiState
+    data class Fail(
+        val throwable: Throwable? = null,
+        @StringRes val message: Int? = null
+    ) : HomesMyRankUiState
presentation/src/main/java/view/main/Screen/MainScreen.kt (6)

3-3: 모듈화된 임포트 구성이 잘 이루어졌습니다.
별다른 문제 없이 필요한 라이브러리를 적절히 불러오고 있습니다.

Also applies to: 17-18, 22-22, 28-29, 31-32, 34-36


38-58: MainRoute 함수 설계가 적절합니다.
MainScreen 호출 전에 ViewModel 상태를 수집하고 주입하여, UI와 로직 사이의 분리가 명료해졌습니다.


63-68: MainScreen 파라미터 확장
homesUiState, homesMyRankUiState 등 상태를 직접 주입받아 관리하는 방식으로, UI 상태 예외 처리가 용이해졌습니다.


104-107: MyRanking 컴포저블 사용
homesMyRankUiState를 직접 전달하며, 에러 콜백도 연결되어 있어 UI 상태 관리가 간결해졌습니다.


172-175: RankingList 컴포저블 사용
homesUiState를 받아 내부에서 다양한 상태 처리를 수행하도록 위임한 구조가 명확합니다.


186-192: 프리뷰 함수 파라미터 예시가 적절합니다.
프리뷰에서 Loading 상태를 시뮬레이션하여 UI 확인이 깔끔해졌습니다.

presentation/src/main/java/view/main/navigation/MainNavigation.kt (1)

1-25: 신규 네비게이션 구성 코드가 명확합니다.

  • navigationToMain() 확장 함수로 단순화된 라우팅이 가능합니다.
  • mainScreen에서 composable 누적 및 MainRoute 호출 흐름이 자연스럽습니다.
presentation/src/main/java/view/main/component/MyRankingComponent.kt (4)

23-23: 임포트 추가
MyRankResponseModelHomesMyRankUiState 불러오는 부분에 문제 없습니다.

Also applies to: 25-25


27-54: 새로 추가된 MyRanking 함수
when 블록을 통해 로딩, 성공, 실패, 빈 상태를 구분하여 적절히 처리하고 있습니다. 구조가 간결하고 가독성이 높습니다.


62-62: MyRankingComponent 파라미터 변경
기존 정수 rank 대신 모델(MyRankResponseModel)을 넘겨받아 확장성 있는 코드 구조가 되었습니다.


91-91: data.rank 사용
랭킹 값을 data 객체에서 바로 꺼내 사용하는 방식이 읽기 좋아졌습니다.

presentation/src/main/java/view/main/component/Rankingcomponent.kt (1)

12-16: 필요한 import 문이 잘 추가되었습니다!

LazyColumn과 PersistentList 관련 import가 적절하게 추가되었습니다.

Also applies to: 27-32

Comment on lines 71 to 74
LaunchedEffect(Unit) {
myRankCallBack
rankListCallBack
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

함수 호출 누락으로 인한 로직 오작동 가능성
현재 콜백 함수를 참조만 하고 실제로 호출하지 않아, 예상한 동작(데이터 로딩)이 수행되지 않을 수 있습니다.

아래 diff를 적용하여 콜백을 실제 호출하는 것이 좋습니다:

-LaunchedEffect(Unit) {
-    myRankCallBack
-    rankListCallBack
-}
+LaunchedEffect(Unit) {
+    myRankCallBack()
+    rankListCallBack()
+}
📝 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
LaunchedEffect(Unit) {
myRankCallBack
rankListCallBack
}
LaunchedEffect(Unit) {
myRankCallBack()
rankListCallBack()
}

Comment on lines +119 to +146
@Composable
internal fun RankingListItem(
modifier: Modifier = Modifier,
list: PersistentList<RankResponseModel>,

) {
Column(modifier = modifier.fillMaxWidth()) {
LazyColumn(
modifier = Modifier
.fillMaxWidth()
.heightIn(max = 10_000.dp)
) {
items(
items = list,
key = { data ->
data.userId
}
) { data ->
RankingComponent(
modifier = Modifier.fillMaxWidth(),
data = data
)
}

}

}
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

LazyColumn의 높이 제한을 재검토해주세요.

현재 설정된 heightIn(max = 10_000.dp)는 다음과 같은 문제가 있을 수 있습니다:

  1. 불필요하게 큰 값으로 설정되어 있습니다
  2. 메모리 사용량에 영향을 줄 수 있습니다

다음과 같이 수정하는 것을 제안드립니다:

 LazyColumn(
     modifier = Modifier
-        .fillMaxWidth()
-        .heightIn(max = 10_000.dp)
+        .fillMaxWidth()
+        .heightIn(max = 300.dp)
 ) {

또는 스크롤이 필요한 경우라면:

 LazyColumn(
     modifier = Modifier
-        .fillMaxWidth()
-        .heightIn(max = 10_000.dp)
+        .fillMaxWidth()
+        .weight(1f)
 ) {
📝 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
@Composable
internal fun RankingListItem(
modifier: Modifier = Modifier,
list: PersistentList<RankResponseModel>,
) {
Column(modifier = modifier.fillMaxWidth()) {
LazyColumn(
modifier = Modifier
.fillMaxWidth()
.heightIn(max = 10_000.dp)
) {
items(
items = list,
key = { data ->
data.userId
}
) { data ->
RankingComponent(
modifier = Modifier.fillMaxWidth(),
data = data
)
}
}
}
}
@Composable
internal fun RankingListItem(
modifier: Modifier = Modifier,
list: PersistentList<RankResponseModel>,
) {
Column(modifier = modifier.fillMaxWidth()) {
LazyColumn(
modifier = Modifier
.fillMaxWidth()
.heightIn(max = 300.dp)
) {
items(
items = list,
key = { data ->
data.userId
}
) { data ->
RankingComponent(
modifier = Modifier.fillMaxWidth(),
data = data
)
}
}
}
}
Suggested change
@Composable
internal fun RankingListItem(
modifier: Modifier = Modifier,
list: PersistentList<RankResponseModel>,
) {
Column(modifier = modifier.fillMaxWidth()) {
LazyColumn(
modifier = Modifier
.fillMaxWidth()
.heightIn(max = 10_000.dp)
) {
items(
items = list,
key = { data ->
data.userId
}
) { data ->
RankingComponent(
modifier = Modifier.fillMaxWidth(),
data = data
)
}
}
}
}
@Composable
internal fun RankingListItem(
modifier: Modifier = Modifier,
list: PersistentList<RankResponseModel>,
) {
Column(modifier = modifier.fillMaxWidth()) {
LazyColumn(
modifier = Modifier
.fillMaxWidth()
.weight(1f)
) {
items(
items = list,
key = { data ->
data.userId
}
) { data ->
RankingComponent(
modifier = Modifier.fillMaxWidth(),
data = data
)
}
}
}
}

Copy link
Collaborator

@xx-lvr xx-lvr left a comment

Choose a reason for hiding this comment

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

수고하셨습니다

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: 0

🧹 Nitpick comments (2)
presentation/src/main/java/view/main/Screen/MainScreen.kt (2)

77-178: UI 컴포넌트 구조 개선 제안

현재 중첩된 레이아웃 구조가 복잡하여 유지보수가 어려울 수 있습니다. 다음과 같은 개선을 제안합니다:

  1. 각 섹션을 별도의 컴포저블 함수로 분리
  2. 공통 스타일을 테마로 추출
  3. 하드코딩된 색상값을 Color 클래스로 분리

예시:

@Composable
private fun RankingHeader() {
    Column(
        modifier = Modifier.fillMaxWidth(),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(
            text = "이번주 랭킹",
            style = MaterialTheme.typography.titleLarge.copy(
                fontWeight = FontWeight.Bold
            )
        )
    }
}

182-194: 프리뷰 함수 개선 제안

현재 프리뷰가 Loading 상태만 보여주고 있습니다. 다양한 상태를 테스트할 수 있도록 개선이 필요합니다.

다음과 같이 여러 상태의 프리뷰를 추가하는 것을 제안합니다:

@Preview(name = "로딩 상태")
@Composable
fun PreviewMainScreenLoading() {
    MainScreen(
        homesUiState = HomesUiState.Loading,
        // ... other params
    )
}

@Preview(name = "성공 상태")
@Composable
fun PreviewMainScreenSuccess() {
    MainScreen(
        homesUiState = HomesUiState.Success(
            listOf(/* 테스트 데이터 */)
        ),
        // ... other params
    )
}

@Preview(name = "에러 상태")
@Composable
fun PreviewMainScreenError() {
    MainScreen(
        homesUiState = HomesUiState.Fail(Exception("테스트 에러")),
        // ... other params
    )
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d240865 and b95ee6f.

📒 Files selected for processing (1)
  • presentation/src/main/java/view/main/Screen/MainScreen.kt (5 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build
🔇 Additional comments (2)
presentation/src/main/java/view/main/Screen/MainScreen.kt (2)

42-42: LocalContext의 ComponentActivity 캐스팅에 대한 안전성 검토 필요

LocalContext.current as ComponentActivity 캐스팅은 런타임 시 ClassCastException을 발생시킬 수 있습니다. 컨텍스트가 항상 ComponentActivity임을 보장할 수 없기 때문입니다.

다음과 같은 안전한 방식으로 수정하는 것을 고려해보세요:

-viewModel: HomesViewModel = hiltViewModel(LocalContext.current as ComponentActivity)
+viewModel: HomesViewModel = hiltViewModel()

71-74: 콜백 구현이 올바르게 수정되었습니다

LaunchedEffect 내에서 콜백 함수들이 적절하게 호출되도록 구현되어 있습니다.

@kimjeakwan kimjeakwan merged commit f27ba0b into develop Feb 18, 2025
2 checks passed
@kimjeakwan kimjeakwan deleted the feature/54-main-network branch February 18, 2025 03:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

1️⃣ Priority: High 우선순위 - 상

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants