// @flow import React from 'react'; import classnames from 'classnames'; import Spinner from 'component/spinner'; import CommentCreate from 'component/commentCreate'; import LivestreamComment from 'component/livestreamComment'; import Button from 'component/button'; import UriIndicator from 'component/uriIndicator'; import CreditAmount from 'component/common/credit-amount'; import ChannelThumbnail from 'component/channelThumbnail'; import Tooltip from 'component/common/tooltip'; type Props = { uri: string, claim: ?StreamClaim, activeViewers: number, embed?: boolean, doCommentSocketConnect: (string, string) => void, doCommentSocketDisconnect: (string) => void, doCommentList: (string, number, number) => void, comments: Array, fetchingComments: boolean, doSuperChatList: (string) => void, superChats: Array, superChatsTotalAmount: number, myChannels: ?Array, }; const VIEW_MODE_CHAT = 'view_chat'; const VIEW_MODE_SUPER_CHAT = 'view_superchat'; export default function LivestreamComments(props: Props) { const { claim, uri, embed, doCommentSocketConnect, doCommentSocketDisconnect, comments, doCommentList, fetchingComments, doSuperChatList, superChats, superChatsTotalAmount, myChannels, } = props; const commentsRef = React.createRef(); const [isBottomScroll, setIsBottomScroll] = React.useState(); const [viewMode, setViewMode] = React.useState(VIEW_MODE_CHAT); const [performedInitialScroll, setPerformedInitialScroll] = React.useState(false); const claimId = claim && claim.claim_id; const commentsLength = comments && comments.length; const commentsToDisplay = viewMode === VIEW_MODE_CHAT ? comments : superChats; // todo: implement comment_list --mine in SDK so redux can grab with selectCommentIsMine function isMyComment(channelId: string) { if (myChannels != null && channelId != null) { for (let i = 0; i < myChannels.length; i++) { if (myChannels[i].claim_id === channelId) { return true; } } } return false; } React.useEffect(() => { if (claimId) { doCommentList(uri, 1, 75); doSuperChatList(uri); doCommentSocketConnect(uri, claimId); } return () => { if (claimId) { doCommentSocketDisconnect(claimId); } }; }, [claimId, uri, doCommentList, doSuperChatList, doCommentSocketConnect, doCommentSocketDisconnect]); React.useEffect(() => { const element = document.querySelector('.livestream__comments'); function handleScroll() { if (element) { const isAtBottom = element.scrollTop >= -100; setIsBottomScroll(isAtBottom); } } if (element) { element.addEventListener('scroll', handleScroll); if (commentsLength > 0) { // Only update comment scroll if the user hasn't scrolled up to view old comments // If they have, do nothing if (!performedInitialScroll) { setTimeout(() => (element.scrollTop = element.scrollHeight - element.offsetHeight + 100), 20); setPerformedInitialScroll(true); } } return () => element.removeEventListener('scroll', handleScroll); } }, [commentsLength, isBottomScroll, performedInitialScroll, setPerformedInitialScroll, setIsBottomScroll]); if (!claim) { return null; } function scrollBack() { const element = document.querySelector('.livestream__comments'); if (element) element.scrollTop = 0; } return (
{__('Live discussion')}
{superChatsTotalAmount > 0 && (
)}
<> {fetchingComments && !comments && (
)}
{viewMode === VIEW_MODE_CHAT && superChatsTotalAmount > 0 && (
{superChats.map((superChat: Comment) => (
))}
)} {!fetchingComments && comments.length > 0 ? (
{commentsToDisplay.map((comment) => ( ))}
) : (
)} {!isBottomScroll && (
); }