Files
drinkmarble/app/game/chat-feed.tsx
kimyu 347dfc1f4a 게임·입장 UX와 물리/고지 개선을 반영한다.
비행기(세계여행) 칸 선택 이동, 주사위 무게감, 설정 패널·주사위 초기화,
개인정보 고지·파비콘·탭 제목을 정리하고 런타임 로그는 추적에서 제외한다.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-21 12:50:22 +09:00

79 lines
2.2 KiB
TypeScript

'use client';
import { useEffect, useRef } from 'react';
export type ChatFeedItem = {
id: string;
at: number;
nickname: string;
message: string;
kind: 'chat' | 'donation';
payAmount?: number;
};
export default function ChatFeedPanel({
items,
visible,
compact = false,
}: {
items: ChatFeedItem[];
visible: boolean;
compact?: boolean;
}) {
const listRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const el = listRef.current;
if (!el) return;
el.scrollTop = el.scrollHeight;
}, [items.length, items[items.length - 1]?.id]);
if (!visible) return null;
return (
<div
className={
compact
? 'flex h-full max-h-[200px] min-h-0 w-full flex-col overflow-hidden rounded-md bg-black/75 text-white shadow-md'
: 'flex h-full min-h-0 w-full flex-col overflow-hidden rounded-lg bg-black/70 text-white shadow-lg'
}
>
<div
className={
compact
? 'shrink-0 border-b border-white/10 px-1.5 py-0.5 text-[20px] font-semibold text-white/80'
: 'shrink-0 border-b border-white/10 px-2 py-1 text-[22px] font-semibold text-white/80'
}
>
채팅
</div>
<div
ref={listRef}
className={
compact
? 'min-h-0 flex-1 space-y-0.5 overflow-y-auto px-1.5 py-1 text-[20px] leading-snug'
: 'min-h-0 flex-1 space-y-1 overflow-y-auto px-2 py-1.5 text-[22px] leading-snug'
}
>
{items.length === 0 ? (
<p className="text-white/40">채팅 대기 중…</p>
) : (
items.map((item) => (
<p
key={item.id}
className={item.kind === 'donation' ? 'text-amber-200' : 'text-white/90'}
>
<span className="font-semibold text-white/70">{item.nickname}</span>
<span className="text-white/40">: </span>
<span>{item.message || (item.kind === 'donation' ? '치즈 후원' : '')}</span>
{item.kind === 'donation' && item.payAmount != null ? (
<span className="text-amber-300"> ({item.payAmount}치즈)</span>
) : null}
</p>
))
)}
</div>
</div>
);
}