From 79bfa0145fd8e8451b91ed205ded2b0362c16aef Mon Sep 17 00:00:00 2001 From: Gabe Kangas Date: Tue, 19 Apr 2022 19:57:27 -0700 Subject: [PATCH] Moved admin to /admin and created blank placeholder for v2 frontend --- web/components/layouts/simple-layout.tsx | 11 ++ web/components/main-layout.tsx | 40 ++-- web/components/message-visiblity-toggle.tsx | 2 +- web/next.config.js | 1 - web/pages/_app.tsx | 20 +- web/pages/{ => admin}/access-tokens.tsx | 7 +- web/pages/{ => admin}/actions.tsx | 10 +- web/pages/admin/admin-layout.tsx | 18 ++ web/pages/{ => admin}/chat/messages.tsx | 15 +- web/pages/{ => admin}/chat/users.tsx | 10 +- web/pages/{ => admin}/config-chat.tsx | 16 +- web/pages/{ => admin}/config-federation.tsx | 16 +- web/pages/{ => admin}/config-notify.tsx | 16 +- .../{ => admin}/config-public-details.tsx | 10 +- .../{ => admin}/config-server-details.tsx | 2 +- web/pages/{ => admin}/config-social-items.tsx | 2 +- web/pages/{ => admin}/config-storage.tsx | 2 +- web/pages/{ => admin}/config-video.tsx | 6 +- web/pages/{ => admin}/federation/actions.tsx | 4 +- .../{ => admin}/federation/followers.tsx | 6 +- web/pages/{ => admin}/hardware-info.tsx | 6 +- web/pages/{ => admin}/help.tsx | 0 web/pages/admin/index.tsx | 180 ++++++++++++++++++ web/pages/{ => admin}/logs.tsx | 4 +- web/pages/{ => admin}/stream-health.tsx | 6 +- web/pages/{ => admin}/upgrade.tsx | 2 +- web/pages/{ => admin}/viewer-info.tsx | 10 +- web/pages/{ => admin}/webhooks.tsx | 4 +- web/pages/index.tsx | 178 +---------------- 29 files changed, 323 insertions(+), 281 deletions(-) create mode 100644 web/components/layouts/simple-layout.tsx rename web/pages/{ => admin}/access-tokens.tsx (98%) rename web/pages/{ => admin}/actions.tsx (96%) create mode 100644 web/pages/admin/admin-layout.tsx rename web/pages/{ => admin}/chat/messages.tsx (95%) rename web/pages/{ => admin}/chat/users.tsx (90%) rename web/pages/{ => admin}/config-chat.tsx (93%) rename web/pages/{ => admin}/config-federation.tsx (95%) rename web/pages/{ => admin}/config-notify.tsx (86%) rename web/pages/{ => admin}/config-public-details.tsx (77%) rename web/pages/{ => admin}/config-server-details.tsx (88%) rename web/pages/{ => admin}/config-social-items.tsx (78%) rename web/pages/{ => admin}/config-storage.tsx (94%) rename web/pages/{ => admin}/config-video.tsx (86%) rename web/pages/{ => admin}/federation/actions.tsx (96%) rename web/pages/{ => admin}/federation/followers.tsx (98%) rename web/pages/{ => admin}/hardware-info.tsx (94%) rename web/pages/{ => admin}/help.tsx (100%) create mode 100644 web/pages/admin/index.tsx rename web/pages/{ => admin}/logs.tsx (87%) rename web/pages/{ => admin}/stream-health.tsx (98%) rename web/pages/{ => admin}/upgrade.tsx (96%) rename web/pages/{ => admin}/viewer-info.tsx (94%) rename web/pages/{ => admin}/webhooks.tsx (98%) diff --git a/web/components/layouts/simple-layout.tsx b/web/components/layouts/simple-layout.tsx new file mode 100644 index 000000000..eafa3d947 --- /dev/null +++ b/web/components/layouts/simple-layout.tsx @@ -0,0 +1,11 @@ +import { AppProps } from 'next/app'; + +function SimpleLayout({ Component, pageProps }: AppProps) { + return ( +
+ +
+ ); +} + +export default SimpleLayout; diff --git a/web/components/main-layout.tsx b/web/components/main-layout.tsx index 73ecf463c..bebec70c3 100644 --- a/web/components/main-layout.tsx +++ b/web/components/main-layout.tsx @@ -141,11 +141,11 @@ export default function MainLayout(props) { className="menu-container" > }> - Home + Home } title="Current stream"> - Viewers + Viewers - Messages + Messages - Users + Users @@ -176,51 +176,51 @@ export default function MainLayout(props) { /> } > - Followers + Followers }> - General + General - Server Setup + Server Setup - Video + Video - Chat + Chat - Social + Social - Notifications + Notifications - S3 Storage + S3 Storage } title="Utilities"> - Hardware + Hardware - Stream Health + Stream Health - Logs + Logs - Social Actions + Social Actions {upgradeMessage} @@ -228,17 +228,17 @@ export default function MainLayout(props) { } title="Integrations"> - Webhooks + Webhooks - Access Tokens + Access Tokens - External Actions + External Actions } title="Help"> - Help + Help diff --git a/web/components/message-visiblity-toggle.tsx b/web/components/message-visiblity-toggle.tsx index 5eae3b7d9..f61323a66 100644 --- a/web/components/message-visiblity-toggle.tsx +++ b/web/components/message-visiblity-toggle.tsx @@ -9,7 +9,7 @@ import { } from '@ant-design/icons'; import { fetchData, UPDATE_CHAT_MESSGAE_VIZ } from '../utils/apis'; import { MessageType } from '../types/chat'; -import { OUTCOME_TIMEOUT } from '../pages/chat/messages'; +import { OUTCOME_TIMEOUT } from '../pages/admin/chat/messages'; import { isEmptyObject } from '../utils/format'; interface MessageToggleProps { diff --git a/web/next.config.js b/web/next.config.js index 1ed3dd98f..b0a42127e 100644 --- a/web/next.config.js +++ b/web/next.config.js @@ -1,6 +1,5 @@ const withLess = require('next-with-less'); module.exports = withLess({ - basePath: '/admin', trailingSlash: true, }); diff --git a/web/pages/_app.tsx b/web/pages/_app.tsx index ad6a37292..914bba36c 100644 --- a/web/pages/_app.tsx +++ b/web/pages/_app.tsx @@ -21,21 +21,17 @@ import '../styles/pages.scss'; import '../styles/offline-notice.scss'; import { AppProps } from 'next/app'; -import ServerStatusProvider from '../utils/server-status-context'; -import AlertMessageProvider from '../utils/alert-message-context'; +import { useRouter } from 'next/router'; -import MainLayout from '../components/main-layout'; +import AdminLayout from './admin/admin-layout'; +import SimpleLayout from '../components/layouts/simple-layout'; function App({ Component, pageProps }: AppProps) { - return ( - - - - - - - - ); + const router = useRouter(); + if (router.pathname.startsWith('/admin')) { + return ; + } + return ; } export default App; diff --git a/web/pages/access-tokens.tsx b/web/pages/admin/access-tokens.tsx similarity index 98% rename from web/pages/access-tokens.tsx rename to web/pages/admin/access-tokens.tsx index e3c143c3c..8c4d719bf 100644 --- a/web/pages/access-tokens.tsx +++ b/web/pages/admin/access-tokens.tsx @@ -16,7 +16,12 @@ import { DeleteOutlined } from '@ant-design/icons'; import format from 'date-fns/format'; -import { fetchData, ACCESS_TOKENS, DELETE_ACCESS_TOKEN, CREATE_ACCESS_TOKEN } from '../utils/apis'; +import { + fetchData, + ACCESS_TOKENS, + DELETE_ACCESS_TOKEN, + CREATE_ACCESS_TOKEN, +} from '../../utils/apis'; const { Title, Paragraph } = Typography; diff --git a/web/pages/actions.tsx b/web/pages/admin/actions.tsx similarity index 96% rename from web/pages/actions.tsx rename to web/pages/admin/actions.tsx index 28240b218..a6df1256c 100644 --- a/web/pages/actions.tsx +++ b/web/pages/admin/actions.tsx @@ -1,15 +1,15 @@ import { DeleteOutlined } from '@ant-design/icons'; import { Button, Checkbox, Input, Modal, Space, Table, Typography } from 'antd'; import React, { useContext, useEffect, useState } from 'react'; -import FormStatusIndicator from '../components/config/form-status-indicator'; +import FormStatusIndicator from '../../components/config/form-status-indicator'; import { API_EXTERNAL_ACTIONS, postConfigUpdateToAPI, RESET_TIMEOUT, -} from '../utils/config-constants'; -import { createInputStatus, STATUS_ERROR, STATUS_SUCCESS } from '../utils/input-statuses'; -import { ServerStatusContext } from '../utils/server-status-context'; -import isValidUrl, { DEFAULT_TEXTFIELD_URL_PATTERN } from '../utils/urls'; +} from '../../utils/config-constants'; +import { createInputStatus, STATUS_ERROR, STATUS_SUCCESS } from '../../utils/input-statuses'; +import { ServerStatusContext } from '../../utils/server-status-context'; +import isValidUrl, { DEFAULT_TEXTFIELD_URL_PATTERN } from '../../utils/urls'; const { Title, Paragraph } = Typography; let resetTimer = null; diff --git a/web/pages/admin/admin-layout.tsx b/web/pages/admin/admin-layout.tsx new file mode 100644 index 000000000..ec5474deb --- /dev/null +++ b/web/pages/admin/admin-layout.tsx @@ -0,0 +1,18 @@ +import { AppProps } from 'next/app'; +import ServerStatusProvider from '../../utils/server-status-context'; +import AlertMessageProvider from '../../utils/alert-message-context'; +import MainLayout from '../../components/main-layout'; + +function AdminLayout({ Component, pageProps }: AppProps) { + return ( + + + + + + + + ); +} + +export default AdminLayout; diff --git a/web/pages/chat/messages.tsx b/web/pages/admin/chat/messages.tsx similarity index 95% rename from web/pages/chat/messages.tsx rename to web/pages/admin/chat/messages.tsx index ce6cdd82c..84dd24f31 100644 --- a/web/pages/chat/messages.tsx +++ b/web/pages/admin/chat/messages.tsx @@ -5,11 +5,16 @@ import classNames from 'classnames'; import { ColumnsType } from 'antd/es/table'; import format from 'date-fns/format'; -import { CHAT_HISTORY, fetchData, FETCH_INTERVAL, UPDATE_CHAT_MESSGAE_VIZ } from '../../utils/apis'; -import { MessageType } from '../../types/chat'; -import { isEmptyObject } from '../../utils/format'; -import MessageVisiblityToggle from '../../components/message-visiblity-toggle'; -import UserPopover from '../../components/user-popover'; +import { MessageType } from '../../../types/chat'; +import { + CHAT_HISTORY, + fetchData, + FETCH_INTERVAL, + UPDATE_CHAT_MESSGAE_VIZ, +} from '../../../utils/apis'; +import { isEmptyObject } from '../../../utils/format'; +import MessageVisiblityToggle from '../../../components/message-visiblity-toggle'; +import UserPopover from '../../../components/user-popover'; const { Title } = Typography; diff --git a/web/pages/chat/users.tsx b/web/pages/admin/chat/users.tsx similarity index 90% rename from web/pages/chat/users.tsx rename to web/pages/admin/chat/users.tsx index cada2b442..4178e7538 100644 --- a/web/pages/chat/users.tsx +++ b/web/pages/admin/chat/users.tsx @@ -1,16 +1,16 @@ import React, { useState, useEffect, useContext } from 'react'; import { Tabs } from 'antd'; -import { ServerStatusContext } from '../../utils/server-status-context'; +import { ServerStatusContext } from '../../../utils/server-status-context'; import { CONNECTED_CLIENTS, fetchData, DISABLED_USERS, MODERATORS, BANNED_IPS, -} from '../../utils/apis'; -import UserTable from '../../components/user-table'; -import ClientTable from '../../components/client-table'; -import BannedIPsTable from '../../components/banned-ips-table'; +} from '../../../utils/apis'; +import UserTable from '../../../components/user-table'; +import ClientTable from '../../../components/client-table'; +import BannedIPsTable from '../../../components/banned-ips-table'; const { TabPane } = Tabs; diff --git a/web/pages/config-chat.tsx b/web/pages/admin/config-chat.tsx similarity index 93% rename from web/pages/config-chat.tsx rename to web/pages/admin/config-chat.tsx index 6b96225f9..e57762a5b 100644 --- a/web/pages/config-chat.tsx +++ b/web/pages/admin/config-chat.tsx @@ -1,17 +1,17 @@ import { Typography } from 'antd'; import React, { useContext, useEffect, useState } from 'react'; -import { TEXTFIELD_TYPE_TEXTAREA } from '../components/config/form-textfield'; -import TextFieldWithSubmit from '../components/config/form-textfield-with-submit'; -import ToggleSwitch from '../components/config/form-toggleswitch'; -import EditValueArray from '../components/config/edit-string-array'; +import { TEXTFIELD_TYPE_TEXTAREA } from '../../components/config/form-textfield'; +import TextFieldWithSubmit from '../../components/config/form-textfield-with-submit'; +import ToggleSwitch from '../../components/config/form-toggleswitch'; +import EditValueArray from '../../components/config/edit-string-array'; import { createInputStatus, StatusState, STATUS_ERROR, STATUS_SUCCESS, -} from '../utils/input-statuses'; +} from '../../utils/input-statuses'; -import { UpdateArgs } from '../types/config-section'; +import { UpdateArgs } from '../../types/config-section'; import { API_CHAT_FORBIDDEN_USERNAMES, API_CHAT_SUGGESTED_USERNAMES, @@ -23,8 +23,8 @@ import { TEXTFIELD_PROPS_CHAT_FORBIDDEN_USERNAMES, TEXTFIELD_PROPS_CHAT_SUGGESTED_USERNAMES, TEXTFIELD_PROPS_SERVER_WELCOME_MESSAGE, -} from '../utils/config-constants'; -import { ServerStatusContext } from '../utils/server-status-context'; +} from '../../utils/config-constants'; +import { ServerStatusContext } from '../../utils/server-status-context'; export default function ConfigChat() { const { Title } = Typography; diff --git a/web/pages/config-federation.tsx b/web/pages/admin/config-federation.tsx similarity index 95% rename from web/pages/config-federation.tsx rename to web/pages/admin/config-federation.tsx index be2e5aa78..a82aed00e 100644 --- a/web/pages/config-federation.tsx +++ b/web/pages/admin/config-federation.tsx @@ -6,11 +6,11 @@ import { TEXTFIELD_TYPE_TEXT, TEXTFIELD_TYPE_TEXTAREA, TEXTFIELD_TYPE_URL, -} from '../components/config/form-textfield'; -import TextFieldWithSubmit from '../components/config/form-textfield-with-submit'; -import ToggleSwitch from '../components/config/form-toggleswitch'; -import EditValueArray from '../components/config/edit-string-array'; -import { UpdateArgs } from '../types/config-section'; +} from '../../components/config/form-textfield'; +import TextFieldWithSubmit from '../../components/config/form-textfield-with-submit'; +import ToggleSwitch from '../../components/config/form-toggleswitch'; +import EditValueArray from '../../components/config/edit-string-array'; +import { UpdateArgs } from '../../types/config-section'; import { FIELD_PROPS_ENABLE_FEDERATION, TEXTFIELD_PROPS_FEDERATION_LIVE_MESSAGE, @@ -23,9 +23,9 @@ import { RESET_TIMEOUT, API_FEDERATION_BLOCKED_DOMAINS, FIELD_PROPS_FEDERATION_NSFW, -} from '../utils/config-constants'; -import { ServerStatusContext } from '../utils/server-status-context'; -import { createInputStatus, STATUS_ERROR, STATUS_SUCCESS } from '../utils/input-statuses'; +} from '../../utils/config-constants'; +import { ServerStatusContext } from '../../utils/server-status-context'; +import { createInputStatus, STATUS_ERROR, STATUS_SUCCESS } from '../../utils/input-statuses'; function FederationInfoModal({ cancelPressed, okPressed }) { return ( diff --git a/web/pages/config-notify.tsx b/web/pages/admin/config-notify.tsx similarity index 86% rename from web/pages/config-notify.tsx rename to web/pages/admin/config-notify.tsx index 3a952cf25..082a8ef31 100644 --- a/web/pages/config-notify.tsx +++ b/web/pages/admin/config-notify.tsx @@ -2,16 +2,16 @@ import { Alert, Button, Col, Row, Typography } from 'antd'; import React, { useContext, useEffect, useState } from 'react'; import Link from 'next/link'; -import Discord from '../components/config/notification/discord'; -import Browser from '../components/config/notification/browser'; -import Twitter from '../components/config/notification/twitter'; -import Federation from '../components/config/notification/federation'; +import Discord from '../../components/config/notification/discord'; +import Browser from '../../components/config/notification/browser'; +import Twitter from '../../components/config/notification/twitter'; +import Federation from '../../components/config/notification/federation'; import TextFieldWithSubmit, { TEXTFIELD_TYPE_URL, -} from '../components/config/form-textfield-with-submit'; -import { TEXTFIELD_PROPS_FEDERATION_INSTANCE_URL } from '../utils/config-constants'; -import { ServerStatusContext } from '../utils/server-status-context'; -import { UpdateArgs } from '../types/config-section'; +} from '../../components/config/form-textfield-with-submit'; +import { TEXTFIELD_PROPS_FEDERATION_INSTANCE_URL } from '../../utils/config-constants'; +import { ServerStatusContext } from '../../utils/server-status-context'; +import { UpdateArgs } from '../../types/config-section'; import isValidUrl from '../utils/urls'; const { Title } = Typography; diff --git a/web/pages/config-public-details.tsx b/web/pages/admin/config-public-details.tsx similarity index 77% rename from web/pages/config-public-details.tsx rename to web/pages/admin/config-public-details.tsx index 438aee8e8..374650821 100644 --- a/web/pages/config-public-details.tsx +++ b/web/pages/admin/config-public-details.tsx @@ -1,11 +1,11 @@ import React from 'react'; import { Typography } from 'antd'; -import EditInstanceDetails from '../components/config/edit-instance-details'; -import EditInstanceTags from '../components/config/edit-tags'; -import EditSocialLinks from '../components/config/edit-social-links'; -import EditPageContent from '../components/config/edit-page-content'; -import EditCustomStyles from '../components/config/edit-custom-css'; +import EditInstanceDetails from '../../components/config/edit-instance-details'; +import EditInstanceTags from '../../components/config/edit-tags'; +import EditSocialLinks from '../../components/config/edit-social-links'; +import EditPageContent from '../../components/config/edit-page-content'; +import EditCustomStyles from '../../components/config/edit-custom-css'; const { Title } = Typography; diff --git a/web/pages/config-server-details.tsx b/web/pages/admin/config-server-details.tsx similarity index 88% rename from web/pages/config-server-details.tsx rename to web/pages/admin/config-server-details.tsx index 6333c7292..0d1f9df5b 100644 --- a/web/pages/config-server-details.tsx +++ b/web/pages/admin/config-server-details.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Typography } from 'antd'; -import EditServerDetails from '../components/config/edit-server-details'; +import EditServerDetails from '../../components/config/edit-server-details'; const { Title } = Typography; diff --git a/web/pages/config-social-items.tsx b/web/pages/admin/config-social-items.tsx similarity index 78% rename from web/pages/config-social-items.tsx rename to web/pages/admin/config-social-items.tsx index 12dd692ff..94d2614c2 100644 --- a/web/pages/config-social-items.tsx +++ b/web/pages/admin/config-social-items.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Typography } from 'antd'; -import EditSocialLinks from '../components/config/edit-social-links'; +import EditSocialLinks from '../../components/config/edit-social-links'; const { Title } = Typography; diff --git a/web/pages/config-storage.tsx b/web/pages/admin/config-storage.tsx similarity index 94% rename from web/pages/config-storage.tsx rename to web/pages/admin/config-storage.tsx index 4773627a4..432a2a272 100644 --- a/web/pages/config-storage.tsx +++ b/web/pages/admin/config-storage.tsx @@ -1,6 +1,6 @@ import { Typography } from 'antd'; import React from 'react'; -import EditStorage from '../components/config/edit-storage'; +import EditStorage from '../../components/config/edit-storage'; const { Title } = Typography; diff --git a/web/pages/config-video.tsx b/web/pages/admin/config-video.tsx similarity index 86% rename from web/pages/config-video.tsx rename to web/pages/admin/config-video.tsx index 770b9955b..b22fbd4cb 100644 --- a/web/pages/config-video.tsx +++ b/web/pages/admin/config-video.tsx @@ -1,8 +1,8 @@ import { Col, Collapse, Row, Typography } from 'antd'; import React from 'react'; -import VideoCodecSelector from '../components/config/video-codec-selector'; -import VideoLatency from '../components/config/video-latency'; -import VideoVariantsTable from '../components/config/video-variants-table'; +import VideoCodecSelector from '../../components/config/video-codec-selector'; +import VideoLatency from '../../components/config/video-latency'; +import VideoVariantsTable from '../../components/config/video-variants-table'; const { Panel } = Collapse; const { Title } = Typography; diff --git a/web/pages/federation/actions.tsx b/web/pages/admin/federation/actions.tsx similarity index 96% rename from web/pages/federation/actions.tsx rename to web/pages/admin/federation/actions.tsx index d67a5ea6e..e11470fbb 100644 --- a/web/pages/federation/actions.tsx +++ b/web/pages/admin/federation/actions.tsx @@ -2,9 +2,9 @@ import React, { useEffect, useState } from 'react'; import { Table, Typography } from 'antd'; import { ColumnsType } from 'antd/lib/table/interface'; import format from 'date-fns/format'; -import { FEDERATION_ACTIONS, fetchData } from '../../utils/apis'; +import { FEDERATION_ACTIONS, fetchData } from '../../../utils/apis'; -import { isEmptyObject } from '../../utils/format'; +import { isEmptyObject } from '../../../utils/format'; const { Title, Paragraph } = Typography; diff --git a/web/pages/federation/followers.tsx b/web/pages/admin/federation/followers.tsx similarity index 98% rename from web/pages/federation/followers.tsx rename to web/pages/admin/federation/followers.tsx index c86bcefdb..b10863ff4 100644 --- a/web/pages/federation/followers.tsx +++ b/web/pages/admin/federation/followers.tsx @@ -3,15 +3,15 @@ import { Table, Avatar, Button, Tabs } from 'antd'; import { ColumnsType, SortOrder } from 'antd/lib/table/interface'; import format from 'date-fns/format'; import { UserAddOutlined, UserDeleteOutlined } from '@ant-design/icons'; -import { ServerStatusContext } from '../../utils/server-status-context'; +import { ServerStatusContext } from '../../../utils/server-status-context'; import { FOLLOWERS, FOLLOWERS_PENDING, SET_FOLLOWER_APPROVAL, FOLLOWERS_BLOCKED, fetchData, -} from '../../utils/apis'; -import { isEmptyObject } from '../../utils/format'; +} from '../../../utils/apis'; +import { isEmptyObject } from '../../../utils/format'; const { TabPane } = Tabs; export interface Follower { diff --git a/web/pages/hardware-info.tsx b/web/pages/admin/hardware-info.tsx similarity index 94% rename from web/pages/hardware-info.tsx rename to web/pages/admin/hardware-info.tsx index 0e3a01d84..c048ce39e 100644 --- a/web/pages/hardware-info.tsx +++ b/web/pages/admin/hardware-info.tsx @@ -1,9 +1,9 @@ import { BulbOutlined, LaptopOutlined, SaveOutlined } from '@ant-design/icons'; import { Row, Col, Typography } from 'antd'; import React, { useEffect, useState } from 'react'; -import { fetchData, FETCH_INTERVAL, HARDWARE_STATS } from '../utils/apis'; -import Chart from '../components/chart'; -import StatisticItem from '../components/statistic'; +import { fetchData, FETCH_INTERVAL, HARDWARE_STATS } from '../../utils/apis'; +import Chart from '../../components/chart'; +import StatisticItem from '../../components/statistic'; // TODO: FIX TS WARNING FROM THIS. // interface TimedValue { diff --git a/web/pages/help.tsx b/web/pages/admin/help.tsx similarity index 100% rename from web/pages/help.tsx rename to web/pages/admin/help.tsx diff --git a/web/pages/admin/index.tsx b/web/pages/admin/index.tsx new file mode 100644 index 000000000..d9dcc5b69 --- /dev/null +++ b/web/pages/admin/index.tsx @@ -0,0 +1,180 @@ +import React, { useState, useEffect, useContext } from 'react'; +import { Skeleton, Card, Statistic, Row, Col } from 'antd'; +import { UserOutlined, ClockCircleOutlined } from '@ant-design/icons'; +import { formatDistanceToNow, formatRelative } from 'date-fns'; +import { ServerStatusContext } from '../../utils/server-status-context'; +import LogTable from '../../components/log-table'; +import Offline from '../../components/offline-notice'; +import StreamHealthOverview from '../../components/stream-health-overview'; + +import { LOGS_WARN, fetchData, FETCH_INTERVAL } from '../../utils/apis'; +import { formatIPAddress, isEmptyObject } from '../../utils/format'; +import NewsFeed from '../../components/news-feed'; + +function streamDetailsFormatter(streamDetails) { + return ( +
    +
  • + {streamDetails.videoCodec || 'Unknown'} @ {streamDetails.videoBitrate || 'Unknown'} kbps +
  • +
  • {streamDetails.framerate || 'Unknown'} fps
  • +
  • + {streamDetails.width} x {streamDetails.height} +
  • +
+ ); +} + +export default function Home() { + const serverStatusData = useContext(ServerStatusContext); + const { broadcaster, serverConfig: configData } = serverStatusData || {}; + const { remoteAddr, streamDetails } = broadcaster || {}; + + const encoder = streamDetails?.encoder || 'Unknown encoder'; + + const [logsData, setLogs] = useState([]); + const getLogs = async () => { + try { + const result = await fetchData(LOGS_WARN); + setLogs(result); + } catch (error) { + console.log('==== error', error); + } + }; + const getMoreStats = () => { + getLogs(); + }; + + useEffect(() => { + getMoreStats(); + + let intervalId = null; + intervalId = setInterval(getMoreStats, FETCH_INTERVAL); + + return () => { + clearInterval(intervalId); + }; + }, []); + + if (isEmptyObject(configData) || isEmptyObject(serverStatusData)) { + return ( + <> + + + + + ); + } + + if (!broadcaster) { + return ; + } + + // map out settings + const videoQualitySettings = serverStatusData?.currentBroadcast?.outputSettings?.map(setting => { + const { audioPassthrough, videoPassthrough, audioBitrate, videoBitrate, framerate } = setting; + + const audioSetting = audioPassthrough + ? `${streamDetails.audioCodec || 'Unknown'}, ${streamDetails.audioBitrate} kbps` + : `${audioBitrate || 'Unknown'} kbps`; + + const videoSetting = videoPassthrough + ? `${streamDetails.videoBitrate || 'Unknown'} kbps, ${streamDetails.framerate} fps ${ + streamDetails.width + } x ${streamDetails.height}` + : `${videoBitrate || 'Unknown'} kbps, ${framerate} fps`; + + return ( +
+ + +
+ ); + }); + + // inbound + const { viewerCount, sessionPeakViewerCount } = serverStatusData; + + const streamAudioDetailString = `${streamDetails.audioCodec}, ${ + streamDetails.audioBitrate || 'Unknown' + } kbps`; + + const broadcastDate = new Date(broadcaster.time); + + return ( +
+
+
+ + + + } + /> + + + } /> + + + } + /> + + + + +
+ + + + + {videoQualitySettings} + + + + + + + + + + + + + +
+
+ +
+ ); +} diff --git a/web/pages/logs.tsx b/web/pages/admin/logs.tsx similarity index 87% rename from web/pages/logs.tsx rename to web/pages/admin/logs.tsx index ce15c6bee..084a33137 100644 --- a/web/pages/logs.tsx +++ b/web/pages/admin/logs.tsx @@ -1,7 +1,7 @@ import React, { useState, useEffect } from 'react'; -import LogTable from '../components/log-table'; +import LogTable from '../../components/log-table'; -import { LOGS_ALL, fetchData } from '../utils/apis'; +import { LOGS_ALL, fetchData } from '../../utils/apis'; const FETCH_INTERVAL = 5 * 1000; // 5 sec diff --git a/web/pages/stream-health.tsx b/web/pages/admin/stream-health.tsx similarity index 98% rename from web/pages/stream-health.tsx rename to web/pages/admin/stream-health.tsx index 2c0972591..437fae0b0 100644 --- a/web/pages/stream-health.tsx +++ b/web/pages/admin/stream-health.tsx @@ -3,9 +3,9 @@ import { Row, Col, Typography, Space, Statistic, Card, Alert, Spin } from 'antd'; import React, { ReactNode, useEffect, useState } from 'react'; import { ClockCircleOutlined, WarningOutlined, WifiOutlined } from '@ant-design/icons'; -import { fetchData, FETCH_INTERVAL, API_STREAM_HEALTH_METRICS } from '../utils/apis'; -import Chart from '../components/chart'; -import StreamHealthOverview from '../components/stream-health-overview'; +import { fetchData, FETCH_INTERVAL, API_STREAM_HEALTH_METRICS } from '../../utils/apis'; +import Chart from '../../components/chart'; +import StreamHealthOverview from '../../components/stream-health-overview'; interface TimedValue { time: Date; diff --git a/web/pages/upgrade.tsx b/web/pages/admin/upgrade.tsx similarity index 96% rename from web/pages/upgrade.tsx rename to web/pages/admin/upgrade.tsx index c19326c9c..fa38c218c 100644 --- a/web/pages/upgrade.tsx +++ b/web/pages/admin/upgrade.tsx @@ -1,7 +1,7 @@ import React, { useState, useEffect } from 'react'; import ReactMarkdown from 'react-markdown'; import { Table, Typography } from 'antd'; -import { getGithubRelease } from '../utils/apis'; +import { getGithubRelease } from '../../utils/apis'; const { Title } = Typography; diff --git a/web/pages/viewer-info.tsx b/web/pages/admin/viewer-info.tsx similarity index 94% rename from web/pages/viewer-info.tsx rename to web/pages/admin/viewer-info.tsx index 952cff12e..24a905d8b 100644 --- a/web/pages/viewer-info.tsx +++ b/web/pages/admin/viewer-info.tsx @@ -2,13 +2,13 @@ import React, { useState, useEffect, useContext } from 'react'; import { Row, Col, Typography, Menu, Dropdown, Spin, Alert } from 'antd'; import { DownOutlined, UserOutlined } from '@ant-design/icons'; import { getUnixTime, sub } from 'date-fns'; -import Chart from '../components/chart'; -import StatisticItem from '../components/statistic'; -import ViewerTable from '../components/viewer-table'; +import Chart from '../../components/chart'; +import StatisticItem from '../../components/statistic'; +import ViewerTable from '../../components/viewer-table'; -import { ServerStatusContext } from '../utils/server-status-context'; +import { ServerStatusContext } from '../../utils/server-status-context'; -import { VIEWERS_OVER_TIME, ACTIVE_VIEWER_DETAILS, fetchData } from '../utils/apis'; +import { VIEWERS_OVER_TIME, ACTIVE_VIEWER_DETAILS, fetchData } from '../../utils/apis'; const FETCH_INTERVAL = 60 * 1000; // 1 min diff --git a/web/pages/webhooks.tsx b/web/pages/admin/webhooks.tsx similarity index 98% rename from web/pages/webhooks.tsx rename to web/pages/admin/webhooks.tsx index 48ebf8568..3db7ef67d 100644 --- a/web/pages/webhooks.tsx +++ b/web/pages/admin/webhooks.tsx @@ -14,8 +14,8 @@ import { Typography, } from 'antd'; import React, { useEffect, useState } from 'react'; -import { CREATE_WEBHOOK, DELETE_WEBHOOK, fetchData, WEBHOOKS } from '../utils/apis'; -import isValidUrl, { DEFAULT_TEXTFIELD_URL_PATTERN } from '../utils/urls'; +import { CREATE_WEBHOOK, DELETE_WEBHOOK, fetchData, WEBHOOKS } from '../../utils/apis'; +import isValidUrl, { DEFAULT_TEXTFIELD_URL_PATTERN } from '../../utils/urls'; const { Title, Paragraph } = Typography; diff --git a/web/pages/index.tsx b/web/pages/index.tsx index 36014bf14..531382b4e 100644 --- a/web/pages/index.tsx +++ b/web/pages/index.tsx @@ -1,180 +1,8 @@ -import React, { useState, useEffect, useContext } from 'react'; -import { Skeleton, Card, Statistic, Row, Col } from 'antd'; -import { UserOutlined, ClockCircleOutlined } from '@ant-design/icons'; -import { formatDistanceToNow, formatRelative } from 'date-fns'; -import { ServerStatusContext } from '../utils/server-status-context'; -import LogTable from '../components/log-table'; -import Offline from '../components/offline-notice'; -import StreamHealthOverview from '../components/stream-health-overview'; - -import { LOGS_WARN, fetchData, FETCH_INTERVAL } from '../utils/apis'; -import { formatIPAddress, isEmptyObject } from '../utils/format'; -import NewsFeed from '../components/news-feed'; - -function streamDetailsFormatter(streamDetails) { - return ( -
    -
  • - {streamDetails.videoCodec || 'Unknown'} @ {streamDetails.videoBitrate || 'Unknown'} kbps -
  • -
  • {streamDetails.framerate || 'Unknown'} fps
  • -
  • - {streamDetails.width} x {streamDetails.height} -
  • -
- ); -} - export default function Home() { - const serverStatusData = useContext(ServerStatusContext); - const { broadcaster, serverConfig: configData } = serverStatusData || {}; - const { remoteAddr, streamDetails } = broadcaster || {}; - - const encoder = streamDetails?.encoder || 'Unknown encoder'; - - const [logsData, setLogs] = useState([]); - const getLogs = async () => { - try { - const result = await fetchData(LOGS_WARN); - setLogs(result); - } catch (error) { - console.log('==== error', error); - } - }; - const getMoreStats = () => { - getLogs(); - }; - - useEffect(() => { - getMoreStats(); - - let intervalId = null; - intervalId = setInterval(getMoreStats, FETCH_INTERVAL); - - return () => { - clearInterval(intervalId); - }; - }, []); - - if (isEmptyObject(configData) || isEmptyObject(serverStatusData)) { - return ( - <> - - - - - ); - } - - if (!broadcaster) { - return ; - } - - // map out settings - const videoQualitySettings = serverStatusData?.currentBroadcast?.outputSettings?.map(setting => { - const { audioPassthrough, videoPassthrough, audioBitrate, videoBitrate, framerate } = setting; - - const audioSetting = audioPassthrough - ? `${streamDetails.audioCodec || 'Unknown'}, ${streamDetails.audioBitrate} kbps` - : `${audioBitrate || 'Unknown'} kbps`; - - const videoSetting = videoPassthrough - ? `${streamDetails.videoBitrate || 'Unknown'} kbps, ${streamDetails.framerate} fps ${ - streamDetails.width - } x ${streamDetails.height}` - : `${videoBitrate || 'Unknown'} kbps, ${framerate} fps`; - - return ( -
- - -
- ); - }); - - // inbound - const { viewerCount, sessionPeakViewerCount } = serverStatusData; - - const streamAudioDetailString = `${streamDetails.audioCodec}, ${ - streamDetails.audioBitrate || 'Unknown' - } kbps`; - - const broadcastDate = new Date(broadcaster.time); - return ( -
-
-
- - - - } - /> - - - } /> - - - } - /> - - - - -
- - - - - {videoQualitySettings} - - - - - - - - - - - - - -
-
- +
+ This is where v2 of the Owncast web UI will be built. Begin with the layout component + https://ant.design/components/layout/ and edit pages/index.tsx.
); }