cleanup some forms; break out major config styles into their own files

This commit is contained in:
gingervitis
2021-02-04 08:04:00 -08:00
parent e8c24fd2d4
commit 6e43870d41
18 changed files with 374 additions and 530 deletions

View File

@@ -41,14 +41,14 @@ export default function CPUUsageSelector({ defaultValue, onChange }) {
};
return (
<div className="module-container config-video-segements-conatiner">
<div className="config-video-segements-conatiner">
<Title level={3}>CPU Usage</Title>
<p>There are trade-offs when considering CPU usage blah blah more wording here.</p>
<br />
<br />
<div className="segment-slider">
<div className="segment-slider-container">
<Slider
tipFormatter={value => TOOLTIPS[value] }
tipFormatter={value => TOOLTIPS[value]}
onChange={handleChange}
min={1}
max={Object.keys(SLIDER_MARKS).length}

View File

@@ -51,8 +51,8 @@ export default function EditInstanceDetails() {
};
const showConfigurationRestartMessage = () => {
setMessage('Updating server settings requires a restart of your Owncast server.')
}
setMessage('Updating server settings requires a restart of your Owncast server.');
};
function generateStreamKey() {
let key = '';

View File

@@ -157,7 +157,7 @@ export default function EditSocialLinks() {
postUpdateToAPI(postData);
};
const handleDeleteItem = index => {
const handleDeleteItem = (index: number) => {
const postData = [...currentSocialHandles];
postData.splice(index, 1);
postUpdateToAPI(postData);

View File

@@ -1,4 +1,4 @@
import { Switch, Button, Collapse, Alert } from 'antd';
import { Switch, Button, Collapse } from 'antd';
import classNames from 'classnames';
import React, { useContext, useState, useEffect } from 'react';
import { UpdateArgs } from '../../../types/config-section';
@@ -32,7 +32,7 @@ function checkSaveable(formValues: any, currentValues: any) {
if (enabled) {
if (!!endpoint && isValidUrl(endpoint) && !!accessKey && !!secret && !!bucket && !!region) {
if (
enabled !== currentValues.enabled ||
enabled !== currentValues.enabled ||
endpoint !== currentValues.endpoint ||
accessKey !== currentValues.accessKey ||
secret !== currentValues.secret ||
@@ -52,13 +52,12 @@ function checkSaveable(formValues: any, currentValues: any) {
export default function EditStorage() {
const [formDataValues, setFormDataValues] = useState(null);
const [submitStatus, setSubmitStatus] = useState<StatusState>(null);
const [saved, setSaved] = useState<Boolean>(false);
const [shouldDisplayForm, setShouldDisplayForm] = useState(false);
const serverStatusData = useContext(ServerStatusContext);
const { serverConfig, setFieldInConfigState } = serverStatusData || {};
const {message, setMessage} = useContext(AlertMessageContext);
const { setMessage: setAlertMessage } = useContext(AlertMessageContext);
const { s3 } = serverConfig;
const {
@@ -117,8 +116,9 @@ export default function EditStorage() {
setFieldInConfigState({ fieldName: 's3', value: postValue, path: '' });
setSubmitStatus(createInputStatus(STATUS_SUCCESS, 'Updated.'));
resetTimer = setTimeout(resetStates, RESET_TIMEOUT);
setSaved(true);
setMessage('Changing your storage configuration will take place the next time you start a new stream.');
setAlertMessage(
'Changing your storage configuration will take place the next time you start a new stream.',
);
},
onError: (message: string) => {
setSubmitStatus(createInputStatus(STATUS_ERROR, message));
@@ -131,12 +131,6 @@ export default function EditStorage() {
const handleSwitchChange = (storageEnabled: boolean) => {
setShouldDisplayForm(storageEnabled);
handleFieldChange({ fieldName: 'enabled', value: storageEnabled });
// if current data in current store says s3 is enabled,
// we should save this state
// if (!storageEnabled && s3.enabled) {
// handleSave();
// }
};
const containerClass = classNames({

View File

@@ -11,7 +11,7 @@ interface DropdownProps {
}
export default function SocialDropdown({ iconList, selectedOption, onSelected }: DropdownProps) {
const handleSelected = value => {
const handleSelected = (value: string) => {
if (onSelected) {
onSelected(value);
}

View File

@@ -1,12 +1,15 @@
import React, { useContext, useState, useEffect } from 'react';
import { Typography, Slider } from 'antd';
import { ServerStatusContext } from '../../../utils/server-status-context';
import { API_VIDEO_SEGMENTS, RESET_TIMEOUT, postConfigUpdateToAPI } from './constants';
import {
API_VIDEO_SEGMENTS,
SUCCESS_STATES,
RESET_TIMEOUT,
postConfigUpdateToAPI,
} from './constants';
createInputStatus,
StatusState,
STATUS_ERROR,
STATUS_PROCESSING,
STATUS_SUCCESS,
} from '../../../utils/input-statuses';
import FormStatusIndicator from './form-status-indicator';
const { Title } = Typography;
@@ -37,8 +40,10 @@ function SegmentToolTip({ value }: SegmentToolTipProps) {
}
export default function VideoLatency() {
const [submitStatus, setSubmitStatus] = useState(null);
const [submitStatusMessage, setSubmitStatusMessage] = useState('');
const [submitStatus, setSubmitStatus] = useState<StatusState>(null);
// const [submitStatus, setSubmitStatus] = useState(null);
// const [submitStatusMessage, setSubmitStatusMessage] = useState('');
const [selectedOption, setSelectedOption] = useState(null);
const serverStatusData = useContext(ServerStatusContext);
@@ -57,13 +62,15 @@ export default function VideoLatency() {
const resetStates = () => {
setSubmitStatus(null);
setSubmitStatusMessage('');
// setSubmitStatusMessage('');
resetTimer = null;
clearTimeout(resetTimer);
};
// posts all the variants at once as an array obj
const postUpdateToAPI = async (postValue: any) => {
setSubmitStatus(createInputStatus(STATUS_PROCESSING));
await postConfigUpdateToAPI({
apiPath: API_VIDEO_SEGMENTS,
data: { value: postValue },
@@ -73,34 +80,28 @@ export default function VideoLatency() {
value: postValue,
path: 'videoSettings',
});
setSubmitStatus(createInputStatus(STATUS_SUCCESS, 'Variants updated.'));
setSubmitStatus('success');
setSubmitStatusMessage('Variants updated.');
// setSubmitStatus('success');
// setSubmitStatusMessage('Variants updated.');
resetTimer = setTimeout(resetStates, RESET_TIMEOUT);
},
onError: (message: string) => {
setSubmitStatus('error');
setSubmitStatusMessage(message);
setSubmitStatus(createInputStatus(STATUS_ERROR, message));
// setSubmitStatus('error');
// setSubmitStatusMessage(message);
resetTimer = setTimeout(resetStates, RESET_TIMEOUT);
},
});
};
const { icon: newStatusIcon = null, message: newStatusMessage = '' } =
SUCCESS_STATES[submitStatus] || {};
const statusMessage = (
<div className={`status-message ${submitStatus || ''}`}>
{newStatusIcon} {newStatusMessage} {submitStatusMessage}
</div>
);
const handleChange = value => {
postUpdateToAPI(value);
};
return (
<div className="module-container config-video-segements-conatiner">
<div className="config-video-segements-conatiner">
<Title level={3}>Latency Buffer</Title>
<p>
There are trade-offs when cosidering video latency and reliability. Blah blah .. better
@@ -108,7 +109,7 @@ export default function VideoLatency() {
</p>
<br />
<br />
<div className="segment-slider">
<div className="segment-slider-container">
<Slider
tipFormatter={value => <SegmentToolTip value={SLIDER_COMMENTS[value]} />}
onChange={handleChange}
@@ -119,7 +120,7 @@ export default function VideoLatency() {
value={selectedOption}
/>
</div>
{statusMessage}
<FormStatusIndicator status={submitStatus} />
</div>
);
}

View File

@@ -1,12 +1,11 @@
// This content populates the video variant modal, which is spawned from the variants table.
import React from 'react';
import { Slider, Select, Switch, Divider, Collapse } from 'antd';
import { FieldUpdaterFunc, CpuUsageLevel, VideoVariant } from '../../../types/config-section';
import { Slider, Switch, Collapse } from 'antd';
import { FieldUpdaterFunc, VideoVariant } from '../../../types/config-section';
import { DEFAULT_VARIANT_STATE } from './constants';
import InfoTip from '../info-tip';
import CPUUsageSelector from './cpu-usage';
const { Option } = Select;
const { Panel } = Collapse;
const VIDEO_VARIANT_DEFAULTS = {
@@ -57,12 +56,6 @@ export default function VideoVariantForm({
const handleVideoBitrateChange = (value: number) => {
onUpdateField({ fieldName: 'videoBitrate', value });
};
const handleAudioBitrateChange = (value: number) => {
onUpdateField({ fieldName: 'audioBitrate', value });
};
const handleAudioPassChange = (value: boolean) => {
onUpdateField({ fieldName: 'audioPassthrough', value });
};
const handleVideoPassChange = (value: boolean) => {
onUpdateField({ fieldName: 'videoPassthrough', value });
};
@@ -80,18 +73,12 @@ export default function VideoVariantForm({
const videoBRMax = videoBitrateDefaults.max;
const videoBRUnit = videoBitrateDefaults.unit;
const audioBitrateDefaults = VIDEO_VARIANT_DEFAULTS.audioBitrate;
const audioBRMin = audioBitrateDefaults.min;
const audioBRMax = audioBitrateDefaults.max;
const audioBRUnit = audioBitrateDefaults.unit;
const selectedVideoBRnote = `Selected: ${dataState.videoBitrate}${videoBRUnit} - it sucks`;
const selectedAudioBRnote = `Selected: ${dataState.audioBitrate}${audioBRUnit} - too slow`;
const selectedFramerateNote = `Selected: ${dataState.framerate}${framerateUnit} - whoa there`;
const selectedPresetNote = '';
return (
<div className="variant-form">
<div className="config-variant-form">
<div className="section-intro">
Say a thing here about how this all works. Read more{' '}
<a href="https://owncast.online/docs/configuration/">here</a>.
@@ -130,6 +117,7 @@ export default function VideoVariantForm({
</div>
</div>
</div>
{/* VIDEO BITRATE FIELD */}
<div className={`field ${dataState.videoPassthrough ? 'disabled' : ''}`}>
<p className="label">
@@ -192,55 +180,6 @@ export default function VideoVariantForm({
) : null}
</div>
</div>
<Divider />
{/* AUDIO PASSTHROUGH FIELD */}
{/* <div className="field">
<p className="label">
<InfoTip tip={VIDEO_VARIANT_DEFAULTS.audioPassthrough.tip} />
Use Audio Passthrough?
</p>
<div className="form-component">
<Switch
defaultChecked={dataState.audioPassthrough}
checked={dataState.audioPassthrough}
onChange={handleAudioPassChange}
checkedChildren="Yes"
unCheckedChildren="No"
/>
{dataState.audioPassthrough ? <span className="note">Same as source</span> : null}
</div>
</div> */}
{/* AUDIO BITRATE FIELD */}
{/* <div className={`field ${dataState.audioPassthrough ? 'disabled' : ''}`}>
<p className="label">
<InfoTip tip={VIDEO_VARIANT_DEFAULTS.audioBitrate.tip} />
Audio Bitrate:
</p>
<div className="form-component">
<Slider
// tooltipVisible={dataState.audioPassthrough !== true}
tipFormatter={value => `${value} ${audioBRUnit}`}
disabled={dataState.audioPassthrough === true}
defaultValue={dataState.audioBitrate}
value={dataState.audioBitrate}
onChange={handleAudioBitrateChange}
step={audioBitrateDefaults.incrementBy}
min={audioBRMin}
max={audioBRMax}
marks={{
[audioBRMin]: `${audioBRMin} ${audioBRUnit}`,
[audioBRMax]: `${audioBRMax} ${audioBRUnit}`,
}}
/>
{selectedAudioBRnote ? (
<span className="selected-value-note">{selectedAudioBRnote}</span>
) : null}
</div>
</div> */}
</Panel>
</Collapse>
</div>

View File

@@ -1,6 +1,5 @@
// Updating a variant will post ALL the variants in an array as an update to the API.
// todo : add DELETE option
import React, { useContext, useState } from 'react';
import { Typography, Table, Modal, Button } from 'antd';
import { ColumnsType } from 'antd/lib/table';
@@ -20,11 +19,19 @@ import {
const { Title } = Typography;
const CPU_USAGE_LEVEL_MAP = {
1: 'lowest',
2: 'low',
3: 'medium',
4: 'high',
5: 'highest',
};
export default function CurrentVariantsTable() {
const [displayModal, setDisplayModal] = useState(false);
const [modalProcessing, setModalProcessing] = useState(false);
const [editId, setEditId] = useState(0);
const {setMessage} = useContext(AlertMessageContext);
const { setMessage } = useContext(AlertMessageContext);
// current data inside modal
const [modalDataState, setModalDataState] = useState(DEFAULT_VARIANT_STATE);
@@ -76,7 +83,9 @@ export default function CurrentVariantsTable() {
setSubmitStatusMessage('Variants updated.');
resetTimer = setTimeout(resetStates, RESET_TIMEOUT);
setMessage('Updating your video configuration will take effect the next time you begin a new stream.');
setMessage(
'Updating your video configuration will take effect the next time you begin a new stream.',
);
},
onError: (message: string) => {
setSubmitStatus('error');
@@ -117,14 +126,6 @@ export default function CurrentVariantsTable() {
const { icon: newStatusIcon = null, message: newStatusMessage = '' } =
SUCCESS_STATES[submitStatus] || {};
const cpuUsageLevelLabelMap = {
1: 'lowest',
2: 'low',
3: 'medium',
4: 'high',
5: 'highest',
};
const videoQualityColumns: ColumnsType<VideoVariant> = [
{
title: 'Video bitrate',
@@ -137,7 +138,7 @@ export default function CurrentVariantsTable() {
title: 'CPU Usage',
dataIndex: 'cpuUsageLevel',
key: 'cpuUsageLevel',
render: (level: string) => (!level ? 'n/a' : cpuUsageLevelLabelMap[level]),
render: (level: string) => (!level ? 'n/a' : CPU_USAGE_LEVEL_MAP[level]),
},
{
title: '',