import React, { FC, ReactNode, useContext, useEffect, useState } from 'react'; import PropTypes from 'prop-types'; import Link from 'next/link'; import Head from 'next/head'; import { differenceInSeconds } from 'date-fns'; import { useRouter } from 'next/router'; import { Layout, Menu, Popover, Alert, Typography, Button, Space, Tooltip } from 'antd'; import { SettingOutlined, HomeOutlined, LineChartOutlined, ToolOutlined, PlayCircleFilled, MinusSquareFilled, QuestionCircleOutlined, MessageOutlined, ExperimentOutlined, EditOutlined, } from '@ant-design/icons'; import classNames from 'classnames'; import { upgradeVersionAvailable } from '../utils/apis'; import { parseSecondsToDurationString } from '../utils/format'; import { OwncastLogo } from './common/OwncastLogo/OwncastLogo'; import { ServerStatusContext } from '../utils/server-status-context'; import { AlertMessageContext } from '../utils/alert-message-context'; import { TextFieldWithSubmit } from './config/TextFieldWithSubmit'; import { TEXTFIELD_PROPS_STREAM_TITLE } from '../utils/config-constants'; import { ComposeFederatedPost } from './ComposeFederatedPost'; import { UpdateArgs } from '../types/config-section'; export type MainLayoutProps = { children: ReactNode; }; export const MainLayout: FC = ({ children }) => { const context = useContext(ServerStatusContext); const { serverConfig, online, broadcaster, versionNumber } = context || {}; const { instanceDetails, chatDisabled, federation } = serverConfig; const { enabled: federationEnabled } = federation; const [currentStreamTitle, setCurrentStreamTitle] = useState(''); const [postModalDisplayed, setPostModalDisplayed] = useState(false); const alertMessage = useContext(AlertMessageContext); const router = useRouter(); const { route } = router || {}; const { Header, Footer, Content, Sider } = Layout; const { SubMenu } = Menu; const [upgradeVersion, setUpgradeVersion] = useState(''); const checkForUpgrade = async () => { try { const result = await upgradeVersionAvailable(versionNumber); setUpgradeVersion(result); } catch (error) { console.log('==== error', error); } }; useEffect(() => { checkForUpgrade(); }, [versionNumber]); useEffect(() => { setCurrentStreamTitle(instanceDetails.streamTitle); }, [instanceDetails]); const handleStreamTitleChanged = ({ value }: UpdateArgs) => { setCurrentStreamTitle(value); }; const handleCreatePostButtonPressed = () => { setPostModalDisplayed(true); }; const appClass = classNames({ 'app-container': true, online, }); const upgradeMenuItemStyle = upgradeVersion ? 'block' : 'none'; const upgradeVersionString = `${upgradeVersion}` || ''; const upgradeMessage = `Upgrade to v${upgradeVersionString}`; const chatMenuItemStyle = chatDisabled ? 'none' : 'block'; const openMenuItems = upgradeVersion ? ['utilities-menu'] : []; const clearAlertMessage = () => { alertMessage.setMessage(null); }; const headerAlertMessage = alertMessage.message ? ( ) : null; // status indicator items const streamDurationString = broadcaster ? parseSecondsToDurationString(differenceInSeconds(new Date(), new Date(broadcaster.time))) : ''; const currentThumbnail = online ? ( current thumbnail ) : null; const statusIcon = online ? : ; const statusMessage = online ? `Online ${streamDurationString}` : 'Offline'; const popoverTitle = Thumbnail; const statusIndicator = (
{statusMessage} {statusIcon}
); const statusIndicatorWithThumb = online ? ( {statusIndicator} ) : ( statusIndicator ); return ( Owncast Admin

Owncast Admin

}> Home } title="Current stream"> Viewers } style={{ display: chatMenuItemStyle }} > Messages Users } > Followers }> General Server Setup Video Chat Social Notifications S3 Storage } title="Utilities"> Hardware Stream Health Logs Social Actions {upgradeMessage} } title="Integrations"> Webhooks Access Tokens External Actions } title="Help"> Help
{headerAlertMessage} {children}
setPostModalDisplayed(false)} />
); }; MainLayout.propTypes = { children: PropTypes.element.isRequired, };