mirror of
				https://github.com/owncast/owncast.git
				synced 2025-11-04 13:27:21 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			149 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			149 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
/* eslint-disable react/no-danger */
 | 
						|
import { useRecoilValue } from 'recoil';
 | 
						|
import { Layout, Tabs, Spin } from 'antd';
 | 
						|
import {
 | 
						|
  clientConfigStateAtom,
 | 
						|
  chatMessagesAtom,
 | 
						|
  chatDisplayNameAtom,
 | 
						|
  chatUserIdAtom,
 | 
						|
  isChatVisibleSelector,
 | 
						|
  serverStatusState,
 | 
						|
  appStateAtom,
 | 
						|
  isOnlineSelector,
 | 
						|
} from '../../stores/ClientConfigStore';
 | 
						|
import { ClientConfig } from '../../../interfaces/client-config.model';
 | 
						|
import CustomPageContent from '../../CustomPageContent';
 | 
						|
import OwncastPlayer from '../../video/OwncastPlayer';
 | 
						|
import FollowerCollection from '../../FollowersCollection';
 | 
						|
import s from './Content.module.scss';
 | 
						|
import Sidebar from '../Sidebar';
 | 
						|
import Footer from '../Footer';
 | 
						|
import ChatContainer from '../../chat/ChatContainer';
 | 
						|
import { ChatMessage } from '../../../interfaces/chat-message.model';
 | 
						|
import ChatTextField from '../../chat/ChatTextField/ChatTextField';
 | 
						|
import ActionButtonRow from '../../action-buttons/ActionButtonRow';
 | 
						|
import ActionButton from '../../action-buttons/ActionButton';
 | 
						|
import Statusbar from '../Statusbar/Statusbar';
 | 
						|
import { ServerStatus } from '../../../interfaces/server-status.model';
 | 
						|
import { Follower } from '../../../interfaces/follower';
 | 
						|
import SocialLinks from '../SocialLinks/SocialLinks';
 | 
						|
import NotifyReminderPopup from '../NotifyReminderPopup/NotifyReminderPopup';
 | 
						|
import ServerLogo from '../Logo/Logo';
 | 
						|
import CategoryIcon from '../CategoryIcon/CategoryIcon';
 | 
						|
import OfflineBanner from '../OfflineBanner/OfflineBanner';
 | 
						|
import { AppStateOptions } from '../../stores/application-state';
 | 
						|
import FollowButton from '../../action-buttons/FollowButton';
 | 
						|
import NotifyButton from '../../action-buttons/NotifyButton';
 | 
						|
 | 
						|
const { TabPane } = Tabs;
 | 
						|
const { Content } = Layout;
 | 
						|
 | 
						|
export default function ContentComponent() {
 | 
						|
  const appState = useRecoilValue<AppStateOptions>(appStateAtom);
 | 
						|
  const status = useRecoilValue<ServerStatus>(serverStatusState);
 | 
						|
  const clientConfig = useRecoilValue<ClientConfig>(clientConfigStateAtom);
 | 
						|
  const isChatVisible = useRecoilValue<boolean>(isChatVisibleSelector);
 | 
						|
  const messages = useRecoilValue<ChatMessage[]>(chatMessagesAtom);
 | 
						|
  const online = useRecoilValue<boolean>(isOnlineSelector);
 | 
						|
  const chatDisplayName = useRecoilValue<string>(chatDisplayNameAtom);
 | 
						|
  const chatUserId = useRecoilValue<string>(chatUserIdAtom);
 | 
						|
 | 
						|
  const { extraPageContent, version, socialHandles, name, title, tags, summary } = clientConfig;
 | 
						|
  const { viewerCount, lastConnectTime, lastDisconnectTime } = status;
 | 
						|
 | 
						|
  const followers: Follower[] = [];
 | 
						|
 | 
						|
  const total = 0;
 | 
						|
 | 
						|
  // This is example content. It should be removed.
 | 
						|
  const externalActions = [
 | 
						|
    {
 | 
						|
      url: 'https://owncast.online/docs',
 | 
						|
      title: 'Example button',
 | 
						|
      description: 'Example button description',
 | 
						|
      icon: 'https://owncast.online/images/logo.svg',
 | 
						|
      color: '#5232c8',
 | 
						|
      openExternally: false,
 | 
						|
    },
 | 
						|
  ];
 | 
						|
 | 
						|
  const externalActionButtons = externalActions.map(action => (
 | 
						|
    <ActionButton key={action.url} action={action} />
 | 
						|
  ));
 | 
						|
 | 
						|
  return (
 | 
						|
    <Content className={`${s.root}`}>
 | 
						|
      <Spin className={s.loadingSpinner} size="large" spinning={appState.appLoading} />
 | 
						|
 | 
						|
      <div className={`${s.leftCol}`}>
 | 
						|
        {online && <OwncastPlayer source="/hls/stream.m3u8" online={online} />}
 | 
						|
        {!online && (
 | 
						|
          <OfflineBanner
 | 
						|
            name={name}
 | 
						|
            text="Stream is offline text goes here. Will create a new form to set it in the Admin."
 | 
						|
          />
 | 
						|
        )}
 | 
						|
 | 
						|
        <Statusbar
 | 
						|
          online={online}
 | 
						|
          lastConnectTime={lastConnectTime}
 | 
						|
          lastDisconnectTime={lastDisconnectTime}
 | 
						|
          viewerCount={viewerCount}
 | 
						|
        />
 | 
						|
        <div className={s.buttonsLogoTitleSection}>
 | 
						|
          <ActionButtonRow>
 | 
						|
            {externalActionButtons}
 | 
						|
            <FollowButton />
 | 
						|
            <NotifyReminderPopup
 | 
						|
              visible
 | 
						|
              notificationClicked={() => {}}
 | 
						|
              notificationClosed={() => {}}
 | 
						|
            >
 | 
						|
              <NotifyButton />
 | 
						|
            </NotifyReminderPopup>
 | 
						|
          </ActionButtonRow>
 | 
						|
 | 
						|
          <div className={`${s.lowerRow}`}>
 | 
						|
            <div className={s.logoTitleSection}>
 | 
						|
              <ServerLogo src="/logo" />
 | 
						|
              <div className={s.titleSection}>
 | 
						|
                <div className={s.title}>{name}</div>
 | 
						|
                <div className={s.subtitle}>
 | 
						|
                  {title}
 | 
						|
                  <CategoryIcon tags={tags} />
 | 
						|
                </div>
 | 
						|
                <div>{tags.length > 0 && tags.map(tag => <span key={tag}>#{tag} </span>)}</div>
 | 
						|
                <SocialLinks links={socialHandles} />
 | 
						|
              </div>
 | 
						|
            </div>
 | 
						|
          </div>
 | 
						|
 | 
						|
          <Tabs defaultActiveKey="1">
 | 
						|
            <TabPane tab="About" key="1" className={`${s.pageContentSection}`}>
 | 
						|
              <div dangerouslySetInnerHTML={{ __html: summary }} />
 | 
						|
              <CustomPageContent content={extraPageContent} />
 | 
						|
            </TabPane>
 | 
						|
            <TabPane tab="Followers" key="2" className={`${s.pageContentSection}`}>
 | 
						|
              <FollowerCollection total={total} followers={followers} />
 | 
						|
            </TabPane>
 | 
						|
          </Tabs>
 | 
						|
          {isChatVisible && (
 | 
						|
            <div className={`${s.mobileChat}`}>
 | 
						|
              <ChatContainer
 | 
						|
                messages={messages}
 | 
						|
                loading={appState.chatLoading}
 | 
						|
                usernameToHighlight={chatDisplayName}
 | 
						|
                chatUserId={chatUserId}
 | 
						|
                isModerator={false}
 | 
						|
              />
 | 
						|
              <ChatTextField />
 | 
						|
            </div>
 | 
						|
          )}
 | 
						|
          <Footer version={version} />
 | 
						|
        </div>
 | 
						|
      </div>
 | 
						|
      {isChatVisible && <Sidebar />}
 | 
						|
    </Content>
 | 
						|
  );
 | 
						|
}
 |