Skip to content

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

Open
gdaegeun539 wants to merge 8 commits into
project-lyrics:developfrom
gdaegeun539:feature/SCRUM-282-block-list-screen
Open

SCRUM-282 design: add blocked user management screen#64
gdaegeun539 wants to merge 8 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)?

차단된 유저 목록을 확인하고 관리할 수 있는 화면을 신규 구현했습니다.

  • 서버 연동 없이 목업 데이터를 사용하는 레이아웃 중심의 구현입니다.
  • 마이페이지 설정 메뉴에 '차단된 유저 관리' 메뉴 항목을 추가하여 화면 진입을 연결했습니다.
  • 상단 앱바, 유저 리스트, 유저가 없을 때의 빈 화면 상태, 동작 피드백을 위한 스낵바를 포함합니다.
  • 공통 컴포넌트로 FeelinActionButtonFeelinSnackbar를 신규 구현하거나 추출하여 적용했습니다.

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

Dark mode

Screenshot_20260707_004336_ DEV  Feelin Screenshot_20260707_004351_ DEV  Feelin

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" feature to the MyPage section: a new screen, ViewModel, UI state, and list-item data model, backed by two new design-system components (FeelinActionButton, FeelinSnackbar). Navigation wiring connects Settings to the new screen, and existing SettingInfoActionButton usage is replaced with FeelinActionButton.

Changes

Blocked Users Feature

Layer / File(s) Summary
Design system components
core/designsystem/component/FeelinActionButton.kt, core/designsystem/component/FeelinSnackbar.kt
New FeelinActionButton and FeelinSnackbar/FeelinSnackbarHost composables with themed styling and previews.
Data model and state
blockedusers/BlockedUserListItemData.kt, blockedusers/BlockedUsersUiState.kt, blockedusers/BlockedUsersViewModel.kt
Adds BlockedUserListItemData, BlockedUsersUiState with initial() factory, and a Hilt BlockedUsersViewModel exposing hardcoded uiState.
List item component
blockedusers/component/BlockedUserListItem.kt
Renders a blocked-user row with profile image, nickname, unblock button, and divider, with light/dark previews.
Screen implementation
blockedusers/BlockedUsersScreen.kt
Implements BlockedUsersScreen with empty/non-empty states, LazyColumn, snackbar on unblock, and multiple previews.
Navigation wiring
navigation/FeelinDestination.kt, navigation/FeelinNavHost.kt, mypage/setting/SettingScreen.kt
Adds BlockedUsers route, registers the composable destination, and adds a "차단된 유저 관리" menu item calling onBlockedUsersClick.
Action button refactor
mypage/component/SettingInfoItem.kt, mypage/userinfo/UserInfoScreen.kt
Removes SettingInfoActionButton and replaces its usage with FeelinActionButton.
UI tests
androidTest/.../BlockedUsersScreenTest.kt
Adds Compose tests verifying list item rendering and snackbar display after 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->>BlockedUsersScreen: onUnblockClick -> show snackbar
Loading

Possibly related PRs

  • project-lyrics/app-Android#31: Builds on the settings/MyPage navigation structure introduced in this PR, adding the BlockedUsers destination and onBlockedUsersClick wiring.

Suggested labels: design

🚥 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 and concisely describes the main change: adding the blocked user management screen.
✨ 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".

* (Figma component name Button_Copy)
*/
@Composable
fun FeelinActionButton(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge 마이페이지 전용 버튼을 로컬로 유지하세요

제가 rg "FeelinActionButton"로 확인한 현재 호출부는 mypage/blockedusersmypage/userinfo뿐입니다. 그런데 app/src/main/java/com/lyrics/feelin/core/AGENTS.md는 “New shared UI belongs here only if reused across multiple features”라고 하고, app/src/main/java/com/lyrics/feelin/presentation/view/mypage/AGENTS.md도 “Do not move mypage-only rows into core/designsystem unless another feature truly reuses them”라고 합니다. 이 상태로 core에 공개하면 마이페이지 설정용 trailing 버튼이 전역 디자인 시스템 API가 되어 feature-agnostic 경계가 흐려지므로, 다른 기능에서 실제로 재사용될 때까지 mypage 컴포넌트로 두는 편이 안전합니다.

Useful? React with 👍 / 👎.

@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

Comment on lines +38 to +42
fun BlockedUsersScreen(
blockedUsers: List<BlockedUserListItemData>,
onBackClick: () -> Unit,
modifier: Modifier = Modifier
) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Same parameter-order issue: lambda should be last, not modifier.

onBackClick precedes modifier, which contradicts "Keep lambda parameters as the last parameter in Composable functions" and "Keep modifier as the first optional parameter in Composable functions" per path instructions.

♻️ Proposed fix
 fun BlockedUsersScreen(
     blockedUsers: List<BlockedUserListItemData>,
-    onBackClick: () -> Unit,
-    modifier: Modifier = Modifier
+    modifier: Modifier = Modifier,
+    onBackClick: () -> 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
fun BlockedUsersScreen(
blockedUsers: List<BlockedUserListItemData>,
onBackClick: () -> Unit,
modifier: Modifier = Modifier
) {
fun BlockedUsersScreen(
blockedUsers: List<BlockedUserListItemData>,
modifier: Modifier = Modifier,
onBackClick: () -> Unit
) {
🤖 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 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.

Source: Path instructions

Comment on lines +10 to +22
@HiltViewModel
class BlockedUsersViewModel @Inject constructor() : ViewModel() {
private val _uiState: MutableStateFlow<BlockedUsersUiState> = MutableStateFlow(
BlockedUsersUiState(
blockedUsers = listOf(
BlockedUserListItemData(userId = 1, nickname = "username01", profileImageUrl = null),
BlockedUserListItemData(userId = 2, nickname = "username02", profileImageUrl = null),
BlockedUserListItemData(userId = 3, nickname = "username03", profileImageUrl = null),
)
)
)
val uiState: StateFlow<BlockedUsersUiState> = _uiState.asStateFlow()
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the relevant files first
git ls-files 'app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/*'

# Show outlines for the ViewModel and screen
ast-grep outline app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/BlockedUsersViewModel.kt --view expanded
ast-grep outline app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/BlockedUsersScreen.kt --view expanded

# Read the relevant sections with line numbers
cat -n app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/BlockedUsersViewModel.kt
printf '\n====\n'
cat -n app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/BlockedUsersScreen.kt

Repository: project-lyrics/app-Android

Length of output: 8792


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find all references to this screen / view model / unblock action
rg -n "BlockedUsersScreen|BlockedUsersViewModel|onUnblockClick|unblockUser|blockedUsers" app/src/main/java

# Inspect the state holder and any route/parent that feeds the screen
cat -n app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/BlockedUsersUiState.kt
printf '\n====\n'
cat -n app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/BlockedUserListItemData.kt

Repository: project-lyrics/app-Android

Length of output: 5294


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the nav host route that owns this screen
sed -n '405,435p' app/src/main/java/com/lyrics/feelin/navigation/FeelinNavHost.kt

# Show the list item implementation to confirm the action surface
cat -n app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/component/BlockedUserListItem.kt

Repository: project-lyrics/app-Android

Length of output: 5909


Add an unblock mutation to the blocked-users state

app/src/main/java/com/lyrics/feelin/presentation/view/mypage/blockedusers/BlockedUsersViewModel.kt:10-22 currently exposes only a read-only StateFlow, so the UI can show “차단 해제되었습니다” without ever removing that user from blockedUsers. Add a state update method here and wire BlockedUsersScreen/FeelinNavHost to call it from onUnblockClick.

🤖 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/BlockedUsersViewModel.kt`
around lines 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.

Comment on lines +32 to +36
fun BlockedUserListItem(
data: BlockedUserListItemData,
onUnblockClick: () -> Unit,
modifier: Modifier = Modifier
) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Reorder parameters: lambda should be last, not modifier.

onUnblockClick (a lambda) currently precedes modifier. As per path instructions, "Keep lambda parameters as the last parameter in Composable functions" and "Keep modifier as the first optional parameter in Composable functions".

♻️ Proposed fix
 fun BlockedUserListItem(
     data: BlockedUserListItemData,
-    onUnblockClick: () -> Unit,
-    modifier: Modifier = Modifier
+    modifier: Modifier = Modifier,
+    onUnblockClick: () -> 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
fun BlockedUserListItem(
data: BlockedUserListItemData,
onUnblockClick: () -> Unit,
modifier: Modifier = Modifier
) {
fun BlockedUserListItem(
data: BlockedUserListItemData,
modifier: Modifier = Modifier,
onUnblockClick: () -> Unit
) {
🤖 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 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.

Source: Path instructions

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