diff --git a/web/pages/components/main-layout.tsx b/web/pages/components/main-layout.tsx index 72bdd59de..1e099cdfc 100644 --- a/web/pages/components/main-layout.tsx +++ b/web/pages/components/main-layout.tsx @@ -9,8 +9,10 @@ import { LineChartOutlined, CloseCircleOutlined, PlayCircleFilled, + StopFilled, + MinusSquareFilled, } from '@ant-design/icons'; -import classNames from 'classNames'; +import classNames from 'classnames'; import OwncastLogo from './logo'; @@ -30,7 +32,9 @@ export default function MainLayout(props) { const { Header, Footer, Content, Sider } = Layout; const { SubMenu } = Menu; - const statusMessage = broadcastActive ? + const statusIcon = broadcastActive ? + : ; + const statusMessage = broadcastActive ? 'Online' : 'Offline'; const appClass = classNames({ @@ -59,7 +63,7 @@ export default function MainLayout(props) { Owncast Admin }> - Home + Home } title="Stream Details"> @@ -96,12 +100,12 @@ export default function MainLayout(props) {
- - - {statusMessage} + + {statusIcon} +
diff --git a/web/pages/connected-clients.tsx b/web/pages/connected-clients.tsx index 312cbc9cc..458e4a78e 100644 --- a/web/pages/connected-clients.tsx +++ b/web/pages/connected-clients.tsx @@ -1,5 +1,6 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useContext } from 'react'; import { Table } from 'antd'; +import { BroadcastStatusContext } from './utils/broadcast-status-context'; import { CONNECTED_CLIENTS, fetchData, FETCH_INTERVAL } from './utils/apis'; @@ -12,13 +13,16 @@ geo data looks like this } */ -export default function HardwareInfo() { +export default function ConnectedClients() { + const context = useContext(BroadcastStatusContext); + const { broadcastActive } = context || {}; + const [clients, setClients] = useState([]); const getInfo = async () => { try { const result = await fetchData(CONNECTED_CLIENTS); + console.log("result",result) setClients(result); - } catch (error) { console.log("==== error", error) } @@ -28,14 +32,22 @@ export default function HardwareInfo() { let getStatusIntervalId = null; getInfo(); - getStatusIntervalId = setInterval(getInfo, FETCH_INTERVAL); - - // returned function will be called on component unmount - return () => { - clearInterval(getStatusIntervalId); + if (broadcastActive) { + getStatusIntervalId = setInterval(getInfo, FETCH_INTERVAL); + // returned function will be called on component unmount + return () => { + clearInterval(getStatusIntervalId); + } } + return () => []; }, []); + if (!clients.length) { + return "no clients"; + } + + // todo - check to see if broadcast active has changed. if so, start polling. + const columns = [ { title: 'User name', diff --git a/web/pages/hardware-info.tsx b/web/pages/hardware-info.tsx index d92876499..f26c0aeee 100644 --- a/web/pages/hardware-info.tsx +++ b/web/pages/hardware-info.tsx @@ -1,7 +1,11 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useContext } from 'react'; import { HARDWARE_STATS, fetchData, FETCH_INTERVAL } from './utils/apis'; +import { BroadcastStatusContext } from './utils/broadcast-status-context'; export default function HardwareInfo() { + const context = useContext(BroadcastStatusContext); + const { broadcastActive } = context || {}; + const [hardwareStatus, setHardwareStatus] = useState({}); const getHardwareStatus = async () => { diff --git a/web/pages/index.tsx b/web/pages/index.tsx index 7284410bf..58cbdaaf9 100644 --- a/web/pages/index.tsx +++ b/web/pages/index.tsx @@ -1,11 +1,19 @@ +import React from 'react'; import { Card, Alert, Statistic, Row, Col } from "antd"; import { LikeOutlined } from "@ant-design/icons"; const { Meta } = Card; -export default function Home() { +export default function AdminHome() { return (
+
+ < pick something
+ Home view. pretty pictures. Rainbows. Kittens. +
+ +

+ - < pick something
- Home view. pretty pictures. Rainbows. Kittens. -
- ); -} diff --git a/web/pages/update-server-config.tsx b/web/pages/update-server-config.tsx index 7aa101dd0..3abc52178 100644 --- a/web/pages/update-server-config.tsx +++ b/web/pages/update-server-config.tsx @@ -1,7 +1,12 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useContext } from 'react'; import { SERVER_CONFIG, fetchData, FETCH_INTERVAL } from './utils/apis'; +import { BroadcastStatusContext } from './utils/broadcast-status-context'; export default function ServerConfig() { + const context = useContext(BroadcastStatusContext); + const { broadcastActive } = context || {}; + + const [clients, setClients] = useState({}); const getInfo = async () => { diff --git a/web/pages/utils/broadcast-status-context.tsx b/web/pages/utils/broadcast-status-context.tsx index 86e595b24..309c2152d 100644 --- a/web/pages/utils/broadcast-status-context.tsx +++ b/web/pages/utils/broadcast-status-context.tsx @@ -17,7 +17,7 @@ const BroadcastStatusProvider = ({ children }) => { const getBroadcastStatus = async () => { try { const result = await fetchData(BROADCASTER); - const broadcastActive = !!result.broadcaster; + const broadcastActive = !!result.broadcaster || result.success; setBroadcasterStatus({ ...result, broadcastActive }); } catch (error) { diff --git a/web/pages/viewer-info.tsx b/web/pages/viewer-info.tsx index e63806a03..c545506ce 100644 --- a/web/pages/viewer-info.tsx +++ b/web/pages/viewer-info.tsx @@ -1,12 +1,16 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useContext } from 'react'; import {timeFormat} from 'd3-time-format'; import { LineChart, XAxis, YAxis, Line, Tooltip } from 'recharts'; +import { BroadcastStatusContext } from './utils/broadcast-status-context'; import { VIEWERS_OVER_TIME, fetchData } from './utils/apis'; const FETCH_INTERVAL = 5 * 60 * 1000; // 5 mins export default function ViewersOverTime() { + const context = useContext(BroadcastStatusContext); + const { broadcastActive } = context || {}; + const [viewerInfo, setViewerInfo] = useState([]); const getInfo = async () => { @@ -17,18 +21,28 @@ export default function ViewersOverTime() { console.log("==== error", error) } }; - + useEffect(() => { let getStatusIntervalId = null; getInfo(); - getStatusIntervalId = setInterval(getInfo, FETCH_INTERVAL); - - // returned function will be called on component unmount - return () => { - clearInterval(getStatusIntervalId); + if (broadcastActive) { + getStatusIntervalId = setInterval(getInfo, FETCH_INTERVAL); + // returned function will be called on component unmount + return () => { + clearInterval(getStatusIntervalId); + } } + return () => []; }, []); + + + // todo - check to see if broadcast active has changed. if so, start polling. + + + if (!viewerInfo.length) { + return "no info"; + } const timeFormatter = (tick) => {return timeFormat('%H:%M:%S')(new Date(tick));}; diff --git a/web/styles/styles.module.css b/web/styles/styles.module.css index 0b59be3fb..5c1fe19ed 100644 --- a/web/styles/styles.module.css +++ b/web/styles/styles.module.css @@ -36,6 +36,7 @@ display: flex; flex-direction: row; justify-content: flex-end; + padding-right: 1rem; } .statusIndicatorContainer { @@ -49,15 +50,15 @@ font-size: 1.5rem; } .statusIcon svg { - fill: #ccc; + fill: #999; } .statusLabel { color: #fff; text-transform: uppercase; font-size: .75rem; display: inline-block; - margin-left: .5rem; - color: #ccc; + margin-right: .5rem; + color: #999; } .online .statusIcon svg { fill: #52c41a;