-
-
- }
- />
- } />
- }
- />
+
+
+
+
+ }
+ />
+
+
+ } />
+
+
+ }
+ />
+
+
-
-
{videoQualitySettings}
+
+
+
+ {videoQualitySettings}
+
+
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
);
diff --git a/web/pages/offline-notice.tsx b/web/pages/offline-notice.tsx
index a5bb16ab8..28b059616 100644
--- a/web/pages/offline-notice.tsx
+++ b/web/pages/offline-notice.tsx
@@ -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 (
<>
-
-
+
+
}
title="No stream is active."
subTitle="You should start one."
/>
-
-
+
+
+
{data.map(item => (
-
+
))}
-
-
+
+
>
);
diff --git a/web/pages/upgrade.tsx b/web/pages/upgrade.tsx
index a0e7e2c32..c5a3795f2 100644
--- a/web/pages/upgrade.tsx
+++ b/web/pages/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 React, { useState, useEffect } from 'react';
+import ReactMarkdown from 'react-markdown';
+import { Table, Typography } from 'antd';
+import { getGithubRelease } from '../utils/apis';
const { Title } = Typography;
@@ -10,32 +10,29 @@ function AssetTable(assets) {
const columns = [
{
- title: "Name",
- dataIndex: "name",
- key: "name",
- render: (text, entry) =>
-
{text} ,
+ title: 'Name',
+ dataIndex: 'name',
+ key: 'name',
+ render: (text, entry) =>
{text} ,
},
{
- title: "Size",
- dataIndex: "size",
- key: "size",
- render: (text) => (`${(text/1024/1024).toFixed(2)} MB`),
+ title: 'Size',
+ dataIndex: 'size',
+ key: 'size',
+ render: text => `${(text / 1024 / 1024).toFixed(2)} MB`,
},
];
- return
+ return
;
}
-
export default function Logs() {
const [release, setRelease] = useState({
- html_url: "",
- name: "",
+ html_url: '',
+ name: '',
created_at: null,
- body: "",
+ body: '',
assets: [],
-
});
const getRelease = async () => {
@@ -43,7 +40,7 @@ export default function Logs() {
const result = await getGithubRelease();
setRelease(result);
} catch (error) {
- console.log("==== error", error);
+ console.log('==== error', error);
}
};
@@ -56,14 +53,14 @@ export default function Logs() {
}
return (
-
+
{release.name}
{new Date(release.created_at).toDateString()}
-
{release.body} Downloads
+
{release.body}
+
Downloads
);
}
-
diff --git a/web/pages/viewer-info.tsx b/web/pages/viewer-info.tsx
index 5a3ece0e5..c3db3ce40 100644
--- a/web/pages/viewer-info.tsx
+++ b/web/pages/viewer-info.tsx
@@ -1,5 +1,5 @@
import React, { useState, useEffect, useContext } from 'react';
-import { Table, Row } from 'antd';
+import { Table, Row, Col, Typography } from 'antd';
import { formatDistanceToNow } from 'date-fns';
import { UserOutlined } from '@ant-design/icons';
import { SortOrder } from 'antd/lib/table/interface';
@@ -94,28 +94,37 @@ export default function ViewersOverTime() {
];
return (
-
+ <>
+
Viewer Info
+
{online && (
+
+ }
+ />
+
+ )}
+
}
/>
- )}
- }
- />
- }
- />
+
+
+ }
+ />
+
+
{online &&
row.clientID} />}
-
+ >
);
}
diff --git a/web/pages/webhooks.tsx b/web/pages/webhooks.tsx
index a232bef90..5072f4962 100644
--- a/web/pages/webhooks.tsx
+++ b/web/pages/webhooks.tsx
@@ -1,24 +1,12 @@
import React, { useState, useEffect } from 'react';
-import {
- Table,
- Tag,
- Space,
- Button,
- Modal,
- Checkbox,
- Input,
- Typography,
- Tooltip,
- Select,
-} from 'antd';
-import { DeleteOutlined, EyeTwoTone, EyeInvisibleOutlined } from '@ant-design/icons';
+import { Table, Tag, Space, Button, Modal, Checkbox, Input, Typography, Tooltip } from 'antd';
+import { DeleteOutlined } from '@ant-design/icons';
import { isValidUrl } from '../utils/urls';
-const { Title, Paragraph, Text } = Typography;
-const { Option } = Select;
-
import { fetchData, DELETE_WEBHOOK, CREATE_WEBHOOK, WEBHOOKS } from '../utils/apis';
+const { Title, Paragraph } = Typography;
+
const availableEvents = {
CHAT: { name: 'Chat messages', description: 'When a user sends a chat message', color: 'purple' },
USER_JOINED: { name: 'User joined', description: 'When a user joins the chat', color: 'green' },
@@ -49,12 +37,19 @@ function convertEventStringToTag(eventString) {
);
}
+interface Props {
+ onCancel: () => void;
+ onOk: any; // todo: make better type
+ visible: boolean;
+}
+
+function NewWebhookModal(props: Props) {
+ const { onOk, onCancel, visible } = props;
-function NewWebhookModal(props) {
const [selectedEvents, setSelectedEvents] = useState([]);
const [webhookUrl, setWebhookUrl] = useState('');
- const events = Object.keys(availableEvents).map(function (key) {
+ const events = Object.keys(availableEvents).map(key => {
return { value: key, label: availableEvents[key].description };
});
@@ -67,7 +62,7 @@ function NewWebhookModal(props) {
}
function save() {
- props.onOk(webhookUrl, selectedEvents);
+ onOk(webhookUrl, selectedEvents);
// Reset the modal
setWebhookUrl('');
@@ -81,9 +76,9 @@ function NewWebhookModal(props) {
return (
@@ -96,9 +91,12 @@ function NewWebhookModal(props) {
Select the events that will be sent to this webhook.
-
- Select all
-
+
+
+
+ Select all
+
+
);
}
@@ -136,14 +134,19 @@ export default function Webhooks() {
},
];
- const getWebhooks = async () => {
+ function handleError(error) {
+ console.error('error', error);
+ alert(error);
+ }
+
+ async function getWebhooks() {
try {
const result = await fetchData(WEBHOOKS);
setWebhooks(result);
} catch (error) {
handleError(error);
}
- };
+ }
useEffect(() => {
getWebhooks();
@@ -151,7 +154,7 @@ export default function Webhooks() {
async function handleDelete(id) {
try {
- const result = await fetchData(DELETE_WEBHOOK, { method: 'POST', data: { id: id } });
+ await fetchData(DELETE_WEBHOOK, { method: 'POST', data: { id } });
getWebhooks();
} catch (error) {
handleError(error);
@@ -162,7 +165,7 @@ export default function Webhooks() {
try {
const newHook = await fetchData(CREATE_WEBHOOK, {
method: 'POST',
- data: { url: url, events: events },
+ data: { url, events },
});
setWebhooks(webhooks.concat(newHook));
} catch (error) {
@@ -170,11 +173,6 @@ export default function Webhooks() {
}
}
- function handleError(error) {
- console.error('error', error);
- alert(error);
- }
-
const showCreateModal = () => {
setIsModalVisible(true);
};
@@ -194,7 +192,7 @@ export default function Webhooks() {
A webhook is a callback made to an external API in response to an event that takes place
within Owncast. This can be used to build chat bots or sending automatic notifications that
- you've started streaming.
+ you've started streaming.
Read more about how to use webhooks, with examples, at{' '}
diff --git a/web/styles/ant-overrides.scss b/web/styles/ant-overrides.scss
index 52e7cbbab..5ba431166 100644
--- a/web/styles/ant-overrides.scss
+++ b/web/styles/ant-overrides.scss
@@ -1,6 +1,5 @@
// GENERAL ANT OVERRIDES
-
// RESET BG, TEXT COLORS
.ant-layout,
.ant-layout-header,
@@ -9,6 +8,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,
@@ -20,28 +22,52 @@ td.ant-table-column-sort,
.ant-menu-submenu > .ant-menu,
.ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected {
background-color: transparent;
- color: var(--default-text-color)
+ color: var(--default-text-color);
}
-
-h1.ant-typography,
-h2.ant-typography,
-h3.ant-typography,
-h4.ant-typography,
-h5.ant-typography,
+h1.ant-typography,
+h2.ant-typography,
+h3.ant-typography,
+h4.ant-typography,
+h5.ant-typography,
.ant-typography,
.ant-typography h1,
.ant-typography h2,
.ant-typography h3,
.ant-typography h4,
.ant-typography h5 {
- color: var(--default-text-color);
- font-weight: 500;
+ color: var(--white);
+ font-weight: 400;
+ margin: 0.5em 0;
+}
+.ant-typography.ant-typography-secondary {
+ color: var(--white);
+ font-weight: 400;
+}
+.ant-typography {
+ font-weight: 300;
+ color: var(--white-75);
+ a {
+ color: var(--owncast-purple);
+ }
}
-.ant-typography.ant-typography-secondary {
- color: rgba(255,255,255,.85);
- font-weight: 400;
+.ant-typography h1,
+h1.ant-typography {
+ font-size: 1.75em;
+ color: var(--pink);
+ &:first-of-type {
+ margin-top: 0;
+ }
+}
+.ant-typography h2,
+h2.ant-typography {
+ font-size: 1.5em;
+}
+
+.ant-typography h3,
+h3.ant-typography {
+ font-size: 1.25em;
}
.ant-progress-text,
@@ -49,8 +75,6 @@ h5.ant-typography,
color: var(--default-text-color);
}
-
-
// ANT MENU
// menu base
.ant-menu-item {
@@ -58,7 +82,7 @@ h5.ant-typography,
.anticon {
transition-duration: var(--ant-transition-duration);
- color: var(--nav-text);
+ color: var(--nav-text);
}
a {
@@ -66,21 +90,26 @@ h5.ant-typography,
color: var(--nav-text);
&:hover {
- color: white;
+ color: var(--white);
}
}
&:hover {
- background-color: rgba(0,0,0,.15);
-
+ background-color: var(--black-50);
+ color: var(--white);
.anticon {
- color: white;
+ color: var(--white);
}
}
}
+.ant-menu-item:active,
+.ant-menu-submenu-title:active {
+ background-color: var(--black-50);
+}
+
// menu item selected
.ant-menu-item-selected,
.ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected {
- background-color: black;
+ background-color: var(--black);
a {
color: var(--nav-selected-text);
}
@@ -96,14 +125,14 @@ h5.ant-typography,
}
// submenu items
.ant-menu-submenu {
- &> .ant-menu {
- border-left: 1px solid rgba(255,255,255,.4);
- background-color: rgba(0,0,0,.15);
+ & > .ant-menu {
+ border-left: 1px solid var(--white-50);
+ background-color: var(--black-35);
}
.ant-menu-submenu-title {
transition-duration: var(--ant-transition-duration);
color: var(--nav-text);
-
+
.anticon {
color: var(--nav-text);
}
@@ -117,30 +146,28 @@ h5.ant-typography,
}
&:hover {
.ant-menu-submenu-title {
- color: white;
+ color: var(--white);
.anticon {
- color: white;
+ color: var(--white);
}
.ant-menu-submenu-arrow {
&:before,
&:after {
- background-image: linear-gradient(to right, white, white);
+ background-image: linear-gradient(to right, var(--white), var(--white));
}
}
}
}
}
-
// ANT RESULT
.ant-result-title {
color: var(--default-text-color);
}
.ant-result-subtitle {
- color: var(--default-text-color);
+ color: var(--white-75);
}
-
// ANT CARD
.ant-card {
border-radius: var(--container-border-radius);
@@ -148,16 +175,30 @@ h5.ant-typography,
color: var(--default-text-color);
}
.ant-card-bordered {
- border-color: rgba(255,255,255,.25);
+ border-color: var(--white-25);
+}
+.ant-card-meta-title {
+ color: var(--white);
}
-.ant-card-meta-title,
.ant-card-meta-description {
- color: white;
+ color: var(--white-75);
+}
+.ant-card-type-inner .ant-card-head {
+ background-color: var(--black);
+ color: var(--white-88);
+ border-color: var(--white-25);
}
-
-
// ANT INPUT
+input.ant-input,
+textarea.ant-input {
+ background-color: var(--textfield-bg);
+ color: var(--white-88);
+ border-color: var(--black);
+ &::placeholder {
+ color: var(--owncast-purple-50);
+ }
+}
.ant-input-affix-wrapper,
.ant-input-number {
background-color: var(--textfield-bg);
@@ -165,66 +206,90 @@ h5.ant-typography,
input,
textarea {
background-color: transparent;
- color: rgba(255,255,255,.85);
- border-color: rgba(0,0,0,1);
+ color: var(--white-88);
+ border-color: var(--black);
&::placeholder {
- color: var(--textfield-border);
+ color: var(--owncast-purple-50);
}
&:-webkit-autofill {
background-color: transparent;
}
}
}
+.ant-input:hover,
.ant-input-number:hover,
.ant-input-affix-wrapper:hover {
- border-color: var(--owncast-purple-highlight);
+ border-color: var(--owncast-purple);
input,
textarea {
- border-color: var(--owncast-purple-highlight);
+ border-color: var(--owncast-purple);
}
}
+.ant-input,
.ant-input-number:focus,
-.ant-input-affix-wrapper:focus,
+.ant-input-affix-wrapper:focus,
.ant-input-affix-wrapper-focused {
border-color: var(--owncast-purple);
input,
textarea {
- color: white;
+ color: var(--white);
border-color: var(--owncast-purple);
}
}
-.ant-input-textarea-clear-icon,
-.ant-input-clear-icon {
- color: rgba(255,255,255,.5);
-}
+
textarea.ant-input {
padding-right: 25px;
}
+.ant-input-affix-wrapper {
+ color: transparent;
+}
-
-
+.ant-input-suffix,
+.ant-input-clear-icon,
+.ant-input-textarea-clear-icon,
+.ant-input-password-icon {
+ color: var(--white-50);
+ &:hover {
+ color: var(--white);
+ }
+}
// ANT BUTTON
+.ant-btn {
+ background-color: var(--owncast-purple-25);
+ border-color: var(--owncast-purple-25);
+ color: var(--white-75);
+ &:hover,
+ &:focus {
+ background-color: var(--button-focused);
+ color: var(--white);
+ }
+}
.ant-btn-primary {
background-color: var(--owncast-purple);
border-color: var(--owncast-purple);
}
-.ant-btn-primary:hover,
+.ant-btn-primary:hover,
.ant-btn-primary:focus {
- background-color: var(--form-focused);
- border-color: var(--form-focused);
+ background-color: var(--button-focused);
+ color: var(--white);
}
.ant-btn.ant-btn-primary:hover {
- border-color: white;
+ border-color: var(--white);
}
+.ant-btn:focus,
+.ant-btn-primary:focus {
+ border-color: var(--white);
+}
+
.ant-btn-primary[disabled] {
- background-color: rgba(255,255,255,.2);
- border-color: rgba(255,255,255,.2);
- color: white;
+ background-color: var(--white-25);
+ border-color: var(--white-25);
+ color: var(--white-50);
&:hover {
- background-color: rgba(255,255,255,.2);
- border-color: rgba(255,255,255,.2);
+ background-color: var(--white-35);
+ border-color: var(--white-35);
}
}
.ant-input-affix-wrapper,
@@ -233,30 +298,31 @@ textarea.ant-input {
transition-duration: 0.15s;
}
-// ANT TABLE
+// ANT TABLE
.ant-table-thead > tr > th,
.ant-table-small .ant-table-thead > tr > th {
transition-duration: var(--ant-transition-duration);
- background-color: #112;
+ background-color: var(--purple-dark);
font-weight: 500;
- color: var(--owncast-purple);
+ color: var(--white);
}
.ant-table-tbody > tr > td,
.ant-table-thead > tr > th,
.ant-table-small .ant-table-thead > tr > th {
- border-color: var(--textfield-border);
+ border-color: var(--white-15);
}
.ant-table-tbody > tr > td {
transition-duration: var(--ant-transition-duration);
- background-color: var(--textfield-bg);
+ background-color: #222325;
+ color: var(--white-75);
}
-.ant-table-tbody > tr:nth-child(odd) > td {
- background-color: var(--textfield-bg);
+.ant-table-tbody > tr.ant-table-row:hover > td {
+ background-color: var(--gray-dark);
}
+
.ant-empty {
- color: white;
- opacity: .75;
+ color: var(--white-75);
}
.ant-table-empty .ant-table-tbody > tr.ant-table-placeholder {
&:hover > td {
@@ -269,18 +335,26 @@ textarea.ant-input {
background-color: var(--textfield-border);
}
}
-
+.ant-table-thead th.ant-table-column-sort {
+ background-color: var(--owncast-purple-25);
+ opacity: 0.75;
+}
// MODAL
+.ant-modal,
+.ant-modal-body {
+ font-size: 1em;
+}
.ant-modal-content {
border-radius: var(--container-border-radius);
- border: 1px solid var(--owncast-purple-highlight);
+ border: 1px solid var(--owncast-purple);
+ background-color: var(--black);
}
.ant-modal-header {
border-radius: var(--container-border-radius) var(--container-border-radius) 0 0;
}
.ant-modal-close-x {
- color: white;
+ color: var(--white);
}
.ant-modal-title {
font-weight: 500;
@@ -288,79 +362,151 @@ textarea.ant-input {
color: var(--nav-selected-text);
}
.ant-modal-body {
- background-color: var(--nav-bg-color);
+ background-color: var(--gray);
color: var(--default-text-color);
}
.ant-modal-header,
.ant-modal-footer {
- background-color: black;
+ background: var(--black);
}
.ant-modal-content,
.ant-modal-header,
.ant-modal-footer {
- border-color: #333;
+ border-color: var(--white-50);
}
// SELECT
.ant-select-dropdown {
- background-color: #334;
+ 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 {
// margin-right: 2em;
// }
.ant-slider-mark-text {
- font-size: .85em;
+ font-size: 0.85em;
white-space: nowrap;
+ color: var(--white);
+ opacity: 0.5;
+}
+.ant-slider-handle {
+ border-color: var(--blue);
+}
+.ant-slider:hover .ant-slider-track {
+ background-color: var(--blue);
+}
+.ant-slider-rail {
+ background-color: var(--black);
+}
+.ant-slider-track {
+ background-color: var(--nav-text);
+}
+.ant-slider-mark-text-active {
+ opacity: 1;
}
// ANT SWITCH
.ant-switch {
- background-color: #666;
+ background-color: var(--gray-medium);
}
.ant-switch-checked {
background-color: var(--ant-success);
.ant-switch-inner {
- color: white;
+ color: var(--white);
}
}
-
// ANT COLLAPSE
.ant-collapse {
+ font-size: 1em;
border-color: transparent;
- &> .ant-collapse-item,
+ & > .ant-collapse-item,
.ant-collapse-content {
border-color: transparent;
- &> .ant-collapse-header {
+ & > .ant-collapse-header {
+ border-radius: var(--container-border-radius);
border-color: transparent;
- background-color: var(--textfield-bg);
- color: var(--nav-text);
+ background-color: var(--purple-dark);
+ color: var(--white);
font-weight: 500;
}
}
}
.ant-collapse-content {
- background-color: #181231;
+ background-color: var(--black-35); //#181231;
+}
+.ant-collapse > .ant-collapse-item:last-child,
+.ant-collapse > .ant-collapse-item:last-child > .ant-collapse-header {
+ border-radius: var(--container-border-radius) var(--container-border-radius) 0 0;
+}
+.ant-collapse-item:last-child > .ant-collapse-content {
+ border-radius: 0 0 var(--container-border-radius) var(--container-border-radius);
}
-
-
// ANT POPOVER
-.ant-popover {
-
-}
.ant-popover-inner {
- background-color: black;
+ background-color: var(--gray);
}
.ant-popover-message,
.ant-popover-inner-content {
color: var(--default-text-color);
-
}
.ant-popover-placement-topLeft > .ant-popover-content > .ant-popover-arrow {
- border-color: black;
+ border-color: var(--gray);
}
+// ANT TAGS
+.ant-tag-red,
+.ant-tag-orange,
+.ant-tag-green,
+.ant-tag-purple,
+.ant-tag-blue {
+ background-color: var(--black);
+}
+
+// ANT PAGINATOR
+.ant-pagination-item-active {
+ color: var(--white);
+ background-color: var(--default-link-color);
+ border-color: var(--default-link-color);
+ a {
+ color: var(--white);
+ &:hover {
+ color: var(--white);
+ opacity: 0.75;
+ }
+ }
+}
+
+// ANT CHECKBOX
+.ant-checkbox-wrapper {
+ color: var(--white-75);
+ margin: 0.5em 0;
+}
+.ant-checkbox-group {
+ .ant-checkbox-group-item {
+ display: block;
+ }
+}
diff --git a/web/styles/chat.scss b/web/styles/chat.scss
index 13a84a0cc..6f0412b07 100644
--- a/web/styles/chat.scss
+++ b/web/styles/chat.scss
@@ -8,11 +8,11 @@
}
.ant-table-row.hidden {
.ant-table-cell {
- color: rgba(0,0,0,.25)
+ color: var(--black-35)
}
@media (prefers-color-scheme: dark) {
.ant-table-cell {
- color: rgba(255,255,255,.25)
+ color: var(--white-25);
}
}
}
@@ -47,29 +47,21 @@
.bulk-editor {
margin: .5rem 0;
padding: .5rem;
- border: 1px solid #ccc;
+ border: 1px solid var(--textfield-border);
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-end;
border-radius: 4px;
- opacity: .5;
-
&.active {
- opacity: 1;
.label {
- color: #000;
- }
- @media (prefers-color-scheme: dark) {
- .label {
- color: #fff;
- }
+ color: var(--black);
}
}
.label {
font-size: .75rem;
- color: #666;
+ color: var(--white-50);
margin-right: .5rem;
}
@@ -112,11 +104,6 @@
}
}
.ant-btn-text:hover {
- background-color: rgba(0,0,0,.1)
- }
- @media (prefers-color-scheme: dark) {
- .ant-btn-text:hover {
- background-color: rgba(255,255,255,.3)
- }
+ background-color: var(--black-35)
}
}
diff --git a/web/styles/colors.scss b/web/styles/colors.scss
deleted file mode 100644
index 7770daeb3..000000000
--- a/web/styles/colors.scss
+++ /dev/null
@@ -1,35 +0,0 @@
-// rename to variables.scss
-
-:root {
-
- --default-text-color: #fff;
-
- --owncast-purple: rgba(90,103,216,1); //5a67d8
- --owncast-purple-highlight: #ccd;
-
- --online-color: #73dd3f;
-
- --owncast-dark1: #1f1f21;
-
- --ant-error: #ff4d4f;
- --ant-success: #52c41a;
- --ant-warning: #faad14;
- --ant-transition-duration: .15s;
-
-
- --container-bg-color: #1A1C24;
- --container-bg-color-alt: #251c49;
- --container-border-radius: 2px;
-
- --code-purple: #82aaff;
-
- --nav-bg-color: #1A1C24;
- --nav-text: #6a76ba;
- --nav-selected-text: #c48dff;
-
- --form-focused: #8d71ff;
-
- --textfield-border: #373640;
- --textfield-bg: #100f0f;
-
-}
diff --git a/web/styles/config-public-details.scss b/web/styles/config-public-details.scss
index 868051455..c03d9a13b 100644
--- a/web/styles/config-public-details.scss
+++ b/web/styles/config-public-details.scss
@@ -38,14 +38,21 @@
}
.instance-details-container {
width: 100%;
+
+ .logo-preview {
+ display: inline-block;
+ margin: -1em 0 1em 11em;
+ height: 120px;
+ border: 1px solid var(--white-25);
+ }
}
.social-items-container {
background-color: var(--container-bg-color-alt);
- padding: 0 .75em;
+ padding: 0 0.75em;
margin-left: 1em;
max-width: 450px;
.form-module {
- background-color: #000;
+ background-color: var(--black);
}
.social-handles-container {
@@ -62,4 +69,8 @@
height: 6em !important;
}
}
-}
\ No newline at end of file
+}
+
+.other-field-container {
+ margin: 0.5em 0;
+}
diff --git a/web/styles/config-socialhandles.scss b/web/styles/config-socialhandles.scss
index 9e880c935..8e18128dd 100644
--- a/web/styles/config-socialhandles.scss
+++ b/web/styles/config-socialhandles.scss
@@ -8,7 +8,7 @@
flex-direction: row;
justify-content: flex-start;
align-items: center;
- padding: .25em;
+ padding: 0.25em;
line-height: normal;
.option-icon {
@@ -31,9 +31,9 @@
flex-direction: row;
align-items: center;
justify-content: flex-start;
- color: rgba(255,255,255,.85);
+ color: var(--white-75);
- .option-icon {
+ .option-icon {
height: 2em;
width: 2em;
line-height: normal;
@@ -43,7 +43,7 @@
flex-direction: column;
margin: 0 0 0 1em;
line-height: 2;
- font-size: .85em;
+ font-size: 0.85em;
}
}
.actions {
@@ -54,4 +54,4 @@
width: 6em;
}
}
-}
\ No newline at end of file
+}
diff --git a/web/styles/config-storage.scss b/web/styles/config-storage.scss
index d3f06bb74..ac8155830 100644
--- a/web/styles/config-storage.scss
+++ b/web/styles/config-storage.scss
@@ -22,29 +22,37 @@
}
-// Do something special for the stream key field
-.field-streamkey-container {
- margin-bottom: 1.5em;
- .field-tip {
- color: var(--ant-warning);
- }
- .left-side {
- display: flex;
- flex-direction: row;
- align-items: flex-start;
- }
-
- .textfield-with-submit-container {
- margin-bottom: 0;
- }
-
- .streamkey-actions {
- white-space: nowrap;
- button {
- margin: .25em;
+.edit-server-details-container {
+
+ // Do something special for the stream key field
+ .field-streamkey-container {
+ margin-bottom: 1.5em;
+ .field-tip {
+ color: var(--ant-warning);
}
- @media (max-width: 800px) {
- margin-top: 2em;
+ .left-side {
+ display: flex;
+ flex-direction: row;
+ align-items: flex-start;
+ }
+
+ .textfield-with-submit-container {
+ margin-bottom: 0;
+ }
+
+ .streamkey-actions {
+ white-space: nowrap;
+ button {
+ margin: .25em;
+ }
+ @media (max-width: 800px) {
+ margin-top: 2em;
+ }
}
}
-}
+
+ .advanced-settings {
+ max-width: 800px;
+ }
+
+}
\ No newline at end of file
diff --git a/web/styles/config-tags.scss b/web/styles/config-tags.scss
index f69936386..462cd350d 100644
--- a/web/styles/config-tags.scss
+++ b/web/styles/config-tags.scss
@@ -15,12 +15,12 @@
margin-left: .3rem;
padding: 2px;
border-radius: 5rem;
- color: black;
- border: 1px solid #000;
+ color: var(--black);
+ border: 1px solid var(--black);
transition-duration: var(--ant-transition-duration);
&:hover {
- border-color: #5a67d8;
- background-color: white;
+ border-color: var(--owncast-purple);
+ background-color: var(--white);
svg {
fill: black;
transition: fill var(--ant-transition-duration);
diff --git a/web/styles/config-video-variants.scss b/web/styles/config-video-variants.scss
index 1d7526484..a0d57711c 100644
--- a/web/styles/config-video-variants.scss
+++ b/web/styles/config-video-variants.scss
@@ -1,17 +1,13 @@
// styles for Video variant editor (table + modal)
.config-video-variants {
-
.variants-table {
margin-top: 2em;
}
.variants-table-module {
- min-width: 48%;
- max-width: 600px;
- margin-right: 1em
+ min-width: 400px;
}
-
}
// modal content
@@ -20,84 +16,16 @@
margin-top: 0;
}
+ .cpu-usage-container,
+ .bitrate-container {
+ height: 20em;
+ }
.advanced-settings {
- width: 48%;
- margin-left: 2em;
- }
- .blurb {
- margin: 1em;
- opacity: .75;
- }
- .note {
- display: inline-block;
- margin-left: 1em;
- font-size: .75em;
- opacity: .5;
- font-style: italic;
- }
-
-
- // .field {
- // margin-bottom: 2em;
- // display: flex;
- // flex-direction: row;
- // justify-content: center;
- // align-items: flex-start;
- // transform: opacity .15s;
- // &.disabled {
- // opacity: .25;
- // }
-
- // .label {
- // width: 40%;
- // text-align: right;
- // padding-right: 2em;
- // font-weight: bold;
- // color: var(--owncast-purple);
- // }
- // .info-tip {
- // margin-right: 1em;
- // }
- // .form-component {
- // width: 60%;
-
- // .selected-value-note {
- // font-size: .85em;
- // display: inline-block;
- // text-align: center;
- // }
- // }
- // }
- // .ant-collapse {
- // border: none;
- // border-radius: 6px;
- // }
- // .ant-collapse > .ant-collapse-item:last-child,
- // .ant-collapse > .ant-collapse-item:last-child > .ant-collapse-header {
- // border: none;
- // background-color: rgba(0,0,0,.25);
- // border-radius: 6px;
- // }
- // .ant-collapse-content {
- // background-color: rgba(0,0,0,.1);
- // }
-}
-
-
-
-.config-video-segements-conatiner {
- // display: flex;
- // flex-direction: row;
- // justify-content: center;
- // align-items: flex-start;
-
- .status-message {
- text-align: center;
+ margin-top: 1em;
}
}
-
.variants-table {
.actions {
display: flex;
@@ -105,11 +33,11 @@
justify-content: center;
}
.delete-button {
- margin-left: .5em;
- opacity: .8;
+ margin-left: 0.5em;
+ opacity: 0.8;
}
}
-.advanced-settings {
- margin-top: 2em;
-}
\ No newline at end of file
+.read-more-subtext {
+ font-size: 0.8rem;
+}
diff --git a/web/styles/config.scss b/web/styles/config.scss
deleted file mode 100644
index e27398dc7..000000000
--- a/web/styles/config.scss
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-// todo: put these somewhere else
-
-
-
-.edit-page-content {
- .page-content-actions {
- margin-top: 1em;
- display: flex;
- flex-direction: row;
- justify-content: flex-start;
- align-items: center;
-
- .status-message {
- margin-left: 1em;
- }
- }
-}
-
-
-
-
-.segment-tip {
- width: 10em;
- text-align: center;
- margin: auto;
- display: inline-block;
-}
diff --git a/web/styles/form-misc-elements.scss b/web/styles/form-misc-elements.scss
index 8030b45ae..5c53b82d5 100644
--- a/web/styles/form-misc-elements.scss
+++ b/web/styles/form-misc-elements.scss
@@ -30,7 +30,7 @@
/* TIP CONTAINER BASE */
.field-tip {
font-size: .8em;
- color: rgba(255,255,255,.5)
+ color: var(--white-50);
}
@@ -39,38 +39,34 @@ Ideal for wrapping each Textfield on a page with many text fields in a row. This
*/
.field-container {
padding: .85em 0 .5em;
- // &:nth-child(even) {
- // background-color: rgba(0,0,0,.25);
- // }
}
-/* SEGMENT SLIDER */
+/* SEGMENT SLIDER GROUP WITH SELECTED NOTE, OR STATUS */
.segment-slider-container {
- width: 90%;
+ width: 100%;
margin: auto;
padding: 1em 2em .75em;
- background-color: var(--textfield-border);
- border-radius: 1em;
- .ant-slider-rail {
- background-color: black;
- }
- .ant-slider-track {
- background-color: var(--nav-text);
- }
- .ant-slider-mark-text,
- .ant-slider-mark-text-active {
- color: white;
- opacity: .5;
- }
- .ant-slider-mark-text-active {
- opacity: 1;
- }
+ background-color: var(--owncast-purple-25);
+ border-radius: var(--container-border-radius);
+
.status-container {
width: 100%;
margin: .5em auto;
text-align: center;
}
+
+ .selected-value-note {
+ width: 100%;
+ margin: 3em auto 0;
+ text-align: center;
+ font-size: .75em;
+ line-height: normal;
+ color: var(--white);
+ padding: 1em;
+ border-radius: var(--container-border-radius);
+ background-color: var(--black-35);
+ }
}
diff --git a/web/styles/globals.scss b/web/styles/globals.scss
index 7a8e619ea..9d822f741 100644
--- a/web/styles/globals.scss
+++ b/web/styles/globals.scss
@@ -6,16 +6,16 @@ body {
margin: 0;
font-family: system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
- font-size: 14px;
+ font-size: 16px;
- background-color: #000;
- color: var(--default-text-color);;
+ background-color: var(--default-bg-color);
+ color: var(--default-text-color);
}
a {
color: inherit;
text-decoration: none;
- color: var(--owncast-purple);
+ color: var(--default-link-color);
&:hover {
color: var(--default-text-color);
@@ -25,19 +25,29 @@ a {
* {
box-sizing: border-box;
}
-p {
+
+p,
+p.description,
+.ant-typography {
font-weight: 300;
+ margin: 1em 0;
+ color: var(--white-75);
}
pre {
display: block;
padding: 1rem;
margin: .5rem 0;
- background-color: rgb(44, 44, 44);
- color:lightgrey;
+ background-color: var(--code-bg-color);
+ color: var(--white-50);
}
code {
- color: var(--owncast-purple);
+ color: var(--code-color);
+ background-color: var(--white-15);
+ display: inline-block;
+ padding: 2px 4px;
+ border-radius: 4px;
+ font-size: .88em;
}
@@ -46,37 +56,28 @@ code {
width: 2rem;
}
-p.description {
- margin: 1em 0;
- color: #ccc;
-}
+
.line-chart-container {
margin: 2em auto;
+ padding: 1em;
+ border: 1px solid var(--gray-dark);
}
-h2.ant-typography.page-title,
-h3.ant-typography.page-title
- {
- font-weight: 400;
- font-size: 1.5em;
- color: var(--nav-selected-text);
-}
-h2.section-title,
-h3.section-title {
- font-weight: 400;
- font-size: 1.25em;
-}
+
.form-module {
- // width: 100%;
- // max-width: 500px;
- // min-width: 300px;
margin: 1em 0;
background-color: var(--container-bg-color);
padding: 2em;
border-radius: var(--container-border-radius);
+
+ h3 {
+ &:first-of-type {
+ margin-top: 0;
+ }
+ }
}
.row {
diff --git a/web/styles/home.scss b/web/styles/home.scss
index 68fd41559..7a5a211a4 100644
--- a/web/styles/home.scss
+++ b/web/styles/home.scss
@@ -1,137 +1,51 @@
.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, 0.1);
}
}
}
-
.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 +58,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;
+ margin-top: 0.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%
- }
-
- }
}
diff --git a/web/styles/main-layout.scss b/web/styles/main-layout.scss
index 2eeda969e..2a67831cf 100644
--- a/web/styles/main-layout.scss
+++ b/web/styles/main-layout.scss
@@ -1,5 +1,4 @@
.app-container {
-
.side-nav {
position: fixed;
height: 100vh;
@@ -20,20 +19,20 @@
align-items: center;
.logo-container {
- background-color: #fff;
- padding: .35rem;
+ background-color: var(--white);
+ padding: 0.35rem;
border-radius: 9999px;
}
.title-label {
display: inline-block;
margin-left: 1rem;
- color: rgba(203,213,224, 1);
+ color: var(--white);
font-size: 1.15rem;
font-weight: 200;
text-transform: uppercase;
line-height: normal;
- letter-spacing: .05em;
+ letter-spacing: 0.05em;
}
}
@@ -48,17 +47,17 @@
background-color: var(--nav-bg-color);
}
-
.main-content-container {
- padding: 3em;
+ padding: 2em 3em 3em;
+ max-width: 1024px;
+ min-width: 50vw;
+ margin: auto;
}
.footer-container {
text-align: center;
}
-
-
.online-status-indicator {
display: flex;
flex-direction: row;
@@ -70,21 +69,21 @@
}
.status-label {
- color: #fff;
+ color: var(--white);
text-transform: uppercase;
- font-size: .75rem;
+ font-size: 0.75rem;
display: inline-block;
- margin-right: .5rem;
- color: #999;
+ margin-right: 0.5rem;
+ color: var(--offline-color);
}
.status-icon {
font-size: 1.5rem;
svg {
- fill: #999;
+ fill: var(--offline-color);
}
}
}
- .online {
+ &.online {
.online-status-indicator {
.status-icon {
svg {
@@ -92,13 +91,13 @@
}
}
.status-label {
+ white-space: nowrap;
color: var(--online-color);
}
}
}
}
-
// stream title form field in header
.global-stream-title-container {
display: flex;
@@ -111,8 +110,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 {
@@ -135,10 +147,9 @@
}
.update-button-container {
margin: 0;
- margin-left: .5em;
+ margin-left: 0.5em;
line-height: 1;
}
- }
- }
+ }
+ }
}
-
diff --git a/web/styles/markdown-editor.scss b/web/styles/markdown-editor.scss
index 64b528b8b..15fa84cf0 100644
--- a/web/styles/markdown-editor.scss
+++ b/web/styles/markdown-editor.scss
@@ -1,26 +1,38 @@
-
// markdown editor overrides
.rc-virtual-list-scrollbar {
display: block !important;
}
.rc-md-editor {
- border-color: black !important;
- border: 1px solid black;
- background-color: black !important;
+ border-color: var(--black) !important;
+ border: 1px solid var(--black);
+ background-color: var(--black) !important;
.rc-md-navigation {
- background-color: black;
- border-color: black;
+ background-color: var(--black);
+ border-color: var(--black);
}
// Set the background color of the preview container
.editor-container {
- color: rgba(45,55,72,1);
- background-color: rgba(226,232,240, 1) !important;
+ p {
+ color: var(--black-75);
+ }
+ background-color: rgba(226, 232, 240, 1) !important;
+ .sec-html {
+ background-color: white;
+
+ pre,
+ code {
+ background-color: #eee;
+ color: #900;
+ }
+ }
}
// Custom CSS for formatting the preview text
.markdown-editor-preview-pane {
+ color: var(--black-75);
+
a {
color: var(--owncast-purple);
}
@@ -31,23 +43,29 @@
// Custom CSS class used to format the text of the editor
.markdown-editor-pane {
- color: rgba(255,255,255,.85) !important;
- border-color: black !important;
+ color: rgba(255, 255, 255, 0.85) !important;
+ border-color: black !important;
background-color: black;
font-family: monospace;
}
-
-
// Set the background color of the editor text input
textarea {
- background-color: #223 !important;
- color: rgba(255,255,255,.5) !important;
+ background-color: var(--gray) !important;
+ color: rgba(255, 255, 255, 0.5) !important;
+ overflow: auto;
}
-
// Hide extra toolbar buttons.
- .button-type-undo, .button-type-redo, .button-type-clear, .button-type-image, .button-type-wrap, .button-type-quote, .button-type-strikethrough, .button-type-code-inline, .button-type-code-block {
+ .button-type-undo,
+ .button-type-redo,
+ .button-type-clear,
+ .button-type-image,
+ .button-type-wrap,
+ .button-type-quote,
+ .button-type-strikethrough,
+ .button-type-code-inline,
+ .button-type-code-block {
display: none !important;
}
}
diff --git a/web/styles/pages.scss b/web/styles/pages.scss
new file mode 100644
index 000000000..6f2661d5c
--- /dev/null
+++ b/web/styles/pages.scss
@@ -0,0 +1,20 @@
+// misc styling for various /pages
+
+
+// .help-page {
+// .ant-result-image {
+// height: 100px;
+// svg {
+// height: 100%;
+// width: 100%;
+// }
+// }
+// }
+
+
+.upgrade-page {
+ h2,h3 {
+ color: var(--pink);
+ font-size: 1.25em;
+ }
+}
diff --git a/web/styles/variables.scss b/web/styles/variables.scss
new file mode 100644
index 000000000..78114fa0b
--- /dev/null
+++ b/web/styles/variables.scss
@@ -0,0 +1,61 @@
+:root {
+ // colors
+ --white: rgba(255,255,255,1);
+ --white-15: rgba(255,255,255,.15);
+ --white-25: rgba(255,255,255,.25);
+ --white-35: rgba(255,255,255,.35);
+ --white-50: rgba(255,255,255,.5);
+ --white-75: rgba(255,255,255,.75);
+ --white-88: rgba(255,255,255,.88);
+
+ --black: rgba(0,0,0,1);
+ --black-35: rgba(0,0,0,.35);
+ --black-50: rgba(0,0,0,.5);
+ --black-75: rgba(0,0,0,.75);
+
+ // owncast logo color family
+ --owncast-purple: rgba(120,113,255,1); // #7871FF;
+ --purple-dark: rgba(28,26,59,1); // #1c1a3b;//
+ --pink: rgba(201,139,254,1); // #D18BFE;
+ --blue: rgba(32,134,225,1); // #2086E1;
+
+ // owncast puprple variations
+ --owncast-purple-25: rgba(120,113,255,.25);
+ --owncast-purple-50: rgba(120,113,255,.5);
+
+ --gray-light: rgba(168,175,197,1);
+ --gray-medium: rgba(102,107,120,1);
+ --gray: rgba(51,53,60,1);
+ --gray-dark: rgba(23,24,27,1); // #17181b;
+
+ --online-color: #73dd3f;
+ --offline-color: #999;
+
+ --ant-error: #ff4d4f;
+ --ant-success: #52c41a;
+ --ant-warning: #faad14;
+ --ant-transition-duration: .15s;
+
+
+ // ////////////////////////////////
+ --default-text-color: var(--white-88);
+ --default-bg-color: var(--black);
+ --default-link-color: var(--owncast-purple);
+
+ --container-bg-color: var(--gray-dark);
+ --container-bg-color-alt: var(--purple-dark);
+ --container-border-radius: 4px;
+
+ --code-color: #9cdcfe;
+ --code-bg-color: var(--owncast-purple-25);
+
+ --nav-bg-color: var(--gray-dark);
+ --nav-text: #aaa;
+ --nav-selected-text: var(--pink); //#cd7cff;
+
+ --button-focused: var(--owncast-purple-50);
+
+ --textfield-border: var(--white-25);;
+ --textfield-bg: var(--black);
+
+}