From c61e7e9c14150c6708c1870f188ea82f9a08b44a Mon Sep 17 00:00:00 2001 From: gingervitis Date: Sun, 3 Jan 2021 00:29:37 -0800 Subject: [PATCH] - start a README to document config admin later - update constants - add instanceUrl field to public details; if empty, then turn off yp.enabled. - edit YP/Directory settings; hide if instanceUrl is empty - update toggleswitch logic --- .../components/config/edit-directory.tsx | 2 +- web/pages/config-public-details.tsx | 63 ++++++++++++---- web/pages/config-server-details.tsx | 23 +++--- web/styles/config.scss | 71 +++++++++++-------- web/styles/globals.scss | 20 +++++- web/types/config-section.ts | 51 ++++++++++++- web/utils/server-status-context.tsx | 16 ++++- 7 files changed, 188 insertions(+), 58 deletions(-) diff --git a/web/pages/components/config/edit-directory.tsx b/web/pages/components/config/edit-directory.tsx index c2e1d5c1a..e7d530903 100644 --- a/web/pages/components/config/edit-directory.tsx +++ b/web/pages/components/config/edit-directory.tsx @@ -1,4 +1,4 @@ -// rename to "directory" +// Note: references to "yp" in the app are likely related to Owncast Directory import React, { useContext, useEffect } from 'react'; import { Typography, Form } from 'antd'; diff --git a/web/pages/config-public-details.tsx b/web/pages/config-public-details.tsx index 9394019df..e19d1ec77 100644 --- a/web/pages/config-public-details.tsx +++ b/web/pages/config-public-details.tsx @@ -3,9 +3,11 @@ import { Typography, Form } from 'antd'; import TextField, { TEXTFIELD_TYPE_TEXTAREA } from './components/config/form-textfield'; -import EditInstanceTags from './components/config/tags'; +import EditInstanceTags from './components/config/edit-tags'; +import EditDirectoryDetails from './components/config/edit-directory'; import { ServerStatusContext } from '../utils/server-status-context'; +import { TEXTFIELD_DEFAULTS, postConfigUpdateToAPI } from './components/config/constants'; const { Title } = Typography; @@ -15,25 +17,50 @@ export default function PublicFacingDetails() { const serverStatusData = useContext(ServerStatusContext); const { serverConfig } = serverStatusData || {}; - const { instanceDetails = {} } = serverConfig; - console.log(serverConfig) - + const { instanceDetails, yp } = serverConfig; + const { instanceDetails: instanceDetailsDefaults, yp: ypDefaults } = TEXTFIELD_DEFAULTS; + + const initialValues = { + ...instanceDetails, + ...yp, + }; + + const defaultFields = { + ...instanceDetailsDefaults, + ...ypDefaults, + }; + useEffect(() => { - form.setFieldsValue({...instanceDetails}); + form.setFieldsValue(initialValues); }, [instanceDetails]); - const handleResetValue = (fieldName: string) => { - form.setFieldsValue({ [fieldName]: instanceDetails[fieldName]}); + const defaultValue = defaultFields[fieldName] && defaultFields[fieldName].defaultValue || ''; + + form.setFieldsValue({ [fieldName]: initialValues[fieldName] || defaultValue }); + } + + // if instanceUrl is empty, we should also turn OFF the `enabled` field of directory. + const handleSubmitInstanceUrl = () => { + if (form.getFieldValue('instanceUrl') === '') { + if (yp.enabled === true) { + const { apiPath } = TEXTFIELD_DEFAULTS.yp.enabled; + postConfigUpdateToAPI({ + apiPath, + data: { value: false }, + }); + } + } } const extraProps = { handleResetValue, - initialValues: instanceDetails, + initialValues, + configPath: 'instanceDetails', }; return ( - <> +
Edit your public facing instance details
@@ -42,10 +69,18 @@ export default function PublicFacingDetails() { form={form} layout="vertical" > - - + + + + +
@@ -53,11 +88,11 @@ export default function PublicFacingDetails() {
add tags comp */} - - +

+
- + ); } diff --git a/web/pages/config-server-details.tsx b/web/pages/config-server-details.tsx index 41f7fd8ea..1f89fccb0 100644 --- a/web/pages/config-server-details.tsx +++ b/web/pages/config-server-details.tsx @@ -4,6 +4,7 @@ import { Typography, Form } from 'antd'; import TextField, { TEXTFIELD_TYPE_NUMBER, TEXTFIELD_TYPE_PASSWORD, TEXTFIELD_TYPE_TEXTAREA } from './components/config/form-textfield'; import { ServerStatusContext } from '../utils/server-status-context'; +import { TEXTFIELD_DEFAULTS } from './components/config/constants'; const { Title } = Typography; @@ -13,27 +14,30 @@ export default function ConfigServerDetails() { const serverStatusData = useContext(ServerStatusContext); const { serverConfig } = serverStatusData || {}; - const { ffmpegPath, streamKey, webServerPort } = serverConfig; + const { ffmpegPath, streamKey, webServerPort, rtmpServerPort } = serverConfig; - const streamDetails = { - ffmpegPath, streamKey, webServerPort + const initialValues = { + ffmpegPath, + streamKey, + webServerPort, + rtmpServerPort, }; useEffect(() => { - form.setFieldsValue({...streamDetails}); + form.setFieldsValue(initialValues); }, [serverStatusData]); - const handleResetValue = (fieldName: string) => { - form.setFieldsValue({ [fieldName]: streamDetails[fieldName]}); + const defaultValue = TEXTFIELD_DEFAULTS[fieldName] && TEXTFIELD_DEFAULTS[fieldName].defaultValue || ''; + + form.setFieldsValue({ [fieldName]: initialValues[fieldName] || defaultValue }); } const extraProps = { handleResetValue, - initialValues: streamDetails, + initialValues, + configPath: '', }; - - console.log(streamDetails) return ( <> Edit your Server's details @@ -46,6 +50,7 @@ export default function ConfigServerDetails() { + diff --git a/web/styles/config.scss b/web/styles/config.scss index d24b6761f..6c79c2165 100644 --- a/web/styles/config.scss +++ b/web/styles/config.scss @@ -1,16 +1,3 @@ - -.ant-btn-primary:hover, .ant-btn-primary:focus { - background-color: white; - color: #40a9ff; -} -.ant-btn-primary:focus { - box-shadow: 0px 1px 3px 2px rgba(90,103,216, .25) -} -.ant-input-affix-wrapper, -.ant-btn { - transition-delay: 0s; - transition-duration: 0.15s; -} .config-public-details-container { display: flex; flex-direction: row; @@ -22,19 +9,34 @@ } .misc-fields { - border: 1px solid var(--owncast-purple); + // border: 1px solid var(--owncast-purple); padding: 2em; - } } + + +.status-message { + margin: 1rem 0; + min-height: 1.25em; + font-size: .75rem; + &.success { + color: var(--ant-success); + } + &.error { + color: var(--ant-error); + } +} + +// form-textfield +// form-textfield .textfield-container { display: flex; flex-direction: column; - align-items: flex-end; + align-items: flex-start; justify-content: flex-end; position: relative; + width: 314px; } - .textfield { display: flex; flex-direction: row; @@ -68,6 +70,30 @@ } +// form-toggleswitch +// form-toggleswitch +.toggleswitch-container { + .status-message { + margin-top: .25rem; + } +} +.toggleswitch { + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-start; + .label { + font-weight: bold; + color: var(--owncast-purple); + } + .info { margin-left: .5rem } + .ant-form-item { + margin: 0 .75rem 0 0; + } +} + +// TAGS STUFF +// TAGS STUFF .tag-current-tags { .ant-tag { margin: .1rem; @@ -102,15 +128,4 @@ width: 16em; } } -.add-new-status { - margin: 1em 0; - min-height: 1.25em; - font-size: .75rem; - &.success { - color: var(--ant-success); - } - &.error { - color: var(--ant-error); - } -} diff --git a/web/styles/globals.scss b/web/styles/globals.scss index 49e7e41d8..d74d17bb6 100644 --- a/web/styles/globals.scss +++ b/web/styles/globals.scss @@ -30,10 +30,28 @@ pre { background-color: $owncast-purple; } -// misc system overrides + +// GENERAL ANT FORM OVERRIDES +// GENERAL ANT FORM OVERRIDES .ant-card { border-radius: .5em; } +.ant-btn-primary:hover, .ant-btn-primary:focus { + background-color: white; + color: #40a9ff; +} +.ant-btn.ant-btn-primary:focus { + border: 1px solid var(--owncast-purple); + @media (prefers-color-scheme: dark) { + border-color: white; + } +} +.ant-input-affix-wrapper, +.ant-btn { + transition-delay: 0s; + transition-duration: 0.15s; +} + @media (prefers-color-scheme: dark) { @import "~antd/dist/antd.dark"; diff --git a/web/types/config-section.ts b/web/types/config-section.ts index 522918039..aff704442 100644 --- a/web/types/config-section.ts +++ b/web/types/config-section.ts @@ -1,10 +1,21 @@ // TS types for elements on the Config pages export interface TextFieldProps { - handleResetValue: ({ fieldName }) => void; + handleResetValue?: (fieldName) => void; fieldName: string; - initialValues: any; - type: string; + initialValues?: any; + type?: string; + configPath?: string; + required?: boolean; + disabled?: boolean; + onSubmit?: () => void; +} + +export interface ToggleSwitchProps { + fieldName: string; + initialValues?: any; + configPath?: string; + disabled?: boolean; } export interface UpdateArgs { @@ -12,3 +23,37 @@ export interface UpdateArgs { value: string; path?: string; } + +export interface ApiPostArgs { + apiPath: string, + data: object, + onSuccess?: () => {}, + onError?: () => {}, +} + +export interface ConfigDirectoryFields { + enabled: boolean; + instanceUrl: string, +} + +export interface ConfigInstanceDetailsFields { + extraPageContent: string; + logo: string; + name: string; + nsfw: boolean; + streamTitle: string; + summary: string; + tags: string[]; + title: string; +} + +export interface ConfigDetails { + ffmpegPath: string; + instanceDetails: ConfigInstanceDetailsFields; + rtmpServerPort: string; + s3: any; // tbd + streamKey: string; + webServerPort: string; + yp: ConfigDirectoryFields; + videoSettings: any; // tbd +} \ No newline at end of file diff --git a/web/utils/server-status-context.tsx b/web/utils/server-status-context.tsx index 3eed0cb6e..afc3798ee 100644 --- a/web/utils/server-status-context.tsx +++ b/web/utils/server-status-context.tsx @@ -2,15 +2,27 @@ import React, { useState, useEffect } from 'react'; import PropTypes, { any } from 'prop-types'; import { STATUS, fetchData, FETCH_INTERVAL, SERVER_CONFIG } from './apis'; -import { UpdateArgs } from '../types/config-section'; +import { ConfigDetails, UpdateArgs } from '../types/config-section'; -export const initialServerConfigState = { +export const initialServerConfigState: ConfigDetails = { streamKey: '', instanceDetails: { + extraPageContent: '', + logo: '', + name: '', + nsfw: false, + streamTitle: '', + summary: '', tags: [], + title: '', }, + ffmpegPath: '', + rtmpServerPort: '', + webServerPort: '', + s3: {}, yp: { enabled: false, + instanceUrl: '', }, videoSettings: { videoQualityVariants: [