Skip to content

SCRUM-282 design: add blocked user management screen - #64

Merged
gdaegeun539 merged 9 commits into
project-lyrics:developfrom
gdaegeun539:feature/SCRUM-282-block-list-screen
Jul 8, 2026
Merged

SCRUM-282 design: add blocked user management screen#64
gdaegeun539 merged 9 commits into
project-lyrics:developfrom
gdaegeun539:feature/SCRUM-282-block-list-screen

Conversation

@gdaegeun539

@gdaegeun539 gdaegeun539 commented Jul 6, 2026

Copy link
Copy Markdown
Member

Please check if the PR fulfills these requirements

  • The commit message follows our guidelines

What kind of change does this PR introduce?

  • Implement design

What is the current behavior?

๋งˆ์ดํŽ˜์ด์ง€ ์„ค์ • ๋ฉ”๋‰ด ๋‚ด์— ์ฐจ๋‹จ๋œ ์œ ์ €๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ํ™”๋ฉด์œผ๋กœ์˜ ์ง„์ž…์ ์ด ์—†์œผ๋ฉฐ, ๊ด€๋ จ ๊ธฐ๋Šฅ์„ ์œ„ํ•œ ํ™”๋ฉด UI๊ฐ€ ๊ตฌํ˜„๋˜์–ด ์žˆ์ง€ ์•Š์€ ์ƒํƒœ์ž…๋‹ˆ๋‹ค.

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

์ฐจ๋‹จ๋œ ์œ ์ € ๋ชฉ๋ก์„ ํ™•์ธํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ํ™”๋ฉด์„ ์‹ ๊ทœ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ์„œ๋ฒ„ ์—ฐ๋™ ์—†์ด ๋ชฉ์—… ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ ˆ์ด์•„์›ƒ ์ค‘์‹ฌ์˜ ๊ตฌํ˜„์ž…๋‹ˆ๋‹ค.
  • ๋งˆ์ดํŽ˜์ด์ง€ ์„ค์ • ๋ฉ”๋‰ด์— '์ฐจ๋‹จ๋œ ์œ ์ € ๊ด€๋ฆฌ' ๋ฉ”๋‰ด ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•˜์—ฌ ํ™”๋ฉด ์ง„์ž…์„ ์—ฐ๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ์ƒ๋‹จ ์•ฑ๋ฐ”, ์œ ์ € ๋ฆฌ์ŠคํŠธ, ์œ ์ €๊ฐ€ ์—†์„ ๋•Œ์˜ ๋นˆ ํ™”๋ฉด ์ƒํƒœ, ๋™์ž‘ ํ”ผ๋“œ๋ฐฑ์„ ์œ„ํ•œ ์Šค๋‚ต๋ฐ”๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
  • ๊ณตํ†ต ์ปดํฌ๋„ŒํŠธ๋กœ FeelinActionButton๊ณผ FeelinSnackbar๋ฅผ ์‹ ๊ทœ ๊ตฌํ˜„ํ•˜๊ฑฐ๋‚˜ ์ถ”์ถœํ•˜์—ฌ ์ ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

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

์—†์Œ.

ScreenShots (If needed)

Light mode

Screenshot_20260707_004320_ DEV  Feelin Screenshot_20260707_004322_ DEV  Feelin Screenshot_20260708_195047

Dark mode

Screenshot_20260707_004336_ DEV  Feelin Screenshot_20260707_004351_ DEV  Feelin Screenshot_20260708_195031

Other information:

AI Agent

  • ./gradlew detekt ๋ฐ ./gradlew :app:assembleDebug ๋ช…๋ น์„ ํ†ตํ•ด ์ฝ”๋“œ ํ’ˆ์งˆ ๋ฐ ๋นŒ๋“œ ์ •์ƒ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ ์š”์•ฝ:
    • BlockedUsersScreen.kt: ์ฐจ๋‹จ ๋ชฉ๋ก UI ๋ฐ ํ™”๋ฉด ์ƒํƒœ ๋ถ„๊ธฐ ์ฒ˜๋ฆฌ.
    • BlockedUsersViewModel.kt: UI ์ƒํƒœ ๋ฐ ๋ชฉ์—… ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ.
    • FeelinActionButton.kt: ์—ฌ๋Ÿฌ ํ™”๋ฉด์—์„œ ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ถ”์ถœํ•œ ๋ฒ„ํŠผ ์ปดํฌ๋„ŒํŠธ.
    • FeelinSnackbar.kt: ์ปค์Šคํ…€ ๋””์ž์ธ์ด ์ ์šฉ๋œ ์‹ ๊ทœ ๊ณตํ†ต ์Šค๋‚ต๋ฐ”.
    • FeelinNavHost.kt, FeelinDestination.kt: ๋‚จ๋น„๊ฒŒ์ด์…˜ ๊ฒฝ๋กœ ์ •์˜ ๋ฐ ๋งˆ์ดํŽ˜์ด์ง€ ๊ทธ๋ž˜ํ”„ ์—ฐ๊ฒฐ.
    • BlockedUsersScreenTest.kt: ๋ฆฌ์ŠคํŠธ ์•„์ดํ…œ ๋ฐ ์Šค๋‚ต๋ฐ” ๋…ธ์ถœ ์—ฌ๋ถ€์— ๋Œ€ํ•œ UI ํ…Œ์ŠคํŠธ ์ถ”๊ฐ€.

User

์ด๋ฒˆ์— ์ถ”๊ฐ€ํ•œ ์Šค๋‚ต๋ฐ”๊ฐ€ ์‹œ์Šคํ…œ ๋‚ด๋น„๋ฐ”๊ฐ€ 3๋ฒ„ํŠผ์œผ๋กœ ํ‘œ์‹œ๋  ๊ฒฝ์šฐ์— ์•ฑ ํ•˜๋‹จ๋ฐ”์™€ ๊ฒน์ณ ํ‘œ์‹œ๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ถ”ํ›„ ์Šค๋‚ต๋ฐ”๋ฅผ ์ „์—ญ์œผ๋กœ ํ‘œ์‹œํ•˜๋Š” ๋“ฑ์˜ ์กฐ์น˜๋ฅผ ํ†ตํ•ด ์ด๋ฅผ ์ˆ˜์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

Move the local action button component
to the shared core design system directory as FeelinActionButton.
Replace its usage in UserInfoScreen
Integrate BlockedUsersScreen into the mypage navigation graph.
Add the destination to FeelinDestination, connect it in FeelinNavHost with mock data,
and expose a menu item in SettingScreen.
Create BlockedUsersUiState and BlockedUsersViewModel to manage state.
Update FeelinNavHost to inject the ViewModel within the MyPageGraph scope and collect its state,
migrating away from the hardcoded list.
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

๐Ÿ“ Walkthrough

Walkthrough

This PR adds a "Blocked Users" management feature: a new screen, ViewModel, UI state, and list item component, backed by new design-system components (FeelinActionButton, FeelinSnackbar/FeelinSnackbarHost). Navigation wiring connects Settings to the new screen, and existing screens are refactored to reuse the new action button.

Changes

Blocked Users Feature

Layer / File(s) Summary
Design system components
.../component/FeelinActionButton.kt, .../designsystem/component/FeelinSnackbar.kt
Adds FeelinActionButton (small rounded action button) and FeelinSnackbarHost/FeelinSnackbar (styled snackbar with icon and message), each with light/dark previews.
Data model and UI state
.../blockedusers/BlockedUserListItemData.kt, .../blockedusers/BlockedUsersUiState.kt, .../blockedusers/BlockedUsersViewModel.kt
Adds BlockedUserListItemData, BlockedUsersUiState with initial(), and Hilt BlockedUsersViewModel exposing hardcoded blocked users via StateFlow with an unblockUser(userId) method.
List item component
.../blockedusers/component/BlockedUserListItem.kt
Renders a row with profile image, nickname, and unblock button using FeelinActionButton, with divider and previews.
BlockedUsersScreen
.../blockedusers/BlockedUsersScreen.kt
Implements Scaffold with top bar and snackbar host, empty vs. populated states via LazyColumn, unblock action triggering snackbar, and multiple previews.
Navigation wiring
navigation/FeelinDestination.kt, navigation/FeelinNavHost.kt, .../setting/SettingScreen.kt
Adds BlockedUsers route, registers the composable destination scoped to MyPageGraph, wires SettingScreen's new "์ฐจ๋‹จ๋œ ์œ ์ € ๊ด€๋ฆฌ" menu item and onBlockedUsersClick callback.
Action button refactor
.../component/SettingInfoItem.kt, .../userinfo/UserInfoScreen.kt
Removes SettingInfoActionButton and updates UserInfoScreen's "๋ณต์‚ฌ" button to use FeelinActionButton.
Tests
androidTest/.../BlockedUsersScreenTest.kt
Adds Compose UI tests verifying list item rendering and snackbar display on unblock.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SettingScreen
  participant FeelinNavHost
  participant BlockedUsersViewModel
  participant BlockedUsersScreen

  SettingScreen->>FeelinNavHost: onBlockedUsersClick()
  FeelinNavHost->>FeelinNavHost: navigate(BlockedUsers.route)
  FeelinNavHost->>BlockedUsersViewModel: collect uiState
  FeelinNavHost->>BlockedUsersScreen: render(blockedUsers)
  BlockedUsersScreen->>BlockedUsersViewModel: onUnblockClick(userId)
  BlockedUsersViewModel->>BlockedUsersViewModel: filter blockedUsers, update state
  BlockedUsersScreen->>BlockedUsersScreen: show snackbar("์ฐจ๋‹จ ํ•ด์ œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค")
Loading

Possibly related PRs

  • project-lyrics/app-Android#31: Modifies the same SettingScreen and settings navigation surface, overlapping with the "์ฐจ๋‹จ๋œ ์œ ์ € ๊ด€๋ฆฌ" menu item wiring introduced here.

Suggested reviewers: hyunjung-choi

๐Ÿšฅ Pre-merge checks | โœ… 5
โœ… Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage โœ… Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check โœ… Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check โœ… Passed Check skipped because no linked issues were found for this pull request.
Description Check โœ… Passed Check skipped - CodeRabbitโ€™s high-level summary is enabled.
Title check โœ… Passed The title clearly matches the PRโ€™s main change: adding the blocked user management screen and related UI/navigation work.
โœจ Finishing Touches
๐Ÿงช Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

โค๏ธ Share

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

@gdaegeun539
gdaegeun539 requested a review from hyunjung-choi July 6, 2026 16:02
@gdaegeun539 gdaegeun539 self-assigned this Jul 6, 2026
@gdaegeun539 gdaegeun539 added the design ๋””์ž์ธ ๊ด€๋ จ ์ˆ˜์ • label Jul 6, 2026
@gdaegeun539 gdaegeun539 changed the title SCRUM-282 design: ์ฐจ๋‹จ๋œ ์œ ์ € ๊ด€๋ฆฌ ํ™”๋ฉด UI ๊ตฌํ˜„ SCRUM-282 design: add blocked user management screen Jul 6, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

๐Ÿ’ก Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d3cce7ccb1

โ„น๏ธ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with ๐Ÿ‘.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

๐Ÿงน Nitpick comments (7)
app/src/main/java/com/lyrics/feelin/core/designsystem/component/FeelinSnackbar.kt (2)

81-86: ๐Ÿ“ Maintainability & Code Quality | ๐Ÿ”ต Trivial | ๐Ÿ’ค Low value

Icon is hardcoded to a success checkmark for all snackbars.

Icons.Filled.CheckCircle is baked into the shared component regardless of message semantics. Since this snackbar is a general-purpose design-system component (already used for the unblock-success message), a future error/warning snackbar reusing this component would show a misleading success icon. Consider parameterizing the icon or adding a type/variant param.

๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@app/src/main/java/com/lyrics/feelin/core/designsystem/component/FeelinSnackbar.kt`
around lines 81 - 86, The snackbar icon is hardcoded to Icons.Filled.CheckCircle
in the shared FeelinSnackbar component, so all snackbar variants show a success
symbol. Update FeelinSnackbar to accept an icon-related parameter or a
type/variant value, and use that instead of the fixed checkmark so callers can
supply the appropriate icon for success, warning, or error states.

63-94: ๐ŸŽฏ Functional Correctness | ๐Ÿ”ต Trivial | โšก Quick win

Fixed-height Surface will clip longer messages.

The Surface is a fixed height(56.dp) and clipped to RoundedCornerShape(8.dp). Since the message Text has no maxLines/overflow handling, any message that wraps to more than one line will be clipped by the shape rather than the container growing to fit it.

โ™ป๏ธ Suggested fix
     Surface(
         modifier = modifier
             .fillMaxWidth()
-            .height(56.dp)
+            .heightIn(min = 56.dp)
             .shadow(
             Text(
                 text = message,
                 style = FeelinTypography.body2,
-                color = textColor
+                color = textColor,
+                maxLines = 2,
+                overflow = TextOverflow.Ellipsis
             )
๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@app/src/main/java/com/lyrics/feelin/core/designsystem/component/FeelinSnackbar.kt`
around lines 63 - 94, The Snackbar layout in FeelinSnackbar is forcing a fixed
height, which can clip multi-line messages. Update the Surface/Row sizing so the
container can expand with content instead of using a hardcoded 56.dp height, and
add appropriate text handling in the Text composable (for example line limits or
overflow behavior) so longer messages are displayed cleanly without being cut
off.
app/src/main/java/com/lyrics/feelin/core/designsystem/component/FeelinActionButton.kt (2)

24-46: ๐ŸŽฏ Functional Correctness | ๐Ÿ”ต Trivial | โšก Quick win

Text can clip inside the fixed-size box; no accessibility role.

The button's Box has a hardcoded 68.dp x 28.dp size with no maxLines/overflow handling on the inner Text โ€” longer localized strings than "๋ณต์‚ฌ"/"์ฐจ๋‹จ ํ•ด์ œ" will get clipped by the rounded-corner clip. Also, clickable(onClick = onClick) doesn't set role = Role.Button, so screen readers won't announce this as an actionable button.

โ™ป๏ธ Suggested improvements
         Text(
             text = text,
             style = FeelinTypography.body2.copy(color = feelinColors.brandPrimary),
+            maxLines = 1,
+            overflow = TextOverflow.Ellipsis,
         )
             .background(color = feelinColors.brandSecondary)
-            .clickable(onClick = onClick)
+            .clickable(role = Role.Button, onClick = onClick)
๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@app/src/main/java/com/lyrics/feelin/core/designsystem/component/FeelinActionButton.kt`
around lines 24 - 46, The FeelinActionButton composable is using a fixed-size
Box that can clip longer localized labels and its clickable modifier is missing
a button accessibility role. Update FeelinActionButton so the inner Text can
safely fit or truncate by handling text overflow/max lines instead of relying on
the hardcoded size, and keep the layout flexible enough for translations. Also
change the Box click handling to use an explicit Role.Button in clickable so
screen readers announce it as a button.

24-28: ๐Ÿ“ Maintainability & Code Quality | ๐Ÿ”ต Trivial | ๐Ÿ’ค Low value

Parameter order deviates from lambda-last convention.

onClick (a lambda) is placed before modifier. Reordering to (text, modifier, onClick) follows the trailing-lambda convention used elsewhere and matches the project's stated composable parameter ordering preference for lambdas.

๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@app/src/main/java/com/lyrics/feelin/core/designsystem/component/FeelinActionButton.kt`
around lines 24 - 28, Reorder the FeelinActionButton composable parameters to
follow the lambda-last convention by moving onClick after modifier, matching the
project's composable ordering style used elsewhere. Update the
FeelinActionButton function signature so it reads text, modifier, then onClick,
and keep all call sites aligned with the new parameter order.
app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/BlockedUsersUiState.kt (1)

6-8: ๐Ÿ“ Maintainability & Code Quality | ๐Ÿ”ต Trivial | ๐Ÿ’ค Low value

Remove the unused initial() factory.

BlockedUsersViewModel constructs BlockedUsersUiState directly, and there are no call sites for BlockedUsersUiState.initial(). Drop the factory or make the ViewModel use it as the base state.

๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/BlockedUsersUiState.kt`
around lines 6 - 8, The BlockedUsersUiState companion object exposes an unused
initial() factory that is not referenced anywhere, while BlockedUsersViewModel
already creates BlockedUsersUiState directly. Remove the initial() method from
BlockedUsersUiState, or alternatively update BlockedUsersViewModel to use
BlockedUsersUiState.initial() consistently as its base state so there is a
single construction path.
app/src/main/java/com/lyrics/feelin/navigation/FeelinNavHost.kt (1)

350-350: ๐Ÿ“ Maintainability & Code Quality | ๐Ÿ”ต Trivial | โš–๏ธ Poor tradeoff

@Suppress("LongMethod") masks growing complexity in myPageNavGraph.

Each new destination adds to the same function; consider extracting each composable(...) block (e.g., settingComposable, blockedUsersComposable) into private extension functions instead of suppressing the lint rule.

๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/main/java/com/lyrics/feelin/navigation/FeelinNavHost.kt` at line 350,
The `@Suppress("LongMethod")` on `myPageNavGraph` is hiding increasing
complexity in the navigation setup. Remove the suppression and refactor the
large `myPageNavGraph` function by extracting individual `composable(...)`
blocks into private helper/extension functions such as `settingComposable` and
`blockedUsersComposable`, then keep `myPageNavGraph` focused on wiring the graph
together.
app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/component/BlockedUserListItem.kt (1)

51-59: ๐Ÿ“ Maintainability & Code Quality | ๐Ÿ”ต Trivial | โšก Quick win

Localize contentDescription and add a placeholder for AsyncImage.

"Profile Image" is a hardcoded English string while the rest of the screen is Korean, and there's no placeholder/error drawable when profileImageUrl is null or fails to load.

๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/component/BlockedUserListItem.kt`
around lines 51 - 59, Update BlockedUserListItemโ€™s AsyncImage so the
contentDescription is pulled from localized resources instead of the hardcoded
English string, and add placeholder/error drawables for the image loading state.
Use the AsyncImage call in BlockedUserListItem and the surrounding image
modifier setup to wire in a fallback when data.profileImageUrl is null or fails
to load, while keeping the existing size/clip/background styling.
๐Ÿค– Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/BlockedUsersScreen.kt`:
- Around line 38-42: The BlockedUsersScreen composable has the lambda parameter
ordered before modifier, which conflicts with the composable parameter ordering
guidelines. Update the BlockedUsersScreen signature so modifier is the first
optional parameter after required data parameters, and move onBackClick to the
end of the parameter list to keep the lambda last.

In
`@app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/BlockedUsersViewModel.kt`:
- Around line 10-22: The BlockedUsersViewModel currently exposes only a
read-only uiState, so blockedUsers never changes after an unblock action. Add a
state-update method on BlockedUsersViewModel that removes the matching
BlockedUserListItemData from the current BlockedUsersUiState, then update
BlockedUsersScreen and FeelinNavHost to invoke that method from onUnblockClick
so the UI reflects the removal immediately.

In
`@app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/component/BlockedUserListItem.kt`:
- Around line 32-36: The Composable signature for BlockedUserListItem should
follow the standard parameter order by moving modifier before the lambda so the
optional modifier comes first and onUnblockClick is last. Update the
BlockedUserListItem declaration accordingly, and keep the same ordering pattern
anywhere this composable is called to match the intended Compose API style.

---

Nitpick comments:
In
`@app/src/main/java/com/lyrics/feelin/core/designsystem/component/FeelinActionButton.kt`:
- Around line 24-46: The FeelinActionButton composable is using a fixed-size Box
that can clip longer localized labels and its clickable modifier is missing a
button accessibility role. Update FeelinActionButton so the inner Text can
safely fit or truncate by handling text overflow/max lines instead of relying on
the hardcoded size, and keep the layout flexible enough for translations. Also
change the Box click handling to use an explicit Role.Button in clickable so
screen readers announce it as a button.
- Around line 24-28: Reorder the FeelinActionButton composable parameters to
follow the lambda-last convention by moving onClick after modifier, matching the
project's composable ordering style used elsewhere. Update the
FeelinActionButton function signature so it reads text, modifier, then onClick,
and keep all call sites aligned with the new parameter order.

In
`@app/src/main/java/com/lyrics/feelin/core/designsystem/component/FeelinSnackbar.kt`:
- Around line 81-86: The snackbar icon is hardcoded to Icons.Filled.CheckCircle
in the shared FeelinSnackbar component, so all snackbar variants show a success
symbol. Update FeelinSnackbar to accept an icon-related parameter or a
type/variant value, and use that instead of the fixed checkmark so callers can
supply the appropriate icon for success, warning, or error states.
- Around line 63-94: The Snackbar layout in FeelinSnackbar is forcing a fixed
height, which can clip multi-line messages. Update the Surface/Row sizing so the
container can expand with content instead of using a hardcoded 56.dp height, and
add appropriate text handling in the Text composable (for example line limits or
overflow behavior) so longer messages are displayed cleanly without being cut
off.

In `@app/src/main/java/com/lyrics/feelin/navigation/FeelinNavHost.kt`:
- Line 350: The `@Suppress("LongMethod")` on `myPageNavGraph` is hiding
increasing complexity in the navigation setup. Remove the suppression and
refactor the large `myPageNavGraph` function by extracting individual
`composable(...)` blocks into private helper/extension functions such as
`settingComposable` and `blockedUsersComposable`, then keep `myPageNavGraph`
focused on wiring the graph together.

In
`@app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/BlockedUsersUiState.kt`:
- Around line 6-8: The BlockedUsersUiState companion object exposes an unused
initial() factory that is not referenced anywhere, while BlockedUsersViewModel
already creates BlockedUsersUiState directly. Remove the initial() method from
BlockedUsersUiState, or alternatively update BlockedUsersViewModel to use
BlockedUsersUiState.initial() consistently as its base state so there is a
single construction path.

In
`@app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/component/BlockedUserListItem.kt`:
- Around line 51-59: Update BlockedUserListItemโ€™s AsyncImage so the
contentDescription is pulled from localized resources instead of the hardcoded
English string, and add placeholder/error drawables for the image loading state.
Use the AsyncImage call in BlockedUserListItem and the surrounding image
modifier setup to wire in a fallback when data.profileImageUrl is null or fails
to load, while keeping the existing size/clip/background styling.
๐Ÿช„ Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

โ„น๏ธ Review info
โš™๏ธ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3dbc3c41-f30e-4a9e-8ce6-8aa1a6b365c5

๐Ÿ“ฅ Commits

Reviewing files that changed from the base of the PR and between a9aeeec and d3cce7c.

๐Ÿ“’ Files selected for processing (13)
  • app/src/androidTest/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/BlockedUsersScreenTest.kt
  • app/src/main/java/com/lyrics/feelin/core/designsystem/component/FeelinActionButton.kt
  • app/src/main/java/com/lyrics/feelin/core/designsystem/component/FeelinSnackbar.kt
  • 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/view/mypage/blockedusers/BlockedUserListItemData.kt
  • app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/BlockedUsersScreen.kt
  • app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/BlockedUsersUiState.kt
  • app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/BlockedUsersViewModel.kt
  • app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/component/BlockedUserListItem.kt
  • app/src/main/java/com/lyrics/feelin/presentation/view/mypage/component/SettingInfoItem.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
๐Ÿ’ค Files with no reviewable changes (1)
  • app/src/main/java/com/lyrics/feelin/presentation/view/mypage/component/SettingInfoItem.kt

Add unblock functionality by introducing the unblockUser method
to BlockedUsersViewModel and wiring it to BlockedUsersScreen.
Additionally,
move FeelinActionButton to the mypage component package to refine code structure.
@gdaegeun539

Copy link
Copy Markdown
Member Author

@codex re-review this.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

๐Ÿงน Nitpick comments (2)
app/src/main/java/com/lyrics/feelin/presentation/view/mypage/component/FeelinActionButton.kt (1)

1-1: ๐Ÿ“ Maintainability & Code Quality | ๐Ÿ”ต Trivial | ๐Ÿ’ค Low value

Move onClick to the end of the parameter list FeelinActionButton should keep the lambda last, so the signature should be text, modifier, onClick to match the Compose guidelines.

๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@app/src/main/java/com/lyrics/feelin/presentation/view/mypage/component/FeelinActionButton.kt`
at line 1, Update FeelinActionButton so its parameter order follows Compose
conventions by moving the onClick lambda to the end of the signature after text
and modifier. Locate the FeelinActionButton declaration in the mypage component
and adjust any call sites if needed so the function keeps the trailing lambda
style and matches the expected parameter ordering.

Source: Coding guidelines

app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/BlockedUsersScreen.kt (1)

91-96: ๐Ÿฉบ Stability & Availability | ๐Ÿ”ต Trivial | โšก Quick win

Snackbar shows unconditionally regardless of unblock outcome.

onUnblockClick(user.userId) is called, then the success snackbar is launched without checking whether the operation actually succeeded. With current mock data this is harmless, but once backend integration lands, a failure would still show a success message. Consider gating the snackbar on the result of the unblock action.

๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/BlockedUsersScreen.kt`
around lines 91 - 96, The unblock handler in BlockedUsersScreen currently
launches the success snackbar immediately after onUnblockClick(user.userId), so
it will show even if the unblock fails. Update the onUnblockClick callback flow
to return or observe a success/failure result from the unblock action, and only
call snackbarHostState.showSnackbar inside the success path. Use the existing
onUnblockClick and coroutineScope launch block as the place to gate the snackbar
on the actual outcome.
๐Ÿค– Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/BlockedUsersScreen.kt`:
- Around line 92-95: The snackbar message in BlockedUsersScreenโ€™s unblock flow
does not match the design spec; update the text used in the
coroutineScope.launch call that shows the snackbar after
onUnblockClick(user.userId) so it uses the honorific phrasing specified in the
PR (โ€œ์ฐจ๋‹จ ํ•ด์ œ๋˜์…จ์Šต๋‹ˆ๋‹คโ€) instead of the current plain-form message.

---

Nitpick comments:
In
`@app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/BlockedUsersScreen.kt`:
- Around line 91-96: The unblock handler in BlockedUsersScreen currently
launches the success snackbar immediately after onUnblockClick(user.userId), so
it will show even if the unblock fails. Update the onUnblockClick callback flow
to return or observe a success/failure result from the unblock action, and only
call snackbarHostState.showSnackbar inside the success path. Use the existing
onUnblockClick and coroutineScope launch block as the place to gate the snackbar
on the actual outcome.

In
`@app/src/main/java/com/lyrics/feelin/presentation/view/mypage/component/FeelinActionButton.kt`:
- Line 1: Update FeelinActionButton so its parameter order follows Compose
conventions by moving the onClick lambda to the end of the signature after text
and modifier. Locate the FeelinActionButton declaration in the mypage component
and adjust any call sites if needed so the function keeps the trailing lambda
style and matches the expected parameter ordering.
๐Ÿช„ Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

โ„น๏ธ Review info
โš™๏ธ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3c7d1ff9-3fff-4b2e-b571-31481a068d36

๐Ÿ“ฅ Commits

Reviewing files that changed from the base of the PR and between d3cce7c and 1f5b2cf.

๐Ÿ“’ Files selected for processing (6)
  • app/src/main/java/com/lyrics/feelin/navigation/FeelinNavHost.kt
  • app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/BlockedUsersScreen.kt
  • app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/BlockedUsersViewModel.kt
  • app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/component/BlockedUserListItem.kt
  • app/src/main/java/com/lyrics/feelin/presentation/view/mypage/component/FeelinActionButton.kt
  • app/src/main/java/com/lyrics/feelin/presentation/view/mypage/userinfo/UserInfoScreen.kt
๐Ÿšง Files skipped from review as they are similar to previous changes (4)
  • app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/BlockedUsersViewModel.kt
  • app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/component/BlockedUserListItem.kt
  • app/src/main/java/com/lyrics/feelin/presentation/view/mypage/userinfo/UserInfoScreen.kt
  • app/src/main/java/com/lyrics/feelin/navigation/FeelinNavHost.kt

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

๐Ÿ’ก Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1f5b2cf730

โ„น๏ธ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with ๐Ÿ‘.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@gdaegeun539

Copy link
Copy Markdown
Member Author

๋ณ‘ํ•ฉํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

@gdaegeun539
gdaegeun539 merged commit c76e9f1 into project-lyrics:develop Jul 8, 2026
3 checks passed
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