hella cleanup - index page items; use more Row/Cols to reduce custom css layout
This commit is contained in:
@@ -42,3 +42,5 @@ There are also a variety of other local states to manage the display of error/su
|
||||
|
||||
|
||||
|
||||
segment-slider-container
|
||||
selected-value-note
|
||||
@@ -221,6 +221,19 @@ export default function EditSocialLinks() {
|
||||
disabled: !isValidUrl(modalDataState.url),
|
||||
};
|
||||
|
||||
const otherField = (
|
||||
<div className="other-field-container formfield-container">
|
||||
<div className="label-side" />
|
||||
<div className="input-side">
|
||||
<Input
|
||||
placeholder="Other platform name"
|
||||
defaultValue={modalDataState.platform}
|
||||
onChange={handleOtherNameChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="social-links-edit-container">
|
||||
<Title level={3} className="section-title">
|
||||
@@ -249,30 +262,23 @@ export default function EditSocialLinks() {
|
||||
confirmLoading={modalProcessing}
|
||||
okButtonProps={okButtonProps}
|
||||
>
|
||||
<SocialDropdown
|
||||
iconList={availableIconsList}
|
||||
selectedOption={selectedOther ? OTHER_SOCIAL_HANDLE_OPTION : modalDataState.platform}
|
||||
onSelected={handleDropdownSelect}
|
||||
/>
|
||||
{displayOther ? (
|
||||
<>
|
||||
<Input
|
||||
placeholder="Other"
|
||||
defaultValue={modalDataState.platform}
|
||||
onChange={handleOtherNameChange}
|
||||
/>
|
||||
<br />
|
||||
</>
|
||||
) : null}
|
||||
<br />
|
||||
<TextField
|
||||
fieldName="social-url"
|
||||
label="URL"
|
||||
placeholder={PLACEHOLDERS[modalDataState.platform] || 'Url to page'}
|
||||
value={modalDataState.url}
|
||||
onChange={handleUrlChange}
|
||||
/>
|
||||
<FormStatusIndicator status={submitStatus} />
|
||||
<div className="social-handle-modal-content">
|
||||
<SocialDropdown
|
||||
iconList={availableIconsList}
|
||||
selectedOption={selectedOther ? OTHER_SOCIAL_HANDLE_OPTION : modalDataState.platform}
|
||||
onSelected={handleDropdownSelect}
|
||||
/>
|
||||
{displayOther && otherField}
|
||||
<br />
|
||||
<TextField
|
||||
fieldName="social-url"
|
||||
label="URL"
|
||||
placeholder={PLACEHOLDERS[modalDataState.platform] || 'Url to page'}
|
||||
value={modalDataState.url}
|
||||
onChange={handleUrlChange}
|
||||
/>
|
||||
<FormStatusIndicator status={submitStatus} />
|
||||
</div>
|
||||
</Modal>
|
||||
<br />
|
||||
<Button
|
||||
|
||||
@@ -23,39 +23,41 @@ export default function SocialDropdown({ iconList, selectedOption, onSelected }:
|
||||
If you are looking for a platform name not on this list, please select Other and type in
|
||||
your own name. A logo will not be provided.
|
||||
</p>
|
||||
<p className="description">
|
||||
If you DO have a logo, drop it in to the <code>/webroot/img/platformicons</code> directory
|
||||
and update the <code>/socialHandle.go</code> list. Then restart the server and it will show
|
||||
up in the list.
|
||||
</p>
|
||||
|
||||
<Select
|
||||
style={{ width: 240 }}
|
||||
className="social-dropdown"
|
||||
placeholder="Social platform..."
|
||||
defaultValue={inititalSelected}
|
||||
value={inititalSelected}
|
||||
onSelect={handleSelected}
|
||||
>
|
||||
{iconList.map(item => {
|
||||
const { platform, icon, key } = item;
|
||||
return (
|
||||
<Select.Option className="social-option" key={`platform-${key}`} value={key}>
|
||||
<span className="option-icon">
|
||||
<img src={`${NEXT_PUBLIC_API_HOST}${icon}`} alt="" className="option-icon" />
|
||||
</span>
|
||||
<span className="option-label">{platform}</span>
|
||||
<div className="formfield-container">
|
||||
<div className="label-side">
|
||||
<span className="formfield-label">Social Platform</span>
|
||||
</div>
|
||||
<div className="input-side">
|
||||
<Select
|
||||
style={{ width: 240 }}
|
||||
className="social-dropdown"
|
||||
placeholder="Social platform..."
|
||||
defaultValue={inititalSelected}
|
||||
value={inititalSelected}
|
||||
onSelect={handleSelected}
|
||||
>
|
||||
{iconList.map(item => {
|
||||
const { platform, icon, key } = item;
|
||||
return (
|
||||
<Select.Option className="social-option" key={`platform-${key}`} value={key}>
|
||||
<span className="option-icon">
|
||||
<img src={`${NEXT_PUBLIC_API_HOST}${icon}`} alt="" className="option-icon" />
|
||||
</span>
|
||||
<span className="option-label">{platform}</span>
|
||||
</Select.Option>
|
||||
);
|
||||
})}
|
||||
<Select.Option
|
||||
className="social-option"
|
||||
key={`platform-${OTHER_SOCIAL_HANDLE_OPTION}`}
|
||||
value={OTHER_SOCIAL_HANDLE_OPTION}
|
||||
>
|
||||
Other...
|
||||
</Select.Option>
|
||||
);
|
||||
})}
|
||||
<Select.Option
|
||||
className="social-option"
|
||||
key={`platform-${OTHER_SOCIAL_HANDLE_OPTION}`}
|
||||
value={OTHER_SOCIAL_HANDLE_OPTION}
|
||||
>
|
||||
Other...
|
||||
</Select.Option>
|
||||
</Select>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ export default function VideoVariantForm({
|
||||
</p>
|
||||
|
||||
<Row gutter={16}>
|
||||
<Col xs={12} xl={12}>
|
||||
<Col sm={24} md={12}>
|
||||
{/* ENCODER PRESET FIELD */}
|
||||
<div className="form-module cpu-usage-container">
|
||||
<CPUUsageSelector
|
||||
@@ -177,7 +177,7 @@ export default function VideoVariantForm({
|
||||
</div>
|
||||
</Col>
|
||||
|
||||
<Col xs={12} xl={12}>
|
||||
<Col sm={24} md={12}>
|
||||
{/* VIDEO BITRATE FIELD */}
|
||||
<div
|
||||
className={`form-module bitrate-container ${
|
||||
|
||||
@@ -75,7 +75,7 @@ export default function LogTable({ logs, pageSize }: Props) {
|
||||
|
||||
return (
|
||||
<div className="logs-section">
|
||||
<Title level={2}>Logs</Title>
|
||||
<Title>Logs</Title>
|
||||
<Table
|
||||
size="middle"
|
||||
dataSource={logs}
|
||||
|
||||
@@ -194,7 +194,7 @@ export default function MainLayout(props) {
|
||||
<TextFieldWithSubmit
|
||||
fieldName="streamTitle"
|
||||
{...TEXTFIELD_PROPS_STREAM_TITLE}
|
||||
placeholder="What you're streaming right now"
|
||||
placeholder="What are you streaming now"
|
||||
value={currentStreamTitle}
|
||||
initialValue={instanceDetails.streamTitle}
|
||||
onChange={handleStreamTitleChanged}
|
||||
|
||||
@@ -202,7 +202,7 @@ export default function Chat() {
|
||||
|
||||
return (
|
||||
<div className="chat-messages">
|
||||
<Title level={2}>Chat Messages</Title>
|
||||
<Title>Chat Messages</Title>
|
||||
<p>Manage the messages from viewers that show up on your stream.</p>
|
||||
<div className={bulkDivClasses}>
|
||||
<span className="label">Check multiple messages to change their visibility to: </span>
|
||||
|
||||
@@ -16,13 +16,13 @@ export default function ConfigVideoSettings() {
|
||||
how it impacts your stream performance.
|
||||
</p>
|
||||
|
||||
<Row gutter={16}>
|
||||
<Col xl={12}>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col md={24} lg={12}>
|
||||
<div className="form-module variants-table-module">
|
||||
<VideoVariantsTable />
|
||||
</div>
|
||||
</Col>
|
||||
<Col xl={12}>
|
||||
<Col md={24} lg={12}>
|
||||
<div className="form-module latency-module">
|
||||
<VideoLatency />
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { BulbOutlined, LaptopOutlined, SaveOutlined } from '@ant-design/icons';
|
||||
import { Row } from 'antd';
|
||||
import { Row, Typography } from 'antd';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { fetchData, FETCH_INTERVAL, HARDWARE_STATS } from '../utils/apis';
|
||||
import Chart from '../components/chart';
|
||||
@@ -67,6 +67,8 @@ export default function HardwareInfo() {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Typography.Title>Hardware Info</Typography.Title>
|
||||
<br />
|
||||
<div>
|
||||
<Row gutter={[16, 16]} justify="space-around">
|
||||
<StatisticItem
|
||||
|
||||
@@ -1,24 +1,13 @@
|
||||
/*
|
||||
Will display an overview with the following datasources:
|
||||
1. Current broadcaster.
|
||||
2. Viewer count.
|
||||
3. Video settings.
|
||||
|
||||
TODO: Link each overview value to the sub-page that focuses on it.
|
||||
*/
|
||||
|
||||
import React, { useState, useEffect, useContext } from 'react';
|
||||
import { Skeleton, Card, Statistic } from 'antd';
|
||||
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 StatisticItem from '../components/statistic';
|
||||
import LogTable from '../components/log-table';
|
||||
import Offline from './offline-notice';
|
||||
|
||||
import { LOGS_WARN, fetchData, FETCH_INTERVAL } from '../utils/apis';
|
||||
import { formatIPAddress, isEmptyObject } from '../utils/format';
|
||||
import { UpdateArgs } from '../types/config-section';
|
||||
|
||||
function streamDetailsFormatter(streamDetails) {
|
||||
return (
|
||||
@@ -80,31 +69,34 @@ export default function Home() {
|
||||
}
|
||||
|
||||
// map out settings
|
||||
const videoQualitySettings = serverStatusData?.currentBroadcast?.outputSettings?.map(
|
||||
(setting, index) => {
|
||||
const { audioPassthrough, videoPassthrough, audioBitrate, videoBitrate, framerate } = setting;
|
||||
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 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`;
|
||||
const videoSetting = videoPassthrough
|
||||
? `${streamDetails.videoBitrate || 'Unknown'} kbps, ${streamDetails.framerate} fps ${
|
||||
streamDetails.width
|
||||
} x ${streamDetails.height}`
|
||||
: `${videoBitrate || 'Unknown'} kbps, ${framerate} fps`;
|
||||
|
||||
let settingTitle = 'Outbound Stream Details';
|
||||
settingTitle =
|
||||
videoQualitySettings?.length > 1 ? `${settingTitle} ${index + 1}` : settingTitle;
|
||||
return (
|
||||
<Card title={settingTitle} type="inner" key={`${settingTitle}${index}`}>
|
||||
<StatisticItem title="Outbound Video Stream" value={videoSetting} prefix={null} />
|
||||
<StatisticItem title="Outbound Audio Stream" value={audioSetting} prefix={null} />
|
||||
</Card>
|
||||
);
|
||||
},
|
||||
);
|
||||
return (
|
||||
<div className="stream-details-item-container">
|
||||
<Statistic
|
||||
className="stream-details-item"
|
||||
title="Outbound Video Stream"
|
||||
value={videoSetting}
|
||||
/>
|
||||
<Statistic
|
||||
className="stream-details-item"
|
||||
title="Outbound Audio Stream"
|
||||
value={audioSetting}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
// inbound
|
||||
const { viewerCount, sessionPeakViewerCount } = serverStatusData;
|
||||
@@ -118,57 +110,60 @@ export default function Home() {
|
||||
return (
|
||||
<div className="home-container">
|
||||
<div className="sections-container">
|
||||
<div className="section online-status-section">
|
||||
<Card title="Stream is online" type="inner">
|
||||
<Statistic
|
||||
title={`Stream started ${formatRelative(broadcastDate, Date.now())}`}
|
||||
value={formatDistanceToNow(broadcastDate)}
|
||||
prefix={<ClockCircleOutlined />}
|
||||
/>
|
||||
<Statistic title="Viewers" value={viewerCount} prefix={<UserOutlined />} />
|
||||
<Statistic
|
||||
title="Peak viewer count"
|
||||
value={sessionPeakViewerCount}
|
||||
prefix={<UserOutlined />}
|
||||
/>
|
||||
<div className="online-status-section">
|
||||
<Card size="small" type="inner" className="online-details-card">
|
||||
<Row gutter={[16, 16]} align="middle">
|
||||
<Col span={8} sm={24} md={8}>
|
||||
<Statistic
|
||||
title={`Stream started ${formatRelative(broadcastDate, Date.now())}`}
|
||||
value={formatDistanceToNow(broadcastDate)}
|
||||
prefix={<ClockCircleOutlined />}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={8} sm={24} md={8}>
|
||||
<Statistic title="Viewers" value={viewerCount} prefix={<UserOutlined />} />
|
||||
</Col>
|
||||
<Col span={8} sm={24} md={8}>
|
||||
<Statistic
|
||||
title="Peak viewer count"
|
||||
value={sessionPeakViewerCount}
|
||||
prefix={<UserOutlined />}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div className="section stream-details-section">
|
||||
<div className="details outbound-details">{videoQualitySettings}</div>
|
||||
<Row gutter={[16, 16]} className="section stream-details-section">
|
||||
<Col className="outbound-details" span={12} sm={24} md={24} lg={12}>
|
||||
<Card size="small" title="Outbound Stream Details" type="inner">
|
||||
{videoQualitySettings}
|
||||
</Card>
|
||||
</Col>
|
||||
|
||||
<div className="details other-details">
|
||||
<Card title="Inbound Stream Details" type="inner">
|
||||
<StatisticItem
|
||||
<Col className="inbound-details" span={12} sm={24} md={24} lg={12}>
|
||||
<Card size="small" title="Inbound Stream Details" type="inner">
|
||||
<Statistic
|
||||
className="stream-details-item"
|
||||
title="Input"
|
||||
value={`${encoder} ${formatIPAddress(remoteAddr)}`}
|
||||
prefix={null}
|
||||
/>
|
||||
<StatisticItem
|
||||
<Statistic
|
||||
className="stream-details-item"
|
||||
title="Inbound Video Stream"
|
||||
value={streamDetails}
|
||||
formatter={streamDetailsFormatter}
|
||||
prefix={null}
|
||||
/>
|
||||
<StatisticItem
|
||||
<Statistic
|
||||
className="stream-details-item"
|
||||
title="Inbound Audio Stream"
|
||||
value={streamAudioDetailString}
|
||||
prefix={null}
|
||||
/>
|
||||
</Card>
|
||||
|
||||
<div className="server-detail">
|
||||
<Card title="Server Config" type="inner">
|
||||
<StatisticItem
|
||||
title="Directory registration enabled"
|
||||
value={configData.yp.enabled.toString()}
|
||||
prefix={null}
|
||||
/>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
<br />
|
||||
<LogTable logs={logsData} pageSize={5} />
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Link from 'next/link';
|
||||
import { Result, Card } from 'antd';
|
||||
import { Result, Card, Row, Col } from 'antd';
|
||||
import {
|
||||
MessageTwoTone,
|
||||
QuestionCircleTwoTone,
|
||||
@@ -55,22 +55,23 @@ export default function Offline({ logs = [] }) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="offline-content">
|
||||
<div className="logo-section">
|
||||
<Row gutter={[16, 16]} className="offline-content">
|
||||
<Col span={12} xs={24} sm={24} md={24} lg={12} className="logo-section">
|
||||
<Result
|
||||
icon={<OwncastLogo />}
|
||||
title="No stream is active."
|
||||
subTitle="You should start one."
|
||||
/>
|
||||
</div>
|
||||
<div className="list-section">
|
||||
</Col>
|
||||
|
||||
<Col span={12} xs={24} sm={24} md={24} lg={12} className="list-section">
|
||||
{data.map(item => (
|
||||
<Card key={item.title}>
|
||||
<Card key={item.title} size="small" bordered={false}>
|
||||
<Meta avatar={item.icon} title={item.title} description={item.content} />
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
<LogTable logs={logs} pageSize={5} />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useState, useEffect, useContext } from 'react';
|
||||
import { Table, Row } from 'antd';
|
||||
import { Table, Row, Typography } from 'antd';
|
||||
import { formatDistanceToNow } from 'date-fns';
|
||||
import { UserOutlined } from '@ant-design/icons';
|
||||
import { SortOrder } from 'antd/lib/table/interface';
|
||||
@@ -94,7 +94,9 @@ export default function ViewersOverTime() {
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<>
|
||||
<Typography.Title>Viewer Info</Typography.Title>
|
||||
<br />
|
||||
<Row gutter={[16, 16]} justify="space-around">
|
||||
{online && (
|
||||
<StatisticItem
|
||||
@@ -117,6 +119,6 @@ export default function ViewersOverTime() {
|
||||
|
||||
<Chart title="Viewers" data={viewerInfo} color="#2087E2" unit="" />
|
||||
{online && <Table dataSource={clients} columns={columns} rowKey={row => row.clientID} />}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
.ant-card,
|
||||
.ant-collapse,
|
||||
.ant-collapse-content,
|
||||
.ant-statistic,
|
||||
.ant-statistic-title,
|
||||
.ant-statistic-content,
|
||||
.ant-table,
|
||||
.ant-table-thead > tr > th,
|
||||
.ant-table-small .ant-table-thead > tr > th,
|
||||
@@ -187,12 +190,10 @@ h3.ant-typography {
|
||||
.ant-card-meta-description {
|
||||
color: var(--white-75);
|
||||
}
|
||||
.ant-card {
|
||||
.ant-statistic,
|
||||
.ant-statistic-title,
|
||||
.ant-statistic-content {
|
||||
color: var(--default-text-color);
|
||||
}
|
||||
.ant-card-type-inner .ant-card-head {
|
||||
background-color: var(--black);
|
||||
color: var(--white-88);
|
||||
border-color: var(--white-25);
|
||||
}
|
||||
|
||||
|
||||
@@ -262,7 +263,6 @@ textarea.ant-input {
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: var(--button-focused);
|
||||
border-color: var(--button-focused);
|
||||
color: var(--white);
|
||||
}
|
||||
}
|
||||
@@ -273,11 +273,16 @@ textarea.ant-input {
|
||||
.ant-btn-primary:hover,
|
||||
.ant-btn-primary:focus {
|
||||
background-color: var(--button-focused);
|
||||
border-color: var(--button-focused);
|
||||
color: var(--white);
|
||||
}
|
||||
.ant-btn.ant-btn-primary:hover {
|
||||
border-color: var(--white);
|
||||
}
|
||||
.ant-btn:focus,
|
||||
.ant-btn-primary:focus {
|
||||
border-color: var(--white);
|
||||
}
|
||||
|
||||
.ant-btn-primary[disabled] {
|
||||
background-color: var(--white-25);
|
||||
border-color: var(--white-25);
|
||||
@@ -375,9 +380,29 @@ textarea.ant-input {
|
||||
|
||||
// SELECT
|
||||
.ant-select-dropdown {
|
||||
background-color: var(--gray);
|
||||
background-color: var(--black);
|
||||
}
|
||||
.ant-select-single:not(.ant-select-customize-input) .ant-select-selector {
|
||||
background-color: var(--black);
|
||||
border-color: var(--owncast-purple-50);
|
||||
}
|
||||
.ant-select-arrow {
|
||||
color: var(--owncast-purple);
|
||||
}
|
||||
.ant-select-selection-placeholder {
|
||||
color: var(--owncast-purple-50);
|
||||
}
|
||||
.ant-select {
|
||||
color: var(--white);
|
||||
}
|
||||
.ant-select-item {
|
||||
background-color: var(--gray-dark);
|
||||
color: var(--white-88);
|
||||
}
|
||||
.ant-select-item-option-active:not(.ant-select-item-option-disabled) {
|
||||
background-color: var(--gray);
|
||||
color: var(--white-75);
|
||||
}
|
||||
|
||||
|
||||
// SLIDER
|
||||
// .ant-slider-with-marks {
|
||||
@@ -460,13 +485,12 @@ textarea.ant-input {
|
||||
|
||||
|
||||
|
||||
|
||||
// ANT TAGS
|
||||
|
||||
.ant-tag-orange {
|
||||
background: #fa8c16;
|
||||
color: #fff7e6;
|
||||
border-color: #ffd591;
|
||||
.ant-tag-red,
|
||||
.ant-tag-orange,
|
||||
.ant-tag-green,
|
||||
.ant-tag-blue {
|
||||
background-color: var(--black);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -69,4 +69,8 @@
|
||||
height: 6em !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.other-field-container {
|
||||
margin: .5em 0;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
color: rgba(255,255,255,.85);
|
||||
color: var(--white-75);
|
||||
|
||||
.option-icon {
|
||||
height: 2em;
|
||||
|
||||
@@ -1,121 +1,45 @@
|
||||
.home-container {
|
||||
max-width: 1000px;
|
||||
|
||||
.statistics-list {
|
||||
li {
|
||||
margin-left: -.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.section {
|
||||
margin: 1rem 0;
|
||||
|
||||
.ant-statistic-content {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.online-status-section {
|
||||
> .ant-card {
|
||||
box-shadow: 0px 1px 10px 2px rgba(0, 22, 40, 0.1);
|
||||
margin-bottom: 1em;
|
||||
.online-details-card {
|
||||
border-color: var(--online-color);
|
||||
}
|
||||
|
||||
.ant-card-head {
|
||||
background-color: #40b246;
|
||||
border-color: #ccc;
|
||||
color:#fff;
|
||||
@media (prefers-color-scheme: dark) {
|
||||
background-color: #2a762e;
|
||||
border-bottom-color: black;
|
||||
}
|
||||
}
|
||||
.ant-card-head-title {
|
||||
font-size: .88rem;
|
||||
.ant-statistic {
|
||||
text-align: center;
|
||||
}
|
||||
.ant-statistic-title {
|
||||
font-size: .88rem;
|
||||
}
|
||||
.ant-card-body {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
.ant-statistic {
|
||||
width: 30%;
|
||||
text-align: center;
|
||||
margin: 0 1rem;
|
||||
}
|
||||
color: var(--white-50);
|
||||
}
|
||||
}
|
||||
|
||||
.ant-card-head {
|
||||
color: var(--online-color);
|
||||
}
|
||||
|
||||
.stream-details-section {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
.details {
|
||||
width: 49%;
|
||||
|
||||
> .ant-card {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.ant-card-head {
|
||||
background-color: #ccd;
|
||||
color: black;
|
||||
@media (prefers-color-scheme: dark) {
|
||||
background-color: #000;
|
||||
color: #ccd;
|
||||
}
|
||||
|
||||
}
|
||||
.stream-details-item-container {
|
||||
margin: 1em 0;
|
||||
&:first-of-type {
|
||||
margin-top: 0;
|
||||
}
|
||||
.server-detail {
|
||||
.ant-card-body {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
|
||||
.ant-card {
|
||||
width: 45%;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.ant-card-head {
|
||||
background-color: #669;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.ant-statistic.stream-details-item {
|
||||
background-color: var(--black-50);
|
||||
padding: 1em;
|
||||
.ant-statistic-title {
|
||||
color: var(--blue);
|
||||
}
|
||||
.ant-statistic-content {
|
||||
font-size: 1.25em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 800px) {
|
||||
.online-status-section{
|
||||
.ant-card-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
.ant-statistic {
|
||||
width: auto;
|
||||
text-align: left;
|
||||
margin: 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.stream-details-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
.details {
|
||||
width: 100%;
|
||||
}
|
||||
.outbound-details,
|
||||
.inbound-details {
|
||||
>.ant-card-bordered {
|
||||
border-color: rgba(255,255,255,.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -124,14 +48,7 @@
|
||||
.offline-content {
|
||||
max-width: 1000px;
|
||||
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
.logo-section {
|
||||
width: 50%;
|
||||
.ant-result-title {
|
||||
font-size: 2rem;
|
||||
}
|
||||
@@ -144,36 +61,20 @@
|
||||
}
|
||||
}
|
||||
.list-section {
|
||||
width: 50%;
|
||||
background-color: var(--container-bg-color-alt);
|
||||
border-radius: var(--container-border-radius);
|
||||
padding: 1em;
|
||||
|
||||
> .ant-card {
|
||||
margin-bottom: 1rem;
|
||||
.ant-card-head {
|
||||
background-color: #dde;
|
||||
}
|
||||
.ant-card-head-title {
|
||||
font-size: 1rem;
|
||||
}
|
||||
background-color: var(--black);
|
||||
margin-bottom: 1em;
|
||||
.ant-card-meta-avatar {
|
||||
margin-top: .25rem;
|
||||
svg {
|
||||
height: 1.25rem;
|
||||
width: 1.25rem;
|
||||
height: 1.5em;
|
||||
width: 1.5em;
|
||||
}
|
||||
}
|
||||
.ant-card-body {
|
||||
font-size: .88rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 800px) {
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
.logo-section,
|
||||
.list-section {
|
||||
width: 100%
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.online {
|
||||
&.online {
|
||||
.online-status-indicator {
|
||||
.status-icon {
|
||||
svg {
|
||||
@@ -92,6 +92,7 @@
|
||||
}
|
||||
}
|
||||
.status-label {
|
||||
white-space: nowrap;
|
||||
color: var(--online-color);
|
||||
}
|
||||
}
|
||||
@@ -111,8 +112,21 @@
|
||||
align-items: center;
|
||||
margin-bottom: 0;
|
||||
|
||||
.ant-input-affix-wrapper {
|
||||
border-color: var(--owncast-purple-50);
|
||||
}
|
||||
input.ant-input {
|
||||
&::placeholder {
|
||||
color: var(--owncast-purple);
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.input-side {
|
||||
width: 400px;
|
||||
@media (max-width: 800px) {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.label-side {
|
||||
|
||||
Reference in New Issue
Block a user