This commit is contained in:
Ginger Wong
2020-10-21 01:19:29 -07:00
parent 654f70dcf9
commit 81e25d3540
3 changed files with 108 additions and 38 deletions

View File

@@ -1,4 +1,6 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { Table } from 'antd';
import { CONNECTED_CLIENTS, fetchData, FETCH_INTERVAL } from '../utils/apis'; import { CONNECTED_CLIENTS, fetchData, FETCH_INTERVAL } from '../utils/apis';
export default function HardwareInfo() { export default function HardwareInfo() {
@@ -16,12 +18,10 @@ geo data looks like this
const getInfo = async () => { const getInfo = async () => {
try { try {
const result = await fetchData(CONNECTED_CLIENTS); const result = await fetchData(CONNECTED_CLIENTS);
console.log("================ result", result) setClients(result);
setClients({ ...result });
} catch (error) { } catch (error) {
setClients({ ...clients, message: error.message }); console.log("==== error", error)
} }
}; };
@@ -37,14 +37,45 @@ geo data looks like this
} }
}, []); }, []);
const columns = [
{
title: 'User name',
dataIndex: 'username',
key: 'username',
render: username => username || '-',
sorter: (a, b) => a.username - b.username,
sortDirections: ['descend', 'ascend'],
},
{
title: 'Messages sent',
dataIndex: 'messageCount',
key: 'messageCount',
sorter: (a, b) => a.messageCount - b.messageCount,
sortDirections: ['descend', 'ascend'],
},
{
title: 'Connected Time',
dataIndex: 'connectedAt',
key: 'connectedAt',
render: time => (Date.now() - (new Date(time).getTime())) / 1000 / 60,
},
{
title: 'User Agent',
dataIndex: 'userAgent',
key: 'userAgent',
},
{
title: 'Location',
dataIndex: 'geo',
key: 'geo',
render: geo => geo && `${geo.regionName}, ${geo.countryCode}`,
},
];
return ( return (
<div> <div>
<h2>Connected Clients</h2> <h2>Connected Clients</h2>
<p>a table of info..</p> <Table dataSource={clients} columns={columns} />;
<p>who's watching, how long they've been there, have they chatted? where they from?</p>
<div style={{border: '1px solid purple', height: '300px', width: '100%', overflow:'auto'}}>
{JSON.stringify(clients)}
</div>
</div> </div>
); );
} }

View File

@@ -3,7 +3,6 @@ import {timeFormat} from 'd3-time-format';
import { LineChart, XAxis, YAxis, Line, Tooltip } from 'recharts'; import { LineChart, XAxis, YAxis, Line, Tooltip } from 'recharts';
import { VIEWERS_OVER_TIME, fetchData } from '../utils/apis'; import { VIEWERS_OVER_TIME, fetchData } from '../utils/apis';
const FETCH_INTERVAL = 5 * 60 * 1000; // 5 mins const FETCH_INTERVAL = 5 * 60 * 1000; // 5 mins
export default function ViewersOverTime() { export default function ViewersOverTime() {
@@ -13,7 +12,6 @@ export default function ViewersOverTime() {
try { try {
const result = await fetchData(VIEWERS_OVER_TIME); const result = await fetchData(VIEWERS_OVER_TIME);
setViewerInfo(result); setViewerInfo(result);
} catch (error) { } catch (error) {
console.log("==== error", error) console.log("==== error", error)
} }
@@ -33,22 +31,41 @@ export default function ViewersOverTime() {
const timeFormatter = (tick) => {return timeFormat('%H:%M:%S')(new Date(tick));}; const timeFormatter = (tick) => {return timeFormat('%H:%M:%S')(new Date(tick));};
const CustomizedTooltip = (props) => {
const { active, payload, label } = props;
if (active) {
const numViewers = payload && payload[0] && payload[0].value;
const time = timeFormatter(label);
const message = `${numViewers} viewer(s) at ${time}`;
return (
<div className="custom-tooltip">
<p className="label">{message}</p>
</div>
);
}
return null;
};
return ( return (
<div style={{backgroundColor: '#333'}}> <div>
<h2>Viewers over time</h2> <h2>Current Viewers</h2>
<p>Time on X axis, # Viewer on Y</p> <div className="chart-container">
<div style={{border: '1px solid red', height: '300px', width: '100%', overflow:'auto'}}>
{JSON.stringify(viewerInfo)}
</div>
<LineChart width={800} height={400} data={viewerInfo}> <LineChart width={800} height={400} data={viewerInfo}>
<XAxis dataKey="time" tickFormatter={timeFormatter}/> <XAxis dataKey="time" tickFormatter={timeFormatter}/>
<YAxis dataKey="value"/> <YAxis dataKey="value"/>
<Tooltip cursor={{ stroke: 'red', strokeWidth: 2 }} /> <Tooltip
<Line type="monotone" dataKey="value" stroke="#ff84d8" dot={{ stroke: 'red', strokeWidth: 2 }} /> content={<CustomizedTooltip />}
/>
<Line
type="monotone"
dataKey="value"
stroke="#ff84d8"
dot={{ stroke: 'red', strokeWidth: 2 }}
/>
</LineChart> </LineChart>
</div>
</div> </div>
); );

View File

@@ -1,4 +1,6 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { Layout } from 'antd';
import BroadcastInfo from './components/broadcast-info'; import BroadcastInfo from './components/broadcast-info';
import HardwareInfo from './components/hardware-info'; import HardwareInfo from './components/hardware-info';
@@ -9,20 +11,32 @@ import ConnectedClients from './components/connected-clients';
export default function HomeView(props) { export default function HomeView(props) {
const { broadcastActive, broadcaster, message } = props; const { broadcastActive, broadcaster, message } = props;
const { Header, Footer, Content } = Layout;
const broadcastDetails = broadcastActive ? ( const broadcastDetails = broadcastActive ? (
<> <>
{/* <BroadcastInfo {...broadcaster} /> {/* <BroadcastInfo {...broadcaster} />
<HardwareInfo /> */} <HardwareInfo /> */}
<ViewerInfo /> <ViewerInfo />
{/* <ConnectedClients /> <ConnectedClients />
<ServerConfig /> */} {/* <ServerConfig /> */}
</> </>
) : null; ) : null;
const disconnectButton = broadcastActive ? <button type="button">Boot (Disconnect)</button> : null; const disconnectButton = broadcastActive ? <button type="button">Boot (Disconnect)</button> : null;
return ( return (
<div style={{ padding: '2em' }}> <Layout className="layout">
<Header>
<div className="logo">logo</div>
{/* <Menu theme="dark" mode="horizontal" defaultSelectedKeys={['2']}>
<Menu.Item key="1">nav 1</Menu.Item>
<Menu.Item key="2">nav 2</Menu.Item>
<Menu.Item key="3">nav 3</Menu.Item>
</Menu> */}
</Header>
<Content style={{ padding: '0 50px' }}>
<div className="site-layout-content">
<p> <p>
<b>Status: {broadcastActive ? 'on' : 'off'}</b> <b>Status: {broadcastActive ? 'on' : 'off'}</b>
</p> </p>
@@ -38,6 +52,14 @@ export default function HomeView(props) {
<br /> <br />
{broadcastDetails} {broadcastDetails}
</div> </div>
</Content>
<Footer style={{ textAlign: 'center' }}><a href="https://owncast.online/">About Owncast</a></Footer>
</Layout>
); );
} }