import { ILinkEventTracker, RoomObjectType } from '@nitrots/nitro-renderer'; import { FC, useEffect, useMemo, useRef, useState } from 'react'; import { AddEventLinkTracker, ChatEntryType, LocalizeText, RemoveLinkEventTracker } from '../../api'; import { Column, Flex, InfiniteScroll, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text, Button } from '../../common'; import { useChatHistory, useOnClickChat } from '../../hooks'; import { motion, AnimatePresence } from 'framer-motion'; export const ChatHistoryView: FC<{}> = props => { const { chatHistory = [], clearChatHistory } = useChatHistory(); const [ isVisible, setIsVisible ] = useState(false); const { onClickChat = null } = useOnClickChat(); const [ searchText, setSearchText ] = useState(''); const elementRef = useRef(null); const filteredChatHistory = useMemo(() => { if (searchText.length === 0) return chatHistory; let text = searchText.toLowerCase(); return chatHistory.filter(entry => ((entry.message && entry.message.toLowerCase().includes(text))) || (entry.name && entry.name.toLowerCase().includes(text))); }, [ chatHistory, searchText ]); const handleClearHistory = () => { if (clearChatHistory) { clearChatHistory(); } }; useEffect(() => { if(elementRef && elementRef.current && isVisible) elementRef.current.scrollTop = elementRef.current.scrollHeight; }, [ isVisible ]); useEffect(() => { const linkTracker: ILinkEventTracker = { linkReceived: (url: string) => { const parts = url.split('/'); if(parts.length < 2) return; switch(parts[1]) { case 'show': setIsVisible(true); return; case 'hide': setIsVisible(false); return; case 'toggle': setIsVisible(prevValue => !prevValue); return; } }, eventUrlPrefix: 'chat-history/' }; AddEventLinkTracker(linkTracker); return () => RemoveLinkEventTracker(linkTracker); }, []); return ( { isVisible && ( { // Define styles where imageUrl should not be loaded const stylesWithoutImage = [1, 2, 8, 28, 30, 32, 33, 34, 35, 36, 38]; const shouldDisplayImage = !stylesWithoutImage.includes(row.style); // Determine image dimensions and positioning based on entityType const isPet = row.entityType === RoomObjectType.PET; const imageWidth = isPet ? '41px' : '90px'; // Double for users to account for transform: scale(0.5) const imageHeight = isPet ? '54px' : '130px'; // Double for users to account for transform: scale(0.5) const imageTop = isPet ? '-15px' : '-50px'; // Adjusted to shift user image up const imageLeft = isPet ? '-9.25px' : '-31px'; // Adjusted to shift user image left return ( {row.timestamp} { (row.type === ChatEntryType.TYPE_CHAT) &&
{ (row.style === 0) &&
}
{ shouldDisplayImage && row.imageUrl && (row.imageUrl.length > 0) &&
}
onClickChat(e)} />
} { (row.type === ChatEntryType.TYPE_ROOM_INFO) && <> {row.name} } ) }} /> setIsVisible(false)} /> )} ); };