Skip to content

20260403 #748 채팅방 및 채팅 상세 페이지 UI 개선#752

Merged
SeoHyun1024 merged 5 commits intomainfrom
20260403_#748_채팅방_및_채팅_상세_페이지_UI_개선
Apr 6, 2026

Hidden character warning

The head ref may contain hidden characters: "20260403_#748_\ucc44\ud305\ubc29_\ubc0f_\ucc44\ud305_\uc0c1\uc138_\ud398\uc774\uc9c0_UI_\uac1c\uc120"
Merged

20260403 #748 채팅방 및 채팅 상세 페이지 UI 개선#752
SeoHyun1024 merged 5 commits intomainfrom
20260403_#748_채팅방_및_채팅_상세_페이지_UI_개선

Conversation

@SeoHyun1024
Copy link
Copy Markdown
Collaborator

@SeoHyun1024 SeoHyun1024 commented Apr 6, 2026

#748

Summary by CodeRabbit

릴리즈 노트

  • 새로운 기능

    • 채팅 목록에서 오른쪽(내 아이템) 이미지가 별도 표시됩니다.
    • 상대 프로필 아바타를 탭해 프로필 화면으로 이동(상대 정보 없으면 오류 모달 표시).
  • UI 개선

    • 상품 이미지 위에 원형 프로필 배지 오버레이 적용으로 가독성 향상.
    • 이미지 테두리 반경 및 간격을 축소·조정하여 레이아웃 정돈.
    • 삭제된 계정 표기 및 닉네임 처리 개선.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 6, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 350df299-fe31-485d-abbc-e9a953d35382

📥 Commits

Reviewing files that changed from the base of the PR and between 5ede051 and 1dc50f5.

📒 Files selected for processing (1)
  • lib/widgets/trade_request_target_preview.dart
✅ Files skipped from review due to trivial changes (1)
  • lib/widgets/trade_request_target_preview.dart

Walkthrough

ChatRoomDetailDto에 nullable 필드 myItemImageUrl가 추가되고, 이 필드가 JSON 직렬화/역직렬화에 포함되며 ChatTabScreen → ChatRoomListItem → ChatTradeInfoCard로 전달되어 썸네일/아바타 오버레이, borderRadius, 닉네임/프로필 네비게이션 처리 등이 변경되었습니다.

Changes

Cohort / File(s) Summary
데이터 모델 및 직렬화
lib/models/apis/objects/chat_room_detail_dto.dart, lib/models/apis/objects/chat_room_detail_dto.g.dart
ChatRoomDetailDtofinal String? myItemImageUrl 추가 및 JsonSerializable 매핑(myItemImageUrl) 생성.
채팅 화면 라우팅
lib/screens/chat_tab_screen.dart
ChatRoomListItem 호출에 myItemImageUrl 인자 전달 추가(널 시 빈 문자열로 폴백).
채팅 목록 아이템 UI
lib/widgets/chat_room_list_item.dart
myItemImageUrl 필드·생성자 추가. 왼쪽 썸네일과 프로필 아바타를 Stack으로 오버레이, 오른쪽에 myItemImageUrl 렌더링, 닉네임 삭제계정 처리 및 레이아웃/간격/radius 조정.
채팅 거래 정보 카드 UI
lib/widgets/chat_trade_info_card.dart
아이템 썸네일에 프로필 아바타 오버레이 적용, 상대 프로필 탭 시 MemberProfileScreen으로 네비게이션(없으면 에러 모달), isDeletedAccount 도출 및 borderRadius 조정.
미세 UI 조정
lib/widgets/trade_request_target_preview.dart
아이템 썸네일의 ClipRRect radius를 10.r → 4.r로 변경.

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant ListItem as ChatRoomListItem/ChatTradeInfoCard
    participant Nav as Navigator
    participant Profile as MemberProfileScreen
    participant Item as ItemDetailScreen

    User->>ListItem: tap overlaid profile avatar
    ListItem->>Nav: push(MemberProfileScreen, opponentId)
    Nav->>Profile: render with opponentId

    User->>ListItem: tap item thumbnail
    ListItem->>Nav: push(ItemDetailScreen, itemId)
    Nav->>Item: render with itemId
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • Cassiiopeia
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 채팅방 및 채팅 상세 페이지 UI 개선을 나타내며, 실제 변경 사항인 마이 아이템 이미지 URL 필드 추가 및 UI 레이아웃 개선과 일치합니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 20260403_#748_채팅방_및_채팅_상세_페이지_UI_개선

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 and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 6, 2026

✅ 프로젝트 빌드 성공

APK 빌드가 완료되었습니다.

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.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
lib/screens/chat_tab_screen.dart (2)

142-151: ⚠️ Potential issue | 🟠 Major

ChatRoomDetailDto 재생성 시 targetItemImageUrlmyItemImageUrl이 누락됩니다.

WebSocket 메시지 수신 시 ChatRoomDetailDto를 새로 생성하면서 기존의 targetItemImageUrlmyItemImageUrl 필드가 포함되지 않아 null이 됩니다. 이로 인해 채팅방 목록의 아이템 이미지가 갑자기 사라질 수 있습니다.

🐛 수정 제안
      final updatedRoom = ChatRoomDetailDto(
        chatRoomId: room.chatRoomId,
        targetMember: room.targetMember,
        targetMemberEupMyeonDong: room.targetMemberEupMyeonDong,
        targetItemImageUrl: room.targetItemImageUrl,
+       myItemImageUrl: room.myItemImageUrl,
        lastMessageContent: message.content ?? '',
        lastMessageTime: message.createdDate ?? DateTime.now(),
        unreadCount: _calculateUnreadCount(room, message),
        chatRoomType: room.chatRoomType,
      );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/screens/chat_tab_screen.dart` around lines 142 - 151, When recreating
ChatRoomDetailDto as updatedRoom in the WebSocket handler, include the missing
image fields so they aren’t nulled; add targetItemImageUrl:
room.targetItemImageUrl and myItemImageUrl: room.myItemImageUrl (or appropriate
source) into the ChatRoomDetailDto constructor alongside existing fields
(chatRoomId, targetMember, lastMessageContent, lastMessageTime, unreadCount from
_calculateUnreadCount, chatRoomType) so updatedRoom preserves both item images.

359-367: ⚠️ Potential issue | 🟠 Major

채팅방 입장 시 ChatRoomDetailDto 재생성에서도 이미지 URL들이 누락됩니다.

onTap 핸들러에서 unreadCount를 0으로 초기화하기 위해 ChatRoomDetailDto를 새로 생성하지만, targetItemImageUrlmyItemImageUrl이 포함되지 않습니다.

🐛 수정 제안
                          _chatRoomsDetail[roomIndex] = ChatRoomDetailDto(
                            chatRoomId: room.chatRoomId,
                            targetMember: room.targetMember,
                            targetMemberEupMyeonDong: room.targetMemberEupMyeonDong,
+                           targetItemImageUrl: room.targetItemImageUrl,
+                           myItemImageUrl: room.myItemImageUrl,
                            lastMessageContent: room.lastMessageContent,
                            lastMessageTime: room.lastMessageTime,
                            unreadCount: 0, // 읽음 처리
                            chatRoomType: room.chatRoomType,
                          );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/screens/chat_tab_screen.dart` around lines 359 - 367, When recreating a
ChatRoomDetailDto in the onTap handler you omitted the image fields, so update
the assignment to include targetItemImageUrl and myItemImageUrl from the
existing room object when setting _chatRoomsDetail[roomIndex] (keep unreadCount:
0 and all other fields as-is); locate the code that assigns ChatRoomDetailDto in
the onTap path (uses _chatRoomsDetail, roomIndex, ChatRoomDetailDto and room)
and add targetItemImageUrl: room.targetItemImageUrl and myItemImageUrl:
room.myItemImageUrl to the constructor arguments.
🧹 Nitpick comments (4)
lib/widgets/chat_room_list_item.dart (3)

170-173: 읽지 않은 메시지 뱃지의 크기에 일관된 스케일링을 적용하세요.

원형 뱃지에 width: 16.wheight: 16.h를 혼용하면 iPad에서 타원형으로 보일 수 있습니다. 원형을 유지하려면 둘 다 .w를 사용하세요.

♻️ 수정 제안
                          child: Container(
                            width: 16.w,
-                           height: 16.h,
+                           height: 16.w,
                            decoration: const BoxDecoration(shape: BoxShape.circle, color: AppColors.chatUnreadBadge),

As per coding guidelines: "Use height: N.w (width-based scaling) instead of height: N.h for images and square elements for safer iPad responsiveness"

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

In `@lib/widgets/chat_room_list_item.dart` around lines 170 - 173, The circular
unread-message badge in ChatRoomListItem uses mixed scaling (width: 16.w,
height: 16.h) which can render as an oval on iPad; update the Container sizing
to use width-based scaling for both dimensions (e.g., change height from 16.h to
16.w) so the BoxDecoration(shape: BoxShape.circle, ...) keeps a true circle;
locate the Container inside chat_room_list_item.dart and make this height
adjustment.

117-117: SizedBox(width: 8.h)SizedBox(width: 8.w)가 되어야 합니다.

가로 간격에 .h(높이 기반 스케일링)를 사용하면 iPad에서 예상치 못한 레이아웃이 발생할 수 있습니다.

♻️ 수정 제안
-                     SizedBox(width: 8.h),
+                     SizedBox(width: 8.w),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/widgets/chat_room_list_item.dart` at line 117, The SizedBox in
chat_room_list_item uses height-based scaling for horizontal spacing; change the
widget instance where SizedBox(width: 8.h) appears to use width-based scaling
(SizedBox(width: 8.w)) so the horizontal gap uses responsive width units instead
of height units—locate the SizedBox(...) in the build method of the
ChatRoomListItem widget and replace the .h with .w for correct horizontal
scaling.

75-77: bottom: -6.h 대신 bottom: -6.w를 사용하세요.

chat_trade_info_card.dart와 동일하게, 프로필 아바타 위치 지정에 일관된 너비 기반 스케일링을 적용해야 iPad에서 올바르게 표시됩니다.

♻️ 수정 제안
              Positioned(
                right: -6.w,
-               bottom: -6.h,
+               bottom: -6.w,

As per coding guidelines: "Use height: N.w (width-based scaling) instead of height: N.h for images and square elements for safer iPad responsiveness"

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

In `@lib/widgets/chat_room_list_item.dart` around lines 75 - 77, Replace the
height-based offset used for the avatar Positioned widget with a width-based
one: in chat_room_list_item.dart update the Positioned instance that sets right:
-6.w to also use bottom: -6.w (replace bottom: -6.h), so the profile avatar uses
width-based scaling (consistent with chat_trade_info_card.dart) for correct iPad
responsiveness.
lib/widgets/chat_trade_info_card.dart (1)

66-68: bottom: -6.h 대신 bottom: -6.w를 사용하세요.

코딩 가이드라인에 따르면, 이미지와 정사각형 요소의 안전한 iPad 반응형을 위해 height: N.h 대신 height: N.w(너비 기반 스케일링)를 사용해야 합니다. 프로필 아바타 위치 지정에도 동일한 원칙을 적용하여 일관성을 유지하세요. right: -6.wbottom: -6.w를 함께 사용하면 iPad에서도 비율이 유지됩니다.

♻️ 수정 제안
              Positioned(
                right: -6.w,
-               bottom: -6.h,
+               bottom: -6.w,

As per coding guidelines: "Use height: N.w (width-based scaling) instead of height: N.h for images and square elements for safer iPad responsiveness"

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

In `@lib/widgets/chat_trade_info_card.dart` around lines 66 - 68, The Positioned
widget placing the profile avatar uses mixed scaling units (right: -6.w, bottom:
-6.h) which breaks iPad square-element scaling; change bottom from -6.h to -6.w
so both offsets use width-based scaling. Locate the Positioned instance in
chat_trade_info_card.dart (the Positioned with right: -6.w) and update bottom to
-6.w to maintain consistent width-based responsive layout for the avatar.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lib/widgets/chat_trade_info_card.dart`:
- Around line 74-75: The current onTap handler passes opponentId ?? '' into
MemberProfileScreen which causes a bad API request when opponentId is null;
update the GestureDetector onTap (the onTap closure that calls
context.navigateTo and constructs MemberProfileScreen) to first check opponentId
for null/empty and either abort navigation or show user feedback (e.g., a
toast/snackbar/error dialog) instead of navigating with an empty id; ensure
MemberProfileScreen is only instantiated/called when opponentId is non-null and
non-empty to avoid invalid backend requests.
- Around line 30-33: The isDeletedAccount check currently always inspects
takeItem.member?.accountStatus; update it to mirror the same isMyTakeItem
branching used for profileImageUrl so it reads the opponent's accountStatus from
giveItem when isMyTakeItem is true and from takeItem otherwise (use
chatRoom.tradeRequestHistory?.giveItem.member?.accountStatus and
chatRoom.tradeRequestHistory?.takeItem.member?.accountStatus accordingly) so the
boolean reflects the correct opponent account status.

---

Outside diff comments:
In `@lib/screens/chat_tab_screen.dart`:
- Around line 142-151: When recreating ChatRoomDetailDto as updatedRoom in the
WebSocket handler, include the missing image fields so they aren’t nulled; add
targetItemImageUrl: room.targetItemImageUrl and myItemImageUrl:
room.myItemImageUrl (or appropriate source) into the ChatRoomDetailDto
constructor alongside existing fields (chatRoomId, targetMember,
lastMessageContent, lastMessageTime, unreadCount from _calculateUnreadCount,
chatRoomType) so updatedRoom preserves both item images.
- Around line 359-367: When recreating a ChatRoomDetailDto in the onTap handler
you omitted the image fields, so update the assignment to include
targetItemImageUrl and myItemImageUrl from the existing room object when setting
_chatRoomsDetail[roomIndex] (keep unreadCount: 0 and all other fields as-is);
locate the code that assigns ChatRoomDetailDto in the onTap path (uses
_chatRoomsDetail, roomIndex, ChatRoomDetailDto and room) and add
targetItemImageUrl: room.targetItemImageUrl and myItemImageUrl:
room.myItemImageUrl to the constructor arguments.

---

Nitpick comments:
In `@lib/widgets/chat_room_list_item.dart`:
- Around line 170-173: The circular unread-message badge in ChatRoomListItem
uses mixed scaling (width: 16.w, height: 16.h) which can render as an oval on
iPad; update the Container sizing to use width-based scaling for both dimensions
(e.g., change height from 16.h to 16.w) so the BoxDecoration(shape:
BoxShape.circle, ...) keeps a true circle; locate the Container inside
chat_room_list_item.dart and make this height adjustment.
- Line 117: The SizedBox in chat_room_list_item uses height-based scaling for
horizontal spacing; change the widget instance where SizedBox(width: 8.h)
appears to use width-based scaling (SizedBox(width: 8.w)) so the horizontal gap
uses responsive width units instead of height units—locate the SizedBox(...) in
the build method of the ChatRoomListItem widget and replace the .h with .w for
correct horizontal scaling.
- Around line 75-77: Replace the height-based offset used for the avatar
Positioned widget with a width-based one: in chat_room_list_item.dart update the
Positioned instance that sets right: -6.w to also use bottom: -6.w (replace
bottom: -6.h), so the profile avatar uses width-based scaling (consistent with
chat_trade_info_card.dart) for correct iPad responsiveness.

In `@lib/widgets/chat_trade_info_card.dart`:
- Around line 66-68: The Positioned widget placing the profile avatar uses mixed
scaling units (right: -6.w, bottom: -6.h) which breaks iPad square-element
scaling; change bottom from -6.h to -6.w so both offsets use width-based
scaling. Locate the Positioned instance in chat_trade_info_card.dart (the
Positioned with right: -6.w) and update bottom to -6.w to maintain consistent
width-based responsive layout for the avatar.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 172b43f4-96f5-49bc-9ed5-47d3f51aa3cb

📥 Commits

Reviewing files that changed from the base of the PR and between cc94c35 and 3bf5c66.

📒 Files selected for processing (5)
  • lib/models/apis/objects/chat_room_detail_dto.dart
  • lib/models/apis/objects/chat_room_detail_dto.g.dart
  • lib/screens/chat_tab_screen.dart
  • lib/widgets/chat_room_list_item.dart
  • lib/widgets/chat_trade_info_card.dart

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 6, 2026

✅ 프로젝트 빌드 성공

APK 빌드가 완료되었습니다.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 6, 2026

✅ 프로젝트 빌드 성공

APK 빌드가 완료되었습니다.

@SeoHyun1024 SeoHyun1024 merged commit 4d2066b into main Apr 6, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant