mirror of
https://github.com/yusufipk/YTChatHub.git
synced 2026-09-11 19:06:14 +00:00
refactor: extract ChatListPanel component and add conditional auto-scroll behavior
This commit is contained in:
@@ -105,21 +105,22 @@ export default function DashboardPage() {
|
||||
<div className="panel__header">
|
||||
<h2>💬 CHAT MESSAGES</h2>
|
||||
</div>
|
||||
<div className="chatList">
|
||||
{regularMessages.map((message) => (
|
||||
<ChatListPanel
|
||||
messages={regularMessages}
|
||||
renderItem={(message) => (
|
||||
<ChatItem
|
||||
key={message.id}
|
||||
message={message}
|
||||
isSelected={selection?.id === message.id}
|
||||
onSelect={() => handleSelect(message)}
|
||||
/>
|
||||
))}
|
||||
{regularMessages.length === 0 && (
|
||||
)}
|
||||
emptyState={
|
||||
<div className="chatList__empty">
|
||||
<p>⏳ Waiting for chat messages...</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="dashboard__grid-right">
|
||||
@@ -127,42 +128,44 @@ export default function DashboardPage() {
|
||||
<div className="panel__header">
|
||||
<h2>🔥 SUPER CHATS</h2>
|
||||
</div>
|
||||
<div className="chatList">
|
||||
{superChats.map((message) => (
|
||||
<ChatListPanel
|
||||
messages={superChats}
|
||||
renderItem={(message) => (
|
||||
<ChatItem
|
||||
key={message.id}
|
||||
message={message}
|
||||
isSelected={selection?.id === message.id}
|
||||
onSelect={() => handleSelect(message)}
|
||||
/>
|
||||
))}
|
||||
{superChats.length === 0 && (
|
||||
)}
|
||||
emptyState={
|
||||
<div className="chatList__empty">
|
||||
<p>No super chats yet</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="panel panel--members">
|
||||
<div className="panel__header">
|
||||
<h2>⭐ MEMBERSHIPS & MILESTONES</h2>
|
||||
</div>
|
||||
<div className="chatList">
|
||||
{newMembers.map((message) => (
|
||||
<ChatListPanel
|
||||
messages={newMembers}
|
||||
renderItem={(message) => (
|
||||
<MemberItem
|
||||
key={message.id}
|
||||
message={message}
|
||||
isSelected={selection?.id === message.id}
|
||||
onSelect={() => handleSelect(message)}
|
||||
/>
|
||||
))}
|
||||
{newMembers.length === 0 && (
|
||||
)}
|
||||
emptyState={
|
||||
<div className="chatList__empty">
|
||||
<p>No new members yet</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -380,6 +383,33 @@ type ChatItemProps = {
|
||||
onSelect: () => void;
|
||||
};
|
||||
|
||||
type ChatListPanelProps = {
|
||||
messages: ChatMessage[];
|
||||
renderItem: (message: ChatMessage) => React.ReactNode;
|
||||
emptyState: React.ReactNode;
|
||||
};
|
||||
|
||||
function ChatListPanel({ messages, renderItem, emptyState }: ChatListPanelProps) {
|
||||
const scrollRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const node = scrollRef.current;
|
||||
if (node) {
|
||||
// Check if user is near the bottom before scrolling
|
||||
const isAtBottom = node.scrollHeight - node.scrollTop - node.clientHeight <= 100;
|
||||
if (isAtBottom) {
|
||||
node.scrollTop = node.scrollHeight;
|
||||
}
|
||||
}
|
||||
}, [messages]);
|
||||
|
||||
return (
|
||||
<div className="chatList" ref={scrollRef}>
|
||||
{messages.length > 0 ? messages.map(renderItem) : emptyState}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ChatItem({ message, isSelected, onSelect }: ChatItemProps) {
|
||||
return (
|
||||
<button
|
||||
|
||||
@@ -86,15 +86,17 @@ export default function OverlayPage() {
|
||||
</div>
|
||||
{message.superChat && (
|
||||
<div className="overlay__superchat" style={{ backgroundColor: message.superChat.color }}>
|
||||
💰 {message.superChat.amount} {message.superChat.currency}
|
||||
💰 {message.superChat.currency}{message.superChat.amount}
|
||||
</div>
|
||||
)}
|
||||
{message.membershipGift && (
|
||||
<div className="overlay__membership">
|
||||
🎁 {message.membershipLevel || 'New Member'}
|
||||
🎁 New Member!
|
||||
</div>
|
||||
)}
|
||||
<p className="overlay__text">{message.text}</p>
|
||||
{(!message.superChat && !message.membershipGift) && message.text && (
|
||||
<p className="overlay__text">{message.text}</p>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<div className="overlay__placeholder">
|
||||
|
||||
Reference in New Issue
Block a user