From 2ddce9b75a3817662025da31a1913ef44aae6cac Mon Sep 17 00:00:00 2001
From: gingervitis
Date: Sat, 16 Jan 2021 19:46:19 -0800
Subject: [PATCH] get variant modal to submit to api and update values
---
web/pages/components/config/constants.tsx | 2 +
.../components/config/video-variant-form.tsx | 33 ++--
.../config/video-variants-table.tsx | 152 ++++++++++++------
web/pages/config-video.tsx | 3 +
web/types/config-section.ts | 8 +-
5 files changed, 136 insertions(+), 62 deletions(-)
diff --git a/web/pages/components/config/constants.tsx b/web/pages/components/config/constants.tsx
index 19108bf8a..5040fac8d 100644
--- a/web/pages/components/config/constants.tsx
+++ b/web/pages/components/config/constants.tsx
@@ -23,6 +23,8 @@ export const SUCCESS_STATES = {
},
};
+// CONFIG API ENDPOINTS
+export const API_VIDEO_VARIANTS = '/video/streamoutputvariants';
export async function postConfigUpdateToAPI(args: ApiPostArgs) {
const {
diff --git a/web/pages/components/config/video-variant-form.tsx b/web/pages/components/config/video-variant-form.tsx
index a4262f8ee..9d78b714f 100644
--- a/web/pages/components/config/video-variant-form.tsx
+++ b/web/pages/components/config/video-variant-form.tsx
@@ -1,6 +1,7 @@
+// 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 { PRESETS, VideoVariant } from '../../../types/config-section';
+import { FieldUpdaterFunc, PRESET, VideoVariant } from '../../../types/config-section';
import { ENCODER_PRESETS, DEFAULT_VARIANT_STATE } from './constants';
import InfoTip from '../info-tip';
@@ -46,29 +47,31 @@ const VIDEO_VARIANT_DEFAULTS = {
interface VideoVariantFormProps {
dataState: VideoVariant;
- onUpdateField: () => void;
+ onUpdateField: FieldUpdaterFunc;
}
export default function VideoVariantForm({ dataState = DEFAULT_VARIANT_STATE, onUpdateField }: VideoVariantFormProps) {
+ console.log("======form", dataState)
+
// const [dataState, setDataState] = useState(initialValues);
const handleFramerateChange = (value: number) => {
- onUpdateField({ fieldname: 'framerate', value });
+ onUpdateField({ fieldName: 'framerate', value });
};
const handleVideoBitrateChange = (value: number) => {
- onUpdateField({ fieldname: 'videoBitrate', value });
+ onUpdateField({ fieldName: 'videoBitrate', value });
};
const handleAudioBitrateChange = (value: number) => {
- onUpdateField({ fieldname: 'audioBitrate', value });
+ onUpdateField({ fieldName: 'audioBitrate', value });
};
- const handleEncoderPresetChange = (value: PRESETS) => {
- onUpdateField({ fieldname: 'encoderPreset', value });
+ const handleEncoderPresetChange = (value: PRESET) => {
+ onUpdateField({ fieldName: 'encoderPreset', value });
};
const handleAudioPassChange = (value: boolean) => {
- onUpdateField({ fieldname: 'audioPassthrough', value });
+ onUpdateField({ fieldName: 'audioPassthrough', value });
};
const handleVideoPassChange = (value: boolean) => {
- onUpdateField({ fieldname: 'videoPassthrough', value });
+ onUpdateField({ fieldName: 'videoPassthrough', value });
};
@@ -109,7 +112,10 @@ export default function VideoVariantForm({ dataState = DEFAULT_VARIANT_STATE, on
Encoder Preset:
-
-
-
diff --git a/web/pages/components/config/video-variants-table.tsx b/web/pages/components/config/video-variants-table.tsx
index 3c38377f3..e7e4ec641 100644
--- a/web/pages/components/config/video-variants-table.tsx
+++ b/web/pages/components/config/video-variants-table.tsx
@@ -3,39 +3,102 @@ import { Typography, Table, Modal, Button } from 'antd';
import { CheckOutlined, CloseOutlined } from '@ant-design/icons';
import { ColumnsType } from 'antd/lib/table';
import { ServerStatusContext } from '../../../utils/server-status-context';
-import { VideoVariant } from '../../../types/config-section';
+import { UpdateArgs, VideoVariant } from '../../../types/config-section';
import VideoVariantForm from './video-variant-form';
-import { DEFAULT_VARIANT_STATE } from './constants';
+import { API_VIDEO_VARIANTS, DEFAULT_VARIANT_STATE, SUCCESS_STATES, RESET_TIMEOUT,postConfigUpdateToAPI } from './constants';
const { Title } = Typography;
export default function CurrentVariantsTable() {
const serverStatusData = useContext(ServerStatusContext);
const [displayModal, setDisplayModal] = useState(false);
+ const [modalProcessing, setModalProcessing] = useState(false);
const [editId, setEditId] = useState(0);
- const [dataState, setDataState] = useState(DEFAULT_VARIANT_STATE);
- const { serverConfig } = serverStatusData || {};
+
+ // current data inside modal
+ const [modalDataState, setModalDataState] = useState(DEFAULT_VARIANT_STATE);
+
+ const [submitStatus, setSubmitStatus] = useState(null);
+ const [submitStatusMessage, setSubmitStatusMessage] = useState('');
+
+ const { serverConfig, setFieldInConfigState } = serverStatusData || {};
const { videoSettings } = serverConfig || {};
const { videoQualityVariants } = videoSettings || {};
+
+ let resetTimer = null;
+
if (!videoSettings) {
return null;
}
- const handleModalOk = () => {
- setDisplayModal(false);
- setEditId(-1);
+ const resetStates = () => {
+ setSubmitStatus(null);
+ setSubmitStatusMessage('');
+ resetTimer = null;
+ clearTimeout(resetTimer);
}
+
const handleModalCancel = () => {
setDisplayModal(false);
setEditId(-1);
+ setModalDataState(DEFAULT_VARIANT_STATE);
+ }
+
+ // posts all the variants at once as an array obj
+ const postUpdateToAPI = async (postValue: any) => {
+ await postConfigUpdateToAPI({
+ apiPath: API_VIDEO_VARIANTS,
+ data: { value: postValue },
+ onSuccess: () => {
+ setFieldInConfigState({ fieldName: 'videoQualityVariants', value: postValue, path: 'videoSettings' });
+
+ // close modal
+ setModalProcessing(false);
+ handleModalCancel();
+
+ setSubmitStatus('success');
+ setSubmitStatusMessage('Variants updated.');
+ resetTimer = setTimeout(resetStates, RESET_TIMEOUT);
+ },
+ onError: (message: string) => {
+ setSubmitStatus('error');
+ setSubmitStatusMessage(message);
+ resetTimer = setTimeout(resetStates, RESET_TIMEOUT);
+ },
+ });
+ };
+
+ // on Ok, send all of dataState to api
+ // show loading
+ // close modal when api is done
+ const handleModalOk = () => {
+ setModalProcessing(true);
+
+ const postData = [
+ ...videoQualityVariants,
+ ];
+ if (editId === -1) {
+ postData.push(modalDataState);
+ } else {
+ postData.splice(editId, 1, modalDataState);
+ }
+ console.log("==== submit postData", postData)
+
+ postUpdateToAPI(postData);
}
- const handleUpdateField = (fieldName: string, value: any) => {
- setDataState({
- ...dataState,
+ const handleUpdateField = ({ fieldName, value }: UpdateArgs) => {
+ console.log("===update field", fieldName, value)
+ setModalDataState({
+ ...modalDataState,
[fieldName]: value,
});
}
+
+ const {
+ icon: newStatusIcon = null,
+ message: newStatusMessage = '',
+ } = SUCCESS_STATES[submitStatus] || {};
const videoQualityColumns: ColumnsType = [
{
@@ -50,13 +113,7 @@ export default function CurrentVariantsTable() {
render: (bitrate: number) =>
!bitrate ? "Same as source" : `${bitrate} kbps`,
},
- // {
- // title: "Framerate",
- // dataIndex: "framerate",
- // key: "framerate",
- // render: (framerate: number) =>
- // !framerate ? "Same as source" : `${framerate} fps`,
- // },
+
{
title: "Encoder preset",
dataIndex: "encoderPreset",
@@ -64,47 +121,38 @@ export default function CurrentVariantsTable() {
render: (preset: string) =>
!preset ? "n/a" : preset,
},
- // {
- // title: "Audio bitrate",
- // dataIndex: "audioBitrate",
- // key: "audioBitrate",
- // render: (bitrate: number) =>
- // !bitrate ? "Same as source" : `${bitrate} kbps`,
- // },
- // {
- // title: "Audio passthrough",
- // dataIndex: "audioPassthrough",
- // key: "audioPassthrough",
- // render: (item: boolean) => item ? : ,
- // },
- // {
- // title: "Video passthrough",
- // dataIndex: "videoPassthrough",
- // key: "audioPassthrough",
- // render: (item: boolean) => item ? : ,
- // },
{
title: '',
dataIndex: '',
key: 'edit',
render: (data: VideoVariant) => (
-
+
),
},
];
+ const statusMessage = (
+
+ {newStatusIcon} {newStatusMessage} {submitStatusMessage}
+
+ );
const videoQualityVariantData = videoQualityVariants.map((variant, index) => ({ key: index + 1, ...variant }));
+ // console.log("=========", { modalDataState })
return (
<>
Current Variants
+ {statusMessage}
+
-
-
-
-
+
+
+ {statusMessage}
+
+
>
);
diff --git a/web/pages/config-video.tsx b/web/pages/config-video.tsx
index f190dccf3..432699afe 100644
--- a/web/pages/config-video.tsx
+++ b/web/pages/config-video.tsx
@@ -43,6 +43,9 @@ export default function VideoConfig() {
Video configuration
Learn more about configuring Owncast by visiting the documentation.
+
+ {JSON.stringify(videoSettings)}
+