From 7425e71d08fb9d65e81e145d3a9946a358b51a1b Mon Sep 17 00:00:00 2001 From: nebunez Date: Sat, 6 Feb 2021 17:26:44 -0500 Subject: [PATCH 01/23] tweaks to offline state in admin viewers page If stream is offline, hide current viewers statistic and viewers table. Also, change wording for describing max viewers. --- web/pages/viewer-info.tsx | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/web/pages/viewer-info.tsx b/web/pages/viewer-info.tsx index 9dbdfd677..6790a956e 100644 --- a/web/pages/viewer-info.tsx +++ b/web/pages/viewer-info.tsx @@ -96,24 +96,26 @@ export default function ViewersOverTime() { return (
+ {online && ( + } + /> + )} } - /> - } /> } /> - row.clientID} /> + {online &&
row.clientID} />} ); } From 44cef18a001dd3ca605565f3d47adcfede5a4c02 Mon Sep 17 00:00:00 2001 From: gingervitis Date: Sun, 14 Feb 2021 00:41:20 -0800 Subject: [PATCH 02/23] define more readable owncast color variables; apply var style names consistenly through other stylessheets; reaname file for clarity --- web/pages/_app.tsx | 2 +- web/styles/ant-overrides.scss | 164 +++++++++++++++++--------- web/styles/chat.scss | 25 +--- web/styles/colors.scss | 35 ------ web/styles/config-public-details.scss | 2 +- web/styles/config-tags.scss | 8 +- web/styles/form-misc-elements.scss | 8 +- web/styles/globals.scss | 27 +++-- web/styles/main-layout.scss | 10 +- web/styles/markdown-editor.scss | 26 ++-- web/styles/variables.scss | 63 ++++++++++ 11 files changed, 230 insertions(+), 140 deletions(-) delete mode 100644 web/styles/colors.scss create mode 100644 web/styles/variables.scss diff --git a/web/pages/_app.tsx b/web/pages/_app.tsx index 75576a8b2..06c93ac67 100644 --- a/web/pages/_app.tsx +++ b/web/pages/_app.tsx @@ -1,6 +1,6 @@ // order matters! import 'antd/dist/antd.css'; -import '../styles/colors.scss'; +import '../styles/variables.scss'; import '../styles/ant-overrides.scss'; import '../styles/markdown-editor.scss'; import '../styles/globals.scss'; diff --git a/web/styles/ant-overrides.scss b/web/styles/ant-overrides.scss index 52e7cbbab..7872130ff 100644 --- a/web/styles/ant-overrides.scss +++ b/web/styles/ant-overrides.scss @@ -35,14 +35,27 @@ h5.ant-typography, .ant-typography h3, .ant-typography h4, .ant-typography h5 { - color: var(--default-text-color); + color: var(--white); font-weight: 500; } - .ant-typography.ant-typography-secondary { - color: rgba(255,255,255,.85); + color: var(--white); font-weight: 400; } +.ant-typography { + a { + color: var(--owncast-purple); + } +} +.ant-typography h1, +h1.ant-typography { + color: var(--white); +} +.ant-typography h2, +h2.ant-typography{ + color: var(--pink); +} + .ant-progress-text, .ant-progress-circle .ant-progress-text { @@ -66,21 +79,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); } @@ -97,8 +115,8 @@ 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); + border-left: 1px solid var(--white-50); + background-color: var(--black-35); } .ant-menu-submenu-title { transition-duration: var(--ant-transition-duration); @@ -117,14 +135,14 @@ 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)); } } } @@ -137,7 +155,7 @@ h5.ant-typography, color: var(--default-text-color); } .ant-result-subtitle { - color: var(--default-text-color); + color: var(--white-75); } @@ -148,13 +166,21 @@ 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 { + .ant-statistic, + .ant-statistic-title, + .ant-statistic-content { + color: var(--default-text-color); + } } - // ANT INPUT @@ -165,10 +191,10 @@ 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; @@ -177,10 +203,10 @@ h5.ant-typography, } .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-number:focus, @@ -189,13 +215,13 @@ h5.ant-typography, 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); + color: var(--white-55); } textarea.ant-input { padding-right: 25px; @@ -211,20 +237,20 @@ textarea.ant-input { } .ant-btn-primary:hover, .ant-btn-primary:focus { - background-color: var(--form-focused); - border-color: var(--form-focused); + background-color: var(--button-focused); + border-color: var(--button-focused); } .ant-btn.ant-btn-primary:hover { - border-color: white; + 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 +259,31 @@ textarea.ant-input { transition-duration: 0.15s; } + // 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: #141417; + color: var(--white-75); } .ant-table-tbody > tr:nth-child(odd) > td { - background-color: var(--textfield-bg); + background-color: #222325; } .ant-empty { - color: white; - opacity: .75; + color: var(--white-75); } .ant-table-empty .ant-table-tbody > tr.ant-table-placeholder { &:hover > td { @@ -269,18 +296,23 @@ textarea.ant-input { background-color: var(--textfield-border); } } +.ant-table-thead th.ant-table-column-sort { + background-color: var(--owncast-purple-25); + opacity: .75; +} // MODAL .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,22 +320,22 @@ 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(--gray); } // SELECT .ant-select-dropdown { - background-color: #334; + background-color: var(--gray); } @@ -318,12 +350,12 @@ textarea.ant-input { // 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); } } @@ -335,15 +367,16 @@ textarea.ant-input { .ant-collapse-content { border-color: transparent; &> .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; } @@ -353,7 +386,7 @@ textarea.ant-input { } .ant-popover-inner { - background-color: black; + background-color: var(--black); } .ant-popover-message, .ant-popover-inner-content { @@ -361,6 +394,31 @@ textarea.ant-input { } .ant-popover-placement-topLeft > .ant-popover-content > .ant-popover-arrow { - border-color: black; + border-color: var(--black); } + + + +// ANT TAGS + +.ant-tag-orange { + background: #fa8c16; + color: #fff7e6; + border-color: #ffd591; +} + + +// 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: .75; + } + } +} \ No newline at end of file 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..7d8325a56 100644 --- a/web/styles/config-public-details.scss +++ b/web/styles/config-public-details.scss @@ -45,7 +45,7 @@ margin-left: 1em; max-width: 450px; .form-module { - background-color: #000; + background-color: var(--black); } .social-handles-container { 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/form-misc-elements.scss b/web/styles/form-misc-elements.scss index 8030b45ae..a038a336b 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); } @@ -50,17 +50,17 @@ Ideal for wrapping each Textfield on a page with many text fields in a row. This width: 90%; margin: auto; padding: 1em 2em .75em; - background-color: var(--textfield-border); + background-color: var(--black-35); border-radius: 1em; .ant-slider-rail { - background-color: black; + background-color: var(--black); } .ant-slider-track { background-color: var(--nav-text); } .ant-slider-mark-text, .ant-slider-mark-text-active { - color: white; + color: var(--white); opacity: .5; } .ant-slider-mark-text-active { diff --git a/web/styles/globals.scss b/web/styles/globals.scss index 7a8e619ea..6480495fe 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); @@ -27,17 +27,23 @@ a { } p { font-weight: 300; + 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; } @@ -48,12 +54,14 @@ code { p.description { margin: 1em 0; - color: #ccc; + color: var(--white-75); } .line-chart-container { margin: 2em auto; + padding: 1em; + border: 1px solid var(--gray-dark); } h2.ant-typography.page-title, @@ -70,9 +78,6 @@ h3.section-title { } .form-module { - // width: 100%; - // max-width: 500px; - // min-width: 300px; margin: 1em 0; background-color: var(--container-bg-color); padding: 2em; diff --git a/web/styles/main-layout.scss b/web/styles/main-layout.scss index 2eeda969e..f3514a488 100644 --- a/web/styles/main-layout.scss +++ b/web/styles/main-layout.scss @@ -20,7 +20,7 @@ align-items: center; .logo-container { - background-color: #fff; + background-color: var(--white); padding: .35rem; border-radius: 9999px; } @@ -28,7 +28,7 @@ .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; @@ -70,17 +70,17 @@ } .status-label { - color: #fff; + color: var(--white); text-transform: uppercase; font-size: .75rem; display: inline-block; margin-right: .5rem; - color: #999; + color: var(--offline-color); } .status-icon { font-size: 1.5rem; svg { - fill: #999; + fill: var(--offline-color); } } } diff --git a/web/styles/markdown-editor.scss b/web/styles/markdown-editor.scss index 64b528b8b..c688a7a63 100644 --- a/web/styles/markdown-editor.scss +++ b/web/styles/markdown-editor.scss @@ -5,18 +5,29 @@ 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); + 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 @@ -41,8 +52,9 @@ // Set the background color of the editor text input textarea { - background-color: #223 !important; + background-color: var(--gray) !important; color: rgba(255,255,255,.5) !important; + overflow: auto; } diff --git a/web/styles/variables.scss b/web/styles/variables.scss new file mode 100644 index 000000000..16b9b0beb --- /dev/null +++ b/web/styles/variables.scss @@ -0,0 +1,63 @@ +// rename to variables.scss + +: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); + +} From d55e4dfe2966d13d23afabd2ba9377c667cf38e4 Mon Sep 17 00:00:00 2001 From: gingervitis Date: Sun, 14 Feb 2021 01:30:42 -0800 Subject: [PATCH 03/23] misc cleanup --- web/components/config/edit-page-content.tsx | 6 +-- web/pages/_app.tsx | 2 +- web/pages/access-tokens.tsx | 18 ++++---- web/pages/config-public-details.tsx | 4 +- web/pages/config-server-details.tsx | 2 +- web/pages/config-social-items.tsx | 2 +- web/pages/config-storage.tsx | 2 +- web/pages/config-video.tsx | 4 +- web/pages/help.tsx | 9 ++-- web/pages/upgrade.tsx | 41 +++++++++--------- web/pages/viewer-info.tsx | 1 + web/pages/webhooks.tsx | 29 +++++-------- web/styles/ant-overrides.scss | 46 ++++++++++++++++++--- web/styles/config.scss | 29 ------------- web/styles/form-misc-elements.scss | 5 +-- web/styles/globals.scss | 24 ++++------- web/styles/main-layout.scss | 2 +- web/styles/pages.scss | 13 ++++++ web/styles/variables.scss | 2 - 19 files changed, 116 insertions(+), 125 deletions(-) delete mode 100644 web/styles/config.scss create mode 100644 web/styles/pages.scss diff --git a/web/components/config/edit-page-content.tsx b/web/components/config/edit-page-content.tsx index ee12a403d..0f07b45cf 100644 --- a/web/components/config/edit-page-content.tsx +++ b/web/components/config/edit-page-content.tsx @@ -104,13 +104,13 @@ export default function EditPageContent() { markdownClass: 'markdown-editor-pane', }} /> - +
- {hasChanged ? ( + {hasChanged && ( - ) : null} + )}
diff --git a/web/pages/_app.tsx b/web/pages/_app.tsx index 06c93ac67..fad9a31e8 100644 --- a/web/pages/_app.tsx +++ b/web/pages/_app.tsx @@ -17,7 +17,7 @@ import '../styles/config-public-details.scss'; import '../styles/home.scss'; import '../styles/chat.scss'; -import '../styles/config.scss'; +import '../styles/pages.scss'; import { AppProps } from 'next/app'; import ServerStatusProvider from '../utils/server-status-context'; diff --git a/web/pages/access-tokens.tsx b/web/pages/access-tokens.tsx index f259ea50c..ffcba58bc 100644 --- a/web/pages/access-tokens.tsx +++ b/web/pages/access-tokens.tsx @@ -1,12 +1,13 @@ import React, { useState, useEffect } from 'react'; import { Table, Tag, Space, Button, Modal, Checkbox, Input, Typography, Tooltip } from 'antd'; -import { DeleteOutlined, EyeTwoTone, EyeInvisibleOutlined } from '@ant-design/icons'; -const { Title, Paragraph, Text } = Typography; +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'; +const { Title, Paragraph } = Typography; + const availableScopes = { CAN_SEND_SYSTEM_MESSAGES: { name: 'System messages', @@ -87,9 +88,12 @@ function NewTokenModal(props) { Select the permissions this access token will have. It cannot be edited after it's created.

- + +

+ +

); } @@ -162,7 +166,7 @@ export default function AccessTokens() { try { const result = await fetchData(DELETE_ACCESS_TOKEN, { method: 'POST', - data: { token: token }, + data: { token }, }); getAccessTokens(); } catch (error) { @@ -174,7 +178,7 @@ export default function AccessTokens() { try { const newToken = await fetchData(CREATE_ACCESS_TOKEN, { method: 'POST', - data: { name: name, scopes: scopes }, + data: { name, scopes }, }); setTokens(tokens.concat(newToken)); } catch (error) { diff --git a/web/pages/config-public-details.tsx b/web/pages/config-public-details.tsx index 0798871b8..f6b6896e1 100644 --- a/web/pages/config-public-details.tsx +++ b/web/pages/config-public-details.tsx @@ -11,9 +11,7 @@ const { Title } = Typography; export default function PublicFacingDetails() { return (
- - General Settings - + General Settings

The following are displayed on your site to describe your stream and its content.{' '} Learn more. diff --git a/web/pages/config-server-details.tsx b/web/pages/config-server-details.tsx index b9c9008d6..7592a8c3a 100644 --- a/web/pages/config-server-details.tsx +++ b/web/pages/config-server-details.tsx @@ -7,7 +7,7 @@ const { Title } = Typography; export default function ConfigServerDetails() { return (

- + <Title> Server Settings

diff --git a/web/pages/config-social-items.tsx b/web/pages/config-social-items.tsx index c7ae8f9c8..12dd692ff 100644 --- a/web/pages/config-social-items.tsx +++ b/web/pages/config-social-items.tsx @@ -7,7 +7,7 @@ const { Title } = Typography; export default function ConfigSocialThings() { return (

- Social Items + Social Items
diff --git a/web/pages/config-storage.tsx b/web/pages/config-storage.tsx index e0f4a4e39..8d5a7c2f3 100644 --- a/web/pages/config-storage.tsx +++ b/web/pages/config-storage.tsx @@ -7,7 +7,7 @@ const { Title } = Typography; export default function ConfigStorageInfo() { return ( <> - + <Title> Storage

diff --git a/web/pages/config-video.tsx b/web/pages/config-video.tsx index ec1fe6b32..d5a9eba62 100644 --- a/web/pages/config-video.tsx +++ b/web/pages/config-video.tsx @@ -9,9 +9,7 @@ const { Title } = Typography; export default function ConfigVideoSettings() { return (

- - Video configuration - + Video configuration

Before changing your video configuration{' '} visit the video documentation to learn diff --git a/web/pages/help.tsx b/web/pages/help.tsx index 0affc08ed..c4e504678 100644 --- a/web/pages/help.tsx +++ b/web/pages/help.tsx @@ -2,9 +2,7 @@ import { Button, Card, Col, Divider, Result, Row } from 'antd'; import Meta from 'antd/lib/card/Meta'; import Title from 'antd/lib/typography/Title'; import { - AlertOutlined, ApiTwoTone, - BookOutlined, BugTwoTone, CameraTwoTone, DatabaseTwoTone, @@ -17,9 +15,10 @@ import { } from '@ant-design/icons'; import React from 'react'; -interface Props {} -export default function Help(props: Props) { + + +export default function Help() { const questions = [ { icon: , @@ -144,7 +143,7 @@ export default function Help(props: Props) { ]; return ( -

+
How can we help you?
diff --git a/web/pages/upgrade.tsx b/web/pages/upgrade.tsx index a0e7e2c32..dfe46afae 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); } }; @@ -61,9 +58,9 @@ export default function Logs() { {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..b54b08f47 100644 --- a/web/pages/viewer-info.tsx +++ b/web/pages/viewer-info.tsx @@ -114,6 +114,7 @@ export default function ViewersOverTime() { prefix={} /> + {online &&
row.clientID} />} diff --git a/web/pages/webhooks.tsx b/web/pages/webhooks.tsx index a232bef90..546152768 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' }, @@ -96,9 +84,12 @@ function NewWebhookModal(props) {

Select the events that will be sent to this webhook.

- + +

+ +

); } diff --git a/web/styles/ant-overrides.scss b/web/styles/ant-overrides.scss index 7872130ff..5ccaeae08 100644 --- a/web/styles/ant-overrides.scss +++ b/web/styles/ant-overrides.scss @@ -36,25 +36,36 @@ h5.ant-typography, .ant-typography h4, .ant-typography h5 { color: var(--white); - font-weight: 500; + font-weight: 400; + margin: .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 h1, h1.ant-typography { - color: var(--white); -} -.ant-typography h2, -h2.ant-typography{ + font-size: 1.75em; color: var(--pink); } +.ant-typography h2, +h2.ant-typography { + font-size: 1.5em; +} + +.ant-typography h3, +h3.ant-typography { + font-size: 1.25em; +} + .ant-progress-text, @@ -184,6 +195,15 @@ h2.ant-typography{ // 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); @@ -201,6 +221,7 @@ h2.ant-typography{ } } } +.ant-input:hover, .ant-input-number:hover, .ant-input-affix-wrapper:hover { border-color: var(--owncast-purple); @@ -209,6 +230,7 @@ h2.ant-typography{ border-color: var(--owncast-purple); } } +.ant-input, .ant-input-number:focus, .ant-input-affix-wrapper:focus, .ant-input-affix-wrapper-focused { @@ -421,4 +443,16 @@ textarea.ant-input { opacity: .75; } } -} \ No newline at end of file +} + + +// ANT CHECKBOX +.ant-checkbox-wrapper { + color: var(--white-75); + margin: .5em 0; +} +.ant-checkbox-group { + .ant-checkbox-group-item { + display: block; + } +} 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 a038a336b..6ccd49ad5 100644 --- a/web/styles/form-misc-elements.scss +++ b/web/styles/form-misc-elements.scss @@ -39,9 +39,6 @@ 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); - // } } @@ -50,7 +47,7 @@ Ideal for wrapping each Textfield on a page with many text fields in a row. This width: 90%; margin: auto; padding: 1em 2em .75em; - background-color: var(--black-35); + background-color: var(--owncast-purple-25); border-radius: 1em; .ant-slider-rail { background-color: var(--black); diff --git a/web/styles/globals.scss b/web/styles/globals.scss index 6480495fe..6601a0b14 100644 --- a/web/styles/globals.scss +++ b/web/styles/globals.scss @@ -25,8 +25,12 @@ a { * { box-sizing: border-box; } -p { + +p, +p.description, +.ant-typography { font-weight: 300; + margin: 1em 0; color: var(--white-75); } pre { @@ -52,10 +56,7 @@ code { width: 2rem; } -p.description { - margin: 1em 0; - color: var(--white-75); -} + .line-chart-container { @@ -64,18 +65,7 @@ p.description { 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 { margin: 1em 0; diff --git a/web/styles/main-layout.scss b/web/styles/main-layout.scss index f3514a488..d36045c44 100644 --- a/web/styles/main-layout.scss +++ b/web/styles/main-layout.scss @@ -50,7 +50,7 @@ .main-content-container { - padding: 3em; + padding: 2em 3em 3em; } .footer-container { diff --git a/web/styles/pages.scss b/web/styles/pages.scss new file mode 100644 index 000000000..6481f0458 --- /dev/null +++ b/web/styles/pages.scss @@ -0,0 +1,13 @@ +// misc styling for various /pages + + +.help-page { + + .ant-result-image { + height: 100px; + svg { + height: 100%; + width: 100%; + } + } +} diff --git a/web/styles/variables.scss b/web/styles/variables.scss index 16b9b0beb..78114fa0b 100644 --- a/web/styles/variables.scss +++ b/web/styles/variables.scss @@ -1,5 +1,3 @@ -// rename to variables.scss - :root { // colors --white: rgba(255,255,255,1); From 682ddf96c3e56035e51dc88dc8ccea7396fc3872 Mon Sep 17 00:00:00 2001 From: gingervitis Date: Sun, 14 Feb 2021 01:45:08 -0800 Subject: [PATCH 04/23] more cleanup --- web/components/config/edit-social-links.tsx | 1 - web/components/config/edit-storage.tsx | 10 ++++++---- .../config/form-toggleswitch-with-submit.tsx | 6 ++++-- web/components/config/video-variants-table.tsx | 1 - web/pages/config-server-details.tsx | 4 +--- web/pages/config-storage.tsx | 4 +--- web/styles/ant-overrides.scss | 11 +++++++++++ web/styles/pages.scss | 1 - 8 files changed, 23 insertions(+), 15 deletions(-) diff --git a/web/components/config/edit-social-links.tsx b/web/components/config/edit-social-links.tsx index 6e5a75e18..d93b24ddc 100644 --- a/web/components/config/edit-social-links.tsx +++ b/web/components/config/edit-social-links.tsx @@ -196,7 +196,6 @@ export default function EditSocialLinks() { return (
{/* ENCODER PRESET FIELD */}
- {selectedPresetNote && ( - {selectedPresetNote} - )}
- {/* VIDEO PASSTHROUGH FIELD */} + {/* VIDEO PASSTHROUGH FIELD - currently disabled */}
-

- - Use Video Passthrough? -

-
- {/* todo: change to ToggleSwitch for layout */} - -
+
+ + {/* VIDEO BITRATE FIELD */} -
- - Video Bitrate - +
+ Video Bitrate

{VIDEO_VARIANT_DEFAULTS.videoBitrate.tip}

- {selectedVideoBRnote()} +

{selectedVideoBRnote()}

-
- - -
- Resizing your content will take additional resources on your server. If you wish to - optionally resize your output for this stream variant then you should either set the - width or the height to keep your aspect ratio. -
-
- -
-
- -
+ + + + +

+ Resizing your content will take additional resources on your server. If you wish to + optionally resize your output for this stream variant then you should either set the + width or the height to keep your aspect ratio. +

- {/* FRAME RATE FIELD */} -
-

- - Frame rate: -

-
- `${value} ${framerateUnit}`} - defaultValue={dataState.framerate} - value={dataState.framerate} - onChange={handleFramerateChange} - step={framerateDefaults.incrementBy} - min={framerateMin} - max={framerateMax} - marks={framerateMarks} - /> - {selectedFramerateNote()} -
+ + + + {/* FRAME RATE FIELD */} +
+ Frame rate +

{VIDEO_VARIANT_DEFAULTS.framerate.tip}

+
+ `${value} ${framerateUnit}`} + defaultValue={dataState.framerate} + value={dataState.framerate} + onChange={handleFramerateChange} + step={framerateDefaults.incrementBy} + min={framerateMin} + max={framerateMax} + marks={framerateMarks} + /> +

{selectedFramerateNote()}

- - -
+
+
+
); } diff --git a/web/pages/config-video.tsx b/web/pages/config-video.tsx index d5a9eba62..c117d30d1 100644 --- a/web/pages/config-video.tsx +++ b/web/pages/config-video.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Typography } from 'antd'; +import { Typography, Row, Col } from 'antd'; import VideoVariantsTable from '../components/config/video-variants-table'; import VideoLatency from '../components/config/video-latency'; @@ -16,15 +16,18 @@ export default function ConfigVideoSettings() { how it impacts your stream performance.

-
-
- -
- -
- -
-
+ +
+
+ +
+ + +
+ +
+ + ); } diff --git a/web/styles/ant-overrides.scss b/web/styles/ant-overrides.scss index 41844d26e..e275a075f 100644 --- a/web/styles/ant-overrides.scss +++ b/web/styles/ant-overrides.scss @@ -54,6 +54,9 @@ h5.ant-typography, h1.ant-typography { font-size: 1.75em; color: var(--pink); + &:first-of-type { + margin-top: 0; + } } .ant-typography h2, h2.ant-typography { @@ -253,13 +256,13 @@ textarea.ant-input { // ANT BUTTON .ant-btn { - background-color: var(--purple-dark); - border-color: var(--white-25); + background-color: var(--owncast-purple-25); + border-color: var(--owncast-purple-25); color: var(--white-75); &:hover, &:focus { - background-color: var(--owncast-purple); - border-color: var(--owncast-purple); + background-color: var(--button-focused); + border-color: var(--button-focused); color: var(--white); } } @@ -308,12 +311,13 @@ textarea.ant-input { } .ant-table-tbody > tr > td { transition-duration: var(--ant-transition-duration); - background-color: #141417; + background-color: #222325; color: var(--white-75); } -.ant-table-tbody > tr:nth-child(odd) > td { - background-color: #222325; +.ant-table-tbody > tr.ant-table-row:hover > td { + background-color: var(--gray-dark); } + .ant-empty { color: var(--white-75); } @@ -335,6 +339,10 @@ textarea.ant-input { // MODAL +.ant-modal, +.ant-modal-body { + font-size: 1em; +} .ant-modal-content { border-radius: var(--container-border-radius); border: 1px solid var(--owncast-purple); @@ -362,7 +370,7 @@ textarea.ant-input { .ant-modal-content, .ant-modal-header, .ant-modal-footer { - border-color: var(--gray); + border-color: var(--white-50); } // SELECT @@ -378,6 +386,23 @@ textarea.ant-input { .ant-slider-mark-text { font-size: .85em; white-space: nowrap; + color: var(--white); + opacity: .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 @@ -394,6 +419,7 @@ textarea.ant-input { // ANT COLLAPSE .ant-collapse { + font-size: 1em; border-color: transparent; &> .ant-collapse-item, .ant-collapse-content { @@ -410,13 +436,16 @@ textarea.ant-input { .ant-collapse-content { 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: var(--black); } diff --git a/web/styles/config-video-variants.scss b/web/styles/config-video-variants.scss index 1d7526484..a0d5c7213 100644 --- a/web/styles/config-video-variants.scss +++ b/web/styles/config-video-variants.scss @@ -7,9 +7,7 @@ } .variants-table-module { - min-width: 48%; - max-width: 600px; - margin-right: 1em + min-width: 400px; } } @@ -20,80 +18,13 @@ 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; } } @@ -109,7 +40,3 @@ opacity: .8; } } - -.advanced-settings { - margin-top: 2em; -} \ No newline at end of file diff --git a/web/styles/form-misc-elements.scss b/web/styles/form-misc-elements.scss index 6ccd49ad5..5c53b82d5 100644 --- a/web/styles/form-misc-elements.scss +++ b/web/styles/form-misc-elements.scss @@ -42,32 +42,31 @@ Ideal for wrapping each Textfield on a page with many text fields in a row. This } -/* 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(--owncast-purple-25); - border-radius: 1em; - .ant-slider-rail { - background-color: var(--black); - } - .ant-slider-track { - background-color: var(--nav-text); - } - .ant-slider-mark-text, - .ant-slider-mark-text-active { - color: var(--white); - opacity: .5; - } - .ant-slider-mark-text-active { - opacity: 1; - } + 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 6601a0b14..9d822f741 100644 --- a/web/styles/globals.scss +++ b/web/styles/globals.scss @@ -72,6 +72,12 @@ code { background-color: var(--container-bg-color); padding: 2em; border-radius: var(--container-border-radius); + + h3 { + &:first-of-type { + margin-top: 0; + } + } } .row { From 6d83992ff0dbf82d61519407d99e94100ef1f060 Mon Sep 17 00:00:00 2001 From: gingervitis Date: Sun, 14 Feb 2021 19:04:38 -0800 Subject: [PATCH 08/23] style adjustments --- web/components/config/cpu-usage.tsx | 2 ++ web/components/config/video-latency.tsx | 3 ++- web/pages/config-video.tsx | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/web/components/config/cpu-usage.tsx b/web/components/config/cpu-usage.tsx index fe1e046d6..5b1c7f0b4 100644 --- a/web/components/config/cpu-usage.tsx +++ b/web/components/config/cpu-usage.tsx @@ -51,6 +51,7 @@ export default function CPUUsageSelector({ defaultValue, onChange }: Props) {

TOOLTIPS[value]} onChange={handleChange} min={1} @@ -59,6 +60,7 @@ export default function CPUUsageSelector({ defaultValue, onChange }: Props) { defaultValue={selectedOption} value={selectedOption} /> +

Selected: {TOOLTIPS[selectedOption]}

); diff --git a/web/components/config/video-latency.tsx b/web/components/config/video-latency.tsx index 78771975c..ab4fa0020 100644 --- a/web/components/config/video-latency.tsx +++ b/web/components/config/video-latency.tsx @@ -120,7 +120,7 @@ export default function VideoLatency() {
} + tooltipVisible={false} onChange={handleChange} min={1} max={6} @@ -128,6 +128,7 @@ export default function VideoLatency() { defaultValue={selectedOption} value={selectedOption} /> +

{SLIDER_COMMENTS[selectedOption]}

diff --git a/web/pages/config-video.tsx b/web/pages/config-video.tsx index c117d30d1..aa7cf5585 100644 --- a/web/pages/config-video.tsx +++ b/web/pages/config-video.tsx @@ -17,12 +17,12 @@ export default function ConfigVideoSettings() {

-
+
- +
From 8d5411a0d60fe9b524ad4b3e6c554cb4f8fa26c1 Mon Sep 17 00:00:00 2001 From: gingervitis Date: Sun, 14 Feb 2021 22:20:25 -0800 Subject: [PATCH 09/23] hella cleanup - index page items; use more Row/Cols to reduce custom css layout --- web/components/config/README.md | 2 + web/components/config/edit-social-links.tsx | 54 +++--- .../config/social-icons-dropdown.tsx | 64 +++---- web/components/config/video-variant-form.tsx | 4 +- web/components/log-table.tsx | 2 +- web/components/main-layout.tsx | 2 +- web/pages/chat.tsx | 2 +- web/pages/config-video.tsx | 6 +- web/pages/hardware-info.tsx | 4 +- web/pages/index.tsx | 133 +++++++------- web/pages/offline-notice.tsx | 17 +- web/pages/viewer-info.tsx | 8 +- web/styles/ant-overrides.scss | 56 ++++-- web/styles/config-public-details.scss | 6 +- web/styles/config-socialhandles.scss | 2 +- web/styles/home.scss | 169 ++++-------------- web/styles/main-layout.scss | 16 +- 17 files changed, 250 insertions(+), 297 deletions(-) diff --git a/web/components/config/README.md b/web/components/config/README.md index 2117f290e..578e2193d 100644 --- a/web/components/config/README.md +++ b/web/components/config/README.md @@ -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 \ No newline at end of file diff --git a/web/components/config/edit-social-links.tsx b/web/components/config/edit-social-links.tsx index d93b24ddc..570a5ec40 100644 --- a/web/components/config/edit-social-links.tsx +++ b/web/components/config/edit-social-links.tsx @@ -221,6 +221,19 @@ export default function EditSocialLinks() { disabled: !isValidUrl(modalDataState.url), }; + const otherField = ( +
+
+
+ +
+
+ ); + return (
@@ -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 diff --git a/web/components/config/social-icons-dropdown.tsx b/web/components/config/social-icons-dropdown.tsx index dec12cdf0..df1fab8dd 100644 --- a/web/components/config/social-icons-dropdown.tsx +++ b/web/components/config/social-icons-dropdown.tsx @@ -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> ); } diff --git a/web/components/config/video-variant-form.tsx b/web/components/config/video-variant-form.tsx index 96152288c..75c862863 100644 --- a/web/components/config/video-variant-form.tsx +++ b/web/components/config/video-variant-form.tsx @@ -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 ${ diff --git a/web/components/log-table.tsx b/web/components/log-table.tsx index 603d6af56..8223bd398 100644 --- a/web/components/log-table.tsx +++ b/web/components/log-table.tsx @@ -75,7 +75,7 @@ export default function LogTable({ logs, pageSize }: Props) { return ( <div className="logs-section"> - <Title level={2}>Logs + Logs
- Chat Messages + Chat Messages

Manage the messages from viewers that show up on your stream.

Check multiple messages to change their visibility to: diff --git a/web/pages/config-video.tsx b/web/pages/config-video.tsx index aa7cf5585..f0042f469 100644 --- a/web/pages/config-video.tsx +++ b/web/pages/config-video.tsx @@ -16,13 +16,13 @@ export default function ConfigVideoSettings() { how it impacts your stream performance.

- -
+ +
- +
diff --git a/web/pages/hardware-info.tsx b/web/pages/hardware-info.tsx index e8d446342..cb5e6c3fb 100644 --- a/web/pages/hardware-info.tsx +++ b/web/pages/hardware-info.tsx @@ -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 (
+ Hardware Info +
{ - 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 ( - - - - - ); - }, - ); + return ( +
+ + +
+ ); + }); // inbound const { viewerCount, sessionPeakViewerCount } = serverStatusData; @@ -118,57 +110,60 @@ export default function Home() { return (
-
- - } - /> - } /> - } - /> +
+ + +
+ } + /> + + + } /> + + + } + /> + + -
-
{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/viewer-info.tsx b/web/pages/viewer-info.tsx index b54b08f47..eaa73a8eb 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, 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 ( -
+ <> + Viewer Info +
{online && ( {online &&
row.clientID} />} - + ); } diff --git a/web/styles/ant-overrides.scss b/web/styles/ant-overrides.scss index e275a075f..03e03f381 100644 --- a/web/styles/ant-overrides.scss +++ b/web/styles/ant-overrides.scss @@ -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); } diff --git a/web/styles/config-public-details.scss b/web/styles/config-public-details.scss index f1e50acbf..c97ad7e4d 100644 --- a/web/styles/config-public-details.scss +++ b/web/styles/config-public-details.scss @@ -69,4 +69,8 @@ height: 6em !important; } } -} \ No newline at end of file +} + +.other-field-container { + margin: .5em 0; +} diff --git a/web/styles/config-socialhandles.scss b/web/styles/config-socialhandles.scss index 9e880c935..188d0d92a 100644 --- a/web/styles/config-socialhandles.scss +++ b/web/styles/config-socialhandles.scss @@ -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; diff --git a/web/styles/home.scss b/web/styles/home.scss index 68fd41559..dbb9f9643 100644 --- a/web/styles/home.scss +++ b/web/styles/home.scss @@ -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% - } - - } } diff --git a/web/styles/main-layout.scss b/web/styles/main-layout.scss index d36045c44..a17425a3e 100644 --- a/web/styles/main-layout.scss +++ b/web/styles/main-layout.scss @@ -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 { From 1b116d225299c7a98bbbd5154200ecea4f7d0aba Mon Sep 17 00:00:00 2001 From: gingervitis Date: Mon, 15 Feb 2021 06:24:09 +0000 Subject: [PATCH 10/23] Prettified Code! --- web/styles/ant-overrides.scss | 68 ++++++++++----------------- web/styles/config-public-details.scss | 4 +- web/styles/config-socialhandles.scss | 8 ++-- web/styles/home.scss | 9 ++-- web/styles/main-layout.scss | 20 +++----- 5 files changed, 41 insertions(+), 68 deletions(-) diff --git a/web/styles/ant-overrides.scss b/web/styles/ant-overrides.scss index 03e03f381..91eb5887e 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, @@ -23,14 +22,14 @@ 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, @@ -39,7 +38,7 @@ h5.ant-typography, .ant-typography h5 { color: var(--white); font-weight: 400; - margin: .5em 0; + margin: 0.5em 0; } .ant-typography.ant-typography-secondary { color: var(--white); @@ -71,15 +70,11 @@ h3.ant-typography { font-size: 1.25em; } - - .ant-progress-text, .ant-progress-circle .ant-progress-text { color: var(--default-text-color); } - - // ANT MENU // menu base .ant-menu-item { @@ -87,7 +82,7 @@ h3.ant-typography { .anticon { transition-duration: var(--ant-transition-duration); - color: var(--nav-text); + color: var(--nav-text); } a { @@ -106,7 +101,7 @@ h3.ant-typography { } } } -.ant-menu-item:active, +.ant-menu-item:active, .ant-menu-submenu-title:active { background-color: var(--black-50); } @@ -130,14 +125,14 @@ h3.ant-typography { } // submenu items .ant-menu-submenu { - &> .ant-menu { + & > .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); } @@ -165,7 +160,6 @@ h3.ant-typography { } } - // ANT RESULT .ant-result-title { color: var(--default-text-color); @@ -174,7 +168,6 @@ h3.ant-typography { color: var(--white-75); } - // ANT CARD .ant-card { border-radius: var(--container-border-radius); @@ -196,7 +189,6 @@ h3.ant-typography { border-color: var(--white-25); } - // ANT INPUT input.ant-input, textarea.ant-input { @@ -235,7 +227,7 @@ textarea.ant-input { } .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, @@ -252,9 +244,6 @@ textarea.ant-input { padding-right: 25px; } - - - // ANT BUTTON .ant-btn { background-color: var(--owncast-purple-25); @@ -270,7 +259,7 @@ textarea.ant-input { 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(--button-focused); color: var(--white); @@ -299,8 +288,7 @@ 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); @@ -339,10 +327,9 @@ textarea.ant-input { } .ant-table-thead th.ant-table-column-sort { background-color: var(--owncast-purple-25); - opacity: .75; + opacity: 0.75; } - // MODAL .ant-modal, .ant-modal-body { @@ -384,7 +371,7 @@ textarea.ant-input { } .ant-select-single:not(.ant-select-customize-input) .ant-select-selector { background-color: var(--black); - border-color: var(--owncast-purple-50); + border-color: var(--owncast-purple-50); } .ant-select-arrow { color: var(--owncast-purple); @@ -409,10 +396,10 @@ textarea.ant-input { // margin-right: 2em; // } .ant-slider-mark-text { - font-size: .85em; + font-size: 0.85em; white-space: nowrap; color: var(--white); - opacity: .5; + opacity: 0.5; } .ant-slider-handle { border-color: var(--blue); @@ -441,15 +428,14 @@ textarea.ant-input { } } - // 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(--purple-dark); @@ -461,15 +447,14 @@ textarea.ant-input { .ant-collapse-content { background-color: var(--black-35); //#181231; } -.ant-collapse > .ant-collapse-item:last-child, .ant-collapse > .ant-collapse-item:last-child > .ant-collapse-header { +.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-inner { background-color: var(--black); @@ -477,14 +462,11 @@ textarea.ant-input { .ant-popover-message, .ant-popover-inner-content { color: var(--default-text-color); - } .ant-popover-placement-topLeft > .ant-popover-content > .ant-popover-arrow { border-color: var(--black); } - - // ANT TAGS .ant-tag-red, .ant-tag-orange, @@ -493,7 +475,6 @@ textarea.ant-input { background-color: var(--black); } - // ANT PAGINATOR .ant-pagination-item-active { color: var(--white); @@ -503,16 +484,15 @@ textarea.ant-input { color: var(--white); &:hover { color: var(--white); - opacity: .75; + opacity: 0.75; } } } - // ANT CHECKBOX .ant-checkbox-wrapper { color: var(--white-75); - margin: .5em 0; + margin: 0.5em 0; } .ant-checkbox-group { .ant-checkbox-group-item { diff --git a/web/styles/config-public-details.scss b/web/styles/config-public-details.scss index c97ad7e4d..c03d9a13b 100644 --- a/web/styles/config-public-details.scss +++ b/web/styles/config-public-details.scss @@ -48,7 +48,7 @@ } .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 { @@ -72,5 +72,5 @@ } .other-field-container { - margin: .5em 0; + margin: 0.5em 0; } diff --git a/web/styles/config-socialhandles.scss b/web/styles/config-socialhandles.scss index 188d0d92a..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 { @@ -33,7 +33,7 @@ justify-content: flex-start; 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/home.scss b/web/styles/home.scss index dbb9f9643..19477b914 100644 --- a/web/styles/home.scss +++ b/web/styles/home.scss @@ -38,13 +38,12 @@ .outbound-details, .inbound-details { - >.ant-card-bordered { - border-color: rgba(255,255,255,.1); + > .ant-card-bordered { + border-color: rgba(255, 255, 255, 0.1); } } } - .offline-content { max-width: 1000px; @@ -64,12 +63,12 @@ background-color: var(--container-bg-color-alt); border-radius: var(--container-border-radius); padding: 1em; - + > .ant-card { background-color: var(--black); margin-bottom: 1em; .ant-card-meta-avatar { - margin-top: .25rem; + margin-top: 0.25rem; svg { height: 1.5em; width: 1.5em; diff --git a/web/styles/main-layout.scss b/web/styles/main-layout.scss index a17425a3e..9878c4099 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; @@ -21,7 +20,7 @@ .logo-container { background-color: var(--white); - padding: .35rem; + padding: 0.35rem; border-radius: 9999px; } @@ -33,7 +32,7 @@ font-weight: 200; text-transform: uppercase; line-height: normal; - letter-spacing: .05em; + letter-spacing: 0.05em; } } @@ -48,7 +47,6 @@ background-color: var(--nav-bg-color); } - .main-content-container { padding: 2em 3em 3em; } @@ -57,8 +55,6 @@ text-align: center; } - - .online-status-indicator { display: flex; flex-direction: row; @@ -72,9 +68,9 @@ .status-label { color: var(--white); text-transform: uppercase; - font-size: .75rem; + font-size: 0.75rem; display: inline-block; - margin-right: .5rem; + margin-right: 0.5rem; color: var(--offline-color); } .status-icon { @@ -99,7 +95,6 @@ } } - // stream title form field in header .global-stream-title-container { display: flex; @@ -149,10 +144,9 @@ } .update-button-container { margin: 0; - margin-left: .5em; + margin-left: 0.5em; line-height: 1; } - } - } + } + } } - From b7ba430b3246e7526a23bd3bfd1696c4e86832a8 Mon Sep 17 00:00:00 2001 From: gingervitis Date: Sun, 14 Feb 2021 22:29:41 -0800 Subject: [PATCH 11/23] add linting script --- web/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/package.json b/web/package.json index e4f99c1d1..443214cc3 100644 --- a/web/package.json +++ b/web/package.json @@ -5,7 +5,8 @@ "scripts": { "dev": "next dev", "build": "next build && next export", - "start": "next start" + "start": "next start", + "lint": "eslint --ext .js,.ts,.tsx types/ pages/ components/" }, "dependencies": { "@ant-design/icons": "^4.2.2", From 834ddafc9b0a34e049359e893ed22431057fba70 Mon Sep 17 00:00:00 2001 From: gingervitis Date: Mon, 15 Feb 2021 00:08:52 -0800 Subject: [PATCH 12/23] update readme; more style tweaks --- web/components/config/README.md | 69 +++++++++++++++---- web/components/config/cpu-usage.tsx | 1 - web/components/config/edit-server-details.tsx | 2 +- web/components/config/reset-yp.tsx | 32 +++++++-- web/components/config/video-latency.tsx | 10 +-- web/components/config/video-variant-form.tsx | 1 - web/styles/ant-overrides.scss | 4 +- web/styles/config-storage.scss | 54 ++++++++------- 8 files changed, 119 insertions(+), 54 deletions(-) diff --git a/web/components/config/README.md b/web/components/config/README.md index 578e2193d..1750b5ded 100644 --- a/web/components/config/README.md +++ b/web/components/config/README.md @@ -1,10 +1,44 @@ -# About the Config editing section +# Tips for creating a new Admin form -An adventure with React, React Hooks and Ant Design forms. +### Layout +- Give your page or form a title. Feel free to use Ant Design's `` component. +- Give your form a description inside of a `<p className="description" />` tag. -## General data flow in this React app +- Use some Ant Design `Row` and `Col`'s to layout your forms if you want to spread them out into responsive columns. + +- Use the `form-module` CSS class if you want to add a visual separation to a grouping of items. + + + +### Form fields +- Feel free to use the pre-styled `<TextField>` text form field or the `<ToggleSwitch>` compnent, in a group of form fields together. These have been styled and laid out to match each other. + +- `Slider`'s - If your form uses an Ant Slider component, follow this recommended markup of CSS classes to maintain a consistent look and feel to other Sliders in the app. + ``` + <div className="segment-slider-container"> + <Slider ...props /> + <p className="selected-value-note">{selected value}</p> + </div> + ``` + +### Submit Statuses +- It would be nice to display indicators of success/warnings to let users know if something has been successfully updated on the server. It has a lot of steps (sorry, but it could probably be optimized), but it'll provide a consistent way to display messaging. + + - See `reset-yp.tsx` for an example of using `submitStatus` with `useState()` and the `<FormStatusIndicator>` component to achieve this. + +### Styling +- This admin site chooses to have a generally Dark color palette, but with colors that are different from Ant design's _dark_ stylesheet, so that style sheet is not included. This results in a very large `ant-overrides.scss` file to reset colors on frequently used Ant components in the system. If you find yourself a new Ant Component that has not yet been used in this app, feel free to add a reset style for that component to the overrides stylesheet. + + - Take a look at `variables.scss` CSS file if you want to give some elements custom css colors. + + +--- +--- +# Creating Admin forms the Config section +First things first.. + +## General Config data flow in this React app -### First things to note - When the Admin app loads, the `ServerStatusContext` (in addition to checking server `/status` on a timer) makes a call to the `/serverconfig` API to get your config details. This data will be stored as **`serverConfig`** in app state, and _provided_ to the app via `useContext` hook. - The `serverConfig` in state is be the central source of data that pre-populates the forms. @@ -13,10 +47,14 @@ An adventure with React, React Hooks and Ant Design forms. - After you have updated a config value in a form field, and successfully submitted it through its endpoint, you should call `setFieldInConfigState` to update the global state with the new value. -- Each top field of the serverConfig has its own API update endpoint. -### Form Flow -Each form input (or group of inputs) you make, you should +## Suggested Config Form Flow +- *NOTE: Each top field of the serverConfig has its own API update endpoint.* + + +There many steps here, but they are highly suggested to ensure that Config values are updated and displayed properly throughout the entire admin form. + +For each form input (or group of inputs) you make, you should: 1. Get the field values that you want out of `serverConfig` from ServerStatusContext with `useContext`. 2. Next we'll have to put these field values of interest into a `useState` in each grouping. This will help you edit the form. 3. Because ths config data is populated asynchronously, Use a `useEffect` to check when that data has arrived before putting it into state. @@ -27,7 +65,18 @@ Each form input (or group of inputs) you make, you should There are also a variety of other local states to manage the display of error/success messaging. -## Notes about `form-textfield` and `form-togglefield` +- It is recommended that you use `form-textfield-with-submit` and `form-toggleswitch`(with `useSubmit=true`) Components to edit Config fields. + +Examples of Config form groups where individual form fields submitting to the update API include: +- `edit-instance-details.tsx` +- `edit-server-details.tsx` + +Examples of Config form groups where there is 1 submit button for the entire group include: +- `edit-storage.tsx` + + +--- +#### Notes about `form-textfield-with-submit` and `form-togglefield` (with useSubmit=true) - The text field is intentionally designed to make it difficult for the user to submit bad data. - If you make a change on a field, a Submit buttton will show up that you have to click to update. That will be the only way you can update it. - If you clear out a field that is marked as Required, then exit/blur the field, it will repopulate with its original value. @@ -40,7 +89,3 @@ There are also a variety of other local states to manage the display of error/su - NOTE: you don't have to use these components. Some form groups may require a customized UX flow where you're better off using the Ant components straight up. - - -segment-slider-container -selected-value-note \ No newline at end of file diff --git a/web/components/config/cpu-usage.tsx b/web/components/config/cpu-usage.tsx index 5b1c7f0b4..8f64ac509 100644 --- a/web/components/config/cpu-usage.tsx +++ b/web/components/config/cpu-usage.tsx @@ -51,7 +51,6 @@ export default function CPUUsageSelector({ defaultValue, onChange }: Props) { </p> <div className="segment-slider-container"> <Slider - tooltipVisible={false} tipFormatter={value => TOOLTIPS[value]} onChange={handleChange} min={1} diff --git a/web/components/config/edit-server-details.tsx b/web/components/config/edit-server-details.tsx index 92541625d..c13acfc9b 100644 --- a/web/components/config/edit-server-details.tsx +++ b/web/components/config/edit-server-details.tsx @@ -86,7 +86,7 @@ export default function EditInstanceDetails() { } return ( - <div className="edit-public-details-container"> + <div className="edit-server-details-container"> <div className="field-container field-streamkey-container"> <div className="left-side"> <TextFieldWithSubmit diff --git a/web/components/config/reset-yp.tsx b/web/components/config/reset-yp.tsx index 97d3ad79d..e40f12da6 100644 --- a/web/components/config/reset-yp.tsx +++ b/web/components/config/reset-yp.tsx @@ -1,27 +1,46 @@ import { Popconfirm, Button, Typography } from 'antd'; -import { useContext } from 'react'; +import { useContext, useState } from 'react'; import { AlertMessageContext } from '../../utils/alert-message-context'; import { API_YP_RESET, fetchData } from '../../utils/apis'; +import { RESET_TIMEOUT } from '../../utils/config-constants'; +import { + createInputStatus, + STATUS_ERROR, + STATUS_PROCESSING, + STATUS_SUCCESS, +} from '../../utils/input-statuses'; +import FormStatusIndicator from './form-status-indicator'; export default function ResetYP() { const { setMessage } = useContext(AlertMessageContext); - const { Title } = Typography; + const [submitStatus, setSubmitStatus] = useState(null); + let resetTimer = null; + const resetStates = () => { + setSubmitStatus(null); + resetTimer = null; + clearTimeout(resetTimer); + }; const resetDirectoryRegistration = async () => { + setSubmitStatus(createInputStatus(STATUS_PROCESSING)); try { await fetchData(API_YP_RESET); setMessage(''); + setSubmitStatus(createInputStatus(STATUS_SUCCESS)); + resetTimer = setTimeout(resetStates, RESET_TIMEOUT); } catch (error) { - alert(error); + setSubmitStatus(createInputStatus(STATUS_ERROR, `There was an error: ${error}`)); + resetTimer = setTimeout(resetStates, RESET_TIMEOUT); } }; + return ( <> - <Title level={3} className="section-title"> + <Typography.Title level={3} className="section-title"> Reset Directory - +

If you are experiencing issues with your listing on the Owncast Directory and were asked to "reset" your connection to the service, you can do that here. The next time you go @@ -37,6 +56,9 @@ export default function ResetYP() { > +

+ +

); } diff --git a/web/components/config/video-latency.tsx b/web/components/config/video-latency.tsx index ab4fa0020..e7ab44f0f 100644 --- a/web/components/config/video-latency.tsx +++ b/web/components/config/video-latency.tsx @@ -36,14 +36,6 @@ const SLIDER_COMMENTS = { 6: 'Highest latency, highest error tolerance', }; -interface SegmentToolTipProps { - value: string; -} - -function SegmentToolTip({ value }: SegmentToolTipProps) { - return {value}; -} - export default function VideoLatency() { const [submitStatus, setSubmitStatus] = useState(null); const [selectedOption, setSelectedOption] = useState(null); @@ -120,7 +112,7 @@ export default function VideoLatency() {
SLIDER_COMMENTS[value]} onChange={handleChange} min={1} max={6} diff --git a/web/components/config/video-variant-form.tsx b/web/components/config/video-variant-form.tsx index 75c862863..f428d227f 100644 --- a/web/components/config/video-variant-form.tsx +++ b/web/components/config/video-variant-form.tsx @@ -230,7 +230,6 @@ export default function VideoVariantForm({

{VIDEO_VARIANT_DEFAULTS.framerate.tip}

`${value} ${framerateUnit}`} defaultValue={dataState.framerate} value={dataState.framerate} diff --git a/web/styles/ant-overrides.scss b/web/styles/ant-overrides.scss index 03e03f381..355deb8d8 100644 --- a/web/styles/ant-overrides.scss +++ b/web/styles/ant-overrides.scss @@ -472,7 +472,7 @@ textarea.ant-input { // ANT POPOVER .ant-popover-inner { - background-color: var(--black); + background-color: var(--gray); } .ant-popover-message, .ant-popover-inner-content { @@ -480,7 +480,7 @@ textarea.ant-input { } .ant-popover-placement-topLeft > .ant-popover-content > .ant-popover-arrow { - border-color: var(--black); + border-color: var(--gray); } 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 From 90c19c2201cfce0aa96e69fd05aadab352ec437e Mon Sep 17 00:00:00 2001 From: gingervitis Date: Mon, 15 Feb 2021 00:10:50 -0800 Subject: [PATCH 13/23] move readme to docs --- web/{components/config => docs}/README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename web/{components/config => docs}/README.md (100%) diff --git a/web/components/config/README.md b/web/docs/README.md similarity index 100% rename from web/components/config/README.md rename to web/docs/README.md From 97187f55417d0c9a5e5d93f4b899cac907fa6ece Mon Sep 17 00:00:00 2001 From: gingervitis Date: Mon, 15 Feb 2021 00:36:06 -0800 Subject: [PATCH 14/23] lint for passing builds --- web/components/statistic.tsx | 7 ++- web/pages/access-tokens.tsx | 104 ++++++++++++++++++----------------- web/pages/broadcast-info.tsx | 18 ------ web/pages/hardware-info.tsx | 15 ++--- web/pages/help.tsx | 3 - web/pages/webhooks.tsx | 37 ++++++++----- web/styles/pages.scss | 18 +++--- 7 files changed, 99 insertions(+), 103 deletions(-) delete mode 100644 web/pages/broadcast-info.tsx diff --git a/web/components/statistic.tsx b/web/components/statistic.tsx index a6edd9da9..f1e81e2c6 100644 --- a/web/components/statistic.tsx +++ b/web/components/statistic.tsx @@ -1,3 +1,6 @@ +/* eslint-disable react/no-unused-prop-types */ +// TODO: This component should be cleaned up and usage should be re-examined. The types should be reconsidered as well. + import { Typography, Statistic, Card, Progress } from 'antd'; const { Text } = Typography; @@ -5,7 +8,7 @@ const { Text } = Typography; interface StatisticItemProps { title?: string; value?: any; - prefix?: JSX.Element; + prefix?: any; color?: string; progress?: boolean; centered?: boolean; @@ -43,7 +46,7 @@ function ProgressView({ title, value, prefix, color }: StatisticItemProps) { '0%': color, '90%': endColor, }} - format={percent => content} + format={() => content} /> ); } diff --git a/web/pages/access-tokens.tsx b/web/pages/access-tokens.tsx index ffcba58bc..adc2447a1 100644 --- a/web/pages/access-tokens.tsx +++ b/web/pages/access-tokens.tsx @@ -40,11 +40,17 @@ function convertScopeStringToTag(scopeString) { ); } -function NewTokenModal(props) { +interface Props { + onCancel: () => void; + onOk: any; // todo: make better type + visible: boolean; +} +function NewTokenModal(props: Props) { + const { onOk, onCancel, visible } = props; const [selectedScopes, setSelectedScopes] = useState([]); const [name, setName] = useState(''); - const scopes = Object.keys(availableScopes).map(function (key) { + const scopes = Object.keys(availableScopes).map(key => { return { value: key, label: availableScopes[key].description }; }); @@ -53,7 +59,7 @@ function NewTokenModal(props) { } function saveToken() { - props.onOk(name, selectedScopes); + onOk(name, selectedScopes); // Clear the modal setSelectedScopes([]); @@ -71,9 +77,9 @@ function NewTokenModal(props) { return (

@@ -85,7 +91,8 @@ function NewTokenModal(props) {

- Select the permissions this access token will have. It cannot be edited after it's created. + Select the permissions this access token will have. It cannot be edited after it's + created.

@@ -102,6 +109,47 @@ export default function AccessTokens() { const [tokens, setTokens] = useState([]); const [isTokenModalVisible, setIsTokenModalVisible] = useState(false); + function handleError(error) { + console.error('error', error); + alert(error); + } + + async function getAccessTokens() { + try { + const result = await fetchData(ACCESS_TOKENS); + setTokens(result); + } catch (error) { + handleError(error); + } + } + useEffect(() => { + getAccessTokens(); + }, []); + + async function handleDeleteToken(token) { + try { + await fetchData(DELETE_ACCESS_TOKEN, { + method: 'POST', + data: { token }, + }); + getAccessTokens(); + } catch (error) { + handleError(error); + } + } + + async function handleSaveToken(name: string, scopes: string[]) { + try { + const newToken = await fetchData(CREATE_ACCESS_TOKEN, { + method: 'POST', + data: { name, scopes }, + }); + setTokens(tokens.concat(newToken)); + } catch (error) { + handleError(error); + } + } + const columns = [ { title: '', @@ -121,7 +169,7 @@ export default function AccessTokens() { title: 'Token', dataIndex: 'token', key: 'token', - render: (text, record) => , + render: text => , }, { title: 'Scopes', @@ -149,48 +197,6 @@ export default function AccessTokens() { }, ]; - const getAccessTokens = async () => { - try { - const result = await fetchData(ACCESS_TOKENS); - setTokens(result); - } catch (error) { - handleError(error); - } - }; - - useEffect(() => { - getAccessTokens(); - }, []); - - async function handleDeleteToken(token) { - try { - const result = await fetchData(DELETE_ACCESS_TOKEN, { - method: 'POST', - data: { token }, - }); - getAccessTokens(); - } catch (error) { - handleError(error); - } - } - - async function handleSaveToken(name: string, scopes: string[]) { - try { - const newToken = await fetchData(CREATE_ACCESS_TOKEN, { - method: 'POST', - data: { name, scopes }, - }); - setTokens(tokens.concat(newToken)); - } catch (error) { - handleError(error); - } - } - - function handleError(error) { - console.error('error', error); - alert(error); - } - const showCreateTokenModal = () => { setIsTokenModalVisible(true); }; diff --git a/web/pages/broadcast-info.tsx b/web/pages/broadcast-info.tsx deleted file mode 100644 index 2cd8a7a63..000000000 --- a/web/pages/broadcast-info.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import React, { useContext } from 'react'; -import { ServerStatusContext } from '../utils/server-status-context'; - - -export default function BroadcastInfo() { - const context = useContext(ServerStatusContext); - const { broadcaster } = context || {}; - const { remoteAddr, time, streamDetails } = broadcaster || {}; - - return ( -
-

Broadcast Info

-

Remote Address: {remoteAddr}

-

Time: {(new Date(time)).toLocaleTimeString()}

-

Stream Details: {JSON.stringify(streamDetails)}

-
- ); -} diff --git a/web/pages/hardware-info.tsx b/web/pages/hardware-info.tsx index cb5e6c3fb..3bff965ea 100644 --- a/web/pages/hardware-info.tsx +++ b/web/pages/hardware-info.tsx @@ -5,16 +5,17 @@ import { fetchData, FETCH_INTERVAL, HARDWARE_STATS } from '../utils/apis'; import Chart from '../components/chart'; import StatisticItem from '../components/statistic'; -interface TimedValue { - time: Date; - value: Number; -} +// TODO: FIX TS WARNING FROM THIS. +// interface TimedValue { +// time: Date; +// value: Number; +// } export default function HardwareInfo() { const [hardwareStatus, setHardwareStatus] = useState({ - cpu: Array(), - memory: Array(), - disk: Array(), + cpu: [], // Array(), + memory: [], // Array(), + disk: [], // Array(), message: '', }); diff --git a/web/pages/help.tsx b/web/pages/help.tsx index c4e504678..e746ac13b 100644 --- a/web/pages/help.tsx +++ b/web/pages/help.tsx @@ -15,9 +15,6 @@ import { } from '@ant-design/icons'; import React from 'react'; - - - export default function Help() { const questions = [ { diff --git a/web/pages/webhooks.tsx b/web/pages/webhooks.tsx index 546152768..5072f4962 100644 --- a/web/pages/webhooks.tsx +++ b/web/pages/webhooks.tsx @@ -37,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 }; }); @@ -55,7 +62,7 @@ function NewWebhookModal(props) { } function save() { - props.onOk(webhookUrl, selectedEvents); + onOk(webhookUrl, selectedEvents); // Reset the modal setWebhookUrl(''); @@ -69,9 +76,9 @@ function NewWebhookModal(props) { return (
@@ -127,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(); @@ -142,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); @@ -153,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) { @@ -161,11 +173,6 @@ export default function Webhooks() { } } - function handleError(error) { - console.error('error', error); - alert(error); - } - const showCreateModal = () => { setIsModalVisible(true); }; @@ -185,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/pages.scss b/web/styles/pages.scss index 27032d0a5..6f2661d5c 100644 --- a/web/styles/pages.scss +++ b/web/styles/pages.scss @@ -1,15 +1,15 @@ // misc styling for various /pages -.help-page { - .ant-result-image { - height: 100px; - svg { - height: 100%; - width: 100%; - } - } -} +// .help-page { +// .ant-result-image { +// height: 100px; +// svg { +// height: 100%; +// width: 100%; +// } +// } +// } .upgrade-page { From c5e2e9aa5804cf8e27cb2d0c296eff8df4ef9299 Mon Sep 17 00:00:00 2001 From: Gabe Kangas Date: Mon, 15 Feb 2021 12:08:42 -0800 Subject: [PATCH 15/23] Point to static logo path due to the logo backend change --- web/components/config/edit-instance-details.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/components/config/edit-instance-details.tsx b/web/components/config/edit-instance-details.tsx index 6d649f21a..5de5b2440 100644 --- a/web/components/config/edit-instance-details.tsx +++ b/web/components/config/edit-instance-details.tsx @@ -105,7 +105,7 @@ export default function EditInstanceDetails() { /> {instanceDetails.logo && ( uploaded logo From 7b36f91af11beca31c050e47674f8c9f502fd151 Mon Sep 17 00:00:00 2001 From: gabek Date: Mon, 15 Feb 2021 20:09:23 +0000 Subject: [PATCH 16/23] Prettified Code! --- web/components/config/edit-instance-details.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/web/components/config/edit-instance-details.tsx b/web/components/config/edit-instance-details.tsx index 5de5b2440..e23eada5f 100644 --- a/web/components/config/edit-instance-details.tsx +++ b/web/components/config/edit-instance-details.tsx @@ -104,11 +104,7 @@ export default function EditInstanceDetails() { onChange={handleFieldChange} /> {instanceDetails.logo && ( - uploaded logo + uploaded logo )}
From ee5e462c596d08aeb21a14a05ca09302d221ce23 Mon Sep 17 00:00:00 2001 From: Gabe Kangas Date: Mon, 15 Feb 2021 14:08:47 -0800 Subject: [PATCH 17/23] Update hint texts and add links to documentation --- web/components/config/cpu-usage.tsx | 2 +- web/components/config/video-variant-form.tsx | 25 ++++++++++---------- web/pages/config-video.tsx | 4 ++-- web/styles/config-video-variants.scss | 4 ++++ 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/web/components/config/cpu-usage.tsx b/web/components/config/cpu-usage.tsx index 8f64ac509..09acc19b9 100644 --- a/web/components/config/cpu-usage.tsx +++ b/web/components/config/cpu-usage.tsx @@ -47,7 +47,7 @@ export default function CPUUsageSelector({ defaultValue, onChange }: Props) {
CPU Usage

- There are trade-offs when considering CPU usage blah blah more wording here. + Reduce the to improve server performance, or increase it to improve video quality.

{ let note = `Selected: ${dataState.videoBitrate}${videoBRUnit}`; - if (dataState.videoBitrate < 3000) { + if (dataState.videoBitrate < 2000) { note = `${note} - Good for low bandwidth environments.`; - } else if (dataState.videoBitrate < 4500) { + } else if (dataState.videoBitrate < 3500) { note = `${note} - Good for most bandwidth environments.`; } else { note = `${note} - Good for high bandwidth environments.`; @@ -150,9 +150,7 @@ export default function VideoVariantForm({ return (

- Say a thing here about how this all works. Read more{' '} - here. Click the OK button below to - save your information. + Learn more about how each of these settings can impact the performance of your server.

@@ -163,6 +161,7 @@ export default function VideoVariantForm({ defaultValue={dataState.cpuUsageLevel} onChange={handleVideoCpuUsageLevelChange} /> +

Read more about CPU usage.

{/* VIDEO PASSTHROUGH FIELD - currently disabled */} @@ -180,9 +179,8 @@ export default function VideoVariantForm({
{/* VIDEO BITRATE FIELD */}
Video Bitrate

{VIDEO_VARIANT_DEFAULTS.videoBitrate.tip}

@@ -200,6 +198,7 @@ export default function VideoVariantForm({ />

{selectedVideoBRnote()}

+

Read more about bitrates.

@@ -207,8 +206,9 @@ export default function VideoVariantForm({

Resizing your content will take additional resources on your server. If you wish to - optionally resize your output for this stream variant then you should either set the - width or the height to keep your aspect ratio. + optionally resize your content for this stream output then you should either set the + width or the height to keep your aspect ratio.{' '} + Read more about resolutions.

{selectedFramerateNote()}

+

Read more about framerates.

diff --git a/web/pages/config-video.tsx b/web/pages/config-video.tsx index f0042f469..d6e3bf39c 100644 --- a/web/pages/config-video.tsx +++ b/web/pages/config-video.tsx @@ -12,8 +12,8 @@ export default function ConfigVideoSettings() { Video configuration

Before changing your video configuration{' '} - visit the video documentation to learn - how it impacts your stream performance. + visit the video documentation to learn + how it impacts your stream performance. The general rule is to start conservatively by having one middle quality stream output variant and experiment with adding more of varied qualities.

diff --git a/web/styles/config-video-variants.scss b/web/styles/config-video-variants.scss index a0d5c7213..32b29d67b 100644 --- a/web/styles/config-video-variants.scss +++ b/web/styles/config-video-variants.scss @@ -40,3 +40,7 @@ opacity: .8; } } + +.read-more-subtext { + font-size: 0.8rem; +} \ No newline at end of file From 259ac676ff6d47fe8c13adf75fe2ec3ce3b606a0 Mon Sep 17 00:00:00 2001 From: gabek Date: Mon, 15 Feb 2021 22:09:34 +0000 Subject: [PATCH 18/23] Prettified Code! --- web/components/config/video-variant-form.tsx | 23 ++++++++++++++------ web/pages/config-video.tsx | 6 +++-- web/styles/config-video-variants.scss | 9 +++----- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/web/components/config/video-variant-form.tsx b/web/components/config/video-variant-form.tsx index 0830e3d60..3ec73c566 100644 --- a/web/components/config/video-variant-form.tsx +++ b/web/components/config/video-variant-form.tsx @@ -16,7 +16,8 @@ const VIDEO_VARIANT_DEFAULTS = { defaultValue: 24, unit: 'fps', incrementBy: null, - tip: 'Reducing your framerate will decrease the amount of video that needs to be encoded and sent to your viewers, saving CPU and bandwidth at the expense of smoothness. A lower value is generally is fine for most content.', + tip: + 'Reducing your framerate will decrease the amount of video that needs to be encoded and sent to your viewers, saving CPU and bandwidth at the expense of smoothness. A lower value is generally is fine for most content.', }, videoBitrate: { min: 600, @@ -150,7 +151,8 @@ export default function VideoVariantForm({ return (

- Learn more about how each of these settings can impact the performance of your server. + Learn more about how each of these settings + can impact the performance of your server.

@@ -161,7 +163,9 @@ export default function VideoVariantForm({ defaultValue={dataState.cpuUsageLevel} onChange={handleVideoCpuUsageLevelChange} /> -

Read more about CPU usage.

+

+ Read more about CPU usage. +

{/* VIDEO PASSTHROUGH FIELD - currently disabled */} @@ -179,8 +183,9 @@ export default function VideoVariantForm({
{/* VIDEO BITRATE FIELD */}
Video Bitrate

{VIDEO_VARIANT_DEFAULTS.videoBitrate.tip}

@@ -198,7 +203,9 @@ export default function VideoVariantForm({ />

{selectedVideoBRnote()}

-

Read more about bitrates.

+

+ Read more about bitrates. +

@@ -241,7 +248,9 @@ export default function VideoVariantForm({ />

{selectedFramerateNote()}

-

Read more about framerates.

+

+ Read more about framerates. +

diff --git a/web/pages/config-video.tsx b/web/pages/config-video.tsx index d6e3bf39c..a62bfb936 100644 --- a/web/pages/config-video.tsx +++ b/web/pages/config-video.tsx @@ -12,8 +12,10 @@ export default function ConfigVideoSettings() { Video configuration

Before changing your video configuration{' '} - visit the video documentation to learn - how it impacts your stream performance. The general rule is to start conservatively by having one middle quality stream output variant and experiment with adding more of varied qualities. + visit the video documentation to learn how + it impacts your stream performance. The general rule is to start conservatively by having + one middle quality stream output variant and experiment with adding more of varied + qualities.

diff --git a/web/styles/config-video-variants.scss b/web/styles/config-video-variants.scss index 32b29d67b..a0d57711c 100644 --- a/web/styles/config-video-variants.scss +++ b/web/styles/config-video-variants.scss @@ -1,7 +1,6 @@ // styles for Video variant editor (table + modal) .config-video-variants { - .variants-table { margin-top: 2em; } @@ -9,7 +8,6 @@ .variants-table-module { min-width: 400px; } - } // modal content @@ -28,7 +26,6 @@ } } - .variants-table { .actions { display: flex; @@ -36,11 +33,11 @@ justify-content: center; } .delete-button { - margin-left: .5em; - opacity: .8; + margin-left: 0.5em; + opacity: 0.8; } } .read-more-subtext { font-size: 0.8rem; -} \ No newline at end of file +} From 2c7f59dd2a2a69486d2511ea9294b9b2c2979476 Mon Sep 17 00:00:00 2001 From: gingervitis Date: Mon, 15 Feb 2021 16:17:46 -0800 Subject: [PATCH 19/23] fix textfield icon color --- web/styles/ant-overrides.scss | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/web/styles/ant-overrides.scss b/web/styles/ant-overrides.scss index 07277346d..53a52097d 100644 --- a/web/styles/ant-overrides.scss +++ b/web/styles/ant-overrides.scss @@ -236,13 +236,24 @@ textarea.ant-input { border-color: var(--owncast-purple); } } -.ant-input-textarea-clear-icon, -.ant-input-clear-icon { - color: var(--white-55); -} + 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 { From f8f757e49a571afcc7f3d0d36d4347eeed3ac09e Mon Sep 17 00:00:00 2001 From: gingervitis Date: Mon, 15 Feb 2021 16:35:39 -0800 Subject: [PATCH 20/23] quick color fixes --- web/styles/ant-overrides.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/web/styles/ant-overrides.scss b/web/styles/ant-overrides.scss index 53a52097d..587558fca 100644 --- a/web/styles/ant-overrides.scss +++ b/web/styles/ant-overrides.scss @@ -482,6 +482,7 @@ textarea.ant-input { .ant-tag-red, .ant-tag-orange, .ant-tag-green, +.ant-tag-purple, .ant-tag-blue { background-color: var(--black); } From 1a0339e64e591cf8c43ba816fac393c4706a9ac1 Mon Sep 17 00:00:00 2001 From: gingervitis Date: Tue, 16 Feb 2021 00:36:21 +0000 Subject: [PATCH 21/23] Prettified Code! --- web/styles/ant-overrides.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/web/styles/ant-overrides.scss b/web/styles/ant-overrides.scss index 587558fca..5ba431166 100644 --- a/web/styles/ant-overrides.scss +++ b/web/styles/ant-overrides.scss @@ -254,7 +254,6 @@ textarea.ant-input { } } - // ANT BUTTON .ant-btn { background-color: var(--owncast-purple-25); From dd1cfb64dbcbd24620e32a9fbf70a8b0811ff196 Mon Sep 17 00:00:00 2001 From: gingervitis Date: Mon, 15 Feb 2021 21:22:17 -0800 Subject: [PATCH 22/23] - add s to areas with s for consitency - give main content a fixed width so really wide forms dont look that funny - fix to make markdown editor preview text black to address https://github.com/owncast/owncast/issues/726 --- web/docs/README.md | 2 +- web/pages/hardware-info.tsx | 60 ++++++++++++++++++--------------- web/pages/viewer-info.tsx | 34 +++++++++++-------- web/styles/home.scss | 2 -- web/styles/main-layout.scss | 3 ++ web/styles/markdown-editor.scss | 3 +- 6 files changed, 59 insertions(+), 45 deletions(-) diff --git a/web/docs/README.md b/web/docs/README.md index 1750b5ded..6515b560e 100644 --- a/web/docs/README.md +++ b/web/docs/README.md @@ -4,7 +4,7 @@ - Give your page or form a title. Feel free to use Ant Design's `` component. - Give your form a description inside of a `<p className="description" />` tag. -- Use some Ant Design `Row` and `Col`'s to layout your forms if you want to spread them out into responsive columns. +- Use some Ant Design `Row` and `Col`'s to layout your forms if you want to spread them out into responsive columns. If you use an `<Row>`s, be sure to use `<Col>`s with them too! - Use the `form-module` CSS class if you want to add a visual separation to a grouping of items. diff --git a/web/pages/hardware-info.tsx b/web/pages/hardware-info.tsx index 3bff965ea..bb2a3779f 100644 --- a/web/pages/hardware-info.tsx +++ b/web/pages/hardware-info.tsx @@ -1,5 +1,5 @@ import { BulbOutlined, LaptopOutlined, SaveOutlined } from '@ant-design/icons'; -import { Row, Typography } from 'antd'; +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'; @@ -67,39 +67,45 @@ export default function HardwareInfo() { ]; return ( - <div> + <> <Typography.Title>Hardware Info</Typography.Title> <br /> <div> <Row gutter={[16, 16]} justify="space-around"> - <StatisticItem - title={series[0].name} - value={`${currentCPUUsage}`} - prefix={<LaptopOutlined style={{ color: series[0].color }} />} - color={series[0].color} - progress - centered - /> - <StatisticItem - title={series[1].name} - value={`${currentRamUsage}`} - prefix={<BulbOutlined style={{ color: series[1].color }} />} - color={series[1].color} - progress - centered - /> - <StatisticItem - title={series[2].name} - value={`${currentDiskUsage}`} - prefix={<SaveOutlined style={{ color: series[2].color }} />} - color={series[2].color} - progress - centered - /> + <Col> + <StatisticItem + title={series[0].name} + value={`${currentCPUUsage}`} + prefix={<LaptopOutlined style={{ color: series[0].color }} />} + color={series[0].color} + progress + centered + /> + </Col> + <Col> + <StatisticItem + title={series[1].name} + value={`${currentRamUsage}`} + prefix={<BulbOutlined style={{ color: series[1].color }} />} + color={series[1].color} + progress + centered + /> + </Col> + <Col> + <StatisticItem + title={series[2].name} + value={`${currentDiskUsage}`} + prefix={<SaveOutlined style={{ color: series[2].color }} />} + color={series[2].color} + progress + centered + /> + </Col> </Row> <Chart title="% used" dataCollections={series} color="#FF7700" unit="%" /> </div> - </div> + </> ); } diff --git a/web/pages/viewer-info.tsx b/web/pages/viewer-info.tsx index eaa73a8eb..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, Typography } 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'; @@ -99,22 +99,28 @@ export default function ViewersOverTime() { <br /> <Row gutter={[16, 16]} justify="space-around"> {online && ( + <Col span={8} md={8}> + <StatisticItem + title="Current viewers" + value={viewerCount.toString()} + prefix={<UserOutlined />} + /> + </Col> + )} + <Col md={online ? 8 : 12}> <StatisticItem - title="Current viewers" - value={viewerCount.toString()} + title={online ? 'Max viewers this session' : 'Max viewers last session'} + value={sessionPeakViewerCount.toString()} prefix={<UserOutlined />} /> - )} - <StatisticItem - title={online ? 'Max viewers this session' : 'Max viewers last session'} - value={sessionPeakViewerCount.toString()} - prefix={<UserOutlined />} - /> - <StatisticItem - title="All-time max viewers" - value={overallPeakViewerCount.toString()} - prefix={<UserOutlined />} - /> + </Col> + <Col md={online ? 8 : 12}> + <StatisticItem + title="All-time max viewers" + value={overallPeakViewerCount.toString()} + prefix={<UserOutlined />} + /> + </Col> </Row> <Chart title="Viewers" data={viewerInfo} color="#2087E2" unit="" /> diff --git a/web/styles/home.scss b/web/styles/home.scss index 19477b914..7a5a211a4 100644 --- a/web/styles/home.scss +++ b/web/styles/home.scss @@ -1,6 +1,4 @@ .home-container { - max-width: 1000px; - .online-status-section { margin-bottom: 1em; .online-details-card { diff --git a/web/styles/main-layout.scss b/web/styles/main-layout.scss index 9878c4099..2a67831cf 100644 --- a/web/styles/main-layout.scss +++ b/web/styles/main-layout.scss @@ -49,6 +49,9 @@ .main-content-container { padding: 2em 3em 3em; + max-width: 1024px; + min-width: 50vw; + margin: auto; } .footer-container { diff --git a/web/styles/markdown-editor.scss b/web/styles/markdown-editor.scss index c688a7a63..b6ac25ad8 100644 --- a/web/styles/markdown-editor.scss +++ b/web/styles/markdown-editor.scss @@ -32,6 +32,8 @@ // Custom CSS for formatting the preview text .markdown-editor-preview-pane { + color: var(--black-75); + a { color: var(--owncast-purple); } @@ -49,7 +51,6 @@ } - // Set the background color of the editor text input textarea { background-color: var(--gray) !important; From a5303e64cbe6428d3075bfa9c70361d21404f248 Mon Sep 17 00:00:00 2001 From: gingervitis <gingervitis@users.noreply.github.com> Date: Tue, 16 Feb 2021 05:24:11 +0000 Subject: [PATCH 23/23] Prettified Code! --- web/styles/markdown-editor.scss | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/web/styles/markdown-editor.scss b/web/styles/markdown-editor.scss index b6ac25ad8..15fa84cf0 100644 --- a/web/styles/markdown-editor.scss +++ b/web/styles/markdown-editor.scss @@ -1,4 +1,3 @@ - // markdown editor overrides .rc-virtual-list-scrollbar { @@ -17,17 +16,17 @@ p { color: var(--black-75); } - background-color: rgba(226,232,240, 1) !important; + background-color: rgba(226, 232, 240, 1) !important; .sec-html { background-color: white; - pre,code { + pre, + code { background-color: #eee; color: #900; } } - } // Custom CSS for formatting the preview text @@ -44,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: var(--gray) !important; - color: rgba(255,255,255,.5) !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; } }