import React, { useState, useContext, useEffect, FC } from 'react'; import { Button, Modal, Typography } from 'antd'; import { markdown, markdownLanguage } from '@codemirror/lang-markdown'; import CodeMirror from '@uiw/react-codemirror'; import { bbedit } from '@uiw/codemirror-theme-bbedit'; import { languages } from '@codemirror/language-data'; import { TextFieldWithSubmit, TEXTFIELD_TYPE_TEXTAREA, TEXTFIELD_TYPE_URL, } from '../../TextFieldWithSubmit'; import { ServerStatusContext } from '../../../../utils/server-status-context'; import { postConfigUpdateToAPI, TEXTFIELD_PROPS_INSTANCE_URL, TEXTFIELD_PROPS_SERVER_NAME, TEXTFIELD_PROPS_SERVER_SUMMARY, TEXTFIELD_PROPS_SERVER_OFFLINE_MESSAGE, API_YP_SWITCH, FIELD_PROPS_YP, FIELD_PROPS_NSFW, FIELD_PROPS_HIDE_VIEWER_COUNT, API_SERVER_OFFLINE_MESSAGE, FIELD_PROPS_DISABLE_SEARCH_INDEXING, } from '../../../../utils/config-constants'; import { UpdateArgs } from '../../../../types/config-section'; import { ToggleSwitch } from '../../ToggleSwitch'; import { EditLogo } from '../../EditLogo'; import FormStatusIndicator from '../../FormStatusIndicator'; import { createInputStatus, STATUS_SUCCESS } from '../../../../utils/input-statuses'; const { Title } = Typography; export type DirectoryInfoModalProps = { cancelPressed: () => void; okPressed: () => void; }; const DirectoryInfoModal: FC = ({ cancelPressed, okPressed }) => ( } > What is the Owncast Directory? Owncast operates a public directory at{' '} directory.owncast.online to share your video streams with more people, while also using these as examples for others. Live streams and servers listed on the directory may optionally be shared on other platforms and applications. Disclaimers and Responsibility
  • By enabling this feature you are granting explicit rights to Owncast to share your stream to the public via the directory, as well as other sites, applications and any platform where the Owncast project may be promoting Owncast-powered streams including social media.
  • There is no obligation to list any specific server or topic. Servers can and will be removed at any time for any reason.
  • Any server that is streaming Not Safe For Work (NSFW) content and does not have the NSFW toggle enabled on their server will be removed.
  • Any server streaming harmful, hurtful, misleading or hateful content in any way will not be listed.
  • You may reach out to the Owncast team to report any objectionable content or content that you believe should not be be publicly listed.
  • You have the right to free software and to build whatever you want with it. But there is no obligation for others to share it.
); // eslint-disable-next-line react/function-component-definition export default function EditInstanceDetails() { const [formDataValues, setFormDataValues] = useState(null); const serverStatusData = useContext(ServerStatusContext); const { serverConfig } = serverStatusData || {}; const { instanceDetails, yp, hideViewerCount, disableSearchIndexing } = serverConfig; const { instanceUrl } = yp; const [offlineMessageSaveStatus, setOfflineMessageSaveStatus] = useState(null); const [isDirectoryInfoModalOpen, setIsDirectoryInfoModalOpen] = useState(false); useEffect(() => { setFormDataValues({ ...instanceDetails, ...yp, hideViewerCount, disableSearchIndexing, }); }, [instanceDetails, yp]); if (!formDataValues) { return null; } const handleDirectorySwitchChange = (value: boolean) => { if (!value) { // Disabled. No-op. } else { setIsDirectoryInfoModalOpen(true); } setFormDataValues({ ...formDataValues, yp: { enabled: value, }, }); }; // if instanceUrl is empty, we should also turn OFF the `enabled` field of directory. const handleSubmitInstanceUrl = () => { if (formDataValues.instanceUrl === '') { if (yp.enabled === true) { postConfigUpdateToAPI({ apiPath: API_YP_SWITCH, data: { value: false }, }); } } }; const handleSaveOfflineMessage = () => { postConfigUpdateToAPI({ apiPath: API_SERVER_OFFLINE_MESSAGE, data: { value: formDataValues.offlineMessage }, }); setOfflineMessageSaveStatus(createInputStatus(STATUS_SUCCESS)); setTimeout(() => { setOfflineMessageSaveStatus(null); }, 2000); }; const handleFieldChange = ({ fieldName, value }: UpdateArgs) => { setFormDataValues({ ...formDataValues, [fieldName]: value, }); }; function handleHideViewerCountChange(enabled: boolean) { handleFieldChange({ fieldName: 'hideViewerCount', value: enabled }); } function handleDisableSearchEngineIndexingChange(enabled: boolean) { handleFieldChange({ fieldName: 'disableSearchIndexing', value: enabled }); } function directoryInfoModalCancelPressed() { setIsDirectoryInfoModalOpen(false); handleDirectorySwitchChange(false); handleFieldChange({ fieldName: 'enabled', value: false }); } function directoryInfoModalOkPressed() { setIsDirectoryInfoModalOpen(false); handleFieldChange({ fieldName: 'enabled', value: true }); setFormDataValues({ ...formDataValues, yp: { enabled: true, }, }); } const hasInstanceUrl = instanceUrl !== ''; return (
Configure Instance Details

Offline Message:

{ handleFieldChange({ fieldName: 'offlineMessage', value }); }} extensions={[markdown({ base: markdownLanguage, codeLanguages: languages })]} />
The offline message is displayed to your page visitors when you're not streaming. Markdown is supported.
{/* Logo section */}

Increase your audience by appearing in the{' '} Owncast Directory . This is an external service run by the Owncast project.{' '} Learn more .

{!yp.instanceUrl && (

You must set your Server URL above to enable the directory.

)}
{isDirectoryInfoModalOpen && ( )}
); }