mirror of
				https://github.com/owncast/owncast.git
				synced 2025-11-01 02:44:31 +08:00 
			
		
		
		
	 383b80851b
			
		
	
	383b80851b
	
	
	
		
			
			* Initial plan * Add localization support to admin form status and error messages Co-authored-by: gabek <414923+gabek@users.noreply.github.com> * Format updated files with prettier Co-authored-by: gabek <414923+gabek@users.noreply.github.com> * Replace t() with Translation component in admin page JSX Co-authored-by: gabek <414923+gabek@users.noreply.github.com> * update package-lock.json * Update web/i18n/en/translation.json Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: gabek <414923+gabek@users.noreply.github.com> Co-authored-by: Gabe Kangas <gabek@real-ity.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
		
			
				
	
	
		
			129 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			129 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| // This is a wrapper for the Ant Switch component.
 | |
| // This one is styled to match the form-textfield component.
 | |
| // If `useSubmit` is true then it will automatically post to the config API onChange.
 | |
| 
 | |
| import React, { useState, useContext, FC } from 'react';
 | |
| import { Switch } from 'antd';
 | |
| import { useTranslation } from 'next-export-i18n';
 | |
| import {
 | |
|   createInputStatus,
 | |
|   StatusState,
 | |
|   STATUS_ERROR,
 | |
|   STATUS_PROCESSING,
 | |
|   STATUS_SUCCESS,
 | |
| } from '../../utils/input-statuses';
 | |
| import { Localization } from '../../types/localization';
 | |
| import { FormStatusIndicator } from './FormStatusIndicator';
 | |
| 
 | |
| import { RESET_TIMEOUT, postConfigUpdateToAPI } from '../../utils/config-constants';
 | |
| import { ServerStatusContext } from '../../utils/server-status-context';
 | |
| 
 | |
| export type ToggleSwitchProps = {
 | |
|   fieldName: string;
 | |
| 
 | |
|   apiPath?: string;
 | |
|   checked?: boolean;
 | |
|   reversed?: boolean;
 | |
|   configPath?: string;
 | |
|   disabled?: boolean;
 | |
|   label?: string;
 | |
|   tip?: string;
 | |
|   useSubmit?: boolean;
 | |
|   onChange?: (arg: boolean) => void;
 | |
| };
 | |
| 
 | |
| export const ToggleSwitch: FC<ToggleSwitchProps> = ({
 | |
|   apiPath,
 | |
|   checked,
 | |
|   reversed = false,
 | |
|   configPath = '',
 | |
|   disabled = false,
 | |
|   fieldName,
 | |
|   label,
 | |
|   tip,
 | |
|   useSubmit,
 | |
|   onChange,
 | |
| }) => {
 | |
|   const { t } = useTranslation();
 | |
|   const [submitStatus, setSubmitStatus] = useState<StatusState>(null);
 | |
| 
 | |
|   let resetTimer = null;
 | |
| 
 | |
|   const serverStatusData = useContext(ServerStatusContext);
 | |
|   const { setFieldInConfigState } = serverStatusData || {};
 | |
| 
 | |
|   const resetStates = () => {
 | |
|     setSubmitStatus(null);
 | |
|     clearTimeout(resetTimer);
 | |
|     resetTimer = null;
 | |
|   };
 | |
| 
 | |
|   const handleChange = async (isChecked: boolean) => {
 | |
|     if (useSubmit) {
 | |
|       setSubmitStatus(createInputStatus(STATUS_PROCESSING));
 | |
|       const isCheckedSend = reversed ? !isChecked : isChecked;
 | |
| 
 | |
|       await postConfigUpdateToAPI({
 | |
|         apiPath,
 | |
|         data: { value: isCheckedSend },
 | |
|         onSuccess: () => {
 | |
|           setFieldInConfigState({ fieldName, value: isCheckedSend, path: configPath });
 | |
|           setSubmitStatus(createInputStatus(STATUS_SUCCESS));
 | |
|         },
 | |
|         onError: (message: string) => {
 | |
|           setSubmitStatus(
 | |
|             createInputStatus(
 | |
|               STATUS_ERROR,
 | |
|               t(Localization.Admin.StatusMessages.thereWasAnError, { message }),
 | |
|             ),
 | |
|           );
 | |
|         },
 | |
|       });
 | |
|       resetTimer = setTimeout(resetStates, RESET_TIMEOUT);
 | |
|     }
 | |
|     if (onChange) {
 | |
|       onChange(isChecked);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   const loading = submitStatus !== null && submitStatus.type === STATUS_PROCESSING;
 | |
|   return (
 | |
|     <div className="formfield-container toggleswitch-container">
 | |
|       {label && (
 | |
|         <div className="label-side">
 | |
|           <span className="formfield-label">{label}</span>
 | |
|         </div>
 | |
|       )}
 | |
| 
 | |
|       <div className="input-side">
 | |
|         <div className="input-group">
 | |
|           <Switch
 | |
|             className={`switch field-${fieldName}`}
 | |
|             loading={loading}
 | |
|             onChange={handleChange}
 | |
|             defaultChecked={checked}
 | |
|             checked={checked}
 | |
|             checkedChildren="ON"
 | |
|             unCheckedChildren="OFF"
 | |
|             disabled={disabled}
 | |
|           />
 | |
|           <FormStatusIndicator status={submitStatus} />
 | |
|         </div>
 | |
|         <p className="field-tip">{tip}</p>
 | |
|       </div>
 | |
|     </div>
 | |
|   );
 | |
| };
 | |
| 
 | |
| ToggleSwitch.defaultProps = {
 | |
|   apiPath: '',
 | |
|   checked: false,
 | |
|   reversed: false,
 | |
|   configPath: '',
 | |
|   disabled: false,
 | |
|   label: '',
 | |
|   tip: '',
 | |
|   useSubmit: false,
 | |
|   onChange: null,
 | |
| };
 |