From 112cc3af14e596628f1d1f4deefcf58ac59645c8 Mon Sep 17 00:00:00 2001 From: gingervitis Date: Mon, 2 Nov 2020 20:49:52 -0800 Subject: [PATCH] add a hook to track window resize so we can dynamically size charts; default highlight Home link in nav; some typescript fixes --- web/pages/components/chart.tsx | 86 +++++++++++++++------------- web/pages/components/main-layout.tsx | 8 +-- web/pages/viewer-info.tsx | 7 +-- web/styles/globals.scss | 9 +++ web/styles/styles.module.css | 5 +- web/utils/hook-windowresize.tsx | 32 +++++++++++ 6 files changed, 96 insertions(+), 51 deletions(-) create mode 100644 web/utils/hook-windowresize.tsx diff --git a/web/pages/components/chart.tsx b/web/pages/components/chart.tsx index 67dcd0380..080e722a4 100644 --- a/web/pages/components/chart.tsx +++ b/web/pages/components/chart.tsx @@ -1,5 +1,7 @@ import { LineChart, XAxis, YAxis, Line, Tooltip, Legend } from "recharts"; import { timeFormat } from "d3-time-format"; +import useWindowSize from '../../utils/hook-windowresize'; +import styles from '../../styles/styles.module.css'; interface ToolTipProps { active?: boolean, @@ -10,20 +12,18 @@ interface ToolTipProps { const defaultProps = { active: false, payload: Object, - unit: "", + unit: '', }; interface TimedValue { time: Date; - value: Number; + value: number; } interface ChartProps { - // eslint-disable-next-line react/require-default-props data?: TimedValue[], color: string, unit: string, - // eslint-disable-next-line react/require-default-props dataCollections?: any[], } @@ -47,61 +47,67 @@ export default function Chart({ data, color, unit, dataCollections }: ChartProps if (!data && !dataCollections) { return null; } + + const windowSize = useWindowSize(); + const chartWidth = windowSize.width * .68; + const chartHeight = chartWidth * .333; const timeFormatter = (tick: string) => { return timeFormat("%I:%M")(new Date(tick)); }; - let ticks + let ticks = []; if (dataCollections.length > 0) { - ticks = dataCollections[0].data?.map(function (collection) { + ticks = dataCollections[0].data?.map((collection) => { return collection?.time; }) } else if (data?.length > 0){ - ticks = data?.map(function (item) { + ticks = data?.map(item => { return item?.time; }); } return ( - - - - } /> - - - {dataCollections?.map((s) => ( - + + + + } /> + + - ))} - + {dataCollections?.map((s) => ( + + ))} + + ); } diff --git a/web/pages/components/main-layout.tsx b/web/pages/components/main-layout.tsx index 400007718..b8bf3e31d 100644 --- a/web/pages/components/main-layout.tsx +++ b/web/pages/components/main-layout.tsx @@ -13,7 +13,7 @@ import { MinusSquareFilled, } from '@ant-design/icons'; import classNames from 'classnames'; -import {parseSecondsToDurationString} from '../../utils/format' +import { parseSecondsToDurationString } from '../../utils/format' import OwncastLogo from './logo'; import { BroadcastStatusContext } from '../../utils/broadcast-status-context'; @@ -24,7 +24,7 @@ export default function MainLayout(props) { const { children } = props; const context = useContext(BroadcastStatusContext); - const { broadcastActive } = context || {}; + const { broadcastActive, broadcaster } = context || {}; const router = useRouter(); const { route } = router || {}; @@ -33,7 +33,7 @@ export default function MainLayout(props) { const { SubMenu } = Menu; const streamDurationString = broadcastActive ? - parseSecondsToDurationString(differenceInSeconds(new Date(), new Date(context.broadcaster.time))) : "" + parseSecondsToDurationString(differenceInSeconds(new Date(), new Date(broadcaster.time))) : "" const statusIcon = broadcastActive ? : ; @@ -56,7 +56,7 @@ export default function MainLayout(props) { > diff --git a/web/pages/viewer-info.tsx b/web/pages/viewer-info.tsx index a3b367c60..fb39f6af6 100644 --- a/web/pages/viewer-info.tsx +++ b/web/pages/viewer-info.tsx @@ -35,7 +35,6 @@ export default function ViewersOverTime() { try { const result = await fetchData(CONNECTED_CLIENTS); - console.log("result", result); setClients(result); } catch (error) { console.log("==== error", error); @@ -71,7 +70,6 @@ export default function ViewersOverTime() { return "no info"; } - const columns = [ { title: "User name", @@ -124,11 +122,8 @@ export default function ViewersOverTime() {
- -
- ; - +
; ); } diff --git a/web/styles/globals.scss b/web/styles/globals.scss index 00a0ff23f..7583cbbf0 100644 --- a/web/styles/globals.scss +++ b/web/styles/globals.scss @@ -23,3 +23,12 @@ a { .owncast-layout .ant-menu-dark.ant-menu-dark:not(.ant-menu-horizontal) .ant-menu-item-selected { background-color: $owncast-purple; } + +// misc system overrides +.ant-card { + border-radius: .5em; +} + +.recharts-wrapper { + font-size: 12px; +} \ No newline at end of file diff --git a/web/styles/styles.module.css b/web/styles/styles.module.css index 5c1fe19ed..07702e59c 100644 --- a/web/styles/styles.module.css +++ b/web/styles/styles.module.css @@ -67,4 +67,7 @@ color: #52c41a; } -/* //844-227-3943 */ \ No newline at end of file + +.lineChartContainer { + margin: 2em auto; +} \ No newline at end of file diff --git a/web/utils/hook-windowresize.tsx b/web/utils/hook-windowresize.tsx new file mode 100644 index 000000000..c062c2b38 --- /dev/null +++ b/web/utils/hook-windowresize.tsx @@ -0,0 +1,32 @@ +import { useState, useEffect } from 'react'; + +export default function useWindowSize() { + // Initialize state with undefined width/height so server and client renders match + // Learn more here: https://joshwcomeau.com/react/the-perils-of-rehydration/ + const [windowSize, setWindowSize] = useState({ + width: undefined, + height: undefined, + }); + + useEffect(() => { + // Handler to call on window resize + function handleResize() { + // Set window width/height to state + setWindowSize({ + width: window.innerWidth, + height: window.innerHeight, + }); + } + + // Add event listener + window.addEventListener("resize", handleResize); + + // Call handler right away so state gets updated with initial window size + handleResize(); + + // Remove event listener on cleanup + return () => window.removeEventListener("resize", handleResize); + }, []); // Empty array ensures that effect is only run on mount + + return windowSize; +}