Skip to content

Conversation

@grimza99
Copy link
Collaborator

@grimza99 grimza99 commented Sep 18, 2025

🔎 작업 사항

  • 채팅이 쌓여있는 방에 들어오거나, 채팅을 보냈을때 자동으로 가장 밑의 스크롤로 이동 합니다.
  • 채팅을 보낸 유저의 이름을 표시합니다.

❗️ 전달 사항

e.g. ) npm i 하세요 ...


➕ 관련 이슈

Summary by CodeRabbit

  • 신규 기능

    • 채팅방이 새 메시지 도착/초기 로드 시 자동으로 하단으로 스크롤됩니다.
    • 메시지 버블 위에 발신자 닉네임이 표시됩니다.
  • 스타일

    • 메시지 배경색을 의미 기반 색상 토큰으로 정리하고, 타임스탬프 색상을 회색 토큰으로 통일했습니다.
    • 전역 테마에 회색 색상 토큰(gray500)을 추가했습니다.
  • 정리/관리

    • 이미지 관련 구성 구조를 재배치하여 설정 호환성과 유지보수성을 개선했습니다.

@grimza99 grimza99 self-assigned this Sep 18, 2025
@coderabbitai
Copy link

coderabbitai bot commented Sep 18, 2025

Walkthrough

NextConfig의 최상위 remotePatterns를 제거하고 images.remotePatterns로 이동시켰다. 전역 CSS 테마에 --color-gray500 변수를 추가했다. 채팅 메시지 컴포넌트에 발신자 닉네임 렌더링과 색상 토큰을 적용했고, 채팅 룸에 하단 자동 스크롤(useRef/useEffect) 동작을 추가했다.

Changes

Cohort / File(s) Change Summary
Next.js 이미지 설정 정리
next.config.ts
최상위 remotePatterns 제거, 동일 항목을 images.remotePatterns로 이동(다른 설정 불변).
테마 색상 토큰 추가
src/app/globals.css
@theme 블록에 --color-gray500: #888 추가.
채팅 메시지 UI 조정
src/features/chat/ui/chatMessage/ChatMessage.tsx
보낸이 닉네임 <p> 추가(좌/우 정렬), 말풍선 배경 클래스들을 bg-primary/bg-secondary-background로 교체, 타임스탬프 색상 text-gray500으로 변경, 너비 제약 w-fit 적용.
채팅 룸 자동 스크롤
src/features/chat/ui/chatRoom/index.tsx
useRefendRef 추가, useEffect로 의존성별 스크롤 적용: roomId/initMessages 변경 시 즉시(instant), realTimeMessages 변경 시 부드럽게(smooth), 메시지 컨테이너 하단에 ref div 삽입.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User as 사용자
  participant ChatRoom as ChatRoom 컴포넌트
  participant EffectInit as useEffect(roomId, initMessages)
  participant EffectRT as useEffect(realTimeMessages)
  participant DOM as 하단 앵커 div(endRef)

  User->>ChatRoom: 채팅 화면 진입 또는 방 전환
  ChatRoom->>EffectInit: roomId/initMessages 변경 감지
  EffectInit->>DOM: endRef.scrollIntoView({ behavior: "instant" })
  Note over DOM,ChatRoom: 초기 진입/방 전환 시 즉시 스크롤

  User->>ChatRoom: 실시간 메시지 수신
  ChatRoom->>EffectRT: realTimeMessages 변경 감지
  EffectRT->>DOM: endRef.scrollIntoView({ behavior: "smooth" })
  Note over DOM,ChatRoom: 새 메시지 도착 시 부드럽게 스크롤
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

새 깃털로 고친 config,
회색 한 줄 더해 빛을 보네.
이름은 위에, 말풍선 아래,
끝에 닿으면 살며시 스르르—
토끼가 깔짝, 채팅이 반짝! 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description Check ⚠️ Warning 제공된 PR 설명에는 템플릿의 최상단 ‘PR Title’ 섹션이 누락되어 있고 ‘❗️ 전달 사항’에는 기본 예시 문구가 그대로 남아 있으며 관련 이슈도 구체적으로 지정되지 않아 템플릿 요구사항을 충족하지 않습니다. 템플릿 상단의 ‘PR Title’ 섹션을 작성 또는 제거하고 ‘❗️ 전달 사항’에 실제 전달해야 할 내용을 입력한 뒤 관련 이슈를 명시해주세요.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title Check ✅ Passed 제목 “[feat] 채팅 전송시 스크롤 자동이동 , 채팅 보낸 유저 이름 추가”는 이번 변경의 핵심인 자동 스크롤 이동 기능과 유저 이름 표시 기능을 명확히 요약하고 있어 간결하고 적합합니다.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/chat

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.

@grimza99 grimza99 added the feat label Sep 18, 2025
@grimza99 grimza99 changed the title [Fix] 채팅 전송시 스크롤 자동이동 , 채팅 보낸 유저 이름 추가 [feat] 채팅 전송시 스크롤 자동이동 , 채팅 보낸 유저 이름 추가 Sep 18, 2025
@coderabbitai coderabbitai bot added the fix label Sep 18, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4f08b8d and 313d348.

📒 Files selected for processing (4)
  • next.config.ts (1 hunks)
  • src/app/globals.css (1 hunks)
  • src/features/chat/ui/chatMessage/ChatMessage.tsx (1 hunks)
  • src/features/chat/ui/chatRoom/index.tsx (4 hunks)
🔇 Additional comments (2)
src/app/globals.css (1)

16-16: 새 토큰 --color-gray500 추가 OK — Tailwind 빌드에서 text-gray500 생성 여부 확인 필요

  • 사용처: src/features/chat/ui/chatMessage/ChatMessage.tsx:19 — text-gray500 사용 확인됨.
  • package.json에서 tailwindcss 버전이 출력되지 않았습니다. tailwind.config.{js,cjs,ts}에서 theme.colors에 gray500: 'var(--color-gray500)' 매핑 또는 CSS 변수→색상 매핑 플러그인(또는 Tailwind v4 토큰 체계)이 적용되어 있는지 확인해 주세요.
next.config.ts (1)

6-14: 확인 완료 — images.remotePatterns 설정 유효 (Next.js 15.3.3)

package.json에서 next가 15.3.3으로 확인되었습니다. images.remotePatterns는 공식 설정이며(v15.3.0에서 new URL() 배열 지원 추가) 현재 구성(단일 호스트 + '/**')은 과도하지 않아 안전합니다. (en.nextjs.im)

승인합니다.

import ChatMessage from '../chatMessage/ChatMessage';
import ChatRoomHeader from './ChatRoomHeader';
import { useMyInfoQuery } from '@/entities/mypage/model/query';
import { useEffect, useRef } from 'react';
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick

자동 스크롤 기본 동작은 충족. 다만 사용자가 위로 스크롤 중일 때 강제 하단 점프를 막아주세요.

현재는 새 메시지/초기 메시지 로딩마다 무조건 하단으로 스크롤됩니다. 사용자가 과거 메시지를 읽는 중에도 끌어내리는 UX 문제가 있습니다. 스크롤이 바닥에 근접한 경우에만 자동 스크롤하도록 가드하세요.

다음과 같이 변경을 제안합니다.

@@
-  const endRef = useRef<HTMLDivElement>(null);
+  const endRef = useRef<HTMLDivElement>(null);
+  const scrollContainerRef = useRef<HTMLDivElement>(null);
+  const isAtBottomRef = useRef(true);
@@
-  useEffect(() => {
-    if (endRef.current) {
-      endRef.current.scrollIntoView({ behavior: 'smooth' });
-    }
-  }, [realTimeMessages, initMessages]);
+  useEffect(() => {
+    if (!endRef.current) return;
+    if (isAtBottomRef.current) {
+      endRef.current.scrollIntoView({ behavior: 'smooth', block: 'end', inline: 'nearest' });
+    }
+  }, [realTimeMessages, initMessages]);

추가로 적용해야 하는 변경(선택적 별도 패치):

// 컴포넌트 상단에 핸들러 추가
const handleScroll = () => {
  const el = scrollContainerRef.current;
  if (!el) return;
  const threshold = 80; // px
  const atBottom = el.scrollHeight - el.scrollTop - el.clientHeight <= threshold;
  isAtBottomRef.current = atBottom;
};
-          <div className="flex-1 p-4 flex flex-col gap-4 overflow-y-scroll">
+          <div
+            ref={scrollContainerRef}
+            onScroll={handleScroll}
+            className="flex-1 p-4 flex flex-col gap-4 overflow-y-scroll"
+          >

Also applies to: 19-19, 28-33, 57-57

🤖 Prompt for AI Agents
In src/features/chat/ui/chatRoom/index.tsx around lines 9, 19, 28-33 and 57, the
component currently forces scroll-to-bottom on every new/initial message which
interrupts users reading older messages; add an isAtBottomRef and a scroll
handler that computes atBottom using a threshold (e.g. 80px) by comparing
el.scrollHeight - el.scrollTop - el.clientHeight, update isAtBottomRef in the
onScroll handler attached to the scroll container, and guard all auto-scroll
calls (initial load and on new messages) to only perform scroll-to-bottom when
isAtBottomRef.current is true; ensure the handler is created near the top of the
component, uses the existing scrollContainerRef, and that refs are kept stable
(useRef) so auto-scroll logic references the latest isAtBottom state.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ec38f9d and 92c8f97.

📒 Files selected for processing (1)
  • src/features/chat/ui/chatMessage/ChatMessage.tsx (1 hunks)
🔇 Additional comments (2)
src/features/chat/ui/chatMessage/ChatMessage.tsx (2)

10-12: 발신자 닉네임 렌더링 수정 — LGTM

msg.name 사용으로 이전 리뷰의 문제(내 닉네임 표기)가 해결되었습니다. 정렬 처리도 isOwn과 일관적입니다.


17-19: 접근성: 작은 텍스트(text-xs) 대비 검증 필요

text-gray500(중간 회색)은 text-xs 크기에서 WCAG AA(대비비 4.5:1)를 충족하지 못할 가능성이 큽니다.
파일: src/features/chat/ui/chatMessage/ChatMessage.tsx (라인 17–19)

  • 권장: Tailwind 'text-gray-600' 이상 사용하거나 글자 크기/굵기 조정. 또는 사용 중인 색상 토큰(HEX 또는 토큰 매핑)을 제공하면 대비비를 계산해 권장 색상을 제안하겠습니다.

Comment on lines +13 to +15
className={`max-w-[70%] w-fit px-4 py-2 rounded-[14px] ${isOwn ? ' bg-primary' : ' bg-secondary-background'}`}
>
<p className="whitespace-pre-wrap break-words">{msg.message}</p>
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick

동적 클래스 문자열의 불필요한 공백 제거

템플릿 내 ' bg-primary', ' bg-secondary-background' 앞 공백은 불필요합니다. 다음처럼 정리하세요.

- className={`max-w-[70%] w-fit px-4 py-2 rounded-[14px] ${isOwn ? ' bg-primary' : ' bg-secondary-background'}`}
+ className={`max-w-[70%] w-fit px-4 py-2 rounded-[14px] ${isOwn ? 'bg-primary' : 'bg-secondary-background'}`}
📝 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
className={`max-w-[70%] w-fit px-4 py-2 rounded-[14px] ${isOwn ? ' bg-primary' : ' bg-secondary-background'}`}
>
<p className="whitespace-pre-wrap break-words">{msg.message}</p>
className={`max-w-[70%] w-fit px-4 py-2 rounded-[14px] ${isOwn ? 'bg-primary' : 'bg-secondary-background'}`}
>
<p className="whitespace-pre-wrap break-words">{msg.message}</p>
🤖 Prompt for AI Agents
In src/features/chat/ui/chatMessage/ChatMessage.tsx around lines 13 to 15, the
conditional class strings include unnecessary leading spaces (' bg-primary' and
' bg-secondary-background'); remove the leading spaces so the template builds
classes without embedded leading spaces (e.g., use isOwn ? 'bg-primary' :
'bg-secondary-background') and ensure a single separating space is present in
the surrounding string/template so final className still has proper spacing
between tokens.

⚠️ Potential issue

🧩 Analysis chain

색상 토큰 존재 여부 확인 필요: bg-primary / bg-secondary-background

Tailwind 설정(theme.extend.colors) 혹은 전역 CSS에 해당 토큰이 실제로 매핑되어 있는지 확인 바랍니다. 미정의 시 배경색이 적용되지 않습니다.


🏁 Script executed:

#!/bin/bash
# 토큰 정의 위치 탐색
fd -HI "tailwind.config.*" | xargs -I{} rg -n --no-heading -C2 "colors\s*:|primary|secondary-background|gray500" {}
# 전역 CSS에서 커스텀 클래스/변수 확인
rg -n --type=css -S "\.bg-secondary-background|\.bg-primary|--color-gray500" -C2

Length of output: 197


색상 토큰 미정의: bg-primary / bg-secondary-background 확인 필요

검증 결과: src/app/globals.css에서 --color-gray700, --color-gray500, --color-active 등 CSS 변수는 존재하나 'bg-primary' / 'bg-secondary-background' 클래스 또는 tailwind.config.*(theme.extend.colors) 정의는 검색되지 않음 (예: src/app/globals.css:16 — --color-gray500: #888).

조치: tailwind.config.js의 theme.extend.colors에 primary / secondary-background 추가하거나 globals.css에 .bg-primary/.bg-secondary-background 유틸(또는 기존 CSS 변수에 대한 매핑)을 추가하거나 컴포넌트에서 --color-* 변수를 사용하도록 변경.

🤖 Prompt for AI Agents
src/features/chat/ui/chatMessage/ChatMessage.tsx lines 13-15: The component uses
non-existent utility classes 'bg-primary' and 'bg-secondary-background', so add
definitions for these tokens; either add primary and secondary-background color
entries under theme.extend.colors in tailwind.config.js, or create CSS utility
classes in src/app/globals.css that map .bg-primary/.bg-secondary-background to
the appropriate --color-* variables (or change the component to use the existing
CSS variables directly), then rebuild Tailwind to ensure the classes are
generated.

Comment on lines +17 to +19
<p className={`text-xs text-gray500 mt-1 ${isOwn ? 'text-right' : 'text-left'}`}>
{formattedDate}
</p>
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

비표준 클래스 text-gray500: Tailwind에서 생성되지 않을 수 있음

Tailwind 기본 클래스는 text-gray-500 형태입니다. 커스텀 색을 CSS 변수로 쓰는 목적이라면, 클래스 생성 없이도 다음처럼 임의 값 표기를 쓰는 편이 안전합니다.

- <p className={`text-xs text-gray500 mt-1 ${isOwn ? 'text-right' : 'text-left'}`}>
+ <p className={`text-xs mt-1 ${isOwn ? 'text-right' : 'text-left'} text-[var(--color-gray500)]`}>

대안: Tailwind 설정에 colors: { gray500: 'var(--color-gray500)' }를 추가해 text-gray500을 실제로 생성.

📝 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
<p className={`text-xs text-gray500 mt-1 ${isOwn ? 'text-right' : 'text-left'}`}>
{formattedDate}
</p>
<p className={`text-xs mt-1 ${isOwn ? 'text-right' : 'text-left'} text-[var(--color-gray500)]`}>
{formattedDate}
</p>
🤖 Prompt for AI Agents
In src/features/chat/ui/chatMessage/ChatMessage.tsx around lines 17 to 19, the
class name uses a nonstandard Tailwind token "text-gray500" which may not be
generated; replace it with a valid Tailwind utility (e.g., "text-gray-500") or
use an arbitrary value that references the CSS variable (e.g., the
bracket/inline arbitrary color syntax) to ensure the style is applied, or
alternatively add the custom color mapping to tailwind.config.js under
theme.colors (e.g., gray500: 'var(--color-gray500)') so "text-gray500" will be
emitted.

🧹 Nitpick

타임스탬프는 <time> 태그 사용 권장

시맨틱/접근성 및 i18n에 유리합니다.

- <p className={`text-xs mt-1 ${isOwn ? 'text-right' : 'text-left'} text-[var(--color-gray500)]`}>
-   {formattedDate}
- </p>
+ <time
+   className={`text-xs mt-1 ${isOwn ? 'text-right' : 'text-left'} text-[var(--color-gray500)]`}
+   dateTime={new Date(msg.time).toISOString()}
+ >
+   {formattedDate}
+ </time>
📝 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
<p className={`text-xs text-gray500 mt-1 ${isOwn ? 'text-right' : 'text-left'}`}>
{formattedDate}
</p>
<time
className={`text-xs mt-1 ${isOwn ? 'text-right' : 'text-left'} text-[var(--color-gray500)]`}
dateTime={new Date(msg.time).toISOString()}
>
{formattedDate}
</time>
🤖 Prompt for AI Agents
In src/features/chat/ui/chatMessage/ChatMessage.tsx around lines 17 to 19, the
timestamp is rendered with a <p> tag; replace it with a <time> element to
improve semantics/accessibility and i18n support, keep the existing className
including the conditional alignment (isOwn ? 'text-right' : 'text-left'), render
the same formattedDate as the element content, and add a dateTime attribute with
the ISO/UTC timestamp (e.g. timestamp.toISOString() or the original raw
timestamp string) so assistive tech and browsers can parse the time.

@grimza99 grimza99 merged commit c2147bb into dev Sep 18, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants