From 438161b373ee6f373b5b1d11736ac51fee060b32 Mon Sep 17 00:00:00 2001 From: nebunez Date: Sat, 30 Jan 2021 22:25:44 -0500 Subject: [PATCH] Add random streamkey generation and copy key closes #616 --- .../components/config/edit-server-details.tsx | 45 +++++++++++++++++++ .../components/config/form-textfield.tsx | 23 +++++----- 2 files changed, 58 insertions(+), 10 deletions(-) diff --git a/web/pages/components/config/edit-server-details.tsx b/web/pages/components/config/edit-server-details.tsx index 79c465afb..de1f56d5b 100644 --- a/web/pages/components/config/edit-server-details.tsx +++ b/web/pages/components/config/edit-server-details.tsx @@ -1,4 +1,7 @@ import React, { useState, useContext, useEffect } from 'react'; +import { Button, Input, Tooltip } from 'antd'; +import { CopyOutlined, RedoOutlined } from '@ant-design/icons'; + import TextField, { TEXTFIELD_TYPE_NUMBER, TEXTFIELD_TYPE_PASSWORD } from './form-textfield'; import { ServerStatusContext } from '../../../utils/server-status-context'; @@ -14,6 +17,10 @@ export default function EditInstanceDetails() { const { streamKey, ffmpegPath, rtmpServerPort, webServerPort } = serverConfig; + const [copyIsVisible, setCopyVisible] = useState(false); + + const COPY_TOOLTIP_TIMEOUT = 3000; + useEffect(() => { setFormDataValues({ streamKey, ffmpegPath, rtmpServerPort, webServerPort @@ -31,6 +38,23 @@ export default function EditInstanceDetails() { }); } + function generateStreamKey () { + let key = ''; + for (let i = 0; i < 3; i+=1) { + key += Math.random().toString(36).substring(2); + } + + handleFieldChange({ fieldName: 'streamKey', value: key }); + } + + function copyStreamKey () { + navigator.clipboard.writeText(formDataValues.streamKey) + .then(() => { + setCopyVisible(true); + setTimeout(() => setCopyVisible(false), COPY_TOOLTIP_TIMEOUT); + }); + } + return (
@@ -42,6 +66,27 @@ export default function EditInstanceDetails() { type={TEXTFIELD_TYPE_PASSWORD} onChange={handleFieldChange} /> +
+ + Save this key somewhere safe, + you will need it to stream or login to the admin dashboard! + + +
(''); const [submitStatusMessage, setSubmitStatusMessage] = useState(''); const [hasChanged, setHasChanged] = useState(false); - const [fieldValueForSubmit, setFieldValueForSubmit] = useState(''); + const [fieldValueForSubmit, setFieldValueForSubmit] = useState(''); const serverStatusData = useContext(ServerStatusContext); const { setFieldInConfigState } = serverStatusData || {}; @@ -71,21 +71,24 @@ export default function TextField(props: TextFieldProps) { resetTimer = null; }; - // if field is required but value is empty, or equals initial value, then don't show submit/update button. otherwise clear out any result messaging and display button. - const handleChange = (e: any) => { - const val = type === TEXTFIELD_TYPE_NUMBER ? e : e.target.value; - + useEffect(() => { + // TODO: Add native validity checks here, somehow // https://developer.mozilla.org/en-US/docs/Web/API/ValidityState - const hasValidity = (type !== TEXTFIELD_TYPE_NUMBER && e.target.validity.valid) || type === TEXTFIELD_TYPE_NUMBER ; - - if ((required && (val === '' || val === null)) || val === initialValue || !hasValidity) { + // const hasValidity = (type !== TEXTFIELD_TYPE_NUMBER && e.target.validity.valid) || type === TEXTFIELD_TYPE_NUMBER ; + if ((required && (value === '' || value === null)) || value === initialValue) { setHasChanged(false); } else { // show submit button resetStates(); setHasChanged(true); - setFieldValueForSubmit(val); + setFieldValueForSubmit(value); } + }, [value]); + + // if field is required but value is empty, or equals initial value, then don't show submit/update button. otherwise clear out any result messaging and display button. + const handleChange = (e: any) => { + const val = type === TEXTFIELD_TYPE_NUMBER ? e : e.target.value; + // if an extra onChange handler was sent in as a prop, let's run that too. if (onChange) { onChange({ fieldName, value: val });