cleanup some forms; break out major config styles into their own files
This commit is contained in:
@@ -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}
|
||||
|
||||
@@ -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 = '';
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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: '',
|
||||
|
||||
Reference in New Issue
Block a user