165 lines
5.1 KiB
TypeScript
165 lines
5.1 KiB
TypeScript
import React, { useContext, useEffect, useState } from 'react';
|
|
import PropTypes from 'prop-types';
|
|
import Link from 'next/link';
|
|
import { differenceInSeconds } from "date-fns";
|
|
import { useRouter } from 'next/router';
|
|
import { Layout, Menu } from 'antd';
|
|
|
|
import {
|
|
SettingOutlined,
|
|
HomeOutlined,
|
|
LineChartOutlined,
|
|
CloseCircleOutlined,
|
|
PlayCircleFilled,
|
|
MinusSquareFilled,
|
|
} from '@ant-design/icons';
|
|
import classNames from 'classnames';
|
|
import { upgradeVersionAvailable } from "../../utils/apis";
|
|
import { parseSecondsToDurationString } from '../../utils/format'
|
|
|
|
import OwncastLogo from './logo';
|
|
import { ServerStatusContext } from '../../utils/server-status-context';
|
|
|
|
import adminStyles from '../../styles/styles.module.css';
|
|
|
|
let performedUpgradeCheck = false;
|
|
|
|
export default function MainLayout(props) {
|
|
const { children } = props;
|
|
|
|
const context = useContext(ServerStatusContext);
|
|
const { online, broadcaster, versionNumber } = context || {};
|
|
|
|
const router = useRouter();
|
|
const { route } = router || {};
|
|
|
|
const { Header, Footer, Content, Sider } = Layout;
|
|
const { SubMenu } = Menu;
|
|
|
|
const streamDurationString = online ? parseSecondsToDurationString(differenceInSeconds(new Date(), new Date(broadcaster.time))) : "";
|
|
|
|
const statusIcon = online ? <PlayCircleFilled /> : <MinusSquareFilled />;
|
|
const statusMessage = online ? `Online ${streamDurationString}` : "Offline";
|
|
|
|
const [upgradeVersion, setUpgradeVersion] = useState(null);
|
|
const checkForUpgrade = async () => {
|
|
try {
|
|
const result = await upgradeVersionAvailable(versionNumber);
|
|
setUpgradeVersion(result);
|
|
} catch (error) {
|
|
console.log("==== error", error);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (!performedUpgradeCheck && !context.disableUpgradeChecks) {
|
|
checkForUpgrade();
|
|
console.log('checking')
|
|
performedUpgradeCheck = true
|
|
}
|
|
});
|
|
|
|
const appClass = classNames({
|
|
"owncast-layout": true,
|
|
[adminStyles.online]: online,
|
|
});
|
|
|
|
const upgradeMenuItemStyle = upgradeVersion ? 'block' : 'none';
|
|
const upgradeVersionString = upgradeVersion || '';
|
|
|
|
return (
|
|
<Layout className={appClass}>
|
|
<Sider
|
|
width={240}
|
|
style={{
|
|
overflow: "auto",
|
|
height: "100vh",
|
|
}}
|
|
>
|
|
<Menu
|
|
theme="dark"
|
|
defaultSelectedKeys={[route.substring(1) || "home"]}
|
|
defaultOpenKeys={["current-stream-menu", "utilities-menu"]}
|
|
mode="inline"
|
|
>
|
|
<h1 className={adminStyles.owncastTitleContainer}>
|
|
<span className={adminStyles.logoContainer}>
|
|
<OwncastLogo />
|
|
</span>
|
|
<span className={adminStyles.owncastTitle}>Owncast Admin</span>
|
|
</h1>
|
|
<Menu.Item key="home" icon={<HomeOutlined />}>
|
|
<Link href="/">Home</Link>
|
|
</Menu.Item>
|
|
|
|
<SubMenu
|
|
key="current-stream-menu"
|
|
icon={<LineChartOutlined />}
|
|
title="Current stream"
|
|
>
|
|
<Menu.Item key="viewer-info">
|
|
<Link href="/viewer-info">Viewers</Link>
|
|
</Menu.Item>
|
|
{online ? (
|
|
<Menu.Item key="disconnect-stream" icon={<CloseCircleOutlined />}>
|
|
<Link href="/disconnect-stream">Disconnect Stream...</Link>
|
|
</Menu.Item>
|
|
) : null}
|
|
</SubMenu>
|
|
|
|
<SubMenu
|
|
key="configuration"
|
|
title="Configuration"
|
|
icon={<SettingOutlined />}
|
|
>
|
|
<Menu.Item key="update-server-config">
|
|
<Link href="/update-server-config">Server Configuration</Link>
|
|
</Menu.Item>
|
|
<Menu.Item key="video-config">
|
|
<Link href="/video-config">Video Configuration</Link>
|
|
</Menu.Item>
|
|
<Menu.Item key="storage">
|
|
<Link href="/storage">Storage</Link>
|
|
</Menu.Item>
|
|
</SubMenu>
|
|
|
|
<SubMenu
|
|
key="utilities-menu"
|
|
icon={<SettingOutlined />}
|
|
title="Utilities"
|
|
>
|
|
<Menu.Item key="hardware-info">
|
|
<Link href="/hardware-info">Hardware</Link>
|
|
</Menu.Item>
|
|
<Menu.Item key="logs">
|
|
<Link href="/logs">Logs</Link>
|
|
</Menu.Item>
|
|
<Menu.Item key="upgrade" style={{ display: upgradeMenuItemStyle }}>
|
|
<Link href="/upgrade">
|
|
<a>Upgrade to v{upgradeVersionString}</a>
|
|
</Link>
|
|
</Menu.Item>
|
|
</SubMenu>
|
|
</Menu>
|
|
</Sider>
|
|
|
|
<Layout>
|
|
<Header className={adminStyles.header}>
|
|
<div className={adminStyles.statusIndicatorContainer}>
|
|
<span className={adminStyles.statusLabel}>{statusMessage}</span>
|
|
<span className={adminStyles.statusIcon}>{statusIcon}</span>
|
|
</div>
|
|
</Header>
|
|
<Content className={adminStyles.contentMain}>{children}</Content>
|
|
|
|
<Footer style={{ textAlign: "center" }}>
|
|
<a href="https://owncast.online/">About Owncast v{versionNumber}</a>
|
|
</Footer>
|
|
</Layout>
|
|
</Layout>
|
|
);
|
|
}
|
|
|
|
MainLayout.propTypes = {
|
|
children: PropTypes.element.isRequired,
|
|
}; |