diff --git a/web/.eslintrc.js b/web/.eslintrc.js index 960aa2bb7..c5f1d70fe 100644 --- a/web/.eslintrc.js +++ b/web/.eslintrc.js @@ -21,6 +21,7 @@ module.exports = { 'no-unused-vars': 'off', '@typescript-eslint/no-unused-vars': 'error', + 'no-console': 'off', 'no-use-before-define': [0], '@typescript-eslint/no-use-before-define': [1], diff --git a/web/components/chart.tsx b/web/components/chart.tsx index 6fcc06806..a97520c34 100644 --- a/web/components/chart.tsx +++ b/web/components/chart.tsx @@ -1,7 +1,10 @@ -import { LineChart } from 'react-chartkick'; -import 'chartkick/chart.js' - +import ChartJs from 'chart.js/auto'; +import Chartkick from 'chartkick'; import format from 'date-fns/format'; +import { LineChart } from 'react-chartkick'; + +// from https://github.com/ankane/chartkick.js/blob/master/chart.js/chart.esm.js +Chartkick.use(ChartJs); interface TimedValue { time: Date; diff --git a/web/components/config/edit-custom-css.tsx b/web/components/config/edit-custom-css.tsx index d309c35f1..8134a9759 100644 --- a/web/components/config/edit-custom-css.tsx +++ b/web/components/config/edit-custom-css.tsx @@ -86,13 +86,10 @@ export default function EditCustomStyles() {

Customize the look and feel of your Owncast instance by overriding the CSS styles of various components on the page. Refer to the{' '} - + CSS & Components guide - . + + .

Please input plain CSS text, as this will be directly injected onto your page during load. diff --git a/web/components/config/edit-logo.tsx b/web/components/config/edit-logo.tsx index ca1bdeecb..c92189e3d 100644 --- a/web/components/config/edit-logo.tsx +++ b/web/components/config/edit-logo.tsx @@ -91,7 +91,7 @@ export default function EditLogo() { } }; - const logoDisplayUrl = NEXT_PUBLIC_API_HOST + 'logo?random=' + logoCachedbuster; + const logoDisplayUrl = `${NEXT_PUBLIC_API_HOST}logo?random=${logoCachedbuster}`; return (

diff --git a/web/components/config/edit-social-links.tsx b/web/components/config/edit-social-links.tsx index dc00563e3..d92c8f351 100644 --- a/web/components/config/edit-social-links.tsx +++ b/web/components/config/edit-social-links.tsx @@ -3,7 +3,7 @@ import { Typography, Table, Button, Modal, Input } from 'antd'; import { ColumnsType } from 'antd/lib/table'; import { DeleteOutlined } from '@ant-design/icons'; import SocialDropdown from './social-icons-dropdown'; -import { fetchData, SOCIAL_PLATFORMS_LIST } from '../../utils/apis'; +import { fetchData, SOCIAL_PLATFORMS_LIST, NEXT_PUBLIC_API_HOST } from '../../utils/apis'; import { ServerStatusContext } from '../../utils/server-status-context'; import { API_SOCIAL_HANDLES, @@ -17,7 +17,6 @@ import isValidUrl, { DEFAULT_TEXTFIELD_URL_PATTERN } from '../../utils/urls'; import TextField from './form-textfield'; import { createInputStatus, STATUS_ERROR, STATUS_SUCCESS } from '../../utils/input-statuses'; import FormStatusIndicator from './form-status-indicator'; -import { NEXT_PUBLIC_API_HOST } from '../../utils/apis'; const { Title } = Typography; @@ -62,9 +61,8 @@ export default function EditSocialLinks() { } }; - const isPredefinedSocial = (platform: string) => { - return availableIconsList.find(item => item.key === platform) || false; - }; + const isPredefinedSocial = (platform: string) => + availableIconsList.find(item => item.key === platform) || false; const selectedOther = modalDataState.platform !== '' && @@ -192,7 +190,7 @@ export default function EditSocialLinks() { ); } const { icon, platform: platformName } = platformInfo; - const iconUrl = NEXT_PUBLIC_API_HOST + `${icon.slice(1)}`; + const iconUrl = `${NEXT_PUBLIC_API_HOST}${icon.slice(1)}`; return (
diff --git a/web/components/config/edit-tags.tsx b/web/components/config/edit-tags.tsx index 5cfeeb46d..27441945c 100644 --- a/web/components/config/edit-tags.tsx +++ b/web/components/config/edit-tags.tsx @@ -37,11 +37,12 @@ export default function EditInstanceTags() { let resetTimer = null; - useEffect(() => { - return () => { + useEffect( + () => () => { clearTimeout(resetTimer); - }; - }, []); + }, + [], + ); const resetStates = () => { setSubmitStatus(null); diff --git a/web/components/config/form-textfield-with-submit.tsx b/web/components/config/form-textfield-with-submit.tsx index 63ed87495..23a9175ad 100644 --- a/web/components/config/form-textfield-with-submit.tsx +++ b/web/components/config/form-textfield-with-submit.tsx @@ -1,10 +1,8 @@ -import React, { useEffect, useState, useContext } from 'react'; import { Button } from 'antd'; import classNames from 'classnames'; -import { RESET_TIMEOUT, postConfigUpdateToAPI } from '../../utils/config-constants'; - -import { ServerStatusContext } from '../../utils/server-status-context'; -import TextField, { TextFieldProps } from './form-textfield'; +import React, { useContext, useEffect, useState } from 'react'; +import { UpdateArgs } from '../../types/config-section'; +import { postConfigUpdateToAPI, RESET_TIMEOUT } from '../../utils/config-constants'; import { createInputStatus, StatusState, @@ -12,8 +10,9 @@ import { STATUS_PROCESSING, STATUS_SUCCESS, } from '../../utils/input-statuses'; -import { UpdateArgs } from '../../types/config-section'; +import { ServerStatusContext } from '../../utils/server-status-context'; import FormStatusIndicator from './form-status-indicator'; +import TextField, { TextFieldProps } from './form-textfield'; export const TEXTFIELD_TYPE_TEXT = 'default'; export const TEXTFIELD_TYPE_PASSWORD = 'password'; // Input.Password @@ -72,13 +71,15 @@ export default function TextFieldWithSubmit(props: TextFieldWithSubmitProps) { // 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 = ({ fieldName: changedFieldName, value: changedValue }: UpdateArgs) => { if (onChange) { + let newValue: string = changedValue; + if (useTrim) { + newValue = changedValue.trim(); + } else if (useTrimLead) { + newValue = changedValue.replace(/^\s+/g, ''); + } onChange({ fieldName: changedFieldName, - value: useTrim - ? changedValue.trim() - : useTrimLead - ? changedValue.replace(/^\s+/g, '') - : changedValue, + value: newValue, }); } }; diff --git a/web/components/config/social-icons-dropdown.tsx b/web/components/config/social-icons-dropdown.tsx index cb2bc4e55..feb540655 100644 --- a/web/components/config/social-icons-dropdown.tsx +++ b/web/components/config/social-icons-dropdown.tsx @@ -39,7 +39,7 @@ export default function SocialDropdown({ iconList, selectedOption, onSelected }: > {iconList.map(item => { const { platform, icon, key } = item; - const iconUrl = NEXT_PUBLIC_API_HOST + `${icon.slice(1)}`; + const iconUrl = `${NEXT_PUBLIC_API_HOST}${icon.slice(1)}`; return ( diff --git a/web/components/config/video-codec-selector.tsx b/web/components/config/video-codec-selector.tsx index 6a9489f39..bbd9bef8f 100644 --- a/web/components/config/video-codec-selector.tsx +++ b/web/components/config/video-codec-selector.tsx @@ -1,19 +1,18 @@ -import React, { useContext, useState, useEffect } from 'react'; -import { Typography, Select, Popconfirm } from 'antd'; -import { ServerStatusContext } from '../../utils/server-status-context'; +import { Popconfirm, Select, Typography } from 'antd'; +import React, { useContext, useEffect, useState } from 'react'; import { AlertMessageContext } from '../../utils/alert-message-context'; import { API_VIDEO_CODEC, - RESET_TIMEOUT, postConfigUpdateToAPI, + RESET_TIMEOUT, } from '../../utils/config-constants'; import { createInputStatus, StatusState, STATUS_ERROR, - STATUS_PROCESSING, STATUS_SUCCESS, } from '../../utils/input-statuses'; +import { ServerStatusContext } from '../../utils/server-status-context'; import FormStatusIndicator from './form-status-indicator'; export default function CodecSelector() { @@ -76,8 +75,8 @@ export default function CodecSelector() { }); } - const items = supportedCodecs.map(function (codec) { - var title = codec; + const items = supportedCodecs.map(codec => { + let title = codec; if (title === 'libx264') { title = 'Default (libx264)'; } else if (title === 'h264_nvenc') { @@ -97,7 +96,7 @@ export default function CodecSelector() { ); }); - var description = ''; + let description = ''; if (selectedCodec === 'libx264') { description = 'libx264 is the default codec and generally the only working choice for shared VPS enviornments. This is likely what you should be using unless you know you have set up other options.'; @@ -138,10 +137,10 @@ export default function CodecSelector() {