hella cleanup - index page items; use more Row/Cols to reduce custom css layout

This commit is contained in:
gingervitis
2021-02-14 22:20:25 -08:00
parent 6d83992ff0
commit 8d5411a0d6
17 changed files with 250 additions and 297 deletions

View File

@@ -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

View File

@@ -221,6 +221,19 @@ export default function EditSocialLinks() {
disabled: !isValidUrl(modalDataState.url), 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 ( return (
<div className="social-links-edit-container"> <div className="social-links-edit-container">
<Title level={3} className="section-title"> <Title level={3} className="section-title">
@@ -249,30 +262,23 @@ export default function EditSocialLinks() {
confirmLoading={modalProcessing} confirmLoading={modalProcessing}
okButtonProps={okButtonProps} okButtonProps={okButtonProps}
> >
<SocialDropdown <div className="social-handle-modal-content">
iconList={availableIconsList} <SocialDropdown
selectedOption={selectedOther ? OTHER_SOCIAL_HANDLE_OPTION : modalDataState.platform} iconList={availableIconsList}
onSelected={handleDropdownSelect} selectedOption={selectedOther ? OTHER_SOCIAL_HANDLE_OPTION : modalDataState.platform}
/> onSelected={handleDropdownSelect}
{displayOther ? ( />
<> {displayOther && otherField}
<Input <br />
placeholder="Other" <TextField
defaultValue={modalDataState.platform} fieldName="social-url"
onChange={handleOtherNameChange} label="URL"
/> placeholder={PLACEHOLDERS[modalDataState.platform] || 'Url to page'}
<br /> value={modalDataState.url}
</> onChange={handleUrlChange}
) : null} />
<br /> <FormStatusIndicator status={submitStatus} />
<TextField </div>
fieldName="social-url"
label="URL"
placeholder={PLACEHOLDERS[modalDataState.platform] || 'Url to page'}
value={modalDataState.url}
onChange={handleUrlChange}
/>
<FormStatusIndicator status={submitStatus} />
</Modal> </Modal>
<br /> <br />
<Button <Button

View File

@@ -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 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. your own name. A logo will not be provided.
</p> </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 <div className="formfield-container">
style={{ width: 240 }} <div className="label-side">
className="social-dropdown" <span className="formfield-label">Social Platform</span>
placeholder="Social platform..." </div>
defaultValue={inititalSelected} <div className="input-side">
value={inititalSelected} <Select
onSelect={handleSelected} style={{ width: 240 }}
> className="social-dropdown"
{iconList.map(item => { placeholder="Social platform..."
const { platform, icon, key } = item; defaultValue={inititalSelected}
return ( value={inititalSelected}
<Select.Option className="social-option" key={`platform-${key}`} value={key}> onSelect={handleSelected}
<span className="option-icon"> >
<img src={`${NEXT_PUBLIC_API_HOST}${icon}`} alt="" className="option-icon" /> {iconList.map(item => {
</span> const { platform, icon, key } = item;
<span className="option-label">{platform}</span> 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>
); </Select>
})} </div>
<Select.Option </div>
className="social-option"
key={`platform-${OTHER_SOCIAL_HANDLE_OPTION}`}
value={OTHER_SOCIAL_HANDLE_OPTION}
>
Other...
</Select.Option>
</Select>
</div> </div>
); );
} }

View File

@@ -156,7 +156,7 @@ export default function VideoVariantForm({
</p> </p>
<Row gutter={16}> <Row gutter={16}>
<Col xs={12} xl={12}> <Col sm={24} md={12}>
{/* ENCODER PRESET FIELD */} {/* ENCODER PRESET FIELD */}
<div className="form-module cpu-usage-container"> <div className="form-module cpu-usage-container">
<CPUUsageSelector <CPUUsageSelector
@@ -177,7 +177,7 @@ export default function VideoVariantForm({
</div> </div>
</Col> </Col>
<Col xs={12} xl={12}> <Col sm={24} md={12}>
{/* VIDEO BITRATE FIELD */} {/* VIDEO BITRATE FIELD */}
<div <div
className={`form-module bitrate-container ${ className={`form-module bitrate-container ${

View File

@@ -75,7 +75,7 @@ export default function LogTable({ logs, pageSize }: Props) {
return ( return (
<div className="logs-section"> <div className="logs-section">
<Title level={2}>Logs</Title> <Title>Logs</Title>
<Table <Table
size="middle" size="middle"
dataSource={logs} dataSource={logs}

View File

@@ -194,7 +194,7 @@ export default function MainLayout(props) {
<TextFieldWithSubmit <TextFieldWithSubmit
fieldName="streamTitle" fieldName="streamTitle"
{...TEXTFIELD_PROPS_STREAM_TITLE} {...TEXTFIELD_PROPS_STREAM_TITLE}
placeholder="What you're streaming right now" placeholder="What are you streaming now"
value={currentStreamTitle} value={currentStreamTitle}
initialValue={instanceDetails.streamTitle} initialValue={instanceDetails.streamTitle}
onChange={handleStreamTitleChanged} onChange={handleStreamTitleChanged}

View File

@@ -202,7 +202,7 @@ export default function Chat() {
return ( return (
<div className="chat-messages"> <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> <p>Manage the messages from viewers that show up on your stream.</p>
<div className={bulkDivClasses}> <div className={bulkDivClasses}>
<span className="label">Check multiple messages to change their visibility to: </span> <span className="label">Check multiple messages to change their visibility to: </span>

View File

@@ -16,13 +16,13 @@ export default function ConfigVideoSettings() {
how it impacts your stream performance. how it impacts your stream performance.
</p> </p>
<Row gutter={16}> <Row gutter={[16, 16]}>
<Col xl={12}> <Col md={24} lg={12}>
<div className="form-module variants-table-module"> <div className="form-module variants-table-module">
<VideoVariantsTable /> <VideoVariantsTable />
</div> </div>
</Col> </Col>
<Col xl={12}> <Col md={24} lg={12}>
<div className="form-module latency-module"> <div className="form-module latency-module">
<VideoLatency /> <VideoLatency />
</div> </div>

View File

@@ -1,5 +1,5 @@
import { BulbOutlined, LaptopOutlined, SaveOutlined } from '@ant-design/icons'; import { BulbOutlined, LaptopOutlined, SaveOutlined } from '@ant-design/icons';
import { Row } from 'antd'; import { Row, Typography } from 'antd';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { fetchData, FETCH_INTERVAL, HARDWARE_STATS } from '../utils/apis'; import { fetchData, FETCH_INTERVAL, HARDWARE_STATS } from '../utils/apis';
import Chart from '../components/chart'; import Chart from '../components/chart';
@@ -67,6 +67,8 @@ export default function HardwareInfo() {
return ( return (
<div> <div>
<Typography.Title>Hardware Info</Typography.Title>
<br />
<div> <div>
<Row gutter={[16, 16]} justify="space-around"> <Row gutter={[16, 16]} justify="space-around">
<StatisticItem <StatisticItem

View File

@@ -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 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 { UserOutlined, ClockCircleOutlined } from '@ant-design/icons';
import { formatDistanceToNow, formatRelative } from 'date-fns'; import { formatDistanceToNow, formatRelative } from 'date-fns';
import { ServerStatusContext } from '../utils/server-status-context'; import { ServerStatusContext } from '../utils/server-status-context';
import StatisticItem from '../components/statistic';
import LogTable from '../components/log-table'; import LogTable from '../components/log-table';
import Offline from './offline-notice'; import Offline from './offline-notice';
import { LOGS_WARN, fetchData, FETCH_INTERVAL } from '../utils/apis'; import { LOGS_WARN, fetchData, FETCH_INTERVAL } from '../utils/apis';
import { formatIPAddress, isEmptyObject } from '../utils/format'; import { formatIPAddress, isEmptyObject } from '../utils/format';
import { UpdateArgs } from '../types/config-section';
function streamDetailsFormatter(streamDetails) { function streamDetailsFormatter(streamDetails) {
return ( return (
@@ -80,31 +69,34 @@ export default function Home() {
} }
// map out settings // map out settings
const videoQualitySettings = serverStatusData?.currentBroadcast?.outputSettings?.map( const videoQualitySettings = serverStatusData?.currentBroadcast?.outputSettings?.map(setting => {
(setting, index) => { const { audioPassthrough, videoPassthrough, audioBitrate, videoBitrate, framerate } = setting;
const { audioPassthrough, videoPassthrough, audioBitrate, videoBitrate, framerate } = setting;
const audioSetting = audioPassthrough const audioSetting = audioPassthrough
? `${streamDetails.audioCodec || 'Unknown'}, ${streamDetails.audioBitrate} kbps` ? `${streamDetails.audioCodec || 'Unknown'}, ${streamDetails.audioBitrate} kbps`
: `${audioBitrate || 'Unknown'} kbps`; : `${audioBitrate || 'Unknown'} kbps`;
const videoSetting = videoPassthrough const videoSetting = videoPassthrough
? `${streamDetails.videoBitrate || 'Unknown'} kbps, ${streamDetails.framerate} fps ${ ? `${streamDetails.videoBitrate || 'Unknown'} kbps, ${streamDetails.framerate} fps ${
streamDetails.width streamDetails.width
} x ${streamDetails.height}` } x ${streamDetails.height}`
: `${videoBitrate || 'Unknown'} kbps, ${framerate} fps`; : `${videoBitrate || 'Unknown'} kbps, ${framerate} fps`;
let settingTitle = 'Outbound Stream Details'; return (
settingTitle = <div className="stream-details-item-container">
videoQualitySettings?.length > 1 ? `${settingTitle} ${index + 1}` : settingTitle; <Statistic
return ( className="stream-details-item"
<Card title={settingTitle} type="inner" key={`${settingTitle}${index}`}> title="Outbound Video Stream"
<StatisticItem title="Outbound Video Stream" value={videoSetting} prefix={null} /> value={videoSetting}
<StatisticItem title="Outbound Audio Stream" value={audioSetting} prefix={null} /> />
</Card> <Statistic
); className="stream-details-item"
}, title="Outbound Audio Stream"
); value={audioSetting}
/>
</div>
);
});
// inbound // inbound
const { viewerCount, sessionPeakViewerCount } = serverStatusData; const { viewerCount, sessionPeakViewerCount } = serverStatusData;
@@ -118,57 +110,60 @@ export default function Home() {
return ( return (
<div className="home-container"> <div className="home-container">
<div className="sections-container"> <div className="sections-container">
<div className="section online-status-section"> <div className="online-status-section">
<Card title="Stream is online" type="inner"> <Card size="small" type="inner" className="online-details-card">
<Statistic <Row gutter={[16, 16]} align="middle">
title={`Stream started ${formatRelative(broadcastDate, Date.now())}`} <Col span={8} sm={24} md={8}>
value={formatDistanceToNow(broadcastDate)} <Statistic
prefix={<ClockCircleOutlined />} title={`Stream started ${formatRelative(broadcastDate, Date.now())}`}
/> value={formatDistanceToNow(broadcastDate)}
<Statistic title="Viewers" value={viewerCount} prefix={<UserOutlined />} /> prefix={<ClockCircleOutlined />}
<Statistic />
title="Peak viewer count" </Col>
value={sessionPeakViewerCount} <Col span={8} sm={24} md={8}>
prefix={<UserOutlined />} <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> </Card>
</div> </div>
<div className="section stream-details-section"> <Row gutter={[16, 16]} className="section stream-details-section">
<div className="details outbound-details">{videoQualitySettings}</div> <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"> <Col className="inbound-details" span={12} sm={24} md={24} lg={12}>
<Card title="Inbound Stream Details" type="inner"> <Card size="small" title="Inbound Stream Details" type="inner">
<StatisticItem <Statistic
className="stream-details-item"
title="Input" title="Input"
value={`${encoder} ${formatIPAddress(remoteAddr)}`} value={`${encoder} ${formatIPAddress(remoteAddr)}`}
prefix={null}
/> />
<StatisticItem <Statistic
className="stream-details-item"
title="Inbound Video Stream" title="Inbound Video Stream"
value={streamDetails} value={streamDetails}
formatter={streamDetailsFormatter} formatter={streamDetailsFormatter}
prefix={null}
/> />
<StatisticItem <Statistic
className="stream-details-item"
title="Inbound Audio Stream" title="Inbound Audio Stream"
value={streamAudioDetailString} value={streamAudioDetailString}
prefix={null}
/> />
</Card> </Card>
</Col>
<div className="server-detail"> </Row>
<Card title="Server Config" type="inner">
<StatisticItem
title="Directory registration enabled"
value={configData.yp.enabled.toString()}
prefix={null}
/>
</Card>
</div>
</div>
</div>
</div> </div>
<br />
<LogTable logs={logsData} pageSize={5} /> <LogTable logs={logsData} pageSize={5} />
</div> </div>
); );

View File

@@ -1,5 +1,5 @@
import Link from 'next/link'; import Link from 'next/link';
import { Result, Card } from 'antd'; import { Result, Card, Row, Col } from 'antd';
import { import {
MessageTwoTone, MessageTwoTone,
QuestionCircleTwoTone, QuestionCircleTwoTone,
@@ -55,22 +55,23 @@ export default function Offline({ logs = [] }) {
return ( return (
<> <>
<div className="offline-content"> <Row gutter={[16, 16]} className="offline-content">
<div className="logo-section"> <Col span={12} xs={24} sm={24} md={24} lg={12} className="logo-section">
<Result <Result
icon={<OwncastLogo />} icon={<OwncastLogo />}
title="No stream is active." title="No stream is active."
subTitle="You should start one." subTitle="You should start one."
/> />
</div> </Col>
<div className="list-section">
<Col span={12} xs={24} sm={24} md={24} lg={12} className="list-section">
{data.map(item => ( {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} /> <Meta avatar={item.icon} title={item.title} description={item.content} />
</Card> </Card>
))} ))}
</div> </Col>
</div> </Row>
<LogTable logs={logs} pageSize={5} /> <LogTable logs={logs} pageSize={5} />
</> </>
); );

View File

@@ -1,5 +1,5 @@
import React, { useState, useEffect, useContext } from 'react'; import React, { useState, useEffect, useContext } from 'react';
import { Table, Row } from 'antd'; import { Table, Row, Typography } from 'antd';
import { formatDistanceToNow } from 'date-fns'; import { formatDistanceToNow } from 'date-fns';
import { UserOutlined } from '@ant-design/icons'; import { UserOutlined } from '@ant-design/icons';
import { SortOrder } from 'antd/lib/table/interface'; import { SortOrder } from 'antd/lib/table/interface';
@@ -94,7 +94,9 @@ export default function ViewersOverTime() {
]; ];
return ( return (
<div> <>
<Typography.Title>Viewer Info</Typography.Title>
<br />
<Row gutter={[16, 16]} justify="space-around"> <Row gutter={[16, 16]} justify="space-around">
{online && ( {online && (
<StatisticItem <StatisticItem
@@ -117,6 +119,6 @@ export default function ViewersOverTime() {
<Chart title="Viewers" data={viewerInfo} color="#2087E2" unit="" /> <Chart title="Viewers" data={viewerInfo} color="#2087E2" unit="" />
{online && <Table dataSource={clients} columns={columns} rowKey={row => row.clientID} />} {online && <Table dataSource={clients} columns={columns} rowKey={row => row.clientID} />}
</div> </>
); );
} }

View File

@@ -9,6 +9,9 @@
.ant-card, .ant-card,
.ant-collapse, .ant-collapse,
.ant-collapse-content, .ant-collapse-content,
.ant-statistic,
.ant-statistic-title,
.ant-statistic-content,
.ant-table, .ant-table,
.ant-table-thead > tr > th, .ant-table-thead > tr > th,
.ant-table-small .ant-table-thead > tr > th, .ant-table-small .ant-table-thead > tr > th,
@@ -187,12 +190,10 @@ h3.ant-typography {
.ant-card-meta-description { .ant-card-meta-description {
color: var(--white-75); color: var(--white-75);
} }
.ant-card { .ant-card-type-inner .ant-card-head {
.ant-statistic, background-color: var(--black);
.ant-statistic-title, color: var(--white-88);
.ant-statistic-content { border-color: var(--white-25);
color: var(--default-text-color);
}
} }
@@ -262,7 +263,6 @@ textarea.ant-input {
&:hover, &:hover,
&:focus { &:focus {
background-color: var(--button-focused); background-color: var(--button-focused);
border-color: var(--button-focused);
color: var(--white); color: var(--white);
} }
} }
@@ -273,11 +273,16 @@ textarea.ant-input {
.ant-btn-primary:hover, .ant-btn-primary:hover,
.ant-btn-primary:focus { .ant-btn-primary:focus {
background-color: var(--button-focused); background-color: var(--button-focused);
border-color: var(--button-focused); color: var(--white);
} }
.ant-btn.ant-btn-primary:hover { .ant-btn.ant-btn-primary:hover {
border-color: var(--white); border-color: var(--white);
} }
.ant-btn:focus,
.ant-btn-primary:focus {
border-color: var(--white);
}
.ant-btn-primary[disabled] { .ant-btn-primary[disabled] {
background-color: var(--white-25); background-color: var(--white-25);
border-color: var(--white-25); border-color: var(--white-25);
@@ -375,9 +380,29 @@ textarea.ant-input {
// SELECT // SELECT
.ant-select-dropdown { .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 // SLIDER
// .ant-slider-with-marks { // .ant-slider-with-marks {
@@ -460,13 +485,12 @@ textarea.ant-input {
// ANT TAGS // ANT TAGS
.ant-tag-red,
.ant-tag-orange { .ant-tag-orange,
background: #fa8c16; .ant-tag-green,
color: #fff7e6; .ant-tag-blue {
border-color: #ffd591; background-color: var(--black);
} }

View File

@@ -69,4 +69,8 @@
height: 6em !important; height: 6em !important;
} }
} }
} }
.other-field-container {
margin: .5em 0;
}

View File

@@ -31,7 +31,7 @@
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
justify-content: flex-start; justify-content: flex-start;
color: rgba(255,255,255,.85); color: var(--white-75);
.option-icon { .option-icon {
height: 2em; height: 2em;

View File

@@ -1,121 +1,45 @@
.home-container { .home-container {
max-width: 1000px; max-width: 1000px;
.statistics-list {
li {
margin-left: -.5em;
}
}
.section {
margin: 1rem 0;
.ant-statistic-content {
font-size: 1rem;
}
}
.online-status-section { .online-status-section {
> .ant-card { margin-bottom: 1em;
box-shadow: 0px 1px 10px 2px rgba(0, 22, 40, 0.1); .online-details-card {
border-color: var(--online-color);
} }
.ant-statistic {
.ant-card-head { text-align: center;
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-title { .ant-statistic-title {
font-size: .88rem; color: var(--white-50);
}
.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;
}
} }
} }
.ant-card-head {
color: var(--online-color);
}
.stream-details-section { .stream-details-item-container {
display: flex; margin: 1em 0;
flex-direction: row; &:first-of-type {
justify-content: space-between; margin-top: 0;
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;
}
}
} }
.server-detail { }
.ant-card-body { .ant-statistic.stream-details-item {
display: flex; background-color: var(--black-50);
flex-direction: row; padding: 1em;
justify-content: space-between; .ant-statistic-title {
align-items: flex-start; color: var(--blue);
}
.ant-card { .ant-statistic-content {
width: 45%; font-size: 1.25em;
text-align: center; white-space: nowrap;
}
}
.ant-card-head {
background-color: #669;
color: #fff;
}
} }
} }
.outbound-details,
@media (max-width: 800px) { .inbound-details {
.online-status-section{ >.ant-card-bordered {
.ant-card-body { border-color: rgba(255,255,255,.1);
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%;
}
} }
} }
} }
@@ -124,14 +48,7 @@
.offline-content { .offline-content {
max-width: 1000px; max-width: 1000px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: flex-start;
width: 100%;
.logo-section { .logo-section {
width: 50%;
.ant-result-title { .ant-result-title {
font-size: 2rem; font-size: 2rem;
} }
@@ -144,36 +61,20 @@
} }
} }
.list-section { .list-section {
width: 50%; background-color: var(--container-bg-color-alt);
border-radius: var(--container-border-radius);
padding: 1em;
> .ant-card { > .ant-card {
margin-bottom: 1rem; background-color: var(--black);
.ant-card-head { margin-bottom: 1em;
background-color: #dde;
}
.ant-card-head-title {
font-size: 1rem;
}
.ant-card-meta-avatar { .ant-card-meta-avatar {
margin-top: .25rem; margin-top: .25rem;
svg { svg {
height: 1.25rem; height: 1.5em;
width: 1.25rem; 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%
}
}
} }

View File

@@ -84,7 +84,7 @@
} }
} }
} }
.online { &.online {
.online-status-indicator { .online-status-indicator {
.status-icon { .status-icon {
svg { svg {
@@ -92,6 +92,7 @@
} }
} }
.status-label { .status-label {
white-space: nowrap;
color: var(--online-color); color: var(--online-color);
} }
} }
@@ -111,8 +112,21 @@
align-items: center; align-items: center;
margin-bottom: 0; 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 { .input-side {
width: 400px; width: 400px;
@media (max-width: 800px) {
width: auto;
}
} }
.label-side { .label-side {