import { AvatarFigurePartType, AvatarScaleType, AvatarSetType, ILinkEventTracker } from '@nitrots/nitro-renderer'; import { FC, useEffect, useMemo, useRef, useState } from 'react'; import { AutoSizer, CellMeasurer, CellMeasurerCache, List, ListRowProps, ListRowRenderer, Size } from 'react-virtualized'; import { AddEventLinkTracker, ChatEntryType, GetAvatarRenderManager, LocalizeText, RemoveLinkEventTracker } from '../../api'; import { Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../common'; import { useChatHistory } from '../../hooks'; const avatarColorCache: Map = new Map(); const avatarImageCache: Map = new Map(); export const ChatHistoryView: FC<{}> = props => { const [ isVisible, setIsVisible ] = useState(false); const { chatHistory = [] } = useChatHistory(); const elementRef = useRef(null); const [ searchText, setSearchText ] = useState('z'); const setFigureImage = (figure: string) => { const avatarImage = GetAvatarRenderManager().createAvatarImage(figure, AvatarScaleType.LARGE, null, { resetFigure: figure => { setFigureImage(figure); }, dispose: () => {}, disposed: false }); if(!avatarImage) return; const image = avatarImage.getCroppedImage(AvatarSetType.HEAD); const color = avatarImage.getPartColor(AvatarFigurePartType.CHEST); avatarColorCache.set(figure, ((color && color.rgb) || 16777215)); avatarImage.dispose(); avatarImageCache.set(figure, image.src); return image.src; } const getUserImage = (figure: string) => { let existing = avatarImageCache.get(figure); if(!existing) existing = setFigureImage(figure); return existing; } const cache = useMemo(() => new CellMeasurerCache({ defaultHeight: 25, fixedWidth: true }), []); const filteredChatHistory = useMemo(() => { if (searchText.length === 0) return chatHistory; return chatHistory.filter((i) => i.message && i.message.includes(searchText)); }, [ chatHistory, searchText ]); const RowRenderer: ListRowRenderer = (props: ListRowProps) => { const item = filteredChatHistory[props.index]; if (!item) return null; return ( { item.timestamp } { (item.type === ChatEntryType.TYPE_CHAT) &&
{ (item.style === 0) &&
}
{ item.imageUrl && (item.imageUrl.length > 0) &&
}
} { (item.type === ChatEntryType.TYPE_ROOM_INFO) && <> { item.name } } ); }; const onResize = (info: Size) => cache.clearAll(); 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); }, []); useEffect(() => { if(elementRef && elementRef.current && isVisible) elementRef.current.scrollToRow(-1); }, [ isVisible ]); if(!isVisible) return null; return ( setIsVisible(false) }/> setSearchText(event.target.value) } />
{ ({ height, width }) => { return ( ) } }
); }