Skip to content

SCRUM-232 design: add setting view#31

Open
gdaegeun539 wants to merge 6 commits intoproject-lyrics:developfrom
gdaegeun539:feature/SCRUM-232-setting-view
Open

SCRUM-232 design: add setting view#31
gdaegeun539 wants to merge 6 commits intoproject-lyrics:developfrom
gdaegeun539:feature/SCRUM-232-setting-view

Conversation

@gdaegeun539
Copy link
Copy Markdown
Member

@gdaegeun539 gdaegeun539 commented Apr 6, 2026

Please check if the PR fulfills these requirements

  • The commit message follows our guidelines

What kind of change does this PR introduce?

Select your one and delete others

  • Implement design

What is the current behavior?

You can also link to an open issue here

  • 마이페이지 화면에서 설정 화면으로 이동하는 아이콘이 더미 로그아웃으로 연결됨
  • 내부의 설정 화면과 계정정보 화면이 구현되지 않음

What is the new behavior (if this is a feature change)?

  • 설정 화면과 계정정보 화면을 구현
  • 마이페이지 화면에서 이들을 들어갈 수 있도록 라우팅을 추가

Does this PR introduce a breaking change? (What changes might users need to make in their application due to this PR?)

하단 내비게이션 바를 이용해 진입하는 화면이 nested route로 변경됩니다.

ScreenShots (If needed)

Other information:

기존 코드에 있던 로컬에 저장하는 더미 유저 초기화 기능은 연결하지 않았습니다. (빠르게 실제 기능을 연동해야 합니다.)

Summary by CodeRabbit

New Features

  • Added Settings screen enabling access to user preferences and account options
  • Added User Info screen displaying user profile and login information
  • Restructured app navigation with dedicated sections for Home, Note Search, and My Page flows

@gdaegeun539 gdaegeun539 self-assigned this Apr 6, 2026
@gdaegeun539 gdaegeun539 added the design 디자인 관련 수정 label Apr 6, 2026
@gdaegeun539
Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 13, 2026

✅ Actions performed

Full review triggered.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 13, 2026

📝 Walkthrough

Walkthrough

The changes introduce a new Settings and User Info flow within the MyPage section, including refactored navigation with nested graph routes (HomeGraph, NoteSearchGraph, MyPageGraph), a new centralized KAKAO_YELLOW color constant, and several new Compose UI components and screens for settings and user information management.

Changes

Cohort / File(s) Summary
Navigation Structure
app/src/main/java/com/lyrics/feelin/navigation/FeelinDestination.kt, app/src/main/java/com/lyrics/feelin/navigation/FeelinNavHost.kt
Added three new navigation graph destinations (HomeGraph, NoteSearchGraph, MyPageGraph) and two new main-flow destinations (Setting, UserInfo). Refactored main navigation to use nested graph routes, updated login/onboarding flow routing, and modified bottom navigation tabs to route to graph-level destinations instead of individual screens.
Color Theme
app/src/main/java/com/lyrics/feelin/presentation/designsystem/theme/Color.kt, app/src/main/java/com/lyrics/feelin/presentation/view/login/SocialLoginButton.kt
Extracted KAKAO_YELLOW constant to centralized theme file and updated SocialLoginButton to import and use the theme constant instead of local definition.
MyPage Navigation
app/src/main/java/com/lyrics/feelin/presentation/view/mypage/MyPageScreen.kt
Added onSettingClick callback parameter to MyPageScreen and routed settings icon click handler to external callback instead of internal viewModel method.
UI Components (MyPage)
app/src/main/java/com/lyrics/feelin/presentation/view/mypage/component/MyPageItemRowShell.kt, app/src/main/java/com/lyrics/feelin/presentation/view/mypage/component/SettingInfoItem.kt, app/src/main/java/com/lyrics/feelin/presentation/view/mypage/component/SettingMenuItem.kt, app/src/main/java/com/lyrics/feelin/presentation/view/mypage/component/UserLoginInfoItem.kt
Added four new reusable Compose UI components: MyPageItemRowShell (flexible row layout shell), SettingInfoItem (settings display item with optional trailing content), SettingMenuItem (clickable menu item with caret icon), and UserLoginInfoItem (login provider info display with config-driven styling).
New Screens
app/src/main/java/com/lyrics/feelin/presentation/view/mypage/setting/SettingScreen.kt, app/src/main/java/com/lyrics/feelin/presentation/view/mypage/userinfo/UserInfoScreen.kt
Added two new full-screen composables: SettingScreen displaying settings menu items, category dividers, and informational rows (version, logout, withdrawal), and UserInfoScreen showing user login info, UID, and gender/birth year sections with appropriate callbacks and UI components.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Through nested graphs and settings deep,
New destinations for profiles to keep!
With UserInfo screens and yellow hue,
The navigation flows fresh and new! ✨
Composable shells and items galore,
MyPage adventures worth exploring more!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change as adding a settings view, which aligns with the primary objective of implementing Settings and User Info screens.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

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

🧹 Nitpick comments (6)
app/src/main/java/com/lyrics/feelin/presentation/view/mypage/userinfo/UserInfoScreen.kt (2)

41-44: Simplify hardcoded data declarations.

Using remember { mutableStateOf(...) } for static mock data adds unnecessary overhead and suggests the values could change when they won't. For design placeholders, simple val declarations suffice.

Proposed simplification
-    val loginInfoItem by remember { mutableStateOf(LoginInfoConfigs.kakao) }
-    val uid by remember { mutableStateOf("8ca0fd81-fd03-438c-8730-c6c4e7ef4aa9-8ca0fd81-fd03") }
-    val gender by remember { mutableStateOf("여성") }
-    val birthYear by remember { mutableStateOf("2000") }
+    // TODO: Replace with actual user data from ViewModel
+    val loginInfoItem = LoginInfoConfigs.kakao
+    val uid = "8ca0fd81-fd03-438c-8730-c6c4e7ef4aa9-8ca0fd81-fd03"
+    val gender = "여성"
+    val birthYear = "2000"

When real data integration is added, these should be hoisted to a ViewModel and observed as state.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@app/src/main/java/com/lyrics/feelin/presentation/view/mypage/userinfo/UserInfoScreen.kt`
around lines 41 - 44, Replace the unnecessary remembered mutable state used for
static mock values with plain immutable vals: change loginInfoItem, uid, gender,
and birthYear (currently created with remember { mutableStateOf(...) }) to
simple val declarations (e.g., val loginInfoItem = LoginInfoConfigs.kakao) since
these are static design placeholders; when real data arrives, hoist them to a
ViewModel and expose as state instead.

74-74: TODO noted for UID copy functionality.

The clipboard copy and snackbar feedback will need to be implemented. Consider using ClipboardManager from LocalClipboardManager and a SnackbarHostState hoisted to the Scaffold.

Would you like me to generate the implementation for the UID copy functionality?

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@app/src/main/java/com/lyrics/feelin/presentation/view/mypage/userinfo/UserInfoScreen.kt`
at line 74, The TODO in SettingInfoActionButton should be replaced with code
that copies the UID to the clipboard and shows a snackbar: obtain
LocalClipboardManager.current (e.g., clipboardManager) and a
rememberCoroutineScope plus the Scaffold's SnackbarHostState (or create one if
not already hoisted), then in SettingInfoActionButton's onClick call
clipboardManager.setText(AnnotatedString(uid)) and launch a coroutine to call
snackbarHostState.showSnackbar("복사되었습니다" or similar); update UserInfoScreen to
accept or provide the SnackbarHostState and the UID string used for copying so
the button can access both.
app/src/main/java/com/lyrics/feelin/presentation/view/mypage/setting/SettingScreen.kt (2)

69-73: Logout and withdrawal actions need implementation.

Currently using SettingInfoItem which doesn't support click actions. When implementing the actual logout/withdrawal flows, these will need to be replaced with clickable components or SettingInfoItem will need an optional onClick parameter.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@app/src/main/java/com/lyrics/feelin/presentation/view/mypage/setting/SettingScreen.kt`
around lines 69 - 73, SettingInfoItem instances for "로그아웃" and "회원 탈퇴" are not
clickable and therefore lack the required logout/withdrawal behavior; update the
UI so these actions are tappable by either adding an optional onClick parameter
to SettingInfoItem (and wiring it through to its clickable container) or
replacing those two items in SettingScreen with a clickable composable (e.g.,
ClickableSettingItem) that calls your logout and withdrawal handlers; ensure you
reference SettingInfoItem in SettingScreen and hook the appropriate
logout/withdrawal functions so the UI triggers the flows.

77-81: Consider responsive sizing for the feedback banner.

Fixed dimensions (350.dp × 110.dp) may not render well on all screen widths.

Proposed improvement for responsive width
             Image(
                 painter = painterResource(R.drawable.feedback_banner),
                 contentDescription = "feedback banner",
-                modifier = Modifier.width(350.dp).height(110.dp)
+                modifier = Modifier
+                    .fillMaxWidth()
+                    .padding(horizontal = 20.dp)
+                    .height(110.dp),
+                contentScale = ContentScale.FillWidth
             )

You'll need to import ContentScale from androidx.compose.ui.layout.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@app/src/main/java/com/lyrics/feelin/presentation/view/mypage/setting/SettingScreen.kt`
around lines 77 - 81, The Image currently uses fixed dimensions which break on
different screens; update the Image composable (the call using
painterResource(R.drawable.feedback_banner)) to use a responsive Modifier such
as fillMaxWidth() combined with either a fixed height or aspectRatio, and set
contentScale = ContentScale.Crop (import
androidx.compose.ui.layout.ContentScale) so the banner scales and crops
correctly across devices; ensure the modifier replaces
width(350.dp).height(110.dp) with the responsive combination and keep
contentDescription unchanged.
app/src/main/java/com/lyrics/feelin/presentation/view/mypage/component/SettingInfoItem.kt (1)

83-89: Consider reordering modifiers for clearer intent.

The current order .clip().background().clickable().padding() works, but placing .clickable() before .background() is more idiomatic in Compose as it ensures the ripple indication is drawn under the background. The current order works because .clip() is applied first, but it's a subtle distinction.

This is minor and doesn't affect functionality.

🔧 Optional modifier reorder
     Box(
         modifier = modifier
             .height(28.dp)
             .clip(shape = RoundedCornerShape(4.dp))
-            .background(color = feelinColors.brandSecondary)
             .clickable(onClick = onClick)
+            .background(color = feelinColors.brandSecondary)
             .padding(horizontal = 8.dp, vertical = 4.dp),
         contentAlignment = Alignment.Center,
     ) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@app/src/main/java/com/lyrics/feelin/presentation/view/mypage/component/SettingInfoItem.kt`
around lines 83 - 89, Reorder the Box modifier chain in SettingInfoItem (the Box
using
modifier.height(...).clip(...).background(...).clickable(...).padding(...)) so
that .clickable(onClick = onClick) appears before .background(color =
feelinColors.brandSecondary); keep .clip(RoundedCornerShape(4.dp)) directly
after height to preserve rounded bounds and retain .padding(horizontal = 8.dp,
vertical = 4.dp) at the end so the clickable ripple is drawn under the
background while behavior and layout remain unchanged.
app/src/main/java/com/lyrics/feelin/navigation/FeelinNavHost.kt (1)

222-222: Consider deriving bottom bar selection from navigation state.

The selectedBottomBarIndex is local state initialized from selectedIndex parameter. While this works for the current flow, it creates a duplication of truth (local state vs. navigation state). A more robust approach would derive the selection from navController.currentBackStackEntryAsState().

However, given the current nested graph structure and how selectedIndex is passed correctly to each screen's MainScaffold, this works correctly for typical user flows.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/java/com/lyrics/feelin/navigation/FeelinNavHost.kt` at line 222,
The local mutable state selectedBottomBarIndex (created with remember {
mutableIntStateOf(selectedIndex) }) duplicates navigation truth; replace it by
deriving the selected index from navController.currentBackStackEntryAsState(),
mapping the active destination route to the bottom-bar index (e.g., via when or
a route->index helper) so selection reflects navigation changes automatically;
remove the mutable variable and any setters and use the derived val wherever
selectedBottomBarIndex was used (reference symbols: selectedBottomBarIndex,
selectedIndex, navController.currentBackStackEntryAsState()).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@app/src/main/java/com/lyrics/feelin/navigation/FeelinNavHost.kt`:
- Line 222: The local mutable state selectedBottomBarIndex (created with
remember { mutableIntStateOf(selectedIndex) }) duplicates navigation truth;
replace it by deriving the selected index from
navController.currentBackStackEntryAsState(), mapping the active destination
route to the bottom-bar index (e.g., via when or a route->index helper) so
selection reflects navigation changes automatically; remove the mutable variable
and any setters and use the derived val wherever selectedBottomBarIndex was used
(reference symbols: selectedBottomBarIndex, selectedIndex,
navController.currentBackStackEntryAsState()).

In
`@app/src/main/java/com/lyrics/feelin/presentation/view/mypage/component/SettingInfoItem.kt`:
- Around line 83-89: Reorder the Box modifier chain in SettingInfoItem (the Box
using
modifier.height(...).clip(...).background(...).clickable(...).padding(...)) so
that .clickable(onClick = onClick) appears before .background(color =
feelinColors.brandSecondary); keep .clip(RoundedCornerShape(4.dp)) directly
after height to preserve rounded bounds and retain .padding(horizontal = 8.dp,
vertical = 4.dp) at the end so the clickable ripple is drawn under the
background while behavior and layout remain unchanged.

In
`@app/src/main/java/com/lyrics/feelin/presentation/view/mypage/setting/SettingScreen.kt`:
- Around line 69-73: SettingInfoItem instances for "로그아웃" and "회원 탈퇴" are not
clickable and therefore lack the required logout/withdrawal behavior; update the
UI so these actions are tappable by either adding an optional onClick parameter
to SettingInfoItem (and wiring it through to its clickable container) or
replacing those two items in SettingScreen with a clickable composable (e.g.,
ClickableSettingItem) that calls your logout and withdrawal handlers; ensure you
reference SettingInfoItem in SettingScreen and hook the appropriate
logout/withdrawal functions so the UI triggers the flows.
- Around line 77-81: The Image currently uses fixed dimensions which break on
different screens; update the Image composable (the call using
painterResource(R.drawable.feedback_banner)) to use a responsive Modifier such
as fillMaxWidth() combined with either a fixed height or aspectRatio, and set
contentScale = ContentScale.Crop (import
androidx.compose.ui.layout.ContentScale) so the banner scales and crops
correctly across devices; ensure the modifier replaces
width(350.dp).height(110.dp) with the responsive combination and keep
contentDescription unchanged.

In
`@app/src/main/java/com/lyrics/feelin/presentation/view/mypage/userinfo/UserInfoScreen.kt`:
- Around line 41-44: Replace the unnecessary remembered mutable state used for
static mock values with plain immutable vals: change loginInfoItem, uid, gender,
and birthYear (currently created with remember { mutableStateOf(...) }) to
simple val declarations (e.g., val loginInfoItem = LoginInfoConfigs.kakao) since
these are static design placeholders; when real data arrives, hoist them to a
ViewModel and expose as state instead.
- Line 74: The TODO in SettingInfoActionButton should be replaced with code that
copies the UID to the clipboard and shows a snackbar: obtain
LocalClipboardManager.current (e.g., clipboardManager) and a
rememberCoroutineScope plus the Scaffold's SnackbarHostState (or create one if
not already hoisted), then in SettingInfoActionButton's onClick call
clipboardManager.setText(AnnotatedString(uid)) and launch a coroutine to call
snackbarHostState.showSnackbar("복사되었습니다" or similar); update UserInfoScreen to
accept or provide the SnackbarHostState and the UID string used for copying so
the button can access both.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f5ba8f38-43f2-413c-bc00-87f96d9e64f2

📥 Commits

Reviewing files that changed from the base of the PR and between ef72f7c and f4c1807.

⛔ Files ignored due to path filters (1)
  • app/src/main/res/drawable/feedback_banner.png is excluded by !**/*.png
📒 Files selected for processing (11)
  • app/src/main/java/com/lyrics/feelin/navigation/FeelinDestination.kt
  • app/src/main/java/com/lyrics/feelin/navigation/FeelinNavHost.kt
  • app/src/main/java/com/lyrics/feelin/presentation/designsystem/theme/Color.kt
  • app/src/main/java/com/lyrics/feelin/presentation/view/login/SocialLoginButton.kt
  • app/src/main/java/com/lyrics/feelin/presentation/view/mypage/MyPageScreen.kt
  • app/src/main/java/com/lyrics/feelin/presentation/view/mypage/component/MyPageItemRowShell.kt
  • app/src/main/java/com/lyrics/feelin/presentation/view/mypage/component/SettingInfoItem.kt
  • app/src/main/java/com/lyrics/feelin/presentation/view/mypage/component/SettingMenuItem.kt
  • app/src/main/java/com/lyrics/feelin/presentation/view/mypage/component/UserLoginInfoItem.kt
  • app/src/main/java/com/lyrics/feelin/presentation/view/mypage/setting/SettingScreen.kt
  • app/src/main/java/com/lyrics/feelin/presentation/view/mypage/userinfo/UserInfoScreen.kt

@gdaegeun539
Copy link
Copy Markdown
Member Author

Potential issue 미발견으로 #14 병합 이전 혹은 직후 바로 병합하겠습니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

design 디자인 관련 수정

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant