실시간 마을 채팅 티커
- 오른쪽 상단에 한 줄씩 뜨는 반투명 채팅, 20초 후 페이드아웃 (최대 6줄) - 💬 버튼으로 입력창 토글, Enter 전송 / ESC 닫기 - SSE 스트림(/api/chat/stream): 접속 즉시 연결, 최근 20개 백로그는 비동기 전송, 25초 하트비트로 프록시 유휴 타임아웃 방지 - 전송(/api/chat/send): 닉네임+토큰 검증(사칭 방지), 1.5초 도배 제한, 120자 제한 - chat_messages 테이블 자동 생성, 인프로세스 EventEmitter 브로드캐스트 (단일 컨테이너) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
이 커밋은 다음에 포함됨:
@@ -5,6 +5,7 @@ import { useGame } from "@/hooks/useGame";
|
||||
import VillageView, { type PlacingState } from "@/components/game/VillageView";
|
||||
import DbStatus from "@/components/DbStatus";
|
||||
import NicknameModal from "@/components/game/NicknameModal";
|
||||
import ChatTicker from "@/components/game/ChatTicker";
|
||||
import {
|
||||
engine,
|
||||
effectiveRate,
|
||||
@@ -232,6 +233,11 @@ export default function Game() {
|
||||
}
|
||||
/>
|
||||
|
||||
{/* ── 실시간 마을 채팅 (닉네임 확정 후) ── */}
|
||||
{state.nickname && state.syncToken && (
|
||||
<ChatTicker nickname={state.nickname} token={state.syncToken} />
|
||||
)}
|
||||
|
||||
{/* ── 닉네임 입력 (인사 후, 미입력 시 게임 차단) ── */}
|
||||
{!state.nickname && (state.tutorialStep ?? TUTORIAL_DONE) >= 1 && (
|
||||
<NicknameModal onDone={() => dispatch(() => undefined)} />
|
||||
|
||||
새 이슈에서 참조
사용자 차단