import { motion } from 'framer-motion'; import { useCallback, useState, useRef } from 'react'; import { channel as $channelContent } from '../../content'; import { clsm } from '../../utils'; import { Provider as NotificationProvider } from '../../contexts/Notification'; import { Provider as ChatProvider } from '../../contexts/Chat'; import { Provider as PlayerProvider } from './contexts/Player'; import { sanitizeAmazonProductData } from '../../helpers/streamActionHelpers'; import { STREAM_ACTION_NAME } from '../../constants'; import { useChannel } from '../../contexts/Channel'; import { useChannelView } from './contexts/ChannelView'; import { useLayoutEffect } from 'react'; import { useProfileViewAnimation } from './contexts/ProfileViewAnimation'; import { useResponsiveDevice } from '../../contexts/ResponsiveDevice'; import { useViewerStreamActions } from '../../contexts/ViewerStreamActions'; import Chat from './Chat'; import PageUnavailable from '../../components/PageUnavailable'; import Player from './Player'; import ProductDescriptionModal from './ViewerStreamActions/Product/components/ProductDescriptionModal'; import ProductViewerStreamAction from './ViewerStreamActions/Product/components/Product'; import ProfileViewFloatingNav from './ProfileViewFloatingNav'; import QuizViewerStreamAction from './ViewerStreamActions/QuizCard'; import Tabs from '../../components/Tabs/Tabs'; import useMount from '../../hooks/useMount'; import useResize from '../../hooks/useResize'; import Poll from './Chat/Poll/Poll'; import { usePoll } from '../../contexts/StreamManagerActions/Poll'; const DEFAULT_SELECTED_TAB_INDEX = 0; const CHAT_PANEL_TAB_INDEX = 1; const Channel = () => { const { channelError } = useChannel(); const { isLandscape, isMobileView } = useResponsiveDevice(); const { isStackedView, isSplitView } = useChannelView(); const { getProfileViewAnimationProps, chatAnimationControls } = useProfileViewAnimation(); const { currentViewerStreamActionData, currentViewerStreamActionName, currentViewerStreamActionTitle, setCurrentViewerAction, shouldRenderActionInTab, isChannelPageStackedView } = useViewerStreamActions(); const { isActive: isPollActive, pollTabLabel, hasVotes } = usePoll(); const [selectedTabIndex, setSelectedTabIndex] = useState( DEFAULT_SELECTED_TAB_INDEX ); const channelRef = useRef(); const chatSectionRef = useRef(); const isMounted = useMount(); let visibleChatWidth = 360; if (isSplitView) visibleChatWidth = 308; else if (isStackedView) visibleChatWidth = '100%'; const isTabView = shouldRenderActionInTab || (isPollActive && isChannelPageStackedView); const updateChatSectionHeight = useCallback(() => { let chatSectionHeight = 200; if (isStackedView) { /** * When switching between mobile landscape and portrait modes, channelWidth may not be accurate. * Therefore, we use the window.innerHeight instead; otherwise, we use the channel width. */ const { innerWidth, innerHeight } = window; const { clientWidth: channelWidth = 0 } = channelRef?.current || {}; const width = isMobileView ? innerWidth : channelWidth; chatSectionHeight = Math.max(innerHeight - (width * 9) / 16, 200); // chat section should be no less than 200px in height } if (chatSectionRef.current) chatSectionRef.current.style.minHeight = `${chatSectionHeight}px`; }, [isMobileView, isStackedView]); useResize(updateChatSectionHeight, { shouldCallOnMount: true }); // Ensures we have computed and set the chat section min-height before the first render useLayoutEffect(() => { if (!isMounted()) updateChatSectionHeight(); }, [isMounted, updateChatSectionHeight]); if (channelError) return ; return (
{isTabView && ( <> {hasVotes && ( )} {!isPollActive && currentViewerStreamActionName === STREAM_ACTION_NAME.QUIZ && ( )} {!isPollActive && [ STREAM_ACTION_NAME.AMAZON_PRODUCT, STREAM_ACTION_NAME.PRODUCT ].includes(currentViewerStreamActionName) && (
)}
)} {selectedTabIndex === 0 && isTabView && ( )} {!isTabView && hasVotes && }
); }; export default Channel;